summaryrefslogtreecommitdiff
path: root/v4.0/src/CMD/LABEL/LABEL.ASM
diff options
context:
space:
mode:
Diffstat (limited to 'v4.0/src/CMD/LABEL/LABEL.ASM')
-rw-r--r--v4.0/src/CMD/LABEL/LABEL.ASM1351
1 files changed, 1351 insertions, 0 deletions
diff --git a/v4.0/src/CMD/LABEL/LABEL.ASM b/v4.0/src/CMD/LABEL/LABEL.ASM
new file mode 100644
index 0000000..c29d5b7
--- /dev/null
+++ b/v4.0/src/CMD/LABEL/LABEL.ASM
@@ -0,0 +1,1351 @@
1 PAGE 90,132 ;A2
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>
128IF1
129 %OUT COMPONENT=LABEL, MODULE=LABEL.SAL
130ENDIF
131HEADER 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
142FCB_SEARCH equ 11h
143FCB_DELETE equ 13h
144GET_DEFAULT equ 19h
145SET_DTA equ 1Ah
146CLOSE equ 3Eh
147READ equ 3Fh
148IOCTL equ 44h
149LOC_OR_NET equ 9h ;AN000;K Local or network, subfunc of IOCTL
150EXIT equ 4Ch
151CREATE_FILE equ 5Bh
152YN_CHECK equ 6523h ;AN001; 65=GetExtCtry 23=Y/NCheck
153GET_MEDIA_ID equ 6900h ;AN000;S Int 21 for Serial Number
154GET_DBCS_ENV equ 6300h ;AN000;D DBCS support
155XNAMETRANS equ 60h ;AN000;
156
157; DBCS SPECIAL CHARACTER DEFINITIONS
158
159DBCSBLK_BYTEONE equ 81h ;AN000;D 1st byte of DBCS blank
160DBCSBLK_BYTETWO equ 40h ;AN000;D 2nd byte of DBCS blank
161SBCSBLANKS equ 2020h ;AN000;D 2 SBCS blanks
162
163; MISCELLANEOUS EQUATES
164
165ASCII_DRV equ "A"-1 ;AN000;D Convert to Ascii drive
166BLANK equ " "
167CHAR_ZERO equ "0" ;AN000;K Padding for serial number
168COLON equ ":"
169DEFAULT_DRIVE equ 0
170DOT_LOCATION equ 8
171DRIVE_INVALID equ 0FFh
172END_OF_STRING equ 0
173MAX_CHARS equ 11
174MAX_INPUT equ 100h-81h ;Size of input buffer
175NO equ 0 ;AN001; Compare for Y/N response
176PERIOD equ "."
177YES equ 1 ;AN001; Compare for Y/N response
178ZERO equ 0
179
180; ERROR LEVEL RETURN CODES
181
182ERRORLEVEL_0 equ 0
183ERRORLEVEL_1 equ 1
184
185; ATTRIBUTE OF DIRECTORY ENTRY
186
187VOL_ATTRIBUTE equ 8
188
189; ERROR CODES FROM DOS FUNCTIONS
190
191VOL_NOT_FOUND equ 0FFh
192TOO_MANY_FILES equ 4
193
194; ID IF MESSAGES DISPLAYED BY "LABEL"
195
196TOO_MANY_MSG equ 1 ;AN000;M Too many files open
197NO_ROOM_MSG equ 2 ;AN000;M Cannot make directory entry
198INV_CHAR_MSG equ 3 ;AN000;M Invalid characters in volume label
199NEW_LABEL_MSG equ 4 ;AN000;M Vol label (11 chars, ENTER for none)?
200INV_DRIVE_MSG equ 5 ;AN000;M Invalid drive specification
201NETWORKDRIVEMSG equ 6 ;AN000;M Cannot %1 a Network drive
202SUBSTASSIGNMSG equ 7 ;AN000;M Cannot %1 a SUBSTed or ASSIGNed drive
203NO_LABEL_MSG equ 8 ;AN000;M Volume in drive %1 has no label
204SERIAL_NUM_MSG equ 9 ;AN000;M Volume Serial Number is %1
205HAS_LABEL_MSG equ 10 ;AN000;M Volume in Drive %1 is %2
206DEL_LABEL_MSG equ 11 ;AN001;M Delete current volume label (Y/N)?
207CRLF_MSG equ 12 ;AN001;M CR,LF
208
209; DEFINITIONS OF FIELDS WITHIN MSG SUBLISTS
210
211MAXWIDTH equ 0 ;AN000;M 0 will ensure no padding
212MINWIDTH equ 1 ;AN000;M At least 1 char to insert in msg
213STR_INPUT equ 16 ;AN000;M Byte definition for s?_flags
214SUBLIST_LENGTH equ 11 ;AN000;M Length of sublist structure
215RESERVED equ 0 ;AN000;M Reserved byte field
216CR equ 0Dh ;Carriage Return
217NO_INPUT equ 00h ;AN000;M No input characters
218DOS_CON_INPUT equ 00C8h ;AN000;M No input characters
219EXT_ERR_CLASS equ 01h ;AN000;M DOS Extended error class
220UTILITY_MSG_CLASS equ 0FFh ;AN000;M Utility message class
221STDIN equ 0000h ;File handle
222STDOUT equ 0001h ;Standard Output device handle
223STDERR equ 0002h ;Standard Error Output device handle
224BIN_HEX_WORD equ 23h ;AN000;M a0100011
225RIGHT_ALIGN equ 80h ;AN000;M 10xxxxxx
226CHAR_FIELD_CHAR equ 0 ;AN000;M a0000000
227 HEADER <MAIN CODE - PSP, ENTRY POINT>
228CSEG 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
236FCB1 label byte
237
238 org 80h
239Num_Parms label byte
240
241 org 81h
242Parm_Area label byte
243
244 org 100h
245Start: ;DOS ENTRY POINT
246 jmp Main_Begin ;SKIP CONSTANTS
247 HEADER <DATA AREAS - STACK, BUFFERS, FCB'S, MESSAGE SUBLISTS>
248 EVEN
249Stack_Area db 512 dup ("S") ;Added in DOS 3.20 to support hardware requiring
250End_Stack_Area db 0 ;large stacks. DO NOT PUT DATA ABOVE THIS !
251New_Vol_Path db " :\" ;Path for new vol label
252New_Vol_Name db " " ;Where first 8 chars go
253New_Vol_Ext db ". ",0 ;Dot and extension
254End_Parameters dw 0 ;End of input string
255
256Program_Flag db 0 ;Status Flag
257USER_INPUT equ 01h ;User has input already
258LABEL_FND equ 02h ;Volume label found
259NO_DELETE equ 04h ;No need for label delete
260GET_INPUT equ 08h ;Need user input
261CHAR_BAD equ 10h ;Invalid character in string
262FOUND_DBCS equ 20h ;AN000;K in process of handling DBCS chars
263
264Vol_FCB db 0FFh ;Extended FCB
265 db 0,0,0,0,0
266 db VOL_ATTRIBUTE ;Attribute for vol label
267FCB_Drive db 0 ;Drive number
268Vol_Name db "???????????" ;Match any vol name found
269 db 25 dup (0) ;Rest of the opened FCB
270Label_Name db "???????????",0 ;AN000;
271FCB_Drive_Char db " " ;AN000;K printable version of FCB_Drive above
272
273TranSrc db "A:CON",0,0 ;AN000;A Device so we don't hit the drive
274TranDst db 64 dup(' ') ;AN000;A
275Label_Word db "LABEL",0 ;AN000;M Message substitution parm
276
277Del_FCB db 0FFh ;Extended FCB
278 db 0,0,0,0,0
279 db VOL_ATTRIBUTE ;Attribute for vol label
280Del_Drive db 0 ;Drive number
281Del_Name db "???????????" ;Match any vol name found
282
283; MESSAGE SUBLIST STRUCTURES
284
285Sublist1 Label Dword ;AN000;M Substitution list
286s1_nxtlst db SUBLIST_LENGTH ;AN000;M (11)Ptr to next sublist
287s1_reserve db RESERVED ;AN000;M (0)Reserved
288s1_offset dw ? ;AN000;M Time/date or data pointer
289s1_segment dw ? ;AN000;M Time/date or data pointer
290s1_id db 1 ;AN000;M N of %n
291s1_flags db ? ;AN000;M Data-type flags (a0sstttt)
292s1_maxwidth db ? ;AN000;M Maximum field width
293s1_minwidth db ? ;AN000;M Minimum field width
294s1_padchar db ? ;AN000;M Char to pad field
295
296Sublist2 Label Dword ;AN000;M Substitution list
297s2_nxtlst db SUBLIST_LENGTH ;AN000;M (11)Ptr to next sublist
298s2_reserve db RESERVED ;AN000;M (0)Reserved
299s2_offset dw ? ;AN000;M Time/date or data pointer
300s2_segment dw ? ;AN000;M Time/date or data pointer
301s2_id db 2 ;AN000;M N of %n
302s2_flags db ? ;AN000;M Data-type flags (a0sstttt)
303s2_maxwidth db ? ;AN000;M Maximum field width
304s2_minwidth db ? ;AN000;M Minimum field width
305s2_padchar db ? ;AN000;M Char to pad field
306
307; GET_MEDIA_ID STRUCTURE
308
309SerNumBuf Label Byte ;AN000;S GET_MEDIA_ID buffer
310 dw 0 ;AN000;S Info level (set on input)
311SerNum 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
316DBCSev_Off dw 0 ;AC000;D offset of DBCS EV
317DBCSev_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
358Main_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
370Main_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
378Drive_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
429Drive_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
440Check_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
450Check_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
462Find_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
481Find_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
492Get_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
512Need_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:
519Input_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
525Get_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
537Find_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
566Find_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
578Chk_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
622Chk_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
634Chk_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
648Chk_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
659Check_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:
682Drive_Letter_Ret:
683 ret
684Check_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
699Process_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
723Do_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
730Check_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
736Got_Ok_Character:
737 stosb ;Good char, store it
738Scan_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
744Get_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:
750Process_String_Return:
751 ret
752Process_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
763Character_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
800Char_Check_Done:
801 ret
802Character_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
813Output_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
833Output_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
844Get_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
851Get_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
862Get_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
882Get_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
893Check_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
898Delete_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
910Delete_Label: ;AN001;
911 or Program_Flag,NO_DELETE ;AN001; Yes, set flag
912Check_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;
917Check_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
929Delete_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
939Delete_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
947Create_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
1001Create_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
1013Preload_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
1037Preload_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
1049Display_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
1075Display_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
1085Setup_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
1092Setup_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
1102Setup_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
1109Setup_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
1119Setup_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
1126Setup_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
1136Setup_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
1143Setup_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
1153Setup_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
1167Setup_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
1177Setup_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
1191Setup_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
1201Setup_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
1215Setup_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
1225Setup_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
1239Setup_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
1249Setup_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
1269Setup_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
1279Setup_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
1299Setup_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
1309Setup_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
1316Setup_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
1326Setup_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
1333Setup_CRLF ENDP ;AN001;M
1334
1335 HEADER <ERROR_EXIT - ABNORMAL RETURN TO DOS>
1336;*****************************************************************************
1337; Error on exit
1338;*****************************************************************************
1339
1340 PUBLIC ERROR_EXIT
1341Error_Exit PROC NEAR ;AC000;M
1342 mov ax,(EXIT SHL 8)+ERRORLEVEL_1 ;AN000;K Terminate, with ret code
1343 INT 21H
1344Error_Exit ENDP ;AN000;M
1345
1346End_Of_Program label byte
1347 Public End_Of_Program
1348
1349CSEG ends
1350 end Start
1351 \ No newline at end of file