Как запустить программу от имени пользователя
От: Maxus  
Дата: 26.07.02 09:42
Оценка:
CreateProcessWithLogonW работает (гружу из библиотеки advapi32.dll), но почему-то работает с любым именем пользователя и паролем. Все процессы создает от моего имени (пользователя в данный момент залогинившегося в систему). Почему? Кто знает?
Что-то я не так делаю?

Подскажите, плз.
Re: Как запустить программу от имени пользователя
От: Алекс Россия http://wise-orm.com
Дата: 26.07.02 10:32
Оценка:
Здравствуйте Maxus, Вы писали:

M>CreateProcessWithLogonW работает (гружу из библиотеки advapi32.dll), но почему-то работает с любым именем пользователя и паролем. Все процессы создает от моего имени (пользователя в данный момент залогинившегося в систему). Почему? Кто знает?

M>Что-то я не так делаю?

M>Подскажите, плз.


Что значит
работает с любым именем пользователя и паролем
Непонятно! Приведи код.
Re[2]: Как запустить программу от имени пользователя
От: Maxus  
Дата: 26.07.02 10:46
Оценка:
Здравствуйте Алекс, Вы писали:

А>Что значит

А>работает с любым именем пользователя и паролем
А>Непонятно! Приведи код.

{skiped}
type
FCreateProc = function (
lpUsername: PChar; // user's name
lpDomain: PChar; // user's domain
lpPassword: PChar; // user's password
dwLogonFlags: DWORD; // logon option
lpApplicationName: PWideChar; // executable module name
lpCommandLine: PWideChar; // command-line string
dwCreationFlags: DWORD; // creation flags
lpEnvironment: Pointer; // new environment block
lpCurrentDirectory: PChar; // current directory name
const lpStartupInfo: TStartupInfo;
var lpProcessInformation: TProcessInformation) : Boolean; stdcall;

procedure TForm1.Button1Click(Sender: TObject);
var
si: TStartUpInfo;
pi: TProcessInformation;
ShowWnd: WORD;
Succ: Boolean;
dwIndex: DWORD;
i: Integer;
begin

{skiped}


dl:=LoadLibrary('advapi32.dll');
@CreateProc:=GetProcAddress(dl,'CreateProcessWithLogonW');
res:=CreateProc(
'User', // user's name
nil, // user's domain
'xxxx', // user's password
$00000002, // logon option
'C:\logon.exe', // executable module name
'C:\logon.exe', // command-line string
CREATE_DEFAULT_ERROR_MODE or NORMAL_PRIORITY_CLASS, // creation flags
nil, // new environment block
nil, // current directory name
si, // startup information
pi // process information
);
E:=GetLastError;

end;

Ввожу люое имя пользователя и пароль — запускается от моего имени.
Re[3]: Как запустить программу от имени пользователя
От: vasketsov Россия http://ntprog.by.ru
Дата: 26.07.02 11:07
Оценка:
Здравствуйте Maxus, Вы писали:

M>Здравствуйте Алекс, Вы писали:


А>>Что значит

А>>работает с любым именем пользователя и паролем
А>>Непонятно! Приведи код.

M>{skiped}

M>type
M> FCreateProc = function (
M> lpUsername: PChar; // user's name
M> lpDomain: PChar; // user's domain
M> lpPassword: PChar; // user's password
M> dwLogonFlags: DWORD; // logon option
M> lpApplicationName: PWideChar; // executable module name
M> lpCommandLine: PWideChar; // command-line string
M> dwCreationFlags: DWORD; // creation flags
M> lpEnvironment: Pointer; // new environment block
M> lpCurrentDirectory: PChar; // current directory name
M> const lpStartupInfo: TStartupInfo;
M> var lpProcessInformation: TProcessInformation) : Boolean; stdcall;

По-моему функция неправильно описана.

BOOL CreateProcessWithLogonW(
LPCWSTR lpUsername, // user's name
LPCWSTR lpDomain, // user's domain
LPCWSTR lpPassword, // user's password
DWORD dwLogonFlags, // logon option
LPCWSTR lpApplicationName, // executable module name
LPWSTR lpCommandLine, // command-line string
DWORD dwCreationFlags, // creation flags
LPVOID lpEnvironment, // new environment block
LPCWSTR lpCurrentDirectory, // current directory name
LPSTARTUPINFOW lpStartupInfo, // startup information
LPPROCESS_INFORMATION lpProcessInfo // process information
);

на паскаль переводится так:

type
FCreateProc = function (
lpUsername: PWideChar; // user's name
lpDomain: PWideChar; // user's domain
lpPassword: PWideChar; // user's password
dwLogonFlags: DWORD; // logon option
lpApplicationName: PWideChar; // executable module name
lpCommandLine: PWideChar; // command-line string
dwCreationFlags: DWORD; // creation flags
lpEnvironment: Pointer; // new environment block
lpCurrentDirectory: PWideChar; // current directory name
lpStartupInfo: PStartupInfoW;
lpProcessInformation: PProcessInformation) : int; stdcall;


lpCommandLine: LPWSTR — а у тебя константа, нельзя так делать.
Васкецов Сергей
http://registry.km.ru
Re[4]: Как запустить программу от имени пользователя
От: Maxus  
Дата: 26.07.02 11:20
Оценка:
Здравствуйте vasketsov, Вы писали:


V>По-моему функция неправильно описана.


V>на паскаль переводится так:


V>type

V> FCreateProc = function (
V> lpUsername: PWideChar; // user's name
V> lpDomain: PWideChar; // user's domain
V> lpPassword: PWideChar; // user's password
V> dwLogonFlags: DWORD; // logon option
V> lpApplicationName: PWideChar; // executable module name
V> lpCommandLine: PWideChar; // command-line string
V> dwCreationFlags: DWORD; // creation flags
V> lpEnvironment: Pointer; // new environment block
V> lpCurrentDirectory: PWideChar; // current directory name
V> lpStartupInfo: PStartupInfoW;
V> lpProcessInformation: PProcessInformation) : int; stdcall;


V>lpCommandLine: LPWSTR — а у тебя константа, нельзя так делать.


Дык у меня константа и lpCommandLine и lpApplicationName, а они обе у меня описаны как PWideChar. Однако запускается же приложение. Вот только все время от моего имени (того кто сейчас находится в системе), а надо от другого.
Re[5]: Как запустить программу от имени пользователя
От: vasketsov Россия http://ntprog.by.ru
Дата: 26.07.02 11:22
Оценка:
Здравствуйте Maxus, Вы писали:

M>Здравствуйте vasketsov, Вы писали:



V>>По-моему функция неправильно описана.


V>>на паскаль переводится так:


V>>type

V>> FCreateProc = function (
V>> lpUsername: PWideChar; // user's name
V>> lpDomain: PWideChar; // user's domain
V>> lpPassword: PWideChar; // user's password
V>> dwLogonFlags: DWORD; // logon option
V>> lpApplicationName: PWideChar; // executable module name
V>> lpCommandLine: PWideChar; // command-line string
V>> dwCreationFlags: DWORD; // creation flags
V>> lpEnvironment: Pointer; // new environment block
V>> lpCurrentDirectory: PWideChar; // current directory name
V>> lpStartupInfo: PStartupInfoW;
V>> lpProcessInformation: PProcessInformation) : int; stdcall;


V>>lpCommandLine: LPWSTR — а у тебя константа, нельзя так делать.


M>Дык у меня константа и lpCommandLine и lpApplicationName, а они обе у меня описаны как PWideChar. Однако запускается же приложение. Вот только все время от моего имени (того кто сейчас находится в системе), а надо от другого.


Это не я придумал, откройте MSDN и посмотрите, хотя бы msdn.microsoft.com
Там это английским по белому написано.
И первые параметры, в частности, юзер — не PCHAR.
Васкецов Сергей
http://registry.km.ru
Re[6]: Как запустить программу от имени пользователя
От: Maxus  
Дата: 26.07.02 11:27
Оценка:
Здравствуйте vasketsov, Вы писали:

V>Это не я придумал, откройте MSDN и посмотрите, хотя бы msdn.microsoft.com

V>Там это английским по белому написано.
V>И первые параметры, в частности, юзер — не PCHAR.

Да я признателен за советы. Сейчас попробовал вот так:

type
FCreateProc = function (
lpUsername: PWideChar; // user's name
lpDomain: PWideChar; // user's domain
lpPassword: PWideChar; // user's password
dwLogonFlags: DWORD; // logon option
lpApplicationName: PWideChar; // executable module name
lpCommandLine: PWideChar; // command-line string
dwCreationFlags: DWORD; // creation flags
lpEnvironment: Pointer; // new environment block
lpCurrentDirectory: PWideChar; // current directory name
const lpStartupInfo: TStartupInfo;
var lpProcessInformation: TProcessInformation) : Boolean; stdcall;


{skiped}

var
UserName,Paswd: PWideChar;

{skiped}

procedure TForm1.Button1Click(Sender: TObject);
var
si: TStartUpInfo;
pi: TProcessInformation;
ShowWnd: WORD;
Succ: Boolean;
dwIndex: DWORD;
i: Integer;
begin

{skiped}

UserName:='User';
Paswd:='xxxx';
dl:=LoadLibrary('advapi32.dll');
@CreateProc:=GetProcAddress(dl,'CreateProcessWithLogonW');
res:=CreateProc(
UserName, // user's name
nil, // user's domain
Paswd, // user's password
$00000002, // logon option
'C:\logon.exe', // executable module name
'C:\logon.exe', // command-line string
CREATE_DEFAULT_ERROR_MODE or NORMAL_PRIORITY_CLASS, // creation flags
nil, // new environment block
nil, // current directory name
si, // startup information
pi // process information
);
E:=GetLastError;

end;

Все равно не помогает.
Re[7]: Как запустить программу от имени пользователя
От: vasketsov Россия http://ntprog.by.ru
Дата: 26.07.02 11:37
Оценка:
Здравствуйте Maxus, Вы писали:

M> 'C:\logon.exe', // executable module name

M> 'C:\logon.exe', // command-line string

Вы как, вообще понимаете что вам пишут?
CommandLine либо NULL либо НЕ константа, а переменная.
Для тех, кто в танке.

lpCommandLine
[in] Pointer to a null-terminated string that specifies the command line to execute.
This function will fail if this parameter is a const string.

The lpCommandLine parameter can be NULL. In that case, the function uses the string pointed to by lpApplicationName as the command line.
Васкецов Сергей
http://registry.km.ru
Re[8]: Как запустить программу от имени пользователя
От: Maxus  
Дата: 26.07.02 11:41
Оценка: -1
Здравствуйте vasketsov, Вы писали:

V>Вы как, вообще понимаете что вам пишут?

V>CommandLine либо NULL либо НЕ константа, а переменная.
V>Для тех, кто в танке.

V>lpCommandLine

V>[in] Pointer to a null-terminated string that specifies the command line to execute.
V>This function will fail if this parameter is a const string.

V>The lpCommandLine parameter can be NULL. In that case, the function uses the string pointed to by lpApplicationName as the command line.



Я нормально понимаюто, что мне пишут. Все это уже попробовано. То, что я это здесь не привел прошу не считать пробелом в знаниях и неумением читать хелп.
Re[9]: Как запустить программу от имени пользователя
От: vasketsov Россия http://ntprog.by.ru
Дата: 26.07.02 11:49
Оценка: 18 (1)
Здравствуйте Maxus, Вы писали:

M>Здравствуйте vasketsov, Вы писали:


V>>Вы как, вообще понимаете что вам пишут?

V>>CommandLine либо NULL либо НЕ константа, а переменная.
V>>Для тех, кто в танке.

V>>lpCommandLine

V>>[in] Pointer to a null-terminated string that specifies the command line to execute.
V>>This function will fail if this parameter is a const string.

V>>The lpCommandLine parameter can be NULL. In that case, the function uses the string pointed to by lpApplicationName as the command line.



