Solved

how can i find Partition/disk letter ?

Posted on 2003-10-21
20
1,139 Views
Last Modified: 2008-09-29
ex : i want know harddisk drive letter(ex : C:,D:) or its partition's drive letters using its windows device name like  "\\.\PHYSICALDRIVE1".  And i don't know how partitions are naming by windows. is it like "\\.\PHYSICALDRIVE1\PARTITION1" ?
0
Comment
Question by:undefinity
  • 9
  • 5
  • 3
  • +1
20 Comments
 
LVL 2

Accepted Solution

by:
joepezt earned 200 total points
ID: 9594490
try this

function DriveType(DriveLetter: string): TDriveType;
var
  x,
  DrvType   : Integer;
  DrvLetter,
  DrvString : String;
begin

    result := dtUnknown;
    DriveLetter := DriveLetter + ':\';

    // get the drive type
    DrvType := GetDriveType(pChar(DriveLetter));

    // set our drive type string accordingly
    case DrvType of
      0                 : result := dtUnknown;
      1                 : result := dtDoesNotExist;
      DRIVE_REMOVABLE  : result := dtRemovable;
      DRIVE_FIXED : result := dtFixed;
      DRIVE_REMOTE : result := dtNetwork;
      DRIVE_CDROM : result := dtCDROM;
      DRIVE_RAMDISK : result := dtRAMDisk;
    end;


end;
0
 
LVL 2

Expert Comment

by:joepezt
ID: 9594504
sorry..
here is it all

type TDriveType = (dtUnknown, dtDoesNotExist, dtRemovable, dtFixed,
dtNetwork, dtCDROM, dtRAMDisk);

type TDriveInfo = record
   DriveLetter: string;
   DriveType: TDriveType;
   TypeDescrip: string;
   DriveSize: single;  //size in Kilobytes
   DriveFreeSpace: single; //free space in Kilobytes
end;

type TDriveInfoArray = array of TDriveInfo;


//pass a single character string as the 'DriveLetter' param
function DriveType(DriveLetter: string): TDriveType;
var
  x,
  DrvType   : Integer;
  DrvLetter,
  DrvString : String;
begin

    result := dtUnknown;
    DriveLetter := DriveLetter + ':\';

    // get the drive type
    DrvType := GetDriveType(pChar(DriveLetter));

    // set our drive type string accordingly
    case DrvType of
      0                 : result := dtUnknown;
      1                 : result := dtDoesNotExist;
      DRIVE_REMOVABLE  : result := dtRemovable;
      DRIVE_FIXED : result := dtFixed;
      DRIVE_REMOTE : result := dtNetwork;
      DRIVE_CDROM : result := dtCDROM;
      DRIVE_RAMDISK : result := dtRAMDisk;
    end;


end;


//returns a listing of all drives and types on the system
procedure GetAllDriveTypes(var DriveInfoArray: TDriveInfoArray);
var
  x: integer;

begin

DriveInfoArray := nil;
SetLength(DriveInfoArray, 0);

//25 possible drives ... a-z
for x := Ord('A') to Ord('Z') do
begin
   if not ( DriveType(Chr(x)) = dtDoesNotExist) then
   begin
      SetLength(DriveInfoArray, Length(DriveInfoArray) + 1);
      DriveInfoArray[Length(DriveInfoArray) - 1].DriveLetter := Chr(x);
      DriveInfoArray[Length(DriveInfoArray) - 1].DriveType :=
DriveType(Chr(x));
      DriveInfoArray[Length(DriveInfoArray) - 1].TypeDescrip :=
DriveTypeToString(DriveInfoArray[Length(DriveInfoArray) - 1].DriveType);
      DriveInfoArray[Length(DriveInfoArray) - 1].DriveSize := DiskSize(x -
64) / 1024;  //size in KB
      DriveInfoArray[Length(DriveInfoArray) - 1].DriveFreeSpace :=
DiskFree(x - 64) / 1024;  //size in KB
   end;


end;


end;


function DriveTypeToString(DriveType: TDriveType): string;
begin

case DriveType of
   dtUnknown: result := 'Unknown Drive Type';
   dtDoesNotExist: result := 'Drive Does Not Exist';
   dtRemovable: result := 'Removable Drive';
   dtFixed: result := 'Fixed Drive';
   dtNetwork: result := 'Network Drive';
   dtCDROM: result := 'CD-ROM Drive';
   dtRAMDisk: result := 'RAM Disk Drive';

end;

end;



//Returns true if the drive is ready (useful for removable drives)
function DriveReady(DriveLetter: string): boolean;
var
  code: Integer;
  rec: TSearchRec;
  EMode: Word;

begin

 EMode := SetErrorMode(SEM_FAILCRITICALERRORS);

 DriveLetter := AnsiLowerCase(DriveLetter);

 //FYI,  ord('a') = 97

 try
   result := (DiskSize( Ord(DriveLetter[1]) - 96 ) <> -1)
  finally
   SetErrorMode(EMode);
 end;




end;

0
 
LVL 2

Expert Comment

by:joepezt
ID: 9594541
another example

procedure Tform1.GetCDInformation;
var
  DriveInfo   : integer;
  Letter      : integer;
  DriveID     : shortstring;
  DriveChar   : Char;
  DriveLetter : string;
  begin
  Application.ProcessMessages;
  Letter := 64;
  Repeat
    Inc(Letter);
    DriveChar := Chr(Letter);
    DriveLetter := DriveChar+':\';
    DriveInfo := GetDriveType(Pchar(DriveLetter));
    Application.ProcessMessages;
  Until DriveInfo = DRIVE_CDROM;

  // DriveLetter is the CD-ROM
end;
0
 
LVL 2

Expert Comment

by:joepezt
ID: 9594569
procedure TForm1.Button1Click(Sender: TObject);
var
  i : Integer;
begin
  OpenDialog1.Execute;
  i := GetDriveType(pchar(OpenDialog1.FileName));
  case i of
    DRIVE_REMOVABLE: // floppy... iomega.. etc etc
    DRIVE_CDROM: // cdrom
    DRIVE_FIXED: //fixed disk
  end;
end;
0
 

Author Comment

by:undefinity
ID: 9594891
thanx but i don't want this.
i want that i give device name like "\\.\PHYSICALDRIVE1" to program and then program gives me it's letter. And i want to how paritions naming in windows.
0
 
LVL 2

Expert Comment

by:joepezt
ID: 9595372
you can use these functions to achieve this
you just name them whatever you need.

where you have seen \\.\physicaldrive1 I don't know, it is probably done the same way like this. just naming it like \\.\physicaldrive.. etc etc
0
 

Author Comment

by:undefinity
ID: 9599854
i saw it in delphi project that we can acces linux files with.
0
 
LVL 2

Expert Comment

by:joepezt
ID: 9600118
tell again what you are looking for.. exactly
0
 

Author Comment

by:undefinity
ID: 9602581
i am trying to make a program which give me list of disks and disks' partitions(any type) in my computer like partition magic. And i want to know which partitions have a which letter.
0
Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 
LVL 2

Expert Comment

by:joepezt
ID: 9602880
try this component

save as uidedriveinfo.pas under delphi lib folder
component -> install component -> recompiler and install

maybe this will work



unit uIdeDriveInfo;

