Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Запуск команды runas [D4, D6, WinXP]


Страницы:   1 2 3

olevacho ©   (2004-10-30 15:56:00) 

Есть в винде ХР команда runas. Она позволяет находясь в системе под одним пользователем  выполнить другую команду или внешнюю программу от имени другого пользователя. Проблемма в том что нужно после запуска вводить пароль другого пользователя вручную. Можно ли сделать прогу на дельфе так чтоб пароль другого пользователя передавался из моей проге команде runas автоматически. А может в дельфе есть какой-нить аналог команды runas ?


GuAV   (2004-10-31 13:35:00) [1]

Игорь Шевченко ©   (31.10.04 13:05) [39]
Честно говоря, страдаю идиосинкразией к слову absolute, не знаю, почему, но факт :)

Ну можно ещё объявить как переменную и установить в initialization или сделать функцией :)
Или вообще так
type
 WIN_BOOL = type DWORD;

const
 WIN_FALSE = 0;
 WIN_TRUE = 1;


GuAV   (2004-10-31 13:15:00) [2]

VMcL ©   (31.10.04 10:35) [38]
Относительно безопасно передачи в качестве параметра, но совершенно не допустимо сравнение или другие операции с константой TRUE. Гарантирована только константа FALSE и правильная работа с ней во всех случаях. В других случаях если требуется работа с TRUE оно должно заменяться на arg <> FALSE


В принципе, сравнивать в С я смысла вообще не вижу.
В Delphi есть смысл сравнивать, например хэндлы или указатели, чтобы избежать необходимости приведения типов. Ptr <> nil почему-то лучше чем BOOL(Ptr).
Но сравнивают действительно не Handle = 1, а Handle <> 0, иначе просто не работает.

Что интересно, в отличии от С, в Delphi есть защита от этих граблей
см. код в [18].
В С различается логическое и побитное and or not. Почему же нет такого xor и сравения ?


Игорь Шевченко   (2004-10-31 13:05:00) [3]

GuAV ©   (31.10.04 02:10) [30]


> Работает так:
>
> const
>  WIN_TRUE_VALUE: LongWord = 1;
> var
>  WIN_TRUE: BOOL absolute WIN_TRUE_VALUE;


Честно говоря, страдаю идиосинкразией к слову absolute, не знаю, почему, но факт :)


VMcL   (2004-10-31 10:35:00) [4]

>> Defunct ©  (31.10.04 02:23) [32]
> хотя в общем с вами согласен, проверка с 1 это клиника.
>> GuAV ©  (31.10.04 02:33) [33]
> Вы представляете, с этим и я согласен.

Вот и я пытался объяснить alena.svt © здесь:
http://www.delphimaster.ru/cgi-bin/forum.pl?id=1099061998&n=0
Только как горохом об стенку. Дело вкуса, дело вкуса, блин. За такие вкусы надо к стенке и расстреливать... из водяного пистолета :-)


Anatoly Podgoretsky   (2004-10-31 09:57:00) [5]

VMcL ©   (31.10.04 02:07) [29]
Вот на подобных методах работы пострадало много программистов, когда сменилось определение контстанты TRUE в языке или возвращаемое значение из ОС.
Это пример опасного программирования, который выявляется не в момент написания, а иногда только несколько лет спустя.

Относительно безопасно передачи в качестве параметра, но совершенно не допустимо сравнение или другие операции с константой TRUE. Гарантирована только константа FALSE и правильная работа с ней во всех случаях. В других случаях если требуется работа с TRUE оно должно заменяться на arg <> FALSE


GuAV   (2004-10-31 02:49:00) [6]

Defunct ©   (31.10.04 2:36) [35]
мда.. не зря некоторые говорили масдай..

Ну я же перезапустил. Поэтому Хэндлы другие и сами окна другие. А значение ISWindow видимо больше чем просто BOOL, имеет физический смысл :-))


Defunct   (2004-10-31 02:36:00) [7]

> Позакрывал немонго окон. Ещё раз результат.

мда.. не зря некоторые говорили масдай..


GuAV   (2004-10-31 02:34:00) [8]

GuAV ©   (31.10.04 2:33) [33]
Позакрывал немонго окон. Ещё раз результат.

Забыл сказать, что перезапустил - иначе хэндлы бы не поменялись, конечно.


GuAV   (2004-10-31 02:33:00) [9]


> скорее там будет 255 не так ли?

Не так.
function IsWindowInt(hWnd: HWND): Integer; stdcall; external
user32 name 'IsWindow';

procedure TForm1.Button1Click(Sender: TObject);
begin
Memo1.Lines.Add(Format('%.8X %.8X', [Handle, IsWindowInt(Handle)]));
with Application do
Memo1.Lines.Add(Format('%.8X %.8X', [Handle, IsWindowInt(Handle)]));
end;