M>Я нормально понимаюто, что мне пишут. Все это уже попробовано. То, что я это здесь не привел прошу не считать пробелом в знаниях и неумением читать хелп.


Все, я пас.
Написали правильно формат функции — "не заметил" последние параметры как были бредовые, так и остались, вообще, различаете структуру и указатель на нее?
сказано не писать константу — пишешь.

вот специально проверил — все работает нормально, если писать нормально.
Васкецов Сергей
http://registry.km.ru
Re[10]: Как запустить программу от имени пользователя
От: Maxus  
Дата: 26.07.02 11:52
Оценка:
Здравствуйте vasketsov, Вы писали:

V>Все, я пас.

V>Написали правильно формат функции — "не заметил" :???: последние параметры как были бредовые, так и остались, вообще, различаете структуру и указатель на нее?
V>сказано не писать константу — пишешь.
V> :crash: :crash: :crash:
V>вот специально проверил — все работает нормально, если писать нормально.


Блин! Да писал я "нормально". Просто уже после того как отправил то сообщение!!!!!!!!
Может поделитесь тогда куском кода (вызова функции)?
Re[10]: Как запустить программу от имени пользователя
От: Maxus  
Дата: 26.07.02 12:03
Оценка: -1
Здравствуйте vasketsov, Вы писали:


V>Все, я пас.

V>Написали правильно формат функции — "не заметил" :???: последние параметры как были бредовые, так и остались, вообще, различаете структуру и указатель на нее?


Если Вы имеете в виду последние параметры, то это только в в С++ на ставить &. В Дельфи, для танкистов ;-), не надо получать указатель на структуру — это делается автоматически! Если я поставлю & перед последними параметрами мне выдастся сообщение что праметры formal и actuаl не совпадают.
Re[11]: Как запустить программу от имени пользователя
От: vasketsov Россия http://ntprog.by.ru
Дата: 26.07.02 12:06
Оценка:
Здравствуйте Maxus, Вы писали:

M>Здравствуйте vasketsov, Вы писали:



V>>Все, я пас.

V>>Написали правильно формат функции — "не заметил" последние параметры как были бредовые, так и остались, вообще, различаете структуру и указатель на нее?


M>Если Вы имеете в виду последние параметры, то это только в в С++ на ставить &. В Дельфи, для танкистов , не надо получать указатель на структуру — это делается автоматически! Если я поставлю & перед последними параметрами мне выдастся сообщение что праметры formal и actuаl не совпадают.


Пусть есть функция, которая принимает на вход LARGE_INTEGER (это 8 байт)
И есть другая, которая хочет указатель PLARGE_INTEGER (это 4 байта).
И те и другие есть, и немало.
Как тогда отличить их вызов?
Васкецов Сергей
http://registry.km.ru
Re[12]: Как запустить программу от имени пользователя
От: Maxus  
Дата: 26.07.02 12:10
Оценка:
Здравствуйте vasketsov, Вы писали:


V>Пусть есть функция, которая принимает на вход LARGE_INTEGER (это 8 байт)

V>И есть другая, которая хочет указатель PLARGE_INTEGER (это 4 байта).
V>И те и другие есть, и немало.
V>Как тогда отличить их вызов?

OK!! Special for you!

l:=LoadLibrary('advapi32.dll');
@CreateProc:=GetProcAddress(dl,'CreateProcessWithLogonW');
res:=CreateProc(
UserName, // user's name
nil, // user's domain
Paswd, // user's password
$00000002, // logon option
FileName, // executable module name
CmdLine, // command-line string
CREATE_DEFAULT_ERROR_MODE or NORMAL_PRIORITY_CLASS, // creation flags
nil, // new environment block
nil, // current directory name
@si, // startup information
@pi // process information
);
E:=GetLastError;

Пишет:
Incompatible types _STARTUPINFOA and Pointer
Types of actual and formal parameters must be identical.

Что и требовалось доказать.

Дельфи автоматически в функцию передвет указатель. Здесь не надо подходяить с точки зрения С++.
Re[13]: Как запустить программу от имени пользователя
От: vasketsov Россия http://ntprog.by.ru
Дата: 26.07.02 12:14
Оценка:
Здравствуйте Maxus, Вы писали:

M>Incompatible types _STARTUPINFOA and Pointer


Что здесь делает STARTUPINFOA ???
Васкецов Сергей
http://registry.km.ru
Re[14]: Как запустить программу от имени пользователя
От: Maxus  
Дата: 26.07.02 12:19
Оценка:
Здравствуйте vasketsov, Вы писали:

M>>Incompatible types _STARTUPINFOA and Pointer


V>Что здесь делает STARTUPINFOA ???


То есть как это что?! Мы с Вами говорим про последние параметры?

si, // startup information
pi // process information

Так они у меня определены.

si: TStartUpInfo;
pi: TProcessInformation;

А уж в Windows.pas это указатели на структуру. Потому и не надо ставить & перед нимим когда передаем их в функцию.

//windows.pas

PStartupInfo = ^TStartupInfo;
TStartupInfo = record
cb: Longint;
lpReserved: Pointer;
lpDesktop: Pointer;
lpTitle: Pointer;
dwX: Longint;
dwY: Longint;
dwXSize: Longint;
dwYSize: Longint;
dwXCountChars: Longint;
dwYCountChars: Longint;
dwFillAttribute: Longint;
dwFlags: Longint;
wShowWindow: Word;
cbReserved2: Word;
lpReserved2: ^Byte;
hStdInput: Integer;
hStdOutput: Integer;
hStdError: Integer;
end;
Re[14]: Как запустить программу от имени пользователя
От: Maxus  
Дата: 26.07.02 12:22
Оценка:
Здравствуйте vasketsov, Вы писали:

M>>Incompatible types _STARTUPINFOA and Pointer


V>Что здесь делает STARTUPINFOA ???


Да собсно не о том речь. Было бы что-то не то в параметрах — функция бы выдавала False и код ошибки, то ведь выдает True и 0. Процесс-то запускается!
Re[15]: Как запустить программу от имени пользователя
От: vasketsov Россия http://ntprog.by.ru
Дата: 26.07.02 12:23
Оценка:
Здравствуйте Maxus, Вы писали:

M>si: TStartUpInfo;


M>PStartupInfo = ^TStartupInfo;

M> TStartupInfo = record
M> cb: Longint;
M> lpReserved: Pointer;
M> lpDesktop: Pointer;
M> lpTitle: Pointer;
M> dwX: Longint;
M> dwY: Longint;
M> dwXSize: Longint;
M> dwYSize: Longint;
M> dwXCountChars: Longint;
M> dwYCountChars: Longint;
M> dwFillAttribute: Longint;
M> dwFlags: Longint;
M> wShowWindow: Word;
M> cbReserved2: Word;
M> lpReserved2: ^Byte;
M> hStdInput: Integer;
M> hStdOutput: Integer;
M> hStdError: Integer;
M> end;


И здесь si — это указатель на структуру?
Указатель будет PStartupInfo, в ПРАВИЛЬНО описанную функцию (а не как у вас) надо передавать @si
Васкецов Сергей
http://registry.km.ru
Re[16]: Как запустить программу от имени пользователя
От: Maxus  
Дата: 26.07.02 12:25
Оценка:
Здравствуйте vasketsov, Вы писали:

V>Здравствуйте Maxus, Вы писали:



V>И здесь si — это указатель на структуру? :no: :no: :no:

V>Указатель будет PStartupInfo, в ПРАВИЛЬНО описанную функцию (а не как у вас) надо передавать @si

Я же Вам писал, что получается когда так пишем.


Incompatible types _STARTUPINFOA and Pointer
Types of actual and formal parameters must be identical.


Это Дельфи. Она сама это все делает. Здесь переменная, когда ее передаешь в функцию — это указаетель на нее.
Re[16]: Как запустить программу от имени пользователя
От: Maxus  
Дата: 26.07.02 12:26
Оценка:
Здравствуйте vasketsov, Вы писали:


V>И здесь si — это указатель на структуру? :no: :no: :no:

V>Указатель будет PStartupInfo, в ПРАВИЛЬНО описанную функцию (а не как у вас) надо передавать @si

windows.pas

{$EXTERNALSYM _STARTUPINFOA}
TStartupInfo = _STARTUPINFOA;
Re[16]: Как запустить программу от имени пользователя
От: Maxus  
Дата: 26.07.02 12:32
Оценка:
Здравствуйте vasketsov, Вы писали:

V>Здравствуйте Maxus, Вы писали:


M>>si: TStartUpInfo;


M>>PStartupInfo = ^TStartupInfo;

M>> TStartupInfo = record
M>> cb: Longint;
M>> lpReserved: Pointer;
M>> lpDesktop: Pointer;
M>> lpTitle: Pointer;
M>> dwX: Longint;
M>> dwY: Longint;
M>> dwXSize: Longint;
M>> dwYSize: Longint;
M>> dwXCountChars: Longint;
M>> dwYCountChars: Longint;
M>> dwFillAttribute: Longint;
M>> dwFlags: Longint;
M>> wShowWindow: Word;
M>> cbReserved2: Word;
M>> lpReserved2: ^Byte;
M>> hStdInput: Integer;
M>> hStdOutput: Integer;
M>> hStdError: Integer;
M>> end;


V>И здесь si — это указатель на структуру? :no: :no: :no:

V>Указатель будет PStartupInfo, в ПРАВИЛЬНО описанную функцию (а не как у вас) надо передавать @si

windows.pas

PStartupInfo = ^TStartupInfo;
_STARTUPINFOA = record
cb: DWORD;
lpReserved: Pointer;
lpDesktop: Pointer;
lpTitle: Pointer;
dwX: DWORD;
dwY: DWORD;
dwXSize: DWORD;
dwYSize: DWORD;
dwXCountChars: DWORD;
dwYCountChars: DWORD;
dwFillAttribute: DWORD;
dwFlags: DWORD;
wShowWindow: Word;
cbReserved2: Word;
lpReserved2: PByte;
hStdInput: THandle;
hStdOutput: THandle;
hStdError: THandle;
end;
Re[16]: Как запустить программу от имени пользователя
От: Maxus  
Дата: 26.07.02 12:52
Оценка:
Здравствуйте vasketsov, Вы писали:

Ктстати говоря...
Что CreateProcessWithLogonW за меня и юзера в windowstation и desktop добавит?
Раньше все это руками приходилось делать. МОжет в этом дело? Моет надо в si добавлять инфу про того юзера от которого запускаем?
Re[5]: Как запустить программу от имени пользователя
От: Vi2 Удмуртия http://www.adem.ru
Дата: 26.07.02 12:58
Оценка:
Здравствуйте Maxus:

Только из уважения как к новичку форума.

Есть же разница в описании функции, а не в передаче параметров. Я вот не понимаю в Pascal-е ни бум-бум, и то ясно

Твой Maxus вариант
type 
 FCreateProc = function ( 
 lpUsername: PChar; // user's name 
 lpDomain: PChar; // user's domain 
 lpPassword: PChar; // user's password 
 dwLogonFlags: DWORD; // logon option 
 lpApplicationName: PWideChar; // executable module name 
 lpCommandLine: PWideChar; // command-line string 
 dwCreationFlags: DWORD; // creation flags 
 lpEnvironment: Pointer; // new environment block 
 lpCurrentDirectory: PChar; // current directory name 
 const lpStartupInfo: TStartupInfo; 
 var lpProcessInformation: TProcessInformation) : Boolean; stdcall;

и от vasketsov-а вариант
type 
 FCreateProc = function ( 
 lpUsername: PWideChar; // user's name 
 lpDomain: PWideChar; // user's domain 
 lpPassword: PWideChar; // user's password 
 dwLogonFlags: DWORD; // logon option 
 lpApplicationName: PWideChar; // executable module name 
 lpCommandLine: PWideChar; // command-line string 
 dwCreationFlags: DWORD; // creation flags 
 lpEnvironment: Pointer; // new environment block 
 lpCurrentDirectory: PWideChar; // current directory name 
 lpStartupInfo: PStartupInfoW; 
 lpProcessInformation: PProcessInformation) : int; stdcall;