interface

 uses
   Windows,
   SysUtils,
   Classes;

 const
   DFP_GET_VERSION        = $00074080;
   DFP_SEND_DRIVE_COMMAND = $0007C084;
   DFP_RECEIVE_DRIVE_DATA = $0007C088;
   IDE_IDENTIFY_DEVICE    = $EC;

 type
   {$Z1}
   TDevices = (dmIdePrimary0, dmIdePrimary1, dmIdeSecondary0,
     dmIdeSecondary1, dmAtapiPrimary0, dmAtapiPrimary1,
     dmAtapiSecondary0, dmAtapiSecondary1);

   TDeviceMap = set of TDevices;

   TCapability = (cpIdeIdentify, cpAtapiIdentify, cpSmart,
     cpReserved03, cpReserved04, cpReserved05, cpReserved06,
     cpReserved07, cpReserved08, cpReserved09, cpReserved10,
     cpReserved11, cpReserved12, cpReserved13, cpReserved14,
     cpReserved15, cpReserved16, cpReserved17, cpReserved18,
     cpReserved19, cpReserved20, cpReserved21, cpReserved22,
     cpReserved23, cpReserved24, cpReserved25, cpReserved26,
     cpReserved27, cpReserved28, cpReserved29, cpReserved30,
     cpReserved31);

   TCapabilities = set of TCapability;

   PGetVersionOutParams = ^TGetVersionOutParams;
   TGetVersionOutParams = packed record
     Version: Byte;
     Revision: Byte;
     Reserved1: Byte;
     IdeDeviceMap: TDeviceMap;
     Capabilities: TCapabilities;
     Reserved2: array[0..3] of DWord end;

   PIdeRegs = ^TIdeRegs;
   TIdeRegs = packed record
     FeaturesReg: Byte;
     SectorCount: Byte;
     SectorNumber: Byte;
     CylLow: Byte;
     CylHigh: Byte;
     DriveHead: Byte;
     Command: Byte;
     Reserved: Byte end;

   PSendCmdInParams = ^TSendCmdInParams;
   TSendCmdInParams = packed record
     BufferSize: DWord;
     DriveRegs: TIdeRegs;
     DriveNumber: Byte;
     Reserved1: array[1..3] of Byte;
     Reserved2: array[0..3] of DWord end;

   PDriverStatus = ^TDriverStatus;
   TDriverStatus = packed record
     DriverError: Byte;
     IdeStatus: Byte;
     Reserved1: array[2..3] of Byte;
     Reserved2: array[0..1] of DWord end;

   PSendCmdOutParams = ^TSendCmdOutParams;
   TSendCmdOutParams = packed record
     BufferSize: DWord;
     DriverStatus: TDriverStatus;
     Buffer: array[0..255] of Word end;

 const
   DriveNumberMin = 0;
   DriveNumberMax = 3;

 type
   TDriveNumber = DriveNumberMin..DriveNumberMax;

   TIdeDriveInfo = class(TComponent)
     private
       FCylinders: array[TDriveNumber] of Integer;
       FFirmwareRevision: array[TDriveNumber] of String;
       FHeads: array[TDriveNumber] of Integer;
       FModelNumber: array[TDriveNumber] of String;
       FRemovableMedia: array[TDriveNumber] of Boolean;
       FSectorsPerTrack: array[TDriveNumber] of Integer;
       FSerialNumber: array[TDriveNumber] of String;
     protected
       procedure CheckDriveNumber(Drive: TDriveNumber); virtual;
       function GetCylinders(Drive: TDriveNumber): Integer; virtual;
       function GetFirmwareRevision(Drive: TDriveNumber): String;
         virtual;
       function GetHeads(Drive: TDriveNumber): Integer; virtual;
       function GetModelNumber(Drive: TDriveNumber): String; virtual;
       function GetRemovableMedia(Drive: TDriveNumber): Boolean;
         virtual;
       function GetSectorsPerTrack(Drive: TDriveNumber): Integer;
         virtual;
       function GetSerialNumber(Drive: TDriveNumber): String; virtual;
       procedure QueryDrive(Drive: TDriveNumber); virtual;
     public
       constructor Create(AOwner: TComponent); override;
       property Cylinders[Drive: TDriveNumber]: Integer
         read GetCylinders;
       property FirmwareRevision[Drive: TDriveNumber]: String
         read GetFirmwareRevision;
       property Heads[Drive: TDriveNumber]: Integer read GetHeads;
       property ModelNumber[Drive: TDriveNumber]: String
         read GetModelNumber;
       property RemovableMedia[Drive: TDriveNumber]: Boolean
         read GetRemovableMedia;
       property SectorsPerTrack[Drive: TDriveNumber]: Integer
         read GetSectorsPerTrack;
       property SerialNumber[Drive: TDriveNumber]: String
         read GetSerialNumber; end;

   EIdeDriveInfo = class(Exception);

 procedure Register;

 implementation

 procedure Register;
   begin
   RegisterComponents('Samples', [TIdeDriveInfo]) end;

 constructor TIdeDriveInfo.Create(AOwner: TComponent);
   var
     I: TDriveNumber;
   begin
   inherited Create(AOwner);
   for I := DriveNumberMin to DriveNumberMax do
     QueryDrive(I) end;

 procedure TIdeDriveInfo.CheckDriveNumber(Drive: TDriveNumber);
   begin
   if (Drive < DriveNumberMin) or (Drive > DriveNumberMax) then
     raise EIdeDriveInfo.CreateFmt('The drive number (%d) is out ' +
       'of range; the allowable range is %d to %d',
       [Drive, DriveNumberMin, DriveNumberMax]) end;

 function TIdeDriveInfo.GetCylinders(Drive: TDriveNumber): Integer;
   begin
   CheckDriveNumber(Drive);
   Result := FCylinders[Drive] end;

 function TIdeDriveInfo.GetFirmwareRevision(Drive: TDriveNumber):
   String;
   begin
   CheckDriveNumber(Drive);
   Result := FFirmwareRevision[Drive] end;

 function TIdeDriveInfo.GetHeads(Drive: TDriveNumber): Integer;
   begin
   CheckDriveNumber(Drive);
   Result := FHeads[Drive] end;

 function TIdeDriveInfo.GetModelNumber(Drive: TDriveNumber): String;
   begin
   CheckDriveNumber(Drive);
   Result := FModelNumber[Drive] end;

 function TIdeDriveInfo.GetRemovableMedia(Drive: TDriveNumber):
   Boolean;
   begin
   CheckDriveNumber(Drive);
   Result := FRemovableMedia[Drive] end;

 function TIdeDriveInfo.GetSectorsPerTrack(Drive: TDriveNumber):
   Integer;
   begin
   CheckDriveNumber(Drive);
   Result := FSectorsPerTrack[Drive] end;

 function TIdeDriveInfo.GetSerialNumber(Drive: TDriveNumber): String;
   begin
   CheckDriveNumber(Drive);
   Result := FSerialNumber[Drive] end;

 procedure TIdeDriveInfo.QueryDrive(Drive: TDriveNumber);
   var
     BytesReturned: DWord;
     CmdIn: TSendCmdInParams;
     CmdOut: TSendCmdOutParams;
     DriveName: String;
     H: THandle;
     I: Integer;
     VersionInfo: TGetVersionOutParams;
   begin
   FCylinders[Drive] := 0;
   FFirmwareRevision[Drive] := '';
   FHeads[Drive] := 0;
   FModelNumber[Drive] := '';
   FRemovableMedia[Drive] := False;
   FSectorsPerTrack[Drive] := 0;
   FSerialNumber[Drive] := '';
   DriveName := Format('\\.\PHYSICALDRIVE%d', [Drive]);
   H := CreateFile(PChar(DriveName), GENERIC_READ or GENERIC_WRITE, 0,
     nil, OPEN_EXISTING, 0, 0);
   if H = INVALID_HANDLE_VALUE then
     Exit;
   try
     FillChar(VersionInfo, SizeOf(VersionInfo), 0);
     BytesReturned := 0;
     if not DeviceIoControl(H, DFP_GET_VERSION, nil, 0, @VersionInfo,
       SizeOf(VersionInfo), BytesReturned, nil) then
       Exit;
     if not (cpIdeIdentify in VersionInfo.Capabilities) then
       Exit;
     FillChar(CmdIn, SizeOf(CmdIn), 0);
     CmdIn.BufferSize := 0;
     CmdIn.DriveRegs.Command := IDE_IDENTIFY_DEVICE;
     CmdIn.DriveNumber := Drive;
     FillChar(CmdOut, SizeOf(CmdOut), 0);
     CmdOut.BufferSize := SizeOf(CmdOut.Buffer);
     BytesReturned := 0;
     if not DeviceIoControl(H, DFP_RECEIVE_DRIVE_DATA, @CmdIn,
       SizeOf(CmdIn), @CmdOut, SizeOf(CmdOut), BytesReturned,
       nil) then
       Exit;
     with CmdOut do begin
       for I := 10 to 19 do
         Buffer[I] := (Lo(Buffer[I]) shl 8) + Hi(Buffer[I]);
       for I := 23 to 46 do
         Buffer[I] := (Lo(Buffer[I]) shl 8) + Hi(Buffer[I]);
       FRemovableMedia[Drive] := (Buffer[0] and $80) <> 0;
       FCylinders[Drive] := Buffer[1];
       FHeads[Drive] := Buffer[3];
       FSectorsPerTrack[Drive] := Buffer[6];
       SetLength(FSerialNumber[Drive], 20);
       Move(Buffer[10], FSerialNumber[Drive][1],
         Length(FSerialNumber[Drive]));
       FSerialNumber[Drive] := Trim(FSerialNumber[Drive]);
       SetLength(FFirmwareRevision[Drive], 8);
       Move(Buffer[23], FFirmwareRevision[Drive][1],
         Length(FFirmwareRevision[Drive]));
       FFirmwareRevision[Drive] := Trim(FFirmwareRevision[Drive]);
       SetLength(FModelNumber[Drive], 40);
       Move(Buffer[27], FModelNumber[Drive][1],
         Length(FModelNumber[Drive]));
       FModelNumber[Drive] := Trim(FModelNumber[Drive]) end;
     finally
       CloseHandle(H) end end;

 end.

