mirror of
https://github.com/decompals/wibo.git
synced 2025-10-15 22:55:11 +00:00
FindFirstFileW
This commit is contained in:
parent
87c71a6763
commit
f80d7dda62
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user