Hallo Forum,
Aufgrund einer Randbemerkung hatte ich in
diesem Thread meinen "vermeintlichen" Wissenstand geschrieben.
Kurz erklärt: UserA ist Mitglieder Administratorgruppe unter Windows 7 bzw. 8 und
UAC ist aktiviert. Startet UserA das Programm ganz normal kann man per WNetEnumResource die Netzlaufwerke bestimmen, die immer wieder verbunden werden sollen /
RESOURCE_REMEMBERED. Startet UserA das Programm mit erhöhten Rechten - aber noch als er selber - liefert
WNetENumResource unter Windows 7 weiterhin die Liste der Netzlaufwerke. Unter Windows 8 bekommt man eine leere Liste. Daher meine Annahme, dass man jetzt unter Windows 8 die Netzlaufwerke im erhöhten Rechte-Kontext gar nicht mehr hat.
Jetzt zeigt sich, das mit
WNetGetConnection das ganze auch mit erhöhten Rechten funktioniert, wenn man einfach alle Laufwerksbuchstaben "durchprobiert".
Und hier die Frage:
Was ist an den Routinen falsch, wo habe ich den Fehler gemacht?
Unten der Quelltext der beiden Möglichkeiten und angehängt ein Beispielprojekt - erstellt mit XE2:
Delphi-Quellcode:
function GetAllNetDrivesPerEnum(LaufWerke_Lokal: TStrings; LaufWerke_Remote: TStrings): DWord;
const
cbBuffer: DWord = 16384;
cEntries: DWord = DWord(-1);
var
dwResult: DWord;
hEnum: THandle;
lpnrDrv: array [0 .. 16384 div SizeOf(TNetResource)] of TNetResource; // pointer to enumerated structures
i: Integer;
lname: string;
rname: string;
begin
result := NO_ERROR;
dwResult := WNetOpenEnum(RESOURCE_REMEMBERED, RESOURCETYPE_ANY, 0, nil, hEnum);
if (dwResult <> NO_ERROR) then
begin
result := dwResult;
Exit;
end;
repeat
FillChar(lpnrDrv, length(lpnrDrv) * SizeOf(TNetResource), #0);
cEntries := DWord(-1);
dwResult := WNetEnumResource(hEnum, cEntries, @lpnrDrv, cbBuffer);
if (dwResult = NO_ERROR) then
begin
for i := 0 to cEntries - 1 do
begin
if (lpnrDrv[i].lpLocalName <> nil) and // Lokaler Name ist da (X: Y: Z: etc.)
(lpnrDrv[i].lpRemoteName <> nil) and // Remote Name ist da (\\Server\Freigabe)
(lpnrDrv[i].dwType = RESOURCETYPE_DISK) and // Die Resource ist vom Typ Disk
(lpnrDrv[i].dwDisplayType = RESOURCEDISPLAYTYPE_SHARE) then // Die Resource sollte lauf Windows im Bereich Shares angezeigt werden
begin
lname := lpnrDrv[i].lpLocalName;
lname := Trim(lname);
rname := lpnrDrv[i].lpRemoteName;
rname := Trim(rname);
if (lname <> '') and (rname <> '') then
begin
if LaufWerke_Lokal.IndexOf(lname) = -1 then
begin
LaufWerke_Lokal.Add(lpnrDrv[i].lpLocalName);
LaufWerke_Remote.Add(lpnrDrv[i].lpRemoteName);
end;
end;
end;
end;
end else if dwResult <> ERROR_NO_MORE_ITEMS then
begin
result := dwResult;
break;
end;
until (dwResult = ERROR_NO_MORE_ITEMS);
WNetCloseEnum(hEnum);
if dwResult = ERROR_NO_MORE_ITEMS then
result := NO_ERROR;
end;
function GetAllNetDrivesPerDirectTest(LaufWerke_Lokal: TStrings; LaufWerke_Remote: TStrings): Boolean;
var
c: Char;
laufwerk: PChar;
remotename: PChar;
bufs: DWord;
res: DWord;
begin
GetMem(laufwerk, MAX_PATH * SizeOf(Char));
GetMem(remotename, MAX_PATH * SizeOf(Char));
try
try
for c in ['a' .. 'z'] do
begin
bufs := MAX_PATH * SizeOf(Char);
FillChar(laufwerk[0], bufs , #0);
FillChar(remotename[0], bufs, #0);
laufwerk[0] := c;
laufwerk[1] := ':';
res := WNetGetConnection(@laufwerk[0], @remotename[0], bufs);
if (res = ERROR_SUCCESS) (*or (res = ERROR_NOT_CONNECTED)*) or (res = ERROR_CONNECTION_UNAVAIL) then
begin
LaufWerke_Lokal.Add(trim(laufwerk));
LaufWerke_Remote.Add(trim(remotename));
end;
end;
finally
FreeMem(remotename);
FreeMem(laufwerk);
end;
except
result := FALSE;
end;
end;