0,0 → 1,6359 |
; Cb-n#%li.-# @l$i Lkbnbe |
format PE GUI 4.0 at 400000h |
section '.text' code readable executable |
entry start |
i40_nt: |
jmp i40_9x |
start: |
xor ebx, ebx |
call [GetVersion] |
shr eax, 31 |
mov [bIs9x], al |
; get default heap |
call [GetProcessHeap] |
mov [hHeap], eax |
push 261 |
push startcurdir |
push ebx |
call [GetModuleFileNameA] |
xchg ecx, eax |
inc ecx |
inc ecx |
lea edi, [ecx+startcurdir-1] |
mov al, '\' |
std |
repnz scasb |
cld |
mov byte [edi+2], bl |
mov esi, startcurdir |
mov edi, esi |
xor ecx, ecx |
dec ecx |
mov al, 0 |
repnz scasb |
not ecx |
dec ecx |
mov edi, win32_path |
push edi |
rep movsb |
mov al, '\' |
cmp byte [edi-1], al |
jz @f |
stosb |
@@: mov esi, inifilename |
mov ecx, inifilenamesize |
rep movsb |
; parse command line |
call [GetCommandLineA] |
xchg eax, esi |
mov edi, inname |
call getfilename |
mov edi, inname |
call getfilename |
jc no_file_given |
cmp byte [esi], bl |
jz file_known |
mov [parameters], esi |
jmp file_known |
no_file_given: |
mov [inname], bl |
push comdlg32_name |
call [LoadLibraryA] |
test eax, eax |
jz @f |
push eax |
push aGetOpenFileNameA |
push eax |
call [GetProcAddress] |
test eax, eax |
jz @f |
push ofn |
call eax |
test eax, eax |
jz @f |
call [FreeLibrary] |
jmp file_known |
@@: |
push ebx |
call [ExitProcess] |
file_known: |
; TLS data |
mov eax, [tls_index] |
mov ecx, [fs:2Ch] |
mov ebp, [ecx+eax*4] |
; save registers |
mov [ebp+tls._cs], cs |
mov [ebp+tls._ds], ds |
mov [ebp+tls._fs], fs |
mov [ebp+tls._esp], esp |
mov [ebp+tls._eip], exception |
mov eax, 1000h |
call malloc_big |
mov edi, eax |
; test for server |
push seh |
push dword [fs:ebx] |
mov [fs:ebx], esp |
xor eax, eax |
server_test: |
div edx |
pop dword [fs:ebx] |
pop esi |
test eax, eax |
jz server |
mov [ebp+tls.cur_slot], eax |
mov [hSharedData], ecx |
mov [hSharedMutex], edx |
push edi |
push user32_thunks |
push user32_name |
call init_dll |
push gdi32_thunks |
push gdi32_name |
call init_dll |
pop edi |
push edi |
call [lstrlenA] |
inc eax |
push eax |
push eax |
call malloc |
pop ecx |
mov [ebp+tls.cur_dir], eax |
push edi |
xchg eax, edi |
xchg eax, esi |
rep movsb |
call free_big |
call map_shared_data |
push bgr_mutex_name |
push ebx |
push ebx |
call [CreateMutexA] |
mov [hBgrMutex], eax |
push ebx |
push ebx |
push 3 ; OPEN_EXISTING |
push ebx |
push 1 ; FILE_SHARE_READ |
push 80000000h ; GENERIC_READ |
push inname |
call [CreateFileA] |
inc eax |
jnz infileopened |
mov esi, fileopenerr |
fail: |
push 10h |
push ebx |
fail2: |
push esi |
push ebx |
cmp [bInitialized], 0 |
jnz @f |
mov eax, [esi-4] |
loadfailed: |
div edx |
@@: |
call [MessageBoxA] |
call free_ldt |
push ebx |
call [ExitProcess] |
infileopened: |
dec eax |
xchg eax, edi |
push eax |
mov eax, esp |
push ebx |
push eax |
push 36 |
push header |
push edi |
call [ReadFile] |
test eax, eax |
pop eax |
mov esi, filereaderr |
jz fail |
cmp eax, 36 |
jnz fail |
cmp [header], 'KPCK' |
jnz .program_not_packed |
mov eax, [header+4] |
call malloc_big |
test eax, eax |
mov esi, memerr |
jz fail |
push eax |
push eax |
push ebx |
push edi |
call [GetFileSize] |
mov [limit], eax |
call malloc_big |
test eax, eax |
jz fail |
push eax |
push ebx |
push ebx |
push ebx |
push edi |
call [SetFilePointer] |
push eax |
mov eax, esp |
push ebx |
push eax |
push [limit] |
push dword [esp+16] |
push edi |
call [ReadFile] |
test eax, eax |
pop eax |
mov esi, filereaderr |
jz fail |
cmp eax, [limit] |
jnz fail |
pop esi |
push esi |
mov eax, [esi+4] |
mov [limit], eax |
call unpack |
push esi |
call free_big |
pop edx |
mov esi, notexe |
cmp dword [edx], 'MENU' |
jnz fail |
cmp word [edx+4], 'ET' |
jnz fail |
mov ax, word [edx+6] |
sub ax, '00' |
xchg al, ah |
cmp ax, 1 |
ja fail |
push edi |
mov esi, edx |
mov edi, header |
mov ecx, 9 |
rep movsd |
jz @f |
mov eax, [edx+18h] |
mov [header+1Ch], eax |
mov eax, [edx+14h] |
shr eax, 1 |
sub eax, 10h |
mov [header+18h], eax |
mov [header+20h], ebx |
@@: |
push edx |
push 40h ; PAGE_EXECUTE_READWRITE |
push 1000h ; MEM_COMMIT |
push dword [edx+14h] |
push ebx |
call [VirtualAlloc] |
pop edx |
test eax, eax |
mov esi, memerr |
jz fail |
mov [base], eax |
mov edi, eax |
mov esi, edx |
mov ecx, [limit] |
mov eax, ecx |
shr ecx, 2 |
rep movsd |
mov ecx, eax |
and ecx, 3 |
rep movsb |
jmp .program_packed_common |
.program_not_packed: |
mov esi, notexe |
cmp [header], 'MENU' |
jnz fail |
cmp word [header+4], 'ET' |
jnz fail |
mov ax, word [header+6] |
sub ax, '00' |
xchg al, ah |
cmp ax, 1 |
ja fail |
jz @f |
mov eax, [header+18h] |
mov [header+1Ch], eax |
mov eax, [header+14h] |
shr eax, 1 |
sub eax, 10h |
mov [header+18h], eax |
mov [header+20h], ebx |
@@: |
; hmm... Menuet/Kolibri seems to ignore app_i_end field in case of running from ramdisk (fn 19) |
; but depend on app_i_end in case of running from fn 58 |
|
; so force read all file |
push ebx |
push edi |
call [GetFileSize] |
mov [header+10h], eax |
mov eax, [header+14h] |
cmp eax, [header+10h] |
jb fail |
push 40h ; PAGE_EXECUTE_READWRITE |
push 1000h ; MEM_COMMIT |
push eax |
push ebx |
call [VirtualAlloc] |
test eax, eax |
mov esi, memerr |
jz fail |
mov [base], eax |
push ebx |
push ebx |
push ebx |
push edi |
call [SetFilePointer] |
push eax |
mov eax, esp |
push ebx |
push eax |
push [header+10h] |
push [base] |
push edi |
call [ReadFile] |
test eax, eax |
pop eax |
mov esi, filereaderr |
jz fail |
push edi |
.program_packed_common: |
call [CloseHandle] |
mov esi, [parameters] |
mov edi, esi |
test esi, esi |
jz no_params |
mov eax, [header+1Ch] |
test eax, eax |
jz no_params |
mov edx, eax |
add eax, 256 |
cmp eax, [header+14h] |
mov esi, params_err |
ja fail |
mov esi, edi |
mov ecx, 256 |
xor eax, eax |
repnz scasb |
neg cl |
mov edi, edx |
add edi, [base] |
rep movsb |
no_params: |
; read ini file client settings |
; disks |
push 512 |
push ramdisk_path |
push default_ramdisk |
push ramdisk_keyname |
push aDisk |
call [GetPrivateProfileStringA] |
mov edi, hd_partitions_num |
hdloop: |
push win32_path |
push ebx |
push hdxn |
push aDisk |
call [GetPrivateProfileIntA] |
stosd |
test eax, eax |
jz .cont |
push eax |
shl eax, 9 ; *512 |
push eax |
call malloc |
mov [edi-4+hd_partitions_array-hd_partitions_num], eax |
pop ecx |
xchg esi, eax |
xor eax, eax |
inc eax |
.partitions: |
push eax ecx |
push eax |
push hdpart |
push converted_path |
call [wsprintfA] |
add esp, 12 |
mov byte [esi+511], 0 |
push win32_path |
push 511 |
push esi |
push null_string |
push converted_path |
push aDisk |
call [GetPrivateProfileStringA] |
test eax, eax |
jnz @f |
push 10h |
push converted_path |
mov esi, no_partition |
jmp fail2 |
@@: |
push esi |
call [lstrlenA] |
cmp eax, 10 |
jbe @f |
lea eax, [eax+esi-9] |
cmp byte [eax], ',' |
jnz @f |
cmp dword [eax+1], 'read' |
jnz @f |
cmp dword [eax+5], 'only' |
jnz @f |
mov byte [eax], 0 |
mov byte [esi+511], 1 |
@@: |
add esi, 512 |
pop ecx eax |
inc eax |
dec ecx |
jnz .partitions |
.cont: |
inc [hdxn+2] |
inc [hdpart+2] |
cmp edi, hd_partitions_num+4*4 |
jnz hdloop |
mov esi, converted_path |
; read fonts |
push win32_path |
push 512 |
push esi |
push null_string |
push aFont1 |
push aMain |
call [GetPrivateProfileStringA] |
call getfilemap |
mov [char_mt], eax |
push win32_path |
push 512 |
push esi |
push null_string |
push aFont2 |
push aMain |
call [GetPrivateProfileStringA] |
call getfilemap |
mov [char2_mt], eax |
push win32_path |
push ebx |
push aSetBgr |
push aQuestions |
call [GetPrivateProfileIntA] |
mov [SetBgrQuestion], eax |
; read skin |
push win32_path |
push 512 |
push esi |
push null_string |
push aSkin |
push aMain |
call [GetPrivateProfileStringA] |
call getfilemap |
xchg eax, edi |
cmp dword [edi], 'KPCK' |
jnz @f |
mov eax, [edi+4] |
call malloc_big |
mov esi, memerr |
test eax, eax |
jz fail |
push eax |
push eax |
push edi |
call unpack |
push edi |
call [UnmapViewOfFile] |
pop edi |
inc ebx |
@@: |
cmp dword [edi], 'SKIN' ; ident |
mov esi, skinfileerr |
jnz fail |
cmp dword [edi+4], 1 ; version |
jnz fail |
; skin parameters |
mov esi, edi |
add esi, [esi+8] ; parameters offset |
mov ecx, 9 |
push edi |
mov edi, _skinh |
rep movsd |
pop edi |
mov ecx, common_colors |
mov edx, 127 |
call get_wnd_colors |
test al, al |
jnz @f |
lodsd |
and eax, edx |
push eax |
xchg eax, ecx |
push edi |
mov edi, common_colors |
push edi |
rep movsb |
pop ecx |
pop edi |
pop edx |
call set_wnd_colors |
@@: |
; skin bitmaps |
mov esi, edi |
add esi, [esi+16] |
skinbmploop: |
cmp dword [esi], 0 |
jz skinbmploopend |
movzx eax, word [esi] |
movzx ecx, word [esi+2] |
mov edx, [esi+4] |
add esi, 8 |
add edx, edi |
lea eax, [eax*2+ecx-1] |
; convert bmp data to Win32 DIB |
push eax edx |
mov eax, [edx] |
add eax, 3 |
and al, not 3 |
mul dword [edx+4] |
imul eax, 3 |
add eax, 40 |
push eax |
push 8 ; HEAP_ZERO_MEMORY |
push [hHeap] |
call [HeapAlloc] |
pop edx |
mov dword [eax], 40 ; biSize |
mov ecx, [edx] |
mov [eax+4], ecx ; biWidth |
mov ecx, [edx+4] |
mov [eax+8], ecx ; biHeight |
mov dword [eax+12], 180001h ; biPlanes, biBitCount |
push esi edi |
lea edi, [eax+40] |
lea esi, [edx+8] |
mov ecx, [edx+4] |
push eax |
mov eax, [edx] |
imul eax, ecx |
add esi, eax |
add esi, eax |
add esi, eax |
.x1: |
push ecx |
mov ecx, [edx] |
add ecx, ecx |
add ecx, [edx] |
sub esi, ecx |
push esi |
rep movsb |
add edi, 3 |
and edi, not 3 |
pop esi |
pop ecx |
loop .x1 |
pop edx |
pop edi esi |
pop eax |
dec eax |
jnz @f |
; inactive left |
mov [left1_bmp], edx |
jmp skinbmploop |
@@: |
dec eax |
jnz @f |
; active left |
mov [left_bmp], edx |
jmp skinbmploop |
@@: |
dec eax |
jnz @f |
; inactive oper |
mov [oper1_bmp], edx |
jmp skinbmploop |
@@: |
dec eax |
jnz @f |
; active oper |
mov [oper_bmp], edx |
jmp skinbmploop |
@@: |
dec eax |
jnz @f |
; inactive base |
mov [base1_bmp], edx |
jmp skinbmploop |
@@: |
dec eax |
jnz skinbmploop |
; active base |
mov [base_bmp], edx |
jmp skinbmploop |
skinbmploopend: |
; skin buttons |
mov esi, edi |
add esi, [esi+12] |
skinbuttonsloop: |
lodsd |
test eax, eax |
jz skinbuttonsloopend |
mov edx, skin_btn_close |
dec eax |
jz .button |
mov edx, skin_btn_minimize |
dec eax |
jz .button |
lodsd |
lodsd |
jmp skinbuttonsloop |
.button: |
mov ecx, 4 |
@@: |
lodsw |
cwde |
mov [edx], eax |
add edx, 4 |
loop @b |
jmp skinbuttonsloop |
skinbuttonsloopend: |
dec ebx |
jz .mem |
xor ebx, ebx |
push edi |
call [UnmapViewOfFile] |
jmp @f |
.mem: |
push edi |
call free_big |
@@: |
; sound volume |
push win32_path |
push 10 |
push aSoundVol |
push aSetup |
call [GetPrivateProfileIntA] |
and al, 0x7F |
mov [sound_vol], al |
; direct screen access parameters |
push win32_path |
push 32 |
push aColorDepth |
push aDirectScreenAccess |
call [GetPrivateProfileIntA] |
test eax, eax |
jz @f |
cmp eax, 24 |
jz @f |
cmp eax, 32 |
jz @f |
mov esi, aInvalidColorDepth |
jmp fail |
@@: |
mov [ColorDepth], eax |
push win32_path |
push 200 |
push aInvalidateTime |
push aDirectScreenAccess |
call [GetPrivateProfileIntA] |
mov [InvalidateTime], eax |
mov [DSA], ebx |
push DSACritSect |
call [InitializeCriticalSection] |
cmp [ColorDepth], ebx |
jz @f |
push 4 ; PAGE_READWRITE |
push 2000h ; MEM_RESERVE |
push 1000000h |
push ebx |
call [VirtualAlloc] |
mov esi, memerr |
test eax, eax |
jz fail |
mov [DSA], eax |
@@: |
; parse path |
mov eax, [header+20h] |
test eax, eax |
jz path_done |
cmp eax, [header+14h] |
jae path_done |
; jb @f |
; push 30h |
; push aWarning |
; push aPathInvalid |
; push 0 |
; call [MessageBoxA] |
; jmp path_done |
;@@: |
push 0 |
push startcurdir |
push 261 |
push inname |
call [GetFullPathNameA] |
; test for /rd/1 |
push ramdisk_path |
call [lstrlenA] |
push eax |
push eax |
push ramdisk_path |
push eax |
push startcurdir |
push 1 |
push 800h |
call [CompareStringA] |
cmp eax, 2 |
pop eax |
jz .ramdisk |
; test for /hdx/y |
xor ecx, ecx |
.hdxloop: |
push ecx |
mov esi, [hd_partitions_array+ecx*4] |
mov edi, [hd_partitions_num+ecx*4] |
test edi, edi |
jz .hdxcont |
.hdyloop: |
push esi |
call [lstrlenA] |
push eax |
push eax |
push esi |
push eax |
push startcurdir |
push 1 |
push 800h |
call [CompareStringA] |
cmp eax, 2 |
pop eax |
jz .hdxy |
add esi, 512 |
dec edi |
jnz .hdyloop |
.hdxcont: |
pop ecx |
inc ecx |
cmp ecx, 4 |
jb .hdxloop |
mov esi, aPathUnknown |
jmp fail |
.ramdisk: |
push eax |
mov edi, [header+20h] |
add edi, [base] |
mov eax, '/RD/' |
stosd |
mov ax, '1/' |
stosw |
jmp .common |
.hdxy: |
pop ecx |
sub esi, [hd_partitions_array+ecx*4] |
shr esi, 9 |
inc esi |
push eax |
mov edi, [header+20h] |
add edi, [base] |
push esi |
push ecx |
push hdxy_str |
push edi |
call [wsprintfA] |
add esp, 10h |
add edi, eax |
.common: |
pop eax |
lea esi, [startcurdir+eax] |
.l: |
lodsb |
cmp al, '\' |
jnz @f |
mov al, '/' |
@@: |
stosb |
test al, al |
jnz .l |
mov eax, [header+20h] |
add eax, [base] |
push eax |
push eax |
call [CharToOemA] |
path_done: |
; create window |
; push 0 |
; push 16 |
; push 16 |
; push 1 |
; push 1 |
; push 400000h |
; call [LoadImageA] |
; push eax ; hIconSm |
push ebx ; hIconSm |
push classname ; lpszClassName |
push ebx ; lpszMenuName |
push ebx ; hbrBackground |
push 32512 |
push ebx |
call [LoadCursorA] |
mov [hArrow], eax |
push eax ; hCursor |
; push ebx ; hIcon |
push 1 |
push 400000h |
call [LoadIconA] |
push eax ; hIcon |
push 400000h ; hInstance |
push ebx ; cbWndExtra |
push ebx ; cbClsExtra |
push wndproc ; lpfnWndProc |
push 3 ; style = CS_HREDRAW or CS_VREDRAW |
push 48 ; cbSize |
push esp |
call [RegisterClassExA] |
add esp, 48 |
push ebx ; lpParam |
push 400000h ; hInstance |
push ebx ; hMenu |
push ebx ; hWndParent |
mov eax, 80000000h ; CW_USEDEFAULT |
push eax ; nHeight |
push eax ; nWidth |
push eax ; y |
push eax ; x |
push eax ; dwStyle = WS_POPUP |
; push ebx ; lpWindowName |
mov esi, inname |
mov edx, esi |
@@: |
lodsb |
cmp al, 0 |
jz .done |
cmp al, '\' |
jz .x |
cmp al, '/' |
jz .x |
cmp al, ':' |
jnz @b |
.x: mov edx, esi |
jmp @b |
.done: |
dec esi |
cmp byte [esi-1], '.' |
jnz @f |
dec esi |
mov byte [esi], 0 |
@@: |
push edx |
mov [process_name], edx |
push classname ; lpClassName |
push ebx ; dwExStyle |
call [CreateWindowExA] |
mov [ebp+tls.hWnd], eax |
mov [ebp+tls.bActive], 1 |
mov [ebp+tls.bFirstMouseMove], 1 |
test eax, eax |
mov esi, createwnderr |
jz fail |
call get_cur_slot_ptr |
mov [edi+shared_data_struc.hWnd-shared_data_struc.threads], eax |
cmp [edi+shared_data_struc.thread_id-shared_data_struc.threads], 2 |
jnz .notfirst |
mov esi, [shared_data] |
cmp [esi+shared_data_struc.vk], 0 |
jnz .workarea_vk |
push ebx |
lea eax, [esi+shared_data_struc.workarea_left] |
push eax |
push ebx |
push 30h ; SPI_GETWORKAREA |
call [SystemParametersInfoA] |
dec [esi+shared_data_struc.workarea_right] |
dec [esi+shared_data_struc.workarea_bottom] |
jmp .workarea_set |
.workarea_vk: |
push esi |
call get_screen_size |
pop esi |
inc ebx |
mov word [esi+shared_data_struc.workarea_bottom], bx |
shr ebx, 10h |
inc ebx |
mov [esi+shared_data_struc.workarea_right], ebx |
xor ebx, ebx |
.workarea_set: |
.notfirst: |
push newprg_section_name |
push 1000h |
push ebx |
push 4 |
push ebx |
push -1 |
call [CreateFileMappingA] |
push eax |
mov esi, shared_section_create_err |
test eax, eax |
jz fail |
push ebx |
push ebx |
push ebx |
push 2 |
push eax |
call [MapViewOfFile] |
pop ecx |
push eax |
push ecx |
call [CloseHandle] |
pop eax |
push eax |
cmp word [eax], 0x201 |
jnz @f |
mov ecx, [ebp+tls.hWnd] |
mov [eax+2], ecx |
mov byte [eax+1], 3 |
@@: |
call [UnmapViewOfFile] |
; allocate LDT selectors |
; data segment |
mov esi, selector_data |
mov eax, [base] |
mov [esi+2], ax |
shr eax, 10h |
mov [esi+4], al |
mov [esi+7], ah |
mov eax, [header+14h] |
dec eax |
mov [limit], eax |
mov [fn9limit], eax |
call get_cur_slot_ptr |
mov [edi+24], eax |
shr eax, 0Ch |
mov [esi], ax |
shr eax, 10h |
or al, 11000000b |
mov [esi+6], al |
mov byte [esi+5], 11110010b |
lea edi, [esi+8] |
; code segment |
movsd |
movsd |
mov byte [esi+5], 11111010b |
cmp [bIs9x], 0 |
jnz alloc_ldt_9x |
push ntdll_name |
call [GetModuleHandleA] |
push aNtSetLdtEntries |
push eax |
call [GetProcAddress] |
mov [NtSetLdtEntries], eax |
push dword [esi-4] |
push dword [esi-8] |
push 17h |
push dword [esi+4] |
push dword [esi] |
push 0Fh |
call eax |
mov esi, ldterr |
test eax, eax |
js fail |
mov eax, [DSA] |
test eax, eax |
jz @f |
push ebx |
push ebx |
push ebx |
mov edx, eax |
mov dx, (11000000b shl 8) + 11110010b |
ror edx, 16 |
xchg dl, dh |
ror edx, 8 |
push edx |
shl eax, 16 |
mov ax, 0FFFh |
push eax |
push 1Fh |
call [NtSetLdtEntries] |
test eax, eax |
js fail |
mov [_gs], 1Fh |
@@: |
dorunklbr: |
; jump to program code |
mov eax, [header+18h] |
mov [ebp+tls._esp], eax |
mov eax, [header+0Ch] |
mov [ebp+tls._eip], eax |
push 3200h ; eflags |
xor eax, eax |
push eax |
push eax |
push eax |
push eax |
push eax |
push eax |
push eax |
push eax |
; Kolibri process was successfully created, notify parent |
call get_cur_slot_ptr |
mov [edi+shared_data_struc.win32_stack-shared_data_struc.threads], esp |
mov [bInitialized], 1 |
notify_parent: |
div edx |
jmp i40_done |
|
alloc_ldt_9x: |
mov eax, r0p |
call CallRing0 |
; patch int40 |
add edi, (40h-9)*8 |
mov eax, i40_9x |
mov [edi], ax |
mov word [edi+2], cs |
shr eax, 16 |
mov [edi+6], ax |
mov word [edi+4], 1110111100000000b |
xor ebx, ebx |
jmp dorunklbr |
free_ldt: |
cmp [bIs9x], 0 |
jnz @f |
.ret: ret |
@@: |
cmp [temp_cs], 0 |
jz .ret |
mov eax, fl0p |
|
CallRing0: |
call acquire_shared ; int 9 is global resource |
sidt [idtr] |
mov edi, dword [idtr+2] |
add edi, 8*9 |
push dword [edi] |
push dword [edi+4] |
mov [edi], ax |
mov word [edi+2], 28h |
; mov word [edi+4], 0xEE00 |
; shr eax, 16 |
; mov [edi+6], ax |
mov [edi+4], eax |
mov word [edi+4], 0xEE00 |
int 9 |
pop dword [edi+4] |
pop dword [edi] |
call release_shared |
ret |
|
r0p: |
int 20h ; VMMCall Get_Cur_VM_Handle |
dw 1 |
dw 1 |
push 0 |
push 1 |
push dword [esi] |
push dword [esi+4] |
push ebx |
int 20h ; VMMCall _Allocate_LDT_Selector |
dw 78h |
dw 1 |
add esp, 14h |
mov [klbr_cs], ax |
push 0 |
push 1 |
push dword [esi-8] |
push dword [esi-4] |
push ebx |
int 20h ; VMMCall _Allocate_LDT_Selector |
dw 78h |
dw 1 |
add esp, 14h |
mov [klbr_ds], ax |
mov eax, [DSA] |
test eax, eax |
jz @f |
push 0 |
push 1 |
mov edx, eax |
mov dx, (11000000b shl 8) + 11110010b |
ror edx, 16 |
xchg dl, dh |
ror edx, 8 |
shl eax, 16 |
mov ax, 0FFFh |
push eax |
push edx |
push ebx |
int 20h ; VMMCall _Allocate_LDT_Selector |
dw 78h |
dw 1 |
add esp, 14h |
mov [_gs], ax |
@@: |
push 0 |
push 1 |
mov eax, temp_code |
mov ecx, eax |
shl eax, 16 |
add eax, temp_code_size-1 |
push eax |
mov eax, ecx |
and eax, 0xFF000000 |
add eax, 0000000011111011b shl 8 |
shr ecx, 16 |
mov al, cl |
push eax |
push ebx |
int 20h ; VMMCall _Allocate_LDT_Selector |
dw 78h |
dw 1 |
add esp, 14h |
mov [temp_cs], ax |
mov [temp_cs2], ax |
push 0 |
push 1 |
mov eax, temp_stack |
mov ecx, eax |
shl eax, 16 |
add eax, temp_stack_size-1 |
push eax |
mov eax, ecx |
and eax, 0xFF000000 |
add eax, 0000000011110011b shl 8 |
shr ecx, 16 |
mov al, cl |
push eax |
push ebx |
int 20h ; VMMCall _Allocate_LDT_Selector |
dw 78h |
dw 1 |
add esp, 14h |
mov [temp_ss], ax |
; mov eax, 40h |
; mov cx, [_cs] |
; mov edx, i40_9x |
; int 20h ; VMMCall Set_PM_Int_Vector |
; dw 45h |
; dw 1 |
; xor ecx, ecx |
; xor edx, edx |
; int 20h ; VMMCall Get_PM_Int_Vector |
; dw 44h |
; dw 1 |
iret |
fl0p: |
int 20h ; VMMCall Get_Cur_VM_Handle |
dw 1 |
dw 1 |
movzx eax, [klbr_cs] |
call free_selector |
movzx eax, [klbr_ds] |
call free_selector |
movzx eax, [temp_cs] |
call free_selector |
movzx eax, [temp_ss] |
call free_selector |
xor ebx, ebx |
iret |
sl0p: |
int 20h ; VMMCall Get_Cur_VM_Handle |
dw 1 |
dw 1 |
push 0 |
push dword [esi] |
push dword [esi+4] |
push ebx |
movzx eax, [klbr_cs] |
push eax |
int 20h ; VMMCall _SetDescriptor |
dw 7Ch |
dw 1 |
push 0 |
push dword [esi-8] |
push dword [esi-4] |
push ebx |
movzx eax, [klbr_ds] |
push eax |
int 20h ; VMMCall _SetDescriptor |
dw 7Ch |
dw 1 |
add esp, 40 |
iret |
rdmsrp: |
; rdmsr may throw exception |
mov esi, .exception_struc |
int 20h ; VMMCall Install_Exception_Handler |
dw 0EFh |
dw 1 |
xor ebx, ebx ; assume OK |
.start_eip: |
rdmsr |
.end_eip: |
mov esi, .exception_struc |
int 20h ; VMMCall Remove_Exception_Handler |
dw 0F0h |
dw 1 |
iret |
.exception_struc: |
dd 0 |
dd .start_eip |
dd .end_eip |
dd .exception_handler |
.exception_handler: |
inc ebx |
jmp .end_eip |
|
free_selector: |
push 0 |
push eax |
push ebx |
int 20h ; VMMCall _Free_LDT_Selector |
dw 79h |
dw 1 |
add esp, 12 |
ret |
|
seh: |
mov eax, [esp+12] |
add dword [eax+0xB8], 2 |
xor eax, eax |
ret |
|
ofn_hook: |
cmp dword [esp+8], 2 ; WM_DESTROY |
jnz @f |
push 260 |
mov eax, converted_path |
mov [parameters], eax |
push eax |
push 23 |
push dword [esp+12+4] |
push user32_name |
call [GetModuleHandleA] |
push GetDlgItemTextA_thunk+2 |
push eax |
call [GetProcAddress] |
call eax |
@@: |
xor eax, eax |
ret 10h |
|
getfilename: |
@@: |
lodsb |
cmp al, 0 |
jz .not |
cmp al, ' ' |
jbe @b |
cmp al, '"' |
setz dl |
jz .loo |
dec esi |
.loo: |
lodsb |
cmp al, 0 |
jz .end |
cmp al, ' ' |
ja @f |
test dl, 1 |
jz .end |
@@: cmp al, '"' |
jnz @f |
test dl, 1 |
jnz .end_quote |
@@: stosb |
jmp .loo |
.end_quote: |
lodsb |
.end: |
or al, al |
jnz @f |
dec esi |
@@: mov al, 0 |
stosb |
clc |
ret |
.not: |
stc |
ret |
|
map_shared_data: |
push 0 |
push 0 |
push 0 |
push 2 |
push [hSharedData] |
call [MapViewOfFile] |
mov [shared_data], eax |
ret |
|
acquire_shared: |
pushad |
push -1 |
push [hSharedMutex] |
call [WaitForSingleObject] |
popad |
ret |
release_shared: |
pushad |
push [hSharedMutex] |
call [ReleaseMutex] |
popad |
ret |
|
get_cur_slot_ptr_server: |
push eax |
mov eax, [cur_slot] |
@@: |
call get_slot_ptr |
pop eax |
ret |
get_cur_slot_ptr: |
push eax |
mov eax, [ebp+tls.cur_slot] |
jmp @b |
get_slot_ptr: |
mov edi, [shared_data] |
shl eax, 6 |
lea edi, [eax+edi+shared_data_struc.threads] |
ret |
|
read_color: |
push esi |
mov ecx, 6 |
xor edx, edx |
.l: |
lodsb |
cmp al, 0 |
jz .d |
or al, 20h |
sub al, '0' |
cmp al, 10 |
jb @f |
sub al, 'a'-10-'0' |
@@: |
shl edx, 4 |
or dl, al |
loop .l |
.d: |
pop esi |
xchg eax, edx |
ret |
|
i40_9x: |
; set Win32 context |
push eax ecx |
mov eax, [cs:tls_index] |
shl eax, 2 |
add eax, [fs:2Ch] |
mov eax, [cs:eax] |
mov ds, [cs:eax+tls._ds] |
mov es, [eax+tls._ds] |
; mov fs, [_fs] |
mov ecx, [esp+8] ; eip |
dec ecx |
dec ecx |
mov [eax+tls._eip], ecx |
mov ecx, [esp+16] ; eflags |
mov ss, [eax+tls._ds] |
xchg esp, [eax+tls._esp] |
push ecx |
add [eax+tls._esp], 20 |
mov eax, [eax+tls._esp] |
add eax, [base] |
mov ecx, [eax-20] |
mov eax, [eax-16] |
popfd |
|
exception: |
pushfd |
cld |
; test for page fault in direct screen area |
push ebp eax |
mov eax, [tls_index] |
mov ebp, [fs:2Ch] |
mov ebp, [ebp+eax*4] |
mov eax, [ebp+tls.saved_fs0] |
mov [fs:0], eax |
mov eax, [ebp+tls.saved_fs4] |
mov [fs:4], eax |
cmp [ebp+tls.exc_code], 0C0000005h |
jnz noaccvio |
mov eax, [ebp+tls.exc_data] |
sub eax, [DSA] |
cmp eax, 0FFFFFFh |
ja noaccvio |
; handle page fault in direct screen area |
pop eax ebp |
pushad |
mov ebp, [tls_index] |
shl ebp, 2 |
add ebp, [fs:2Ch] |
mov ebp, [ebp] |
push DSACritSect |
call [EnterCriticalSection] |
cmp [bHaveDSA], 0 |
jnz dsafail |
call get_screen_size |
mov eax, ebx |
shr eax, 16 |
movzx ebx, bx |
inc eax |
inc ebx |
mov edi, eax |
mul ebx |
mul [ColorDepth] |
shr eax, 3 |
add eax, 0xFFF |
and eax, not 0xFFF |
mov ecx, [ebp+tls.exc_data] |
sub ecx, [DSA] |
cmp ecx, eax |
jb @f |
dsafail: |
push DSACritSect |
call [LeaveCriticalSection] |
push 40h |
push 0 |
push DSAErr |
push 0 |
mbni: |
call [MessageBoxA] |
popad |
push ebp eax |
mov ebp, [tls_index] |
shl ebp, 2 |
add ebp, [fs:2Ch] |
mov ebp, [ebp] |
jmp notint40 |
@@: |
push 4 |
push 1000h |
push eax |
push [DSA] |
call [VirtualAlloc] |
; get screen data |
push ebp |
push 0 |
call [GetDC] |
push eax |
xchg eax, ebp |
call [CreateCompatibleDC] |
xchg eax, esi |
push ebx |
push edi |
push ebp |
call [CreateCompatibleBitmap] |
push eax |
push esi |
call [SelectObject] |
push eax |
xor eax, eax |
push 0xCC0020 |
push eax |
push eax |
push ebp |
push ebx |
push edi |
push eax |
push eax |
push esi |
call [BitBlt] |
push esi |
call [SelectObject] |
push ebp |
xchg eax, ebp |
xor eax, eax |
; now esi=hDC, ebp=hBitmap |
push eax ; biClrImportant |
push eax ; biClrUsed |
push eax ; biYPelsPerMeter |
push eax ; biXPelsPerMeter |
push eax ; biSizeImage |
push eax ; biCompression |
push 1 ; biPlanes |
mov ecx, [ColorDepth] |
mov [esp+2], cx ; biBitColor |
neg ebx |
push ebx ; biHeight |
neg ebx |
push edi ; biWidth |
push 40 ; biSize |
mov ecx, esp |
push eax |
push ecx |
push [DSA] |
push ebx |
push eax |
push ebp |
push esi |
call [GetDIBits] |
add esp, 40 |
push ebp |
call [DeleteObject] |
push esi |
call [DeleteDC] |
push 0 |
call [ReleaseDC] |
mov [bHaveDSA], 1 |
push eax |
push esp |
push 0 |
push 0 |
push DSAFreeThread |
push 10000h |
push 0 |
call [CreateThread] |
pop eax |
push DSACritSect |
call [LeaveCriticalSection] |
pop ebp |
mov ebp, [tls_index] |
shl ebp, 2 |
add ebp, [fs:2Ch] |
mov ebp, [ebp] |
jmp i40_done |
noaccvio: |
; test for int40 |
mov eax, [ebp+tls._eip] |
cmp eax, [limit] |
jae notint40 |
add eax, [base] |
cmp word [eax], 0x40CD |
jz int40 |
notint40: |
|
pop eax |
push esi |
sub esp, 400h |
mov esi, esp |
push dword [esi+408h] |
push [ebp+tls._eip] |
push dword [esi+404h] |
push [ebp+tls._esp] |
push edi |
push dword [esi+400h] |
push edx |
push ecx |
push ebx |
push eax |
push excstr |
push esi |
call [wsprintfA] |
push 0 |
push exceptionstr |
push esi |
push 0 |
call [MessageBoxA] |
lock dec [NumThreads] |
jnz .et |
call free_ldt |
push 0 |
call [ExitProcess] |
.et: |
push 0 |
call [ExitThread] |
|
int40: |
add [ebp+tls._eip], 2 |
pop eax ebp |
pushad |
safe_to_suspend: |
mov ebp, [tls_index] |
shl ebp, 2 |
add ebp, [fs:2Ch] |
mov ebp, [ebp] |
inc eax |
cmp eax, num_i40_fns |
push eax ; emulate ret addr for not_supported_i40_fn |
jae not_supported_i40_fn |
pop eax |
call [i40fns + eax*4] |
i40_done: |
cmp [NumThreads], 1 |
jnz i40_done_mt |
mov eax, [ebp+tls._esp] |
mov [klbr_esp], eax |
mov eax, [ebp+tls._eip] |
mov [jmp_klbr_eip], eax |
lea eax, [esp+24h] |
mov [ebp+tls._esp], eax |
mov [ebp+tls._eip], exception |
mov eax, [fs:0] |
mov [ebp+tls.saved_fs0], eax |
mov eax, [fs:4] |
mov [ebp+tls.saved_fs4], eax |
popad |
popfd |
mov ss, [klbr_ds] |
mov esp, [klbr_esp] |
mov es, [klbr_ds] |
; mov fs, [klbr_null] |
; mov gs, [klbr_null] |
mov gs, [_gs] |
mov ds, [klbr_ds] |
i40_done_jmp1: |
jmp [cs:jmp_klbr] |
i40_done_mt: |
mov eax, [ebp+tls._esp] |
mov [esp+12], eax |
mov ecx, [ebp+tls._eip] |
xchg [fs:0], ecx |
mov [ebp+tls.saved_fs0], ecx |
movzx ecx, [klbr_cs] |
xchg [fs:4], ecx |
mov [ebp+tls.saved_fs4], ecx |
lea eax, [esp+24h] |
mov [ebp+tls._esp], eax |
mov [ebp+tls._eip], exception |
popad |
popfd |
mov ss, [klbr_ds] |
mov esp, [ds:esp-24h+12] |
mov es, [klbr_ds] |
; mov fs, [klbr_null] |
; mov gs, [klbr_null] |
mov gs, [_gs] |
mov ds, [klbr_ds] |
i40_done_jmp2: |
jmp fword [fs:0] |
|
not_supported_i40_fn: |
sub esp, 200h-4 |
mov esi, esp |
push dword [esi+200h+20h] |
push [ebp+tls._eip] |
push dword [esi+200h+8] |
push [ebp+tls._esp] |
push dword [esi+200h] |
push dword [esi+200h+4] |
push dword [esi+200h+14h] |
push dword [esi+200h+18h] |
push dword [esi+200h+10h] |
push dword [esi+200h+1Ch] |
push notsupportedmsg |
push esi |
call [wsprintfA] |
push 0 |
push nsm |
push esi |
push 0 |
call [MessageBoxA] |
i40_terminate: |
lock dec [NumThreads] |
jnz .thread |
call free_ldt |
push 0 |
call [ExitProcess] |
.thread: |
push 0 |
call [ExitThread] |
|
align 4 |
i40fns dd i40_terminate ; -1 |
dd i40_draw_window ; 0 |
dd i40_put_pixel ; 1 |
dd i40_getkey ; 2 |
dd i40_get_sys_time ; 3 |
dd i40_writetext ; 4 |
dd i40_delay ; 5 |
dd i40_read_floppy_file ; 6 |
dd i40_putimage ; 7 |
dd i40_define_button ; 8 |
dd i40_get_process_info ; 9 |
dd i40_wait_event ; 10 |
dd i40_check_event ; 11 |
dd i40_redraw_status ; 12 |
dd i40_drawrect ; 13 |
dd i40_get_screen_size ; 14 |
dd i40_set_background ; 15 |
dd not_supported_i40_fn ; 16 |
dd i40_getbutton ; 17 |
dd i40_sys_service ; 18 |
dd not_supported_i40_fn ; 19 |
dd not_supported_i40_fn ; 20 |
dd i40_sys_setup ; 21 |
dd not_supported_i40_fn ; 22 |
dd i40_wait_event_timeout ; 23 |
dd not_supported_i40_fn ; 24 |
dd not_supported_i40_fn ; 25 |
dd i40_getsetup ; 26 |
dd not_supported_i40_fn ; 27 |
dd not_supported_i40_fn ; 28 |
dd i40_get_sys_date ; 29 |
dd i40_current_folder ; 30 |
dd not_supported_i40_fn ; 31 |
dd i40_delete_ramdisk_file ; 32 |
dd i40_write_ramdisk_file ; 33 |
dd not_supported_i40_fn ; 34 |
dd i40_screen_getpixel ; 35 |
dd i40_screen_getarea ; 36 |
dd i40_read_mouse_pos ; 37 |
dd i40_draw_line ; 38 |
dd i40_get_background ; 39 |
dd i40_set_event_mask ; 40 |
dd not_supported_i40_fn ; 41 |
dd not_supported_i40_fn ; 42 |
dd not_supported_i40_fn ; 43 |
dd not_supported_i40_fn ; 44 |
dd not_supported_i40_fn ; 45 |
dd i40_reserve_free_ports ; 46 |
dd i40_display_number ; 47 |
dd i40_display_settings ; 48 |
dd not_supported_i40_fn ; 49 |
dd i40_set_window_shape ; 50 |
dd i40_create_thread ; 51 |
dd not_supported_i40_fn ; 52 |
dd not_supported_i40_fn ; 53 |
dd not_supported_i40_fn ; 54 |
dd i40_sound_interface ; 55 |
dd not_supported_i40_fn ; 56 |
dd not_supported_i40_fn ; 57 |
dd i40_file_system ; 58 |
dd not_supported_i40_fn ; 59 |
dd i40_ipc ; 60 |
dd i40_direct_scr_access ; 61 |
dd i40_pci ; 62 |
dd i40_debug_board ; 63 |
dd i40_resize_app_memory ; 64 |
dd i40_putimage_palette ; 65 |
dd i40_process_def ; 66 |
dd i40_move_resize ; 67 |
dd i40_sys_services ; 68 |
dd i40_debug_services ; 69 |
dd i40_file_system_lfn ; 70 |
dd i40_window_settings ; 71 |
num_i40_fns = ($ - i40fns)/4 |
|
getfilemap: |
; in: esi->filename |
; out: eax->mapped file |
push esi |
sub esp, 200h |
cmp word [esi+1], ':\' |
jz .fullpath |
mov edi, esp |
push esi |
mov esi, startcurdir |
@@: |
lodsb |
stosb |
test al, al |
jnz @b |
pop esi |
dec edi |
mov al, '\' |
cmp byte [edi-1], al |
jz @f |
stosb |
@@: |
lodsb |
stosb |
test al, al |
jnz @b |
mov esi, esp |
.fullpath: |
push ebx |
push ebx |
push 3 ; OPEN_EXISTING |
push ebx |
push 1 ; FILE_SHARE_READ |
push 80000000h ; GENERIC_READ |
push esi |
call [CreateFileA] |
add esp, 200h |
pop esi |
inc eax |
jz .failed |
dec eax |
xchg eax, edi |
push ebx |
push ebx |
push ebx |
push 2 ; PAGE_READONLY |
push ebx |
push edi |
call [CreateFileMappingA] |
test eax, eax |
jz .failed |
push edi |
xchg eax, edi |
call [CloseHandle] |
push ebx |
push ebx |
push ebx |
push 4 ; FILE_MAP_READ |
push edi |
call [MapViewOfFile] |
test eax, eax |
jz .failed |
push eax |
push edi |
call [CloseHandle] |
pop eax |
ret |
.failed: |
push ebx |
push filereaderr |
jmp fail2 |
|
DSAFreeThread: |
push [InvalidateTime] |
call [Sleep] |
push DSACritSect |
call [EnterCriticalSection] |
push 4000h |
push 0 |
push [DSA] |
call [VirtualFree] |
mov [bHaveDSA], 0 |
push DSACritSect |
call [LeaveCriticalSection] |
ret |
|
virtual at 0 |
button_desc: |
.next dd ? ; must be 1st dword |
.id dd ? |
.xsize dw ? |
.xstart dw ? |
.ysize dw ? |
.ystart dw ? |
.color dd ? |
.size = $ |
end virtual |
|
test_maximized: |
sub esp, 40 |
push 44 |
push esp |
push [ebp+tls.hWnd] |
call [GetWindowPlacement] |
mov eax, [esp+8] ; showCmd |
add esp, 44 |
cmp eax, 3 ; SW_SHOWMAXIMIZED |
ret |
|
wndproc: |
; LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) |
push ebp |
mov ebp, [tls_index] |
mov eax, [fs:2Ch] |
mov ebp, [eax+ebp*4] |
mov eax, [esp+8+4] |
cmp eax, 0xF ; WM_PAINT |
jz wmpaint |
dec eax |
; jz wmcreate |
dec eax |
jz wmdestroy |
dec eax |
jz wmmove |
dec eax |
dec eax |
jz wmsize |
dec eax |
jz wmactivate |
cmp eax, 0x1A-6 |
jz wmsettingchange |
cmp eax, 0x20-6 |
jz wmsetcursor |
cmp eax, 0x24-6 |
jz wmgetminmaxinfo |
sub eax, 0x84-6 |
jz wmnchittest |
cmp eax, 0xA1-0x84 |
jz wmnclbuttondown |
cmp eax, 0xA3-0x84 |
jz wmnclbuttondblclk |
sub eax, 0x100-0x84 ; WM_KEYDOWN |
jz wmkeydown |
dec eax |
jz wmkeyup |
dec eax |
jz wmchar |
dec eax |
dec eax |
jz wmsyskeydown |
dec eax |
jz wmsyskeyup |
sub eax, 0x200-0x105 ; WM_MOUSEMOVE |
jz wmmousemove |
dec eax |
jz wmlbuttondown |
dec eax |
jz wmlbuttonup |
dec eax |
dec eax |
jz wmrbuttondown |
dec eax |
jz wmrbuttonup |
cmp eax, 0x20A-0x205 |
jz wmmousewheel |
cmp eax, 0x214-0x205 |
jz wmsizing |
sub eax, 0x400-0x205 ; WM_USER |
jz wm_ipc |
cmp eax, 0xC000-0x400 |
jz vk_mouse |
dec eax |
jz wm_debug1 |
dec eax |
jz wm_debug2 |
wmdef: |
pop ebp |
jmp [DefWindowProcA] |
wmsettingchange: |
call del_background |
@@: |
test [ebp+tls.message_mask], 10h |
jz wmdef |
mov [ebp+tls.translated_msg_code], 5 |
push 0 |
push 0 |
push 0 |
push dword [esp+20] |
call [PostMessageA] |
jmp wmdef |
wmactivate: |
mov eax, [shared_data] |
mov ecx, [ebp+tls.cur_slot] |
inc ecx |
cmp word [esp+12+4], 0 |
jz .inact1 |
mov [eax+shared_data_struc.active_process], ecx |
jmp .cmn1 |
.inact1: |
call acquire_shared |
cmp [eax+shared_data_struc.active_process], ecx |
jnz @f |
mov [eax+shared_data_struc.active_process], 1 |
@@: call release_shared |
.cmn1: |
mov al, byte [ebp+tls.color_main+3] |
and al, 0Fh |
cmp al, 3 |
jz .setactive |
cmp al, 4 |
jnz wmdef |
.setactive: |
mov al, [esp+12+4] |
mov [ebp+tls.bActive], al ; 0/1/2 |
wndproc_update_wnd: |
mov [ebp+tls.curdraw], 0 |
push 0 |
push 0 |
push [ebp+tls.hWnd] |
call [InvalidateRect] |
jmp wmdef |
wmpaint: |
push esi |
push edi |
sub esp, 0x40 |
push esp |
push [ebp+tls.hWnd] |
call [BeginPaint] |
; test [ebp+tls.message_mask], 1 |
; jz @f |
; mov [ebp+tls.translated_msg_code], 1 |
@@: xchg eax, edi |
cmp [ebp+tls.curdraw], 0 |
mov [ebp+tls.curdraw], 1 |
jz .nopaint |
call draw_window_base |
.nopaint: |
push esp |
push [ebp+tls.hWnd] |
call [EndPaint] |
add esp, 40h |
pop edi |
pop esi |
pop ebp |
xor eax, eax |
ret 10h |
wmdestroy: |
push 0 |
call [PostQuitMessage] |
@@: |
xor eax, eax |
pop ebp |
ret 10h |
wmnclbuttondown: |
call test_maximized |
jnz wmdef |
push [ebp+tls.hWnd] |
call [SetForegroundWindow] |
jmp @b |
;wmwindowposchanging: |
; call test_maximized |
; jnz @b |
; mov eax, [esp+0x10+4] |
; or byte [eax+18h], 2 ; SWP_NOMOVE |
; jmp @b |
wmnchittest: |
; for window type 1 always return HTCLIENT |
mov cl, byte [ebp+tls.color_main+3] |
and cl, 0x0F |
cmp cl, 0x01 |
jz .client |
mov ax, [esp+0x10+4] ; x |
sub ax, [ebp+tls.x_start] |
mov dx, [esp+0x12+4] ; y |
sub dx, [ebp+tls.y_start] |
; test for caption |
push eax |
mov eax, [_skinh] |
cmp cl, 0x03 |
jz @f |
mov al, 21 |
@@: |
cmp dx, ax |
pop eax |
jae .nocaption |
; check for buttons |
push esi |
call find_button |
test esi, esi |
pop esi |
jnz .button |
.caption: |
push 2 ; HTCAPTION |
pop eax |
pop ebp |
ret 10h |
.button: |
.client: |
push 1 ; HTCLIENT |
jmp .ret |
.nocaption: |
; do not resize window with type 0 |
jecxz .client |
; do not resize window with type 4 |
cmp ecx, 0x04000000 |
jz .client |
; do not resize maximized window |
push eax edx |
call test_maximized |
pop edx eax |
jz .client |
sub dx, [ebp+tls.y_size] |
neg dx |
cmp dx, 7 |
jbe .bottomall |
cmp ax, 7 |
jbe .left |
sub ax, [ebp+tls.x_size] |
neg ax |
cmp ax, 7 |
ja .client |
push 11 ; HTRIGHT |
jmp .ret |
.left: |
push 10 ; HTLEFT |
.ret: |
pop eax |
pop ebp |
ret 10h |
.bottomall: |
cmp ax, 7 |
jbe .bottomleft |
sub ax, [ebp+tls.x_size] |
neg ax |
cmp ax, 7 |
ja .bottom |
push 17 ; HTBOTTOMRIGHT |
jmp .ret |
.bottomleft: |
push 16 ; HTBOTTOMLEFT |
jmp .ret |
.bottom: |
push 15 ; HTBOTTOM |
jmp .ret |
wmsetcursor: |
cmp [ebp+tls.hCursor], 0 |
jz wmdef |
push [ebp+tls.hCursor] |
call [SetCursor] |
push 1 |
pop eax |
pop ebp |
ret 10h |
wmnclbuttondblclk: |
mov al, byte [ebp+tls.color_main+3] |
and al, 0xF |
jz .nomaximize |
cmp al, 1 |
jz .nomaximize |
cmp al, 4 |
jz .nomaximize |
call test_maximized |
mov eax, 3 ; SW_MAXIMIZED |
jnz @f |
mov al, 1 ; SW_SHOWNORMAL |
@@: |
push eax |
push [ebp+tls.hWnd] |
call [ShowWindow] |
push 1 |
push 0 |
push [ebp+tls.hWnd] |
call [InvalidateRect] |
.nomaximize: |
xor eax, eax |
pop ebp |
ret 10h |
wmmove: |
mov ax, [esp+0x10+4] |
mov [ebp+tls.x_start], ax |
mov ax, [esp+0x12+4] |
mov [ebp+tls.y_start], ax |
; jmp wndproc_update_wnd |
xor eax, eax |
pop ebp |
ret 10h |
wmsize: |
mov ax, [esp+0x10+4] |
mov [ebp+tls.x_size], ax |
mov ax, [esp+0x12+4] |
mov [ebp+tls.y_size], ax |
; jmp wndproc_update_wnd |
xor eax, eax |
pop ebp |
ret 10h |
wmsizing: |
mov eax, [esp+0x14] |
mov ecx, [eax] |
mov [ebp+tls.x_start], cx |
mov ecx, [eax+4] |
mov [ebp+tls.y_start], cx |
mov ecx, [eax+8] |
sub ecx, [eax] |
mov [ebp+tls.x_size], cx |
mov ecx, [eax+12] |
sub ecx, [eax+4] |
mov [ebp+tls.y_size], cx |
; push 0 |
; push 0 |
; push [ebp+tls.hWnd] |
; call [InvalidateRect] |
xor eax, eax |
inc eax |
pop ebp |
ret 10h |
wmsyskeydown: |
; test byte [esp+16+3+4], 20h ; Alt pressed? |
; jnz wmdef |
cmp byte [esp+16+2+4], 3Eh ; Alt+F4? |
jz wmdestroy |
wmkeydown: |
movzx eax, byte [esp+16+2+4] |
test eax, eax |
jnz @f |
mov al, 1Ch ; <Enter> |
@@: |
cmp [ebp+tls.usescancode], 0 |
jnz .putkeycode |
; ignore keys-modifiers |
cmp al, 2Ah |
jz .ret |
cmp al, 36h |
jz .ret |
cmp al, 38h |
jz .ret |
cmp al, 1Dh |
jz .ret |
cmp al, 3Ah |
jz .ret |
cmp al, 45h |
jz .ret |
cmp al, 46h |
jz .ret |
; translate NumPad keys |
test byte [esp+14h+3], 1 |
jnz .nonumpad |
mov cl, '*' |
cmp al, 55 |
jz @f |
cmp al, 71 |
jb .nonumpad |
cmp al, 83 |
ja .nonumpad |
mov cl, [numlock_map+eax-71] |
@@: |
push eax |
push ecx |
sub esp, 100h |
push esp |
call [GetKeyboardState] |
mov al, [esp+0x90] ; VK_NUMLOCK |
add esp, 100h |
test al, 1 |
pop ecx |
pop eax |
jnz .put_cl |
.nonumpad: |
mov cl, [keymap+eax] |
push eax |
push ecx |
push 0x11 ; VK_CONTROL |
call [GetAsyncKeyState] |
test ax, ax |
jns @f |
sub byte [esp], 60h |
@@: |
push 0x10 ; VK_SHIFT |
call [GetAsyncKeyState] |
test ax, ax |
jns @f |
pop ecx |
pop eax |
mov cl, [keymap_shift+eax] |
push eax |
push ecx |
@@: |
push 0x12 ; VK_MENU |
call [GetAsyncKeyState] |
test ax, ax |
pop ecx |
pop eax |
jns @f |
mov cl, [keymap_alt+eax] |
@@: |
.put_cl: |
xchg eax, ecx |
.putkeycode: |
movzx ecx, [ebp+tls.keybuflen] |
inc cl |
jz .ret |
; test for extended key (0xE0 prefix) |
test byte [esp+14h+3], 1 ; lParam+3 |
jz .noext |
cmp [ebp+tls.usescancode], 0 |
jz .noext |
mov [ebp+tls.keybuflen], cl |
mov [ebp+tls.keybuffer+ecx-1], 0xE0 |
inc cl |
jz .ret |
.noext: |
mov [ebp+tls.keybuflen], cl |
mov [ebp+tls.keybuffer+ecx-1], al |
test [ebp+tls.message_mask], 2 |
jz @f |
mov [ebp+tls.translated_msg_code], 2 |
@@: |
.ret: |
wmchar: |
xor eax, eax |
pop ebp |
ret 10h |
wmkeyup: |
wmsyskeyup: |
cmp [ebp+tls.usescancode], 0 |
jz wmkeydown.ret |
mov al, [esp+16+2+4] |
or al, 80h |
jmp wmkeydown.putkeycode |
;wmchar: |
; cmp [usescancode], 0 |
; jnz wmkeydown.ret |
; mov al, [esp+12] |
; jmp wmkeydown.putkeycode |
wmlbuttondown: |
push esi |
push 1 |
jmp @f |
wmrbuttondown: |
push esi |
push 2 |
@@: |
call capture1 |
mov ax, [esp+0x10+12] ; x |
mov dx, [esp+0x12+12] ; y |
call find_button |
pop eax |
test esi, esi |
jnz .onbutton |
test [ebp+tls.message_mask], 20h |
jz @f |
mov [ebp+tls.translated_msg_code], 6 |
@@: |
.done: |
pop esi |
pop ebp |
xor eax, eax |
ret 10h |
.onbutton: |
or [ebp+tls.current_buttons], al |
cmp [ebp+tls.original_buttons], 0 |
jnz @f |
mov [ebp+tls.original_buttons], al |
@@: |
mov [ebp+tls.active_button], esi |
; don't highlight button if bit 29 is set |
test [esi+button_desc.id], 20000000h |
jnz .done |
; highlight - negate border |
call negate_button_border |
jmp .done |
wmrbuttonup: |
push -3 |
jmp @f |
wmlbuttonup: |
push -2 |
@@: |
call capture2 |
pop eax |
cmp [ebp+tls.active_button], 0 |
jz wmrbuttondown.nobutton |
and [ebp+tls.current_buttons], al |
jnz wmrbuttondown.nobutton |
push esi |
xor esi, esi |
xchg esi, [ebp+tls.active_button] |
test byte [esi+button_desc.id+3], 20h |
jnz @f |
call negate_button_border |
@@: |
; minimize button - special handler (see event.inc) |
cmp word [esi+button_desc.id], 0FFFFh |
jz .minimize |
test [ebp+tls.message_mask], 4 |
jz @f |
mov [ebp+tls.translated_msg_code], 3 |
@@: |
test [ebp+tls.message_mask], 20h |
jz @f |
mov [ebp+tls.translated_msg_code], 86h |
@@: |
mov [ebp+tls.bFirstMouseMove], 1 |
movzx ecx, [ebp+tls.butbuflen] |
inc cl |
jz @f |
mov [ebp+tls.butbuflen], cl |
mov eax, [esi+button_desc.id] |
shl eax, 8 |
mov al, [ebp+tls.original_buttons] |
mov [ebp+tls.butbuffer+ecx*4-4], eax |
@@: |
mov [ebp+tls.original_buttons], 0 |
.done: |
pop esi |
.ret: |
xor eax, eax |
pop ebp |
ret 10h |
.minimize: |
call minimize_window |
jmp .done |
wmrbuttondown.nobutton: |
wmmousemove: |
cmp [ebp+tls.bFirstMouseMove], 0 |
mov [ebp+tls.bFirstMouseMove], 0 |
jnz wmdef |
vk_mouse: |
; N.B. Due of current implementation of buttons in the kernel |
; mouse events are NOT processed when any button is active! |
cmp [ebp+tls.active_button], 0 |
jnz wmlbuttonup.ret |
test [ebp+tls.message_mask], 20h |
jz wmlbuttonup.ret |
mov [ebp+tls.translated_msg_code], 6 |
jmp wmlbuttonup.ret |
wmmousewheel: |
movsx eax, word [esp+0xE+4] |
sub [ebp+tls.scroll], eax |
jmp vk_mouse |
wm_ipc: |
test [ebp+tls.message_mask], 40h |
jz wmlbuttonup.ret |
mov [ebp+tls.translated_msg_code], 7 |
jmp wmlbuttonup.ret |
wm_debug1: |
test byte [ebp+tls.message_mask+1], 1 |
jz .failed2 |
push edi |
call get_cur_slot_ptr |
mov edi, [edi+shared_data_struc.debugger_mem-shared_data_struc.threads] |
test edi, edi |
jz .failed |
add edi, [base] |
mov eax, [edi] |
mov ecx, [edi+4] |
sub eax, ecx |
cmp eax, 12 |
jl .failed |
add dword [edi+4], 12 |
lea edi, [edi+ecx+8] |
xor eax, eax |
inc eax |
stosd |
push edi |
mov eax, [esp+0xC+12] |
call get_slot_ptr |
mov eax, [edi] |
pop edi |
stosd |
mov eax, [esp+0x10+8] |
; translate Win32 exception code to x86 exception vector |
cmp eax, 0x80000004 |
jz .singlestep |
xor ecx, ecx |
push edi |
mov edi, exccode2number-5 |
.1: |
add edi, 5 |
cmp eax, [edi] |
jnz .2 |
mov cl, [edi+4] |
jmp .3 |
.2: |
cmp dword [edi], ecx |
jnz .1 |
mov cl, 0xD ; translate unrecognized codes to #GP |
.3: |
pop edi |
jmp .4 |
.singlestep: |
push ebx |
mov ecx, [edi-4] |
call find_debuggee |
mov ecx, ebx |
pop ebx |
jecxz .failed |
sub esp, 0xB2*4 |
push 1001Fh |
push esp |
push dword [ecx+12] |
call [GetThreadContext] |
mov ecx, [esp+0x14] ; DR6 |
mov byte [edi-8], 3 ; signal #DB |
add esp, 0xB3*4 |
.4: |
mov [edi], ecx |
.written: |
pop edi |
mov [ebp+tls.translated_msg_code], 9 |
jmp wmlbuttonup.ret |
.failed: |
pop edi |
.failed2: |
push 40h |
push 0 |
push aFailedToDeliverDebugMessage |
push [ebp+tls.hWnd] |
call [MessageBoxA] |
jmp wmlbuttonup.ret |
wm_debug2: |
test byte [ebp+tls.message_mask+1], 1 |
jz wm_debug1.failed2 |
push edi |
call get_cur_slot_ptr |
mov edi, [edi+shared_data_struc.debugger_mem-shared_data_struc.threads] |
test edi, edi |
jz wm_debug1.failed |
add edi, [base] |
mov eax, [edi] |
mov ecx, [edi+4] |
sub eax, ecx |
cmp eax, 8 |
jl wm_debug1.failed |
add dword [edi+4], 8 |
lea edi, [edi+ecx+8] |
push 2 |
pop eax |
stosd |
push edi |
mov eax, [esp+0xC+12] |
call get_slot_ptr |
mov eax, [edi] |
pop edi |
stosd |
; delete this item from debuggees list |
lea ecx, [ebp+tls.debuggees] |
@@: |
mov edx, [ecx] |
test edx, edx |
jz wm_debug1.written |
cmp dword [edx+4], eax |
jz .found |
mov ecx, edx |
jmp @b |
.found: |
push dword [edx] |
push ecx |
push edx |
call free |
pop ecx |
pop dword [ecx] |
jmp wm_debug1.written |
|
wmgetminmaxinfo: |
mov ecx, [shared_data] |
cmp [ecx+shared_data_struc.vk], 0 |
jnz @f |
sub esp, 10h |
mov eax, esp |
push 0 |
push eax |
push 0 |
push 30h ; SPI_GETWORKAREA |
call [SystemParametersInfoA] |
mov eax, [esp+20+10h] ; lParam |
mov ecx, esp |
mov edx, [ecx] |
mov [eax+10h], edx |
mov edx, [ecx+4] |
mov [eax+14h], edx |
mov edx, [ecx+8] |
sub edx, [ecx] |
mov [eax+8], edx |
mov edx, [ecx+12] |
sub edx, [ecx+4] |
mov [eax+0Ch], edx |
add esp, 10h |
jmp .ret |
@@: |
call acquire_shared |
mov eax, [esp+20] ; lParam |
mov edx, [ecx+shared_data_struc.workarea_left] |
mov [eax+10h], edx |
mov edx, [ecx+shared_data_struc.workarea_top] |
mov [eax+14h], edx |
mov edx, [ecx+shared_data_struc.workarea_right] |
sub edx, [ecx+shared_data_struc.workarea_left] |
mov [eax+8], edx |
mov edx, [ecx+shared_data_struc.workarea_bottom] |
sub edx, [ecx+shared_data_struc.workarea_top] |
mov [eax+0Ch], edx |
call release_shared |
.ret: |
xor eax, eax |
pop ebp |
ret 10h |
|
find_button: |
mov esi, [ebp+tls.buttons] |
.loop: |
test esi, esi |
jz .done |
push eax |
sub ax, [esi+button_desc.xstart] |
cmp ax, [esi+button_desc.xsize] |
pop eax |
jae .cont |
push edx |
sub dx, [esi+button_desc.ystart] |
cmp dx, [esi+button_desc.ysize] |
pop edx |
jb .done |
.cont: |
mov esi, [esi] |
jmp .loop |
.done: |
ret |
|
negate_button_border: |
push edi |
push [ebp+tls.hWnd] |
call [GetDC] |
xchg eax, edi |
push 6 ; R2_NOT |
push edi |
call [SetROP2] |
push eax |
movzx eax, [esi+button_desc.xstart] |
movzx edx, [esi+button_desc.ystart] |
; point 4 |
push edx |
push eax |
; point 3 |
mov ecx, edx |
add cx, [esi+button_desc.ysize] |
push ecx |
push eax |
; point 2 |
push ecx |
mov ecx, eax |
add cx, [esi+button_desc.xsize] |
push ecx |
; point 1 |
push edx |
push ecx |
; point 0 |
push edx |
push eax |
; Polyline |
mov eax, esp |
push 5 |
push eax |
push edi |
call [Polyline] |
add esp, 5*8 |
push edi |
call [SetROP2] |
push edi |
push [ebp+tls.hWnd] |
call [ReleaseDC] |
pop edi |
ret |
|
draw_border: |
mov eax, [ebp+tls.color_border] |
shr eax, 1 |
and eax, 0x007F7F7F |
cmp byte [esp+4], 0 |
jz @f |
mov eax, [skin_active_outer] |
cmp [ebp+tls.bActive], 0 |
jnz @f |
mov eax, [skin_passive_outer] |
@@: |
call create_select_pen |
push eax |
xor esi, esi |
call rect_wnd |
call select_delete |
mov eax, [ebp+tls.color_border] |
cmp byte [esp+4], 0 |
jz @f |
mov eax, [skin_active_frame] |
cmp [ebp+tls.bActive], 0 |
jnz @f |
mov eax, [skin_passive_frame] |
@@: |
call create_select_pen |
push eax |
@@: |
inc esi |
call rect_wnd |
cmp esi, 3 |
jnz @b |
call select_delete |
mov eax, [ebp+tls.color_border] |
shr eax, 1 |
and eax, 0x007F7F7F |
cmp byte [esp+4], 0 |
jz @f |
mov eax, [skin_active_inner] |
cmp [ebp+tls.bActive], 0 |
jnz @f |
mov eax, [skin_passive_inner] |
@@: |
call create_select_pen |
push eax |
inc esi |
call rect_wnd |
call select_delete |
ret 4 |
|
rect_wnd: |
movzx ecx, [ebp+tls.y_size] |
dec ecx |
sub ecx, esi |
movzx edx, [ebp+tls.x_size] |
dec edx |
sub edx, esi |
; point 5 |
push esi |
push esi |
; point 4 |
push esi |
push edx |
; point 3 |
push ecx |
push edx |
; point 2 |
push ecx |
push esi |
; point 1 |
push esi |
push esi |
mov eax, esp |
push 5 |
push eax |
push edi |
call [Polyline] |
add esp, 40 |
ret |
|
rectangle_gradient: |
; in: edi=hDC |
; stack: |
; [esp+4] = xstart |
; [esp+8] = ystart |
; [esp+12] = xend |
; [esp+16] = yend (end is excluded) |
; [esp+20] = color |
; [esp+24] = color_delta (if gradient specified) |
test byte [esp+20+3], 80h |
jnz .dograd |
; no gradient |
mov eax, [esp+20] |
call convert_color |
push eax |
call [CreateSolidBrush] |
push eax |
push dword [esp+4+16] |
push dword [esp+8+12] |
push dword [esp+12+8] |
push dword [esp+16+4] |
mov ecx, esp |
push eax |
push ecx |
push edi |
call [FillRect] |
add esp, 10h |
call [DeleteObject] |
.done: |
ret 24 |
.dograd: |
; gradient |
mov esi, [esp+8] |
.gradloop: |
cmp esi, [esp+16] |
jae .done |
mov eax, [esp+20] |
call create_select_pen |
push eax |
push 0 |
push esi |
push dword [esp+12+4] |
push edi |
call [MoveToEx] |
push esi |
push dword [esp+8+12] |
push edi |
call [LineTo] |
call select_delete |
inc esi |
; mov eax, [esp+24] |
; sub [esp+20], eax |
test byte [esp+27], 80h |
jnz .signed |
mov al, [esp+24] |
sub [esp+20], al |
jnb @f |
add [esp+20], al |
@@: mov al, [esp+25] |
sub [esp+21], al |
jnb @f |
add [esp+21], al |
@@: mov al, [esp+26] |
sub [esp+22], al |
jnb @f |
add [esp+22], al |
@@: jmp .gradloop |
.signed: |
mov al, [esp+24] |
add [esp+20], al |
jnb @f |
sub [esp+20], al |
@@: mov al, [esp+25] |
add [esp+21], al |
jnb @f |
sub [esp+21], al |
@@: mov al, [esp+26] |
add [esp+22], al |
jnb @f |
sub [esp+22], al |
@@: jmp .gradloop |
|
create_select_pen: |
call convert_color |
push eax |
push 1 |
push 0 |
call [CreatePen] |
push eax |
push edi |
call [SelectObject] |
ret |
select_delete: |
push dword [esp+4] |
push edi |
call [SelectObject] |
push eax |
call [DeleteObject] |
ret 4 |
|
malloc: |
push dword [esp+4] |
push 0 |
push [hHeap] |
call [HeapAlloc] |
ret 4 |
free: |
push dword [esp+4] |
push 0 |
push [hHeap] |
call [HeapFree] |
ret 4 |
malloc_big: |
push 4 ; PAGE_READWRITE |
push 1000h ; MEM_COMMIT |
push eax |
push 0 |
call [VirtualAlloc] |
ret |
free_big: |
push 8000h ; MEM_RELEASE |
push 0 |
push dword [esp+12] |
call [VirtualFree] |
ret 4 |
|
capture1: |
inc [bCaptured] |
cmp [bCaptured], 1 |
jnz @f |
push [ebp+tls.hWnd] |
call [SetCapture] |
@@: ret |
capture2: |
cmp [bCaptured], 0 |
jz @f |
dec [bCaptured] |
jnz @f |
call [ReleaseCapture] |
@@: ret |
|
server_fail: |
push 10h |
push 0 |
push esi |
push 0 |
call init_MessageBox |
call [MessageBoxA] |
push 0 |
call [ExitProcess] |
|
server_exists: |
mov esi, vkerr |
cmp [vk], 0 |
jnz server_fail |
mov al, 1 |
mov edx, [newprg_section] |
lock xchg [edx], al |
test al, al |
jz @f |
push edx |
push 200 |
call [Sleep] |
pop edx |
dec edi |
jnz server_exists |
@@: |
mov esi, inname |
lea edi, [edx+8] |
mov ecx, 108h/4 |
rep movsd |
mov esi, [parameters] |
test esi, esi |
jnz @f |
mov esi, converted_path |
@@: mov ecx, 100h/4 |
rep movsd |
mov byte [edx+1], 1 |
mov esi, edx |
push 50 |
pop edi |
@@: |
push 200 |
call [Sleep] |
cmp byte [esi+1], 3 |
jz @f |
dec edi |
jnz @b |
push ebx |
call [ExitProcess] |
@@: |
push esi |
push user32_thunks |
push user32_name |
call init_dll |
pop esi |
push dword [esi+2] |
call [SetForegroundWindow] |
mov word [esi], bx |
push ebx |
call [ExitProcess] |
|
newprg_request: |
lea edi, [eax+8] |
lea esi, [eax+110h] |
call acquire_shared |
call new_kolibri_process_with_default_curdir |
call release_shared |
mov eax, [newprg_section] |
mov byte [eax+1], 2 |
jmp debugloop |
|
server: |
push edi |
call free_big |
sub esp, 44h |
push esp |
call [GetStartupInfoA] |
mov eax, [esp+8] |
test eax, eax |
jz @f |
cmp dword [eax], 'Koli' |
jnz @f |
cmp dword [eax+4], 'briD' |
jnz @f |
mov [vk], 1 |
@@: |
push newprg_section_name |
push 1000h |
push ebx |
push 4 |
push ebx |
push -1 |
call [CreateFileMappingA] |
mov esi, shared_section_create_err |
test eax, eax |
jz server_fail |
xchg eax, edi |
call [GetLastError] |
push eax |
push ebx |
push ebx |
push ebx |
push 2 |
push edi |
call [MapViewOfFile] |
mov [newprg_section], eax |
test eax, eax |
jz server_fail |
; push edi |
; call [CloseHandle] |
pop eax |
cmp eax, 183 |
jz server_exists |
mov ecx, [esp+2Ch] |
add esp, 44h |
test cl, cl |
js @f |
cmp [vk], 0 |
jnz @f |
; We were created without STARTF_FORCEOFFFEEDBACK flag. |
; Rerun self. This has two goals: first, this avoids "hour glass" cursor, |
; second, if GetOpenFileNameA was used, it didn't cleanup all resources, |
; but new process will run in clean environment. |
push [newprg_section] |
call [UnmapViewOfFile] |
push edi |
call [CloseHandle] |
mov [bDontDebug], 1 |
call create_child |
push ebx |
call [ExitProcess] |
@@: |
if 0 |
push ebx |
push ebx |
push ebx |
call [GetCurrentThreadId] |
push eax |
call [PostThreadMessageA] |
sub esp, 40h |
mov eax, esp |
push ebx |
push ebx |
push ebx |
push eax |
call [GetMessageA] |
add esp, 40h |
end if |
; create shared data |
push ebx |
push shared_section_size |
push ebx |
push 4 |
push ebx |
push -1 |
call [CreateFileMappingA] |
test eax, eax |
jz server_fail |
mov [hSharedData], eax |
push ebx |
push ebx |
push ebx |
call [CreateMutexA] |
mov esi, shared_mutex_create_err |
test eax, eax |
jz server_fail |
mov [hSharedMutex], eax |
call map_shared_data |
xor ecx, ecx |
inc ecx |
mov dword [eax], ecx ; 1 process (OS/IDLE) |
mov dword [eax+4], ecx ; 1 process |
mov [eax+shared_data_struc.active_process], ecx |
mov [eax+shared_data_struc.thread_id], ecx ; PID=1 |
mov [eax+shared_data_struc.sound_dma], ecx |
mov [eax+shared_data_struc.fat32part], ecx |
mov [eax+shared_data_struc.hd_base], cl |
mov [eax+shared_data_struc.mouse_delay], 10 |
mov [eax+shared_data_struc.mouse_speed_factor], 3 |
xchg eax, esi |
mov al, [vk] |
or [esi+shared_data_struc.vk], al |
mov [esi+shared_data_struc.pci_data_init], bl |
; read ini file server settings |
mov edi, aSetup |
push win32_path |
push ebx |
push aSoundFlag |
push edi |
call [GetPrivateProfileIntA] |
mov [esi+shared_data_struc.sound_flag], al |
push win32_path |
push 1 |
push aSysLang |
push edi |
call [GetPrivateProfileIntA] |
mov [esi+shared_data_struc.syslang], eax |
push win32_path |
push 1 |
push aKeyboard |
push edi |
call [GetPrivateProfileIntA] |
mov [esi+shared_data_struc.keyboard], ax |
mov ebp, esi |
mov ecx, 1028 |
sub esp, ecx |
mov esi, esp |
mov edi, aMain |
push win32_path |
push ecx |
push esi |
push null_string |
push aAllowReadMSR |
push edi |
call [GetPrivateProfileStringA] |
cmp byte [esi], 't' |
setz [ebp+shared_data_struc.bAllowReadMSR] |
push win32_path |
push 1028 |
push esi |
push null_string |
push aAllowReadPCI |
push edi |
call [GetPrivateProfileStringA] |
cmp byte [esi], 't' |
setz [ebp+shared_data_struc.bAllowReadPCI] |
setz byte [ebp+shared_data_struc.pci_access_enabled] |
push win32_path |
push 1028 |
push esi |
push null_string |
push aKeepLoadedDriver |
push edi |
call [GetPrivateProfileStringA] |
cmp byte [esi], 't' |
setz [keep_loaded_driver] |
push win32_path |
push 1028 |
push esi |
push null_string |
push aEnablePorts |
push edi |
call [GetPrivateProfileStringA] |
; parse EnablePorts parameter |
or eax, -1 |
lea edi, [ebp+shared_data_struc.DisabledPorts] |
mov ecx, 1000h |
rep stosd |
ParseEnablePorts: |
lodsb |
test al, al |
jz .done |
cmp al, 0x20 |
jbe ParseEnablePorts |
call read_hex |
cmp al, '-' |
jz .minus |
mov edx, ecx |
shr ecx, 3 |
and edx, 7 |
btr dword [ebp+shared_data_struc.DisabledPorts+ecx], edx |
.x1: test al, al |
jz .done |
cmp al, 0x20 |
jbe ParseEnablePorts |
.err: |
mov esi, EnablePortsSyntaxErr |
jmp server_fail |
.minus: |
push ecx |
lodsb |
call read_hex |
cmp ecx, [esp] |
jb .err |
push eax |
@@: |
mov eax, ecx |
shr ecx, 3 |
mov edx, eax |
and edx, 7 |
btr dword [ebp+shared_data_struc.DisabledPorts+ecx], edx |
test eax, eax |
jz @f |
lea ecx, [eax-1] |
cmp ecx, [esp+4] |
jae @b |
@@: |
pop eax |
pop ecx |
jmp .x1 |
.done: |
add esp, 1028 |
xor eax, eax |
cmp [bIs9x], al |
jnz .skipload |
cmp [ebp+shared_data_struc.bAllowReadMSR], bl |
jnz .load |
cmp [ebp+shared_data_struc.bAllowReadPCI], bl |
jnz .load |
mov ecx, 2000h |
lea edi, [ebp+shared_data_struc.DisabledPorts] |
mov al, -1 |
repz scasb |
jz .skipload |
.load: |
; load driver kiw0.sys |
; note that this must execute after all work with ini-file |
; because win32_path is overwritten |
call load_kiw0 |
.skipload: |
call create_child |
debugloop: |
mov eax, [newprg_section] |
cmp byte [eax+1], 1 |
jz newprg_request |
push 500 ; wait a half of second |
push debugevent |
call [WaitForDebugEvent] |
test eax, eax |
jz debugloop |
; get hProcess |
mov eax, [debugevent+4] |
mov ecx, [pids] |
@@: cmp [ecx+4], eax |
jz @f |
mov ecx, [ecx] |
jmp @b |
@@: mov eax, [ecx+8] |
mov [hProcess], eax |
; parse debug event |
mov eax, [debugevent] ; dwDebugEventCode |
dec eax ; EXCEPTION_DEBUG_EVENT = 1 |
jz exceptionevent |
dec eax ; CREATE_THREAD_DEBUG_EVENT = 2 |
jz threadcreated |
dec eax ; CREATE_PROCESS_DEBUG_EVENT = 3 |
jz processcreated |
dec eax ; EXIT_THREAD_DEBUG_EVENT = 4 |
jz threadexited |
dec eax ; EXIT_PROCESS_DEBUG_EVENT = 5 |
jz exited |
debugcont: |
push 10002h ; DBG_CONTINUE |
dodebugcont: |
push [debugevent+8] |
push [debugevent+4] |
call [ContinueDebugEvent] |
jmp debugloop |
exited: |
; delete Win32 pid and tid |
mov eax, [debugevent+4] |
mov ecx, pids |
call delete_id |
call find_tid |
jecxz @f |
call on_thread_exited |
mov eax, [debugevent+8] |
mov ecx, tids |
call delete_id |
@@: |
; if all processes are done, exit |
dec [num_kolibri_proc] |
jnz debugcont |
jmp server_done |
threadcreated: |
mov eax, [debugevent+12] |
mov [hThread], eax |
mov eax, [debugevent+8] |
mov [dwThreadId], eax |
call alloc_thread |
mov eax, [debugevent+16] |
mov ecx, [cur_tid_ptr] |
mov [ecx+16], eax |
mov [ecx+20], ebx |
jmp debugcont |
processcreated: |
call find_tid |
test ecx, ecx |
jz debugcont |
push [debugevent+12] |
call [CloseHandle] |
mov eax, [debugevent+24h] |
mov ecx, [cur_tid_ptr] |
mov [ecx+16], eax |
jmp debugcont |
threadexited: |
call find_tid |
test ecx, ecx |
jz debugcont |
cmp [cur_slot], -1 |
jz @f |
call on_thread_exited |
@@: |
mov eax, [debugevent+8] |
mov ecx, tids |
call delete_id |
jmp debugcont |
exceptionevent: |
call find_tid |
test eax, eax |
jz debugcont |
; special handling of #PF exceptions in shared memory areas |
cmp [debugevent+12], 0xC0000005 |
jnz .nopf |
mov ecx, [debugevent+36] |
call get_cur_slot_ptr_server |
mov edi, [edi+shared_data_struc.shmem_list-shared_data_struc.threads] |
.scanaddr: |
test edi, edi |
jz .nopf |
cmp ecx, [edi+shmem_proc_descr.ptr] |
jb @f |
cmp ecx, [edi+shmem_proc_descr.end] |
jb .pfshared |
@@: |
mov edi, [edi+shmem_proc_descr.next] |
jmp .scanaddr |
.pfshared: |
; this is really exception in shared area |
mov esi, [edi+shmem_proc_descr.item] |
mov eax, [esi+shmem_item.pOwner] |
cmp eax, ebx |
jz .pfsh_noowner |
call shmem_load |
.pfsh_noowner: |
mov edx, [edi+shmem_proc_descr.end] |
mov ecx, [edi+shmem_proc_descr.ptr] |
sub edx, ecx |
push ecx edx |
push eax |
push esp |
push 4 ; PAGE_READWRITE |
push edx |
push ecx |
push [hProcess] |
call [VirtualProtectEx] |
pop eax |
pop edx ecx |
push ecx edx |
push ebx |
push edx |
push [esi+shmem_item.ptr] |
push ecx |
push [hProcess] |
call [WriteProcessMemory] |
pop edx ecx |
cmp dword [debugevent+32], ebx |
jz .pfsh_read |
cmp [edi+shmem_proc_descr.access], ebx |
jz .nopf |
mov [esi+shmem_item.pOwner], edi |
mov eax, [hProcess] |
mov [esi+shmem_item.hOwner], eax |
jmp debugcont |
.pfsh_read: |
push eax |
push esp |
push 2 ; PAGE_READONLY |
push edx |
push ecx |
push [hProcess] |
call [VirtualProtectEx] |
pop eax |
jmp debugcont |
.nopf: |
; first exception is int3 in loader code |
; ignore all exceptions before executing our code |
; (there is one exception, debugging int3, in ntdll loader code, |
; this exception must be continued as handled) |
mov edi, context |
push edi |
push [hThread] |
mov dword [edi], 1000Fh |
call [GetThreadContext] |
add edi, 0xB8 |
; breakpoints int3 (0xCC): decrement EIP (incremented by Windows) |
cmp [debugevent+12], 0x80000003 |
jnz @f |
dec dword [edi] |
@@: |
; single-step exceptions: restore TF flag (cleared by Windows) |
mov dx, cs |
mov eax, [edi] |
mov ecx, [cur_tid_ptr] |
cmp [debugevent+12], 0x80000004 |
jnz .noss |
cmp word [edi+4], dx |
jnz .set_tf |
cmp eax, exception+1 |
jz @f |
.set_tf: |
or byte [edi+8+1], 1 |
@@: |
cmp [ecx+52], ebx |
mov [ecx+52], ebx |
jnz x |
cmp word [edi+4], dx |
jnz .noss |
cmp eax, i40_done_jmp1 |
jz .skipnext |
cmp eax, i40_done_jmp2 |
jnz @f |
.skipnext: |
inc dword [ecx+52] |
@@: |
cmp eax, exception+1 |
jz x |
cmp eax, i40_done |
jb .noss |
cmp eax, not_supported_i40_fn |
jb x |
.noss: |
mov [ecx+52], ebx |
mov esi, tls_index |
push eax |
push esp |
push 4 |
push esi |
push esi |
push [hProcess] |
call [ReadProcessMemory] |
mov eax, [cur_tid_ptr] |
mov eax, [eax+16] |
add eax, 2Ch |
mov ecx, esp |
push ebx |
push ecx |
sub ecx, 4 |
push 4 |
push ecx |
push eax |
push [hProcess] |
call [ReadProcessMemory] |
pop eax |
pop ecx |
test eax, eax |
jz debugcont |
mov ecx, [esi] |
cmp ecx, -1 |
jz debugcont |
lea eax, [eax+ecx*4] |
push eax |
mov ecx, esp |
push ebx |
push ecx |
sub ecx, 4 |
push 4 |
push ecx |
push eax |
push [hProcess] |
call [ReadProcessMemory] |
pop eax |
pop ecx |
; now eax -> TLS data |
xchg eax, esi |
push eax |
push esp |
push 24 |
push _cs |
push esi |
push [hProcess] |
call [ReadProcessMemory] |
pop eax |
mov ax, [_cs] |
test ax, ax |
jz debugcont |
; test for exceptions in Kolibri code |
cmp word [context+0xBC], ax |
jz process_exception |
; debugged process? |
mov edx, [cur_tid_ptr] |
mov edi, [edx+20] |
test edi, edi |
jz .nodebuggee |
; yes |
; int40? |
cmp [debugevent+12], 0xC0000005 |
jnz .exception2dbg |
push edx edi |
push ebx |
mov ecx, esp |
push ebx |
push esp |
push 4 |
push ecx |
push base |
call get_cur_slot_ptr_server |
push [edi+shared_data_struc.win32_hBaseProcess-shared_data_struc.threads] |
call [ReadProcessMemory] |
lea ecx, [esp+4] |
push esp |
mov eax, [ecx] |
push 2 |
add eax, [context+0xB8] |
push ecx |
push eax |
push [edi+shared_data_struc.win32_hBaseProcess-shared_data_struc.threads] |
call [ReadProcessMemory] |
pop eax |
pop ecx |
pop edi edx |
cmp al, 2 |
jnz .exception2dbg |
cmp cx, 0x40CD |
jz .nodebuggee |
; suspend current thread and notify debugger |
.exception2dbg: |
push dword [edx+8] |
call [SuspendThread] |
push context |
push [hThread] |
call [SetThreadContext] |
mov eax, [edi+12] |
call get_slot_ptr |
push [debugevent+12] |
push [cur_slot] |
push 401h |
push [edi+shared_data_struc.hWnd-shared_data_struc.threads] |
call init_MessageBox |
call [PostMessageA] |
jmp debugcont |
.nodebuggee: |
; set Win32 context |
mov word [context+0xBC], ax |
mov ax, [_ds] |
mov word [context+0x98], ax |
mov word [context+0x94], ax |
mov word [context+0xC8], ax |
mov ax, [_fs] |
mov word [context+0x90], ax |
; mov word [context+0x8C], 0 |
mov eax, [_eip] |
xchg eax, [context+0xB8] |
mov [_eip], eax |
mov eax, [_esp] |
xchg eax, [context+0xC4] |
mov [_esp], eax |
mov eax, [debugevent+12] |
mov [exc_code], eax |
mov eax, [debugevent+36] |
mov [exc_data], eax |
push eax |
push esp |
push 24 |
push _cs |
push esi |
push [hProcess] |
call [WriteProcessMemory] |
pop eax |
x: |
push context |
push [hThread] |
call [SetThreadContext] |
jmp debugcont |
process_exception: |
mov eax, [context+0xB8] |
cmp eax, server_test |
jnz .no_server_test |
mov eax, [debugevent+4] |
mov ecx, [pids] |
@@: cmp [ecx+4], eax |
jz @f |
mov ecx, [ecx] |
jmp @b |
@@: |
mov edi, [ecx+12] |
push ebx |
push 1000h |
push edi |
push [context+0x9C] |
push [hProcess] |
call [WriteProcessMemory] |
push edi |
call free_big |
mov eax, [cur_slot] |
mov [context+0xB0], eax |
mov eax, context+0xAC ; ecx |
mov ecx, [hSharedData] |
call DuplicateMyHandle |
mov eax, context+0xA8 ; edx |
mov ecx, [hSharedMutex] |
call DuplicateMyHandle |
jmp add2 |
.no_server_test: |
cmp eax, server_new_thread |
jnz @f |
mov eax, [debugevent+8] |
mov [dwThreadId], eax |
call new_kolibri_thread |
mov eax, [cur_slot] |
mov [context+0xAC], eax |
jmp add2 |
@@: |
cmp eax, server_run_prg |
jnz @f |
; create new process |
push ebx |
push 4096 |
push process_curdir |
push process_curdir |
push [hProcess] |
call [ReadProcessMemory] |
mov eax, [context+0x9C] |
mov edx, converted_path |
mov edi, edx ; edi=name |
call read_asciz |
mov eax, [context+0xA0] |
xor esi, esi ; esi=params |
test eax, eax |
jz .x |
mov edx, win32_path |
mov esi, edx |
call read_asciz |
.x: |
mov eax, [cur_tid_ptr] |
mov [parent_tid_ptr], eax |
push 2 ; dwOptions = DUPLICATE_SAME_ACCESS |
push ebx ; bInheritHandle |
push ebx ; dwDesiredAccess |
push context+0xAC ; lpTargetHandle |
push [hProcess] |
push eax |
call new_kolibri_process |
pop ecx |
mov edx, [context+0xB0] ; flags for 70.7 |
mov [ecx+32], edx |
mov [ecx+36], ebx |
mov [ecx+40], ebx |
; mov [context+0xB0], eax |
mov [ecx+28], eax |
push dword [ecx+24] |
call [GetCurrentProcess] |
push eax |
call [DuplicateHandle] |
jmp add2 |
@@: |
cmp eax, server_get_run_result |
jnz @f |
mov esi, [cur_tid_ptr] |
push dword [esi+24] |
call [CloseHandle] |
mov eax, [esi+28] |
mov [context+0xB0], eax |
mov eax, context+0xAC |
mov ecx, [esi+36] |
call DuplicateMyHandle |
mov eax, context+0xA8 |
mov ecx, [esi+40] |
call DuplicateMyHandle |
mov eax, [esi+44] |
mov [context+0xA0], eax |
mov eax, [esi+48] |
mov [context+0x9C], eax |
jmp add2 |
@@: |
cmp eax, set_wnd_colors |
jnz @f |
mov ecx, [context+0xA8] |
and ecx, 7Fh |
push ebx |
push ecx |
push common_colors |
push [context+0xAC] |
push [hProcess] |
call [ReadProcessMemory] |
mov [bCommonColorsSet], 1 |
add2: |
add [context+0xB8], 2 |
jmp x |
@@: |
cmp eax, notify_parent |
jnz nonotifyparent |
mov eax, [cur_tid_ptr] |
mov edi, [eax+20] |
test edi, edi |
jz add2 |
test byte [edi+32], 1 |
jz @f |
push [hThread] |
call [SuspendThread] |
mov eax, [hProcess] |
mov [edi+36], eax |
mov eax, [hThread] |
mov [edi+40], eax |
mov eax, [context+0xB4] |
mov [edi+44], eax |
mov eax, [context+0xC4] |
mov [edi+48], eax |
jmp setparev |
@@: |
mov dword [eax+20], ebx |
setparev: |
push dword [edi+24] |
call [SetEvent] |
jmp add2 |
nonotifyparent: |
cmp eax, loadfailed |
jnz @f |
mov ecx, [context+0xB0] |
mov eax, [cur_tid_ptr] |
mov edi, [eax+20] |
test edi, edi |
jz add2 |
mov [edi+28], ecx |
jmp @b |
@@: |
cmp eax, get_wnd_colors |
jnz @f |
mov ecx, [context+0xA8] |
and ecx, 7Fh |
push ebx |
push ecx |
push common_colors |
push [context+0xAC] |
push [hProcess] |
call [WriteProcessMemory] |
mov al, [bCommonColorsSet] |
mov byte [context+0xB0], al |
jmp add2 |
@@: |
cmp eax, set_button_style |
jnz @f |
mov ecx, [context+0xAC] |
cmp cl, [buttontype] |
jz add2 |
mov [buttontype], cl |
call update_buttontype |
jmp add2 |
@@: |
cmp eax, server_send_ipc |
jnz no_server_send_ipc |
; find target slot |
mov eax, [context+0xAC] ; ecx |
mov esi, [shared_data] |
mov ecx, [esi] |
add esi, shared_data_struc.threads |
@@: |
cmp [esi], eax |
jz @f |
add esi, 64 |
loop @b |
mov [context+0xB0], 4 ; no such PID |
jmp .done |
@@: |
mov eax, [esi+4] |
test eax, eax |
jnz @f |
mov [context+0xB0], 1 ; no IPC memory |
jmp .done |
@@: |
push -1 |
mov ecx, esp |
push ebx |
push 4 |
push ecx |
push eax |
push dword [esi+12] |
call [ReadProcessMemory] |
pop ecx |
jecxz @f |
mov [context+0xB0], 2 ; IPC blocked |
jmp .done |
@@: |
push ebx |
mov eax, esp |
push ebx |
push 4 |
push eax |
mov eax, [esi+4] |
add eax, 4 |
push eax |
push dword [esi+12] |
call [ReadProcessMemory] |
pop eax |
mov ecx, [esi+8] |
sub ecx, 8 |
sub ecx, eax |
sub ecx, [context+0xA0] ; esi = message length |
jns @f |
mov [context+0xB0], 3 ; buffer overflow |
jmp .done |
@@: |
mov edi, eax |
add eax, 8 |
add eax, [context+0xA0] |
push eax |
mov eax, esp |
push ebx |
push 4 |
push eax |
mov eax, [esi+4] |
add eax, 4 |
push eax |
push dword [esi+12] |
call [WriteProcessMemory] |
pop eax |
add edi, [esi+4] ; edi = pointer to place for our message |
; message header: dd source_pid, dd size |
push [context+0xA0] |
push edi |
call get_cur_slot_ptr_server |
mov eax, [edi] |
pop edi |
push eax |
mov eax, esp |
push ebx |
push 8 |
push eax |
push edi |
push dword [esi+12] |
call [WriteProcessMemory] |
pop eax |
pop eax |
; now read message from source process and write it to target |
push eax |
call malloc |
xchg eax, ebp |
push ebx |
push [context+0xA0] |
push ebp |
push [context+0xA8] |
push [hProcess] |
call [ReadProcessMemory] |
add edi, 8 |
push ebx |
push [context+0xA0] |
push ebp |
push edi |
push dword [esi+12] |
call [WriteProcessMemory] |
push ebp |
call free |
mov [context+0xB0], ebx ; success |
; now notify window of target handle |
; push 0 |
; push 0 |
; push 400h ; WM_USER |
; push dword [esi+20] |
; call [PostMessageA] |
; let source thread to notify target window |
mov eax, [esi+20] |
mov [context+0xAC], eax |
.done: |
jmp add2 |
no_server_send_ipc: |
cmp eax, server_convert |
jnz no_server_convert |
mov eax, context+0xB0 ; eax |
mov ecx, [eax] |
call DuplicateMyHandle |
jmp add2 |
no_server_convert: |
cmp eax, ..server_create_shmem |
jnz no_server_create_shmem |
sub esp, 32 |
mov eax, esp |
push ebx |
push 32 |
push eax |
push dword [context+0xAC] ; ecx |
push [hProcess] |
call [ReadProcessMemory] |
test eax, eax |
jnz @f |
.invparam: |
push 33 ; E_PARAM |
pop edx |
.ret: |
add esp, 32 |
mov dword [context+0xB0], edx ; eax |
jmp add2 |
@@: |
; scan for shared memory area with requested name |
mov edx, [shmem_list] |
.scan: |
mov esi, esp |
cmp edx, shmem_list - shmem_item.next |
jz .new |
mov edi, edx |
push 32 |
pop ecx |
@@: |
lodsb |
scasb |
jnz @f |
test al, al |
loopnz @b |
@@: |
jz .found |
mov edx, [edx+shmem_item.next] |
jmp .scan |
.new: |
; requested section was not found, create new if needed |
push 5 ; E_NOTFOUND |
pop edx |
mov al, byte [context+0xA0] ; esi |
and al, 0xC |
jz .ret |
jp .invparam |
; create |
mov eax, [context+0xA8] ; edx |
test eax, eax |
jz .invparam |
call malloc_big |
push 30 ; E_NOMEM |
pop edx |
test eax, eax |
jz .ret |
push eax |
push shmem_item.sizeof |
call malloc |
test eax, eax |
jnz @f |
call free_big |
push 30 |
pop edx |
jmp .ret |
@@: |
mov edi, eax |
push 32/4 |
pop ecx |
rep movsd |
mov ecx, [shmem_list] |
mov [eax+shmem_item.next], ecx |
mov [ecx+shmem_item.prev], eax |
mov [eax+shmem_item.prev], shmem_list - shmem_item.next |
mov [shmem_list], eax |
mov [eax+shmem_item.refs], ebx |
pop [eax+shmem_item.ptr] |
push [context+0xA8] |
pop [eax+shmem_item.size] |
mov [eax+shmem_item.hOwner], ebx |
mov [eax+shmem_item.pOwner], ebx |
mov esi, eax |
mov eax, [context+0xA0] ; esi |
and eax, 1 |
mov [esi+shmem_item.access], eax |
jmp .created |
.found: |
mov esi, edx |
push 10 ; E_ACCESS |
pop edx |
mov al, byte [context+0xA0] ; esi |
and al, 0xC |
jz @f |
jp .invparam |
cmp al, 8 |
jz .ret |
@@: |
test byte [context+0xA0], 1 |
jz .created |
cmp [esi+shmem_item.access], ebx |
jz .ret |
.created: |
inc [esi+shmem_item.refs] |
; section ok, now create descriptor for address space in target process |
push shmem_proc_descr.sizeof |
call malloc |
test eax, eax |
jnz @f |
push [esi+shmem_item.next] |
pop [shmem_list] |
push esi |
push [esi+shmem_item.ptr] |
call free_big |
call free |
push 30 |
pop edx |
jmp .ret |
@@: |
mov [eax+shmem_proc_descr.item], esi |
mov [eax+shmem_proc_descr.ptr], ebx |
mov [eax+shmem_proc_descr.end], ebx |
xor edx, edx |
test byte [context+0xA0], 1 |
jz @f |
inc edx |
@@: |
cmp [esi+shmem_item.refs], 1 |
jnz @f |
mov dl, 1 |
@@: |
mov [eax+shmem_proc_descr.access], edx |
; no need to synchronize - only server uses this list |
call get_cur_slot_ptr_server |
push [edi+shared_data_struc.shmem_list-shared_data_struc.threads] |
pop [eax+shmem_proc_descr.next] |
mov [edi+shared_data_struc.shmem_list-shared_data_struc.threads], eax |
; all is OK, return to caller |
mov [context+0xB0], ebx ; eax |
mov eax, [esi+shmem_item.size] |
mov [context+0xAC], eax ; ecx |
add eax, 0xFFF |
and eax, not 0xFFF |
cmp [esi+shmem_item.refs], 1 |
jnz @f |
xor eax, eax |
@@: |
mov [context+0xA8], eax ; edx |
add esp, 32 |
jmp add2 |
no_server_create_shmem: |
cmp eax, ..server_notify_shmem |
jnz no_server_notify_shmem |
call get_cur_slot_ptr_server |
mov edi, [edi+shared_data_struc.shmem_list-shared_data_struc.threads] |
push [context+0xB0] ; eax |
pop [edi+shmem_proc_descr.ptr] |
mov eax, [edi+shmem_proc_descr.item] |
mov eax, [eax+shmem_item.size] |
add eax, 0xFFF |
and eax, not 0xFFF |
add eax, [edi+shmem_proc_descr.ptr] |
mov [edi+shmem_proc_descr.end], eax |
jmp add2 |
no_server_notify_shmem: |
cmp eax, ..server_destroy_shmem |
jnz no_server_destroy_shmem |
sub esp, 32 |
mov eax, esp |
push ebx |
push 32 |
push eax |
push dword [context+0xAC] ; ecx |
push [hProcess] |
call [ReadProcessMemory] |
mov [context+0xAC], ebx |
test eax, eax |
jz .ret |
call get_cur_slot_ptr_server |
lea ebp, [edi+shared_data_struc.shmem_list-shared_data_struc.threads - shmem_proc_descr.next] |
.scan: |
mov edx, [ebp+shmem_proc_descr.next] |
test edx, edx |
jz .ret |
mov esi, [edx+shmem_proc_descr.item] |
mov edi, esp |
push 32 |
pop ecx |
@@: |
lodsb |
scasb |
jnz @f |
test al, al |
loopnz @b |
@@: |
jz .found |
mov ebp, edx |
jmp .scan |
.found: |
push [edx+shmem_proc_descr.next] |
pop [ebp+shmem_proc_descr.next] |
push [edx+shmem_proc_descr.ptr] |
pop [context+0xAC] ; ecx |
mov esi, [edx+shmem_proc_descr.item] |
push edx |
call free |
dec [esi+shmem_item.refs] |
jnz .ret |
call shmem_free_item |
.ret: |
add esp, 32 |
jmp add2 |
no_server_destroy_shmem: |
cmp eax, i40_sys_service.server_terminate |
jz server_done |
no_server_terminate: |
if idletime_via_ring0 |
cmp eax, i40_sys_service.idlecount_init |
jnz @f |
push eax |
push esp |
push ebx |
push [cur_slot] |
push idlecount_thread |
push 2000h |
push ebx |
call [CreateThread] |
pop eax |
mov eax, [shared_data] |
mov [eax+shared_data_struc.idlecount], 1000 |
mov [eax+shared_data_struc.b9xPerfInited], 1 |
jmp add2 |
@@: |
end if |
cont_nh: |
; ignore int3 breaks (continue as handled) |
cmp [debugevent+12], 80000003h ; EXCEPTION_BREAKPOINT |
jz debugcont |
if 1 |
; ignore first-chance exceptions (continue as not handled) |
cmp dword [debugevent+0x5C], ebx |
jnz .first_chance |
mov eax, context |
int3 |
mov eax, [context+0xB8] |
mov edi, eeeeip+7 |
std |
mov ecx, 8 |
@@: |
mov edx, eax |
and al, 0xF |
cmp al, 10 |
sbb al, 69h |
das |
stosb |
mov eax, edx |
shr eax, 4 |
loop @b |
cld |
call init_MessageBox |
push ebx |
push ebx |
push eee |
push ebx |
call [MessageBoxA] |
.first_chance: |
end if |
push 80010001h ; DBG_EXCEPTION_NOT_HANDLED |
jmp dodebugcont |
|
find_tid: |
; get hThread |
mov [hThread], ebx |
mov [cur_slot], ebx |
mov eax, [debugevent+8] |
mov ecx, [tids] |
@@: jecxz .ret |
cmp [ecx+4], eax |
jz @f |
mov ecx, [ecx] |
jmp @b |
@@: mov eax, [ecx+12] |
mov [cur_slot], eax |
mov eax, [ecx+8] |
mov [hThread], eax |
mov [cur_tid_ptr], ecx |
.ret: |
ret |
|
read_asciz: |
; in: eax=client pointer, edx->buffer |
push eax |
push edx |
push eax |
push esp |
push 260 |
push edx |
push eax |
push [hProcess] |
call [ReadProcessMemory] |
test eax, eax |
pop ecx |
pop edx |
pop eax |
jnz @f |
xor ecx, ecx |
@@: mov byte [edx+ecx], bl |
ret |
|
create_child: |
mov edi, inname |
mov esi, [parameters] |
|
new_kolibri_process_with_default_curdir: |
mov dword [process_curdir], '/rd/' |
mov word [process_curdir+4], '1' |
mov [parent_tid_ptr], ebx |
|
new_kolibri_process: |
; in: edi=pointer to process name, esi=pointer to parameters |
; create command line |
mov [process_name], edi |
push esi |
push edi |
mov edi, cmdline |
mov al, '"' |
stosb |
push 2000 |
push edi |
push ebx |
call [GetModuleFileNameA] |
add edi, eax |
mov ax, '" ' |
stosw |
mov al, '"' |
stosb |
pop esi |
push esi |
call [lstrlenA] |
xchg eax, ecx |
rep movsb |
mov al, '"' |
stosb |
mov al, ' ' |
stosb |
pop esi |
test esi, esi |
jz @f |
push esi |
call [lstrlenA] |
xchg eax, ecx |
rep movsb |
@@: |
xor eax, eax |
stosb |
; create process |
push [hThread] |
push pinfo |
push sinfo |
push ebx |
push ebx |
push ebx |
cmp [bDontDebug], bl |
jnz @f |
pop ebx |
push 2 ; DEBUG_ONLY_THIS_PROCESS |
@@: |
push ebx |
push ebx |
push ebx |
push cmdline |
push ebx |
call [CreateProcessA] |
test eax, eax |
jnz @f |
call init_MessageBox |
push ebx |
push ebx |
push cpe |
push ebx |
call [MessageBoxA] |
pop eax |
xor eax, eax |
dec eax |
ret |
@@: |
cmp [bDontDebug], bl |
jz @f |
pop eax |
ret |
@@: |
mov eax, pids |
@@: mov ecx, [eax] |
jecxz @f |
xchg eax, ecx |
jmp @b |
@@: push eax |
push 16 |
call malloc |
pop ecx |
mov [ecx], eax |
mov [eax], ebx |
mov ecx, [dwProcessId] |
mov [eax+4], ecx |
mov ecx, [hProcess] |
mov [eax+8], ecx |
push eax |
mov eax, 1000h |
call malloc_big |
pop ecx |
mov [ecx+12], eax |
mov edi, eax |
mov esi, process_curdir |
mov ecx, 1000h/4 |
rep movsd |
call alloc_thread |
call new_kolibri_thread |
push eax |
add edi, 8 |
mov esi, [process_name] |
mov edx, esi |
.1: |
lodsb |
cmp al, '\' |
jnz @f |
mov edx, esi |
@@: cmp al, 0 |
jnz .1 |
mov esi, edx |
mov ecx, 11 |
push ecx edi |
mov al, ' ' |
rep stosb |
pop edi ecx |
push edi |
.s: |
lodsb |
test al, al |
jz .d |
cmp al, '.' |
jnz @f |
mov edi, [esp] |
add edi, 8 |
mov cl, 3 |
jmp .s |
@@: |
cmp al, 'a' |
jb @f |
cmp al, 'z' |
ja @f |
and al, not 20h |
@@: stosb |
loop .s |
.d: |
pop edi |
add edi, 11 |
mov byte [edi], 0 |
pop eax |
pop [hThread] |
inc [num_kolibri_proc] |
ret |
alloc_thread: |
mov eax, tids |
@@: mov ecx, [eax] |
jecxz @f |
xchg eax, ecx |
jmp @b |
@@: push eax |
push 56 |
call malloc |
pop ecx |
mov [ecx], eax |
mov [eax], ebx |
mov ecx, [dwThreadId] |
mov [eax+4], ecx |
mov ecx, [hThread] |
mov [eax+8], ecx |
or dword [eax+12], -1 |
mov ecx, [parent_tid_ptr] |
mov [eax+20], ecx |
mov [eax+52], ebx |
mov [cur_tid_ptr], eax |
push ecx |
push ebx ; lpName |
push ebx ; bInitialState |
push ebx ; bManualReset |
push ebx ; lpEventAttributes |
call [CreateEventA] |
pop ecx |
jecxz @f |
mov [ecx+24], eax |
@@: |
ret |
new_kolibri_thread: |
; find free slot |
mov edi, [shared_data] |
inc dword [edi+4] |
mov ecx, [edi] |
add edi, shared_data_struc.threads |
xor edx, edx |
@@: |
cmp dword [edi], 0 |
jz @f |
inc edx |
add edi, 64 |
loop @b |
mov ecx, [shared_data] |
inc dword [ecx] |
@@: |
mov eax, [cur_tid_ptr] |
mov [eax+12], edx |
mov [cur_slot], edx |
mov eax, [max_pid] |
inc eax |
mov [max_pid], eax |
stosd |
push eax |
xor eax, eax |
stosd |
stosd |
mov eax, [hProcess] |
stosd |
mov eax, [dwThreadId] |
stosd |
push edi |
add edi, 20 |
mov eax, [hThread] |
stosd |
xor eax, eax |
stosd |
stosd |
stosd |
stosd |
stosd |
pop edi |
pop eax |
ret |
|
delete_id: |
@@: mov edx, [ecx] |
cmp [edx+4], eax |
jz @f |
mov ecx, edx |
jmp @b |
@@: |
push dword [edx] |
push ecx |
push edx |
push ebx |
push [hHeap] |
; push dword [edx+8] |
; call [CloseHandle] |
call [HeapFree] |
pop ecx |
pop dword [ecx] |
.ret: |
ret |
|
on_thread_exited: |
mov ecx, [cur_tid_ptr] |
; send notification message to debugger, if it is present |
mov edi, [ecx+20] |
test edi, edi |
jz @f |
push ecx |
mov eax, [edi+12] |
call get_slot_ptr |
push ebx |
push [cur_slot] |
push 402h |
push [edi+shared_data_struc.hWnd-shared_data_struc.threads] |
call init_MessageBox |
call [PostMessageA] |
pop ecx |
@@: |
; terminate all debuggees, if are |
mov esi, tids |
@@: |
mov esi, [esi] |
test esi, esi |
jz @f |
cmp [esi+20], ecx |
jnz @b |
push ecx |
push ebx |
push dword [esi+8] |
call [TerminateThread] |
pop ecx |
jmp @b |
@@: |
; free all shared memory |
call get_cur_slot_ptr_server |
mov edi, [edi+shared_data_struc.shmem_list-shared_data_struc.threads] |
.freeshared: |
test edi, edi |
jz .doneshared |
push [edi+shmem_proc_descr.next] |
mov esi, [edi+shmem_proc_descr.item] |
dec [esi+shmem_item.refs] |
jz .freephys |
cmp [esi+shmem_item.pOwner], edi |
jnz .nextshared |
call shmem_load |
jmp .nextshared |
.freephys: |
call shmem_free_item |
.nextshared: |
push edi |
call free |
pop edi |
jmp .freeshared |
.doneshared: |
; create thread to do rest of job (part which must be done with SharedDataMutex acquired) |
; it is not safe to acquire_shared right here, because of possible deadlock |
push eax |
push esp |
push ebx |
push [cur_slot] |
push on_thread_exited_thread |
push 10000h |
push ebx |
call [CreateThread] |
pop eax |
ret |
|
on_thread_exited_thread: |
call acquire_shared |
mov eax, [shared_data] |
dec dword [eax+4] |
mov eax, [esp+4] |
call get_slot_ptr |
and dword [edi], 0 |
; avoid problems with @panel |
mov eax, ' ' |
add edi, 28 |
stosd |
stosd |
stosd |
call release_shared |
push 0 |
call [ExitThread] |
|
if idletime_via_ring0 |
idlecount_thread: |
mov eax, .count |
call CallRing0 |
.workloop: |
mov esi, eax |
push 1000 |
call [Sleep] |
mov eax, .count |
call CallRing0 |
sub esi, eax |
; add esi, 1000 |
; jc @f |
; mov esi, 1000 |
;@@: |
neg esi |
cmp esi, 1000 |
jb @f |
mov esi, 1000 |
@@: |
mov ecx, [shared_data] |
mov [ecx+shared_data_struc.idlecount], esi |
jmp .workloop |
.count: |
push edi |
; xor edx, edx |
int 0x20 ; VMMCall Get_Sys_Thread_Handle |
dw 10Ah |
dw 1 |
push edi |
int 0x20 ; VMMCall _GetThreadExecTime |
dw 106h |
dw 1 |
pop edi |
; int 0x20 ; VMMCall Get_Sys_Thread_Handle |
; dw 10Ah |
; dw 1 |
;@@: |
; int 0x20 ; VMMCall Get_Next_Thread_Handle |
; dw 113h |
; dw 1 |
; int 0x20 ; VMMCall Test_Sys_Thread_Handle |
; dw 10Bh |
; dw 1 |
; jz @f |
; push edi |
; int 0x20 ; VMMCall _GetThreadExecTime |
; dw 106h |
; dw 1 |
; add edx, eax |
; pop eax |
; jmp @b |
;@@: |
; mov eax, edx |
pop edi |
iret |
end if |
|
update_buttontype: |
mov esi, [pids] |
@@: |
test esi, esi |
jz .done |
push 0 |
push 1 |
push buttontype |
push buttontype |
push dword [esi+8] |
call [WriteProcessMemory] |
mov esi, [esi] |
jmp @b |
.done: |
ret |
|
init_background: |
push -1 |
push [hBgrMutex] |
call [WaitForSingleObject] |
cmp [bgr_section], 0 |
jnz .ret |
push ebx |
call get_screen_size |
movzx eax, bx |
shr ebx, 16 |
inc eax |
inc ebx |
mul ebx |
imul eax, 3 |
pop ebx |
add eax, 20h |
push bgr_section_name |
; push 0 |
push eax |
push 0 |
push 4 |
push 0 |
push -1 |
call [CreateFileMappingA] |
test eax, eax |
jz .ret |
xchg eax, esi |
call [GetLastError] |
push eax |
push 0 |
push 0 |
push 0 |
push 2 |
push esi |
call [MapViewOfFile] |
push eax |
; push esi |
; call [CloseHandle] |
pop eax |
mov [bgr_section], eax |
test eax, eax |
xchg eax, edi |
pop eax |
jz .ret |
cmp eax, 183 |
jz .ret |
; init background data |
call get_screen_size |
xor eax, eax |
shld eax, ebx, 16 |
inc eax |
stosd |
mov ax, bx |
inc eax |
stosd |
mov byte [edi], 2 |
add edi, 8 |
xor ebx, ebx |
; cmp byte [esp+4], 0 |
; jz read_bgr |
jmp read_bgr |
.ret: |
push [hBgrMutex] |
call [ReleaseMutex] |
ret 4 |
|
read_bgr: |
; read and parse desktop background to edi (=[bgr_section]+10h) |
; call [GetDesktopWindow] |
xor eax, eax |
push eax |
push eax |
call [GetDC] |
push eax |
push eax |
call [CreateCompatibleDC] |
xchg eax, esi |
push dword [edi-0Ch] |
push dword [edi-10h] |
push dword [esp+8] |
call [CreateCompatibleBitmap] |
push eax |
push esi |
call [SelectObject] |
push eax |
push 0xCC0020 |
push ebx |
push ebx |
push dword [esp+16] |
push dword [edi-0Ch] |
push dword [edi-10h] |
push ebx |
push ebx |
push esi |
call [BitBlt] |
push dword [esp+4] |
call [PaintDesktop] |
push 0x660046 |
push ebx |
push ebx |
push dword [esp+16] |
push dword [edi-0Ch] |
push dword [edi-10h] |
push ebx |
push ebx |
push esi |
call [BitBlt] |
push 0x660046 |
push ebx |
push ebx |
push esi |
push dword [edi-0Ch] |
push dword [edi-10h] |
push ebx |
push ebx |
push dword [esp+36] |
call [BitBlt] |
push 0x660046 |
push ebx |
push ebx |
push dword [esp+16] |
push dword [edi-0Ch] |
push dword [edi-10h] |
push ebx |
push ebx |
push esi |
call [BitBlt] |
push esi |
call [SelectObject] |
push ebp |
xchg eax, ebp |
; now esi=hDC, ebp=hBitmap |
push ebx ; biClrImportant |
push ebx ; biClrUsed |
push ebx ; biYPelsPerMeter |
push ebx ; biXPelsPerMeter |
push ebx ; biSizeImage |
push ebx ; biCompression |
push 200001h ; biBitCount, biPlanes |
push dword [edi-0Ch] ; biHeight |
push dword [edi-10h] ; biWidth |
push 40 ; biSize |
mov ecx, esp |
push ebx |
push ecx |
mov eax, [edi-0Ch] |
mul dword [edi-10h] |
shl eax, 2 |
call malloc_big |
push eax |
push dword [edi-0Ch] |
push ebx |
push ebp |
push esi |
xchg eax, edi |
call [GetDIBits] |
add esp, 40 |
push ebp |
call [DeleteObject] |
pop ebp |
push esi |
call [DeleteDC] |
pop eax |
pop ecx |
push eax |
push ecx |
call [ReleaseDC] |
mov esi, [bgr_section] |
mov eax, [esi] ; width |
mov ecx, [esi+4] ; height |
add esi, 10h |
xchg esi, edi |
; esi=source, edi=destination |
push eax |
mul ecx |
shl eax, 2 |
add esi, eax |
pop edx |
.1: |
push ecx |
mov ecx, edx |
neg ecx |
lea esi, [esi+ecx*4] |
neg ecx |
push esi |
.2: |
lodsd |
; call convert_color |
stosd |
dec edi |
loop .2 |
pop esi |
pop ecx |
loop .1 |
push esi |
call free_big |
push [hBgrMutex] |
call [ReleaseMutex] |
ret 4 |
|
del_background: |
call [GetTickCount] |
mov ecx, [shared_data] |
cmp eax, [ecx+shared_data_struc.dwNewBgrTime] |
jb .ret |
add eax, 3000 |
mov [ecx+shared_data_struc.dwNewBgrTime], eax |
xor eax, eax |
lock xchg eax, [bgr_section] |
test eax, eax |
jz .ret |
push eax |
call [UnmapViewOfFile] |
.ret: |
ret |
|
read_hex: |
xor ecx, ecx |
.l: |
cmp al, '0' |
jb .done |
cmp al, '9' |
jbe .digit |
cmp al, 'A' |
jb .done |
cmp al, 'F' |
jbe .digit2 |
cmp al, 'a' |
jb .done |
cmp al, 'f' |
jbe .digit3 |
.done: |
ret |
.digit3: |
sub al, 0x20 |
.digit2: |
sub al, 'A'-'0'-10 |
.digit: |
sub al, '0' |
movzx eax, al |
shl ecx, 4 |
add ecx, eax |
cmp ecx, 0x10000 |
jae ParseEnablePorts.err |
lodsb |
jmp .l |
|
send_driver_request: |
xor ebx, ebx |
push ebx |
push ebx |
push 3 |
push ebx |
push ebx |
push 0xC0000000 |
push kiw0 |
call [CreateFileA] |
inc eax |
jz .ret |
dec eax |
push eax |
push eax |
mov ecx, esp |
push ebx ; lpOverlapped |
push ecx ; lpBytesReturned |
push dword [ecx+8+20] ; nOutBufferSize |
push dword [ecx+8+16] ; lpOutBuffer |
push dword [ecx+8+12] ; nInBufferSize |
push dword [ecx+8+8] ; lpInBuffer |
push dword [ecx+8+4] ; dwIoControlCode |
push eax |
call [DeviceIoControl] |
pop ecx |
pop ecx |
push eax |
push ecx |
call [CloseHandle] |
pop eax |
.ret: |
ret 20 |
|
driver_via_scm = 0 |
REQUIRED_DRIVER_VERSION = 1 |
|
load_kiw0: |
; check whether driver with required version is already loaded |
push eax |
mov eax, esp |
push 4 |
push eax |
push ebx |
push ebx |
push 0x222008 |
call send_driver_request |
test eax, eax |
pop edi |
jz .load |
if driver_via_scm |
push 3 ; dwDesiredAccess = SC_MANAGER_CONNECT+SC_MANAGER_CREATE_SERVICE |
cmp edi, REQUIRED_DRIVER_VERSION |
jnz .open |
pop eax |
cmp [keep_loaded_driver], 0 |
jnz .noopen |
push 1 ; dwDesiredAccess = SC_MANAGER_CONNECT |
.open: |
mov esi, DrvLoadErr |
push ebx ; lpDatabaseName |
push ebx ; lpMachineName |
call [OpenSCManagerA] |
test eax, eax |
jz server_fail |
mov [hSCManager], eax |
push 10030h |
push kiw0_drivername |
push [hSCManager] |
call [OpenServiceA] |
test eax, eax |
jz server_fail |
mov [hService], eax |
.noopen: |
cmp edi, REQUIRED_DRIVER_VERSION |
jz .driverok |
; driver is loaded, but has incorrect version |
; try to unload and load new driver |
call unload_kiw0 |
jmp @f |
|
.load: |
mov esi, DrvLoadErr |
push 2 ; dwDesiredAccess = SC_MANAGER_CREATE_SERVICE |
push ebx ; lpDatabaseName |
push ebx ; lpMachineName |
call [OpenSCManagerA] |
test eax, eax |
jz server_fail |
mov [hSCManager], eax |
@@: |
mov edi, win32_path |
push edi |
push edi |
call [lstrlenA] |
lea edi, [edi+eax+1-inifilenamesize] |
push esi |
mov esi, kiw0filename |
mov ecx, kiw0filenamesize |
rep movsb |
pop esi |
pop edi |
push ebx ; lpPassword |
push ebx ; lpServiceStartName |
push ebx ; lpDependencies |
push ebx ; lpdwTagId |
push ebx ; lpLoadOrderGroup |
push edi ; lpBinaryPathName |
push ebx ; dwErrorControl = SERVICE_ERROR_IGNORE |
push 3 ; dwStartType = SERVICE_DEMAND_START |
push 1 ; dwServiceType = SERVICE_KERNEL_DRIVER |
push 10030h ; dwDesiredAccess = SERVICE_START or SERVICE_STOP or DELETE |
push kiw0_username ; lpDisplayName |
push kiw0_drivername ; lpServiceName |
push [hSCManager] |
call [CreateServiceA] |
; test eax, eax |
; jnz .cont |
; call [GetLastError] |
; cmp eax, 431h ; ERROR_SERVICE_EXISTS |
; jnz server_fail |
; push 10030h |
; push kiw0_drivername |
; push [hSCManager] |
; call [OpenServiceA] |
test eax, eax |
jz server_fail |
.cont: |
mov [hService], eax |
push ebx ; lpServiceArgVectors |
push ebx ; dwNumServiceArgs |
push eax |
call [StartServiceA] |
test eax, eax |
jz server_fail |
.driverok: |
ret |
|
unload_kiw0: |
sub esp, 20h |
push esp |
push 1 ; SERVICE_CONTROL_STOP |
push [hService] |
call [ControlService] |
add esp, 20h |
push [hService] |
call [DeleteService] |
push [hService] |
call [CloseServiceHandle] |
ret |
|
server_done: |
cmp [hService], 0 |
jz .skip_drv |
cmp [keep_loaded_driver], 0 |
jnz .skip_drv |
call unload_kiw0 |
push [hSCManager] |
call [CloseServiceHandle] |
.skip_drv: |
|
else |
cmp edi, REQUIRED_DRIVER_VERSION |
jz load_kiw0.driverok |
call unload_kiw0 |
load_kiw0.load: |
mov esi, DrvLoadErr |
push eax |
mov eax, esp |
xor ecx, ecx |
push ecx ; lpdwDisposition |
push eax ; phkResult |
push ecx ; lpSecurityAttributes |
push 6 ; samDesired = KEY_SET_VALUE | KEY_CREATE_SUB_KEY |
push ecx ; dwOptions |
push ecx ; lpClass |
push ecx ; Reserved |
push DrvKey ; lpSubKey |
push 0x80000002 ; hKey = HKEY_LOCAL_MACHINE |
call [RegCreateKeyExA] |
test eax, eax |
jnz server_fail |
push esi |
mov esi, win32_path |
push esi |
call [lstrlenA] |
lea esi, [esi+eax-1] |
lea edi, [esi+4] |
mov ecx, eax |
push edi |
std |
rep movsb |
cld |
mov dword [edi-3], '\??\' |
pop edi |
sub edi, inifilenamesize-2 |
mov esi, kiw0filename |
mov ecx, kiw0filenamesize |
rep movsb |
sub edi, win32_path+1 |
mov [drvpathlen], edi |
pop esi |
mov edi, DrvKeyValues |
.write_values: |
push dword [edi+12] ; cbData |
push dword [edi+8] ; lpData |
push dword [edi+4] ; dwType |
push 0 ; Reserved |
push dword [edi] ; lpValueName |
push dword [esp+20] ; hKey |
call [RegSetValueExA] |
test eax, eax |
jz @f |
call [RegCloseKey] |
.del_fail: |
push DrvKey |
push 0x80000002 |
call [RegDeleteKeyA] |
jmp server_fail |
@@: |
add edi, 16 |
cmp dword [edi], 0 |
jnz .write_values |
call [RegCloseKey] |
; NtLoadDriver and NtUnloadDriver require SeLoadPrivilege enabled. |
; But I found that if user has this privilege, then it is already enabled |
; (unlike things like SeShutdownPrivilege - in such cases there must be |
; additional code with AdjustTokenPrivileges(OpenProcessToken(...),LookupPrivilegeValue(...),...)) |
push ntdll_name |
call [GetModuleHandleA] |
push aNtLoadDriver |
push eax |
call [GetProcAddress] |
push DrvKeySys |
call eax |
test eax, eax |
js .del_fail |
load_kiw0.driverok: |
mov [bDriverLoaded], 1 |
ret |
|
unload_kiw0: |
; Unload and delete driver kiw0.sys |
; 1. Unload |
push ntdll_name |
call [GetModuleHandleA] |
push aNtUnloadDriver |
push eax |
call [GetProcAddress] |
push DrvKeySys |
call eax |
; 2. When the kernel loads driver, it (kernel) creates auxiliary reg keys |
; in HKLM\System\CurrentControlSet\Enum\ |
; (for legacy drivers such as kiw0, this is Root\LEGACY_KIW0\<instance>) |
; To delete this key and possibly reenumerate, call umpnpmgr.DeleteServicePlugPlayRegKeys |
; In Win2k the library umpnpmgr.dll doesn't export this function, |
; but under Win2k there is impossible to delete this key, because it is still opened by the kernel |
mov esi, aCannotLoadDll |
push umpnpmgr_name |
call [LoadLibraryA] |
test eax, eax |
jz .nodll |
push eax |
push umpnpmgr_uninst |
push eax |
call [GetProcAddress] |
test eax, eax |
jz @f |
push kiw0_unicode |
call eax |
@@: |
call [FreeLibrary] |
.nodll: |
; 3. Delete main registry key, HKLM\System\CurrentControlSet\Services\kiw0 |
; (and created by the kernel subkey Enum) |
push DrvKeyEnum |
push 0x80000002 |
call [RegDeleteKeyA] |
push DrvKey |
push 0x80000002 |
call [RegDeleteKeyA] |
.ret: |
ret |
|
server_done: |
cmp [bDriverLoaded], 0 |
jz .skip_drv |
cmp [keep_loaded_driver], 0 |
jnz .skip_drv |
call unload_kiw0 |
.skip_drv: |
end if |
|
cmp [bIs9x], 0 |
jz server_done_perf |
mov eax, [shared_data] |
cmp [eax+shared_data_struc.b9xPerfInited], 0 |
jz server_done_perf |
if ~idletime_via_ring0 |
push eax |
push esp ; phkResult |
push 1 ; samDesired = KEY_QUERY_VALUE |
push ebx ; ulOptions |
push perfend ; lpSubKey |
push 80000006h ; hKey = HKEY_DYN_DATA |
call [RegOpenKeyExA] |
pop esi |
test eax, eax |
jnz server_done_perf |
push eax |
mov eax, esp |
push 4 |
push esp ; lpcbData |
push eax ; lpData |
push ebx ; lpType |
push ebx ; lpReserved |
push perfval ; lpValueName |
push esi ; hKey |
call [RegQueryValueExA] |
pop ecx |
pop ecx |
push esi |
call [RegCloseKey] |
end if |
server_done_perf: |
push ebx |
call [ExitProcess] |
|
PlaySoundA_delayed_imp: |
push winmm_name |
call [LoadLibraryA] |
test eax, eax |
jz .fail |
push eax |
push aPlaySoundA |
push eax |
call [GetProcAddress] |
pop ecx |
test eax, eax |
jz .fail_free |
mov [PlaySoundA], eax |
jmp eax |
.fail_free: |
push ecx |
call [FreeLibrary] |
.fail: |
mov [PlaySoundA], @f |
@@: |
xor eax, eax |
ret 12 |
|
init_dll: |
push dword [esp+4] |
call [LoadLibraryA] |
xchg edi, eax |
mov esi, [esp+8] |
@@: |
lodsd |
test eax, eax |
jz @f |
add eax, 0x400002 |
push eax |
push edi |
call [GetProcAddress] |
mov [esi-4], eax |
jmp @b |
@@: |
ret 8 |
|
init_MessageBox: |
cmp [MessageBoxA], rva MessageBoxA_thunk |
jnz @f |
push user32_thunks |
push user32_name |
call init_dll |
@@: |
ret |
|
DuplicateMyHandle: |
jecxz @f |
push 2 ; DUPLICATE_SAME_ACCESS |
push ebx |
push ebx |
push eax |
push [hProcess] |
push ecx |
call [GetCurrentProcess] |
push eax |
call [DuplicateHandle] |
ret |
@@: |
mov [eax], ecx |
ret |
|
shmem_load: |
mov edx, [eax+shmem_proc_descr.end] |
mov ecx, [eax+shmem_proc_descr.ptr] |
sub edx, ecx |
push eax ecx edx |
push eax |
push esp |
push 2 ; PAGE_READONLY |
push edx |
push ecx |
push [esi+shmem_item.hOwner] |
call [VirtualProtectEx] |
pop eax |
pop edx ecx eax |
push ebx |
push edx |
push [esi+shmem_item.ptr] |
push ecx |
push [esi+shmem_item.hOwner] |
call [ReadProcessMemory] |
mov [esi+shmem_item.hOwner], ebx |
mov [esi+shmem_item.pOwner], ebx |
ret |
|
shmem_free_item: |
mov eax, [esi+shmem_item.next] |
mov ecx, [esi+shmem_item.prev] |
mov [eax+shmem_item.prev], ecx |
mov [ecx+shmem_item.next], eax |
push [esi+shmem_item.ptr] |
call free_big |
push esi |
call free |
ret |
|
include 'i40emul.inc' |
|
section '.rdata' data readable |
|
data import |
macro thunk a { |
a#_thunk:dw 0 |
db `a,0} |
dd 0,0,0, rva kernel32_name, rva kernel32_thunks |
; dd 0,0,0, rva user32_name, rva user32_thunks |
; dd 0,0,0, rva gdi32_name, rva gdi32_thunks |
; dd 0,0,0, rva comdlg32_name, rva comdlg32_thunks |
dd 0,0,0, rva advapi32_name, rva advapi32_thunks |
; dd 0,0,0, rva winmm_name, rva winmm_thunks |
dd 0,0,0,0,0 |
kernel32_name db 'kernel32.dll',0 |
user32_name db 'user32.dll',0 |
gdi32_name db 'gdi32.dll',0 |
ntdll_name db 'ntdll.dll',0 |
comdlg32_name db 'comdlg32.dll',0 |
advapi32_name db 'advapi32.dll',0 |
winmm_name db 'winmm.dll',0 |
;winsock_name db 'wsock32.dll',0 |
kernel32_thunks: |
CreateFileA dd rva CreateFileA_thunk |
CloseHandle dd rva CloseHandle_thunk |
CreateFileMappingA dd rva CreateFileMappingA_thunk |
OpenFileMappingA dd rva OpenFileMappingA_thunk |
MapViewOfFile dd rva MapViewOfFile_thunk |
UnmapViewOfFile dd rva UnmapViewOfFile_thunk |
ReadFile dd rva ReadFile_thunk |
WriteFile dd rva WriteFile_thunk |
GetFileSize dd rva GetFileSize_thunk |
SetEndOfFile dd rva SetEndOfFile_thunk |
VirtualAlloc dd rva VirtualAlloc_thunk |
VirtualFree dd rva VirtualFree_thunk |
VirtualProtect dd rva VirtualProtect_thunk |
VirtualProtectEx dd rva VirtualProtectEx_thunk |
SetFilePointer dd rva SetFilePointer_thunk |
ExitProcess dd rva ExitProcess_thunk |
ExitThread dd rva ExitThread_thunk |
CreateProcessA dd rva CreateProcessA_thunk |
CreateThread dd rva CreateThread_thunk |
TerminateThread dd rva TerminateThread_thunk |
GetCommandLineA dd rva GetCommandLineA_thunk |
ReadProcessMemory dd rva ReadProcessMemory_thunk |
WriteProcessMemory dd rva WriteProcessMemory_thunk |
WaitForDebugEvent dd rva WaitForDebugEvent_thunk |
ContinueDebugEvent dd rva ContinueDebugEvent_thunk |
SuspendThread dd rva SuspendThread_thunk |
ResumeThread dd rva ResumeThread_thunk |
GetThreadContext dd rva GetThreadContext_thunk |
SetThreadContext dd rva SetThreadContext_thunk |
GetProcessHeap dd rva GetProcessHeap_thunk |
HeapAlloc dd rva HeapAlloc_thunk |
HeapReAlloc dd rva HeapReAlloc_thunk |
HeapFree dd rva HeapFree_thunk |
Sleep dd rva Sleep_thunk |
GetLocalTime dd rva GetLocalTime_thunk |
SetFileTime dd rva SetFileTime_thunk |
GetCurrentDirectoryA dd rva GetCurrentDirectoryA_thunk |
SetCurrentDirectoryA dd rva SetCurrentDirectoryA_thunk |
GetTickCount dd rva GetTickCount_thunk |
GetCurrentProcess dd rva GetCurrentProcess_thunk |
GetPrivateProfileStringA dd rva GetPrivateProfileStringA_thunk |
GetPrivateProfileIntA dd rva GetPrivateProfileIntA_thunk |
lstrcpyA dd rva lstrcpyA_thunk |
lstrcpynA dd rva lstrcpynA_thunk |
lstrcatA dd rva lstrcatA_thunk |
lstrlenA dd rva lstrlenA_thunk |
lstrcmpA dd rva lstrcmpA_thunk |
GetFileAttributesA dd rva GetFileAttributesA_thunk |
SetFileAttributesA dd rva SetFileAttributesA_thunk |
GetModuleFileNameA dd rva GetModuleFileNameA_thunk |
GetLastError dd rva GetLastError_thunk |
CreateMutexA dd rva CreateMutexA_thunk |
CreateEventA dd rva CreateEventA_thunk |
SetEvent dd rva SetEvent_thunk |
DuplicateHandle dd rva DuplicateHandle_thunk |
WaitForSingleObject dd rva WaitForSingleObject_thunk |
ReleaseMutex dd rva ReleaseMutex_thunk |
GetVersion dd rva GetVersion_thunk |
GetModuleHandleA dd rva GetModuleHandleA_thunk |
GetProcAddress dd rva GetProcAddress_thunk |
GetCurrentThreadId dd rva GetCurrentThreadId_thunk |
GetStartupInfoA dd rva GetStartupInfoA_thunk |
FindFirstFileA dd rva FindFirstFileA_thunk |
FindNextFileA dd rva FindNextFileA_thunk |
FindClose dd rva FindClose_thunk |
FileTimeToDosDateTime dd rva FileTimeToDosDateTime_thunk |
DeleteFileA dd rva DeleteFileA_thunk |
DeviceIoControl dd rva DeviceIoControl_thunk |
MultiByteToWideChar dd rva MultiByteToWideChar_thunk |
FileTimeToSystemTime dd rva FileTimeToSystemTime_thunk |
SystemTimeToFileTime dd rva SystemTimeToFileTime_thunk |
GetFullPathNameA dd rva GetFullPathNameA_thunk |
CompareStringA dd rva CompareStringA_thunk |
GlobalMemoryStatus dd rva GlobalMemoryStatus_thunk |
InitializeCriticalSection dd rva InitializeCriticalSection_thunk |
EnterCriticalSection dd rva EnterCriticalSection_thunk |
LeaveCriticalSection dd rva LeaveCriticalSection_thunk |
CreateDirectoryA dd rva CreateDirectoryA_thunk |
RemoveDirectoryA dd rva RemoveDirectoryA_thunk |
LoadLibraryA dd rva LoadLibraryA_thunk |
FreeLibrary dd rva FreeLibrary_thunk |
dw 0 |
thunk CreateFileA |
thunk CloseHandle |
thunk CreateFileMappingA |
thunk OpenFileMappingA |
thunk MapViewOfFile |
thunk UnmapViewOfFile |
thunk ReadFile |
thunk WriteFile |
thunk GetFileSize |
thunk SetEndOfFile |
thunk VirtualAlloc |
thunk VirtualFree |
thunk VirtualProtect |
thunk VirtualProtectEx |
thunk SetFilePointer |
thunk ExitProcess |
thunk ExitThread |
thunk CreateProcessA |
thunk CreateThread |
thunk TerminateThread |
thunk GetCurrentProcess |
thunk GetCommandLineA |
thunk ReadProcessMemory |
thunk WriteProcessMemory |
thunk WaitForDebugEvent |
thunk ContinueDebugEvent |
thunk SuspendThread |
thunk ResumeThread |
thunk GetThreadContext |
thunk SetThreadContext |
thunk GetProcessHeap |
thunk HeapAlloc |
thunk HeapReAlloc |
thunk HeapFree |
thunk Sleep |
thunk GetLocalTime |
thunk SetFileTime |
thunk GetCurrentDirectoryA |
thunk SetCurrentDirectoryA |
thunk GetTickCount |
thunk GetPrivateProfileStringA |
thunk GetPrivateProfileIntA |
thunk lstrcpyA |
thunk lstrcpynA |
thunk lstrcatA |
thunk lstrlenA |
thunk lstrcmpA |
thunk GetFileAttributesA |
thunk SetFileAttributesA |
thunk GetModuleFileNameA |
thunk GetLastError |
thunk CreateMutexA |
thunk CreateEventA |
thunk SetEvent |
thunk DuplicateHandle |
thunk WaitForSingleObject |
thunk ReleaseMutex |
thunk GetVersion |
thunk GetModuleHandleA |
thunk GetProcAddress |
thunk GetCurrentThreadId |
thunk GetStartupInfoA |
thunk FindFirstFileA |
thunk FindNextFileA |
thunk FindClose |
thunk CharToOemA |
thunk OemToCharA |
thunk FileTimeToDosDateTime |
thunk DeleteFileA |
thunk DeviceIoControl |
thunk MultiByteToWideChar |
thunk FileTimeToSystemTime |
thunk SystemTimeToFileTime |
thunk GetFullPathNameA |
thunk CompareStringA |
thunk GlobalMemoryStatus |
thunk InitializeCriticalSection |
thunk EnterCriticalSection |
thunk LeaveCriticalSection |
thunk CreateDirectoryA |
thunk RemoveDirectoryA |
thunk LoadLibraryA |
thunk FreeLibrary |
aNtSetLdtEntries db 'NtSetLdtEntries',0 |
if ~driver_via_scm |
aNtLoadDriver db 'NtLoadDriver',0 |
aNtUnloadDriver db 'NtUnloadDriver',0 |
end if |
align 4 |
advapi32_thunks: |
if ~driver_via_scm |
RegCreateKeyExA dd rva RegCreateKeyExA_thunk |
RegDeleteKeyA dd rva RegDeleteKeyA_thunk |
end if |
RegOpenKeyExA dd rva RegOpenKeyExA_thunk |
RegCloseKey dd rva RegCloseKey_thunk |
RegQueryValueExA dd rva RegQueryValueExA_thunk |
RegSetValueExA dd rva RegSetValueExA_thunk |
OpenSCManagerA dd rva OpenSCManagerA_thunk |
CreateServiceA dd rva CreateServiceA_thunk |
OpenServiceA dd rva OpenServiceA_thunk |
StartServiceA dd rva StartServiceA_thunk |
ControlService dd rva ControlService_thunk |
DeleteService dd rva DeleteService_thunk |
CloseServiceHandle dd rva CloseServiceHandle_thunk |
dw 0 |
if ~driver_via_scm |
thunk RegCreateKeyExA |
thunk RegDeleteKeyA |
end if |
thunk RegOpenKeyExA |
thunk RegCloseKey |
thunk RegQueryValueExA |
thunk RegSetValueExA |
thunk OpenSCManagerA |
thunk CreateServiceA |
thunk OpenServiceA |
thunk StartServiceA |
thunk ControlService |
thunk DeleteService |
thunk CloseServiceHandle |
;winmm_thunks: |
;PlaySoundA dd rva PlaySoundA_thunk |
; dw 0 |
;thunk PlaySoundA |
end data |
|
aGetOpenFileNameA db 'GetOpenFileNameA',0 |
aPlaySoundA db 'PlaySoundA',0 |
|
align 4 |
;data resource from 'klbrico.res' |
;end data |
data resource |
rsrcdata: |
; only icon resource from file 'KlbrInWin.ico' |
; for graphics thanks to goglus, Leency, Heavyiron |
iconfile equ 'KlbrInWin.ico' |
|
virtual at 0 |
; load .ico header |
file iconfile:0,6 |
load .idReserved word from 0 |
load .idType word from 2 |
load .idCount word from 4 |
if (.idReserved <> 0) | (.idType <> 1) |
error invalid icon file |
end if |
end virtual |
|
; root resource directory |
dd 0, 0, 0 |
dw 0, 2 ; 2 entries by id |
dd 3, (.icon1 - rsrcdata) or 80000000h ; entry 1: RT_ICON |
dd 14, (.gicon1 - rsrcdata) or 80000000h ; entry 2: RT_GROUP_ICON |
; level-1 resource directory for RT_ICON |
.icon1: |
dd 0, 0, 0 |
dw 0, .idCount ; .idCount entries by id |
repeat .idCount |
dd %, ((.icon2 - rsrcdata) + 18h*(%-1)) or 80000000h |
end repeat |
; level-1 resource directory for RT_GROUP_ICON |
.gicon1: |
dd 0, 0, 0 |
dw 0, 1 ; 1 entry by id |
dd 1, (.gicon2 - rsrcdata) or 80000000h |
; level-2 resource directories for RT_ICON |
.icon2: |
repeat .idCount |
dd 0, 0, 0 |
dw 0, 1 ; 1 entry by id |
dd 0, (.icon3 - rsrcdata) + 10h*(%-1) |
end repeat |
; level-2 resource directory for RT_GROUP_ICON |
.gicon2: |
dd 0, 0, 0 |
dw 0, 1 ; 1 entry by id |
dd 0, (.gicon3 - rsrcdata) |
; leaf entries for RT_ICON |
.icon3: |
.a = rva .icons |
repeat .idCount |
virtual at 0 |
file iconfile:6+16*(%-1)+8,4 |
load .dwBytesInRes dword from 0 |
end virtual |
dd .a, .dwBytesInRes, 0, 0 |
.a = (.a + .dwBytesInRes + 3) and not 3 |
end repeat |
; leaf entry for RT_GROUP_ICON |
.gicon3: |
dd rva .gicon, .gicon_end - .gicon, 0, 0 |
; icon data |
.icons: |
repeat .idCount |
virtual at 0 |
file iconfile:6+16*(%-1)+8,8 |
load .dwBytesInRes dword from 0 |
load .dwImageOffset dword from 4 |
end virtual |
file iconfile:.dwImageOffset,.dwBytesInRes |
while .dwBytesInRes and 3 |
.dwBytesInRes = .dwBytesInRes + 1 |
db 0 |
end while |
end repeat |
.gicon: |
dw 0, 1, .idCount ; .idCount images |
repeat .idCount |
file iconfile:6+16*(%-1),12 |
dw % |
end repeat |
.gicon_end: |
end data |
|
data 9 |
dd tls_init_start |
dd tls_init_end |
dd tls_index |
dd 0 |
dd 0 |
dd 0 |
end data |
|
virtual at 0 |
tls: |
._cs dw ? |
._ds dw ? |
._esp dd ? |
._eip dd ? |
._fs dw ? |
dw ? ; align |
.exc_code dd ? |
.exc_data dd ? |
.message_mask dd ? |
.lpShapeData dd ? |
.scale dd ? |
.curdraw db ? |
|
.uninit_size = .size - $ |
|
.showwnd db ? |
.bFirstMouseMove db ? |
.bActive db ? |
.hWnd dd ? |
.hCursor dd ? |
.buttons dd ? |
.x_size dw ? |
.x_start dw ? |
.y_size dw ? |
.y_start dw ? |
.client_left dd ? |
.client_top dd ? |
.client_width dd ? |
.client_height dd ? |
.color_main dd ? |
.color_capt dd ? |
.color_border dd ? |
.caption dd ? |
.debuggees dd ? |
.translated_msg_code db ? |
.usescancode db ? |
.keybuflen db ? |
.butbuflen db ? |
.keybuffer rb 0x100 |
.butbuffer rd 0x100 |
.active_button dd ? |
.cur_slot dd ? |
.saved_fs0 dd ? |
.saved_fs4 dd ? |
.prev_snd_block dd ? |
.cur_dir dd ? |
.scroll dd ? |
.original_buttons db ? |
.current_buttons db ? |
dw ? |
.size = $ |
end virtual |
|
align 4 |
ofn_arg_template: |
dw 1,-1 ; dlgVer,signature |
dd 0 ; helpId |
dd 0 ; exStyle |
dd 56000444h ; style |
dw 2 ; cDlgItems |
dw 0,0,275,28 ; x,y,cx,cy |
dw 0,0,0 ; menu,windowClass,title |
dw 8 ; pointsize |
dd 0 ; weight,italic,charset |
du 'MS Sans Serif',0 |
align 4 |
dd 0 ; helpId |
dd 0 ; exStyle |
dd 50010000h ; style |
dw 5,12,45,9 ; x,y,cx,cy |
dw -1 ; id |
dw 0 |
dw -1,82h ; windowClass |
du "Parameters:",0 |
dw 0 |
align 4 |
dd 0 |
dd 204h |
dd 50010080h |
dw 54,10,218,12 |
dw 23 |
dw 0 |
dw -1,81h |
dw 0 |
dw 0 |
|
align 4 |
_1193180 dd 1193180 |
_100 dd 100 |
|
kontrOctave: |
; note that values 0, D,E,F must not be used, but 0 is used (e.g. by icon2) |
dw 0xC3FB, 0x4742, 0x4342, 0x3F7C, 0x3BEC, 0x388F, 0x3562, 0x3264 |
dw 0x2F8F, 0x2CE4, 0x2A5F, 0x2802, 0x25BF, 0xFDA, 0, 0x19 |
|
dir0: |
db 'HARDDISK ',10h |
db 'RAMDISK ',10h |
dir1 db 'FIRST ',10h |
|
path_begin: |
db 1,2,'RD' |
db 1,7,'RAMDISK' |
db 2,2,'FD' |
db 2,11,'FLOPPYDI.SK' |
db 4,3,'HD0' |
db 5,3,'HD1' |
db 6,3,'HD2' |
db 7,3,'HD3' |
db 3,2,'HD' |
db 3,8,'HARDDISK' |
db 0 |
|
|
; align 4 |
; winsock_imports: |
; WSAStartup dd WSAStartup_name |
; WSACleanup dd WSACleanup_name |
; socket dd socket_name |
; closesocket dd closesocket_name |
; dd 0 |
|
; WSAStartup_name db 'WSAStartup',0 |
; WSACleanup_name db 'WSACleanup',0 |
; socket_name db 'socket',0 |
; closesocket_name db 'closesocket',0 |
|
ofn_title db 'Select KolibriOS executable',0 |
dd -10 |
fileopenerr db 'Cannot open input file',0 |
dd -31 |
filereaderr db 'Input file read error',0 |
dd -31 |
notexe db 'Not KolibriOS executable!',0 |
dd -7 |
params_err db 'Parameters pointer is outside used memory!',0 |
dd -30 |
memerr db 'Not enough memory',0 |
dd -30 |
ldterr db 'Cannot allocate LDT selectors',0 |
idt_err db 'IDT limit too small',0 |
exceptionstr db 'Exception',0 |
excstr db 'Emulated process has caused an exception and will be terminated.',13,10 |
db 'Registers:',13,10 |
db 'EAX=%08X EBX=%08X ECX=%08X EDX=%08X',13,10 |
db 'ESI=%08X EDI=%08X ESP=%08X EBP=%08X',13,10 |
db 'EIP=%08X EFLAGS=%08X',0 |
nsm db 'Unsupported system function',0 |
notsupportedmsg db 'Emulated process has called unknown system function and will be terminated.',13,10 |
db 'Registers:',13,10 |
db 'EAX=%08X EBX=%08X ECX=%08X EDX=%08X',13,10 |
db 'ESI=%08X EDI=%08X ESP=%08X EBP=%08X',13,10 |
db 'EIP=%08X EFLAGS=%08X',0 |
cpe db 'Cannot create process',0 |
aConfirm db 'Ïîäòâåðæäåíèå',0 |
BgrQuestionText db 'Ïðîãðàììà õî÷åò óñòàíîâèòü ôîí ðàáî÷åãî ñòîëà.',13,10 |
db 'Óñòàíîâèòü êàê ïîñòîÿííûé?',0 |
BgrFileErrorMsg db 'Cannot create background image file',0 |
dd -1 |
skinfileerr db 'Invalid skin file',0 |
vkerr db 'A running instance of KlbrInWin already exists, cannot continue',0 |
dd -1 |
no_partition db 'Partition is not defined',0 |
EnablePortsSyntaxErr db 'EnablePorts parameter: syntax error',0 |
DrvLoadErr db 'Cannot load driver',0 |
DrvOpenErr db 'Cannot send command to driver',0 |
PortsRangeErr db 'Sysfunction 46: invalid ports range',0 |
PortsNotEnabledErr db 'Sysfunction 46: attempt to allocate not enabled ports',0 |
PortsUsedErr db 'Sysfunction 46: attempt to allocate already used ports',0 |
PortsNotUsedErr db 'Sysfunction 46: attempt to free ports which were not allocated',0 |
|
;aPathInvalid db 'Path pointer is outside used memory and will be ignored',0 |
dd -2 |
aPathUnknown db 'Win32 path to program cannot be written as Kolibri path!',0 |
|
aReadMSRDisabled db 'Emulated process tries to read MSR, and this is disabled in ini-file.',0 |
aNoMsr db 'Emulated process has tried to read invalid MSR and will be terminated',0 |
aInvFn64Call db 'Function 64 has been called after heap initialization, will fail.',0 |
aHeapNotInited db 'Attempt to work with uninitialized heap!',0 |
aInternalError db 'Internal error',0 |
aMallocFailed db 'Memory request failed!',0 |
aFreeInvalid db 'Attempt to free/realloc not allocated block!',0 |
aCannotLoadDll db 'Cannot load DLL',0 |
aUnknownReloc db 'Unknown relocation type',0 |
aExportsNotFound db 'DLL export table was not found!',0 |
aInvCursorData db 'Invalid cursor data',0 |
aOnlyOneCursor db 'Cursor data must contain only one cursor',0 |
aInvCursorDim db 'Cursor must be of size 32*32 pixels',0 |
aCursorFailed db 'Cursor creation failed',0 |
aCursorLimitExceeded db 'Cursors limit exceeded',0 |
aInvalidCursor db 'Invalid handle for delete_cursor!',0 |
aSound db 'SOUND',0 |
aInfinity db 'INFINITY',0 |
aUnknownDriver db 'Attempt to load unknown driver will fail',0 |
aCannotGetPci db 'Cannot get PCI BIOS parameters',0 |
;aPciDisabled db 'Emulated process tries to enable PCI access, and this is disabled in ini-file.',0 |
dd -1 |
aInvalidColorDepth db 'Invalid ColorDepth parameter in ini-file',0 |
DSAErr db 'Access to DirectScreenArea outside real screen data causes an exception...',0 |
DSADisabled db 'The program has called sysfunction 61 (Direct Screen Access parameters),',10 |
db 'but Direct Screen Access is disabled in ini-file. The program will be terminated :(',0 |
aFailedToDeliverDebugMessage db 'Failed to deliver debug message',0 |
aInvalidDataForDR db 'Invalid data for 69.9, returning an error',0 |
aCannotDestroyShMem db 'Attempt to close not opened shared memory area',0 |
;aWinsockInitErr db 'Cannot initialize Winsock DLL!',0 |
;aSocketErr db 'Cannot allocate socket!',0 |
|
inifilename db 'KlbrInWin.ini' |
null_string db 0 |
inifilenamesize = $ - inifilename |
kiw0filename db 'kiw0.sys',0 |
kiw0filenamesize = $ - kiw0filename |
kiw0_username db 'KlbrInWin ring-0 component',0 |
kiw0_drivername db 'kiw0',0 |
kiw0 db '\\.\kiw0',0 |
if ~driver_via_scm |
DrvKey db 'SYSTEM\CurrentControlSet\Services\kiw0',0 |
DrvKeyEnum db 'SYSTEM\CurrentControlSet\Services\kiw0\Enum',0 |
align 4 |
DrvKeySys: |
dw DrvKeySysLen-2, DrvKeySysLen |
dd @f |
@@ du '\REGISTRY\MACHINE\SYSTEM\CurrentControlSet\Services\kiw0',0 |
DrvKeySysLen = $ - @b |
aDisplayName db 'DisplayName',0 |
aType db 'Type',0 |
aStart db 'Start',0 |
addr3 dd 3 ; SERVICE_DEMAND_START |
aErrorControl db 'ErrorControl',0 |
aImagePath db 'ImagePath',0 |
|
umpnpmgr_name db 'umpnpmgr.dll',0 |
umpnpmgr_uninst db 'DeleteServicePlugPlayRegKeys',0 |
kiw0_unicode du 'kiw0',0 |
end if |
|
default_ramdisk db 'A:\',0 |
ramdisk_keyname db 'RamDisk',0 |
aDisk db 'Disk',0 |
aMain db 'Main',0 |
aFont1 db 'Font1',0 |
aFont2 db 'Font2',0 |
aSkin db 'Skin',0 |
aQuestions db 'Questions',0 |
aSetBgr db 'SetBgr',0 |
aSetup db 'sys_setup',0 |
aSoundFlag db 'sound_flag',0 |
aSoundVol db 'sound_vol',0 |
aSysLang db 'syslang',0 |
aKeyboard db 'keyboard',0 |
aEnablePorts db 'EnablePorts',0 |
aAllowReadMSR db 'AllowReadMSR',0 |
aAllowReadPCI db 'AllowReadPCI',0 |
aKeepLoadedDriver db 'KeepLoadedDriver',0 |
aDirectScreenAccess db 'DirectScreenAccess',0 |
aColorDepth db 'ColorDepth',0 |
aInvalidateTime db 'DSAInvalidateTime',0 |
|
classname db 'KolibriInWin_WndClass',0 |
dd -30 |
createwnderr db 'Cannot create window!',0 |
|
dd -30 |
shared_section_size = 8000h |
shared_section_create_err db 'Cannot create section for shared data!',0 |
shared_mutex_create_err db 'Cannot create mutex for shared data!',0 |
virtual at 0 |
shared_data_struc: |
.alloc_threads dd ? |
.num_threads dd ? |
.vk db ? |
.bAllowReadMSR db ? |
.b9xPerfInited db ? |
if idletime_via_ring0 |
.idlecount dd ? |
end if |
; \begin{sys_setup} |
.sound_flag db ? |
.syslang dd ? |
.midi_base dw ? |
.cd_base db ? |
.hd_base db ? |
.sb16 dd ? |
.wss dd ? |
.fat32part dd ? |
.sound_dma dd ? |
.lba_read_enabled dd ? |
.pci_access_enabled dd ? |
.keyboard dw ? |
.mouse_speed_factor dw ? |
.mouse_delay dd ? |
; \end{sys_setup} |
.pci_data_init db ? ; initialized? |
.bAllowReadPCI db ? |
.curport dw ? |
.cursocket dd ? |
.pci_bios_mj db ? ; major PCI BIOS version |
.pci_bios_mn db ? ; minor PCI BIOS version |
.pci_bios_lb db ? ; last PCI bus |
.pci_bios_pc db ? ; PCI characteristics |
.workarea_left dd ? |
.workarea_top dd ? |
.workarea_right dd ? |
.workarea_bottom dd ? |
.dwNewBgrTime dd ? |
.msg_board_count dd ? |
.msg_board_data rb 512 |
.active_process dd ? |
.cpuspeed dd ? |
.DisabledPorts rb 2000h |
.UsedIoMap rb 2000h |
num_cursors = 63 ; exclude standard arrow cursor, it is handled separately |
.cursors rd num_cursors*2 |
.threads: |
; rept .alloc_threads |
.thread_id dd ? ; 0 for free slot |
.thread_ipc_mem dd ? |
.thread_ipc_size dd ? |
.win32_hBaseProcess dd ? ; this is handle for debugger! |
.win32_dwThreadId dd ? |
.hWnd dd ? |
.limit dd ? |
.name rb 12 |
.win32_hThread dd ? ; this is handle for debugger! |
.debugger_mem dd ? |
.win32_stack dd ? |
.shmem_list dd ? ; head of L1-list of shmem_proc_descr |
rd 2 |
end virtual |
|
bgr_section_name db 'KolibriInWin_background',0 |
bgr_section_size = 0x160000+0x10 |
bgr_mutex_name db 'KolibriInWin_bgrmtx',0 |
bgrkeyname db 'Control Panel\Desktop',0 |
bgrstylevalue db 'WallpaperStyle',0 |
bgrtilevalue db 'TileWallpaper',0 |
bgrtempfilename db 'klbrbgr.bmp',0 |
bgrfilename db 'klbr_bgr.bmp',0 |
|
newprg_section_name db 'KolibriInWin_newprg',0 |
|
keycpu db 'HARDWARE\DESCRIPTION\System\CentralProcessor\0',0 |
keymhz db '~MHz',0 |
|
aIdentifier db 'Identifier',0 |
aConfigurationData db 'Configuration Data',0 |
|
perfstart db 'PerfStats\StartStat',0 |
perfget db 'PerfStats\StatData',0 |
perfend db 'PerfStats\StopStat',0 |
perfval db 'KERNEL\CPUUsage',0 |
aPerfInitFailed db 'Failed to init performance counter',0 |
|
exccode2number: |
dd 0xC0000094 ; EXCEPTION_INT_DIVIDE_BY_ZERO |
db 0 ; #DE |
; dd 0x80000004 ; EXCEPTION_SINGLE_STEP (handled separately) |
; db 1 ; #DB |
dd 0x80000003 ; EXCEPTION_BREAKPOINT |
db 0xD ; #GP (yes, in Kolibri it's #GP, not #BP) |
dd 0xC0000095 ; EXCEPTION_INT_OVERFLOW |
db 4 ; #OF |
dd 0xC000008C ; EXCEPTION_ARRAY_BOUNDS_EXCEEDED |
db 5 ; #BR |
dd 0xC000001D ; EXCEPTION_ILLEGAL_INSTRUCTION |
db 6 ; #UD |
dd 0xC0000096 ; EXCEPTION_PRIV_INSTRUCTION |
db 0xD ; #GP |
dd 0xC0000005 ; EXCEPTION_ACCESS_VIOLATION |
db 0xE ; #PF |
dd 0x80000002 ; EXCEPTION_DATATYPE_MISALIGNMENT |
db 0x11 ; #AC |
dd 0xC000008D ; EXCEPTION_FLT_DENORMAL_OPERAND |
db 0x10 ; #MF |
dd 0xC000008E ; EXCEPTION_FLT_DIVIDE_BY_ZERO |
db 0x10 ; #MF |
dd 0xC000008F ; EXCEPTION_FLT_INEXACT_RESULT |
db 0x10 ; #MF |
dd 0xC0000090 ; EXCEPTION_FLT_INVALID_OPERATION |
db 0x10 ; #MF |
dd 0xC0000091 ; EXCEPTION_FLT_OVERFLOW |
db 0x10 ; #MF |
dd 0xC0000092 ; EXCEPTION_FLT_STACK_CHECK |
db 0x10 ; #MF |
dd 0xC0000093 ; EXCEPTION_FLT_UNDERFLOW |
db 0x10 ; #MF |
dd 0 |
|
section '.data' data readable writable |
|
user32_thunks: |
MessageBoxA dd rva MessageBoxA_thunk |
wsprintfA dd rva wsprintfA_thunk |
GetDC dd rva GetDC_thunk |
ReleaseDC dd rva ReleaseDC_thunk |
LoadIconA dd rva LoadIconA_thunk |
LoadCursorA dd rva LoadCursorA_thunk |
LoadImageA dd rva LoadImageA_thunk |
RegisterClassExA dd rva RegisterClassExA_thunk |
CreateWindowExA dd rva CreateWindowExA_thunk |
MoveWindow dd rva MoveWindow_thunk |
ShowWindow dd rva ShowWindow_thunk |
DefWindowProcA dd rva DefWindowProcA_thunk |
BeginPaint dd rva BeginPaint_thunk |
EndPaint dd rva EndPaint_thunk |
GetMessageA dd rva GetMessageA_thunk |
PeekMessageA dd rva PeekMessageA_thunk |
TranslateMessage dd rva TranslateMessage_thunk |
DispatchMessageA dd rva DispatchMessageA_thunk |
FillRect dd rva FillRect_thunk |
PostQuitMessage dd rva PostQuitMessage_thunk |
GetDesktopWindow dd rva GetDesktopWindow_thunk |
GetAsyncKeyState dd rva GetAsyncKeyState_thunk |
GetKeyboardState dd rva GetKeyboardState_thunk |
SetCapture dd rva SetCapture_thunk |
ReleaseCapture dd rva ReleaseCapture_thunk |
GetCursorPos dd rva GetCursorPos_thunk |
SetCursorPos dd rva SetCursorPos_thunk |
InvalidateRect dd rva InvalidateRect_thunk |
ValidateRect dd rva ValidateRect_thunk |
SetWindowRgn dd rva SetWindowRgn_thunk |
EnumThreadWindows dd rva EnumThreadWindows_thunk |
PostMessageA dd rva PostMessageA_thunk |
SendMessageTimeoutA dd rva SendMessageTimeoutA_thunk |
GetDlgItemTextA dd rva GetDlgItemTextA_thunk |
PaintDesktop dd rva PaintDesktop_thunk |
SystemParametersInfoA dd rva SystemParametersInfoA_thunk |
GetWindowRect dd rva GetWindowRect_thunk |
GetWindowPlacement dd rva GetWindowPlacement_thunk |
;BringWindowToTop dd rva BringWindowToTop_thunk |
PostThreadMessageA dd rva PostThreadMessageA_thunk |
CharToOemA dd rva CharToOemA_thunk |
OemToCharA dd rva OemToCharA_thunk |
IsWindowVisible dd rva IsWindowVisible_thunk |
CreateIconFromResourceEx dd rva CreateIconFromResourceEx_thunk |
CreateIconIndirect dd rva CreateIconIndirect_thunk |
SetCursor dd rva SetCursor_thunk |
DestroyCursor dd rva DestroyCursor_thunk |
SetForegroundWindow dd rva SetForegroundWindow_thunk |
dw 0 |
thunk MessageBoxA |
thunk wsprintfA |
thunk GetDC |
thunk ReleaseDC |
thunk CreateCompatibleDC |
thunk LoadIconA |
thunk LoadCursorA |
thunk LoadImageA |
thunk RegisterClassExA |
thunk CreateWindowExA |
thunk MoveWindow |
thunk ShowWindow |
thunk DefWindowProcA |
thunk BeginPaint |
thunk EndPaint |
thunk GetMessageA |
thunk PeekMessageA |
thunk TranslateMessage |
thunk DispatchMessageA |
thunk PostQuitMessage |
thunk GetDesktopWindow |
thunk GetPixel |
thunk SetPixel |
thunk GetAsyncKeyState |
thunk GetKeyboardState |
thunk SetCapture |
thunk ReleaseCapture |
thunk GetCursorPos |
thunk SetCursorPos |
thunk InvalidateRect |
thunk ValidateRect |
thunk SetWindowRgn |
thunk PostMessageA |
thunk SendMessageTimeoutA |
thunk EnumThreadWindows |
thunk GetDlgItemTextA |
thunk PaintDesktop |
thunk SystemParametersInfoA |
thunk GetWindowRect |
thunk GetWindowPlacement |
;thunk BringWindowToTop |
thunk PostThreadMessageA |
thunk IsWindowVisible |
thunk CreateIconFromResourceEx |
thunk CreateIconIndirect |
thunk SetCursor |
thunk DestroyCursor |
thunk SetForegroundWindow |
gdi32_thunks: |
SetDIBitsToDevice dd rva SetDIBitsToDevice_thunk |
GetDIBits dd rva GetDIBits_thunk |
CreatePen dd rva CreatePen_thunk |
SelectObject dd rva SelectObject_thunk |
DeleteObject dd rva DeleteObject_thunk |
CreateSolidBrush dd rva CreateSolidBrush_thunk |
CreateBitmap dd rva CreateBitmap_thunk |
CreateCompatibleDC dd rva CreateCompatibleDC_thunk |
CreateCompatibleBitmap dd rva CreateCompatibleBitmap_thunk |
BitBlt dd rva BitBlt_thunk |
MoveToEx dd rva MoveToEx_thunk |
LineTo dd rva LineTo_thunk |
GetDeviceCaps dd rva GetDeviceCaps_thunk |
GetPixel dd rva GetPixel_thunk |
SetPixel dd rva SetPixel_thunk |
SetROP2 dd rva SetROP2_thunk |
Polyline dd rva Polyline_thunk |
ExtCreateRegion dd rva ExtCreateRegion_thunk |
DeleteDC dd rva DeleteDC_thunk |
dw 0 |
thunk SetDIBitsToDevice |
thunk GetDIBits |
thunk CreatePen |
thunk SelectObject |
thunk DeleteObject |
thunk CreateSolidBrush |
thunk FillRect |
thunk BitBlt |
thunk CreateBitmap |
thunk CreateCompatibleBitmap |
thunk MoveToEx |
thunk LineTo |
thunk GetDeviceCaps |
thunk SetROP2 |
thunk Polyline |
thunk ExtCreateRegion |
thunk DeleteDC |
;comdlg32_thunks: |
;GetOpenFileNameA dd rva GetOpenFileNameA_thunk |
; dw 0 |
;thunk GetOpenFileNameA |
|
align 4 |
ofn: |
dd 76 ; lStructSize |
dd 0 ; hWndOwner |
dd ofn_arg_template ; hInstance |
dd 0 ; lpstrFilter |
dd 0 ; lpstrCustomFilter |
dd 0 ; nMaxCustFilter |
dd 0 ; nFilterIndex |
dd inname ; lpstrFile |
dd 100h ; nMaxFile |
dd 0 ; lpstrFileTitle |
dd 0 ; nMaxFileTitle |
dd 0 ; lpstrInitialDir |
dd ofn_title ; lpstrTitle |
dd 818A4h ; flags |
dw 0 ; nFileOffset |
dw 0 ; nFileExtension |
dd 0 ; lpstrDefExt |
dd 0 ; lCustData |
dd ofn_hook ; lpfnHook |
dd 0 ; lpTemplateName |
|
align 4 |
PlaySoundA dd PlaySoundA_delayed_imp |
|
NumThreads dd 1 |
|
virtual at 0 |
shmem_item: |
.name rb 32 |
.next dd ? |
.prev dd ? |
.refs dd ? |
.ptr dd ? |
.size dd ? |
.access dd ? |
.hOwner dd ? |
.pOwner dd ? |
.sizeof = $ |
end virtual |
|
virtual at 0 |
shmem_proc_descr: |
.next dd ? |
.item dd ? |
.ptr dd ? |
.end dd ? |
.access dd ? |
.sizeof = $ |
end virtual |
|
shmem_list dd shmem_list - shmem_item.next |
dd shmem_list - shmem_item.next |
|
DrvKeyValues: |
dd aDisplayName, 1, kiw0_username, kiw0_drivername-kiw0_username-1 |
dd aType, 4, DrvKeyValues+4, 4 |
dd aStart, 4, addr3, 4 |
dd aErrorControl, 4, DrvKeyValues+4, 4 |
dd aImagePath, 1, win32_path, ? |
drvpathlen = $-4 |
dd 0 |
|
keymfa db 'HARDWARE\DESCRIPTION\System\MultifunctionAdapter\' |
idxmfa db '0' |
db 0 |
|
hdxn db 'hd0n',0 |
hdpart db 'hd0_%d',0 |
hdxy_str db '/hd%d/%d/',0 |
|
bInitialized db 0 |
bCaptured db 0 |
|
label jmp_klbr fword |
jmp_klbr_eip dd 0 |
klbr_cs dw 0Fh |
klbr_ds dw 17h |
klbr_null dw 0 |
label jmp_temp_int33 fword |
dd 0 |
temp_cs dw 0 |
label jmp_temp_int1A fword |
dd temp_code_int1A - temp_code |
temp_cs2 dw 0 |
|
eee db 'exception in debuggee at ' |
eeeeip db '00000000' |
db 0 |
|
; data for int40 emulating code - initialized |
; from kernel.asm |
keymap: |
db '6',27,'1234567890-=',8,9 ; 0x00 |
db 'qwertyuiop[]',13,'~as' ; 0x10 |
db 'dfghjkl;',39,96,0,'\zxcv' ; 0x20 |
db 'bnm,./',0,'45 @23456' ; 0x30 |
db '7890123',180,178,184,'6',176,'7',179,'8',181 ; 0x40 |
db 177,183,185,182,'AB<D',255,'FGHIJKL' ; 0x50 |
db 'MNOPQRSTUVWXYZAB' ; 0x60 |
db 'CDEFGHIJKLMNOPQR' ; 0x70 |
keymap_shift: |
db '6',27,'!@#$%^&*()_+',8,9 ; 0x00 |
db 'QWERTYUIOP{}',13,'~AS' ; 0x10 |
db 'DFGHJKL:"~',0,'|ZXCV' ; 0x20 |
db 'BNM<>?',0,'45 @23456' ; 0x30 |
db '7890123',180,178,184,'6',176,'7',179,'8',181 ; 0x40 |
db 177,183,185,182,'AB>D',255,'FGHIJKL' ; 0x50 |
db 'MNOPQRSTUVWXYZAB' ; 0x60 |
db 'CDEFGHIJKLMNOPQR' ; 0x70 |
keymap_alt: |
db ' ',27,' @ $ {[]}\ ',8,9 ; 0x00 |
db ' ',13,' ' ; 0x10 |
db ' ',0,' ' ; 0x20 |
db ' ',0,'4',0,' ' ; 0x30 |
db ' ',180,178,184,'6',176,'7',179,'8',181 ; 0x40 |
db 177,183,185,182,'ABCD',255,'FGHIJKL' ; 0x50 |
db 'MNOPQRSTUVWXYZAB' ; 0x60 |
db 'CDEFGHIJKLMNOPQR' ; 0x70 |
|
numlock_map db '789-456+1230.' |
|
version_inf: |
db 0,7,1,0 ; emulate Kolibri 0.7.1.0 |
db 3 ; UID_KlbrInWin |
dd 945 ; emulate revision 945 |
; (last change: functions 68.22 and 68.23) |
version_end: |
|
bCommonColorsSet db 0 |
|
bHaveDSA db 0 |
|
vk db 0 |
|
tls_index dd -1 |
|
max_pid dd 1 |
num_kolibri_proc dd 0 |
|
window_topleft: |
dd 1, 21 ; type 1 |
dd 0, 0 ; no drawn window |
dd 5, 20 ; type 2 |
dd 5, ? ; skinned |
dd 5, ? ; skinned fixed-size |
|
buttontype db 1 |
|
bgr_bmp_header: |
db 'B','M' |
dd ? ; size |
dd 0 |
dd 36h |
dd 28h |
dd ? ; width |
dd ? ; height |
dw 1 |
dw 24 |
dd 0 |
dd ? ; size |
dd 0,0 |
dd 0,0 |
|
wave_block_begin: |
db 'RIFF' |
dd ? |
db 'WAVEfmt ' |
dd 10h |
dw 1,1 |
wave_r dd 22050 |
dd 22050 |
dw 1,8 |
db 'data' |
; dd ? |
wbb_size = $ - wave_block_begin |
|
; note that all uninitialized variables are set to 0 by Windows |
sinfo dd 44h |
rb 28h |
dd 80h |
rb 14h |
|
tls_init_start: |
times 24 db 0 |
dd 7 ; message_mask |
dd 0 ; lpShapeData |
dd 1 ; scale |
db 1 ; curdraw |
times tls.uninit_size db ? |
tls_init_end: |
|
bDontDebug db ? |
keep_loaded_driver db ? |
|
align 4 |
bgr_section dd ? |
hBgrMutex dd ? |
;dwNewBgrTime dd ? |
|
SetBgrQuestion dd ? |
|
newprg_section dd ? |
|
hArrow dd ? |
|
bIs9x db ? |
bDriverLoaded db ? |
heap_status db ? |
|
align 4 |
inname rb 256 |
header rd 9 |
base dd ? |
limit dd ? |
fn9limit dd ? |
heap_start dd ? |
heap_control_block dd ? |
heap_region_size dd ? |
heap_critical_sec rb 0x18 |
DSACritSect rb 0x18 |
selector_data rb 8 |
selector_code rb 8 |
NtSetLdtEntries dd ? |
idtr dp ? |
pinfo: |
hProcess dd ? |
hThread dd ? |
dwProcessId dd ? |
dwThreadId dd ? |
cur_slot dd ? |
cur_tid_ptr dd ? |
parent_tid_ptr dd ? |
|
debugevent rd 18h |
tids dd ? |
pids dd ? |
|
_cs dw ? |
_ds dw ? |
_esp dd ? |
_eip dd ? |
_fs dw ? |
_gs dw ? |
exc_code dd ? |
exc_data dd ? |
klbr_esp dd ? |
|
temp_ss dw ? |
temp_stack_size = 0x1000 |
temp_stack rb temp_stack_size |
|
parameters dd ? |
|
startcurdir rb 261 |
|
sound_vol db ? |
|
align 4 |
context rd 0xB3 |
|
; data for int40 emulating code - uninitialized |
hHeap dd ? |
|
hSharedData dd ? |
hSharedMutex dd ? |
shared_data dd ? |
|
_skinh dd ? |
margins rw 4 ; right:left:bottom:top |
skin_active_inner dd ? |
skin_active_outer dd ? |
skin_active_frame dd ? |
skin_passive_inner dd ? |
skin_passive_outer dd ? |
skin_passive_frame dd ? |
|
common_colors rb 128 |
|
left_bmp dd ? |
oper_bmp dd ? |
base_bmp dd ? |
left1_bmp dd ? |
oper1_bmp dd ? |
base1_bmp dd ? |
|
skin_btn_close: |
.left dd ? |
.top dd ? |
.width dd ? |
.height dd ? |
skin_btn_minimize: |
.left dd ? |
.top dd ? |
.width dd ? |
.height dd ? |
|
char_mt dd ? |
char2_mt dd ? |
|
process_name dd ? |
|
ramdisk_path rb 512 |
converted_path rb 512 |
win32_path rb 512 |
|
hd_partitions_num rd 4 |
hd_partitions_array rd 4 |
|
cmdline rb 2000 |
process_curdir rb 4096 ; protected by the same mutex as for shared data |
|
if driver_via_scm |
hSCManager dd ? |
hService dd ? |
end if |
|
ColorDepth dd ? |
InvalidateTime dd ? |
DSA dd ? |
|
;WinSockDLL dd ? |
|
align 4 |
unpack.p rd unpack.LZMA_BASE_SIZE + (unpack.LZMA_LIT_SIZE shl (unpack.lc+unpack.lp)) |
unpack.code_ dd ? |
unpack.range dd ? |
unpack.rep0 dd ? |
unpack.rep1 dd ? |
unpack.rep2 dd ? |
unpack.rep3 dd ? |
unpack.previousByte db ? |