Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

how can i find Partition/disk letter ?

Posted on 2003-10-21
20
Medium Priority
?
1,153 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 9
  • 5
  • 3
  • +1
20 Comments
 
LVL 2

Accepted Solution

by:
joepezt earned 400 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
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
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
 
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 28

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 28

Expert Comment

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

Expert Comment

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

Featured Post

Important Lessons on Recovering from Petya

In their most recent webinar, Skyport Systems explores ways to isolate and protect critical databases to keep the core of your company safe from harm.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
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 video, Percona Director of Solution Engineering Jon Tobin discusses the function and features of Percona Server for MongoDB. How Percona can help Percona can help you determine if Percona Server for MongoDB is the right solution for …
In a question here at Experts Exchange (https://www.experts-exchange.com/questions/29062564/Adobe-acrobat-reader-DC.html), a member asked how to create a signature in Adobe Acrobat Reader DC (the free Reader product, not the paid, full Acrobat produ…
Suggested Courses

618 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