У тебя вместо указателей описАны структуры.
Ребята! Вместо того чтобы ставить 0 отметили бы где ошибка — и вопрос м.б. был бы решён.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re: Как запустить программу от имени пользователя
От: ZZ  
Дата: 27.07.02 14:22
Оценка: 18 (1)
Я не очень понял, решили вы тут проблему или нет Поэтому предложу вариант

type
TCreateProcessWithLogonW = function(
lpUsername : PWideChar;
lpDomain : PWideChar;
lpPassword : PWideChar;
dwLogonFlags : DWORD;
lpApplicationName : PWideChar;
lpCommandLine : PWideChar;
dwCreationFlags : DWORD;
lpEnvironment : Pointer;
lpCurrentDirectory : PWideChar;
const lpStartupInfo : _STARTUPINFOA;
var lpProcessInfo : PROCESS_INFORMATION):BOOL;stdcall;

procedure TForm1.Button1Click(Sender: TObject);
var hLib:THandle;
CreateProcessWithLogon : TCreateProcessWithLogonW;
si : _STARTUPINFOA;
pi : Process_Information;
begin
hLib:=LoadLibrary('advapi32.dll');
ZeroMemory(@Si,Sizeof(si));
si.cb:=SizeOf(si);
CreateProcessWithLogon:=GetProcAddress(hLib,'CreateProcessWithLogonW');

CreateProcessWithLogon('login',nil,'password',1,nil,'cmd.exe',0,nil,nil,si,pi);

end;
Re[2]: Как запустить программу от имени пользователя
От: SergH Россия  
Дата: 27.07.02 14:52
Оценка:
Здравствуйте ZZ, Вы писали:

ZZ>Я не очень понял, решили вы тут проблему или нет Поэтому предложу вариант


ZZ>type

ZZ> TCreateProcessWithLogonW = function(
ZZ> lpUsername : PWideChar;
ZZ> lpDomain : PWideChar;
ZZ> lpPassword : PWideChar;
ZZ> dwLogonFlags : DWORD;
ZZ> lpApplicationName : PWideChar;
ZZ> lpCommandLine : PWideChar;
ZZ> dwCreationFlags : DWORD;
ZZ> lpEnvironment : Pointer;
ZZ> lpCurrentDirectory : PWideChar;
ZZ> const lpStartupInfo : _STARTUPINFOA;
ZZ> var lpProcessInfo : PROCESS_INFORMATION):BOOL;stdcall;

ZZ>procedure TForm1.Button1Click(Sender: TObject);

ZZ>var hLib:THandle;
ZZ> CreateProcessWithLogon : TCreateProcessWithLogonW;
ZZ> si : _STARTUPINFOA;
ZZ> pi : Process_Information;
ZZ>begin
ZZ> hLib:=LoadLibrary('advapi32.dll');
ZZ> ZeroMemory(@Si,Sizeof(si));
ZZ> si.cb:=SizeOf(si);
ZZ> CreateProcessWithLogon:=GetProcAddress(hLib,'CreateProcessWithLogonW');

ZZ> CreateProcessWithLogon('login',nil,'password',1,nil,'cmd.exe',0,nil,nil,si,pi);


ZZ>end;


Ты чисто теоретически предлагаешь, или это у тебя заработало? Если первое — тебя сейчас забьёт vasketsov и будет совершенно прав, т.к. ни один из его советов (обобщённых Vi2, но он тебя, наверное, трогать не будет, т.к. более терпелив) ты не учёл. Если второе — скорее всего произошло чудо, попробуй запустить ещё раз. Если всё равно получилось — дико извиняюсь за наглый тон, видимо чего-то я сильно не понимаю.
Делай что должно, и будь что будет
Re[3]: Как запустить программу от имени пользователя
От: ZZ  
Дата: 27.07.02 16:27
Оценка:
Здравствуйте SergH, Вы писали:

SH>Здравствуйте ZZ, Вы писали:


ZZ>>Я не очень понял, решили вы тут проблему или нет Поэтому предложу вариант


ZZ>>type

ZZ>> TCreateProcessWithLogonW = function(
ZZ>> lpUsername : PWideChar;
ZZ>> lpDomain : PWideChar;
ZZ>> lpPassword : PWideChar;
ZZ>> dwLogonFlags : DWORD;
ZZ>> lpApplicationName : PWideChar;
ZZ>> lpCommandLine : PWideChar;
ZZ>> dwCreationFlags : DWORD;
ZZ>> lpEnvironment : Pointer;
ZZ>> lpCurrentDirectory : PWideChar;
ZZ>> const lpStartupInfo : _STARTUPINFOA;
ZZ>> var lpProcessInfo : PROCESS_INFORMATION):BOOL;stdcall;

ZZ>>procedure TForm1.Button1Click(Sender: TObject);

ZZ>>var hLib:THandle;
ZZ>> CreateProcessWithLogon : TCreateProcessWithLogonW;
ZZ>> si : _STARTUPINFOA;
ZZ>> pi : Process_Information;
ZZ>>begin
ZZ>> hLib:=LoadLibrary('advapi32.dll');
ZZ>> ZeroMemory(@Si,Sizeof(si));
ZZ>> si.cb:=SizeOf(si);
ZZ>> CreateProcessWithLogon:=GetProcAddress(hLib,'CreateProcessWithLogonW');

ZZ>> CreateProcessWithLogon('login',nil,'password',1,nil,'cmd.exe',0,nil,nil,si,pi);


ZZ>>end;


SH>Ты чисто теоретически предлагаешь, или это у тебя заработало? Если первое — тебя сейчас забьёт vasketsov и будет совершенно прав, т.к. ни один из его советов (обобщённых Vi2, но он тебя, наверное, трогать не будет, т.к. более терпелив) ты не учёл. Если второе — скорее всего произошло чудо, попробуй запустить ещё раз. Если всё равно получилось — дико извиняюсь за наглый тон, видимо чего-то я сильно не понимаю.


