; 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,