812bae4a84
git-svn-id: svn://kolibrios.org@2783 a494cfbc-eb01-0410-851d-a64ba20cac60
493 lines
9.4 KiB
NASM
493 lines
9.4 KiB
NASM
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
|