How to display letters from removable disk drives in Delphi?

Asked

Viewed 755 times

3

Hello, I need to have a "Combobox" display the letter of the volumes of the pen drives that may eventually be connected to the computer, how can I do this?

  • Explain what you mean by this!

  • 1

    Pascal, could you show what you’ve done with code? What do you have ready? What limitations do you have?

  • Limitation is what I have the most, I’m starting now, the question is only this, is to display the name of connected units, only this.

  • In a quick search on google found this

  • 1

    @Caiofelipepereira pq does not put as an answer quoting the source?

Show 1 more comment

2 answers

2

According to this discussion in the gringo OS, and following @Math’s suggestion, the code below should solve your problem:

{$MINENUMSIZE 4}
const
  IOCTL_STORAGE_QUERY_PROPERTY =  $002D1400;

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;

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

  OldMode := SetErrorMode(SEM_FAILCRITICALERRORS);
  try
    H := CreateFile(PChar(Format('\\.\%s:', [AnsiLowerCase(Drive)])), 0, 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;
      finally
        CloseHandle(H);
      end;
    end;
  finally
    SetErrorMode(OldMode);
  end;
end;


procedure GetUsbDrives(List: TStrings);
var
  DriveBits: set of 0..25;
  I: Integer;
  Drive: AnsiChar;
begin
  List.BeginUpdate;
  try
    Cardinal(DriveBits) := GetLogicalDrives;

    for I := 0 to 25 do
      if I in DriveBits then
      begin
        Drive := Chr(Ord('a') + I);
        if GetBusType(Drive) = BusTypeUsb then
          List.Add(Drive);
      end;
  finally
    List.EndUpdate;
  end;
end;
  • Is giving error in this last line Drive := Chr('Ord') + I);

2


this can help you, it adds in a list all the drives you need.

uses ... FileCtrl, Vcl.StdCtrls

function ListaDrives : TStringList; 
var 
  Lista : TStringList; 
  DriveNum : Integer; 
  LetraDrive : Char; 
  DriveBits : set of 0..25; 
  TipoDrive : TDriveType; 
begin 
  Lista := TStringList.Create; 
  Integer (DriveBits) := GetLogicalDrives; 
  for DriveNum := 0 to 25 do 
    begin 
      if not (DriveNum in DriveBits) then 
        Continue; 
      LetraDrive := UpCase (Char (DriveNum + ord ('a'))); 
      TipoDrive := TDriveType (GetDriveType (PChar (LetraDrive + ':')));

      case TipoDrive of 
        dtFloppy : Lista.Add ('Drive ' + LetraDrive + ': - Disco
flexível'); 
        dtFixed  : Lista.Add ('Drive ' + LetraDrive + ': - Disco
rígido'); 
        dtCDROM  : Lista.Add ('Drive ' + LetraDrive + ': - CD-ROM'); 
        dtRAM    : Lista.Add ('Drive ' + LetraDrive + ': - RAM Disk'); 
        dtNetwork: Lista.Add ('Drive ' + LetraDrive + ': - Drive de
rede'); 
      end; 
    end; 
  Result := Lista; 
end; 
  • 1

    Guy really liked it, there’s only one problem, I have no idea how to make this function display the volumes in Combobox, or any other component.

  • The return of this function is a Tstringlist, the Voce combobox can add item by item, within a for receive the position i of the return string list of the function =)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.