Subversion Repositories Kolibri OS

Rev

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

  1.         format PE GUI 4.0
  2. section '.text' code readable executable
  3. entry start
  4. start:
  5.         xor     ebx, ebx
  6.         mov     esi, a2_src
  7.         mov     edi, a2
  8.         movsd
  9.         movsd
  10.         movsd
  11.         movsd
  12.         movsd
  13.         push    1
  14.         call    [SetErrorMode]
  15.         push    ebx     ; lpParam
  16.         push    400000h ; hInstance
  17.         push    ebx     ; hMenu
  18.         push    ebx     ; hWndParent
  19.         push    100     ; nHeight
  20.         push    200     ; nWidth
  21.         mov     eax, 80000000h
  22.         push    eax     ; y
  23.         push    eax     ; x
  24.         push    10EF0140h       ; dwStyle
  25.         push    WndName
  26.         push    ClassName
  27.         push    388h    ; dwExStyle
  28.         call    [CreateWindowExA]
  29.         xchg    edi, eax
  30.         push    0Ah     ; OEM_FIXED_FONT
  31.         call    [GetStockObject]
  32.         push    ebx
  33.         push    eax
  34.         push    30h     ; WM_SETFONT
  35.         call    ListCommand
  36.         call    CollectDrivesInfo
  37.         push    MyWndProc
  38.         push    -4      ; GWL_WNDPROC
  39.         push    edi
  40.         call    [SetWindowLongA]
  41.         mov     [OldWndProc], eax
  42.         sub     esp, 20h
  43.         mov     esi, esp
  44. @@:
  45.         push    ebx
  46.         push    ebx
  47.         push    ebx
  48.         push    esi
  49.         call    [GetMessageA]
  50.         test    eax, eax
  51.         jz      @f
  52.         push    esi
  53.         call    [TranslateMessage]
  54.         push    esi
  55.         call    [DispatchMessageA]
  56.         jmp     @b
  57. @@:
  58.         add     esp, 20h
  59.         ret
  60.  
  61. ListCommand:
  62.         pop     eax
  63.         push    edi
  64.         push    eax
  65.         jmp     [SendMessageA]
  66.  
  67. MyWndProc:
  68.         push    edi ebx
  69.         xor     ebx, ebx
  70.         mov     edi, [esp+12]
  71.         cmp     dword [esp+16], 2       ; WM_DESTROY
  72.         jnz     @f
  73.         push    ebx
  74.         call    [PostQuitMessage]
  75. @@:
  76.         cmp     dword [esp+16], 219h    ; WM_DEVICECHANGE
  77.         jnz     w
  78.         cmp     dword [esp+20], 8000h   ; DBT_DEVICEARRIVAL
  79.         jz      @f
  80.         cmp     dword [esp+20], 8004h   ; DBT_DEVICEREMOVECOMPLETE
  81.         jnz     w
  82. @@:
  83.         call    UpdateDrivesInfo
  84. w:
  85.         cmp     dword [esp+16], 203h    ; WM_LBUTTONDBLCLK
  86.         jnz     @f
  87.         push    ebx
  88.         push    ebx
  89.         push    188h    ; LB_GETCURSEL
  90.         call    ListCommand
  91.         cmp     eax, -1
  92.         jz      @f
  93.         push    n
  94.         push    eax
  95.         push    189h    ; LB_GETTEXT
  96.         call    ListCommand
  97.         mov     eax, n
  98.         mov     byte [eax+2], bl
  99.         mov     edx, [eax]
  100.         mov     [mtldr_out], dl
  101.         mov     dword [eax], '\\.\'
  102.         mov     dword [eax+4], edx
  103.         call    install
  104. @@:
  105.         pop     ebx edi
  106.         pop     eax
  107.         push    [OldWndProc]
  108.         push    eax
  109.         jmp     [CallWindowProcA]
  110.  
  111. UpdateDrivesInfo:
  112.         push    ebx
  113.         push    ebx
  114.         push    184h    ; LB_RESETCONTENT
  115.         call    ListCommand
  116.  
  117. CollectDrivesInfo:
  118.         push    esi
  119.         call    [GetLogicalDrives]
  120.         mov     esi, eax
  121.         mov     edx, a
  122.         mov     byte [edx], 'A'
  123. l:
  124.         shr     esi, 1
  125.         jnc     d
  126.         mov     [edx+2], bl
  127.         push    edx
  128.         call    [GetDriveTypeA]
  129. ; Uncomment following lines to allow hard drives
  130. ;       cmp     eax, 3  ; DRIVE_FIXED
  131. ;       jz      @f
  132.         cmp     eax, 2  ; DRIVE_REMOVABLE
  133.         jnz     d
  134.         push    ebx     ; hTemplateFile
  135.         push    ebx     ; dwFlagsAndAttributes
  136.         push    3       ; dwCreationDisposition = OPEN_EXISTING
  137.         push    ebx     ; lpSecurityAttributes
  138.         push    3       ; dwShareMode = FILE_SHARE_READ|FILE_SHARE_WRITE
  139.         push    ebx     ; dwDesiredAccess
  140.         push    a2
  141.         call    [CreateFileA]
  142.         cmp     eax, -1
  143.         jz      d
  144.         push    eax
  145.         push    ebx
  146.         mov     ecx, esp
  147.         push    ebx     ; lpOverlapped
  148.         push    ecx     ; lpBytesReturned
  149.         push    1024    ; nOutBufferSize
  150.         push    n       ; lpOutBuffer
  151.         push    ebx
  152.         push    ebx
  153.         push    70C00h  ; IOCTL_DISK_GET_MEDIA_TYPES
  154.         push    eax
  155.         call    [DeviceIoControl]
  156.         pop     ecx
  157.         pop     eax
  158.         push    ecx
  159.         push    eax
  160.         call    [CloseHandle]
  161.         pop     ecx
  162.         jecxz   @f      ; not supported => OK
  163.         cmp     byte [n+8], 11
  164.         jnz     d
  165. @@:
  166.         mov     eax, a
  167.         mov     ecx, n
  168.         mov     byte [eax+2], '\'
  169.         push    ecx
  170.         push    ebx     ; nFileSystemNameSize
  171.         push    ebx     ; lpFileSystemNameBuffer
  172.         push    ebx     ; lpFileSystemFlags
  173.         push    ebx     ; lpMaximumComponentLength
  174.         push    ebx     ; lpVolumeSerialNumber
  175.         push    1024    ; nVolumeNameSize
  176.         mov     edx, [eax]
  177.         mov     [ecx], edx
  178.         mov     word [ecx+3], ' ['
  179.         add     ecx, 5
  180.         mov     byte [ecx], bl
  181.         push    ecx     ; lpVolumeNameBuffer
  182.         push    eax     ; lpRootPathName
  183.         call    [GetVolumeInformationA]
  184.         pop     eax
  185.         push    eax
  186.         cmp     byte [eax+5], bl
  187.         jz      nol
  188. @@:
  189.         inc     eax
  190.         cmp     byte [eax-1], bl
  191.         jnz     @b
  192.         mov     word [eax-1], ']'
  193. ;       jmp     @f
  194. nol:
  195.         mov     byte [eax+3], bl
  196. @@:
  197.         push    ebx
  198.         push    180h    ; LB_ADDSTRING
  199.         call    ListCommand
  200. d:
  201.         mov     edx, a
  202.         inc     byte [edx]
  203.         test    esi, esi
  204.         jnz     l
  205.         pop     esi
  206.         ret
  207.  
  208. install:
  209.         push    ebx     ; hTemplateFile
  210.         push    ebx     ; dwFlagsAndAttributes
  211.         push    3       ; dwCreationDisposition = OPEN_EXISTING
  212.         push    ebx     ; lpSecurityAttributes
  213.         push    3       ; dwShareMode = FILE_SHARE_READ|FILE_SHARE_WRITE
  214.         push    0C0000000h      ; dwDesiredAccess = GENERIC_READ|GENERIC_WRITE
  215.         push    eax
  216.         call    [CreateFileA]
  217.         cmp     eax, -1
  218.         jz      deverre
  219.         push    esi ebp
  220.         mov     ebp, bootsect_dev
  221.         xchg    esi, eax
  222.         push    eax
  223.         mov     eax, esp
  224.         push    ebx
  225.         push    eax
  226.         push    512
  227.         push    ebp
  228.         push    esi
  229.         call    [ReadFile]
  230.         test    eax, eax
  231.         jnz     @f
  232. deverrl:
  233.         push    esi
  234.         call    [CloseHandle]
  235.         pop     eax
  236.         pop     ebp esi
  237. deverre:
  238.         push    10h
  239.         push    ebx
  240.         push    deverr
  241.         push    edi
  242.         call    [MessageBoxA]
  243.         ret
  244. @@:
  245. ; make sure that this is FAT32 volume
  246.         cmp     word [ebp+0Bh], 200h    ; bytes per sector
  247.         jnz     bootinv
  248.         cmp     word [ebp+0Eh], bx      ; reserved sectors
  249.         jz      bootinv
  250.         cmp     byte [ebp+10h], bl      ; number of FATs
  251.         jz      bootinv
  252.         cmp     word [ebp+11h], bx      ; root dir entries
  253.         jnz     bootinv                 ; must be 0 for FAT32
  254.         cmp     word [ebp+16h], bx      ; length of one copy of FAT1x
  255.         jnz     bootinv
  256.         cmp     dword [ebp+20h], ebx    ; length of one copy of FAT32
  257.         jz      bootinv
  258.         cmp     byte [ebp+42h], ')'     ; magic value
  259.         jz      @f
  260. bootinv:
  261.         push    10h
  262.         push    ebx
  263.         push    nofat32
  264.         jmp     re
  265. @@:
  266. ; ok, this is really correct FAT32 volume, so start install
  267. ; copy file mtldr_f
  268.         push    80h
  269.         push    mtldr_out
  270.         call    [SetFileAttributesA]
  271.         push    ebx     ; bFailIfExists
  272.         push    mtldr_out       ; lpNewFileName
  273.         push    mtldr_in        ; lpExistingFileName
  274.         call    [CopyFileA]
  275.         test    eax, eax
  276.         jnz     @f
  277.         push    10h
  278.         push    ebx
  279.         push    mterr
  280. re:
  281.         push    edi
  282.         call    [MessageBoxA]
  283.         jmp     r
  284. @@:
  285.         push    7
  286.         push    mtldr_out
  287.         call    [SetFileAttributesA]
  288. ; load bootsector
  289.         push    ebx     ; hTemplateFile
  290.         push    ebx     ; dwFlagsAndAttributes
  291.         push    3       ; dwCreationDisposition = OPEN_EXISTING
  292.         push    ebx     ; lpSecurityAttributes
  293.         push    1       ; dwShareMode = FILE_SHARE_READ
  294.         push    80000000h       ; dwDesiredAccess = GENERIC_READ
  295.         push    btname
  296.         call    [CreateFileA]
  297.         cmp     eax, -1
  298.         jnz     @f
  299. bterrc:
  300.         push    40h
  301.         push    ebx
  302.         push    bterr
  303.         jmp     re
  304. @@:
  305.         mov     ecx, esp
  306.         push    eax
  307.         push    ebx
  308.         push    ecx
  309.         push    512
  310.         push    bootsect_new
  311.         push    eax
  312.         call    [ReadFile]
  313.         pop     ecx
  314.         push    eax
  315.         push    ecx
  316.         call    [CloseHandle]
  317.         pop     eax
  318.         test    eax, eax
  319.         jz      bterrc
  320.         cmp     dword [esp], 512
  321.         jnz     bterrc
  322. ; patch bootsector with real values
  323.         push    esi edi
  324.         mov     esi, bootsect_new
  325.         mov     edi, bootsect_dev
  326.         movsb
  327.         movsb
  328.         movsb
  329.         add     esi, 57h
  330.         add     edi, 57h
  331.         mov     ecx, 200h-5Ah
  332.         rep     movsb
  333.         pop     edi esi
  334. ; write bootsector
  335.         push    ebx
  336.         push    ebx
  337.         push    ebx
  338.         push    esi
  339.         call    [SetFilePointer]
  340.         test    eax, eax
  341.         jnz     deverrl
  342.         mov     eax, esp
  343.         push    ebx
  344.         push    eax
  345.         push    512
  346.         push    ebp
  347.         push    esi
  348.         call    [WriteFile]
  349.         test    eax, eax
  350.         jz      deverrl
  351.         cmp     dword [esp], 512
  352.         jnz     deverrl
  353. ; Patch backup copy of boot sector, ignore errors
  354.         movzx   eax, word [ebp+50]
  355.         test    eax, eax
  356.         jz      done_succ
  357. ; sanity check: it must be in the reserved area, not in data
  358.         cmp     ax, word [ebp+14]
  359.         jae     done_succ
  360.         shl     eax, 9
  361.         push    ebx
  362.         push    ebx
  363.         push    eax
  364.         push    esi
  365.         call    [SetFilePointer]
  366.         cmp     eax, -1
  367.         jz      done_succ
  368.         mov     eax, esp
  369.         push    ebx
  370.         push    eax
  371.         push    512
  372.         push    ebp
  373.         push    esi
  374.         call    [WriteFile]
  375. ; done!
  376. done_succ:
  377.         push    40h
  378.         push    ok
  379.         push    succ
  380.         push    edi
  381.         call    [MessageBoxA]
  382.         push    ebx
  383.         call    [PostQuitMessage]
  384. r:
  385.         pop     eax
  386.         push    esi
  387.         call    [CloseHandle]
  388.         pop     ebp esi
  389.         ret
  390.  
  391. section '.rdata' data readable
  392.  
  393. data resource from 'rsrc.res'
  394. end data
  395.  
  396. ClassName db    'LISTBOX',0
  397. WndName db      'Select drive',0
  398. deverr  db      'Cannot open physical device or device error (no administrator rights?)',0
  399. nofat32 db      'Not FAT32 volume. Sorry, only FAT32 is supported at moment.',0
  400. ok      db      'Success',0
  401. succ    db      'Kolibri flash loader was successfully installed!',10
  402.         db      'Now you can copy the image kolibri.img and boot!',0
  403. mterr   db      'Cannot copy MTLD_F32',0
  404. bterr   db      'Cannot load '
  405. btname  db      'BOOT_F32.BIN',0
  406.  
  407. data import
  408. macro thunk a
  409. {a#_thunk:dw 0
  410. db `a,0}
  411.         dd      0,0,0, rva kernel32_name, rva kernel32_thunks
  412.         dd      0,0,0, rva user32_name, rva user32_thunks
  413.         dd      0,0,0, rva gdi32_name, rva gdi32_thunks
  414.         dd      0,0,0,0,0
  415. kernel32_name   db      'kernel32.dll',0
  416. user32_name     db      'user32.dll',0
  417. gdi32_name      db      'gdi32.dll',0
  418. kernel32_thunks:
  419. GetLogicalDrives        dd      rva GetLogicalDrives_thunk
  420. GetDriveTypeA           dd      rva GetDriveTypeA_thunk
  421. GetVolumeInformationA   dd      rva GetVolumeInformationA_thunk
  422. CreateFileA             dd      rva CreateFileA_thunk
  423. ReadFile                dd      rva ReadFile_thunk
  424. WriteFile               dd      rva WriteFile_thunk
  425. SetFilePointer          dd      rva SetFilePointer_thunk
  426. CloseHandle             dd      rva CloseHandle_thunk
  427. SetErrorMode            dd      rva SetErrorMode_thunk
  428. CopyFileA               dd      rva CopyFileA_thunk
  429. SetFileAttributesA      dd      rva SetFileAttributesA_thunk
  430. DeviceIoControl         dd      rva DeviceIoControl_thunk
  431.         dw      0
  432. thunk GetLogicalDrives
  433. thunk GetDriveTypeA
  434. thunk GetVolumeInformationA
  435. thunk CreateFileA
  436. thunk ReadFile
  437. thunk WriteFile
  438. thunk SetFilePointer
  439. thunk CloseHandle
  440. thunk SetErrorMode
  441. thunk CopyFileA
  442. thunk SetFileAttributesA
  443. thunk DeviceIoControl
  444. user32_thunks:
  445. CreateWindowExA         dd      rva CreateWindowExA_thunk
  446. GetMessageA             dd      rva GetMessageA_thunk
  447. TranslateMessage        dd      rva TranslateMessage_thunk
  448. DispatchMessageA        dd      rva DispatchMessageA_thunk
  449. PostQuitMessage         dd      rva PostQuitMessage_thunk
  450. CallWindowProcA         dd      rva CallWindowProcA_thunk
  451. SetWindowLongA          dd      rva SetWindowLongA_thunk
  452. SendMessageA            dd      rva SendMessageA_thunk
  453. MessageBoxA             dd      rva MessageBoxA_thunk
  454.         dw      0
  455. thunk CreateWindowExA
  456. thunk GetMessageA
  457. thunk TranslateMessage
  458. thunk DispatchMessageA
  459. thunk PostQuitMessage
  460. thunk CallWindowProcA
  461. thunk SetWindowLongA
  462. thunk SendMessageA
  463. thunk MessageBoxA
  464. gdi32_thunks:
  465. GetStockObject          dd      rva GetStockObject_thunk
  466.         dw      0
  467. thunk GetStockObject
  468. end data
  469.  
  470. a2_src:
  471.         db      '\\.\'
  472.         db      '?:',0,0
  473.         db      '?:\'
  474.         db      'MTLD_F32',0
  475.  
  476. section '.data' data readable writable
  477.  
  478. ;a2     db      '\\.\'
  479. ;a      db      '?:',0,0
  480. ;mtldr_out      db      '?:\'
  481. ;mtldr_in       db      'MTLD_F32',0
  482. a2      rb      4
  483. a       rb      4
  484. mtldr_out       rb      3
  485. mtldr_in        rb      9
  486.  
  487. align 4
  488. OldWndProc      dd      ?
  489. devpath         rb      1024
  490. n               rb      1032
  491. bootsect_dev    rb      512
  492. bootsect_new    rb      512
  493.