reupload this
This commit is contained in:
395
file.c
Normal file
395
file.c
Normal file
@@ -0,0 +1,395 @@
|
||||
#include "progwrp.h"
|
||||
#include "export.h"
|
||||
#include "implementations.h"
|
||||
#include <strsafe.h>
|
||||
|
||||
typedef enum {
|
||||
FileDirectoryInfo = 1,
|
||||
FileFullDirectoryInformation, // 2
|
||||
FileBothDirectoryInformation, // 3
|
||||
FileBasicInformation, // 4
|
||||
FileStandardInformation, // 5
|
||||
FileInternalInformation, // 6
|
||||
FileEaInformation, // 7
|
||||
FileAccessInformation, // 8
|
||||
FileNameInformation, // 9
|
||||
FileRenameInformation, // 10
|
||||
FileLinkInformation, // 11
|
||||
FileNamesInformation, // 12
|
||||
FileDispositionInformation, // 13
|
||||
FilePositionInformation, // 14
|
||||
FileFullEaInformation, // 15
|
||||
FileModeInformation, // 16
|
||||
FileAlignmentInformation, // 17
|
||||
FileAllInformation, // 18
|
||||
FileAllocationInformation, // 19
|
||||
FileEndOfFileInformation, // 20
|
||||
FileAlternateNameInformation, // 21
|
||||
FileStreamInformation, // 22
|
||||
FilePipeInformation, // 23
|
||||
FilePipeLocalInformation, // 24
|
||||
FilePipeRemoteInformation, // 25
|
||||
FileMailslotQueryInformation, // 26
|
||||
FileMailslotSetInformation, // 27
|
||||
FileCompressionInformation, // 28
|
||||
FileObjectIdInformation, // 29
|
||||
FileCompletionInformation, // 30
|
||||
FileMoveClusterInformation, // 31
|
||||
FileQuotaInformation, // 32
|
||||
FileReparsePointInformation, // 33
|
||||
FileNetworkOpenInformation, // 34
|
||||
FileAttributeTagInformation, // 35
|
||||
FileTrackingInformation, // 36
|
||||
FileIdBothDirectoryInformation, // 37
|
||||
FileIdFullDirectoryInformation, // 38
|
||||
FileValidDataLengthInformation, // 39
|
||||
FileShortNameInformation, // 40
|
||||
FileIoCompletionNotificationInformation, // 41
|
||||
FileIoStatusBlockRangeInformation, // 42
|
||||
FileIoPriorityHintInformation, // 43
|
||||
FileSfioReserveInformation, // 44
|
||||
FileSfioVolumeInformation, // 45
|
||||
FileHardLinkInformation, // 46
|
||||
FileProcessIdsUsingFileInformation, // 47
|
||||
FileNormalizedNameInformation, // 48
|
||||
FileNetworkPhysicalNameInformation, // 49
|
||||
FileIdGlobalTxDirectoryInformation, // 50
|
||||
FileIsRemoteDeviceInformation, // 51
|
||||
FileUnusedInformation, // 52
|
||||
FileNumaNodeInformation, // 53
|
||||
FileStandardLinkInformation, // 54
|
||||
FileRemoteProtocolInformation, // 55
|
||||
|
||||
//
|
||||
// These are special versions of these operations (defined earlier)
|
||||
// which can be used by kernel mode drivers only to bypass security
|
||||
// access checks for Rename and HardLink operations. These operations
|
||||
// are only recognized by the IOManager, a file system should never
|
||||
// receive these.
|
||||
//
|
||||
|
||||
FileRenameInformationBypassAccessCheck, // 56
|
||||
FileLinkInformationBypassAccessCheck, // 57
|
||||
|
||||
//
|
||||
// End of special information classes reserved for IOManager.
|
||||
//
|
||||
|
||||
FileVolumeNameInformation, // 58
|
||||
FileIdInformation, // 59
|
||||
FileIdExtdDirectoryInformation, // 60
|
||||
FileReplaceCompletionInformation, // 61
|
||||
FileHardLinkFullIdInformation, // 62
|
||||
FileIdExtdBothDirectoryInformation, // 63
|
||||
FileDispositionInformationEx, // 64
|
||||
FileRenameInformationEx, // 65
|
||||
FileRenameInformationExBypassAccessCheck, // 66
|
||||
FileDesiredStorageClassInformation, // 67
|
||||
FileStatInformation, // 68
|
||||
FileMemoryPartitionInformation, // 69
|
||||
FileStatLxInformation, // 70
|
||||
FileCaseSensitiveInformation, // 71
|
||||
FileLinkInformationEx, // 72
|
||||
FileLinkInformationExBypassAccessCheck, // 73
|
||||
FileStorageReserveIdInformation, // 74
|
||||
FileCaseSensitiveInformationForceAccessCheck, // 75
|
||||
FileKnownFolderInformation, // 76
|
||||
|
||||
FileMaximumInformation
|
||||
} FILEINFOCLASS, *PFILEINFOCLASS;
|
||||
|
||||
#define ObjectNameInformation 1
|
||||
|
||||
typedef struct _OBJECT_NAME_INFORMATION {
|
||||
UNICODE_STRING Name;
|
||||
WCHAR NameBuffer[1];
|
||||
} OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION;
|
||||
|
||||
typedef struct _FILE_NAME_INFORMATION {
|
||||
ULONG FileNameLength;
|
||||
WCHAR FileName[1];
|
||||
} FILE_NAME_INFORMATION, *PFILE_NAME_INFORMATION;
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NtQueryInformationFile (
|
||||
_In_ HANDLE FileHandle,
|
||||
_Out_ PIO_STATUS_BLOCK IoStatusBlock,
|
||||
_Out_writes_bytes_(Length) PVOID FileInformation,
|
||||
_In_ ULONG Length,
|
||||
_In_ FILEINFOCLASS FileInformationClass
|
||||
);
|
||||
|
||||
typedef enum _FSINFOCLASS {
|
||||
FileFsVolumeInformation,
|
||||
FileFsLabelInformation,
|
||||
FileFsSizeInformation,
|
||||
FileFsDeviceInformation,
|
||||
FileFsAttributeInformation,
|
||||
FileFsControlInformation,
|
||||
FileFsFullSizeInformation,
|
||||
FileFsObjectIdInformation,
|
||||
FileFsDriverPathInformation,
|
||||
FileFsVolumeFlagsInformation,
|
||||
FileFsSectorSizeInformation,
|
||||
FileFsDataCopyInformation,
|
||||
FileFsMetadataSizeInformation,
|
||||
FileFsFullSizeInformationEx,
|
||||
FileFsGuidInformation,
|
||||
FileFsMaximumInformation
|
||||
} FS_INFORMATION_CLASS, *PFS_INFORMATION_CLASS;
|
||||
|
||||
NTSTATUS NTAPI NtQueryVolumeInformationFile(
|
||||
_In_ HANDLE FileHandle,
|
||||
_Out_ PIO_STATUS_BLOCK IoStatusBlock,
|
||||
_Out_ PVOID FsInformation,
|
||||
_In_ ULONG Length,
|
||||
_In_ FS_INFORMATION_CLASS FsInformationClass
|
||||
);
|
||||
|
||||
HANDLE WINAPI Implementation_FindFirstFileExW(LPCWSTR lpFileName, FINDEX_INFO_LEVELS fInfoLevelId, LPVOID lpFindFileData,
|
||||
FINDEX_SEARCH_OPS fSearchOp, LPVOID lpSearchFilter, DWORD dwAdditionalFlags)
|
||||
{
|
||||
|
||||
if(dwAdditionalFlags & FIND_FIRST_EX_LARGE_FETCH)
|
||||
dwAdditionalFlags &= ~FIND_FIRST_EX_LARGE_FETCH;
|
||||
|
||||
typedef HANDLE (WINAPI* pfnFindFirstFileExW)(LPCWSTR, FINDEX_INFO_LEVELS, LPVOID, FINDEX_SEARCH_OPS, LPVOID, DWORD);
|
||||
pfnFindFirstFileExW pFFFEXW = (pfnFindFirstFileExW)Implementation_GetProcAddress(GetModuleHandleA("kernel32.dll"), "FindFirstFileExW");
|
||||
return pFFFEXW(lpFileName, FindExInfoStandard, lpFindFileData, fSearchOp, lpSearchFilter, dwAdditionalFlags);
|
||||
}
|
||||
|
||||
BOOL WINAPI Implementation_GetFileInformationByHandleEx(
|
||||
HANDLE hFile,
|
||||
FILE_INFO_BY_HANDLE_CLASS FileInformationClass,
|
||||
LPVOID lpFileInformation,
|
||||
DWORD dwBufferSize
|
||||
)
|
||||
/*
|
||||
Seems like a wrapper around NtQueryInformationFile, but with the
|
||||
file information classes shifted around a little bit.
|
||||
A switch statement will take care of that.
|
||||
*/
|
||||
{
|
||||
IO_STATUS_BLOCK isb;
|
||||
NTSTATUS Status;
|
||||
|
||||
switch(FileInformationClass)
|
||||
{
|
||||
case FileBasicInfo:
|
||||
Status = NtQueryInformationFile(hFile, &isb, lpFileInformation, dwBufferSize, FileBasicInformation);
|
||||
break;
|
||||
case FileStandardInfo:
|
||||
Status = NtQueryInformationFile(hFile, &isb, lpFileInformation, dwBufferSize, FileStandardInformation);
|
||||
break;
|
||||
case FileNameInfo:
|
||||
Status = NtQueryInformationFile(hFile, &isb, lpFileInformation, dwBufferSize, FileNameInformation);
|
||||
break;
|
||||
case FileRenameInfo:
|
||||
Status = NtQueryInformationFile(hFile, &isb, lpFileInformation, dwBufferSize, FileRenameInformation);
|
||||
break;
|
||||
case FileDispositionInfo:
|
||||
Status = NtQueryInformationFile(hFile, &isb, lpFileInformation, dwBufferSize, FileDispositionInformation);
|
||||
break;
|
||||
case FileAllocationInfo:
|
||||
Status = NtQueryInformationFile(hFile, &isb, lpFileInformation, dwBufferSize, FileAllocationInformation);
|
||||
break;
|
||||
case FileEndOfFileInfo:
|
||||
Status = NtQueryInformationFile(hFile, &isb, lpFileInformation, dwBufferSize, FileEndOfFileInformation);
|
||||
break;
|
||||
case FileStreamInfo:
|
||||
Status = NtQueryInformationFile(hFile, &isb, lpFileInformation, dwBufferSize, FileStreamInformation);
|
||||
break;
|
||||
case FileCompressionInfo:
|
||||
Status = NtQueryInformationFile(hFile, &isb, lpFileInformation, dwBufferSize, FileCompressionInformation);
|
||||
break;
|
||||
case FileAttributeTagInfo:
|
||||
Status = NtQueryInformationFile(hFile, &isb, lpFileInformation, dwBufferSize, FileAttributeTagInformation);
|
||||
break;
|
||||
case FileIdBothDirectoryInfo:
|
||||
Status = NtQueryInformationFile(hFile, &isb, lpFileInformation, dwBufferSize, FileIdBothDirectoryInformation);
|
||||
break;
|
||||
case FileIdBothDirectoryRestartInfo:
|
||||
Status = NtQueryInformationFile(hFile, &isb, lpFileInformation, dwBufferSize, FileIdFullDirectoryInformation); // ??
|
||||
break;
|
||||
case FileIoPriorityHintInfo:
|
||||
Status = NtQueryInformationFile(hFile, &isb, lpFileInformation, dwBufferSize, FileIoPriorityHintInformation);
|
||||
break;
|
||||
case FileRemoteProtocolInfo:
|
||||
Status = NtQueryInformationFile(hFile, &isb, lpFileInformation, dwBufferSize, FileRemoteProtocolInformation);
|
||||
break;
|
||||
default: // All other classes are not known to work on XP or below
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if(Status == 0x0)
|
||||
return TRUE;
|
||||
else
|
||||
{
|
||||
BaseSetLastNTError(Status);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
BOOL WINAPI Implementation_CancelIoEx(HANDLE hFile, LPOVERLAPPED lpOverlapped)
|
||||
{
|
||||
return CancelIo(hFile);
|
||||
}
|
||||
|
||||
DWORD WINAPI Implementation_GetFinalPathNameByHandleW(
|
||||
HANDLE hFile,
|
||||
LPWSTR lpszFilePath,
|
||||
DWORD cchFilePath,
|
||||
DWORD dwFlags
|
||||
)
|
||||
/*
|
||||
NtQueryInformationFile returns the path without the volume name.
|
||||
NtQueryObject returns the path with the NT volume name.
|
||||
The DOS volume name can be retrieved using QueryDosDeviceW to compare with the NtQueryObject value.
|
||||
*/
|
||||
{
|
||||
IO_STATUS_BLOCK isb;
|
||||
PFILE_NAME_INFORMATION fni;
|
||||
NTSTATUS Status;
|
||||
ULONG BufferSize, NtNameLen, VolumeNameLen, NoVolNameLen;
|
||||
WCHAR DosDriveLetter [3] = L"A:";
|
||||
WCHAR Path [MAX_PATH];
|
||||
PWSTR VolumeName;
|
||||
HANDLE hMap;
|
||||
PVOID Mem;
|
||||
|
||||
if(dwFlags & ~(VOLUME_NAME_NONE | VOLUME_NAME_NT | FILE_NAME_OPENED)) // todo: add VOLUME_NAME_GUID support
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
BufferSize = sizeof(FILE_NAME_INFORMATION);
|
||||
fni = (PFILE_NAME_INFORMATION)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, BufferSize);
|
||||
while(1)
|
||||
{
|
||||
Status = NtQueryInformationFile(hFile, &isb, (PVOID)fni, BufferSize, FileNameInformation);
|
||||
if(Status == 0)
|
||||
break;
|
||||
else if(Status == 0x80000005)
|
||||
BufferSize += 8;
|
||||
else
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, fni);
|
||||
BaseSetLastNTError(Status);
|
||||
return 0;
|
||||
}
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, fni);
|
||||
fni = (PFILE_NAME_INFORMATION)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, BufferSize);
|
||||
}
|
||||
|
||||
NoVolNameLen = fni->FileNameLength;
|
||||
|
||||
if(dwFlags & VOLUME_NAME_NONE)
|
||||
{
|
||||
if(cchFilePath >= fni->FileNameLength)
|
||||
StringCchCopyW(lpszFilePath, cchFilePath, fni->FileName);
|
||||
HeapFree(GetProcessHeap(), 0, fni);
|
||||
return NoVolNameLen;
|
||||
}
|
||||
|
||||
hMap = CreateFileMappingW(hFile, NULL, PAGE_READONLY, 0, 1, NULL);
|
||||
|
||||
if(hMap)
|
||||
{
|
||||
Mem = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 1);
|
||||
|
||||
if(Mem)
|
||||
{
|
||||
NtNameLen = GetMappedFileNameW(GetCurrentProcess(), Mem, Path, MAX_PATH);
|
||||
}
|
||||
else
|
||||
{
|
||||
CloseHandle(hMap);
|
||||
return 0;
|
||||
}
|
||||
CloseHandle(hMap);
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
BufferSize = sizeof(OBJECT_NAME_INFORMATION);
|
||||
oni = (POBJECT_NAME_INFORMATION)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, BufferSize);
|
||||
while(1)
|
||||
{
|
||||
Status = NtQueryObject(hFile, ObjectNameInformation, oni, BufferSize, NULL);
|
||||
if(Status == 0)
|
||||
break;
|
||||
else if(Status == 0x80000005)
|
||||
BufferSize += 8;
|
||||
else
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, oni);
|
||||
BaseSetLastNTError(Status);
|
||||
return 0;
|
||||
}
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, oni);
|
||||
oni = (POBJECT_NAME_INFORMATION)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, BufferSize);
|
||||
}
|
||||
*/
|
||||
if(dwFlags & VOLUME_NAME_NT)
|
||||
{
|
||||
if(cchFilePath >= NtNameLen)
|
||||
StringCchCopyW(lpszFilePath, cchFilePath, Path);
|
||||
return NtNameLen;
|
||||
}
|
||||
|
||||
VolumeName = (PWSTR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, BufferSize);
|
||||
|
||||
while(DosDriveLetter[0] <= L"Z")
|
||||
{
|
||||
VolumeNameLen = QueryDosDeviceW(DosDriveLetter, VolumeName, BufferSize / sizeof(WCHAR));
|
||||
|
||||
if(LimitedStrCmp(0, VolumeNameLen, Path, VolumeName))
|
||||
break;
|
||||
|
||||
if(DosDriveLetter[0] == L"Z")
|
||||
{
|
||||
SetLastError(ERROR_PATH_NOT_FOUND);
|
||||
return 0;
|
||||
}
|
||||
|
||||
++DosDriveLetter[0];
|
||||
}
|
||||
|
||||
StringCchCopyW(lpszFilePath, cchFilePath, L"\?\\");
|
||||
StringCchCatW(lpszFilePath, cchFilePath, DosDriveLetter);
|
||||
StringCchCatW(lpszFilePath, cchFilePath, L"\\");
|
||||
StringCchCatW(lpszFilePath, cchFilePath, fni->FileName);
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, VolumeName);
|
||||
HeapFree(GetProcessHeap(), 0, fni);
|
||||
|
||||
return NoVolNameLen + 8;
|
||||
}
|
||||
|
||||
|
||||
BOOL WINAPI Implementation_SetFileInformationByHandle(
|
||||
HANDLE hFile,
|
||||
FILE_INFO_BY_HANDLE_CLASS FileInformationClass,
|
||||
LPVOID lpFileInformation,
|
||||
DWORD dwBufferSize
|
||||
)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL Implementation_GetVolumePathNamesForVolumeNameW(
|
||||
LPCWSTR lpszVolumeName,
|
||||
LPWCH lpszVolumePathNames,
|
||||
DWORD cchBufferLength,
|
||||
PDWORD lpcchReturnLength
|
||||
)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
Reference in New Issue
Block a user