unit EjectUSB;
interface
uses
Windows, SysUtils, Classes, Dialogs, ShlObj;
const
{ BusTypeUnknown = $0000;
BusTypeScsi = $0001;}
BusTypeAtapi = $0002;
BusTypeAta = $0003;
BusType1394 = $0004;
{ BusTypeSsa = $0005;
BusTypeFibre = $0006;}
BusTypeUsb = $0007;
{ BusTypeRAID = $0008;
BusTypeiSCSI = $0009;
BusTypeSas = $000A;
BusTypeSata = $000B;
BusTypeSd = $000C;
BusTypeMmc = $000D;
BusTypeMax = $000E;
BusTypeMaxReserved = $007F;}
PNP_VetoTypeUnknown = $0000;
{ PNP_VetoLegacyDevice = $0001;
PNP_VetoPendingClose = $0002;
PNP_VetoWindowsApp = $0003;
PNP_VetoWindowsService = $0004;
PNP_VetoOutstandingOpen = $0005;
PNP_VetoDevice = $0006;
PNP_VetoDriver = $0007;
PNP_VetoIllegalDeviceRequest = $0008;
PNP_VetoInsufficientPower = $0009;
PNP_VetoNonDisableable = $000A;
PNP_VetoLegacyDriver = $000B;
PNP_VetoInsufficientRights = $000C;}
CR_SUCCESS = $00000000;
{ CR_DEFAULT = $00000001;
CR_OUT_OF_MEMORY = $00000002;
CR_INVALID_POINTER = $00000003;
CR_INVALID_FLAG = $00000004;
CR_INVALID_DEVNODE = $00000005;
CR_INVALID_DEVINST = CR_INVALID_DEVNODE;
CR_INVALID_RES_DES = $00000006;
CR_INVALID_LOG_CONF = $00000007;
CR_INVALID_ARBITRATOR = $00000008;
CR_INVALID_NODELIST = $00000009;
CR_DEVNODE_HAS_REQS = $0000000A;
CR_DEVINST_HAS_REQS = CR_DEVNODE_HAS_REQS;
CR_INVALID_RESOURCEID = $0000000B;
CR_DLVXD_NOT_FOUND = $0000000C; // WIN 95 ONLY
CR_NO_SUCH_DEVNODE = $0000000D;
CR_NO_SUCH_DEVINST = CR_NO_SUCH_DEVNODE;
CR_NO_MORE_LOG_CONF = $0000000E;
CR_NO_MORE_RES_DES = $0000000F;
CR_ALREADY_SUCH_DEVNODE = $00000010;
CR_ALREADY_SUCH_DEVINST = CR_ALREADY_SUCH_DEVNODE;
CR_INVALID_RANGE_LIST = $00000011;
CR_INVALID_RANGE = $00000012;
CR_FAILURE = $00000013;
CR_NO_SUCH_LOGICAL_DEV = $00000014;
CR_CREATE_BLOCKED = $00000015;
CR_NOT_SYSTEM_VM = $00000016; // WIN 95 ONLY
CR_REMOVE_VETOED = $00000017;
CR_APM_VETOED = $00000018;
CR_INVALID_LOAD_TYPE = $00000019;
CR_BUFFER_SMALL = $0000001A;
CR_NO_ARBITRATOR = $0000001B;
CR_NO_REGISTRY_HANDLE = $0000001C;
CR_REGISTRY_ERROR = $0000001D;
CR_INVALID_DEVICE_ID = $0000001E;
CR_INVALID_DATA = $0000001F;
CR_INVALID_API = $00000020;
CR_DEVLOADER_NOT_READY = $00000021;
CR_NEED_RESTART = $00000022;
CR_NO_MORE_HW_PROFILES = $00000023;
CR_DEVICE_NOT_THERE = $00000024;
CR_NO_SUCH_VALUE = $00000025;
CR_WRONG_TYPE = $00000026;
CR_INVALID_PRIORITY = $00000027;
CR_NOT_DISABLEABLE = $00000028;
CR_FREE_RESOURCES = $00000029;
CR_QUERY_VETOED = $0000002A;
CR_CANT_SHARE_IRQ = $0000002B;
CR_NO_DEPENDENT = $0000002C;
CR_SAME_RESOURCES = $0000002D;
CR_NO_SUCH_REGISTRY_KEY = $0000002E;
CR_INVALID_MACHINENAME = $0000002F; // NT ONLY
CR_REMOTE_COMM_FAILURE = $00000030; // NT ONLY
CR_MACHINE_UNAVAILABLE = $00000031; // NT ONLY
CR_NO_CM_SERVICES = $00000032; // NT ONLY
CR_ACCESS_DENIED = $00000033; // NT ONLY
CR_CALL_NOT_IMPLEMENTED = $00000034;
CR_INVALID_PROPERTY = $00000035;
CR_DEVICE_INTERFACE_ACTIVE = $00000036;
CR_NO_SUCH_DEVICE_INTERFACE = $00000037;
CR_INVALID_REFERENCE_STRING = $00000038;
CR_INVALID_CONFLICT_LIST = $00000039;
CR_INVALID_INDEX = $0000003A;
CR_INVALID_STRUCTURE_SIZE = $0000003B;
NUM_CR_RESULTS = $0000003C;}
{ FILE_DEVICE_BEEP = $00000001;
FILE_DEVICE_CD_ROM = $00000002;
FILE_DEVICE_CD_ROM_FILE_SYSTEM = $00000003;
FILE_DEVICE_CONTROLLER = $00000004;
FILE_DEVICE_DATALINK = $00000005;
FILE_DEVICE_DFS = $00000006;
FILE_DEVICE_DISK = $00000007;
FILE_DEVICE_DISK_FILE_SYSTEM = $00000008;
FILE_DEVICE_FILE_SYSTEM = $00000009;
FILE_DEVICE_INPORT_PORT = $0000000a;
FILE_DEVICE_KEYBOARD = $0000000b;
FILE_DEVICE_MAILSLOT = $0000000c;
FILE_DEVICE_MIDI_IN = $0000000d;
FILE_DEVICE_MIDI_OUT = $0000000e;
FILE_DEVICE_MOUSE = $0000000f;
FILE_DEVICE_MULTI_UNC_PROVIDER = $00000010;
FILE_DEVICE_NAMED_PIPE = $00000011;
FILE_DEVICE_NETWORK = $00000012;
FILE_DEVICE_NETWORK_BROWSER = $00000013;
FILE_DEVICE_NETWORK_FILE_SYSTEM = $00000014;
FILE_DEVICE_NULL = $00000015;
FILE_DEVICE_PARALLEL_PORT = $00000016;
FILE_DEVICE_PHYSICAL_NETCARD = $00000017;
FILE_DEVICE_PRINTER = $00000018;
FILE_DEVICE_SCANNER = $00000019;
FILE_DEVICE_SERIAL_MOUSE_PORT = $0000001a;
FILE_DEVICE_SERIAL_PORT = $0000001b;
FILE_DEVICE_SCREEN = $0000001c;
FILE_DEVICE_SOUND = $0000001d;
FILE_DEVICE_STREAMS = $0000001e;
FILE_DEVICE_TAPE = $0000001f;
FILE_DEVICE_TAPE_FILE_SYSTEM = $00000020;
FILE_DEVICE_TRANSPORT = $00000021;
FILE_DEVICE_UNKNOWN = $00000022;
FILE_DEVICE_VIDEO = $00000023;
FILE_DEVICE_VIRTUAL_DISK = $00000024;
FILE_DEVICE_WAVE_IN = $00000025;
FILE_DEVICE_WAVE_OUT = $00000026;
FILE_DEVICE_8042_PORT = $00000027;
FILE_DEVICE_NETWORK_REDIRECTOR = $00000028;
FILE_DEVICE_BATTERY = $00000029;
FILE_DEVICE_BUS_EXTENDER = $0000002a;
FILE_DEVICE_MODEM = $0000002b;
FILE_DEVICE_VDM = $0000002c;
FILE_DEVICE_MASS_STORAGE = $0000002d;
FILE_DEVICE_SMB = $0000002e;
FILE_DEVICE_KS = $0000002f;
FILE_DEVICE_CHANGER = $00000030;
FILE_DEVICE_SMARTCARD = $00000031;
FILE_DEVICE_ACPI = $00000032;
FILE_DEVICE_DVD = $00000033;
FILE_DEVICE_FULLSCREEN_VIDEO = $00000034;
FILE_DEVICE_DFS_FILE_SYSTEM = $00000035;
FILE_DEVICE_DFS_VOLUME = $00000036;}
DIGCF_PRESENT = $00000002;
DIGCF_DEVICEINTERFACE = $00000010;
GUID_DEVINTERFACE_FLOPPY : TGUID = (D1:$53f56311;D2:$b6bf;D3:$11d0;D4:($94,$f2,$00,$a0,$c9,$1e,$fb,$8b));
GUID_DEVINTERFACE_DISK : TGUID = (D1:$53f56307;D2:$b6bf;D3:$11d0;D4:($94,$f2,$00,$a0,$c9,$1e,$fb,$8b));
GUID_DEVINTERFACE_CDROM : TGUID = (D1:$53f56308;D2:$b6bf;D3:$11d0;D4:($94,$f2,$00,$a0,$c9,$1e,$fb,$8b));
IOCTL_STORAGE_GET_DEVICE_NUMBER = (($0000002d shl 16) or ($0000 shl 14) or ($0420 shl 2) or 0);
IOCTL_STORAGE_GET_HOTPLUG_INFO = (($0000002d shl 16) or ($0000 shl 14) or ($0305 shl 2) or 0);
IOCTL_STORAGE_MEDIA_REMOVAL = (($0000002d shl 16) or ($0001 shl 14) or ($0201 shl 2) or 0);
IOCTL_STORAGE_EJECT_MEDIA = (($0000002d shl 16) or ($0001 shl 14) or ($0202 shl 2) or 0);
IOCTL_STORAGE_CHECK_VERIFY = (($0000002d shl 16) or ($0001 shl 14) or ($0200 shl 2) or 0);
IOCTL_STORAGE_EJECTION_CONTROL = (($0000002d shl 16) or ($0000 shl 14) or ($0250 shl 2) or 0);
IOCTL_STORAGE_QUERY_PROPERTY = (($0000002d shl 16) or ($0000 shl 14) or ($0500 shl 2) or 0);
{ IOCTL_STORAGE_SET_HOTPLUG_INFO = (($0000002d shl 16) or (($0001 or $0002) shl 14) or ($0306 shl 2) or 0);
IOCTL_STORAGE_LOAD_MEDIA = (($0000002d shl 16) or ($0001 shl 14) or ($0203 shl 2) or 0);
IOCTL_STORAGE_RESERVE = (($0000002d shl 16) or ($0001 shl 14) or ($0204 shl 2) or 0);
IOCTL_STORAGE_RELEASE = (($0000002d shl 16) or ($0001 shl 14) or ($0205 shl 2) or 0);
IOCTL_STORAGE_FIND_NEW_DEVICES = (($0000002d shl 16) or ($0001 shl 14) or ($0206 shl 2) or 0);
IOCTL_STORAGE_GET_MEDIA_TYPES = (($0000002d shl 16) or ($0000 shl 14) or ($0300 shl 2) or 0);
IOCTL_STORAGE_GET_MEDIA_TYPES_EX = (($0000002d shl 16) or ($0000 shl 14) or ($0301 shl 2) or 0);
IOCTL_STORAGE_RESET_BUS = (($0000002d shl 16) or ($0001 shl 14) or ($0400 shl 2) or 0);
IOCTL_STORAGE_RESET_DEVICE = (($0000002d shl 16) or ($0001 shl 14) or ($0401 shl 2) or 0);}
FSCTL_LOCK_VOLUME = (($00000009 shl 16) or ($0000 shl 14) or (00006 shl 2) or 0);
FSCTL_DISMOUNT_VOLUME = (($00000009 shl 16) or ($0000 shl 14) or (00008 shl 2) or 0);
FSCTL_UNLOCK_VOLUME = (($00000009 shl 16) or ($0000 shl 14) or (00007 shl 2) or 0);
type
PPNP_VETO_TYPE = ^PNP_VETO_TYPE;
PNP_VETO_TYPE = DWORD;
PDEVINST = ^DEVINST;
DEVINST = DWORD;
PRETURN_TYPE = ^RETURN_TYPE;
RETURN_TYPE = DWORD;
PCONFIGRET = ^CONFIGRET;
CONFIGRET = RETURN_TYPE;
PHDEVINFO = ^HDEVINFO;
HDEVINFO = Pointer;
PDEVICE_TYPE = ^DEVICE_TYPE;
DEVICE_TYPE = DWORD;
PSTORAGE_BUS_TYPE = ^STORAGE_BUS_TYPE;
STORAGE_BUS_TYPE = DWORD;
PULONG_PTR = ^ULONG_PTR;
ULONG_PTR = LONGWORD;
PPTSTR = ^LPWSTR;
PTSTR = LPWSTR;
PSPDeviceInterfaceData = ^TSPDeviceInterfaceData;
SP_DEVICE_INTERFACE_DATA = packed record
cbSize : DWORD;
InterfaceClassGuid : TGUID;
Flags : DWORD;
Reserved : ULONG_PTR;
end;
TSPDeviceInterfaceData = SP_DEVICE_INTERFACE_DATA;
PSPDevInfoData = ^TSPDevInfoData;
SP_DEVINFO_DATA = packed record
cbSize : DWORD;
ClassGuid : TGUID;
DevInst : DWORD;
Reserved : ULONG_PTR;
end;
TSPDevInfoData = SP_DEVINFO_DATA;
PSPDeviceInterfaceDetailDataA = ^TSPDeviceInterfaceDetailDataA;
PSPDeviceInterfaceDetailDataW = ^TSPDeviceInterfaceDetailDataW;
SP_DEVICE_INTERFACE_DETAIL_DATA_A = packed record
cbSize : DWORD;
DevicePath : array [0..0] of AnsiChar;
end;
SP_DEVICE_INTERFACE_DETAIL_DATA_W = packed record
cbSize : DWORD;
DevicePath : array [0..0] of WideChar;
end;
TSPDeviceInterfaceDetailDataA = SP_DEVICE_INTERFACE_DETAIL_DATA_A;
TSPDeviceInterfaceDetailDataW = SP_DEVICE_INTERFACE_DETAIL_DATA_W;
{$IFDEF UNICODE}
TSPDeviceInterfaceDetailData = TSPDeviceInterfaceDetailDataW;
PSPDeviceInterfaceDetailData = PSPDeviceInterfaceDetailDataW;
{$ELSE}
TSPDeviceInterfaceDetailData = TSPDeviceInterfaceDetailDataA;
PSPDeviceInterfaceDetailData = PSPDeviceInterfaceDetailDataA;
{$ENDIF UNICODE}

