使用NtQueryInformationFile函数获得不到完整路径
可以用NtQueryObject获取完整的NT路径:
1 #include <windows.h> 2 #include <iostream> 3 using namespace std; 4 5 6 typedef struct _OBJECT_NAME_INFORMATION { 7 WORD Length; 8 WORD MaximumLength; 9 LPWSTR Buffer; 10 } OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION; 11 12 typedef long(__stdcall*PNtQueryObject)(HANDLE ObjectHandle,ULONG ObjectInformationClass,PVOID ObjectInformation,ULONG ObjectInformationLength,PULONG ReturnLength); 13 14 int main(){ 15 PNtQueryObject NtQueryObject(reinterpret_cast<PNtQueryObject>(GetProcAddress(GetModuleHandleW(L"ntdll.dll"),"NtQueryObject"))); 16 OBJECT_NAME_INFORMATION name,*pname;ULONG len; 17 HANDLE hFile=CreateFile(L"D:\\xiao\\xiaoma.txt",FILE_READ_DATA,1,0,OPEN_EXISTING,0,0); 18 NtQueryObject(hFile,1,&name,sizeof name,&len); 19 pname=reinterpret_cast<POBJECT_NAME_INFORMATION>(new char[len]); 20 NtQueryObject(hFile,1,pname,len,&len); 21 wcout<<pname->Buffer<<endl; 22 return 0; 23 }
这样获得的路径是NT路径,如果要转化为DOS路径的话,可以用下面的函数。
1 /// 2 //功 能:传入一个逻辑路径,转化成DOS路径 3 //参 数:DeviceName,逻辑路径 4 // DosName,DOS路径 5 //返回值:执行成功,返回YES 6 /// 7 8 9 NTSTATUS 10 RtlVolumeDeviceToDosName_( 11 IN PUNICODE_STRING DeviceName, 12 OUT PUNICODE_STRING DosName 13 ) 14 15 { 16 17 UNICODE_STRING driveLetterName; 18 WCHAR driveLetterNameBuf[256]; 19 NTSTATUS status=STATUS_SUCCESS; 20 WCHAR c; 21 int Len,i,j; 22 WCHAR DriLetter[3]; 23 UNICODE_STRING linkTarget; 24 USHORT len; 25 ANSI_STRING ANSI_PATH; 26 CHAR T2[256]; 27 ANSI_PATH.Buffer=T2; 28 ANSI_PATH.MaximumLength=256; 29 30 for (c = L'A'; c <= L'Z'; c++) 31 { 32 RtlInitEmptyUnicodeString(&driveLetterName,driveLetterNameBuf,sizeof(driveLetterNameBuf)); 33 RtlAppendUnicodeToString(&driveLetterName, L"\\??\"); 34 DriLetter[0] = c; 35 DriLetter[1] = L':'; 36 DriLetter[2] = 0; 37 RtlAppendUnicodeToString(&driveLetterName,DriLetter); 38 status = QuerySymbolicLink(&driveLetterName, &linkTarget); 39 if (!NT_SUCCESS(status)) 40 { 41 continue; 42 } 43 if (RtlPrefixUnicodeString(&linkTarget, DeviceName, TRUE)) 44 { 45 Len=linkTarget.Length; 46 ExFreePool(linkTarget.Buffer); 47 break; 48 } 49 ExFreePool(linkTarget.Buffer); 50 } 51 if (c <= L'Z') 52 { 53 DosName->Length = DeviceName->Length+4-Len; 54 *(DosName->Buffer) = c; 55 *(DosName->Buffer+ 1) = ':'; 56 *(DosName->Buffer+ 2) = 0; 57 j=2; 58 for(i=Len/2;i<DeviceName->Length/2;i++,j++) 59 { 60 *(DosName->Buffer+j)=DeviceName->Buffer[i]; 61 } 62 return STATUS_SUCCESS; 63 } 64 return status; 65 }