locked
Netzlaufwerke aus Anwendung heraus wiederherstellen?

    Frage

  • Guten Tag.

    Ich habe folgendes Problem:
    Ein Dienst startet eine Anwendung unter einem Benutzerkonto.
    Dieses Konto verfügt über ein Netzlaufwerk M:\ welches zu einem Backupverzeichnis auf nem Server führt.
    Die Anwendung soll nun vom User definierte Daten nach M:\ schieben.
    Das Problem ist, dass die Anwendung zwar per LogonUser, DuplicateTokenEx, LoadUserProfile, CreateEnvironmentBlock und CreateProcessAsUser gestartet wird, die Netzlaufwerke sind jedoch nicht da.
    Nun versuche ich per WNetAddConnection2 die Laufwerke wiederherzustellen, die sich angeblich in der Registry HKEY_CURRENT_USER\Network befinden sollen. Nur da sind die nicht. Bzw. die sind da nur wenn sich ein Benutzer "richtig" anmeldet. Also die Frage, wie kann ich diese Laufwerke korrekt wiederherstellen und darauf zugreifen?
    Die Anwendung läuft ja unter einem Benutzerkonto, sollte also kein Problem sein, oder doch?

    BTW: Ist kein spezielles Vistaproblem, ist unter W2000, WXP udn W7 genauso
    Montag, 31. August 2009 12:06

Antworten

  • Hast Du wirklich die Doku von LoadUserProfile berücksichtigt:

    Zitat: http://msdn.microsoft.com/en-us/library/bb762281(VS.85).aspx
    Upon successful return, the hProfile member of PROFILEINFO is a registry key handle opened to the root of the user's hive. It has been opened with full access (KEY_ALL_ACCESS). If a service that is impersonating a user needs to read or write to the user's registry file, use this handle instead of HKEY_CURRENT_USER . Do not close the hProfile handle. Instead, pass it to the UnloadUserProfile function. This function closes the handle. You should ensure that all handles to keys in the user's registry hive are closed. If you do not close all open registry handles, the user's profile fails to unload. For more information, see Registry Key Security and Access Rights and Registry Hives.
    Martin Richter -- MVP for VC++ [Germany] -- http://blog.m-ri.de
    Dienstag, 1. September 2009 10:26

