FindFirstFileW

This commit is contained in:
rjkiv 2025-08-09 14:53:56 -07:00
parent 87c71a6763
commit f80d7dda62
4 changed files with 75 additions and 2 deletions

View File

@ -4,6 +4,7 @@
#include "handles.h"
#include <algorithm>
#include <climits>
#include <cstdint>
#include <cstdlib>
#include <ctype.h>
#include <filesystem>
@ -780,6 +781,27 @@ namespace kernel32 {
strcpy(data->cAlternateFileName, "8P3FMTFN.BAD");
}
void setFindFileDataFromPathW(WIN32_FIND_DATA<uint16_t>* data, const std::filesystem::path &path){
auto status = std::filesystem::status(path);
uint64_t fileSize = 0;
data->dwFileAttributes = 0;
if (std::filesystem::is_directory(status)) {
data->dwFileAttributes |= 0x10;
}
if (std::filesystem::is_regular_file(status)) {
data->dwFileAttributes |= 0x80;
fileSize = std::filesystem::file_size(path);
}
data->nFileSizeHigh = (uint32_t)(fileSize >> 32);
data->nFileSizeLow = (uint32_t)fileSize;
auto fileName = path.filename().string();
assert(fileName.size() < 260);
auto wideFileName = stringToWideString(fileName.c_str());
wstrcpy(data->cFileName, wideFileName.data());
auto wideBad = stringToWideString("8P3FMTFN.BAD");
wstrcpy(data->cAlternateFileName, wideBad.data());
}
void *WIN_FUNC FindFirstFileA(const char *lpFileName, WIN32_FIND_DATA<char> *lpFindFileData) {
// This should handle wildcards too, but whatever.
auto path = files::pathFromWindows(lpFileName);
@ -822,6 +844,49 @@ namespace kernel32 {
return handle;
}
void *WIN_FUNC FindFirstFileW(const uint16_t *lpFileName, WIN32_FIND_DATA<uint16_t> *lpFindFileData) {
std::string filename = wideStringToString(lpFileName);
// This should handle wildcards too, but whatever.
auto path = files::pathFromWindows(filename.c_str());
DEBUG_LOG("FindFirstFileW %s (%s)\n", filename.c_str(), path.c_str());
lpFindFileData->ftCreationTime = defaultFiletime;
lpFindFileData->ftLastAccessTime = defaultFiletime;
lpFindFileData->ftLastWriteTime = defaultFiletime;
auto status = std::filesystem::status(path);
if (status.type() == std::filesystem::file_type::regular) {
setFindFileDataFromPathW(lpFindFileData, path);
return (void *) 1;
}
// If the parent path is empty then we assume the parent path is the current directory.
auto parent_path = path.parent_path();
if (parent_path == "") {
parent_path = ".";
}
if (!std::filesystem::exists(parent_path)) {
wibo::lastError = ERROR_PATH_NOT_FOUND;
return INVALID_HANDLE_VALUE;
}
auto *handle = new FindFirstFileHandle();
std::filesystem::directory_iterator it(parent_path);
handle->it = it;
handle->pattern = path.filename().string();
if (!findNextFile(handle)) {
wibo::lastError = ERROR_FILE_NOT_FOUND;
delete handle;
return INVALID_HANDLE_VALUE;
}
setFindFileDataFromPathW(lpFindFileData, *handle->it++);
return handle;
}
typedef enum _FINDEX_INFO_LEVELS {
FindExInfoStandard,
FindExInfoBasic,
@ -2529,6 +2594,7 @@ static void *resolveByName(const char *name) {
if (strcmp(name, "GetFullPathNameW") == 0) return (void *) kernel32::GetFullPathNameW;
if (strcmp(name, "GetShortPathNameA") == 0) return (void *) kernel32::GetShortPathNameA;
if (strcmp(name, "FindFirstFileA") == 0) return (void *) kernel32::FindFirstFileA;
if (strcmp(name, "FindFirstFileW") == 0) return (void *) kernel32::FindFirstFileW;
if (strcmp(name, "FindFirstFileExA") == 0) return (void *) kernel32::FindFirstFileExA;
if (strcmp(name, "FindNextFileA") == 0) return (void *) kernel32::FindNextFileA;
if (strcmp(name, "FindClose") == 0) return (void *) kernel32::FindClose;

View File

@ -310,11 +310,11 @@ namespace msvcrt {
int WIN_ENTRY _itow_s(int value, uint16_t *buffer, size_t size, int radix){
DEBUG_LOG("_itow_s value %d, size %d, radix %d\n", value, size, radix);
if (!buffer || size == 0) return -1;
if (radix != 10) return -1; // only base 10 supported for now
assert(radix == 10); // only base 10 supported for now
std::string str = std::to_string(value);
std::vector<uint16_t> wstr = stringToWideString(str.c_str());
buffer = wstr.data();
wstrcpy(buffer, wstr.data());
return 0;
}

View File

@ -77,6 +77,12 @@ uint16_t* wstrncat(uint16_t* dest, const uint16_t* src, size_t count){
return dest;
}
uint16_t* wstrcpy(uint16_t* dest, const uint16_t* src){
uint16_t* d = dest;
while ((*d++ = *src++) != 0);
return dest;
}
size_t wstrncpy(uint16_t *dst, const uint16_t *src, size_t n) {
size_t i = 0;
while (i < n && src[i] != 0) {

View File

@ -8,6 +8,7 @@ const uint16_t* wstrstr(const uint16_t *dest, const uint16_t *src);
uint16_t* wstrrchr(const uint16_t* str, uint16_t c);
uint16_t* wstrcat(uint16_t* dest, const uint16_t* src);
uint16_t* wstrncat(uint16_t* dest, const uint16_t* src, size_t count);
uint16_t* wstrcpy(uint16_t* dest, const uint16_t* src);
size_t wstrncpy(uint16_t *dst, const uint16_t *src, size_t n);
std::string wideStringToString(const uint16_t *src, int len = -1);
std::vector<uint16_t> stringToWideString(const char *src);