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

390 lines
6.8 KiB
NASM
Raw Normal View History

format PE GUI 4.0
section '.text' code readable executable
entry start
start:
xor ebx, ebx
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]
mov edi, eax
push 0Ah ; OEM_FIXED_FONT
call [GetStockObject]
push ebx
push eax
push 30h ; WM_SETFONT
push edi
call [SendMessageA]
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
MyWndProc:
push edi
mov edi, [esp+8]
cmp dword [esp+12], 2 ; WM_DESTROY
jnz @f
push 0
call [PostQuitMessage]
@@:
cmp dword [esp+12], 219h ; WM_DEVICECHANGE
jnz w
cmp dword [esp+16], 8000h ; DBT_DEVICEARRIVAL
jz @f
cmp dword [esp+16], 8004h ; DBT_DEVICEREMOVECOMPLETE
jnz w
@@:
call UpdateDrivesInfo
w:
cmp dword [esp+12], 203h ; WM_LBUTTONDBLCLK
jnz @f
push 0
push 0
push 188h ; LB_GETCURSEL
push edi
call [SendMessageA]
cmp eax, -1
jz @f
push n+4
push eax
push 189h ; LB_GETTEXT
push edi
call [SendMessageA]
mov dword [n], '\\.\'
mov byte [n+4+aPhysicalDrive.sz], 0
call install
@@:
pop edi
pop eax
push [OldWndProc]
push eax
jmp [CallWindowProcA]
UpdateDrivesInfo:
push 0
push 0
push 184h ; LB_RESETCONTENT
push edi
call [SendMessageA]
CollectDrivesInfo:
xor eax, eax
mov ecx, 32
push edi
mov edi, PhysicalDrives
rep stosd
pop edi
push esi
call [GetLogicalDrives]
mov esi, eax
mov [a], 'A'
l:
shr esi, 1
jnc d
mov [a+2], 0
push a
call [GetDriveTypeA]
; Uncomment following lines to allow hard drives
; cmp eax, 3 ; DRIVE_FIXED
; jz @f
cmp eax, 2 ; DRIVE_REMOVABLE
jnz d
@@:
push 0 ; hTemplateFile
push 0 ; dwFlagsAndAttributes
push 3 ; dwCreationDisposition = OPEN_EXISTING
push 0 ; lpSecurityAttributes
push 3 ; dwShareMode = FILE_SHARE_READ|FILE_SHARE_WRITE
push 0 ; dwDesiredAccess
push a2
call [CreateFileA]
cmp eax, -1
jz d
push eax
push 0
mov ecx, esp
push 0 ; lpOverlapped
push ecx ; lpBytesReturned
push 12 ; nOutBufferSize
push sdn ; lpOutBuffer
push 0
push 0
push 2D1080h ; IOCTL_STORAGE_GET_DEVICE_NUMBER
push eax
call [DeviceIoControl]
pop ecx
pop edx
push eax
push edx
call [CloseHandle]
pop eax
test eax, eax
jz d ; probably it is floppy
mov eax, [sdn+4]
cmp eax, 32
jae d
movzx ecx, byte [a]
sub cl, 'A'
bts [PhysicalDrives+eax*4], ecx
d:
inc [a]
test esi, esi
jnz l
xor esi, esi
.physloop:
push esi
mov esi, [PhysicalDrives+esi*4]
test esi, esi
jz .physnext
push edi esi
mov esi, aPhysicalDrive
mov edi, n
@@:
lodsb
stosb
test al, al
jnz @b
pop esi
dec edi
mov eax, [esp+4]
cmp al, 10
jb .1dig
aam
add ah, '0'
mov byte [edi], ah
inc edi
.1dig:
add al, '0'
stosb
mov al, ':'
stosb
mov cl, 'A'-1
.logloop:
mov al, ' '
stosb
mov al, cl
stosb
@@:
inc byte [edi-1]
shr esi, 1
jnc @b
mov cl, [edi-1]
mov al, ':'
stosb
mov al, '\'
stosb
test esi, esi
jnz .logloop
mov al, 0
stosb
pop edi
push n
push 0
push 180h ; LB_ADDSTRING
push edi
call [SendMessageA]
.physnext:
pop esi
inc esi
cmp esi, 32
jb .physloop
pop esi
ret
install:
push 0 ; hTemplateFile
push 0 ; dwFlagsAndAttributes
push 3 ; dwCreationDisposition = OPEN_EXISTING
push 0 ; lpSecurityAttributes
push 3 ; dwShareMode = FILE_SHARE_READ|FILE_SHARE_WRITE
push 0C0000000h ; dwDesiredAccess = GENERIC_READ|GENERIC_WRITE
push n
call [CreateFileA]
cmp eax, -1
jnz @f
deverre:
push 10h
push 0
push deverr
push edi
call [MessageBoxA]
ret
@@:
push esi
mov esi, eax
push eax
mov eax, esp
push 0
push eax
push 512
push mbr_dev
push esi
call [ReadFile]
test eax, eax
jnz @f
deverrl:
push esi
call [CloseHandle]
pop eax
pop esi
jmp deverre
@@:
push esi edi
mov esi, mbr_new
mov edi, mbr_dev
mov ecx, 1B8h
rep movsb
mov al, [edi+6]
or al, [edi+16h]
or al, [edi+26h]
or al, [edi+36h]
test al, al
js @f
or byte [edi+6], 80h
@@:
pop edi esi
push 0
push 0
push 0
push esi
call [SetFilePointer]
test eax, eax
jnz deverrl
mov eax, esp
push 0
push eax
push 512
push mbr_dev
push esi
call [WriteFile]
test eax, eax
jz deverrl
cmp dword [esp], 512
jnz deverrl
; done!
done_succ:
push 40h
push ok
push succ
push edi
call [MessageBoxA]
push 0
call [PostQuitMessage]
r:
pop eax
push esi
call [CloseHandle]
pop esi
ret
section '.data' data readable writable
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
ok db 'Success',0
succ db 'Standard MBR has been installed',0
a2 db '\\.\'
a db '?:',0,0
aPhysicalDrive db 'PhysicalDrive',0
.sz = $ - aPhysicalDrive
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
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
DeviceIoControl dd rva DeviceIoControl_thunk
dw 0
thunk GetLogicalDrives
thunk GetDriveTypeA
thunk CreateFileA
thunk ReadFile
thunk WriteFile
thunk SetFilePointer
thunk CloseHandle
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
align 4
mbr_new:
file 'mbr'
align 4
OldWndProc dd ?
PhysicalDrives rd 32
sdn rd 3
n rb 1024
mbr_dev rb 512