; $SALUT (4,25,30,41) ;******************* START OF SPECIFICATIONS *********************************** ; ; MODULE NAME: PRINT.COM ; ; DESCRIPTIVE NAME: DOS PRINT program for background printing of ; text files to the list device. ; ; FUNCTION: DOS PRINT program for background printing of ; text files to the list device. The utility is ; constructed of 3 .SAL files. They are: ; ; PRINT_R.SAL - The resident portion of PRINT ; PRINT_T.SAL - The transient portion of PRINT ; PRINT_SR.SAL - The service routines of PRINT ; ; NOTE: The Link order is VERY important for this module. ; This is due to the Resident/Transient nature of ; PRINT. ; ; INT 28H is a software interrupt generated by the ; DOS in its I/O wait loops. This spooler ; can be assembled for operation using only this ; interrupt which is portable from system to ; system. It may also be assembled to use a ; hardware timer interrupt in addition to the ; software INT 28H. The purpose of using ; hardware interrupts is to allow printing to ; continue during programs which do not enter ; the system and therefore causes the INT 28H to ; go away. A timer interrupt is chosen in ; preference to a "printer buffer empty" interrupt ; because PRINT in the timer form is generic. It ; can be given the name of any currently installed ; character device as the "printer", this makes it ; portable to devices which are installed by the ; user even in the hardware case. It could be ; Revised to use a buffer empty interrupt (no ; code is given for this case), if this is done ; the PROMPT and BADMES messages and their ; associated code should be removed as PRINT will ; then be device specific. ; ; NOTE From Aaron Reynolds ; ; BEWARE ALL YEE WHO ENTER HERE. ; PRINT is an amazingly complex program. MS-DOS versions below 3.00 are ; NOT re-entrant, this means that this utility is basically not a ; possibility. It gets by on the fact that it is written by the same ; person who wrote the OS. Since you are not that person, you must be very ; careful about making any modification to this utility. There are a ; number of things which may seem to be unnecessary on first examination. ; BEWARE, almost every line of code is there for a very good reason. The ; order of things is very carefully chosen. PRINT is full of potential ; windows, make sure that you do not open one by careless modification. Do ; not look for a lot of help from the comments, a complete explanation ; would probably fill a book. A succesful modifier will have an in-depth ; knowledge of the internal function of MS-DOS, and of the PRINT utility ; itself through in depth study of the comments AND the code. ; ; ENTRY POINT: ; ; INPUT: ; ; EXIT NORMAL: ; ; EXIT ERROR: ; ; INTERNAL REFERENCES: ; ; ROUTINES: ; ; DATA AREAS: ; ; EXTERNAL REFERENCES: ; ; ROUTINES: ; ; DATA AREAS: ; ; NOTES: ; ; REVISION HISTORY: Ax000 Version 4.0 05/01/87 - first release FG ; Ax001 DCR D201 - Extended Atrib change FG ; Ax002 P 1175 - move msgs back to TRANS FG ; Ax003 P 1487 - PARSE error message problemFG ; Ax004 P 1546 - PARSE error trailing : FG ; Ax005 P 1717 - multiples of same switch FG ; Ax006 P 1996 - Extended open error FG ; Ax007 P 2052 - [PRN] prompt lpt1 error FG ; Ax008 P 2053 - CPSW prints empty file FG ; Ax009 P 2229 - filename truncation FG ; Ax010 D 389 - use transname /server DOS FG ; Ax011 P 3122 - attrib missing /server DOS FG ; Ax012 P 3949 - Error in opening an open FG ; Ax013 P 3949 - open mode - second attempt FG ; Ax014 P 4396 - some messages need STDOUT FG ; Ax015 P 4880 - DRIVERS not recognized FG ; ; PRE-VERSION 4.0 HISTORY: ; ; V1.00 07/03/82 ; V2.00 07/05/83 A.R ; New INT 2FH interface, Pathnames, context switch. ; V2.50 09/14/83 M.A.U ; Turned it back to a print ; 11/21/83 M.A.U ; Repaired bug in file cancel code ; 11/28/83 M.A.U ; Added int 23 and 24 handlers to transient. ; 01/27/84 M.A.U ; Allways checks for valid drive. ; V3.00 02/03/84 M.A.U ; Partitioned so as to assemble on a PC ; By the by, it is V3.00 now. ; 05/23/85 K.G.S ; Chains into INT19 (bootstrap) to unhook ; INT_1C (timer) and INT_15 (AT's Wait On Event) ; ; COPYRIGHT: "The DOS PRINT Utility" ; "Version 4.00 (C) Copyright 1988 Microsoft ; "Licenced Material - Program Property of Microsoft" ; ; ;******************* END OF SPECIFICATIONS ************************************* subttl PRINT - Program Organization page ;******************* START PROGRAM ORGANIZATION ******************************* ; ; ;Group / Label Contents File ; ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ Ä¿ ;CODER ³ Data buffer ³ à PRINT_RM ; ÃÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ´ ÄÙ ; ³ ³ Ä¿ ; ³ Resident ³ ³ ; ³ Code ³ ³ ; ³ ³ ³ ;filequeue --- ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ³ ; ³ Resident ³ ³ ; ³ Initalization³ ÃÄ PRINT_R ; ³ Code ³ ³ ; ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ³ ; ÃÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ´ ÄÙ ; ³ CL1 data ³ ³ ; ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ³ ; ³ CL2 data ³ ; ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ³ ; ³ CLB data ³ ³ ; ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ÃÄ PRINT_TM ; ³ CLC data ³ ³ ; ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ³ ; ³ CLD data ³ ³ ; ÃÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ´ ÄÙ ;DG ³ Transient ³ Ä¿ ; ³ code ³ ³ ; ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ³ ; ³ DispMsg ³ ³ ; ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ³ ; ³ SYSMSG ³ ³ ; ³ Code ³ ³ ; ³ Parser ³ ³ ; ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ³ ; ³ Transient ³ ÃÄ PRINT_T ; ³ data ³ ³ ; ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ³ ; ³ Stack ³ ³ ;transsize --- ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ÄÙ ; ; ;******************* END ROGRAM ORGANIZATION ******************************** subttl PRINT - Data Space page INCLUDE SYSVAR.INC FALSE EQU 0 TRUE EQU NOT FALSE IBM EQU IBMVER ;IBMVER EQU IBM ;MSVER EQU FALSE IF MSVER HARDINT EQU FALSE ;No hardware ints AINT EQU FALSE ;No need to do interrupt acknowledge ENDIF IF IBM HARDINT EQU TRUE INTLOC EQU 1CH ;Hardware interrupt location (Timer) REBOOT EQU 19H ;ROM BIOS "Bootstrap" AINT EQU TRUE ;Acknowledge interrupts EOI EQU 20H ;End Of Interrupt "instruction" AKPORT EQU 20H ;Interrupt Acknowledge port ENDIF ; The following values have to do with the ERRCNT variable and the CNTMES ; message. The values define levels at wich it is assumed an off-line error ; exists. ERRCNT1 defines the value of ERRCNT above which the CNTMES message ; is printed by the transient. ERRCNT2 defines the value of ERRCNT above ; which the resident will give up trying to print messages on the printer, it ; is much greater than ERRCNT1 because a much tighter loop is involved. The ; bounding event which determines the correct value is the time required to ; do a form feed. IF IBM ERRCNT1 EQU 1500 ERRCNT2 EQU 20000 ELSE ERRCNT1 EQU 1500 ERRCNT2 EQU 20000 ENDIF ;WARNING DANGER WARNING: ; PRINT is a systems utility. It is clearly understood that it may have ; to be entirely re-written for future versions of MS-DOS. The following ; TWO vectors are version specific, they may not exist at all in future ; versions. If they do exist, they may function differently. ; ANY PROGRAM WHICH IMITATES PRINTS USE OF THESE VECTORS IS ALSO A SYSTEMS ; UTILITY AND IS THEREFORE NOT VERSION PORTABLE IN ANY WAY SHAPE OR FORM. ; YOU HAVE BEEN WARNED, "I DID IT THE SAME WAY PRINT DID" IS NOT AN REASON ; TO EXPECT A PROGRAM TO WORK ON FUTURE VERSIONS OF MS-DOS. SOFTINT EQU 28H ;Software interrupt generated by DOS ComInt EQU 2FH ;Communications interrupt used by PSPRINT ; Multiplex number 0 and 1 ;----- Default (and Maximal / Minimal) Print queue length MinQueueLen equ 4 ; 4 files worth min MaxQueueLen equ 32 ; 32 files worth max. DefQueueLen equ 10 ; 10 files worth ;----- Default (and Maximal / Minimal) Print buffer length MinBufferLen equ 512 ; set minimum to 512 bytes MaxBufferLen equ 1024 * 16 ; maximum is 16 K bytes DefBufferLen equ MinBufferLen ; set default to minimum ;----- Default (and Maximal / Minimal) Time Slice MinTimeSlice equ 1 ; set minimum to 1 MaxTimeSlice equ 255 ; maximum is 255 DefTimeSlice equ 10 ; set default to 10 ;----- Default (and Maximal / Minimal) Busy Tick MinBusyTick equ 1 ; set minimum to 1 MaxBusyTick equ 255 ; maximum is 255 DefBusyTick equ MinBusyTick ; set default to minimum ;----- Default (and Maximal / Minimal) Max Tick MinMaxTick equ 1 ; set minimum to 1 MaxMaxTick equ 255 ; maximum is 255 DefMaxTick equ 2 ; set default to 2 ;----- Maximum length of a file name (incl nul) MaxFileLen equ 64 ; **************** Bogosity Warning ***************** ; Below is the equate that MaxFile SHOULD be. Since the 3.0/3.1 documentation ; documents each queue entry as being 64 chars long. Yes it is known that ; that causes Print to misbehave on files deep in trees. But for ; compatibilities sake, IBM insisted that we change the code back to the ; way it was. ;MaxFileLen equ 63 + 2 + 12 ; 63 characters as Command.com's ; max. path length ; 2 character for the Drive ext. ; 12 characters for the max. valid ; DOS filename ;---------------------------------------- ; definition of the MODE bits ; for an extended open ;---------------------------------------- ; BITS DEFINED FOR THE MODE WORD ; FORMAT = 0WF00000ISSS0AAA ; Write ÄÄÄÄÄÄÄÄÄÄÄÙ³ ³³ ÀÄÄÄ Access code ; 0 = no commit ³ ³³ 0 = read ; 1 = auto commit ³ ³³ 1 = write ; ³ ³³ 2 = read/write ; Fail action ÄÄÄÄÄÄÄÄÄÄÄÄÙ ³³ 3 = execute ; 0 = INT 24h ³³ 4 = FCB ; 1 = return error ³³ ; ³ÀÄÄÄ Sharing mode ; ³ 0 = compatability ; ³ 1 = deny read/write ; ³ 2 = deny write ; ³ 3 = deny read ; ³ 4 = deny none ; Inherit ; 0 = pass handle to child ; 1 = no inherit ; MODE_COM equ 0100000000000000b ; Auto Commit MODE_NO24 equ 0010000000000000b ; No 24 - return error MODE_NOINH equ 0000000010000000b ; No child procees access ; Sharing mode MODE_SH_COMP equ 0000000000000000b ; 0 = compatability MODE_SH_D_RW equ 0000000000010000b ; 1 = deny read/write MODE_SH_D_W equ 0000000000100000b ; 2 = deny write MODE_SH_D_R equ 0000000000110000b ; 3 = deny read MODE_SH_D_NONE equ 0000000001000000b ; 4 = deny none ; Access code MODE_AC_R equ 0000000000000000b ; 0 = read MODE_AC_W equ 0000000000000001b ; 1 = write MODE_AC_RW equ 0000000000000010b ; 2 = read/write MODE_AC_EXE equ 0000000000000011b ; 3 = execute MODE_AC_FCB equ 0000000000000100b ; 4 = FCB GET_CPSW equ 3 ; Get state of CPSW CPSW_on equ 1 ; CPSW is active major_code equ 0ADh ; INT 2F PRINT semaphore minor_code equ 040h ; INT 2F PRINTER set and lock CP ; ; The Extended Open mode is set as: ; Shareing Mode - Compatability ; Access - Read ; Inharitance - yes ; -- WARNING ---- ; These MUST be set this way ; in order to do a second open ; of a file accross the network open_mode equ MODE_NO24+MODE_SH_COMP+MODE_AC_R ;AC013; ignore_cp equ 1 ; dont validate CP - it may be different ; than CON openit equ 1 ; extended open 'exsists' action failopen equ 0 ; extended open 'does not exsist' action Cap_ASCIIZ equ 22h ; Capitalize ASCIIZ string (INT 21 - 65) ;----- Message related information ;================================================ ; PRINT Message Skeleton File ;================================================ ;util PRINT ;class 1 ;use EXTEND19 ;use EXTEND20 ;use EXTEND21 ;use EXTEND22 ;use EXTEND23 ;use EXTEND24 ;use EXTEND25 ;use EXTEND26 ;use EXTEND27 ;use EXTEND28 ;use EXTEND29 ;use EXTEND30 ;use EXTEND31 ;class 2 ;1 - Too many operands ;2 - Required operand missing ;use PARSE3 ;3 - Not in switch list provided ;4 - Not in keyword list provided ;use PARSE6 ;6 - Out of range specified ;7 - Not in value list provided ;8 - Not in string list provided ;use PARSE9 ;9 - Invalid Parameter ;class A ;def 6 " error reading file",CR,LF,"$" ;def 7 "File not found",CR,LF,"$" ;def 8 CR,LF,LF,"File $" ;def 9 " canceled by operator$" ;def 10 CR,LF,LF,"All files canceled by operator$" ;def 11 "File allocation table bad drive " ;def 12 "A.",CR,LF,"$" ;def 13 "List output is not assigned to a device",CR,LF ;def 14 "Resident part of PRINT installed",CR,LF ;class B ;use 1 COMMON1 ;def 2 CR,LF ;def 15 "Cannot use PRINT - Use NET PRINT",CR,LF ;def 17 "PRINT queue is full",CR,LF ;def 18 "PRINT queue is empty",CR,LF ;def 19 "Access denied",CR,LF ;def 20 "Invalid drive specification",CR,LF ;def 21 "Errors on list device indicate that it",CR,LF ; "may be off-line. Please check it.",CR,LF ;class C ;def 22 CR,LF,LF," %1 is currently being printed",CR,LF ;def 23 " %1 is in queue",CR,LF ;use 24 EXTEND2 ;def 25 "Pathname too long",CR,LF ;def 26 "File not in PRINT queue",CR,LF ;class D ;def 27 "Name of list device [PRN]: " ;end ;-------------------------------------- ; PRINT Equates ;-------------------------------------- MesSerCLASS equ 0 ; Message Service class DOS_error equ 1 ; DOS extended error Parse_error equ 2 ; Parse error CLASS_A equ 0Ah ; PRINT_R message CLASS_B equ 0Bh ; PRINT_T message CLASS_C equ 0Ch ; PRINT_T message with insert CLASS_D equ 0Dh ; PRINT_T message with input buffer where: CLASS_Util equ 0FFh ; PRINT utility message (Class A - D) buffered_input equ 0Ah ; Buffered keyboard input ; CLASS 1 ERR0 equ 19 ERR12 equ 31 ; CLASS 2 INVPARM equ 9 ; Invalid parameter (PARSE) ; CLASS A ERRMEST equ 6 ; error reading file ErrMesT2 equ 7 ; File not found CanMes equ 8 ; File CanFilNam equ 9 ; canceled by operator AllCan equ 10 ; All files canceled by operator FATMES equ 11 ; File allocation table bad drive BADDRVM equ 12 ; A. BADMES equ 13 ; List output is not assigned to a device GOODMES equ 14 ; Resident part of PRINT installed ; CLASS B NEXT_LINE equ 2 ; advance to next line CONFLICTMES equ 15 ; Cannot use PRINT - Use NET PRINT FULLMES equ 17 ; PRINT queue is full NoFils equ 18 ; PRINT queue is empty AccDen equ 19 ; Access denied InvDrvMes equ 20 ; Invalid drive specification CNTMES equ 21 ; Errors on list device indicate that it ; may be off-line. Please check it. ; CLASS C FstMes equ 22 ; %1 is currently being printed SecMes equ 23 ; %1 is in queue BadNameMes equ 24 ; %1 File not found NamTMes equ 25 ; %1 Pathname too long BadCanMes equ 26 ; %1 File not in PRINT queue ; CLASS D PROMPT equ 27 ; Name of list device [PRN]: DOLLAR equ "$" Std_Out_Dev equ 1 ; $SALUT (0,41,46,52) .xlist .xcref BREAK MACRO subtitle SUBTTL subtitle PAGE ENDM SaveReg MACRO reglist ;; push those registers IRP reg, PUSH reg ENDM ENDM .xcref SaveReg RestoreReg MACRO reglist ;; pop those registers IRP reg, POP reg ENDM ENDM ; $SALUT (4,25,30,41) INCLUDE DEVSYM.INC INCLUDE SYSCALL.INC INCLUDE ERROR.INC INCLUDE FIND.INC include dpl.asm INCLUDE PDB.INC INCLUDE SYSCALL.INC INCLUDE MI.INC INCLUDE SYSMSG.INC include versiona.inc .list .cref MSG_UTILNAME error_busy EQU 9 error_queue_full EQU 8 error_name_too_long EQU 12 get_ea_by_handle equ 2 IF1 IF IBM ; %out IBM VERSION ELSE %out MS-DOS VERSION ENDIF ENDIF BREAK CodeR Segment public para CodeR EndS Code Segment public para Code EndS Data Segment public byte Data EndS Stack Segment Stack Stack Ends DG group Code,Data,Stack