0,0 → 1,385 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; Copyright (C) Vasiliy Kosenko (vkos), 2009 ;; |
;; Launch is free software: you can redistribute it and/or modify it under the terms of the GNU ;; |
;; General Public License as published by the Free Software Foundation, either version 2 ;; |
;; of the License, or (at your option) any later version. ;; |
;; ;; |
;; Launch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without ;; |
;; even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ;; |
;; General Public License for more details. ;; |
;; ;; |
;; You should have received a copy of the GNU General Public License along with Launch. ;; |
;; If not, see <http://www.gnu.org/licenses/>. ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; Launch finds program in search dirictories and runs it. ;; |
;; For more details see readme.txt ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
|
APP_NAME fix 'Launch' |
APP_VERSION fix '0.1.3' |
|
use32 |
org 0x0 |
|
db 'MENUET01' |
dd 0x01 |
dd START |
dd APP_END |
dd MEM_END |
dd APP_STACK |
dd args |
dd path |
|
define PATH_MAX_LEN 1024 |
define DEBUG_MAX_LEN 8 |
define DEBUG_DEFAULT debug_no_num |
define BUFF_SIZE 1024 |
|
include 'macros.inc' |
include 'proc32.inc' |
include 'libio.inc' |
include 'mem.inc' |
include 'dll.inc' |
|
START: |
;; Initialize process heap |
mcall 68,11 |
test eax, eax |
jz exit |
|
;; Import modules |
stdcall dll.Load,importTable |
test eax, eax |
jnz exit |
|
read_ini: |
;; First read config in /sys/etc |
invoke ini.get_str, etc_cfg, cfg_main, cfg_path, search_path, PATH_MAX_LEN, empty_str |
|
;; Next, read config from current directory |
;; Find end of path string |
.find_path_eol: |
mov edi, path |
mov ecx, PATH_MAX_LEN |
xor al, al |
cld |
repne scasb |
|
;; Append ext to run path (NOTE: this work only when config file has name <launch-file-name>.cfg and ext size is dword) |
mov eax, dword [cfg_ext] |
dec edi |
mov dword [edi], eax |
mov byte [edi+5], 0 |
|
;; Currently there is no checking for repeating pathes, so we should only concatenate two strings |
;; So we need to find end of current search_path string |
.find_search_eol: |
mov edi, search_path |
mov ecx, PATH_MAX_LEN |
xor al, al |
;cld |
repne scasb |
dec edi |
|
;; Now we need to correct buffer length |
mov eax, path+PATH_MAX_LEN |
sub eax, edi |
;; Read ini |
invoke ini.get_str, path, cfg_main, cfg_path, edi, PATH_MAX_LEN, empty_str |
|
read_ini_debug: |
;; Read debug options from config files |
invoke ini.get_str, etc_cfg, cfg_debug, cfg_debug, debug_option, DEBUG_MAX_LEN, DEBUG_DEFAULT |
invoke ini.get_str, path, cfg_debug, cfg_debug, debug_option, DEBUG_MAX_LEN, debug_option |
|
;; Now convert debug_option from string to number of debug mode |
mov ebx, modes-4 |
.convert: |
mov al, byte [debug_option] |
cmp al, 10 |
jbe .converted |
|
.convert_nxt: |
add ebx, 4 |
mov esi, dword [ebx] |
test esi, esi |
je .set_default ;; String is incorrect, so set default |
mov edi, debug_option |
.conv_loop: |
mov al, byte [esi] |
cmp al, byte [edi] |
jne .convert_nxt ;; Not equal, so try next |
test al, al |
je .found ;; Equal, end of loop |
inc esi |
inc edi |
jmp .conv_loop |
|
.set_default: |
mov al, byte [DEBUG_DEFAULT] |
mov byte [debug_option], al |
jmp .converted |
|
.found: |
sub ebx, modes |
shr ebx, 2 |
add ebx, modes_nums |
mov al, byte [ebx] |
mov byte [debug_option], al |
|
.converted: |
dec al |
test al, al |
je .ok |
dec al |
test al, al |
je .con_init |
|
.noconsole: |
mov al, 1 |
mov byte [debug_option], al |
jmp .ok |
|
.con_init: |
stdcall dll.Load, consoleImport |
test eax, eax |
jnz .noconsole |
invoke con.init, -1, -1, -1, -1, WinTitle |
|
.read_level: |
invoke ini.get_int, etc_cfg, cfg_debug, cfg_level, 0 |
invoke ini.get_int, path, cfg_debug, cfg_level, eax |
mov dword [debug_level], eax |
.ok: |
|
parse_args: |
;; Now parse command line arguments |
;; TODO: use optparse library |
;; Currently the only argument to parse is program name |
|
.skip_spaces: |
mov ecx, -1 |
mov edi, args |
mov al, ' ' |
;cld |
repe scasb |
|
push edi |
|
mov ecx, -1 |
repne scasb |
mov dword [prog_args], edi |
|
pop edi |
dec edi |
;; Now edi = program name |
|
;; End of preparations! Now we can find file and launch it. |
search_file: |
push edi |
mov esi, search_path |
xchg esi, [esp] |
.loop: |
or dl, dl |
je .prn_dbg |
xor dl, dl |
jmp .prn_end |
.prn_dbg: |
push eax |
mov al, byte [debug_option] |
dec al |
test al, al |
je .prn_stp |
mov eax, dword [debug_level] |
or eax, eax |
je .prn_stp |
dec eax |
or eax, eax |
je .prn_1 |
.prn_1: |
cinvoke con.printf, message_dbg_not_found, buff |
|
.prn_stp: |
pop eax |
.prn_end: |
xor eax, eax ;; When we check is proramme launched we are checking for eax |
xchg esi, [esp] |
mov edi, buff |
.copy_path: |
lodsb |
cmp al, ';' |
je .copy_file |
or al, al |
je exit |
stosb |
jmp .copy_path |
|
.copy_file: |
xchg esi, [esp] |
push esi |
.cp_file_loop: |
lodsb |
or al, al |
je .copy_end |
cmp al, ' ' |
je .copy_end |
stosb |
jmp .cp_file_loop |
|
.copy_end: |
pop esi |
xor al, al |
stosb |
|
;; Try to launch |
|
mov dword [LaunchStruct.Function], 7 |
push dword [prog_args] |
pop dword [LaunchStruct.Arguments] |
mov dword [LaunchStruct.Flags], 0 |
mov dword [LaunchStruct.Zero], 0 |
mov dword [LaunchStruct.FileNameP], buff |
mcall 70, LaunchStruct |
cmp eax, 0 |
jl .loop |
|
exit: |
push eax |
;; If console is present we should write some info |
mov al, byte [debug_option] |
cmp al, 2 |
je .write_console |
|
.close: |
mcall -1 |
|
.write_console: |
pop eax |
test eax, eax |
jz .write_error |
.write_launched: |
cinvoke con.printf, message_ok, buff, eax, eax |
jmp .wr_end |
.write_error: |
pop edi |
cinvoke con.printf, message_error, edi |
.wr_end: |
invoke con.exit, 0 |
jmp .close |
|
align 16 |
importTable: |
library \ |
libini, 'libini.obj';, \ |
; libio, 'libio.obj', \ |
|
import libini, \ |
ini.get_str ,'ini.get_str', \ |
\; ini.set_str ,'ini.set_str', \ |
ini.get_int ,'ini.get_int';, \ |
\; ini.set_int ,'ini.set_int', \ |
; ini.get_color,'ini.get_color', \ |
; ini.set_color,'ini.set_color' |
|
;import libio, \ |
; file.find_first,'file.find_first', \ |
; file.find_next ,'file.find_next', \ |
; file.find_close,'file.find_close', \ |
; file.size ,'file.size', \ |
; file.open ,'file.open', \ |
; file.read ,'file.read', \ |
; file.write ,'file.write', \ |
; file.seek ,'file.seek', \ |
; file.tell ,'file.tell', \ |
; file.eof? ,'file.eof?', \ |
; file.truncate ,'file.truncate', \ |
; file.close ,'file.close' |
|
consoleImport: |
library \ |
conlib, 'console.obj' |
|
import conlib, \ |
con.init, 'con.init',\ |
con.exit, 'con.exit',\ |
con.printf, 'con.printf';,\ |
; con.write_asciiz, 'con.write_asciiz' |
|
align 16 |
APP_DATA: |
|
WinTitle: |
db APP_NAME, ' ', APP_VERSION, 0 |
|
message_dbg_not_found: |
db '%s not found', 10, 0 |
|
message_error: |
db 'File (%s) not found!', 0 |
|
message_ok: |
db '%s loaded succesfully. PID: %d (0x%X)' |
|
empty_str: |
db 0 |
etc_cfg: |
db '/sys/etc/' |
cfg_name: |
db 'launch' |
cfg_ext: |
db '.cfg', 0 |
|
cfg_main: |
db 'main', 0 |
cfg_path: |
db 'path', 0 |
cfg_debug: |
db 'debug', 0 |
cfg_level: |
db 'level', 0 |
|
modes: |
dd debug_no |
dd debug_console |
dd 0 |
|
debug_no: |
db 'no', 0 |
debug_console: |
db 'console', 0 |
|
modes_nums: |
debug_no_num: |
db 1 |
|
debug_console_num: |
db 2 |
|
debug_level: |
dd 0 |
|
LaunchStruct FileInfoRun |
|
args: db 0 |
APP_END: |
rb 255 |
|
prog_args: |
rd 1 |
path: |
rb 1024 |
|
search_path: |
rb PATH_MAX_LEN |
|
debug_option: |
rb DEBUG_MAX_LEN |
|
buff: |
rb BUFF_SIZE |
|
rb 0x1000 ;; 4 Kb stack |
APP_STACK: |
MEM_END: |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |