Add GetTempFileNameA (#84)

This commit is contained in:
Dávid Balatoni 2025-06-18 00:12:39 +02:00 committed by GitHub
parent 5343bc70d9
commit 8bd112f0e4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 47 additions and 0 deletions

View File

@ -55,6 +55,7 @@ typedef unsigned char BYTE;
#define ERROR_HANDLE_EOF 38
#define ERROR_NOT_SUPPORTED 50
#define ERROR_INVALID_PARAMETER 87
#define ERROR_BUFFER_OVERFLOW 111
#define ERROR_INSUFFICIENT_BUFFER 122
#define ERROR_NEGATIVE_SEEK 131
#define ERROR_ALREADY_EXISTS 183
@ -72,6 +73,8 @@ typedef int NTSTATUS;
typedef int HRESULT;
#define S_OK ((HRESULT)0x00000000)
#define MAX_PATH (260)
namespace wibo {
extern uint32_t lastError;
extern char **argv;

View File

@ -3,6 +3,7 @@
#include "processes.h"
#include "handles.h"
#include <algorithm>
#include <climits>
#include <cstdlib>
#include <ctype.h>
#include <filesystem>
@ -10,6 +11,7 @@
#include <string>
#include "strutil.h"
#include <malloc.h>
#include <random>
#include <stdarg.h>
#include <system_error>
#include <sys/mman.h>
@ -17,6 +19,7 @@
#include <sys/wait.h>
#include <spawn.h>
#include <vector>
#include <fcntl.h>
typedef union _RTL_RUN_ONCE {
PVOID Ptr;
@ -649,6 +652,46 @@ namespace kernel32 {
}
}
using random_shorts_engine = std::independent_bits_engine<std::default_random_engine, sizeof(unsigned short) * 8, unsigned short>;
unsigned int WIN_FUNC GetTempFileNameA(LPSTR lpPathName, LPSTR lpPrefixString, unsigned int uUnique, LPSTR lpTempFileName) {
DEBUG_LOG("GetTempFileNameA\n");
if (lpPathName == 0) {
return 0;
}
if (strlen(lpPathName) > MAX_PATH - 14) {
wibo::lastError = ERROR_BUFFER_OVERFLOW;
return 0;
}
char uniqueStr[20];
std::filesystem::path path;
if (uUnique == 0) {
std::random_device rd;
random_shorts_engine rse(rd());
while(true) {
uUnique = rse();
if (uUnique == 0) {
continue;
}
snprintf(uniqueStr, sizeof(uniqueStr), "%.3s%X.TMP", lpPrefixString, uUnique);
path = files::pathFromWindows(lpPathName) / uniqueStr;
// Atomically create it if it doesn't exist
int fd = open(path.c_str(), O_CREAT | O_EXCL | O_WRONLY, 0644);
if (fd >= 0) {
close(fd);
break;
}
}
}
else {
snprintf(uniqueStr, sizeof(uniqueStr), "%.3s%X.TMP", lpPrefixString, uUnique & 0xFFFF);
path = files::pathFromWindows(lpPathName) / uniqueStr;
}
strncpy(lpTempFileName, files::pathToWindows(path).c_str(), MAX_PATH);
return uUnique;
}
DWORD WIN_FUNC GetTempPathA(DWORD nBufferLength, LPSTR lpBuffer) {
DEBUG_LOG("GetTempPathA\n");
@ -2368,6 +2411,7 @@ static void *resolveByName(const char *name) {
if (strcmp(name, "GetFileType") == 0) return (void *) kernel32::GetFileType;
if (strcmp(name, "FileTimeToLocalFileTime") == 0) return (void *) kernel32::FileTimeToLocalFileTime;
if (strcmp(name, "GetFileInformationByHandle") == 0) return (void *) kernel32::GetFileInformationByHandle;
if (strcmp(name, "GetTempFileNameA") == 0) return (void *) kernel32::GetTempFileNameA;
if (strcmp(name, "GetTempPathA") == 0) return (void *) kernel32::GetTempPathA;
// sysinfoapi.h