AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

GetVolumePathNamesForVolume

Ein Thema von himitsu · begonnen am 2. Aug 2006
Antwort Antwort
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#1

GetVolumePathNamesForVolume

  Alt 2. Aug 2006, 13:10
hab hier mal 'nen WorkAround für GetVolumePathNamesForVolumeNameW, welches ja erst seit WinXP vorhanden ist,
ist nicht perfekt und das Ergebnis is och nich ganz zu 100% identisch mit dem Original, aber es müßte zumindestens "voll" kompatibel sein.


Wie die meisten unktionen aus diesem Bereich des VolumeManagements ist(sollte) dieses ab Windows 2000 Professional lauffähig.

Delphi-Quellcode:
  Function _GetVolumePathNamesForVolumeNameW(VolumeName, VolumePathNames: PWideChar; BufferLength: LongWord; ReturnLength: PLongWord): LongBool; StdCall;
    Var LogicalDriveStrings, SearchBuffer, ResultS: WideString;
      ResultBuffer: Array[0..MAX_VOLUMENAME-1] of WideChar;

    Procedure SearchRecursiv(Const SearchBuffer2: WideString);
      Var SearchHandle: THandle;
        SearchBuffer3: WideString;

      Begin
        SearchHandle := FindFirstVolumeMountPointW(@ResultBuffer, @ResultBuffer, MAX_VOLUMENAME);
        If SearchHandle = INVALID_HANDLE_VALUE Then Exit;
        Repeat
          SearchBuffer3 := SearchBuffer2 + ResultBuffer;
          If GetVolumeNameForVolumeMountPointW(PWideChar(SearchBuffer3), @ResultBuffer, MAX_VOLUMENAME) Then Begin
            If CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE, VolumeName, -1, @ResultBuffer, -1) = 2 Then
              ResultS := ResultS + Copy(SearchBuffer3, 5, MAX_PATH) + #0;
            SearchRecursiv(SearchBuffer3);
          End;
        Until not FindNextVolumeMountPointW(SearchHandle, @ResultBuffer, MAX_VOLUMENAME);
        FindVolumeMountPointClose(SearchHandle);
      End;

    Begin
      ResultS := '';
      SetLength(LogicalDriveStrings, GetLogicalDriveStringsW(0, nil));
      GetLogicalDriveStringsW(255, @LogicalDriveStrings[1]);
      LogicalDriveStrings := Trim(LogicalDriveStrings);
      While LogicalDriveStrings <> 'do Begin
        SearchBuffer := '\\.\' + PWideChar(LogicalDriveStrings);
        Delete(LogicalDriveStrings, 1, Length(SearchBuffer) - 4);
        LogicalDriveStrings := TrimLeft(LogicalDriveStrings);
        If (SearchBuffer[5] <= 'B') and (SearchBuffer[6] = ':') Then Continue;
        If GetVolumeNameForVolumeMountPointW(PWideChar(SearchBuffer), @ResultBuffer, MAX_VOLUMENAME) Then Begin
          If CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE, VolumeName, -1, @ResultBuffer, -1) = 2 Then
            ResultS := ResultS + Copy(SearchBuffer, 5, MAX_PATH) + #0;
          SearchRecursiv(SearchBuffer);
        End;
      End;
      ResultS := ResultS + #0;
      If (BufferLength >= LongWord(Length(ResultS))) and (VolumePathNames <> nil) Then Begin
        Move(ResultS[1], VolumePathNames^, 2*Length(ResultS));
        If ReturnLength <> nil Then ReturnLength^ := Length(ResultS);
        Result := True;
      End Else If (BufferLength = 0) and (VolumePathNames = nil) Then Begin
        If ReturnLength <> nil Then ReturnLength^ := Length(ResultS);
        Result := True;
      End Else Begin
        If VolumePathNames <> nil Then VolumePathNames^ := #0;
        If ReturnLength <> nil Then ReturnLength^ := 1;
        Result := False;
      End;
    End;

Dieses If (SearchBuffer[5] <= 'B') and (SearchBuffer[6] = ':') Then Continue; müßte eigentlich raus, aber dann fragt GetVolumeNameForVolumeMountPointW immer nach 'ner Diskette, wenn grad keine im Laufwerk ist.

Wer Verbesserungsvorschläge hat, oder Fehler im Code findet, sollte sich bitte mal melden ._.


Eingebunden hab ich es so,
Delphi-Quellcode:
Var GetVolumePathNamesForVolumeNameW: Function(VolumeName, VolumePathNames: PWideChar;
  BufferLength: LongWord; ReturnLength: PLongWord): LongBool; StdCall;
statt GetVolumePathNamesForVolumeName direkt aus der API aufrurufen:
Delphi-Quellcode:
Function GetVolumePathNamesForVolumeNameW(VolumeName, VolumePathNames: PWideChar;
  BufferLength: LongWord; ReturnLength: PLongWord): LongBool; StdCall;
  External 'kernel32.dllName 'GetVolumePathNamesForVolumeNameW';
Und dann natürlich noch die passende Initialization:
(ab WinXP wird ja das Original gefunden und initialisiert ... davor (Win2000 Pro) kann wird halt meine Funktion verwendet.
Delphi-Quellcode:
Initialization
  GetVolumePathNamesForVolumeNameW := GetProcAddress(GetModuleHandle('kernel32.dll'), 'GetVolumePathNamesForVolumeNameW');
  If @GetVolumePathNamesForVolumeNameW = nil Then
    GetVolumePathNamesForVolumeNameW := @_GetVolumePathNamesForVolumeNameW;

End.
Die kernel32.dll ist meist eh schon geladen, also man braucht sich nur das passende Handle mit GetModuleHandle zubesorgen.
Und Freigeben braucht man somit dann auch nichts.



PS: für eine AnsiVersion braucht man halt nur die ganzen "Wide" durch "Ansi" und die "W(" durch "A(" zu ersetzen.
$2B or not $2B
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:10 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