Alle Antworten

  • Das Ganze wird IMHO hier erklärt!
    Das Problem existiert letzten Endes seit W2K SP2. Siehe auch letzter Kommentar.
    http://blogs.msdn.com/cjacks/archive/2007/02/19/mapped-network-drives-with-uac-on-windows-vista.aspx
    Martin Richter -- MVP for VC++ [Germany] -- http://blog.m-ri.de
    • Als Antwort vorgeschlagen Martin Richter Montag, 31. August 2009 12:19
    • Nicht als Antwort vorgeschlagen MaWeber Dienstag, 1. September 2009 05:51
    Montag, 31. August 2009 12:18
  • Hallo MaWeber,

    Schau Dir mal folgenden Diskussionsfaden an. Vielleicht kann er Dir weiter helfen.

    Befehl für Netzlaufwerk verbinden à http://social.msdn.microsoft.com/Forums/de-DE/vbasicexpresseditionde/thread/2cdd55d2-bf14-4a3d-8670-eeb14f67265a

    Grüße,

    Robert

    Montag, 31. August 2009 12:20
    Besitzer
  • Wenn ich das recht verstehe, benötige ich im einen Fall bereits vorhandene Netzlaufwerke unter dem Account unter dem das Programm laufen soll, d.h. es muss jemand eingeloggt seind er die Laufwerke hergestellt hat, und beim andern muss ich wissen welcher Laufwerksbuchstabe zu welchem Netzwerkpfad gehört?

    Nun ist das Prblem aber, dass ich nur ein Laufwerk M:\ habe. Keinen zugehörigen UNC Pfad. Ich muss also irgendwoher wissen wie der UNC Pfad ist um dieses Laufwerk wiederherzustellen, oder mit einer Systemfunktion alle Netzlaufwerke die wie beim richtigen Login verbunden werden, auch in meinem Fall automatisch verbinden.

    Wie man ein Netzlaufwerk herstellt weis ich, wenn ich die Daten ovn Hand übergebe geht es ja. Aber ich bekomm die Daten nicht bevor sich jemand eingeloggt, bzw dann auch nur von demjenigen der dann tatsächlich eingeloggt ist.

    Gibt es keine Möglichkeit vor Login von irgendeinem User, dessen Netzlaufwerke auszulesen, zusammen mit den notwendigen Daten um diese wiederherzustellen?
    Montag, 31. August 2009 13:06
  • Wie machst Du Deinen Zugriff auf HKEY_CURRENT_USER\Network? Mit dem Handle, dass Die LoadUserProfile gibt?
    Martin Richter -- MVP for VC++ [Germany] -- http://blog.m-ri.de
    Dienstag, 1. September 2009 06:44
  • Das ist ne TNetwork Klasse in Delphi. Die verwende ich in dem Programm welches gestartet wird.
    Im Programm selbst habe ich dieses Handle welches du ansprichst nichtmehr. Muss ich etwas mit dem Handle machen damit die Netzlaufwerke direkt geladen werden?
    Dienstag, 1. September 2009 07:23
  • Hast Du wirklich die Doku von LoadUserProfile berücksichtigt:

    Zitat: http://msdn.microsoft.com/en-us/library/bb762281(VS.85).aspx
    Upon successful return, the hProfile member of PROFILEINFO is a registry key handle opened to the root of the user's hive. It has been opened with full access (KEY_ALL_ACCESS). If a service that is impersonating a user needs to read or write to the user's registry file, use this handle instead of HKEY_CURRENT_USER . Do not close the hProfile handle. Instead, pass it to the UnloadUserProfile function. This function closes the handle. You should ensure that all handles to keys in the user's registry hive are closed. If you do not close all open registry handles, the user's profile fails to unload. For more information, see Registry Key Security and Access Rights and Registry Hives.
    Martin Richter -- MVP for VC++ [Germany] -- http://blog.m-ri.de
    Dienstag, 1. September 2009 10:26
  • Ja, aber ich lese ja nicht aus dem Service heraus die Registry aus.

    Der Service startet das Programm unter einem Benutzeraccount - das funktioniert.
    Das Programm liest dann die Registry aus - das funktioniert nicht korrekt.

    Es werden fast alle Schlüssel ausgelesen, aber Network, Session Information und noch ein oder zwei Schlüssel stehen dann nciht in der Registry drin.
    Ich konnte das auch nachvollziehen, wenn ich zwei Benutzer zeitgleich eingeloggt habe, konnte ich bei UserA in Regedit unter HKEY_USERS unter UserB den Network Schlüssel finden.
    Als ich UserB ausgeloggt hatte war der Schlüssel dann weg. Hab ich UserB wieder eingeloggt war Network wieder da.

    So war es, momentan bin ich jedoch komplett verwirrt, da Network jedesmal da ist und auf die Netzlaufwerke zugegriffen werden kann. Ich hab keine Ahnung wieseo, aber ist auf 3 verschiedenen Systemen jetz so :(

    Wenns morgen wieder anders iss hab ich en Problem weils für mich absolut nicht nachvollziehbar ist.
    Dienstag, 1. September 2009 10:35
  • Nunja, also die Netzlaufwerke scheinen in dem Networkschlüssel zu liegen, allerdings habe ich jetzt ein Proglem beim anwenden der WNetAddConnection2:

    function TNetMapper.TryToConnect(sDrive,sShare,sUserName: String): Boolean;
    var NetRes: TNetResourceA;
    begin
    Result:=False;
    ExcludeTrailingPathDelimiter(sShare);
    ExcludeTrailingPathDelimiter(sDrive);
    // Zuerst versuchen mit den aktuellen Anmeldedaten das Laufwerk zu verknüpfen
    NetRes.dwScope:=RESOURCE_GLOBALNET;
    NetRes.dwType:=RESOURCETYPE_ANY;
    NetRes.dwDisplayType:=RESOURCEDISPLAYTYPE_SHARE;
    NetRes.dwUsage:=RESOURCEUSAGE_CONTAINER;
    if sDrive[2]=':' then NetRes.lpLocalName:=PChar(sDrive)
    else NetRes.lpLocalName:=nil;
    NetRes.lpRemoteName:=PChar(sShare);
    NetRes.lpComment:=Nil;
    NetRes.lpProvider:=Nil;
    NetRes.lpRemoteName:=PChar(SysErrorMessage(WNetAddConnection2(NetRes,nil,nil,CONNECT_UPDATE_PROFILE)));
    Result:=NO_ERROR=WNetAddConnection2(NetRes,nil,nil,CONNECT_UPDATE_PROFILE);
    if not Result then
    Result:=NO_ERROR=WNetAddConnection2(NetRes,'',PChar(sUserName),CONNECT_UPDATE_PROFILE);
    
    end;
    Nach
    NetRes.lpRemoteName:=PChar(SysErrorMessage(WNetAddConnection2(NetRes,nil,nil,CONNECT_UPDATE_PROFILE)));
    

    bekomme ich folgende Fehlermeldung:
    Überlappender E/A-Vorgang wird verarbeitet

    Nach den anderen WNetAddConnection2 aufrufen dann:
    Es wurde versucht, eine bereits gespeicherte Verbindung zu einem Gerät zu speichern

    Ich nutze die Funktion nur, hab die nich selbst geschrieben un kann daher wenig damit anfangen.
    Zu den Fehlermeldungen finde ich nicht allzuviel..
    Dienstag, 1. September 2009 13:02
  • Hallo MaWeber,

    Könntest Du Dein Problem lösen? Dein obiger Code ist doch Delphi nicht wahr?

    Schau Dir mal die folgenden Links an. Vielleicht können Sie Dir weiter helfen.

    http://bytes.com/topic/c-sharp/answers/499365-calling-wnetaddconnection2-c

    Grüße,

    Robert

    Montag, 26. Oktober 2009 15:07
    Besitzer
  • Hallo MaWeber,

    Ich gehe davon aus, dass die Antworten Dir weitergeholfen haben.
    Solltest Du noch "Rückfragen" dazu haben, so gib uns bitte Bescheid.

    Grüße,
    Robert

    Montag, 2. November 2009 14:22
    Besitzer