![]() |
CreateProcessWithTokenW ERROR_DEVICE_NO_RESOURCES
Hallo,
Ich habe nen verzwicktes Problem und bisher hat nichts geholfen. Was ich erreichen möchte(oder besser gesagt MUSS, ist so vorgegeben ;) ) Ich möchte ein programm mithilfe von zuvor angegebenen Logindaten unter einem anderen Benutzer ausführen. Dabei kann dies entweder aus einem Nutzerkontext oder Servicekontext pasieren. Ich bearbeite gerade den Usecase das ich versuche von NutzerA mit NutzerB ein Programm auszuführen. Bei ausführen mit CreateProcessWithTokenW wird das Programm gestartet(CreateProcessWithTokenW meldet erfolg), windows wirft aber sofort die im Titel erwähnte Fehlermeldung(Code 0.x142) das wäre der Rohbau der aktuell den Fehler wirft: (Dummycode)
Delphi-Quellcode:
Jemand eine Idee?
ZeroMemory(@Startup, SizeOf(Startup));
Startup.cb := SizeOf(Startup); ZeroMemory(@Process, SizeOf(Process)); LogonUserW(Name, Domäne, Passwort, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, Token); CreateEnvironmentBlock(@Umgebungsblock, Token, False); CreateProcessWithTokenW(Token, LOGON_WITH_PROFILE, nil, @PfadZurExe[1], CREATE_NEW_CONSOLE or CREATE_UNICODE_ENVIRONMENT or CREATE_DEFAULT_ERROR_MODE, Umgebungsblock, nil, @Startup, @Process); MFG Memnarch |
AW: CreateProcessWithTokenW ERROR_DEVICE_NO_RESOURCES
Habe ich das richtig verstanden: Der Prozess wird erzeugt und CreateProcessWithToken meldet TRUE, aber GetLastError ist ERROR_DEVICE_NO_RESOURCES? Bei Erfolg eines API Aufrufs ist GetLastError nicht eindeutig definiert, von daher würde ich mir keine Gedanken machen, sofern die Process Creation ansich funktioniert.
Ansonsten musst du beachten, dass dein Prozess diverse Privilegien benötigt. Hier der Auszug aus dem MSDN: Zitat:
|
AW: CreateProcessWithTokenW ERROR_DEVICE_NO_RESOURCES
Der Fehlercode wird von Windows in einem Error Dialog angezeigt. Ist also kein GetLastError.
CreateProcessWithLogon ist keine Option, in einem Service ist es nicht verfügbar :( (es wäre schöner eine Lösung anstatt mehrere zu haben). AH bei dir steht das SE_IMPERSONATE_NAME für CreateProcessWithToken benötigt wird. Das bekomm ich sicherlich noch hin(wie ich die Privilegien setzen kann habe ich schon raus). Was immer funktioniert hat war LOGON32_LOGON_BATCH bei LogoinUser. Dann liefen die Programme, aber halt ohne Fenster^^ |
AW: CreateProcessWithTokenW ERROR_DEVICE_NO_RESOURCES
Mit dem SE_IMPERSONATE_NAME musst du aufpassen. Das Privileg steht dir standardmäßig nur auf Administratorkonten zur Verfügung.
Da tatsächlich eine Fehlermeldung erscheint, CreateProcessWithToken aber erfolgreich ist, vermute ich, dass die Meldung im Prozess geschmissen wird, den du versuchst zu starten. Hast du mal versucht einfach nur notepad.exe oder etwas Vergleichbares zu starten? |
AW: CreateProcessWithTokenW ERROR_DEVICE_NO_RESOURCES
Genau die tun das ;) (Notepad, MSPaint, ALLE, auch selbst geschriebene kleine programme)
Die Meldung die ich bekomme heißt soviel wie, dass benötigte Dateien nicht gefunden wurden. Das macht aber keinen Sinn. Hat der irgendwie keine Umgebungsvariablen zum suchen der DLLs oder sontigen sachen o.O? |
AW: CreateProcessWithTokenW ERROR_DEVICE_NO_RESOURCES
Du könntest es mal mit CreateProcessAsUser probieren. Das funktioniert auf jeden Fall auch aus einem Service heraus. Hatte folgenden Code verwenden, um einen Prozess im Kontext des aktuell eingeloggten Benutzers zu erstellen (mit UAC Elevation):
![]() |
AW: CreateProcessWithTokenW ERROR_DEVICE_NO_RESOURCES
Inzwischen habe ich es mit CreateProcessWithTokenW hinbekommen(und dann festgestellt das es ja nur auf Vista und aufwärts geht(XP sollte noch gehen -.-) UND die StdOut/In/Error handle nicht korrekt unterstützt wen der Prozess 32bit ist und auf einem 64bit OS ausgeführt wird).
Komischerweise, kann ich den token den ich in CreateProcessWithTokenW genutzt habe nicht in CreateProcessAsUser verwenden. Und das versteh ich nicht. wenn ich zum einloggen meinen eigenen account verwende, hat er angeblich nicht die korrekten rechte. wenn ich mir einfach den Token meines laufenden Prozesses hole(der ich auch bin) dan gehts? Was ist dann der Unterschied zwischen Mir(per LogonUser) und Mir(bestehender Prozesstoken)? Habe mir deinen Source durchgelesen. Es für mich selbst auszuführen klappt in meinem kleinen Usecase auch so, aber wie soll es in bezug auf Logonuser gehen? Die Tokens die mir das ausspuckt scheinen(auch nach DublicateTokenEx mit entsprechenden Flags) nicht brauchbar. Das hier ist die CreateProcasUserEx aus JclMiscel. Die habe ich mir kopiert und nutze am ende CreateProcessWithTokenW anstatt CreateProcessAsUser(Letzteres geht auch hier wegen den Rechten nicht, allerdings brauch ich es ja nun doch so, weil es erst ab Vista geht -.-) hier der Auszug aus der JCLMiscl.pas damit nicht alles gegooglet werden muss ;)
Delphi-Quellcode:
EDIT: also ich werde jetzt wohl doch 2 gleisig fahren müssen. CreateProcessAsUser vom Service und CreateProcessWithLogonW vom Benutzer
{ TODO -cTest : Check for Win9x }
procedure CreateProcAsUserEx(const UserDomain, UserName, Password, CommandLine: string; const Environment: PChar); const // default values for window stations and desktops CreateProcDEFWINSTATION = 'WinSta0'; CreateProcDEFDESKTOP = 'Default'; // CreateProcDOMUSERSEP = '\'; var ConsoleTitle: string; Help: string; WinStaName: string; DesktopName: string; hUserToken: THandle; hWindowStation: HWINSTA; hDesktop: HDESK; StartUpInfo: TStartUpInfo; ProcInfo: TProcessInformation; begin // Step 1: check for the correct OS version CheckOSVersion; // Step 2: logon as the specified user hUserToken := 0; if not LogonUser(PChar(UserName), PChar(UserDomain), PChar(Password), LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, hUserToken) then begin case GetLastError of ERROR_PRIVILEGE_NOT_HELD: raise EJclCreateProcessError.CreateResFmt(@RsCreateProcPrivilegeMissing, [GetPrivilegeDisplayName(SE_TCB_NAME), SE_TCB_NAME]); ERROR_LOGON_FAILURE: raise EJclCreateProcessError.CreateRes(@RsCreateProcLogonUserError); ERROR_ACCESS_DENIED: raise EJclCreateProcessError.CreateRes(@RsCreateProcAccessDenied); else raise EJclCreateProcessError.CreateRes(@RsCreateProcLogonFailed); end; end; // Step 3: give the new user access to the current WindowStation and Desktop hWindowStation:= GetProcessWindowStation; WinStaName := GetUserObjectName(hWindowStation); if WinStaName = '' then WinStaName := CreateProcDEFWINSTATION; if not SetUserObjectFullAccess(hWindowStation) then begin CloseHandle(hUserToken); raise EJclCreateProcessError.CreateResFmt(@RsCreateProcSetStationSecurityError, [WinStaName]); end; hDesktop := GetThreadDesktop(GetCurrentThreadId); DesktopName := GetUserObjectName(hDesktop); if DesktopName = '' then DesktopName := CreateProcDEFDESKTOP; if not SetUserObjectFullAccess(hDesktop) then begin CloseHandle(hUserToken); raise EJclCreateProcessError.CreateResFmt(@RsCreateProcSetDesktopSecurityError, [DesktopName]); end; // Step 4: set the startup info for the new process ConsoleTitle := UserDomain + UserName; ResetMemory(StartUpInfo, SizeOf(StartUpInfo)); with StartUpInfo do begin cb:= SizeOf(StartUpInfo); lpTitle:= PChar(ConsoleTitle); Help := WinStaName + '\' + DeskTopName; lpDesktop:= PChar(Help); end; // Step 5: create the child process if not CreateProcessAsUser(hUserToken, nil, PChar(CommandLine), nil, nil, False, CREATE_NEW_CONSOLE or CREATE_NEW_PROCESS_GROUP, Environment, nil, {$IFDEF FPC} @StartUpInfo, @ProcInfo) then {$ELSE ~FPC} StartUpInfo, ProcInfo) then {$ENDIF ~FPC} begin case GetLastError of ERROR_PRIVILEGE_NOT_HELD: raise EJclCreateProcessError.CreateResFmt(@RsCreateProcPrivilegesMissing, [GetPrivilegeDisplayName(SE_ASSIGNPRIMARYTOKEN_NAME), SE_ASSIGNPRIMARYTOKEN_NAME, GetPrivilegeDisplayName(SE_INCREASE_QUOTA_NAME), SE_INCREASE_QUOTA_NAME]); ERROR_FILE_NOT_FOUND: raise EJclCreateProcessError.CreateResFmt(@RsCreateProcCommandNotFound, [CommandLine]); else raise EJclCreateProcessError.CreateRes(@RsCreateProcFailed); end; end; // clean up CloseWindowStation(hWindowStation); CloseDesktop(hDesktop); CloseHandle(hUserToken); // if this code should be called although there has // been an exception during invocation of CreateProcessAsUser, // it will quite surely fail. you should make sure this doesn't happen. // (it shouldn't happen due to the use of exceptions in the above lines) CloseHandle(ProcInfo.hThread); CloseHandle(ProcInfo.hProcess); end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:37 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