/programs/hd_load/mtldr_install/compile.bat |
---|
0,0 → 1,0 |
fasm mtldr_install.asm |
/programs/hd_load/mtldr_install/mtldr_code/compile.bat |
---|
0,0 → 1,0 |
fasm mtldr.asm ..\mtldr_for_installer |
/programs/hd_load/mtldr_install/mtldr_code/fat32.inc |
---|
0,0 → 1,112 |
fat32_parse_dir: |
; in: eax=directory cluster |
; out: eax=entry cluster |
mov bx, 900h |
mov di, bx |
push eax |
call read_cluster |
mov cx, word [cluster_size] |
shr cx, 5 ; div 20h |
.scan_cluster: |
pop eax |
cmp byte [di], 0 |
jz file_not_found |
mov si, [esp+2] |
push eax |
call fat_compare_name |
jz .file_found |
and di, not 1Fh |
add di, 20h |
loop .scan_cluster |
pop eax |
call next_cluster |
jnc file_not_found |
jc fat32_parse_dir |
.file_found: |
pop eax |
mov si, [esp+2] |
mov [cur_obj], si |
and di, not 1Fh |
mov si, directory_string |
mov ax, [di+14h] |
shl eax, 10h |
mov ax, [di+1Ah] |
test eax, eax |
mov si, nodata_string |
jz find_error_si |
ret 2 |
fat_compare_name: |
push cx |
mov cx, 9 |
.scan: |
lodsb |
cmp al, '.' |
jz .ext |
cmp al, 0 |
jz .nameend |
cmp al, 'a' |
jb .notletter |
cmp al, 'z' |
ja .notletter |
or byte [di], 20h |
.notletter: |
scasb |
loopz .scan |
.notfound: |
inc cx ; to clear ZF flag |
pop cx |
ret |
.ext: |
mov al, ' ' |
dec cx |
repz scasb |
jnz .notfound |
test di, 1 |
jnz .notfound |
mov cx, 4 |
jmp .scan |
.nameend: |
mov al, ' ' |
dec cx |
repz scasb |
jnz .notfound |
test di, 1 |
jnz .file_found |
mov cx, 3 |
repz scasb |
jnz .notfound |
.file_found: |
xor cx, cx ; to set ZF flag |
pop cx |
ret |
read_cluster: |
; in: eax=cluster,bx->buffer |
and eax, 0FFFFFFFh |
movzx ecx, byte [50Dh] ; sects_per_clust |
mul ecx |
add eax, [data_start] |
; call read |
; ret |
jmp relative_read |
next_cluster: |
mov bx, 700h |
; sector is 200h bytes long, one entry in FAT occupies 4 bytes => 80h entries in sector |
push eax |
shr eax, 7 ; div 80h |
cmp eax, [fat_cur_sector] |
jz @f |
mov [fat_cur_sector], eax |
add eax, [fat_start] |
mov cx, 1 |
call relative_read |
@@: |
pop eax |
and eax, 7Fh |
mov eax, [700h+eax*4] |
and eax, 0FFFFFFFh |
cmp eax, 0FFFFFF7h |
mov si, bad_cluster_string |
jz find_error_si |
ret |
/programs/hd_load/mtldr_install/mtldr_code/mtldr.asm |
---|
0,0 → 1,786 |
; KolibriOS bootloader |
; this code has been written by diamond in 2005,2006 specially for KolibriOS |
; this code is loaded by ntldr to 0D00:0000 |
; and by io.sys from config.sys to xxxx:0100 |
; and by bootmgr in vista to 0000:7C00 |
format binary |
use16 |
org 0xD000 |
; entry point for 9x booting |
call @f |
; db 'd' xor 'i' xor 'a' xor 'm' xor 'o' xor 'n' xor 'd' |
db 'NTFS' |
; file offset +7 |
; may be changed by installator |
boot_drive db 80h |
partition_start dd -1 |
imgnameofs dw menuet_img_name |
@@: |
pop si |
sub si, 3 |
cmp si, 7C00h |
jz boot_vista |
mov si, load_question + 100h - 0D000h |
call out_string |
mov si, answer + 100h - 0D000h |
xxy: mov ah, 0 |
int 16h |
or al, 20h |
mov [si], al |
cmp al, 'y' |
jz xxz |
cmp al, 'n' |
jnz xxy |
; continue load Windows |
; call out_string |
; ret |
out_string: |
lodsb |
test al, al |
jz .xxx |
mov ah, 0Eh |
mov bx, 7 |
int 10h |
jmp out_string |
.xxx: ret |
xxz: |
; boot KolibriOS |
call out_string |
push 0 |
pop ds |
mov word [4], new01handler + 100h - 0D000h |
mov [6], cs |
pushf |
pop ax |
or ah, 1 |
push ax |
popf |
; int 19h |
; pushf ; there will be no iret |
call far [19h*4] |
xxt: |
; TF has been cleared when entered new01handler |
; pushf |
; pop ax |
; and ah, not 1 |
; push ax |
; popf |
push 0 |
pop ds |
cmp word [8*4+2], 0F000h |
jz @f |
les bx, [8*4] |
mov eax, [es:bx+1] |
mov [8*4], eax |
@@: |
mov si, 100h |
boot_vista: |
xor di, di |
push cs |
pop ds |
push 0D00h |
pop es |
mov cx, 2000h/2 |
rep movsw |
jmp 0D00h:0256h |
new01handler: |
; [sp]=ip, [sp+2]=cs, [sp+4]=flags |
push bp |
mov bp, sp |
push bx |
push ds |
lds bx, [bp+2] |
cmp word [bx], 19cdh |
jz xxt |
pop ds |
pop bx |
pop bp |
iret |
relative_read: |
add eax, [partition_start] |
; read from hard disk |
; drive_size must be already initialized |
; in: eax = absolute sector |
; cx = number of sectors |
; es:bx -> buffer |
read: |
pushad |
cmp eax, [drive_size] |
jb .old_style |
xor dx, dx |
; new style - LBA, function 42 |
cmp [has_lba], dl |
jz disk_error |
; allocate disk address packet on the stack |
; qword +8: absolute block number |
push dx |
push dx |
; push dword 0 ; dword +C is high dword |
push eax ; dword +8 is low dword |
; dword +4: buffer address |
push es ; word +6 is segment |
push bx ; word +4 is offset |
; word +2: number of blocks = 1 |
push 1 |
; word +0: size of packet = 10h |
push 10h |
; now pair ss:sp contain address of disk address packet |
.patch1: |
mov ax, 4200h |
mov dl, [boot_drive] |
mov si, sp |
push ds |
push ss |
pop ds |
int 13h |
pop ds |
lea sp, [si+10h] |
.end: |
popad |
jc disk_error |
add bx, 200h |
inc eax |
dec cx |
jnz read |
ret |
.old_style: |
; old style - CHS, function 2 |
; convert absolute sector in eax to cylinder-head-sector coordinates |
; calculate sector |
xor edx, edx |
movzx ecx, [sectors] |
div ecx |
; sectors are counted from 1 |
inc dl |
mov cl, dl ; low 6 bits of cl = sector number |
; calculate head number |
; shld edx, eax, 10h ; convert eax to dx:ax |
push eax |
pop ax |
pop dx |
div [heads] |
mov dh, dl ; dh = head |
mov ch, al ; ch = low 8 bits of cylinder |
shl ah, 6 |
or cl, ah ; high 2 bits of cl = high 2 bits of cylinder |
.patch2: |
mov ax, 201h ; function 2, al=1 - number of sectors |
mov dl, [boot_drive] |
int 13h |
jmp .end |
disk_error: |
mov si, disk_error_msg |
call out_string |
jmp $ |
answer db ? |
db 13,10 |
has_lba db 0 |
disk_error_msg db 'Disk read error!',0 |
start_msg db 2,' KolibriOS bootloader, running on ',0 |
errfs_msg db 'unknown filesystem, cannot continue',0 |
fat16_msg db 'FAT12/FAT16 - unsupported',13,10,0 |
fat32_msg db 'FAT32',13,10,0 |
ntfs_msg db 'NTFS',13,10,0 |
error_msg db 'Error' |
colon db ': ',0 |
mft_string db 'MFT',0 |
root_string db '\',0 |
noindex_string db '$INDEX_ROOT not found',0 |
invalid_read_request_string db 'cannot read attribute',0 |
nodata_string db '$DATA ' |
notfound_string db 'not found',0 |
directory_string db 'is a directory',0 |
notdir_string db 'not a directory',0 |
fragmented_string db 'too fragmented file',0 |
bad_cluster_string db 'bad cluster',0 |
exmem_string db 'extended memory error',0 |
load_question db 'Load KolibriOS? [y/n]: ',0 |
repeat 0D256h - $ |
db 1 |
end repeat |
start: |
xor ax, ax |
mov ds, ax |
mov es, ax |
; our stack is 4Kb-2b!!! (0xFFE) |
mov ss, ax |
mov esp, 0FFFEh |
cld |
sti |
; calculate drive size |
mov dl, [boot_drive] |
mov ah, 8 ; 8 = get drive parameters |
int 13h |
; now: CF is set on error; |
; ch = low 8 bits of maximum cylinder number |
; cl : low 6 bits makes maximum sector number, high 2 bits are high 2 bits of maximum cylinder number |
; dh = maximum head number |
jnc @f |
mov cx, -1 |
mov dh, cl |
@@: |
movzx ax, dh |
inc ax |
; ax = number of heads |
mov [heads], ax |
mov dl, cl |
and dx, 3Fh |
; dx = number of sectors |
; (note that sectors are counted from 1, and maximum sector number = number of sectors) |
mov [sectors], dx |
mul dx |
xchg cl, ch |
shr ch, 6 |
inc cx |
; cx = number of cylinders |
mov [cyls], cx |
mul cx |
mov word [drive_size], ax |
mov word [drive_size+2], dx |
; this drive supports LBA? |
mov dl, [boot_drive] |
mov ah, 41h |
mov bx, 55AAh |
int 13h |
jc .no_lba |
cmp bx, 0AA55h |
jnz .no_lba |
test cl, 1 |
jz .no_lba |
inc [has_lba] |
.no_lba: |
; say hi to user |
mov si, start_msg |
call out_string |
mov eax, [partition_start] |
cmp eax, -1 |
jnz @f |
; now read first sector to determine file system type |
; first sector of disk is MBR sector |
xor eax, eax |
mov cx, 1 |
mov bx, 500h |
call read |
mov eax, [6C6h] ; first disk |
mov [partition_start], eax |
@@: |
mov cx, 1 |
mov bx, 500h |
call read |
movzx ax, byte [50Dh] |
mov [sect_per_clust], ax |
; determine file system |
cmp dword [536h], 'FAT1' |
jz fat1x |
cmp dword [552h], 'FAT3' |
jz fat32 |
cmp dword [503h], 'NTFS' |
jz ntfs |
; mov si, errfs_msg ; already is |
call out_string |
jmp $ |
fat1x: |
mov si, fat16_msg |
call out_string |
jmp $ |
fat32: |
mov si, fat32_msg |
call out_string |
movzx eax, word [50Bh] ; bytes_per_sect |
movzx ebx, byte [50Dh] ; sects_per_clust |
mul ebx |
mov [cluster_size], eax |
movzx ebx, word [50Eh] ; reserved_sect |
mov [fat_start], ebx |
movzx eax, byte [510h] ; num_fats |
mul dword [524h] ; sect_fat |
add eax, ebx |
; cluster 2 begins from sector eax |
movzx ebx, byte [50Dh] ; sects_per_clust |
sub eax, ebx |
sub eax, ebx |
mov [data_start], eax |
; parse image name |
mov eax, [52Ch] ; root_cluster |
mov [cur_obj], root_string |
.parsedir: |
push ax |
mov si, [imgnameofs] |
push si |
@@: |
lodsb |
cmp al, '\' |
jz @f |
cmp al, 0 |
jnz @b |
@@: |
xchg ax, [esp+2] |
mov byte [si-1], 0 |
mov [imgnameofs], si |
call fat32_parse_dir |
pop cx |
test cl, cl |
jz .end |
test byte [di+0Bh], 10h |
mov si, notdir_string |
jz find_error_si |
jmp .parsedir |
.end: |
test byte [di+0Bh], 10h |
mov si, directory_string |
jnz find_error_si |
; parse FAT chunk |
; runlist at 2000:0000 |
mov di, 5 |
push 2000h |
pop es |
mov byte [es:di-5], 1 ; of course, non-resident |
mov dword [es:di-4], 1 |
stosd |
.parsefat: |
push es |
push ds |
pop es |
call next_cluster |
pop es |
jnc .done |
mov ecx, [es:di-8] |
add ecx, [es:di-4] |
cmp eax, ecx |
jz .contc |
mov dword [es:di], 1 |
scasd |
stosd |
jmp .parsefat |
.contc: |
inc dword [es:di-8] |
jmp .parsefat |
.done: |
xor eax, eax |
stosd |
jmp read_img_file |
ntfs: |
mov si, ntfs_msg |
call out_string |
movzx eax, word [50Bh] ; bpb_bytes_per_sect |
push eax |
movzx ebx, byte [50Dh] ; bpb_sects_per_clust |
mul ebx |
mov [cluster_size], eax |
mov [data_start], 0 |
mov ecx, [540h] ; frs_size |
cmp cl, 0 |
jg .1 |
neg cl |
xor eax, eax |
inc eax |
shl eax, cl |
jmp .2 |
.1: |
mul ecx |
.2: |
mov [frs_size], eax |
pop ebx |
xor edx, edx |
div ebx |
mov [frs_sectors], ax |
; read first MFT record - description of MFT itself |
mov [cur_obj], mft_string |
movzx eax, byte [50Dh] ; bpb_sects_per_clust |
mul dword [530h] ; mft_cluster |
mov cx, [frs_sectors] |
mov bx, 4000h |
mov di, bx |
push bx |
call relative_read |
call restore_usa |
; scan for unnamed $DATA attribute |
pop di |
mov ax, 80h ; $DATA |
mov bx, 700h |
call load_attr |
mov si, nodata_string |
jc find_error_si |
mov [free], bx |
; load menuet.img |
; parse image name |
mov eax, 5 ; root cluster |
mov [cur_obj], root_string |
.parsedir: |
push ax |
mov si, [imgnameofs] |
push si |
@@: |
lodsb |
cmp al, '\' |
jz @f |
cmp al, 0 |
jnz @b |
@@: |
xchg ax, [esp+2] |
mov byte [si-1], 0 |
mov [imgnameofs], si |
call ntfs_parse_dir |
pop cx |
test cl, cl |
jnz .parsedir |
read_img_file: |
xor si, si |
push es |
pop fs |
; yes! Now read file to 0x100000 |
lods byte [fs:si] |
cmp al, 0 ; assume nonresident attr |
mov si, invalid_read_request_string |
jz find_error_si |
mov si, 1 |
xor edi, edi |
; read buffer to 1000:0000 and move it to extended memory |
push 1000h |
pop es |
xor bx, bx |
.img_read_block: |
lods dword [fs:si] ; eax=length |
xchg eax, ecx |
jecxz .img_read_done |
lods dword [fs:si] ; eax=disk cluster |
.img_read_cluster: |
pushad |
; read part of file |
movzx ecx, byte [50Dh] |
mul ecx |
add eax, [data_start] |
call relative_read |
; move it to extended memory |
mov ah, 87h |
mov ecx, [cluster_size] |
push ecx |
shr cx, 1 |
mov si, movedesc |
push es |
push ds |
pop es |
int 15h |
pop es |
test ah, ah |
mov si, exmem_string |
jnz find_error_si |
pop ecx |
add [dest_addr], ecx |
popad |
inc eax |
loop .img_read_cluster |
jmp .img_read_block |
.img_read_done: |
; menuet.img loaded; now load kernel.mnt |
load_kernel: |
push ds |
pop es |
mov [cur_obj], kernel_mnt_name |
; read boot sector |
xor eax, eax |
mov bx, 500h |
mov cx, 1 |
call read_img |
; init vars |
mov ax, [50Eh] ; reserved_sect |
add ax, [51Ch] ; hidden |
mov word [fat_start], ax |
xchg ax, bx |
movzx ax, byte [510h] ; num_fats |
mul word [516h] ; fat_length |
add ax, bx |
; read root dir |
mov bx, 700h |
mov cx, [511h] ; dir_entries |
add cx, 0Fh |
shr cx, 4 |
call read_img |
add ax, cx |
mov [img_data_start], ax |
shl cx, 9 |
mov di, bx |
add bx, cx |
mov byte [bx], 0 |
.scan_loop: |
cmp byte [di], 0 |
mov si, notfound_string |
jz find_error_si |
mov si, kernel_mnt_name |
call fat_compare_name |
jz .found |
and di, not 1Fh |
add di, 20h |
jmp .scan_loop |
.found: |
and di, not 1Fh |
mov si, directory_string |
test byte [di+0Bh], 10h |
jnz find_error_si |
; found, now load it to 1000h:0000h |
mov ax, [di+1Ah] |
; first cluster of kernel.mnt in ax |
; translate it to sector on disk in menuet.img |
push ax |
dec ax |
dec ax |
movzx cx, byte [50Dh] |
mul cx |
add ax, [img_data_start] |
; now ax is sector in menuet.img |
mov [kernel_mnt_in_img], ax |
div [sect_per_clust] |
; now ax is cluster in menuet.img and |
; dx is offset from the beginning of cluster |
movzx eax, ax |
push 2000h |
pop ds |
mov si, 1 |
.scani: |
sub eax, [si] |
jb .scanidone |
; sanity check |
cmp dword [si], 0 |
push invalid_read_request_string |
jz find_error_sp |
pop cx |
; next chunk |
add si, 8 |
jmp .scani |
.scanidone: |
add eax, [si] ; undo last subtract |
add eax, [si+4] ; get cluster |
push 0 |
pop ds |
movzx ecx, [sect_per_clust] |
push dx |
mul ecx ; get sector |
pop dx |
movzx edx, dx |
add eax, edx |
add eax, [data_start] |
mov [kernel_mnt_1st], eax |
pop ax |
push 1000h |
pop es |
.read_loop: |
push ax |
xor bx, bx |
call img_read_cluster |
shl cx, 9-4 |
mov ax, es |
add ax, cx |
mov es, ax |
pop ax |
call img_next_cluster |
jc .read_loop |
mov ax, 'KL' |
mov si, loader_block |
jmp 1000h:0000h |
img_next_cluster: |
mov bx, 700h |
push ax |
shr ax, 1 |
add ax, [esp] |
mov dx, ax |
shr ax, 9 |
add ax, word [fat_start] |
mov cx, 2 |
push es |
push ds |
pop es |
call read_img |
pop es |
and dx, 1FFh |
add bx, dx |
mov ax, [bx] |
pop cx |
test cx, 1 |
jz .1 |
shr ax, 4 |
.1: |
and ax, 0FFFh |
mov si, bad_cluster_string |
cmp ax, 0FF7h |
jz find_error_si |
ret |
img_read_cluster: |
dec ax |
dec ax |
movzx cx, byte [50Dh] ; sects_per_clust |
mul cx |
add ax, [img_data_start] |
movzx eax, ax |
; call read_img |
; ret |
read_img: |
; in: ax = sector, es:bx->buffer, cx=length in sectors |
pushad |
movzx ebx, bx |
mov si, movedesc |
shl eax, 9 |
add eax, 93100000h |
mov dword [si+sou_addr-movedesc], eax |
mov eax, 9300000h |
mov ax, es |
shl eax, 4 |
add eax, ebx |
mov [si+dest_addr-movedesc], eax |
mov ah, 87h |
shl cx, 8 ; mul 200h/2 |
push es |
push 0 |
pop es |
int 15h |
pop es |
cmp ah, 0 |
mov si, exmem_string |
jnz find_error_si |
popad |
ret |
movedesc: |
times 16 db 0 |
; source |
dw 0xFFFF ; segment length |
sou_addr dw 0000h ; linear address |
db 1 ; linear address |
db 93h ; access rights |
dw 0 |
; destination |
dw 0xFFFF ; segment length |
dest_addr dd 93100000h ; high byte contains access rights |
; three low bytes contains linear address (updated when reading) |
dw 0 |
times 32 db 0 |
find_error_si: |
push si |
find_error_sp: |
mov si, error_msg |
call out_string |
mov si, [cur_obj] |
call out_string |
mov si, colon |
call out_string |
pop si |
call out_string |
jmp $ |
file_not_found: |
mov si, [esp+2] |
mov [cur_obj], si |
push notfound_string |
jmp find_error_sp |
include 'fat32.inc' |
include 'ntfs.inc' |
write1st: |
; callback from kernel.mnt |
; write first sector of kernel.mnt from 1000:0000 back to disk |
push cs |
pop ds |
push cs |
pop es |
; sanity check |
mov bx, 500h |
mov si, bx |
mov cx, 1 |
push cx |
mov eax, [kernel_mnt_1st] |
push eax |
call relative_read |
push 1000h |
pop es |
xor di, di |
mov cx, 8 |
repz cmpsw |
mov si, data_error_msg |
jnz find_error_si |
; ok, now write back to disk |
or byte [read.patch1+2], 1 |
or byte [read.patch2+2], 1 |
xor bx, bx |
pop eax |
pop cx |
call relative_read |
and byte [read.patch1+1], not 1 |
and byte [read.patch2+2], not 2 |
; and to image in memory (probably this may be done by kernel.mnt itself?) |
mov dword [sou_addr], 93010000h |
movzx eax, [kernel_mnt_in_img] |
shl eax, 9 |
add eax, 93100000h |
mov dword [dest_addr], eax |
mov si, movedesc |
push ds |
pop es |
mov ah, 87h |
mov cx, 100h |
int 15h |
cmp ah, 0 |
mov si, exmem_string |
jnz find_error_si |
retf |
loader_block: |
db 1 ; version |
dw 1 ; flags - image is loaded |
dw write1st ; offset |
dw 0 ; segment |
fat_cur_sector dd -1 |
data_error_msg db 'data error',0 |
; ----------------------------------------------- |
; ------------------ Settings ------------------- |
; ----------------------------------------------- |
; must be in lowercase, see ntfs_parse_dir.scan, fat32_parse_dir.scan |
kernel_mnt_name db 'kernel.mnt',0 |
; will be initialized by installer |
menuet_img_name rb 300 |
; uninitialized data follows |
drive_size dd ? ; in sectors |
heads dw ? |
sectors dw ? |
cyls dw ? |
free dw ? |
cur_obj dw ? |
data_start dd ? |
img_data_start dw ? |
sect_per_clust dw ? |
kernel_mnt_in_img dw ? |
kernel_mnt_1st dd ? |
; NTFS data |
cluster_size dd ? ; in bytes |
frs_size dd ? ; in bytes |
frs_sectors dw ? ; in sectors |
mft_data_attr dw ? |
index_root dw ? |
index_alloc dw ? |
ofs dw ? |
dir dw ? |
; FAT32 data |
fat_start dd ? |
cur_cluster dd ? |
/programs/hd_load/mtldr_install/mtldr_code/ntfs.inc |
---|
0,0 → 1,531 |
restore_usa: |
; Update Sequence Array restore |
mov bx, [di+4] |
mov cx, [di+6] |
inc bx |
add bx, di |
inc bx |
add di, 1feh |
dec cx |
@@: |
mov ax, [bx] |
stosw |
inc bx |
inc bx |
add di, 1feh |
loop @b |
ret |
find_attr: |
; in: di->file record, ax=attribute |
; out: di->attribute or di=0 if not found |
add di, [di+14h] |
.1: |
; attributes codes are formally dwords, but all they fit in word |
cmp word [di], -1 |
jz .notfound |
cmp word [di], ax |
jnz .continue |
; for $DATA attribute, scan only unnamed |
cmp ax, 80h |
jnz .found |
cmp byte [di+9], 0 |
jz .found |
.continue: |
add di, [di+4] |
jmp .1 |
.notfound: |
xor di, di |
.found: |
ret |
process_mcb_nonres: |
; in: si->attribute, es:di->buffer |
; out: di->buffer end |
add si, [si+20h] |
xor ebx, ebx |
.loop: |
lodsb |
test al, al |
jz .done |
push invalid_read_request_string |
movzx cx, al |
shr cx, 4 |
jz find_error_sp |
xchg ax, dx |
and dx, 0Fh |
jz find_error_sp |
add si, cx |
add si, dx |
pop ax |
push si |
dec si |
movsx eax, byte [si] |
dec cx |
jz .l1e |
.l1: |
dec si |
shl eax, 8 |
mov al, [si] |
loop .l1 |
.l1e: |
xchg ebp, eax |
dec si |
movsx eax, byte [si] |
mov cx, dx |
dec cx |
jz .l2e |
.l2: |
dec si |
shl eax, 8 |
mov al, byte [si] |
loop .l2 |
.l2e: |
pop si |
add ebx, ebp |
; eax=length, ebx=disk block |
stosd |
mov eax, ebx |
stosd |
jmp .loop |
.done: |
xor eax, eax |
stosd |
ret |
load_attr: |
; in: ax=attribute, es:bx->buffer, di->base record |
; out: bx->buffer end; CF set if not found |
push di |
push ax |
mov byte [es:bx], 1 |
inc bx |
push bx |
mov [ofs], bx |
; scan for attrubute |
add di, [di+14h] |
@@: |
call find_attr.1 |
test di, di |
jz .notfound1 |
cmp byte [di+8], 0 |
jnz .nonresident |
jmp .resident |
.aux_resident: |
push di |
popad |
; resident attribute |
.resident: |
mov si, di |
pop di |
dec di |
mov al, 0 |
stosb |
mov ax, [si+10h] |
stosw |
xchg ax, cx |
add si, [si+14h] |
rep movsb |
mov bx, di |
pop ax |
pop di |
ret |
.nonresident: |
; nonresident attribute |
cmp dword [di+10h], 0 |
jnz @b |
; read start of data |
mov si, di |
pop di |
call process_mcb_nonres |
sub di, 4 |
push di |
.notfound1: |
; $ATTRIBUTE_LIST is always in base file record |
cmp word [esp+2], 20h |
jz .nofragmented |
; scan for $ATTRIBUTE_LIST = 20h |
mov di, [esp+4] |
mov ax, 20h |
call find_attr |
test di, di |
jz .nofragmented |
; load $ATTRIBUTE_LIST itself |
push es |
mov bx, 0C000h |
mov di, [esp+6] |
push bx |
push [ofs] |
push ds |
pop es |
call load_attr |
pop [ofs] |
pop si |
mov bx, 8000h |
push bx |
push si |
call read_attr_full |
pop si |
pop bx |
add dx, bx |
mov ax, [esp+4] |
pop es |
.1: |
cmp [bx], ax |
jnz .continue1 |
; only unnamed $DATA attributes! |
cmp ax, 80h |
jnz @f |
cmp byte [bx+6], 0 |
jnz .continue1 |
@@: |
cmp dword [bx+10h], 0 |
jz .continue1 |
cmp dword [bx+8], 0 |
jnz @f |
push ax |
mov ax, [esp+2] |
cmp ax, [ofs] |
pop ax |
jnz .continue1 |
@@: |
pushad |
mov eax, [bx+10h] |
mov bx, dx |
push [ofs] |
push es |
push ds |
pop es |
call read_file_record |
pop es |
pop [ofs] |
popad |
pushad |
pop di |
mov di, dx |
add di, [di+14h] |
.2: |
call find_attr.1 |
cmp byte [di+8], 0 |
jz .aux_resident |
mov eax, [bx+8] |
cmp eax, [di+10h] |
jnz .2 |
mov si, di |
mov di, [esp+1Eh] |
call process_mcb_nonres |
sub di, 4 |
mov [esp+1Eh], di |
push di |
popad |
.continue1: |
add bx, [bx+4] |
cmp bx, dx |
jb .1 |
.nofragmented: |
pop bx |
pop ax |
pop di |
cmp bx, [ofs] |
jnz @f |
dec bx |
stc |
ret |
@@: |
add bx, 4 |
ret |
read_attr_full: |
; in: si->decoded attribute data, bx->buffer |
; out: edx=length in bytes |
lodsb |
cmp al, 0 |
jnz .nonresident |
; resident |
lodsw |
movzx edx, ax |
xchg ax, cx |
mov di, bx |
rep movsb |
ret |
.nonresident: |
; nonresident :-) |
xor edx, edx |
.loop: |
lodsd |
xchg ecx, eax |
jecxz .loopend |
lodsd |
xchg edi, eax |
; read ecx clusters from cluster edi to es:bx |
.intloop: |
push ecx |
; read 1 cluster from physical cluster edi to es:bx |
mov ecx, [cluster_size] |
mov eax, edi |
mul ecx |
push bx |
call relative_read |
pop bx |
pop ecx |
inc edi |
mov eax, [cluster_size] |
add edx, eax |
shr eax, 4 |
mov bp, es |
add bp, ax |
mov es, bp |
loop .intloop |
jmp .loop |
.loopend: |
mov es, cx |
ret |
read_file_record: |
; in: eax=index of record, bx=buffer |
mov si, 700h |
mov ecx, [frs_size] |
mul ecx |
push bx |
push [cur_obj] |
mov [cur_obj], mft_string |
call read_attr |
pop [cur_obj] |
pop di |
call restore_usa |
ret |
read_attr: |
; in: edx:eax=offset in bytes, ecx=size in bytes, bx=buffer, si=attribute |
push invalid_read_request_string |
cmp byte [si], 0 |
jnz .nonresident |
test edx, edx |
jnz find_error_sp |
cmp eax, 10000h |
jae find_error_sp |
cmp ecx, 10000h |
jae find_error_sp |
cmp ax, [si+2] |
jae find_error_sp |
cmp cx, [si+2] |
ja find_error_sp |
add si, 3 |
add si, ax |
mov di, bx |
rep movsb |
pop ax |
ret |
.nonresident: |
mov edi, [cluster_size] |
div edi |
mov [ofs], dx |
add cx, dx |
push eax |
xchg eax, ecx |
xor edx, edx |
dec eax |
div edi |
inc eax |
xchg eax, ecx |
pop eax |
add si, 1 |
xor edx, edx |
push bx |
; eax=offset in clusters, ecx=size in clusters |
.scan: |
mov ebx, [si] |
test ebx, ebx |
jz .notfound |
add edx, ebx |
add si, 8 |
cmp eax, edx |
jae .scan |
mov edi, [si-4] |
; now edx=end of block, ebx=length of block, edi=start of block on disk |
; eax=required offset, ecx=required length |
push edx |
push edi |
sub edx, eax |
add edi, ebx |
sub edi, edx |
cmp edx, ecx |
jb @f |
mov edx, ecx |
@@: |
; read (edx) clusters from (edi=disk offset in clusters) to ([esp+8]) |
cmp [ofs], 0 |
jnz .ofs_read |
.cont: |
pushad |
movzx ebx, byte [50Dh] |
; xchg eax, edx |
; mul ebx |
xchg ax, dx |
mul bx |
xchg cx, ax |
xchg eax, edi |
mul ebx |
mov bx, [esp+8+20h] |
call relative_read |
mov [esp+8+20h], bx |
popad |
.cont2: |
add eax, edx |
sub ecx, edx |
.cont3: |
pop edi |
pop edx |
jnz .scan |
pop bx |
pop ax |
ret |
.ofs_read: |
push ecx |
movzx ecx, byte [50Dh] ; bpb_sects_per_clust |
mov eax, edi |
push edx |
mul ecx |
push 1000h |
pop es |
xor bx, bx |
call relative_read |
mov cx, bx |
push si |
push di |
mov si, [ofs] |
mov di, [esp+8+12] |
sub cx, si |
push ds |
push es |
pop ds |
pop es |
rep movsb |
mov [esp+8+12], di |
push es |
pop ds |
pop di |
pop si |
pop edx |
pop ecx |
inc edi |
mov [ofs], 0 |
inc eax |
dec ecx |
jz .cont3 |
dec edx |
jnz .cont |
jmp .cont2 |
.notfound: |
mov si, invalid_read_request_string |
jmp find_error_si |
ntfs_parse_dir: |
; in: eax=directory iRecord, [word sp+2]=filename |
; out: si=$DATA attribute of file |
mov bx, [free] |
mov [dir], bx |
push bx |
call read_file_record |
mov ax, word [frs_size] |
add [free], ax |
pop di |
; find attributes $INDEX_ROOT, $INDEX_ALLOCATION, $BITMAP |
mov ax, 90h ; $INDEX_ROOT |
push di |
mov bx, [free] |
mov [index_root], bx |
call load_attr |
mov si, noindex_string |
jc find_error_si |
mov [free], bx |
pop di |
mov ax, 0A0h ; $INDEX_ALLOCATION |
mov bx, [free] |
mov [index_alloc], bx |
call load_attr |
jnc @f |
mov [index_alloc], 0 |
@@: |
mov [free], bx |
; search for entry |
mov si, [index_root] |
mov bx, [free] |
call read_attr_full |
mov ebp, [bx+8] ; subnode_size |
add bx, 10h |
.scan_record: |
add bx, [bx] |
.scan: |
test byte [bx+0Ch], 2 |
jnz .not_found |
mov si, [esp+2] |
movzx cx, byte [bx+50h] ; namelen |
lea di, [bx+52h] ; name |
xor ax, ax |
@@: |
lodsb |
cmp al, 'a' |
jb .notletter |
cmp al, 'z' |
ja .notletter |
or byte [di], 20h |
.notletter: |
scasw |
loopz @b |
jb .not_found |
ja @f |
cmp byte [esi], 0 |
jz .file_found |
@@: |
add bx, [bx+8] |
jmp .scan |
.not_found: |
test byte [bx+0Ch], 1 |
jz file_not_found |
cmp [index_alloc], 0 |
jz file_not_found |
add bx, [bx+8] |
mov eax, [bx-8] |
mul [cluster_size] |
mov si, [index_alloc] |
mov ecx, ebp |
mov bx, [free] |
call read_attr |
mov di, [free] |
call restore_usa |
mov bx, [free] |
add bx, 18h |
jmp .scan_record |
.file_found: |
mov si, [esp+2] |
mov [cur_obj], si |
cmp byte [esp+4], 0 |
jz .need_file |
mov si, notdir_string |
test byte [bx+48h+3], 10h |
jz find_error_si |
mov eax, [bx] |
mov bx, [dir] |
mov [free], bx |
ret 2 |
.need_file: |
mov si, directory_string |
test byte [bx+48h+3], 10h ; directory? |
jnz find_error_si |
; read entry |
mov eax, [bx] |
mov bx, [dir] |
mov [free], bx |
mov bx, 4000h |
push bx |
call read_file_record |
pop di |
mov ax, 80h |
push 2000h |
pop es |
xor bx, bx |
call load_attr |
mov si, nodata_string |
jz find_error_si |
mov [free], bx |
ret 2 |
/programs/hd_load/mtldr_install/mtldr_install.asm |
---|
0,0 → 1,1426 |
format PE GUI 4.0 |
section '.text' code readable executable |
entry start |
start: |
xor ebx, ebx |
push ofn |
call [GetOpenFileNameA] |
test eax, eax |
jnz @f |
push ebx |
call [ExitProcess] |
@@: |
call [GetVersion] |
test eax, eax |
sets [b9x] |
js install_9x |
mov [img_name+2], bl |
push ebx |
push ebx |
push 3 |
push ebx |
push 3 |
push 80000000h |
push dn |
call [CreateFileA] |
inc eax |
jnz @f |
norights: |
push 10h |
push ebx |
push norightsmsg |
mbx: |
push ebx |
call [MessageBoxA] |
push ebx |
call [ExitProcess] |
@@: |
lea esi, [eax-1] |
push ebx |
push tmp |
push 12 |
push sdn |
push ebx |
push ebx |
push 0x2D1080 |
push esi |
call [DeviceIoControl] |
test eax, eax |
jnz @f |
cnr: |
push esi |
call [CloseHandle] |
jmp norights |
@@: |
push ebx |
push tmp |
push 20h |
push pi |
push ebx |
push ebx |
push 0x74004 |
push esi |
call [DeviceIoControl] |
test eax, eax |
jz cnr |
push esi |
call [CloseHandle] |
cmp [sdn], 7 |
jz @f |
push 10h |
push 0 |
push nohd |
jmp mbx |
@@: |
mov al, byte [sdn+4] |
or al, 80h |
mov [mtldr_code+7], al |
mov eax, [pi] |
mov edx, [pi+4] |
shrd eax, edx, 9 |
shr edx, 9 |
jz @f |
m1e: push 10h |
push ebx |
push m1 |
jmp mbx |
@@: |
install_cmn: |
mov [mtldr_code+8], eax |
mov esi, img_name |
mov edi, img_real_name |
mov byte [esi+2], '\' |
push 256 |
push edi |
push esi |
call [GetShortPathNameA] |
cmp eax, 256 |
jb @f |
push 10h |
push ebx |
push ptl |
jmp mbx |
@@: |
test eax, eax |
jnz @f |
push esi edi |
mov ecx, 256/4 |
rep movsd |
pop edi esi |
@@: |
cmp byte [edi], 0 |
jz lcd |
cmp byte [edi], 'A' |
jb lcc |
cmp byte [edi], 'Z' |
ja lcc |
add byte [edi], 20h |
lcc: |
inc edi |
jmp @b |
lcd: |
mov esi, img_real_name |
cmp [b9x], 0 |
jnz @f |
cmp byte [esi], 'c' |
jnz notc |
@@: |
push 256/4 |
pop ecx |
lea edi, [esi+ecx*4] |
rep movsd |
mov edi, esi |
xor eax, eax |
or ecx, -1 |
repnz scasb |
dec edi |
std |
mov al, '\' |
repnz scasb |
cld |
inc edi |
inc edi |
mov eax, 'mtld' |
stosd |
mov al, 'r' |
stosb |
jmp cmn |
notc: |
mov dword [mtldr_name], 'C:\m' |
mov dword [mtldr_name+4], 'tldr' |
mov edi, mtldr_name+8 |
cmn: |
and word [edi], 0 |
mf: |
push mtldr_name |
call [GetFileAttributesA] |
inc eax |
jnz @f |
call [GetLastError] |
cmp eax, 2 |
jz fo |
@@: |
cmp byte [edi], 0 |
jnz @f |
mov byte [edi], '0' |
jmp mf |
@@: |
cmp byte [edi], '9' |
jae @f |
mfi: |
inc byte [edi] |
jmp mf |
@@: |
ja @f |
mov byte [edi], 'A' |
jmp mf |
@@: |
cmp byte [edi], 'Z' |
jb mfi |
nomx: push 10h |
push ebx |
push nom |
jmp mbx |
fo: |
cmp [b9x], 0 |
jnz install_9x_2 |
call write_mtldr1 |
push ecx |
call [GetVersion] |
pop ecx |
cmp al, 6 |
jae install_vista |
mov al, 2 |
mov edi, tmp_data |
neg ecx |
add ecx, 2000h - mtldr_code_size |
push ebx |
push tmp |
push ecx |
push edi |
push esi |
rep stosb |
call [WriteFile] |
push esi |
call [CloseHandle] |
push bootini |
mov edi, systitle+1 |
mov esi, ostitle |
mov byte [edi-1], '"' |
@@: |
lodsb |
test al, al |
jz @f |
stosb |
jmp @b |
@@: |
mov word [edi], '"' |
push bootini |
call [GetFileAttributesA] |
push eax |
and al, not 1 |
push eax |
push bootini |
call [SetFileAttributesA] |
push bootini |
push systitle |
push mtldr_name |
push mtldr_name |
push mtldr_name |
call [CharToOemA] |
push osstr |
call [WritePrivateProfileStringA] |
xchg eax, [esp] |
push eax |
push bootini |
call [SetFileAttributesA] |
pop eax |
test eax, eax |
jnz suci |
; failed, delete written mtldr |
call delete_mtldr |
push 10h |
push ebx |
push insterr |
jmp mbx |
suci: |
push 40h |
push suct |
push succ |
jmp mbx |
install_9x: |
mov al, [img_name] |
or al, 20h |
sub al, 'a'-1 |
mov byte [regs], al |
push ebx |
push ebx |
push 3 |
push ebx |
push 3 |
push 80000000h |
push vwin32 |
call [CreateFileA] |
inc eax |
jz norights |
dec eax |
xchg eax, esi |
push ebx |
push tmp |
push 28 |
push regs |
push 28 |
push regs |
push 1 |
push esi |
call [DeviceIoControl] |
push eax |
push esi |
call [CloseHandle] |
pop eax |
test eax, eax |
@@: jz norights |
mov al, [diskinfobuf+3] |
cmp al, 0xFF |
jz @b |
cmp al, 80h |
jb norights |
mov [mtldr_code+7], al |
cmp dword [diskinfobuf+12], 0 |
jnz m1e |
mov eax, [diskinfobuf+8] |
jmp install_cmn |
install_9x_2: |
push ebx |
push ebx |
push 3 |
push ebx |
push 1 |
push 80000000h |
push config |
call [CreateFileA] |
inc eax |
jnz @f |
ie2: |
push 10h |
push ebx |
push insterr2 |
jmp mbx |
@@: |
dec eax |
xchg eax, esi |
push ebx |
push esi |
call [GetFileSize] |
inc eax |
jz ie2 |
dec eax |
xchg eax, ebp |
push 4 |
push 1000h |
push ebp |
push ebx |
call [VirtualAlloc] |
xchg eax, edi |
test edi, edi |
jz ie2 |
push ebx |
push tmp |
push ebp |
push edi |
push esi |
call [ReadFile] |
push esi |
call [CloseHandle] |
push ebx |
push 80h |
push 2 |
push ebx |
push ebx |
push 40000000h |
push config |
call [CreateFileA] |
inc eax |
jz ie2 |
dec eax |
xchg eax, esi |
mov eax, dword [edi] |
or eax, 0x20202000 |
cmp eax, '[men' |
jz menu |
push ostitle |
call [lstrlenA] |
cmp eax, 17 |
ja bt1 |
push esi edi |
mov esi, ostitle |
mov edi, mtldr_code+23Ah |
mov ecx, eax |
rep movsb |
mov dword [edi], '? [y' |
mov dword [edi+4], '/n]:' |
mov word [edi+8], ' ' |
pop edi esi |
jmp ct1 |
bt1: |
push img_real_name+3 |
call [lstrlenA] |
add eax, mtldr_code_size+1+100h |
mov word [mtldr_code+0x19], ax |
ct1: |
push ebx |
push tmp |
push 8 |
push install |
push esi |
call [WriteFile] |
cfgd: |
mov eax, mtldr_name |
push eax |
push eax |
push eax |
call [CharToOemA] |
call [lstrlenA] |
push ebx |
push tmp |
push eax |
push mtldr_name |
push esi |
call [WriteFile] |
push ebx |
push tmp |
push 2 |
push newline |
push esi |
call [WriteFile] |
push ebx |
push tmp |
push ebp |
push edi |
push esi |
call [WriteFile] |
push esi |
call [CloseHandle] |
call write_mtldr1 |
push ostitle |
call [lstrlenA] |
cmp eax, 11 |
jbe @f |
push ebx |
push tmp |
push ld2sz |
push ld2 |
push esi |
push ebx |
push tmp |
push eax |
push ostitle |
push esi |
push ebx |
push tmp |
push ld1sz |
push ld1 |
push esi |
call [WriteFile] |
call [WriteFile] |
call [WriteFile] |
@@: |
push esi |
call [CloseHandle] |
jmp suci |
menu: |
push edi |
or ecx, -1 |
mes: |
mov al, 0xA |
repnz scasb |
cmp byte [edi], '[' |
jz med |
cmp dword [edi], 'menu' |
jnz mes |
cmp dword [edi+4], 'item' |
jnz mes |
cmp byte [edi+8], '=' |
jnz mes |
mov eax, [edi+9] |
or eax, ' ' |
cmp eax, 'koli' |
jnz mes |
mov eax, [edi+13] |
and eax, 0xFFFFFF |
or eax, ' ' |
cmp eax, 'bri' |
jnz mes |
movzx eax, byte [edi+16] |
or al, 0x20 |
mov [menuitems+eax], 1 |
jmp mes |
med: |
cmp word [edi-4], 0x0A0D |
jnz @f |
dec edi |
dec edi |
jmp med |
@@: |
sub edi, [esp] |
push ebx |
push tmp |
push edi |
push dword [esp+12] |
push esi |
call [WriteFile] |
add [esp], edi |
sub ebp, edi |
mov ecx, 7 |
cmp [menuitems+0x20], 0 |
jnz @f |
cmp [menuitems+','], 0 |
jz mef |
@@: |
mov eax, '0' |
mel1: |
cmp [menuitems+eax], 0 |
jz med1 |
inc eax |
cmp al, '9'+1 |
jb mel1 |
jnz @f |
mov al, 'a' |
jmp mel1 |
@@: |
cmp al, 'z' |
jbe mel1 |
push ebx |
push tmp |
push ebp |
push dword [esp+12] |
push esi |
call [WriteFile] |
push esi |
call [CloseHandle] |
jmp nomx |
med1: |
mov [menuitem+7], al |
mov ecx, 8 |
mef: |
push ebx |
push tmp |
push ecx |
push menuitem |
push esi |
push ebx |
push tmp |
push ecx |
push menuitem |
push esi |
push ebx |
push tmp |
push 9 |
push mis |
push esi |
call [WriteFile] |
call [WriteFile] |
push ebx |
push tmp |
push title9xsz |
push title9x |
push esi |
call [WriteFile] |
push ebx |
push tmp |
push ostitle |
call [lstrlenA] |
push eax |
push ostitle |
push esi |
call [WriteFile] |
push ebx |
push tmp |
push title9x2sz |
push title9x2 |
push esi |
call [WriteFile] |
call [WriteFile] |
push ebx |
push tmp |
push 11 |
push sec9x2 |
push esi |
call [WriteFile] |
mov byte [mtldr_code+1], 37h |
pop edi |
jmp cfgd |
install_vista: |
push esi |
call [CloseHandle] |
mov edi, sbn |
call adjust_privilege |
mov edi, srn |
call adjust_privilege |
push ebx |
push ebx |
call [CoInitializeEx] |
test eax, eax |
js we |
push ebx |
push ebx |
push ebx |
push 3 |
push ebx |
push ebx |
push ebx |
push -1 |
push ebx |
call [CoInitializeSecurity] |
test eax, eax |
jns @f |
we2: |
call [CoUninitialize] |
we: |
call delete_mtldr |
push 10h |
push ebx |
push wmierr |
jmp mbx |
@@: |
push ebx |
push esp |
push IID_IWbemLocator |
push 1 |
push ebx |
push CLSID_WbemLocator |
call [CoCreateInstance] |
pop edi |
test eax, eax |
js we2 |
push ebx |
push esp |
push ebx |
push ebx |
push ebx |
push ebx |
push ebx |
push ebx |
push ns |
push edi |
mov esi, [edi] |
call dword [esi+12] |
push eax |
push edi |
call dword [esi+8] |
pop eax |
pop edi |
test eax, eax |
js we2 |
push ebx |
push ebx |
push 3 |
push 3 |
push ebx |
push ebx |
push 10 |
push edi |
call [CoSetProxyBlanket] |
test eax, eax |
jns @f |
we3: |
mov eax, [edi] |
push edi |
call dword [eax+8] |
jmp we2 |
@@: |
xor esi, esi |
push osp |
push osn |
push bs |
call call_method |
test eax, eax |
js we3 |
mov esi, guid |
mov ebp, menuitems |
push esi |
call [CoCreateGuid] |
push 2000h/2 |
push ebp |
push esi |
call [StringFromGUID2] |
mov esi, [varout+8] |
push con |
push bs |
call call_method |
jns @f |
wecei: |
mov ebp, coerr |
wece: |
mov eax, [esi] |
push esi |
call dword [eax+8] |
mov eax, [edi] |
push edi |
call dword [eax+8] |
call [CoUninitialize] |
call delete_mtldr |
push 10h |
push ebx |
push ebp |
jmp mbx |
@@: |
pop eax |
push esi |
push eax |
mov ebp, tmp_data |
mov dword [vartmpstr+8], ebp |
mov dword [vari32+8], 0x12000004 |
push 2000h/2 |
push ebp |
push -1 |
push ostitle |
push ebx |
push ebx |
call [MultiByteToWideChar] |
mov esi, [varout+8] |
push ssen |
push bo |
call call_method |
mov ebp, setproperr |
js wece2 |
sub dword [esp], 24 |
mov byte [vari32+8], 2 |
push 2000h/2 |
push tmp_data |
push -1 |
push mtldr_name+2 |
push ebx |
push ebx |
call [MultiByteToWideChar] |
push ssen |
push bo |
call call_method |
js wece2 |
mov dword [vari32+8], 0x11000001 |
mov ecx, tmp_data |
mov dword [ecx], '\' + ('?' shl 16) |
mov dword [ecx+4], '?' + ('\' shl 16) |
xor eax, eax |
mov dword [ecx+12], eax |
mov al, [mtldr_name+1] |
shl eax, 16 |
mov al, [mtldr_name] |
mov dword [ecx+8], eax |
push spden |
push bo |
call call_method |
js wece2 |
mov eax, [esi] |
push esi |
call dword [eax+8] |
pop eax |
pop esi |
push eax |
push oon |
push bs |
call call_method |
mov ebp, orerr |
js wece3 |
pop eax |
push esi |
push eax |
mov esi, [varout+8] |
mov dword [vari32+8], 0x24000001 |
push gen |
push bo |
call call_method |
js wece2 |
push esi |
mov esi, [varout+8] |
push ebx |
push ebx |
push varout |
push ebx |
push idsn |
mov eax, [esi] |
push esi |
call dword [eax+16] |
push eax |
mov eax, [esi] |
push esi |
call dword [eax+8] |
pop eax |
pop esi |
test eax, eax |
js wece2 |
push esi |
cmp word [varout], 2008h |
jnz wece4 |
mov esi, [varout+8] |
cmp word [esi], 1 |
jnz wece4 |
push dword [esi+20] |
mov eax, [esi+16] |
inc eax |
push eax |
push esp |
push esi |
call [SafeArrayRedim] |
pop ecx |
pop ecx |
test eax, eax |
js wece4 |
push menuitems |
call [SysAllocString] |
test eax, eax |
jz wece4 |
push eax |
mov ecx, [esi+16] |
add ecx, [esi+20] |
dec ecx |
push ecx |
mov ecx, esp |
push eax |
push ecx |
push esi |
call [SafeArrayPutElement] |
pop ecx |
call [SysFreeString] |
pop esi |
push solen |
push bo |
call call_method |
js wece2 |
push varout |
call [VariantClear] |
mov eax, [esi] |
push esi |
call dword [eax+8] |
pop eax |
pop esi |
mov eax, [esi] |
push esi |
call dword [eax+8] |
mov eax, [edi] |
push edi |
call dword [eax+8] |
call [CoUninitialize] |
jmp suci |
wece4: |
pop esi |
wece2: |
mov eax, [esi] |
push esi |
call dword [eax+8] |
pop eax |
pop esi |
push eax |
wece3: |
mov dword [vartmpstr+8], menuitems |
pop eax |
push dop |
push don |
push bs |
call call_method |
pop eax |
jmp wece |
write_mtldr1: |
push ebx |
push 80h |
push 2 |
push ebx |
push ebx |
push 40000000h |
push mtldr_name |
call [CreateFileA] |
inc eax |
jnz @f |
push 10h |
push ebx |
push noc |
jmp mbx |
@@: |
dec eax |
xchg eax, esi |
push ebx |
push tmp |
push mtldr_code_size |
push mtldr_code |
push esi |
call [WriteFile] |
push img_real_name |
push img_real_name |
call [CharToOemA] |
mov edi, img_real_name+3 |
push edi |
call [lstrlenA] |
inc eax |
push eax |
push ebx |
push tmp |
push eax |
push edi |
push esi |
call [WriteFile] |
pop ecx |
ret |
delete_mtldr: |
push mtldr_name |
push mtldr_name |
push mtldr_name |
call [OemToCharA] |
call [DeleteFileA] |
ret |
adjust_privilege: |
cmp [advapi32], 0 |
jnz @f |
push advapi32_name |
call [LoadLibraryA] |
mov [advapi32], eax |
mov esi, eax |
test esi, esi |
jz ape |
push opts |
push esi |
call [GetProcAddress] |
mov [OpenProcessToken], eax |
test eax, eax |
jz ape |
push lpvs |
push esi |
call [GetProcAddress] |
mov [LookupPrivilegeValueA], eax |
test eax, eax |
jz ape |
push atps |
push esi |
call [GetProcAddress] |
mov [AdjustTokenPrivileges], eax |
test eax, eax |
jz ape |
@@: |
push ebx |
push esp |
push 28h |
call [GetCurrentProcess] |
push eax |
call [OpenProcessToken] |
test eax, eax |
pop esi |
jz ape |
push 2 |
push ebx |
push ebx |
mov eax, esp |
push 1 |
push eax |
push edi |
push ebx |
call [LookupPrivilegeValueA] |
test eax, eax |
jz ape2 |
mov eax, esp |
push ebx |
push ebx |
push ebx |
push eax |
push ebx |
push esi |
call [AdjustTokenPrivileges] |
test eax, eax |
jz ape2 |
add esp, 10h |
push esi |
call [CloseHandle] |
ret |
ape2: |
add esp, 10h |
push esi |
call [CloseHandle] |
ape: |
push 10h |
push ebx |
push apf |
jmp mbx |
call_method: |
push ebx |
mov eax, esp |
push ebx |
push eax |
push ebx |
push ebx |
push dword [eax+8] |
mov eax, [edi] |
push edi |
call dword [eax+24] |
xchg edi, [esp] |
test eax, eax |
js r |
push ebx |
mov eax, esp |
push ebx |
push eax |
push ebx |
push dword [eax+16] |
mov eax, [edi] |
push edi |
call dword [eax+76] |
push eax |
mov eax, [edi] |
push edi |
call dword [eax+8] |
pop eax |
pop edi |
test eax, eax |
js r |
push ebx |
push esp |
push ebx |
mov eax, [edi] |
push edi |
call dword [eax+60] |
push eax |
mov eax, [edi] |
push edi |
call dword [eax+8] |
pop eax |
pop edi |
test eax, eax |
js r |
cml1: |
mov eax, [esp+16] |
add dword [esp+16], 8 |
cmp dword [eax], 0 |
jz cme1 |
push ebx |
push dword [eax+4] |
push ebx |
push dword [eax] |
mov eax, [edi] |
push edi |
call dword [eax+20] |
test eax, eax |
js r2 |
jmp cml1 |
cme1: |
and dword [varout], 0 |
mov ecx, [esp+8] |
test esi, esi |
jz cms |
push ebx |
push ebx |
push varout |
push ebx |
push rpn |
mov eax, [esi] |
push esi |
call dword [eax+16] |
test eax, eax |
js r2 |
cmp word [varout], 8 |
jnz r2 |
mov ecx, [varout+8] |
cms: |
pop edx |
push edx |
push ebx |
mov eax, esp |
push ebx |
push eax |
push edi |
push ebx |
push ebx |
push dword [eax+16] |
push ecx |
mov eax, [edx] |
push edx |
call dword [eax+96] |
push eax |
mov eax, [edi] |
push edi |
call dword [eax+8] |
push varout |
call [VariantClear] |
pop eax |
pop edi |
test eax, eax |
js r |
push ebx |
push ebx |
push varout |
push ebx |
push retvaln |
mov eax, [edi] |
push edi |
call dword [eax+16] |
test eax, eax |
js r2 |
mov eax, 80000000h |
cmp word [varout], 11 |
jnz r2 |
cmp word [varout+8], 0 |
jz r2 |
mov eax, [esp+16] |
mov eax, [eax-4] |
test eax, eax |
jz r2 |
push ebx |
push ebx |
push varout |
push ebx |
push eax |
mov eax, [edi] |
push edi |
call dword [eax+16] |
test eax, eax |
js r2 |
cmp word [varout], 13 |
setnz al |
shl eax, 31 |
r2: |
push eax |
mov eax, [edi] |
push edi |
call dword [eax+8] |
pop eax |
r: |
pop edi |
test eax, eax |
ret 8 |
ofn_hook: |
cmp dword [esp+8], 2 |
jnz @f |
push 260 |
push ostitle |
push 23 |
push dword [esp+12+4] |
call [GetDlgItemTextA] |
@@: |
xor eax, eax |
ret 10h |
section '.data' data readable writable |
data resource from 'rsrc.res' |
end data |
align 4 |
ofn: |
dd 76 |
dd 0 |
dd ofn_title_template |
dd filter |
dd 0 |
dd 0 |
dd 0 |
dd img_name |
dd 100h |
dd 0 |
dd 0 |
dd 0 |
dd ofn_title |
dd 818A4h |
dd 0 |
dd aImg |
dd 0 |
dd ofn_hook |
dd 0 |
ofn_title_template: |
dw 1,-1 |
dd 0 |
dd 0 |
dd 56000444h |
dw 2 |
dw 0,0,275,28 |
dw 0,0,0 |
dw 8 |
dd 0 |
du 'MS Sans Serif',0 |
align 4 |
dd 0 |
dd 0 |
dd 50010000h |
dw 5,12,45,9 |
dw -1 |
dw 0 |
dw -1,82h |
du 'Title:',0 |
dw 0 |
align 4 |
dd 0 |
dd 204h |
dd 50010080h |
dw 54,10,218,12 |
dw 23 |
dw 0 |
dw -1,81h |
du 'KolibriOS',0 |
dw 0 |
filter db 'Image files (*.img)',0,'*.img',0,'All files',0,'*.*',0,0 |
ofn_title db 'Select KolibriOS image file',0 |
aImg db 'img',0 |
norightsmsg db 'Cannot query drive info.',10 |
db 'Probably it is invalid drive or you are not administrator',0 |
nohd db 'Image must be on hard disk!',0 |
m1 db 'Please mail to diamondz@land.ru',0 |
nom db "Too many mtldr's found!",0 |
noc db 'Cannot create mtldr file!',0 |
osstr db 'operating systems',0 |
bootini db 'c:\boot.ini',0 |
insterr db 'Cannot write to boot.ini. Probably you are not administrator.',0 |
insterr2 db 'Cannot open config.sys',0 |
ptl db 'Path is too long',0 |
succ db 'Installation successful!',0 |
suct db 'Success',0 |
vwin32 db '\\.\vwin32',0 |
config db 'C:\config.sys',0 |
sec9x2 db ']',13,10 |
install db 'install=' |
newline db 13,10 |
menuitem db 'kolibri',0 |
mis db 'menuitem=' |
title9x db ',Load ' |
title9xsz = $ - title9x |
title9x2 db 13,10,13,10,'[' |
title9x2sz = $ - title9x2 |
ld1 db 'Load ' |
ld1sz = $ - ld1 |
ld2 db '? [y/n]: ',0 |
ld2sz = $ - ld2 |
apf db 'Cannot adjust backup and restore privileges',0 |
opts db 'OpenProcessToken',0 |
lpvs db 'LookupPrivilegeValueA',0 |
atps db 'AdjustTokenPrivileges',0 |
sbn db 'SeBackupPrivilege',0 |
srn db 'SeRestorePrivilege',0 |
wmierr db 'BCD WMI API: initialization error',0 |
coerr db 'Cannot create BCD object for KolibriOS loader',0 |
setproperr db 'Cannot create BCD element in object for KolibriOS loader',0 |
orerr db 'Cannot add KolibriOS loader in BCD display list',0 |
ns du 'root\wmi',0 |
retvaln du 'ReturnValue' |
emptystr du 0 |
rpn du '__Relpath',0 |
bs du 'BcdStore',0 |
bo du 'BcdObject',0 |
osn du 'OpenStore',0 |
con du 'CreateObject',0 |
don du 'DeleteObject',0 |
oon du 'OpenObject',0 |
ssen du 'SetStringElement',0 |
spden du 'SetPartitionDeviceElement',0 |
gen du 'GetElement',0 |
solen du 'SetObjectListElement',0 |
fn du 'File',0 |
storen du 'Store',0 |
idn du 'Id',0 |
idsn du 'Ids',0 |
tn du 'Type',0 |
obn du 'Object',0 |
sn du 'String',0 |
dtn du 'DeviceType',0 |
aon du 'AdditionalOptions',0 |
pn du 'Path',0 |
en du 'Element',0 |
bg du '{9dea862c-5cdd-4e70-acc1-f32b344d4795}',0 |
align 4 |
advapi32 dd 0 |
regs: |
dd 0 |
dd diskinfobuf |
dd 86Fh |
dd 440Dh |
dd 0 |
dd 0 |
dd 1 |
diskinfobuf: |
db 10h,0,0,0FFh |
times 0Ch db 0 |
IID_IWbemLocator: |
dd 0DC12A687h |
dw 737Fh |
dw 11CFh |
db 88h, 4Dh, 00h, 0AAh, 00h, 4Bh, 2Eh, 24h |
CLSID_WbemLocator: |
dd 4590F811h |
dw 1D3Ah |
dw 11D0h |
db 89h, 1Fh, 00h, 0AAh, 00h, 4Bh, 2Eh, 24h |
IID_IWbemClassObject: |
dd 0DC12A681h |
dw 737Fh |
dw 11CFh |
db 88h, 4Dh, 00h, 0AAh, 00h, 4Bh, 2Eh, 24h |
varemptystr: |
dd 8, 0, emptystr, 0 |
vartmpstr: |
dd 8, 0, menuitems, 0 |
varbootmgr: |
dd 8, 0, bg, 0 |
vari32: |
dd 3, 0, 10400008h, 0 |
vari32_pd: |
dd 3, 0, 2, 0 |
osp: |
dd fn, varemptystr |
dd 0, storen |
dd idn, vartmpstr |
dd tn, vari32 |
dd 0, obn |
dd tn, vari32 |
dd sn, vartmpstr |
dd 0, 0 |
dd tn, vari32 |
dd dtn, vari32_pd |
dd aon, varemptystr |
dd pn, vartmpstr |
dd 0, 0 |
dd idn, varbootmgr |
dd 0, obn |
dd tn, vari32 |
dd 0, en |
dd tn, vari32 |
dd idsn, varout |
dd 0, 0 |
dop: |
dd idn, vartmpstr |
dd 0, 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 comdlg32_name, rva comdlg32_thunks |
dd 0,0,0, rva ole32_name, rva ole32_thunks |
dd 0,0,0, rva oleaut32_name, rva oleaut32_thunks |
dd 0,0,0,0,0 |
kernel32_name db 'kernel32.dll',0 |
user32_name db 'user32.dll',0 |
advapi32_name db 'advapi32.dll',0 |
comdlg32_name db 'comdlg32.dll',0 |
ole32_name db 'ole32.dll',0 |
oleaut32_name db 'oleaut32.dll',0 |
kernel32_thunks: |
GetVersion dd rva GetVersion_thunk |
CreateFileA dd rva CreateFileA_thunk |
DeviceIoControl dd rva DeviceIoControl_thunk |
CloseHandle dd rva CloseHandle_thunk |
GetFileAttributesA dd rva GetFileAttributesA_thunk |
SetFileAttributesA dd rva SetFileAttributesA_thunk |
GetLastError dd rva GetLastError_thunk |
ReadFile dd rva ReadFile_thunk |
WriteFile dd rva WriteFile_thunk |
ExitProcess dd rva ExitProcess_thunk |
WritePrivateProfileStringA dd rva WritePrivateProfileStringA_thunk |
GetShortPathNameA dd rva GetShortPathNameA_thunk |
lstrlenA dd rva lstrlenA_thunk |
VirtualAlloc dd rva VirtualAlloc_thunk |
GetFileSize dd rva GetFileSize_thunk |
DeleteFileA dd rva DeleteFileA_thunk |
MultiByteToWideChar dd rva MultiByteToWideChar_thunk |
GetCurrentProcess dd rva GetCurrentProcess_thunk |
LoadLibraryA dd rva LoadLibraryA_thunk |
GetProcAddress dd rva GetProcAddress_thunk |
dw 0 |
thunk GetVersion |
thunk CreateFileA |
thunk DeviceIoControl |
thunk CloseHandle |
thunk GetFileAttributesA |
thunk SetFileAttributesA |
thunk GetLastError |
thunk ReadFile |
thunk WriteFile |
thunk ExitProcess |
thunk WritePrivateProfileStringA |
thunk GetShortPathNameA |
thunk lstrlenA |
thunk VirtualAlloc |
thunk GetFileSize |
thunk DeleteFileA |
thunk MultiByteToWideChar |
thunk GetCurrentProcess |
thunk LoadLibraryA |
thunk GetProcAddress |
user32_thunks: |
MessageBoxA dd rva MessageBoxA_thunk |
CharToOemA dd rva CharToOemA_thunk |
OemToCharA dd rva OemToCharA_thunk |
GetDlgItemTextA dd rva GetDlgItemTextA_thunk |
dw 0 |
thunk MessageBoxA |
thunk CharToOemA |
thunk OemToCharA |
thunk GetDlgItemTextA |
comdlg32_thunks: |
GetOpenFileNameA dd rva GetOpenFileNameA_thunk |
dw 0 |
thunk GetOpenFileNameA |
ole32_thunks: |
CoInitializeEx dd rva CoInitializeEx_thunk |
CoUninitialize dd rva CoUninitialize_thunk |
CoInitializeSecurity dd rva CoInitializeSecurity_thunk |
CoCreateInstance dd rva CoCreateInstance_thunk |
CoSetProxyBlanket dd rva CoSetProxyBlanket_thunk |
CoCreateGuid dd rva CoCreateGuid_thunk |
StringFromGUID2 dd rva StringFromGUID2_thunk |
dw 0 |
thunk CoInitializeEx |
thunk CoUninitialize |
thunk CoInitializeSecurity |
thunk CoCreateInstance |
thunk CoSetProxyBlanket |
thunk CoCreateGuid |
thunk StringFromGUID2 |
oleaut32_thunks: |
VariantClear dd rva VariantClear_thunk |
SafeArrayRedim dd rva SafeArrayRedim_thunk |
SafeArrayPutElement dd rva SafeArrayPutElement_thunk |
SysAllocString dd rva SysAllocString_thunk |
SysFreeString dd rva SysFreeString_thunk |
dw 0 |
thunk VariantClear |
thunk SafeArrayRedim |
thunk SafeArrayPutElement |
thunk SysAllocString |
thunk SysFreeString |
end data |
mtldr_code: |
file 'mtldr_for_installer' |
mtldr_code_size = $ - mtldr_code |
dn db '\\.\' |
img_name rb 256 |
img_real_name rb 256 |
mtldr_name rb 256 |
tmp_data rb 2000h |
ostitle rb 260 |
systitle rb 262 |
align 4 |
OpenProcessToken dd ? |
LookupPrivilegeValueA dd ? |
AdjustTokenPrivileges dd ? |
tmp dd ? |
sdn rd 3 |
pi rd 8 |
varout rd 4 |
guid rd 4 |
b9x db ? |
menuitems rb 100h |
/programs/hd_load/mtldr_install/rsrc.res |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |