home *** CD-ROM | disk | FTP | other *** search
- TITLE TIMESEND
- PAGE 65,132
- ;╔═══════════════════════════════════════════════════════════════════════════╗
- ;║ TIMESEND -- A TSR to Broadcast Time Periodically Via NETBIOS ║
- ;║ ║
- ;║ I am the original author of this work and hereby place it into ║
- ;║ the public domain. If your conscience bothers you, please feel ║
- ;║ free to send me $25.00 so that I may provide more such goodies. ║
- ;║ ║
- ;║ NOTE: This source code was written to be assembled with OPTASM. ║
- ;║ Phase errors and near jump problems will surely occur if ║
- ;║ MASM is used. Also, this program must be constructed as ║
- ;║ a .COM file. ║
- ;║ ║
- ;║ Programmer ...... George W. Mays ║
- ;║ Date ............ February, 1993 ║
- ;║ Site ............ 3314 Prince George ║
- ;║ San Antonio, TX 78230 ║
- ;║ Source .......... 80286 Assembler ║
- ;║ System .......... IBM PC/AT Compatible System Under MSDOS ║
- ;║ ║
- ;╚═══════════════════════════════════════════════════════════════════════════╝
- .286
- CSEG SEGMENT PARA PUBLIC 'CODE'
-
- ASSUME CS:CSEG,DS:NOTHING,ES:NOTHING,SS:NOTHING
-
- INCLUDE NETBIOS.INC
-
- ORG 100H ;SKIP TO END OF THE PSP
- ENTPT: JMP INITIALIZE ;COM FILE ENTRY ALWAYS AT 100H
-
- COPYRIGHT DB "TIMESEND V1.0, (C) 1993, G.W. Mays",0Ah,0Dh
- DB "In the Public Domain. Use Freely.",0Ah,0Dh,'$'
-
- ;╒═══════════════════════════════════════════════════════════════════════════╕
- ;│ Program data area. Buffers & Stack at end of resident code. │
- ;╘═══════════════════════════════════════════════════════════════════════════╛
- ;
- ; Data Stuff
- STACKSIZE EQU 0200h ;Our stack size
- VER DW 0 ;DOS version as returned
- DOSMAJOR DB 0 ;DOS major version number
- DOSMINOR DB 0 ;DOS minor version number
- REDIRACTIVE DB 0 ;Redirector flag
- BUSYFLAG DB 0 ;NB request outstanding flag
- LASTSTATUS DB 0 ;Completion code from last send
- NAMENUM DB 0 ;Name Number returned by NB
- SAVE_SP DW 0 ;Stack save cells
- SAVE_SS DW 0
- BUFF DB " " ;Data buff for NB send
- PREVGUY DD 0 ;Addr of original 1C Handler
- COUNTER DW 0 ;Tick counter
- NTICKS DW 182 ;Tick count to trip action
- MYNAME DB "TIMESERVER " ;My NETBIOS name
- THEIRNAME DB "TIMECLIENT " ;Their NETBIOS name
- CB NCB <> ;Our NCB
-
- ;╒═══════════════════════════════════════════════════════════════════════════╕
- ;│ Control is passed here by DOS via INT 0x1C (the Timer interrupt). │
- ;╘═══════════════════════════════════════════════════════════════════════════╛
-
- INT_1C PROC FAR
- NOP ; INT 3 ;Debug or NOP
- PUSHF ;Save flags
- PUSH DS
- PUSH AX
- ; Bump & Test Counter
- MOV AX,CS ;Set up addressing
- MOV DS,AX
- MOV AX,COUNTER ;Bump counter
- INC AX
- MOV COUNTER,AX
- CMP AX,NTICKS ;Have we hit "NTICKS"?
- JB RESTORE ;No, restore & return
- XOR AX,AX ;Yes, fall thru...
- MOV COUNTER,AX ;Zero counter
- ; Time to Broadcast Date/Time
- INT 3 ;Debug or NOP
- CLI ;Set our stack
- MOV CS:SAVE_SP,SP ;Save stack address
- MOV SP,SS ;
- MOV CS:SAVE_SS,SP
- MOV SP,CS
- MOV SS,SP
- MOV SP,OFFSET STACKTOP ;
- STI
- PUSHF
- PUSH ES ;Save registers
- PUSH DS
- PUSH DI
- PUSH SI
- PUSH DX
- PUSH CX
- PUSH BX
- PUSH AX
- ; The Reason We Came ----------------------------
- CALL DOTIME ;Get & send date & time
- ; -----------------------------------------------
- POP AX
- POP BX ;Restore registers
- POP CX
- POP DX
- POP SI
- POP DI
- POP DS
- POP ES
- POPF
- CLI
- MOV SP,CS:SAVE_SS ;Restore stack address
- MOV SS,SP
- MOV SP,CS:SAVE_SP
- STI
- RESTORE:
- POP AX ;Restore registers
- POP DS
- POPF ;Restore flags and
- JMP CS:[PREVGUY] ; percolate the call
- INT_1C ENDP
-
-
- ;╒═══════════════════════════════════════════════════════════════════════════╕
- ;│ Get date & time from BIOS; pack 'em up & ship 'em out.... │
- ;╘═══════════════════════════════════════════════════════════════════════════╛
-
- DOTIME PROC NEAR
- MOV AL,BUSYFLAG ;Test for request already
- OR AL,AL ; in progress....
- JZ NOTBUSY
- RET ;Just skip this time thru
- NOTBUSY:
- MOV BUFF+00h,'D' ;Format our packet
- MOV BUFF+01h,'/' ;It starts with "D/T"
- MOV BUFF+02h,'T'
- MOV BUFF+03h,00h
- MOV AH,04h ;Get date
- INT 1Ah ;From the BIOS (AT or PS/2)
- MOV AX,CX ;Start forming checksum
- ADD AX,DX
- MOV BUFF+04h,CH ;Century (in packed decimal)
- MOV BUFF+05h,CL ;Year
- MOV BUFF+06h,DH ;Month
- MOV BUFF+07h,DL ;Day
- PUSH AX ;Save checksum accumulator
- MOV AH,02h ;Get time
- INT 1Ah ;From the BIOS (AT or PS/2)
- POP AX ;Restore the checksum
- ADD AX,CX ;Continue checksumming
- ADD AX,DX
- MOV BUFF+08h,CH ;Hour
- MOV BUFF+09h,CL ;Minutes
- MOV BUFF+0Ah,DH ;Seconds
- MOV BUFF+0Bh,DL ;Daylight Savings Flag
- MOV BUFF+0Ch,00h
- MOV BUFF+0Dh,AL ;Store the checksum
- MOV BUFF+0Eh,AH ;
- MOV BUFF+0Fh,00h ;
- ;
- CALL CLEARNCB ;Prepare NCB
- MOV AX,CS
- MOV DS,AX
- MOV ES,AX
- MOV DI,OFFSET CB.NCB_CALLNAME
- MOV SI,OFFSET THEIRNAME ;Call Name
- MOV CX,16
- CLD
- REP MOVSB
- MOV AH,NAMENUM ;Name Number
- MOV CB.NCB_NUM,AH
- MOV CB.NCB_LENGTH,16 ;Length
- MOV AX,CS
- MOV ES,AX
- MOV CB.NCB_BUFF_SEG,AX ;Buffer Address and
- MOV CB.NCB_POST_SEG,AX ; Post Address
- MOV AX,OFFSET BUFF
- MOV CB.NCB_BUFF_OFF,AX
- MOV AX,OFFSET NBPOST
- MOV CB.NCB_POST_OFF,AX
- ;Function Code
- MOV AL,SENDDATAGRAM+NCB_NOWAIT
- MOV CB.NCB_COMMAND,AL
- MOV BUSYFLAG,AL ;Set BUSYFLAG
- MOV BX,OFFSET CB ;ES:BX -> NCB
- CALL CALLNB ;Call NETBIOS
- RET ;Return
- DOTIME ENDP
-
-
- ;╒═══════════════════════════════════════════════════════════════════════════╕
- ;│ NBPOST Function --- NETBIOS posts us here upon SEND DATAGRAM completion. │
- ;╘═══════════════════════════════════════════════════════════════════════════╛
-
- NBPOST PROC NEAR
- PUSHF
- PUSH DS ;Save regs
- PUSH AX
- STI ;Reenable interrupts
- NOP ; INT 3 ;Debug or NOP
- MOV AX,CS ;Set DS = CS
- MOV DS,AX
- MOV AL,CB.NCB_RETCODE ;Tuck away completion status
- MOV LASTSTATUS,AL
- MOV BUSYFLAG,00h ;Clear BUSYFLAG
- POP AX ;Restore regs
- POP DS
- POPF
- IRET ;Return from interrupt
- NBPOST ENDP
-
-
- ;╒═══════════════════════════════════════════════════════════════════════════╕
- ;│ CLEARNCB Function --- Fill the NCB with binary zeroes. │
- ;╘═══════════════════════════════════════════════════════════════════════════╛
-
- CLEARNCB PROC NEAR
- PUSHF ;Save regs & flags
- PUSH ES
- PUSH DI
- PUSH CX
- PUSH AX
- MOV AX,CS
- MOV ES,AX
- MOV DI,OFFSET CB ;Zero the NCB
- MOV CX,NCB_SIZE
- XOR AL,AL
- CLD
- REP STOSB
- POP AX ;Restore regs & flags
- POP CX
- POP DI
- POP ES
- POPF
- RET
- CLEARNCB ENDP
-
-
- ;╔═══════════════════════════════════════════════════════════════════════════╗
- ;║ CALL NETBIOS - This routine is called to send an NCB to the NETBIOS. ║
- ;║ If a redirector is loaded use int 2Ah otherwise use int 5Ch. ║
- ;║ ║
- ;║ On entry: ║
- ;║ ES:BX addr of NCB ║
- ;║ On exit: ║
- ;║ AX return code ║
- ;╚═══════════════════════════════════════════════════════════════════════════╝
-
- CALLNB PROC NEAR
- CMP REDIRACTIVE,0 ;Is a redirector active?
- JNE THRUREDIR
- INT 5Ch
- RET
- THRUREDIR:
- MOV AX,0400h
- INT 2Ah
- RET
- CALLNB ENDP
-
- ;╞═══════════════════════════════════════════════════════════════════════════╡
- PC = $ ;End of Code, OFFSET -> PC
-
- STACKBOT = PC ;Stack starts after I/O Buffs
- PC = PC + STACKSIZE ; and is STACKSIZE bytes long
- STACKTOP = PC ;STACKTOP here since stack
- ; grows downward
- PC = PC + 16
- LASTBYTE = PC ;LASTBYTE in resident code
-
-
- ;╔═══════════════════════════════════════════════════════════════════════════╗
- ;║ Initialization Procedure ║
- ;╚═══════════════════════════════════════════════════════════════════════════╝
-
- INITIALIZE PROC NEAR
- ASSUME CS:CSEG,DS:CSEG,ES:CSEG,SS:CSEG ;Set by loader.
- NOP ; INT 3 ;Debug or NOP
- MOV AX,CS
- MOV DS,AX
- MOV AH,9
- MOV DX,OFFSET COPYRIGHT
- INT 21H
- ;╒═══════════════════════════════════════════════════════════════════════════╕
- ;│ Check to see that NETBIOS is active. Check for a redirector. │
- ;╘═══════════════════════════════════════════════════════════════════════════╛
- CALL CHECKDOS ;DOS better be 3.1 or greater
- CALL CHKNETB ;See if NETBIOS is in here
- JNC NBTHERE
- PUSH OFFSET CS:NASTYGRAM ;Whoa! No NETBIOS!
- CALL FAILPROG ;Die.
- NBTHERE:
- MOV AH,0
- INT 2Ah ;Check for redirector
- MOV REDIRACTIVE,AH
- ;╒═══════════════════════════════════════════════════════════════════════════╕
- ;│ Look for TIMESEND.DAT file. Verify filesize. Extract NETBIOS names. │
- ;╘═══════════════════════════════════════════════════════════════════════════╛
- MOV AH,3Dh ;Open file
- XOR AL,AL
- MOV DX,OFFSET FILENAME
- INT 21h
- JNC FILEISOPEN ;Good open, jump
- MOV AH,9 ;Bad open
- MOV DX,OFFSET ASSUMPTION ;Display warning msg
- INT 21h
- JMP ADDNBNAME ;...and proceed.
- FILEISOPEN:
- MOV HANDLE,AX
- MOV BX,AX
- MOV AH,42h ;Seek to end of file
- MOV AL,02h
- XOR CX,CX
- XOR DX,DX
- INT 21h
- CMP AX,32
- JB SHORTFILE
- CMP AX,35
- JA LONGFILE
- MOV BX,HANDLE
- MOV AH,42h ;Seek to start of file
- MOV AL,00h
- XOR CX,CX
- XOR DX,DX
- INT 21h
- MOV BX,HANDLE
- MOV AH,3Fh ;Read from file
- MOV CX,32
- MOV DX,OFFSET MYNAME
- INT 21h
- JNC CLOSEFILE
- PUSH OFFSET CS:READFAILED
- CALL FAILPROG
- SHORTFILE:
- PUSH OFFSET CS:FILESHORT
- CALL FAILPROG
- LONGFILE:
- PUSH OFFSET CS:FILELONG
- CALL FAILPROG
- CLOSEFILE:
- MOV BX,HANDLE
- MOV AH,3Eh ;Close file
- INT 21h
- ;╒═══════════════════════════════════════════════════════════════════════════╕
- ;│ Add our name to the NETBIOS name table. │
- ;╘═══════════════════════════════════════════════════════════════════════════╛
- ADDNBNAME:
- CALL CLEARNCB ;Zero the NCB first
- MOV AL,ADDNAME ;Fill in NCB fields
- MOV CB.NCB_COMMAND,AL
- PUSH CS
- POP ES
- MOV DI,OFFSET CB.NCB_NAME
- MOV SI,OFFSET MYNAME
- MOV CX,16
- CLD
- REP MOVSB
- MOV BX,OFFSET CB
- CALL CALLNB ;Call NETBIOS
- MOV AL,CB.NCB_RETCODE
- OR AL,AL ;Check status
- JZ ADDWASOK
- PUSH OFFSET CS:ADDFAILED ;Whoa! It didn't work.
- CALL FAILPROG ;Die.
- ADDWASOK:
- MOV AL,CB.NCB_NUM ;Grab "name number" returned
- MOV NAMENUM,AL ; and save it for use later.
- ;╒═══════════════════════════════════════════════════════════════════════════╕
- ;│ Get the current address of Int 1C and save (it's the timer interrupt) │
- ;╘═══════════════════════════════════════════════════════════════════════════╛
- MOV AH,35h ;Get Int vector
- MOV AL,1Ch ;For this Int
- INT 21h ;Result in ES:BX
- ASSUME ES:NOTHING
- MOV WORD PTR PREVGUY[0],BX ;offset
- MOV WORD PTR PREVGUY[2],ES ;segment
- ;╒═══════════════════════════════════════════════════════════════════════════╕
- ;│ Free our environment segment to save a little space. │
- ;╘═══════════════════════════════════════════════════════════════════════════╛
- PUSH DS
- MOV AH,62h ;Get PSP address
- INT 21h ;
- MOV DS,BX
- MOV ES,DS:2Ch ;ES<-Env Seg Addr
- MOV AH,49h ;Free memory alloc
- INT 21h ;
- POP DS
- ;╒═══════════════════════════════════════════════════════════════════════════╕
- ;│ Plug ourselves into DOS Timer Interrupt (Interrupt 1C). │
- ;╘═══════════════════════════════════════════════════════════════════════════╛
- PUSH DS
- PUSH CS
- POP DS
- MOV DX,OFFSET INT_1C ;INT_1C is ISR entry
- MOV AH,25h ;Set Interrupt vector
- MOV AL,1Ch ; 1Ch.
- INT 21h ;
- POP DS
- ;╒═══════════════════════════════════════════════════════════════════════════╕
- ;│ Terminate and stay resident. │
- ;╘═══════════════════════════════════════════════════════════════════════════╛
- MOV AX,3100H
- MOV DX,(OFFSET LASTBYTE - OFFSET CSEG + 15) SHR 4
- INT 21H
-
- INITIALIZE ENDP
-
- HANDLE DW 0
- FILENAME DB "\TIMESEND.DAT",00h
- NASTYGRAM DB "NETBIOS is NOT active on this system",0Ah,0Dh,'$'
- ADDFAILED DB "NETBIOS Add Name failed",0Ah,0Dh,'$'
- ASSUMPTION DB "Assuming TIMESERVER sends to TIMECLIENT",0Ah,0Dh,'$'
- FILESHORT DB "TIMESEND.DAT file too small to be valid",0Ah,0Dh,'$'
- FILELONG DB "TIMESEND.DAT fill too big to be valid",0Ah,0Dh,'$'
- READFAILED DB "Error reading TIMESEND.DAT",0Ah,0Dh,'$'
-
-
- ;╒═══════════════════════════════════════════════════════════════════════════╕
- ;│ FAILPROG --- Display string (terminated with "$") on console, then │
- ;│ exit the program with nonzero condition code. │
- ;╘═══════════════════════════════════════════════════════════════════════════╛
-
- FAILPROG PROC NEAR
- PUSH SP
- POP BX
- MOV DX,WORD PTR [BX+2] ;Get offset of string
- PUSH CS ;Assume offset w/in this code
- POP DS
- MOV AH,09h ;Display String function
- INT 21h ; of DOS
- MOV AH,4Ch ;Terminate a Process func
- MOV AL,01h ; of DOS
- INT 21h ;
- INT 20h ;Just to be safe....
- FAILPROG ENDP
-
-
- ;╒═══════════════════════════════════════════════════════════════════════════╕
- ;│ CHECKDOS --- Get the DOS version. Bomb if < DOS 3.10. │
- ;╘═══════════════════════════════════════════════════════════════════════════╛
-
- CHECKDOS PROC NEAR
- PUSH BP ;Save register(s)
- MOV BP,SP
- PUSH CX
- PUSH BX
- PUSH AX
- MOV AH,30h ;Get DOS Version
- INT 21h
- MOV CS:VER,AX ;Save results
- MOV CS:DOSMAJOR,AL
- MOV CS:DOSMINOR,AH
- CMP AL,3 ;Check major level
- JL VERCHOKE ;<3, VERCHOKE
- JNE VEROK ;>3, VEROK
- CMP AH,1 ;Check minor level for 3.x
- JGE VEROK ;VEROK if 3.1 or better
- VERCHOKE:
- PUSH OFFSET CS:VERMSG ;Push offset of nastygram
- CALL FAILPROG ;And kiss off....
- VEROK:
- POP AX ;Restore registers
- POP BX
- POP CX
- MOV SP,BP ;Restore stack
- POP BP
- RET ;Return to caller
- CHECKDOS ENDP
-
- VERMSG DB "DOS Version MUST be 3.1 or greater$"
-
-
- ;╔═══════════════════════════════════════════════════════════════════════════╗
- ;║ Check For NETBIOS Installed in System ║
- ;║ Return with CARRY SET if NOT installed ║
- ;╚═══════════════════════════════════════════════════════════════════════════╝
-
- CHKNETB PROC NEAR
- MOV AH,35h ;Who's plugged into INT 5C?
- MOV AL,5Ch
- INT 21h
- MOV AX,ES
- CMP AX,0000h
- JE NOTKOSHER
- CMP AX,0F000h
- JE NOTKOSHER
- ITSPLUGGED:
- PUSH CS
- POP ES
- MOV DI,OFFSET FUNKYNCB ;Zero the NCB
- MOV CX,NCB_SIZE
- XOR AL,AL
- CLD
- REP STOSB
- MOV BX,OFFSET FUNKYNCB
- MOV AL,0FFh
- MOV FUNKYNCB.NCB_COMMAND,AL
- MOV AL,00h
- INT 5Ch ;Check it.
- MOV AL,FUNKYNCB.NCB_RETCODE
- CMP AL,03h ;Zero ?
- JNE NOTKOSHER ;Yes, so not installed.
- CLC
- RET
- NOTKOSHER:
- STC
- RET
-
- FUNKYNCB NCB <> ;NCB with FUNKY command
- ; to test things out
- CHKNETB ENDP
-
- CSEG ENDS
-
- END ENTPT
-
- ;╔═══════════════════════════════════════════════════════════════════════════╗
- ;║ End of Program --- TIMESEND ║
- ;╚═══════════════════════════════════════════════════════════════════════════╝
-