public static extern int ZwQueryInformationFile(int hfile, ref IO_STATUS_BLOCK ioStatusBlock, ref FILE_NAME_INFO fileInformation, int length, int FileInformationClass);
/// <summary> /// 把远程file handle复制到本地进程 /// 然后获取文件名 /// </summary> /// <param name="p_hfile"></param> private unsafe void ReadFileInfo(IntPtr p_hfile) { IntPtr my_hfile = new IntPtr(-1); int hCurProcess = -1; //WinApi.GetCurrentProcess(); bool result; result = WinApi.DuplicateHandle(processHandle.ToInt32(), p_hfile.ToInt32(), hCurProcess, ref my_hfile, 0x80000000, false, 2); #region GetFileInformationByHandle 文件最基本信息 var fileinfo = new BY_HANDLE_FILE_INFORMATION(); result = WinApi.GetFileInformationByHandle(my_hfile.ToInt32(), ref fileinfo); //Console.Out.WriteLine(fileinfo.dwFileAttributes); #endregion #region GetFileInformationByHandleEx var fileinfo2 = new FILE_FULL_DIR_INFO(); int fileInfo2Type = (int)FileInformationClass.FileFullDirectoryInfo; //0xe; //本来想用开辟非托管内存的操作,传指针到winapi,后来发现那块内存有数据后用 //PtrToStructure转结构体报错,也许是操作问题,还不如直接传结构体 int size2 = Marshal.SizeOf(fileinfo2); IntPtr p_fileInfo2 = Marshal.AllocHGlobal(size2); Marshal.StructureToPtr(fileinfo2, p_fileInfo2, false); //调用失败 大概是LARGE_INTEGER 这个union的结构不对 result = WinApi.GetFileInformationByHandleEx(my_hfile.ToInt32(), fileInfo2Type, ref fileinfo2, size2); var fileinfo3 = new FILE_NAME_INFO(); //fileinfo3.FileName = ""; int fileInfo3Type = (int)FileInformationClass.FileNameInfo; //0x2; int size3 = Marshal.SizeOf(fileinfo3) + 1000 * 2; IntPtr p_fileInfo3 = Marshal.AllocHGlobal(size3); Marshal.StructureToPtr(fileinfo3, p_fileInfo3, false); //\otherproject\WriteFileHook\Log4netLoger\bin\x86\Debug\Logs\debug.log20170901 //result = WinApi.GetFileInformationByHandleEx(my_hfile.ToInt32(), fileInfo3Type, p_fileInfo3, size3); result = WinApi.GetFileInformationByHandleEx(my_hfile.ToInt32(), fileInfo3Type, ref fileinfo3, size3); StringBuilder fn3 = new StringBuilder(1000); int len3 = WinApi.GetFullPathName(fileinfo3.FileName, 1000, fn3, null); //输出正常路径 //E:\otherproject\WriteFileHook\Log4netLoger\bin\x86\Debug\Logs\debug.log20170901 Console.Out.WriteLine(fn3); #endregion #region GetFinalPathNameByHandle //char[] fileName = new char[1000]; StringBuilder fileName = new StringBuilder(1000); //获取的带设备路径 //\Device\HarddiskVolume4\otherproject\WriteFileHook\Log4netLoger\bin\x86\Debug\Logs\debug.log20170901 int size4 = WinApi.GetFinalPathNameByHandle(my_hfile.ToInt32(), fileName, 1000, 0x2); StringBuilder fn4 = new StringBuilder(1000); //会在前面在加个盘符,然而没去掉设备路径,超谐 //有专门根据设备路径获取盘符路径的方法 //E:\Device\HarddiskVolume4\otherproject\WriteFileHook\Log4netLoger\bin\x86\Debug\Logs\debug.log20170901 int len4 = WinApi.GetFullPathName(fileName.ToString(), 1000, fn4, null); Console.Out.WriteLine(fn4); #endregion #region ZwQueryInformationFile //GetFileInformationByHandleEx 内部调用的就是这个吧( var fileStatus5 = new IO_STATUS_BLOCK(); int ssize5 = Marshal.SizeOf(fileStatus5); IntPtr p_fileStatus5 = Marshal.AllocHGlobal(ssize5); Marshal.StructureToPtr(fileStatus5, p_fileStatus5, false); var fileinfo5 = new FILE_NAME_INFO(); //fileinfo5.FileName = ""; int fileInfo5Type = (int)FileInformationClass.FileFullDirectoryInfo; //9; int size5 = Marshal.SizeOf(fileinfo5) + 1000 * 2; IntPtr p_fileInfo5 = Marshal.AllocHGlobal(size5); Marshal.StructureToPtr(fileinfo5, p_fileInfo5, false); int ret = WinApi.ZwQueryInformationFile(my_hfile.ToInt32(), ref fileStatus5, ref fileinfo5, size5, fileInfo5Type); //\otherproject\WriteFileHook\Log4netLoger\bin\x86\Debug\Logs\debug.log20170901 Console.Out.WriteLine(fileinfo5.FileName); #endregion }
public static extern unsafe bool GetFileInformationByHandleEx(int hFile, int FileInformationClass, ref FILE_NAME_INFO lpFileInformation, int dwBufferSize);