Added new driver for mount raw disk images.

- Added driver virt_disk.sys
 - Added the program "virtdisk" which allows you to add, delete and view virtual disks.

git-svn-id: svn://kolibrios.org@9945 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
Doczom 2023-10-01 08:47:52 +00:00
parent 244de0059e
commit 9ab6258bfe
7 changed files with 1557 additions and 0 deletions

View File

@ -2,3 +2,4 @@ if tup.getconfig("NO_FASM") ~= "" then return end
ROOT = "../.."
tup.include(ROOT .. "/programs/use_fasm.lua")
tup.rule("tmpdisk.asm", "fasm %f %o " .. PESTRIP_CMD .. tup.getconfig("KPACK_CMD"), "%B.sys")
tup.rule("virt_disk.asm", "fasm %f %o " .. PESTRIP_CMD .. tup.getconfig("KPACK_CMD"), "%B.sys")

725
drivers/disk/virt_disk.asm Normal file
View File

@ -0,0 +1,725 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2023. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; Virtual disk driver for KolibriOS ;;
;; ;;
;; Written by Mikhail Frolov aka Doczom ;;
;; ;;
;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
DISK_STATUS_OK = 0 ; success
DISK_STATUS_GENERAL_ERROR = -1; if no other code is suitable
DISK_STATUS_INVALID_CALL = 1 ; invalid input parameters
DISK_STATUS_NO_MEDIA = 2 ; no media present
DISK_STATUS_END_OF_MEDIA = 3 ; end of media while reading/writing data
; For all IOCTLs the driver returns one of the following error codes:
NO_ERROR equ 0
ERROR_INVALID_IOCTL equ 1 ; unknown IOCTL code
maxPathLength = 1000h
include '../struct.inc'
; TODO list:
; add support VDI image
; Input structures:
Flag:
.Ro = 1b
.Wo = 10b
.RW = 11b
struct DISK_DEV
next rd 1
pref rd 1
SectorCount rd 2
DiskHandle rd 1
DiskNumber rd 1
Flags rd 1 ; 1-ro 2-wo 3-rw
TypeImage rd 1 ; 0-raw 1-vhd 2-vdi 3-imd
SectorSize rd 1
DiskPath rb maxPathLength
ends
struct IMAGE_ADD_STRUCT
Flags rd 1 ; 1-ro 2-wo 3-rw
TypeImage rd 1 ; 0-raw 1-vhd 2-vdi 3-imd
SectorSize rd 1
DiskPath rb maxPathLength
ends
struct DISKMEDIAINFO
Flags dd ?
SectorSize dd ?
Capacity dq ?
ends
DEBUG = 1
__DEBUG__ = 1
__DEBUG_LEVEL__ = 1 ; 1 = verbose, 2 = errors only
format PE DLL native 0.05
entry START
section '.flat' code readable writable executable
include '../proc32.inc'
include '../peimport.inc'
include '../macros.inc'
include '../fdo.inc'
proc START c, state:dword, cmdline:dword
xor eax, eax ; set return value in case we will do nothing
cmp dword [state], 1
jne .nothing
mov ecx, disk_list_lock
invoke MutexInit
DEBUGF 1, "VIRT_DISK: driver loaded\n"
invoke RegService, my_service, service_proc
ret
.nothing:
ret
endp
; get version
; add disk
; del disk
; get list disks
; get disk info
proc service_proc
push ebx esi edi
; 2. Get parameter from the stack: [esp+16] is the first parameter,
; pointer to IOCTL structure.
mov ebx, [esp + 16] ; edx -> IOCTL
mov ecx, [ebx + IOCTL.io_code]
test ecx, ecx ; check for SRV_GETVERSION
jnz .add_disk
cmp [ebx + IOCTL.out_size], 4
jb .error_ret
mov eax, [ebx + IOCTL.output]
mov dword [eax], 1 ;API_VERSION
xor eax, eax
jmp .return
.add_disk:
dec ecx ; check for DEV_ADD_DISK
jnz .del_disk
cmp [ebx + IOCTL.inp_size], sizeof.IMAGE_ADD_STRUCT
jb .error_ret
cmp [ebx + IOCTL.out_size], 4
jb .error_ret
invoke KernelAlloc, sizeof.DISK_DEV
test eax, eax
jz .error_ret
push eax
mov edi, eax
mov ecx, sizeof.DISK_DEV/4
xor eax, eax
rep stosd
pop eax
mov edi, eax
add edi, DISK_DEV.Flags
mov esi, [ebx + IOCTL.input]
mov ecx, sizeof.IMAGE_ADD_STRUCT/4
rep movsd
mov esi, eax ;save
cmp byte[esi + DISK_DEV.DiskPath], '/'
jnz .add_disk.error
mov ecx, disk_list_lock
invoke MutexLock
call get_free_num
jnz .add_disk.error2
mov [esi + DISK_DEV.DiskNumber], eax
mov ecx,[ebx + IOCTL.output]
mov [ecx], eax
; init image
mov eax, [esi + DISK_DEV.TypeImage]
cmp eax, image_type.max_num
ja .add_disk.error2
call dword[image_type + eax*8] ;esi - DISK_DEV*
test eax, eax
jnz .add_disk.error2
; creating name
push ebp
mov ebp, esp
mov eax, [esi + DISK_DEV.DiskNumber]
mov edi, esp
dec edi
mov byte[edi], 0
mov ecx, 10
@@:
xor edx, edx
div ecx
add edx,'0'
dec edi
mov byte[edi], dl
test eax, eax
jnz @b
mov esp, edi
push word 'vd'
sub edi, 2
; add disk
mov eax, [esi + DISK_DEV.TypeImage]
invoke DiskAdd, dword[image_type + eax*8 + 4] , \
edi, esi, 0
mov [esi + DISK_DEV.DiskHandle], eax
mov esp, ebp
pop ebp
test eax, eax
jz .add_disk.error2
invoke DiskMediaChanged, eax, 1
; add in list
mov dword[esi], disk_root_list
mov eax, [disk_root_list + 4]
mov [esi + 4], eax
mov [eax], esi
mov [disk_root_list + 4], esi
inc dword[disk_count]
mov ecx, disk_list_lock
invoke MutexUnlock
xor eax, eax
jmp .return
.add_disk.error2:
mov ecx, disk_list_lock
invoke MutexUnlock
.add_disk.error:
invoke KernelFree, esi
jmp .error_ret
.del_disk:
dec ecx ; check for DEV_DEL_DISK
jnz .get_root_list
cmp [ebx + IOCTL.inp_size], 4
jb .error_ret
mov ecx, [ebx + IOCTL.input]
mov ecx, [ecx]
call get_disk
test eax, eax
jz .error_ret
cmp [eax + DISK_DEV.DiskHandle], 0
jz .error_ret
mov ecx, [eax + DISK_DEV.DiskHandle]
mov [eax + DISK_DEV.DiskHandle], 0
invoke DiskDel, ecx
xor eax, eax
jmp .return
.get_root_list:
dec ecx ; check for DEV_DEL_DISK
jnz .get_disk_info
cmp [ebx + IOCTL.inp_size], 4*2 ; offset + count
jb .error_ret
mov ecx, [ebx + IOCTL.input]
mov edx, [ecx] ; offset
mov eax, [ecx + 4] ; count
add edx, eax
cmp edx, [disk_count]
ja .error_ret
xor edx, edx
imul eax, sizeof.DISK_DEV - 8
add eax, 4
cmp [ebx + IOCTL.out_size], eax
jb .error_ret
mov edi, [ebx + IOCTL.output]
mov eax, [disk_count]
stosd
mov edx, [ecx]
mov eax, [disk_root_list]
@@:
test edx, edx
jz @f
mov eax, [eax]
dec edx
jmp @b
@@:
mov edx, [ecx + 4]
@@:
test edx, edx
jz @f
mov esi, eax
add esi, 8
mov ecx, (sizeof.DISK_DEV - 8)/4
rep movsd
mov eax, [eax]
dec edx
jmp @b
@@:
xor eax, eax
jmp .return
.get_disk_info:
dec ecx
jnz .error_ret
cmp [ebx + IOCTL.inp_size], 4
jb .error_ret
cmp [ebx + IOCTL.out_size], sizeof.DISK_DEV - 8
jb .error_ret
mov ecx, [ebx + IOCTL.input]
mov ecx, [ecx]
call get_disk
test eax, eax
jz .error_ret
mov esi, eax
add esi, 4*2
mov edi, [ebx + IOCTL.output]
mov ecx, (sizeof.DISK_DEV - 8)/4
rep movsd
xor eax, eax
jmp .return
.error_ret:
mov eax, ERROR_INVALID_IOCTL
.return:
pop edi esi ebx
retn 4
endp
; IN: ecx - ptr DISK_DEV
; OUT: ZF - found zF - not found
proc disk_dev_check
push eax
mov eax, disk_root_list
@@:
mov eax, [eax]
cmp eax, disk_root_list
jz .nf
cmp eax, ecx
jnz @b
pop eax
ret
.nf:
test eax, eax
pop eax
ret
endp
; IN: ecx - disk number
; OUT: eax - ptr DISK_DEV
proc get_disk
push ecx
mov ecx, disk_list_lock
invoke MutexLock
pop ecx
mov eax, disk_root_list
@@:
mov eax, [eax]
cmp eax, disk_root_list
jz .nf
cmp ecx, [eax + DISK_DEV.DiskNumber]
jnz @b
push eax
mov ecx, disk_list_lock
invoke MutexUnlock
pop eax
ret
.nf:
mov ecx, disk_list_lock
invoke MutexUnlock
xor eax, eax
ret
endp
; OUT: eax - number free disk
; Zf - good zf - not found
proc get_free_num
xor eax, eax
mov edx, disk_root_list
@@:
mov edx, [edx]
cmp edx, disk_root_list
jz @f
cmp eax, [edx + DISK_DEV.DiskNumber]
jnz @b
inc eax
jnz @b
test edx, edx ; random :)
@@:
ret
endp
;; IN: ecx - number disk
;; OUT: eax - ptr to DISK_DEV or zero
;proc get_link_disk
;
; push ecx
; mov ecx, disk_list_lock
; invoke MutexLock
; pop ecx
;
; xor eax, eax
; cmp ecx, [disk_array.len]
; jae .end
;
; mov eax, [disk_array]
; mov eax, [edx + ecx*4]
;
;.end:
; push eax
; ; unlock disk list
; mov ecx, disk_list_lock
; invoke MutexUnlock
; pop eax
; ret
;endp
;; IN: esi - ptr to DISK_DEV
;; OUT: eax - offset in array or -1
;proc add_link_disk
; ; find free item
; mov ecx, [disk_array]
; xor eax, eax
; dec eax
;@@:
; inc eax
; cmp eax, [disk_array.len]
; jae .not_found
;
; cmp dword[ecx + eax*4], 0
; jnz @b
;
; mov [ecx + eax*4], esi
; ret
;
;.not_found:
; inc dword[disk_array.len]
; ;get new memory
; mov eax,[disk_array.len]
; shl eax, 2 ;*4
; invoke Kmalloc
; test eax, eax
; jz .err
; ; copy data
; push edi esi
; mov ecx, [disk_array.len]
; mov edi, eax
; mov esi, [disk_array]
; rep movsd
; pop esi edi
; ; del old array
; xchg [disk_array], eax
; invoke Kfree
; mov eax, [disk_array.len]
; ret
;.err:
; dec dword[disk_array.len]
; mov eax, -1
; ret
;endp
;
;; IN: ecx - offset in array
;proc del_link_disk
; mov edx, ecx
; dec edx
; cmp edx,[disk_array.len]
; jz .last_item
;
; mov edx,[disk_array]
; mov [edx + ecx*4], 0
; ret
;.last_item:
; dec dword[disk_array.len]
; ;get new memory
; mov eax,[disk_array.len]
; shl eax, 2 ;*4
; invoke Kmalloc
; test eax, eax
; jz .err
; ; copy data
; push edi esi
; mov ecx, [disk_array.len]
; mov edi, eax
; mov esi, [disk_array]
; rep movsd
; pop esi edi
; ; del old array
; xchg [disk_array], eax
; invoke Kfree
; ret
;.err:
; inc dword[disk_array.len]
; mov eax, -1
; ret
;endp
; RAW IMAGE DISK FUNCTIONS
proc raw_disk_close stdcall, pdata
; del item list
mov ecx, disk_list_lock
invoke MutexLock
mov ecx, [pdata]
mov eax, [ecx] ; eax = next
mov edx, [ecx + 4] ; edx = prev
mov [eax + 4], edx ; [next.prev] = prev
mov [edx], eax ; [prev.next] = next
dec dword[disk_count]
mov ecx, disk_list_lock
invoke MutexUnlock
invoke KernelFree, [pdata]
DEBUGF 1, "VIRT_DISK: disk deleted\n"
ret
endp
proc disk_querymedia stdcall, pdata, mediainfo
mov eax, [mediainfo]
mov edx, [pdata]
mov [eax + DISKMEDIAINFO.Flags], 0
mov ecx, [edx + DISK_DEV.SectorSize]
mov [eax + DISKMEDIAINFO.SectorSize], ecx
mov ecx, [edx + DISK_DEV.SectorCount]
mov dword[eax + DISKMEDIAINFO.Capacity], ecx
mov ecx, [edx + DISK_DEV.SectorCount + 4]
mov dword[eax + DISKMEDIAINFO.Capacity + 4], ecx
xor eax, eax
ret
endp
proc raw_disk_rd stdcall pdata: dword,\
buffer: dword,\
startsector: qword,\
numsectors_ptr:dword
mov ecx, [pdata]
test [ecx + DISK_DEV.Flags], Flag.Ro
jz .no_support
pusha
lea eax,[ecx + DISK_DEV.DiskPath]
push eax
dec esp
mov byte[esp], 0
push dword[buffer]
mov eax, [numsectors_ptr]
mov eax, [eax]
mul dword[ecx + DISK_DEV.SectorSize]
push eax
; get offset for startsector
mov eax, dword[startsector]
xor edx, edx
mul dword[ecx + DISK_DEV.SectorSize]
push edx
push eax
mov eax, dword[startsector + 4]
mul dword[ecx + DISK_DEV.SectorSize]
add [esp + 4], eax
push dword 0 ;read file
mov ebx, esp
invoke FS_Service
push eax
mov ecx, [pdata]
mov eax, ebx
xor edx, edx
div dword[ecx + DISK_DEV.SectorSize]
mov edx, [numsectors_ptr]
mov [edx], eax
pop eax
add esp, 6*4+1 ; size FS struct
test eax, eax
popa
jz @f
mov eax, 1
ret
@@:
xor eax, eax
ret
.no_support:
mov eax, DISK_STATUS_GENERAL_ERROR
ret
endp
proc raw_disk_wr stdcall pdata: dword,\
buffer: dword,\
startsector: qword,\
numsectors_ptr:dword
mov ecx, [pdata]
test [ecx + DISK_DEV.Flags], Flag.Wo
jz .no_support
pusha
lea eax,[ecx + DISK_DEV.DiskPath]
push eax
dec esp
mov byte[esp],0
push dword[buffer]
mov eax, [numsectors_ptr]
mov eax, [eax]
mul dword[ecx + DISK_DEV.SectorSize]
push eax
; get offset for startsector
mov eax, dword[startsector]
xor edx, edx
mul dword[ecx + DISK_DEV.SectorSize]
push edx
push eax
xor edx, edx
mov eax, dword[startsector + 4]
mul dword[ecx + DISK_DEV.SectorSize]
add [esp + 4], eax
push dword 3 ; write file
mov ebx, esp
invoke FS_Service
push eax
mov ecx, [pdata]
mov eax, ebx
xor edx, edx
div dword[ecx + DISK_DEV.SectorSize]
mov edx, [numsectors_ptr]
mov [edx], eax
pop eax
add esp, 6*4+1 ; size FS struct
test eax, eax
popa
jz @f
mov eax, 1
ret
@@:
xor eax, eax
ret
.no_support:
mov eax, DISK_STATUS_GENERAL_ERROR
ret
endp
disk_root_list:
dd disk_root_list
dd disk_root_list
disk_count: dd 0
disk_list_lock: MUTEX
image_type:
; init function, table disk function
dd raw_image_init, raw_disk_functions
; vdi
.max_num = ($ - image_type - 8) / 8; 8 - item size
align 4
; esi - ptr to DISK_DEV
;WARNING: raw image size >=2tb not supported.
proc raw_image_init
sub esp, 40 ; for file_info
mov ecx, esp
pusha
lea eax,[esi + DISK_DEV.DiskPath]
push eax
dec esp
mov byte[esp],0
push ecx
xor eax, eax
push eax eax eax
push dword 5
mov ebx, esp
invoke FS_Service
add esp, 6*4+1
test eax, eax
popa
lea esp,[esp + 40]
jnz .err
; WARNING: Not working with stack, destroys the structure!
mov eax, [ecx + 32]
mov edx, [ecx + 36]
test eax, eax
jz .err
div dword[esi + DISK_DEV.SectorSize] ; undefined exeption
mov [esi + DISK_DEV.SectorCount], eax
mov [esi + DISK_DEV.SectorCount + 4], 0
; END WARNING
xor eax, eax
ret
.err:
or eax, -1
ret
endp
align 4
raw_disk_functions:
dd .size
dd raw_disk_close
dd 0 ; no need in .closemedia
dd disk_querymedia
dd raw_disk_rd
dd raw_disk_wr
dd 0 ; no need in .flush
dd disk_adjust_cache_size
.size = $ - raw_disk_functions
proc disk_adjust_cache_size
virtual at esp+4
.userdata dd ?
.suggested_size dd ?
end virtual
xor eax, eax
retn 8
endp
my_service db 'VIRT_DISK',0
data fixups
end data
include_debug_strings

