Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. ; Cb-n#%li.-# @l$i Lkbnbe
  2. format PE GUI 4.0 at 400000h
  3. section '.text' code readable executable
  4. entry start
  5. i40_nt:
  6.         jmp     i40_9x
  7. start:
  8.         xor     ebx, ebx
  9.         call    [GetVersion]
  10.         shr     eax, 31
  11.         mov     [bIs9x], al
  12. ; get default heap
  13.         call    [GetProcessHeap]
  14.         mov     [hHeap], eax
  15.         push    261
  16.         push    startcurdir
  17.         push    ebx
  18.         call    [GetModuleFileNameA]
  19.         xchg    ecx, eax
  20.         inc     ecx
  21.         inc     ecx
  22.         lea     edi, [ecx+startcurdir-1]
  23.         mov     al, '\'
  24.         std
  25.         repnz   scasb
  26.         cld
  27.         mov     byte [edi+2], bl
  28.         mov     esi, startcurdir
  29.         mov     edi, esi
  30.         xor     ecx, ecx
  31.         dec     ecx
  32.         mov     al, 0
  33.         repnz   scasb
  34.         not     ecx
  35.         dec     ecx
  36.         mov     edi, win32_path
  37.         push    edi
  38.         rep     movsb
  39.         mov     al, '\'
  40.         cmp     byte [edi-1], al
  41.         jz      @f
  42.         stosb
  43. @@:     mov     esi, inifilename
  44.         mov     ecx, inifilenamesize
  45.         rep     movsb
  46. ; parse command line
  47.         call    [GetCommandLineA]
  48.         xchg    eax, esi
  49.         mov     edi, inname
  50.         call    getfilename
  51.         mov     edi, inname
  52.         call    getfilename
  53.         jc      no_file_given
  54.         cmp     byte [esi], bl
  55.         jz      file_known
  56.         mov     [parameters], esi
  57.         jmp     file_known
  58. no_file_given:
  59.         mov     [inname], bl
  60.         push    comdlg32_name
  61.         call    [LoadLibraryA]
  62.         test    eax, eax
  63.         jz      @f
  64.         push    eax
  65.         push    aGetOpenFileNameA
  66.         push    eax
  67.         call    [GetProcAddress]
  68.         test    eax, eax
  69.         jz      @f
  70.         push    ofn
  71.         call    eax
  72.         test    eax, eax
  73.         jz      @f
  74.         call    [FreeLibrary]
  75.         jmp     file_known
  76. @@:
  77.         push    ebx
  78.         call    [ExitProcess]
  79. file_known:
  80. ; TLS data
  81.         mov     eax, [tls_index]
  82.         mov     ecx, [fs:2Ch]
  83.         mov     ebp, [ecx+eax*4]
  84. ; save registers
  85.         mov     [ebp+tls._cs], cs
  86.         mov     [ebp+tls._ds], ds
  87.         mov     [ebp+tls._fs], fs
  88.         mov     [ebp+tls._esp], esp
  89.         mov     [ebp+tls._eip], exception
  90.         mov     eax, 1000h
  91.         call    malloc_big
  92.         mov     edi, eax
  93. ; test for server
  94.         push    seh
  95.         push    dword [fs:ebx]
  96.         mov     [fs:ebx], esp
  97.         xor     eax, eax
  98. server_test:
  99.         div     edx
  100.         pop     dword [fs:ebx]
  101.         pop     esi
  102.         test    eax, eax
  103.         jz      server
  104.         mov     [ebp+tls.cur_slot], eax
  105.         mov     [hSharedData], ecx
  106.         mov     [hSharedMutex], edx
  107.         push    edi
  108.         push    user32_thunks
  109.         push    user32_name
  110.         call    init_dll
  111.         push    gdi32_thunks
  112.         push    gdi32_name
  113.         call    init_dll
  114.         pop     edi
  115.         push    edi
  116.         call    [lstrlenA]
  117.         inc     eax
  118.         push    eax
  119.         push    eax
  120.         call    malloc
  121.         pop     ecx
  122.         mov     [ebp+tls.cur_dir], eax
  123.         push    edi
  124.         xchg    eax, edi
  125.         xchg    eax, esi
  126.         rep     movsb
  127.         call    free_big
  128.         call    map_shared_data
  129.         push    bgr_mutex_name
  130.         push    ebx
  131.         push    ebx
  132.         call    [CreateMutexA]
  133.         mov     [hBgrMutex], eax
  134.         push    ebx
  135.         push    ebx
  136.         push    3       ; OPEN_EXISTING
  137.         push    ebx
  138.         push    1       ; FILE_SHARE_READ
  139.         push    80000000h       ; GENERIC_READ
  140.         push    inname
  141.         call    [CreateFileA]
  142.         inc     eax
  143.         jnz     infileopened
  144.         mov     esi, fileopenerr
  145. fail:
  146.         push    10h
  147.         push    ebx
  148. fail2:
  149.         push    esi
  150.         push    ebx
  151.         cmp     [bInitialized], 0
  152.         jnz     @f
  153.         mov     eax, [esi-4]
  154. loadfailed:
  155.         div     edx
  156. @@:
  157.         call    [MessageBoxA]
  158.         call    free_ldt
  159.         push    ebx
  160.         call    [ExitProcess]
  161. infileopened:
  162.         dec     eax
  163.         xchg    eax, edi
  164.         push    eax
  165.         mov     eax, esp
  166.         push    ebx
  167.         push    eax
  168.         push    36
  169.         push    header
  170.         push    edi
  171.         call    [ReadFile]
  172.         test    eax, eax
  173.         pop     eax
  174.         mov     esi, filereaderr
  175.         jz      fail
  176.         cmp     eax, 36
  177.         jnz     fail
  178.         cmp     [header], 'KPCK'
  179.         jnz     .program_not_packed
  180.         mov     eax, [header+4]
  181.         call    malloc_big
  182.         test    eax, eax
  183.         mov     esi, memerr
  184.         jz      fail
  185.         push    eax
  186.         push    eax
  187.         push    ebx
  188.         push    edi
  189.         call    [GetFileSize]
  190.         mov     [limit], eax
  191.         call    malloc_big
  192.         test    eax, eax
  193.         jz      fail
  194.         push    eax
  195.         push    ebx
  196.         push    ebx
  197.         push    ebx
  198.         push    edi
  199.         call    [SetFilePointer]
  200.         push    eax
  201.         mov     eax, esp
  202.         push    ebx
  203.         push    eax
  204.         push    [limit]
  205.         push    dword [esp+16]
  206.         push    edi
  207.         call    [ReadFile]
  208.         test    eax, eax
  209.         pop     eax
  210.         mov     esi, filereaderr
  211.         jz      fail
  212.         cmp     eax, [limit]
  213.         jnz     fail
  214.         pop     esi
  215.         push    esi
  216.         mov     eax, [esi+4]
  217.         mov     [limit], eax
  218.         call    unpack
  219.         push    esi
  220.         call    free_big
  221.         pop     edx
  222.         mov     esi, notexe
  223.         cmp     dword [edx], 'MENU'
  224.         jnz     fail
  225.         cmp     word [edx+4], 'ET'
  226.         jnz     fail
  227.         mov     ax, word [edx+6]
  228.         sub     ax, '00'
  229.         xchg    al, ah
  230.         cmp     ax, 1
  231.         ja      fail
  232.         push    edi
  233.         mov     esi, edx
  234.         mov     edi, header
  235.         mov     ecx, 9
  236.         rep     movsd
  237.         jz      @f
  238.         mov     eax, [edx+18h]
  239.         mov     [header+1Ch], eax
  240.         mov     eax, [edx+14h]
  241.         shr     eax, 1
  242.         sub     eax, 10h
  243.         mov     [header+18h], eax
  244.         mov     [header+20h], ebx
  245. @@:
  246.         push    edx
  247.         push    40h     ; PAGE_EXECUTE_READWRITE
  248.         push    1000h   ; MEM_COMMIT
  249.         push    dword [edx+14h]
  250.         push    ebx
  251.         call    [VirtualAlloc]
  252.         pop     edx
  253.         test    eax, eax
  254.         mov     esi, memerr
  255.         jz      fail
  256.         mov     [base], eax
  257.         mov     edi, eax
  258.         mov     esi, edx
  259.         mov     ecx, [limit]
  260.         mov     eax, ecx
  261.         shr     ecx, 2
  262.         rep     movsd
  263.         mov     ecx, eax
  264.         and     ecx, 3
  265.         rep     movsb
  266.         jmp     .program_packed_common
  267. .program_not_packed:
  268.         mov     esi, notexe
  269.         cmp     [header], 'MENU'
  270.         jnz     fail
  271.         cmp     word [header+4], 'ET'
  272.         jnz     fail
  273.         mov     ax, word [header+6]
  274.         sub     ax, '00'
  275.         xchg    al, ah
  276.         cmp     ax, 1
  277.         ja      fail
  278.         jz      @f
  279.         mov     eax, [header+18h]
  280.         mov     [header+1Ch], eax
  281.         mov     eax, [header+14h]
  282.         shr     eax, 1
  283.         sub     eax, 10h
  284.         mov     [header+18h], eax
  285.         mov     [header+20h], ebx
  286. @@:
  287. ; hmm... Menuet/Kolibri seems to ignore app_i_end field in case of running from ramdisk (fn 19)
  288. ; but depend on app_i_end in case of running from fn 58
  289.  
  290. ; so force read all file
  291.         push    ebx
  292.         push    edi
  293.         call    [GetFileSize]
  294.         mov     [header+10h], eax
  295.         mov     eax, [header+14h]
  296.         cmp     eax, [header+10h]
  297.         jb      fail
  298.         push    40h     ; PAGE_EXECUTE_READWRITE
  299.         push    1000h   ; MEM_COMMIT
  300.         push    eax
  301.         push    ebx
  302.         call    [VirtualAlloc]
  303.         test    eax, eax
  304.         mov     esi, memerr
  305.         jz      fail
  306.         mov     [base], eax
  307.         push    ebx
  308.         push    ebx
  309.         push    ebx
  310.         push    edi
  311.         call    [SetFilePointer]
  312.         push    eax
  313.         mov     eax, esp
  314.         push    ebx
  315.         push    eax
  316.         push    [header+10h]
  317.         push    [base]
  318.         push    edi
  319.         call    [ReadFile]
  320.         test    eax, eax
  321.         pop     eax
  322.         mov     esi, filereaderr
  323.         jz      fail
  324.         push    edi
  325. .program_packed_common:
  326.         call    [CloseHandle]
  327.         mov     esi, [parameters]
  328.         mov     edi, esi
  329.         test    esi, esi
  330.         jz      no_params
  331.         mov     eax, [header+1Ch]
  332.         test    eax, eax
  333.         jz      no_params
  334.         mov     edx, eax
  335.         add     eax, 256
  336.         cmp     eax, [header+14h]
  337.         mov     esi, params_err
  338.         ja      fail
  339.         mov     esi, edi
  340.         mov     ecx, 256
  341.         xor     eax, eax
  342.         repnz   scasb
  343.         neg     cl
  344.         mov     edi, edx
  345.         add     edi, [base]
  346.         rep     movsb
  347. no_params:
  348. ; read ini file client settings
  349. ; disks
  350.         push    512
  351.         push    ramdisk_path
  352.         push    default_ramdisk
  353.         push    ramdisk_keyname
  354.         push    aDisk
  355.         call    [GetPrivateProfileStringA]
  356.         mov     edi, hd_partitions_num
  357. hdloop:
  358.         push    win32_path
  359.         push    ebx
  360.         push    hdxn
  361.         push    aDisk
  362.         call    [GetPrivateProfileIntA]
  363.         stosd
  364.         test    eax, eax
  365.         jz      .cont
  366.         push    eax
  367.         shl     eax, 9          ; *512
  368.         push    eax
  369.         call    malloc
  370.         mov     [edi-4+hd_partitions_array-hd_partitions_num], eax
  371.         pop     ecx
  372.         xchg    esi, eax
  373.         xor     eax, eax
  374.         inc     eax
  375. .partitions:
  376.         push    eax ecx
  377.         push    eax
  378.         push    hdpart
  379.         push    converted_path
  380.         call    [wsprintfA]
  381.         add     esp, 12
  382.         mov     byte [esi+511], 0
  383.         push    win32_path
  384.         push    511
  385.         push    esi
  386.         push    null_string
  387.         push    converted_path
  388.         push    aDisk
  389.         call    [GetPrivateProfileStringA]
  390.         test    eax, eax
  391.         jnz     @f
  392.         push    10h
  393.         push    converted_path
  394.         mov     esi, no_partition
  395.         jmp     fail2
  396. @@:
  397.         push    esi
  398.         call    [lstrlenA]
  399.         cmp     eax, 10
  400.         jbe     @f
  401.         lea     eax, [eax+esi-9]
  402.         cmp     byte [eax], ','
  403.         jnz     @f
  404.         cmp     dword [eax+1], 'read'
  405.         jnz     @f
  406.         cmp     dword [eax+5], 'only'
  407.         jnz     @f
  408.         mov     byte [eax], 0
  409.         mov     byte [esi+511], 1
  410. @@:
  411.         add     esi, 512
  412.         pop     ecx eax
  413.         inc     eax
  414.         dec     ecx
  415.         jnz     .partitions
  416. .cont:
  417.         inc     [hdxn+2]
  418.         inc     [hdpart+2]
  419.         cmp     edi, hd_partitions_num+4*4
  420.         jnz     hdloop
  421.         mov     esi, converted_path
  422. ; read fonts
  423.         push    win32_path
  424.         push    512
  425.         push    esi
  426.         push    null_string
  427.         push    aFont1
  428.         push    aMain
  429.         call    [GetPrivateProfileStringA]
  430.         call    getfilemap
  431.         mov     [char_mt], eax
  432.         push    win32_path
  433.         push    512
  434.         push    esi
  435.         push    null_string
  436.         push    aFont2
  437.         push    aMain
  438.         call    [GetPrivateProfileStringA]
  439.         call    getfilemap
  440.         mov     [char2_mt], eax
  441.         push    win32_path
  442.         push    ebx
  443.         push    aSetBgr
  444.         push    aQuestions
  445.         call    [GetPrivateProfileIntA]
  446.         mov     [SetBgrQuestion], eax
  447. ; read skin
  448.         push    win32_path
  449.         push    512
  450.         push    esi
  451.         push    null_string
  452.         push    aSkin
  453.         push    aMain
  454.         call    [GetPrivateProfileStringA]
  455.         call    getfilemap
  456.         xchg    eax, edi
  457.         cmp     dword [edi], 'KPCK'
  458.         jnz     @f
  459.         mov     eax, [edi+4]
  460.         call    malloc_big
  461.         mov     esi, memerr
  462.         test    eax, eax
  463.         jz      fail
  464.         push    eax
  465.         push    eax
  466.         push    edi
  467.         call    unpack
  468.         push    edi
  469.         call    [UnmapViewOfFile]
  470.         pop     edi
  471.         inc     ebx
  472. @@:
  473.         cmp     dword [edi], 'SKIN'     ; ident
  474.         mov     esi, skinfileerr
  475.         jnz     fail
  476.         cmp     dword [edi+4], 1        ; version
  477.         jnz     fail
  478. ; skin parameters
  479.         mov     esi, edi
  480.         add     esi, [esi+8]            ; parameters offset
  481.         mov     ecx, 9
  482.         push    edi
  483.         mov     edi, _skinh
  484.         rep     movsd
  485.         pop     edi
  486.         mov     ecx, common_colors
  487.         mov     edx, 127
  488.         call    get_wnd_colors
  489.         test    al, al
  490.         jnz     @f
  491.         lodsd
  492.         and     eax, edx
  493.         push    eax
  494.         xchg    eax, ecx
  495.         push    edi
  496.         mov     edi, common_colors
  497.         push    edi
  498.         rep     movsb
  499.         pop     ecx
  500.         pop     edi
  501.         pop     edx
  502.         call    set_wnd_colors
  503. @@:
  504. ; skin bitmaps
  505.         mov     esi, edi
  506.         add     esi, [esi+16]
  507. skinbmploop:
  508.         cmp     dword [esi], 0
  509.         jz      skinbmploopend
  510.         movzx   eax, word [esi]
  511.         movzx   ecx, word [esi+2]
  512.         mov     edx, [esi+4]
  513.         add     esi, 8
  514.         add     edx, edi
  515.         lea     eax, [eax*2+ecx-1]
  516. ; convert bmp data to Win32 DIB
  517.         push    eax edx
  518.         mov     eax, [edx]
  519.         add     eax, 3
  520.         and     al, not 3
  521.         mul     dword [edx+4]
  522.         imul    eax, 3
  523.         add     eax, 40
  524.         push    eax
  525.         push    8       ; HEAP_ZERO_MEMORY
  526.         push    [hHeap]
  527.         call    [HeapAlloc]
  528.         pop     edx
  529.         mov     dword [eax], 40         ; biSize
  530.         mov     ecx, [edx]
  531.         mov     [eax+4], ecx            ; biWidth
  532.         mov     ecx, [edx+4]
  533.         mov     [eax+8], ecx            ; biHeight
  534.         mov     dword [eax+12], 180001h ; biPlanes, biBitCount
  535.         push    esi edi
  536.         lea     edi, [eax+40]
  537.         lea     esi, [edx+8]
  538.         mov     ecx, [edx+4]
  539.         push    eax
  540.         mov     eax, [edx]
  541.         imul    eax, ecx
  542.         add     esi, eax
  543.         add     esi, eax
  544.         add     esi, eax
  545. .x1:
  546.         push    ecx
  547.         mov     ecx, [edx]
  548.         add     ecx, ecx
  549.         add     ecx, [edx]
  550.         sub     esi, ecx
  551.         push    esi
  552.         rep     movsb
  553.         add     edi, 3
  554.         and     edi, not 3
  555.         pop     esi
  556.         pop     ecx
  557.         loop    .x1
  558.         pop     edx
  559.         pop     edi esi
  560.         pop     eax
  561.         dec     eax
  562.         jnz     @f
  563. ; inactive left
  564.         mov     [left1_bmp], edx
  565.         jmp     skinbmploop
  566. @@:
  567.         dec     eax
  568.         jnz     @f
  569. ; active left
  570.         mov     [left_bmp], edx
  571.         jmp     skinbmploop
  572. @@:
  573.         dec     eax
  574.         jnz     @f
  575. ; inactive oper
  576.         mov     [oper1_bmp], edx
  577.         jmp     skinbmploop
  578. @@:
  579.         dec     eax
  580.         jnz     @f
  581. ; active oper
  582.         mov     [oper_bmp], edx
  583.         jmp     skinbmploop
  584. @@:
  585.         dec     eax
  586.         jnz     @f
  587. ; inactive base
  588.         mov     [base1_bmp], edx
  589.         jmp     skinbmploop
  590. @@:
  591.         dec     eax
  592.         jnz     skinbmploop
  593. ; active base
  594.         mov     [base_bmp], edx
  595.         jmp     skinbmploop
  596. skinbmploopend:
  597. ; skin buttons
  598.         mov     esi, edi
  599.         add     esi, [esi+12]
  600. skinbuttonsloop:
  601.         lodsd
  602.         test    eax, eax
  603.         jz      skinbuttonsloopend
  604.         mov     edx, skin_btn_close
  605.         dec     eax
  606.         jz      .button
  607.         mov     edx, skin_btn_minimize
  608.         dec     eax
  609.         jz      .button
  610.         lodsd
  611.         lodsd
  612.         jmp     skinbuttonsloop
  613. .button:
  614.         mov     ecx, 4
  615. @@:
  616.         lodsw
  617.         cwde
  618.         mov     [edx], eax
  619.         add     edx, 4
  620.         loop    @b
  621.         jmp     skinbuttonsloop
  622. skinbuttonsloopend:
  623.         dec     ebx
  624.         jz      .mem
  625.         xor     ebx, ebx
  626.         push    edi
  627.         call    [UnmapViewOfFile]
  628.         jmp     @f
  629. .mem:
  630.         push    edi
  631.         call    free_big
  632. @@:
  633. ; sound volume
  634.         push    win32_path
  635.         push    10
  636.         push    aSoundVol
  637.         push    aSetup
  638.         call    [GetPrivateProfileIntA]
  639.         and     al, 0x7F
  640.         mov     [sound_vol], al
  641. ; direct screen access parameters
  642.         push    win32_path
  643.         push    32
  644.         push    aColorDepth
  645.         push    aDirectScreenAccess
  646.         call    [GetPrivateProfileIntA]
  647.         test    eax, eax
  648.         jz      @f
  649.         cmp     eax, 24
  650.         jz      @f
  651.         cmp     eax, 32
  652.         jz      @f
  653.         mov     esi, aInvalidColorDepth
  654.         jmp     fail
  655. @@:
  656.         mov     [ColorDepth], eax
  657.         push    win32_path
  658.         push    200
  659.         push    aInvalidateTime
  660.         push    aDirectScreenAccess
  661.         call    [GetPrivateProfileIntA]
  662.         mov     [InvalidateTime], eax
  663.         mov     [DSA], ebx
  664.         push    DSACritSect
  665.         call    [InitializeCriticalSection]
  666.         cmp     [ColorDepth], ebx
  667.         jz      @f
  668.         push    4       ; PAGE_READWRITE
  669.         push    2000h   ; MEM_RESERVE
  670.         push    1000000h
  671.         push    ebx
  672.         call    [VirtualAlloc]
  673.         mov     esi, memerr
  674.         test    eax, eax
  675.         jz      fail
  676.         mov     [DSA], eax
  677. @@:
  678. ; parse path
  679.         mov     eax, [header+20h]
  680.         test    eax, eax
  681.         jz      path_done
  682.         cmp     eax, [header+14h]
  683.         jae     path_done
  684. ;        jb      @f
  685. ;        push    30h
  686. ;        push    aWarning
  687. ;        push    aPathInvalid
  688. ;        push    0
  689. ;        call    [MessageBoxA]
  690. ;        jmp     path_done
  691. ;@@:
  692.         push    0
  693.         push    startcurdir
  694.         push    261
  695.         push    inname
  696.         call    [GetFullPathNameA]
  697. ; test for /rd/1
  698.         push    ramdisk_path
  699.         call    [lstrlenA]
  700.         push    eax
  701.         push    eax
  702.         push    ramdisk_path
  703.         push    eax
  704.         push    startcurdir
  705.         push    1
  706.         push    800h
  707.         call    [CompareStringA]
  708.         cmp     eax, 2
  709.         pop     eax
  710.         jz      .ramdisk
  711. ; test for /hdx/y
  712.         xor     ecx, ecx
  713. .hdxloop:
  714.         push    ecx
  715.         mov     esi, [hd_partitions_array+ecx*4]
  716.         mov     edi, [hd_partitions_num+ecx*4]
  717.         test    edi, edi
  718.         jz      .hdxcont
  719. .hdyloop:
  720.         push    esi
  721.         call    [lstrlenA]
  722.         push    eax
  723.         push    eax
  724.         push    esi
  725.         push    eax
  726.         push    startcurdir
  727.         push    1
  728.         push    800h
  729.         call    [CompareStringA]
  730.         cmp     eax, 2
  731.         pop     eax
  732.         jz      .hdxy
  733.         add     esi, 512
  734.         dec     edi
  735.         jnz     .hdyloop
  736. .hdxcont:
  737.         pop     ecx
  738.         inc     ecx
  739.         cmp     ecx, 4
  740.         jb      .hdxloop
  741.         mov     esi, aPathUnknown
  742.         jmp     fail
  743. .ramdisk:
  744.         push    eax
  745.         mov     edi, [header+20h]
  746.         add     edi, [base]
  747.         mov     eax, '/RD/'
  748.         stosd
  749.         mov     ax, '1/'
  750.         stosw
  751.         jmp     .common
  752. .hdxy:
  753.         pop     ecx
  754.         sub     esi, [hd_partitions_array+ecx*4]
  755.         shr     esi, 9
  756.         inc     esi
  757.         push    eax
  758.         mov     edi, [header+20h]
  759.         add     edi, [base]
  760.         push    esi
  761.         push    ecx
  762.         push    hdxy_str
  763.         push    edi
  764.         call    [wsprintfA]
  765.         add     esp, 10h
  766.         add     edi, eax
  767. .common:
  768.         pop     eax
  769.         lea     esi, [startcurdir+eax]
  770. .l:
  771.         lodsb
  772.         cmp     al, '\'
  773.         jnz     @f
  774.         mov     al, '/'
  775. @@:
  776.         stosb
  777.         test    al, al
  778.         jnz     .l
  779.         mov     eax, [header+20h]
  780.         add     eax, [base]
  781.         push    eax
  782.         push    eax
  783.         call    [CharToOemA]
  784. path_done:
  785. ; create window
  786. ;        push    0
  787. ;        push    16
  788. ;        push    16
  789. ;        push    1
  790. ;        push    1
  791. ;        push    400000h
  792. ;        call    [LoadImageA]
  793. ;        push    eax             ; hIconSm
  794.         push    ebx             ; hIconSm
  795.         push    classname       ; lpszClassName
  796.         push    ebx             ; lpszMenuName
  797.         push    ebx             ; hbrBackground
  798.         push    32512
  799.         push    ebx
  800.         call    [LoadCursorA]
  801.         mov     [hArrow], eax
  802.         push    eax             ; hCursor
  803. ;       push    ebx             ; hIcon
  804.         push    1
  805.         push    400000h
  806.         call    [LoadIconA]
  807.         push    eax             ; hIcon
  808.         push    400000h         ; hInstance
  809.         push    ebx             ; cbWndExtra
  810.         push    ebx             ; cbClsExtra
  811.         push    wndproc         ; lpfnWndProc
  812.         push    3               ; style = CS_HREDRAW or CS_VREDRAW
  813.         push    48              ; cbSize
  814.         push    esp
  815.         call    [RegisterClassExA]
  816.         add     esp, 48
  817.         push    ebx             ; lpParam
  818.         push    400000h         ; hInstance
  819.         push    ebx             ; hMenu
  820.         push    ebx             ; hWndParent
  821.         mov     eax, 80000000h  ; CW_USEDEFAULT
  822.         push    eax             ; nHeight
  823.         push    eax             ; nWidth
  824.         push    eax             ; y
  825.         push    eax             ; x
  826.         push    eax             ; dwStyle = WS_POPUP
  827. ;       push    ebx             ; lpWindowName
  828.         mov     esi, inname
  829.         mov     edx, esi
  830. @@:
  831.         lodsb
  832.         cmp     al, 0
  833.         jz      .done
  834.         cmp     al, '\'
  835.         jz      .x
  836.         cmp     al, '/'
  837.         jz      .x
  838.         cmp     al, ':'
  839.         jnz     @b
  840. .x:     mov     edx, esi
  841.         jmp     @b
  842. .done:
  843.         dec     esi
  844.         cmp     byte [esi-1], '.'
  845.         jnz     @f
  846.         dec     esi
  847.         mov     byte [esi], 0
  848. @@:
  849.         push    edx
  850.         mov     [process_name], edx
  851.         push    classname       ; lpClassName
  852.         push    ebx             ; dwExStyle
  853.         call    [CreateWindowExA]
  854.         mov     [ebp+tls.hWnd], eax
  855.         mov     [ebp+tls.bActive], 1
  856.         mov     [ebp+tls.bFirstMouseMove], 1
  857.         test    eax, eax
  858.         mov     esi, createwnderr
  859.         jz      fail
  860.         call    get_cur_slot_ptr
  861.         mov     [edi+shared_data_struc.hWnd-shared_data_struc.threads], eax
  862.         cmp     [edi+shared_data_struc.thread_id-shared_data_struc.threads], 2
  863.         jnz     .notfirst
  864.         mov     esi, [shared_data]
  865.         cmp     [esi+shared_data_struc.vk], 0
  866.         jnz     .workarea_vk
  867.         push    ebx
  868.         lea     eax, [esi+shared_data_struc.workarea_left]
  869.         push    eax
  870.         push    ebx
  871.         push    30h     ; SPI_GETWORKAREA
  872.         call    [SystemParametersInfoA]
  873.         dec     [esi+shared_data_struc.workarea_right]
  874.         dec     [esi+shared_data_struc.workarea_bottom]
  875.         jmp     .workarea_set
  876. .workarea_vk:
  877.         push    esi
  878.         call    get_screen_size
  879.         pop     esi
  880.         inc     ebx
  881.         mov     word [esi+shared_data_struc.workarea_bottom], bx
  882.         shr     ebx, 10h
  883.         inc     ebx
  884.         mov     [esi+shared_data_struc.workarea_right], ebx
  885.         xor     ebx, ebx
  886. .workarea_set:
  887. .notfirst:
  888.         push    newprg_section_name
  889.         push    1000h
  890.         push    ebx
  891.         push    4
  892.         push    ebx
  893.         push    -1
  894.         call    [CreateFileMappingA]
  895.         push    eax
  896.         mov     esi, shared_section_create_err
  897.         test    eax, eax
  898.         jz      fail
  899.         push    ebx
  900.         push    ebx
  901.         push    ebx
  902.         push    2
  903.         push    eax
  904.         call    [MapViewOfFile]
  905.         pop     ecx
  906.         push    eax
  907.         push    ecx
  908.         call    [CloseHandle]
  909.         pop     eax
  910.         push    eax
  911.         cmp     word [eax], 0x201
  912.         jnz     @f
  913.         mov     ecx, [ebp+tls.hWnd]
  914.         mov     [eax+2], ecx
  915.         mov     byte [eax+1], 3
  916. @@:
  917.         call    [UnmapViewOfFile]
  918. ; allocate LDT selectors
  919. ; data segment
  920.         mov     esi, selector_data
  921.         mov     eax, [base]
  922.         mov     [esi+2], ax
  923.         shr     eax, 10h
  924.         mov     [esi+4], al
  925.         mov     [esi+7], ah
  926.         mov     eax, [header+14h]
  927.         dec     eax
  928.         mov     [limit], eax
  929.         mov     [fn9limit], eax
  930.         call    get_cur_slot_ptr
  931.         mov     [edi+24], eax
  932.         shr     eax, 0Ch
  933.         mov     [esi], ax
  934.         shr     eax, 10h
  935.         or      al, 11000000b
  936.         mov     [esi+6], al
  937.         mov     byte [esi+5], 11110010b
  938.         lea     edi, [esi+8]
  939. ; code segment
  940.         movsd
  941.         movsd
  942.         mov     byte [esi+5], 11111010b
  943.         cmp     [bIs9x], 0
  944.         jnz     alloc_ldt_9x
  945.         push    ntdll_name
  946.         call    [GetModuleHandleA]
  947.         push    aNtSetLdtEntries
  948.         push    eax
  949.         call    [GetProcAddress]
  950.         mov     [NtSetLdtEntries], eax
  951.         push    dword [esi-4]
  952.         push    dword [esi-8]
  953.         push    17h
  954.         push    dword [esi+4]
  955.         push    dword [esi]
  956.         push    0Fh
  957.         call    eax
  958.         mov     esi, ldterr
  959.         test    eax, eax
  960.         js      fail
  961.         mov     eax, [DSA]
  962.         test    eax, eax
  963.         jz      @f
  964.         push    ebx
  965.         push    ebx
  966.         push    ebx
  967.         mov     edx, eax
  968.         mov     dx, (11000000b shl 8) + 11110010b
  969.         ror     edx, 16
  970.         xchg    dl, dh
  971.         ror     edx, 8
  972.         push    edx
  973.         shl     eax, 16
  974.         mov     ax, 0FFFh
  975.         push    eax
  976.         push    1Fh
  977.         call    [NtSetLdtEntries]
  978.         test    eax, eax
  979.         js      fail
  980.         mov     [_gs], 1Fh
  981. @@:
  982. dorunklbr:
  983. ; jump to program code
  984.         mov     eax, [header+18h]
  985.         mov     [ebp+tls._esp], eax
  986.         mov     eax, [header+0Ch]
  987.         mov     [ebp+tls._eip], eax
  988.         push    3200h           ; eflags
  989.         xor     eax, eax
  990.         push    eax
  991.         push    eax
  992.         push    eax
  993.         push    eax
  994.         push    eax
  995.         push    eax
  996.         push    eax
  997.         push    eax
  998. ; Kolibri process was successfully created, notify parent
  999.         call    get_cur_slot_ptr
  1000.         mov     [edi+shared_data_struc.win32_stack-shared_data_struc.threads], esp
  1001.         mov     [bInitialized], 1
  1002. notify_parent:
  1003.         div     edx
  1004.         jmp     i40_done
  1005.  
  1006. alloc_ldt_9x:
  1007.         mov     eax, r0p
  1008.         call    CallRing0
  1009. ; patch int40
  1010.         add     edi, (40h-9)*8
  1011.         mov     eax, i40_9x
  1012.         mov     [edi], ax
  1013.         mov     word [edi+2], cs
  1014.         shr     eax, 16
  1015.         mov     [edi+6], ax
  1016.         mov     word [edi+4], 1110111100000000b
  1017.         xor     ebx, ebx
  1018.         jmp     dorunklbr
  1019. free_ldt:
  1020.         cmp     [bIs9x], 0
  1021.         jnz     @f
  1022. .ret:   ret
  1023. @@:
  1024.         cmp     [temp_cs], 0
  1025.         jz      .ret
  1026.         mov     eax, fl0p
  1027.  
  1028. CallRing0:
  1029.         call    acquire_shared          ; int 9 is global resource
  1030.         sidt    [idtr]
  1031.         mov     edi, dword [idtr+2]
  1032.         add     edi, 8*9
  1033.         push    dword [edi]
  1034.         push    dword [edi+4]
  1035.         mov     [edi], ax
  1036.         mov     word [edi+2], 28h
  1037. ;       mov     word [edi+4], 0xEE00
  1038. ;       shr     eax, 16
  1039. ;       mov     [edi+6], ax
  1040.         mov     [edi+4], eax
  1041.         mov     word [edi+4], 0xEE00
  1042.         int     9
  1043.         pop     dword [edi+4]
  1044.         pop     dword [edi]
  1045.         call    release_shared
  1046.         ret
  1047.  
  1048. r0p:
  1049.         int     20h     ; VMMCall Get_Cur_VM_Handle
  1050.         dw      1
  1051.         dw      1
  1052.         push    0
  1053.         push    1
  1054.         push    dword [esi]
  1055.         push    dword [esi+4]
  1056.         push    ebx
  1057.         int     20h     ; VMMCall _Allocate_LDT_Selector
  1058.         dw      78h
  1059.         dw      1
  1060.         add     esp, 14h
  1061.         mov     [klbr_cs], ax
  1062.         push    0
  1063.         push    1
  1064.         push    dword [esi-8]
  1065.         push    dword [esi-4]
  1066.         push    ebx
  1067.         int     20h     ; VMMCall _Allocate_LDT_Selector
  1068.         dw      78h
  1069.         dw      1
  1070.         add     esp, 14h
  1071.         mov     [klbr_ds], ax
  1072.         mov     eax, [DSA]
  1073.         test    eax, eax
  1074.         jz      @f
  1075.         push    0
  1076.         push    1
  1077.         mov     edx, eax
  1078.         mov     dx, (11000000b shl 8) + 11110010b
  1079.         ror     edx, 16
  1080.         xchg    dl, dh
  1081.         ror     edx, 8
  1082.         shl     eax, 16
  1083.         mov     ax, 0FFFh
  1084.         push    eax
  1085.         push    edx
  1086.         push    ebx
  1087.         int     20h     ; VMMCall _Allocate_LDT_Selector
  1088.         dw      78h
  1089.         dw      1
  1090.         add     esp, 14h
  1091.         mov     [_gs], ax
  1092. @@:
  1093.         push    0
  1094.         push    1
  1095.         mov     eax, temp_code
  1096.         mov     ecx, eax
  1097.         shl     eax, 16
  1098.         add     eax, temp_code_size-1
  1099.         push    eax
  1100.         mov     eax, ecx
  1101.         and     eax, 0xFF000000
  1102.         add     eax, 0000000011111011b shl 8
  1103.         shr     ecx, 16
  1104.         mov     al, cl
  1105.         push    eax
  1106.         push    ebx
  1107.         int     20h     ; VMMCall _Allocate_LDT_Selector
  1108.         dw      78h
  1109.         dw      1
  1110.         add     esp, 14h
  1111.         mov     [temp_cs], ax
  1112.         mov     [temp_cs2], ax
  1113.         push    0
  1114.         push    1
  1115.         mov     eax, temp_stack
  1116.         mov     ecx, eax
  1117.         shl     eax, 16
  1118.         add     eax, temp_stack_size-1
  1119.         push    eax
  1120.         mov     eax, ecx
  1121.         and     eax, 0xFF000000
  1122.         add     eax, 0000000011110011b shl 8
  1123.         shr     ecx, 16
  1124.         mov     al, cl
  1125.         push    eax
  1126.         push    ebx
  1127.         int     20h     ; VMMCall _Allocate_LDT_Selector
  1128.         dw      78h
  1129.         dw      1
  1130.         add     esp, 14h
  1131.         mov     [temp_ss], ax
  1132. ;       mov     eax, 40h
  1133. ;       mov     cx, [_cs]
  1134. ;       mov     edx, i40_9x
  1135. ;       int     20h     ; VMMCall Set_PM_Int_Vector
  1136. ;       dw      45h
  1137. ;       dw      1
  1138. ;       xor     ecx, ecx
  1139. ;       xor     edx, edx
  1140. ;       int     20h     ; VMMCall Get_PM_Int_Vector
  1141. ;       dw      44h
  1142. ;       dw      1
  1143.         iret
  1144. fl0p:
  1145.         int     20h     ; VMMCall Get_Cur_VM_Handle
  1146.         dw      1
  1147.         dw      1
  1148.         movzx   eax, [klbr_cs]
  1149.         call    free_selector
  1150.         movzx   eax, [klbr_ds]
  1151.         call    free_selector
  1152.         movzx   eax, [temp_cs]
  1153.         call    free_selector
  1154.         movzx   eax, [temp_ss]
  1155.         call    free_selector
  1156.         xor     ebx, ebx
  1157.         iret
  1158. sl0p:
  1159.         int     20h     ; VMMCall Get_Cur_VM_Handle
  1160.         dw      1
  1161.         dw      1
  1162.         push    0
  1163.         push    dword [esi]
  1164.         push    dword [esi+4]
  1165.         push    ebx
  1166.         movzx   eax, [klbr_cs]
  1167.         push    eax
  1168.         int     20h     ; VMMCall _SetDescriptor
  1169.         dw      7Ch
  1170.         dw      1
  1171.         push    0
  1172.         push    dword [esi-8]
  1173.         push    dword [esi-4]
  1174.         push    ebx
  1175.         movzx   eax, [klbr_ds]
  1176.         push    eax
  1177.         int     20h     ; VMMCall _SetDescriptor
  1178.         dw      7Ch
  1179.         dw      1
  1180.         add     esp, 40
  1181.         iret
  1182. rdmsrp:
  1183. ; rdmsr may throw exception
  1184.         mov     esi, .exception_struc
  1185.         int     20h     ; VMMCall Install_Exception_Handler
  1186.         dw      0EFh
  1187.         dw      1
  1188.         xor     ebx, ebx        ; assume OK
  1189. .start_eip:
  1190.         rdmsr
  1191. .end_eip:
  1192.         mov     esi, .exception_struc
  1193.         int     20h     ; VMMCall Remove_Exception_Handler
  1194.         dw      0F0h
  1195.         dw      1
  1196.         iret
  1197. .exception_struc:
  1198.         dd      0
  1199.         dd      .start_eip
  1200.         dd      .end_eip
  1201.         dd      .exception_handler
  1202. .exception_handler:
  1203.         inc     ebx
  1204.         jmp     .end_eip
  1205.  
  1206. free_selector:
  1207.         push    0
  1208.         push    eax
  1209.         push    ebx
  1210.         int     20h     ; VMMCall _Free_LDT_Selector
  1211.         dw      79h
  1212.         dw      1
  1213.         add     esp, 12
  1214.         ret
  1215.  
  1216. seh:
  1217.         mov     eax, [esp+12]
  1218.         add     dword [eax+0xB8], 2
  1219.         xor     eax, eax
  1220.         ret
  1221.  
  1222. ofn_hook:
  1223.         cmp     dword [esp+8], 2        ; WM_DESTROY
  1224.         jnz     @f
  1225.         push    260
  1226.         mov     eax, converted_path
  1227.         mov     [parameters], eax
  1228.         push    eax
  1229.         push    23
  1230.         push    dword [esp+12+4]
  1231.         push    user32_name
  1232.         call    [GetModuleHandleA]
  1233.         push    GetDlgItemTextA_thunk+2
  1234.         push    eax
  1235.         call    [GetProcAddress]
  1236.         call    eax
  1237. @@:
  1238.         xor     eax, eax
  1239.         ret     10h
  1240.  
  1241. getfilename:
  1242. @@:
  1243.         lodsb
  1244.         cmp     al, 0
  1245.         jz      .not
  1246.         cmp     al, ' '
  1247.         jbe     @b
  1248.         cmp     al, '"'
  1249.         setz    dl
  1250.         jz      .loo
  1251.         dec     esi
  1252. .loo:
  1253.         lodsb
  1254.         cmp     al, 0
  1255.         jz      .end
  1256.         cmp     al, ' '
  1257.         ja      @f
  1258.         test    dl, 1
  1259.         jz      .end
  1260. @@:     cmp     al, '"'
  1261.         jnz     @f
  1262.         test    dl, 1
  1263.         jnz     .end_quote
  1264. @@:     stosb
  1265.         jmp     .loo
  1266. .end_quote:
  1267.         lodsb
  1268. .end:
  1269.         or      al, al
  1270.         jnz     @f
  1271.         dec     esi
  1272. @@:     mov     al, 0
  1273.         stosb
  1274.         clc
  1275.         ret
  1276. .not:
  1277.         stc
  1278.         ret
  1279.  
  1280. map_shared_data:
  1281.         push    0
  1282.         push    0
  1283.         push    0
  1284.         push    2
  1285.         push    [hSharedData]
  1286.         call    [MapViewOfFile]
  1287.         mov     [shared_data], eax
  1288.         ret
  1289.  
  1290. acquire_shared:
  1291.         pushad
  1292.         push    -1
  1293.         push    [hSharedMutex]
  1294.         call    [WaitForSingleObject]
  1295.         popad
  1296.         ret
  1297. release_shared:
  1298.         pushad
  1299.         push    [hSharedMutex]
  1300.         call    [ReleaseMutex]
  1301.         popad
  1302.         ret
  1303.  
  1304. get_cur_slot_ptr_server:
  1305.         push    eax
  1306.         mov     eax, [cur_slot]
  1307. @@:
  1308.         call    get_slot_ptr
  1309.         pop     eax
  1310.         ret
  1311. get_cur_slot_ptr:
  1312.         push    eax
  1313.         mov     eax, [ebp+tls.cur_slot]
  1314.         jmp     @b
  1315. get_slot_ptr:
  1316.         mov     edi, [shared_data]
  1317.         shl     eax, 6
  1318.         lea     edi, [eax+edi+shared_data_struc.threads]
  1319.         ret
  1320.  
  1321. read_color:
  1322.         push    esi
  1323.         mov     ecx, 6
  1324.         xor     edx, edx
  1325. .l:
  1326.         lodsb
  1327.         cmp     al, 0
  1328.         jz      .d
  1329.         or      al, 20h
  1330.         sub     al, '0'
  1331.         cmp     al, 10
  1332.         jb      @f
  1333.         sub     al, 'a'-10-'0'
  1334. @@:
  1335.         shl     edx, 4
  1336.         or      dl, al
  1337.         loop    .l
  1338. .d:
  1339.         pop     esi
  1340.         xchg    eax, edx
  1341.         ret
  1342.  
  1343. i40_9x:
  1344. ; set Win32 context
  1345.         push    eax ecx
  1346.         mov     eax, [cs:tls_index]
  1347.         shl     eax, 2
  1348.         add     eax, [fs:2Ch]
  1349.         mov     eax, [cs:eax]
  1350.         mov     ds, [cs:eax+tls._ds]
  1351.         mov     es, [eax+tls._ds]
  1352. ;       mov     fs, [_fs]
  1353.         mov     ecx, [esp+8]    ; eip
  1354.         dec     ecx
  1355.         dec     ecx
  1356.         mov     [eax+tls._eip], ecx
  1357.         mov     ecx, [esp+16]   ; eflags
  1358.         mov     ss, [eax+tls._ds]
  1359.         xchg    esp, [eax+tls._esp]
  1360.         push    ecx
  1361.         add     [eax+tls._esp], 20
  1362.         mov     eax, [eax+tls._esp]
  1363.         add     eax, [base]
  1364.         mov     ecx, [eax-20]
  1365.         mov     eax, [eax-16]
  1366.         popfd
  1367.  
  1368. exception:
  1369.         pushfd
  1370.         cld
  1371. ; test for page fault in direct screen area
  1372.         push    ebp eax
  1373.         mov     eax, [tls_index]
  1374.         mov     ebp, [fs:2Ch]
  1375.         mov     ebp, [ebp+eax*4]
  1376.         mov     eax, [ebp+tls.saved_fs0]
  1377.         mov     [fs:0], eax
  1378.         mov     eax, [ebp+tls.saved_fs4]
  1379.         mov     [fs:4], eax
  1380.         cmp     [ebp+tls.exc_code], 0C0000005h
  1381.         jnz     noaccvio
  1382.         mov     eax, [ebp+tls.exc_data]
  1383.         sub     eax, [DSA]
  1384.         cmp     eax, 0FFFFFFh
  1385.         ja      noaccvio
  1386. ; handle page fault in direct screen area
  1387.         pop     eax ebp
  1388.         pushad
  1389.         mov     ebp, [tls_index]
  1390.         shl     ebp, 2
  1391.         add     ebp, [fs:2Ch]
  1392.         mov     ebp, [ebp]
  1393.         push    DSACritSect
  1394.         call    [EnterCriticalSection]
  1395.         cmp     [bHaveDSA], 0
  1396.         jnz     dsafail
  1397.         call    get_screen_size
  1398.         mov     eax, ebx
  1399.         shr     eax, 16
  1400.         movzx   ebx, bx
  1401.         inc     eax
  1402.         inc     ebx
  1403.         mov     edi, eax
  1404.         mul     ebx
  1405.         mul     [ColorDepth]
  1406.         shr     eax, 3
  1407.         add     eax, 0xFFF
  1408.         and     eax, not 0xFFF
  1409.         mov     ecx, [ebp+tls.exc_data]
  1410.         sub     ecx, [DSA]
  1411.         cmp     ecx, eax
  1412.         jb      @f
  1413. dsafail:
  1414.         push    DSACritSect
  1415.         call    [LeaveCriticalSection]
  1416.         push    40h
  1417.         push    0
  1418.         push    DSAErr
  1419.         push    0
  1420. mbni:
  1421.         call    [MessageBoxA]
  1422.         popad
  1423.         push    ebp eax
  1424.         mov     ebp, [tls_index]
  1425.         shl     ebp, 2
  1426.         add     ebp, [fs:2Ch]
  1427.         mov     ebp, [ebp]
  1428.         jmp     notint40
  1429. @@:
  1430.         push    4
  1431.         push    1000h
  1432.         push    eax
  1433.         push    [DSA]
  1434.         call    [VirtualAlloc]
  1435. ; get screen data
  1436.         push    ebp
  1437.         push    0
  1438.         call    [GetDC]
  1439.         push    eax
  1440.         xchg    eax, ebp
  1441.         call    [CreateCompatibleDC]
  1442.         xchg    eax, esi
  1443.         push    ebx
  1444.         push    edi
  1445.         push    ebp
  1446.         call    [CreateCompatibleBitmap]
  1447.         push    eax
  1448.         push    esi
  1449.         call    [SelectObject]
  1450.         push    eax
  1451.         xor     eax, eax
  1452.         push    0xCC0020
  1453.         push    eax
  1454.         push    eax
  1455.         push    ebp
  1456.         push    ebx
  1457.         push    edi
  1458.         push    eax
  1459.         push    eax
  1460.         push    esi
  1461.         call    [BitBlt]
  1462.         push    esi
  1463.         call    [SelectObject]
  1464.         push    ebp
  1465.         xchg    eax, ebp
  1466.         xor     eax, eax
  1467. ; now esi=hDC, ebp=hBitmap
  1468.         push    eax     ; biClrImportant
  1469.         push    eax     ; biClrUsed
  1470.         push    eax     ; biYPelsPerMeter
  1471.         push    eax     ; biXPelsPerMeter
  1472.         push    eax     ; biSizeImage
  1473.         push    eax     ; biCompression
  1474.         push    1       ; biPlanes
  1475.         mov     ecx, [ColorDepth]
  1476.         mov     [esp+2], cx     ; biBitColor
  1477.         neg     ebx
  1478.         push    ebx     ; biHeight
  1479.         neg     ebx
  1480.         push    edi     ; biWidth
  1481.         push    40      ; biSize
  1482.         mov     ecx, esp
  1483.         push    eax
  1484.         push    ecx
  1485.         push    [DSA]
  1486.         push    ebx
  1487.         push    eax
  1488.         push    ebp
  1489.         push    esi
  1490.         call    [GetDIBits]
  1491.         add     esp, 40
  1492.         push    ebp
  1493.         call    [DeleteObject]
  1494.         push    esi
  1495.         call    [DeleteDC]
  1496.         push    0
  1497.         call    [ReleaseDC]
  1498.         mov     [bHaveDSA], 1
  1499.         push    eax
  1500.         push    esp
  1501.         push    0
  1502.         push    0
  1503.         push    DSAFreeThread
  1504.         push    10000h
  1505.         push    0
  1506.         call    [CreateThread]
  1507.         pop     eax
  1508.         push    DSACritSect
  1509.         call    [LeaveCriticalSection]
  1510.         pop     ebp
  1511.         mov     ebp, [tls_index]
  1512.         shl     ebp, 2
  1513.         add     ebp, [fs:2Ch]
  1514.         mov     ebp, [ebp]
  1515.         jmp     i40_done
  1516. noaccvio:
  1517. ; test for int40
  1518.         mov     eax, [ebp+tls._eip]
  1519.         cmp     eax, [limit]
  1520.         jae     notint40
  1521.         add     eax, [base]
  1522.         cmp     word [eax], 0x40CD
  1523.         jz      int40
  1524. notint40:
  1525.  
  1526.         pop     eax
  1527.         push    esi
  1528.         sub     esp, 400h
  1529.         mov     esi, esp
  1530.         push    dword [esi+408h]
  1531.         push    [ebp+tls._eip]
  1532.         push    dword [esi+404h]
  1533.         push    [ebp+tls._esp]
  1534.         push    edi
  1535.         push    dword [esi+400h]
  1536.         push    edx
  1537.         push    ecx
  1538.         push    ebx
  1539.         push    eax
  1540.         push    excstr
  1541.         push    esi
  1542.         call    [wsprintfA]
  1543.         push    0
  1544.         push    exceptionstr
  1545.         push    esi
  1546.         push    0
  1547.         call    [MessageBoxA]
  1548. lock    dec     [NumThreads]
  1549.         jnz     .et
  1550.         call    free_ldt
  1551.         push    0
  1552.         call    [ExitProcess]
  1553. .et:
  1554.         push    0
  1555.         call    [ExitThread]
  1556.  
  1557. int40:
  1558.         add     [ebp+tls._eip], 2
  1559.         pop     eax ebp
  1560.         pushad
  1561. safe_to_suspend:
  1562.         mov     ebp, [tls_index]
  1563.         shl     ebp, 2
  1564.         add     ebp, [fs:2Ch]
  1565.         mov     ebp, [ebp]
  1566.         inc     eax
  1567.         cmp     eax, num_i40_fns
  1568.         push    eax     ; emulate ret addr for not_supported_i40_fn
  1569.         jae     not_supported_i40_fn
  1570.         pop     eax
  1571.         call    [i40fns + eax*4]
  1572. i40_done:
  1573.         cmp     [NumThreads], 1
  1574.         jnz     i40_done_mt
  1575.         mov     eax, [ebp+tls._esp]
  1576.         mov     [klbr_esp], eax
  1577.         mov     eax, [ebp+tls._eip]
  1578.         mov     [jmp_klbr_eip], eax
  1579.         lea     eax, [esp+24h]
  1580.         mov     [ebp+tls._esp], eax
  1581.         mov     [ebp+tls._eip], exception
  1582.         mov     eax, [fs:0]
  1583.         mov     [ebp+tls.saved_fs0], eax
  1584.         mov     eax, [fs:4]
  1585.         mov     [ebp+tls.saved_fs4], eax
  1586.         popad
  1587.         popfd
  1588.         mov     ss, [klbr_ds]
  1589.         mov     esp, [klbr_esp]
  1590.         mov     es, [klbr_ds]
  1591. ;       mov     fs, [klbr_null]
  1592. ;       mov     gs, [klbr_null]
  1593.         mov     gs, [_gs]
  1594.         mov     ds, [klbr_ds]
  1595. i40_done_jmp1:
  1596.         jmp     [cs:jmp_klbr]
  1597. i40_done_mt:
  1598.         mov     eax, [ebp+tls._esp]
  1599.         mov     [esp+12], eax
  1600.         mov     ecx, [ebp+tls._eip]
  1601.         xchg    [fs:0], ecx
  1602.         mov     [ebp+tls.saved_fs0], ecx
  1603.         movzx   ecx, [klbr_cs]
  1604.         xchg    [fs:4], ecx
  1605.         mov     [ebp+tls.saved_fs4], ecx
  1606.         lea     eax, [esp+24h]
  1607.         mov     [ebp+tls._esp], eax
  1608.         mov     [ebp+tls._eip], exception
  1609.         popad
  1610.         popfd
  1611.         mov     ss, [klbr_ds]
  1612.         mov     esp, [ds:esp-24h+12]
  1613.         mov     es, [klbr_ds]
  1614. ;       mov     fs, [klbr_null]
  1615. ;       mov     gs, [klbr_null]
  1616.         mov     gs, [_gs]
  1617.         mov     ds, [klbr_ds]
  1618. i40_done_jmp2:
  1619.         jmp     fword [fs:0]
  1620.  
  1621. not_supported_i40_fn:
  1622.         sub     esp, 200h-4
  1623.         mov     esi, esp
  1624.         push    dword [esi+200h+20h]
  1625.         push    [ebp+tls._eip]
  1626.         push    dword [esi+200h+8]
  1627.         push    [ebp+tls._esp]
  1628.         push    dword [esi+200h]
  1629.         push    dword [esi+200h+4]
  1630.         push    dword [esi+200h+14h]
  1631.         push    dword [esi+200h+18h]
  1632.         push    dword [esi+200h+10h]
  1633.         push    dword [esi+200h+1Ch]
  1634.         push    notsupportedmsg
  1635.         push    esi
  1636.         call    [wsprintfA]
  1637.         push    0
  1638.         push    nsm
  1639.         push    esi
  1640.         push    0
  1641.         call    [MessageBoxA]
  1642. i40_terminate:
  1643. lock    dec     [NumThreads]
  1644.         jnz     .thread
  1645.         call    free_ldt
  1646.         push    0
  1647.         call    [ExitProcess]
  1648. .thread:
  1649.         push    0
  1650.         call    [ExitThread]
  1651.  
  1652. align 4
  1653. i40fns  dd      i40_terminate           ; -1
  1654.         dd      i40_draw_window         ; 0
  1655.         dd      i40_put_pixel           ; 1
  1656.         dd      i40_getkey              ; 2
  1657.         dd      i40_get_sys_time        ; 3
  1658.         dd      i40_writetext           ; 4
  1659.         dd      i40_delay               ; 5
  1660.         dd      i40_read_floppy_file    ; 6
  1661.         dd      i40_putimage            ; 7
  1662.         dd      i40_define_button       ; 8
  1663.         dd      i40_get_process_info    ; 9
  1664.         dd      i40_wait_event          ; 10
  1665.         dd      i40_check_event         ; 11
  1666.         dd      i40_redraw_status       ; 12
  1667.         dd      i40_drawrect            ; 13
  1668.         dd      i40_get_screen_size     ; 14
  1669.         dd      i40_set_background      ; 15
  1670.         dd      not_supported_i40_fn    ; 16
  1671.         dd      i40_getbutton           ; 17
  1672.         dd      i40_sys_service         ; 18
  1673.         dd      not_supported_i40_fn    ; 19
  1674.         dd      not_supported_i40_fn    ; 20
  1675.         dd      i40_sys_setup           ; 21
  1676.         dd      not_supported_i40_fn    ; 22
  1677.         dd      i40_wait_event_timeout  ; 23
  1678.         dd      not_supported_i40_fn    ; 24
  1679.         dd      not_supported_i40_fn    ; 25
  1680.         dd      i40_getsetup            ; 26
  1681.         dd      not_supported_i40_fn    ; 27
  1682.         dd      not_supported_i40_fn    ; 28
  1683.         dd      i40_get_sys_date        ; 29
  1684.         dd      i40_current_folder      ; 30
  1685.         dd      not_supported_i40_fn    ; 31
  1686.         dd      i40_delete_ramdisk_file ; 32
  1687.         dd      i40_write_ramdisk_file  ; 33
  1688.         dd      not_supported_i40_fn    ; 34
  1689.         dd      i40_screen_getpixel     ; 35
  1690.         dd      i40_screen_getarea      ; 36
  1691.         dd      i40_read_mouse_pos      ; 37
  1692.         dd      i40_draw_line           ; 38
  1693.         dd      i40_get_background      ; 39
  1694.         dd      i40_set_event_mask      ; 40
  1695.         dd      not_supported_i40_fn    ; 41
  1696.         dd      not_supported_i40_fn    ; 42
  1697.         dd      not_supported_i40_fn    ; 43
  1698.         dd      not_supported_i40_fn    ; 44
  1699.         dd      not_supported_i40_fn    ; 45
  1700.         dd      i40_reserve_free_ports  ; 46
  1701.         dd      i40_display_number      ; 47
  1702.         dd      i40_display_settings    ; 48
  1703.         dd      not_supported_i40_fn    ; 49
  1704.         dd      i40_set_window_shape    ; 50
  1705.         dd      i40_create_thread       ; 51
  1706.         dd      not_supported_i40_fn    ; 52
  1707.         dd      not_supported_i40_fn    ; 53
  1708.         dd      not_supported_i40_fn    ; 54
  1709.         dd      i40_sound_interface     ; 55
  1710.         dd      not_supported_i40_fn    ; 56
  1711.         dd      not_supported_i40_fn    ; 57
  1712.         dd      i40_file_system         ; 58
  1713.         dd      not_supported_i40_fn    ; 59
  1714.         dd      i40_ipc                 ; 60
  1715.         dd      i40_direct_scr_access   ; 61
  1716.         dd      i40_pci                 ; 62
  1717.         dd      i40_debug_board         ; 63
  1718.         dd      i40_resize_app_memory   ; 64
  1719.         dd      i40_putimage_palette    ; 65
  1720.         dd      i40_process_def         ; 66
  1721.         dd      i40_move_resize         ; 67
  1722.         dd      i40_sys_services        ; 68
  1723.         dd      i40_debug_services      ; 69
  1724.         dd      i40_file_system_lfn     ; 70
  1725.         dd      i40_window_settings     ; 71
  1726. num_i40_fns = ($ - i40fns)/4
  1727.  
  1728. getfilemap:
  1729. ; in: esi->filename
  1730. ; out: eax->mapped file
  1731.         push    esi
  1732.         sub     esp, 200h
  1733.         cmp     word [esi+1], ':\'
  1734.         jz      .fullpath
  1735.         mov     edi, esp
  1736.         push    esi
  1737.         mov     esi, startcurdir
  1738. @@:
  1739.         lodsb
  1740.         stosb
  1741.         test    al, al
  1742.         jnz     @b
  1743.         pop     esi
  1744.         dec     edi
  1745.         mov     al, '\'
  1746.         cmp     byte [edi-1], al
  1747.         jz      @f
  1748.         stosb
  1749. @@:
  1750.         lodsb
  1751.         stosb
  1752.         test    al, al
  1753.         jnz     @b
  1754.         mov     esi, esp
  1755. .fullpath:
  1756.         push    ebx
  1757.         push    ebx
  1758.         push    3       ; OPEN_EXISTING
  1759.         push    ebx
  1760.         push    1       ; FILE_SHARE_READ
  1761.         push    80000000h       ; GENERIC_READ
  1762.         push    esi
  1763.         call    [CreateFileA]
  1764.         add     esp, 200h
  1765.         pop     esi
  1766.         inc     eax
  1767.         jz      .failed
  1768.         dec     eax
  1769.         xchg    eax, edi
  1770.         push    ebx
  1771.         push    ebx
  1772.         push    ebx
  1773.         push    2       ; PAGE_READONLY
  1774.         push    ebx
  1775.         push    edi
  1776.         call    [CreateFileMappingA]
  1777.         test    eax, eax
  1778.         jz      .failed
  1779.         push    edi
  1780.         xchg    eax, edi
  1781.         call    [CloseHandle]
  1782.         push    ebx
  1783.         push    ebx
  1784.         push    ebx
  1785.         push    4       ; FILE_MAP_READ
  1786.         push    edi
  1787.         call    [MapViewOfFile]
  1788.         test    eax, eax
  1789.         jz      .failed
  1790.         push    eax
  1791.         push    edi
  1792.         call    [CloseHandle]
  1793.         pop     eax
  1794.         ret
  1795. .failed:
  1796.         push    ebx
  1797.         push    filereaderr
  1798.         jmp     fail2
  1799.  
  1800. DSAFreeThread:
  1801.         push    [InvalidateTime]
  1802.         call    [Sleep]
  1803.         push    DSACritSect
  1804.         call    [EnterCriticalSection]
  1805.         push    4000h
  1806.         push    0
  1807.         push    [DSA]
  1808.         call    [VirtualFree]
  1809.         mov     [bHaveDSA], 0
  1810.         push    DSACritSect
  1811.         call    [LeaveCriticalSection]
  1812.         ret
  1813.  
  1814. virtual at 0
  1815. button_desc:
  1816.         .next   dd      ?       ; must be 1st dword
  1817.         .id     dd      ?
  1818.         .xsize  dw      ?
  1819.         .xstart dw      ?
  1820.         .ysize  dw      ?
  1821.         .ystart dw      ?
  1822.         .color  dd      ?
  1823.         .size = $
  1824. end virtual
  1825.  
  1826. test_maximized:
  1827.         sub     esp, 40
  1828.         push    44
  1829.         push    esp
  1830.         push    [ebp+tls.hWnd]
  1831.         call    [GetWindowPlacement]
  1832.         mov     eax, [esp+8]    ; showCmd
  1833.         add     esp, 44
  1834.         cmp     eax, 3  ; SW_SHOWMAXIMIZED
  1835.         ret
  1836.  
  1837. wndproc:
  1838. ; LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
  1839.         push    ebp
  1840.         mov     ebp, [tls_index]
  1841.         mov     eax, [fs:2Ch]
  1842.         mov     ebp, [eax+ebp*4]
  1843.         mov     eax, [esp+8+4]
  1844.         cmp     eax, 0xF        ; WM_PAINT
  1845.         jz      wmpaint
  1846.         dec     eax
  1847. ;       jz      wmcreate
  1848.         dec     eax
  1849.         jz      wmdestroy
  1850.         dec     eax
  1851.         jz      wmmove
  1852.         dec     eax
  1853.         dec     eax
  1854.         jz      wmsize
  1855.         dec     eax
  1856.         jz      wmactivate
  1857.         cmp     eax, 0x1A-6
  1858.         jz      wmsettingchange
  1859.         cmp     eax, 0x20-6
  1860.         jz      wmsetcursor
  1861.         cmp     eax, 0x24-6
  1862.         jz      wmgetminmaxinfo
  1863.         sub     eax, 0x84-6
  1864.         jz      wmnchittest
  1865.         cmp     eax, 0xA1-0x84
  1866.         jz      wmnclbuttondown
  1867.         cmp     eax, 0xA3-0x84
  1868.         jz      wmnclbuttondblclk
  1869.         sub     eax, 0x100-0x84 ; WM_KEYDOWN
  1870.         jz      wmkeydown
  1871.         dec     eax
  1872.         jz      wmkeyup
  1873.         dec     eax
  1874.         jz      wmchar
  1875.         dec     eax
  1876.         dec     eax
  1877.         jz      wmsyskeydown
  1878.         dec     eax
  1879.         jz      wmsyskeyup
  1880.         sub     eax, 0x200-0x105        ; WM_MOUSEMOVE
  1881.         jz      wmmousemove
  1882.         dec     eax
  1883.         jz      wmlbuttondown
  1884.         dec     eax
  1885.         jz      wmlbuttonup
  1886.         dec     eax
  1887.         dec     eax
  1888.         jz      wmrbuttondown
  1889.         dec     eax
  1890.         jz      wmrbuttonup
  1891.         cmp     eax, 0x20A-0x205
  1892.         jz      wmmousewheel
  1893.         cmp     eax, 0x214-0x205
  1894.         jz      wmsizing
  1895.         sub     eax, 0x400-0x205        ; WM_USER
  1896.         jz      wm_ipc
  1897.         cmp     eax, 0xC000-0x400
  1898.         jz      vk_mouse
  1899.         dec     eax
  1900.         jz      wm_debug1
  1901.         dec     eax
  1902.         jz      wm_debug2
  1903. wmdef:
  1904.         pop     ebp
  1905.         jmp     [DefWindowProcA]
  1906. wmsettingchange:
  1907.         call    del_background
  1908. @@:
  1909.         test    [ebp+tls.message_mask], 10h
  1910.         jz      wmdef
  1911.         mov     [ebp+tls.translated_msg_code], 5
  1912.         push    0
  1913.         push    0
  1914.         push    0
  1915.         push    dword [esp+20]
  1916.         call    [PostMessageA]
  1917.         jmp     wmdef
  1918. wmactivate:
  1919.         mov     eax, [shared_data]
  1920.         mov     ecx, [ebp+tls.cur_slot]
  1921.         inc     ecx
  1922.         cmp     word [esp+12+4], 0
  1923.         jz      .inact1
  1924.         mov     [eax+shared_data_struc.active_process], ecx
  1925.         jmp     .cmn1
  1926. .inact1:
  1927.         call    acquire_shared
  1928.         cmp     [eax+shared_data_struc.active_process], ecx
  1929.         jnz     @f
  1930.         mov     [eax+shared_data_struc.active_process], 1
  1931. @@:     call    release_shared
  1932. .cmn1:
  1933.         mov     al, byte [ebp+tls.color_main+3]
  1934.         and     al, 0Fh
  1935.         cmp     al, 3
  1936.         jz      .setactive
  1937.         cmp     al, 4
  1938.         jnz     wmdef
  1939. .setactive:
  1940.         mov     al, [esp+12+4]
  1941.         mov     [ebp+tls.bActive], al   ; 0/1/2
  1942. wndproc_update_wnd:
  1943.         mov     [ebp+tls.curdraw], 0
  1944.         push    0
  1945.         push    0
  1946.         push    [ebp+tls.hWnd]
  1947.         call    [InvalidateRect]
  1948.         jmp     wmdef
  1949. wmpaint:
  1950.         push    esi
  1951.         push    edi
  1952.         sub     esp, 0x40
  1953.         push    esp
  1954.         push    [ebp+tls.hWnd]
  1955.         call    [BeginPaint]
  1956. ;       test    [ebp+tls.message_mask], 1
  1957. ;       jz      @f
  1958. ;       mov     [ebp+tls.translated_msg_code], 1
  1959. @@:     xchg    eax, edi
  1960.         cmp     [ebp+tls.curdraw], 0
  1961.         mov     [ebp+tls.curdraw], 1
  1962.         jz      .nopaint
  1963.         call    draw_window_base
  1964. .nopaint:
  1965.         push    esp
  1966.         push    [ebp+tls.hWnd]
  1967.         call    [EndPaint]
  1968.         add     esp, 40h
  1969.         pop     edi
  1970.         pop     esi
  1971.         pop     ebp
  1972.         xor     eax, eax
  1973.         ret     10h
  1974. wmdestroy:
  1975.         push    0
  1976.         call    [PostQuitMessage]
  1977. @@:
  1978.         xor     eax, eax
  1979.         pop     ebp
  1980.         ret     10h
  1981. wmnclbuttondown:
  1982.         call    test_maximized
  1983.         jnz     wmdef
  1984.         push    [ebp+tls.hWnd]
  1985.         call    [SetForegroundWindow]
  1986.         jmp     @b
  1987. ;wmwindowposchanging:
  1988. ;        call    test_maximized
  1989. ;        jnz     @b
  1990. ;        mov     eax, [esp+0x10+4]
  1991. ;        or      byte [eax+18h], 2       ; SWP_NOMOVE
  1992. ;        jmp     @b
  1993. wmnchittest:
  1994. ; for window type 1 always return HTCLIENT
  1995.         mov     cl, byte [ebp+tls.color_main+3]
  1996.         and     cl, 0x0F
  1997.         cmp     cl, 0x01
  1998.         jz      .client
  1999.         mov     ax, [esp+0x10+4]        ; x
  2000.         sub     ax, [ebp+tls.x_start]
  2001.         mov     dx, [esp+0x12+4]        ; y
  2002.         sub     dx, [ebp+tls.y_start]
  2003. ; test for caption
  2004.         push    eax
  2005.         mov     eax, [_skinh]
  2006.         cmp     cl, 0x03
  2007.         jz      @f
  2008.         mov     al, 21
  2009. @@:
  2010.         cmp     dx, ax
  2011.         pop     eax
  2012.         jae     .nocaption
  2013. ; check for buttons
  2014.         push    esi
  2015.         call    find_button
  2016.         test    esi, esi
  2017.         pop     esi
  2018.         jnz     .button
  2019. .caption:
  2020.         push    2               ; HTCAPTION
  2021.         pop     eax
  2022.         pop     ebp
  2023.         ret     10h
  2024. .button:
  2025. .client:
  2026.         push    1               ; HTCLIENT
  2027.         jmp     .ret
  2028. .nocaption:
  2029. ; do not resize window with type 0
  2030.         jecxz   .client
  2031. ; do not resize window with type 4
  2032.         cmp     ecx, 0x04000000
  2033.         jz      .client
  2034. ; do not resize maximized window
  2035.         push    eax edx
  2036.         call    test_maximized
  2037.         pop     edx eax
  2038.         jz      .client
  2039.         sub     dx, [ebp+tls.y_size]
  2040.         neg     dx
  2041.         cmp     dx, 7
  2042.         jbe     .bottomall
  2043.         cmp     ax, 7
  2044.         jbe     .left
  2045.         sub     ax, [ebp+tls.x_size]
  2046.         neg     ax
  2047.         cmp     ax, 7
  2048.         ja      .client
  2049.         push    11              ; HTRIGHT
  2050.         jmp     .ret
  2051. .left:
  2052.         push    10              ; HTLEFT
  2053. .ret:
  2054.         pop     eax
  2055.         pop     ebp
  2056.         ret     10h
  2057. .bottomall:
  2058.         cmp     ax, 7
  2059.         jbe     .bottomleft
  2060.         sub     ax, [ebp+tls.x_size]
  2061.         neg     ax
  2062.         cmp     ax, 7
  2063.         ja      .bottom
  2064.         push    17              ; HTBOTTOMRIGHT
  2065.         jmp     .ret
  2066. .bottomleft:
  2067.         push    16              ; HTBOTTOMLEFT
  2068.         jmp     .ret
  2069. .bottom:
  2070.         push    15              ; HTBOTTOM
  2071.         jmp     .ret
  2072. wmsetcursor:
  2073.         cmp     [ebp+tls.hCursor], 0
  2074.         jz      wmdef
  2075.         push    [ebp+tls.hCursor]
  2076.         call    [SetCursor]
  2077.         push    1
  2078.         pop     eax
  2079.         pop     ebp
  2080.         ret     10h
  2081. wmnclbuttondblclk:
  2082.         mov     al, byte [ebp+tls.color_main+3]
  2083.         and     al, 0xF
  2084.         jz      .nomaximize
  2085.         cmp     al, 1
  2086.         jz      .nomaximize
  2087.         cmp     al, 4
  2088.         jz      .nomaximize
  2089.         call    test_maximized
  2090.         mov     eax, 3  ; SW_MAXIMIZED
  2091.         jnz     @f
  2092.         mov     al, 1   ; SW_SHOWNORMAL
  2093. @@:
  2094.         push    eax
  2095.         push    [ebp+tls.hWnd]
  2096.         call    [ShowWindow]
  2097.         push    1
  2098.         push    0
  2099.         push    [ebp+tls.hWnd]
  2100.         call    [InvalidateRect]
  2101. .nomaximize:
  2102.         xor     eax, eax
  2103.         pop     ebp
  2104.         ret     10h
  2105. wmmove:
  2106.         mov     ax, [esp+0x10+4]
  2107.         mov     [ebp+tls.x_start], ax
  2108.         mov     ax, [esp+0x12+4]
  2109.         mov     [ebp+tls.y_start], ax
  2110. ;       jmp     wndproc_update_wnd
  2111.         xor     eax, eax
  2112.         pop     ebp
  2113.         ret     10h
  2114. wmsize:
  2115.         mov     ax, [esp+0x10+4]
  2116.         mov     [ebp+tls.x_size], ax
  2117.         mov     ax, [esp+0x12+4]
  2118.         mov     [ebp+tls.y_size], ax
  2119. ;       jmp     wndproc_update_wnd
  2120.         xor     eax, eax
  2121.         pop     ebp
  2122.         ret     10h
  2123. wmsizing:
  2124.         mov     eax, [esp+0x14]
  2125.         mov     ecx, [eax]
  2126.         mov     [ebp+tls.x_start], cx
  2127.         mov     ecx, [eax+4]
  2128.         mov     [ebp+tls.y_start], cx
  2129.         mov     ecx, [eax+8]
  2130.         sub     ecx, [eax]
  2131.         mov     [ebp+tls.x_size], cx
  2132.         mov     ecx, [eax+12]
  2133.         sub     ecx, [eax+4]
  2134.         mov     [ebp+tls.y_size], cx
  2135. ;       push    0
  2136. ;       push    0
  2137. ;       push    [ebp+tls.hWnd]
  2138. ;       call    [InvalidateRect]
  2139.         xor     eax, eax
  2140.         inc     eax
  2141.         pop     ebp
  2142.         ret     10h
  2143. wmsyskeydown:
  2144. ;       test    byte [esp+16+3+4], 20h  ; Alt pressed?
  2145. ;       jnz     wmdef
  2146.         cmp     byte [esp+16+2+4], 3Eh  ; Alt+F4?
  2147.         jz      wmdestroy
  2148. wmkeydown:
  2149.         movzx   eax, byte [esp+16+2+4]
  2150.         test    eax, eax
  2151.         jnz     @f
  2152.         mov     al, 1Ch         ; <Enter>
  2153. @@:
  2154.         cmp     [ebp+tls.usescancode], 0
  2155.         jnz     .putkeycode
  2156. ; ignore keys-modifiers
  2157.         cmp     al, 2Ah
  2158.         jz      .ret
  2159.         cmp     al, 36h
  2160.         jz      .ret
  2161.         cmp     al, 38h
  2162.         jz      .ret
  2163.         cmp     al, 1Dh
  2164.         jz      .ret
  2165.         cmp     al, 3Ah
  2166.         jz      .ret
  2167.         cmp     al, 45h
  2168.         jz      .ret
  2169.         cmp     al, 46h
  2170.         jz      .ret
  2171. ; translate NumPad keys
  2172.         test    byte [esp+14h+3], 1
  2173.         jnz     .nonumpad
  2174.         mov     cl, '*'
  2175.         cmp     al, 55
  2176.         jz      @f
  2177.         cmp     al, 71
  2178.         jb      .nonumpad
  2179.         cmp     al, 83
  2180.         ja      .nonumpad
  2181.         mov     cl, [numlock_map+eax-71]
  2182. @@:
  2183.         push    eax
  2184.         push    ecx
  2185.         sub     esp, 100h
  2186.         push    esp
  2187.         call    [GetKeyboardState]
  2188.         mov     al, [esp+0x90]  ; VK_NUMLOCK
  2189.         add     esp, 100h
  2190.         test    al, 1
  2191.         pop     ecx
  2192.         pop     eax
  2193.         jnz     .put_cl
  2194. .nonumpad:
  2195.         mov     cl, [keymap+eax]
  2196.         push    eax
  2197.         push    ecx
  2198.         push    0x11    ; VK_CONTROL
  2199.         call    [GetAsyncKeyState]
  2200.         test    ax, ax
  2201.         jns     @f
  2202.         sub     byte [esp], 60h
  2203. @@:
  2204.         push    0x10    ; VK_SHIFT
  2205.         call    [GetAsyncKeyState]
  2206.         test    ax, ax
  2207.         jns     @f
  2208.         pop     ecx
  2209.         pop     eax
  2210.         mov     cl, [keymap_shift+eax]
  2211.         push    eax
  2212.         push    ecx
  2213. @@:
  2214.         push    0x12    ; VK_MENU
  2215.         call    [GetAsyncKeyState]
  2216.         test    ax, ax
  2217.         pop     ecx
  2218.         pop     eax
  2219.         jns     @f
  2220.         mov     cl, [keymap_alt+eax]
  2221. @@:
  2222. .put_cl:
  2223.         xchg    eax, ecx
  2224. .putkeycode:
  2225.         movzx   ecx, [ebp+tls.keybuflen]
  2226.         inc     cl
  2227.         jz      .ret
  2228. ; test for extended key (0xE0 prefix)
  2229.         test    byte [esp+14h+3], 1     ; lParam+3
  2230.         jz      .noext
  2231.         cmp     [ebp+tls.usescancode], 0
  2232.         jz      .noext
  2233.         mov     [ebp+tls.keybuflen], cl
  2234.         mov     [ebp+tls.keybuffer+ecx-1], 0xE0
  2235.         inc     cl
  2236.         jz      .ret
  2237. .noext:
  2238.         mov     [ebp+tls.keybuflen], cl
  2239.         mov     [ebp+tls.keybuffer+ecx-1], al
  2240.         test    [ebp+tls.message_mask], 2
  2241.         jz      @f
  2242.         mov     [ebp+tls.translated_msg_code], 2
  2243. @@:
  2244. .ret:
  2245. wmchar:
  2246.         xor     eax, eax
  2247.         pop     ebp
  2248.         ret     10h
  2249. wmkeyup:
  2250. wmsyskeyup:
  2251.         cmp     [ebp+tls.usescancode], 0
  2252.         jz      wmkeydown.ret
  2253.         mov     al, [esp+16+2+4]
  2254.         or      al, 80h
  2255.         jmp     wmkeydown.putkeycode
  2256. ;wmchar:
  2257. ;       cmp     [usescancode], 0
  2258. ;       jnz     wmkeydown.ret
  2259. ;       mov     al, [esp+12]
  2260. ;       jmp     wmkeydown.putkeycode
  2261. wmlbuttondown:
  2262.         push    esi
  2263.         push    1
  2264.         jmp     @f
  2265. wmrbuttondown:
  2266.         push    esi
  2267.         push    2
  2268. @@:
  2269.         call    capture1
  2270.         mov     ax, [esp+0x10+12]       ; x
  2271.         mov     dx, [esp+0x12+12]       ; y
  2272.         call    find_button
  2273.         pop     eax
  2274.         test    esi, esi
  2275.         jnz     .onbutton
  2276.         test    [ebp+tls.message_mask], 20h
  2277.         jz      @f
  2278.         mov     [ebp+tls.translated_msg_code], 6
  2279. @@:
  2280. .done:
  2281.         pop     esi
  2282.         pop     ebp
  2283.         xor     eax, eax
  2284.         ret     10h
  2285. .onbutton:
  2286.         or      [ebp+tls.current_buttons], al
  2287.         cmp     [ebp+tls.original_buttons], 0
  2288.         jnz     @f
  2289.         mov     [ebp+tls.original_buttons], al
  2290. @@:
  2291.         mov     [ebp+tls.active_button], esi
  2292. ; don't highlight button if bit 29 is set
  2293.         test    [esi+button_desc.id], 20000000h
  2294.         jnz     .done
  2295. ; highlight - negate border
  2296.         call    negate_button_border
  2297.         jmp     .done
  2298. wmrbuttonup:
  2299.         push    -3
  2300.         jmp     @f
  2301. wmlbuttonup:
  2302.         push    -2
  2303. @@:
  2304.         call    capture2
  2305.         pop     eax
  2306.         cmp     [ebp+tls.active_button], 0
  2307.         jz      wmrbuttondown.nobutton
  2308.         and     [ebp+tls.current_buttons], al
  2309.         jnz     wmrbuttondown.nobutton
  2310.         push    esi
  2311.         xor     esi, esi
  2312.         xchg    esi, [ebp+tls.active_button]
  2313.         test    byte [esi+button_desc.id+3], 20h
  2314.         jnz     @f
  2315.         call    negate_button_border
  2316. @@:
  2317. ; minimize button - special handler (see event.inc)
  2318.         cmp     word [esi+button_desc.id], 0FFFFh
  2319.         jz      .minimize
  2320.         test    [ebp+tls.message_mask], 4
  2321.         jz      @f
  2322.         mov     [ebp+tls.translated_msg_code], 3
  2323. @@:
  2324.         test    [ebp+tls.message_mask], 20h
  2325.         jz      @f
  2326.         mov     [ebp+tls.translated_msg_code], 86h
  2327. @@:
  2328.         mov     [ebp+tls.bFirstMouseMove], 1
  2329.         movzx   ecx, [ebp+tls.butbuflen]
  2330.         inc     cl
  2331.         jz      @f
  2332.         mov     [ebp+tls.butbuflen], cl
  2333.         mov     eax, [esi+button_desc.id]
  2334.         shl     eax, 8
  2335.         mov     al, [ebp+tls.original_buttons]
  2336.         mov     [ebp+tls.butbuffer+ecx*4-4], eax
  2337. @@:
  2338.         mov     [ebp+tls.original_buttons], 0
  2339. .done:
  2340.         pop     esi
  2341. .ret:
  2342.         xor     eax, eax
  2343.         pop     ebp
  2344.         ret     10h
  2345. .minimize:
  2346.         call    minimize_window
  2347.         jmp     .done
  2348. wmrbuttondown.nobutton:
  2349. wmmousemove:
  2350.         cmp     [ebp+tls.bFirstMouseMove], 0
  2351.         mov     [ebp+tls.bFirstMouseMove], 0
  2352.         jnz     wmdef
  2353. vk_mouse:
  2354. ; N.B. Due of current implementation of buttons in the kernel
  2355. ; mouse events are NOT processed when any button is active!
  2356.         cmp     [ebp+tls.active_button], 0
  2357.         jnz     wmlbuttonup.ret
  2358.         test    [ebp+tls.message_mask], 20h
  2359.         jz      wmlbuttonup.ret
  2360.         mov     [ebp+tls.translated_msg_code], 6
  2361.         jmp     wmlbuttonup.ret
  2362. wmmousewheel:
  2363.         movsx   eax, word [esp+0xE+4]
  2364.         sub     [ebp+tls.scroll], eax
  2365.         jmp     vk_mouse
  2366. wm_ipc:
  2367.         test    [ebp+tls.message_mask], 40h
  2368.         jz      wmlbuttonup.ret
  2369.         mov     [ebp+tls.translated_msg_code], 7
  2370.         jmp     wmlbuttonup.ret
  2371. wm_debug1:
  2372.         test    byte [ebp+tls.message_mask+1], 1
  2373.         jz      .failed2
  2374.         push    edi
  2375.         call    get_cur_slot_ptr
  2376.         mov     edi, [edi+shared_data_struc.debugger_mem-shared_data_struc.threads]
  2377.         test    edi, edi
  2378.         jz      .failed
  2379.         add     edi, [base]
  2380.         mov     eax, [edi]
  2381.         mov     ecx, [edi+4]
  2382.         sub     eax, ecx
  2383.         cmp     eax, 12
  2384.         jl      .failed
  2385.         add     dword [edi+4], 12
  2386.         lea     edi, [edi+ecx+8]
  2387.         xor     eax, eax
  2388.         inc     eax
  2389.         stosd
  2390.         push    edi
  2391.         mov     eax, [esp+0xC+12]
  2392.         call    get_slot_ptr
  2393.         mov     eax, [edi]
  2394.         pop     edi
  2395.         stosd
  2396.         mov     eax, [esp+0x10+8]
  2397. ; translate Win32 exception code to x86 exception vector
  2398.         cmp     eax, 0x80000004
  2399.         jz      .singlestep
  2400.         xor     ecx, ecx
  2401.         push    edi
  2402.         mov     edi, exccode2number-5
  2403. .1:
  2404.         add     edi, 5
  2405.         cmp     eax, [edi]
  2406.         jnz     .2
  2407.         mov     cl, [edi+4]
  2408.         jmp     .3
  2409. .2:
  2410.         cmp     dword [edi], ecx
  2411.         jnz     .1
  2412.         mov     cl, 0xD         ; translate unrecognized codes to #GP
  2413. .3:
  2414.         pop     edi
  2415.         jmp     .4
  2416. .singlestep:
  2417.         push    ebx
  2418.         mov     ecx, [edi-4]
  2419.         call    find_debuggee
  2420.         mov     ecx, ebx
  2421.         pop     ebx
  2422.         jecxz   .failed
  2423.         sub     esp, 0xB2*4
  2424.         push    1001Fh
  2425.         push    esp
  2426.         push    dword [ecx+12]
  2427.         call    [GetThreadContext]
  2428.         mov     ecx, [esp+0x14]         ; DR6
  2429.         mov     byte [edi-8], 3         ; signal #DB
  2430.         add     esp, 0xB3*4
  2431. .4:
  2432.         mov     [edi], ecx
  2433. .written:
  2434.         pop     edi
  2435.         mov     [ebp+tls.translated_msg_code], 9
  2436.         jmp     wmlbuttonup.ret
  2437. .failed:
  2438.         pop     edi
  2439. .failed2:
  2440.         push    40h
  2441.         push    0
  2442.         push    aFailedToDeliverDebugMessage
  2443.         push    [ebp+tls.hWnd]
  2444.         call    [MessageBoxA]
  2445.         jmp     wmlbuttonup.ret
  2446. wm_debug2:
  2447.         test    byte [ebp+tls.message_mask+1], 1
  2448.         jz      wm_debug1.failed2
  2449.         push    edi
  2450.         call    get_cur_slot_ptr
  2451.         mov     edi, [edi+shared_data_struc.debugger_mem-shared_data_struc.threads]
  2452.         test    edi, edi
  2453.         jz      wm_debug1.failed
  2454.         add     edi, [base]
  2455.         mov     eax, [edi]
  2456.         mov     ecx, [edi+4]
  2457.         sub     eax, ecx
  2458.         cmp     eax, 8
  2459.         jl      wm_debug1.failed
  2460.         add     dword [edi+4], 8
  2461.         lea     edi, [edi+ecx+8]
  2462.         push    2
  2463.         pop     eax
  2464.         stosd
  2465.         push    edi
  2466.         mov     eax, [esp+0xC+12]
  2467.         call    get_slot_ptr
  2468.         mov     eax, [edi]
  2469.         pop     edi
  2470.         stosd
  2471. ; delete this item from debuggees list
  2472.         lea     ecx, [ebp+tls.debuggees]
  2473. @@:
  2474.         mov     edx, [ecx]
  2475.         test    edx, edx
  2476.         jz      wm_debug1.written
  2477.         cmp     dword [edx+4], eax
  2478.         jz      .found
  2479.         mov     ecx, edx
  2480.         jmp     @b
  2481. .found:
  2482.         push    dword [edx]
  2483.         push    ecx
  2484.         push    edx
  2485.         call    free
  2486.         pop     ecx
  2487.         pop     dword [ecx]
  2488.         jmp     wm_debug1.written
  2489.  
  2490. wmgetminmaxinfo:
  2491.         mov     ecx, [shared_data]
  2492.         cmp     [ecx+shared_data_struc.vk], 0
  2493.         jnz     @f
  2494.         sub     esp, 10h
  2495.         mov     eax, esp
  2496.         push    0
  2497.         push    eax
  2498.         push    0
  2499.         push    30h     ; SPI_GETWORKAREA
  2500.         call    [SystemParametersInfoA]
  2501.         mov     eax, [esp+20+10h]       ; lParam
  2502.         mov     ecx, esp
  2503.         mov     edx, [ecx]
  2504.         mov     [eax+10h], edx
  2505.         mov     edx, [ecx+4]
  2506.         mov     [eax+14h], edx
  2507.         mov     edx, [ecx+8]
  2508.         sub     edx, [ecx]
  2509.         mov     [eax+8], edx
  2510.         mov     edx, [ecx+12]
  2511.         sub     edx, [ecx+4]
  2512.         mov     [eax+0Ch], edx
  2513.         add     esp, 10h
  2514.         jmp     .ret
  2515. @@:
  2516.         call    acquire_shared
  2517.         mov     eax, [esp+20]   ; lParam
  2518.         mov     edx, [ecx+shared_data_struc.workarea_left]
  2519.         mov     [eax+10h], edx
  2520.         mov     edx, [ecx+shared_data_struc.workarea_top]
  2521.         mov     [eax+14h], edx
  2522.         mov     edx, [ecx+shared_data_struc.workarea_right]
  2523.         sub     edx, [ecx+shared_data_struc.workarea_left]
  2524.         mov     [eax+8], edx
  2525.         mov     edx, [ecx+shared_data_struc.workarea_bottom]
  2526.         sub     edx, [ecx+shared_data_struc.workarea_top]
  2527.         mov     [eax+0Ch], edx
  2528.         call    release_shared
  2529. .ret:
  2530.         xor     eax, eax
  2531.         pop     ebp
  2532.         ret     10h
  2533.  
  2534. find_button:
  2535.         mov     esi, [ebp+tls.buttons]
  2536. .loop:
  2537.         test    esi, esi
  2538.         jz      .done
  2539.         push    eax
  2540.         sub     ax, [esi+button_desc.xstart]
  2541.         cmp     ax,