Recent

Author Topic: list Windows drive Letters (compile on Linux)  (Read 6710 times)

bjlockie1

  • New member
  • *
  • Posts: 8
list Windows drive Letters (compile on Linux)
« on: November 19, 2020, 10:39:50 pm »
I am writing a file manager type app on Linux that also needs to run on Windows.
It is ok on Linux but I don't account for drive letters on Windows.
Is there a way to list available drive letters (instead of hard coding A: to Z:)?

I am using ChDir, is that going to change the drive?

Leledumbo

  • Hero Member
  • *****
  • Posts: 8746
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: list Windows drive Letters (compile on Linux)
« Reply #1 on: November 19, 2020, 10:45:58 pm »
Guess you have to ifdef since drive letters is a Windows only concept. Windows API has GetLogicalDrives function that you can call, it will return a single LongWord / DWord value whose bits indicate whether the corresponding drive letter is assigned or not, i.e. bit 0 = drive A, bit 1 = drive B and so on.

Bart

  • Hero Member
  • *****
  • Posts: 5275
    • Bart en Mariska's Webstek
Re: list Windows drive Letters (compile on Linux)
« Reply #2 on: November 19, 2020, 10:47:07 pm »
Maybe take a look at TShellTreeView and see how the root node is populated?

Bart

Aidex

  • Jr. Member
  • **
  • Posts: 82
Re: list Windows drive Letters (compile on Linux)
« Reply #3 on: November 19, 2020, 10:57:56 pm »
And if it is of interest what type each drive is, I recommend Windows.GetDriveType()

https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getdrivetypea

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 1312
    • Lebeau Software
Re: list Windows drive Letters (compile on Linux)
« Reply #4 on: November 20, 2020, 06:08:58 pm »
Windows API has GetLogicalDrives function that you can call, it will return a single LongWord / DWord value whose bits indicate whether the corresponding drive letter is assigned or not

The API also has a GetLogicalDriveStrings() function, which returns each assigned drive letter in a '<letter>:\' string format, which can be passed as-is to any API that takes a drive root as input, including GetDriveType().
« Last Edit: November 20, 2020, 06:11:23 pm by Remy Lebeau »
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

Bart

  • Hero Member
  • *****
  • Posts: 5275
    • Bart en Mariska's Webstek
Re: list Windows drive Letters (compile on Linux)
« Reply #5 on: November 20, 2020, 06:22:35 pm »
From one of my units:
Code: Pascal  [Select][+][-]
  1. function DiskInDrive(Drive: Char): Boolean;
  2. var
  3.   ErrorMode: word;
  4. begin
  5.   { maak er een hoofdletter van }
  6.   Drive := UpCase(Drive);
  7.   if not (Drive in ['A'..'Z']) then
  8.     raise EConvertError.Create('Geen geldige stationsaanduiding: '+Drive+':');
  9.   { schakel kritieke fouten uit }
  10.   ErrorMode := SetErrorMode(SEM_FailCriticalErrors);
  11.   try
  12.     { drive 1 = a, 2 = b, 3 = c, etc. }
  13.     if DiskSize(Ord(Drive) - Ord('A') + 1) = -1 then
  14.       Result := False
  15.     else
  16.       Result := True;
  17.   finally
  18.     { restore old error mode }
  19.     SetErrorMode(ErrorMode);
  20.   end;
  21. end;
  22.  
  23. function GetAvailableDrives(DiskMustBeInDrive: Boolean = False): TSysCharSet;
  24. var
  25.   D, Mask: DWORD;
  26.   C: Char;
  27. begin
  28.   Result := [];
  29.   D := GetLogicalDrives;
  30.   for C := 'A' to 'Z' do
  31.   begin
  32.     Mask := (1 shl (Ord(C) - Ord('A')));
  33.     if (Mask and D) = Mask then
  34.     begin
  35.       if (not DiskMustBeInDrive) or DiskInDrive(C) then
  36.       Include(Result, C);
  37.     end;
  38.   end;
  39. end;
  40.  

