wsopenarch proc pascal wsub:dword
local	arcname[WMAXPATH]:byte
	les bx,wsub
	invoke strfcat, addr arcname, es:[bx.ws_path], es:[bx.ws_file]
	invoke osopen, dx::ax, _A_NORMAL, M_RDONLY, A_OPEN
	ret
wsopenarch endp

wsfblk	proc pascal wsub:dword, index:word
	mov ax,index
	les bx,wsub
	cmp es:[bx],ax
	jle wsfblk_err
	les bx,es:[bx.ws_fcb]
	add ax,ax
	add ax,ax
	add bx,ax
	mov dx,es:[bx+2]
	mov bx,es:[bx]		; return DX:BX, ES:BX - fblk
	mov es,dx		;        DX:AX - fblk.name
	mov ax,bx		;        CX - fblk.flag
	add ax,fb_name		;        ZF - clear
	mov cx,es:[bx]
    wsfblk_end:
	ret
    wsfblk_err:
	xor ax,ax
	mov dx,ax
	jmp wsfblk_end
wsfblk	endp

wsfree	proc pascal wsub:dword
	push si
	push di
	mov di,word ptr wsub
	xor ax,ax
	mov si,ax
	cmp word ptr [di.ws_fcb],ax
	jz wsfree_end
	cmp [di.ws_count],ax
	jz wsfree_end
    wsfree_loop:
	les bx,[di.ws_fcb]
	mov ax,si
	shl ax,2
	add bx,ax
	xor ax,ax
	cmp ax,es:[bx]	; assume offset == 4
	je @F
	pushm es:[bx]
	mov es:[bx],ax
	mov es:[bx+2],ax
	call free
    @@:
	inc si
	dec [di.ws_count]
	jnz wsfree_loop
    wsfree_end:
	mov ax,si
	pop di
	pop si
	ret
wsfree	endp

panel_curobj proc
	mov bx,ax
	mov ax,word ptr [bx.pn_wsub]
	or ax,ax
	jnz @F
	cwd
	ret
      @@:
	mov ax,[bx.pn_fcb_index]
	add ax,[bx.pn_cel_index]
	invoke wsfblk, [bx.pn_wsub], ax
	ret
panel_curobj endp
;
; Clear selection set from panel
;
wsclrsel proc pascal wsub:dword
	push si
	push di
	mov si,1
	mov di,word ptr wsub
	cmp [di.ws_count],si
	jbe wsclrsel_end
    wsclrsel_loop:
	cmp [di.ws_count],si
	jbe wsclrsel_end
	les bx,[di.ws_fcb]
	mov ax,si
	shl ax,2
	add bx,ax
	les bx,es:[bx]
	and es:[bx.fb_flag],not _A_SELECTED
	inc si
	jmp wsclrsel_loop
    wsclrsel_end:
	pop di
	pop si
	ret
wsclrsel endp
;
; Returns 0 if entry not part of basepath,
; else _A_ARCH or _A_SUBDIR.
;
testentryname proc pascal wsub:dword, ename:dword
	push si
	push di
	mov bx,word ptr wsub
	invoke strlen, [bx.ws_arch]
	assert ax,256,jb,"arch >= 256"
	mov di,ax
	mov si,word ptr ename
	invoke strlen, ename
	assert ax,256,jb,"entry >= 256"
	cmp di,ax
	jae testentryname_fail
	cmp di,0
	jle testentryname_flag
	invoke strnicmp, ename, [bx.ws_arch], di
	or ax,ax
	jnz testentryname_fail
	mov bx,di
	mov al,[si+bx]
	cmp al,'\'
	jne testentryname_fail
    testentryname_copy:
	mov ax,si
	add ax,di
	inc ax
	invoke strcpy, ss::si, ss::ax
    testentryname_comma:
	cmp byte ptr [si],','
	jne testentryname_flag
	mov ax,si
	inc ax
	invoke strcpy, ss::si, ss::ax
	jmp testentryname_comma
    testentryname_flag:
	mov di,_A_ARCH
	cld
    testentryname_loop:
	lodsb
	or al,al
	jz testentryname_find
	cmp al,'\'
	jne testentryname_loop
	xor ax,ax
	mov [si-1],al
	mov di,_A_SUBDIR
    testentryname_find:
	mov si,1
	mov bx,word ptr wsub
	cmp [bx.ws_count],si
	jbe testentryname_ok
    testentryname_cmp:
	mov bx,word ptr wsub
	cmp [bx.ws_count],si
	jbe testentryname_ok
	les bx,[bx.ws_fcb]
	mov ax,si
	shl ax,2
	add bx,ax
	push es:[bx+2]
	mov ax,es:[bx]
	add ax,fb_name
	push ax
	pushm ename
	call stricmp
	or ax,ax
	jz testentryname_fail
	inc si
	jmp testentryname_cmp
    testentryname_ok:
	mov ax,di
	or ax,ax
    testentryname_end:
	pop di
	pop si
	ret
    testentryname_fail:
	xor ax,ax
	jmp testentryname_end
testentryname endp

fbupdir proc pascal flag:word
	invoke malloc, SIZE S_FBLK+1
	jz fbupdir_end
	push dx
	push ax
	call twdostime
	push ax
	call dwdosdate
	pop dx
	pop bx
	pop es
	mov es:[bx.fb_time],dx
	mov es:[bx.fb_date],ax
	mov ax,flag
	or  ax,_A_UPDIR or _A_SUBDIR
	mov es:[bx.fb_flag],ax
	mov ax,bx
	add bx,fb_name
	mov word ptr es:[bx],'..'
	mov byte ptr es:[bx+2],0
	mov dx,es
    fbupdir_end:
	ret
fbupdir endp
