Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   GetLogicalDriveStrings 64bit liest nicht alle Laufwerke aus (https://www.delphipraxis.net/203165-getlogicaldrivestrings-64bit-liest-nicht-alle-laufwerke-aus.html)

DieDolly 19. Jan 2020 21:27


GetLogicalDriveStrings 64bit liest nicht alle Laufwerke aus
 
Mir ist es nie in den sinn gekommen, diese Funktion mit einem 64bit-Kompilat zu testen.
Heute habe ich es aber mal gemacht und siehe da, es werden nicht alle Laufwerke erkannt.

Woran liegt das?
Delphi-Quellcode:
procedure GetDiskDriveLetters(aList: TStringList);
var
 vDrivesSize: Cardinal;
 vDrives: array [0 .. 128] of Char;
 vDrive: PChar;
begin
 if not Assigned(aList) then
  Exit;

 aList.BeginUpdate;
 try
  aList.Clear;
  vDrivesSize := GetLogicalDriveStrings(SizeOf(vDrives), vDrives);

  if vDrivesSize = 0 then
   Exit;

  if vDrivesSize > SizeOf(vDrives) then
   raise Exception.Create(SysErrorMessage(ERROR_OUTOFMEMORY));

  vDrive := vDrives;

  while vDrive^ <> #0 do
   begin
    aList.Add(vDrive);
    Inc(vDrive, SizeOf(vDrive));
   end;
 finally
  aList.EndUpdate;
 end;

 showmessage(aList.Text);
end;

Uwe Raabe 19. Jan 2020 21:49

AW: GetLogicalDriveStrings 64bit ließt nicht alle Laufwerke aus
 
Dein Code funktioniert nur dann, wenn Sizeof(Pointer) = 4 ist und auch nur wenn die Laufwerke drei Buchstaben haben (3 + 1 Null-Char). Das ist unter 64 Bit aber nicht der Fall.
So geht's:
Delphi-Quellcode:
  vDrive := @vDrives[0];

  while vDrive^ <> #0 do
   begin
    aList.Add(vDrive);
    Inc(vDrive, Length(vDrive) + 1);
   end;

Uwe Raabe 19. Jan 2020 22:27

AW: GetLogicalDriveStrings 64bit ließt nicht alle Laufwerke aus
 
Zitat:

Zitat von Frühlingsrolle (Beitrag 1455547)
Es ginge auch kürzer

Mal abgesehen davon, dass man damit den beobachteten Fehler nicht erklärt, halte ich 26 Aufrufe von GetLogicalDrives, die vermutlich jedes Mal dasselbe Ergebnis liefern, für optimierungsfähig.

Luckie 19. Jan 2020 23:14

AW: GetLogicalDriveStrings 64bit ließt nicht alle Laufwerke aus
 
Im ungünstigsten Fall wären es 26. :wink:

DieDolly 20. Jan 2020 06:49

AW: GetLogicalDriveStrings 64bit ließt nicht alle Laufwerke aus
 
Zitat:

Dein Code funktioniert nur dann, wenn Sizeof(Pointer) = 4
Danke für die Erklärung.

Inm TDirectory habe ich gestern noch zufällig was gefunden. Ist das auch imn Ordnung?
Delphi-Quellcode:
Drives := TDirectory.GetLogicalDrives;
for Drive in Drives do
 AList.Add(Drive);

Uwe Raabe 20. Jan 2020 09:22

AW: GetLogicalDriveStrings 64bit liest nicht alle Laufwerke aus
 
Delphi-Quellcode:
TDirectory.GetLogicalDrives
gibt ein
Delphi-Quellcode:
array of string
zurück. Das kann problemlos mit einem
Delphi-Quellcode:
for-in
durchlaufen werden.

Interessanterweise benutzt die Implementierung von
Delphi-Quellcode:
TDirectory.GetLogicalDrives
ein
Delphi-Quellcode:
StrEnd(CurrDrive) + 1
um auf den nächsten Eintrag zu positionieren. Das ist vermutlich etwas effizienter als mein Vorschlag mit dem Inc/Length.

DieDolly 25. Jan 2020 17:50

AW: GetLogicalDriveStrings 64bit liest nicht alle Laufwerke aus
 
Liste der Anhänge anzeigen (Anzahl: 1)
Ich habe wieder ein neues Problem.
Egal ob 32 Bit oder 64 Bit.

Wenn man die Exe-Datei mit Administratorrechten ausführt, dann ließt TDirectory.GetLogicalDrives; ebenfall nicht alle Laufwerke aus.
S und U sind Netzlaufwerke.

Ist das bekannt? Gibt es hier eine Fehlerbeseitigung für?

Frisches Projekt, ListBox aufs Formular, nur das hier an Code wurde hinzugefügt:
Delphi-Quellcode:
uses ... System.IOUtils;

procedure TForm1.FormCreate(Sender: TObject);
var
 Drives: TArray<string>;
 Drive: string;
begin
 ListBox1.Items.BeginUpdate;
 try
  ListBox1.Items.Clear;

  Drives := TDirectory.GetLogicalDrives;
  for Drive in Drives do
   ListBox1.Items.Add(Drive);
 finally
  ListBox1.Items.EndUpdate;
 end;
end;
Hier steht das ist angeblich ein Windows 7 Fehler.
http://codeverge.com/embarcadero.del...ning-m/1071775

Dalai 25. Jan 2020 18:16

AW: GetLogicalDriveStrings 64bit liest nicht alle Laufwerke aus
 
Netzlaufwerke sind nutzerspezifisch bzw. an ein Nutzertoken gebunden. Daher hat jeder Nutzer seine eigenen Netzlaufwerke, und als Administrator ausgeführte Programme (elevated) ebenfalls. Daher braucht es dafür auch keine Fehlerbeseitigung - außer das Programm nur dann elevated auszuführen, wenn es wirklich sein muss, und eben nicht zu erwarten, dass dort dieselben Laufwerke gelistet werden.

PS: Diese Sache hat übrigens nichts mit Windows 7 zu tun. Dieses Verhalten gibt es bereits seit XP. Hat nur dort kaum einer mitbekommen, es sei denn, man hat mit ordentlich getrennten Nutzerkonten gearbeitet.

Grüße
Dalai


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:32 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz