![]() |
WNetENumResource -> Unterschiede auf Win7 und Win 8 / 8.1
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo Forum,
Aufgrund einer Randbemerkung hatte ich in ![]() 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 / ![]() ![]() Jetzt zeigt sich, das mit ![]() 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; |
AW: WNetENumResource -> Unterschiede auf Win7 und Win 8 / 8.1
- PUSH -
:dp: :angel: |
AW: WNetENumResource -> Unterschiede auf Win7 und Win 8 / 8.1
Hallo Miteinander,
ich versuche nochmal ganz vorsichtig einen Push. Vielleicht stolpert ja jemand drüber :-) Gruß, Chris |
AW: WNetENumResource -> Unterschiede auf Win7 und Win 8 / 8.1
Das Verhalten von "WNetEnumResource" ist aus meiner Sicht genau so wie es sein soll (auch unter Windows 8)
Vorsicht: Unter Windows 8 hat sich der Zugriff zwischen UAC-elevated bzw. non-elevated verbundenen Netzlaufwerken und UAC-elevated bzw. non-elevated Prozesse offensichtlich geändert... Hier zum Verständnis... unter Windows 7 (mit aktivierter UAC)... 1) "Normale" CMD -> net use R: \\meinserver\freigabe1 2) "Normale" CMD -> net use S: \\meinserver\freigabe2 3) "Als Admin ausgeführte" CMD -> net use T: \\meinserver\freigabe3 4!) In einer "Normalen" NOTEPAD (Speichern unter...) hast du Zugriff auf R:, S: und T: (Das Laufwerke T: ist jedoch nicht auf Anhieb verbunden) 5!) In einer "Als Admin ausgeführten" NOTEPAD (Speichern unter...) hast du Zugriff auf R:, S: und T: (Die Laufwerke R: und S: sind jedoch nicht auf Anhieb verbunden) 6) "Normale" CMD -> net use 7) "Als Admin ausgeführte" CMD -> net use unter Windows 8 (mit aktivierter UAC)... 1) "Normale" CMD -> net use R: \\meinserver\freigabe1 2) "Normale" CMD -> net use S: \\meinserver\freigabe2 3) "Als Admin ausgeführte" CMD -> net use T: \\meinserver\freigabe3 4!) In einer "Normalen" NOTEPAD (Speichern unter...) hast du nur Zugriff auf R: und S: 5!) In einer "Als Admin ausgeführten" NOTEPAD (Speichern unter...) hast nur Zugriff auf T: 6) "Normale" CMD -> net use 7) "Als Admin ausgeführte" CMD -> net use Spätestens bei Punkt 6 und 7 solltest du das unterschiedliche Verhalten zwischen Windows 7 und Windows 8 erkennen Unter Windows 7 kann man "alle" Netzlaufwerke auflisten -> Jedoch sind nur die "eigenen" Netzlaufwerke verbunden -> Der "Trick" hierbei ist, dass man auf ein "nicht verbundenes" Netzlaufwerk zugreift wird es auch im derzeit verwendeten UAC-Kontext sofort verbunden. (Was auch funktioniert sofern die Berechtigungen es zulassen). Unter Windows 8 siehst du nur jene Laufwerke die im jeweiligen UAC-Kontext (Heißt das so?) verbunden wurden. Ich bin mir ziemlich sicher dass es die Möglichkeit gibt um dieses Verhalten zwecks Abwärtskompatibilität zu steuern. (Policies od. Registry) Nachtrag: Ja gibt es... HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows/CurrentVersion/Policies/System [EnableLinkedConnections (DWORD) = 1] (Anschließend PC neu starten, dann klappt's auch mit deinem Programm wieder) Zu deinem Problem -> siehe auch ![]() |
AW: WNetENumResource -> Unterschiede auf Win7 und Win 8 / 8.1
Hallo Kyro,
vielen Dank - du hast damit genau das beschrieben, was ich mir schon gedacht habe. Danke für Deine Ausführung. Leider, ändert das nichts an der Problematik, dass man bis Windows 7 mit WNetEnumResource sehr zuverlässige die Netzlaufwerke unabhängig vom Account / UAC festellen konnte und ab Windows 8 nur dann wenn die Registry angepasst wurde. Nur passiert diese Anpassung viel zu selten im freien Umfeld da draußen. Ergo - kann ich mit nicht mehr auf diese API-Funktion verlassen :-/ [Schmipf AN]Wenn ich doch mehr Rechte habe als eval. Process des selben Benutzers, warum sehe ich dann nicht was nicht eval. Prozesse sehen[Schimpf AUS] Auf jeden Fall ist erstmal die Alternative klar -> wenn Windows 8 oder höher und ProcessHasAdminRights -> Durchprobieren der Laufwerksbuchstaben anstatt WNetEnumResource - zumindest ist das mein Fazit daraus. Dir - Kryo - nochmals danke für die Aufarbeitung und Bestätigung. Gruß und eine schöne Woche, Chris |
AW: WNetENumResource -> Unterschiede auf Win7 und Win 8 / 8.1
Ich muss meine vorherige Info leicht abändern - denn das Verhalten hat sich nicht mit Windows 8 geändert...
Das Verhalten gab es schon mit Windows Vista und auch mit Windows 7. Es dürfte also mehr Faktoren geben als nur dem Registry Key und eine aktivierte UAC wann es sich so verhält wie du es bereits von Windows 8/8.1 kennst! Ich würde jedenfalls davon abraten dem ganzen einem Windows 8 Check o.ä. zu verpassen. Aus meiner Sicht arbeitet "WNetEnumResource" nach wie vor wie es sein soll (Es listet nämlich die Netzlaufwerke genauso auf wie es z.B.: ein TFileOpenDialog machen würde) Anderes Szenario - gleiches Problem... UserA ist kein Administrator, und er macht einen rechtsklick auf dein Programm -> "Als Administrator ausführen..." -> nun gibt er die Credentials von UserB (der Administrator ist) ein -> Das Programm startet mit den Rechten von UserB -> In dem Fall wirst du die Laufwerke von UserA ebenfalls nicht sehen - es sei denn du berücksichtigst exakt dieses Szenario. Unabhängig von dem Problem, wirst du noch in ganz andere Probleme mit UAC laufen wenn du nicht im vorhinein UAC-Aware programmierst. Falls du ausschließlich die Laufwerke des Benutzers anzeigen lassen willst (und nicht darauf mit dem Laufwerksbuchstaben zugreifen musst) könntest du folgende Quick&Dirty Routine verwenden:
Code:
procedure GetUserNetDrivesPerReg(var LaufWerke_Lokal: TStrings; LaufWerke_Remote: TStrings);
var i: Integer; var Reg: TRegistry; var ValidEntry: Boolean; begin Reg := TRegistry.Create(KEY_READ or KEY_WOW64_64KEY); try Reg.RootKey := HKEY_CURRENT_USER; if Reg.OpenKey('Network',False) then begin Reg.GetKeyNames(LaufWerke_Lokal); Reg.CloseKey; for i := Pred(LaufWerke_Lokal.Count) downto 0 do begin ValidEntry := False; if Reg.OpenKey('Network\'+LaufWerke_Lokal[i],False) then begin if Reg.ValueExists('RemotePath') then begin LaufWerke_Remote.Add(Reg.ReadString('RemotePath')); LaufWerke_Lokal[i] := LaufWerke_Lokal[i]+':'; ValidEntry := True; end; Reg.CloseKey; end; if not ValidEntry then LaufWerke_Lokal.Delete(i); end; end; finally Reg.Free; end; end; |
AW: WNetENumResource -> Unterschiede auf Win7 und Win 8 / 8.1
Zitat:
Zitat:
Zitat:
Zitat:
Gruß, Chris |
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:25 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-2025 by Thomas Breitkreuz