CreateProcessAsUser/CreateProcessWithLogon
2005-09-28 10:10 i269 [permalink]
Pre-Windows 2000 versions have a function call CreateProcessAsUser available, but this requires the SeTcbPrivilege, which only the local Administrator account have (and the local SYSTEM account, but not user accounts in the Administrators group). So this first method only works with the local administrator account:procedure SetPrivilege(th:THandle;pn:string);Since Windows 2000, advapi32.dll also has a CreateProcessWithLogonW function call, which doesn't require you to have the SeTcbPrivilege. Using this call, the above code can be condesed to this: (Delphi 6 doesn't have this function call declared, so the declaration is included here)
var
tp:TTokenPrivileges;
tpc:cardinal;
begin
tpc:=0;
tp.PrivilegeCount:=1;
tp.Privileges[0].Attributes:=SE_PRIVILEGE_ENABLED;
if not(LookupPrivilegeValue('',PChar(pn),tp.Privileges[0].Luid)) then RaiseLastOSError;
if not(AdjustTokenPrivileges(th,false,tp,SizeOf(tp),nil,tpc)) then RaiseLastOSError;
end;
procedure RunAs(Logon,Pwd,Domain,App:string);
var
th:THandle;
si:TStartupInfo;
pi:TProcessInformation;
begin
if not(OpenProcessToken(GetCurrentProcess,
TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY or TOKEN_ASSIGN_PRIMARY,th)) then RaiseLastOSError;
SetPrivilege(th,'SeTcbPrivilege');
SetPrivilege(th,'SeAssignPrimaryTokenPrivilege');
SetPrivilege(th,'SeIncreaseQuotaPrivilege');
CloseHandle(th);
if not(LogonUser(
PChar(Logon),PChar(Domain),PChar(Pwd),
LOGON32_LOGON_INTERACTIVE,LOGON32_PROVIDER_DEFAULT,th)) then RaiseLastOSError;
try
ZeroMemory(@si,sizeof(si));
si.cb:=sizeof(si);
si.dwFlags:=STARTF_USESHOWWINDOW;
si.wShowWindow:=SW_NORMAL;
ZeroMemory(@pi,sizeof(pi));
if not(CreateProcessAsUserW(th,nil,PWideChar(WideString(App)),
nil,nil,false,0,nil,nil,si,pi)) then RaiseLastOSError;
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
finally
CloseHandle(th);
end;
end;
function CreateProcessWithLogonW(
lpUsername: PWideChar;lpDomain: PWideChar;lpPassword: PWideChar;
dwLogonFlags: DWORD; lpApplicationName: PWideChar;
lpCommandLine: PWideChar; dwCreationFlags: DWORD; lpEnvironment: Pointer; lpCurrentDirectory: PWideChar;
const lpStartupInfo: TStartupInfo; var lpProcessInformation: TProcessInformation): BOOL; stdcall;
const
LOGON_WITH_PROFILE =$00000001;
LOGON_NETCREDENTIALS_ONLY =$00000002;
LOGON_ZERO_PASSWORD_BUFFER =$80000000;
function CreateProcessWithLogonW; external 'advapi32.dll' name 'CreateProcessWithLogonW';
procedure RunAs(Logon,Pwd,Domain,App:string);
var
si:TStartupInfo;
pi:TProcessInformation;
begin
ZeroMemory(@si,sizeof(si));
si.cb:=sizeof(si);
si.dwFlags:=STARTF_USESHOWWINDOW;
si.wShowWindow:=SW_NORMAL;
ZeroMemory(@pi,sizeof(pi));
if not(CreateProcessWithLogonW(
PWideChar(WideString(Logon)),
PWideChar(WideString(Domain)),
PWideChar(WideString(Pwd)),LOGON_WITH_PROFILE,nil,
PWideChar(WideString(App)),
0,nil,nil,si,pi)) then RaiseLastOSError;
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
end;