Результат.
00000A48 82198090
00000A20 82198EF8


Позакрывал немонго окон. Ещё раз результат.
0000046C 821999A4
00000770 82199C7C


И где-то так же для других функций.


> хотя в общем с вами согласен, проверка с 1 это клиника.

Вы представляете, с этим и я согласен.


Defunct   (2004-10-31 02:23:00) [10]

GuAV ©   (31.10.04 02:13) [31]
> Такое значение может вернуть BOOL-функция в 9х.

Я очень в этом сомневаюсь.
скорее там будет 255 не так ли?

У вас w98 скажите често, что возвращает функция?

VMcL ©   (31.10.04 02:07) [29]
чаще видел:
if a != 0 {...}
if a == 0 {...}
реже видел:
if a != 1 {...}

хотя в общем с вами согласен, проверка с 1 это клиника.


GuAV   (2004-10-31 02:13:00) [11]

VMcL ©   (31.10.04 2:07) [29]
Неудачный пример. Byte(256) = 0.


Именно об этом речь. Такое значение может вернуть BOOL-функция в 9х. DWord не равен 0, а байт - равен.


> С точностью до наоборот: 4, 2 и 1.

угу.


> Кхм. Обычно пишут что-то типа "этот оператор не
> выполнится". А то как-то непонятно, кто выпадет,
> откуда и куда

ок. "этот оператор не выполнится".


GuAV   (2004-10-31 02:10:00) [12]


>const WIN_TRUE=BOOL(1);

Идея хорошая но не работает !

Работает так:

const
 WIN_TRUE_VALUE: LongWord = 1;
var
 WIN_TRUE: BOOL absolute WIN_TRUE_VALUE;


VMcL   (2004-10-31 02:07:00) [13]

>> GuAV ©  (31.10.04 01:39) [28]

> Для совместимости с другими языками введены ещё три логических типа - LongBool, WordBool и ByteBool. Размер их соответственно 1, 2 и 4 байта.

С точностью до наоборот: 4, 2 и 1.

> function b3: boolean;

Неудачный пример. Byte(256) = 0.

> // выпадет

Кхм. Обычно пишут что-то типа "этот оператор не выполнится". А то как-то непонятно, кто выпадет, откуда и куда.

>> Игорь Шевченко ©  (30.10.04 23:24) [20]

> Причем, внутри этих функций (Enumxxxx) стоит сравнение с именно с единицей, а не с неким "ненулевым значением".

Вот яркий пример людей, который вместо
if (a) {...}
и
if (!a) {...}
пишут
if (a == TRUE) {...}
и
if (a == FALSE) {...}
соотвественно.

Повбывав бы :-)


GuAV   (2004-10-31 01:39:00) [14]

Какая разница между Boolean и BOOL ?
Как использовать внешние функции, работающие с логическими значениями ?

В Borland Delphi основным логическим типом является boolean. Длина его 1 байт. Если этот байт равен единице, то значение логического типа - истина, если нулю, то ложь. Другие значения являются недопустимыми, и их использование может привести к неожиданным результатам. Пример неожиданных результатов:

function b1: boolean;
asm
mov eax, 4 //недопустимое значение
end;

function b2: boolean;
asm
mov eax, 1
end;

function b3: boolean;
asm
mov eax, 256 //недопустимое значение
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
if b1 = b2 then showmessage('b1 = b2'); // не выпадет
if b3 then showmessage('b3'); // не выпадет
end;

Для совместимости с другими языками введены ещё три логических типа - LongBool, WordBool и ByteBool. Размер их соответственно 1, 2 и 4 байта. LongBool значение - истинна если LongWord не равен 0 и ложь если равен 0. Для WordBool и ByteBool соответсвенно Word и Byte.

Для типа LongBool приведенный выше пример работает, т.к. значения 4 (не допустимые для Boolean) и 256 (не соответсвующее разрядности Boolean) будут истиной для LongBool

function b1: LongBool;
asm
mov eax, 4
end;

function b2: LongBool;
asm
mov eax, 1
end;

function b3: LongBool;
asm
mov eax, 256
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
if b1 = b2 then showmessage('b1 = b2'); // выпадет
if b3 then showmessage('b3'); // выпадет
end;


Константам True типов LongBool, WordBool и ByteBool соответствуют значения $FFFFFFFF, $FFFF и $FF.

Логические операции над Boolean эффективнее, чем над XxxxBool, т.к. сводятся к соответствующим побитным операциям. Кроме того Boolean упорядочен, ord(False)=0 ord(True)=1. Поэтому предпочтительно использовать Boolean.

