kolibrios-fun/programs/hd_load/usb_boot/inst.asm

493 lines
9.4 KiB
NASM
Raw Normal View History

format PE GUI 4.0
section '.text' code readable executable
entry start
start:
xor ebx, ebx
mov esi, a2_src
mov edi, a2
movsd
movsd
movsd
movsd
movsd
push 1
call [SetErrorMode]
push ebx ; lpParam
push 400000h ; hInstance
push ebx ; hMenu
push ebx ; hWndParent
push 100 ; nHeight
push 200 ; nWidth
mov eax, 80000000h
push eax ; y
push eax ; x
push 10EF0140h ; dwStyle
push WndName
push ClassName
push 388h ; dwExStyle
call [CreateWindowExA]
xchg edi, eax
push 0Ah ; OEM_FIXED_FONT
call [GetStockObject]
push ebx
push eax
push 30h ; WM_SETFONT
call ListCommand
call CollectDrivesInfo
push MyWndProc
push -4 ; GWL_WNDPROC
push edi
call [SetWindowLongA]
mov [OldWndProc], eax
sub esp, 20h
mov esi, esp
@@:
push ebx
push ebx
push ebx
push esi
call [GetMessageA]
test eax, eax
jz @f
push esi
call [TranslateMessage]
push esi
call [DispatchMessageA]
jmp @b
@@:
add esp, 20h
ret
ListCommand:
pop eax
push edi
push eax
jmp [SendMessageA]
MyWndProc:
push edi ebx
xor ebx, ebx
mov edi, [esp+12]
cmp dword [esp+16], 2 ; WM_DESTROY
jnz @f
push ebx
call [PostQuitMessage]
@@:
cmp dword [esp+16], 219h ; WM_DEVICECHANGE
jnz w
cmp dword [esp+20], 8000h ; DBT_DEVICEARRIVAL
jz @f
cmp dword [esp+20], 8004h ; DBT_DEVICEREMOVECOMPLETE
jnz w
@@:
call UpdateDrivesInfo
w:
cmp dword [esp+16], 203h ; WM_LBUTTONDBLCLK
jnz @f
push ebx
push ebx
push 188h ; LB_GETCURSEL
call ListCommand
cmp eax, -1
jz @f
push n
push eax
push 189h ; LB_GETTEXT
call ListCommand
mov eax, n
mov byte [eax+2], bl
mov edx, [eax]
mov [mtldr_out], dl
mov dword [eax], '\\.\'
mov dword [eax+4], edx
call install
@@:
pop ebx edi
pop eax
push [OldWndProc]
push eax
jmp [CallWindowProcA]
UpdateDrivesInfo:
push ebx
push ebx
push 184h ; LB_RESETCONTENT
call ListCommand
CollectDrivesInfo:
push esi
call [GetLogicalDrives]
mov esi, eax
mov edx, a
mov byte [edx], 'A'
l:
shr esi, 1
jnc d
mov [edx+2], bl
push edx
call [GetDriveTypeA]
; Uncomment following lines to allow hard drives
; cmp eax, 3 ; DRIVE_FIXED
; jz @f
cmp eax, 2 ; DRIVE_REMOVABLE
jnz d
push ebx ; hTemplateFile
push ebx ; dwFlagsAndAttributes
push 3 ; dwCreationDisposition = OPEN_EXISTING
push ebx ; lpSecurityAttributes
push 3 ; dwShareMode = FILE_SHARE_READ|FILE_SHARE_WRITE
push ebx ; dwDesiredAccess
push a2
call [CreateFileA]
cmp eax, -1
jz d
push eax
push ebx
mov ecx, esp
push ebx ; lpOverlapped
push ecx ; lpBytesReturned
push 1024 ; nOutBufferSize
push n ; lpOutBuffer
push ebx
push ebx
push 70C00h ; IOCTL_DISK_GET_MEDIA_TYPES
push eax
call [DeviceIoControl]
pop ecx
pop eax
push ecx
push eax
call [CloseHandle]
pop ecx
jecxz @f ; not supported => OK
cmp byte [n+8], 11
jnz d
@@:
mov eax, a
mov ecx, n
mov byte [eax+2], '\'
push ecx
push ebx ; nFileSystemNameSize
push ebx ; lpFileSystemNameBuffer
push ebx ; lpFileSystemFlags
push ebx ; lpMaximumComponentLength
push ebx ; lpVolumeSerialNumber
push 1024 ; nVolumeNameSize
mov edx, [eax]
mov [ecx], edx
mov word [ecx+3], ' ['
add ecx, 5
mov byte [ecx], bl
push ecx ; lpVolumeNameBuffer
push eax ; lpRootPathName
call [GetVolumeInformationA]
pop eax
push eax
cmp byte [eax+5], bl
jz nol
@@:
inc eax
cmp byte [eax-1], bl
jnz @b
mov word [eax-1], ']'
; jmp @f
nol:
mov byte [eax+3], bl
@@:
push ebx
push 180h ; LB_ADDSTRING
call ListCommand
d:
mov edx, a
inc byte [edx]
test esi, esi
jnz l
pop esi
ret
install:
push ebx ; hTemplateFile
push ebx ; dwFlagsAndAttributes
push 3 ; dwCreationDisposition = OPEN_EXISTING
push ebx ; lpSecurityAttributes
push 3 ; dwShareMode = FILE_SHARE_READ|FILE_SHARE_WRITE
push 0C0000000h ; dwDesiredAccess = GENERIC_READ|GENERIC_WRITE
push eax
call [CreateFileA]
cmp eax, -1
jz deverre
push esi ebp
mov ebp, bootsect_dev
xchg esi, eax
push eax
mov eax, esp
push ebx
push eax
push 512
push ebp
push esi
call [ReadFile]
test eax, eax
jnz @f
deverrl:
push esi
call [CloseHandle]
pop eax
pop ebp esi
deverre:
push 10h
push ebx
push deverr
push edi
call [MessageBoxA]
ret
@@:
; make sure that this is FAT32 volume
cmp word [ebp+0Bh], 200h ; bytes per sector
jnz bootinv
cmp word [ebp+0Eh], bx ; reserved sectors
jz bootinv
cmp byte [ebp+10h], bl ; number of FATs
jz bootinv
cmp word [ebp+11h], bx ; root dir entries
jnz bootinv ; must be 0 for FAT32
cmp word [ebp+16h], bx ; length of one copy of FAT1x
jnz bootinv
cmp dword [ebp+20h], ebx ; length of one copy of FAT32
jz bootinv
cmp byte [ebp+42h], ')' ; magic value
jz @f
bootinv:
push 10h
push ebx
push nofat32
jmp re
@@:
; ok, this is really correct FAT32 volume, so start install
; copy file mtldr_f
push 80h
push mtldr_out
call [SetFileAttributesA]
push ebx ; bFailIfExists
push mtldr_out ; lpNewFileName
push mtldr_in ; lpExistingFileName
call [CopyFileA]
test eax, eax
jnz @f
push 10h
push ebx
push mterr
re:
push edi
call [MessageBoxA]
jmp r
@@:
push 7
push mtldr_out
call [SetFileAttributesA]
; load bootsector
push ebx ; hTemplateFile
push ebx ; dwFlagsAndAttributes
push 3 ; dwCreationDisposition = OPEN_EXISTING
push ebx ; lpSecurityAttributes
push 1 ; dwShareMode = FILE_SHARE_READ
push 80000000h ; dwDesiredAccess = GENERIC_READ
push btname
call [CreateFileA]
cmp eax, -1
jnz @f
bterrc:
push 40h
push ebx
push bterr
jmp re
@@:
mov ecx, esp
push eax
push ebx
push ecx
push 512
push bootsect_new
push eax
call [ReadFile]
pop ecx
push eax
push ecx
call [CloseHandle]
pop eax
test eax, eax
jz bterrc
cmp dword [esp], 512
jnz bterrc
; patch bootsector with real values
push esi edi
mov esi, bootsect_new
mov edi, bootsect_dev
movsb
movsb
movsb
add esi, 57h
add edi, 57h
mov ecx, 200h-5Ah
rep movsb
pop edi esi
; write bootsector
push ebx
push ebx
push ebx
push esi
call [SetFilePointer]
test eax, eax
jnz deverrl
mov eax, esp
push ebx
push eax
push 512
push ebp
push esi
call [WriteFile]
test eax, eax
jz deverrl
cmp dword [esp], 512
jnz deverrl
; Patch backup copy of boot sector, ignore errors
movzx eax, word [ebp+50]
test eax, eax
jz done_succ
; sanity check: it must be in the reserved area, not in data
cmp ax, word [ebp+14]
jae done_succ
shl eax, 9
push ebx
push ebx
push eax
push esi
call [SetFilePointer]
cmp eax, -1
jz done_succ
mov eax, esp
push ebx
push eax
push 512
push ebp
push esi
call [WriteFile]
; done!
done_succ:
push 40h
push ok
push succ
push edi
call [MessageBoxA]
push ebx
call [PostQuitMessage]
r:
pop eax
push esi
call [CloseHandle]
pop ebp esi
ret
section '.rdata' data readable
data resource from 'rsrc.res'
end data
ClassName db 'LISTBOX',0
WndName db 'Select drive',0
deverr db 'Cannot open physical device or device error (no administrator rights?)',0
nofat32 db 'Not FAT32 volume. Sorry, only FAT32 is supported at moment.',0
ok db 'Success',0
succ db 'Kolibri flash loader was successfully installed!',10
db 'Now you can copy the image kolibri.img and boot!',0
mterr db 'Cannot copy MTLD_F32',0
bterr db 'Cannot load '
btname db 'BOOT_F32.BIN',0
data import
macro thunk a
{a#_thunk:dw 0
db `a,0}
dd 0,0,0, rva kernel32_name, rva kernel32_thunks
dd 0,0,0, rva user32_name, rva user32_thunks
dd 0,0,0, rva gdi32_name, rva gdi32_thunks
dd 0,0,0,0,0
kernel32_name db 'kernel32.dll',0
user32_name db 'user32.dll',0
gdi32_name db 'gdi32.dll',0
kernel32_thunks:
GetLogicalDrives dd rva GetLogicalDrives_thunk
GetDriveTypeA dd rva GetDriveTypeA_thunk
GetVolumeInformationA dd rva GetVolumeInformationA_thunk
CreateFileA dd rva CreateFileA_thunk
ReadFile dd rva ReadFile_thunk
WriteFile dd rva WriteFile_thunk
SetFilePointer dd rva SetFilePointer_thunk
CloseHandle dd rva CloseHandle_thunk
SetErrorMode dd rva SetErrorMode_thunk
CopyFileA dd rva CopyFileA_thunk
SetFileAttributesA dd rva SetFileAttributesA_thunk
DeviceIoControl dd rva DeviceIoControl_thunk
dw 0
thunk GetLogicalDrives
thunk GetDriveTypeA
thunk GetVolumeInformationA
thunk CreateFileA
thunk ReadFile
thunk WriteFile
thunk SetFilePointer
thunk CloseHandle
thunk SetErrorMode
thunk CopyFileA
thunk SetFileAttributesA
thunk DeviceIoControl
user32_thunks:
CreateWindowExA dd rva CreateWindowExA_thunk
GetMessageA dd rva GetMessageA_thunk
TranslateMessage dd rva TranslateMessage_thunk
DispatchMessageA dd rva DispatchMessageA_thunk
PostQuitMessage dd rva PostQuitMessage_thunk
CallWindowProcA dd rva CallWindowProcA_thunk
SetWindowLongA dd rva SetWindowLongA_thunk
SendMessageA dd rva SendMessageA_thunk
MessageBoxA dd rva MessageBoxA_thunk
dw 0
thunk CreateWindowExA
thunk GetMessageA
thunk TranslateMessage
thunk DispatchMessageA
thunk PostQuitMessage
thunk CallWindowProcA
thunk SetWindowLongA
thunk SendMessageA
thunk MessageBoxA
gdi32_thunks:
GetStockObject dd rva GetStockObject_thunk
dw 0
thunk GetStockObject
end data
a2_src:
db '\\.\'
db '?:',0,0
db '?:\'
db 'MTLD_F32',0
section '.data' data readable writable
;a2 db '\\.\'
;a db '?:',0,0
;mtldr_out db '?:\'
;mtldr_in db 'MTLD_F32',0
a2 rb 4
a rb 4
mtldr_out rb 3
mtldr_in rb 9
align 4
OldWndProc dd ?
devpath rb 1024
n rb 1032
bootsect_dev rb 512
bootsect_new rb 512