/drivers/disk/Tupfile.lua |
---|
2,3 → 2,4 |
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") |
/drivers/disk/virt_disk.asm |
---|
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 |
/programs/system/virtdisk/README.md |
---|
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> |
/programs/system/virtdisk/Tupfile.lua |
---|
0,0 → 1,2 |
if tup.getconfig("NO_FASM") ~= "" then return end |
tup.rule("virtdisk.asm", "fasm %f %o " .. tup.getconfig("KPACK_CMD"), "virtdisk") |
/programs/system/virtdisk/parser.inc |
---|
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 |
/programs/system/virtdisk/shell.inc |
---|
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 |
/programs/system/virtdisk/virtdisk.asm |
---|
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 |