Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 9944 → Rev 9945

/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