]> wirehaze git hosting - MS-DOS.git/blob - v4.0/src/DOS/HANDLE.ASM

wirehaze git hosting

MZ is back!
[MS-DOS.git] / v4.0 / src / DOS / HANDLE.ASM
1 ; SCCSID = @(#)handle.asm 1.1 85/04/10
2 TITLE HANDLE - Handle-related system calls
3 NAME 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 ;
34 include dosseg.asm
35
36 CODE SEGMENT BYTE PUBLIC 'CODE'
37 ASSUME SS:DOSGROUP,CS:DOSGROUP
38
39 .xcref
40 INCLUDE DOSSYM.INC
41 INCLUDE DEVSYM.INC
42 include EA.inc
43 include version.inc
44 .cref
45 .list
46 .sall
47
48 EXTRN DOS_Read:NEAR, DOS_Write:NEAR
49
50 IF BUFFERFLAG
51 extrn save_user_map:near
52 extrn restore_user_map:near
53 extrn Setup_EMS_Buffers:near
54 ENDIF
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
75 IF 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
86 ENDIF
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
91 if debug
92 I_need BugLev,WORD
93 I_need BugTyp,WORD
94 include bugtyp.asm
95 endif
96
97 BREAK <$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
110 Procedure $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 ;
141 FreeJFN:
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
145 PostFree:
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
158 CloseError:
159 ASSUME DS:NOTHING
160 fmt TypSysCall,LevLog,<"$p: Close error $x\n">,<AX>
161 transfer Sys_Ret_Err
162 EndProc $Close
163
164 BREAK <$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
177 Procedure $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
199 Commiterror:
200 ASSUME DS:NOTHING
201 transfer Sys_Ret_Err
202 EndProc $Commit
203
204
205 BREAK <$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
218 Procedure $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
228 getpdb:
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
239 chck_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
252 larger:
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
269 movhandl:
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
277 ok_done:
278 transfer Sys_Ret_OK
279 too_many_files:
280 MOV AL,error_too_many_open_files
281 transfer Sys_Ret_Err
282 enlarge:
283 MOV CX,DS:[PDB_JFN_Length] ; get number of old handles
284 copy_hand:
285 MOV DX,CX
286 LDS SI,DS:[PDB_JFN_Pointer] ; get old table pointer
287 ASSUME 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
308 update_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
313 non_psp:
314 MOV WORD PTR DS:[PDB_JFN_Pointer],0 ; new table pointer offset always 0
315 final:
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
319 no_memory:
320 POP BX ; clean stack
321 MOV AL,error_not_enough_memory
322 transfer Sys_Ret_Err
323 invalid_func:
324 MOV AL,error_invalid_function
325 transfer Sys_Ret_Err
326 EndProc $ExtHandle
327
328 BREAK <$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
343 procedure $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
348 ReadDo:
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
354 ReadError:
355 fmt TypSysCall,LevLog,<"Read/Write error $x\n">,<AX>
356 transfer SYS_RET_ERR ; go to error traps
357 ReadSetup:
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
364 needi24: ;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
372 IF 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:
382 ENDIF
383 context DS ; go for DOS addressability
384 CALL SI ; indirect call to operation
385 RestoreReg <<WORD PTR [DMAAdd+2]>, <WORD PTR [DMAAdd]>>
386
387 IF 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
405 dos_call_done:
406 pop bx
407 pop ax
408 popf
409 ENDIF
410
411 IF NOT BUFFERFLAG
412 JC ReadError ; if error, say bye bye
413 ELSE
414 jmp tmp_rerr
415 tmp_rerr:
416 jc ReadError
417 ENDIF
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
422 EndProc $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
431 procedure 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;
445 EndProc Align_Buffer ;AN000;
446
447 BREAK <$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
463 procedure $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
469 EndProc $Write
470
471 BREAK <$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
487 procedure $LSEEK,NEAR
488 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP
489 call CheckOwner ; get system file entry
490 LSeekError:
491
492 IF BUFFERFLAG
493 JC TMP_RERR
494 ELSE
495 JC ReadError ; error return
496 ENDIF
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
501 LSeekDisp:
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]
507 LSeekStore:
508 MOV AX,CX ; AX:DX
509 XCHG AX,DX ; DX:AX is the correct value
510 LSeekSetpos:
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
517 LSeekEOF:
518 TEST ES:[DI.sf_flags],sf_isnet
519 JNZ Check_LSeek_Mode ; Is Net
520 LOCAL_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
525 Check_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
534 NET_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
541 EndProc $LSeek
542
543 BREAK <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
580 procedure $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;
586 gsetxa: ;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
590 funcerr: ;AN000;
591 JMP inval_func ;AN000;;FT. invalid function
592 ;AN000;
593 gshandle: ;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;
607 getsetit: ;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
613 nomask: ;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.
619 IFSsearch: ;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.
624 localhandle: ;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
629 getsetfile8: ;AN000;
630 ; MOV [XA_device],0 ;AN000;;FT. indicating File
631 ; LES BP,ES:[DI.sf_devptr] ;AN000;;FT. ES:BP -> DPB
632
633 doXA: ;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
653 getexit: ;AN000;;FT.
654 LeaveCrit critSFT ;AN000;;FT. leave critical section
655
656
657 getseterror: ;AN000;
658 transfer SYS_RET_ERR ;AN000;;FT. mark file as dirty
659 inval_func:
660
661 ;;;;; DOS 4.00
662 MOV EXTERR_LOCUS,errLoc_Unk ; Extended Error Locus
663 error error_invalid_function ; give bad return
664 filetimes_ok:
665 call CheckOwner ; get sf pointer
666 JNC gsdt
667 JMP LSeekError ; turkey handle
668 gsdt:
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
678 ext_done:
679 transfer SYS_RET_OK ; and say goodnight
680 filetimes_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
685 do_share:
686 if installed
687 Call JShare + 14 * 4
688 else
689 Call ShSU
690 endif
691 datetimeflg:
692 AND ES:[DI.sf_Flags],NOT devid_file_clean
693 OR ES:[DI.sf_Flags],sf_close_nodate
694 ftok:
695 LeaveCrit critSFT
696 transfer SYS_RET_OK ; mark file as dirty and return
697 EndProc $File_Times
698
699 BREAK <$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
709 Procedure $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
713 DupErrorCheck:
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
725 DupErr: transfer SYS_RET_ERR
726
727 EndProc $Dup
728
729 BREAK <$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 ;
739 Procedure $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
747 EndProc $Dup2
748
749 Break <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
766 Procedure 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
778 EndProc 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
891 CODE ENDS
892 END
893 \1a