View File

@ -0,0 +1,34 @@
# VIRT_DISK
Driver for mounting RAW disk images in KolibriOS.
To demonstrate the operation of the driver, the virtdisk program was written. Program allows you to add, delete and view virtual disks.
![foto](https://github.com/Doczom/VIRT_DISK/blob/main/utils/scr_1.png)
## List of virtdisk arguments:
- Delete command:
<CODE> virtdisk -d <DISK_NUMBER> </CODE>
- Information from disk:
<CODE> virtdisk -i <DISK_NUMBER> </CODE>
- Add disk image in file system:
<CODE> virtdisk -a <IMAGE_PATH> -s <SECTOR_SIZE> -t <IMAGE_TYPE> -f <ACCESS_FLAGS> </CODE>
- Input list all virtual disks:
<CODE> virtdisk -l </CODE>
## List flags:
- <CODE>ro</CODE> - read only access
- <CODE>rw</CODE> - read-write access
## List disk image types:
- <CODE>RAW</CODE> - it is used to mount disk images in "raw", "img" and "iso" formats
## Exemples command:
<CODE> virtdisk -a /sd0/4/kolibri.img -f ro </CODE>
<CODE> virtdisk -d 3 </CODE>

View File

@ -0,0 +1,2 @@
if tup.getconfig("NO_FASM") ~= "" then return end
tup.rule("virtdisk.asm", "fasm %f %o " .. tup.getconfig("KPACK_CMD"), "virtdisk")

View File

@ -0,0 +1,322 @@
; data for parsing string
param_cmd: dd 0 ;set when for "-a" command
; virtdisk -d <DISK_NUMBER>
; virtdisk -i <DISK_NUMBER>
; virtdisk -a <PATH> -s <SECTOR_SIZE> -t <IMAGE_TYPE> -f <FLAGS>
; virtdisk -l
parse_cmd:
mov edi, PATH
; find string length
xor al, al
mov ecx, 4096
repne scasb
mov ecx, edi
sub ecx, PATH
mov edi, PATH
.still:
mov al, ' '
repz scasb
test ecx, ecx
jz .end_parser
dec edi
or word[edi], 0x2020 ; ïåðåâîäèì â íèæíèé ðåãèñòð
; -a -d -i -l -s -t -f
cmp word[edi], '-a'
jnz @f
;add virt disk
mov dword[param_cmd],-1
add edi, 3
sub ecx, 2
js ERROR_EXIT ; error not found path
mov edx, add_disk.file
call .copy_str
or dword[edx -4], 0x20202020
mov dword[add_disk.size], 512
cmp dword[edx -4], '.iso'
jnz .still
mov dword[add_disk.size], 2048
jmp .still
@@:
cmp word[edi], '-d'
jnz @f
add edi, 3
sub ecx, 2
js ERROR_EXIT ; error not found path
call .get_number
mov [disk_num],eax
pusha
mov al, 68
mov bl, 17
mov ecx, ioctl_del_disk
int 0x40
push str_command_successfully
call _sc_puts
popa
jmp .still
@@:
cmp word[edi], '-i'
jnz .no_disk_info
; write info
add edi, 3
sub ecx, 2
js ERROR_EXIT ; error not found path
; get disk number
call .get_number
mov [disk_num],eax
pusha
mov al, 68
mov bl, 17
mov ecx, ioctl_info_disk
int 0x40
call write_disk_info
popa
jmp .still
.no_disk_info:
cmp word[edi], '-l'
jnz .no_disk_list
; write list disks
add edi, 2
sub ecx, 1
pusha
mov al, 68
mov bl, 17
mov ecx, ioctl_count_disk
int 0x40
test eax, eax
jnz ERROR_EXIT
push str_header_disk_list
call _sc_puts
mov ecx, ioctl_list_disk.count
mov eax, 68
mov bl, 12
imul ecx, sizeof.info_buffer
add ecx, 4
mov [ioctl_list_disk.size_buffer], ecx
int 0x40
test eax, eax
jz ERROR_EXIT
mov [ioctl_list_disk.buffer], eax
mov esi, eax
mov edi, eax
add esi, 4
mov al, 68
mov bl, 17
mov ecx, ioctl_list_disk
int 0x40
test eax, eax
jnz ERROR_EXIT
cmp dword[edi], 0
jz .end_list
.next_item_list:
; num2str
push dword 10
mov ecx, esp
mov eax, [esi + info_buffer.disk_num - info_buffer]
@@:
xor edx, edx
div dword[esp]
dec ecx
add dl, '0'
mov byte[ecx], dl
test eax, eax
jnz @b
mov edx, str_input_disk_number + 1
mov dword[edx], ' '
@@:
mov al, byte[ecx]
mov byte[edx], al
inc edx
inc ecx
cmp ecx, esp
jnz @b
;-------
mov ecx, esp
mov eax, [esi + info_buffer.sector_size - info_buffer]
@@:
xor edx, edx
div dword[esp]
dec ecx
add dl, '0'
mov byte[ecx], dl
test eax, eax
jnz @b
mov edx, str_input_disk_sector
mov dword[edx], ' '
@@:
mov al, byte[ecx]
mov byte[edx], al
inc edx
inc ecx
cmp ecx, esp
jnz @b
;-------
add esp, 4
; flags
mov dword[str_input_disk_flags], ' '
cmp dword[esi + info_buffer.flags - info_buffer], 1b
jnz @f
mov word[str_input_disk_flags], 'ro'
@@:
cmp dword[esi + info_buffer.flags - info_buffer], 11b
jnz @f
mov word[str_input_disk_flags], 'rw'
@@:
;-------
pusha
add esi, info_buffer.path - info_buffer
push esi
push str_input_disk_number
call _sc_puts
call _sc_puts
push str_newline
call _sc_puts
popa
add esi, sizeof.info_buffer
dec dword[edi]
jnz .next_item_list
.end_list:
mov eax, 68
mov ebx, 13
mov ecx, edi
int 0x40
popa
jmp .still
.no_disk_list:
cmp dword[param_cmd],0
jz .no_cmd
cmp word[edi], '-s'
jnz .no_sector_size
; set sector size for -a command
add edi, 3
sub ecx, 2
js ERROR_EXIT ; error
; get number
call .get_number
mov [add_disk.size], eax
jmp .still
.no_sector_size:
cmp word[edi], '-t'
jnz .no_disk_type
; set image type for -a command
add edi, 3+3
sub ecx, 2+3
js ERROR_EXIT ; error
or dword[edi - 4], 0x20202020
cmp dword[edi - 4], ' raw'
jnz .still
; TODO!!!
mov dword[add_disk.type], 0
jmp .still
.no_disk_type:
cmp word[edi], '-f'
jnz .no_cmd
; set flags for -a command
add edi, 3+2
sub ecx, 2+2
js ERROR_EXIT ; error
or word[edi - 2], 0x2020
cmp word[edi - 2], 'ro'
jnz @f
mov dword[add_disk.flags], 1b
@@: cmp word[edi - 2], 'rw'
jnz .still
mov dword[add_disk.flags], 11b
jmp .still
.no_cmd:
inc edi
jmp .still
.end_parser:
ret
.get_str:
push edi
inc dword[esp]
mov al, '"'
cmp byte[edi], al
jz @f
dec dword[esp]
mov al, ' '
dec edi
@@:
inc edi
repne scasb
and byte[edi - 1], 0
pop eax
ret
; edx - buffer
.copy_str:
mov al, ' '
cmp byte[edi], '"'
jnz @f
mov al, '"'
inc edi
dec ecx
@@:
mov ah, byte[edi]
test ah, ah
jz @f
cmp ah, al
jz @f
mov byte[edx], ah
inc edx
inc edi
dec ecx
jmp @b
@@:
mov byte[edx], 0
ret
.get_number:
xor eax, eax
@@:
movzx edx, byte[edi]
test edx, edx
jz @f
cmp dl, ' '
jz @f
sub dl, '0'
js ERROR_EXIT
cmp dl, 9
ja ERROR_EXIT
imul eax, 10
add eax, edx
dec ecx
inc edi
jmp @b
@@:
ret

View File

@ -0,0 +1,300 @@
SC_OK = 0
SC_EXIT = 1
SC_PUTC = 2
SC_PUTS = 3
SC_GETC = 4
SC_GETS = 5
SC_CLS = 6
SC_PID = 7
SC_PING = 8
SHM_WRITE = 0x01
SHM_OPEN_ALWAYS = 0x04
;============================
align 4
sc_name rb 64
sc_pid dd 0
sc_buffer dd 0
sc_process dd 0
;============================
if used _sc_pid2name
align 4
_sc_pid2name:
push esp
push ebx
xor ecx, ecx
mov eax, [sc_pid]
mov ebx, 10
@@:
xor edx, edx
div ebx
push edx
inc ecx
test eax, eax
jnz @b
mov edi, sc_name
@@:
pop eax
add al, '0'
stosb
loop @b
mov al, '-'
stosb
mov al, 'S'
stosb
mov al, 'H'
stosb
mov al, 'E'
stosb
mov al, 'L'
stosb
mov al, 'L'
stosb
mov al, 0
stosb
pop ebx
pop esp
ret
end if
;============================
if used _sc_init
align 4
; void __stdcall sc_init();
_sc_init:
push esp
push ebx
mov eax, 68
mov ebx, 11
int 0x40
mov eax, 68 ; ¢ë¤¥«¨âì ¯ ¬ïâì
mov ebx, 12
mov ecx, 1024
int 0x40
mov [sc_process], eax
mov eax, 9 ; ¯®«ãç¨âì ¨­ä®à¬ æ¨î ® ⥪ã饬 ¯à®æ¥áá¥
mov ebx, [sc_process]
mov ecx, -1
int 0x40
mov dword eax, [ebx+30] ; ¯®«ãç ¥¬ PID ⥪饣® ¯à®æ¥áá 
mov [sc_pid], eax
mov eax, 68 ; ®á¢®¡®¤¨âì ¯ ¬ïâì
mov ebx, 13
mov ecx, [sc_process]
int 0x40
call _sc_pid2name
mov eax, 68 ; ®âªàëâì ¨¬¥­®¢ ­­ãî ®¡« áâì
mov ebx, 22
mov dword ecx, sc_name
mov edx, 4096
mov esi, SHM_OPEN_ALWAYS or SHM_WRITE
int 0x40
mov [sc_buffer], eax
pop ebx
pop esp
ret
end if
;============================
if used _sc_puts
align 4
; void __stdcall sc_puts(char *str);
_sc_puts:
push esp
push ebx
mov esi, [esp+12]
mov edi, [sc_buffer]
mov al, SC_PUTS
stosb
@@:
lodsb
stosb
test al, al
jnz @b
mov ebx, [sc_buffer]
@@:
mov byte dl, [ebx]
test dl, dl
jz @f
push ebx
mov eax, 5
mov ebx, 5
int 0x40
pop ebx
jmp @b
@@:
pop ebx
pop esp
ret 4
end if
;============================
if used _sc_exit
align 4
; void __stdcall sc_exit();
_sc_exit:
push ebx
push esp
mov ebx, [sc_buffer]
mov byte [ebx], SC_EXIT
@@:
mov byte dl, [ebx]
test dl, dl
jz @f
push ebx
mov eax, 5
mov ebx, 5
int 0x40
pop ebx
jmp @b
@@:
mov eax, 68 ;§ ªàëâì ¨¬¥­®¢ ­­ãî ®¡« áâì
mov ebx, 23
mov dword ecx, sc_name
int 0x40
pop esp
pop ebx
ret
end if
;============================
if used _sc_gets
align 4
; void __stdcall sc_gets(char *str);
_sc_gets:
push esp
push ebx
mov edi, [esp+12]
mov ebx, [sc_buffer]
mov byte [ebx], SC_GETS
@@:
mov byte dl, [ebx]
test dl, dl
jz @f
push ebx
mov eax, 5
mov ebx, 5
int 0x40
pop ebx
jmp @b
@@:
mov esi, [sc_buffer]
inc esi
@@:
lodsb
stosb
test al, al
jnz @b
pop ebx
pop esp
ret 4
end if
;============================
if used _sc_pid
_sc_pid:
;int __stdcall sc_pid (void);
push ebx ecx
mov ecx, [sc_buffer]
mov byte [ecx], SC_PID
@@:
mov eax, 5
mov ebx, 5
int 0x40
cmp byte [ecx], 0
je @f
call _sc_ping
test eax, eax
jnz .err
@@:
mov eax, [ecx+1]
pop ecx ebx
ret
.err:
pop ecx ebx
xor eax, eax
dec eax
ret
end if
;============================
if used _sc_ping
_sc_ping:
;int __stdcall sc_ping (void);
push ebx ecx
mov ecx, [sc_buffer]
mov byte [ecx], SC_PING
mov eax, 5
mov ebx, 200
int 0x40
xor eax, eax
cmp byte [ecx], 0
je @f
dec eax
@@:
pop ecx ebx
ret
end if

View File

@ -0,0 +1,173 @@
;-----------------------------------------------------------------------------;
; Copyright (C) 2023, Mikhail Frolov aka Doczom . All rights reserved. ;
; Distributed under terms of the GNU General Public License ;
; ;
; Demo program for the VIRT_DISK driver. ;
; ;
; GNU GENERAL PUBLIC LICENSE ;
; Version 2, June 1991 ;
; ;
;-----------------------------------------------------------------------------;
format binary as ""
use32
org 0
db 'MENUET01'
dd 1, START, I_END, MEM, STACKTOP, PATH, 0
include 'parser.inc'
include 'shell.inc'
START:
call _sc_init
mov al, 68
mov bl, 16
mov ecx, drv_name
int 0x40
mov [ioctl_add_disk.hand], eax
mov [ioctl_del_disk.hand], eax
mov [ioctl_info_disk.hand], eax
mov [ioctl_list_disk.hand], eax
mov [ioctl_count_disk.hand], eax
test eax, eax
jz .end
cmp byte[PATH], 0
jz .end
call parse_cmd
cmp dword[param_cmd],0
jz .end
mov al, 68
mov bl, 17
mov ecx, ioctl_add_disk
int 0x40
test eax, eax
jnz @f
push str_command_successfully
call _sc_puts
jmp .end
@@:
push str_error
call _sc_puts
.end:
call _sc_exit
mov eax,-1
int 0x40
ERROR_EXIT:
push str_runtime_err
call _sc_puts
call _sc_exit
mov eax,-1
int 0x40
write_disk_info:
pusha
push str_disk_info.path
call _sc_puts
push info_buffer.path
call _sc_puts
push str_newline
call _sc_puts
popa
ret
I_END:
drv_name: db 'VIRT_DISK',0
; messages
str_runtime_err:
db 'Runtime error', 13, 10, 0
str_command_successfully:
db 'Command successfully', 13, 10, 0
str_header_disk_list:
db ' disk | sector | flags | file', 13, 10
db '-------|--------|-------|---------------------',13, 10, 0
str_input_disk_number:
db ' | ' ; ,0
str_input_disk_sector:
db ' | ';,0
str_input_disk_flags:
db ' | ',0
str_error:
db 'Error',0
str_disk_info:
.num: db 'Disk number: ',0
;.type: db 'Type: ', 0
;.sector_size:
; db 'Sector size: ', 0
.path: db 'File: ', 0
str_newline:
db ' ', 13, 10, 0
ioctl_count_disk:
.hand: dd 0, 3 ;iocode
dd .get_count_disk, 8
dd ioctl_list_disk.count, 4
.get_count_disk:
dd 0, 0
ioctl_list_disk:
.hand: dd 0, 3 ;iocode
dd .inp, 8
.buffer:
dd 0
.size_buffer:
dd 0
.inp:
dd 0
.count: dd 0
ioctl_info_disk:
.hand: dd 0, 4 ;iocode
dd disk_num, 4
dd info_buffer, sizeof.info_buffer
ioctl_del_disk:
.hand: dd 0, 2 ;iocode
dd disk_num, 4
dd 0, 0
ioctl_add_disk:
.hand: dd 0, 1 ;iocode
dd add_disk, add_disk.end - add_disk
dd disk_num, 4
disk_num: rd 0
add_disk:
.flags: dd 11b ;rw
.type: dd 0 ; TypeImage 0 - RAW
.size: dd 512
.file: rb 4096
.end:
PATH: rb 4096
info_buffer:
.sector_count: rd 2
.disk_hand: rd 1
.disk_num: rd 1
.flags: rd 1
.type: rd 1
.sector_size: rd 1
.path: rb 4096
sizeof.info_buffer = $ - info_buffer
rb 4096
STACKTOP:
MEM:
; EXAMPLE COMMANDS:
; virtdisk -f/sd0/4/kolibri.img -s512
; virtdisk -f/sd0/4/kolibri.img
; virtdisk -f/sd0/4/kolibri.iso -s2048
; default sector size = 512 for all disk
; 2048 for ISO disk
;struct IMAGE_ADD_STRUCT
; Flags rd 1 ; 1-ro 2-wo 3-rw
; TypeImage rd 1 ; 0-raw 1-vhd 2-vdi 3-imd
; SectorSize rd 1
; DiskPath rb maxPathLength
;ends