|
|
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
|