;++ ; ; WOW v1.0 ; ; Copyright (c) 1991, Microsoft Corporation ; ; WINSTR.ASM ; Win16 string services ; ; History: ; ; Created 18-Jun-1991 by Jeff Parsons (jeffpar) ; Copied from WIN31 and edited (as little as possible) for WOW16 ;-- ;**************************************************************************** ;* * ;* WinStr.ASM - * ;* * ;* String related API calls to support different lanuages * ;* * ;**************************************************************************** TITLE WinStr.ASM ifdef WOW NOEXTERNS equ 1 endif NOTEXT = 1 .xlist include user.inc .list sBegin DATA sEnd createSeg _TEXT, CODE, WORD, PUBLIC, CODE sBegin CODE assumes CS,CODE assumes DS,DATA ExternNP Loc_IsConvertibleToUpperCase ExternNP Loc_Upper ExternFP IAnsiUpper ExternFP IAnsiLower ExternFP Ilstrcmpi ifdef FE_SB ExternFP IsDBCSLeadByte endif ; Function codes for all the string functions in USER ; ANSINEXT_ID equ 1 ANSIPREV_ID equ 2 ANSIUPPER_ID equ 3 ANSILOWER_ID equ 4 ;-------------------------------------------------------------------------- ; The order of entries in the following table can not be changed ; unless the *_ID codes are also changed in KERNEL also. ; ((FunctionCode - 1) << 1) is used as the index into this table ; ; Function Codes: ; ; NOTE: If you change the entries in this table, kindly update the ; *_ID statements above and also lString.asm of KERNEL. ; ;-------------------------------------------------------------------------- LabelW StringFuncTable dw codeOFFSET IAnsiNext dw codeOFFSET IAnsiPrev dw codeOFFSET IAnsiUpper dw codeOFFSET IAnsiLower ;*----------------------------------------------------------------------* ;* StringFunc() * ;* The string manipulation functions in kernel have been moved * ;* into USER. * ;* This is the common entry point in USER for all the string * ;* manipulation functions Kernel wants to call. Kernel jumps to * ;* this function with the function code in CX * ;* * ;* Input Parameters: * ;* [CX] contains the Function code. * ;* [sp] contains the FAR return address of the original caller of * ;* the string manipulation functions in Kernel * ;*----------------------------------------------------------------------* cProc StringFunc, cBegin nogen xchg bx,cx ; move function code to BX dec bx shl bx, 1 jmp StringFuncTable[bx] ; Control does not comeback here. It returns directly ; to the caller cEnd nogen ;*----------------------------------------------------------------------* ;* * ;* AnsiPrev() * ;* * ;*----------------------------------------------------------------------* ifdef FE_SB cProc IAnsiPrev, ; parmD pFirst ; [bx+10] es:di ; parmD pStr ; [bx+6] ds:si cBegin nogen push bp mov bp,sp push ds push si push di lds si,[bp+6] les di,[bp+10] regptr dssi,ds,si regptr esdi,es,di cld cmp si,di ; pointer to first char? jz ap5 ; yes, just quit dec si ; backup once cmp si,di ; pointer to first char? jz ap5 ; yse, just quit ap1: dec si ; backup once mov al, [si] ; fetch a character cCall IsDBCSLeadByte, ; DBCS lead byte candidate? test ax,ax ; jz ap2 ; jump if not. cmp si,di ; backword exhausted? jz ap3 ; jump if so jmp ap1 ; repeat if not ap2: inc si ; adjust pointer correctly ap3: mov bx, [bp+6] ; mov di, bx ; result in DI dec di ; sub bx, si ; how many characters backworded test bx, 1 ; see even or odd... jnz ap4 ; odd - previous char is SBCS dec di ; make DI for DBCS ap4: mov si, di ; final result in SI ap5: mov ax,si mov dx,ds pop di pop si pop ds pop bp ret 8 cEnd nogen else cProc IAnsiPrev, ; parmD pFirst ; [bx+8] es:di ; parmD pStr ; [bx+4] ds:si cBegin nogen mov bx,sp push ds push si push di lds si,ss:[bx+4] les di,ss:[bx+8] regptr dssi,ds,si regptr esdi,es,di cld cmp si,di ; pointer to first char? jz ap3 ; yes, just quit ;;ifdef FE_SB ;; xchg si,di ;;ap1: mov dx,si ;; lodsb ; get a char ;; cCall IsDBCSLeadByte, ; is it kanji? ;; cmp al,0 ;; je ap2 ; no, get next char ;; inc si ; yes, inc past second part ;;ap2: cmp si,di ; have we at or past end? ;; jb ap1 ; no, keep going ;; mov si,dx ; return previous pointer ;;else dec si ; assume easy case... ;;endif ; FE_SB ap3: mov ax,si mov dx,ds pop di pop si pop ds ret 8 cEnd nogen endif ;*----------------------------------------------------------------------* ;* * ;* AnsiNext() * ;* * ;*----------------------------------------------------------------------* cProc IAnsiNext, ; parmD pStr cBegin nogen mov bx,sp push di les di,ss:[bx+4] mov al,es:[di] or al,al jz an1 inc di ifdef FE_SB cCall IsDBCSLeadByte, cmp al,0 je an1 inc di endif ; FE_SB an1: mov ax,di mov dx,es pop di ret 4 cEnd nogen ;----------------------------------------------------------------------- ; MyAnsiUpper() ; convert string at es:di to upper case ;----------------------------------------------------------------------- public MyAnsiUpper MyAnsiUpper: cld mov si,di mau1: lods byte ptr es:[si] ifdef FE_SB push ax cCall IsDBCSLeadByte, cmp ax,0 pop ax je mau2 inc si inc di inc di jmp short mau1 endif mau2: call MyUpper stosb or al,al jnz mau1 ret ;----------------------------------------------------------------------- ; MyAnsiLower() ; convert string at es:di to lower case ;----------------------------------------------------------------------- public MyAnsiLower MyAnsiLower: cld mov si,di mal1: lods byte ptr es:[si] ifdef FE_SB push ax cCall IsDBCSLeadByte, ; first byte of double byte? cmp ax,0 pop ax je mal2 ; no just do normal stuff inc si ; skip the two bytes inc di inc di jmp short mal1 endif mal2: call MyLower stosb or al,al jnz mal1 ret ;------------------------------------------------------------------------- ; MyUpper() ; convert lower case to upper, must preserve es,di,cx ;------------------------------------------------------------------------- public MyUpper MyUpper: call Loc_IsConvertibleToUpperCase ; Check if it is a lower case char ; that has an uppercase equivalent jnc myu1 ; sub al,'a'-'A' myu1: ret ifdef KANJI #################### KANJI ############################################### ; convert upper case to lower, must preserve es,di,cx public MyLower MyLower: cmp al,'A' jb myl2 cmp al,'Z' jbe myl1 push ds SetKernelDS cmp [fFarEast],1 ; this is a far east kbd 1/12/87 linsh pop ds UnSetKernelDS jge myl2 ; yes do nothing to the 0C0H - 0DEH range cmp al,0C0H ; this is lower case a with a back slash jb myl2 cmp al,0DEH ja myl2 myl1: add al,'a'-'A' myl2: ret #################### KANJI ############################################### endif ;-------------------------------------------------------------------------- ; MyLower() ; convert upper case to lower, must preserve es,di,cx ;-------------------------------------------------------------------------- public MyLower MyLower: call Loc_Upper jnc myl1 add al, 'a'-'A' myl1: ret sEnd CODE end