Windows IOCTL 获取 Volume 信息 (FSCTL_GET_NTFS_VOLUME_DATA)
#define UNICODE 1 #define _UNICODE 1 /* The code of interest is in the subroutine GetDriveGeometry. The code in main shows how to interpret the results of the call. */ #include <windows.h> #include <winioctl.h> #include <stdio.h> #define wszDrive L"\\\\.\\PhysicalDrive0" //#define wszVol L"\\\\?\\Volume{32ef8775-ad83-45dd-9617-312e4c36f1ca}" #define wszVol L"\\\\.\\M:" //#define wszVol L"\\\\?\\Volume{fd47549e-0000-0000-0000-402400000000}" BOOL GetVolInfo(LPWSTR wszPath, NTFS_VOLUME_DATA_BUFFER *pdg) { HANDLE hDevice = INVALID_HANDLE_VALUE; // handle to the drive to be examined BOOL bResult = FALSE; // results flag DWORD bytesReturned = 0; // discard results hDevice = CreateFileW(wszPath, FILE_EXECUTE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, // default security attributes OPEN_EXISTING, // disposition FILE_ATTRIBUTE_NORMAL, // file attributes NULL); // do not copy file attributes if (hDevice == INVALID_HANDLE_VALUE) // cannot open the drive { printf("Failed to open vol %ls\n", wszPath); return (FALSE); } bResult = DeviceIoControl(hDevice, // device to be queried FSCTL_GET_NTFS_VOLUME_DATA, // operation to perform NULL, 0, // no input buffer (LPVOID)pdg, sizeof(*pdg), // output buffer &bytesReturned, // # bytes returned (LPOVERLAPPED)NULL); // synchronous I/O CloseHandle(hDevice); printf("FSCTL_GET_NTFS_VOLUME_DATA bytesReturned %ld\n", bytesReturned); return (bResult); } int wmain(int argc, wchar_t *argv[]) { NTFS_VOLUME_DATA_BUFFER pdg = { 0 }; // disk drive geometry structure BOOL bResult = FALSE; // generic results flag ULONGLONG DiskSize = 0; // size of the drive, in bytes bResult = GetVolInfo(wszVol, &pdg); if (bResult) { wprintf(L"Volume path = %ws\n", wszVol); wprintf(L"BytesPerCluster = %ld\n", pdg.BytesPerCluster); } else { wprintf(L"GetVolInfo %ls failed. Error %ld.\n", wszVol, GetLastError()); } return ((int)bResult); }