forked from KolibriOS/kolibrios
Ivan Baravy
c5c24e6776
This is example/experimental build: - It uses INCLUDE environment variable to locate includes; - It specifies language as -dlang=xx fasm option, no lang.inc file. git-svn-id: svn://kolibrios.org@6834 a494cfbc-eb01-0410-851d-a64ba20cac60
469 lines
11 KiB
NASM
Executable File
469 lines
11 KiB
NASM
Executable File
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;; 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 3 ;;
|
|
;; 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 ;;
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
format binary
|
|
|
|
APP_NAME fix 'Launch'
|
|
APP_VERSION fix '0.1.80.1'
|
|
|
|
use32
|
|
org 0x0
|
|
|
|
db 'MENUET01'
|
|
dd 0x01
|
|
dd START
|
|
dd APP_END
|
|
dd MEM_END
|
|
dd APP_STACK
|
|
dd args
|
|
dd path
|
|
|
|
define DEBUG_NO 0
|
|
define DEBUG_CONSOLE 1
|
|
define DEBUG_BOARD 2 ;; Not used now
|
|
|
|
define PATH_MAX_LEN 1024
|
|
define DEBUG_MAX_LEN 8
|
|
define DEBUG_DEFAULT 0
|
|
define BUFF_SIZE 1024
|
|
|
|
include 'proc32.inc'
|
|
include 'macros.inc'
|
|
include 'develop/libraries/libs-dev/libio/libio.inc'
|
|
include 'dll.inc'
|
|
|
|
purge mov
|
|
|
|
include 'thread.inc'
|
|
include 'ipc.inc'
|
|
include 'kobra.inc'
|
|
|
|
;;--------------------------------------------------------------------------------------------------
|
|
;; Basic initialization
|
|
START:
|
|
;; Initialize process heap
|
|
mcall 68,11
|
|
test eax, eax
|
|
jz exit
|
|
|
|
;; Import modules
|
|
stdcall dll.Load,importTable
|
|
test eax, eax
|
|
jnz exit
|
|
|
|
;;--------------------------------------------------------------------------------------------------
|
|
;; Reading config
|
|
read_ini_path: ;; Read search path
|
|
;; 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
|
|
;; Read debug options from config files
|
|
invoke ini.get_option_str, etc_cfg, cfg_debug, cfg_debug, debug_strings, DEBUG_MAX_LEN, DEBUG_DEFAULT
|
|
invoke ini.get_option_str, path, cfg_debug, cfg_debug, debug_strings, DEBUG_MAX_LEN, eax
|
|
mov [debug_option], eax
|
|
|
|
test eax, eax ;; No console
|
|
je .ok
|
|
|
|
jmp .con_init
|
|
|
|
.console_err:
|
|
mov byte [debug_option], 0
|
|
jmp .ok
|
|
|
|
.con_init:
|
|
stdcall dll.Load, consoleImport
|
|
test eax, eax
|
|
jnz .console_err
|
|
invoke con.init, -1, -1, -1, -1, window_title
|
|
|
|
.read_level:
|
|
invoke ini.get_int, etc_cfg, cfg_debug, cfg_level, 0
|
|
invoke ini.get_int, path, cfg_debug, cfg_level, eax
|
|
mov byte [debug_level], al
|
|
.ok:
|
|
|
|
read_ini_kobra:
|
|
invoke ini.get_bool, etc_cfg, cfg_kobra, cfg_use, 0
|
|
invoke ini.get_bool, path, cfg_kobra, cfg_use, eax
|
|
|
|
mov byte [kobra_use], al
|
|
|
|
;;--------------------------------------------------------------------------------------------------
|
|
;; Parse command line options
|
|
parse_args:
|
|
;; Now parse command line arguments
|
|
;; TODO: use optparse library
|
|
;; Currently the only argument to parse is program name with its' arguments
|
|
|
|
.skip_spaces:
|
|
mov ecx, -1
|
|
mov edi, args
|
|
mov al, ' '
|
|
xor bl, bl
|
|
;cld
|
|
repe scasb
|
|
|
|
push edi
|
|
|
|
mov ecx, -1
|
|
@@:
|
|
scasb
|
|
je @f
|
|
xchg al, bl
|
|
dec edi
|
|
scasb
|
|
jne @b
|
|
@@:
|
|
mov dword [prog_args], edi
|
|
|
|
pop edi
|
|
dec edi
|
|
;; Now edi = program name
|
|
|
|
;;--------------------------------------------------------------------------------------------------
|
|
;; Finding file
|
|
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 al, byte [debug_level]
|
|
or al, al
|
|
je .prn_stp
|
|
dec al
|
|
or al, al
|
|
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
|
|
exit:
|
|
mov dword [tid], eax
|
|
;; If console is present we should write some info
|
|
mov al, byte [debug_option]
|
|
cmp al, DEBUG_CONSOLE
|
|
jne .kobra
|
|
|
|
.write_console:
|
|
mov eax, dword [tid]
|
|
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
|
|
|
|
.kobra:
|
|
mov al, byte [kobra_use]
|
|
test al, al
|
|
je .close
|
|
|
|
.register:
|
|
mov dword [IPC_area], buff
|
|
call IPC_init
|
|
; jnz .close
|
|
|
|
mov dword [thread_find_buff], another_buff
|
|
|
|
call kobra_register
|
|
|
|
test eax, eax
|
|
jnz .close
|
|
|
|
;; Prepare message
|
|
mov dword [kobra_message], KOBRA_MESSAGE_LAUNCH_STATE
|
|
|
|
mov eax, dword [tid]
|
|
mov dword [kobra_message+4], eax
|
|
|
|
.kobra_send:
|
|
stdcall kobra_send_message, kobra_group_launch_reactive, kobra_message, 8
|
|
|
|
.close:
|
|
mcall -1
|
|
|
|
;; End of code
|
|
;;--------------------------------------------------------------------------------------------------
|
|
|
|
;;--------------------------------------------------------------------------------------------------
|
|
;; Imports
|
|
align 16
|
|
importTable:
|
|
|
|
library libini, 'libconfig.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', \
|
|
ini.get_option_str ,'ini_get_option_str', \
|
|
ini.get_bool ,'ini_get_bool';,\
|
|
|
|
;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'
|
|
|
|
;;--------------------------------------------------------------------------------------------------
|
|
;; Data
|
|
align 16
|
|
APP_DATA:
|
|
|
|
;; Window title
|
|
window_title:
|
|
db APP_NAME, ' ', APP_VERSION, 0
|
|
|
|
;; Messages
|
|
if lang eq it
|
|
message_dbg_not_found:
|
|
db '%s non trovato', 10, 0
|
|
|
|
message_error:
|
|
db 'File (%s) non trovato!', 0
|
|
|
|
message_ok:
|
|
db '%s caricato correttamente. PID: %d (0x%X)', 0
|
|
else
|
|
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)', 0
|
|
end if
|
|
;; Configuration path
|
|
etc_cfg:
|
|
db '/sys/etc/'
|
|
cfg_name:
|
|
db 'launch'
|
|
cfg_ext:
|
|
db '.cfg', 0
|
|
|
|
;; Strings in config file
|
|
cfg_main:
|
|
db 'main', 0
|
|
cfg_path:
|
|
db 'path', 0
|
|
cfg_debug:
|
|
db 'debug', 0
|
|
cfg_level:
|
|
db 'level', 0
|
|
cfg_kobra:
|
|
db 'kobra', 0
|
|
cfg_use:
|
|
db 'use', 0
|
|
|
|
;; List of debug modes for parsing debug option
|
|
debug_strings:
|
|
dd debug_no
|
|
dd debug_console
|
|
dd 0
|
|
|
|
debug_no:
|
|
db 'no', 0
|
|
debug_console:
|
|
db 'console', 0
|
|
|
|
;; Empty string
|
|
empty_str:
|
|
db 0
|
|
|
|
kobra_group_launch_reactive:
|
|
db 'launch_reactive', 0
|
|
|
|
;;--------------------------------------------------------------------------------------------------
|
|
;; Configuration options
|
|
debug_level:
|
|
db 0
|
|
|
|
; debug_kobra:
|
|
; db 0
|
|
|
|
;; debug option (bool)
|
|
debug_option:
|
|
db 0
|
|
|
|
kobra_use:
|
|
db 0
|
|
|
|
;;--------------------------------------------------------------------------------------------------
|
|
tid:
|
|
dd 0
|
|
|
|
struct FileInfoRun
|
|
Function dd 7
|
|
Flags dd ?
|
|
Arguments dd 0
|
|
Reserved0 dd ?
|
|
Reserved1 dd ?
|
|
union
|
|
FileName rb 1024
|
|
struct
|
|
Zero db 0
|
|
FileNameP dd ?
|
|
ends
|
|
ends
|
|
ends
|
|
|
|
LaunchStruct FileInfoRun
|
|
|
|
args: db 0
|
|
APP_END:
|
|
rb 255
|
|
|
|
prog_args:
|
|
rd 1
|
|
path:
|
|
rb 1024
|
|
|
|
;; Search path will be here
|
|
search_path:
|
|
rb PATH_MAX_LEN
|
|
|
|
;; Buffer
|
|
buff:
|
|
rb BUFF_SIZE
|
|
|
|
another_buff:
|
|
rb 0x1000
|
|
|
|
kobra_message:
|
|
rb 0x100
|
|
|
|
rb 0x1000 ;; 4 Kb stack
|
|
APP_STACK:
|
|
MEM_END:
|