3
0
mirror of https://github.com/XboxDev/nxdk.git synced 2025-12-01 12:03:59 +00:00

winapi: Implement Set/GetFileInformationByHandle

This commit is contained in:
Ryzee119
2025-09-09 09:32:12 +09:30
committed by Stefan Schmidt
parent 56f54e4faf
commit d0ae96acc9
4 changed files with 162 additions and 0 deletions

View File

@ -53,6 +53,23 @@ BOOL GetDiskFreeSpaceA (LPCSTR lpRootPathName, LPDWORD lpSectorsPerCluster, LPDW
DWORD GetLogicalDrives (VOID);
DWORD GetLogicalDriveStringsA (DWORD nBufferLength, LPSTR lpBuffer);
typedef struct _BY_HANDLE_FILE_INFORMATION
{
DWORD dwFileAttributes;
FILETIME ftCreationTime;
FILETIME ftLastAccessTime;
FILETIME ftLastWriteTime;
DWORD dwVolumeSerialNumber;
DWORD nFileSizeHigh;
DWORD nFileSizeLow;
DWORD nNumberOfLinks;
DWORD nFileIndexHigh;
DWORD nFileIndexLow;
} BY_HANDLE_FILE_INFORMATION, *PBY_HANDLE_FILE_INFORMATION, *LPBY_HANDLE_FILE_INFORMATION;
BOOL SetFileInformationByHandle (HANDLE hFile, FILE_INFO_BY_HANDLE_CLASS FileInformationClass, LPVOID lpFileInformation, DWORD dwBufferSize);
BOOL GetFileInformationByHandle (HANDLE hFile, LPBY_HANDLE_FILE_INFORMATION lpFileInformation);
#ifndef UNICODE
#define GetFileAttributes GetFileAttributesA
#define GetFileAttributesEx GetFileAttributesExA

View File

@ -651,3 +651,94 @@ DWORD GetLogicalDriveStringsA (DWORD nBufferLength, LPSTR lpBuffer)
*lpBuffer = '\0';
return requiredBufLength;
}
BOOL SetFileInformationByHandle (HANDLE hFile, FILE_INFO_BY_HANDLE_CLASS FileInformationClass, LPVOID lpFileInformation, DWORD dwBufferSize)
{
FILE_INFORMATION_CLASS infoClass;
// Convert Windows API file information class to the corresponding kernel file information class.
switch (FileInformationClass) {
case FileBasicInfo:
infoClass = FileBasicInformation;
break;
case FileDispositionInfo:
infoClass = FileDispositionInformation;
break;
case FileAllocationInfo:
infoClass = FileAllocationInformation;
break;
case FileEndOfFileInfo:
infoClass = FileEndOfFileInformation;
break;
case FileIoPriorityHintInfo:
case FileRenameInfo:
// These should be supported by SetFileInformationByHandle however they are not implemented here for the following reasons:
// FileIoPriorityHintInfo: No corresponding kernel file information class
// FileRenameInfo: FILE_RENAME_INFO expects WCHAR file names which we do not support
assert(0 && "Specified File Information Class not implemented");
// fall through
default:
infoClass = -1;
}
if (infoClass == -1) {
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
IO_STATUS_BLOCK ioStatusBlock;
NTSTATUS status = NtSetInformationFile(hFile, &ioStatusBlock, lpFileInformation, dwBufferSize, infoClass);
if (!NT_SUCCESS(status)) {
SetLastError(RtlNtStatusToDosError(status));
return FALSE;
}
return TRUE;
}
BOOL GetFileInformationByHandle (HANDLE hFile, LPBY_HANDLE_FILE_INFORMATION lpFileInformation)
{
NTSTATUS status;
IO_STATUS_BLOCK ioStatusBlock;
FILE_NETWORK_OPEN_INFORMATION network;
FILE_FS_VOLUME_INFORMATION volume;
FILE_INTERNAL_INFORMATION internal;
assert(lpFileInformation != NULL);
status = NtQueryInformationFile(hFile, &ioStatusBlock, &network, sizeof(network), FileNetworkOpenInformation);
if (!NT_SUCCESS(status)) {
SetLastError(RtlNtStatusToDosError(status));
return FALSE;
}
status = NtQueryVolumeInformationFile(hFile, &ioStatusBlock, &volume, sizeof(volume), FileFsVolumeInformation);
if (!NT_SUCCESS(status)) {
SetLastError(RtlNtStatusToDosError(status));
return FALSE;
}
status = NtQueryInformationFile(hFile, &ioStatusBlock, &internal, sizeof(internal), FileInternalInformation);
if (!NT_SUCCESS(status)) {
SetLastError(RtlNtStatusToDosError(status));
return FALSE;
}
lpFileInformation->dwFileAttributes = network.FileAttributes;
lpFileInformation->ftCreationTime.dwHighDateTime = network.CreationTime.HighPart;
lpFileInformation->ftCreationTime.dwLowDateTime = network.CreationTime.LowPart;
lpFileInformation->ftLastAccessTime.dwHighDateTime = network.LastAccessTime.HighPart;
lpFileInformation->ftLastAccessTime.dwLowDateTime = network.LastAccessTime.LowPart;
lpFileInformation->ftLastWriteTime.dwHighDateTime = network.LastWriteTime.HighPart;
lpFileInformation->ftLastWriteTime.dwLowDateTime = network.LastWriteTime.LowPart;
lpFileInformation->dwVolumeSerialNumber = volume.VolumeSerialNumber;
lpFileInformation->nFileSizeHigh = network.EndOfFile.HighPart;
lpFileInformation->nFileSizeLow = network.EndOfFile.LowPart;
lpFileInformation->nFileIndexHigh = internal.IndexNumber.HighPart;
lpFileInformation->nFileIndexLow = internal.IndexNumber.LowPart;
// For the FAT file system this member is always 1
lpFileInformation->nNumberOfLinks = 1;
return TRUE;
}

View File

@ -60,4 +60,34 @@ typedef struct _SYSTEMTIME
#define EXCEPTION_GUARD_PAGE STATUS_GUARD_PAGE_VIOLATION
#define EXCEPTION_INVALID_HANDLE STATUS_INVALID_HANDLE
typedef enum _FILE_INFO_BY_HANDLE_CLASS
{
FileBasicInfo,
FileStandardInfo,
FileNameInfo,
FileRenameInfo,
FileDispositionInfo,
FileAllocationInfo,
FileEndOfFileInfo,
FileStreamInfo,
FileCompressionInfo,
FileAttributeTagInfo,
FileIdBothDirectoryInfo,
FileIdBothDirectoryRestartInfo,
FileIoPriorityHintInfo,
FileRemoteProtocolInfo,
FileFullDirectoryInfo,
FileFullDirectoryRestartInfo,
FileStorageInfo,
FileAlignmentInfo,
FileIdInfo,
FileIdExtdDirectoryInfo,
FileIdExtdDirectoryRestartInfo,
FileDispositionInfoEx,
FileRenameInfoEx,
FileCaseSensitiveInfo,
FileNormalizedNameInfo,
MaximumFileInfoByHandleClass
} FILE_INFO_BY_HANDLE_CLASS, *PFILE_INFO_BY_HANDLE_CLASS;
#endif

View File

@ -123,6 +123,30 @@ typedef struct _WIN32_FIND_DATAA
CHAR cAlternateFileName[14];
} WIN32_FIND_DATAA, *PWIN32_FIND_DATAA, *LPWIN32_FIND_DATAA;
typedef struct _FILE_BASIC_INFO
{
LARGE_INTEGER CreationTime;
LARGE_INTEGER LastAccessTime;
LARGE_INTEGER LastWriteTime;
LARGE_INTEGER ChangeTime;
DWORD FileAttributes;
} FILE_BASIC_INFO, *PFILE_BASIC_INFO;
typedef struct _FILE_DISPOSITION_INFO
{
BOOLEAN DeleteFile;
} FILE_DISPOSITION_INFO, *PFILE_DISPOSITION_INFO;
typedef struct _FILE_ALLOCATION_INFO
{
LARGE_INTEGER AllocationSize;
} FILE_ALLOCATION_INFO, *PFILE_ALLOCATION_INFO;
typedef struct _FILE_END_OF_FILE_INFO
{
LARGE_INTEGER EndOfFile;
} FILE_END_OF_FILE_INFO, *PFILE_END_OF_FILE_INFO;
#ifndef UNICODE
#define WIN32_FIND_DATA WIN32_FIND_DATAA
#define PWIN32_FIND_DATA PWIN32_FIND_DATAA