1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
|
; SCCSID = @(#)segcheck.asm 1.2 85/07/24
TITLE SegCheck - internal consistency check
NAME SegCheck
.xlist
INCLUDE DOSSYM.INC
INCLUDE DEVSYM.INC
ShareF = FALSE
IF NOT SHAREF
include dosseg.asm
ENDIF
.list
AsmVars <NET, DEBUG>
DEBUG = FALSE
IF NOT SHAREF
CODE SEGMENT BYTE PUBLIC 'CODE'
ASSUME CS:DOSGroup
ELSE
SHARE SEGMENT BYTE PUBLIC 'SHARE'
ASSUME CS:SHARE
ENDIF
DEBUG = FALSE
BREAK <SegCheck - validate segments in MSDOS>
Off Macro reg,var
IF SHAREF
mov reg,offset var
else
mov reg,offset DOSGroup:var
endif
endm
zfmt MACRO fmts,args
local a,b
PUSHF
PUSH AX
PUSH BP
MOV BP,SP
If (not sharef) and (not redirector)
Table segment
a db fmts,0
Table ends
MOV AX,OFFSET DOSGROUP:a
else
jmp short b
a db fmts,0
if sharef
b: mov ax,offset share:a
else
b: mov ax,offset netwrk:a
endif
endif
PUSH AX
cargs = 2
IRP item,<args>
IFIDN <AX>,<item>
MOV AX,[BP+2]
ELSE
MOV AX,item
ENDIF
PUSH AX
cargs = cargs + 2
ENDM
invoke PFMT
ADD SP,Cargs
POP BP
POP AX
POPF
ENDM
segFrame Struc
segbp DW ?
segip DW ?
segmes dw ?
segtemp DW ?
segFrame ENDS
;
; SegCheck - assure that segments are correctly set up
;
; Inputs: top of stack points to:
; 2-byte jump
; byte flags 04h is ES 02h is DS 01 is CS/SS
; offset asciz message
;
; Outputs: message to screen (via INT 29h)
; Nothing modified (flags too)
Procedure SegCheck,NEAR
ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING
SaveReg <BP>
MOV BP,SP ; set up addressing
PUSHF
SaveReg <AX,BX,CX,DX>
MOV AL,BYTE PTR [BP].segtemp; get flags
MOV CX,SS
TEST AL,1 ; shall we use CS or SS?
JZ SegUseSS ; use SS
MOV CX,CS ; use CS instead
SegUseSS:
TEST AL,2 ; do we check DS?
JZ SegTestES ; no, go check ES
MOV DX,DS
CMP CX,DX
JZ SegTestES ; DS is valid, go check ES
MOV AX,[BP].segmes
zfmt <"Assumed DS invalid $s\n">,<AX>
SegTestES:
TEST AL,4 ; do we check ES?
JZ SegTestDone ; no, all done
MOV DX,ES
CMP CX,DX
JZ SegTestDone ; ES is valid, all done
MOV AX,[BP].segmes
zfmt <"Assumed ES invalid $s\n">,<AX>
SegTestDone:
RestoreReg <DX,CX,BX,AX>
POPF
RestoreReg <BP>
ret 4 ; release message, temp
EndProc SegCheck
IF NOT SHAREF
I_need DPBHead,DWORD
I_need BuffHead,DWORD
I_need sftFCB,DWORD
I_need AuxStack,BYTE
I_need IOStack,BYTE
I_need renbuf,byte
I_need CurrentPDB,WORD
I_need User_In_AX,WORD
extrn ECritDisk:NEAR
CritNOP label byte
RET
AstFrame STRUC
Astbp dw ?
Astip dw ?
Astmes dw ?
Astarg dd ?
AstFrame ENDS
Public SGCHK001S,SGCHK001E
SGCHK001S label byte
DPBMes DB "DPB assertion failed: ",0
BUFMes DB "BUF assertion failed: ",0
SFTMes DB "SFT assertion failed: ",0
BlankSp DB " ",0
Colon DB ":",0
Msg DW ?
SGCHK001E label byte
Table segment
Extrn SectPDB:WORD, SectRef:WORD
Table ends
; DPBCheck - validate a supposed DPB pointer
; Inputs: Pushed arguments
; Outputs: Message to screen
; Registers modified: none
Procedure DPBCheck,NEAR
MOV Msg,OFFSET DOSGroup:DPBMes
SaveReg <BP>
MOV BP,SP
PUSHF
SaveReg <AX,BX,DS,SI,ES,DI>
LES DI,DPBHead
LDS SI,[BP].Astarg
DPBLoop:CMP DI,-1
JZ DPBNotFound
invoke PointComp
JZ DPBRet
LES DI,ES:[DI.dpb_next_dpb]
JMP DPBLoop
DPBNotFound:
MOV AX,[BP].Astmes
zfmt <"$s$x:$x $s\n">,<msg,ds,si,AX>
CLI
a: JMP a ; slam the door.
DPBRet: RestoreReg <DI,ES,SI,DS,BX,AX> ; Done:
POPF
RestoreReg <BP>
RET 6
EndProc DPBCheck
; SFTCheck - validate a supposed SFT pointer
; Inputs: Pushed arguments
; Outputs: Message to screen
; Registers modified: none
Procedure SFTCheck,NEAR
MOV Msg,OFFSET DOSGroup:SFTMes
SaveReg <BP>
MOV BP,SP
PUSHF
SaveReg <AX,BX,DS,SI,ES,DI>
LDS SI,[BP].Astarg
XOR BX,BX ; i = 0;
SFTLoop:
SaveReg <BX>
invoke SFFromSFN ; while ((d=SF(i)) != NULL)
RestoreReg <BX>
JC Sft1
invoke PointComp
JZ DPBRet ; goto Done;
SFTNext:INC BX ; else
JMP SFTLoop ; i++;
SFT1: LES DI,sftFCB
MOV BX,ES:[DI.sfCount]
LEA DI,[DI.sfTable]
SFT2:
invoke PointComp
DPBRETJ:JZ DPBRet
ADD DI,SIZE sf_entry
DEC BX
JNZ SFT2
;
; The SFT is not in the allocated tables. See if it is one of the static
; areas.
;
Context ES
MOV DI,OFFSET DOSGROUP:AUXSTACK - SIZE SF_ENTRY
Invoke PointComp
JZ DPBRet
MOV DI,OFFSET DOSGROUP:RenBuf
Invoke PointComp
JZ DPBRetj
DPBNotFoundJ:
JMP DPBNotFound
EndProc SFTCheck
; BUFCheck - validate a supposed BUF pointer
; Inputs: Pushed arguments
; Outputs: Message to screen
; Registers modified: none
Procedure BUFCheck,NEAR
MOV Msg,OFFSET DOSGroup:BUFMes
SaveReg <BP>
MOV BP,SP
PUSHF
SaveReg <AX,BX,DS,SI,ES,DI>
;
; CheckDisk - make sure that we are in the disk critical section...
;
MOV AL,BYTE PTR ECritDisk
CMP AL,CritNOP
JZ CheckDone
MOV AX,CurrentPDB
CMP SectPDB + 2 * critDisk,AX
MOV AX,[BP].astmes
JZ CheckRef
zfmt <"$p: $x $s critDisk owned by $x\n">,<User_In_AX,AX,SectPDB+2*critDisk>
CheckRef:
CMP SectRef + 2 * critDisk,0
JNZ CheckDone
zfmt <"$p: $x $s critDisk ref count is 0\n">,<User_In_AX,AX>
CheckDone:
LDS SI,[BP].Astarg
LES DI,BUFFHead
BUFLoop:CMP DI,-1
JZ DPBNotFoundJ
invoke PointComp
JNZ BufNext
JMP DPBRet
BufNext:
LES DI,ES:[DI.buf_link]
JMP BUFLoop
EndProc BUFCheck
CODE ENDS
ELSE
SHARE ENDS
ENDIF
END
|