summaryrefslogtreecommitdiff
path: root/v4.0/src/DOS/MKNODE.ASM
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--v4.0/src/DOS/MKNODE.ASM890
1 files changed, 890 insertions, 0 deletions
diff --git a/v4.0/src/DOS/MKNODE.ASM b/v4.0/src/DOS/MKNODE.ASM
new file mode 100644
index 0000000..968c8eb
--- /dev/null
+++ b/v4.0/src/DOS/MKNODE.ASM
@@ -0,0 +1,890 @@
1; SCCSID = @(#)mknode.asm 1.5 85/08/29
2TITLE MKNODE - Node maker
3NAME MKNODE
4; Low level routines for making a new local file system node
5; and filling in an SFT from a directory entry
6;
7; BUILDDIR
8; SETDOTENT
9; MakeNode
10; NEWENTRY
11; FREEENT
12; NEWDIR
13; DOOPEN
14; RENAME_MAKE
15; CHECK_VIRT_OPEN
16;
17; Revision history:
18;
19; AN000 version 4.0 Jan. 1988
20; A004 PTM 3680 --- Make SFT NAME field offset same as 3.30
21
22;
23; get the appropriate segment definitions
24;
25.xlist
26include dosseg.asm
27include fastopen.inc
28
29CODE SEGMENT BYTE PUBLIC 'CODE'
30 ASSUME SS:DOSGROUP,CS:DOSGROUP
31
32.xcref
33include dossym.inc
34include devsym.inc
35.cref
36.list
37
38 i_need EntFree,WORD
39 i_need DirStart,WORD
40 i_need LastEnt,WORD
41 i_need ClusNum,WORD
42 i_need CurBuf,DWORD
43 i_need Attrib,BYTE
44 i_need VolID,BYTE
45 i_need Name1,BYTE
46 i_need ThisDPB,DWORD
47 i_need EntLast,WORD
48 i_need Creating,BYTE
49 i_need SecClusPos,BYTE
50 i_need ClusFac,BYTE
51 i_need NxtClusNum,WORD
52 i_need DirSec,WORD
53 i_need NoSetDir,BYTE
54 i_need THISSFT,DWORD
55 i_need SATTRIB,BYTE
56 i_need ALLOWED,BYTE
57 i_need FAILERR,BYTE
58 i_need VIRTUAL_OPEN
59 I_need FastOpen_Ext_info,BYTE ; DOS 3.3
60 I_need FastOpenFlg,BYTE ; DOS 3.3
61 I_need CPSWFLAG,BYTE ;FT. DOS 3.4 ;AN000;
62 I_need EXTOPEN_ON,BYTE ;FT. DOS 3.4 ;AN000;
63 I_need EXTOPEN_FLAG,WORD ;FT. DOS 3.4 ;AN000;
64 I_need EXTOPEN_IO_MODE,WORD ;FT. DOS 3.4 ;AN000;
65 I_need HIGH_SECTOR,WORD ;>32mb ;AN000;
66 I_need ACT_PAGE,WORD ;>32mb ;AN000;
67
68Break <BUILDDIR,NEWDIR -- ALLOCATE DIRECTORIES>
69
70; Inputs:
71; ES:BP Points to DPB
72; [THISSFT] Set if using NEWDIR entry point
73; (used by ALLOCATE)
74; [LASTENT] current last valid entry number in directory if no free
75; entries
76; [DIRSTART] Points to first cluster of dir (0 means root)
77; Function:
78; Grow directory if no free entries and not root
79; Outputs:
80; CARRY SET IF FAILURE
81; ELSE
82; AX entry number of new entry
83; If a new dir [DIRSTART],[CLUSFAC],[CLUSNUM],[DIRSEC] set
84; AX = first entry of new dir
85; GETENT should be called to set [LASTENT]
86
87 procedure BUILDDIR,NEAR
88 DOSAssume CS,<DS>,"BuildDir"
89 ASSUME ES:NOTHING
90
91 MOV AX,[ENTFREE]
92 CMP AX,-1
93 JZ CHECK_IF_ROOT
94 CLC
95 return
96
97CHECK_IF_ROOT:
98 CMP [DIRSTART],0
99 JNZ NEWDIR
100 STC
101 return ; Can't grow root
102
103 entry NEWDIR
104 MOV BX,[DIRSTART]
105 OR BX,BX
106 JZ NULLDIR
107 invoke GETEOF
108 retc ; Screw up
109NULLDIR:
110 MOV CX,1
111 invoke ALLOCATE
112 retc
113 MOV DX,[DIRSTART]
114 OR DX,DX
115 JNZ ADDINGDIR
116 invoke SETDIRSRCH
117 retc
118 MOV [LASTENT],-1
119 JMP SHORT GOTDIRREC
120ADDINGDIR:
121 PUSH BX
122 MOV BX,[ClusNum]
123 Invoke IsEof
124 POP BX
125 JB NOTFIRSTGROW
126;;;; 10/17/86 update CLUSNUM in the fastopen cache
127 MOV [CLUSNUM],BX
128 PUSH CX
129 PUSH AX
130 PUSH BP
131 MOV AH,1 ; CLUSNUM update
132 MOV DL,ES:[BP.dpb_drive] ; drive #
133 MOV CX,[DIRSTART] ; first cluster #
134 MOV BP,BX ; CLUSNUM
135 invoke FastOpen_Update
136 POP BP
137 POP AX
138 POP CX
139
140;;;; 10/17/86 update CLUSNUM in the fastopen cache
141NOTFIRSTGROW:
142 MOV DX,BX
143 XOR BL,BL
144 invoke FIGREC
145GOTDIRREC:
146 MOV CL,ES:[BP.dpb_cluster_mask]
147 INC CL
148 XOR CH,CH
149ZERODIR:
150 PUSH CX
151 MOV [ALLOWED],allowed_FAIL + allowed_RETRY
152 MOV AL,0FFH
153 invoke GETBUFFR
154 JNC GET_SSIZE
155 POP CX
156 return
157
158GET_SSIZE:
159 MOV CX,ES:[BP.dpb_sector_size]
160 PUSH ES
161 LES DI,[CURBUF]
162 OR ES:[DI.buf_flags],buf_isDIR
163 PUSH DI
164 ADD DI,BUFINSIZ
165 XOR AX,AX
166 SHR CX,1
167 REP STOSW
168 JNC EVENZ
169 STOSB
170EVENZ:
171 POP DI
172
173 TEST ES:[DI.buf_flags],buf_dirty ;LB. if already dirty ;AN000;
174 JNZ yesdirty ;LB. don't increment dirty count ;AN000;
175 invoke INC_DIRTY_COUNT ;LB. ;AN000;
176 OR ES:[DI.buf_flags],buf_dirty
177yesdirty:
178 POP ES
179 POP CX
180 INC DX
181 LOOP ZERODIR
182 MOV AX,[LASTENT]
183 INC AX
184 CLC
185 return
186
187EndProc BUILDDIR
188
189;
190; set up a . or .. directory entry for a directory.
191;
192; Inputs: ES:DI point to the beginning of a directory entry.
193; AX contains ". " or ".."
194; DX contains first cluster of entry
195;
196 procedure SETDOTENT,NEAR
197 DOSAssume CS,<DS>,"SetDotEnt"
198;
199; Fill in name field
200;
201 STOSW
202 MOV CX,4
203 MOV AX," "
204 REP STOSW
205 STOSB
206;
207; Set up attribute
208;
209 MOV AL,attr_directory
210 errnz dir_attr-(dir_name+11)
211 STOSB
212;
213; Initialize time and date of creation
214;
215 ADD DI,10
216 MOV SI,WORD PTR [THISSFT]
217 MOV AX,[SI.sf_time]
218 errnz dir_time-(dir_attr+1+10)
219 STOSW
220 MOV AX,[SI.sf_date]
221 errnz dir_date-(dir_time+2)
222 STOSW
223;
224; Set up first cluster field
225;
226 MOV AX,DX
227 errnz dir_first-(dir_date+2)
228 STOSW
229;
230; 0 file size
231;
232 XOR AX,AX
233 errnz dir_size_l-(dir_first+2)
234 STOSW
235 STOSW
236 errnz <(size dir_entry)-(dir_size_l+4)>
237 return
238EndProc SETDOTENT
239
240Break <MAKENODE -- CREATE A NEW NODE>
241
242; Inputs:
243; AL - attribute to create
244; AH = 0 if it is ok to truncate a file already by this name
245; AH = Non 0 if this is an error
246; (AH ignored on dirs and devices)
247; NOTE: When making a DIR or volume ID, AH need not be set since
248; a name already existant is ALWAYS an error in these cases.
249; [WFP_START] Points to WFP string ("d:/" must be first 3 chars, NUL
250; terminated)
251; [CURR_DIR_END] Points to end of Current dir part of string
252; ( = -1 if current dir not involved, else
253; Points to first char after last "/" of current dir part)
254; [THISCDS] Points to CDS being used
255; [THISSFT] Points to an empty SFT. EXCEPT sf_mode filled in.
256; Function:
257; Make a new node
258; Outputs:
259; Sets EXTERR_LOCUS = errLOC_Disk or errLOC_Unk via GetPathNoset
260; CARRY SET IF ERROR
261; AX = 1 A node by this name exists and is a directory
262; AX = 2 A new node could not be created
263; AX = 3 A node by this name exists and is a disk file
264; (AH was NZ on input)
265; AX = 4 Bad Path
266; SI return from GetPath maintained
267; AX = 5 Attribute mismatch
268; AX = 6 Sharing Violation
269; (INT 24 generated ALWAYS since create is always compat mode
270; AX = 7 file not found for Extended Open (not exists and fails)
271; ELSE
272; AX = 0 Disk Node
273; AX = 3 Device Node (error in some cases)
274; [DIRSTART],[DIRSEC],[CLUSFAC],[CLUSNUM] set to directory
275; containing new node.
276; [CURBUF+2]:BX Points to entry
277; [CURBUF+2]:SI Points to entry.dir_first
278; [THISSFT] is filled in
279; sf_mode = unchanged.
280; Attribute byte in entry is input AL
281; DS preserved, others destroyed
282
283 procedure MakeNode,NEAR
284 DOSAssume CS,<DS>,"MakeNode"
285 ASSUME ES:NOTHING
286
287 MOV WORD PTR [CREATING],0E5FFH ; Creating, not DEL *.*
288 PUSH AX ; Save AH value
289 MOV [NoSetDir],0
290 MOV [SATTRIB],AL
291 invoke GetPathNoSet
292 MOV DL,CL ; Save CL info
293 MOV CX,AX ; Device ID to CH
294 POP AX ; Get back AH
295 JNC make_exists ; File existed
296 JNZ make_err_4 ; Path bad
297 CMP DL,80H ; Check "CL" return from GETPATH
298 JZ make_type ; Name simply not found, and no metas
299make_err_4:
300 MOV AL,4 ; case 1 bad path
301make_err_ret:
302 XOR AH,AH
303 STC
304 return
305
306 entry RENAME_MAKE ; Used by DOS_RENAME to "copy" a node
307
308make_type:
309;Extended Open hooks
310 TEST [EXTOPEN_ON],ext_open_on ;FT. from extended open ;AN000;
311 JZ make_type2 ;FT. no ;AN000;
312 OR [EXTOPEN_ON],ext_file_not_exists ;FT. set for extended open ;AN000;
313 TEST [EXTOPEN_FLAG],0F0H ;FT. not exists and fails ;AN000;
314 JNZ make_type2 ;FT. no ;AN000;
315 STC ;FT. set carry ;AN000;
316 MOV AX,7 ;FT. file not found ;AN000;
317 return ;FT. ;AN000;
318make_type2:
319;Extended Open hooks
320 LES DI,[THISSFT]
321; MOV ES:[DI.sf_mode],sharing_compat + open_for_both
322 XOR AX,AX ; nothing exists Disk Node
323 STC ; Not found
324 JMP make_new
325
326;
327; The node exists. It may be either a device, directory or file:
328; Zero set => directory
329; High bit of CH on => device
330; else => file
331make_exists:
332 JZ make_exists_dir
333 MOV AL,3 ; file exists type 3 (error or device node)
334 TEST BYTE PTR [ATTRIB],(attr_volume_id+attr_directory)
335 JNZ make_err_ret_5 ; Cannot already exist as Disk or Device Node
336 ; if making DIR or Volume ID
337 OR CH,CH
338 JS make_share ; No further checks on attributes if device
339 OR AH,AH
340 JNZ make_err_ret ; truncating NOT OK (AL = 3)
341 PUSH CX ; Save device ID
342 MOV ES,WORD PTR [CURBUF+2]
343 MOV CH,ES:[BX+dir_attr] ; Get file attributes
344 TEST CH,attr_read_only
345 JNZ make_err_ret_5P ; Cannot create on read only files
346 invoke MatchAttributes
347 POP CX ; Devid back in CH
348 JNZ make_err_ret_5 ; Attributes not ok
349 XOR AL,AL ; AL = 0, Disk Node
350make_share:
351 XOR AH,AH
352 PUSH AX ; Save Disk or Device node
353 PUSH CX ; Save Device ID
354 MOV AH,CH ; Device ID to AH
355 CALL DOOPEN ; Fill in SFT for share check
356 LES DI,[THISSFT]
357; MOV ES:[DI.sf_mode],sharing_compat + open_for_both
358 SaveReg <SI,BX> ; Save CURBUF pointers
359 invoke ShareEnter
360 jnc MakeEndShare
361;
362; User failed request.
363;
364 RestoreReg <BX,SI,CX,AX>
365Make_Share_ret:
366 MOV AL,6
367 JMP make_err_ret
368
369make_err_ret_5P:
370 POP CX ; Get back device ID
371make_err_ret_5:
372 MOV AL,5 ; Attribute mismatch
373 JMP make_err_ret
374
375make_exists_dir:
376 MOV AL,1 ; exists as directory, always an error
377 JMP make_err_ret
378
379make_save:
380 PUSH AX ; Save whether Disk or File
381 MOV AX,CX ; Device ID to AH
382 CALL NewEntry
383 POP AX ; 0 if Disk, 3 if File
384 retnc
385 MOV AL,2 ; create failed case 2
386 return
387
388make_new:
389 call make_save
390 retc ; case 2 fail
391 TEST BYTE PTR [ATTRIB],attr_directory
392 retnz ; Don't "open" directories, so don't
393 ; tell the sharer about them
394 SaveReg <AX,BX,SI> ; Save AL code
395 invoke ShareEnter
396 RestoreReg <SI,BX,AX>
397 retnc
398;
399; We get here by having the user FAIL a share problem. Typically a failure of
400; this nature is an out-of-space or an internal error. We clean up as best as
401; possible: delete the newly created directory entry and return share_error.
402;
403 PUSH AX
404 LES DI,CurBuf
405 MOV BYTE PTR ES:[BX],0E5H ; nuke newly created entry.
406
407 TEST ES:[DI.buf_flags],buf_dirty ;LB. if already dirty ;AN000;
408 JNZ yesdirty2 ;LB. don't increment dirty count ;AN000;
409 invoke INC_DIRTY_COUNT ;LB. ;AN000;
410 OR ES:[DI].buf_flags,buf_dirty ; flag buffer as dirty
411yesdirty2:
412 LES BP,ThisDPB
413 MOV AL,ES:[BP].DPB_Drive ; get drive for flush
414 Invoke FlushBuf ; write out buffer.
415 POP AX
416 jmp make_Share_ret
417;
418; We have found an existing file. We have also entered it into the share set.
419; At this point we need to call newentry to correctly address the problem of
420; getting rid of old data (create an existing file) or creating a new
421; directory entry (create a new file). Unfortunately, this operation may
422; result in an INT 24 that the user doesn't return from, thus locking the file
423; irretrievably into the share set. The correct solution is for us to LEAVE
424; the share set now, do the operation and then reassert the share access.
425;
426; We are allowed to do this! There is no window! After all, we are in
427; critDisk here and for someone else to get in, they must enter critDisk also.
428;
429MakeEndShare:
430 LES DI,ThisSFT ; grab SFT
431 XOR AX,AX
432 EnterCrit critSFT
433 XCHG AX,ES:[DI].sf_ref_count
434 SaveReg <AX,DI,ES>
435 PUSHF
436 invoke ShareEnd ; remove sharing
437 POPF
438 RestoreReg <ES,DI,ES:[DI].sf_ref_count>
439 LeaveCrit critSFT
440 RestoreReg <BX,SI,CX,AX>
441 CALL make_save
442;
443; If the user failed, we do not reenter into the sharing set.
444;
445 retc ; bye if error
446 SaveReg <AX,BX,SI>
447 PUSHF
448 invoke ShareEnter
449 POPF
450 RestoreReg <SI,BX,AX>
451;
452; If Share_check fails, then we have an internal ERROR!!!!!
453;
454 return
455EndProc MakeNode
456
457; Inputs:
458; [THISSFT] set
459; [THISDPB] set
460; [LASTENT] current last valid entry number in directory if no free
461; entries
462; [VOLID] set if a volume ID was found during search
463; [ATTRIB] Contains attributes for new file
464; [DIRSTART] Points to first cluster of dir (0 means root)
465; CARRY FLAG INDICATES STATUS OF SEARCH FOR FILE
466; NC means file existed (device)
467; C means file did not exist
468; AH = Device ID byte
469; If FILE
470; [CURBUF+2]:BX points to start of directory entry
471; [CURBUF+2]:SI points to dir_first of directory entry
472; If device
473; DS:BX points to start of "fake" directory entry
474; DS:SI points to dir_first of "fake" directory entry
475; (has DWORD pointer to device header)
476; Function:
477; Make a new directory entry
478; If an old one existed it is truncated first
479; Outputs:
480; Carry set if error
481; Can't grow dir, atts didn't match, attempt to make 2nd
482; vol ID, user FAILed to I 24
483; else
484; outputs of DOOPEN
485; DS, BX, SI preserved (meaning on SI BX, not value), others destroyed
486
487 procedure NEWENTRY,NEAR
488 DOSAssume CS,<DS>,"NewEntry"
489 ASSUME ES:NOTHING
490
491 LES BP,[THISDPB]
492ASSUME ES:NOTHING
493 JNC EXISTENT
494 CMP [FAILERR],0
495 STC
496 retnz ; User FAILed, node might exist
497 CALL BUILDDIR ; Try to build dir
498 retc ; Failed
499 invoke GETENT ; Point at that free entry
500 retc ; Failed
501 JMP SHORT FREESPOT
502
503ERRRET3:
504 STC
505 return
506
507EXISTENT:
508 DOSAssume CS,<DS>,"MKNODE/ExistEnt"
509 OR AH,AH ; Check if file is I/O device
510 JNS NOT_DEV1
511 JMP DOOPEN ; If so, proceed with open
512
513NOT_DEV1:
514 invoke FREEENT ; Free cluster chain
515 retc ; Failed
516FREESPOT:
517 TEST BYTE PTR [ATTRIB],attr_volume_id
518 JZ NOTVOLID
519 CMP BYTE PTR [VOLID],0
520 JNZ ERRRET3 ; Can't create a second volume ID
521NOTVOLID:
522 MOV ES,WORD PTR [CURBUF+2]
523 MOV DI,BX
524 MOV SI,OFFSET DOSGROUP:NAME1
525 MOV CX,5
526 REP MOVSW
527 MOVSB ; Move name into dir entry
528 MOV AL,[ATTRIB]
529 errnz dir_attr-(dir_name+11)
530 STOSB ; Attributes
531;; File Tagging for Create DOS 4.00
532 MOV CL,5 ;FT. assume normal ;AN000;
533; CMP [CPSWFLAG],0 ;FT. code page matching on ;AN000;
534; JZ NORMFT ;FT. no, make null code page ;AN000;
535; invoke Get_Global_CdPg ;FT. get global code page ;AN000;
536; STOSW ;FT. tag this file with global code page ;AN000;
537; DEC CL ;FT. only 4 ;AN000;
538;NORMFT: ;FT. ;AN000;
539
540;; File Tagging for Create DOS 4.00
541 XOR AX,AX
542 REP STOSW ; Zero pad
543 invoke DATE16
544 XCHG AX,DX
545 errnz dir_time-(dir_attr+1+2*5)
546 STOSW ; dir_time
547 XCHG AX,DX
548 errnz dir_date-(dir_time+2)
549 STOSW ; dir_date
550 XOR AX,AX
551 PUSH DI ; Correct SI input value (recomputed for new buffer)
552
553 errnz dir_first-(dir_date+2)
554 STOSW ; Zero dir_first and size
555 errnz dir_size_l-(dir_first+2)
556 STOSW
557 STOSW
558updnxt:
559 errnz <(size dir_entry)-(dir_size_l+4)>
560 MOV SI,WORD PTR [CURBUF]
561
562 TEST ES:[SI.buf_flags],buf_dirty ;LB. if already dirty ;AN000;
563 JNZ yesdirty3 ;LB. don't increment dirty count ;AN000;
564 invoke INC_DIRTY_COUNT ;LB. ;AN000;
565 OR ES:[SI.buf_flags],buf_dirty
566yesdirty3:
567 LES BP,[THISDPB]
568 MOV AL,ES:[BP.dpb_drive] ; Sets AH value again (in AL)
569 PUSH AX
570 PUSH BX
571; If we have a file, we need to increment the open ref. count so that
572; we have some protection against invalid media changes if an Int 24
573; error occurs.
574; Do nothing for a device.
575 SaveReg <ES,DI>
576 LES DI,[THISSFT]
577 test es:[di.sf_flags],devid_device
578 jnz GotADevice
579 SaveReg <DS,BX>
580 LDS BX,[THISDPB]
581 MOV word ptr ES:[DI.sf_devptr],BX
582 MOV BX,DS
583 MOV word ptr ES:[DI.sf_devptr+2],BX
584 RestoreReg <BX,DS> ; need to use DS for segment later on
585 invoke Dev_Open_SFT ; increment ref. count
586 mov [VIRTUAL_OPEN],1; set flag
587GotADevice:
588 RestoreReg <DI,ES>
589
590 PUSH [ACT_PAGE] ;LB. save EMS page for curbuf ;AN000;
591 invoke FLUSHBUF
592 POP BX ;LB. restore EMS page for curbuf ;AN000;
593 PUSHF ;LB. save flushbuf falg ;AN000;
594 CMP BX,-1 ;BL-NETWORK PTM #-?
595 JE Page_ok ;BL-NETWORK PTM #-?
596 invoke SET_MAP_PAGE ;LB. remap curbuf ;AN000;
597Page_ok: ;BL-NETWORK PTM #-?
598 POPF ;LB. restore flush flag ;AN000;
599 Call CHECK_VIRT_OPEN ; decrement ref. count ;AN000;
600 POP BX
601 POP AX
602 POP SI ; Get SI input back
603 MOV AH,AL ; Get I/O driver number back
604 retc ; Failed
605
606
607;NOTE FALL THROUGH
608
609; Inputs:
610; [THISDPB] points to DPB if file
611; [THISSFT] points to SFT being used
612; AH = Device ID byte
613; If FILE
614; [CURBUF+2]:BX points to start of directory entry
615; [CURBUF+2]:SI points to dir_first of directory entry
616; If device
617; DS:BX points to start of "fake" directory entry
618; DS:SI points to dir_first of "fake" directory entry
619; (has DWORD pointer to device header)
620; Function:
621; Fill in SFT from dir entry
622; Outputs:
623; CARRY CLEAR
624; sf_ref_count and sf_mode fields not altered
625; sf_flags high byte = 0
626; sf_flags low byte = AH except
627; sf_flags Bit 6 set (not dirty or not EOF)
628; sf_attr sf_date sf_time sf_name set from entry
629; sf_position = 0
630; If device
631; sf_devptr = dword at dir_first (pointer to device header)
632; sf_size = 0
633; If file
634; sf_firclus sf_size set from entry
635; sf_devptr = [THISDPB]
636; sf_cluspos = 0
637; sf_lstclus = sf_firclus
638; sf_dirsec sf_dirpos set
639; DS,SI,BX preserved, others destroyed
640
641 entry DOOPEN
642 DOSAssume CS,<DS>,"DoOpen"
643 ASSUME ES:NOTHING
644
645;
646; Generate and store attribute
647;
648 MOV DH,AH ; AH to different place
649 LES DI,[THISSFT]
650 ADD DI,sf_attr ; Skip ref_count and mode fields
651 XOR AL,AL ; Assume it's a device, devices have an
652 ; attribute of 0 (for R/O testing etc).
653 OR DH,DH ; See if our assumption good.
654 JS DEV_SFT1 ; If device DS=DOSGROUP
655 MOV DS,WORD PTR [CURBUF+2]
656ASSUME DS:NOTHING
657 MOV AL,[BX.dir_attr] ; If file, get attrib from dir entry
658DEV_SFT1:
659 STOSB ; sf_attr, ES:DI -> sf_flags
660;
661; Generate and store flags word
662;
663 XOR AX,AX
664 MOV AL,DH
665 OR AL,devid_file_clean
666 STOSW ; sf_flags, ES:DI -> sf_devptr
667;
668; Generate and store device pointer
669;
670 PUSH DS
671 LDS AX,DWORD PTR [BX.dir_first] ; Assume device
672 OR DH,DH
673 JS DEV_SFT2
674 LDS AX,[THISDPB] ; Was file
675DEV_SFT2:
676 STOSW ; store offset
677 MOV AX,DS
678 POP DS
679 STOSW ; store segment
680 ; ES:DI -> sf_firclus
681;
682; Generate pointer to, generate and store first cluster (irrelevant for
683; devices)
684;
685 PUSH SI ; Save pointer to dir_first
686 MOVSW ; dir_first -> sf_firclus
687 ; DS:SI -> dir_size_l, ES:DI -> sf_time
688;
689; Copy time/date of last modification
690;
691 SUB SI,dir_size_l - dir_time ; DS:SI->dir_time
692 MOVSW ; dir_time -> sf_time
693 ; DS:SI -> dir_date, ES:DI -> sf_date
694 MOVSW ; dir_date -> sf_date
695 ; DS:SI -> dir_first, ES:DI -> sf_size
696;
697; Generate and store file size (0 for devices)
698;
699 LODSW ; skip dir_first, DS:SI -> dir_size_l
700 LODSW ; dir_size_l in AX , DS:SI -> dir_size_h
701 MOV CX,AX ; dir_size_l in CX
702 LODSW ; dir_size_h (size AX:CX), DS:SI -> ????
703 OR DH,DH
704 JNS FILE_SFT1
705 XOR AX,AX
706 MOV CX,AX ; Devices are open ended
707FILE_SFT1:
708 XCHG AX,CX
709 STOSW ; Low word of sf_size
710 XCHG AX,CX
711 STOSW ; High word of sf_size
712 ; ES:DI -> sf_position
713;
714; Initialize position to 0
715;
716 XOR AX,AX
717 STOSW
718 STOSW ; sf_position
719 ; ES:DI -> sf_cluspos
720;
721; Generate cluster optimizations for files
722;
723 OR DH,DH
724 JS DEV_SFT3
725 STOSW ; sf_cluspos
726 MOV AX,[BX.dir_first]
727;;;; STOSW ; sf_lstclus
728 PUSH DI ;AN004; save dirsec offset
729 SUB DI,sf_dirsec ;AN004; es:di -> SFT
730 MOV ES:[DI.sf_lstclus],AX ;AN004; save it
731 POP DI ;AN004; restore dirsec offset
732
733
734
735; DOS 3.3 FastOpen 6/13/86
736
737 PUSH DS
738 context DS
739 TEST [FastOpenFlg],Special_Fill_Set
740 JZ Not_FastOpen
741 MOV SI,OFFSET DOSGROUP:FastOpen_Ext_Info
742 MOV AX,WORD PTR [SI.FEI_dirsec]
743 STOSW ; sf_dirsec
744 MOV AX,WORD PTR [SI.FEI_dirsec+2] ;;; changed for >32mb
745 STOSW ; sf_dirsec
746 MOV AL,[SI.FEI_dirpos]
747 STOSB ; sf_dirpos
748 POP DS
749 JMP Next_Name
750
751; DOS 3.3 FastOpen 6/13/86
752
753Not_FastOpen:
754 POP DS ; normal path
755ASSUME DS:NOTHING
756 MOV SI,WORD PTR [CURBUF] ; DS:SI->buffer header
757 MOV AX,WORD PTR [SI.buf_sector] ;F.C. >32mb ;AN000;
758 STOSW ; sf_dirsec ;F.C. >32mb ;AN000;
759 MOV AX,WORD PTR [SI.buf_sector+2] ;F.C. >32mb ;AN000;
760 STOSW ; sf_dirsec ;F.C. >32mb ;AN000;
761 MOV AX,BX
762 ADD SI,BUFINSIZ ; DS:SI-> start of data in buffer
763 SUB AX,SI ; AX = BX relative to start of sector
764 MOV CL,SIZE dir_entry
765 DIV CL
766 STOSB ; sf_dirpos
767
768Next_Name:
769 errnz sf_name-(sf_dirpos+1)
770 JMP SHORT FILE_SFT2
771
772DEV_SFT3:
773 ADD DI,sf_name - sf_cluspos
774FILE_SFT2:
775;
776; Copy in the object's name
777;
778 MOV SI,BX ; DS:SI points to dir_name
779 MOV CX,11
780 REP MOVSB ; sf_name
781 POP SI ; recover DS:SI -> dir_first
782;; File tagging , code page and XA cluster must be after name
783; MOV AX,[BX.dir_CODEPG] ;FT. set file's code page ;AN000;
784; STOSW ;FT. ;AN000;
785; MOV AX,[BX.dir_EXTCLUSTER] ;FT. set XA cluster ;AN000;
786; STOSW ;FT. ;AN000;
787; MOV AX,[EXTOPEN_IO_MODE] ;FT. extended open ;AN000;
788; STOSW ;FT. ;AN000;
789; MOV AL,[BX.dir_attr2] ;FT. high attribute ;AN000;
790; STOSB ;FT. ;AN000;
791
792;; File tagging , code page and XA cluster must be after name
793
794 context DS
795 CLC
796 return
797
798EndProc NEWENTRY
799
800; Inputs:
801; ES:BP -> DPB
802; [CURBUF] Set
803; [CURBUF+2]:BX points to directory entry
804; [CURBUF+2]:SI points to above dir_first
805; Function:
806; Free the cluster chain for the entry if present
807; Outputs:
808; Carry set if error (currently user FAILed to I 24)
809; (NOTE dir_firclus and dir_size_l/h are wrong)
810; DS BX SI ES BP preserved (BX,SI in meaning, not value) others destroyed
811
812 procedure FREEENT,NEAR
813 DOSAssume CS,<DS>,"FreeEnt"
814 ASSUME ES:NOTHING
815
816 PUSH DS
817 LDS DI,[CURBUF]
818ASSUME DS:NOTHING
819 MOV CX,[SI] ; Get pointer to clusters
820 MOV DX,WORD PTR [DI.buf_sector+2] ;F.C. >32mb ;AN000;
821 MOV [HIGH_SECTOR],DX ;F.C. >32mb ;AN000;
822 MOV DX,WORD PTR [DI.buf_sector]
823 POP DS
824 DOSAssume CS,<DS>,"MKNODE/FreeEnt"
825 CMP CX,2
826 JB RET1 ; Was 0 length file (or mucked Firclus if CX=1)
827 CMP CX,ES:[BP.dpb_max_cluster]
828 JA RET1 ; Treat like zero length file (firclus mucked)
829 SUB BX,DI
830 PUSH BX ; Save offset
831 PUSH [HIGH_SECTOR] ;F.C. >32mb ;AN000;
832 PUSH DX ; Save sector number
833
834 MOV BX,CX
835 invoke Delete_FSeek ; FS. delete Fastseek Clusters ;AN000;
836 invoke RELEASE ; Free any data allocated
837 POP DX
838 POP [HIGH_SECTOR] ;F.C. >32mb ;AN000;
839 JNC GET_BUF_BACK
840 POP BX
841 return ; Screw up
842
843GET_BUF_BACK:
844
845 MOV [ALLOWED],allowed_RETRY + allowed_FAIL
846 XOR AL,AL
847 invoke GETBUFFR ; Get sector back
848 POP BX ; Get offset back
849 retc
850 invoke SET_BUF_AS_DIR
851 ADD BX,WORD PTR [CURBUF] ; Correct it for new buffer
852 MOV SI,BX
853 ADD SI,dir_first ; Get corrected SI
854RET1:
855 CLC
856 return
857EndProc FREEENT
858
859;
860; CHECK_VIRT_OPEN checks to see if we had performed a "virtual open" (by
861; examining the flag [VIRTUAL_OPEN] to see if it is 1). If we did, then
862; it calls Dev_Close_SFT to decrement the ref. count. It also resets the
863; flag [VIRTUAL_OPEN].
864; No registers affected (including flags).
865; On input, [THISSFT] points to current SFT.
866;
867 Procedure CHECK_VIRT_OPEN,NEAR
868 DOSAssume CS,<DS>,"Check_Virt_Open"
869
870 PUSH AX
871 lahf ; preserve flags
872 CMP [VIRTUAL_OPEN],0
873 JZ ALL_CLOSED
874 mov [VIRTUAL_OPEN],0 ; reset flag
875 SaveReg <ES,DI>
876 LES DI,[THISSFT]
877 INVOKE DEV_CLOSE_SFT
878 RestoreReg <DI,ES>
879
880ALL_CLOSED:
881 sahf ; restore flags
882 POP AX
883 return
884
885EndProc CHECK_VIRT_OPEN
886
887
888CODE ENDS
889 END
890 \ No newline at end of file