function CreateTokenOfProcess(ProcessId: DWORD): THandle;
const
PROCESS_QUERY_LIMITED_INFORMATION = $1000;
var
ProcessHandle, TokenHandle: THandle;
begin
result := 0;
ProcessHandle := 0;
try
ProcessHandle:= OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, True, ProcessId);
if ProcessHandle <> 0 then
begin
if OpenProcessToken(ProcessHandle, TOKEN_QUERY or TOKEN_IMPERSONATE, TokenHandle) then
result := TokenHandle;
// Call CloseHandle(TokenHandle) by caller
end;
finally
CloseHandle(ProcessHandle);
end;
end;
function GetParentProcessID: DWORD;
// This function should be part of the
API!
var
Snap: THandle;
Proc: TProcessEntry32;
CurrentProc: cardinal;
begin
result := 0;
Snap := CreateToolHelp32SnapShot(TH32CS_SNAPALL, 0);
try
CurrentProc := GetCurrentProcessId;
Proc.dwSize := SizeOf(TProcessEntry32);
Process32First(Snap, Proc);
repeat
if Proc.th32ProcessID = CurrentProc then
begin
result := Proc.th32ParentProcessID;
Break;
end;
until (not Process32Next(Snap, Proc));
finally
CloseHandle(Snap);
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
hres: HResult;
Folder: array[0..Max_Path] of Char;
Token: THandle;
begin
Token := CreateTokenOfProcess(GetParentProcessID);
try
hRes := SHGetFolderPath(
Handle, CSIDL_PROGRAMS, Token, SHGFP_TYPE_DEFAULT, Folder);
if not Succeeded(hRes) then
raise
Exception.Create(SysErrorMessage(hRes)));
ShowMessage('SHGetFolderPath Succeeded:' + string(Folder));
finally
CloseHandle(Token);
end;
end;