本文介绍了如何获得的名称与打开的句柄相关联的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
什么是获得与在Win32中一个开放的句柄相关联的文件名的最简单的方法?
What's the easiest way to get the filename associated with an open HANDLE in Win32?
推荐答案有一个正确的(虽然无证)的方式来做到这一点在Windows XP上的这也与目录 - 同样的方法 GetFinalPathNameByHandle 使用Windows Vista和更高版本。
There is a correct (although undocumented) way to do this on Windows XP which also works with directories -- the same method GetFinalPathNameByHandle uses on Windows Vista and later.
下面是eneded声明。其中的一些已经在 WInternl.h 和 MountMgr.h ,但我只是把他们在这里反正:
Here are the eneded declarations. Some of these are already in WInternl.h and MountMgr.h but I just put them here anyway:
#include "stdafx.h" #include <Windows.h> #include <assert.h> enum OBJECT_INFORMATION_CLASS { ObjectNameInformation = 1 }; enum FILE_INFORMATION_CLASS { FileNameInformation = 9 }; struct FILE_NAME_INFORMATION { ULONG FileNameLength; WCHAR FileName[1]; }; struct IO_STATUS_BLOCK { PVOID Dummy; ULONG_PTR Information; }; struct UNICODE_STRING { USHORT Length; USHORT MaximumLength; PWSTR Buffer; }; struct MOUNTMGR_TARGET_NAME { USHORT DeviceNameLength; WCHAR DeviceName[1]; }; struct MOUNTMGR_VOLUME_PATHS { ULONG MultiSzLength; WCHAR MultiSz[1]; }; extern "C" NTSYSAPI NTSTATUS NTAPI NtQueryObject(IN HANDLE Handle OPTIONAL, IN OBJECT_INFORMATION_CLASS ObjectInformationClass, OUT PVOID ObjectInformation OPTIONAL, IN ULONG ObjectInformationLength, OUT PULONG ReturnLength OPTIONAL); extern "C" NTSYSAPI NTSTATUS NTAPI NtQueryInformationFile(IN HANDLE FileHandle, OUT PIO_STATUS_BLOCK IoStatusBlock, OUT PVOID FileInformation, IN ULONG Length, IN FILE_INFORMATION_CLASS FileInformationClass); #define MOUNTMGRCONTROLTYPE ((ULONG) 'm') #define IOCTL_MOUNTMGR_QUERY_DOS_VOLUME_PATH \ CTL_CODE(MOUNTMGRCONTROLTYPE, 12, METHOD_BUFFERED, FILE_ANY_ACCESS) union ANY_BUFFER { MOUNTMGR_TARGET_NAME TargetName; MOUNTMGR_VOLUME_PATHS TargetPaths; FILE_NAME_INFORMATION NameInfo; UNICODE_STRING UnicodeString; WCHAR Buffer[USHRT_MAX]; };这里的核心功能:
Here's the core function:
LPWSTR GetFilePath(HANDLE hFile) { static ANY_BUFFER nameFull, nameRel, nameMnt; ULONG returnedLength; IO_STATUS_BLOCK iosb; NTSTATUS status; status = NtQueryObject(hFile, ObjectNameInformation, nameFull.Buffer, sizeof(nameFull.Buffer), &returnedLength); assert(status == 0); status = NtQueryInformationFile(hFile, &iosb, nameRel.Buffer, sizeof(nameRel.Buffer), FileNameInformation); assert(status == 0); //I'm not sure how this works with network paths... assert(nameFull.UnicodeString.Length >= nameRel.NameInfo.FileNameLength); nameMnt.TargetName.DeviceNameLength = (USHORT)( nameFull.UnicodeString.Length - nameRel.NameInfo.FileNameLength); wcsncpy(nameMnt.TargetName.DeviceName, nameFull.UnicodeString.Buffer, nameMnt.TargetName.DeviceNameLength / sizeof(WCHAR)); HANDLE hMountPointMgr = CreateFile(_T("\\\\.\\MountPointManager"), 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, NULL); __try { DWORD bytesReturned; BOOL success = DeviceIoControl(hMountPointMgr, IOCTL_MOUNTMGR_QUERY_DOS_VOLUME_PATH, &nameMnt, sizeof(nameMnt), &nameMnt, sizeof(nameMnt), &bytesReturned, NULL); assert(success && nameMnt.TargetPaths.MultiSzLength > 0); wcsncat(nameMnt.TargetPaths.MultiSz, nameRel.NameInfo.FileName, nameRel.NameInfo.FileNameLength / sizeof(WCHAR)); return nameMnt.TargetPaths.MultiSz; } __finally { CloseHandle(hMountPointMgr); } }和这里的用法的例子:
int _tmain(int argc, _TCHAR* argv[]) { HANDLE hFile = CreateFile(_T("\\\\.\\C:\\Windows\\Notepad.exe"), 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); assert(hFile != NULL && hFile != INVALID_HANDLE_VALUE); __try { wprintf(L"%s\n", GetFilePath(hFile)); // Prints: // C:\Windows\notepad.exe } __finally { CloseHandle(hFile); } return 0; }更多推荐
如何获得的名称与打开的句柄相关联
发布评论