unit uIoctl;
{.$DEFINE DYNAMIC_LINK}
{$IFDEF DYNAMIC_LINK}
{$STACKFRAMES ON}
{$WARNINGS OFF}
{$ENDIF}{$DEFINE USE_DELPHI_TYPES}{.$DEFINE UNICODE}
{.$DEFINE _UNICODE}
{$DEFINE STRICT}
{$DEFINE WINVER_0400_UP}
{$DEFINE WINVER_0500_GREATER}
{$DEFINE WINVER_0400_GREATER}
{$DEFINE WINNT}
{$DEFINE WINNT_0400_UP}
{$DEFINE WINNT_0400_GREATER}
{$DEFINE WINNT_0500_GREATER}
{$DEFINE WINDOWS_0400_GREATER}{$Z4}
{$A+}
interface
uses SysUtils, Windows;const  BusTypeUnknown = 0;
  BusTypeScsi = 1;
  BusTypeAtapi = 2;
  BusTypeAta = 3;
  BusType1394 = 4;
  BusTypeSsa = 5;
  BusTypeFibre = 6;
  BusTypeUsb = 7;
  BusTypeRAID = 8;
  BusTypeMaxReserved = $7F;
  METHOD_BUFFERED = 0;
{$EXTERNALSYM METHOD_BUFFERED}
  FILE_ANY_ACCESS = 0;
{$EXTERNALSYM FILE_ANY_ACCESS}
  FILE_DEVICE_MASS_STORAGE = $0000002D;
{$EXTERNALSYM FILE_DEVICE_MASS_STORAGE}
  IOCTL_STORAGE_BASE = FILE_DEVICE_MASS_STORAGE;
{$EXTERNALSYM IOCTL_STORAGE_BASE}
  IOCTL_STORAGE_QUERY_PROPERTY = (
    (IOCTL_STORAGE_BASE shl 16) or (FILE_ANY_ACCESS shl 14) or
    ($0500 shl 2) or METHOD_BUFFERED);type
  //DWORD = {$IFDEF USE_DELPHI_TYPES}Windows.DWORD{$ELSE}Longword{$ENDIF};
  //{$EXTERNALSYM DWORD}
  //BOOL = {$IFDEF USE_DELPHI_TYPES}Windows.LongBool{$ELSE}Boolean{$ENDIF};
  //{$EXTERNALSYM BOOL}
  STORAGE_BUS_TYPE = DWORD;
{$EXTERNALSYM STORAGE_BUS_TYPE}type
  PSTORAGE_QUERY_TYPE = ^STORAGE_QUERY_TYPE;
  _STORAGE_QUERY_TYPE = (
    PropertyStandardQuery = 0, // 读取描述
    PropertyExistsQuery, // 测试是否支持
    PropertyMaskQuery, // 读取指定的描述
    PropertyQueryMaxDefined // 验证数据
    );
  STORAGE_QUERY_TYPE = _STORAGE_QUERY_TYPE; //* PSTORAGE_QUERY_TYPE;
type
  PSTORAGE_PROPERTY_ID = ^STORAGE_PROPERTY_ID;
  _STORAGE_PROPERTY_ID = (
    StorageDeviceProperty = 0, // 查询设备属性
    StorageAdapterProperty // 查询适配器属性
    );
  STORAGE_PROPERTY_ID = _STORAGE_PROPERTY_ID;
type
  PSTORAGE_PROPERTY_QUERY = ^STORAGE_PROPERTY_QUERY;
  _STORAGE_PROPERTY_QUERY = record
    PropertyId: STORAGE_PROPERTY_ID; // 设备/适配器
    QueryType: STORAGE_QUERY_TYPE; // 查询类型
    AdditionalParameters: array[1..1] of CHAR; // 额外的数据(仅定义了象征性的1个字节)
  end;
  STORAGE_PROPERTY_QUERY = _STORAGE_PROPERTY_QUERY;
