mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-06 18:00:17 +02:00
469 lines
17 KiB
C++
469 lines
17 KiB
C++
// SPDX-License-Identifier: MIT
|
|
#define NTDDI_VERSION 0x0A000005
|
|
#define WINAPI
|
|
#define WINBASEAPI
|
|
|
|
#include <cstdlib>
|
|
#include <cstdio>
|
|
#include <cstdint>
|
|
#include <cerrno>
|
|
#include <winternl.h>
|
|
#include <windows.h>
|
|
#include <processenv.h>
|
|
#include <wine/debug.h>
|
|
#include "../Priv.h"
|
|
|
|
namespace {
|
|
ULONG CreateDispositionToNT(DWORD Disposition) {
|
|
switch (Disposition) {
|
|
case CREATE_ALWAYS: return FILE_OVERWRITE_IF;
|
|
case CREATE_NEW: return FILE_CREATE;
|
|
case TRUNCATE_EXISTING: return FILE_OVERWRITE;
|
|
case OPEN_ALWAYS: return FILE_OPEN_IF;
|
|
case OPEN_EXISTING: return FILE_OPEN;
|
|
default: UNIMPLEMENTED();
|
|
}
|
|
}
|
|
|
|
ULONG OpenFlagsToNT(DWORD Flags) {
|
|
ULONG NTFlags = 0;
|
|
NTFlags |= (Flags & FILE_FLAG_BACKUP_SEMANTICS) ? FILE_OPEN_FOR_BACKUP_INTENT : 0;
|
|
NTFlags |= (Flags & FILE_FLAG_DELETE_ON_CLOSE) ? FILE_DELETE_ON_CLOSE : 0;
|
|
NTFlags |= (Flags & FILE_FLAG_NO_BUFFERING) ? FILE_NO_INTERMEDIATE_BUFFERING : 0;
|
|
NTFlags |= (Flags & FILE_FLAG_RANDOM_ACCESS) ? FILE_RANDOM_ACCESS : 0;
|
|
NTFlags |= (Flags & FILE_FLAG_SEQUENTIAL_SCAN) ? FILE_SEQUENTIAL_ONLY : 0;
|
|
NTFlags |= (Flags & FILE_FLAG_WRITE_THROUGH) ? FILE_WRITE_THROUGH : 0;
|
|
return NTFlags;
|
|
}
|
|
|
|
FILE_INFORMATION_CLASS FileInfoClassToNT(FILE_INFO_BY_HANDLE_CLASS InformationClass) {
|
|
switch (InformationClass) {
|
|
case FileBasicInfo: return FileBasicInformation;
|
|
case FileStandardInfo: return FileStandardInformation;
|
|
default: UNIMPLEMENTED();
|
|
}
|
|
}
|
|
} // namespace
|
|
|
|
DLLEXPORT_FUNC(BOOL, RemoveDirectoryA, (LPCSTR lpFileName)) {
|
|
ScopedUnicodeString FileName {lpFileName};
|
|
return RemoveDirectoryW(FileName->Buffer);
|
|
}
|
|
|
|
DLLEXPORT_FUNC(BOOL, RemoveDirectoryW, (LPCWSTR lpFileName)) {
|
|
UNICODE_STRING PathW;
|
|
RtlInitUnicodeString(&PathW, lpFileName);
|
|
|
|
ScopedUnicodeString NTPath;
|
|
if (!RtlDosPathNameToNtPathName_U(PathW.Buffer, &*NTPath, nullptr, nullptr)) {
|
|
SetLastError(ERROR_PATH_NOT_FOUND);
|
|
return false;
|
|
}
|
|
|
|
OBJECT_ATTRIBUTES ObjAttributes;
|
|
InitializeObjectAttributes(&ObjAttributes, &*NTPath, OBJ_CASE_INSENSITIVE, nullptr, nullptr);
|
|
|
|
HANDLE Handle;
|
|
IO_STATUS_BLOCK IOSB;
|
|
|
|
NTSTATUS Status =
|
|
NtCreateFile(&Handle, SYNCHRONIZE | DELETE, &ObjAttributes, &IOSB, nullptr, 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
|
FILE_OPEN, FILE_DELETE_ON_CLOSE | FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_REPARSE_POINT, nullptr, 0);
|
|
if (WinAPIReturn(Status)) {
|
|
Status = NtClose(Handle);
|
|
}
|
|
|
|
return WinAPIReturn(Status);
|
|
}
|
|
|
|
DLLEXPORT_FUNC(BOOL, DeleteFileA, (LPCSTR lpFileName)) {
|
|
ScopedUnicodeString FileName {lpFileName};
|
|
return DeleteFileW(FileName->Buffer);
|
|
}
|
|
|
|
DLLEXPORT_FUNC(BOOL, DeleteFileW, (LPCWSTR lpFileName)) {
|
|
UNICODE_STRING PathW;
|
|
RtlInitUnicodeString(&PathW, lpFileName);
|
|
|
|
ScopedUnicodeString NTPath;
|
|
if (!RtlDosPathNameToNtPathName_U(PathW.Buffer, &*NTPath, nullptr, nullptr)) {
|
|
SetLastError(ERROR_PATH_NOT_FOUND);
|
|
return false;
|
|
}
|
|
|
|
OBJECT_ATTRIBUTES ObjAttributes;
|
|
InitializeObjectAttributes(&ObjAttributes, &*NTPath, OBJ_CASE_INSENSITIVE, nullptr, nullptr);
|
|
|
|
HANDLE Handle;
|
|
IO_STATUS_BLOCK IOSB;
|
|
|
|
NTSTATUS Status =
|
|
NtCreateFile(&Handle, SYNCHRONIZE | DELETE, &ObjAttributes, &IOSB, nullptr, 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
|
FILE_OPEN, FILE_DELETE_ON_CLOSE | FILE_NON_DIRECTORY_FILE, nullptr, 0);
|
|
if (WinAPIReturn(Status)) {
|
|
Status = NtClose(Handle);
|
|
}
|
|
|
|
return WinAPIReturn(Status);
|
|
}
|
|
|
|
DLLEXPORT_FUNC(HANDLE, CreateFileA,
|
|
(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes,
|
|
DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)) {
|
|
|
|
ScopedUnicodeString FileName {lpFileName};
|
|
return CreateFileW(FileName->Buffer, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes,
|
|
hTemplateFile);
|
|
}
|
|
|
|
DLLEXPORT_FUNC(HANDLE, CreateFileW,
|
|
(LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes,
|
|
DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)) {
|
|
UNICODE_STRING PathW;
|
|
RtlInitUnicodeString(&PathW, lpFileName);
|
|
|
|
ScopedUnicodeString NTPath;
|
|
if (!RtlDosPathNameToNtPathName_U(PathW.Buffer, &*NTPath, nullptr, nullptr)) {
|
|
SetLastError(ERROR_PATH_NOT_FOUND);
|
|
return INVALID_HANDLE_VALUE;
|
|
}
|
|
|
|
OBJECT_ATTRIBUTES ObjAttributes;
|
|
InitializeObjectAttributes(&ObjAttributes, &*NTPath, OBJ_CASE_INSENSITIVE, nullptr, nullptr);
|
|
|
|
HANDLE Handle;
|
|
IO_STATUS_BLOCK IOSB;
|
|
NTSTATUS Status =
|
|
NtCreateFile(&Handle, dwDesiredAccess | GENERIC_READ | SYNCHRONIZE, &ObjAttributes, &IOSB, nullptr, OpenFlagsToNT(dwFlagsAndAttributes),
|
|
dwShareMode, CreateDispositionToNT(dwCreationDisposition), FILE_SYNCHRONOUS_IO_NONALERT, nullptr, 0);
|
|
return WinAPIReturn(Status) ? Handle : INVALID_HANDLE_VALUE;
|
|
}
|
|
|
|
DLLEXPORT_FUNC(WINBOOL, WriteFile,
|
|
(HANDLE hFile, const void* lpBuffer, DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped)) {
|
|
IO_STATUS_BLOCK IOSB;
|
|
LARGE_INTEGER ByteOffset;
|
|
PLARGE_INTEGER ByteOffsetPtr = nullptr;
|
|
if (lpOverlapped) {
|
|
if (lpOverlapped->hEvent) {
|
|
UNIMPLEMENTED();
|
|
}
|
|
ByteOffset.QuadPart = (static_cast<LONGLONG>(lpOverlapped->OffsetHigh) << 32) | lpOverlapped->Offset;
|
|
ByteOffsetPtr = &ByteOffset;
|
|
}
|
|
NTSTATUS Status = NtWriteFile(hFile, nullptr, nullptr, nullptr, &IOSB, lpBuffer, nNumberOfBytesToWrite, ByteOffsetPtr, nullptr);
|
|
if (lpNumberOfBytesWritten) {
|
|
*lpNumberOfBytesWritten = static_cast<DWORD>(IOSB.Information);
|
|
}
|
|
return WinAPIReturn(Status);
|
|
}
|
|
|
|
DLLEXPORT_FUNC(HANDLE, GetStdHandle, (DWORD nStdHandle)) {
|
|
UNIMPLEMENTED();
|
|
}
|
|
|
|
DLLEXPORT_FUNC(WINBOOL, WriteConsoleA,
|
|
(HANDLE hConsoleOutput, CONST void* lpBuffer, DWORD nNumberOfCharsToWrite, LPDWORD lpNumberOfCharsWritten, void* lpReserved)) {
|
|
UNIMPLEMENTED();
|
|
}
|
|
|
|
DLLEXPORT_FUNC(WINBOOL, WriteConsoleW,
|
|
(HANDLE hConsoleOutput, CONST void* lpBuffer, DWORD nNumberOfCharsToWrite, LPDWORD lpNumberOfCharsWritten, void* lpReserved)) {
|
|
UNIMPLEMENTED();
|
|
}
|
|
|
|
DLLEXPORT_FUNC(WINBOOL, GetFileSizeEx, (HANDLE hFile, PLARGE_INTEGER lpFileSize)) {
|
|
IO_STATUS_BLOCK IOSB;
|
|
FILE_STANDARD_INFORMATION StandardInfo;
|
|
if (NTSTATUS Status = NtQueryInformationFile(hFile, &IOSB, &StandardInfo, sizeof(StandardInfo), FileStandardInformation); Status) {
|
|
return WinAPIReturn(Status);
|
|
}
|
|
if (lpFileSize) {
|
|
*lpFileSize = StandardInfo.EndOfFile;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
DLLEXPORT_FUNC(WINBOOL, SetFilePointerEx, (HANDLE hFile, LARGE_INTEGER liDistanceToMove, PLARGE_INTEGER lpNewFilePointer, DWORD dwMoveMethod)) {
|
|
IO_STATUS_BLOCK IOSB;
|
|
FILE_POSITION_INFORMATION PositionInfo;
|
|
if (NTSTATUS Status = NtQueryInformationFile(hFile, &IOSB, &PositionInfo, sizeof(PositionInfo), FilePositionInformation); Status) {
|
|
return WinAPIReturn(Status);
|
|
}
|
|
FILE_STANDARD_INFORMATION StandardInfo;
|
|
if (NTSTATUS Status = NtQueryInformationFile(hFile, &IOSB, &StandardInfo, sizeof(StandardInfo), FileStandardInformation); Status) {
|
|
return WinAPIReturn(Status);
|
|
}
|
|
|
|
switch (dwMoveMethod) {
|
|
case FILE_BEGIN: {
|
|
PositionInfo.CurrentByteOffset = liDistanceToMove;
|
|
break;
|
|
}
|
|
case FILE_CURRENT: {
|
|
PositionInfo.CurrentByteOffset.QuadPart += liDistanceToMove.QuadPart;
|
|
break;
|
|
}
|
|
case FILE_END: {
|
|
PositionInfo.CurrentByteOffset.QuadPart = StandardInfo.EndOfFile.QuadPart + liDistanceToMove.QuadPart;
|
|
break;
|
|
}
|
|
default: UNIMPLEMENTED();
|
|
}
|
|
if (NTSTATUS Status = NtSetInformationFile(hFile, &IOSB, &PositionInfo, sizeof(PositionInfo), FilePositionInformation); Status) {
|
|
return WinAPIReturn(Status);
|
|
}
|
|
if (lpNewFilePointer) {
|
|
*lpNewFilePointer = PositionInfo.CurrentByteOffset;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
DLLEXPORT_FUNC(WINBOOL, ReadFile,
|
|
(HANDLE hFile, void* lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped)) {
|
|
IO_STATUS_BLOCK IOSB;
|
|
LARGE_INTEGER ByteOffset;
|
|
PLARGE_INTEGER ByteOffsetPtr = nullptr;
|
|
if (lpOverlapped) {
|
|
if (lpOverlapped->hEvent) {
|
|
// no actual async-overlapped, just enough for PRead
|
|
UNIMPLEMENTED();
|
|
}
|
|
ByteOffset.QuadPart = (static_cast<LONGLONG>(lpOverlapped->OffsetHigh) << 32) | lpOverlapped->Offset;
|
|
ByteOffsetPtr = &ByteOffset;
|
|
}
|
|
NTSTATUS Status = NtReadFile(hFile, nullptr, nullptr, nullptr, &IOSB, lpBuffer, nNumberOfBytesToRead, ByteOffsetPtr, nullptr);
|
|
if (lpNumberOfBytesRead) {
|
|
*lpNumberOfBytesRead = static_cast<DWORD>(IOSB.Information);
|
|
}
|
|
return WinAPIReturn(Status);
|
|
}
|
|
|
|
DLLEXPORT_FUNC(WINBOOL, FlushFileBuffers, (HANDLE hFile)) {
|
|
UNIMPLEMENTED();
|
|
}
|
|
|
|
DLLEXPORT_FUNC(
|
|
WINBOOL, LockFileEx,
|
|
(HANDLE hFile, DWORD dwFlags, DWORD dwReserved, DWORD nNumberOfBytesToLockLow, DWORD nNumberOfBytesToLockHigh, LPOVERLAPPED lpOverlapped)) {
|
|
if (!lpOverlapped || lpOverlapped->hEvent) {
|
|
UNIMPLEMENTED();
|
|
}
|
|
LARGE_INTEGER ByteOffset;
|
|
ByteOffset.QuadPart = (static_cast<LONGLONG>(lpOverlapped->OffsetHigh) << 32) | lpOverlapped->Offset;
|
|
LARGE_INTEGER Length;
|
|
Length.QuadPart = (static_cast<LONGLONG>(nNumberOfBytesToLockHigh) << 32) | nNumberOfBytesToLockLow;
|
|
// IoStatusBlock must be null on Wine :harold:
|
|
NTSTATUS Status = NtLockFile(hFile, nullptr, nullptr, nullptr, nullptr, &ByteOffset, &Length, 0, !!(dwFlags & LOCKFILE_FAIL_IMMEDIATELY),
|
|
!!(dwFlags & LOCKFILE_EXCLUSIVE_LOCK));
|
|
return WinAPIReturn(Status);
|
|
}
|
|
|
|
DLLEXPORT_FUNC(WINBOOL, UnlockFileEx,
|
|
(HANDLE hFile, DWORD dwReserved, DWORD nNumberOfBytesToUnlockLow, DWORD nNumberOfBytesToUnlockHigh, LPOVERLAPPED lpOverlapped)) {
|
|
if (!lpOverlapped || lpOverlapped->hEvent) {
|
|
UNIMPLEMENTED();
|
|
}
|
|
LARGE_INTEGER ByteOffset;
|
|
ByteOffset.QuadPart = (static_cast<LONGLONG>(lpOverlapped->OffsetHigh) << 32) | lpOverlapped->Offset;
|
|
LARGE_INTEGER Length;
|
|
Length.QuadPart = (static_cast<LONGLONG>(nNumberOfBytesToUnlockHigh) << 32) | nNumberOfBytesToUnlockLow;
|
|
// IoStatusBlock must be non-null on Wine :harold:
|
|
IO_STATUS_BLOCK IoStatusBlock;
|
|
NTSTATUS Status = NtUnlockFile(hFile, &IoStatusBlock, &ByteOffset, &Length, 0);
|
|
return WinAPIReturn(Status);
|
|
}
|
|
|
|
DLLEXPORT_FUNC(DWORD, GetFinalPathNameByHandleA, (HANDLE hFile, LPSTR lpszFilePath, DWORD cchFilePath, DWORD dwFlags)) {
|
|
UNIMPLEMENTED();
|
|
}
|
|
|
|
DLLEXPORT_FUNC(DWORD, GetFinalPathNameByHandleW, (HANDLE hFile, LPWSTR lpszFilePath, DWORD cchFilePath, DWORD dwFlags)) {
|
|
UNIMPLEMENTED();
|
|
}
|
|
|
|
DLLEXPORT_FUNC(WINBOOL, CreateHardLinkA, (LPCSTR lpFileName, LPCSTR lpExistingFileName, LPSECURITY_ATTRIBUTES lpSecurityAttributes)) {
|
|
UNIMPLEMENTED();
|
|
}
|
|
|
|
DLLEXPORT_FUNC(WINBOOL, CreateHardLinkW, (LPCWSTR lpFileName, LPCWSTR lpExistingFileName, LPSECURITY_ATTRIBUTES lpSecurityAttributes)) {
|
|
UNIMPLEMENTED();
|
|
}
|
|
|
|
DLLEXPORT_FUNC(WINBOOL, CreateDirectoryA, (LPCSTR lpPathName, LPSECURITY_ATTRIBUTES lpSecurityAttributes)) {
|
|
UNIMPLEMENTED();
|
|
}
|
|
|
|
DLLEXPORT_FUNC(WINBOOL, CreateDirectoryW, (LPCWSTR lpPathName, LPSECURITY_ATTRIBUTES lpSecurityAttributes)) {
|
|
UNICODE_STRING PathW;
|
|
RtlInitUnicodeString(&PathW, lpPathName);
|
|
|
|
ScopedUnicodeString NTPath;
|
|
if (!RtlDosPathNameToNtPathName_U(PathW.Buffer, &*NTPath, nullptr, nullptr)) {
|
|
SetLastError(ERROR_PATH_NOT_FOUND);
|
|
return false;
|
|
}
|
|
|
|
OBJECT_ATTRIBUTES ObjAttributes;
|
|
InitializeObjectAttributes(&ObjAttributes, &*NTPath, OBJ_CASE_INSENSITIVE, nullptr, nullptr);
|
|
|
|
HANDLE Handle;
|
|
IO_STATUS_BLOCK IOSB;
|
|
NTSTATUS Status = NtCreateFile(&Handle, GENERIC_READ | SYNCHRONIZE, &ObjAttributes, &IOSB, nullptr, FILE_ATTRIBUTE_NORMAL,
|
|
FILE_SHARE_READ, FILE_CREATE, FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, nullptr, 0);
|
|
return WinAPIReturn(Status);
|
|
}
|
|
|
|
DLLEXPORT_FUNC(WINBOOL, GetFileInformationByHandle, (HANDLE hFile, LPBY_HANDLE_FILE_INFORMATION lpFileInformation)) {
|
|
FILE_BASIC_INFO BasicInfo;
|
|
if (!GetFileInformationByHandleEx(hFile, FileBasicInfo, &BasicInfo, sizeof(BasicInfo))) {
|
|
return false;
|
|
}
|
|
FILE_STANDARD_INFO StandardInfo;
|
|
if (!GetFileInformationByHandleEx(hFile, FileStandardInfo, &StandardInfo, sizeof(StandardInfo))) {
|
|
return false;
|
|
}
|
|
|
|
*lpFileInformation = BY_HANDLE_FILE_INFORMATION {
|
|
.dwFileAttributes = BasicInfo.FileAttributes,
|
|
.ftCreationTime = {static_cast<DWORD>(BasicInfo.CreationTime.LowPart), static_cast<DWORD>(BasicInfo.CreationTime.HighPart)},
|
|
.ftLastAccessTime = {static_cast<DWORD>(BasicInfo.LastAccessTime.LowPart), static_cast<DWORD>(BasicInfo.LastAccessTime.HighPart)},
|
|
.ftLastWriteTime = {static_cast<DWORD>(BasicInfo.LastWriteTime.LowPart), static_cast<DWORD>(BasicInfo.LastWriteTime.HighPart)},
|
|
.dwVolumeSerialNumber = 0,
|
|
.nFileSizeHigh = static_cast<DWORD>(StandardInfo.EndOfFile.HighPart),
|
|
.nFileSizeLow = static_cast<DWORD>(StandardInfo.EndOfFile.LowPart),
|
|
.nNumberOfLinks = StandardInfo.NumberOfLinks,
|
|
.nFileIndexHigh = 0,
|
|
.nFileIndexLow = 0};
|
|
return true;
|
|
}
|
|
|
|
DLLEXPORT_FUNC(WINBOOL, SetFileInformationByHandle,
|
|
(HANDLE hFile, FILE_INFO_BY_HANDLE_CLASS FileInformationClass, void* lpFileInformation, DWORD dwBufferSize)) {
|
|
UNIMPLEMENTED();
|
|
}
|
|
|
|
DLLEXPORT_FUNC(WINBOOL, SetEndOfFile, (HANDLE hFile)) {
|
|
UNIMPLEMENTED();
|
|
}
|
|
|
|
DLLEXPORT_FUNC(DWORD, GetFileAttributesA, (LPCSTR lpFileName)) {
|
|
UNIMPLEMENTED();
|
|
}
|
|
|
|
DLLEXPORT_FUNC(DWORD, GetFileAttributesW, (LPCWSTR lpFileName)) {
|
|
UNIMPLEMENTED();
|
|
}
|
|
|
|
DLLEXPORT_FUNC(WINBOOL, SetFileAttributesA, (LPCSTR lpFileName, DWORD dwFileAttributes)) {
|
|
UNIMPLEMENTED();
|
|
}
|
|
|
|
DLLEXPORT_FUNC(WINBOOL, SetFileAttributesW, (LPCWSTR lpFileName, DWORD dwFileAttributes)) {
|
|
UNIMPLEMENTED();
|
|
}
|
|
|
|
DLLEXPORT_FUNC(WINBOOL, SetFileTime,
|
|
(HANDLE hFile, CONST FILETIME* lpCreationTime, CONST FILETIME* lpLastAccessTime, CONST FILETIME* lpLastWriteTime)) {
|
|
UNIMPLEMENTED();
|
|
}
|
|
|
|
DLLEXPORT_FUNC(WINBOOL, MoveFileExA, (LPCSTR lpExistingFileName, LPCSTR lpNewFileName, DWORD dwFlags)) {
|
|
UNIMPLEMENTED();
|
|
}
|
|
|
|
DLLEXPORT_FUNC(WINBOOL, MoveFileExW, (LPCWSTR lpExistingFileName, LPCWSTR lpNewFileName, DWORD dwFlags)) {
|
|
UNIMPLEMENTED();
|
|
}
|
|
|
|
DLLEXPORT_FUNC(WINBOOL, GetDiskFreeSpaceExA,
|
|
(LPCSTR lpDirectoryName, PULARGE_INTEGER lpFreeBytesAvailableToCaller, PULARGE_INTEGER lpTotalNumberOfBytes,
|
|
PULARGE_INTEGER lpTotalNumberOfFreeBytes)) {
|
|
UNIMPLEMENTED();
|
|
}
|
|
|
|
DLLEXPORT_FUNC(WINBOOL, GetDiskFreeSpaceExW,
|
|
(LPCWSTR lpDirectoryName, PULARGE_INTEGER lpFreeBytesAvailableToCaller, PULARGE_INTEGER lpTotalNumberOfBytes,
|
|
PULARGE_INTEGER lpTotalNumberOfFreeBytes)) {
|
|
UNIMPLEMENTED();
|
|
}
|
|
|
|
DLLEXPORT_FUNC(DWORD, GetTempPathA, (DWORD nBufferLength, LPSTR lpBuffer)) {
|
|
UNIMPLEMENTED();
|
|
}
|
|
|
|
DLLEXPORT_FUNC(DWORD, GetTempPathW, (DWORD nBufferLength, LPWSTR lpBuffer)) {
|
|
UNIMPLEMENTED();
|
|
}
|
|
|
|
DLLEXPORT_FUNC(BOOLEAN, CreateSymbolicLinkA, (LPCSTR lpSymlinkFileName, LPCSTR lpTargetFileName, DWORD dwFlags)) {
|
|
UNIMPLEMENTED();
|
|
}
|
|
|
|
DLLEXPORT_FUNC(BOOLEAN, CreateSymbolicLinkW, (LPCWSTR lpSymlinkFileName, LPCWSTR lpTargetFileName, DWORD dwFlags)) {
|
|
UNIMPLEMENTED();
|
|
}
|
|
|
|
DLLEXPORT_FUNC(WINBOOL, AreFileApisANSI, ()) {
|
|
return true;
|
|
}
|
|
|
|
DLLEXPORT_FUNC(WINBOOL, FindNextFileA, (HANDLE hFindFile, LPWIN32_FIND_DATAA lpFindFileData)) {
|
|
UNIMPLEMENTED();
|
|
}
|
|
|
|
DLLEXPORT_FUNC(WINBOOL, FindNextFileW, (HANDLE hFindFile, LPWIN32_FIND_DATAW lpFindFileData)) {
|
|
UNIMPLEMENTED();
|
|
}
|
|
|
|
DLLEXPORT_FUNC(WINBOOL, FindClose, (HANDLE hFindFile)) {
|
|
UNIMPLEMENTED();
|
|
}
|
|
|
|
DLLEXPORT_FUNC(HANDLE, FindFirstFileA, (LPCSTR lpFileName, LPWIN32_FIND_DATAA lpFindFileData)) {
|
|
UNIMPLEMENTED();
|
|
}
|
|
|
|
DLLEXPORT_FUNC(HANDLE, FindFirstFileW, (LPCWSTR lpFileName, LPWIN32_FIND_DATAW lpFindFileData)) {
|
|
UNIMPLEMENTED();
|
|
}
|
|
|
|
DLLEXPORT_FUNC(WINBOOL, DeviceIoControl,
|
|
(HANDLE hDevice, DWORD dwIoControlCode, void* lpInBuffer, DWORD nInBufferSize, void* lpOutBuffer, DWORD nOutBufferSize,
|
|
LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped)) {
|
|
UNIMPLEMENTED();
|
|
}
|
|
|
|
DLLEXPORT_FUNC(WINBOOL, GetFileInformationByHandleEx,
|
|
(HANDLE hFile, FILE_INFO_BY_HANDLE_CLASS FileInformationClass, void* lpFileInformation, DWORD dwBufferSize)) {
|
|
IO_STATUS_BLOCK IOSB;
|
|
return WinAPIReturn(NtQueryInformationFile(hFile, &IOSB, lpFileInformation, dwBufferSize, FileInfoClassToNT(FileInformationClass)));
|
|
}
|
|
|
|
DLLEXPORT_FUNC(void, GetSystemTimeAsFileTime, (LPFILETIME lpSystemTimeAsFileTime)) {
|
|
LARGE_INTEGER Time;
|
|
NtQuerySystemTime(&Time);
|
|
lpSystemTimeAsFileTime->dwLowDateTime = Time.LowPart;
|
|
lpSystemTimeAsFileTime->dwHighDateTime = Time.HighPart;
|
|
}
|
|
|
|
DLLEXPORT_FUNC(void, GetSystemTimePreciseAsFileTime, (LPFILETIME lpSystemTimeAsFileTime)) {
|
|
GetSystemTimeAsFileTime(lpSystemTimeAsFileTime);
|
|
}
|
|
|
|
DLLEXPORT_FUNC(WINBOOL, SetCurrentDirectoryA, (LPCSTR lpPathName)) {
|
|
UNIMPLEMENTED();
|
|
}
|
|
|
|
DLLEXPORT_FUNC(WINBOOL, SetCurrentDirectoryW, (LPCWSTR lpPathName)) {
|
|
UNIMPLEMENTED();
|
|
}
|
|
|
|
DLLEXPORT_FUNC(DWORD, GetCurrentDirectoryA, (DWORD nBufferLength, LPSTR lpBuffer)) {
|
|
UNIMPLEMENTED();
|
|
}
|
|
|
|
DLLEXPORT_FUNC(DWORD, GetCurrentDirectoryW, (DWORD nBufferLength, LPWSTR lpBuffer)) {
|
|
return RtlGetCurrentDirectory_U(nBufferLength * sizeof(wchar_t), lpBuffer) / sizeof(wchar_t);
|
|
}
|