HDEVINFO hDevInfo;
SP_DEVICE_INTERFACE_DATA DevIntfData;
PSP_DEVICE_INTERFACE_DETAIL_DATA DevIntfDetailData;
SP_DEVINFO_DATA DevData;
DWORD dwSize, dwMemberIdx;
// We will try to get device information set for all USB devices that have a
// device interface and are currently present on the system (plugged in).
hDevInfo = SetupDiGetClassDevs(
&DiskClassGuid, NULL, 0, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT);
if (hDevInfo != INVALID_HANDLE_VALUE)
{
// Prepare to enumerate all device interfaces for the device information
// set that we retrieved with SetupDiGetClassDevs(..)
DevIntfData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
dwMemberIdx = 0;
// Next, we will keep calling this SetupDiEnumDeviceInterfaces(..) until this
// function causes GetLastError() to return ERROR_NO_MORE_ITEMS. With each
// call the dwMemberIdx value needs to be incremented to retrieve the next
// device interface information.
SetupDiEnumDeviceInterfaces(hDevInfo, NULL, &DiskClassGuid,
dwMemberIdx, &DevIntfData);
while (GetLastError() != ERROR_NO_MORE_ITEMS)
{
// As a last step we will need to get some more details for each
// of device interface information we are able to retrieve. This
// device interface detail gives us the information we need to identify
// the device (VID/PID), and decide if it's useful to us. It will also
// provide a DEVINFO_DATA structure which we can use to know the serial
// port name for a virtual com port.
DevData.cbSize = sizeof(DevData);
// Get the required buffer size. Call SetupDiGetDeviceInterfaceDetail with
// a NULL DevIntfDetailData pointer, a DevIntfDetailDataSize
// of zero, and a valid RequiredSize variable. In response to such a call,
// this function returns the required buffer size at dwSize.
SetupDiGetDeviceInterfaceDetail(
hDevInfo, &DevIntfData, NULL, 0, &dwSize, NULL);
// Allocate memory for the DeviceInterfaceDetail struct. Don't forget to
// deallocate it later!
DevIntfDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwSize);
DevIntfDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
if (SetupDiGetDeviceInterfaceDetail(hDevInfo, &DevIntfData,
DevIntfDetailData, dwSize, &dwSize, &DevData))
{
// Finally we can start checking if we've found a useable device,
// by inspecting the DevIntfDetailData->DevicePath variable.
// The DevicePath looks something like this:
//
// \\?\usb#vid_04d8&pid_0033#5&19f2438f&0&2#{a5dcbf10-6530-11d2-901f-00c04fb951ed}
//
// The VID for Velleman Projects is always 10cf. The PID is variable
// for each device:
//
// -------------------
// | Device | PID |
// -------------------
// | K8090 | 8090 |
// | VMB1USB | 0b1b |
// -------------------
//
// As you can see it contains the VID/PID for the device, so we can check
// for the right VID/PID with string handling routines.
/* Create File for Device Read/Write */
/* HANDLE DevHandle;
DevHandle = CreateFile(DevIntfDetailData->DevicePath,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
(LPSECURITY_ATTRIBUTES)NULL,
OPEN_EXISTING,
0,
NULL
);*/
//PSTORAGE_DEVICE_DESCRIPTOR pdd = new STORAGE_DEVICE_DESCRIPTOR;
//pdd->Size = sizeof(PSTORAGE_DEVICE_DESCRIPTOR);
//GetDriveProperty(hDevInfo, pdd);
HANDLE hDevice = NULL;
DWORD nDiskBytesRead = 0;//预设为0,当缓冲区的长度不够时,该值为所需的缓冲区的长度
DWORD nDiskBufferSize = sizeof(DRIVE_LAYOUT_INFORMATION)+sizeof(PARTITION_INFORMATION)* 104;//26*4
PDRIVE_LAYOUT_INFORMATION lpDiskPartInfo = (PDRIVE_LAYOUT_INFORMATION)malloc(nDiskBufferSize);
hDevice = CreateFile(LPCTSTR(DevIntfDetailData->DevicePath),//注意一定要是\\\\.\\的形式,CreateFile的要求 ""\\??\\Volume{e9233817-90be-11d6-88b7-00e04c3de005}
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING,
0, NULL);
if (hDevice == NULL)
{
//MessageBox("CreateFile出错!","失败!",MB_OK);
return ;
}
BOOL ret = DeviceIoControl(
hDevice,
IOCTL_DISK_GET_DRIVE_LAYOUT,
NULL,
0,
(LPVOID)lpDiskPartInfo,
(DWORD)nDiskBufferSize,
(LPDWORD)&nDiskBytesRead,
NULL
);
if (!ret)
{
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR)&lpMsgBuf,
0,
NULL
);
}
LARGE_INTEGER Bytes = lpDiskPartInfo->PartitionEntry->PartitionLength;
__int64 tb = 1099511627776;
__int64 gb = 1073741824;
__int64 mb = 1048576;
__int64 kb = 1024;
if (Bytes.QuadPart >= tb)
_TraceA("%.2f TB", (float)Bytes.QuadPart / tb);
else if (Bytes.QuadPart >= gb && Bytes.QuadPart < tb)
_TraceA("%.2f GB", (float)Bytes.QuadPart / gb);
else if (Bytes.QuadPart >= mb && Bytes.QuadPart < gb)
_TraceA("%.2f MB", (float)Bytes.QuadPart / mb);
else if (Bytes.QuadPart >= kb && Bytes.QuadPart < mb)
_TraceA("%.2f KB", (float)Bytes.QuadPart / kb);
else if (Bytes.QuadPart < kb)
_TraceA("%.2f Bytes", Bytes.QuadPart);
else
_TraceA("%.2f Bytes", Bytes.QuadPart);
STORAGE_PROPERTY_QUERY storagePropertyQuery;
ZeroMemory(&storagePropertyQuery, sizeof(STORAGE_PROPERTY_QUERY));
storagePropertyQuery.PropertyId = StorageDeviceProperty;
storagePropertyQuery.QueryType = PropertyStandardQuery;
STORAGE_DESCRIPTOR_HEADER storageDescriptorHeader = { 0 };
DWORD dwBytesReturned = 0;
if (!::DeviceIoControl(hDevice, IOCTL_STORAGE_QUERY_PROPERTY,
&storagePropertyQuery, sizeof(STORAGE_PROPERTY_QUERY),
&storageDescriptorHeader, sizeof(STORAGE_DESCRIPTOR_HEADER),
&dwBytesReturned, NULL))
{
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR)&lpMsgBuf,
0,
NULL
);
_Trace((TCHAR*)lpMsgBuf);
}
const DWORD dwOutBufferSize = storageDescriptorHeader.Size;
BYTE* pOutBuffer = new BYTE[dwOutBufferSize];
ZeroMemory(pOutBuffer, dwOutBufferSize);
if (!::DeviceIoControl(hDevice, IOCTL_STORAGE_QUERY_PROPERTY,
&storagePropertyQuery, sizeof(STORAGE_PROPERTY_QUERY),
pOutBuffer, dwOutBufferSize,
&dwBytesReturned, NULL))
{
// handle error, do cleanup and return
}
// Now, the output buffer points to a STORAGE_DEVICE_DESCRIPTOR structure
// followed by additional info like vendor ID, product ID, serial number, and so on.
STORAGE_DEVICE_DESCRIPTOR* pDeviceDescriptor = (STORAGE_DEVICE_DESCRIPTOR*)pOutBuffer;
const DWORD dwSerialNumberOffset = pDeviceDescriptor->SerialNumberOffset;
if (dwSerialNumberOffset != 0)
{
// Finally, get the serial number
CString strSerialNumber = CString(pOutBuffer + dwSerialNumberOffset);
}
CloseHandle(hDevice);
}
HeapFree(GetProcessHeap(), 0, DevIntfDetailData);
// Continue looping
SetupDiEnumDeviceInterfaces(
hDevInfo, NULL, &DiskClassGuid, ++dwMemberIdx, &DevIntfData);
}
SetupDiDestroyDeviceInfoList(hDevInfo);
}
修正其中一段代码
LARGE_INTEGER Bytes = {0};
for (int i = 0; i < lpDiskPartInfo->PartitionCount; i++){
Bytes.QuadPart += lpDiskPartInfo->PartitionEntry[i].PartitionLength.QuadPart;
}