home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Monster Media 1994 #1
/
monster.zip
/
monster
/
UTILS2
/
SECDR13A.ZIP
/
SETENV.ASM
< prev
next >
Wrap
Assembly Source File
|
1993-12-29
|
8KB
|
380 lines
TITLE setenv - 12.29.93 Large Model
.MODEL large
setenv_TEXT SEGMENT WORD PUBLIC 'CODE'
ASSUME CS:setenv_TEXT,DS:setenv_TEXT
;
;setenv(char * varname,char * strint)
;
command db 356 dup (?)
set db "set "
CR equ 0dh
EnvPtr EQU 2CH ; Offset in PSP
ComInt EQU 2EH ; entry point into first Command.Com
; through interpreter
SegPtr EQU ComInt*4 + 2
sssav dw 0
spsav dw 0
s_path dw 05h ; Size of Path.
d_path db "PATH="
s_comspec dw 08h ; Size of Comspec=.
d_comspec db "COMSPEC="
s_prompt dw 07h ; Size of Prompt=.
d_prompt db "PROMPT="
s_setenv dw 07h ; Size of Setenv=.
d_setenv db "SETENV="
s_config dw 07h ; Size of Config=.
d_config db "CONFIG="
equals equ $-1
szdat dw 0 ;Size of environment data.
szvar dw 0 ;Environment variable size.
zero dw 0 ;constant
exit_code db 00h ; Normal return
envseg dw 0 ;Environment segment address.
envsz dw 0 ;Environment size in bytes.
get4d_err db "Error - can't find/recognize environment space.$"
msg00 db "$"
msg01 db "$"
msg02 db "environment variable erased$"
msg03 db "environment variable created$"
msg04 db "$"
msg05 db "$"
msg06 db "$"
msg07 db "$"
msg08 db "$"
msg09 db "$"
msg10 db "environment space full$"
msgtab dw msg00
dw msg01
dw msg02
dw msg03
dw msg04
dw msg05
dw msg06
dw msg07
dw msg08
dw msg09
dw msg10
public _setenv
_setenv proc far
push bp
mov bp,sp
push si
push di
push es
push ds
push cs
pop ds
les di,ss:[bp+6] ;char * varname
mov bx,di
mov cx,255
mov al,0
cld
repne scasb
sub di,bx
dec di
mov szvar,di ;size of env var
les di,ss:[bp+10] ;char * string
mov bx,di
mov cx,255
mov al,0
cld
repne scasb
sub di,bx
dec di
mov szdat,di ;size of data var
xor si,si ;Point to segment 0
mov es,si
mov si, word ptr es:[SegPtr]
mov ax,si
dec ax
mov es,ax
get4d:
; find memory descriptor + PSP
cmp byte ptr es:0,4dh
jnz inc_seg
cmp word ptr es:10h,20cdh
jz got4d
inc_seg:
mov ax, es ; Increment
inc ax ; to the next
mov es, ax ; segment boundary.
; limit search
mov bx,cs
cmp ax, bx ; Have we gone passed current PSP?
jbe get4d ; No. Continue.
push cs
pop ds
cmp envseg,0
jnz nor_ts
mov si,offset get4d_err
jmp exitmsg
nor_ts:
jmp nor_term ; Exit.
got4d:
mov ax,es:EnvPtr+10h ; Offset in PSP - Environment
or ax,ax
jz inc_seg
push es
dec ax
mov es,ax
cmp byte ptr es:0,4dh
jnz nxt_env
mov ah, 00h
mov al, es:3 ;Get the number of segments.
mov bx, 10h
mul bx ;Get the number of bytes.
mov cs:envsz, ax ;Save it.
mov ax, es ;Increment
inc ax ; to the environment
mov es, ax ; segment boundary.
; Just a double check for environment space.
xor di,di
mov si, offset d_path ; Check
mov cx, s_path ; for
rep cmpsb ; PATH=.
jz got_env
xor di,di
mov si, offset d_prompt ; Check
mov cx, s_prompt ; for
rep cmpsb ; PROMPT=.
jz got_env
xor di,di
mov si, offset d_comspec ;Check
mov cx, s_comspec ; for
rep cmpsb ; COMSPEC=.
jz got_env
xor di,di
mov si, offset d_setenv ; Check
mov cx, s_setenv ; for
rep cmpsb ; SETENV=.
jz got_env
xor di,di
mov si, offset d_config ; Check
mov cx, s_config ; for
rep cmpsb ; CONFIG=.
jz got_env
pop es
jmp inc_seg ; to scan some more.
got_env:
mov ax,es ;don't change same env twice
cmp cs:envseg,ax ; may be pointed to by >1 PSP
je nxt_env
mov cs:envseg,es
call set_env
nxt_env:
pop es
jmp inc_seg
nor_term:
push cs
pop ds
mov al, exit_code
mov ah,0
add ax,ax ; index to msg table
mov si, offset msgtab
add si,ax
mov dx,0[si]
exitmsg:
mov ah, 09h ; display exit msg
int 21h
mov al, exit_code ; Set termination code.
cbw
comrtn:
pop ds
pop es
pop di
pop si
pop bp
ret
_setenv endp
set_env proc near
mov ax, es ; environment to
mov ds, ax ; data segment
xor si,si ; environment offset
les di,ss:[bp+6] ;char * varname
mov bl, es:[di] ;1st char of environment variable.
jmp short zero1
; Scan through environment for the end,
; two null bytes.
lp1:
lodsb ; Get a byte.
cmp al, 00h ; Is it null?
jz zero1 ; Yes. Got first null.
jmp lp1 ; Keep looking.
; Is the variable there?
zero1:
lodsb ; Get a byte.
cmp al, 00h ; Is it zero?
jz write_near ; Yes. Jump out.
cmp al, bl ; Maybe the env. variable?
jnz lp1 ; No. Jump out.
dec si ; We are N+1.
mov ax, ds ; Get the data segment
mov es, ax ; and put it in extra segment.
mov di, si ; This is our destination.
mov dx, si ; Save the address of env. var.
lds si,ss:[bp+6] ;char * varname
mov cx, cs:szvar ;Length of variable.
cld
rep cmpsb ; Does it exist?
jz update
mov ax, es ; Get the extra segment.
mov ds, ax ; and put it in data segment.
mov si, di ; Setup the source.
jmp lp1
write_near:
jmp write
; The environment variable is there.
; Now update the environment variable.
update:
update0:
mov ax, es ; Get the extra segment.
mov ds, ax ; and put it in data segment.
mov di, dx ; This is our destination.
mov si, di ; Setup the source.
update1:
lodsb ; Skip
cmp al, 00h ; over
jnz update1 ; the variable.
lodsb ; Look ahead to see
dec si ; if the next byte
cmp al, 00h ; is zero if not
jz update3 ; compress the data.
update2:
lodsb ; Compress
stosb ; the data
cmp al, 00h ; for a
jnz update2 ; variable.
lodsb ; Get a byte.
dec si
cmp al, 00h ; Is it zero?
jnz update2 ; No. Get next.
update3:
update4:
mov cx, cs:szdat ; Length of data.
cmp cx, 00h ; null data?
jnz write1 ; No. Jump out.
mov cx, si ; End of old environment.
mov dx, di ; Current position.
sub cx, dx
mov al, 00h ; Zero
rep stosb ; the rest.
ret
; The environment variable isn't there.
; Now move the data into place.
write:
mov ax, ds ; Get the data segment
mov es, ax ; and put it in extra segment.
dec si ; We are N+1.
mov di, si ; This is our destination.
mov dx, si ; save for reset
write1:
mov cx, cs:szdat ; Environment data length
jcxz write1a ; delete if none
jmp short write2 ; No. Jump out.
write1a:
mov cs:[exit_code], 08h ; Environment variable not found.
ret
write2:
lds si,ss:[bp+6] ;char * varname
mov cx, cs:szvar ;Set the length.
call cpytenv ;copy to env
push cs
pop ds
mov si, offset equals
mov cx,1
call cpytenv
lds si,ss:[bp+10] ;char * data
mov cx, cs:szdat ;Set the length.
call cpytenv
push cs
pop ds
mov si,offset zero
mov cx,2
call cpytenv
ret
cpytenv label near
write3:
mov ah, es:[di] ; Get destination byte.
write4:
cmp ah, 00h ; Is it a zero?
jnz not_zero ; No. Jump out.
lodsb ; Get byte.
stosb ; Save byte.
loop write3 ; Loop.
ret
not_zero:
mov ax, di ; Get the current offset.
mov bx, cs:envsz ; Get environment size.
cmp ax, bx ; Greater than environment size.
jge reset ; Yes. Jump.
mov ah, 00h ; Make it zero.
jmp write4
reset:
mov di, dx
mov al, 00h ; Put zero back.
stosb
stosb
mov exit_code, 0Ah ; Set code for out of env.,
pop ax ; discard inner return
ret
public lastloc
lastloc label byte ; End of program.
set_env endp
setenv_TEXT ENDS
END