Доброго времени суток мастера!
Мне нужно запустить приложение от имени другого пользователя. Я скачал готовый модуль, текст которого приведен ниже:
unit xAdvAPI;
interface
uses
Windows;
const
LOGON_WITH_PROFILE = $00000001;
LOGON_NETCREDENTIALS_ONLY = $00000002;
LOGON_ZERO_PASSWORD_BUFFER = $80000000;
procedure CreateUserProcess(Command: string;
const UserName: WideString;
const Password: WideString;
const Title: WideString = '';
const Domain: WideString = '';
LogonFlags: DWORD = LOGON_WITH_PROFILE
);
function CreateProcessWithLogonW(const lpUsername: PWideChar;
const lpDomain: PWideChar; const lpPassword: PWideChar;
dwLogonFlags: DWORD; const lpApplicationName: PWideChar;
lpCommandLine: PWideChar; dwCreationFlags: DWORD;
lpEnvironment: Pointer; const lpCurrentDirectory: PWideChar;
lpStartupInfo: PStartupInfo;
lpProcessInfo: PProcessInformation): Boolean; stdcall;
implementation
uses
SysUtils;
type
TCreateProcessWithLogonW =
function(const lpUsername: PWideChar;
const lpDomain: PWideChar; const lpPassword: PWideChar;
dwLogonFlags: DWORD; const lpApplicationName: PWideChar;
lpCommandLine: PWideChar; dwCreationFlags: DWORD;
lpEnvironment: Pointer; const lpCurrentDirectory: PWideChar;
lpStartupInfo: PStartupInfo;
lpProcessInfo: PProcessInformation): Boolean; stdcall;
const
DllName = 'advapi32.dll';
var
DllHandle: THandle;
_CreateProcessWithLogonW: TCreateProcessWithLogonW;
function InitLib: Boolean;
begin
if DllHandle = 0 then
if Win32Platform = VER_PLATFORM_WIN32_NT then
begin
DllHandle := LoadLibrary(DllName);
if DllHandle <> 0 then
begin
@_CreateProcessWithLogonW := GetProcAddress(DllHandle,
'CreateProcessWithLogonW');
end;
end;
Result := (DllHandle <> 0);
end;
function NotImplementedBool: Boolean;
begin
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
Result := false;
end;
function CreateProcessWithLogonW(const lpUsername: PWideChar;
const lpDomain: PWideChar; const lpPassword: PWideChar;
dwLogonFlags: DWORD; const lpApplicationName: PWideChar;
lpCommandLine: PWideChar; dwCreationFlags: DWORD;
lpEnvironment: Pointer; const lpCurrentDirectory: PWideChar;
lpStartupInfo: PStartupInfo;
lpProcessInfo: PProcessInformation): Boolean; stdcall;
begin
if InitLib and Assigned(_CreateProcessWithLogonW) then
Result := _CreateProcessWithLogonW(lpUsername, lpDomain, lpPassword,
dwLogonFlags, lpApplicationName, lpCommandLine, dwCreationFlags,
lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInfo)
else
Result := NotImplementedBool;
end;
procedure CreateUserProcess(Command: string;
const UserName: WideString;
const Password: WideString;
const Title: WideString = '';
const Domain: WideString = '';
LogonFlags: DWORD = LOGON_WITH_PROFILE
);
var
MyStartupInfo: STARTUPINFO;
ProcessInfo: PROCESS_INFORMATION;
CommandLine: array[0..512] of WideChar;
begin
FillChar(MyStartupInfo, SizeOf(MyStartupInfo), 0);
MyStartupInfo.cb := SizeOf(MyStartupInfo);
StringToWideChar(Command, CommandLine,
Sizeof(CommandLine) div SizeOf(WideChar));
MyStartupInfo.lpTitle := PWideChar(Title);
if not CreateProcessWithLogonW(PWideChar(UserName), PWideChar(Domain),
PWideChar(Password), LogonFlags, nil,
CommandLine, 0, nil, nil, @MyStartupInfo, @ProcessInfo)
then
begin
RaiseLastWin32Error();
Exit;
end
else
begin
CloseHandle(ProcessInfo.hProcess);
CloseHandle(ProcessInfo.hThread);
end;
end;
initialization
finalization
if DllHandle <> 0 then
FreeLibrary(DllHandle);
end.
Все хорошо работает за исключение того, что приложение не запускается если учетная запись не имеет пароля. У меня собственно вопрос: это вообще не возможно или я не правильно использую вызов ф-ции. С паролем я вызываю ф-цию следующим образом:
CreateUserProcess('notepad', 'root', 'pass', '', '');
Без пароля вызывал по разному (естесвенно предварительно убрав пароль с учетной записи):
CreateUserProcess('notepad', 'root', '', '', '', LOGON_ZERO_PASSWORD_BUFFER );
и так
CreateUserProcess('notepad', 'root', nil, '', '', LOGON_ZERO_PASSWORD_BUFFER );
и без
LOGON_ZERO_PASSWORD_BUFFER вызывал, меняется только ошибка... Заранее спасибо!