在网上搜索此类问题,搜索到有用的内容相当少,可能是因为比较少人发表这种文章,也不排除比较少人使用内核模式的办法。今晚通过在网上看到的一点资料,结合自己近期研究的课题,使用NtQueryInformationFile实现了根据文件的Handle获取文件路径,程序在VC2008下调试通过,源代码如下:
#include
"
stdafx.h
"
#include
<
windows.h
>
#include
<
tchar.h
>
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
typedef
long
NTSTATUS;
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
#define
NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
//
Define the base asynchronous I/O argument types
typedef
struct
_IO_STATUS_BLOCK
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
union
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
NTSTATUS Status;
PVOID Pointer;
};
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
ULONG_PTR Information;
}
IO_STATUS_BLOCK,
*
PIO_STATUS_BLOCK;
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
typedef
enum
_FILE_INFORMATION_CLASS
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
// end_wdm
FileDirectoryInformation = 1,
FileFullDirectoryInformation, // 2
FileBothDirectoryInformation, // 3
FileBasicInformation, // 4 wdm
FileStandardInformation, // 5 wdm
FileInternalInformation, // 6
FileEaInformation, // 7
FileAccessInformation, // 8
FileNameInformation, // 9
FileRenameInformation, // 10
FileLinkInformation, // 11
FileNamesInformation, // 12
FileDispositionInformation, // 13
FilePositionInformation, // 14 wdm
FileFullEaInformation, // 15
FileModeInformation, // 16
FileAlignmentInformation, // 17
FileAllInformation, // 18
FileAllocationInformation, // 19
FileEndOfFileInformation, // 20 wdm
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
FileMaximumInformation
// begin_wdm
}
FILE_INFORMATION_CLASS,
*
PFILE_INFORMATION_CLASS;
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
typedef
struct
_UNICODE_STRING
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
USHORT Length;
USHORT MaximumLength;
#ifdef MIDL_PASS
[size_is(MaximumLength / 2), length_is((Length) / 2) ] USHORT * Buffer;
#else // MIDL_PASS
PWSTR Buffer;
#endif // MIDL_PASS
}
UNICODE_STRING,
*
PUNICODE_STRING;
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
typedef
struct
_OBJECT_NAME_INFORMATION
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
UNICODE_STRING Name;
}
OBJECT_NAME_INFORMATION,
*
POBJECT_NAME_INFORMATION;
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
typedef NTSTATUS (NTAPI
*
NTQUERYINFORMATIONFILE)(
IN HANDLE FileHandle,
OUT PIO_STATUS_BLOCK IoStatusBlock,
OUT PVOID FileInformation,
IN DWORD Length,
IN FILE_INFORMATION_CLASS FileInformationClass
);
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
NTQUERYINFORMATIONFILE NtQueryInformationFile
=
NULL;
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
void
_tmain(
int
argc, _TCHAR
*
argv[])
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
_tsetlocale(0, _T("chs"));
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
NTSTATUS status = -1;
HMODULE hNtdll = NULL;
HANDLE hFile = INVALID_HANDLE_VALUE;
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
IO_STATUS_BLOCK IoStatus =
{0};
POBJECT_NAME_INFORMATION pfni = NULL;
size_t allocSize = 0;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
hNtdll = LoadLibrary(_T("ntdll.dll"));
NtQueryInformationFile = (NTQUERYINFORMATIONFILE)GetProcAddress(hNtdll, "NtQueryInformationFile");
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
hFile = CreateFile(_T("E:\\test\\Debug\\test.txt"), GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, NULL);
if (hFile != INVALID_HANDLE_VALUE)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
allocSize = sizeof(OBJECT_NAME_INFORMATION) + MAX_PATH * sizeof(WCHAR);
pfni = (POBJECT_NAME_INFORMATION)malloc(allocSize);
if (pfni != NULL)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
RtlZeroMemory(pfni, allocSize);
status = NtQueryInformationFile(hFile, &IoStatus, pfni, allocSize, FileNameInformation);
if (NT_SUCCESS(status))
wprintf(L"文件名: %s\n", pfni->Name.Buffer);
free(pfni);
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
CloseHandle(hFile);
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
FreeLibrary(hNtdll);
}
虽然没有使用编写驱动程序,但使用的API跟内核模式的一样的,使用ntdll.dll里的API。类型定义全部从DDK 2003 SP1中摘出来的。
对于NtQueryInformationFile获取到的文件路径,是不带盘符的,如“\test\Debug\test.txt”。还有一个内核API可以根据文件的Handle获取文件路径,就是NtQueryObject,使用它获取的路径是MS-DOS设备路径,如“\Device\HarddiskVolume3\test\Debug\test.txt”。