通过文件句柄取得到文件名(三)

从文件句柄获得文件名方法(三), 这次是用wdk函数ZwQueryInformationFile(),和GetVolumeInformation()。

通过判断取得的dwVolumeSerialNumber来确定盘符。

其他的内核函数比如说ObDereferenceObject()也可以。

参考了Adly's blog 的 通过文件句柄得到文件所在路径的一种新方法 —— 得到完整路径名

 

LPWSTR GetFileNameFromHandleW3(HANDLE hFile, LPWSTR lpFilePath) { const int FileNameInformation = 9; // enum FILE_INFORMATION_CLASS; Defined in winddk.h typedef struct _IO_STATUS_BLOCK { union { ULONG Status; // NTSTATUS PVOID Pointer; }; ULONG_PTR Information; } IO_STATUS_BLOCK, *PIO_STATUS_BLOCK; // Defined in Wdm.h typedef struct _FILE_NAME_INFORMATION { ULONG FileNameLength; WCHAR FileName[MAX_PATH]; } FILE_NAME_INFORMATION, *PFILE_NAME_INFORMATION; typedef LONG (CALLBACK* ZWQUERYINFORMATIONFILE)( HANDLE FileHandle, IO_STATUS_BLOCK *IoStatusBlock, PVOID FileInformation, ULONG Length, ULONG FileInformationClass ); lpFilePath[0] = 0x00; HMODULE hNtDLL = LoadLibraryW(L"ntdll.dll"); if (hNtDLL == 0x00) { return 0x00; } ZWQUERYINFORMATIONFILE ZwQueryInformationFile = (ZWQUERYINFORMATIONFILE)GetProcAddress(hNtDLL, "ZwQueryInformationFile"); if (ZwQueryInformationFile == 0x00) { return 0x00; } FILE_NAME_INFORMATION fni; IO_STATUS_BLOCK isb; if (ZwQueryInformationFile(hFile, &isb, &fni, sizeof(fni), FileNameInformation) != 0) { return 0x00; } fni.FileName[fni.FileNameLength / sizeof(WCHAR)] = 0x00; BY_HANDLE_FILE_INFORMATION fi; if(!GetFileInformationByHandle(hFile, &fi) || (fi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { return 0x00; } WCHAR szDrive [MAX_PATH]; WCHAR *lpDrive = szDrive; int iPathLen; if (GetLogicalDriveStringsW(MAX_PATH - 1, szDrive) >= MAX_PATH) { return 0x00; } while ((iPathLen = lstrlenW(lpDrive)) != 0) { DWORD dwVolumeSerialNumber; if(!GetVolumeInformation(lpDrive, NULL, NULL, &dwVolumeSerialNumber,NULL, NULL, NULL, NULL)) { return 0x00; } if (dwVolumeSerialNumber == fi.dwVolumeSerialNumber) { lstrcpynW(lpFilePath, lpDrive, lstrlen(lpDrive)); lstrcatW(lpFilePath, fni.FileName); break; } lpDrive += iPathLen + 1; } return lpFilePath; }

你可能感兴趣的:(struct,IO,File,null,Path,callback)