And from a unit that imlements a DriveCombobox:

Code: Pascal  [Select][+][-]
  1. type
  2.  
  3.   TDriveType = (dtUnknown, dtNoRootDir, dtRemovable, dtFixed, dtRemote, dtCdrom, dtRamDisk);
  4.   TDriveTypes = set of TDriveType;
  5.  
  6. function GetDriveType(ADrive: Char): TDriveType;
  7. var
  8.   WinDriveType: UINT;
  9. begin
  10.   WinDriveType := Windows.GetDriveType(PChar(LowerCase(ADrive+':\')));
  11.   case WinDriveType of
  12.     DRIVE_UNKNOWN: Result := dtUnknown;
  13.     DRIVE_NO_ROOT_DIR: Result := dtNoRootDir;
  14.     DRIVE_REMOVABLE: Result := dtRemovable;
  15.     DRIVE_FIXED: Result := dtFixed;
  16.     DRIVE_REMOTE: Result := dtRemote;
  17.     DRIVE_CDROM: Result := dtCdrom;
  18.     DRIVE_RAMDISK: Result := dtRamDisk;
  19.     else Result := dtUnknown;
  20.   end; //case
  21. end;
  22. //refreshs the drive list
  23. //FMountedDrivesOnly: if True then disk must be in drive
  24. //DriveTypes: a set of drivetypes you want in the list, so you can e.g. filter for only removable drives
  25.  
  26. procedure TFSICustomDriveComboBox.RefreshDriveList;
  27. var
  28.   C: Char;
  29.   ADriveType: TDriveType;
  30. begin
  31.   if (csDesigning in ComponentState) then
  32.     Exit;
  33.   Items.Clear;
  34.   for C in GetAvailableDrives(FMountedDrivesOnly) do
  35.   begin
  36.     ADriveType := GetDriveType(C);
  37.     if ADriveType in DriveTypes then
  38.       Items.Add(C + ':\');
  39.   end;
  40.   if FSelectFirstDriveOnRefreshDriveList and (not DroppedDown) and (Items.Count > -1) then
  41.     ItemIndex := 0;
  42. end;
  43.  

Bart

Sieben

  • Sr. Member
  • ****
  • Posts: 310
Re: list Windows drive Letters (compile on Linux)
« Reply #6 on: November 20, 2020, 06:48:24 pm »
Code: Pascal  [Select][+][-]
  1. ... and (Items.Count > -1)

?
Lazarus 2.2.0, FPC 3.2.2, .deb install on Ubuntu Xenial 32 / Gtk2 / Unity7

Bart

  • Hero Member
  • *****
  • Posts: 5275
    • Bart en Mariska's Webstek
Re: list Windows drive Letters (compile on Linux)
« Reply #7 on: November 20, 2020, 07:19:21 pm »
Code: Pascal  [Select][+][-]
  1. ... and (Items.Count > -1)

?

Oops, must be > 0 of course.
Must have been confused with ItemIndex. Count of course can never be < 0.

Thanks.
Fixed in trunk.

Files reside here: https://svn.code.sf.net/p/flyingsheep/code/trunk/MijnLib
Units fsiwinutils and fsiwincontrols.

Bart
« Last Edit: November 20, 2020, 07:25:18 pm by Bart »

Sieben

  • Sr. Member
  • ****
  • Posts: 310
Re: list Windows drive Letters (compile on Linux)
« Reply #8 on: November 20, 2020, 08:06:17 pm »
Thanks for sharing. And Flying Sheep is one of my absolute favourites as well...  :)
« Last Edit: November 20, 2020, 08:11:42 pm by Sieben »
Lazarus 2.2.0, FPC 3.2.2, .deb install on Ubuntu Xenial 32 / Gtk2 / Unity7

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 1312
    • Lebeau Software
Re: list Windows drive Letters (compile on Linux)
« Reply #9 on: November 20, 2020, 09:17:25 pm »
Code: Pascal  [Select][+][-]
  1. ErrorMode := SetErrorMode(SEM_FailCriticalErrors);

Just to point out that SetErrorMode() is global to the whole process and changing its mode introduces a race condition in multi-threaded code.  You really should be using SetThreadErrorMode() instead.
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

bjlockie1

  • New member
  • *
  • Posts: 8
Re: list Windows drive Letters (compile on Linux)
« Reply #10 on: November 20, 2020, 10:15:44 pm »
Guess you have to ifdef since drive letters is a Windows only concept. Windows API has GetLogicalDrives function that you can call, it will return a single LongWord / DWord value whose bits indicate whether the corresponding drive letter is assigned or not, i.e. bit 0 = drive A, bit 1 = drive B and so on.

Thanks.
I have it compiling but it can't ChDir to drive D:\
C:\ and Z:\ work fine.

I'm going to post in the Windows forum.
I could wrap it in a try but I don't think drive D: should be listed.

lucamar

  • Hero Member
  • *****
  • Posts: 4219
Re: list Windows drive Letters (compile on Linux)
« Reply #11 on: November 21, 2020, 12:33:23 am »
I have it compiling but it can't ChDir to drive D:\
C:\ and Z:\ work fine.

That might be normal if drive D: is a CD-ROM but there is no CD in it, or a card-reader without card (or an unmounted card), or similar.
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.12/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

winni

  • Hero Member
  • *****
  • Posts: 3197
Re: list Windows drive Letters (compile on Linux)
« Reply #12 on: November 21, 2020, 12:39:25 am »
I have it compiling but it can't ChDir to drive D:\
C:\ and Z:\ work fine.

That might be normal if drive D: is a CD-ROM but there is no CD in it, or a card-reader without card (or an unmounted card), or similar.

Or D: is a Linux partition
Or D: is a not formatted partition
Or on D:  the filesystem is broken - Windows gives up very quick
Or D: is an external drive and you pulled the plug
Or or or ...

Winni

lucamar

  • Hero Member
  • *****
  • Posts: 4219
Re: list Windows drive Letters (compile on Linux)
« Reply #13 on: November 21, 2020, 12:57:42 am »
Or D: is a Linux partition
Or D: is a not formatted partition
...
Or D: is an external drive and you pulled the plug

In none of those cases (except maybe the "broken FS" one) do my Windows machines ever bother to assign a letter.

The general case I was thinking about is a removable-media drive which gets a letter assigned but fails if no media is loaded, like a CD/DVD drive or a card-reader; in that case and unless you have auto-run set on Windows frequently doesn't bother to ascertain whether there is any media at all until you try to access it (which caused me endless headaches with a 7-slot flash card reader: one never knew which letter Window assigned to each slot so I had to try all 7 until one deigned to respond  %)).

But I left Windows (except punctually 2K, XP, 7 and 10) on Vista times so I might be missing something :-[
« Last Edit: November 21, 2020, 12:59:58 am by lucamar »
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.12/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

winni

  • Hero Member
  • *****
  • Posts: 3197
Re: list Windows drive Letters (compile on Linux)
« Reply #14 on: November 21, 2020, 02:03:03 am »

In none of those cases (except maybe the "broken FS" one) do my Windows machines ever bother to assign a letter.


Hey,hey, hey - you lucky boy!

* Win7 asked me often, if it should format my Linux Partition !!! Somewhere in the Win-Jungle I disabled the partition.
Too long ago, don't know, where it was exactly.
* If you just pull the plug of an external drive and you don't inform the OS to "eject" it, you got a valid  drive letter - until you try the first time to read or write from/to that drive.
* If a network drive (Samba) does not react, but it was alive at boot times, Win is really insistent. It retries in an endless loop to reconnect. It shows a drive letter and the hourglass but not the directory. Until the end of all days. Or a reboot.

And so on.

Winni




 

TinyPortal © 2005-2018