list Windows drive Letters (compile on Linux) lazarus / 66-Unix ---------------------------------------------------------------------- bjlockie1 · 2020-11-19 21:39 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 · 2020-11-19 21:45 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 · 2020-11-19 21:47 Maybe take a look at TShellTreeView and see how the root node is populated? Bart ---------------------------------------------------------------------- Aidex · 2020-11-19 21:57 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 · 2020-11-20 17:08 Quote from: Leledumbo on November 19, 2020, 10:45:58 pmWindows 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 ':\' string format, which can be passed as-is to any API that takes a drive root as input, including GetDriveType(). ---------------------------------------------------------------------- Bart · 2020-11-20 17:22 From one of my units: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i function DiskInDrive(Drive: Char): Boolean;var  ErrorMode: word;begin  { maak er een hoofdletter van }  Drive := UpCase(Drive);  if not (Drive in ['A'..'Z']) then    raise EConvertError.Create('Geen geldige stationsaanduiding: '+Drive+':');  { schakel kritieke fouten uit }  ErrorMode := SetErrorMode(SEM_FailCriticalErrors);  try    { drive 1 = a, 2 = b, 3 = c, etc. }    if DiskSize(Ord(Drive) - Ord('A') + 1) = -1 then      Result := False    else      Result := True;  finally    { restore old error mode }    SetErrorMode(ErrorMode);  end;end; function GetAvailableDrives(DiskMustBeInDrive: Boolean = False): TSysCharSet;var  D, Mask: DWORD;  C: Char;begin  Result := [];  D := GetLogicalDrives;  for C := 'A' to 'Z' do  begin    Mask := (1 shl (Ord(C) - Ord('A')));    if (Mask and D) = Mask then    begin    if (not DiskMustBeInDrive) or DiskInDrive(C) then      Include(Result, C);    end;  end;end;  And from a unit that imlements a DriveCombobox: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i type   TDriveType = (dtUnknown, dtNoRootDir, dtRemovable, dtFixed, dtRemote, dtCdrom, dtRamDisk);  TDriveTypes = set of TDriveType; function GetDriveType(ADrive: Char): TDriveType;var  WinDriveType: UINT;begin  WinDriveType := Windows.GetDriveType(PChar(LowerCase(ADrive+':\')));  case WinDriveType of    DRIVE_UNKNOWN: Result := dtUnknown;    DRIVE_NO_ROOT_DIR: Result := dtNoRootDir;    DRIVE_REMOVABLE: Result := dtRemovable;    DRIVE_FIXED: Result := dtFixed;    DRIVE_REMOTE: Result := dtRemote;    DRIVE_CDROM: Result := dtCdrom;    DRIVE_RAMDISK: Result := dtRamDisk;    else Result := dtUnknown;  end; //caseend;//refreshs the drive list//FMountedDrivesOnly: if True then disk must be in drive//DriveTypes: a set of drivetypes you want in the list, so you can e.g. filter for only removable drives procedure TFSICustomDriveComboBox.RefreshDriveList;var  C: Char;  ADriveType: TDriveType;begin  if (csDesigning in ComponentState) then    Exit;  Items.Clear;  for C in GetAvailableDrives(FMountedDrivesOnly) do  begin    ADriveType := GetDriveType(C);    if ADriveType in DriveTypes then      Items.Add(C + ':\');  end;  if FSelectFirstDriveOnRefreshDriveList and (not DroppedDown) and (Items.Count > -1) then    ItemIndex := 0;end;  Bart ---------------------------------------------------------------------- Sieben · 2020-11-20 17:48 Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i ... and (Items.Count > -1) ? ---------------------------------------------------------------------- Bart · 2020-11-20 18:19 Quote from: Sieben on November 20, 2020, 06:48:24 pmCode: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i ... 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 ---------------------------------------------------------------------- Sieben · 2020-11-20 19:06 Thanks for sharing. And Flying Sheep is one of my absolute favourites as well... ---------------------------------------------------------------------- Remy Lebeau · 2020-11-20 20:17 Quote from: Bart on November 20, 2020, 06:22:35 pmCode: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i 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. ---------------------------------------------------------------------- bjlockie1 · 2020-11-20 21:15 Quote from: Leledumbo on November 19, 2020, 10:45:58 pmGuess 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 · 2020-11-20 23:33 Quote from: bjlockie1 on November 20, 2020, 10:15:44 pmI 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. ---------------------------------------------------------------------- winni · 2020-11-20 23:39 Quote from: lucamar on November 21, 2020, 12:33:23 amQuote from: bjlockie1 on November 20, 2020, 10:15:44 pmI 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 · 2020-11-20 23:57 Quote from: winni on November 21, 2020, 12:39:25 amOr 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 ---------------------------------------------------------------------- winni · 2020-11-21 01:03 Quote from: lucamar on November 21, 2020, 12:57:42 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 ---------------------------------------------------------------------- lucamar · 2020-11-21 04:28 Well, I don't know about the Samba one but neither of the other situations have ever happened to me: Win 7 leaves non-win partitions alone (as it should!) and if you just disconnect a device (say, a USB disk) it sometimes, as do Win10, complains about your lack of manners but is otherwise notified and frees up the volume letter. I'm not much on Windows (and less each year, thank the gods) but some of my customers do and I've never heard about such problems. But then, again, that's not very representative: most of us as well as our customers are on Linux or other *nixen ... or on very ancient systems, but that's another story