Last active
September 5, 2023 09:16
-
-
Save kostix/3c7ac9c1679c71787a272b8eed3a722b to your computer and use it in GitHub Desktop.
FindFirstFile/FindNextFile
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdlib.h> | |
#include <stdio.h> | |
#include <locale.h> | |
#define WIN32_LEAN_AND_MEAN | |
#define _UNICODE | |
#include <windows.h> | |
int print_sys_error(DWORD last_error) | |
{ | |
DWORD rc; | |
LPWSTR msg; | |
rc = FormatMessageW( | |
FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM, | |
NULL, | |
last_error, | |
0, | |
(LPWSTR)&msg, | |
0, | |
NULL); | |
if (rc == 0) { | |
fputws(L"FormatMessage failed\n", stderr); | |
abort(); | |
} | |
fputws(msg, stderr); | |
LocalFree(msg); | |
return 0; | |
} | |
DWORD print_matching(const wchar_t *pattern) | |
{ | |
HANDLE hFile; | |
WIN32_FIND_DATAW ffd; | |
SetLastError(0); | |
hFile = FindFirstFileW(pattern, &ffd); | |
if (hFile == INVALID_HANDLE_VALUE) { | |
return GetLastError(); | |
} | |
DWORD last_error = 0; | |
for (;;) { | |
if (FindNextFile(hFile, &ffd) == 0) { | |
DWORD rc; | |
rc = GetLastError(); | |
if (rc == ERROR_NO_MORE_FILES) { | |
break; | |
} | |
last_error = rc; | |
break; | |
} | |
fputws(ffd.cFileName, stdout); | |
fputwc(L'\n', stdout); | |
} | |
FindClose(hFile); | |
return last_error; | |
} | |
wchar_t *get_pattern(const wchar_t *dirname, const size_t namelen) | |
{ | |
const wchar_t wildcard[] = L"*.*"; | |
const size_t wc_len = sizeof(wildcard)/sizeof(wildcard[0]); | |
size_t dstlen; | |
BOOL need_sep; | |
dstlen = namelen + wc_len; | |
need_sep = dirname[namelen-1] != L'\\'; | |
if (need_sep) { | |
dstlen++; | |
} | |
wchar_t *pattern; | |
pattern = (wchar_t*)malloc(dstlen * sizeof(wchar_t)); | |
if (pattern == NULL) { | |
fputws(L"out of memory\n", stderr); | |
abort(); | |
} | |
wcscpy(pattern, dirname); | |
size_t wc_pos = namelen; | |
if (need_sep) { | |
pattern[wc_pos] = L'\\'; | |
wc_pos++; | |
} | |
wcscpy(pattern + wc_pos, wildcard); | |
pattern[dstlen] = L'\0'; | |
return pattern; | |
} | |
int wmain(int argc, const wchar_t **argv) | |
{ | |
if (setlocale(LC_ALL, "") == NULL) { | |
fputws(L"setlocale failed\n", stderr); | |
abort(); | |
} | |
wchar_t *pattern; | |
BOOL allocated; | |
switch (argc) { | |
case 2: | |
size_t namelen = wcslen(argv[1]); | |
if (namelen > 0) { | |
pattern = get_pattern(argv[1], namelen); | |
allocated = TRUE; | |
break; | |
} | |
// fall through | |
case 1: | |
pattern = L".\\*.*"; | |
allocated = FALSE; | |
break; | |
default: | |
fputws(L"wrong number of arguments.\n", stderr); | |
return 2; | |
} | |
fputws(pattern, stdout); | |
fputwc(L'\n', stdout); | |
fflush(stdout); | |
DWORD rc; | |
rc = print_matching(pattern); | |
if (rc != 0) { | |
print_sys_error(rc); | |
} | |
if (allocated) { | |
free(pattern); | |
} | |
if (rc == 0) { | |
return 0; | |
} | |
return 1; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment