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.dll' Name '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.