WindowsXP/Source/XPSP1/NT/base/mvdm/dpmi/dxini.asm
2024-08-03 16:30:48 +02:00

468 lines
15 KiB
NASM

PAGE ,132
TITLE DXINI.ASM -- Dos Extender INI File Processing
; Copyright (c) Microsoft Corporation 1989-1991. All Rights Reserved.
;***********************************************************************
;
; DXINI.ASM -- Dos Extender INI FIle Processing
;
;-----------------------------------------------------------------------
;
; This module provides the 286 DOS extender's ...
;
;-----------------------------------------------------------------------
;
; 09/27/89 jimmat Modified to use FindFile instead of using its
; own file search logic
; 05/24/89 w-glenns Original (UNCUT, UNCENSORED!) version
;
;***********************************************************************
.286
; -------------------------------------------------------
; INCLUDE FILE DEFINITIONS
; -------------------------------------------------------
.xlist
.sall
include segdefs.inc
include gendefs.inc
include intmac.inc
.list
; -------------------------------------------------------
; GENERAL SYMBOL DEFINITIONS
; -------------------------------------------------------
CR equ 13
LF equ 10
TAB equ 9
EOF equ 26
; -------------------------------------------------------
; EXTERNAL SYMBOL DEFINITIONS
; -------------------------------------------------------
extrn strcpy:NEAR
extrn FindFile:NEAR
; -------------------------------------------------------
; DATA SEGMENT DEFINITIONS
; -------------------------------------------------------
DXDATA segment
extrn rgbXfrBuf1:BYTE
DXDATA ends
; -------------------------------------------------------
subttl Read INI File Routine
page
; -------------------------------------------------------
; READ INI FILE ROUTINE
; -------------------------------------------------------
DXCODE segment
assume cs:DXCODE
;******************************************************************************
;
; ReadIniFile
;
; DESCRIPTION: read and parse a .INI file for the 286 DOS Extender
; initialization.
;
; ENTRY: dx points to the file name
; bx points to structure to fill with ini fields
;
; EXIT: Carry set, if file not found, or not enough memory
;
; USES: ax, cx
;
;==============================================================================
assume ds:DGROUP
public ReadIniFile
ReadIniFile PROC NEAR
push es
push bx
push si
push di
push ds
pop es
assume es:DGROUP
push bx ; ptr to ini structure to fill
mov si,dx
mov di,offset RELOC_BUFFER ; FindFile wants the name here
call strcpy
call FindFile ; locate the .INI file
jc ri_error
mov ax,3D00h ; open the .INI file
mov dx,offset EXEC_PROGNAME ; FindFile puts path name here
int 21h
jc ri_error ; shouldn't happen, but...
mov si, ax ; file handle
mov ah, 48h ; alloc DOS conventional memory
mov bx, 4096d ; want 64k block
int 21h
jc ri_error
pop dx ; ptr to ini structure to fill
call parse_ini ; do the work, and come back
assume es:NOTHING
pushf ; save parse_ini flags
mov ah, 49h ; dealloc DOS conventional memory
int 21h ; es already points to block
npopf ; carry set = problem
ri_end:
pop di
pop si
pop bx
pop es
ret
ri_error: ; error exit
pop bx ; clear stack
stc ; force carry on
jmp short ri_end ; split
ReadIniFile ENDP
;******************************************************************************
;
; Parse_Ini
;
; DESCRIPTION: Read in, and parse the ini file opened
; and find the variable values specified
;
; ENTRY: ax points to the memory block for the file image buffer
; dx points to structure to fill with ini fields
; si has the handle to the file opened
;
; EXIT: Carry set, if file not found, or not enough memory
;
; USES: ax, bx, cx, es
;
;==============================================================================
Parse_Ini PROC NEAR
push bp
push dx
mov bp,dx ; bp = index into structure (es:)
assume ds:NOTHING
push ds
mov ds, ax ; ptr to mem block
mov ah, 3Fh
mov bx, si
mov cx, 0FFFFh ; guess extremely high
xor dx, dx ; offset 0
int 21h
pop es
assume es:DGROUP ; NOTE:!!! es is now data segment !!!
pushf ; save flags from read
push ax ; save # bytes read
mov ah, 3Eh ; close file
mov bx, si
int 21h
pop di ; number bytes read
npopf ; CY flag
jnc @f
jmp parse_done_jump ; if couldn't read, return bad
@@:
mov byte ptr ds:[di], EOF ; write EOF char'r in case none present
; ds:si points to the file image buffer
; es:di/bx structure to fill with ini stuff
xor si,si
; search until section found
find_section:
call Get_Char
jc short parse_done_jump ; end of file, and section not found
cmp al, '[' ; a section ?
jne short find_section
mov di, bp ; point to ini structure
; a section has been found, but is it the right one ?
xor bx, bx ; use as secondary index
cmp_section:
mov al, byte ptr ds:[si+bx] ; char'r from section name in file
inc bx ; bx starts at zero for file pointer
; index, and starts at one for
; structure index
mov ah, byte ptr es:[di+bx]
or ah, ah
jz short find_keyword_start ; yes: found the right section !
call Conv_Char_Lower ; convert char'r in AL to lower case
cmp al, ah ; same so far ?
jne short find_section
jmp short cmp_section
find_keyword_start:
add si,bx ; update file pointer past section name
add bp,bx ; update structure ptr past section name
; now that section is found, want to find keywords
find_keyword:
call Get_Char ; points to 1st char'r of next keyword
jc short parse_done_jump ; end of file, and keyword not found
cmp al, '[' ; new section ?
je short parse_done_jump ; hit a new section, so we're done
search_keyword:
xor di,di
; use beginning of file image buffer for temporary storage of the
; keyword name currently being checked
find_keyword_loop:
mov byte ptr ds:[di], al ; copy the char'r
inc di
mov dx,si ; save position in file image buffer
call Get_Char ; points to 1st char'r of next keyword
jc short parse_done_jump ; end of file, and keyword not found
pushf
cmp al, '='
je short compare_keyword
; yes: found a keyword, lets do some comparisons
npopf
jz short find_keyword_loop ; no white space yet...copy keyword
skip_keyword:
; white space has been skipped, yet there is no '='
; must be an error...ignore, and get next keyword
mov si,dx ; point to last char'r in keyword
mov byte ptr ds:[si], ';'
; fake a comment, so that the rest of the
; line is ignored in the next Get_Char call
; and the next keyword is pointed to
jmp short find_keyword
parse_done_jump:
jmp parse_done
; char'r is an equals, so compare this keyword to the list
compare_keyword:
npopf ; clean top-of-stack
mov byte ptr ds:[di], 0 ; NULL at end of keyword for compare
mov bx,bp ; get index into INI structure in
; data segment DGROUP (where es points)
cmp_keyword1:
xor di,di ; point to start of keyword found
cmp_keyword:
inc bx
mov ah, byte ptr es:[bx] ; next char'r in ini struct keyword
mov al, byte ptr ds:[di] ; next char'r of found keyword
inc di
or al, ah
jz short convert_number ; yes: found the right keyword
call Conv_Char_Lower ; convert char'r in AL to lower case
cmp al, ah ; same so far ?
je short cmp_keyword
xor al,al
dec bx
cmp_keyword_loop:
inc bx
cmp byte ptr es:[bx], al ; next keyword yet?
jne cmp_keyword_loop ; nope: go back until done
; keywords don't match..try next key word in ini structure
inc bx
inc bx ; jump over variable space (1 word)
cmp byte ptr es:[bx+1], al ; more keywords to compare with ?
jne short cmp_keyword1 ; yes: compare the next one
jmp short skip_keyword
; no: search file for next keyword
convert_number:
push si ; save current file pointer
call Get_Char
dec si ; point to first char'r position in number to convert
xor di,di
mov ax,di
mov cx,ax
cmp byte ptr ds:[si], '+' ; positive number ? (default)
jne short cn_1
inc si ; just skip the char'r - positive is default anyway
cn_1: cmp byte ptr ds:[si], '-' ; negative number ?
jne short cn_2
inc si
inc cl ; negative number - flag so we can negate it later
cn_2: push bx
mov bx,si ; save ptr in file buffer - check later if it changed
push cx ; save flag
convert_get_loop:
mov cl, byte ptr ds:[si]
cmp cl, '0'
jb short convert_done
cmp cl, '9'
ja short convert_done
sub cx,'0' ; de-ascii'ize cx ==> 0h - 09h
inc si ; increment pointer
mov dx,010d
mul dx ; multiply ax by 10 : dx is set to zero
add ax,cx ; add number in
jmp short convert_get_loop
convert_done:
pop cx ; restore -ve/+ve flag
jcxz convert_done_1 ; Q: -ve number ?
neg ax ; negate the number
convert_done_1:
cmp si,bx ; Q: has index changed, i.e.
; is the first char'r invalid ?
pop bx
je short convert_done_2 ; Y: don't save number
inc bx ; N: point to number in structure
mov word ptr es:[bx], ax ; save value into ini structure
convert_done_2:
pop si ; get old file pointer
mov byte ptr ds:[si], ';'
; fake a comment, so that the rest of the
; line is ignored in the next Get_Char call
; and the next keyword is pointed to
jmp find_keyword ; go back & get another
; *** single exit point for parsing code
parse_done:
mov ax,es ; swap extended and data segment ptrs
mov bx,ds
mov es,bx
mov ds,ax
pop dx
pop bp
ret
Parse_Ini ENDP
;******************************************************************************
;
; Get_Char
;
; DESCRIPTION: Local routine which gets the next valid ascii
; character from the file image, while skipping white
; space.
;
; ENTRY: ds:si -> buffer pointer
;
; EXIT: ds:si -> new buffer pointer
; al --> character
; Z flag --> set = no white space between last char'r and current
; C flag --> set = reached end of file
;
; USES: cx
;
;==============================================================================
Get_Char PROC NEAR
mov cx,si
inc cx
get_char_loop:
lodsb ; get char from file image
cmp al,EOF
je short get_char_EOF
cmp al,CR
je short get_char_loop
cmp al,LF
je short get_char_loop
cmp al,TAB
je short get_char_loop
cmp al,' '
je short get_char_loop
cmp al,';'
je short get_char_skip_comment
; must have got a good character finally...
call Conv_Char_Lower
cmp cx,si ; skipped a white space ?
clc ; continue
ret
get_char_EOF:
stc ; flag end of the file
ret
get_char_skip_comment:
lodsb ; get char from file image
cmp al,EOF
je short get_char_EOF
cmp al,CR
jne short get_char_skip_comment
jmp short get_char_loop
Get_Char ENDP
Conv_Char_Lower PROC NEAR
cmp al, 'A' ; want char'r 'A'-'Z' to be
jb short lower_done ; converted to 'a'-'z'
cmp al, 'Z'
ja short lower_done
or al, 020h ; convert to lower case
lower_done:
ret
Conv_Char_Lower ENDP
; -------------------------------------------------------
DXCODE ends
;****************************************************************
end