Delphi Pages Forums  

Go Back   Delphi Pages Forums > Delphi Forum > General

Lost Password?

Reply
 
Thread Tools Display Modes
  #1  
Old 06-06-2014, 11:00 AM
DavidB3 DavidB3 is offline
Senior Member
 
Join Date: Jul 2013
Posts: 119
Question detect and read from any drive attached/mounted on the computer

Hi.

I'm trying to detect and read from any drive attached/mounted on the computer (USB and nonUSB).
I'm using this:

Code:
constructor TComponentDrive.Create(AOwner: TComponent);
begin
   inherited Create(AOwner);
   FWindowHandle := Classes.AllocateHWnd(WndProc);
   DriveRegister;
end;

destructor TComponentDrive.Destroy;
begin
   UnregisterDeviceNotification(FHandle);
   Classes.DeallocateHWnd(FWindowHandle);
   inherited Destroy;
end;

procedure TComponentDrive.WndProc(var Msg: TMessage);
begin
   if Msg.Msg = WM_DEVICECHANGE then
   begin
      try
         WMDeviceChange(Msg);
      except
         Application.HandleException(Self);
      end;
   end
   else
      Msg.Result := DefWindowProc(FWindowHandle, Msg.Msg, Msg.wParam, Msg.lParam);
end;

procedure TComponentDrive.WMDeviceChange(var Msg: TMessage);
var
   i: Byte;
   j, k: Integer;
   Mask: DWORD;
   hVolume, hDrive: THandle;
   dwBytesReturned: DWORD;
   sdn: STORAGE_DEVICE_NUMBER;
   RawMBR: array[0..511] of Byte;
   btsIO: DWORD;
   DriveType: Byte;
   strTemp: AnsiString;
begin
   if (Msg.wParam = DBT_DEVICEARRIVAL) and
      (PDevBroadcastHdr(Msg.lParam)^.dbch_devicetype = DBT_DEVTYP_DEVICEINTERFACE) then
....

if (Msg.wParam = DBT_DEVICEARRIVAL) and
      (PDevBroadcastHdr(Msg.lParam)^.dbch_devicetype = DBT_DEVTYP_VOLUME) then
...
end;

procedure TComponentDrive.DriveRegister;
var
   dbi: DEV_BROADCAST_DEVICEINTERFACE;
   Size: Integer;
begin
   Size := SizeOf(DEV_BROADCAST_DEVICEINTERFACE);
   ZeroMemory(@dbi, Size);
   dbi.dbcc_size := Size;
   dbi.dbcc_devicetype := DBT_DEVTYP_DEVICEINTERFACE;
   dbi.dbcc_reserved := 0;
   dbi.dbcc_classguid := GUID_DEVINTERFACE_DISK;
   dbi.dbcc_name := 0;

   FHandle := RegisterDeviceNotification(FWindowHandle, @dbi, DEVICE_NOTIFY_WINDOW_HANDLE);
end;
First time the drive is connected a DBT_DEVTYP_DEVICEINTERFACE is sent, then after a 0.1..3 sec a DBT_DEVTYP_VOLUME.
If I try to read the drive between them it doesn't work so I usualy read it after DBT_DEVTYP_VOLUME.
But this works only if the drive has volume(s) to be mounted.
If it doesn't, I will have to wait some time after DBT_DEVTYP_DEVICEINTERFACE to read from it.
The problem is that I don't know how much I have to wait + I don't know in advance if the drive has mounting volume(s) or not (and a DBT_DEVTYP_VOLUME will be sent).
The time to wait should be as short as possible but to work on all computers/drives. So I can't set, let's say, 3 or 4 sec.

Is there a way to know the exact value?

Thank you.

Regards,
David
Reply With Quote
  #2  
Old 06-07-2014, 08:42 PM
kolbasz kolbasz is offline
Senior Member
 
Join Date: Nov 2013
Posts: 841
Default

You did not post the whole unit, but apparently you declared dbi.dbcc_name as integer or shortint:

Code:
   Size := SizeOf(DEV_BROADCAST_DEVICEINTERFACE);
   ZeroMemory(@dbi, Size);
   dbi.dbcc_size := Size;
   dbi.dbcc_devicetype := DBT_DEVTYP_DEVICEINTERFACE;
   dbi.dbcc_reserved := 0;
   dbi.dbcc_classguid := GUID_DEVINTERFACE_DISK;
   dbi.dbcc_name := 0; <-- this line
This is wrong because you can get precious information from dbcc_name.
You should declare the DEV_BROADCAST_DEVICEINTERFACE like this:
Code:
PDevBroadcastDeviceInterface = ^DEV_BROADCAST_DEVICEINTERFACE;
  DEV_BROADCAST_DEVICEINTERFACE= record
    dbcc_size:         DWORD;
    dbcc_devicetype:   DWORD;
    dbcc_reserved:     DWORD;
    dbcc_classguid:    TGUID;
    dbcc_name:         array[0..255] of Char;
  end;
When DBT_DEVTYP_DEVICEINTERFACE message arrives you can read the dbcc_name value. For example if I plug in my USB device, I get something like this:
\\?\USBSTOR#Disk&Ven_&Prod_silicon-power&Rev_0.00#19015202037244540037&0#{53f56307-b6bf-11d0-94f2-00a0c91efb8b}
Apparently it's garbage but along the vendor name we have a precious information, namely:
{53f56307-b6bf-11d0-94f2-00a0c91efb8b}
which is the GUID of the device interface class, in this case a Disk Device, so it should have a volume(at this point you know that a DBT_DEVTYP_VOLUME message will arrive soon.
You can find the a list with the device classes here:
\\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Cont rol\DeviceClasses
For example:
USB Raw Device --> {a5dcbf10-6530-11d2-901f-00c04fb951ed}
Network Card --> {ad498944-762f-11d0-8dcb-00c04fc3358c}
Disk Device --> {53f56307-b6bf-11d0-94f2-00a0c91efb8b}
//etc..
Reply With Quote
  #3  
Old 06-07-2014, 09:14 PM
DavidB3 DavidB3 is offline
Senior Member
 
Join Date: Jul 2013
Posts: 119
Default

I found this code on Google, in several locations, in all using shortint.

It helps a little, thank you. Btw, what should I put inside "dbi.dbcc_name" instead of 0 in DriveRegister procedure? Or the line of code isn't necessary anymore?

Entire code + compiled exe
Reply With Quote
  #4  
Old 06-07-2014, 09:36 PM
kolbasz kolbasz is offline
Senior Member
 
Join Date: Nov 2013
Posts: 841
Default

Quote:
It helps a little, thank you. Btw, what should I put inside "dbi.dbcc_name" instead of 0 in DriveRegister procedure? Or the line of code isn't necessary anymore?
Isn't necessary!
Reply With Quote
  #5  
Old 06-08-2014, 05:37 AM
DavidB3 DavidB3 is offline
Senior Member
 
Join Date: Jul 2013
Posts: 119
Default

I tried but that GUID is not helping.
It recieves the same GUID even if the drive does not have a "mountable" partition or if it has 2 or more.
That means the GUID is for the drive itself, not for the contained volumes.
So it doesn't help me know a DBT_DEVTYP_VOLUME message will arrive soon.

Thanks anyway.

Last edited by DavidB3; 06-08-2014 at 06:06 AM.
Reply With Quote
Reply

Tags
detect, drive

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is On

Forum Jump


All times are GMT. The time now is 04:14 PM.


Powered by vBulletin® Version 3.8.8
Copyright ©2000 - 2019, vBulletin Solutions, Inc.