;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; RDOS operating system ; Copyright (C) 1988-2000, Leif Ekblad ; ; This program is free software; you can redistribute it and/or modify ; it under the terms of the GNU General Public License as published by ; the Free Software Foundation; either version 2 of the License, or ; (at your option) any later version. The only exception to this rule ; is for commercial usage in embedded systems. For information on ; usage in commercial embedded systems, contact embedded@rdos.net ; ; This program is distributed in the hope that it will be useful, ; but WITHOUT ANY WARRANTY; without even the implied warranty of ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; GNU General Public License for more details. ; ; You should have received a copy of the GNU General Public License ; along with this program; if not, write to the Free Software ; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ; ; The author of this program may be contacted at leif@rdos.net ; ; FILE.ASM ; File module ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; INCLUDE ..\user.def INCLUDE ..\os.def INCLUDE ..\os.inc INCLUDE system.def INCLUDE protseg.def INCLUDE ..\user.inc INCLUDE ..\driver.def INCLUDE system.inc INCLUDE ..\fs.inc INCLUDE ..\handle.inc INCLUDE ..\apicheck.inc INCLUDE gate.def file_handle_seg STRUC file_handle_base handle_header <> file_handle_pos DD ? file_handle_sel DW ? file_handle_access DB ? file_handle_drive DB ? file_handle_seg ENDS CallFileSystem MACRO call_proc push ds push gs push ebp push esi mov si,fs_sys_data_sel mov ds,si movzx si,al add si,si mov ds,ds:[si].fs_sel lgs ebp,fword ptr ds:fs_table lds esi,fword ptr ds:fs_drive_param call fword ptr gs:[ebp].&call_proc pop esi pop ebp pop gs pop ds ENDM data SEGMENT byte public 'DATA' fs_file_list DW ? fs_file_section section_typ <> data ENDS .386p code SEGMENT byte public use16 'CODE' assume cs:code ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: InsertFileSel ; ; DESCRIPTION: Insert a file selector ; ; PARAMETERS: BX File selector ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; InsertFileSel Proc near push ds push es push eax push ebx push di ; mov ax,SEG data mov ds,ax EnterSection ds:fs_file_section ; mov es,bx mov di,ds:fs_file_list or di,di je ins_file_sel_empty ; push ds push si mov ds,di mov si,ds:file_prev mov ds:file_prev,es mov ds,si mov ds:file_next,es mov es:file_next,di mov es:file_prev,si pop si pop ds jmp ins_file_sel_leave ins_file_sel_empty: mov es:file_next,es mov es:file_prev,es mov ds:fs_file_list,es ins_file_sel_leave: LeaveSection ds:fs_file_section ; pop di pop ebx pop eax pop es pop ds ret InsertFileSel Endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: RemoveFileSel ; ; DESCRIPTION: Remove a file selector ; ; PARAMETERS: BX File selector ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; RemoveFileSel Proc near push ds push eax push ebx push si ; mov ax,SEG data mov ds,ax EnterSection ds:fs_file_section ; mov ax,ds:fs_file_list or ax,ax jz rem_file_sel_leave ; mov si,ax rem_file_sel_check: mov es,ax cmp ax,bx je rem_file_sel_ok ; mov ax,es:file_next cmp ax,si jne rem_file_sel_check ; jmp rem_file_sel_leave rem_file_sel_ok: mov es,bx cmp bx,es:file_next je rem_file_sel_empty ; push di push ds mov di,es:file_next mov ds:fs_file_list,di mov si,es:file_prev mov ds,di mov ds:file_prev,si mov ds,si mov ds:file_next,di pop ds pop di jmp rem_file_sel_leave rem_file_sel_empty: mov ds:fs_file_list,0 rem_file_sel_leave: LeaveSection ds:fs_file_section pop si pop ebx pop eax pop ds ret RemoveFileSel Endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: CreateFileHandle ; ; DESCRIPTION: Creates a file handle ; ; PARAMETERS: AL Drive ; BX File selector ; CL Access ; ; RETURNS: BX Handle ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; public CreateFileHandle CreateFileHandle Proc near push ds push es push si ; mov es,bx inc es:file_usage push cx mov cx,SIZE file_handle_seg AllocateHandle pop cx mov [ebx].file_handle_pos,0 mov [ebx].file_handle_sel,es mov [ebx].file_handle_access,cl mov [ebx].file_handle_drive,al mov [ebx].hh_sign,FILE_HANDLE mov bx,[ebx].hh_handle clc ; pop si pop es pop ds ret CreateFileHandle Endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: CreateListEntry ; ; DESCRIPTION: Create a new list entry ; ; PARAMETERS: DS File selector ; EAX Position entry ; ; RETURNS: EAX Base address ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; CreateListEntry Proc near push bx push ecx push edx push esi push edi ; mov esi,eax mov al,ds:file_drive mov bx,ds CallFileSystem fs_allocate_file_list_proc ; mov es:[edi].fl_usage,0 mov es:[edi].fl_ref_count,1 mov es:[edi].fl_size,eax mov es:[edi].fl_base,0 mov es:[edi].fl_sel,ds mov es:[edi].fl_state, FILE_LIST_STATE_EMPTY mov es:[edi].fl_flags,0 mov es:[edi].fl_prev_small,0 mov es:[edi].fl_next_small,0 mov es:[edi].fl_pos,esi mov eax,edi ; pop edi pop esi pop edx pop ecx pop bx ret CreateListEntry Endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: FreeListEntry ; ; DESCRIPTION: Free a list entry ; ; PARAMETERS: DS File selector ; EAX Base address ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; FreeListEntry Proc near push eax push bx push ecx push edx push edi ; mov edi,eax ; mov eax,es:[edi].fl_pos mov dword ptr es:[eax],0 mov edx,es:[edi].fl_base or edx,edx jz free_list_done ; mov es:[edi].fl_state, FILE_LIST_STATE_EMPTY mov ecx,ds:file_block_size cmp ecx,1000h jc free_small_list ; mov al,ds:file_drive mov bx,ds CallFileSystem fs_free_file_list_proc FreeLinear jmp free_list_done free_small_list: push edi push esi free_small_start_loop: mov esi,edi test dx,0FFFh jz free_small_start_found ; mov eax,es:[edi].fl_prev_small or eax,eax jz free_small_fail ; mov edi,eax mov edx,es:[edi].fl_base test es:[edi].fl_state, FILE_LIST_STATE_EMPTY je free_small_start_loop jmp free_small_fail free_small_start_found: xchg esi,edi free_small_end_loop: mov eax,es:[edi].fl_next_small or eax,eax jz free_small_do ; mov edi,eax mov eax,es:[edi].fl_base test ax,0FFFh jz free_small_do ; test es:[edi].fl_state, FILE_LIST_STATE_EMPTY jne free_small_fail jmp free_small_end_loop free_small_do: mov edi,esi free_small_unlink_loop: mov es:[edi].fl_base,0 mov es:[edi].fl_prev_small,0 xor eax,eax xchg eax,es:[edi].fl_next_small or eax,eax jz free_small_unlink_done ; mov edi,eax mov eax,es:[edi].fl_base test ax,0FFFh jnz free_small_unlink_loop free_small_unlink_done: mov ecx,1000h FreeLinear free_small_fail: pop esi pop edi mov al,ds:file_drive mov bx,ds CallFileSystem fs_free_file_list_proc free_list_done: pop edi pop edx pop ecx pop bx pop eax ret FreeListEntry Endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: CreateListDir ; ; DESCRIPTION: Create a new list directory ; ; PARAMETERS: DS File selector ; ; RETURNS: EBX Base address ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; CreateListDir Proc near push ecx push edx push edi ; mov eax,1000h AllocateBigLinear mov edi,edx mov ecx,400h xor eax,eax rep stos dword ptr es:[edi] mov ebx,edx ; pop edi pop edx pop ecx ret CreateListDir Endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: FreeListDir ; ; DESCRIPTION: Free a list directory ; ; PARAMETERS: DS File selector ; EBX Base address ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; FreeListDir Proc near push es push ax push ebx push ecx push edx push edi ; mov ax,flat_sel mov es,ax ; mov edx,ebx mov cx,400h free_list_dir_loop: mov eax,es:[ebx] or eax,eax jz free_list_dir_next ; call FreeListEntry free_list_dir_next: add ebx,4 loop free_list_dir_loop ; mov ecx,1000h FreeLinear ; pop edi pop edx pop ecx pop ebx pop ax pop es ret FreeListDir Endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: CreateFileSelector ; ; DESCRIPTION: Open a file handle ; ; PARAMETERS: AL Drive ; AH Attribute ; ECX File size ; EDX File dir entry ; ; RETURNS: BX File selector ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; public CreateFileSel CreateFileSel PROC near push ds push es push eax push di ; push ecx push edx ; mov bx,ax test ah,80h jnz crfs_skip_lists ; mov al,bl push si push edi GetDriveParam pop edi pop si jnc crfs_ok_params ; mov eax,1000h mov ecx,1000h crfs_ok_params: mov edx,ecx dec eax xor cl,cl crfs_block_loop: inc cl shr eax,1 jnz crfs_block_loop ; mov eax,1 shl eax,cl dec edx add cl,10 shr edx,cl inc edx ; push eax mov eax,edx shl eax,2 add eax,SIZE file_data_struc - 4 AllocateSmallGlobalMem mov ax,es mov ds,ax pop eax ; mov ds:file_block_size,eax mov ds:file_dir_entries,dx mov ds:file_dir_shift,cl sub cl,10 mov ds:file_entry_shift,cl ; mov cx,dx mov di,OFFSET file_entries xor eax,eax rep stosd jmp crfs_init crfs_skip_lists: mov eax,SIZE file_data_struc - 4 AllocateSmallGlobalMem mov ax,es mov ds,ax mov ds:file_block_size,0 mov ds:file_dir_entries,0 crfs_init: pop edx pop ecx InitReadWriteSection ds:file_size_section InitSection ds:file_list_section mov ds:file_usage,0 mov ds:file_drive,bl mov ds:file_attrib,bh mov ds:file_size,ecx mov ds:file_dir_entry,edx mov bx,ds call InsertFileSel ; pop di pop eax pop es pop ds ret CreateFileSel ENDP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: GrowFileSel ; ; DESCRIPTION: Grow file selector ; ; PARAMETERS: BX File selector to grow ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; GrowFileSel PROC near push es push eax push ecx push edx push si push di ; push ds mov si,bx GetSelectorBaseSize AllocateGdt CreateDataSelector16 mov ds,bx ; mov bx,si movzx eax,ds:file_dir_entries shl eax,2 add eax,SIZE file_data_struc AllocateSmallLinear mov ecx,eax CreateDataSelector16 mov es,bx ; xor di,di xor si,si mov cx,ax sub cx,4 rep movsb xor eax,eax stosd inc es:file_dir_entries mov bx,es mov ax,ds mov es,ax pop ds FreeMem ; pop di pop si pop edx pop ecx pop eax pop es ret GrowFileSel ENDP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: FreeFileSel ; ; DESCRIPTION: Free file selector ; ; PARAMETERS: DS File selector ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; public FreeFileSel FreeFileSel PROC near push es push ax push ebx push ecx push si push edi ; mov bx,ds call RemoveFileSel ; mov ax,flat_sel mov es,ax mov edi,ds:file_dir_entry mov cx,es:[edi].de_usage or cx,cx jnz free_file_sel_done ; mov ecx,ds:file_block_size or ecx,ecx jz free_file_sel ; mov cx,ds:file_dir_entries mov si,OFFSET file_entries free_file_dir_loop: mov ebx,[si] or ebx,ebx jz free_file_dir_next ; call FreeListDir free_file_dir_next: add si,4 loop free_file_dir_loop free_file_sel: mov ecx,ds:file_dir_entry mov ax,ds mov es,ax mov ax,flat_sel mov ds,ax mov ds:[ecx].dfe_file_sel,0 FreeMem free_file_sel_done: xor ax,ax mov ds,ax ; pop edi pop si pop ecx pop ebx pop ax pop es ret FreeFileSel ENDP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: FreeFile ; ; DESCRIPTION: Free file selector ; ; PARAMETERS: BX File selector ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; public FreeFile FreeFile PROC near push ds push ax ; mov ds,bx mov ax,ds:file_usage or ax,ax stc jnz free_file_done ; call FreeFileSel free_file_done: pop ax pop ds ret FreeFile Endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: GetFileListEntry ; ; DESCRIPTION: Get list entry ; ; PARAMETERS: BX File selector ; EDX Position ; ; RETURNS: EAX List selector ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; get_file_list_entry_name DB 'Get File List Entry',0 get_file_list_entry Proc far push ds push es push ebx push cx push esi ; mov ds,bx mov ax,flat_sel mov es,ax ; mov eax,ds:file_size dec eax and ax,0F000h add eax,1000h cmp edx,eax jnc get_list_fail ; mov esi,edx mov cl,ds:file_dir_shift shr esi,cl shl si,2 mov ebx,ds:[si].file_entries or ebx,ebx jnz get_list_check_mid ; call CreateListDir mov ds:[si].file_entries,ebx get_list_check_mid: mov esi,edx mov cl,ds:file_entry_shift shr esi,cl shl si,2 and esi,0FFCh mov eax,es:[ebx+esi] or eax,eax clc jnz get_list_done ; lea eax,[ebx+esi] call CreateListEntry mov es:[ebx+esi],eax clc jmp get_list_done get_list_fail: stc get_list_done: pop esi pop cx pop ebx pop es pop ds retf32 get_file_list_entry Endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: FreeFileListEntry ; ; DESCRIPTION: Free a file list entry ; ; PARAMETERS: BX File selector ; EDI File list entry ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; free_file_list_entry_name DB 'Free File List Entry',0 free_file_list_entry Proc far push ds push eax ; mov ds,bx mov eax,edi call FreeListEntry ; pop eax pop ds retf32 free_file_list_entry Endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: ReadFileListEntry ; ; DESCRIPTION: Read a file list entry ; ; PARAMETERS: DS File selector ; EDI File list entry ; EDX File position ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ReadFileListEntry Proc near mov eax,es:[edi].fl_base or eax,eax jnz read_file_list_do ; mov eax,ds:file_block_size cmp eax,1000h jc read_alloc_small ; push ecx push edx AllocateBigLinear mov es:[edi].fl_base,edx pop edx pop ecx jmp read_file_list_do read_alloc_small: push bx push edx push esi push edi ; push ecx push edx mov eax,1000h AllocateBigLinear mov esi,edx pop edx pop ecx ; mov bx,ds mov eax,ds:file_block_size neg eax and edx,eax read_small_start_loop: test dx,0FFFh jz read_small_start_found ; sub edx,ds:file_block_size GetFileListEntry mov edi,eax jmp read_small_start_loop read_small_start_found: mov es:[edi].fl_prev_small,0 read_small_loop: mov es:[edi].fl_next_small,0 mov es:[edi].fl_base,esi add esi,ds:file_block_size add edx,ds:file_block_size test dx,0FFFh jz read_small_done ; GetFileListEntry jc read_small_done ; mov es:[edi].fl_next_small,eax mov es:[eax].fl_prev_small,edi mov edi,eax jmp read_small_loop read_small_done: pop edi pop esi pop edx pop bx read_file_list_do: mov es:[edi].fl_state, FILE_LIST_STATE_USED push edx push ecx mov eax,ds:file_block_size mov ecx,eax neg eax and edx,eax push bx mov al,ds:file_drive mov bx,ds CallFileSystem fs_read_file_block_proc pop bx pop ecx pop edx ret ReadFileListEntry Endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: swap_file_list ; ; DESCRIPTION: Free file list entry, if possible ; ; PARAMETERS: DS File selector ; ES:EDI Dir array ; EAX File list entry ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; swap_file_list Proc near inc ebp mov dx,es:[eax].fl_usage or dx,dx jnz swap_list_done ; mov dx,es:[eax].fl_ref_count cmp dx,4 jbe swap_list_handle_ref ; mov dx,4 swap_list_handle_ref: dec dx mov es:[eax].fl_ref_count,dx or dx,dx jnz swap_list_done ; dec ebp call FreeListEntry swap_list_done: ret swap_file_list Endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: swap_dir ; ; DESCRIPTION: Free physical memory in file directory ; ; PARAMETERS: DS File selector ; ES:EDI Dir array ; ; RETURNS: EBP Entry count ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; swap_dir Proc near xor ebp,ebp mov ecx,400h swap_dir_loop: or ecx,ecx jz swap_dir_done ; xor eax,eax repz scas dword ptr es:[edi] mov eax,es:[edi-4] or eax,eax jz swap_dir_loop ; call swap_file_list jmp swap_dir_loop swap_dir_done: ret swap_dir Endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: swap_file ; ; DESCRIPTION: Free physical memory in file ; ; PARAMETERS: DS File selector ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; swap_file Proc near push es pushad ; EnterSection ds:file_list_section mov ax,flat_sel mov es,ax test ds:file_attrib, FILE_ATTRIB_NOBUFFER jnz swap_file_done ; mov cx,ds:file_dir_entries mov si,OFFSET file_entries swap_file_loop: mov edi,ds:[si] or edi,edi jz swap_file_next ; push cx push si call swap_dir pop si pop cx ; or ebp,ebp jnz swap_file_next ; push ecx xor edx,edx xchg edx,ds:[si] mov ecx,1000h FreeLinear pop ecx swap_file_next: add si,4 loop swap_file_loop swap_file_done: LeaveSection ds:file_list_section ; popad pop es ret swap_file Endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: swap_all ; ; DESCRIPTION: Free physical memory in all files ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; swap_all Proc near push ds push es push ax push bx ; mov ax,SEG data mov ds,ax EnterSection ds:fs_file_section ; mov bx,ds:fs_file_list swap_all_loop: push ds mov ds,bx EnterWriteSection ds:file_size_section call swap_file LeaveWriteSection ds:file_size_section pop ds ; mov es,bx mov bx,es:file_next cmp bx,ds:fs_file_list jne swap_all_loop ; xor ax,ax mov es,ax LeaveSection ds:fs_file_section ; pop bx pop ax pop es pop ds ret swap_all Endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: read file ; ; DESCRIPTION: Reads from a file ; ; PARAMETERS: AL Drive ; DS File selector ; ECX Size ; EDX Position ; ES:EDI Data buffer ; ; RETURNS: EAX Bytes read ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; read_file Proc near push es push fs push ebx push ecx push edx push esi push edi push ebp ; xor ebp,ebp mov ax,es mov fs,ax mov ax,flat_sel mov es,ax ; push edx GetFreePhysical or edx,edx jz read_file_low ; mov eax,0FFFFFFFFh read_file_low: pop edx ; cmp eax,100000h ja read_file_mem_all_ok ; call swap_all read_file_mem_all_ok: EnterReadSection ds:file_size_section cmp edx,ds:file_size jnc read_file_done ; mov eax,edx add eax,ecx sub eax,ds:file_size jc read_file_size_ok ; sub ecx,eax read_file_size_ok: or ecx,ecx jz read_file_done read_file_loop: push edx GetFreePhysical or edx,edx jz read_file_loop_low ; mov eax,0FFFFFFFFh read_file_loop_low: pop edx cmp eax,100000h ja read_file_mem_ok ; call swap_file read_file_mem_ok: push cx mov esi,edx mov cl,ds:file_dir_shift shr esi,cl shl si,2 mov ebx,ds:[si].file_entries EnterSection ds:file_list_section or ebx,ebx jnz read_file_check_mid ; call CreateListDir mov ds:[si].file_entries,ebx read_file_check_mid: mov esi,edx mov cl,ds:file_entry_shift shr esi,cl shl si,2 and esi,0FFCh pop cx mov eax,es:[ebx+esi] or eax,eax jnz read_file_check_base ; lea eax,[ebx+esi] call CreateListEntry mov es:[ebx+esi],eax read_file_check_base: cmp es:[eax].fl_state, FILE_LIST_STATE_EMPTY jne read_file_do_first ; push edi mov edi,eax call ReadFileListEntry pop edi jnc read_file_do_first ; mov dword ptr es:[ebx+esi],0 LeaveSection ds:file_list_section jmp read_file_done read_file_do_first: mov esi,es:[ebx+esi] inc es:[esi].fl_usage inc es:[esi].fl_ref_count LeaveSection ds:file_list_section ; push ds push es push edx push esi ; mov ebx,ds:file_block_size mov esi,es:[esi].fl_base mov ax,fs mov es,ax mov ax,flat_sel mov ds,ax ; mov eax,ebx dec eax and edx,eax add esi,edx ; sub ebx,edx cmp ecx,ebx jnc read_file_do ; mov ebx,ecx read_file_do: push ecx mov ecx,ebx shr ecx,2 rep movs dword ptr es:[edi],ds:[esi] mov ecx,ebx and ecx,3 rep movs byte ptr es:[edi],ds:[esi] pop ecx ; pop esi pop edx pop es pop ds dec es:[esi].fl_usage ; add edx,ebx add ebp,ebx sub ecx,ebx jnz read_file_loop ; clc read_file_done: pushf LeaveReadSection ds:file_size_section popf mov eax,ebp ; pop ebp pop edi pop esi pop edx pop ecx pop ebx pop fs pop es ret read_file Endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: write file ; ; DESCRIPTION: Write to a file ; ; PARAMETERS: AL Drive ; DS File selector ; ECX Size ; EDX Position ; ES:EDI Data buffer ; ; RETURNS: EAX Bytes written ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; write_file Proc near push es push fs push ebx push ecx push edx push esi push edi push ebp ; xor ebp,ebp mov ax,es mov fs,ax mov ax,flat_sel mov es,ax ; push edx GetFreePhysical or edx,edx jz write_file_low ; mov eax,0FFFFFFFFh write_file_low: pop edx cmp eax,100000h ja write_file_mem_all_ok ; call swap_all write_file_mem_all_ok: EnterWriteSection ds:file_size_section cmp edx,ds:file_size jnc write_file_extend ; mov eax,edx add eax,ecx sub eax,ds:file_size jc write_file_size_ok write_file_extend: push edx add edx,ecx mov bx,ds mov al,ds:file_drive CallFileSystem fs_set_file_size_proc pop edx write_file_size_ok: or ecx,ecx jz write_file_done write_file_loop: push edx GetFreePhysical or edx,edx jz write_file_loop_low ; mov eax,0FFFFFFFFh write_file_loop_low: pop edx cmp eax,100000h ja write_file_mem_ok ; call swap_file write_file_mem_ok: push cx mov esi,edx mov cl,ds:file_dir_shift shr esi,cl write_file_retry_entry: cmp si,ds:file_dir_entries jb write_file_entries_ok ; mov bx,ds call GrowFileSel mov ds,bx jmp write_file_retry_entry write_file_entries_ok: shl si,2 mov ebx,ds:[si].file_entries or ebx,ebx jnz write_file_check_mid ; call CreateListDir mov ds:[si].file_entries,ebx write_file_check_mid: mov esi,edx mov cl,ds:file_entry_shift shr esi,cl shl si,2 and esi,0FFCh pop cx mov eax,es:[ebx+esi] or eax,eax jnz write_file_check_base ; lea eax,[ebx+esi] call CreateListEntry mov es:[ebx+esi],eax write_file_check_base: cmp es:[eax].fl_state, FILE_LIST_STATE_EMPTY jne write_file_do_first ; push edi mov edi,eax call ReadFileListEntry pop edi jnc write_file_do_first ; mov dword ptr es:[ebx+esi],0 LeaveSection ds:file_list_section jmp write_file_done write_file_do_first: mov esi,es:[ebx+esi] inc es:[esi].fl_usage inc es:[esi].fl_ref_count push ds push es push edx push esi push edi ; mov ebx,ds:file_block_size mov esi,es:[esi].fl_base xchg esi,edi mov ax,fs mov ds,ax mov ax,flat_sel mov es,ax ; mov eax,ebx dec eax and edx,eax add edi,edx ; sub ebx,edx cmp ecx,ebx jnc write_file_do ; mov ebx,ecx write_file_do: push ecx mov ecx,ebx shr ecx,2 rep movs dword ptr es:[edi],ds:[esi] mov ecx,ebx and ecx,3 rep movs byte ptr es:[edi],ds:[esi] pop ecx ; pop edi pop esi pop edx pop es pop ds ; push bx push ecx push edi mov edi,esi mov ecx,ebx mov al,ds:file_drive mov bx,ds CallFileSystem fs_write_file_block_proc pop edi pop ecx pop bx ; dec es:[esi].fl_usage add edx,ebx add ebp,ebx add edi,ebx sub ecx,ebx jnz write_file_loop ; clc write_file_done: pushf LeaveWriteSection ds:file_size_section popf mov eax,ebp ; pop ebp pop edi pop esi pop edx pop ecx pop ebx pop fs pop es ret write_file Endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: GetFileInfo ; ; DESCRIPTION: Get file info ; ; PARAMETERS: BX FILE HANDLE ; ; RETURNS: AX FILE SYSTEM HANDLE ; CL ACCESS ; CH DRIVE ; NC SUCCESS ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; get_file_info_name DB 'Get File info',0 get_file_info PROC far push ds push ebx mov ax,FILE_HANDLE DerefHandle jc get_file_info_done ; mov ax,[ebx].file_handle_sel mov cl,[ebx].file_handle_access mov ch,[ebx].file_handle_drive clc get_file_info_done: pop ebx pop ds retf32 get_file_info ENDP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: DuplFileInfo ; ; DESCRIPTION: Duplicate handle using file-info ; ; PARAMETERS: AX FILE SYSTEM HANDLE ; CL ACCESS ; CH DRIVE ; ; RETURNS: BX FILE HANDLE ; NC SUCCESS ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; dupl_file_info_name DB 'Duplicate File info',0 dupl_file_info PROC far push ds push ax mov ds,ax inc ds:file_usage pop ax push cx mov cx,SIZE file_handle_seg AllocateHandle pop cx mov [ebx].file_handle_pos,0 mov [ebx].file_handle_sel,ax mov [ebx].file_handle_access,cl mov [ebx].file_handle_drive,ch mov [ebx].hh_sign,FILE_HANDLE mov bx,[ebx].hh_handle clc pop ds retf32 dupl_file_info ENDP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: LockFile ; ; DESCRIPTION: Lock file using file-info ; ; PARAMETERS: AX FILE SYSTEM HANDLE ; ; RETURNS: NC SUCCESS ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; lock_file_name DB 'Lock File',0 lock_file PROC far push ds push ax mov ds,ax inc ds:file_usage pop ax clc pop ds retf32 lock_file ENDP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: UnlockFile ; ; DESCRIPTION: Unlock file using file-info ; ; PARAMETERS: AX FILE SYSTEM HANDLE ; ; RETURNS: NC SUCCESS ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; unlock_file_name DB 'Unlock File',0 unlock_file PROC far push ds push ax ; mov ds,ax sub ds:file_usage,1 jnz unlock_file_done ; call FreeFileSel unlock_file_done: clc pop ax pop ds retf32 unlock_file ENDP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: CLOSE_FILE ; ; DESCRIPTION: Close file ; ; PARAMETERS: BX FILE HANDLE ; NC SUCCESS ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; close_file_name DB 'Close File',0 close_file: ApiSaveEax ApiSaveEcx ApiSaveEdx ApiSaveEsi ApiSaveEdi push ds push eax push ebx push esi ; mov ax,FILE_HANDLE DerefHandle jc close_file_done ; mov esi,ebx mov al,[ebx].file_handle_drive mov bx,[ebx].file_handle_sel or bx,bx stc jz close_file_done ; mov ds,bx sub ds:file_usage,1 jnz close_file_handle ; call FreeFileSel close_file_handle: mov ebx,esi FreeHandle clc close_file_done: pop esi pop ebx pop eax pop ds ApiCheckEdi ApiCheckEsi ApiCheckEdx ApiCheckEcx ApiCheckEax retf32 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: DUPL_FILE ; ; DESCRIPTION: Duplicate file handle ; ; PARAMETERS: AX OLD FILE HANDLE ; ; RETURNS: BX NEW FILE HANDLE ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; dupl_file_name DB 'Duplicate File Handle',0 dupl_file: ApiSaveEax ApiSaveEcx ApiSaveEdx ApiSaveEsi ApiSaveEdi push ds push es push eax push cx push esi ; mov bx,ax mov ax,FILE_HANDLE DerefHandle jc dupl_file_done ; mov esi,ebx mov bx,[ebx].file_handle_sel or bx,bx stc jz dupl_file_done ; mov ds,bx inc ds:file_usage ; mov cx,SIZE file_handle_seg AllocateHandle mov eax,[esi].file_handle_pos mov [ebx].file_handle_pos,eax mov ax,[esi].file_handle_sel mov [ebx].file_handle_sel,ax mov al,[esi].file_handle_access mov [ebx].file_handle_access,al mov al,[esi].file_handle_drive mov [ebx].file_handle_drive,al mov [ebx].hh_sign,FILE_HANDLE mov bx,[ebx].hh_handle clc dupl_file_done: pop esi pop cx pop eax pop es pop ds ApiCheckEdi ApiCheckEsi ApiCheckEdx ApiCheckEcx ApiCheckEax retf32 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: GET_IOCTL_DATA ; ; DESCRIPTION: Get IOCTL data ; ; PARAMETERS: BX FILE HANDLE ; ; RETURNS: DX DEVICE ATTRIBUTE ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; get_ioctl_data_name DB 'Get IOCTL Data',0 get_ioctl_data: ApiSaveEax ApiSaveEcx ApiSaveEsi ApiSaveEdi push ds push ax push ebx ; mov ax,FILE_HANDLE DerefHandle jc get_ioctl_data_done ; mov al,[ebx].file_handle_drive mov bx,[ebx].file_handle_sel or bx,bx stc jz get_ioctl_data_done ; CallFileSystem fs_get_ioctl_data_proc get_ioctl_data_done: pop ebx pop ax pop ds ApiCheckEdi ApiCheckEsi ApiCheckEcx ApiCheckEax retf32 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: GET_FILE_SIZE ; ; DESCRIPTION: Get file size ; ; PARAMETERS: BX FILE HANDLE ; ; RETURNS: EAX SIZE OF FILE ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; get_file_size_name DB 'Get File Size',0 get_file_size: ApiSaveEcx ApiSaveEdx ApiSaveEsi ApiSaveEdi push ds push ebx push edx ; mov ax,FILE_HANDLE DerefHandle jc get_file_size_done ; mov bx,[ebx].file_handle_sel or bx,bx stc jz get_file_size_done ; mov ds,bx EnterReadSection ds:file_size_section mov eax,ds:file_size LeaveReadSection ds:file_size_section clc get_file_size_done: pop edx pop ebx pop ds ApiCheckEdi ApiCheckEsi ApiCheckEdx ApiCheckEcx retf32 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: SET_FILE_SIZE ; ; DESCRIPTION: Set file size ; ; PARAMETERS: BX FILE HANDLE ; EAX SIZE OF FILE ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; set_file_size_name DB 'Set File Size',0 set_file_size: ApiSaveEax ApiSaveEcx ApiSaveEdx ApiSaveEsi ApiSaveEdi push ds push eax push ebx push edx ; mov edx,eax mov ax,FILE_HANDLE DerefHandle jc set_file_size_done ; mov al,[ebx].file_handle_drive mov bx,[ebx].file_handle_sel or bx,bx stc jz set_file_size_done ; mov ds,bx EnterWriteSection ds:file_size_section CallFileSystem fs_set_file_size_proc LeaveWriteSection ds:file_size_section set_file_size_done: pop edx pop ebx pop eax pop ds ApiCheckEdi ApiCheckEsi ApiCheckEdx ApiCheckEcx ApiCheckEax retf32 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: GET_FILE_POS ; ; DESCRIPTION: Get file position ; ; PARAMETERS: BX FILE HANDLE ; ; RETURNS: EAX FILE POSITION ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; get_file_pos_name DB 'Get File Position',0 get_file_pos: ApiSaveEcx ApiSaveEdx ApiSaveEsi ApiSaveEdi push ds push ebx ; mov ax,FILE_HANDLE DerefHandle jc get_file_pos_done ; mov ax,[ebx].file_handle_sel or ax,ax stc jz get_file_pos_done ; mov eax,[ebx].file_handle_pos clc get_file_pos_done: pop ebx pop ds ApiCheckEdi ApiCheckEsi ApiCheckEdx ApiCheckEcx retf32 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: SET_FILE_POS ; ; DESCRIPTION: Set file position ; ; PARAMETERS: BX FILE HANDLE ; EAX FILE POSITION ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; set_file_pos_name DB 'Set File Position',0 set_file_pos: ApiSaveEax ApiSaveEcx ApiSaveEdx ApiSaveEsi ApiSaveEdi push ds push ebx push eax push edx ; mov edx,eax mov ax,FILE_HANDLE DerefHandle jc set_file_pos_done ; mov [ebx].file_handle_pos,edx clc set_file_pos_done: pop edx pop eax pop ebx pop ds ApiCheckEdi ApiCheckEsi ApiCheckEdx ApiCheckEcx ApiCheckEax retf32 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: GET_FILE_TIME ; ; DESCRIPTION: Get file time & date ; ; PARAMETERS: BX FILE HANDLE ; ; RETURNS: EDX:EAX CURRENT FILE TIME ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; get_file_time_name DB 'Get File Time',0 get_file_time: ApiSaveEcx ApiSaveEsi ApiSaveEdi push ds push es push ebx push ecx ; mov ax,FILE_HANDLE DerefHandle jc get_file_time_done ; mov dx,flat_sel mov es,dx mov al,[ebx].file_handle_drive mov bx,[ebx].file_handle_sel or bx,bx stc jz get_file_time_done ; mov ds,bx mov edx,ds:file_dir_entry mov eax,es:[edx].de_time mov edx,es:[edx].de_time+4 clc get_file_time_done: pop ecx pop ebx pop es pop ds ApiCheckEdi ApiCheckEsi ApiCheckEcx retf32 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: SET_FILE_TIME ; ; DESCRIPTION: Set file time & date ; ; PARAMETERS: BX FILE HANDLE ; EDX:EAX NEW FILE TIME ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; set_file_time_name DB 'Set File Time',0 set_file_time: ApiSaveEax ApiSaveEcx ApiSaveEdx ApiSaveEsi ApiSaveEdi push ds push es push fs push ax push ebx push ecx push edx push edi ; mov cx,flat_sel mov es,cx mov ecx,eax mov ax,FILE_HANDLE DerefHandle jc set_file_time_done ; mov al,[ebx].file_handle_drive mov bx,[ebx].file_handle_sel or bx,bx stc jz set_file_time_done ; mov fs,bx mov edi,fs:file_dir_entry mov es:[edi].de_time,ecx mov es:[edi].de_time+4,edx mov edx,edi CallFileSystem fs_update_file_proc clc set_file_time_done: pop edi pop edx pop ecx pop ebx pop ax pop fs pop es pop ds ApiCheckEdi ApiCheckEsi ApiCheckEdx ApiCheckEcx ApiCheckEax retf32 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: READ_FILE ; ; DESCRIPTION: Read file ; ; PARAMETERS: ES:(E)DI BUFFER ; BX HANDLE ; (E)CX NUMBER OF BYTES TO READ ; ; RETURNS: (E)AX NUMBER OF BYTES READ ; NC SUCCESS ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; read_file_name DB 'Read File',0 read_file32: ApiSaveEcx ApiSaveEdx ApiSaveEsi ApiSaveEdi push ds push ebx push edx push esi ; mov ax,FILE_HANDLE DerefHandle jc read_file32_done ; mov esi,ebx mov al,[ebx].file_handle_drive mov edx,[ebx].file_handle_pos mov bx,[ebx].file_handle_sel or bx,bx stc jz read_file32_done ; push ds mov ds,bx test ds:file_attrib, FILE_ATTRIB_NOBUFFER jz read_file32_buf ; CallFileSystem fs_read_file_proc jmp read_file32_save read_file32_buf: call read_file read_file32_save: pop ds pushf jnc read_file32_success ; xor eax,eax read_file32_success: add [esi].file_handle_pos,eax popf read_file32_done: pop esi pop edx pop ebx pop ds ApiCheckEdi ApiCheckEsi ApiCheckEdx ApiCheckEcx retf32 read_file16 PROC far push ds push ebx push ecx push edx push esi push edi ; movzx ecx,cx movzx edi,di mov ax,FILE_HANDLE DerefHandle jc read_file16_done ; mov esi,ebx mov al,[ebx].file_handle_drive mov edx,[ebx].file_handle_pos mov bx,[ebx].file_handle_sel or bx,bx stc jz read_file16_done ; push ds mov ds,bx test ds:file_attrib, FILE_ATTRIB_NOBUFFER jz read_file16_buf ; CallFileSystem fs_read_file_proc jmp read_file16_save read_file16_buf: call read_file read_file16_save: pop ds pushf jnc read_file16_success ; xor eax,eax read_file16_success: add [esi].file_handle_pos,eax popf read_file16_done: pop edi pop esi pop edx pop ecx pop ebx pop ds retf32 read_file16 ENDP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: WRITE_FILE ; ; DESCRIPTION: Write file ; ; PARAMETERS: ES:(E)DI BUFFER ; BX HANDLE ; (E)CX NUMBER OF BYTES TO WRITE ; ; RETURNS: (E)AX NUMBER OF BYTES WRITTEN ; NC SUCCESS ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; write_file_name DB 'Write File',0 write_file32: ApiSaveEcx ApiSaveEdx ApiSaveEsi ApiSaveEdi push ds push ebx push edx push esi ; mov ax,FILE_HANDLE DerefHandle jc write_file32_done ; mov esi,ebx mov al,[ebx].file_handle_drive mov edx,[ebx].file_handle_pos mov bx,[ebx].file_handle_sel or bx,bx stc jz write_file32_done ; push ds mov ds,bx ; push es push edx ; push eax push esi mov ax,flat_sel mov es,ax mov esi,ds:file_dir_entry GetTime mov es:[esi].de_time,eax mov es:[esi].de_time+4,edx mov edx,esi pop esi pop eax CallFileSystem fs_update_file_proc ; pop edx pop es ; test ds:file_attrib, FILE_ATTRIB_NOBUFFER jz write_file32_buf ; CallFileSystem fs_write_file_proc jmp write_file32_save write_file32_buf: call write_file write_file32_save: pop ds pushf add [esi].file_handle_pos,eax popf write_file32_done: pop esi pop edx pop ebx pop ds ApiCheckEdi ApiCheckEsi ApiCheckEdx ApiCheckEcx retf32 write_file16 PROC far push ds push ebx push ecx push edx push esi push edi ; movzx ecx,cx movzx edi,di mov ax,FILE_HANDLE DerefHandle jc write_file16_done ; mov esi,ebx mov al,[ebx].file_handle_drive mov edx,[ebx].file_handle_pos mov bx,[ebx].file_handle_sel or bx,bx stc jz write_file16_done ; push ds mov ds,bx ; push es push edx ; push eax push esi mov ax,flat_sel mov es,ax mov esi,ds:file_dir_entry GetTime mov es:[esi].de_time,eax mov es:[esi].de_time+4,edx mov edx,esi pop esi pop eax CallFileSystem fs_update_file_proc ; pop edx pop es ; test ds:file_attrib, FILE_ATTRIB_NOBUFFER jz write_file16_buf ; CallFileSystem fs_write_file_proc jmp write_file16_save write_file16_buf: call write_file write_file16_save: pop ds pushf add [esi].file_handle_pos,eax popf write_file16_done: pop edi pop esi pop edx pop ecx pop ebx pop ds retf32 write_file16 ENDP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: map_to_file ; ; DESCRIPTION: Map page from file to memory object ; ; PARAMETERS: EAX Offset within object ; BX File handle ; EDX Pagefault base address ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; public map_to_file map_to_file Proc near push ds push es pushad ; mov edi,edx mov edx,eax mov ax,FILE_HANDLE DerefHandle jc map_to_file_done ; mov esi,ebx mov al,[ebx].file_handle_drive mov bx,[ebx].file_handle_sel or bx,bx stc jz map_to_file_done ; mov ds,bx test ds:file_attrib, FILE_ATTRIB_NOBUFFER jnz map_to_file_read ; mov ax,flat_sel mov es,ax ; EnterReadSection ds:file_size_section cmp edx,ds:file_size jnc map_to_file_leave ; mov esi,edx mov cl,ds:file_dir_shift shr esi,cl shl si,2 mov ebx,ds:[si].file_entries EnterSection ds:file_list_section or ebx,ebx jnz map_to_file_check_mid ; call CreateListDir mov ds:[si].file_entries,ebx map_to_file_check_mid: mov esi,edx mov cl,ds:file_entry_shift shr esi,cl shl si,2 and esi,0FFCh mov eax,es:[ebx+esi] or eax,eax jnz map_to_file_check_base ; lea eax,[ebx+esi] call CreateListEntry mov es:[ebx+esi],eax map_to_file_check_base: cmp es:[eax].fl_state, FILE_LIST_STATE_EMPTY jne map_to_file_do_first ; push edi mov edi,eax call ReadFileListEntry pop edi jnc map_to_file_do_first ; xor eax,eax xchg eax,es:[ebx+esi] call FreeListEntry LeaveSection ds:file_list_section stc jmp map_to_file_leave map_to_file_do_first: mov esi,es:[ebx+esi] inc es:[esi].fl_ref_count inc es:[esi].fl_usage mov ebx,ds:file_block_size mov esi,es:[esi].fl_base mov eax,ebx dec eax and edx,eax add esi,edx ; mov edx,esi GetPageEntry or ax,807h and al,NOT 40h mov edx,edi SetPageEntry ; LeaveSection ds:file_list_section clc map_to_file_leave: LeaveReadSection ds:file_size_section jmp map_to_file_done map_to_file_read: push ebx push edx mov edx,edi xor ebx,ebx mov eax,2 SetPageEntry pop edx pop ebx ; mov si,flat_sel mov es,si mov ecx,1000h CallFileSystem fs_read_file_proc map_to_file_done: popad pop es pop ds ret map_to_file Endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: sync_memmap ; ; DESCRIPTION: Sync file region ; ; PARAMETERS: EAX Offset within file ; BX File handle ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; public sync_memmap sync_memmap Proc near push ds push es pushad ; mov ebp,eax mov ax,FILE_HANDLE DerefHandle jc sync_memmap_done ; mov esi,ebx mov al,[ebx].file_handle_drive mov edx,[ebx].file_handle_pos mov bx,[ebx].file_handle_sel or bx,bx stc jz sync_memmap_done ; mov ds,bx test ds:file_attrib, FILE_ATTRIB_NOBUFFER clc jnz sync_memmap_done ; mov ax,flat_sel mov es,ax ; mov esi,ebp mov cl,ds:file_dir_shift shr esi,cl shl si,2 EnterSection ds:file_list_section mov ebx,ds:[si].file_entries or ebx,ebx clc jz sync_memmap_leave ; mov esi,ebp mov cl,ds:file_entry_shift shr esi,cl shl si,2 and esi,0FFCh mov edi,es:[ebx+esi] or edi,edi clc jz sync_memmap_leave ; push bx mov ecx,1000h mov edx,ebp mov al,ds:file_drive mov bx,ds CallFileSystem fs_write_file_block_proc pop bx sync_memmap_leave: LeaveSection ds:file_list_section sync_memmap_done: popad pop es pop ds ret sync_memmap Endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: free_memmap ; ; DESCRIPTION: Free memmapped file region ; ; PARAMETERS: EAX Offset within object ; BX File handle ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; public free_memmap free_memmap Proc near push ds push es pushad ; mov edi,edx mov edx,eax mov ax,FILE_HANDLE DerefHandle jc free_memmap_done ; mov esi,ebx mov al,[ebx].file_handle_drive mov bx,[ebx].file_handle_sel or bx,bx stc jz free_memmap_done ; mov ds,bx test ds:file_attrib, FILE_ATTRIB_NOBUFFER jnz free_memmap_done ; mov ax,flat_sel mov es,ax ; mov esi,edx mov cl,ds:file_dir_shift shr esi,cl shl si,2 EnterSection ds:file_list_section mov ebx,ds:[si].file_entries or ebx,ebx jz free_memmap_leave ; mov esi,edx mov cl,ds:file_entry_shift shr esi,cl shl si,2 and esi,0FFCh mov esi,es:[ebx+esi] or esi,esi jz free_memmap_leave ; dec es:[esi].fl_usage free_memmap_leave: LeaveSection ds:file_list_section clc free_memmap_done: popad pop es pop ds ret free_memmap Endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: Delete_handle ; ; DESCRIPTION: Delete handle (called from handle module) ; ; PARAMETERS: BX FILE HANDLE ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; delete_handle Proc far push ds push ebx push esi ; mov ax,FILE_HANDLE DerefHandle jc delete_handle_done ; mov esi,ebx mov al,[ebx].file_handle_drive mov bx,[ebx].file_handle_sel or bx,bx stc jz delete_handle_done ; mov ds,bx sub ds:file_usage,1 jnz delete_handle_handle ; call FreeFileSel delete_handle_handle: mov ebx,esi FreeHandle clc delete_handle_done: pop esi pop ebx pop ds retf32 delete_handle Endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: swap_proc ; ; DESCRIPTION: Free physical memory in file buffers ; ; PARAMETERS: AL Swapper run level (0 = free all, 15 = preventive) ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; swap_proc Proc far mov ax,SEG data mov ds,ax EnterSection ds:fs_file_section ; mov bx,ds:fs_file_list swap_loop: push ds mov ds,bx EnterWriteSection ds:file_size_section call swap_file LeaveWriteSection ds:file_size_section pop ds ; mov es,bx mov bx,es:file_next cmp bx,ds:fs_file_list jne swap_loop ; xor ax,ax mov es,ax LeaveSection ds:fs_file_section retf32 swap_proc Endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: Init ; ; DESCRIPTION: Init module ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; public init_file init_file PROC near mov ax,cs mov ds,ax mov es,ax ; mov edi,OFFSET delete_handle mov ax,FILE_HANDLE RegisterHandle ; mov edi,OFFSET swap_proc RegisterSwapProc ; mov esi,OFFSET get_file_list_entry mov edi,OFFSET get_file_list_entry_name xor cl,cl mov ax,get_file_list_entry_nr RegisterOsGate ; mov esi,OFFSET free_file_list_entry mov edi,OFFSET free_file_list_entry_name xor cl,cl mov ax,free_file_list_entry_nr RegisterOsGate ; mov esi,OFFSET get_file_info mov edi,OFFSET get_file_info_name xor cl,cl mov ax,get_file_info_nr RegisterOsGate ; mov esi,OFFSET dupl_file_info mov edi,OFFSET dupl_file_info_name xor cl,cl mov ax,dupl_file_info_nr RegisterOsGate ; mov esi,OFFSET lock_file mov edi,OFFSET lock_file_name xor cl,cl mov ax,lock_file_nr RegisterOsGate ; mov esi,OFFSET unlock_file mov edi,OFFSET unlock_file_name xor cl,cl mov ax,unlock_file_nr RegisterOsGate ; mov esi,OFFSET close_file mov edi,OFFSET close_file_name xor dx,dx mov ax,close_file_nr RegisterBimodalUserGate ; mov esi,OFFSET dupl_file mov edi,OFFSET dupl_file_name xor dx,dx xor ecx,ecx mov ax,dupl_file_nr RegisterBimodalSyscall ; mov esi,OFFSET get_ioctl_data mov edi,OFFSET get_ioctl_data_name xor dx,dx xor ecx,ecx mov ax,get_ioctl_data_nr RegisterBimodalSyscall ; mov esi,OFFSET get_file_size mov edi,OFFSET get_file_size_name xor dx,dx xor ecx,ecx mov ax,get_file_size_nr RegisterBimodalSyscall ; mov esi,OFFSET set_file_size mov edi,OFFSET set_file_size_name xor dx,dx xor ecx,ecx mov ax,set_file_size_nr RegisterBimodalSyscall ; mov esi,OFFSET get_file_pos mov edi,OFFSET get_file_pos_name xor dx,dx xor ecx,ecx mov ax,get_file_pos_nr RegisterBimodalSyscall ; mov esi,OFFSET set_file_pos mov edi,OFFSET set_file_pos_name xor dx,dx xor ecx,ecx mov ax,set_file_pos_nr RegisterBimodalSyscall ; mov esi,OFFSET get_file_time mov edi,OFFSET get_file_time_name xor dx,dx xor ecx,ecx mov ax,get_file_time_nr RegisterBimodalSyscall ; mov esi,OFFSET set_file_time mov edi,OFFSET set_file_time_name xor dx,dx xor ecx,ecx mov ax,set_file_time_nr RegisterBimodalSyscall ; mov ebx,OFFSET read_file16 mov esi,OFFSET read_file32 mov edi,OFFSET read_file_name mov ecx,UG_SYSCALL_WR_PAR_ES_EDI mov dx,virt_es_in mov ax,read_file_nr RegisterSyscall ; mov ebx,OFFSET write_file16 mov esi,OFFSET write_file32 mov edi,OFFSET write_file_name mov dx,virt_es_in mov ecx,UG_SYSCALL_RD_PAR_ES_EDI mov ax,write_file_nr RegisterSyscall ; mov ax,SEG data mov ds,ax mov ds:fs_file_list,0 InitSection ds:fs_file_section ret init_file ENDP code ENDS END