summaryrefslogtreecommitdiff
path: root/v4.0/src/DOS/HANDLE.ASM
diff options
context:
space:
mode:
Diffstat (limited to 'v4.0/src/DOS/HANDLE.ASM')
-rw-r--r--v4.0/src/DOS/HANDLE.ASM893
1 files changed, 893 insertions, 0 deletions
diff --git a/v4.0/src/DOS/HANDLE.ASM b/v4.0/src/DOS/HANDLE.ASM
new file mode 100644
index 0000000..e67c2ae
--- /dev/null
+++ b/v4.0/src/DOS/HANDLE.ASM
@@ -0,0 +1,893 @@
1; SCCSID = @(#)handle.asm 1.1 85/04/10
2TITLE HANDLE - Handle-related system calls
3NAME HANDLE
4;
5; Handle related system calls for MSDOS 2.X. Only top-level system calls
6; are present. I/O specs are defined in DISPATCH. The system calls are:
7;
8; $Close written
9; $Commit written DOS 3.3 F.C. 6/4/86
10; $ExtHandle written DOS 3.3 F.C. 6/4/86
11; $Read written
12; Align_Buffer DOS 4.00
13; $Write written
14; $LSeek written
15; $FileTimes written
16; $Dup written
17; $Dup2 written
18;
19; Revision history:
20;
21; Created: MZ 28 March 1983
22; MZ 15 Dec 1982 Jeff Harbers and Multiplan hard disk copy
23; rely on certain values in AX when $CLOSE
24; succeeds even though we document it as
25; always trashing AX.
26;
27; A000 version 4.00 Jan. 1988
28;
29
30.xlist
31;
32; get the appropriate segment definitions
33;
34include dosseg.asm
35
36CODE SEGMENT BYTE PUBLIC 'CODE'
37 ASSUME SS:DOSGROUP,CS:DOSGROUP
38
39.xcref
40INCLUDE DOSSYM.INC
41INCLUDE DEVSYM.INC
42include EA.inc
43include version.inc
44.cref
45.list
46.sall
47
48 EXTRN DOS_Read:NEAR, DOS_Write:NEAR
49
50IF BUFFERFLAG
51 extrn save_user_map:near
52 extrn restore_user_map:near
53 extrn Setup_EMS_Buffers:near
54ENDIF
55
56 I_need ThisSFT,DWORD ; pointer to SFT entry
57 I_need DMAAdd,DWORD ; old-style DMA address
58 I_Need EXTERR_LOCUS,byte ; Extended Error Locus
59 I_need FailErr,BYTE ; failed error flag
60 I_need User_ID,WORD ; current effective user_id
61 i_need JShare,DWORD ; jump table
62 I_need CurrentPDB,WORD ; current process data block
63 I_need EXTOPEN_ON,BYTE ;AN000;FT. flag for extended open
64; I_need XA_device,BYTE ;AN000; XA device
65 I_need XA_type,BYTE ;AN000; extended open subfunction
66; I_need XA_handle,WORD ;AN000; handle
67 I_need THISCDS,DWORD ;AN000;
68 I_need DUMMYCDS,128 ;AN000;
69 I_need SAVE_ES,WORD ;AN000; saved ES
70 I_need SAVE_DI,WORD ;AN000; saved DI
71 I_need SAVE_DS,WORD ;AN000; saved DS
72 I_need SAVE_SI,WORD ;AN000; saved SI
73 I_need SAVE_CX,WORD ;AN000; saved CX
74
75IF BUFFERFLAG
76
77 I_need BUF_EMS_MODE,BYTE
78 I_need BUF_EMS_LAST_PAGE,DWORD
79 I_need BUF_EMS_FIRST_PAGE,DWORD
80 I_need BUF_EMS_SAFE_FLAG,BYTE
81 I_need BUF_EMS_NPA640,WORD
82 I_need BUF_EMS_PAGE_FRAME,WORD
83 I_need BUF_EMS_PFRAME,WORD
84 I_need LASTBUFFER,DWORD
85
86ENDIF
87
88; I_need XA_ES,WORD ;AN000; extended find
89; I_need XA_BP,WORD ;AN000; extended find
90; I_need XA_from,BYTE ;AN000; for filetimes
91if debug
92 I_need BugLev,WORD
93 I_need BugTyp,WORD
94include bugtyp.asm
95endif
96
97BREAK <$Close - return a handle to the system>
98
99;
100; Assembler usage:
101; MOV BX, handle
102; MOV AH, Close
103; INT int_command
104;
105; Error return:
106; AX = error_invalid_handle
107;
108; No registers returned
109
110Procedure $Close,NEAR
111 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP
112 fmt TypSysCall,LevLog,<"$p Close\n">
113 fmt TypSysCall,LevArgs,<"$p Handle = $x\n">,<BX>
114;
115; Grab the SFT pointer from the JFN.
116;
117 call CheckOwner ; get system file entry
118 JC CloseError ; error return
119 fmt TypAccess,LevSFN,<"$p Close SFT $x:$x\n">,<es,di>
120 context DS ; For DOS_CLOSE
121 MOV WORD PTR [ThisSFT],DI ; save offset of pointer
122 MOV WORD PTR [ThisSFT+2],ES ; save segment value
123;
124; DS:SI point to JFN table entry.
125; ES:DI point to SFT
126;
127; We now examine the user's JFN entry; If the file was a 70-mode file (network
128; FCB, we examine the ref count on the SFT; if it was 1, we free the JFN.
129; If the file was not a net FCB, we free the JFN too.
130;
131 CMP ES:[DI].sf_ref_count,1 ; will the SFT become free?
132 JZ FreeJFN ; yes, free JFN anyway.
133 MOV AL,BYTE PTR ES:[DI].sf_mode
134 AND AL,sharing_mask
135 CMP AL,sharing_net_fcb
136 JZ PostFree ; 70-mode and big ref count => free it
137;
138; The JFN must be freed. Get the pointer to it and replace the contents with
139; -1.
140;
141FreeJFN:
142 Invoke pJFNFromHandle ; d = pJFN (handle);
143 fmt TypAccess,LevSFN,<"$p Close jfn pointer $x:$x\n">,<es,di>
144 MOV BYTE PTR ES:[DI],0FFh ; release the JFN
145PostFree:
146;
147; ThisSFT is correctly set, we have DS = DOSGROUP. Looks OK for a DOS_CLOSE!
148;
149 invoke DOS_Close
150;
151; DOS_Close may return an error. If we see such an error, we report it but
152; the JFN stays closed because DOS_Close always frees the SFT!
153;
154 JC CloseError
155 fmt TypSysCall,LevLog,<"$p: Close ok\n">
156 MOV AH,close ; MZ Bogus multiplan fix
157 transfer Sys_Ret_OK
158CloseError:
159 ASSUME DS:NOTHING
160 fmt TypSysCall,LevLog,<"$p: Close error $x\n">,<AX>
161 transfer Sys_Ret_Err
162EndProc $Close
163
164BREAK <$Commit - commit the file>
165
166;
167; Assembler usage:
168; MOV BX, handle
169; MOV AH, Commit
170; INT int_command
171;
172; Error return:
173; AX = error_invalid_handle
174;
175; No registers returned
176
177Procedure $Commit,NEAR
178 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP
179;
180; Grab the SFT pointer from the JFN.
181;
182 call CheckOwner ; get system file entry
183 JC Commiterror ; error return
184 context DS ; For DOS_COMMIT
185 MOV WORD PTR [ThisSFT],DI ; save offset of pointer
186 MOV WORD PTR [ThisSFT+2],ES ; save segment value
187;
188; ES:DI point to SFT
189;
190;
191; ThisSFT is correctly set, we have DS = DOSGROUP. Looks OK for a DOS_COMMIT
192;
193 invoke DOS_COMMIT
194;
195;
196 JC Commiterror
197 MOV AH,Commit ;
198 transfer Sys_Ret_OK
199Commiterror:
200 ASSUME DS:NOTHING
201 transfer Sys_Ret_Err
202EndProc $Commit
203
204
205BREAK <$ExtHandle - extend handle count>
206
207;
208; Assembler usage:
209; MOV BX, Number of Opens Allowed (MAX=65534;66535 is
210; MOV AX, 6700H reserved to mark SFT
211; INT int_command busy )
212;
213; Error return:
214; AX = error_not_enough_memory
215; or error_too_many_open_files
216; No registers returned
217
218Procedure $ExtHandle,NEAR
219 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP
220;
221;
222;
223 XOR BP,BP ; 0: enlarge 1: shrink 2:psp
224 CMP BX,FilPerProc ; < 20
225 JAE getpdb ; no
226 MOV BX,FilPerProc ; bx = 20
227
228getpdb:
229 MOV ES,[CurrentPDB] ; get user process data block
230 MOV CX,ES:[PDB_JFN_Length] ; get number of handle allowed
231 CMP BX,CX ; the requested == current
232 JE ok_done ; yes and exit
233 JA larger ; go allocate new table
234
235 MOV BP,1 ; shrink
236 MOV DS,WORD PTR ES:[PDB_JFN_Pointer+2] ;
237 MOV SI,BX ;
238 SUB CX,BX ; get difference
239chck_handles:
240 CMP BYTE PTR DS:[SI],-1 ; scan through handles to ensure close
241 JNZ too_many_files ; status
242 INC SI
243 LOOP chck_handles
244 CMP BX,FilPerProc ; = 20
245 JA larger ; no
246
247 MOV BP,2 ; psp
248 MOV DI,PDB_JFN_Table ; es:di -> jfn table in psp
249 PUSH BX
250 JMP movhandl
251
252larger:
253 CMP BX,-1 ; 65535 is not allowed
254 JZ invalid_func
255 CLC
256 PUSH BX ; save requested number
257 ADD BX,0FH ; adjust to paragraph boundary
258 MOV CL,4
259 RCR BX,CL ; DOS 4.00 fix ;AC000;
260 AND BX,1FFFH ; clear most 3 bits
261
262 PUSH BP
263 invoke $ALLOC ; allocate memory
264 POP BP
265 JC no_memory ; not enough meory
266
267 MOV ES,AX ; es:di points to new table memory
268 XOR DI,DI
269movhandl:
270 MOV DS,[CurrentPDB] ; get user PDB address
271
272 TEST BP,3 ; enlarge ?
273 JZ enlarge ; yes
274 POP CX ; cx = the amount you shrink
275 PUSH CX
276 JMP copy_hand
277ok_done:
278 transfer Sys_Ret_OK
279too_many_files:
280 MOV AL,error_too_many_open_files
281 transfer Sys_Ret_Err
282enlarge:
283 MOV CX,DS:[PDB_JFN_Length] ; get number of old handles
284copy_hand:
285 MOV DX,CX
286 LDS SI,DS:[PDB_JFN_Pointer] ; get old table pointer
287ASSUME DS:NOTHING
288 REP MOVSB ; copy infomation to new table
289
290 POP CX ; get new number of handles
291 PUSH CX ; save it again
292 SUB CX,DX ; get the difference
293 MOV AL,-1 ; set availability to handles
294 REP STOSB
295
296 MOV DS,[CurrentPDB] ; get user process data block
297 CMP WORD PTR DS:[PDB_JFN_Pointer],0 ; check if original table pointer
298 JNZ update_info ; yes, go update PDB entries
299 PUSH BP
300 PUSH DS ; save old table segment
301 PUSH ES ; save new table segment
302 MOV ES,WORD PTR DS:[PDB_JFN_Pointer+2] ; get old table segment
303 invoke $DEALLOC ; deallocate old table meomory
304 POP ES ; restore new table segment
305 POP DS ; restore old table segment
306 POP BP
307
308update_info:
309 TEST BP,2 ; psp?
310 JZ non_psp ; no
311 MOV WORD PTR DS:[PDB_JFN_Pointer],PDB_JFN_Table ; restore
312 JMP final
313non_psp:
314 MOV WORD PTR DS:[PDB_JFN_Pointer],0 ; new table pointer offset always 0
315final:
316 MOV WORD PTR DS:[PDB_JFN_Pointer+2],ES ; update table pointer segment
317 POP DS:[PDB_JFN_Length] ; restore new number of handles
318 transfer Sys_Ret_Ok
319no_memory:
320 POP BX ; clean stack
321 MOV AL,error_not_enough_memory
322 transfer Sys_Ret_Err
323invalid_func:
324 MOV AL,error_invalid_function
325 transfer Sys_Ret_Err
326EndProc $ExtHandle
327
328BREAK <$READ - Read from a file handle>
329;
330; Assembler usage:
331; LDS DX, buf
332; MOV CX, count
333; MOV BX, handle
334; MOV AH, Read
335; INT int_command
336; AX has number of bytes read
337; Errors:
338; AX = read_invalid_handle
339; = read_access_denied
340;
341; Returns in register AX
342
343procedure $READ,NEAR
344 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP
345 fmt TypSysCall,LevLog,<"Read\n">
346 fmt TypSysCall,LevArgs,<" Handle $x Cnt $x Buf $x:$x\n">,<BX,CX,DS,DX>
347 MOV SI,OFFSET DOSGROUP:DOS_Read
348ReadDo:
349 invoke pJFNFromHandle
350 JC ReadError
351 MOV AL,ES:[DI]
352 call CheckOwner ; get the handle
353 JNC ReadSetup ; no errors do the operation
354ReadError:
355 fmt TypSysCall,LevLog,<"Read/Write error $x\n">,<AX>
356 transfer SYS_RET_ERR ; go to error traps
357ReadSetup:
358 MOV WORD PTR [ThisSFT],DI ; save offset of pointer
359 MOV WORD PTR [ThisSFT+2],ES ; save segment value
360;; Extended Open
361 TEST ES:[DI.sf_mode],INT_24_ERROR ;AN000;;EO. need i24
362 JZ needi24 ;AN000;;EO. yes
363 OR [EXTOPEN_ON],EXT_OPEN_I24_OFF ;AN000;;EO. set it off
364needi24: ;AN000;
365
366;; Extended Open
367 SaveReg <<WORD PTR [DMAAdd]>, <WORD PTR [DMAAdd+2]>>
368;;;;; BAD SPOT FOR 286!!! SEGMENT ARITHMETIC!!!
369 CALL Align_Buffer ;AN000;MS. align user's buffer
370;;;;; END BAD SPOT FOR 286!!! SEGMENT ARITHMETIC!!!
371
372IF BUFFERFLAG
373
374; int 3
375; cmp [BUF_EMS_MODE], -1
376; jz dos_call
377; call choose_buf_page
378; jc ReadError
379; call save_user_map
380
381;dos_call:
382ENDIF
383 context DS ; go for DOS addressability
384 CALL SI ; indirect call to operation
385 RestoreReg <<WORD PTR [DMAAdd+2]>, <WORD PTR [DMAAdd]>>
386
387IF BUFFERFLAG
388 pushf
389 push ax
390 push bx
391
392 cmp cs:[BUF_EMS_MODE], -1
393 jz dos_call_done
394 call restore_user_map
395 mov ax, word ptr cs:[BUF_EMS_LAST_PAGE]
396 cmp cs:[BUF_EMS_PFRAME], ax
397 je dos_call_done
398 mov word ptr cs:[LASTBUFFER], -1
399 mov cs:[BUF_EMS_PFRAME], ax
400 mov ax, word ptr cs:[BUF_EMS_LAST_PAGE+2]
401 mov cs:[BUF_EMS_PAGE_FRAME], ax
402 mov cs:[BUF_EMS_SAFE_FLAG], 1
403 call Setup_EMS_Buffers
404
405dos_call_done:
406 pop bx
407 pop ax
408 popf
409ENDIF
410
411IF NOT BUFFERFLAG
412 JC ReadError ; if error, say bye bye
413ELSE
414 jmp tmp_rerr
415tmp_rerr:
416 jc ReadError
417ENDIF
418
419 MOV AX,CX ; get correct return in correct reg
420 fmt TypSysCall,LevLog,<"Read/Write cnt done $x\n">,<AX>
421 transfer sys_ret_ok ; successful return
422EndProc $READ
423
424;
425; Input: DS:DX points to user's buffer addr
426; Function: rearrange segment and offset for READ/WRITE buffer
427; Output: [DMAADD] set
428;
429;
430
431procedure Align_Buffer,NEAR ;AN000;
432 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP ;AN000;
433 MOV BX,DX ; copy offset
434 SaveReg <CX> ; don't stomp on count
435 MOV CL,4 ; bits to shift bytes->para
436 SHR BX,CL ; get number of paragraphs
437 RestoreReg <CX> ; get count back
438 MOV AX,DS ; get original segment
439 ADD AX,BX ; get new segment
440 MOV DS,AX ; in seg register
441 AND DX,0Fh ; normalize offset
442 MOV WORD PTR [DMAAdd],DX ; use user DX as offset
443 MOV WORD PTR [DMAAdd+2],DS ; use user DS as segment for DMA
444 return ;AN000;
445EndProc Align_Buffer ;AN000;
446
447BREAK <$WRITE - write to a file handle>
448
449;
450; Assembler usage:
451; LDS DX, buf
452; MOV CX, count
453; MOV BX, handle
454; MOV AH, Write
455; INT int_command
456; AX has number of bytes written
457; Errors:
458; AX = write_invalid_handle
459; = write_access_denied
460;
461; Returns in register AX
462
463procedure $WRITE,NEAR
464 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP
465 fmt TypSysCall,LevLog,<"Write\n">
466 fmt TypSysCall,LevArgs,<" Handle $x Cnt $x Buf $x:$x\n">,<BX,CX,DS,DX>
467 MOV SI,OFFSET DOSGROUP:DOS_Write
468 JMP ReadDo
469EndProc $Write
470
471BREAK <$LSEEK - move r/w pointer>
472
473;
474; Assembler usage:
475; MOV DX, offsetlow
476; MOV CX, offsethigh
477; MOV BX, handle
478; MOV AL, method
479; MOV AH, LSeek
480; INT int_command
481; DX:AX has the new location of the pointer
482; Error returns:
483; AX = error_invalid_handle
484; = error_invalid_function
485; Returns in registers DX:AX
486
487procedure $LSEEK,NEAR
488 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP
489 call CheckOwner ; get system file entry
490LSeekError:
491
492IF BUFFERFLAG
493 JC TMP_RERR
494ELSE
495 JC ReadError ; error return
496ENDIF
497 CMP AL,2 ; is the seek value correct?
498 JBE LSeekDisp ; yes, go dispatch
499 MOV EXTERR_LOCUS,errLoc_Unk ; Extended Error Locus
500 error error_invalid_function ; invalid method
501LSeekDisp:
502 CMP AL,1 ; best way to dispatch; check middle
503 JB LSeekStore ; just store CX:DX
504 JA LSeekEOF ; seek from end of file
505 ADD DX,WORD PTR ES:[DI.SF_Position]
506 ADC CX,WORD PTR ES:[DI.SF_Position+2]
507LSeekStore:
508 MOV AX,CX ; AX:DX
509 XCHG AX,DX ; DX:AX is the correct value
510LSeekSetpos:
511 MOV WORD PTR ES:[DI.SF_Position],AX
512 MOV WORD PTR ES:[DI.SF_Position+2],DX
513 invoke Get_user_stack
514 MOV DS:[SI.User_DX],DX ; return DX:AX
515 transfer SYS_RET_OK ; successful return
516
517LSeekEOF:
518 TEST ES:[DI.sf_flags],sf_isnet
519 JNZ Check_LSeek_Mode ; Is Net
520LOCAL_LSeek:
521 ADD DX,WORD PTR ES:[DI.SF_Size]
522 ADC CX,WORD PTR ES:[DI.SF_Size+2]
523 JMP LSeekStore ; go and set the position
524
525Check_LSeek_Mode:
526 TEST ES:[DI.sf_mode],sf_isfcb
527 JNZ LOCAL_LSeek ; FCB treated like local file
528 MOV AX,ES:[DI.sf_mode]
529 AND AX,sharing_mask
530 CMP AX,sharing_deny_none
531 JZ NET_LSEEK ; LSEEK exported in this mode
532 CMP AX,sharing_deny_read
533 JNZ LOCAL_LSeek ; Treated like local Lseek
534NET_LSEEK:
535; JMP LOCAL_LSeek
536; REMOVE ABOVE INSTRUCTION TO ENABLE DCR 142
537 CallInstall Net_Lseek,multNet,33
538 JNC LSeekSetPos
539 transfer SYS_RET_ERR
540
541EndProc $LSeek
542
543BREAK <FileTimes - modify write times on a handle>
544
545;
546; Assembler usage:
547; MOV AH, FileTimes (57H)
548; MOV AL, func
549; MOV BX, handle
550; ; if AL = 1 then then next two are mandatory
551; MOV CX, time
552; MOV DX, date
553; INT 21h
554; ; if AL = 0 then CX/DX has the last write time/date
555; ; for the handle.
556;
557; AL=02 get extended attributes
558; BX=handle
559; CX=size of buffer (0, return max size )
560; DS:SI query list (si=-1, selects all EA)
561; ES:DI buffer to hold EA list
562;
563; AL=03 get EA name list
564; BX=handle
565; CX=size of buffer (0, return max size )
566; ES:DI buffer to hold name list
567;
568; AL=04 set extended attributes
569; BX=handle
570; ES:DI buffer of EA list
571;
572;
573;
574;
575; Error returns:
576; AX = error_invalid_function
577; = error_invalid_handle
578;
579
580procedure $File_Times,NEAR
581 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP
582 CMP AL,2 ; correct subfunction?
583 JAE gsetxa
584 JMP filetimes_ok ; Yes, continue
585;;;; DOS 4.00 ;AN000;
586gsetxa: ;AN000;
587 EnterCrit critSFT ;AN000;;FT. enter critical section
588 CMP AL,4 ;AN000;;FT. =4
589 JBE gshandle ;AN000;;FT. 2,3,4 do get/set by handle
590funcerr: ;AN000;
591 JMP inval_func ;AN000;;FT. invalid function
592 ;AN000;
593gshandle: ;AN000;
594 MOV [SAVE_ES],ES ;AN000;;FT. save regs
595 MOV [SAVE_DI],DI ;AN000;;FT.
596 MOV [SAVE_DS],DS ;AN000;;FT. save regs
597 MOV [SAVE_SI],SI ;AN000;;FT.
598 MOV [SAVE_CX],CX ;AN000;;FT.
599 MOV [XA_TYPE],AL ;AN000;;FT.
600 ;AN000;
601; MOV [XA_handle],BX ;AN000; ;FT. save handle
602 CALL CheckOwner ;AN000; ;FT. get sf pointer
603 JNC getsetit ;AN000; ;FT. good handle
604 LeaveCrit critSFT ;AN000; ;FT. leave critical section
605 JMP LSeekError ;AN000; ;FT. turkey handle
606 ;AN000;
607getsetit: ;AN000;
608 MOV WORD PTR [ThisSFT],DI ;AN000; ;FT. set ThisSFT
609 MOV WORD PTR [ThisSFT+2],ES ;AN000; ;FT. set ThisSFT
610; TEST ES:[DI.sf_mode],INT_24_ERROR ;AN000;;FT. mask INT 24
611; JZ nomask ;AN000;;FT. no
612; OR [EXTOPEN_ON],EXT_OPEN_I24_OFF ;AN000;;FT. set bit for I24 handler
613nomask: ;AN000;
614 TEST ES:[DI.sf_flags],sf_isnet ;AN000;;FT. remote handle
615 JZ localhandle ;AN000;;FT. no
616 LeaveCrit critSFT ;AN000;;FT. doesn't support Network
617
618 MOV BL,[XA_TYPE] ;AN000;;FT.
619IFSsearch: ;AN000;
620 MOV AX,(multNET SHL 8) or 45 ;AN000;;FT. Get/Set XA support
621 INT 2FH ;AN000;
622 JC getseterror ;AN000;;FT. error
623 transfer SYS_RET_OK ;AN000;;FT.
624localhandle: ;AN000;
625; TEST ES:[DI.sf_flags],devid_device ;AN000;;FT. device
626; JZ getsetfile8 ;AN000;;FT. no
627; MOV [XA_device],1 ;AN000;;FT. indicating device
628; JMP SHORT doXA ;AN000;;FT. do XA
629getsetfile8: ;AN000;
630; MOV [XA_device],0 ;AN000;;FT. indicating File
631; LES BP,ES:[DI.sf_devptr] ;AN000;;FT. ES:BP -> DPB
632
633doXA: ;AN000;
634; MOV [XA_from],By_XA ;AN000;;FT. from get/set XA
635; PUSH [SAVE_ES] ;AN000;;FT. save XA list
636; PUSH [SAVE_DI] ;AN000;;FT. save XA list
637
638 invoke GetSet_XA ;AN000;;FT. issue Get/Set XA
639; POP SI ;AN000;;FT. DS:SI -> XA list
640; POP DS ;AN000;
641 JC getexit ;AN000;;FT. error
642; CMP [XA_device],0 ;AN000;;FT. device ?
643; JNZ ftok ;AN000;;FT. yes, exit
644; MOV AX,4 ;AN000;;FT. function 4 for ShSU
645; CMP [XA_type],4 ;AN000;;FT. set XA
646; JNZ ftok ;AN000;;FT. no
647;
648;
649; LES DI,[ThisSFT] ;AN000;;FT. es:di -> sft
650; CMP WORD PTR [SI],0 ;AN000;;FT. null list ?
651; JNZ do_share ;AN000;;FT. no
652 JMP SHORT ftok ;AN000;;FT. return
653getexit: ;AN000;;FT.
654 LeaveCrit critSFT ;AN000;;FT. leave critical section
655
656
657getseterror: ;AN000;
658 transfer SYS_RET_ERR ;AN000;;FT. mark file as dirty
659inval_func:
660
661;;;;; DOS 4.00
662 MOV EXTERR_LOCUS,errLoc_Unk ; Extended Error Locus
663 error error_invalid_function ; give bad return
664filetimes_ok:
665 call CheckOwner ; get sf pointer
666 JNC gsdt
667 JMP LSeekError ; turkey handle
668gsdt:
669 OR AL,AL ; is it Get?
670 JNZ filetimes_set ; no, go set the time
671 CLI
672 MOV CX,ES:[DI.sf_Time] ; suck out time
673 MOV DX,ES:[DI.sf_Date] ; and date
674 STI
675 invoke Get_user_stack ; obtain place to return it
676 MOV [SI.user_CX],CX ; and stash in time
677 MOV [SI.user_DX],DX ; and stask in date
678ext_done:
679 transfer SYS_RET_OK ; and say goodnight
680filetimes_set:
681 EnterCrit critSFT
682 MOV ES:[DI.sf_Time],CX ; drop in new time
683 MOV ES:[DI.sf_Date],DX ; and date
684 XOR AX,AX
685do_share:
686if installed
687 Call JShare + 14 * 4
688else
689 Call ShSU
690endif
691datetimeflg:
692 AND ES:[DI.sf_Flags],NOT devid_file_clean
693 OR ES:[DI.sf_Flags],sf_close_nodate
694ftok:
695 LeaveCrit critSFT
696 transfer SYS_RET_OK ; mark file as dirty and return
697EndProc $File_Times
698
699BREAK <$DUP - duplicate a jfn>
700;
701; Assembler usage:
702; MOV BX, fh
703; MOV AH, Dup
704; INT int_command
705; AX has the returned handle
706; Errors:
707; AX = dup_invalid_handle
708; = dup_too_many_open_files
709Procedure $DUP,NEAR
710 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP
711 MOV AX,BX ; save away old handle in AX
712 invoke JFNFree ; free handle? into ES:DI, new in BX
713DupErrorCheck:
714 JC DupErr ; nope, bye
715 SaveReg <ES,DI> ; save away SFT
716 RestoreReg <SI,DS> ; into convenient place DS:SI
717 XCHG AX,BX ; get back old handle
718 call CheckOwner ; get sft in ES:DI
719 JC DupErr ; errors go home
720 invoke DOS_Dup_Direct
721 invoke pJFNFromHandle ; get pointer
722 MOV BL,ES:[DI] ; get SFT number
723 MOV DS:[SI],BL ; stuff in new SFT
724 transfer SYS_RET_OK ; and go home
725DupErr: transfer SYS_RET_ERR
726
727EndProc $Dup
728
729BREAK <$DUP2 - force a dup on a particular jfn>
730;
731; Assembler usage:
732; MOV BX, fh
733; MOV CX, newfh
734; MOV AH, Dup2
735; INT int_command
736; Error returns:
737; AX = error_invalid_handle
738;
739Procedure $Dup2,NEAR
740 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP
741 SaveReg <BX,CX> ; save source
742 MOV BX,CX ; get one to close
743 invoke $Close ; close destination handle
744 RestoreReg <BX,AX> ; old in AX, new in BX
745 invoke pJFNFromHandle ; get pointer
746 JMP DupErrorCheck ; check error and do dup
747EndProc $Dup2
748
749Break <CheckOwner - verify ownership of handles from server>
750
751;
752; CheckOwner - Due to the ability of the server to close file handles for a
753; process without the process knowing it (delete/rename of open files, for
754; example), it is possible for the redirector to issue a call to a handle
755; that it soes not rightfully own. We check here to make sure that the
756; issuing process is the owner of the SFT. At the same time, we do a
757; SFFromHandle to really make sure that the SFT is good.
758;
759; Inputs: BX has the handle
760; User_ID is the current user
761; Output: Carry Clear => ES:DI points to SFT
762; Carry Set => AX has error code
763; Registers modified: none
764;
765
766Procedure CheckOwner,NEAR
767 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP
768 invoke SFFromHandle
769 retc
770 push ax
771 mov ax,user_id
772 cmp ax,es:[di].sf_UID
773 pop ax
774 retz
775 mov al,error_invalid_handle
776 stc
777 return
778EndProc CheckOwner
779
780;-------------------------------------------------------------------------
781; Function name : choose_buf_page
782; Inputs : DMAADD = Xaddr
783; cx = # of bytes to transfer
784; Outputs : if NC
785;
786; SAFE_FLAG - 0 ==> page is safe. no need to
787; detect collision between
788; user & system buffer.
789; SAFE_FLAG - 1 ==> page is unsafe. Must check
790; for collision
791;
792; CY - error
793;
794;
795; High Level Alogrithm:
796;
797; 1. If Xaddr. is above the first physical page above 640K
798; 2. choose that page
799; 3. set safe flag
800; 4. else
801; 5. choose highest page above 640K
802; 6. If 6 or more pages above 640k
803; 7. Set safe flag
804; 8. else
805; 9. if Xaddr. + # of bytes to transfer does not spill into the
806; chosen page
807; 10. set safe flag
808; 11.else
809; 12. clear safe flag
810; 13.endif
811; 14.endif
812; 15.endif
813;
814;----------------------------------------------------------------------------
815;Procedure choose_buf_page,near
816;
817; assume cs:dosgroup, ds:nothing, es:nothing, ss:dosgroup
818;
819; push cx
820; push bx
821; push dx
822; push si
823; push ds
824; push ax
825;
826; mov ax, word ptr [DMAADD+2]
827; and ax, 0fc00h ; page segment of transfer segment
828;
829; cmp ax, word ptr [BUF_EMS_FIRST_PAGE]
830; ja pick_first
831;
832; cmp [BUF_EMS_NPA640], 6
833; jae safe_pick_last
834;
835; add cx, word ptr [DMAADD] ; get final offset
836; mov bx, cx
837;
838; mov cl, 4
839; shr bx, cl ; get # of paragraphs
840; mov ax, word ptr [DMAADD+2] ; get initial segment
841; add ax, bx ; get final segment
842;
843; and ax, 0fc00h
844; cmp ax, word ptr [BUF_EMS_LAST_PAGE]
845; jne safe_pick_last
846;
847; mov [BUF_EMS_SAFE_FLAG], 0
848; jmp fin_choose_page
849;
850;safe_pick_last:
851; mov [BUF_EMS_SAFE_FLAG], 1
852; jmp fin_choose_page
853;
854;;pick_last:
855;; mov ax, word ptr [BUF_EMS_LAST_PAGE]
856;; mov [BUF_EMS_PFRAME], ax
857;; mov ax, word ptr [BUF_EMS_LAST_PAGE+2]
858;; mov [BUF_EMS_PAGE_FRAME], ax
859;; xor ax, ax
860;; jmp fin_choose_page
861;
862;pick_first:
863; mov ax, word ptr [BUF_EMS_FIRST_PAGE]
864; cmp [BUF_EMS_PFRAME], ax
865; je fin_choose_page
866; mov word ptr [LASTBUFFER], -1
867; mov [BUF_EMS_PFRAME], ax
868; mov ax, word ptr [BUF_EMS_FIRST_PAGE+2]
869; mov [BUF_EMS_PAGE_FRAME], ax
870; mov [BUF_EMS_SAFE_FLAG], 1
871; call Setup_EMS_Buffers
872; jmp fin_choose_page
873;
874;err_choose_page:
875; stc
876;
877;fin_choose_page:
878; clc
879;
880; pop ax
881; pop ds
882; pop si
883; pop dx
884; pop bx
885; pop cx
886; return
887;
888;EndProc choose_buf_page
889;
890
891CODE ENDS
892END
893 \ No newline at end of file