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

wirehaze git hosting

MZ is back!
[MS-DOS.git] / v4.0 / src / CMD / LABEL / LABEL.ASM
1 PAGE 90,132 ;\ f\eA\b\e2
2 title LABEL.SAL - DOS LABEL COMMAND
3 ;*****************************************************************************
4 ;* *
5 ;* MODULE NAME: LABEL *
6 ;* *
7 ;* DESCRIPTIVE NAME: LABEL a diskette or disk *
8 ;* *
9 ;* FUNCTION: Create, change or delete a volume label on a disk. *
10 ;* *
11 ;* ENTRY POINT: Start *
12 ;* *
13 ;* INPUT: (DOS command line parameters) *
14 ;* [d:][path]LABEL [d:][volume label] *
15 ;* where: *
16 ;* [d:][path] before LABEL specifies the drive and path that contains *
17 ;* the LABEL command file. *
18 ;* *
19 ;* [d:][volume label] specifies the volume label. Volume labels are *
20 ;* used to identify a disk. They can be up to 11 characters and are in *
21 ;* the same format as volume labels created by FORMAT/V. *
22 ;* *
23 ;* EXIT-NORMAL: ERRORLEVEL 0 - Normal completion *
24 ;* *
25 ;* EXIT-ERROR: ERRORLEVEL 1 - Any error *
26 ;* *
27 ;* EFFECTS: The volume label is set to the indicated string. The volume *
28 ;* serial number, if present, is also displayed. *
29 ;* *
30 ;* INCLUDED FILES: None *
31 ;* *
32 ;* INTERNAL REFERENCES: *
33 ;* *
34 ;* Routines: *
35 ;* CHARACTER_CHECK - See if char is valid for filename *
36 ;* CHECK_DELETE - Get user Y/N if to delete old label *
37 ;* CHECK_FOR_DRIVE_LETTER - Parse for drive in string *
38 ;* CHECK_TRANSLATE_DRIVE - See if drive is SUBST or ASSIGN *
39 ;* CHK_DBCS -See if specified byte is a DBCS lead byte *
40 ;* CHK_DBCS_BLANK - Process DBCS blank char *
41 ;* CREATE_NEW_LABEL - Output new vol label *
42 ;* DATA AREAS - STACK, buffers, FCB'S, message sublists *
43 ;* DELETE_OLD_LABEL - Delete original volume label *
44 ;* DISPLAY_MSG - Send msg to system message handler *
45 ;* DRIVE_SETUP - Verify drive, get default, setup drive ID *
46 ;* ERROR_EXIT - Abnormal return to DOS *
47 ;* FIND_FIRST_CHAR - Locate first non blank in input *
48 ;* FIND_OLD_LABEL - Get the existing volume label *
49 ;* GET_NEW_LABEL - Parse new vol label name into path *
50 ;* GET_SERIAL_NUM - Get vol ser number from "GET_MEDIA_ID" *
51 ;* GET_USER_INPUT - Read from user new vol label *
52 ;* MAIN CODE - PSP, entry point *
53 ;* MAIN_BEGIN - High level function control *
54 ;* OUTPUT_OLD_LABEL - Display the original vol label *
55 ;* PRELOAD_MESSAGES - Set up sys msgs, DOS version check *
56 ;* PROCESS_STRING - Mov string to buf, check bad chars *
57 ;* SETUP_CRLF - Carriage return, line feed *
58 ;* SETUP_DELLABEL - "Delete current volume label (Y/N)?" *
59 ;* SETUP_HASLABEL - "Volume in drive %1 is %2" *
60 ;* SETUP_INVCHAR - "Invalid characters in volume label" *
61 ;* SETUP_INVDRIVE - "Invalid drive specification" *
62 ;* SETUP_NETDRIVE - "Cannot %1 a Network drive" *
63 ;* SETUP_NEWLABEL - "Volume label (11 characters, ENTER for none)?" *
64 ;* SETUP_NOLABEL - "Volume in drive %1 has no label" *
65 ;* SETUP_NOROOM - "Cannot make directory entry" *
66 ;* SETUP_SERIALNUM - "Volume Serial Number is %1-%2" *
67 ;* SETUP_SUBSTASGN - "Cannot %1 a SUBSTed or ASSIGNed drive" *
68 ;* SETUP_TOOMANY - "Too many files open" *
69 ;* *
70 ;* Data Areas: *
71 ;* CONTROL BLOCKS - SUBLISTS for message parameters *
72 ;* BUFFERS - For GET_MEDIA_ID, several FCB'S *
73 ;* PSP - Contains the DOS command line parameters. *
74 ;* STACK - Temporary save area *
75 ;* *
76 ;* EXTERNAL REFERENCES: *
77 ;* *
78 ;* Routines: *
79 ;* SYSDISPMSG (NEAR) - Message display routine *
80 ;* SYSLOADMSG (NEAR) - System message loader *
81 ;* *
82 ;* Data Areas: *
83 ;* DTA - defined for the DOS FINDFIRST function. *
84 ;* *
85 ;* NOTES: LABEL should not be used with SUBSTed drives. The root directory *
86 ;* of the actual drive will be the target of LABEL. LABEL should *
87 ;* not be used with ASSIGNed drives or to label network drives. * *
88 ;* *
89 ;* This module should be processed with the SALUT pre-processor *
90 ;* with the re-alignment not requested, as: *
91 ;* *
92 ;* SALUT LABEL,NUL *
93 ;* *
94 ;* To assemble these modules, the sequential or alphabetical *
95 ;* ordering of segments may be used. *
96 ;* *
97 ;* Sample LINK command: *
98 ;* *
99 ;* LINK @LABEL.ARF *
100 ;* *
101 ;* Where the LABEL.ARF is defined as: *
102 ;* *
103 ;* LABEL+ *
104 ;* LABELM *
105 ;* *
106 ;* These modules should be linked in this order. The load module is *
107 ;* a COM file. It should be converted via EXE2BIN to a .COM file. *
108 ;* *
109 ;* REVISION HISTORY: *
110 ;* *
111 ;* AN000;D DBCS Support (New LOC) 06/87 S. Maes *
112 ;* AN000;M Message service routine (New LOC) 06/87 S. Maes *
113 ;* AC000;M Message service routine (Changed LOC) 06/87 S. Maes *
114 ;* AN000;S Serial Number (New LOC) 06/87 S. Maes *
115 ;* AC000;K SALUT 08/87 E. Kiser *
116 ;* Ax001; DCR0524 - enable deletion of labelID 04/88 S. Maes *
117 ;* Ax002; PTM4282 - parse complete line for invalids 04/88 S. Maes *
118 ;* AN003; PTM4588 - scan entire line fails DBCS 05/88 S. Maes *
119 ;* *
120 ;* COPYRIGHT: The following notice is found in the OBJ code generated *
121 ;* in the LABELM.SAL module. *
122 ;* *
123 ;* "Version 4.00 (C)Copyright 1988 Microsoft
124 ;* "Licensed Material - Program Property of Microsoft" *
125 ;* *
126 ;*****************************************************************************
127 HEADER <DEFINITIONS - LOCAL MACROS AND LOCAL EQUATES>
128 IF1
129 %OUT COMPONENT=LABEL, MODULE=LABEL.SAL
130 ENDIF
131 HEADER MACRO TEXT
132 .XLIST
133 SUBTTL &TEXT
134 .LIST
135 PAGE
136 ENDM
137 ;*****************************************************************************
138 ; Equate Area
139 ;*****************************************************************************
140 ; $SALUT (4,20,25,36) ;AN000;K
141 ; DOS FUNCTION CALLS
142 FCB_SEARCH equ 11h
143 FCB_DELETE equ 13h
144 GET_DEFAULT equ 19h
145 SET_DTA equ 1Ah
146 CLOSE equ 3Eh
147 READ equ 3Fh
148 IOCTL equ 44h
149 LOC_OR_NET equ 9h ;AN000;K Local or network, subfunc of IOCTL
150 EXIT equ 4Ch
151 CREATE_FILE equ 5Bh
152 YN_CHECK equ 6523h ;AN001; 65=GetExtCtry 23=Y/NCheck
153 GET_MEDIA_ID equ 6900h ;AN000;S Int 21 for Serial Number
154 GET_DBCS_ENV equ 6300h ;AN000;D DBCS support
155 XNAMETRANS equ 60h ;AN000;
156
157 ; DBCS SPECIAL CHARACTER DEFINITIONS
158
159 DBCSBLK_BYTEONE equ 81h ;AN000;D 1st byte of DBCS blank
160 DBCSBLK_BYTETWO equ 40h ;AN000;D 2nd byte of DBCS blank
161 SBCSBLANKS equ 2020h ;AN000;D 2 SBCS blanks
162
163 ; MISCELLANEOUS EQUATES
164
165 ASCII_DRV equ "A"-1 ;AN000;D Convert to Ascii drive
166 BLANK equ " "
167 CHAR_ZERO equ "0" ;AN000;K Padding for serial number
168 COLON equ ":"
169 DEFAULT_DRIVE equ 0
170 DOT_LOCATION equ 8
171 DRIVE_INVALID equ 0FFh
172 END_OF_STRING equ 0
173 MAX_CHARS equ 11
174 MAX_INPUT equ 100h-81h ;Size of input buffer
175 NO equ 0 ;AN001; Compare for Y/N response
176 PERIOD equ "."
177 YES equ 1 ;AN001; Compare for Y/N response
178 ZERO equ 0
179
180 ; ERROR LEVEL RETURN CODES
181
182 ERRORLEVEL_0 equ 0
183 ERRORLEVEL_1 equ 1
184
185 ; ATTRIBUTE OF DIRECTORY ENTRY
186
187 VOL_ATTRIBUTE equ 8
188
189 ; ERROR CODES FROM DOS FUNCTIONS
190
191 VOL_NOT_FOUND equ 0FFh
192 TOO_MANY_FILES equ 4
193
194 ; ID IF MESSAGES DISPLAYED BY "LABEL"
195
196 TOO_MANY_MSG equ 1 ;AN000;M Too many files open
197 NO_ROOM_MSG equ 2 ;AN000;M Cannot make directory entry
198 INV_CHAR_MSG equ 3 ;AN000;M Invalid characters in volume label
199 NEW_LABEL_MSG equ 4 ;AN000;M Vol label (11 chars, ENTER for none)?
200 INV_DRIVE_MSG equ 5 ;AN000;M Invalid drive specification
201 NETWORKDRIVEMSG equ 6 ;AN000;M Cannot %1 a Network drive
202 SUBSTASSIGNMSG equ 7 ;AN000;M Cannot %1 a SUBSTed or ASSIGNed drive
203 NO_LABEL_MSG equ 8 ;AN000;M Volume in drive %1 has no label
204 SERIAL_NUM_MSG equ 9 ;AN000;M Volume Serial Number is %1
205 HAS_LABEL_MSG equ 10 ;AN000;M Volume in Drive %1 is %2
206 DEL_LABEL_MSG equ 11 ;AN001;M Delete current volume label (Y/N)?
207 CRLF_MSG equ 12 ;AN001;M CR,LF
208
209 ; DEFINITIONS OF FIELDS WITHIN MSG SUBLISTS
210
211 MAXWIDTH equ 0 ;AN000;M 0 will ensure no padding
212 MINWIDTH equ 1 ;AN000;M At least 1 char to insert in msg
213 STR_INPUT equ 16 ;AN000;M Byte definition for s?_flags
214 SUBLIST_LENGTH equ 11 ;AN000;M Length of sublist structure
215 RESERVED equ 0 ;AN000;M Reserved byte field
216 CR equ 0Dh ;Carriage Return
217 NO_INPUT equ 00h ;AN000;M No input characters
218 DOS_CON_INPUT equ 00C8h ;AN000;M No input characters
219 EXT_ERR_CLASS equ 01h ;AN000;M DOS Extended error class
220 UTILITY_MSG_CLASS equ 0FFh ;AN000;M Utility message class
221 STDIN equ 0000h ;File handle
222 STDOUT equ 0001h ;Standard Output device handle
223 STDERR equ 0002h ;Standard Error Output device handle
224 BIN_HEX_WORD equ 23h ;AN000;M a0100011
225 RIGHT_ALIGN equ 80h ;AN000;M 10xxxxxx
226 CHAR_FIELD_CHAR equ 0 ;AN000;M a0000000
227 HEADER <MAIN CODE - PSP, ENTRY POINT>
228 CSEG segment public
229
230 ASSUME cs:CSEG,ds:CSEG,es:CSEG,ss:CSEG
231
232 EXTRN SYSDISPMSG:NEAR ;SYSTEM DISPLAY MESSAGE ROUTINE
233 EXTRN SYSLOADMSG:NEAR ;SYSTEM MESSAGE LOADER ROUTINE
234
235 org 5Ch
236 FCB1 label byte
237
238 org 80h
239 Num_Parms label byte
240
241 org 81h
242 Parm_Area label byte
243
244 org 100h
245 Start: ;DOS ENTRY POINT
246 jmp Main_Begin ;SKIP CONSTANTS
247 HEADER <DATA AREAS - STACK, BUFFERS, FCB'S, MESSAGE SUBLISTS>
248 EVEN
249 Stack_Area db 512 dup ("S") ;Added in DOS 3.20 to support hardware requiring
250 End_Stack_Area db 0 ;large stacks. DO NOT PUT DATA ABOVE THIS !
251 New_Vol_Path db " :\" ;Path for new vol label
252 New_Vol_Name db " " ;Where first 8 chars go
253 New_Vol_Ext db ". ",0 ;Dot and extension
254 End_Parameters dw 0 ;End of input string
255
256 Program_Flag db 0 ;Status Flag
257 USER_INPUT equ 01h ;User has input already
258 LABEL_FND equ 02h ;Volume label found
259 NO_DELETE equ 04h ;No need for label delete
260 GET_INPUT equ 08h ;Need user input
261 CHAR_BAD equ 10h ;Invalid character in string
262 FOUND_DBCS equ 20h ;AN000;K in process of handling DBCS chars
263
264 Vol_FCB db 0FFh ;Extended FCB
265 db 0,0,0,0,0
266 db VOL_ATTRIBUTE ;Attribute for vol label
267 FCB_Drive db 0 ;Drive number
268 Vol_Name db "???????????" ;Match any vol name found
269 db 25 dup (0) ;Rest of the opened FCB
270 Label_Name db "???????????",0 ;AN000;
271 FCB_Drive_Char db " " ;AN000;K printable version of FCB_Drive above
272
273 TranSrc db "A:CON",0,0 ;AN000;A Device so we don't hit the drive
274 TranDst db 64 dup(' ') ;AN000;A
275 Label_Word db "LABEL",0 ;AN000;M Message substitution parm
276
277 Del_FCB db 0FFh ;Extended FCB
278 db 0,0,0,0,0
279 db VOL_ATTRIBUTE ;Attribute for vol label
280 Del_Drive db 0 ;Drive number
281 Del_Name db "???????????" ;Match any vol name found
282
283 ; MESSAGE SUBLIST STRUCTURES
284
285 Sublist1 Label Dword ;AN000;M Substitution list
286 s1_nxtlst db SUBLIST_LENGTH ;AN000;M (11)Ptr to next sublist
287 s1_reserve db RESERVED ;AN000;M (0)Reserved
288 s1_offset dw ? ;AN000;M Time/date or data pointer
289 s1_segment dw ? ;AN000;M Time/date or data pointer
290 s1_id db 1 ;AN000;M N of %n
291 s1_flags db ? ;AN000;M Data-type flags (a0sstttt)
292 s1_maxwidth db ? ;AN000;M Maximum field width
293 s1_minwidth db ? ;AN000;M Minimum field width
294 s1_padchar db ? ;AN000;M Char to pad field
295
296 Sublist2 Label Dword ;AN000;M Substitution list
297 s2_nxtlst db SUBLIST_LENGTH ;AN000;M (11)Ptr to next sublist
298 s2_reserve db RESERVED ;AN000;M (0)Reserved
299 s2_offset dw ? ;AN000;M Time/date or data pointer
300 s2_segment dw ? ;AN000;M Time/date or data pointer
301 s2_id db 2 ;AN000;M N of %n
302 s2_flags db ? ;AN000;M Data-type flags (a0sstttt)
303 s2_maxwidth db ? ;AN000;M Maximum field width
304 s2_minwidth db ? ;AN000;M Minimum field width
305 s2_padchar db ? ;AN000;M Char to pad field
306
307 ; GET_MEDIA_ID STRUCTURE
308
309 SerNumBuf Label Byte ;AN000;S GET_MEDIA_ID buffer
310 dw 0 ;AN000;S Info level (set on input)
311 SerNum dd 0 ;AN000;S Serial #
312 db 11 DUP(' ') ;AN000;S Volume label
313 db 8 DUP(' ') ;AN000;S File system type
314
315 ; CHK_DBCS STRUCTURE
316 DBCSev_Off dw 0 ;AC000;D offset of DBCS EV
317 DBCSev_Seg dw 0 ;AC000;D segment of DBCS EV
318
319 HEADER <MAIN_BEGIN - HIGH LEVEL FUNCTION CONTROL>
320 ; $SALUT (4,4,9,36) ;AN000;K
321 ;*****************************************************************************
322 ;* *
323 ;* SUBROUTINE NAME: main_begin *
324 ;* *
325 ;* SUBROUTINE FUNCTION: Preload message file and check DOS version *
326 ;* by calling SYSLOADMSG *
327 ;* Get the command line parameters *
328 ;* Parse command line *
329 ;* Verify the correctness of the parameters *
330 ;* Get label if exists *
331 ;* Get serial number if exists *
332 ;* Get new volume name *
333 ;* Make new volume file *
334 ;* Print messages by calling SYSDISPMSG *
335 ;* *
336 ;* EXTERNAL ROUTINES: SYSDISPMSG *
337 ;* SYSLOADMSG *
338 ;* *
339 ;* INTERNAL ROUTINES: Character_Check Main_Begin *
340 ;* Check_Delete Output_Old_Label *
341 ;* Check_For_Drive_Letter Preload_Messages *
342 ;* Check_Trans_Drive Process_String *
343 ;* Chk_DBCS Setup_CRLF *
344 ;* Chk_DBCS_Blank Setup_DelLabel *
345 ;* Create_New_Label Setup_HasLabel *
346 ;* Delete_Old_Label Setup_InvChar *
347 ;* Display_Msg Setup_InvDrive *
348 ;* Drive_Setup Setup_NetDrive *
349 ;* Error_Exit Setup_NewLabel *
350 ;* Find_First_Char Setup_NoLabel *
351 ;* Find_Old_Label Setup_NoRoom *
352 ;* Get_New_Label Setup_SerialNum *
353 ;* Get_Serial_Num Setup_SubstAsgn *
354 ;* Get_User_Input Setup_TooMany *
355 ;* *
356 ;*****************************************************************************
357 PUBLIC MAIN_BEGIN
358 Main_Begin Proc Near
359 mov sp,offset End_Stack_Area ;Move stack to user area(Added in DOS 3.20)
360 cld
361 call Preload_Messages ;AN000;M Check DOS version & load msgs
362 call Drive_Setup ;Get Drive letters
363 call Find_Old_Label ;Get label if exist
364 call Get_New_Label ;Get New Name
365 call Check_Delete ;AN001; See if delete needed or wanted
366 call Delete_Old_Label ;Del the old label if it exists
367 call Create_New_Label ;Make new Vol file
368 mov ax,(EXIT shl 8)+ERRORLEVEL_0 ;all done, pass back zero ret code
369 INT 21H
370 Main_Begin ENDP
371
372 HEADER <DRIVE_SETUP - VERIFY DRIVE, GET DEFAULT, SETUP DRIVE ID>
373 ;*****************************************************************************
374 ; Verify specified drive, get default if needed, setup drive letters
375 ;*****************************************************************************
376
377 PUBLIC DRIVE_SETUP
378 Drive_Setup PROC NEAR
379 cmp al,DRIVE_INVALID ;Was specified drive ok ?
380 ; $if e ;AN000;K No
381 JNE $$IF1
382 mov ax,INV_DRIVE_MSG ;Nope, tell & quit
383 call Setup_InvDrive ;AN000;M
384 call Display_Msg ;AN000;M Set up msg & display
385 call Error_Exit
386 ; $endif ;AN000;K
387 $$IF1:
388 ; Get_Drive:
389 mov al,FCB1 ;Get specified drive
390 cmp al,DEFAULT_DRIVE ;Was drive given ?
391 ; $if e ;AN000;K No
392 JNE $$IF3
393 mov ah,GET_DEFAULT ;No, get default drive
394 INT 21H
395 inc al ;Get a: based on 1, not 0
396 ; $endif ;AN000;K
397 $$IF3:
398 ; Drive_Letter:
399 mov FCB_Drive,al ;Put drive number in FCB
400 mov Del_Drive,al ;Put drive number in FCB
401 mov bl,al
402 mov al,FCB_Drive ;AN000;K get numeric value of drive letter
403 add al,ASCII_DRV ;AN000;M ("A"-1)
404 mov FCB_Drive_Char,al ;AN000;K make drive printable
405 mov ax,(IOCTL SHL 8)+LOC_OR_NET ;(4409h)determine drive type
406 INT 21H
407 test dx,1000h ;bit 12 on means network drive
408 ; $if nz ;AN000;K
409 JZ $$IF5
410 mov ax,NETWORKDRIVEMSG
411 call Setup_NetDrive ;AN000;M
412 call Display_Msg ;AN000;M First display the msg
413 call Error_Exit
414 ; $endif ;AN000;K
415 $$IF5:
416 call Check_Trans_Drive ;AN000;A Is drv SUBSTed/ASSIGNed?
417 ; $if nz ;AN000;K Yes
418 JZ $$IF7
419 mov ax,SUBSTASSIGNMSG ;AN000;A Prepare SUBST/ASSIGN msg
420 call Setup_SubstAsgn ;AN000;M
421 call Display_Msg ;AN000;A Display the message
422 call Error_Exit ;AN000;A Then exit
423 ; $endif ;AN000;K
424 $$IF7:
425 mov al,Del_Drive
426 add al,ASCII_DRV ;AN000;K ("A"-1) Convert to Ascii
427 mov New_Vol_Path,al ;Put drive letter in path
428 ret
429 Drive_Setup ENDP
430
431 HEADER <CHECK_TRANSLATE_DRIVE - SEE IF DRIVE IS SUBST OR ASSIGN>
432 ;*****************************************************************************
433 ; Routine name: Check_Translate_Drive
434 ;*****************************************************************************
435 ; Descr: Do a name translate call on the drive letter to see if it is
436 ; assigned by SUBST or ASSIGN
437 ; Input: Drive
438
439 PUBLIC CHECK_TRANS_DRIVE
440 Check_Trans_Drive PROC NEAR ;AN000;A
441 mov bl,FCB_Drive_Char ;AN000;A Get drive
442 mov byte ptr [TranSrc],bl ;AN000;A Make string "x:\"
443 mov si,offset TranSrc ;AN000;A Point to translate string
444 mov di,offset TranDst ;AN000;A Point at output buffer
445 mov ah,XNAMETRANS ;AN000;A (60H) Get real path
446 INT 21H ;AN000;A
447 mov bl,byte ptr [TranSrc] ;AN000;A Get drive letter from path
448 cmp bl,byte ptr [TranDst] ;AN000;A Did drive letter change?
449 ret ;AN000;A
450 Check_Trans_Drive ENDP ;AN000;A
451
452 HEADER <FIND_OLD_LABEL - GET THE EXISTING VOLUME LABEL>
453 ;*****************************************************************************
454 ; Find old volume label
455 ;*****************************************************************************
456 ; Input: VOL_FCB set to find any vol label
457 ; Output: VOL_FCB has label name if one found
458 ; PROGRAM_FLAG = LABEL_FND if one is found
459 ; LABEL_NAME gets found label name
460
461 PUBLIC FIND_OLD_LABEL
462 Find_Old_Label PROC NEAR
463 mov dx,offset Vol_FCB ;Point at FCB to find vol
464 mov ah,SET_DTA ;(1AH)
465 INT 21H
466 mov dx,offset Vol_FCB ;Point at FCB to find vol
467 mov ah,FCB_SEARCH ;(11H)
468 INT 21H ;Find vol label
469 cmp al,VOL_NOT_FOUND ;Find one
470 ; $if ne ;AN000;K Yes
471 JE $$IF9
472 or Program_Flag,LABEL_FND ;Yes, set flag
473 mov si,offset Vol_Name ;Found name
474 mov di,offset Label_Name ;Where to put it
475 mov cx,MAX_CHARS ;How many characters
476 rep movsb ;Move the string
477 ; $endif ;AN000;K
478 $$IF9:
479 ; Find_Return:
480 ret
481 Find_Old_Label ENDP
482
483 HEADER <GET_NEW_LABEL - PARSE NEW VOL LABEL NAME INTO PATH>
484 ;*****************************************************************************
485 ; Parse new volume label name into path.
486 ;*****************************************************************************
487 ; Input: PARM_AREA has input string
488 ; Output: NEW_VOL_NAME has ASCIIZ string for new label, or an END_OF_STRING
489 ; if nothing entered
490
491 PUBLIC GET_NEW_LABEL
492 Get_New_Label PROC NEAR
493 ; $do ;AN000;K
494 $$DO11:
495 xor cx,cx ;Zero counter
496 mov si,offset Parm_Area ;Input buffer
497 mov di,offset New_Vol_Name ;Target Buffer
498 call Find_First_Char ;Get first not blank char
499 test Program_Flag,GET_INPUT ;Find input?
500 jnz Need_User_Input ;No, go get it
501 call Process_String ;Scan string, move it
502 test Program_Flag,CHAR_BAD ;Invalid characters?
503 jnz Need_User_Input ;Yes, get user to input
504 mov al,END_OF_STRING ;Mark end of ASCIIZ string
505 stosb
506 cmp New_Vol_Name,END_OF_STRING ;Any chars entered?
507 ; $leave ne ;Yes, all done here
508 JNE $$EN11
509 test Program_Flag,USER_INPUT ;See if command line parse
510 ; $leave nz ;No, user had his chance
511 JNZ $$EN11
512 Need_User_Input:
513 test Program_Flag,USER_INPUT ;Is this the first time here?
514 ; $if z ;AN000;K Yes, label not already gone out
515 JNZ $$IF14
516 call Output_Old_Label ;Yes, print current vol label
517 ; $endif ;AN000;K
518 $$IF14:
519 Input_New_Label:
520 call Get_User_Input ;Get new string
521 ; $enddo ;AN000;K Go parse it again
522 JMP SHORT $$DO11
523 $$EN11:
524 ret
525 Get_New_Label ENDP
526
527 HEADER <FIND_FIRST_CHAR - LOCATE FIRST NON BLANK IN INPUT>
528 ;*****************************************************************************
529 ; Find the first non blank character in input string
530 ;*****************************************************************************
531 ; Input: SI = pointer to next character
532 ; Output: PROGRAM_FLAG = GET_INPUT if user input needed
533 ; AL = First not blank character
534 ; Notes: GET_INPUT set if nothing follows drive letter
535
536 PUBLIC FIND_FIRST_CHAR
537 Find_First_Char PROC NEAR
538 ; $do ;AN000;K
539 $$DO17:
540 and Program_Flag,not GET_INPUT ;Clear flag
541 lodsb ;Get char
542 call Chk_DBCS ;AN000;D Check DBCS env
543 ; $if c ;AN000;K
544 JNC $$IF18
545 call Chk_DBCS_Blank ;AN000;D Is it a DBCS blank?
546 ; $endif ;AN000;K
547 $$IF18:
548 cmp al,BLANK ;Is it a blank?
549 ; $enddo ne ;AN000;K No, quit
550 JE $$DO17
551 call Check_For_Drive_Letter ;Parse out drive letter
552 call Chk_DBCS ;AN000;D Check DBCS env
553 ; $if c ;AN000;K
554 JNC $$IF21
555 call Chk_DBCS_Blank ;AN000;D Is it a DBCS blank?
556 and Program_Flag,not FOUND_DBCS ;AN000;K forget this was a dbcs for now
557 ; $endif ;AN000;K
558 $$IF21:
559 cmp al,BLANK ;Blank following drive letter?
560 ; $if e ;AN000;K
561 JNE $$IF23
562 or Program_Flag,GET_INPUT
563 ; $endif ;AN000;K
564 $$IF23:
565 ret
566 Find_First_Char ENDP
567
568 HEADER <CHK_DBCS -SEE IF SPECIFIED BYTE IS A DBCS LEAD BYTE>
569 ;*****************************************************************************
570 ; Check DBCS environment
571 ;*****************************************************************************
572 ; Function: Check if a specified byte is in ranges of the DBCS lead bytes
573 ; Input: AL = Code to be examined
574 ; Output: If CF is on then a lead byte of DBCS
575 ; Register: FL is used for the output, others are unchanged.
576
577 PUBLIC CHK_DBCS
578 Chk_DBCS PROC ;AC000;D
579 push ds ;AC000;D save regs, about to be clobbered
580 push si ;AC000;D
581 cmp DBCSev_Seg,ZERO ;AC000;D Already set ?
582 ; $if e ;AN000;K if the vector not yet found
583 JNE $$IF25
584 push ax ;AC000;D
585 mov ax,GET_DBCS_ENV ;AC000;D GET DBCS EV call
586 INT 21H ;AC000;D ds:si points to the dbcs vector
587 ASSUME ds:NOTHING ;AN000;K that function clobbered old DS
588 mov DBCSev_Off,si ;AC000;D remem where dbcs vector is so next
589 mov DBCSev_Seg,ds ;AC000;D time don't have to look for it
590 pop ax ;AC000;D
591 ; $endif ;AN000;K
592 $$IF25:
593 mov si,DBCSev_Off ;AC000;D set DS:SI to point to
594 mov ds,DBCSev_Seg ;AC000;D the dbcs vector
595 ; $search ;AN000;K
596 $$DO27:
597 cmp word ptr [si],ZERO ;AC000;D vec ends with nul terminator entry
598 ; $leave e ;AN000;K if that was terminator entry, quit
599 JE $$EN27
600 cmp al,[si] ;AC000;D look at LOW value of vector
601 ; $exitif nb,and ;AN000;K if this byte in range of LOW
602 JB $$IF27
603 cmp al,[si+1] ;AC000;D look at HIGH value of vector
604 ; $exitif na ;AN000;K if this byte is still in range
605 JA $$IF27
606 or Program_Flag,FOUND_DBCS ;AN000;K remember we found one of a pair
607 stc ;AC000;D set flag to say, found a DBCS char
608 ; $orelse ;AN000;K since char not in this vector
609 JMP SHORT $$SR27
610 $$IF27:
611 add si,2 ;AC000;D go look at next vec in dbcs table
612 ; $endloop ;AN000;K go back and ck out new vector entry
613 JMP SHORT $$DO27
614 $$EN27:
615 clc ;AC000;D set flag to say not a DBCS char
616 ; $endsrch ;AN000;K
617 $$SR27:
618 pop si ;AC000;D restore the regs
619 pop ds ;AC000;D
620 ASSUME ds:CSEG ;AN000;K tell masm, DS back to normal
621 ret ;AC000;D
622 Chk_DBCS ENDP ;AC000;D
623
624 HEADER <CHK_DBCS_BLANK - PROCESS DBCS BLANK CHAR>
625 ;*****************************************************************************
626 ; Check DBCS char for a blank (8140)
627 ;*****************************************************************************
628 ; Function: Check if a specified byte is a DBCS blank
629 ; Input: AL = Byte to be examined
630 ; SI = Points to next byte
631 ; Output: SI = UNchanged
632
633 PUBLIC CHK_DBCS_BLANK
634 Chk_DBCS_Blank PROC NEAR ;AN000;D
635 cmp al,DBCSBLK_BYTEONE ;AN000;D Is the leading byte 81h?
636 ; $if e,and ;AN000;K
637 JNE $$IF33
638 cmp byte ptr [si],DBCSBLK_BYTETWO ;AN000;D Is the 2nd byte 40h?
639 ; $if e ;AN000;K Yes, change to 2 SBCS blanks
640 JNE $$IF33
641 ; Convert_DBCS_Blank: ;AN000;D
642 mov word ptr es:[si]-1,SBCSBLANKS ;AN000;D Fill it up with blank-blank
643 mov al,BLANK ;AN000;K pretend this char is a blank
644 ; $endif ;AN000;K
645 $$IF33:
646 ; DBCS_Blank_Exit: ;AN000;D
647 ret ;AN000;D And leave
648 Chk_DBCS_Blank ENDP ;AN000;D
649
650 HEADER <CHECK_FOR_DRIVE_LETTER - PARSE FOR DRIVE IN STRING>
651 ;*****************************************************************************
652 ; Parse a drive letter out of the string [Check_For_Drive_Letter]
653 ;*****************************************************************************
654 ; Input: SI = pointer to next character
655 ; CX = character count
656 ; Output: SI = SI+1 if drive letter entered
657
658 PUBLIC CHECK_FOR_DRIVE_LETTER
659 Check_For_Drive_Letter PROC NEAR
660 test Program_Flag,USER_INPUT ;Input not from command line?
661 ; $if z ;AN000;K
662 JNZ $$IF35
663 cmp cx,END_OF_STRING ;Anything parsed yet
664 ; $if e ;AN000;
665 JNE $$IF36
666 cmp al,CR ;First char a CR ?
667 ; $if ne
668 JE $$IF37
669 cmp byte ptr [si],COLON ;Drive letter entered?
670 ; $if e ;AN000;K
671 JNE $$IF38
672 inc si ;Yes, point past the colon
673 lodsb ;And get next character
674 ; $endif ;AN000;K
675 $$IF38:
676 ; $endif ;AN000;K
677 $$IF37:
678 ; $endif ;AN000;K
679 $$IF36:
680 ; $endif ;AN000;K
681 $$IF35:
682 Drive_Letter_Ret:
683 ret
684 Check_For_Drive_Letter ENDP
685
686 HEADER <PROCESS_STRING - MOV STRING TO BUF, CHECK BAD CHARS>
687 ;*****************************************************************************
688 ; Move the input string into buffer, checking for bad characters
689 ;*****************************************************************************
690 ; Input: SI = pointer to next character
691 ; DI = pointer to buffer
692 ; AL = current character in string
693 ; Output: PROGRAM_FLAG = CHAR_BAD if invalid char in string (Flag set in
694 ; called Character_Check routine)
695 ; Notes: Insert a "." in string to seperate 8th and 9th characters so
696 ; ASCIIZ string is the result.
697
698 PUBLIC PROCESS_STRING
699 Process_String PROC NEAR
700 cmp al,CR ;is it an ENTER ?
701 ; $if e
702 JNE $$IF43
703 test Program_Flag,USER_INPUT ;has user been told to provide input?
704 ; $if nz ;If user has been prompted for input
705 JZ $$IF44
706 cmp cx,ZERO ;And he said - nothing
707 ; $if e
708 JNE $$IF45
709 jmp Process_String_Return ;AN001; ENTER is acceptable
710 ; $endif
711 $$IF45:
712 ; $endif
713 $$IF44:
714 ; $else ;Since got other than just ENTER
715 JMP SHORT $$EN43
716 $$IF43:
717 test Program_Flag,FOUND_DBCS ;AN000;K If prev char not 1st of DBCS pair
718 jz Do_More_Check ;AN000;K then go check it out
719 and Program_Flag,not FOUND_DBCS ;AN000; Reset flag, found its partner
720 cmp cx,11 ;AC003; Continue to check chars but don't
721 jge Scan_Continue ;AC003; store anything more
722 jmp short Got_Ok_Character ;AN000; Partner is ok
723 Do_More_Check:
724 call Chk_DBCS ;AN000;D Check DBCS env
725 jnc Check_Char ;AN000;D If carry, it's a DBCS char
726 cmp cx,10 ;AC003; If previous char was the 10th
727 jge Scan_Continue ;AC003; then there is no room for 11th DBCS
728 call Chk_DBCS_Blank ;AN000;D Is it a DBCS blank?
729 jmp Got_Ok_Character ;AN000;D
730 Check_Char:
731 call Character_Check ;Is it a valid char ?
732 test Program_Flag,CHAR_BAD
733 jnz Process_String_Return ;Flag was set, char was invalid
734 cmp cx,11 ;AN003; Continue to check chars but don't
735 jge Scan_Continue ;AN003; store anything more
736 Got_Ok_Character:
737 stosb ;Good char, store it
738 Scan_Continue: ;AN003; Skip storing chars since past limit
739 inc cx ;Inc character count
740 cmp cx,DOT_LOCATION ;Do we need "." for extension?
741 jne Get_Next_Char ;No
742 mov al,PERIOD ;Get a "." for extension
743 stosb ;And save it
744 Get_Next_Char:
745 lodsb ;Get next character
746 cmp cx,MAX_INPUT ;AN002; Have we reached end?
747 jne Process_String ;No, go diddle with it
748 ; $endif
749 $$EN43:
750 Process_String_Return:
751 ret
752 Process_String ENDP
753
754 HEADER <CHARACTER_CHECK - SEE IF CHAR IS VALID FOR FILENAME>
755 ;*****************************************************************************
756 ; See if a character is valid for filename [Character_Check]
757 ;*****************************************************************************
758 ; Input: AL = character to be checked
759 ; Output: AL = character
760 ; PROGRAM_FLAG = CHAR_BAD if invalid characters found
761
762 PUBLIC CHARACTER_CHECK
763 Character_Check PROC NEAR
764 or Program_Flag,CHAR_BAD ;Assume bad character
765 cmp al,"*"
766 je Char_Check_Done
767 cmp al,"?"
768 je Char_Check_Done
769 cmp al,"["
770 je Char_Check_Done
771 cmp al,"]"
772 je Char_Check_Done
773 cmp al,":"
774 je Char_Check_Done
775 cmp al,"<"
776 je Char_Check_Done
777 cmp al,"|"
778 je Char_Check_Done
779 cmp al,">"
780 je Char_Check_Done
781 cmp al,"+"
782 je Char_Check_Done
783 cmp al,"="
784 je Char_Check_Done
785 cmp al,";"
786 je Char_Check_Done
787 cmp al,","
788 je Char_Check_Done
789 cmp al,"/"
790 je Char_Check_Done
791 cmp al,"\"
792 je Char_Check_Done
793 cmp al,'.'
794 je Char_Check_Done
795 cmp al,'"'
796 je Char_Check_Done
797 cmp al," "
798 jb Char_Check_Done
799 and Program_Flag,not CHAR_BAD ;Char is ok
800 Char_Check_Done:
801 ret
802 Character_Check ENDP
803
804 HEADER <OUTPUT_OLD_LABEL - DISPLAY THE ORIGINAL VOL LABEL>
805 ;*****************************************************************************
806 ; Print the old volume label
807 ;*****************************************************************************
808 ; Input: PROGRAM_FLAG = LABEL_FND if there is a label
809 ; Output: None
810 ; Notes: Print the volume label
811
812 PUBLIC OUTPUT_OLD_LABEL
813 Output_Old_Label PROC NEAR
814 mov ax,HAS_LABEL_MSG ;Assume label
815 call Setup_HasLabel ;AN000;M
816 test Program_Flag,LABEL_FND ;Is there one?
817 ; $if z ;AN000;K If no label found, then
818 JNZ $$IF50
819 mov ax,NO_LABEL_MSG ;No, other message
820 call Setup_NoLabel ;AN000;M
821 ; $endif ;AN000;K
822 $$IF50:
823 call Display_Msg ;AC000;M Set up msg and display
824 call Get_Serial_Num ;AN000;S Since LABEL_FND, ck for SN
825 ; $if nc ;AN000;K SN must be known
826 JC $$IF52
827 mov ax,SERIAL_NUM_MSG ;AN000;S Prepare for SN message
828 call Setup_SerialNum ;AN000;M
829 call Display_Msg ;AC000;M Set up msg and display
830 ; $endif ;AN000;K
831 $$IF52:
832 ret
833 Output_Old_Label ENDP
834
835 HEADER <GET_SERIAL_NUM - GET VOL SER NUMBER FROM "GET_MEDIA_ID">
836 ;*****************************************************************************
837 ; Get the volume serial number
838 ;*****************************************************************************
839 ; Input: FCB_Drive
840 ; Output: SerNum if no carry
841 ; Notes: Only DOS Version 4.0 and above will contain serial numbers
842
843 PUBLIC GET_SERIAL_NUM
844 Get_Serial_Num PROC NEAR ;AN000;S
845 mov ax,GET_MEDIA_ID ;AN000;S
846 mov bh,0 ;AN000;S
847 mov bl,FCB_Drive ;AN000;S Which drive to check
848 lea dx,SerNumBuf ;AN000;S Pt to the buffer
849 INT 21H ;AN000;S Make the call
850 ret ;AN000;S
851 Get_Serial_Num ENDP ;AN000;S
852
853 HEADER <GET_USER_INPUT - READ FROM USER NEW VOL LABEL>
854 ;*****************************************************************************
855 ; Input from user a new volume label string
856 ;*****************************************************************************
857 ; Input: PROGRAM_FLAG = CHAR_BAD if there were invalid characters in string
858 ; Output: New string placed in PARM_AREA
859 ; Notes: Print bad character message if needed and prompt and get user input
860
861 PUBLIC GET_USER_INPUT
862 Get_User_Input PROC NEAR
863 test Program_Flag,CHAR_BAD ;Do we need bad char message
864 ; $if nz ;AN000;K
865 JZ $$IF54
866 mov ax,INV_CHAR_MSG ;Yes
867 call Setup_InvChar ;AN000;M
868 call Display_Msg ;AC000;M Set up msg and display
869 and Program_Flag,not CHAR_BAD ;Char is ok
870 ; $endif ;AN000;K
871 $$IF54:
872 mov ax,NEW_LABEL_MSG ;Tell user to input new label
873 call Setup_NewLabel ;AN000;M
874 call Display_Msg ;AC000;M Set up msg and display
875 mov dx,offset Parm_Area ;Point where to put new name
876 mov cx,MAX_INPUT ;Number of characters to read
877 mov bx,STDIN ;Read from keyboard
878 mov ah,READ ;(3FH)
879 INT 21H
880 or Program_Flag,USER_INPUT ;Indicate user input has been received
881 ret
882 Get_User_Input ENDP
883
884 HEADER <CHECK_DELETE - SEE IF OLD LABEL SHOULD BE DELETED>
885 ;*****************************************************************************
886 ; Check to see if old label should be deleted
887 ;*****************************************************************************
888 ; Input: PROGRAM_FLAG = LABEL_FND if there is a label
889 ; Output: PROGRAM_FLAG = NO_DELETE if label should not be deleted
890 ; Notes: Get user Y/N if to delete previous label
891
892 PUBLIC CHECK_DELETE
893 Check_Delete PROC NEAR
894 test Program_Flag,LABEL_FND ;AN001; Is there a vol label
895 jz Check_Delete_Return ;AN001; No, no need for prompt
896 cmp New_Vol_Name,END_OF_STRING ;AN001; Did user enter label
897 jne Check_Delete_Return ;AN001; Yes, no need for prompt
898 Delete_Prompt: ;AN001;
899 mov ax,DEL_LABEL_MSG ;AN001; Point at Y/N prompt
900 call Setup_DelLabel ;AN001;M Prepare message
901 call Display_Msg ;AN001;M Call to Sysdispmsg
902 mov dx,ax ;AN001; Char ret'd, prep for ck
903 mov ax,YN_CHECK ;AN001; GetExtCtry,Y/NCheck
904 INT 21H ;AN001;
905 cmp ax,YES ;AN001; Delete label ?
906 je Check_Delete_Return ;AN001; Yes
907 cmp ax,NO ;AN001; Delete label ?
908 je Delete_Label ;AN001; Yes
909 jne Delete_Prompt ;AN001; No, try again
910 Delete_Label: ;AN001;
911 or Program_Flag,NO_DELETE ;AN001; Yes, set flag
912 Check_Delete_Return: ;AN001;
913 mov ax,CRLF_MSG ;AN001; Point at CRLF message
914 call Setup_CRLF ;AN001;M Prepare message
915 call Display_Msg ;AN001;M Call to Sysdispmsg
916 ret ;AN001;
917 Check_Delete ENDP
918
919 HEADER <DELETE_OLD_LABEL - DELETE ORIGINAL VOLUME LABEL>
920 ;*****************************************************************************
921 ; Delete old volume label
922 ;*****************************************************************************
923 ; Input: VOL_FCB has name of label if one found
924 ; PROGRAM_FLAG = NO_DELETE if label doesn't need to be deleted
925 ; Output: Vol label deleted if it exists and user say's it is okay
926 ; Notes: Ask user if old label should be deleted.
927
928 PUBLIC DELETE_OLD_LABEL
929 Delete_Old_Label PROC NEAR
930 test Program_Flag,NO_DELETE ;Need to delete label ?
931 ; $if z ;AN000;K
932 JNZ $$IF56
933 lea dx,Del_FCB ;Point at FCB to delete vol
934 mov ah,FCB_DELETE ;(13H) label and delete it
935 INT 21H ;Can't use handle cause Chmod won't find it
936 ; $endif ;AN000;K
937 $$IF56:
938 ret
939 Delete_Old_Label ENDP
940
941 HEADER <CREATE_NEW_LABEL - OUTPUT NEW VOL LABEL>
942 ;*****************************************************************************
943 ; Create new volume label file if user specified one
944 ;*****************************************************************************
945
946 PUBLIC CREATE_NEW_LABEL
947 Create_New_Label PROC NEAR
948 cmp New_Vol_Name,END_OF_STRING ;Did user enter a vol label
949 ; $if ne ;AN000;K
950 JE $$IF58
951 mov dx,offset New_Vol_Path ;Point at path for file
952 mov cx,VOL_ATTRIBUTE ;Set it as a volume label
953 mov ah,CREATE_FILE ;(5BH) Go make it
954 INT 21H
955 ; $if nc ;AN000;K
956 JC $$IF59
957 mov bx,ax ;shift file handle
958 mov ah,CLOSE ;And close the file
959 INT 21H
960 ; $else ;AN000;K since there was creation error,
961 JMP SHORT $$EN59
962 $$IF59:
963 cmp ax,TOO_MANY_FILES ;Is it
964 ; $if ne ;AN000;K if not "too many files", then
965 JE $$IF61
966 mov ax,NO_ROOM_MSG ;AN000;M
967 call Setup_NoRoom ;AN000;M
968 call Display_Msg ;AN000;M
969 test Program_Flag,LABEL_FND ;AN000;K was an old label found?
970 ; $if ne ;AN000;K if there was an old one,
971 JE $$IF62
972 ;need to restore the previous label
973 ;because the new one did not stick
974 mov si,offset Label_Name ;AN000;K where old name was kept
975 mov di,offset New_Vol_Name ;AN000;K where to put old name
976 mov cx,8 ;AN000;K count of filename up to "."
977 rep movsb ;AN000;K
978 inc di ;AN000;K skip the "."
979 mov cx,3 ;AN000;K length of extension
980 rep movsb ;AN000;K
981 mov dx,offset New_Vol_Path ;AN000;K drive\path\filename
982 mov cx,VOL_ATTRIBUTE ;AN000;K make it a label
983 mov ah,CREATE_FILE ;AN000;K make a label
984 INT 21H ;AN000;K at least, try to, anyway...
985 ; $endif ;AN000;K old label?
986 $$IF62:
987 ; $else ;AN000;K since is "too many files", then...
988 JMP SHORT $$EN61
989 $$IF61:
990 mov ax,TOO_MANY_MSG ;AN000;M
991 call Setup_TooMany ;AN000;M
992 call Display_Msg ;AN000;M
993 ; $endif ;AN000;K
994 $$EN61:
995 jmp Error_Exit ;Tell user bad news and quit
996 ; $endif ;AN000;K
997 $$EN59:
998 ; $endif ;AN000;K
999 $$IF58:
1000 ret
1001 Create_New_Label ENDP
1002
1003 HEADER <PRELOAD_MESSAGES - SET UP SYS MSGS, DOS VERSION CHK>
1004 ;*****************************************************************************
1005 ; Preload utility messages
1006 ;*****************************************************************************
1007 ; Input: None
1008 ; Output: None
1009 ; Notes: Checks DOS version, if incorrect, or if error loading messages, will
1010 ; display error message and terminate
1011
1012 PUBLIC PRELOAD_MESSAGES
1013 Preload_Messages PROC NEAR ;AN000;M
1014 push ax ;AN000;M
1015 push bp ;AN000;M
1016 mov bp,sp ;AN000;M
1017 push di ;AN000;M
1018 push si ;AN000;M
1019 call SYSLOADMSG ;AN000;M Load msgs & chk DOS ver
1020 ; $if c ;AN000;K
1021 JNC $$IF68
1022 call SYSDISPMSG ;AN000;M
1023 pop si ;AN000;M
1024 pop di ;AN000;M
1025 mov sp,bp ;AN000;M
1026 pop bp ;AN000;M
1027 pop ax ;AN000;M
1028 call Error_Exit ;AN000;M
1029 ; $endif ;AN000;K
1030 $$IF68:
1031 pop si ;AN000;M
1032 pop di ;AN000;M
1033 mov sp,bp ;AN000;M
1034 pop bp ;AN000;M
1035 pop ax ;AN000;M
1036 ret ;AN000;M
1037 Preload_Messages ENDP ;AN000;M
1038
1039 HEADER <DISPLAY_MSG - SEND MSG TO SYSTEM MESSAGE HANDLER>
1040 ;*****************************************************************************
1041 ; Display utility messages
1042 ;*****************************************************************************
1043 ; Input: dx contains the messsage to display
1044 ; Output: None
1045 ; Notes: The message called is displayed to stdout/stderr unless AX returns
1046 ; with error code (then setup for extended error to display)
1047
1048 PUBLIC DISPLAY_MSG
1049 Display_Msg PROC NEAR ;AN000;M
1050 push bp ;AN000;M
1051 mov bp,sp ;AN000;M
1052 push di ;AN000;M
1053 push si ;AN000;M
1054 call SYSDISPMSG ;AN000;M Now display the message
1055 ; $if c ;AN000;K if there was a problem, then...
1056 JNC $$IF70
1057 mov bx,STDERR ;AN000;M Error msg, so stderr
1058 mov cx,0 ;AN000;M Substitution count
1059 mov dl,NO_INPUT ;AN000;M No input characters
1060 mov dh,EXT_ERR_CLASS ;AN000;M DOS Extended error class
1061 call SYSDISPMSG ;AN000;M Now display the extended error
1062 pop si ;AN000;M
1063 pop di ;AN000;M
1064 mov sp,bp ;AN000;M
1065 pop bp ;AN000;M
1066 call Error_Exit ;AN000;M Nothing we can do so leave
1067 ; $endif ;AN000;K
1068 $$IF70:
1069 ; Done: ;AN000;M
1070 pop si ;AN000;M
1071 pop di ;AN000;M
1072 mov sp,bp ;AN000;M
1073 pop bp ;AN000;M
1074 ret ;AN000;M Bye,bye
1075 Display_Msg ENDP ;AN000;M
1076
1077 HEADER <SETUP_TOOMANY - "Too many files open">
1078 ;*****************************************************************************
1079 ; Setup for utility messages
1080 ;*****************************************************************************
1081 ; Input: None
1082 ; Output: None
1083
1084 PUBLIC SETUP_TOOMANY
1085 Setup_TooMany PROC NEAR ;AN000;M
1086 mov ax,4 ;AN000;M Utility's message number
1087 mov bx,STDERR ;AN000;M Error msg, so stderr
1088 mov cx,0 ;AN000;M Substitution count
1089 mov dl,NO_INPUT ;AN000;M No input characters
1090 mov dh,EXT_ERR_CLASS ;AN000;M DOS Extended error class
1091 ret ;AN000;M Now display the message
1092 Setup_TooMany ENDP ;AN000;M
1093
1094 HEADER <SETUP_NOROOM - "Cannot make directory entry">
1095 ;*****************************************************************************
1096 ; Setup for utility messages
1097 ;*****************************************************************************
1098 ; Input: None
1099 ; Output: None
1100
1101 PUBLIC SETUP_NOROOM
1102 Setup_NoRoom PROC NEAR ;AN000;M
1103 mov ax,82 ;AN000;M Utility's message number
1104 mov bx,STDERR ;AN000;M Error msg, so stderr
1105 mov cx,0 ;AN000;M Substitution count
1106 mov dl,NO_INPUT ;AN000;M No input characters
1107 mov dh,EXT_ERR_CLASS ;AN000;M DOS Extended error class
1108 ret ;AN000;M
1109 Setup_NoRoom ENDP
1110
1111 HEADER <SETUP_INVCHAR - "Invalid characters in volume label">
1112 ;*****************************************************************************
1113 ; Setup for utility messages
1114 ;*****************************************************************************
1115 ; Input: None
1116 ; Output: None
1117
1118 PUBLIC SETUP_INVCHAR
1119 Setup_InvChar PROC NEAR ;AN000;M
1120 mov ax,3 ;AN000;M Utility's message number
1121 mov bx,STDERR ;AN000;M Error msg, so stderr
1122 mov cx,0 ;AN000;M Substitution count
1123 mov dl,NO_INPUT ;AN000;M No input characters
1124 mov dh,UTILITY_MSG_CLASS ;AN000;M Utility message class
1125 ret ;AN000;M
1126 Setup_InvChar ENDP ;AN000;M
1127
1128 HEADER <SETUP_NEWLABEL - "Volume label (11 characters, ENTER for none)?">
1129 ;*****************************************************************************
1130 ; Setup for utility messages
1131 ;*****************************************************************************
1132 ; Input: None
1133 ; Output: None
1134
1135 PUBLIC SETUP_NEWLABEL
1136 Setup_NewLabel PROC NEAR ;AN000;M
1137 mov ax,6 ;AN000;M Utility's message number
1138 mov bx,STDOUT ;AN000;M Info msg, so stdout
1139 mov cx,0 ;AN000;M Substitution count
1140 mov dl,NO_INPUT ;AN000;M No input characters
1141 mov dh,UTILITY_MSG_CLASS ;AN000;M Utility message class
1142 ret ;AN000;M
1143 Setup_NewLabel ENDP ;AN000;M
1144
1145 HEADER <SETUP_INVDRIVE - "Invalid drive specification">
1146 ;*****************************************************************************
1147 ; Setup for utility messages
1148 ;*****************************************************************************
1149 ; Input: None
1150 ; Output: None
1151
1152 PUBLIC SETUP_INVDRIVE
1153 Setup_InvDrive PROC NEAR ;AN000;M
1154 mov s1_offset,offset FCB_Drive_Char ;AN000;M
1155 mov s1_segment,ds ;AN000;M Setup segment
1156 mov s1_flags,CHAR_FIELD_CHAR ;AN000;M Set up the parm formatting
1157 mov s1_maxwidth,MAXWIDTH ;AN000;M 0 ensures no padding
1158 mov s1_minwidth,MINWIDTH ;AN000;M At least 1 char to insert
1159 mov s1_padchar,BLANK ;AN000;M In case, pad with blanks
1160 mov ax,15 ;AN000;M Utility's message number
1161 mov bx,STDERR ;AN000;M Error msg, so stderr
1162 lea si,sublist1 ;AN000;M Display invalid drive
1163 mov cx,0 ;AN000;M Substitution count
1164 mov dl,NO_INPUT ;AN000;M No input characters
1165 mov dh,EXT_ERR_CLASS ;AN000;M DOS Extended error class
1166 ret ;AN000;M
1167 Setup_InvDrive ENDP ;AN000;M
1168
1169 HEADER <SETUP_NETDRIVE - "Cannot %1 a Network drive">
1170 ;*****************************************************************************
1171 ; Setup for utility messages
1172 ;*****************************************************************************
1173 ; Input: None
1174 ; Output: None
1175
1176 PUBLIC SETUP_NETDRIVE
1177 Setup_NetDrive PROC NEAR ;AN000;M
1178 mov s1_offset,offset Label_Word ;AN000;M Cannot LABEL a network...
1179 mov s1_segment,ds ;AN000;M Setup segment
1180 mov s1_flags,STR_INPUT ;AN000;M Set up the parm formatting
1181 mov s1_maxwidth,MAXWIDTH ;AN000;M 0 ensures no padding
1182 mov s1_minwidth,MINWIDTH ;AN000;M At least 1 char to insert
1183 mov s1_padchar,BLANK ;AN000;M In case, pad with blanks
1184 mov ax,8 ;AN000;M Utility's message number
1185 mov bx,STDERR ;AN000;M Error msg, so stderr
1186 lea si,sublist1 ;AN000;M Display network drive msg
1187 mov cx,1 ;AN000;M Substitution count
1188 mov dl,NO_INPUT ;AN000;M No input characters
1189 mov dh,UTILITY_MSG_CLASS ;AN000;M Utility message class
1190 ret ;AN000;M
1191 Setup_NetDrive ENDP ;AN000;M
1192
1193 HEADER <SETUP_SUBSTASGN - "Cannot %1 a SUBSTed or ASSIGNed drive">
1194 ;*****************************************************************************
1195 ; Setup for utility messages
1196 ;*****************************************************************************
1197 ; Input: None
1198 ; Output: None
1199
1200 PUBLIC SETUP_SUBSTASGN
1201 Setup_SubstAsgn PROC NEAR ;AN000;M
1202 mov s1_offset,offset Label_Word ;AN000;M Cannot LABEL a SUBSTed...
1203 mov s1_segment,ds ;AN000;M Setup segment
1204 mov s1_flags,STR_INPUT ;AN000;M Set up the parm formatting
1205 mov s1_maxwidth,MAXWIDTH ;AN000;M 0 ensures no padding
1206 mov s1_minwidth,MINWIDTH ;AN000;M At least 1 char to insert
1207 mov s1_padchar,BLANK ;AN000;M In case, pad with blanks
1208 mov ax,2 ;AN000;M Utility's message number
1209 mov bx,STDERR ;AN000;M Error msg, so stderr
1210 lea si,sublist1 ;AN000;M Display SUBST/ASSIGN drive ,dh
1211 mov cx,1 ;AN000;M Substitution count
1212 mov dl,NO_INPUT ;AN000;M No input characters
1213 mov dh,UTILITY_MSG_CLASS ;AN000;M Utility message class
1214 ret ;AN000;M
1215 Setup_SubstAsgn ENDP ;AN000;M
1216
1217 HEADER <SETUP_NOLABEL - "Volume in drive %1 has no label">
1218 ;*****************************************************************************
1219 ; Setup for utility messages
1220 ;*****************************************************************************
1221 ; Input: None
1222 ; Output: None
1223
1224 PUBLIC SETUP_NOLABEL
1225 Setup_NoLabel PROC NEAR ;AN000;M
1226 mov s1_offset,offset FCB_Drive_Char ;AN000;M
1227 mov s1_segment,ds ;AN000;M Setup segment
1228 mov s1_flags,CHAR_FIELD_CHAR ;AN000;M Set up the parm formatting
1229 mov s1_maxwidth,MAXWIDTH ;AN000;M 0 ensures no padding
1230 mov s1_minwidth,MINWIDTH ;AN000;M At least 1 char to insert
1231 mov s1_padchar,BLANK ;AN000;M In case, pad with blanks
1232 mov ax,4 ;AN000;M Utility's message number
1233 mov bx,STDOUT ;AN000;M Info msg, so stdout
1234 lea si,sublist1 ;AN000;M Display drive
1235 mov cx,1 ;AN000;M Substitution count
1236 mov dl,NO_INPUT ;AN000;M No input characters
1237 mov dh,UTILITY_MSG_CLASS ;AN000;M Utility message class
1238 ret ;AN000;M
1239 Setup_NoLabel ENDP ;AN000;M
1240
1241 HEADER <SETUP_SERIALNUM - "Volume Serial Number is %1-%2">
1242 ;*****************************************************************************
1243 ; Setup for utility messages
1244 ;*****************************************************************************
1245 ; Input: None
1246 ; Output: None
1247
1248 PUBLIC SETUP_SERIALNUM
1249 Setup_SerialNum PROC NEAR ;AN000;M
1250 mov s1_offset,offset SerNum+2 ;AN000;M
1251 mov s1_segment,ds ;AN000;M Setup segment
1252 mov s1_flags,BIN_HEX_WORD+RIGHT_ALIGN ;AN000;M Set up the parm formatting
1253 mov s1_maxwidth,DWORD ;AN000;M 0 ensures no padding
1254 mov s1_minwidth,DWORD ;AN000;M At least 1 char to insert
1255 mov s1_padchar,CHAR_ZERO ;AN000;M In case, pad with ZERO CHAR
1256 mov s2_offset,offset SerNum ;AN000;M
1257 mov s2_segment,ds ;AN000;M Setup segment
1258 mov s2_flags,BIN_HEX_WORD+RIGHT_ALIGN ;AN000;M Set up the parm formatting
1259 mov s2_maxwidth,DWORD ;AN000;M 0 ensures no padding
1260 mov s2_minwidth,DWORD ;AN000;M At least 1 char to insert
1261 mov s2_padchar,CHAR_ZERO ;AN000;M In case, pad with ZERO CHAR
1262 mov ax,7 ;AN000;M Utility's message number
1263 mov bx,STDOUT ;AN000;M Info msg, so stdout
1264 lea si,sublist1 ;AN000;M Display serial number
1265 mov cx,2 ;AN000;M Substitution count
1266 mov dl,NO_INPUT ;AN000;M No input characters
1267 mov dh,UTILITY_MSG_CLASS ;AN000;M Utility message class
1268 ret ;AN000;M
1269 Setup_SerialNum ENDP ;AN000;M
1270
1271 HEADER <SETUP_HASLABEL - "Volume in drive %1 is %2">
1272 ;*****************************************************************************
1273 ; Setup for utility messages
1274 ;*****************************************************************************
1275 ; Input: None
1276 ; Output: None
1277
1278 PUBLIC SETUP_HASLABEL
1279 Setup_HasLabel PROC NEAR ;AN000;M
1280 mov s1_offset,offset FCB_Drive_Char ;AN000;M
1281 mov s1_segment,ds ;AN000;M Setup segment
1282 mov s1_flags,CHAR_FIELD_CHAR ;AN000;M Set up the parm formatting
1283 mov s1_maxwidth,MAXWIDTH ;AN000;M 0 ensures no padding
1284 mov s1_minwidth,MINWIDTH ;AN000;M At least 1 char to insert
1285 mov s1_padchar,BLANK ;AN000;M In case, pad with blanks
1286 mov s2_offset,offset Label_Name ;AN000;M
1287 mov s2_segment,ds ;AN000;M Setup segment
1288 mov s2_flags,STR_INPUT ;AN000;M Set up the parm formatting
1289 mov s2_maxwidth,MAXWIDTH ;AN000;M 0 ensures no padding
1290 mov s2_minwidth,MINWIDTH ;AN000;M At least 1 char to insert
1291 mov s2_padchar,BLANK ;AN000;M In case, pad with blanks
1292 mov ax,5 ;AN000;M Utility's message number
1293 mov bx,STDOUT ;AN000;M Info msg, so stdout
1294 lea si,sublist1 ;AN000;M Display drive then label
1295 mov cx,2 ;AN000;M Substitution count
1296 mov dl,NO_INPUT ;AN000;M No input characters
1297 mov dh,UTILITY_MSG_CLASS ;AN000;M Utility message class
1298 ret ;AN000;M
1299 Setup_HasLabel ENDP ;AN000;M
1300
1301 HEADER <SETUP_DELLABEL - "Delete current volume label (Y/N)?">
1302 ;*****************************************************************************
1303 ; Setup for utility messages
1304 ;*****************************************************************************
1305 ; Input: None
1306 ; Output: None
1307
1308 PUBLIC SETUP_DELLABEL
1309 Setup_DelLabel PROC NEAR ;AN001;M
1310 mov ax,9 ;AN001;M Utility's message number
1311 mov bx,STDOUT ;AN001;M Info msg, so stdout
1312 mov cx,0 ;AN001;M Substitution count
1313 mov dl,DOS_CON_INPUT ;AN001;M Input Y/N character
1314 mov dh,UTILITY_MSG_CLASS ;AN001;M Utility message class
1315 ret ;AN001;M
1316 Setup_DelLabel ENDP ;AN001;M
1317
1318 HEADER <SETUP_CRLF - Carriage return, line feed>
1319 ;*****************************************************************************
1320 ; Setup for utility messages
1321 ;*****************************************************************************
1322 ; Input: None
1323 ; Output: None
1324
1325 PUBLIC SETUP_CRLF
1326 Setup_CRLF PROC NEAR ;AN001;M
1327 mov ax,10 ;AN001;M Utility's message number
1328 mov bx,STDOUT ;AN001;M Info msg, so stdout
1329 mov cx,0 ;AN001;M Substitution count
1330 mov dl,NO_INPUT ;AN001;M Input Y/N character
1331 mov dh,UTILITY_MSG_CLASS ;AN001;M No input characters
1332 ret ;AN001;M
1333 Setup_CRLF ENDP ;AN001;M
1334
1335 HEADER <ERROR_EXIT - ABNORMAL RETURN TO DOS>
1336 ;*****************************************************************************
1337 ; Error on exit
1338 ;*****************************************************************************
1339
1340 PUBLIC ERROR_EXIT
1341 Error_Exit PROC NEAR ;AC000;M
1342 mov ax,(EXIT SHL 8)+ERRORLEVEL_1 ;AN000;K Terminate, with ret code
1343 INT 21H
1344 Error_Exit ENDP ;AN000;M
1345
1346 End_Of_Program label byte
1347 Public End_Of_Program
1348
1349 CSEG ends
1350 end Start
1351 \1a