├── .gitignore
├── CONFIG.txt
├── AltRun.chm
├── altrun.chm
├── altrun.ico
├── altrun.res
├── README.md
├── altrun.lpi
├── altrun.lpr
├── AltExt.pas
├── AltStream.pas
├── AltExe.inc
├── AltSys.pas
├── AltUnit.pas
├── AltCmd.pas
└── altrun.lps
/.gitignore:
--------------------------------------------------------------------------------
1 | /backup
2 | /lib
3 | /*.exe
4 |
--------------------------------------------------------------------------------
/CONFIG.txt:
--------------------------------------------------------------------------------
1 | --run=altrun.chm
2 | --maximize
--------------------------------------------------------------------------------
/AltRun.chm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lostzombie/AltRun/HEAD/AltRun.chm
--------------------------------------------------------------------------------
/altrun.chm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lostzombie/AltRun/HEAD/altrun.chm
--------------------------------------------------------------------------------
/altrun.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lostzombie/AltRun/HEAD/altrun.ico
--------------------------------------------------------------------------------
/altrun.res:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lostzombie/AltRun/HEAD/altrun.res
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # AltRun
2 | AltRun - это прикладной лаунчер настраиваемый через ключи запуска
3 |
4 | Основные функции:
5 |
6 | запуск программ, скриптов, пакетных файлов, открытие файлов в ассоциированных программах (далее цели запуска)
7 |
8 | передача параметров запуска и рабочего каталога запускаемому процессу
9 |
10 | запуск альтернативных целей при удерживании клавиш CTRL, ALT, SHIFT или правой кнопки мыши (далее ПКМ)
11 |
12 | запуск дополнительных программ/скриптов до/после запуска основной цели
13 |
14 | запуск дополнительных программ/скриптов вместо запуска основной цели при её отсутствии или при наличии/отсутствии файла/папки триггера
15 |
16 | запрос прав администратора или подавление этого запроса
17 |
18 | запуск со свёрнутым или развёрнутым окном, скрытие окна
19 |
20 | системная блокировка клавиатуры/мыши на время запуска
21 |
22 | назначение переменных среды запускаемому процессу
23 |
24 | поддержка относительных путей и переменных среды в пути запуска
25 |
26 | запуск различных целей в зависимости от разрядности операционной системы
27 |
28 | автономный режим (возможность указать ключи запуска altrun в файле конфигурации или непосредственно в ресурсах altrun.exe используя любой редактор ресурсов исполняемых файлов)
29 |
30 | сквозная передача параметров запуска запускаемой программе/скрипту в автономном режиме
31 |
32 | Использование:
33 |
34 | добавление дополнительных функций ярлыкам рабочего стола и кнопкам интерфейса различных программ (например Total Commander), у которых есть возможность их настройки
35 |
36 | создание лаунчеров программ с использованием возможностей cmd/bat, vds, ps (прочих) скриптов для манипуляций с реестром, файлами, переменными среды, параметрами запуска
37 |
38 | создание интеллектуальных лаунчеров для любых скриптов и пакетных файлов
39 |
--------------------------------------------------------------------------------
/altrun.lpi:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
--------------------------------------------------------------------------------
/altrun.lpr:
--------------------------------------------------------------------------------
1 | program altrun;
2 | //{$define DBG}
3 | uses
4 |
5 | AltSys,
6 | AltExt,
7 | AltCmd,
8 | AltUnit;
9 | var
10 | c: longint;
11 | s: ArrStr;
12 | state: TKeyboardState;
13 | short: UnicodeString = '';
14 | long: UnicodeString = '';
15 | shortR: UnicodeString = '';
16 | longR: UnicodeString = '';
17 | run_exist_yes: boolean = False;
18 | run_else_yes: boolean = False;
19 | hp_exist: boolean = False;
20 | hp_else: boolean = False;
21 | msg: longword = 0;
22 | MsgText, Caption: PWidechar;
23 | e, exitcode: longword;
24 | {$IFDEF DBG}
25 | i: longword;
26 | {$ENDIF}
27 | press_not_bind: boolean = False;
28 |
29 | {$R *.res}
30 |
31 | {$INCLUDE AltExe.inc}
32 |
33 | begin
34 | GetKeyboardState(state);
35 | GetAllParams(c, s);
36 | {$IFDEF DBG}
37 | Writeln;
38 | Writeln('Arguments');
39 | Writeln;
40 | {$ENDIF}
41 | WorkAllParams(c, s);
42 | {$IFDEF DBG}
43 | for i := 0 to c - 1 do writeln(s[i]);
44 | Writeln;
45 | {$ENDIF}
46 | Caption := PWideChar(ExtractFileName(s[0]));
47 | if GetUserDefaultLCID = 1049 then MsgText := PWidechar('Запущен другой экземпляр ' + ExtractFileName(s[0]))
48 | else MsgText := PWidechar('Another instance of ' + ExtractFileName(s[0]) + ' started');
49 | if hp(c, s, '1', 'one') then
50 | repeat
51 | Msg := 0;
52 | if HasProcess(s[0], 0, gp(c, s, '1', 'one') = 'name', ExtractFilePath(s[0])) then
53 | if not hp(c, s, '1nm', 'one-no-message') then
54 | begin
55 | Msg := MessageBoxEx(0, MsgText, Caption, $5 + $100 + $00000030, $0000);
56 | end
57 | else halt;
58 | until Msg <> 4;
59 | if Msg = 2 then Halt;
60 | if ((State[vk_Control] and 128) = 0) and ((State[vk_Shift] and 128) = 0) and ((State[vk_Menu] and 128) <> 0) then
61 | if (hp(c, s, 'a', 'alt')) then
62 | begin
63 | short := 'a';
64 | long := alt;
65 | end
66 | else press_not_bind := True;
67 | if ((State[vk_Control] and 128) = 0) and ((State[vk_Shift] and 128) <> 0) and ((State[vk_Menu] and 128) = 0) then
68 | if (hp(c, s, 's', 'shift')) then
69 | begin
70 | short := 's';
71 | long := shift;
72 | end
73 | else press_not_bind := True;
74 | if ((State[vk_Control] and 128) <> 0) and ((State[vk_Shift] and 128) = 0) and ((State[vk_Menu] and 128) = 0) then
75 | if (hp(c, s, 'c', 'ctrl')) then
76 | begin
77 | short := 'c';
78 | long := ctrl;
79 | end
80 | else press_not_bind := True;
81 | if ((State[vk_Control] and 128) = 0) and ((State[vk_Shift] and 128) <> 0) and ((State[vk_Menu] and 128) <> 0) then
82 | if (hp(c, s, 'as', 'alt-shift')) then
83 | begin
84 | short := 'as';
85 | long := alt + hyp + shift;
86 | end
87 | else press_not_bind := True;
88 | if ((State[vk_Control] and 128) <> 0) and ((State[vk_Shift] and 128) = 0) and ((State[vk_Menu] and 128) <> 0) then
89 | if (hp(c, s, 'ca', 'ctrl-alt')) then
90 | begin
91 | short := 'ca';
92 | long := ctrl + hyp + alt;
93 | end
94 | else press_not_bind := True;
95 | if ((State[vk_Control] and 128) <> 0) and ((State[vk_Shift] and 128) <> 0) and ((State[vk_Menu] and 128) = 0) then
96 | if (hp(c, s, 'cs', 'ctrl-shift')) then
97 | begin
98 | short := 'cs';
99 | long := ctrl + hyp + shift;
100 | end
101 | else press_not_bind := True;
102 | if ((State[vk_Control] and 128) <> 0) and ((State[vk_Shift] and 128) <> 0) and ((State[vk_Menu] and 128) <> 0) then
103 | if (hp(c, s, 'cas', 'ctrl-alt-shift')) then
104 | begin
105 | short := 'cas';
106 | long := ctrl + hyp + alt + hyp + shift;
107 | end
108 | else press_not_bind := True;
109 | if ((State[vk_RBUTTON] and 128) <> 0) then
110 | if (hp(c, s, 'rb', 'right-button')) then
111 | begin
112 | short := 'rb';
113 | long := 'right-button';
114 | end
115 | else press_not_bind := True;
116 | if hp(c, s, 'k', 'ignore-keys') then
117 | begin
118 | short:='';
119 | long:='';
120 | press_not_bind := False;
121 | end;
122 | {$IFDEF DBG}
123 | if long<>'' then writeln('pressed keys: ', long);
124 | if press_not_bind then writeln('Pressed keys, but not binded');
125 | writeln;
126 | if not (hp(c, s, 'i', 'ignore-undef-bind')or(Exists(ExtractFilePath(s[0])+'ignore-undef-bind'))) then
127 | if press_not_bind then
128 | begin
129 | writeln('Press Enter');
130 | readln;
131 | end;
132 | {$ENDIF}
133 | if press_not_bind then
134 | if hp(c, s, 'i', 'ignore-undef-bind')or(Exists(ExtractFilePath(s[0])+'ignore-undef-bind')) then
135 | begin
136 | if short = '' then shortR := 'r' else shortR := short;
137 | if long = '' then longR := 'run' else
138 | begin
139 | longR := long;
140 | long := long + '-';
141 | end;
142 | end
143 | else Halt
144 | else
145 | begin
146 | if short = '' then shortR := 'r' else shortR := short;
147 | if long = '' then longR := 'run' else
148 | begin
149 | longR := long;
150 | long := long + '-';
151 | end;
152 | end;
153 |
154 | if (short <> '') or (gp(c, s, 'r', 'run') <> '') then
155 | begin
156 | Caption := PWideChar(ExtractFileName(s[0]));
157 | if GetUserDefaultLCID = 1049 then MsgText := PWidechar('Запущен другой экземпляр ' + gp(c, s, shortR, longR))
158 | else MsgText := PWidechar('Another instance of ' + gp(c, s, shortR, longR) + ' started');
159 | if hp(c, s, short + '1t', long + 'one-target') then
160 | repeat
161 | Msg := 0;
162 | if HasProcess(gp(c, s, shortR, longR), 1, gp(c, s, short + '1t', long + 'one-target') = 'name', ExtractFilePath(s[0])) then
163 | if not hp(c, s, '1nm', 'one-no-message') then Msg := MessageBoxEx(0, MsgText, Caption, $5 + $100 + $00000030, $0000) else halt;
164 | until Msg <> 4;
165 | if Msg = 2 then Halt;
166 | if hp(c, s, short + 'b', long + 'before') then AltExe(c, s, short + 'b', long + 'before', e);
167 | if hp(c, s, short + 'x', long + 'exist') then hp_exist := True;
168 | if hp(c, s, short + 'e', long + 'else') then hp_else := True;
169 | if hp_exist then
170 | begin
171 | if hp(c, s, short + 'x1', long + 'if-exist') and (gp(c, s, short + 'x1', long + 'if-exist') <> '') then if Exists(WorkAltVars(gp(c, s, short + 'x1', long + 'if-exist'), c, s, 1)) then run_exist_yes := True;
172 | if hp(c, s, short + 'x2', long + 'if-exist2') and (gp(c, s, short + 'x2', long + 'if-exist2') <> '') then if Exists(WorkAltVars(gp(c, s, short + 'x2', long + 'if-exist2'), c, s, 1)) then run_exist_yes := True;
173 | if hp(c, s, short + 'x3', long + 'if-exist3') and (gp(c, s, short + 'x3', long + 'if-exist3') <> '') then if Exists(WorkAltVars(gp(c, s, short + 'x3', long + 'if-exist3'), c, s, 1)) then run_exist_yes := True;
174 | if hp(c, s, short + 'nx1', long + 'if-no-exist') and (gp(c, s, short + 'nx1', long + 'if-no-exist') <> '') then if not Exists(WorkAltVars(gp(c, s, short + 'nx1', long + 'if-no-exist'), c, s, 1)) then run_exist_yes := True;
175 | if hp(c, s, short + 'nx2', long + 'if-no-exist2') and (gp(c, s, short + 'nx2', long + 'if-no-exist2') <> '') then if not Exists(WorkAltVars(gp(c, s, short + 'nx2', long + 'if-no-exist2'), c, s, 1)) then run_exist_yes := True;
176 | if hp(c, s, short + 'nx3', long + 'if-no-exist3') and (gp(c, s, short + 'nx3', long + 'if-no-exist3') <> '') then if not Exists(WorkAltVars(gp(c, s, short + 'nx3', long + 'if-no-exist3'), c, s, 1)) then run_exist_yes := True;
177 | if run_exist_yes then AltExe(c, s, short + 'x', long + 'exist', e);
178 | end;
179 | if hp_else then
180 | begin
181 | if not Exists(WorkAltVars(gp(c, s, shortR, longR), c, s, 1)) then run_else_yes := True;
182 | if run_else_yes then AltExe(c, s, short + 'e', long + 'else', e);
183 | end;
184 | if hp(c, s, short + 'u', long + 'rerun') and (run_exist_yes or run_else_yes) then
185 | begin
186 | Sleep(100);
187 | AltExe(c, s, shortR, longR, e);
188 | end;
189 | if not (run_exist_yes or run_else_yes) then AltExe(c, s, shortR, longR, e);
190 | exitcode := e;
191 | if hp(c, s, short + 'f', long + 'after') then AltExe(c, s, short + 'f', long + 'after', e);
192 | end;
193 | Halt(exitcode);
194 | end.
195 |
--------------------------------------------------------------------------------
/AltExt.pas:
--------------------------------------------------------------------------------
1 | unit AltExt;
2 |
3 | interface
4 |
5 | //uses windows;
6 |
7 | const
8 | fmCreate = $FFFF;
9 | soFromBeginning = 0;
10 | soFromCurrent = 1;
11 | soFromEnd = 2;
12 | VK_RBUTTON = 2;
13 | VK_SHIFT = 16;
14 | VK_CONTROL = 17;
15 | VK_MENU = 18;
16 | SW_HIDE = 0;
17 | SW_MAXIMIZE = 3;
18 | SW_MINIMIZE = 6;
19 | SW_NORMAL = 1;
20 | SW_RESTORE = 9;
21 | SW_SHOW = 5;
22 | kernel32 ='kernel32.dll';
23 | user32='user32.dll';
24 |
25 | type
26 | PChar = ^char;
27 | PWideChar = ^widechar;
28 | PPWideChar = ^PWideChar;
29 | PLongint = ^longint;
30 | PLongWord = ^longword;
31 | PUnicodeChar = ^widechar;
32 | ArrStr = array of UnicodeString;
33 | ArrStrS = array of ShortString;
34 | PIDs = array of longword;
35 |
36 | PHandle_data = ^THandle_data;
37 | THandle_data = record
38 | process_id: longword;
39 | best_handle: longword;
40 | end;
41 |
42 | TKeyboardState = array[0..255] of byte;
43 |
44 | TSHELLEXECUTEINFOW = record
45 | cbSize: longword;
46 | fMask: longword;
47 | wnd: longword;
48 | lpVerb: PWideChar;
49 | lpFile: PWideChar;
50 | lpParameters: PWideChar;
51 | lpDirectory: PWideChar;
52 | nShow: longint;
53 | hInstApp: longword;
54 | lpIDList: pointer;
55 | lpClass: Pwidechar;
56 | hkeyClass: longword;
57 | dwHotKey: longword;
58 | DUMMYUNIONNAME: record
59 | case longint of
60 | 0: (hIcon: longword);
61 | 1: (hMonitor: longword);
62 | end;
63 | hProcess: longword;
64 | end;
65 | LPSHELLEXECUTEINFOW = ^TSHELLEXECUTEINFOW;
66 |
67 | ENUMWINDOWSPROC = function(_para1: longword; _para2: longint): longbool; stdcall;
68 |
69 | PROCESSENTRY32 = record
70 | dwSize: longword;
71 | cntUsage: longword;
72 | th32ProcessID: longword;
73 | th32DefaultHeapID: longword;
74 | th32ModuleID: longword;
75 | cntThreads: longword;
76 | th32ParentProcessID: longword;
77 | pcPriClassBase: longint;
78 | dwFlags: longword;
79 | szExeFile: array [0..259] of char;
80 | end;
81 |
82 | OSVERSIONINFOA = record
83 | dwOSVersionInfoSize: longword;
84 | dwMajorVersion: longword;
85 | dwMinorVersion: longword;
86 | dwBuildNumber: longword;
87 | dwPlatformId: longword;
88 | szCSDVersion: array[0..127] of char;
89 | end;
90 |
91 | OVERLAPPED = record
92 | Internal: longword;
93 | InternalHigh: longword;
94 | Offset: longword;
95 | OffsetHigh: longword;
96 | hEvent: longword;
97 | end;
98 | POVERLAPPED = ^OVERLAPPED;
99 |
100 | SECURITY_ATTRIBUTES = record
101 | nLength: longword;
102 | lpSecurityDescriptor: pointer;
103 | bInheritHandle: longbool;
104 | end;
105 | LPSECURITY_ATTRIBUTES = ^SECURITY_ATTRIBUTES;
106 | PSECURITYATTRIBUTES = ^SECURITY_ATTRIBUTES;
107 |
108 | FILETIME = record
109 | dwLowDateTime: longword;
110 | dwHighDateTime: longword;
111 | end;
112 |
113 | WIN32_FIND_DATAW = record
114 | dwFileAttributes: longword;
115 | ftCreationTime: FILETIME;
116 | ftLastAccessTime: FILETIME;
117 | ftLastWriteTime: FILETIME;
118 | nFileSizeHigh: longword;
119 | nFileSizeLow: longword;
120 | dwReserved0: longword;
121 | dwReserved1: longword;
122 | cFileName: array[0..259] of widechar;
123 | cAlternateFileName: array[0..13] of widechar;
124 | end;
125 |
126 | function AllowSetForegroundWindow(dwProcessId: longint): longbool; stdcall; external user32 Name 'AllowSetForegroundWindow';
127 | function CloseHandle(hObject: longword): longbool; stdcall; external kernel32 Name 'CloseHandle';
128 | function CreateFileW(lpFileName: Pwidechar; dwDesiredAccess, dwShareMode: longword; lpSecurityAttributes: LPSECURITY_ATTRIBUTES; dwCreationDisposition: longword; dwFlagsAndAttributes: longword; hTemplateFile: longword): longword; stdcall; external kernel32 Name 'CreateFileW';
129 | function CreateToolhelp32Snapshot(dwFlags, th32ProcessID: longword): longword; stdcall; external kernel32 Name 'CreateToolhelp32Snapshot';
130 | function DeleteFile(lpFileName: Pwidechar): boolean; stdcall; external kernel32 Name 'DeleteFileW';
131 | function EnumWindows(lpEnumFunc: ENUMWINDOWSPROC; lParam: longint): longbool; stdcall; external user32 Name 'EnumWindows';
132 | function ReadFile(hFile: longword; var Buffer; nNumberOfBytesToRead: longword; var lpNumberOfBytesRead: longword; lpOverlapped: POverlapped): longbool; stdcall; external kernel32 Name 'ReadFile';
133 | function SetFilePointer(hFile: longword; lDistanceToMove: longint; lpDistanceToMoveHigh: Pointer; dwMoveMethod: longword): longword; stdcall; external kernel32 Name 'SetFilePointer';
134 | function FileTimeToDosDateTime(const lpFileTime: FileTime; var lpFatDate, lpFatTime: word): longbool; stdcall; external kernel32 Name 'FileTimeToDosDateTime';
135 | function FileTimeToLocalFileTime(const lpFileTime: FileTime; var lpLocalFileTime: FileTime): longbool; stdcall; external kernel32 Name 'FileTimeToLocalFileTime';
136 | function FindClose(hFindFile: longword): longbool; stdcall; external kernel32 Name 'FindClose';
137 | function FindFirstFileW(lpFileName: Pwidechar; var lpFindFileData: WIN32_FIND_DATAW): longword; stdcall; external kernel32 Name 'FindFirstFileW';
138 | function FindNextFileW(hFindFile: longword; var lpFindFileData: WIN32_FIND_DATAW): longbool; stdcall; external kernel32 Name 'FindNextFileW';
139 | function FindResourceA(hModule: longword; lpName, lpType: Pchar): longword; stdcall; external kernel32 name 'FindResourceA';
140 | function GetCommandLineW: PWideChar; stdcall; external kernel32 Name 'GetCommandLineW';
141 | function GetEnvironmentVariable(lpName: Pwidechar; lpBuffer: Pwidechar; nSize: longword): longword; stdcall; external kernel32 Name 'GetEnvironmentVariableW';
142 | function GetExitCodeProcess(hProcess: longword; var lpExitCode: longword): longbool; stdcall; external kernel32 Name 'GetExitCodeProcess';
143 | function GetFileAttributesW(lpFileName: Pwidechar): longword; stdcall; external kernel32 Name 'GetFileAttributesW';
144 | function GetForegroundWindow: longint; stdcall; external user32 Name 'GetForegroundWindow';
145 | function GetKeyboardState(var KeyState: TKeyboardState): longbool; stdcall; external user32 Name 'GetKeyboardState';
146 | function GetModuleFileNameExW(hProcess: longword; hModule: longword; lpFilename: PWideChar; nSize: longword): longword; stdcall; external 'psapi.dll' Name 'GetModuleFileNameExW';
147 | function GetProcessId(hProcess: longword): longword; stdcall; external kernel32 Name 'GetProcessId';
148 | function GetUserDefaultLCID: longword; stdcall; external kernel32 Name 'GetUserDefaultLCID';
149 | function GetVersionExA(var lpVersionInformation: OSVersionInfoA): longbool; stdcall; external kernel32 Name 'GetVersionExA';
150 | function GetWindow(hWnd: longword; uCmd: longword): longword; stdcall; external user32 Name 'GetWindow';
151 | function GetWindowThreadProcessId(hWnd: longword; lpdwProcessId: PLongWord): longword; stdcall; external user32 Name 'GetWindowThreadProcessId';
152 | function IsWindowVisible(hWnd: longword): longbool; stdcall; external user32 Name 'IsWindowVisible';
153 | function LoadResource(hModule: longword; hResInfo: longword): longword; stdcall; external kernel32 Name 'LoadResource';
154 | function LockResource(hResData: longword): Pointer; stdcall; external kernel32 Name 'LockResource';
155 | function MessageBoxEx(hWnd: longword; lpText: PWideChar; lpCaption: PWidechar; uType: longword; wLanguageId: word): longint; stdcall; external user32 Name 'MessageBoxExW';
156 | function OpenProcess(dwDesiredAccess: longword; bInheritHandle: longbool; dwProcessId: longword): longword; stdcall; external kernel32 Name 'OpenProcess';
157 | function PathCanonicalize(lpszDst: PWideChar; lpszSrc: PWideChar): longbool; stdcall; external 'shlwapi.dll' Name 'PathCanonicalizeW';
158 | function Process32First(hSnapshot: longword; var lppe: PROCESSENTRY32): longbool; stdcall; external kernel32 Name 'Process32First';
159 | function Process32Next(hSnapshot: longword; var lppe: PROCESSENTRY32): longbool; stdcall; external kernel32 Name 'Process32Next';
160 | function SendMessage(hWnd: longword; Msg: longword; wParam: longint; lParam: longint): longint; stdcall; external user32 Name 'SendMessageA';
161 | function SetActiveWindow(hWnd: longword): longword; stdcall; external user32 Name 'SetActiveWindow';
162 | function SetEnvironmentVariable(lpName: Pwidechar; lpValue: Pwidechar): longbool; stdcall; external kernel32 Name 'SetEnvironmentVariableW';
163 | function SetFocus(hWnd: longword): longword; stdcall; external user32 Name 'SetFocus';
164 | function SetForegroundWindow(hWnd: longword): longbool; stdcall; external user32 Name 'SetForegroundWindow';
165 | function ShellExecuteExW(lpExecInfo: LPSHELLEXECUTEINFOW): boolean; stdcall; external 'shell32.dll' Name 'ShellExecuteExW';
166 | function ShowWindow(hWnd: longword; nCmdShow: longint): longbool; stdcall; external user32 Name 'ShowWindow';
167 | procedure BlockInput(fBlockIt: boolean); stdcall; external user32 Name 'BlockInput';
168 | procedure Sleep(dwMilliseconds: longword); stdcall; external kernel32 Name 'Sleep';
169 | function GetCurrentDirectoryW(nBufferLength: longword; lpBuffer: PwideChar): longword; stdcall; external kernel32 name 'GetCurrentDirectoryW';
170 | function WriteFile(hFile: LongWord; const Buffer; nNumberOfBytesToWrite: LongWord; var lpNumberOfBytesWritten: LongWord; lpOverlapped: POverlapped): longbool; stdcall; external kernel32 name 'WriteFile';
171 |
172 | implementation
173 |
174 | end.
175 |
--------------------------------------------------------------------------------
/AltStream.pas:
--------------------------------------------------------------------------------
1 | unit AltStream;
2 |
3 | interface
4 |
5 | uses
6 | AltExt,
7 | AltSys;
8 |
9 | type
10 | TSeekOrigin = (soBeginning, soCurrent, soEnd);
11 |
12 | type
13 | TStream = class
14 | protected
15 | procedure SetPosition(Value: integer); virtual;
16 | function GetPosition(): integer; virtual;
17 | function GetSize(): integer; virtual;
18 | procedure SetSize(Value: integer); virtual;
19 | public
20 | function Read(var Buffer; Count: integer): integer; virtual; abstract;
21 | procedure ReadBuffer(var Buffer; Count: integer);
22 | function Write(var Buffer; Count: integer): integer; virtual; abstract;
23 | function Seek(Offset: integer; Origin: word): integer; overload; virtual; abstract;
24 | function Seek(Offset: int64; Origin: TSeekOrigin): int64; overload; virtual; abstract;
25 | procedure Clear;
26 | procedure LoadFromStream(aStream: TStream); virtual;
27 | procedure LoadFromFile(const FileName: string);
28 | function CopyFrom(Source: TStream; Count: integer): integer;
29 | property Size: integer read GetSize write SetSize;
30 | property Position: integer read GetPosition write SetPosition;
31 | end;
32 |
33 | TFileStream = class(TStream)
34 | private
35 | fHandle: LongWord;
36 | fFileName: string;
37 | protected
38 | procedure SetSize(Value: integer); override;
39 | public
40 | constructor Create(const FileName: string; Mode: word);
41 | destructor Destroy; override;
42 | property FileName: string read fFileName;
43 | function Read(var Buffer; Count: integer): integer; override;
44 | function Write(var Buffer; Count: integer): integer; override;
45 | function Seek(Offset: integer; Origin: word): integer; overload; override;
46 | function Seek(Offset: int64; Origin: TSeekOrigin): int64; overload; override;
47 | property Handle: LongWord read fHandle;
48 | end;
49 |
50 | TResourceStream = class(TStream)
51 | protected
52 | fPosition, fSize: integer;
53 | fMemory: pointer;
54 | procedure SetPosition(Value: integer); override;
55 | function GetPosition(): integer; override;
56 | function GetSize(): integer; override;
57 | procedure SetSize(Value: integer); override;
58 | public
59 | constructor Create(Instance: LongWord; const ResName: string; ResType: PChar);
60 | function Read(var Buffer; Count: integer): integer; override;
61 | procedure SetPointer(Buffer: pointer; Count: integer);
62 | function Seek(Offset: integer; Origin: word): integer; override;
63 | property Memory: pointer read fMemory;
64 | end;
65 |
66 |
67 | implementation
68 |
69 | function FileRead(Handle: LongWord; var Buffer; Count: LongWord): integer;
70 | begin
71 | if not ReadFile(Handle, Buffer, Count, LongWord(result), nil) then
72 | result := 0;
73 | end;
74 |
75 | function FileSeek(Handle: LongWord; Offset, Origin: integer): integer;
76 | begin
77 | result := SetFilePointer(Handle, Offset, nil, Origin);
78 | end;
79 |
80 | function FileWrite(Handle: THandle; const Buffer; Count: cardinal): integer;
81 | begin
82 | if not WriteFile(Handle, Buffer, Count, cardinal(result), nil) then
83 | result := 0;
84 | end;
85 |
86 | function FileCreate(const FileName: unicodestring): longword;
87 | begin
88 | Result := CreateFileW(@FileName[1], $80000000 or $40000000, 0, nil, 2, $0000080, 0);
89 | end;
90 |
91 | function FileOpen(const FileName: unicodestring; Mode: longword): longword;
92 | const
93 | AccessMode: array[0..2] of longword = ($80000000, $40000000, $80000000 or $40000000);
94 | ShareMode: array[0..4] of longword = (0, 0, 1, 2, 1 or 2);
95 | begin
96 | Result := CreateFileW(@FileName[1], AccessMode[Mode and 3], ShareMode[(Mode and $F0) shr 4], nil, 3, $0000080, 0);
97 | end;
98 |
99 | procedure TStream.Clear;
100 | begin
101 | Position := 0;
102 | Size := 0;
103 | end;
104 |
105 | function TStream.CopyFrom(Source: TStream; Count: integer): integer;
106 | const
107 | MaxBufSize = $F000 * 4;
108 | var
109 | BufSize, N: integer;
110 | Buffer: PChar;
111 | begin
112 | if Count = 0 then
113 | begin
114 | Source.Position := 0;
115 | Count := Source.Size;
116 | end;
117 | Result := Count;
118 | if Count > MaxBufSize then
119 | BufSize := MaxBufSize else
120 | BufSize := Count;
121 | GetMem(Buffer, BufSize);
122 | try
123 | while Count <> 0 do
124 | begin
125 | if Count > BufSize then
126 | N := BufSize else
127 | N := Count;
128 | if Source.Read(Buffer^, N) <> N then
129 | break;
130 | if Write(Buffer^, N) <> N then
131 | break;
132 | Dec(Count, N);
133 | end;
134 | finally
135 | FreeMem(Buffer);
136 | end;
137 | end;
138 |
139 | function TStream.GetPosition(): integer;
140 | begin
141 | Result := Seek(0, soFromCurrent);
142 | end;
143 |
144 | function TStream.GetSize(): integer;
145 | var Pos: integer;
146 | begin
147 | Pos := Seek(0, soFromCurrent);
148 | Result := Seek(0, soFromEnd);
149 | Seek(Pos, soFromBeginning);
150 | end;
151 |
152 | procedure TStream.SetPosition(Value: integer);
153 | begin
154 | Seek(Value, soFromBeginning);
155 | end;
156 |
157 | procedure TStream.SetSize(Value: integer);
158 | begin
159 |
160 | end;
161 |
162 | procedure TStream.LoadFromFile(const FileName: string);
163 | var F: TFileStream;
164 | begin
165 | F := TFileStream.Create(FileName, $0000 or $0001);
166 | try
167 | LoadFromStream(F);
168 | finally
169 | F.Free;
170 | end;
171 | end;
172 |
173 | procedure TStream.LoadFromStream(aStream: TStream);
174 | begin
175 | CopyFrom(aStream, 0);
176 | end;
177 |
178 | procedure TStream.ReadBuffer(var Buffer; Count: integer);
179 | begin
180 | Read(Buffer, Count);
181 | end;
182 |
183 | function TFileStream.Read(var Buffer; Count: integer): integer;
184 | begin
185 | if (fHandle = 0) then
186 | Result := 0 else
187 | if not ReadFile(Handle, Buffer, Count, longword(Result), nil) then
188 | Result := 0;
189 | end;
190 |
191 |
192 | function TFileStream.Seek(Offset: integer; Origin: word): integer;
193 | begin
194 | if (fHandle = 0) then
195 | Result := 0 else
196 | Result := SetFilePointer(fHandle, Offset, nil, Origin);
197 | end;
198 |
199 | function TFileStream.Seek(Offset: int64; Origin: TSeekOrigin): int64;
200 | begin
201 | if (fHandle = 0) then
202 | Result := 0 else
203 | Result := SetFilePointer(fHandle, Offset, nil, Ord(Origin));
204 | end;
205 |
206 | procedure TFileStream.SetSize(Value: integer);
207 | begin
208 | Seek(Value, soFromBeginning);
209 | end;
210 |
211 | function TFileStream.Write(var Buffer; Count: integer): integer;
212 | begin
213 | if (fHandle=0) or (Count<=0) then
214 | result := 0 else
215 | result := FileWrite(fHandle, Buffer, Count);
216 | end;
217 |
218 | constructor TFileStream.Create(const FileName: string; Mode: word);
219 | begin
220 | fFileName := FileName;
221 | if Mode = fmCreate then
222 | fHandle := FileCreate(FileName) else
223 | fHandle := FileOpen(FileName, Mode);
224 | if fHandle = LongWord(-1) then fHandle := 0;
225 | end;
226 |
227 | destructor TFileStream.Destroy;
228 | begin
229 | CloseHandle(fHandle);
230 | inherited;
231 | end;
232 |
233 | function TResourceStream.GetPosition(): integer;
234 | begin
235 | Result := fPosition;
236 | end;
237 |
238 | function TResourceStream.GetSize(): integer;
239 | begin
240 | Result := fSize;
241 | end;
242 |
243 | function TResourceStream.Read(var Buffer; Count: integer): integer;
244 | begin
245 | if Memory <> nil then
246 | if (FPosition >= 0) and (Count > 0) then
247 | begin
248 | Result := FSize - FPosition;
249 | if Result > 0 then
250 | begin
251 | if Result > Count then Result := Count;
252 | Move((PAnsiChar(Memory) + FPosition)^, Buffer, Result);
253 | Inc(FPosition, Result);
254 | Exit;
255 | end;
256 | end;
257 | Result := 0;
258 | end;
259 |
260 | function TResourceStream.Seek(Offset: integer; Origin: word): integer;
261 | begin
262 | Result := Offset;
263 | case Origin of
264 | soFromEnd: Inc(Result, fSize);
265 | soFromCurrent: Inc(Result, fPosition);
266 | end;
267 | if Result <= fSize then
268 | fPosition := Result else
269 | begin
270 | Result := fSize;
271 | fPosition := fSize;
272 | end;
273 | end;
274 |
275 | procedure TResourceStream.SetPointer(Buffer: pointer; Count: integer);
276 | begin
277 | fMemory := Buffer;
278 | fSize := Count;
279 | end;
280 |
281 | procedure TResourceStream.SetPosition(Value: integer);
282 | begin
283 | if Value > fSize then
284 | Value := fSize;
285 | fPosition := Value;
286 | end;
287 |
288 | procedure TResourceStream.SetSize(Value: integer);
289 | begin
290 | fSize := Value;
291 | end;
292 |
293 | function FindResource(hModule: longword; lpName, lpType: PChar): longword;
294 | var aName,aType: Ansistring;
295 | var lpaName, lpaType: PChar;
296 |
297 | begin
298 | if (longword(lpName) shr 16) <> 0 then
299 | begin
300 | aName := AnsiString(lpName);
301 | lpaName := @aName[1];
302 | end
303 | else
304 | lpaName := PChar(lpName);
305 | if (longword(lpType) shr 16) <> 0 then
306 | begin
307 | aType := AnsiString(lpType);
308 | lpaType := @aType[1];
309 | end
310 | else
311 | lpaType := PChar(lpType);
312 | Result := FindResourceA(hModule, lpaName, lpaType);
313 | end;
314 |
315 | constructor TResourceStream.Create(Instance: longword; const ResName: string; ResType: PChar);
316 | var HResInfo: longword;
317 | HGlobal: longword;
318 | ansiresname:ansistring;
319 | begin
320 | ansiresname:=ansistring(resname);
321 | HResInfo := FindResource(Instance, @AnsiResName[1], PChar(ResType));
322 | if HResInfo = 0 then
323 | exit;
324 | HGlobal := LoadResource(HInstance, HResInfo);
325 | if HGlobal = 0 then
326 | exit;
327 | SetPointer(LockResource(HGlobal), SizeOfResource(Instance, HResInfo));
328 | FPosition := 0;
329 | end;
330 |
331 |
332 | end.
333 |
--------------------------------------------------------------------------------
/AltExe.inc:
--------------------------------------------------------------------------------
1 | function GetKeyState(nVirtKey:longint):SHORTint; stdcall; external user32 Name 'GetKeyState';
2 |
3 | function ShiftsPressed:boolean;
4 | var
5 | Press:boolean;
6 | begin
7 | Press:=false;
8 | if GetKeyboardState(state) then
9 | begin
10 | if ((GetKeyState(vk_Control) and 128) <> 0) then Press:=true;
11 | if ((GetKeyState(vk_Shift) and 128) <> 0) then Press:=true;
12 | if ((GetKeyState(vk_Menu) and 128) <> 0) then Press:=true;
13 | end;
14 | Result:=Press;
15 |
16 | end;
17 |
18 | procedure AltExe(c: longint; s: ArrStr; const short, long: UnicodeString; var e:longword);
19 | const
20 | vr = 'er';
21 | vrr = 'envar';
22 | vl = 'el';
23 | val = 'enval';
24 |
25 | var
26 | SEInfo: TShellExecuteInfoW;
27 | ExitCode: longword;
28 | i: integer;
29 | ProcID: longword;
30 | HProcWin: longword;
31 | parent_handle: longint = 0;
32 | hide: boolean = False;
33 | timeout_wait_window: integer = 3000;
34 | timeout: longint = 0;
35 | no_wait: boolean = True;
36 | runfile, params, dir: UnicodeString;
37 | sl: integer;
38 | Show: UnicodeString = '';
39 | lock: boolean = False;
40 | childs: PIDS;
41 | no_child: boolean = True;
42 | wait_child:boolean =false;
43 | sp, lp: UnicodeString;
44 |
45 | begin
46 | runfile := gp(c, s, short, long);
47 | if (runfile = '')or(runfile = ':i:')or(runfile = ':nil:')or(runfile = ':nothing:') then Exit;
48 | if short = 'r' then sp := '' else sp := short;
49 | if long = 'run' then lp := '' else lp := long + '-';
50 | runfile := WorkAltVars(runfile, c, s,1);
51 | if (Pos(dots, runfile) = 2)and(Pos(space, runfile) > 0)and(Pos(dq, runfile) = 0) then runfile:= dq+runfile+dq;
52 | params := gp(c, s, sp + 'p', lp + 'par');
53 | if params<>'' then params := WorkAltVars(params, c, s,0);
54 | if (CharCount(dots, params) = 1)and(Pos(dots, params) = 2)and(Pos(space, params) > 0)and(Pos(dq, params) = 0) then params:= dq+params+dq;
55 | if (Pos(dots, params) = 2)and(Pos(space, params) > 0)and(Pos(dq, params) = 0)and(Pos('\', params)=0) then params:= dq+params+dq;
56 | dir := gp(c, s, sp + 'd', lp + 'dir');
57 | if dir = '' then dir := GetCurrentDir;
58 | dir := WorkAltVars(dir, c, s,1);
59 | if dir[Length(dir)]<>'\' then dir:=dir+'\';
60 | WorkVars(c, s, short, long);
61 | if hp(c, s, sp + 'nn', lp + 'no-admin') then SetEnvironmentVariable(PWideChar('__COMPAT_LAYER'), PWideChar('RUNASINVOKER'));
62 | if hp(c, s, 'tww', 'timeout-wait-window') then timeout_wait_window := StrToInt(gp(c, s, 'tww', 'timeout-wait-window'));
63 | if StrIn(lp, waits_long) or StrIn(sp, waits_short) then
64 | if hp(c, s, sp + 'nw', lp + 'nowait') = False then no_wait := False;
65 | if hp(c, s, sp + 'w', lp + 'wait') then no_wait := False;
66 | if hp(c, s, '1', 'one') then no_wait := False;
67 | if hp(c, s, sp + 'f', lp + 'after') then no_wait := False;
68 | if hp(c, s, sp + 'l', lp + 'lock') then
69 | begin
70 | no_wait := False;
71 | lock := True;
72 | end;
73 | if hp(c, s, sp + 'wc', lp + 'wait-child') then wait_child:=true;
74 | if no_wait = False then timeout := StrToInt(gp(c, s, sp + 't', lp + 'timeout'));
75 | if hp(c, s, sp + 'h', lp + 'hide') then hide := True;
76 | if hp(c, s, sp + 'mx', lp + 'maximize') then Show := 'max';
77 | if hp(c, s, sp + 'mn', lp + 'minimize') then Show := 'min';
78 | ExitCode := 0;
79 | FillChar(SEInfo, SizeOf(SEInfo), 0);
80 | SEInfo.cbSize := SizeOf(TShellExecuteInfoW);
81 | with SEInfo do
82 | begin
83 | fMask := $00000040;
84 | Wnd := GetForegroundWindow;
85 | if hp(c, s, sp + 'n', lp + 'admin') then
86 | begin
87 | lpVerb := PWideChar(WideString('runas'));
88 | if (params<>'') and ((hp(c, s, vr, vrr)) or (hp(c, s, vl, val))) then
89 | begin
90 | if pos(dq,params)<>0 then params:='--run='+runfile+' --par='+sq+params+sq
91 | else
92 | if (pos(space,params)<>0) then
93 | begin
94 | if (CharCount(dots,params)>1) then params:='--run='+runfile+' --par='+sq+params+sq
95 | else
96 | if (CharCount(dots,params)=1) then params:='--run='+runfile+' --par='+dq+params+dq
97 | else params:='--run='+runfile+' --par='+params
98 | end
99 | else
100 | params:='--run='+runfile+' --par='+sq+params+sq;
101 | if hide then params:=params+' --hide';
102 | if hp(c, s, sp + 'mx', lp + 'maximize') then params:=params+' --maximize';
103 | if hp(c, s, sp + 'mn', lp + 'minimize') then params:=params+' --minimize';
104 | if hp(c, s, 'tww', 'timeout-wait-window') then params:=params+' -tww';
105 | if hp(c, s, sp + 'nw', lp + 'nowait') then params:=params+' --nowait';
106 | if (hp(c, s, sp + 'f', lp + 'after'))or(hp(c, s, sp + 'l', lp + 'lock'))or(hp(c, s, sp + 'w', lp + 'wait'))or(hp(c, s, sp + 'wc', lp + 'wait-child')) then
107 | begin
108 | params:=params+' --wait';
109 | params:=params+' --wait-child';
110 | wait_child:=true;
111 | end;
112 | if hp(c, s, sp + 't', lp + 'timeout') then params:=params+' --timeout='+gp(c, s, sp + 't', lp + 'timeout');
113 | if hp(c, s, vr, vrr) then params:=params+' --envar='+gp(c, s, vr, vrr);
114 | if hp(c, s, vl, val) then params:=params+' --enval='+gp(c, s, vl, val);
115 | for i := 2 to 9 do
116 | if hp(c, s, vr + IntToStr(i), vrr + IntToStr(i)) then params:=params+' --envar'+IntToStr(i)+'='+gp(c, s, vr + IntToStr(i), vrr + IntToStr(i));
117 | for i := 2 to 9 do
118 | if hp(c, s, vl + IntToStr(i), val + IntToStr(i)) then params:=params+' --enval'+IntToStr(i)+'='+gp(c, s, vl + IntToStr(i), val + IntToStr(i));
119 | if (sp<>'')and(lp<>'') then
120 | begin
121 | if hp(c, s, sp+vr, lp+vrr) then params:=params+' --envar='+gp(c, s, sp+vr, lp+vrr);
122 | if hp(c, s, sp+vl, lp+val) then params:=params+' --enval='+gp(c, s, sp+vl, lp+val);
123 | for i := 2 to 9 do
124 | if hp(c, s, sp+vr + IntToStr(i), lp+vrr + IntToStr(i)) then params:=params+' --envar'+IntToStr(i)+'='+gp(c, s, sp+vr + IntToStr(i), lp+vrr + IntToStr(i));
125 | for i := 2 to 9 do
126 | if hp(c, s, sp+vl + IntToStr(i), lp+val + IntToStr(i)) then params:=params+' --enval'+IntToStr(i)+'='+gp(c, s, sp+vl + IntToStr(i), lp+val + IntToStr(i));
127 | end;
128 | if (sp='')and(lp='') then
129 | begin
130 | if hp(c, s, 'r'+vr, 'run-'+vrr) then params:=params+' --envar='+gp(c, s, 'r'+vr, 'run-'+vrr);
131 | if hp(c, s, 'r'+vl, 'run-'+val) then params:=params+' --enval='+gp(c, s, 'r'+vl, 'run-'+val);
132 | for i := 2 to 9 do
133 | if hp(c, s, 'r'+vr + IntToStr(i), 'run-'+vrr + IntToStr(i)) then params:=params+' --envar'+IntToStr(i)+'='+gp(c, s, 'r'+vr + IntToStr(i), 'run-'+vrr + IntToStr(i));
134 | for i := 2 to 9 do
135 | if hp(c, s, 'r'+vl + IntToStr(i), 'run-'+val + IntToStr(i)) then params:=params+' --enval'+IntToStr(i)+'='+gp(c, s, 'r'+vl + IntToStr(i), 'run-'+val + IntToStr(i));
136 | end;
137 | runfile:=s[0];
138 | hide:=false;
139 | Show:='';
140 | if (sp<>'')or(lp<>'') then params:=params+' --ignore-keys';
141 | end;
142 | end;
143 | lpParameters := PWideChar(WideString(params));
144 | lpFile := PWideChar(WideString(runfile));
145 | lpDirectory := PWideChar(WideString(dir));
146 | nShow := SW_SHOW;
147 | if hide then nShow := SW_HIDE else
148 | begin
149 | if Show = 'max' then nShow := SW_MAXIMIZE;
150 | if Show = 'min' then nShow := SW_MINIMIZE;
151 | end;
152 | end;
153 | if hp(c, s, sp + 'df', lp + 'delay-first') then
154 | begin
155 | sl := 0;
156 | sl := StrToInt(gp(c, s, sp + 'df', lp + 'delay-first'));
157 | if sl > 0 then Sleep(sl);
158 | end;
159 | if hp(c, s, sp + 'dl', lp + 'delay-last') then no_wait := False;
160 | if lock then BlockInput(True);
161 | {$IFDEF DBG}
162 | writeln('runfile:');
163 | writeln(runfile);
164 | writeln;
165 | writeln('params: ');
166 | writeln(params);
167 | writeln;
168 | writeln('dir: ');
169 | writeln(dir);
170 | writeln;
171 | if no_wait then writeln('wait process: false') else writeln('wait process: true');
172 | writeln;
173 | Writeln('Press Enter to run...');
174 | readln;
175 | {$ENDIF}
176 | if ShellExecuteExW(@SEInfo) then
177 | begin
178 | i := 0;
179 | HProcWin := 0;
180 | ProcID := GetProcessId(SEInfo.hProcess);
181 | repeat
182 | sleep(10);
183 | HProcWin := FindMainWindow(ProcID);
184 | GetExitCodeProcess(SEInfo.hProcess, ExitCode);
185 | i := i + 10;
186 | if wait_child then no_child := NoChildPresent(ProcID, childs);
187 | until (HProcWin > 0) or (i > timeout_wait_window) or (ExitCode <> $103);
188 | if HProcWin > 0 then
189 | for i:=1 to 10 do
190 | begin
191 | if not hide then
192 | begin
193 | AllowSetForegroundWindow(ProcID);
194 | SetForegroundWindow(HProcWin);
195 | SetActiveWindow(HProcWin);
196 | SendMessage(parent_handle, 8, 0, 0);
197 | SetFocus(HProcWin);
198 | if Show = '' then ShowWindow(HProcWin, SW_RESTORE) else
199 | begin
200 | if Show = 'max' then ShowWindow(HProcWin, SW_MAXIMIZE);
201 | if Show = 'min' then ShowWindow(HProcWin, SW_MINIMIZE);
202 | end;
203 | end
204 | else
205 | begin
206 | ShowWindow(HProcWin, SW_MINIMIZE);
207 | ShowWindow(HProcWin, SW_HIDE);
208 | end;
209 | sleep(10);
210 | end;
211 | i := 0;
212 | if timeout > 0 then no_wait := False;
213 | if no_wait = False then
214 | if (ExitCode = $103) or wait_child then
215 | repeat
216 | GetExitCodeProcess(SEInfo.hProcess, ExitCode);
217 | if wait_child then no_child := NoChildPresent(ProcID, childs);
218 | sleep(10);
219 | if timeout > 0 then i := i + 10;
220 | until ((ExitCode <> $103) and no_child) or ((timeout > 0) and (i > timeout));
221 |
222 | end;
223 | i:=0;
224 | repeat
225 | sleep(10);
226 | i := i + 10;
227 | until (not ShiftsPressed) or (i>timeout_wait_window);
228 | if HProcWin > 0 then
229 | if not hide then
230 | begin
231 | AllowSetForegroundWindow(ProcID);
232 | SetForegroundWindow(HProcWin);
233 | SetActiveWindow(HProcWin);
234 | SendMessage(parent_handle, 8, 0, 0);
235 | SetFocus(HProcWin);
236 | if Show = '' then ShowWindow(HProcWin, SW_RESTORE) else
237 | begin
238 | if Show = 'max' then ShowWindow(HProcWin, SW_MAXIMIZE);
239 | if Show = 'min' then ShowWindow(HProcWin, SW_MINIMIZE);
240 | end;
241 | end
242 | else
243 | begin
244 | ShowWindow(HProcWin, SW_MINIMIZE);
245 | ShowWindow(HProcWin, SW_HIDE);
246 | end;
247 | e:=ExitCode;
248 | SetEnvironmentVariable(PWideChar('exitcode'), PWideChar(inttostr(e)));
249 | if lock then BlockInput(False);
250 | if hp(c, s, sp + 'dl', lp + 'delay-last') then
251 | begin
252 | sl := 0;
253 | sl := StrToInt(gp(c, s, sp + 'df', lp + 'delay-last'));
254 | if sl > 0 then Sleep(sl);
255 | end;
256 | end;
257 |
--------------------------------------------------------------------------------
/AltSys.pas:
--------------------------------------------------------------------------------
1 | unit AltSys;
2 |
3 | interface
4 |
5 | uses
6 | AltExt;
7 | type
8 | TReplaceFlags = set of (rfReplaceAll, rfIgnoreCase);
9 |
10 | LongRec = packed record
11 | case integer of
12 | 0: (Lo, Hi: word);
13 | 1: (Words: array [0..1] of word);
14 | 2: (Bytes: array [0..3] of byte);
15 | end;
16 |
17 | TUnicodeSearchRec = record
18 | Time: integer;
19 | Size: int64;
20 | Attr: integer;
21 | Name: unicodestring;
22 | ExcludeAttr: integer;
23 | FindHandle: longword;
24 | FindData: WIN32_FIND_DATAW;
25 | end;
26 |
27 | const
28 | space = ' ';
29 | PathDelim = '\';
30 | dots = ':';
31 | separator = ';';
32 |
33 | tmp_separator = '/';
34 | dq = '"';
35 | sq = chr(39);
36 | //res = 'res';
37 | hyp = '-';
38 | und = '_';
39 | eq = '=';
40 | percent = '%';
41 | pf86 = 'PROGRAMFILES(X86)';
42 | ctrl = 'ctrl';
43 | alt = 'alt';
44 | shift = 'shift';
45 | cmd64 = '%windir%\Sysnative\cmd.exe';
46 | cmd32 = '%windir%\system32\cmd.exe';
47 | waits_long: array[0..26] of UnicodeString = ('before', 'ctrl-before', 'alt-before', 'shift-before', 'ctrl-alt-before', 'ctrl-shift-before', 'alt-shift-before', 'ctr-alt-shift-before', 'right-button-before', 'exist', 'ctrl-exist', 'alt-exist', 'shift-exist', 'ctrl-alt-exist', 'ctrl-shift-exist', 'alt-shift-exist', 'ctr-alt-shift-exist', 'right-button-exist', 'else', 'ctrl-else', 'alt-else', 'shift-else', 'ctrl-alt-else', 'ctrl-shift-else', 'alt-shift-else', 'ctr-alt-shift-else', 'right-button-else');
48 | waits_short: array[0..26] of UnicodeString = ('b', 'cb', 'ab', 'sb', 'cab', 'csb', 'asb', 'casb', 'rbtb', 'x', 'cx', 'ax', 'sx', 'cax', 'csx', 'asx', 'casx', 'rbtx', 'e', 'ce', 'ae', 'se', 'cae', 'cse', 'ase', 'case', 'rbte');
49 |
50 | function GetEnvVar(Name: Unicodestring): Unicodestring;
51 | function StringReplace(const S, OldPattern, NewPattern: unicodestring; Flags: TReplaceFlags): unicodestring;
52 | function UpperCase(const S: unicodestring): unicodestring;
53 | function LowerCase(const S: unicodestring): unicodestring;
54 | function ExtractFilePath(const FileName: unicodestring): unicodestring; overload;
55 | function ExtractFileName(const FileName: unicodestring): unicodestring; overload;
56 | function Exists(const Name: unicodestring): boolean;
57 | function IntToStr(Value: integer): Unicodestring;
58 | function StrToInt(Value: Unicodestring): integer;
59 | function GetCurrentDir: unicodestring;
60 | function RelToAbs(const RelPath, BasePath: unicodestring): unicodestring;
61 | function AltFind(f: UnicodeString): UnicodeString;
62 | function Split(const S, separator: UnicodeString): ArrStr;
63 | function ExtractBetween(const Value, A, B: UnicodeString): UnicodeString;
64 | function StrIn(const AText: UnicodeString; const AValues: array of UnicodeString): boolean;
65 | function CharCount(const C: char; S: UnicodeString): longint;
66 | function pos2(const C: char; S: UnicodeString): longint;
67 |
68 | implementation
69 |
70 | function GetEnvVar(Name: Unicodestring): Unicodestring;
71 | var
72 | buf: array[0..4094] of widechar;
73 | begin
74 | Result := '';
75 | if (GetEnvironmentVariable(pwidechar(WideString(Name)), @buf, sizeof(buf)) <> 0) then Result := string(buf);
76 | end;
77 |
78 | function StringReplace(const S, OldPattern, NewPattern: unicodestring; Flags: TReplaceFlags): unicodestring;
79 | var
80 | SearchStr, Patt, NewStr: unicodestring;
81 | Offset: integer;
82 | begin
83 | if rfIgnoreCase in Flags then
84 | begin
85 | SearchStr := UpperCase(S);
86 | Patt := UpperCase(OldPattern);
87 | end
88 | else
89 | begin
90 | SearchStr := S;
91 | Patt := OldPattern;
92 | end;
93 | NewStr := S;
94 | Result := '';
95 | while SearchStr <> '' do
96 | begin
97 | Offset := Pos(Patt, SearchStr);
98 | if Offset = 0 then
99 | begin
100 | Result := Result + NewStr;
101 | break;
102 | end;
103 | Result := Result + Copy(NewStr, 1, Offset - 1) + NewPattern;
104 | NewStr := Copy(NewStr, Offset + length(OldPattern), MaxInt);
105 | if not (rfReplaceAll in Flags) then
106 | begin
107 | Result := Result + NewStr;
108 | break;
109 | end;
110 | SearchStr := Copy(SearchStr, Offset + length(Patt), MaxInt);
111 | end;
112 | end;
113 |
114 | function UpperCase(const s: UnicodeString): UnicodeString;
115 | begin
116 | Result := widestringmanager.UpperUnicodeStringProc(s);
117 | end;
118 |
119 | function LowerCase(const s: UnicodeString): UnicodeString;
120 | begin
121 | Result := widestringmanager.LowerUnicodeStringProc(s);
122 | end;
123 |
124 | function IntToStr(Value: integer): Unicodestring;
125 | begin
126 | Str(Value, Result);
127 | end;
128 |
129 | function StrToInt(Value: Unicodestring): integer;
130 | var error: integer;
131 | begin
132 | Val(Value, Result, error);
133 | end;
134 |
135 | function LastDelimiter(const Delimiters, S: unicodestring): integer; overload;
136 | begin
137 | Result := Length(S);
138 | while Result > 0 do
139 | if (S[Result] <> #0) and (Pos(S[Result], Delimiters) = 0) then
140 | Dec(Result) else
141 | break;
142 | end;
143 |
144 | function ExtractFilePath(const FileName: unicodestring): unicodestring; overload;
145 | var i: integer;
146 | begin
147 | i := LastDelimiter(unicodestring(PathDelim + dots), FileName);
148 | Result := Copy(FileName, 1, i);
149 | end;
150 |
151 | function ExtractFileName(const FileName: unicodestring): unicodestring; overload;
152 | var i: integer;
153 | begin
154 | i := LastDelimiter(unicodestring(PathDelim + dots), FileName);
155 | Result := Copy(FileName, i + 1, $7fffffff);
156 | end;
157 |
158 | function Exists(const Name: unicodestring): boolean;
159 | var code: integer;
160 | path: unicodestring;
161 | begin
162 | path := Name;
163 | if Pos('..', path) <> 0 then path := RelToAbs(Name, GetCurrentDir);
164 | if Pos(dots, path) = 0 then path := GetCurrentDir + Name else path := Name;
165 | code := GetFileAttributesW(@(path[1]));
166 | Result := code <> -1;
167 | end;
168 |
169 | function GetCurrentDir: unicodestring;
170 | var
171 | Dir: unicodestring;
172 | Len: longword;
173 | begin
174 | Len := GetCurrentDirectoryW(0, nil);
175 | SetLength(Dir, Len - 1);
176 | GetCurrentDirectoryW(Len, PWideChar(Dir));
177 | Result := unicodestring(dir + pathdelim);
178 | end;
179 |
180 | function FFNF_WW(lpFileName: PUnicodeChar; hFindFile: longword; var lpFindFileData: WIN32_FIND_DATAW; var OutFileName: unicodestring; var ResFunc: longword; var LastOSError: longword): boolean;
181 | begin
182 | Result := False;
183 | LastOSError := 0;
184 | if hFindFile = 0 then
185 | begin
186 | ResFunc := FindFirstFileW(lpFileName, lpFindFileData);
187 | if ResFunc = longword(-1) then exit;
188 | end
189 | else
190 | begin
191 | ResFunc := longword(FindNextFileW(hFindFile, lpFindFileData));
192 | if ResFunc = longword(False) then exit;
193 | end;
194 | OutFileName := unicodestring(lpFindFileData.cFileName);
195 | Result := True;
196 | end;
197 |
198 | function FindFirstNextFile(const sFileName: unicodestring; hFindFile: longword; var lpFindFileData: WIN32_FIND_DATAW; var OutFileName: unicodestring; var LastOSError: longword): longword;
199 | begin
200 | if not FFNF_WW(@sFileName[1], hFindFile, lpFindFileData, OutFileName, Result, LastOSError) then exit;
201 | end;
202 |
203 | function FindMatchingFile(var F: TUnicodeSearchRec): integer;
204 | var LocalFileTime: FileTime;
205 | var FileName: unicodestring;
206 | var LastOSError: longword;
207 | begin
208 | with F do
209 | begin
210 | while (FindData.dwFileAttributes and ExcludeAttr) <> 0 do
211 | begin
212 | if FindFirstNextFile('', FindHandle, FindData, FileName, LastOSError) = 0 then exit;
213 | Name := FileName;
214 | end;
215 | FileTimeToLocalFileTime(FindData.ftLastWriteTime, LocalFileTime);
216 | FileTimeToDosDateTime(LocalFileTime, LongRec(Time).Hi, LongRec(Time).Lo);
217 | Size := int64(int64(FindData.nFileSizeHigh) shl 32) + int64(FindData.nFileSizeLow);
218 | Attr := FindData.dwFileAttributes;
219 | end;
220 | Result := 0;
221 | end;
222 |
223 | function FindFirst(const Path: unicodestring; Attr: integer; var F: TUnicodeSearchRec): integer; overload;
224 | const faSpecial = $00000002 or $00000004 or $00000008 or $00000010;
225 | var FileName: unicodestring;
226 | LastOSError: longword;
227 | begin
228 | F.ExcludeAttr := not Attr and faSpecial;
229 | F.FindHandle := FindFirstNextFile
230 | (Path, 0, F.FindData, FileName, LastOSError);
231 | if F.FindHandle <> longword(-1) then
232 | begin
233 | F.Name := FileName;
234 | Result := FindMatchingFile(F);
235 | if Result <> 0 then FindClose(F.FindHandle);
236 | end
237 | else Result := LastOSError;
238 | end;
239 |
240 | function FindNext(var F: TUnicodeSearchRec): integer; overload;
241 | var FileName: unicodestring;
242 | var LastOSError: longword;
243 | begin
244 | if FindFirstNextFile('', F.FindHandle, F.FindData, FileName, LastOSError)<>0 then
245 | begin
246 | F.Name := FileName;
247 | result := FindMatchingFile(F);
248 | end
249 | else
250 | result := LastOSError;
251 | end;
252 |
253 | function RelToAbs(const RelPath, BasePath: unicodestring): unicodestring;
254 | var
255 | Dst: array[0..259] of widechar;
256 | begin
257 | PathCanonicalize(@Dst[0], PWideChar(BasePath + RelPath));
258 | Result := Dst;
259 | end;
260 |
261 | function AltFind(f: UnicodeString): UnicodeString;
262 | var
263 | x: UnicodeString = '';
264 | MySearch: TUnicodeSearchRec;
265 | begin
266 | if Pos('..', x) = 0 then x := RelToAbs(x, GetCurrentDir);
267 | if Pos(dots, f) = 0 then x := GetCurrentDir + f else x := f;
268 | FindFirst(x, $0000003F, MySearch);
269 | x := ExtractFilePath(x) + MySearch.Name;
270 | if (GetEnvVar(pf86) <> '') and (pos('64',MySearch.Name)=0) then
271 | begin
272 | FindNext(MySearch);
273 | if pos('64',MySearch.Name)<>0 then x := ExtractFilePath(x) + MySearch.Name;
274 | end;
275 | if (GetEnvVar(pf86) = '') and (pos('64',MySearch.Name)<>0) then
276 | begin
277 | FindNext(MySearch);
278 | if pos('64',MySearch.Name)=0 then x := ExtractFilePath(x) + MySearch.Name;
279 | end;
280 | FindClose(MySearch.FindHandle);
281 | Result := x;
282 | if ExtractFilePath(Result) = Result then Result := f;
283 | end;
284 |
285 | function Split(const S, separator: UnicodeString): ArrStr;
286 |
287 | var
288 | i: longint;
289 | T: UnicodeString;
290 | begin
291 | i := 0;
292 | T := S;
293 | while (Length(T) > 1) and (Pos(separator, T) <> 0) do
294 | begin
295 | SetLength(Result, i + 1);
296 | Result[i] := Copy(T, 1, Pos(separator, T) - 1);
297 | if Result[i] = separator then Result[i] := '';
298 | T := StringReplace(T, Result[i] + separator, '', []);
299 | Inc(i);
300 | end;
301 | if (Length(T) > 0) then
302 | begin
303 | SetLength(Result, i + 1);
304 | Result[i] := T;
305 | if Result[i] = separator then SetLength(Result, i);
306 | end;
307 | end;
308 |
309 | function ExtractBetween(const Value, A, B: Unicodestring): Unicodestring;
310 | var
311 | aPos, bPos: integer;
312 | begin
313 | Result := '';
314 | aPos := Pos(A, Value);
315 | if aPos > 0 then
316 | begin
317 | aPos := aPos + Length(A);
318 | bPos := Pos(B, Value, aPos);
319 | if bPos > 0 then
320 | begin
321 | Result := Copy(Value, aPos, bPos - aPos);
322 | end;
323 | end;
324 | end;
325 |
326 | function StrIn(const AText: UnicodeString; const AValues: array of UnicodeString): boolean;
327 | var
328 | i: longint;
329 | begin
330 | Result := False;
331 | if (high(AValues) = -1) or (High(AValues) > MaxInt) then
332 | Exit;
333 | for i := low(AValues) to High(Avalues) do
334 | if (avalues[i] = AText) then
335 | Result := True;
336 | end;
337 |
338 | function CharCount(const C: char; S: UnicodeString): longint;
339 | var i: longint;
340 | begin
341 | Result := 0;
342 | for i := 1 to Length(S) do if S[i] = C then Inc(Result);
343 | end;
344 |
345 | function pos2(const C: char; S: UnicodeString): longint;
346 | var i,count: longint;
347 | begin
348 | Result := 0;
349 | count:=0;
350 | for i := 1 to Length(S) do
351 | begin
352 | if S[i] = C then inc(count);
353 | if count=1 then Result:=i;
354 | end;
355 | end;
356 |
357 | end.
358 |
--------------------------------------------------------------------------------
/AltUnit.pas:
--------------------------------------------------------------------------------
1 | unit AltUnit;
2 |
3 | interface
4 |
5 | uses
6 | AltSys,
7 | AltCmd,
8 | AltExt;
9 |
10 | function FindMainWindow(process_id: longword): longword;
11 | function WorkAltVars(altstring: UnicodeString; c: longint; s: ArrStr; Mode: word): UnicodeString;
12 | procedure WorkVars(c: longint; s: ArrStr; const sp, lp: UnicodeString);
13 | function NoChildPresent(ProcessId: longword; var childs: PIDS): boolean;
14 | function HasProcess(target: UnicodeString; mode: longword; Name: boolean; basepath: unicodestring): boolean;
15 |
16 | implementation
17 |
18 | function IsMainWindow(handle: longword): boolean;
19 | begin
20 | Result := (GetWindow(handle, 4) = 0) and IsWindowVisible(handle);
21 | end;
22 |
23 | function EnumWindowsCallback(handle: longword; Param: longint): longbool; stdcall;
24 | var
25 | Data: PHandle_data;
26 | process_id: longword;
27 | begin
28 | Data := PHandle_data(Param);
29 | process_id := 0;
30 | GetWindowThreadProcessId(handle, @process_id);
31 | if (Data^.process_id <> process_id) or (not IsMainWindow(handle)) then
32 | exit(True);
33 | Data^.best_handle := handle;
34 | exit(False);
35 | end;
36 |
37 | function FindMainWindow(process_id: longword): longword;
38 | var
39 | Data: THandle_data;
40 | begin
41 | Data.process_id := process_id;
42 | Data.best_handle := 0;
43 | EnumWindows(@EnumWindowsCallback, longint(@Data));
44 | Result := Data.best_handle;
45 | end;
46 |
47 | function ReplaceEnv(env: UnicodeString): UnicodeString;
48 | var
49 | x, y, envx: UnicodeString;
50 | begin
51 | y := '';
52 | x := env;
53 | Result := x;
54 | y := ExtractBetween(x, percent + percent + percent, percent + percent + percent);
55 | while y <> '' do
56 | begin
57 | envx := GetEnvVar(y);
58 | if envx = '' then
59 | envx := percent + percent + percent + y + percent + percent + percent;
60 | x := StringReplace(x, percent + percent + percent + y + percent + percent + percent, y, [rfReplaceAll, rfIgnoreCase]);
61 | Result := StringReplace(Result, percent + percent + percent + y + percent + percent + percent, envx, [rfReplaceAll, rfIgnoreCase]);
62 | y := ExtractBetween(x, percent + percent + percent, percent + percent + percent);
63 | end;
64 | y := ExtractBetween(x, percent + percent + percent, percent + percent + percent);
65 | while y <> '' do
66 | begin
67 | envx := GetEnvVar(y);
68 | if envx = '' then
69 | envx := percent + percent + y + percent + percent;
70 | x := StringReplace(x, percent + percent + y + percent + percent, y, [rfReplaceAll, rfIgnoreCase]);
71 | Result := StringReplace(Result, percent + percent + y + percent + percent, envx, [rfReplaceAll, rfIgnoreCase]);
72 | y := ExtractBetween(x, percent + percent, percent + percent);
73 | end;
74 | y := ExtractBetween(x, percent, percent);
75 | while y <> '' do
76 | begin
77 | envx := GetEnvVar(y);
78 | if envx = '' then
79 | envx := percent + y + percent;
80 | x := StringReplace(x, percent + y + percent, y, [rfReplaceAll, rfIgnoreCase]);
81 | Result := StringReplace(Result, percent + y + percent, envx, [rfReplaceAll, rfIgnoreCase]);
82 | y := ExtractBetween(x, percent, percent);
83 | end;
84 | end;
85 |
86 | function ReplaceAltVars(const altstring, sv, lv, Value: UnicodeString): UnicodeString;
87 | var
88 | tmp, variable, localvalue: UnicodeString;
89 | vars: ArrStr;
90 | i: longint;
91 | begin
92 | variable := '';
93 | tmp := altstring;
94 | Result := tmp;
95 | variable := ExtractBetween(altstring, dots, dots);
96 | while (variable <> '') or (Pos(variable, separator) <> 0) do
97 | begin
98 | localvalue := '';
99 | if Pos(separator, variable) <> 0 then
100 | begin
101 | vars := split(variable, separator);
102 | for i := 0 to length(vars) - 1 do
103 | if ((vars[i] = sv) or (vars[i] = lv)) then
104 | localvalue := localvalue + Value + separator
105 | else
106 | localvalue := localvalue + dots + vars[i] + dots;
107 | SetLength(vars, 0);
108 | end
109 | else
110 | if ((variable = sv) or (variable = lv)) then
111 | localvalue := Value
112 | else
113 | localvalue := dots + variable + dots;
114 | if Pos(dots, localvalue) <> 0 then
115 | tmp := StringReplace(tmp, dots + variable + dots, '', [rfReplaceAll, rfIgnoreCase])
116 | else
117 | tmp := StringReplace(tmp, dots + variable + dots, Value, [rfReplaceAll, rfIgnoreCase]);
118 | Result := StringReplace(Result, dots + variable + dots, localvalue, [rfReplaceAll, rfIgnoreCase]);
119 | variable := ExtractBetween(tmp, dots, dots);
120 | end;
121 | Result := StringReplace(Result, dots + sv + dots, Value, [rfReplaceAll]);
122 | Result := StringReplace(Result, dots + lv + dots, Value, [rfReplaceAll]);
123 | end;
124 |
125 | function WorkAltVars(altstring: UnicodeString; c: longint; s: ArrStr; Mode: word): UnicodeString;
126 | var
127 | b, cmd, t: UnicodeString;
128 | j: integer;
129 | begin
130 |
131 | if GetEnvVar(pf86) <> '' then
132 | begin
133 | b := gp(c, s, '64', 'x64');
134 | if b = '' then
135 | b := '64';
136 | if hp(c, s, '64', 'x64') and (gp(c, s, '64', 'x64') = '') then
137 | b := '';
138 | cmd := cmd64;
139 | end
140 | else
141 | begin
142 | b := gp(c, s, '32', 'x86');
143 | if b = '' then
144 | b := '32';
145 | if hp(c, s, '32', 'x32') and (gp(c, s, '32', 'x32') = '') then
146 | b := '';
147 | cmd := cmd32;
148 | end;
149 | Result := altstring;
150 | Result := ReplaceAltVars(Result, 'i', 'nil', '');
151 | Result := ReplaceAltVars(Result, 'e', 'space', ' ');
152 | Result := ReplaceAltVars(Result, 'q', 'quote', chr(39));
153 | Result := ReplaceAltVars(Result, 's', 'quotes', '"');
154 | Result := ReplaceAltVars(Result, 'o', 'open', gp(c, s, 'o', 'open'));
155 | Result := ReplaceAltVars(Result, 'b', 'bitness', b);
156 | Result := ReplaceAltVars(Result, 'a', 'altrun', s[0]);
157 | Result := ReplaceAltVars(Result, 'n', 'name', Copy(ExtractFileName(s[0]), 1, Length(ExtractFileName(s[0])) - 4));
158 | Result := ReplaceAltVars(Result, 'c', 'cmd', cmd);
159 | Result := ReplaceAltVars(Result, 'c32', 'cmd32', cmd32);
160 | Result := ReplaceAltVars(Result, 'c64', 'cmd64', cmd64);
161 | Result := ReplaceAltVars(Result, 'ad', 'altdir', ExtractFilePath(s[0]));
162 | Result := ReplaceAltVars(Result, 'd', 'dir', Getcurrentdir);
163 | Result := ReplaceAltVars(Result, 'f', 'folder', ExtractFileName(Copy(Getcurrentdir, 1, Length(Getcurrentdir) - 1)));
164 | Result := ReplaceAltVars(Result, 'p', 'percent', percent);
165 | Result := ReplaceAltVars(Result, 't', 'dots', dots);
166 | Result := ReplaceAltVars(Result, 'v', 'var', gp(c, s, 'v', 'var'));
167 | for j := 1 to 9 do
168 | Result := ReplaceAltVars(Result, 'v' + IntToStr(j), 'var' + IntToStr(j), gp(c, s, 'v' + IntToStr(j), 'var' + IntToStr(j)));
169 | for j := 0 to 255 do
170 | Result := ReplaceAltVars(Result, IntToStr(j), 'chr' + IntToStr(j), chr(j));
171 | Result := ReplaceEnv(Result);
172 | if mode = 1 then
173 | begin
174 | if ((Pos(dots, Result) <> 2) and (not ((Pos('*', Result) <> 0) or (Pos('?', Result) <> 0)))) then
175 | begin
176 | t := RelToAbs(Result, GetCurrentDir);
177 | if not Exists(t) then
178 | t := RelToAbs(Result, ExtractFilePath(s[0]));
179 | if Exists(t) then
180 | Result := t;
181 | end;
182 | if (Pos(dots, Result) <> 2) then
183 | begin
184 | t := RelToAbs(Result, GetCurrentDir);
185 | if ((Pos('*', Result) <> 0) or (Pos('?', Result) <> 0)) then
186 | t := AltFind(t);
187 | Result := t;
188 | end
189 | else
190 | Result := AltFind(Result);
191 | end;
192 |
193 | end;
194 |
195 | procedure WorkVars(c: longint; s: ArrStr; const sp, lp: UnicodeString);
196 | const
197 | vr = 'er';
198 | vrr = 'envar';
199 | vl = 'el';
200 | val = 'enval';
201 | var
202 | Value: UnicodeString;
203 | i: word;
204 | begin
205 | if hp(c, s, vr, vrr) then
206 | if hp(c, s, vl, val) then
207 | begin
208 | Value := gp(c, s, vl, val);
209 | Value := WorkAltVars(Value, c, s, 1);
210 | SetEnvironmentVariable(PWideChar(WideString(gp(c, s, vr, vrr))), PWideChar(WideString(Value)));
211 | end;
212 | for i := 2 to 9 do
213 | if hp(c, s, vr + IntToStr(i), vrr + IntToStr(i)) then
214 | if hp(c, s, vl + IntToStr(i), val + IntToStr(i)) then
215 | begin
216 | Value := gp(c, s, vl + IntToStr(i), val + IntToStr(i));
217 | Value := WorkAltVars(Value, c, s, 1);
218 | SetEnvironmentVariable(PWideChar(WideString(gp(c, s, vr + IntToStr(i), vrr + IntToStr(i)))), PWideChar(WideString(Value)));
219 | end;
220 | if hp(c, s, sp + vr, lp + hyp + vrr) then
221 | if hp(c, s, sp + vl, lp + hyp + val) then
222 | begin
223 | Value := gp(c, s, sp + vl, lp + hyp + val);
224 | Value := WorkAltVars(Value, c, s, 1);
225 | SetEnvironmentVariable(PWideChar(WideString(gp(c, s, sp + vr, lp + hyp + vrr))), PWideChar(WideString(Value)));
226 | end;
227 | for i := 2 to 9 do
228 | if hp(c, s, sp + vr + IntToStr(i), lp + hyp + vrr + IntToStr(i)) then
229 | if hp(c, s, sp + vl + IntToStr(i), lp + hyp + val + IntToStr(i)) then
230 | begin
231 | Value := gp(c, s, sp + vl + IntToStr(i), lp + hyp + val + IntToStr(i));
232 | Value := WorkAltVars(Value, c, s, 1);
233 | SetEnvironmentVariable(PWideChar(WideString(gp(c, s, sp + vr + IntToStr(i), lp + hyp + vrr + IntToStr(i)))), PWideChar(WideString(Value)));
234 | end;
235 | end;
236 |
237 | function IntIn(i: longword; a: array of longword): boolean;
238 | var
239 | b: longword;
240 | begin
241 | Result := False;
242 | for b in a do
243 | begin
244 | Result := i = b;
245 | if Result then
246 | Break;
247 | end;
248 | end;
249 |
250 | function NoChildPresent(ProcessId: longword; var childs: PIDS): boolean;
251 | var
252 | hSnapShot: longword;
253 | ProcInfo: ProcessEntry32;
254 | begin
255 | Result := True;
256 | hSnapShot := CreateToolHelp32Snapshot($00000002, 0);
257 | if (hSnapShot <> longword(-1)) then
258 | try
259 | ProcInfo.dwSize := SizeOf(ProcInfo);
260 | if (Process32First(hSnapshot, ProcInfo)) then
261 | repeat
262 | if ProcInfo.th32ParentProcessID = ProcessId then
263 | begin
264 | if length(childs) = 0 then
265 | begin
266 | SetLength(childs, 1);
267 | childs[0] := ProcInfo.th32ParentProcessID;
268 | end
269 | else
270 | if not (IntIn(ProcInfo.th32ParentProcessID, childs)) then
271 | begin
272 | SetLength(childs, length(childs) + 1);
273 | childs[length(childs) - 1] := ProcInfo.th32ParentProcessID;
274 | end;
275 | if IntIn(ProcInfo.th32ParentProcessID, childs) then
276 | Result := False;
277 | end;
278 | until not Process32Next(hSnapShot, ProcInfo);
279 | finally
280 | CloseHandle(hSnapShot);
281 | end;
282 | end;
283 |
284 | function AltOSVersion: longword;
285 | var
286 | Version: OSVersionInfoA;
287 | begin
288 | Version.dwOSVersionInfoSize := SizeOf(Version);
289 | if GetVersionExA(Version) then
290 | Result := Version.dwMajorVersion;
291 | end;
292 |
293 | function HasProcess(target: UnicodeString; mode: longword; Name: boolean; basepath: unicodestring): boolean;
294 | var
295 | hSnapShot: longword;
296 | ProcInfo: ProcessEntry32;
297 | HProcess: longword;
298 | Len, Count: longword;
299 | Image, Ltarget: UnicodeString;
300 | begin
301 | Result := False;
302 | Count := 0;
303 | Ltarget := LowerCase(target);
304 | if Pos(PathDelim, Ltarget) = 0 then
305 | Ltarget := LowerCase(RelToAbs(target, basepath));
306 | if Name then
307 | Ltarget := LowerCase(ExtractFileName(Ltarget));
308 | hSnapShot := CreateToolHelp32Snapshot($00000002, 0);
309 | if (hSnapShot <> longword(-1)) then
310 | try
311 | ProcInfo.dwSize := SizeOf(ProcInfo);
312 | if (Process32First(hSnapshot, ProcInfo)) then
313 | repeat
314 | if AltOSVersion > 5 then
315 | HProcess := OpenProcess($1000 or $0010, False, ProcInfo.th32ProcessID)
316 | else
317 | HProcess := OpenProcess($000F0000 or $00100000 or $FFF, False, ProcInfo.th32ProcessID);
318 | if HProcess <> 0 then
319 | begin
320 | SetLength(Image, 260);
321 | Len := 261;
322 | if Name then
323 | Image := LowerCase(UnicodeString(ProcInfo.szExeFile))
324 | else
325 | if GetModuleFileNameExW(HProcess, 0, Pwidechar(Image), Len) > 0 then
326 | begin
327 | SetLength(Image, Len);
328 | Image := LowerCase(UnicodeString(PWidechar(Image)));
329 | end;
330 | if Ltarget = Image then
331 | Inc(Count);
332 | end;
333 | CloseHandle(HProcess);
334 | until not Process32Next(hSnapShot, ProcInfo);
335 | finally
336 | CloseHandle(hSnapShot);
337 | end;
338 | if (mode = 0) and (Count > 1) then
339 | Result := True;
340 | if (mode = 1) and (Count > 0) then
341 | Result := True;
342 | end;
343 |
344 | end.
345 |
--------------------------------------------------------------------------------
/AltCmd.pas:
--------------------------------------------------------------------------------
1 | unit AltCmd;
2 |
3 | interface
4 |
5 | uses
6 | AltExt, AltStream,
7 | AltSys;
8 |
9 | function GetAllParams(var ParamCount: longint; var ParamStr: ArrStr): boolean;
10 | procedure WorkAllParams(var ParamCount: longint; var ParamStr: ArrStr);
11 | function hp(ParamCount: longint; ParamStr: ArrStr; const S1, S2: UnicodeString): boolean;
12 | function gp(ParamCount: longint; ParamStr: ArrStr; const C: UnicodeString; const S: UnicodeString): UnicodeString;
13 | procedure CommandLineToArgv(CmdLine: UnicodeString; var ParamCount: longint; var ParamStr: ArrStr);
14 |
15 | implementation
16 |
17 | function ReadStreamLine(Stream: TStream; var Line: UnicodeString): boolean;
18 | var
19 | RawLine: string;
20 | ch: char;
21 | begin
22 | Result := False;
23 | RawLine := '';
24 | ch := #0;
25 | while (Stream.Read(ch, 1) = 1) and (ch <> #13) do
26 | begin
27 | Result := True;
28 | RawLine := RawLine + ch;
29 | end;
30 | Line := RawLine;
31 | if ch = #13 then
32 | begin
33 | Result := True;
34 | if (Stream.Read(ch, 1) = 1) and (ch <> #10) then
35 | Stream.Seek(-1, soCurrent);
36 | end;
37 | end;
38 |
39 | procedure CommandLineToArgv(CmdLine: UnicodeString; var ParamCount: longint; var ParamStr: ArrStr);
40 | var
41 | TmpStr, tmpstr2, tmpstr3: ArrStr;
42 | i, j, k: longint;
43 | begin
44 | tmpStr := split(cmdline, ' ');
45 | i := 0;
46 | j := 0;
47 | while (i < length(tmpstr)) and (j < length(tmpstr)) do
48 | begin
49 | setlength(tmpstr2, j + 1);
50 | TmpStr2[j] := TmpStr[i];
51 | if (Pos(dq, TmpStr2[j]) > 0) and (CharCount(dq, TmpStr2[j]) <> 2) then
52 | begin
53 | if i + 1 <= Length(TmpStr) - 1 then
54 | if Pos(dq, TmpStr[i + 1]) = 0 then
55 | for k := i + 1 to length(tmpstr) - 1 do
56 | begin
57 | if Pos(dq, TmpStr[k]) = 0 then
58 | begin
59 | TmpStr2[j] := TmpStr2[j] + ' ' + TmpStr[k];
60 | Inc(i);
61 | end
62 | else
63 | break;
64 | end;
65 | Inc(i);
66 | if i <= Length(TmpStr) - 1 then
67 | TmpStr2[j] := TmpStr2[j] + ' ' + TmpStr[i];
68 | end;
69 | Inc(i);
70 | Inc(j);
71 | end;
72 | i := 0;
73 | j := 0;
74 | while (i < length(tmpstr2)) and (j < length(tmpstr2)) do
75 | begin
76 | setlength(tmpstr3, j + 1);
77 | TmpStr3[j] := TmpStr2[i];
78 | if (Pos(sq, TmpStr3[j]) > 0) and (CharCount(sq, TmpStr3[j]) <> 2) then
79 | begin
80 | if i + 1 <= Length(TmpStr2) - 1 then
81 | if Pos(sq, TmpStr2[i + 1]) = 0 then
82 | for k := i + 1 to length(tmpstr2) - 1 do
83 | begin
84 | if Pos(sq, TmpStr2[k]) = 0 then
85 | begin
86 | TmpStr3[j] := TmpStr3[j] + ' ' + TmpStr2[k];
87 | Inc(i);
88 | end
89 | else
90 | break;
91 | end;
92 | Inc(i);
93 | if i <= Length(TmpStr2) - 1 then
94 | TmpStr3[j] := TmpStr3[j] + ' ' + TmpStr2[i];
95 | end;
96 | if Length(TmpStr3[j]) = 0 then
97 | Dec(j);
98 | Inc(i);
99 | Inc(j);
100 | end;
101 | for i := 0 to Length(TmpStr3) - 1 do
102 | begin
103 | if CharCount(sq, TmpStr3[i]) = 2 then
104 | if (TmpStr3[i][1] = sq) and (TmpStr3[i][Length(TmpStr3[i])] = sq) then
105 | TmpStr3[i] := Copy(TmpStr3[i], 2, Length(TmpStr3[i]) - 2);
106 | if Pos(sq, TmpStr3[i]) > 0 then
107 | TmpStr3[i] := StringReplace(TmpStr3[i], sq, '', [rfReplaceAll]);
108 | if CharCount(dq, TmpStr3[i]) = 2 then
109 | if (TmpStr3[i][1] = dq) and (TmpStr3[i][Length(TmpStr3[i])] = dq) then
110 | TmpStr3[i] := Copy(TmpStr3[i], 2, Length(TmpStr3[i]) - 2);
111 | end;
112 | i := 0;
113 | while ((TmpStr3[i][1] <> hyp) and (i < Length(TmpStr3) - 1)) do
114 | Inc(i);
115 | if (i > 1) and (i < Length(TmpStr3) - 1) then
116 | begin
117 | SetLength(ParamStr, Length(TmpStr3) - i + 1);
118 | ParamStr[0] := '';
119 | for j := 0 to i - 1 do
120 | if ParamStr[0] = '' then
121 | ParamStr[0] := ParamStr[0] + TmpStr3[j]
122 | else
123 | ParamStr[0] := ParamStr[0] + ' ' + TmpStr3[j];
124 | for j := i to Length(TmpStr3) - 1 do
125 | ParamStr[j - i + 1] := TmpStr3[j];
126 | end
127 | else
128 | ParamStr := TmpStr3;
129 | ParamCount := Length(ParamStr);
130 | end;
131 |
132 | function GetParamsFrom(Mode: string; Name: UnicodeString; Param0, o: UnicodeString; var ParamCount: longint; var ParamStr: ArrStr): boolean;
133 | var
134 | i, j: longint;
135 | FileCfg: TFileStream;
136 | ResCfg: TResourceStream;
137 | Tmp: UnicodeString;
138 | TmpStr: ArrStr;
139 | ReadOK: boolean;
140 | begin
141 | Result := False;
142 | if Mode = 'File' then
143 | FileCfg := TFileStream.Create(Name, 0);
144 | if Mode = 'Res' then
145 | ResCfg := TResourceStream.Create(HInstance, Name, PChar(10));
146 | i := 0;
147 | ReadOK := False;
148 | repeat
149 | Tmp := '';
150 | if Mode = 'File' then
151 | ReadOK := ReadStreamLine(FileCfg, Tmp);
152 | if Mode = 'Res' then
153 | ReadOK := ReadStreamLine(ResCfg, Tmp);
154 | if ReadOK then
155 | begin
156 | SetLength(TmpStr, i + 1);
157 | TmpStr[i] := Tmp;
158 | end;
159 | Inc(i);
160 | until not ReadOK;
161 | if Mode = 'File' then
162 | FileCfg.Free;
163 | if Mode = 'Res' then
164 | ResCfg.Free;
165 | Tmp := Param0;
166 | if Length(TmpStr) > 0 then
167 | begin
168 | for j := 0 to Length(TmpStr) - 1 do
169 | Tmp := Tmp + ' ' + TmpStr[j];
170 | CommandLineToArgv(Tmp, ParamCount, ParamStr);
171 | Result := True;
172 | end;
173 | if o <> '' then
174 | begin
175 | ParamCount := ParamCount + 2;
176 | SetLength(ParamStr, ParamCount);
177 | ParamStr[ParamCount - 2] := '-o';
178 | ParamStr[ParamCount - 1] := o;
179 | end;
180 | end;
181 |
182 | function GetAllParams(var ParamCount: longint; var ParamStr: ArrStr): boolean;
183 | var
184 | CmdLineW: PWideChar;
185 | i: longint;
186 | CfgName, o: UnicodeString;
187 | begin
188 | Result := False;
189 | o := '';
190 | new(CmdLineW);
191 | CmdLineW := GetCommandLineW;
192 | {$IFDEF DBG}
193 | Writeln;
194 | Writeln('Command Line');
195 | Writeln;
196 | writeln(string(CmdLineW));
197 | {$ENDIF}
198 | CommandLineToArgv(UnicodeString(CmdLineW), ParamCount, ParamStr);
199 | if not hp(ParamCount, ParamStr, 'g', 'cfg') then
200 | begin
201 | if hp(ParamCount, ParamStr, 'r', 'run') or hp(ParamCount, ParamStr, 'rb', 'right-button') or hp(ParamCount, ParamStr, 'c', ctrl) or
202 | hp(ParamCount, ParamStr, 'a', alt) or hp(ParamCount, ParamStr, 's', shift) or hp(ParamCount, ParamStr, 'ca', ctrl + hyp + alt) or
203 | hp(ParamCount, ParamStr, 'cs', ctrl + hyp + shift) or hp(ParamCount, ParamStr, 'as', alt + hyp + shift) or hp(ParamCount, ParamStr, 'cas', ctrl + hyp + alt + hyp + shift) then
204 | Result := True
205 | else
206 | begin
207 | if ParamCount > 1 then
208 | begin
209 | if pos(space, ParamStr[1]) > 0 then
210 | o := dq + ParamStr[1] + dq
211 | else
212 | o := ParamStr[1];
213 | for i := 2 to ParamCount - 1 do
214 | if pos(space, ParamStr[i]) > 0 then
215 | o := o + ' ' + dq + ParamStr[i] + dq
216 | else
217 | o := o + ' ' + ParamStr[i];
218 | end;
219 | CfgName := GetCurrentDir + ExtractFileName(ParamStr[0]);
220 | SetLength(CfgName, Length(CfgName) - 3);
221 | CfgName := CfgName + 'cfg';
222 | if not (Exists(CfgName)) then
223 | begin
224 | CfgName := ParamStr[0];
225 | SetLength(CfgName, Length(CfgName) - 3);
226 | CfgName := CfgName + 'cfg';
227 | end;
228 | if Exists(CfgName) then
229 | begin
230 | if GetParamsFrom('File', CfgName, ParamStr[0], o, ParamCount, ParamStr) then
231 | Result := True;
232 | end;
233 | end;
234 | end
235 | else
236 | begin
237 | CfgName := gp(ParamCount, ParamStr, 'g', 'cfg');
238 | if (Pos(dots, CfgName) = 0) then
239 | CfgName := RelToAbs(CfgName, GetCurrentDir);
240 | if not Exists(CfgName) then
241 | begin
242 | CfgName := gp(ParamCount, ParamStr, 'g', 'cfg');
243 | if (Pos(dots, CfgName) = 0) then
244 | CfgName := RelToAbs(CfgName, ExtractFilePath(ParamStr[0]));
245 | end;
246 | if Exists(CfgName) then
247 | begin
248 | if GetParamsFrom('File', CfgName, ParamStr[0], o, ParamCount, ParamStr) then
249 | Result := True;
250 | end;
251 | end;
252 | if not Result then
253 | if GetParamsFrom('Res', 'CONFIG', ParamStr[0], o, ParamCount, ParamStr) then
254 | Result := True;
255 | end;
256 |
257 | procedure WorkAllParams(var ParamCount: longint; var ParamStr: ArrStr);
258 | var
259 | TmpCount: longint;
260 | TmpStr: ArrStr;
261 | i, j, k, offset: longint;
262 | tmp, val: UnicodeString;
263 | tmpsplit: ArrStr;
264 | begin
265 | TmpCount := 1;
266 | SetLength(TmpStr, TmpCount);
267 | TmpStr[0] := ParamStr[0];
268 | j := 0;
269 | if ParamCount > 1 then
270 | begin
271 | for i := 1 to ParamCount - 1 do
272 | begin
273 | offset := 0;
274 | tmp := '';
275 | if Length(ParamStr[i]) > 0 then
276 | if ((ParamStr[i][1] = hyp) and (ParamStr[i][2] = hyp)) then
277 | if Pos(separator, ParamStr[i]) <> 0 then
278 | if Pos(eq, ParamStr[i]) = 0 then
279 | begin
280 | tmp := StringReplace(ParamStr[i], hyp + hyp, '', []);
281 | tmpsplit := split(tmp, separator);
282 | offset := length(tmpsplit);
283 | for k := 0 to Length(tmpsplit) - 1 do
284 | begin
285 | Inc(j);
286 | SetLength(TmpStr, j + 1);
287 | TmpStr[j] := hyp + hyp + tmpsplit[k];
288 | end;
289 | SetLength(tmpsplit, 0);
290 | end
291 | else
292 | if Pos(separator, ParamStr[i]) < Pos(eq, ParamStr[i]) then
293 | begin
294 | val := '';
295 | tmp := ExtractBetween(ParamStr[i], hyp + hyp, eq);
296 | val := StringReplace(ParamStr[i], hyp + hyp + tmp + eq, '', []);
297 | tmpsplit := split(tmp, separator);
298 | offset := length(tmpsplit);
299 | for k := 0 to Length(tmpsplit) - 1 do
300 | begin
301 | Inc(j);
302 | SetLength(TmpStr, j + 1);
303 | TmpStr[j] := hyp + hyp + tmpsplit[k] + eq + val;
304 | end;
305 | SetLength(tmpsplit, 0);
306 | end;
307 | tmp := '';
308 | if Length(ParamStr[i]) > 0 then
309 | if ((ParamStr[i][1] = hyp) and (ParamStr[i][2] <> hyp)) then
310 | if Pos(separator, ParamStr[i]) <> 0 then
311 | begin
312 | tmp := StringReplace(ParamStr[i], hyp, '', []);
313 | tmpsplit := split(tmp, separator);
314 | offset := length(tmpsplit);
315 | val := '';
316 | if i < Length(ParamStr) - 1 then
317 | if ParamStr[i + 1][1] <> hyp then
318 | val := ParamStr[i + 1];
319 | if val <> '' then
320 | offset := length(tmpsplit) * 2
321 | else
322 | offset := length(tmpsplit);
323 | for k := 0 to Length(tmpsplit) - 1 do
324 | begin
325 | Inc(j);
326 | SetLength(TmpStr, j + 1);
327 | TmpStr[j] := hyp + tmpsplit[k];
328 | if val <> '' then
329 | begin
330 | Inc(j);
331 | SetLength(TmpStr, j + 1);
332 | TmpStr[j] := val;
333 | end;
334 | end;
335 | SetLength(tmpsplit, 0);
336 | if val <> '' then
337 | Dec(j);
338 | tmp := '';
339 | end;
340 | if offset = 0 then
341 | begin
342 | Inc(j);
343 | SetLength(TmpStr, j + 1);
344 | TmpStr[j] := ParamStr[i];
345 | end;
346 | end;
347 | end;
348 | ParamCount := Length(TmpStr);
349 | ParamStr := TmpStr;
350 | end;
351 |
352 | function GetParamAtIndex(ParamCount: longint; ParamStr: ArrStr; AIndex: integer; IsLong: boolean): UnicodeString;
353 | var
354 | P: integer;
355 | O: UnicodeString;
356 | begin
357 | Result := '';
358 | if (AIndex = 0) then
359 | Exit;
360 | if IsLong then
361 | begin
362 | O := ParamStr[AIndex];
363 | P := Pos(eq, O);
364 | if (P = 0) then
365 | P := Length(O);
366 | Delete(O, 1, P);
367 | Result := O;
368 | end
369 | else
370 | begin
371 | if ((AIndex + 1) < ParamCount) then
372 | Result := ParamStr[AIndex + 1];
373 | end;
374 | end;
375 |
376 | function FindParamIndex(ParamCount: longint; ParamStr: ArrStr; const S: UnicodeString; var Longopt: boolean; StartAt: integer = 0): integer;
377 | var
378 | SO, O: UnicodeString;
379 | I, P: integer;
380 | begin
381 | SO := S;
382 | Result := 0;
383 | I := StartAt;
384 | if (I = 0) then
385 | I := ParamCount - 1;
386 | while (Result = 0) and (I >= 0) do
387 | begin
388 | O := ParamStr[i];
389 | if (Length(O) > 1) and (O[1] = hyp) then
390 | begin
391 | Delete(O, 1, 1);
392 | LongOpt := (Length(O) > 0) and (O[1] = hyp);
393 | if LongOpt then
394 | begin
395 | Delete(O, 1, 1);
396 | P := Pos(eq, O);
397 | if (P <> 0) then
398 | O := Copy(O, 1, P - 1);
399 | end;
400 | if (O = SO) then
401 | Result := i;
402 | end;
403 | Dec(i);
404 | end;
405 | end;
406 |
407 | function hp(ParamCount: longint; ParamStr: ArrStr; const S1, S2: UnicodeString): boolean;
408 | var
409 | B: boolean;
410 | begin
411 | Result := False;
412 | if FindParamIndex(ParamCount, ParamStr, S1, B) <> 0 or FindParamIndex(ParamCount, ParamStr, S2, B) then
413 | Result := True;
414 | end;
415 |
416 | function gp(ParamCount: longint; ParamStr: ArrStr; const C: UnicodeString; const S: UnicodeString): UnicodeString;
417 | var
418 | B: boolean;
419 | I: integer;
420 | begin
421 | Result := '';
422 | I := FindParamIndex(ParamCount, ParamStr, C, B);
423 | if (I = 0) then
424 | I := FindParamIndex(ParamCount, ParamStr, S, B);
425 | if I <> 0 then
426 | Result := GetParamAtIndex(ParamCount, ParamStr, I, B);
427 | if Result = '""' then
428 | Result := ''
429 | else
430 | if Result <> '' then
431 | if (((Result[1] = dq) and (Result[Length(Result)] = dq)) and (CharCount(dq, Result) = 2)) then
432 | Result := Copy(Result, 2, Length(Result) - 2);
433 | end;
434 |
435 | end.
436 |
--------------------------------------------------------------------------------
/altrun.lps:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 |
318 |
319 |
320 |
321 |
322 |
323 |
324 |
325 |
326 |
327 |
328 |
329 |
330 |
331 |
332 |
333 |
334 |
335 |
336 |
337 |
338 |
339 |
340 |
341 |
342 |
343 |
344 |
345 |
346 |
347 |
348 |
349 |
350 |
351 |
352 |
353 |
354 |
355 |
356 |
357 |
358 |
359 |
360 |
361 |
362 |
363 |
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 |
372 |
373 |
374 |
375 |
376 |
377 |
378 |
379 |
380 |
381 |
382 |
383 |
384 |
385 |
386 |
387 |
388 |
389 |
390 |
391 |
392 |
393 |
394 |
395 |
396 |
397 |
398 |
399 |
400 |
401 |
402 |
403 |
404 |
405 |
406 |
407 |
408 |
409 |
410 |
411 |
412 |
413 |
414 |
415 |
416 |
417 |
418 |
419 |
420 |
421 |
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 |
430 |
431 |
432 |
433 |
434 |
435 |
436 |
437 |
438 |
439 |
440 |
441 |
442 |
443 |
444 |
445 |
446 |
447 |
448 |
449 |
450 |
451 |
452 |
453 |
454 |
455 |
456 |
457 |
458 |
459 |
460 |
461 |
462 |
463 |
464 |
465 |
466 |
467 |
468 |
469 |
470 |
471 |
472 |
473 |
474 |
475 |
476 |
477 |
478 |
479 |
480 |
481 |
482 |
483 |
484 |
485 |
486 |
487 |
488 |
489 |
490 |
491 |
492 |
493 |
494 |
495 |
496 |
497 |
498 |
499 |
500 |
501 |
502 |
503 |
504 |
505 |
506 |
507 |
508 |
509 |
510 |
511 |
512 |
513 |
514 |
515 |
516 |
517 |
518 |
519 |
520 |
521 |
522 |
523 |
524 |
525 |
526 |
527 |
528 |
529 |
530 |
531 |
532 |
533 |
534 |
535 |
536 |
537 |
538 |
539 |
540 |
541 |
542 |
543 |
544 |
545 |
546 |
547 |
548 |
549 |
550 |
551 |
552 |
553 |
554 |
555 |
556 |
557 |
558 |
559 |
560 |
561 |
562 |
563 |
564 |
565 |
566 |
567 |
568 |
569 |
570 |
571 |
572 |
573 |
574 |
575 |
576 |
577 |
578 |
579 |
580 |
581 |
582 |
583 |
584 |
585 |
586 |
587 |
588 |
589 |
590 |
--------------------------------------------------------------------------------