|
|
1.1 root 1: ; SPY Assembly language utility functions.
2:
3: ?WIN=1 ; Use Windows prolog/epilog
4: ?PLM=1 ; Use PLM calling convention
5: DOS5=1
6: .xlist
7: include cmacros.inc
8: .list
9:
10:
11:
12: EXTRN DOSCHGFILEPTR:FAR
13: EXTRN DOSREAD:FAR
14:
15:
16: sBegin CODE
17: assumes cs,CODE
18: assumes ds,DATA
19: .286p
20:
21: ; FValidPointer
22: ;
23: ; FValidPointer(VOID FAR *pVoid, SHORT cbStruct)
24: ;
25: cProc FValidPointer,<NEAR,PUBLIC>
26: ParmD pVoid
27: ParmW cbStruct
28: cBegin
29: xor ax,ax ; Assume Bad address
30: mov bx,SEG_pVoid ; Get the selector of the address
31: lar cx,bx ; make sure we have access
32: jnz NoAccess ; no access
33:
34: lsl cx,bx ; get the segment limit
35: mov bx,OFF_pVoid ; check range
36: add bx,cbStruct ; Add number of bytes on
37: jc NoAccess ; overflowed
38: cmp cx,bx
39: jc NoAccess ; Would overflow, again bad pointer
40: inc ax ; Return No zero for TRUE
41:
42: NoAccess:
43: cEnd
44:
45:
46:
47: ; FGuessValidPointer
48: ;
49: ; FGuessValidPointer(VOID FAR *pVoid, SHORT cbStruct)
50: ; Since a pointer may have come from a different process, we can not
51: ; actually validate the pointer. The Best we can do is simply look
52: ; at the selector, and see if it looks reasonable. For now simply check
53: ; that the selector is for ring 3. Ie the low order two bits are set.
54: ;
55: cProc FGuessValidPointer,<NEAR,PUBLIC>
56: ParmD pVoid
57: ParmW cbStruct
58: cBegin
59: xor ax,ax ; Assume Bad address
60: mov bx,SEG_pVoid ; Get the selector of the address
61: and bx,03h ; only look at two low order bits
62: cmp bx,03h ; Are they both set
63: jnz NoGVAccess ; not ring 3 assume no access
64: inc ax ; Return No zero for TRUE
65:
66: NoGVAccess:
67: cEnd
68:
69:
70:
71: cProc DebugFileSeek,<PUBLIC,NEAR,PASCAL>
72: parmW fh
73: parmD amt
74: parmW typ
75: cBegin
76: push ax
77: push ax
78: mov bx,sp
79: push fh
80: mov dx,SEG_amt
81: mov ax,OFF_amt
82: mov cx,typ
83: cmp cx,2
84: jle noshift
85: shiftamt:
86: shl ax,1
87: rcl dx,1
88: loop shiftamt
89: noshift:
90: push dx
91: push ax
92: push cx
93: push ss
94: push bx
95: call DOSCHGFILEPTR
96: or ax,ax
97: pop ax
98: pop dx
99: jz seek_done
100: xor ax,ax
101: xor dx,dx
102: seek_done:
103: cEnd
104:
105:
106:
107: cProc DebugFileRead,<PUBLIC,NEAR,PASCAL>
108: parmW fh
109: parmD lpBuf
110: parmW nBytes
111: cBegin
112: push ax
113: mov ax,sp
114: push fh
115: push SEG_lpBuf
116: push OFF_lpBuf
117: push nBytes
118: push ss
119: push ax
120: call DOSREAD
121: or ax,ax
122: pop ax
123: jz read_done
124: xor ax,ax
125: read_done:
126: cEnd
127:
128: cProc lstrcat,<PUBLIC>,<SI,DI,DS>
129: parmD szDest
130: parmD szSource
131:
132: cBegin lstrcat
133:
134: ; first lets get the length of the source string and setup pointer to
135: ; source string
136:
137: les di,szSource
138: mov cx,-1 ; count the bytes negatively
139: xor ax,ax ; Look for a null
140:
141: repne scasb ; find null byte & get source length
142: inc cx ; cx=-count of bytes in source string
143: ; (including null)
144: neg cx ; cx=+count
145: mov bx,cx ; save the count
146:
147: lds si,szSource ; now setup Source pointer
148:
149: ; now find the end of destination string.
150: les di,szDest
151: xor ax,ax
152: mov cx,0ffffH
153: repne scasb
154: dec di ; di points to dest null terminator
155:
156: mov cx,bx ; restore count of bytes to copy
157:
158: rep movsb ; concatenate the strings
159:
160: cEnd lstrcat
161:
162: sEnd CODE
163: end
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.