![]() |
GetVolumePathNamesForVolume
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:
statt GetVolumePathNamesForVolumeName direkt aus der API aufrurufen:
Var GetVolumePathNamesForVolumeNameW: Function(VolumeName, VolumePathNames: PWideChar;
BufferLength: LongWord; ReturnLength: PLongWord): LongBool; StdCall;
Delphi-Quellcode:
Und dann natürlich noch die passende Initialization:
Function GetVolumePathNamesForVolumeNameW(VolumeName, VolumePathNames: PWideChar;
BufferLength: LongWord; ReturnLength: PLongWord): LongBool; StdCall; External 'kernel32.dll' Name 'GetVolumePathNamesForVolumeNameW'; (ab WinXP wird ja das Original gefunden und initialisiert ... davor (Win2000 Pro) kann wird halt meine Funktion verwendet.
Delphi-Quellcode:
Die kernel32.dll ist meist eh schon geladen, also man braucht sich nur das passende Handle mit GetModuleHandle zubesorgen.
Initialization
GetVolumePathNamesForVolumeNameW := GetProcAddress(GetModuleHandle('kernel32.dll'), 'GetVolumePathNamesForVolumeNameW'); If @GetVolumePathNamesForVolumeNameW = nil Then GetVolumePathNamesForVolumeNameW := @_GetVolumePathNamesForVolumeNameW; End. Und Freigeben braucht man somit dann auch nichts. :mrgreen: PS: für eine AnsiVersion braucht man halt nur die ganzen "Wide" durch "Ansi" und die "W(" durch "A(" zu ersetzen. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:01 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz