954,529 Members — Technology Publication meets Social Media
Username:
Password:
Lost login information?
Have something to say? Contribute New Article Reply to this Article

detect that a drive is internal or connected to a USB port

How do I detect that a drive is internal or connected to a USB port?
For example I now the letter of a partition from that drive. If I use GetDriveType on one connected to USB it says that it is fixed not removable.
I found some code with witch you can get informations from registry when such a device is connected to the computer. But it doesn't help me if the device is already connected when the program starts.
It is doable because there are programs (like WinSetupFromUsb) which detects them correctly.

Thank you in advance for any help.

Petrica7
Light Poster
25 posts since Dec 2009
Reputation Points: 24
Solved Threads: 0
 

http://stackoverflow.com/questions/3390865/differentiating-between-usb-flash-drive-and-usb-hard-drive-on-windows

Looks like it is driver related and then it would be next to impossible to always get the correct result.

pritaeas
Posting Expert
Moderator
5,480 posts since Jul 2006
Reputation Points: 653
Solved Threads: 874
 

Oh, I already found how to do it:

type
   STORAGE_QUERY_TYPE = (PropertyStandardQuery = 0, PropertyExistsQuery, PropertyMaskQuery, PropertyQueryMaxDefined);
   TStorageQueryType = STORAGE_QUERY_TYPE;

   STORAGE_PROPERTY_ID = (StorageDeviceProperty = 0, StorageAdapterProperty);
   TStoragePropertyID = STORAGE_PROPERTY_ID;

   STORAGE_PROPERTY_QUERY = packed record
      PropertyId: STORAGE_PROPERTY_ID;
      QueryType: STORAGE_QUERY_TYPE;
      AdditionalParameters: array[0..9] of AnsiChar;
   end;
   TStoragePropertyQuery = STORAGE_PROPERTY_QUERY;

   STORAGE_BUS_TYPE = (BusTypeUnknown = 0, BusTypeScsi, BusTypeAtapi, BusTypeAta, BusType1394, BusTypeSsa, BusTypeFibre,
      BusTypeUsb, BusTypeRAID, BusTypeiScsi, BusTypeSas, BusTypeSata, BusTypeMaxReserved = $7F);
   TStorageBusType = STORAGE_BUS_TYPE;

   STORAGE_DEVICE_DESCRIPTOR = packed record
      Version: DWORD;
      Size: DWORD;
      DeviceType: Byte;
      DeviceTypeModifier: Byte;
      RemovableMedia: Boolean;
      CommandQueueing: Boolean;
      VendorIdOffset: DWORD;
      ProductIdOffset: DWORD;
      ProductRevisionOffset: DWORD;
      SerialNumberOffset: DWORD;
      BusType: STORAGE_BUS_TYPE;
      RawPropertiesLength: DWORD;
      RawDeviceProperties: array[0..0] of AnsiChar;
   end;
   TStorageDeviceDescriptor = STORAGE_DEVICE_DESCRIPTOR;

const
    IOCTL_STORAGE_QUERY_PROPERTY = $002D1400;

function IsOnUsb(Drive: AnsiChar): Boolean;
var
   H: THandle;
   Query: TStoragePropertyQuery;
   dwBytesReturned: DWORD;
   Buffer: array[0..1023] of Byte;
   sdd: TStorageDeviceDescriptor absolute Buffer;
   OldMode: UINT;
begin
   Result := False;

   OldMode := SetErrorMode(SEM_FAILCRITICALERRORS);
   try
      H := CreateFile(PChar(Format('\\.\%s:', [AnsiLowerCase(string(Drive))])), GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE, nil,
         OPEN_EXISTING, 0, 0);
      if H <> INVALID_HANDLE_VALUE then
      begin
         try
            dwBytesReturned := 0;
            FillChar(Query, SizeOf(Query), 0);
            FillChar(Buffer, SizeOf(Buffer), 0);
            sdd.Size := SizeOf(Buffer);
            Query.PropertyId := StorageDeviceProperty;
            Query.QueryType := PropertyStandardQuery;
            if DeviceIoControl(H, IOCTL_STORAGE_QUERY_PROPERTY, @Query, SizeOf(Query), @Buffer, SizeOf(Buffer), dwBytesReturned, nil) then
               Result := (sdd.BusType = BusTypeUsb){ and sdd.RemovableMedia};
         finally
            CloseHandle(H);
         end;
      end;
   finally
      SetErrorMode(OldMode);
   end;
end;


Sorry, I was very busy and I forgot to post it...

Petrica7
Light Poster
25 posts since Dec 2009
Reputation Points: 24
Solved Threads: 0
 

This article has been dead for over three months

Post: Markdown Syntax: Formatting Help
You