1 PAGE
90,132 ;\ f\eA\b\e2
2 title
LABEL.SAL - DOS
LABEL COMMAND
3 ;*****************************************************************************
5 ;* MODULE NAME: LABEL *
7 ;* DESCRIPTIVE NAME: LABEL a diskette or disk *
9 ;* FUNCTION: Create, change or delete a volume label on a disk. *
11 ;* ENTRY POINT: Start *
13 ;* INPUT: (DOS command line parameters) *
14 ;* [d:][path]LABEL [d:][volume label] *
16 ;* [d:][path] before LABEL specifies the drive and path that contains *
17 ;* the LABEL command file. *
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. *
23 ;* EXIT-NORMAL: ERRORLEVEL 0 - Normal completion *
25 ;* EXIT-ERROR: ERRORLEVEL 1 - Any error *
27 ;* EFFECTS: The volume label is set to the indicated string. The volume *
28 ;* serial number, if present, is also displayed. *
30 ;* INCLUDED FILES: None *
32 ;* INTERNAL REFERENCES: *
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" *
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 *
76 ;* EXTERNAL REFERENCES: *
79 ;* SYSDISPMSG (NEAR) - Message display routine *
80 ;* SYSLOADMSG (NEAR) - System message loader *
83 ;* DTA - defined for the DOS FINDFIRST function. *
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. * *
89 ;* This module should be processed with the SALUT pre-processor *
90 ;* with the re-alignment not requested, as: *
94 ;* To assemble these modules, the sequential or alphabetical *
95 ;* ordering of segments may be used. *
97 ;* Sample LINK command: *
101 ;* Where the LABEL.ARF is defined as: *
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. *
109 ;* REVISION HISTORY: *
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 *
120 ;* COPYRIGHT: The following notice is found in the OBJ code generated *
121 ;* in the LABELM.SAL module. *
123 ;* "Version 4.00 (C)Copyright 1988 Microsoft
124 ;* "Licensed Material - Program Property of Microsoft" *
126 ;*****************************************************************************
127 HEADER
<DEFINITIONS
- LOCAL MACROS
AND LOCAL EQUATES
>
129 %
OUT COMPONENT
=LABEL, MODULE
=LABEL.SAL
137 ;*****************************************************************************
139 ;*****************************************************************************
140 ; $SALUT (4,20,25,36) ;AN000;K
149 LOC_OR_NET equ 9h
;AN000;K Local or network, subfunc of IOCTL
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;
157 ; DBCS SPECIAL CHARACTER DEFINITIONS
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
163 ; MISCELLANEOUS EQUATES
165 ASCII_DRV equ
"A"-1 ;AN000;D Convert to Ascii drive
167 CHAR_ZERO equ
"0" ;AN000;K Padding for serial number
171 DRIVE_INVALID equ
0FFh
174 MAX_INPUT equ 100h
-81h
;Size of input buffer
175 NO equ
0 ;AN001; Compare for Y/N response
177 YES equ
1 ;AN001; Compare for Y/N response
180 ; ERROR LEVEL RETURN CODES
185 ; ATTRIBUTE OF DIRECTORY ENTRY
189 ; ERROR CODES FROM DOS FUNCTIONS
191 VOL_NOT_FOUND equ
0FFh
194 ; ID IF MESSAGES DISPLAYED BY "LABEL"
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
209 ; DEFINITIONS OF FIELDS WITHIN MSG SUBLISTS
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
>
230 ASSUME
cs:CSEG
,ds:CSEG
,es:CSEG
,ss:CSEG
232 EXTRN SYSDISPMSG
:NEAR ;SYSTEM DISPLAY MESSAGE ROUTINE
233 EXTRN SYSLOADMSG
:NEAR ;SYSTEM MESSAGE LOADER ROUTINE
245 Start: ;DOS ENTRY POINT
246 jmp Main_Begin
;SKIP CONSTANTS
247 HEADER
<DATA AREAS
- STACK, BUFFERS
, FCB
'S
, MESSAGE SUBLISTS
>
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
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
264 Vol_FCB db 0FFh ;Extended FCB
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
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
277 Del_FCB db 0FFh ;Extended FCB
279 db VOL_ATTRIBUTE ;Attribute for vol label
280 Del_Drive db 0 ;Drive number
281 Del_Name db "???????????
" ;Match any vol name found
283 ; MESSAGE SUBLIST STRUCTURES
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
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
307 ; GET_MEDIA_ID STRUCTURE
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
316 DBCSev_Off dw 0 ;AC000;D offset of DBCS EV
317 DBCSev_Seg dw 0 ;AC000;D segment of DBCS EV
319 HEADER <MAIN_BEGIN - HIGH LEVEL FUNCTION CONTROL>
320 ; $SALUT (4,4,9,36) ;AN000;K
321 ;*****************************************************************************
323 ;* SUBROUTINE NAME: main_begin *
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 *
336 ;* EXTERNAL ROUTINES: SYSDISPMSG *
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 *
356 ;*****************************************************************************
359 mov sp,offset End_Stack_Area ;Move stack to user area(Added in DOS 3.20)
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
372 HEADER <DRIVE_SETUP - VERIFY DRIVE, GET DEFAULT, SETUP DRIVE ID>
373 ;*****************************************************************************
374 ; Verify specified drive, get default if needed, setup drive letters
375 ;*****************************************************************************
378 Drive_Setup PROC NEAR
379 cmp al,DRIVE_INVALID ;Was specified drive ok ?
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
389 mov al,FCB1 ;Get specified drive
390 cmp al,DEFAULT_DRIVE ;Was drive given ?
393 mov ah,GET_DEFAULT ;No, get default drive
395 inc al ;Get a: based on 1, not 0
399 mov FCB_Drive,al ;Put drive number in FCB
400 mov Del_Drive,al ;Put drive number in FCB
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
407 test dx,1000h ;bit 12 on means network drive
410 mov ax,NETWORKDRIVEMSG
411 call Setup_NetDrive ;AN000;M
412 call Display_Msg ;AN000;M First display the msg
416 call Check_Trans_Drive ;AN000;A Is drv SUBSTed/ASSIGNed?
417 ; $if nz ;AN000;K Yes
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
426 add al,ASCII_DRV ;AN000;K ("A
"-1) Convert to Ascii
427 mov New_Vol_Path,al ;Put drive letter in path
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
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
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?
450 Check_Trans_Drive ENDP
;AN000;A
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
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)
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
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
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
492 Get_New_Label PROC
NEAR
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
506 cmp New_Vol_Name
,END_OF_STRING
;Any chars entered?
507 ; $leave ne ;Yes, all done here
509 test Program_Flag
,USER_INPUT
;See if command line parse
510 ; $leave nz ;No, user had his chance
513 test Program_Flag
,USER_INPUT
;Is this the first time here?
514 ; $if z ;AN000;K Yes, label not already gone out
516 call Output_Old_Label
;Yes, print current vol label
520 call Get_User_Input
;Get new string
521 ; $enddo ;AN000;K Go parse it again
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
536 PUBLIC FIND_FIRST_CHAR
537 Find_First_Char PROC
NEAR
540 and Program_Flag
,not GET_INPUT
;Clear flag
542 call Chk_DBCS
;AN000;D Check DBCS env
545 call Chk_DBCS_Blank
;AN000;D Is it a DBCS blank?
548 cmp al,BLANK
;Is it a blank?
549 ; $enddo ne ;AN000;K No, quit
551 call Check_For_Drive_Letter
;Parse out drive letter
552 call Chk_DBCS
;AN000;D Check DBCS env
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
559 cmp al,BLANK
;Blank following drive letter?
562 or Program_Flag
,GET_INPUT
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.
578 Chk_DBCS PROC
;AC000;D
579 push ds ;AC000;D save regs, about to be clobbered
581 cmp DBCSev_Seg
,ZERO
;AC000;D Already set ?
582 ; $if e ;AN000;K if the vector not yet found
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
593 mov si,DBCSev_Off
;AC000;D set DS:SI to point to
594 mov ds,DBCSev_Seg
;AC000;D the dbcs vector
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
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
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
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
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
615 clc ;AC000;D set flag to say not a DBCS char
618 pop si ;AC000;D restore the regs
620 ASSUME
ds:CSEG
;AN000;K tell masm, DS back to normal
622 Chk_DBCS ENDP
;AC000;D
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
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?
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
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
646 ; DBCS_Blank_Exit: ;AN000;D
647 ret ;AN000;D And leave
648 Chk_DBCS_Blank ENDP
;AN000;D
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
658 PUBLIC CHECK_FOR_DRIVE_LETTER
659 Check_For_Drive_Letter PROC
NEAR
660 test Program_Flag
,USER_INPUT
;Input not from command line?
663 cmp cx,END_OF_STRING
;Anything parsed yet
666 cmp al,CR
;First char a CR ?
669 cmp byte ptr [si],COLON
;Drive letter entered?
672 inc si ;Yes, point past the colon
673 lodsb ;And get next character
684 Check_For_Drive_Letter ENDP
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.
698 PUBLIC PROCESS_STRING
699 Process_String PROC
NEAR
700 cmp al,CR
;is it an ENTER ?
703 test Program_Flag
,USER_INPUT
;has user been told to provide input?
704 ; $if nz ;If user has been prompted for input
706 cmp cx,ZERO
;And he said - nothing
709 jmp Process_String_Return
;AN001; ENTER is acceptable
714 ; $else ;Since got other than just ENTER
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
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
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
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
745 lodsb ;Get next character
746 cmp cx,MAX_INPUT
;AN002; Have we reached end?
747 jne Process_String
;No, go diddle with it
750 Process_String_Return:
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
762 PUBLIC CHARACTER_CHECK
763 Character_Check PROC
NEAR
764 or Program_Flag
,CHAR_BAD
;Assume bad character
799 and Program_Flag,not CHAR_BAD ;Char is ok
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
810 ; Notes: Print the volume label
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
819 mov ax,NO_LABEL_MSG ;No, other message
820 call Setup_NoLabel ;AN000;M
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
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
833 Output_Old_Label ENDP
835 HEADER <GET_SERIAL_NUM - GET VOL SER NUMBER FROM "GET_MEDIA_ID">
836 ;*****************************************************************************
837 ; Get the volume serial number
838 ;*****************************************************************************
840 ; Output: SerNum if no carry
841 ; Notes: Only DOS Version 4.0 and above will contain serial numbers
843 PUBLIC GET_SERIAL_NUM
844 Get_Serial_Num PROC NEAR ;AN000;S
845 mov ax,GET_MEDIA_ID ;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
851 Get_Serial_Num ENDP ;AN000;S
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
861 PUBLIC GET_USER_INPUT
862 Get_User_Input PROC NEAR
863 test Program_Flag,CHAR_BAD ;Do we need bad char message
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
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
880 or Program_Flag,USER_INPUT ;Indicate user input has been received
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
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
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
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.
928 PUBLIC DELETE_OLD_LABEL
929 Delete_Old_Label PROC NEAR
930 test Program_Flag,NO_DELETE ;Need to delete label ?
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
939 Delete_Old_Label ENDP
941 HEADER <CREATE_NEW_LABEL - OUTPUT NEW VOL LABEL>
942 ;*****************************************************************************
943 ; Create new volume label file if user specified one
944 ;*****************************************************************************
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
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
957 mov bx,ax ;shift file handle
958 mov ah,CLOSE ;And close the file
960 ; $else ;AN000;K since there was creation error,
963 cmp ax,TOO_MANY_FILES ;Is it
964 ; $if ne ;AN000;K if not "too many files", then
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,
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 "."
978 inc di ;AN000;K skip the "."
979 mov cx,3 ;AN000;K length of extension
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?
987 ; $else ;AN000;K since is "too many files", then...
990 mov ax,TOO_MANY_MSG ;AN000;M
991 call Setup_TooMany ;AN000;M
992 call Display_Msg ;AN000;M
995 jmp Error_Exit ;Tell user bad news and quit
1001 Create_New_Label ENDP
1003 HEADER <PRELOAD_MESSAGES - SET UP SYS MSGS, DOS VERSION CHK>
1004 ;*****************************************************************************
1005 ; Preload utility messages
1006 ;*****************************************************************************
1009 ; Notes: Checks DOS version, if incorrect, or if error loading messages, will
1010 ; display error message and terminate
1012 PUBLIC PRELOAD_MESSAGES
1013 Preload_Messages PROC NEAR ;AN000;M
1019 call SYSLOADMSG ;AN000;M Load msgs & chk DOS ver
1022 call SYSDISPMSG ;AN000;M
1028 call Error_Exit ;AN000;M
1037 Preload_Messages ENDP ;AN000;M
1039 HEADER <DISPLAY_MSG - SEND MSG TO SYSTEM MESSAGE HANDLER>
1040 ;*****************************************************************************
1041 ; Display utility messages
1042 ;*****************************************************************************
1043 ; Input: dx contains the messsage to display
1045 ; Notes: The message called is displayed to stdout/stderr unless AX returns
1046 ; with error code (then setup for extended error to display)
1049 Display_Msg PROC NEAR ;AN000;M
1054 call SYSDISPMSG ;AN000;M Now display the message
1055 ; $if c ;AN000;K if there was a problem, then...
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
1066 call Error_Exit ;AN000;M Nothing we can do so leave
1074 ret ;AN000;M Bye,bye
1075 Display_Msg ENDP ;AN000;M
1077 HEADER <SETUP_TOOMANY - "Too many files open">
1078 ;*****************************************************************************
1079 ; Setup for utility messages
1080 ;*****************************************************************************
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
1094 HEADER <SETUP_NOROOM - "Cannot make directory entry">
1095 ;*****************************************************************************
1096 ; Setup for utility messages
1097 ;*****************************************************************************
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
1111 HEADER <SETUP_INVCHAR - "Invalid characters in volume label">
1112 ;*****************************************************************************
1113 ; Setup for utility messages
1114 ;*****************************************************************************
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
1126 Setup_InvChar ENDP ;AN000;M
1128 HEADER <SETUP_NEWLABEL - "Volume label (11 characters, ENTER for none)?">
1129 ;*****************************************************************************
1130 ; Setup for utility messages
1131 ;*****************************************************************************
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
1143 Setup_NewLabel ENDP ;AN000;M
1145 HEADER <SETUP_INVDRIVE - "Invalid drive specification">
1146 ;*****************************************************************************
1147 ; Setup for utility messages
1148 ;*****************************************************************************
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
1167 Setup_InvDrive ENDP ;AN000;M
1169 HEADER <SETUP_NETDRIVE - "Cannot %1 a Network drive">
1170 ;*****************************************************************************
1171 ; Setup for utility messages
1172 ;*****************************************************************************
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
1191 Setup_NetDrive ENDP ;AN000;M
1193 HEADER <SETUP_SUBSTASGN - "Cannot %1 a SUBSTed or ASSIGNed drive">
1194 ;*****************************************************************************
1195 ; Setup for utility messages
1196 ;*****************************************************************************
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
1215 Setup_SubstAsgn ENDP ;AN000;M
1217 HEADER <SETUP_NOLABEL - "Volume in drive %1 has no label">
1218 ;*****************************************************************************
1219 ; Setup for utility messages
1220 ;*****************************************************************************
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
1239 Setup_NoLabel ENDP ;AN000;M
1241 HEADER <SETUP_SERIALNUM - "Volume Serial Number is %1-%2">
1242 ;*****************************************************************************
1243 ; Setup for utility messages
1244 ;*****************************************************************************
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
1269 Setup_SerialNum ENDP ;AN000;M
1271 HEADER <SETUP_HASLABEL - "Volume in drive %1 is %2">
1272 ;*****************************************************************************
1273 ; Setup for utility messages
1274 ;*****************************************************************************
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
1299 Setup_HasLabel ENDP ;AN000;M
1301 HEADER <SETUP_DELLABEL - "Delete current volume label (Y/N)?">
1302 ;*****************************************************************************
1303 ; Setup for utility messages
1304 ;*****************************************************************************
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
1316 Setup_DelLabel ENDP ;AN001;M
1318 HEADER <SETUP_CRLF - Carriage return, line feed>
1319 ;*****************************************************************************
1320 ; Setup for utility messages
1321 ;*****************************************************************************
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
1333 Setup_CRLF ENDP ;AN001;M
1335 HEADER <ERROR_EXIT - ABNORMAL RETURN TO DOS>
1336 ;*****************************************************************************
1338 ;*****************************************************************************
1341 Error_Exit PROC NEAR ;AC000;M
1342 mov ax,(EXIT SHL 8)+ERRORLEVEL_1 ;AN000;K Terminate, with ret code
1344 Error_Exit ENDP ;AN000;M
1346 End_Of_Program label byte
1347 Public End_Of_Program