Чисто практически. Не уверен только в 4 параметре "запускаемой"(не описания)(но с 1 он лучше смотрится
Может объяснишь, что тут не так?? Или ты тоже Delphi никогда не видел и "в pascalе ни бумбум" (ничего личного, просто подозреваю о чем речь). А всю дискуссию я не читал, только первые и последние сообщения....
Re[4]: Как запустить программу от имени пользователя
От: SergH Россия  
Дата: 28.07.02 22:59
Оценка:
Здравствуйте ZZ, Вы писали:

ZZ>Чисто практически.


Значит, заработало?

ZZ>Не уверен только в 4 параметре "запускаемой"(не описания)(но с 1 он лучше смотрится :))

ZZ>Может объяснишь, что тут не так??

В конце.

ZZ>Или ты тоже Delphi никогда не видел и "в pascalе ни бумбум" (ничего личного, просто подозреваю о чем речь).


Видел, но давно. И бумбум, но тоже давно. Могу ошибаться.

ZZ> А всю дискуссию я не читал, только первые и последние сообщения.... :(


Напрасно.

Пытаюсь объяснить, что тут по-моему не так.

1. В правильном прототипе функции последние два параметра — указатели. В твоём прототипе последний параметр наверное будет указателем (точно не знаю, но вроде должен из-за var), но предпоследний — нет. И передаёшь ты его не как указатель. (Или delphi сама его преобразует?)

2. В правильном прототипе не STARTUPINFOA, а STARTUPINFOW

3. В параметр lpCommandLine нельзя передавать константную строку. http://msdn.microsoft.com/library/en-us/dllproc/prothred_2gl3.asp — описание CreateProcessWithLogonW,

lpCommandLine
[in] Pointer to a null-terminated string that specifies the command line to execute.
This function will fail if this parameter is a const string.


ты передаёшь 'cmd.exe'. Возможно, delphi размещает такие строки в куче (или ещё где-то), но сомневаюсь.
Делай что должно, и будь что будет
Re[6]: Как запустить программу от имени пользователя
От: Maxus  
Дата: 29.07.02 05:39
Оценка:
Здравствуйте Vi2, Вы писали:

Vi2> lpStartupInfo: PStartupInfoW;


А где взять описание именно этой структуры (у меня в заголовках только _StartupInfoA)?

Vi2>У тебя вместо указателей описАны структуры.

Vi2>Ребята! Вместо того чтобы ставить 0 отметили бы где ошибка — и вопрос м.б. был бы решён.

Сделал указатели. Все равно та же хрень.
Есть мысль насчет того что в StartupInfoW должен передаваться указатель на desktop и windowstation для того юзера которого мы логиним. А он у меня nil перед вызовом функции CreateProcessWithLogonW. Как сказано в MSDN, в статье
INFO: CreateProcessAsUser, Windowstations and Desktops :

When a process is launched via the CreateProcessAsUser API, the process will be launched into a windowstation and desktop combination based on the value of lpDesktop in the STARTUPINFO structure parameter. If a windowstation and desktop combination is specified in the lpDesktop member, the system will attempt to launch the process into that windowstation and desktop. If the lpDesktop member is initialized to NULL, the system will attempt to use the same windowstation and desktop as the calling process. If it is initialized with the empty string, "", the system will either create a new invisible windowstation and desktop or if one has been created via a prior call using the same access token, the existing windowstation and desktop will be used.

Так что мысль такая — надо как и вслучае использования CreateProcessAsUser давать доступ юзеру к десктопу и виндоустэйшну (получим указатель) и передавать его в структуру PStartupInfoW перед вызовом CreateProcessWithLogonW. Или CreateProcessWithLogonW сама должна все сделать?

Кто, что думает по этому поводу?
Re[5]: Как запустить программу от имени пользователя
От: ZZ  
Дата: 29.07.02 06:53
Оценка:
ZZ>>Чисто практически.

SH>Значит, заработало?


Ага

ZZ>>Не уверен только в 4 параметре "запускаемой"(не описания)(но с 1 он лучше смотрится

ZZ>>Может объяснишь, что тут не так??

SH>В конце.


Я так и подумал

SH>1. В правильном прототипе функции последние два параметра — указатели. В твоём прототипе последний параметр наверное будет указателем (точно не знаю, но вроде должен из-за var), но предпоследний — нет. И передаёшь ты его не как указатель. (Или delphi сама его преобразует?)


По моему, const и var — Это и есть "указатели"

SH>2. В правильном прототипе не STARTUPINFOA, а STARTUPINFOW


Знаю, но STARTUPINFOW в Windows.pas нету ( А самому описывать было лень... Но — SizeOf(STARTUPINFOA)=SizeOf(STARTUPINFOW) Или нет?? А в самих параметрах нет ни одной строки (ни ANSI ни Unicode) => разницы нет.

SH>3. В параметр lpCommandLine нельзя передавать константную строку. http://msdn.microsoft.com/library/en-us/dllproc/prothred_2gl3.asp — описание CreateProcessWithLogonW,


SH>lpCommandLine

SH>[in] Pointer to a null-terminated string that specifies the command line to execute.
SH>This function will fail if this parameter is a const string.


SH>ты передаёшь 'cmd.exe'. Возможно, delphi размещает такие строки в куче (или ещё где-то), но сомневаюсь.

А вот черт его знает, но поверь наслово — работает (если очень хочешь, могу выслать ехе, хотя врядли ты рискнешь его запустить
Re[7]: Как запустить программу от имени пользователя
От: SergH Россия  
Дата: 29.07.02 06:55
Оценка:
Здравствуйте Maxus, Вы писали:

Vi2>> lpStartupInfo: PStartupInfoW;


M>А где взять описание именно этой структуры (у меня в заголовках только _StartupInfoA)?


Это странно. Неужели delphi не поддерживает unicode? Но в любом случае они почти обинаковы, нужно прото поменять все обычные строки на unicod-ные строки.

Vi2>>У тебя вместо указателей описАны структуры.

Vi2>>Ребята! Вместо того чтобы ставить 0 отметили бы где ошибка — и вопрос м.б. был бы решён.

M>Сделал указатели. Все равно та же хрень.

M>Есть мысль насчет того что в StartupInfoW должен передаваться указатель на desktop и windowstation для того юзера которого мы логиним. А он у меня nil перед вызовом функции CreateProcessWithLogonW. Как сказано в MSDN, в статье
M>INFO: CreateProcessAsUser, Windowstations and Desktops :

M>When a process is launched via the CreateProcessAsUser API, the process will be launched into a windowstation and desktop combination based on the value of lpDesktop in the STARTUPINFO structure parameter. If a windowstation and desktop combination is specified in the lpDesktop member, the system will attempt to launch the process into that windowstation and desktop. If the lpDesktop member is initialized to NULL, the system will attempt to use the same windowstation and desktop as the calling process. If it is initialized with the empty string, "", the system will either create a new invisible windowstation and desktop or if one has been created via a prior call using the same access token, the existing windowstation and desktop will be used.


M>Так что мысль такая — надо как и вслучае использования CreateProcessAsUser давать доступ юзеру к десктопу и виндоустэйшну (получим указатель) и передавать его в структуру PStartupInfoW перед вызовом CreateProcessWithLogonW. Или CreateProcessWithLogonW сама должна все сделать?


M>Кто, что думает по этому поводу?


Я не думаю, я пробую

Если из под админа попытаться запустить обычного юзера, функция вернёт TRUE, но созданное приложение не запустится, выскочит исключение — ты бы не пропустил этот момент.

Админ из под админа запускается.

Если в четвёртом параметре передать не LOGON_WITH_PROFILE (1), а LOGON_NETCREDENTIALS_ONLY (2), то ситуация похожа на то, что ты описываешь:
— функция GetUserName из запушенного приложения всегда возвращает моё имя
— приложение запускается не зависимо от содержимого параметров lpUsername, lpDomain и lpPassword.

Если кто-нибудь объяснит мне, в чём смысл этого режима, буду сильно благодарен.
Делай что должно, и будь что будет
Re[6]: Как запустить программу от имени пользователя
От: Maxus  
Дата: 29.07.02 06:59
Оценка:
Здравствуйте ZZ, Вы писали:


SH>>2. В правильном прототипе не STARTUPINFOA, а STARTUPINFOW


ZZ>Знаю, но STARTUPINFOW в Windows.pas нету :(( А самому описывать было лень... Но — SizeOf(STARTUPINFOA)=SizeOf(STARTUPINFOW) Или нет?? А в самих параметрах нет ни одной строки (ни ANSI ни Unicode) => разницы нет.


Вот и я поэтому спросил — чем отличаются эти структуры?! В STARTUPINFOW нет никаких строк.
Re[6]: Как запустить программу от имени пользователя
От: SergH Россия  
Дата: 29.07.02 07:02
Оценка:
Здравствуйте ZZ, Вы писали:

ZZ>По моему, const и var — Это и есть "указатели"


про const не знал, спасибо.

SH>>2. В правильном прототипе не STARTUPINFOA, а STARTUPINFOW


ZZ>Знаю, но STARTUPINFOW в Windows.pas нету ( А самому описывать было лень... Но — SizeOf(STARTUPINFOA)=SizeOf(STARTUPINFOW) Или нет?? А в самих параметрах нет ни одной строки (ни ANSI ни Unicode) => разницы нет.


Ну да, действительно.

SH>>3. В параметр lpCommandLine нельзя передавать константную строку. http://msdn.microsoft.com/library/en-us/dllproc/prothred_2gl3.asp — описание CreateProcessWithLogonW,


SH>>lpCommandLine

SH>>[in] Pointer to a null-terminated string that specifies the command line to execute.
SH>>This function will fail if this parameter is a const string.


SH>>ты передаёшь 'cmd.exe'. Возможно, delphi размещает такие строки в куче (или ещё где-то), но сомневаюсь.

ZZ>А вот черт его знает, но поверь наслово — работает

У меня тоже работает. Странно. Помню CreateProcessW у меня падала, когда я ей константу передовал.

ZZ>(если очень хочешь, могу выслать ехе, хотя врядли ты рискнешь его запустить


Да я доверчивый... Но не надо, я и сам попробовал.


Ещё раз извиняюсь за первоночальные сомнения в твоей профессиональности.
Делай что должно, и будь что будет
Re[8]: Как запустить программу от имени пользователя
От: Maxus  
Дата: 29.07.02 07:05
Оценка:
Здравствуйте SergH, Вы писали:


SH>Это странно. Неужели delphi не поддерживает unicode? Но в любом случае они почти обинаковы, нужно прото поменять все обычные строки на unicod-ные строки.


Конечно поддерживает. Однако в windows.pas такой структуры нет.
Кроме того в STARTUPINFOА нет никаких строк, что бы они были в UNICODE. Спращивается нахрена она вообще такая нужна — вполне хватит и STARTUPINFOA?

M>>Так что мысль такая — надо как и вслучае использования CreateProcessAsUser давать доступ юзеру к десктопу и виндоустэйшну (получим указатель) и передавать его в структуру PStartupInfoW перед вызовом CreateProcessWithLogonW. Или CreateProcessWithLogonW сама должна все сделать?

SH>Я не думаю, я пробую :)

Я тоже! Щас пробую реализовать свою мысль — вручную проделать добавление пользователя к десктопу и винстэйшну, а потом эти указатели передать в STARTUPINFOA. Пока не получается.

SH>Если из под админа попытаться запустить обычного юзера, функция вернёт TRUE, но созданное приложение не запустится, выскочит исключение — ты бы не пропустил этот момент.


Вот потому я и думаю, что CreateProcessWithLogonW не выполняет все "добавки" автоматически.

SH>Админ из под админа запускается.


SH>Если в четвёртом параметре передать не LOGON_WITH_PROFILE (1), а LOGON_NETCREDENTIALS_ONLY (2), то ситуация похожа на то, что ты описываешь:

SH>- функция GetUserName из запушенного приложения всегда возвращает моё имя
SH>- приложение запускается не зависимо от содержимого параметров lpUsername, lpDomain и lpPassword.

Ага! Точно. У меня именно этот параметр установлен.
Такой вопрос. А если указывать LOGON_WITH_PROFILE , надо еще делать LoadUserProfile, да?

SH>Если кто-нибудь объяснит мне, в чём смысл этого режима, буду сильно благодарен.


Аналогично.
Re[9]: Как запустить программу от имени пользователя
От: SergH Россия  
Дата: 29.07.02 07:07
Оценка:
Здравствуйте Maxus, Вы писали:

M>Ага! Точно. У меня именно этот параметр установлен.

M>Такой вопрос. А если указывать LOGON_WITH_PROFILE , надо еще делать LoadUserProfile, да?

Я не делал — всё работало. В Win 2000 Pro.
Делай что должно, и будь что будет
Re[6]: Как запустить программу от имени пользователя
От: vasketsov Россия http://ntprog.by.ru
Дата: 29.07.02 07:45
Оценка:
Здравствуйте ZZ, Вы писали:


ZZ>>>Чисто практически.


ZZ>Знаю, но STARTUPINFOW в Windows.pas нету ( А самому описывать было лень... Но — SizeOf(STARTUPINFOA)=SizeOf(STARTUPINFOW) Или нет?? А в самих параметрах нет ни одной строки (ни ANSI ни Unicode) => разницы нет.


typedef struct _STARTUPINFO {
DWORD cb;
LPTSTR lpReserved;
LPTSTR lpDesktop;
LPTSTR lpTitle;
DWORD dwX;
DWORD dwY;
DWORD dwXSize;
DWORD dwYSize;
DWORD dwXCountChars;
DWORD dwYCountChars;
DWORD dwFillAttribute;
DWORD dwFlags;
WORD wShowWindow;
WORD cbReserved2;
LPBYTE lpReserved2;
HANDLE hStdInput;
HANDLE hStdOutput;
HANDLE hStdError;
} STARTUPINFO, *LPSTARTUPINFO;

Так что разницы нет — весьма условное выражение, верное только если туда nil отдавать.
А вот когда будет вызываться RtlCreateProcessParameters — там уже это не все равно будет, и отлавливание такой ошибки — очень нетривиальный процесс.
sizeof действительно одинаковый, с чего ему разным быть.
А про STARTUPINFO полемика началась, после того как компилер стал ругаться, а в самом начале было неверное описание функции.
Разумеется, последние параметры не при чем, если бы они передавались структурой, была бы ошибка стека какая-нибудь, вплоть до Access Violation. То есть трабла-то в начале была, а именно, если имя юзера nil — запускается под текущим. А там и было nil, первый-то символ для UNICODE тут нулевой.
Васкецов Сергей
http://registry.km.ru
Re[7]: Как запустить программу от имени пользователя
От: Maxus  
Дата: 29.07.02 07:48
Оценка:
ВСЕМ СПАСИБО!!!
ВСЕ РАБОТАЕТ. Не знаю как, но работает.

SH>Админ из под админа запускается.


Поставил LOGON_WITH_PROFILE. Действительно — Админ из под Админа запускается. Попробовал Юзера — говорит "неправильное имя или пароль". Взял удалил пользователя и завел снова. ЗАРАБОТАЛО!!
Хрен знает почему.


Еще раз всем спасибо за мнения и помощь.

Кстати все обошлось — не надо указывать структуру STARTUPINFOW, хватило и STARTUPINFOA.
Re[9]: Ты обязан передать UNICODE
От: Vi2 Удмуртия http://www.adem.ru
Дата: 29.07.02 07:56
Оценка:
Здравствуйте Maxus, Вы писали:

M>Конечно поддерживает. Однако в windows.pas такой структуры нет.

M>Кроме того в STARTUPINFOА нет никаких строк, что бы они были в UNICODE. Спращивается нахрена она вообще такая нужна — вполне хватит и STARTUPINFOA?

typedef struct _STARTUPINFOA {
    DWORD   cb;
    LPSTR   lpReserved;
    LPSTR   lpDesktop;
    LPSTR   lpTitle;
...
} STARTUPINFOA, *LPSTARTUPINFOA;
typedef struct _STARTUPINFOW {
    DWORD   cb;
    LPWSTR  lpReserved;
    LPWSTR  lpDesktop;
    LPWSTR  lpTitle;
...
} STARTUPINFOW, *LPSTARTUPINFOW;


Ведь идёт о WINAPI функции CreateProcessWithLogonW, у неё нет CreateProcessWithLogonA варианта. Т.е. от тебя не зависит, работаешь ты там ANSI или UNICODE, — ты обязан передать UNICODE.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[7]: Как запустить программу от имени пользователя
От: ZZ  
Дата: 29.07.02 12:11
Оценка:
Здравствуйте vasketsov, Вы писали:

V>Здравствуйте ZZ, Вы писали:



ZZ>>>>Чисто практически.


ZZ>>Знаю, но STARTUPINFOW в Windows.pas нету ( А самому описывать было лень... Но — SizeOf(STARTUPINFOA)=SizeOf(STARTUPINFOW) Или нет?? А в самих параметрах нет ни одной строки (ни ANSI ни Unicode) => разницы нет.


V>typedef struct _STARTUPINFO {

V> DWORD cb;
V> LPTSTR lpReserved;
V> LPTSTR lpDesktop;
V> LPTSTR lpTitle;

V>} STARTUPINFO, *LPSTARTUPINFO;


V>Так что разницы нет — весьма условное выражение, верное только если туда nil отдавать.

V>А вот когда будет вызываться RtlCreateProcessParameters — там уже это не все равно будет, и отлавливание такой ошибки — очень нетривиальный процесс.
V>sizeof действительно одинаковый, с чего ему разным быть.
Меня не совсем правильно поняли — Там стояло ZeroMemory() и ничего кроме cb не заполнено и нет ни одной строки => разницы между A и W нет никакой. Если очень надо что-что изменить — пожалуйста переписывай STARTUPINFOW (напомню — в дельфе его вроде как нет).

Ну не буду вам мешать вести интересную полемику продолжайте пожалуйста....
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.