const
SE_SECURITY_NAME = 'SeSecurityPrivilege';
PROC_THREAD_ATTRIBUTE_PARENT_PROCESS = $00020000;
EXTENDED_STARTUPINFO_PRESENT = $00080000;
type
PPROC_THREAD_ATTRIBUTE_LIST = Pointer;
STARTUPINFOEX = packed record
StartupInfo: TStartupInfo;
lpAttributeList: PPROC_THREAD_ATTRIBUTE_LIST;
end;
PSTARTUPINFOEX = ^STARTUPINFOEX;
function InitializeProcThreadAttributeList(lpAttributeList: PPROC_THREAD_ATTRIBUTE_LIST; dwAttributeCount, dwFlags: DWORD; var lpSize: Cardinal): Boolean; stdcall; external 'kernel32.dll';
function UpdateProcThreadAttribute(lpAttributeList: PPROC_THREAD_ATTRIBUTE_LIST; dwFlags, Attribute: DWORD; var pValue: DWORD; cbSize: Cardinal; pPreviousValue: Pointer; pReturnSize: PCardinal): BOOL; stdcall; external 'kernel32.dll';
procedure DeleteProcThreadAttributeList(lpAttributeList: PPROC_THREAD_ATTRIBUTE_LIST); stdcall; external 'Kernel32.dll';
function GetProcessId(FileName: String): DWORD;
var
proc: TProcessEntry32;
hSysSnapshot: THandle;
begin
proc.dwSize := SizeOf(TProcessEntry32);
hSysSnapshot:= CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSysSnapshot <> INVALID_HANDLE_VALUE) and Process32First(hSysSnapshot, proc) then
begin
repeat
if SameText(String(proc.szExeFile), FileName) then
begin
Result:= proc.th32ProcessID;
break;
end;
until not (Process32Next(hSysSnapshot, proc));
end;
CloseHandle(hSysSnapshot);
end;
function EnablePrivilege(name: String; Enable: boolean = true): boolean;
var
hToken: Cardinal;
priv: TOKEN_PRIVILEGES;
begin
priv.PrivilegeCount:= 1;
priv.Privileges[0].Attributes:= 0;
if Enable then priv.Privileges[0].Attributes:= SE_PRIVILEGE_ENABLED;
LookupPrivilegeValue(nil, PCHAR(name), priv.Privileges[0].Luid);
OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES, hToken);
AdjustTokenPrivileges (hToken, FALSE, priv, sizeof(priv), nil, PDWORD(nil)^);
Result:= (GetLastError = ERROR_SUCCESS);
CloseHandle (hToken);
end;
function CreateChildProcess(ExeName, ParentProcess: string): BOOL;
var
pi: TProcessInformation;
si: STARTUPINFOEX;
Size: Cardinal;
hParent: Cardinal;
begin
Result:= false;
EnablePrivilege(SE_SECURITY_NAME, True);
FillChar(si, SizeOf(si), 0);
si.StartupInfo.cb := SizeOf(si);
// si.StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
// si.StartupInfo.wShowWindow := SW_SHOWDEFAULT;
FillChar(pi, SizeOf(pi), 0);
Size := 0;
InitializeProcThreadAttributeList(nil, 1, 0, Size);
si.lpAttributeList:= HeapAlloc(GetProcessHeap(), 0, Size);
InitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, Size);
hParent := OpenProcess(PROCESS_ALL_ACCESS, False, GetProcessID(ParentProcess));
UpdateProcThreadAttribute(si.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, hParent, sizeof(hParent), nil, nil);
if CreateProcess(nil, PChar(ExeName), nil, nil, False, EXTENDED_STARTUPINFO_PRESENT, nil, nil, (PSTARTUPINFO(@si))^, pi) then
begin
Result:= true;
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
end;
DeleteProcThreadAttributeList(si.lpAttributeList);
HeapFree(GetProcessHeap(), 0, si.lpAttributeList);
end;