/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 |