#include "StdAfx.h"
#include <stdio.h>
#include <windows.h>
typedef struct _IO_STATUS_BLOCK
{
LONG Status;
LONG Information;
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
typedef struct _FILE_NAME_INFORMATION
{
ULONG FileNameLength;
WCHAR FileName[MAX_PATH];
} FILE_NAME_INFORMATION;
FARPROC ZwQueryInformationFile;
//通过文件句柄,得到文件所在盘符
BOOL GetVolumeNameByHandle(HANDLE hFile, char *szFullPath)
{
//得到所有磁盘卷的卷序号
char szBuf[500];
int i;
DWORD dwVolumeSerialNumber;
memset(szBuf, 0, sizeof(szBuf));
//通过句柄得到文件的卷序号
//得到卷序号 lpFileInformation.dwVolumeSerialNumber
BY_HANDLE_FILE_INFORMATION lpFileInformation;
if(!GetFileInformationByHandle(hFile, &lpFileInformation) || (lpFileInformation.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
{
//通过句柄得到文件信息失败 或者 此句柄为文件夹句柄,并非文件句柄
return FALSE;
}
if(::GetLogicalDriveStringsA(sizeof(szBuf) - 1,szBuf))
{
for(i = 0; szBuf[i]; i += 4)
{
//得到卷信息->卷序号
if(!stricmp(&(szBuf[i]), "A:\\") || !stricmp(&(szBuf[i]), "B:\\"))
{
//忽略软盘 (一般不会使用,并且查询它的速度非常之慢)
continue;
}
if(GetVolumeInformationA(&(szBuf[i]), NULL, NULL,&dwVolumeSerialNumber,NULL, NULL, NULL, NULL))
{
// 与 lpFileInformation.dwVolumeSerialNumber 比较
// 如果相同,则找到该磁盘
if(dwVolumeSerialNumber == lpFileInformation.dwVolumeSerialNumber)
{
//找到
char szVolumeName[4];
memset(szVolumeName, 0, sizeof(szVolumeName));
strcpy(szVolumeName, &(szBuf[i]));
szVolumeName[strlen(szVolumeName)-1] = '\0';
//得到路径
IO_STATUS_BLOCK isb;
FILE_NAME_INFORMATION fni;
HMODULE hNt = LoadLibraryA("ntdll.dll");
if(hNt)
{
ZwQueryInformationFile = ::GetProcAddress(hNt, "ZwQueryInformationFile");
if(ZwQueryInformationFile)
{
DWORD dwfni = sizeof(fni);
DWORD dwRet = 0;
__asm
{
push 9 ;
push dwfni ;
lea eax, fni ;
push eax ;
lea eax, isb ;
push eax ;
push hFile ;
mov eax, ZwQueryInformationFile ;
call eax ;//调用 ZwQueryInformationFile 函数
mov dwRet, eax;//得到返回值
}
if(!dwRet)
{
//获取文件路径成功
fni.FileName[fni.FileNameLength/2] = 0;
//构造成完整路径名
char szFilePath[MAX_PATH+1];
memset(szFilePath, 0, sizeof(szFilePath));
WideCharToMultiByte( CP_ACP, 0, fni.FileName, -1, szFilePath, sizeof(szFilePath) - 1, NULL, NULL);
sprintf(szFullPath, "%s%s", szVolumeName, szFilePath);
return TRUE;
}
}
FreeLibrary(hNt);
}
}
}
}
}
//没有找到
return FALSE;
}
void main()
{
HANDLE hFile = ::CreateFile(_T("F:\\test1.txt"), GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, NULL);
if(hFile == INVALID_HANDLE_VALUE)
{
printf("ERROR(%d)\n", ::GetLastError());
return ;
}
//得到路径名,合并成完整路径
char szFullPath[MAX_PATH];
memset(szFullPath, 0, sizeof(szFullPath));
if(GetVolumeNameByHandle(hFile, szFullPath))
{
printf("%s\n\n", szFullPath);
}
else
{
printf("Not Found!\n\n");
}
if(hFile != INVALID_HANDLE_VALUE)
{
::CloseHandle(hFile);
}
}