如何获得的名称与打开的句柄相关联 [英] How to get name associated with open HANDLE

查看:155
本文介绍了如何获得的名称与打开的句柄相关联的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

什么是获得与在Win32中一个开放的句柄相关联的文件名的最简单的方法?

What's the easiest way to get the filename associated with an open HANDLE in Win32?

推荐答案

有一个正确的(虽然无证)的方式来做到这一点在Windows XP上的这也与目录 - 同样的方法< A HREF =htt​​p://msdn.microsoft.com/en-us/library/aa364962.aspx> 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;
}

这篇关于如何获得的名称与打开的句柄相关联的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