PSTORAGE_DEVICE_NUMBER = ^TSTORAGE_DEVICE_NUMBER;
STORAGE_DEVICE_NUMBER = record
DeviceType : DEVICE_TYPE;
DeviceNumber : DWORD;
PartitionNumber : DWORD;
end;
TSTORAGE_DEVICE_NUMBER = STORAGE_DEVICE_NUMBER;
DEV_BROADCAST_HDR = ^PDEV_BROADCAST_HDR;
PDEV_BROADCAST_HDR = packed record
dbch_size : DWORD;
dbch_devicetype : DWORD;
dbch_reserved : DWORD;
end;
DEV_BROADCAST_VOLUME = ^PDEV_BROADCAST_VOLUME;
PDEV_BROADCAST_VOLUME = packed record
dbcv_size : DWORD;
dbcv_devicetype : DWORD;
dbcv_reserved : DWORD;
dbcv_unitmask : DWORD;
dbcv_flags : WORD;
end;
PSTORAGE_HOTPLUG_INFO = ^TSTORAGE_HOTPLUG_INFO;
STORAGE_HOTPLUG_INFO = packed record
Size : DWORD;
MediaRemovable : BOOLEAN;
MediaHotplug : BOOLEAN;
DeviceHotplug : BOOLEAN;
WriteCacheEnableOverride : BOOLEAN;
end;
TSTORAGE_HOTPLUG_INFO = STORAGE_HOTPLUG_INFO;
PSTORAGE_PROPERTY_QUERY = ^TSTORAGE_PROPERTY_QUERY;
STORAGE_PROPERTY_QUERY = packed record
PropertyId : DWORD;
QueryType : DWORD;
AdditionalParameters: array[0..3] of Byte;
end;
TSTORAGE_PROPERTY_QUERY = STORAGE_PROPERTY_QUERY;
PSTORAGE_DEVICE_DESCRIPTOR = ^TSTORAGE_DEVICE_DESCRIPTOR;
STORAGE_DEVICE_DESCRIPTOR = packed record
Version : ULONG;
Size : ULONG;
DeviceType : Byte;
DeviceTypeModifier : Byte;
RemovableMedia : Boolean;
CommandQueueing : Boolean;
VendorIdOffset : ULONG;
ProductIdOffset : ULONG;
ProductRevisionOffset : ULONG;
SerialNumberOffset : ULONG;
BusType : STORAGE_BUS_TYPE;
RawPropertiesLength : ULONG;
RawDeviceProperties : array [0..MAX_PATH] of Byte;
end;
TSTORAGE_DEVICE_DESCRIPTOR = STORAGE_DEVICE_DESCRIPTOR;
{ PSTORAGE_BUS_RESET_REQUEST = ^TSTORAGE_BUS_RESET_REQUEST;
STORAGE_BUS_RESET_REQUEST = packed record
PathId : Byte;
end;
TSTORAGE_BUS_RESET_REQUEST = STORAGE_BUS_RESET_REQUEST;
STORAGE_MEDIA_TYPE = DWORD;
PDEVICE_MEDIA_INFO = ^TDEVICE_MEDIA_INFO;
DEVICE_MEDIA_INFO = packed record
DeviceSpecific : packed record
case BYTE of
0 :(DiskInfo : packed record
Cylinders : LARGE_INTEGER;
MediaType : STORAGE_MEDIA_TYPE;
TracksPerCylinder : DWORD;//ULONG
SectorsPerTrack : DWORD;
BytesPerSector : DWORD;
NumberMediaSides : DWORD;
MediaCharacteristics: DWORD;
end );
1 :(RemovableDiskInfo : packed record
Cylinders : LARGE_INTEGER;
MediaType : STORAGE_MEDIA_TYPE;
TracksPerCylinder : DWORD;
SectorsPerTrack : DWORD;
BytesPerSector : DWORD;
NumberMediaSides : DWORD;
MediaCharacteristics: DWORD;
end );
2 :(TapeInfo : packed record
MediaType : STORAGE_MEDIA_TYPE;
MediaCharacteristics: DWORD;
CurrentBlockSize : DWORD;
BusType : STORAGE_BUS_TYPE;
BusSpecificData : packed record
case INTEGER of
0 :(ScsiInformation : packed record
MediumType : BYTE;//UCHAR
DensityCode : BYTE;
end );
end;
end );
end;
end;
TDEVICE_MEDIA_INFO = DEVICE_MEDIA_INFO;
PGET_MEDIA_TYPES = ^TGET_MEDIA_TYPES;
GET_MEDIA_TYPES = packed record
DeviceType : DWORD;
MediaInfoCount : DWORD;
MediaInfo : array [0..0] of DEVICE_MEDIA_INFO;
end;
TGET_MEDIA_TYPES = GET_MEDIA_TYPES;}
TDrive = packed record
Volume : String;
VolumeName : String;
TailleLib : String;
TailleTot : String;
SystFich : String;
Properties : String;
DeviceType : DWORD;
BusType : STORAGE_BUS_TYPE;
MediaRemovable : BOOLEAN;
MediaHotplug : BOOLEAN;
DeviceHotplug : BOOLEAN;
Partition : Integer;
end;
TPREVENT_MEDIA_REMOVAL = record
PreventMediaRemoval : ByteBool;
end;
function SetupDiDestroyDeviceInfoList(DeviceInfoSet: HDEVINFO): BOOL; stdcall;external 'SetupApi.dll';
function SetupDiEnumDeviceInterfaces(DeviceInfoSet:HDEVINFO;DeviceInfoData:PSPDevInfoData;
const InterfaceClassGuid:TGUID;MemberIndex:DWORD;var DeviceInterfaceData:TSPDeviceInterfaceData):BOOL;stdcall;external 'SetupApi.dll';
function CM_Get_Parent(var dnDevInstParent:DEVINST;dnDevInst:DEVINST;ulFlags:ULONG):CONFIGRET;stdcall;external 'CfgMgr32.dll';
function CM_Query_And_Remove_SubTreeW(dnAncestor: DEVINST;pVetoType: PPNP_VETO_TYPE; pszVetoName: PWideChar;
ulNameLength: ULONG; ulFlags: ULONG): CONFIGRET; stdcall;
function CM_Query_And_Remove_SubTreeA(dnAncestor: DEVINST;pVetoType: PPNP_VETO_TYPE; pszVetoName: PAnsiChar;
ulNameLength: ULONG; ulFlags: ULONG): CONFIGRET; stdcall;
function CM_Query_And_Remove_SubTree(dnAncestor: DEVINST;pVetoType: PPNP_VETO_TYPE; pszVetoName: PTSTR;
ulNameLength: ULONG; ulFlags: ULONG): CONFIGRET; stdcall;
function CM_Request_Device_EjectW(dnDevInst:DEVINST;pVetoType:PPNP_VETO_TYPE;pszVetoName:PWideChar;
ulNameLength:ULONG;ulFlags: ULONG):CONFIGRET; stdcall;
function CM_Request_Device_EjectA(dnDevInst:DEVINST;pVetoType:PPNP_VETO_TYPE;pszVetoName:PAnsiChar;
ulNameLength:ULONG;ulFlags: ULONG):CONFIGRET; stdcall;
function CM_Request_Device_Eject(dnDevInst:DEVINST;pVetoType:PPNP_VETO_TYPE;pszVetoName:PTSTR;
ulNameLength:ULONG;ulFlags: ULONG):CONFIGRET; stdcall;
function SetupDiGetClassDevsW(ClassGuid:PGUID;const Enumerator:PWideChar;hwndParent:HWND;Flags:DWORD):HDEVINFO;stdcall;
function SetupDiGetClassDevsA(ClassGuid:PGUID;const Enumerator:PAnsiChar;hwndParent:HWND;Flags:DWORD):HDEVINFO;stdcall;
function SetupDiGetClassDevs(ClassGuid:PGUID;const Enumerator:PTSTR;hwndParent:HWND;Flags:DWORD):HDEVINFO;stdcall;
function SetupDiGetDeviceInterfaceDetailW(DeviceInfoSet:HDEVINFO;DeviceInterfaceData:PSPDeviceInterfaceData;
DeviceInterfaceDetailData:PSPDeviceInterfaceDetailData;DeviceInterfaceDetailDataSize:DWORD;
var RequiredSize:DWORD;Device:PSPDevInfoData):BOOL;stdcall;
function SetupDiGetDeviceInterfaceDetailA(DeviceInfoSet:HDEVINFO;DeviceInterfaceData:PSPDeviceInterfaceData;
DeviceInterfaceDetailData:PSPDeviceInterfaceDetailData;DeviceInterfaceDetailDataSize:DWORD;
var RequiredSize:DWORD;Device:PSPDevInfoData):BOOL;stdcall;
function SetupDiGetDeviceInterfaceDetail(DeviceInfoSet:HDEVINFO;DeviceInterfaceData:PSPDeviceInterfaceData;
DeviceInterfaceDetailData:PSPDeviceInterfaceDetailData;DeviceInterfaceDetailDataSize:DWORD;
var RequiredSize:DWORD;Device:PSPDevInfoData):BOOL;stdcall;
{ function CM_Reenumerate_DevNode(dnDevInst: DEVINST;ulFlags: ULONG): CONFIGRET; stdcall;external 'CfgMgr32.dll';
function GetVolumeNameForVolumeMountPointW(lpszVolumeMountPoint: LPCWSTR;
lpszVolumeName: LPWSTR; cchBufferLength: DWORD): BOOL; stdcall;external 'kernel32.dll';
function SetupDiGetInterfaceDeviceDetailW(DeviceInfoSet:HDEVINFO;DeviceInterfaceData:PSPDeviceInterfaceData;
DeviceInterfaceDetailData:PSPDeviceInterfaceDetailDataW;DeviceInterfaceDetailDataSize:DWORD;RequiredSize:PDWORD;
Device:PSPDevInfoData):BOOL;stdcall;external 'SetupApi.dll';}
function DeviceNumberDrive(DeviceNumber:Integer;DriveType:UINT;szDosDeviceName:PCHAR):DEVINST;
function Eject_USB(LetVol:Char;Rep,TempRep:Integer;MessageEject,MultiSupport:Boolean):Boolean;stdcall;
function Eject_DevHotPlugMedia(LetVol:Char;Rep,TempRep:Integer;MessageEject,MediaRemove:Boolean):Boolean;
function Eject_DevHotPlug(LetVol:Char;Rep,TempRep:Integer;MessageEject,RemoveMediaHotPlug:Boolean):Boolean;
Procedure Liste_USB(Lecteurs:TStrings;DriveRemovable,DriveFixed,DriveCDRom:Boolean);stdcall;
implementation
const
{$IFDEF UNICODE}
LettreFin = 'W';
{$ELSE}
LettreFin = 'A';
{$ENDIF UNICODE}
Var
Drive : TDrive;
//Partie ejection peripherique
function DeviceNumberDrive(DeviceNumber:Integer;DriveType:UINT;szDosDeviceName:PCHAR):DEVINST;
var
IsFloppy : Boolean;
BoucWh : Boolean;
ValGUID : TGUID;
ValHDevInfo : HDEVINFO;
hDrive : THandle;
dwIndex, dwSize, dwBytesReturned : DWORD;
FunctionResult : Boolean;
SPDeviceInterfaceDetailData : PSPDeviceInterfaceDetailData;
SPDeviceInterfaceData : SP_DEVICE_INTERFACE_DATA;
SPDevInfoData : SP_DEVINFO_DATA;
StorageDeviceNumber : STORAGE_DEVICE_NUMBER;
begin
Result:=0;
IsFloppy:=true;
if StrPos(szDosDeviceName, '/Floppy') = nil then
IsFloppy:=false;
case (DriveType) of
DRIVE_REMOVABLE : if ( IsFloppy ) then
begin
ValGUID := GUID_DEVINTERFACE_FLOPPY;
end
else
begin
ValGUID := GUID_DEVINTERFACE_DISK;
end;
DRIVE_FIXED : ValGUID := GUID_DEVINTERFACE_DISK;
DRIVE_CDROM : ValGUID := GUID_DEVINTERFACE_CDROM;
else
exit;
end;
ValHDevInfo := SetupDiGetClassDevs(@ValGUID,nil,0,DIGCF_PRESENT or DIGCF_DEVICEINTERFACE);
if (Cardinal(ValHDevInfo)=INVALID_HANDLE_VALUE) then
exit;
dwIndex := 0;
ZeroMemory(@SPDevInfoData,SizeOf(SPDevInfoData));
SPDeviceInterfaceData.cbSize:=SizeOf(SPDeviceInterfaceData);
BoucWh:=True;
while (BoucWh=true) do
begin
FunctionResult:=SetupDiEnumDeviceInterfaces(ValHDevInfo,nil,ValGUID,dwIndex,SPDeviceInterfaceData);
if FunctionResult=False then
break;
dwSize:=0;
SetupDiGetDeviceInterfaceDetail(ValHDevInfo,@SPDeviceInterfaceData,nil,0,dwSize,nil);
if (dwSize<>0)and(dwSize<=1024)then
begin
GetMem(SPDeviceInterfaceDetailData,dwSize);
try
SPDeviceInterfaceDetailData.cbSize:=SizeOf(SPDeviceInterfaceDetailData^);
ZeroMemory(@SPDevInfoData,SizeOf(SPDevInfoData));
SPDevInfoData.cbSize:=SizeOf(SPDevInfoData);
FunctionResult:=SetupDiGetDeviceInterfaceDetail(ValHDevInfo,@SPDeviceInterfaceData,SPDeviceInterfaceDetailData,dwSize,dwSize,@SPDevInfoData);
if FunctionResult then
begin
hDrive:=DWORD(-1);
try
hDrive := CreateFile(SPDeviceInterfaceDetailData.DevicePath,0,FILE_SHARE_READ or FILE_SHARE_WRITE,nil,OPEN_EXISTING,0,0);
if (hDrive<>INVALID_HANDLE_VALUE) then
begin
dwBytesReturned := 0;
FunctionResult := DeviceIoControl(hDrive,IOCTL_STORAGE_GET_DEVICE_NUMBER,nil,0,@StorageDeviceNumber,SizeOf(StorageDeviceNumber),dwBytesReturned, nil);
if FunctionResult then
begin
if DeviceNumber = LongInt(StorageDeviceNumber.DeviceNumber) then
begin
Result:= SPDevInfoData.DevInst;
break;
end;
end;
end;
finally
CloseHandle(hDrive);
end;
end;
finally
FreeMem(SPDeviceInterfaceDetailData);
end;
end;
dwIndex:=dwIndex+1;
end;
SetupDiDestroyDeviceInfoList(ValHDevInfo);
end;
function Eject_DevHotPlug(LetVol:Char;Rep,TempRep:Integer;MessageEject,RemoveMediaHotPlug:Boolean):Boolean;
var
DeviceNumber : LongInt;
dwBytesReturned : DWord;
DriveType : UINT;
hVolume : THandle;
StorageDeviceNumber : STORAGE_DEVICE_NUMBER;
I : Integer;
ResultInt : DWORD;
ResultIntNod : DWORD;
ResultBool : Boolean;
DeviceInst : DEVINST;
DevInstParent : DEVINST;
szDosDeviceName : array[0..MAX_PATH] of Char;
VetoType : PNP_VETO_TYPE;
VetoNameW : array[0..MAX_PATH] of WChar;
begin
Result:=False;
DeviceNumber:=-1;
hVolume:=INVALID_HANDLE_VALUE;
try
hVolume:=CreateFile(PChar('//./'+LetVol+':'),0,FILE_SHARE_READ or FILE_SHARE_WRITE,nil,OPEN_EXISTING,0,0);
if hVolume=INVALID_HANDLE_VALUE then
exit;
dwBytesReturned:=0;
ResultBool:=DeviceIoControl(hVolume,IOCTL_STORAGE_GET_DEVICE_NUMBER,nil,0,@StorageDeviceNumber,SizeOf(StorageDeviceNumber),dwBytesReturned,nil);
if ResultBool = True then
DeviceNumber:=StorageDeviceNumber.DeviceNumber;
finally
CloseHandle(hVolume);
end;
if DeviceNumber=-1 then
exit;

