以下是从群聊天中整理的代码
#ifndef VolumeType_h__
#define VolumeType_h__
#pragma once
#include <WinIoCtl.h>
#define IOCTL_STORAGE_QUERY_PROPERTY CTL_CODE(IOCTL_STORAGE_BASE, 0x0500, METHOD_BUFFERED, FILE_ANY_ACCESS)
typedef enum _STORAGE_PROPERTY_ID {
StorageDeviceProperty = 0,
StorageAdapterProperty,
StorageDeviceIdProperty
} STORAGE_PROPERTY_ID, *PSTORAGE_PROPERTY_ID;
typedef enum _STORAGE_QUERY_TYPE {
PropertyStandardQuery = 0,
PropertyExistsQuery,
PropertyMaskQuery,
PropertyQueryMaxDefined
} STORAGE_QUERY_TYPE, *PSTORAGE_QUERY_TYPE;
typedef struct _STORAGE_PROPERTY_QUERY {
STORAGE_PROPERTY_ID PropertyId;
STORAGE_QUERY_TYPE QueryType;
UCHAR AdditionalParameters[1];
} STORAGE_PROPERTY_QUERY, *PSTORAGE_PROPERTY_QUERY;
typedef struct _STORAGE_DEVICE_DESCRIPTOR {
ULONG Version;
ULONG Size;
UCHAR DeviceType;
UCHAR DeviceTypeModifier;
BOOLEAN RemovableMedia;
BOOLEAN CommandQueueing;
ULONG VendorIdOffset;
ULONG ProductIdOffset;
ULONG ProductRevisionOffset;
ULONG SerialNumberOffset;
STORAGE_BUS_TYPE BusType;
ULONG RawPropertiesLength;
UCHAR RawDeviceProperties[1];
} STORAGE_DEVICE_DESCRIPTOR, *PSTORAGE_DEVICE_DESCRIPTOR;
typedef struct _STORAGE_DEVICE_DESCRIPTOR_WITH_BUFFER {
STORAGE_DEVICE_DESCRIPTOR sdd;
BYTE Vendor_ID[VENDOR_ID_LENGTH+1];
BYTE Product_ID[PRODUCT_ID_LENGTH+1];
BYTE Revision[REVISION_LENGTH+1];
BYTE SerNum[SERIAL_NUMBER_LENGTH+1];
} STORAGE_DEVICE_DESCRIPTOR_WITH_BUFFER, *PSTORAGE_DEVICE_DESCRIPTOR_WITH_BUFFER;
//#define offsetof(TYPE,MEMBER) ((size_t)&((TYPE *)0)->MEMBER)
#define VENDOR_ID "HangZhou"
#define PRODUCT_ID "ChangJin Virtual"
#define PRODUCT_REV "0"
BOOL QueryDeviceProperity(CONST CHAR* szPath,PSTORAGE_DEVICE_DESCRIPTOR_WITH_BUFFER pDevDesc);
BOOL IsDiskLessDevice(CHAR Ch);
#endif // VolumeType_h__
#include "StdAfx.h"
#include "VolumeType.h"
BOOL QueryDeviceProperity(CONST CHAR* szPath,PSTORAGE_DEVICE_DESCRIPTOR_WITH_BUFFER pDevDesc)
{
if( !szPath || !pDevDesc )
return FALSE;
HANDLE hDevice = ::CreateFile(szPath,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL);
if (INVALID_HANDLE_VALUE == hDevice)
{
return FALSE;
}
STORAGE_PROPERTY_QUERY Query;
DWORD dwReturned;
BOOL bRtn;
Query.PropertyId = StorageDeviceProperty;
Query.QueryType = PropertyStandardQuery;
pDevDesc->sdd.Size = sizeof(STORAGE_DEVICE_DESCRIPTOR_WITH_BUFFER);
pDevDesc->sdd.VendorIdOffset = offsetof(STORAGE_DEVICE_DESCRIPTOR_WITH_BUFFER,Vendor_ID);
pDevDesc->sdd.ProductIdOffset= offsetof(STORAGE_DEVICE_DESCRIPTOR_WITH_BUFFER,Product_ID);
pDevDesc->sdd.ProductRevisionOffset= offsetof(STORAGE_DEVICE_DESCRIPTOR_WITH_BUFFER,Revision);
pDevDesc->sdd.SerialNumberOffset= offsetof(STORAGE_DEVICE_DESCRIPTOR_WITH_BUFFER,SerNum);
bRtn = ::DeviceIoControl(hDevice,
IOCTL_STORAGE_QUERY_PROPERTY,
&Query, sizeof(STORAGE_PROPERTY_QUERY),
pDevDesc, pDevDesc->sdd.Size,
&dwReturned,(LPOVERLAPPED)NULL);
CloseHandle(hDevice);
return bRtn;
}
BOOL IsDiskLessDevice(CHAR Ch)
{
CHAR szDev[] = "\\\\.\\C:";
STORAGE_DEVICE_DESCRIPTOR_WITH_BUFFER Buffer;
ZeroMemory(&Buffer,sizeof(Buffer));
if( Ch >= 'a' && Ch <= 'z' )
Ch -= 'a' - 'A';
if( Ch < 'A' || Ch > 'Z' )
return FALSE;
szDev[4] = Ch;
if( QueryDeviceProperity(szDev,&Buffer) )
{
if( Buffer.sdd.BusType == BusTypeiScsi &&
!memcmp(Buffer.Vendor_ID,VENDOR_ID,strlen(VENDOR_ID)) &&
!memcmp(Buffer.Product_ID,PRODUCT_ID,strlen(PRODUCT_ID) ) )
{
return TRUE;
}
}
return FALSE;
}