So, habe es jetzt nochmal "mundgerecht" aufgeteilt. Es gibt jetzt eine Wrapperfunktion, der man eine Untermenge der Parameter der ursprünglichen
API übergibt. Optional übergibt man auch einen Environment-Block. Das mit dem optional funktioniert natürlich erst ab Delphi 4, wegen dem Default-Parameter.
Delphi-Quellcode:
(******************************************************************************
Function to wrap around the CreateProcessWithLogon() API
******************************************************************************)
function CreateProcessWithLogonWrapper(
lpUsername: LPCWSTR;
lpDomain: LPCWSTR;
lpPassword: LPCWSTR;
lpApplicationName: LPCWSTR;
lpCommandLine: LPWSTR;
dwCreationFlags: DWORD;
lpEnvironment: LPVOID =
nil
): Boolean;
var
sui: STARTUPINFOW;
pi: PROCESS_INFORMATION;
begin
Result := False;
// Fill sui with zeroes
ZeroMemory(@sui, sizeof(sui));
// Fill size member
sui.cb := sizeof(sui);
// Create process
if (CreateProcessWithLogonW(
lpUsername,
lpDomain,
// Domain
lpPassword,
LOGON_WITH_PROFILE,
// No special options
lpApplicationName,
// Module to execute
lpCommandLine,
// Activates extensions
dwCreationFlags
or CREATE_UNICODE_ENVIRONMENT,
// Only these options for now
lpEnvironment,
nil,
// Use current directory
sui,
// STARTUPINFO
pi
// PROCESS_INFORMATION
))
then
Result := True;
// Return success
end;
(******************************************************************************
Function to get a copy of the current environment.
The returned pointer MUST BE DESTROYED using the DestroyEnvironmentBlock() API.
******************************************************************************)
function GetCurrentEnvironmentBlock(): LPVOID;
var
hToken:
HANDLE;
begin
Result :=
nil;
// Open process token of current process
if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY
or TOKEN_DUPLICATE, hToken))
then
try
// Create copy of current environment block
if (
not CreateEnvironmentBlock(Result, hToken, True))
then
Result :=
nil;
finally
CloseHandle(hToken);
// Close the token of the current process
end;
end;
CreateProcessWithLogonWrapper() ist einfach der besagte Wrapper. Die Parameter entsprechen denen der Orginal-
API insofern vorhanden.
GetCurrentEnvironmentBlock() gibt den Environment-Block des aktuellen Prozesses zurück. Dieser muß danach mit der
API DestroyEnvironmentBlock() wieder zerstört werden. Wird nil zurückgegeben, so war der Aufruf nicht erfolgreich.
Anhang und ausführliche Beschreibung zum Code findet sich hier