В 32-разрядной Windows принят 32-разрядный логический тип, с ненулевым значением в качестве истины. Причём в win9x это ненулевое значение произвольно, однако, начиная с Windows 2000, оно строго равно единице.

В Delphi этот тип объявлен как   type BOOL = LongBool;

Так, следующее объявление было бы не корректно в 9х:

function IsWindow(hWnd: HWND): Boolean; stdcall; external
user32 name 'IsWindow';


Однако, оно корректно в 2000, поскольку при приведении LongWord к Byte отсекаются страшие байты, и следовательно если LongWord был равен 1, то и Byte будет равен 1, аналогично c 0.

Для всех ОС подойдёт такое объявление:

function IsWindow(hWnd: HWND): BOOL; stdcall; external
user32 name 'IsWindow';

Для функций появившихся в Windows 2000 оба объявления корректны. Поэтому, исходя из того, что Boolean предпочтительнее в Delphi их лучше объявлять с результатом Boolean.

Теперь о передаче параметров. Как сообщалось ранее, в Windows принят 32-разрядный логический тип, с ненулевым значением в качестве истины. Т.е. вроде бы любое значение не равное нулю  должно сойти за истину. Однако есть функции, которые требуют, чтобы в качестве "любого значение не равное нулю" передавалась единица. Т. е. константа True = $FFFFFFFF не подойдёт. Использовать Boolean тоже не следует, т.к. старшие 3 байта будут не определены и при попытке передать False может передаваться значение отличное от 0, что тоже может иметь негативные последствия. Решение - или объявлять этот параметр как DWORD или использовать константу

const WIN_TRUE=BOOL(1);


GuAV   (2004-10-31 00:17:00) [15]


> function BoolToWin(B: ByteBool): BOOL; overload;


> function BoolToWin(B: WordBool): BOOL; overload;

С этими точнее как я написал не получится - надо так:
function BoolToWin(B: ByteBool): BOOL; overload;
asm
TEST AL, AL
SETNZ AL
AND  EAX, 00000001h
end;

function BoolToWin(B: WordBool): BOOL; overload;
asm
TEST AX, AX
SETNZ AL
AND  EAX, 00000001h
end;


GuAV   (2004-10-31 00:09:00) [16]

или не, во как:

function BoolToWin(B: Boolean): BOOL; overload;
asm
AND  EAX, 00000001h
end;

function BoolToWin(B: ByteBool): BOOL; overload;
asm
TEST AL, AL
JZ   @@Exit
MOV  EAX, 00000001h
@@Exit:
end;

function BoolToWin(B: WordBool): BOOL; overload;
asm
TEST AX, AX
JZ   @@Exit
MOV  EAX, 00000001h
@@Exit:
end;

function BoolToWin(B: LongBool): BOOL; overload;
asm
TEST EAX, EAX
JZ   @@Exit
MOV  EAX, 00000001h
@@Exit:
end;


GuAV   (2004-10-31 00:04:00) [17]

Игорь Шевченко ©   (30.10.04 23:50) [22]
WinBOOL

const
 WIN_NT_FALSE = BOOL(0);
 WIN_NT_TRUE = BOOL(1);

function BoolToWin(B: Boolean): BOOL; overload;
asm
 AND  EAX, 00000001h
end;

{
function BoolToWin(B: BOOL): BOOL; overload;
asm
 TEST EAX, EAX
 SETNZ AL
 AND  EAX, 00000001h
end;
}

function BoolToWin(B: BOOL): BOOL; overload;
asm
 TEST EAX, EAX
 JZ   @@Exit
 MOV  EAX, 00000001h
 @@Exit:
end;


Игорь Шевченко   (2004-10-31 00:00:00) [18]

GuAV ©   (30.10.04 23:55) [23]

Есть функции, которые честно сравнивают результат с нулем, и все от него отличное, интерпретируют как True, для примера, EnumWindows, EnumWindowStations и т.п.


GuAV   (2004-10-30 23:55:00) [19]

Игорь Шевченко ©   (30.10.04 23:24) [20]

Интересно, а есть ли вообще функции winapi, принимающие BOOL(-1) ?

И смотрите как пишут:
как результат - zero или nonzero
как пеарметр - TRUE или FALSE.


Игорь Шевченко   (2004-10-30 23:50:00) [20]

GuAV ©   (30.10.04 23:34) [21]


> Опять же рекомендую не Boolean, а
> const BOOL_TRUE = BOOL(1);


Я нашел альтернативный выход, но идея хорошая. Только я бы назвал не BOOL_TRUE, а MsBOOL или WinBOOL :)


> И может выводы из этой ветки поместить например в FAQ ?


Да, поддерживаю.


Страницы:   1 2 3

Наверх

Титульная страница Поиск, карта сайта Написать письмо