DriveType:=GetDriveType(PChar(String(LetVol+':')));
szDosDeviceName[0]:=#0;
ResultInt:=QueryDosDevice(PChar(String(LetVol+':')),szDosDeviceName,MAX_PATH);
if ResultInt=0 then
exit;
DeviceInst:=DeviceNumberDrive(DeviceNumber,DriveType,szDosDeviceName);
if DeviceInst = 0 then
exit;
VetoType := PNP_VetoTypeUnknown;
VetoNameW[0] := #0;
DevInstParent := 0;
// http://msdn.microsoft.com/en-us/library/ms791198.aspx
CM_Get_Parent(DevInstParent, DeviceInst, 0);
if not RemoveMediaHotPlug then
begin
for I := 0 to Rep - 1 do
begin
VetoNameW[0] := #0;
// http://msdn.microsoft.com/en-us/library/ms790831.aspx
if MessageEject then
ResultInt:=CM_Request_Device_Eject(DevInstParent,nil,nil,0,0)
else
ResultInt:=CM_Request_Device_Eject(DevInstParent,@VetoType,VetoNameW,MAX_PATH,0);
if (ResultInt=CR_SUCCESS)and(VetoType=PNP_VetoTypeUnknown) then
begin
Result:=True;
Break;
end;
Sleep(TempRep);
end;
end
else
begin // if CM_Request_Device_Eject(DevInstParent,@VetoType,VetoNameW,MAX_PATH,0)=CR_REMOVE_VETOED then CM_Query_And_Remove_SubTree(DeviceInst,nil,nil,0,0);
for I := 0 to Rep - 1 do
begin
VetoNameW[0] := #0;
// http://msdn.microsoft.com/en-us/library/ms790877.aspx
if MessageEject then
ResultIntNod:=CM_Query_And_Remove_SubTree(DeviceInst,nil,nil,0,0)
else
ResultIntNod:=CM_Query_And_Remove_SubTree(DeviceInst,@VetoType,VetoNameW,MAX_PATH,0);
if (ResultIntNod=CR_SUCCESS)and(VetoType=PNP_VetoTypeUnknown) then
begin
Result:=True;
if MessageEject then
MessageDlg('Le matériel peut-être retiré en toute sécurité !',mtInformation,[mbOK],0);
Break;
end;
Sleep(TempRep);
end;
end;
end;
function Eject_DevHotPlugMedia(LetVol:Char;Rep,TempRep:Integer;MessageEject,MediaRemove: Boolean):Boolean;
var
HVolume : THandle;
lpBytesReturned : DWORD;
PreventRemoval : TPREVENT_MEDIA_REMOVAL;
FormatLettreLecteur : String;
I : Integer;
begin
Result:=False;
hVolume:=INVALID_HANDLE_VALUE;
try
hVolume:=CreateFile(PChar('//./'+LetVol+':'),FILE_SHARE_READ or FILE_SHARE_WRITE,0,nil,OPEN_EXISTING,0,0);
if hVolume=INVALID_HANDLE_VALUE then
hVolume:=CreateFile(PChar('//./'+LetVol+':'),GENERIC_READ,0,nil,OPEN_EXISTING,0,0);
if hVolume=INVALID_HANDLE_VALUE then
hVolume:=CreateFile(PChar('//./'+LetVol+':'),0,FILE_SHARE_READ or FILE_SHARE_WRITE,nil,OPEN_EXISTING,0,0);
if hVolume=INVALID_HANDLE_VALUE then
exit;
for I := 0 to Rep - 1 do
begin
PreventRemoval.PreventMediaRemoval:=False;
if DeviceIoControl(hVolume,FSCTL_LOCK_VOLUME, nil,0,nil,0,lpBytesReturned,nil) then //Vérrouillage volume
if DeviceIoControl(hVolume,FSCTL_DISMOUNT_VOLUME, nil,0,nil,0,lpBytesReturned,nil) then //Démontage du volume
if DeviceIoControl(hVolume,IOCTL_STORAGE_MEDIA_REMOVAL,@PreventRemoval,SizeOf(TPREVENT_MEDIA_REMOVAL),nil,0,lpBytesReturned,nil) then //Control du volume
if DeviceIoControl(hVolume,IOCTL_STORAGE_EJECT_MEDIA,nil,0,nil,0,lpBytesReturned,nil)then //Ejection du volume
if DeviceIoControl(hVolume,FSCTL_UNLOCK_VOLUME,nil,0,nil,0,lpBytesReturned,nil) then //Déverrouillage du volume
begin
FormatLettreLecteur:=Format('%s:/',[Uppercase(LetVol)]);
// Avertir le système que l'USB est demonter
ShChangeNotify(SHCNE_MEDIAREMOVED,SHCNF_PATH,PChar(FormatLettreLecteur),Nil);
Result:=True;
if (MessageEject) and (not MediaRemove) then
MessageDlg('Le matériel peut-être retiré en toute sécurité !',mtInformation,[mbOK],0);
if (MessageEject) and (MediaRemove) then
MessageDlg('Le lecteur est ouvert !',mtInformation,[mbOK],0);
Break;
end;
if not Result then
Sleep(TempRep);
end;
finally
CloseHandle(hVolume);
end;
if (not Result) and (MessageEject) and (MediaRemove) then
MessageDlg('Le lecteur est en cours d''utilisation par un autre processus !',mtWarning,[mbOK],0);
if (not Result) and (not MediaRemove) then
Eject_DevHotPlug(LetVol,Rep,TempRep,MessageEject,False);
end;
function Eject_USB(LetVol:Char;Rep,TempRep:Integer;MessageEject,MultiSupport:Boolean):Boolean;
var
hVolume : THandle;
GetMediaTypes : STORAGE_HOTPLUG_INFO;
lpBytesReturned : DWORD;
begin
Result:=False;
hVolume:=INVALID_HANDLE_VALUE;
try
hVolume:=CreateFile(PChar('//./'+LetVol+':'),0,FILE_SHARE_READ or FILE_SHARE_WRITE,nil,OPEN_EXISTING,0,0);
if hVolume=INVALID_HANDLE_VALUE then
exit;
DeviceIoControl(hVolume,IOCTL_STORAGE_GET_HOTPLUG_INFO,nil,0,@GetMediaTypes,sizeof(GetMediaTypes),lpBytesReturned,nil);
finally
CloseHandle(hVolume);
end;
if (GetMediaTypes.DeviceHotplug) and (GetMediaTypes.MediaRemovable) and (MultiSupport=False) then //support usb standard...
begin
if Eject_DevHotPlugMedia(LetVol,Rep,TempRep,MessageEject,False) then
Result:=True;
end
else
if GetMediaTypes.DeviceHotplug then //support disque usb...
begin
if Eject_DevHotPlug(LetVol,Rep,TempRep,MessageEject,False)then
Result:=True;
end
else
if (GetMediaTypes.MediaRemovable) and (GetMediaTypes.MediaHotplug) then //support lecteur carte interne...
begin
if Eject_DevHotPlug(LetVol,Rep,TempRep,MessageEject,True)then
Result:=True;
end
else
if GetMediaTypes.MediaRemovable then //support cd/dvd...
begin
if Eject_DevHotPlugMedia(LetVol,Rep,TempRep,MessageEject,True) then
Result:=True;
end
else
MessageDlg('Il est impossible d''éjecter un périphérique interne !',mtWarning,[mbOK],0); //Disque dur
end;