0
 

Author Comment

by:undefinity
ID: 9606867
This component gives only drive geomery and serial number. i must increase points :)
0
 
LVL 2

Expert Comment

by:joepezt
ID: 9607153
hehe :)
0
 
LVL 2

Expert Comment

by:joepezt
ID: 9607171
I will try to find another one later today
0
 

Expert Comment

by:BLayman
ID: 13327631
If anyone does come up with the answer to this, I would appreciate it...  Another way to do this would be to get the Drive (NOT VOLUME) serial number via the drive letter and compare that with the Serial numbers returnd by the controller.

If I find the answer I'll return here with a result.
0
 
LVL 27

Expert Comment

by:Ark
ID: 13533120
Hi
Sorry, I don't speak Delphy, my native language is VB and second one is C++ :)
Here is how I did this:
1. Get HDD signature, using DeviceIoControl on \\.\PHYSICALDRIVE_X with IOCTL_DISK_GET_DRIVE_LAYOUT
2. Loop through HKEY_LOCAL_MACHINE\SYSTEM\MountedDevices\DosDevices\XXX values - first 4 bytes are drive signature, next 8 bytes - volume offset. So, select all devices with signature == your \\.\PHYSICALDRIVE_X and compare offsets - lowest offset will be VOLUME1, next - VOLUME2 etc.

0
 

Author Comment

by:undefinity
ID: 13534912
Thanks ARK and others...
0
 

Expert Comment

by:BLayman
ID: 13534958
Yes that is excellent info.  I'll supply my full Delphi code shortly.  I have lots of info to add but had not found a 100% accurate method till now.  It sounds like  ARK has provided one.
0
 
LVL 27

Expert Comment

by:Ark
ID: 13541597
I can provide ether VB or C++ code if you need...
0
 
LVL 27

Expert Comment

by:Ark
ID: 13584209
Another way is using QueryDosDevice
0

Featured Post

Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

Join & Write a Comment

Suggested Solutions

Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…
This video gives you a great overview about bandwidth monitoring with SNMP and WMI with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're looking for how to monitor bandwidth using netflow or packet s…

708 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now