type
  _STORAGE_DEVICE_DESCRIPTOR = record
    Version: LongInt; // 版本
    Size: LongInt; // 结构大小
    DeviceType: Char; // 设备类型
    DeviceTypeModifier: Char; // SCSI-2额外的设备类型
    RemovableMedia: BOOLEAN; // 是否可移动
    CommandQueueing: BOOLEAN; // 是否支持命令队列
    VendorIdOffset: LongInt; // 厂家设定值的偏移
    ProductIdOffset: LongInt; // 产品ID的偏移
    ProductRevisionOffset: LongInt; // 产品版本的偏移
    SerialNumberOffset: LongInt; // 序列号的偏移
    BusType: STORAGE_BUS_TYPE; // 总线类型
    RawPropertiesLength: longInt; // 额外的属性数据长度
    RawDeviceProperties: array[1..1] of Char; // 额外的属性数据(仅定义了象征性的1个字节)
  end;
  STORAGE_DEVICE_DESCRIPTOR = _STORAGE_DEVICE_DESCRIPTOR;
  PSTORAGE_DEVICE_DESCRIPTOR = ^STORAGE_DEVICE_DESCRIPTOR;function IsUsbDisk(szDisk: CHAR): boolean; stdcall;implementationfunction IsUsbDisk(szDisk: CHAR): boolean; stdcall;
var
  Query: STORAGE_PROPERTY_QUERY; // 查询输入参数
  dwOutBytes: DWORD;
  bResult: bool;
  hDevice: THANDLE;
  lpDeviceName: PChar;
  SddBuffer: array[1..sizeof(STORAGE_DEVICE_DESCRIPTOR) + 512] of BYTE;
  pDevDesc: PSTORAGE_DEVICE_DESCRIPTOR;
begin
  dwOutBytes := 0; // IOCTL输出数据长度
  SddBuffer[sizeof(STORAGE_DEVICE_DESCRIPTOR) + 512 - 1] := 0;  pDevDesc := @SddBuffer; // AS PSTORAGE_DEVICE_DESCRIPTOR;
  pDevDesc.Size := sizeof(STORAGE_DEVICE_DESCRIPTOR) + 512 - 1;  lpDeviceName := PChar(uppercase(format('\\.\%s:', [szDisk])));  hDevice := CreateFile(lpDeviceName,
    GENERIC_READ,
    FILE_SHARE_READ or FILE_SHARE_WRITE,
    nil, OPEN_EXISTING, 0, 0);  if (hDevice = INVALID_HANDLE_VALUE) then // cannot open the drive
  begin
    result := FALSE;
    exit;
  end;
 // 指定查询方式
  Query.PropertyId := StorageDeviceProperty;
  Query.QueryType := PropertyStandardQuery; // 用IOCTL_STORAGE_QUERY_PROPERTY取设备属性信息
  bResult := DeviceIoControl(hDevice, // 设备句柄
    IOCTL_STORAGE_QUERY_PROPERTY, // 取设备属性信息
    @Query, sizeof(STORAGE_PROPERTY_QUERY), // 输入数据缓冲区
    pDevDesc, pDevDesc.Size, // 输出数据缓冲区
    dwOutBytes, // 输出数据长度
    nil); // 用同步I/O
  CloseHandle(hDevice);
  if ((BusTypeUsb = pDevDesc.BusType) and (bResult)) then
    result := TRUE
  else
    result := FALSE;
end;end.同时开贴给LY分

解决方案 »

  1.   

    ARI老大别怪他了
    他是贴上承诺2000分呀,所以我才给他出主意的:)http://community.csdn.net/Expert/topic/3381/3381566.xml?temp=.6943018问题一:解决U盘判断的,有1000,我给他解决了
    http://community.csdn.net/Expert/topic/3363/3363233.xml?temp=.8247339问题二:获取Fix驱动器有那些分区,有1000分,我也给他解决了
    http://community.csdn.net/Expert/topic/3374/3374663.xml?temp=.120083他还欠我600分哦,哈哈,上次有100分给删帖了,只兑现了400分,于是就...嘿嘿,不错!http://lysoft.7u7.net