{function GetVolumeNameForVolumeMountPointString(LetVol: Char): string;
var
Volume: array [0..MAX_PATH] of Char;
begin
if GetDriveType(PChar(Format('%s:/',[Uppercase(LetVol)])))=DRIVE_REMOVABLE then
begin
FillChar(Volume[0],SizeOf(Volume),0);
GetVolumeNameForVolumeMountPointW(PChar(Format('%s:/',[Uppercase(LetVol)])),@Volume[0],SizeOf(Volume));
Result:=Volume;
end;
end;}
//Partie informations peripherique
Procedure StorageDeviceNumberString(Disque:String);
var
HFile : THandle;
lpBytesReturned : DWORD;
StorageDeviceNumber : STORAGE_DEVICE_NUMBER;
begin
Drive.DeviceType:=0;
Drive.Partition:=0;
HFile:=INVALID_HANDLE_VALUE;
try
HFile:=CreateFile(PChar('//./'+Disque),0,FILE_SHARE_READ or FILE_SHARE_WRITE,nil,OPEN_EXISTING,0,0);
if HFile<>INVALID_HANDLE_VALUE then
begin
DeviceIoControl(HFile,IOCTL_STORAGE_GET_DEVICE_NUMBER,nil,0,@StorageDeviceNumber,SizeOf(StorageDeviceNumber),lpBytesReturned, nil);
Drive.DeviceType:=StorageDeviceNumber.DeviceType;
Drive.Partition:=StorageDeviceNumber.PartitionNumber;
end;
finally
CloseHandle(HFile);
end;
end;
{Procedure StorageMediaTypeString(Disque:String);
var
HFile : THandle;
lpBytesReturned : DWORD;
StorageMediaType : GET_MEDIA_TYPES;
MediaTypes : PGET_MEDIA_TYPES;
Buffer : Array[0..2047] of Byte;
Result : String;
begin
Result:='';
HFile:=INVALID_HANDLE_VALUE;
try
HFile:=CreateFile(PChar('//./'+Disque),0,FILE_SHARE_READ or FILE_SHARE_WRITE,nil,OPEN_EXISTING,0,0);
if HFile<>INVALID_HANDLE_VALUE then
begin
DeviceIoControl(HFile,IOCTL_STORAGE_GET_MEDIA_TYPES_EX,nil,0,@StorageMediaType,SizeOf(StorageMediaType),lpBytesReturned, nil);
if DeviceIoControl(HFile,IOCTL_STORAGE_GET_MEDIA_TYPES_EX,nil,0,@Buffer,SizeOf(Buffer),lpBytesReturned,nil) then
MediaTypes := PGET_MEDIA_TYPES(@Buffer);
Result:=IntTostr(MediaTypes.MediaInfo[0].DeviceSpecific.RemovableDiskInfo.MediaType);
end;
finally
CloseHandle(HFile);
end;
end;}
Procedure DeviceDescriptorString(Disque:String);
{type
PCharArray = ^TCharArray;
TCharArray = Array[0..MAX_PATH] of Char;}
var
HFile : THandle;
PropQuery : STORAGE_PROPERTY_QUERY;
DeviceDescriptor : STORAGE_DEVICE_DESCRIPTOR;
lpBytesReturned : DWORD;
I : Integer;
Value : Char;
PosValue : Integer;
// TestString : String;
// TestChar : PChar;
begin
Drive.Properties:='';
HFile:=INVALID_HANDLE_VALUE;
try
HFile:=CreateFile(PChar('//./'+Disque),0,FILE_SHARE_READ or FILE_SHARE_WRITE,nil,OPEN_EXISTING,0,0);
if HFile<>INVALID_HANDLE_VALUE then
begin
ZeroMemory(@PropQuery, SizeOf(PropQuery));
ZeroMemory(@DeviceDescriptor, SizeOf(DeviceDescriptor));
DeviceDescriptor.Size := SizeOf(DeviceDescriptor);
DeviceIoControl(HFile,IOCTL_STORAGE_QUERY_PROPERTY,@PropQuery,SizeOf(PropQuery),@DeviceDescriptor,DeviceDescriptor.Size,lpBytesReturned,nil);
{// vendorid
if DeviceDescriptor.VendorIdOffset<>0 then
begin
TestChar:=@PCharArray(@DeviceDescriptor)^[DeviceDescriptor.VendorIdOffset];
TestString:=Trim(TestChar);
TestString:= String(PChar(@DeviceDescriptor) + DeviceDescriptor.VendorIdOffset);
end;
// productid
if DeviceDescriptor.ProductIdOffset<>0 then
begin
TestChar:=@PCharArray(@DeviceDescriptor)^[DeviceDescriptor.ProductIdOffset];
TestString:=Trim(TestChar);
TestString:= String(PChar(@DeviceDescriptor) + DeviceDescriptor.ProductIdOffset);
end;
// product révision
if DeviceDescriptor.ProductRevisionOffset<>0 then
begin
TestChar:=@PCharArray(@DeviceDescriptor)^[DeviceDescriptor.ProductRevisionOffset];
TestString:=Trim(TestChar);
TestString:= String(PChar(@DeviceDescriptor) + DeviceDescriptor.ProductRevisionOffset);
end;}
Drive.Properties:='';
PosValue:=0;
for I := DeviceDescriptor.RawPropertiesLength-1 Downto 0 do
if DeviceDescriptor.RawDeviceProperties[i]=0 then
begin
PosValue:=I;
Break;
end;
Value:=#0;
for I:=PosValue to DeviceDescriptor.RawPropertiesLength-1 do
begin
case DeviceDescriptor.RawDeviceProperties[i] of
32..126: begin
if Drive.Properties<>'' then
Value:=Drive.Properties[Length(Drive.Properties)-1];
if (Value<>' ')or(DeviceDescriptor.RawDeviceProperties[i]<>32)then
Drive.Properties:=Drive.Properties+Chr(DeviceDescriptor.RawDeviceProperties[i]);
end;
end;
end;
end;
finally
CloseHandle(HFile);
end;
end;
function FormatTaille(Value: Extended): String;
var
i : Integer;
begin
i:=0;
while (Value>=1000) or (i=4) do
begin
Value:=Value / 1024;
Inc(i);
end;
case i of
0 : Result:=FloatToStrF(Value,ffFixed,18,2)+' octet(s)';
1 : Result:=FloatToStrF(Value,ffFixed,18,2)+' Ko';
2 : Result:=FloatToStrF(Value,ffFixed,18,2)+' Mo';
3 : Result:=FloatToStrF(Value,ffFixed,18,2)+' Go';
4 : Result:=FloatToStrF(Value,ffFixed,18,2)+' To';
end;
end;
Procedure InfoDevice(Disque:String);
var
Volume : THandle;
Returned : DWORD;
VolName : Array[0..MAX_PATH]Of Char;
FileSysName : Array[0..MAX_PATH]Of Char;
VolSerial : DWord;
FileMaxLen : DWord;
FileFlags : DWord;
FreeAvailable : Int64;
TotalSpace : Int64;
FreeAvailableString : String;
TotalSpaceString : String;
TempVolName : String;
begin
Drive.VolumeName:='';
Drive.TailleLib:='0 Go';
Drive.TailleTot:='0 Go';
Drive.SystFich:='';
if GetVolumeInformation(PChar(Disque+'/'),VolName,Max_Path,@VolSerial,FileMaxLen,FileFlags,FileSysName,MAX_PATH) then
begin
GetDiskFreeSpaceEx(PChar(Disque),FreeAvailable,TotalSpace,nil);
FreeAvailableString:=FormatTaille(FreeAvailable);
TotalSpaceString:=FormatTaille(TotalSpace);
if VolName<>'' then
TempVolName:=VolName
else
TempVolName:='';
Drive.VolumeName:=TempVolName;
Drive.SystFich:=FileSysName;
Drive.TailleLib:=FreeAvailableString;
Drive.TailleTot:=TotalSpaceString;
end
else
begin
TempVolName:='Lecteur Vide';
Volume := CreateFile(PChar('//./' + Disque + ':'),0,FILE_SHARE_READ or FILE_SHARE_WRITE,nil, OPEN_EXISTING, 0, 0);
try
if not DeviceIoControl(Volume, IOCTL_STORAGE_CHECK_VERIFY, nil, 0, nil, 0, Returned, nil) then
begin
Drive.VolumeName:=TempVolName;
Drive.SystFich:='';
Drive.TailleLib:='0 Go';
Drive.TailleTot:='0 Go';
end;
finally
CloseHandle(Volume);
end;
end;
end;
function HotPlugInfo(Disque:String):Boolean;
var
HFile : THandle;
GetMediaTypes : STORAGE_HOTPLUG_INFO;
PropQuery : STORAGE_PROPERTY_QUERY;
DeviceDescriptor : STORAGE_DEVICE_DESCRIPTOR;
lpBytesReturned : DWORD;
begin
Result:=False;
HFile:=INVALID_HANDLE_VALUE;
try
HFile:=CreateFile(PChar('//./'+Disque),0,FILE_SHARE_READ or FILE_SHARE_WRITE,nil,OPEN_EXISTING,0,0);
if HFile<>INVALID_HANDLE_VALUE then
begin
DeviceIoControl(HFile,IOCTL_STORAGE_GET_HOTPLUG_INFO,nil,0,@GetMediaTypes,sizeof(GetMediaTypes),lpBytesReturned,nil);
ZeroMemory(@PropQuery, SizeOf(PropQuery));
ZeroMemory(@DeviceDescriptor, SizeOf(DeviceDescriptor));
DeviceDescriptor.Size := SizeOf(DeviceDescriptor);
DeviceIoControl(HFile,IOCTL_STORAGE_QUERY_PROPERTY,@PropQuery,SizeOf(PropQuery),@DeviceDescriptor,DeviceDescriptor.Size,lpBytesReturned,nil);
if (DeviceDescriptor.BusType=BusTypeUsb)or(DeviceDescriptor.BusType=BusType1394)or(DeviceDescriptor.BusType=BusTypeAtapi)or
((GetMediaTypes.MediaRemovable)and(GetMediaTypes.MediaHotplug))or
(GetMediaTypes.DeviceHotplug)or(GetMediaTypes.MediaRemovable) then
Result:=True
else
Result:=False;
Drive.Volume:=Disque+'/';
Drive.MediaRemovable:=GetMediaTypes.MediaRemovable;
Drive.MediaHotplug:=GetMediaTypes.MediaHotplug;
Drive.DeviceHotplug:=GetMediaTypes.DeviceHotplug;
Drive.BusType:=DeviceDescriptor.BusType;
DeviceDescriptorString(Disque);
InfoDevice(Disque);
StorageDeviceNumberString(Disque);
end;
finally
CloseHandle(HFile);
end;
end;
Procedure Liste_USB(Lecteurs:TStrings;DriveRemovable,DriveFixed,DriveCDRom:Boolean);
var
Num : Integer;
Bits : set of 0..25;
Disque : String;
begin
Integer(Bits):=GetLogicalDrives;
for Num := 0 to 25 do
begin
if Num in Bits then
begin
Disque:=Char(Num+Ord('A'))+':';
case GetDriveType(PChar(Disque)) of
DRIVE_REMOVABLE : if DriveRemovable then
if HotPlugInfo(Disque) then
Lecteurs.Append(Drive.Volume+' '+Drive.Properties+' Lecteur Amovible'+' '+Drive.SystFich+' ( '+Drive.TailleLib+' / '+Drive.TailleTot+' ) '+Drive.VolumeName);
DRIVE_FIXED : if DriveFixed then
if HotPlugInfo(Disque) then
Lecteurs.Append(Drive.Volume+' '+Drive.Properties+' Disque Externe Amovible'+' '+Drive.SystFich+' ( '+Drive.TailleLib+' / '+Drive.TailleTot+' ) '+Drive.VolumeName)
else
Lecteurs.Append(Drive.Volume+' '+Drive.Properties+' Disque Dur'+' '+Drive.SystFich+' ( '+Drive.TailleLib+' / '+Drive.TailleTot+' ) '+Drive.VolumeName);
DRIVE_CDROM : if DriveCDRom then
if HotPlugInfo(Disque) then
Lecteurs.Append(Drive.Volume+' '+Drive.Properties+' Lecteur CDRom / DVDRom'+' '+Drive.SystFich+' ( '+Drive.TailleLib+' / '+Drive.TailleTot+' ) '+Drive.VolumeName);
end;
end;
end;
end;

