Hi Russel!
Thanks for the solution. I just needed to add the "unit" & "Interface" identifiers to your code and it compiled first time.
There was a glitch which I sorted out with a little debugging. However I don't think it was a fault as such in your solution so I am giving you full points.
I wrote a simple test program to iterate through drives "A" to "Z", call your IsUsbDrive() function & display a list of USB drives.
The program hung for about 20 seconds every time I ran it then an Exception error message dialog from Windows popped up. I could select continue and then the USB drive list was displayed.
I eventually traced it to your function and found that it hung on the CreateFile call:
CreateFile(PChar('\\.\' + DriveLetter + ':'), GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);
With more debugging I found this only happened with my B drive, which is an old LS120 drive (accepts stiffy discs or 120 MB LS120 discs).
I compared your call to the code I had posted in my question and noticed a difference. You had used GENERIC_READ for the access mode. The other code used 0 which = "Specifies device query access to the object. An application can query device attributes without accessing the device". I modified your code to use 0 and the problem went away. Do you think this would be a better value to use anyway?
CreateFile(PChar('\\.\' + DriveLetter + ':'), 0, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);
I don't know if the LS120 drive is actually the cause of the problem - but I'm happy! I had noticed recently that when I boot up - the drive gets accessed several times (sounds like the heads are moved) which never used to happen. So there might be a gltich with it.
Regards,
Mike
Main Topics
Browse All Topics





by: rllibbyPosted on 2009-02-10 at 08:26:57ID: 23602061
Only need to include windows with this. Checks bus type for Usb.
TY = $002D1400;
= ^STORAGE_DEVICE_DESCRIPTOR ;
\\.\' + DriveLetter + ':'), GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);
eDevicePro perty; yStandardQ uery; TY, @lpQuery, SizeOf(lpQuery), @lpDevDesc, SizeOf(lpDevDesc), dwBytesReturn, nil) then _BUS_TYPE = BusTypeUsb)
Regards,
Russell
----
uses
Windows;
const
IOCTL_STORAGE_QUERY_PROPER
//_STORAGE_PROPERTY_ID
const
StorageDeviceProperty = $00000000;
StorageAdapterProperty = $00000001;
StorageDeviceIdProperty = $00000002;
// _STORAGE_QUERY_TYPE
const
PropertyStandardQuery = $00000000;
PropertyExistsQuery = $00000001;
PropertyMaskQuery = $00000002;
// _STORAGE_BUS_TYPE
const
BusTypeUnknown = $00000000;
BusTypeScsi = $00000001;
BusTypeAtapi = $00000002;
BusTypeAta = $00000003;
BusType1394 = $00000004;
BusTypeSsa = $00000005;
BusTypeFibre = $00000006;
BusTypeUsb = $00000007;
BusTypeRAID = $00000008;
type
STORAGE_PROPERTY_QUERY = packed record
PropertyId: DWORD;
QueryType: DWORD;
AdditionalParameters: Array [0..3] of Byte;
end;
PSTORAGE_PROPERTY_ID = ^STORAGE_PROPERTY_QUERY;
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;
STORAGE_BUS_TYPE: DWORD;
RawPropertiesLength: ULONG;
RawDeviceProperties: Array [0..511] of Byte;
end;
PSTORAGE_DEVICE_DESCRIPTOR
function IsUsbDrive(DriveLetter: Char): Boolean;
implementation
function IsUsbDrive(DriveLetter: Char): Boolean;
var lpQuery: STORAGE_PROPERTY_QUERY;
lpDevDesc: STORAGE_DEVICE_DESCRIPTOR;
dwBytesReturn: DWORD;
hDrive: THandle;
begin
// Set default result
result:=False;
// Attempt to open a handle to the drive
hDrive:=CreateFile(PChar('
// Check handle
if (hDrive <> INVALID_HANDLE_VALUE) then
begin
// Resource protection
try
// Clear the structs
FillChar(lpQuery, SizeOf(lpQuery), 0);
FillChar(lpDevDesc, SizeOf(lpDevDesc), 0);
// Set query values
lpQuery.PropertyId:=Storag
lpQuery.QueryType:=Propert
// Call device IO function
if DeviceIoControl(hDrive, IOCTL_STORAGE_QUERY_PROPER
// Connected via USB?
result:=(lpDevDesc.STORAGE
else
// Failed to query
result:=False;
finally
// Close the handle
CloseHandle(hDrive);
end;
end;
end;