在网上搜索此类问题,搜索到有用的内容相当少,可能是因为比较少人发表这种文章,也不排除比较少人使用内核模式的办法。今晚通过在网上看到的一点资料,结合自己近期研究的课题,使用NtQueryInformationFile实现了根据文件的Handle获取文件路径,程序在VC2008下测试,源代码如下:
1
#include <windows.h>
2
#include <tchar.h>
3
4
typedef long NTSTATUS;
5
6
#define STATUS_SUCCESS 0L
7
8
typedef struct _IO_STATUS_BLOCK {
9
union {
10
NTSTATUS Status;
11
PVOID Pointer;
12
};
13
14
ULONG_PTR Information;
15
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
16
17
typedef enum _FILE_INFORMATION_CLASS {
18
// end_wdm
19
FileDirectoryInformation = 1,
20
FileFullDirectoryInformation, // 2
21
FileBothDirectoryInformation, // 3
22
FileBasicInformation, // 4 wdm
23
FileStandardInformation, // 5 wdm
24
FileInternalInformation, // 6
25
FileEaInformation, // 7
26
FileAccessInformation, // 8
27
FileNameInformation, // 9
28
FileRenameInformation, // 10
29
FileLinkInformation, // 11
30
FileNamesInformation, // 12
31
FileDispositionInformation, // 13
32
FilePositionInformation, // 14 wdm
33
FileFullEaInformation, // 15
34
FileModeInformation, // 16
35
FileAlignmentInformation, // 17
36
FileAllInformation, // 18
37
FileAllocationInformation, // 19
38
FileEndOfFileInformation, // 20 wdm
39
FileAlternateNameInformation, // 21
40
FileStreamInformation, // 22
41
FilePipeInformation, // 23
42
FilePipeLocalInformation, // 24
43
FilePipeRemoteInformation, // 25
44
FileMailslotQueryInformation, // 26
45
FileMailslotSetInformation, // 27
46
FileCompressionInformation, // 28
47
FileObjectIdInformation, // 29
48
FileCompletionInformation, // 30
49
FileMoveClusterInformation, // 31
50
FileQuotaInformation, // 32
51
FileReparsePointInformation, // 33
52
FileNetworkOpenInformation, // 34
53
FileAttributeTagInformation, // 35
54
FileTrackingInformation, // 36
55
FileIdBothDirectoryInformation, // 37
56
FileIdFullDirectoryInformation, // 38
57
FileValidDataLengthInformation, // 39
58
FileShortNameInformation, // 40
59
FileMaximumInformation
60
// begin_wdm
61
} FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;
62
63
typedef struct _UNICODE_STRING
64
{
65
USHORT Length;
66
USHORT MaximumLength;
67
PWSTR Buffer;
68
} UNICODE_STRING, *PUNICODE_STRING;
69
70
typedef struct _OBJECT_NAME_INFORMATION {
71
UNICODE_STRING Name;
72
} OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION;
73
74
typedef NTSTATUS (WINAPI *NTQUERYINFORMATIONFILE)(
75
IN HANDLE FileHandle,
76
OUT PIO_STATUS_BLOCK IoStatusBlock,
77
OUT PVOID FileInformation,
78
IN DWORD Length,
79
IN FILE_INFORMATION_CLASS FileInformationClass);
80
81
NTQUERYINFORMATIONFILE NtQueryInformationFile = NULL;
82
83
void _tmain(int argc, _TCHAR* argv[])
84
{
85
_tsetlocale(0, _T("chs"));
86
87
HMODULE hNtdll = ::LoadLibrary(_T("ntdll.dll"));
88
NtQueryInformationFile = (NTQUERYINFORMATIONFILE)::GetProcAddress(hNtdll, "NtQueryInformationFile");
89
HANDLE hFile = ::CreateFile(_T("E:\\test\\Debug\\test.txt"), GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, NULL);
90
if (hFile != INVALID_HANDLE_VALUE)
91
{
92
IO_STATUS_BLOCK IoStatus;
93
POBJECT_NAME_INFORMATION pfni;
94
size_t allocSize = sizeof(OBJECT_NAME_INFORMATION) + MAX_PATH * sizeof(WCHAR);
95
96
pfni = (POBJECT_NAME_INFORMATION)malloc(allocSize);
97
memset(pfni, 0, allocSize);
98
status = NtQueryInformationFile(hFile, &IoStatus, pfni, allocSize, FileNameInformation);
99
if (status == STATUS_SUCCESS)
100
_tprintf(_T("文件名: %s\n"), pfni->Name.Buffer);
101
free(pfni);
102
103
CloseHandle(hFile);
104
}
105
}
#include <windows.h>2
#include <tchar.h>3

4
typedef long NTSTATUS;5

6
#define STATUS_SUCCESS 0L7

8
typedef struct _IO_STATUS_BLOCK {9
union {10
NTSTATUS Status;11
PVOID Pointer;12
};13

14
ULONG_PTR Information;15
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;16

17
typedef enum _FILE_INFORMATION_CLASS {18
// end_wdm19
FileDirectoryInformation = 1,20
FileFullDirectoryInformation, // 221
FileBothDirectoryInformation, // 322
FileBasicInformation, // 4 wdm23
FileStandardInformation, // 5 wdm24
FileInternalInformation, // 625
FileEaInformation, // 726
FileAccessInformation, // 827
FileNameInformation, // 928
FileRenameInformation, // 1029
FileLinkInformation, // 1130
FileNamesInformation, // 1231
FileDispositionInformation, // 1332
FilePositionInformation, // 14 wdm33
FileFullEaInformation, // 1534
FileModeInformation, // 1635
FileAlignmentInformation, // 1736
FileAllInformation, // 1837
FileAllocationInformation, // 1938
FileEndOfFileInformation, // 20 wdm39
FileAlternateNameInformation, // 2140
FileStreamInformation, // 2241
FilePipeInformation, // 2342
FilePipeLocalInformation, // 2443
FilePipeRemoteInformation, // 2544
FileMailslotQueryInformation, // 2645
FileMailslotSetInformation, // 2746
FileCompressionInformation, // 2847
FileObjectIdInformation, // 2948
FileCompletionInformation, // 3049
FileMoveClusterInformation, // 3150
FileQuotaInformation, // 3251
FileReparsePointInformation, // 3352
FileNetworkOpenInformation, // 3453
FileAttributeTagInformation, // 3554
FileTrackingInformation, // 3655
FileIdBothDirectoryInformation, // 3756
FileIdFullDirectoryInformation, // 3857
FileValidDataLengthInformation, // 3958
FileShortNameInformation, // 4059
FileMaximumInformation60
// begin_wdm61
} FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;62

63
typedef struct _UNICODE_STRING64
{65
USHORT Length;66
USHORT MaximumLength;67
PWSTR Buffer;68
} UNICODE_STRING, *PUNICODE_STRING;69

70
typedef struct _OBJECT_NAME_INFORMATION {71
UNICODE_STRING Name;72
} OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION;73

74
typedef NTSTATUS (WINAPI *NTQUERYINFORMATIONFILE)(75
IN HANDLE FileHandle,76
OUT PIO_STATUS_BLOCK IoStatusBlock,77
OUT PVOID FileInformation,78
IN DWORD Length,79
IN FILE_INFORMATION_CLASS FileInformationClass);80

81
NTQUERYINFORMATIONFILE NtQueryInformationFile = NULL;82

83
void _tmain(int argc, _TCHAR* argv[])84
{85
_tsetlocale(0, _T("chs"));86

87
HMODULE hNtdll = ::LoadLibrary(_T("ntdll.dll"));88
NtQueryInformationFile = (NTQUERYINFORMATIONFILE)::GetProcAddress(hNtdll, "NtQueryInformationFile");89
HANDLE hFile = ::CreateFile(_T("E:\\test\\Debug\\test.txt"), GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, NULL);90
if (hFile != INVALID_HANDLE_VALUE)91
{92
IO_STATUS_BLOCK IoStatus;93
POBJECT_NAME_INFORMATION pfni;94
size_t allocSize = sizeof(OBJECT_NAME_INFORMATION) + MAX_PATH * sizeof(WCHAR);95

96
pfni = (POBJECT_NAME_INFORMATION)malloc(allocSize);97
memset(pfni, 0, allocSize);98
status = NtQueryInformationFile(hFile, &IoStatus, pfni, allocSize, FileNameInformation);99
if (status == STATUS_SUCCESS)100
_tprintf(_T("文件名: %s\n"), pfni->Name.Buffer);101
free(pfni);102

103
CloseHandle(hFile);104
}105
}虽然没有使用编写驱动程序,但使用的API跟内核模式的一样的,使用ntdll.dll里的API。类型定义全部从DDK 2003 SP1中摘出来的。
对于NtQueryInformationFile获取到的文件路径,是不带盘符的,如“\test\Debug\test.txt”。还有一个内核API可以根据文件的Handle获取文件路径,就是NtQueryObject,使用它获取的路径是内核模式的全路径,如“\Device\HarddiskVolume3\test\Debug\test.txt”。

typedef 
union