function CM_Query_And_Remove_SubTreeW; external 'SetupApi.dll' name 'CM_Query_And_Remove_SubTreeW';
function CM_Query_And_Remove_SubTreeA; external 'SetupApi.dll' name 'CM_Query_And_Remove_SubTreeA';
function CM_Query_And_Remove_SubTree; external 'SetupApi.dll' name 'CM_Query_And_Remove_SubTree' + LettreFin;
function CM_Request_Device_EjectW; external 'SetupApi.dll' name 'CM_Request_Device_EjectW';
function CM_Request_Device_EjectA; external 'SetupApi.dll' name 'CM_Request_Device_EjectA';
function CM_Request_Device_Eject; external 'SetupApi.dll' name 'CM_Request_Device_Eject' + LettreFin;
function SetupDiGetClassDevsW; external 'SetupApi.dll' name 'SetupDiGetClassDevsW';
function SetupDiGetClassDevsA; external 'SetupApi.dll' name 'SetupDiGetClassDevsA';
function SetupDiGetClassDevs; external 'SetupApi.dll' name 'SetupDiGetClassDevs' + LettreFin;
function SetupDiGetDeviceInterfaceDetailW; external 'SetupApi.dll' name 'SetupDiGetDeviceInterfaceDetailW';
function SetupDiGetDeviceInterfaceDetailA; external 'SetupApi.dll' name 'SetupDiGetDeviceInterfaceDetailA';
function SetupDiGetDeviceInterfaceDetail; external 'SetupApi.dll' name 'SetupDiGetDeviceInterfaceDetail' + LettreFin;
end.