home *** CD-ROM | disk | FTP | other *** search
- ' SLINK Copyright (c) 1989 Thomas G. Hanlin III
- ' Smart LINK shell, version 1.0, 5/21/89
-
- DECLARE FUNCTION Min% (x%, y%)
-
- DECLARE SUB CatchError ()
- DECLARE SUB DelFile (file$, errcode%)
- DECLARE SUB DFRead (handle%, dseg%, dofs%, bytes%, bytesread%, errcode%)
- DECLARE SUB DFWrite (handle%, dseg%, dofs%, bytes%, byteswrit%, errcode%)
- DECLARE SUB DMPrint (st$)
- DECLARE SUB ExtendFSpec (file$, ext$, fullfile$, errcode%)
- DECLARE SUB FClose (handle%)
- DECLARE SUB FCreate (file$, attr%, handle%, errcode%)
- DECLARE SUB FindFirstF (file$, attr%, errcode%)
- DECLARE SUB FindNextF (errcode%)
- DECLARE SUB FOpen (file$, readwrite%, sharing%, handle%, errcode%)
- DECLARE SUB FSetLoc (handle%, posn&)
- DECLARE SUB FSize (handle%, bytes&)
- DECLARE SUB GetError (errorlevel%)
- DECLARE SUB GetNameF (file$, flen%)
- DECLARE SUB GetSizeFL (bytes&)
- DECLARE SUB ParseFSpec (path$, drv$, dlen%, subdir$, slen%, file$, flen%)
- DECLARE SUB Rename (oldfile$, newfile$, errcode%)
- DECLARE SUB RInstr (st$, seekst$, posn%)
- DECLARE SUB SetError (errorlevel%)
-
- CONST buffersize& = 8192&
-
- TYPE exehdr
- signature AS STRING * 2
- lastpagesize AS INTEGER
- filepages AS INTEGER
- reloccount AS INTEGER
- headersize AS INTEGER
- minalloc AS INTEGER
- maxalloc AS INTEGER
- ss AS INTEGER
- sp AS INTEGER
- checksum AS INTEGER
- ip AS INTEGER
- cs AS INTEGER
- relocptr AS INTEGER
- overlay AS INTEGER
- END TYPE
-
- DEFINT A-Z
-
- DIM exeheader AS exehdr
-
- crlf$ = CHR$(13) + CHR$(10)
-
- DMPrint "SLINK 1.0 Copyright (c) 1989 Thomas G. Hanlin III" + crlf$
- DMPrint crlf$
-
- cmd$ = UCASE$(LTRIM$(RTRIM$(COMMAND$)))
- IF LEN(cmd$) = 0 THEN
- DMPrint "This is an enhancement shell for the Microsoft LINK utility. It automatically" + crlf$
- DMPrint "LINKs your file. The resulting .EXE file will be converted to .COM or .SYS" + crlf$
- DMPrint "format if it is appropriate to do so. Otherwise, the program will be" + crlf$
- DMPrint "linked again using the /EXEPACK option and the smaller of the two .EXE files" + crlf$
- DMPrint "will be kept." + crlf$
- DMPrint crlf$
- DMPrint "Syntax:" + crlf$
- DMPrint " SLINK filename[link parameters]" + crlf$
- DMPrint crlf$
- DMPrint "Wildcards may be used in the filename specification." + crlf$
- DMPrint crlf$
- DMPrint "SLINK may be distributed as long as no fee of over $6.00 is charged and all" + crlf$
- DMPrint "files (SLINK.BAS, SLINK.DOC, SLINK.EXE) are included without modification." + crlf$
- DMPrint crlf$
- SetError 0
- END
- END IF
-
- tmp = INSTR(cmd$, ",")
- IF tmp THEN
- runfile$ = mid$(cmd$, tmp + 1)
- tmp = INSTR(runfile$, ",")
- IF tmp THEN
- runfile$ = LEFT$(runfile$, tmp - 1)
- ELSE
- tmp = INSTR(cmd$, ";")
- IF tmp THEN runfile$ = LEFT$(runfile$, tmp - 1)
- END IF
- tmp = INSTR(runfile$, "/")
- IF tmp THEN runfile$ = LEFT$(runfile$, tmp - 1)
- IF LEN(runfile$) THEN
- ExtendFSpec runfile$, ".EXE", path$, errcode
- IF errcode THEN
- DMPrint "*** Error: invalid run file [" + runfile$ + "]" + crlf$
- SetError 3
- END
- ELSE
- runfile$ = path$
- END IF
- END IF
- ELSE
- runfile$ = ""
- END IF
-
-
- t1 = INSTR(cmd$, ","): IF t1 = 0 THEN t1 = LEN(cmd$) + 1
- t2 = INSTR(cmd$, ";"): IF t2 = 0 THEN cmd$ = cmd$ + ";": t2 = LEN(cmd$) + 1
- t3 = INSTR(cmd$, "+"): IF t3 = 0 THEN t3 = LEN(cmd$) + 1
- t4 = INSTR(cmd$, "/"): IF t4 = 0 THEN t4 = LEN(cmd$) + 1
- t5 = INSTR(cmd$, " "): IF t5 = 0 THEN t5 = LEN(cmd$) + 1
- tmp = Min(Min(Min(Min(t1, t2), t3), t4), t5)
- filename$ = LEFT$(cmd$, tmp - 1)
- filetail$ = LTRIM$(MID$(cmd$, tmp))
- IF INSTR(filetail$, "/E") THEN exepacked = -1
- ExtendFSpec filename$, ".OBJ", path$, errcode
- IF errcode THEN
- DMPrint "*** Error: invalid "
- SELECT CASE errcode
- CASE -1: DMPrint "file"
- CASE 1: DMPrint "drive"
- CASE 2: DMPrint "subdirectory"
- END SELECT
- DMPrint " [" + filename$ + "]" + crlf$
- SetError 1
- END
- END IF
- drv$ = " ": subdir$ = SPACE$(64): file$ = SPACE$(12)
- ParseFSpec path$, drv$, dlen, subdir$, slen, file$, flen
- locus$ = drv$ + ":" + LEFT$(subdir$, slen)
- IF RIGHT$(locus$, 1) <> "\" THEN locus$ = locus$ + "\"
- file$ = LEFT$(file$, flen)
-
- FindFirstF path$, 0, errcode
- IF errcode THEN
- DMPrint "*** Error: file not found [" + path$ + "]" + crlf$
- END IF
- DO WHILE errcode = 0
- infile$ = SPACE$(12)
- GetNameF infile$, flen
- infile$ = locus$ + LEFT$(infile$, flen)
- IF LEN(runfile$) THEN
- midfile$ = runfile$
- ELSE
- RInstr infile$, ".", tmp
- midfile$ = LEFT$(infile$, tmp) + "EXE"
- END IF
- CatchError
- SHELL "LINK " + infile$ + filetail$ + " >NUL"
- GetError errorlevel
- IF errorlevel THEN
- DelFile midfile$, errcode
- DMPrint "*** Error: LINK failed on " + infile$ + filetail$ + crlf$
- ELSE
- IF RIGHT$(midfile$, 3) = "EXE" AND NOT exepacked THEN
- GetSizeFL bytes&
- IF bytes& < 99999 THEN
- GOSUB TryConvert ' see if it should be .COM or .SYS
- END IF
- IF NOT convertfile THEN
- GOSUB ExePack ' see if it can be profitably EXEPACKed
- END IF
- ELSE
- DelFile infile$, errcode
- DMPrint infile$ + " --> " + midfile$
- IF exepacked THEN DMPrint " (EXEPACKed)"
- DMPrint crlf$
- END IF
- END IF
- FindNextF errcode
- LOOP
- SetError 0
- END
-
-
-
- ' ----------------- subroutine to try to convert .EXE to .COM or .SYS ---------
-
- TryConvert:
- errorflag = 0
- FOpen midfile$, 0, 0, inhandle, errcode
- IF errcode THEN
- errorflag = 1
- ELSE
- dseg = VARSEG(exeheader)
- dofs = VARPTR(exeheader)
- DFRead inhandle, dseg, dofs, 28, bytesread, errcode
- IF errcode THEN
- FClose inhandle
- errorflag = 1
- END IF
- END IF
-
- IF errorflag = 0 THEN
- IF exeheader.signature <> "MZ" THEN
- FClose inhandle
- errorflag = 2
- END IF
- END IF
-
- IF errorflag = 0 THEN
- errcode = (exeheader.reloccount <> 0) OR (exeheader.cs <> 0)
- errcode = errcode OR (exeheader.ss <> 0) OR (exeheader.sp <> 0)
- IF errcode THEN
- FClose inhandle
- errorflag = -1
- END IF
- END IF
- IF errorflag = 0 THEN
- SELECT CASE exeheader.ip
- CASE 0
- ext$ = "SYS"
- CASE &H100
- ext$ = "COM"
- CASE ELSE
- FClose inhandle
- errorflag = -1
- END SELECT
- IF errorflag = 0 THEN
- RInstr midfile$, ".", tmp
- outfile$ = LEFT$(midfile$, tmp) + ext$
- END IF
- END IF
-
- IF errorflag = 0 THEN
- codeptr& = CLNG(exeheader.headersize) * 16&
- codesize& = CLNG(exeheader.filepages) * 512& - codeptr& - CLNG(exeheader.ip)
- IF exeheader.lastpagesize THEN
- codesize& = codesize& - 512& + CLNG(exeheader.lastpagesize)
- END IF
- codeptr& = codeptr& + CLNG(exeheader.ip) + 1&
- FSetLoc inhandle, codeptr&
- IF codesize& < 1& OR codesize& > 65530 THEN
- FClose inhandle
- errorflag = -1
- END IF
- END IF
-
- IF errorflag = 0 THEN
- FCreate outfile$, 0, outhandle, errcode
- IF errcode THEN
- FClose inhandle
- errorflag = 3
- END IF
- END IF
-
- IF errorflag THEN
- convertfile = 0
- ELSE
- convertfile = -1
- REDIM buffer(1 TO CINT(buffersize/2+.1))
- bytes = buffersize
- DO
- IF codesize& <= buffersize THEN
- bytes = CINT(codesize&)
- codesize& = 0&
- ELSE
- codesize& = codesize& - buffersize
- END IF
- dseg = VARSEG(buffer(1))
- dofs = VARPTR(buffer(1))
- DFRead inhandle, dseg, dofs, bytes, bytesread, errcode
- IF errcode THEN
- errorflag = 1
- ELSE
- DFWrite outhandle, dseg, dofs, bytes, bytesread, errcode
- IF errcode THEN errorflag = 3
- END IF
- LOOP WHILE codesize& > 0& AND errorflag = 0
- FClose inhandle
- FClose outhandle
- ERASE buffer
- END IF
-
- IF errorflag THEN
- IF convertfile THEN
- DelFile outfile$, errcode
- convertfile = 0
- END IF
- SELECT CASE errorflag
- CASE -1
- REM the .EXE file was not suitable for .COM or .SYS conversion
- CASE 1
- DMPrint "*** Error: unable to read file [" + midfile$ + "]" + crlf$
- CASE 2
- DMPrint "*** Error: invalid .EXE file [" + midfile$ + "]" + crlf$
- CASE 3
- DMPrint "*** Error: unable to create file [" + outfile$ + "]"
- DMPrint crlf$
- END SELECT
- ELSE
- DelFile infile$, errcode
- DelFile midfile$, errcode
- DMPrint infile$ + " --> " + outfile$ + crlf$
- END IF
- RETURN
-
-
-
- ' ------------- subroutine to try /EXEPACK ------------------------------------
-
- ExePack:
- IF LEN(runfile$) THEN
- midfile$ = runfile$
- ELSE
- RInstr infile$, ".", tmp
- midfile$ = LEFT$(infile$, tmp) + "EXE"
- END IF
- IF RIGHT$(midfile$, 3) = "EXE" THEN
- RInstr midfile$, ".", tmp
- bakfile$ = LEFT$(midfile$, tmp) + "$SL"
- Rename midfile$, bakfile$, errcode
- CatchError
- SHELL "LINK " + infile$ + "/EXEPACK" + filetail$ + " >NUL"
- GetError errorlevel
- IF errorlevel THEN
- DMPrint "*** Error: LINK failed on " + infile$ + "/EXEPACK"
- DMPrint filetail$ + crlf$
- ELSE
- FOpen bakfile$, 0, 0, handle, errcode
- FSize handle, baksize&
- FClose handle
- FOpen midfile$, 0, 0, handle, errcode
- FSize handle, midsize&
- FClose handle
- IF midsize& > baksize& THEN
- DelFile infile$, errcode
- DelFile midfile$, errcode
- Rename bakfile$, midfile$, errcode
- DMPrint infile$ + " --> " + midfile$ + crlf$
- ELSE
- DelFile bakfile$, errcode
- DelFile infile$, errcode
- DMPrint infile$ + " --> " + midfile$ + " (EXEPACKed)"+ crlf$
- END IF
- END IF
- ELSE
- DelFile infile$, errcode
- DMPrint infile$ + " --> " + midfile$ + crlf$
- END IF
- RETURN
-
-
-
- ' ----------------------------- subprograms and functions ---------------------
-
-
-
-
- FUNCTION Min (x, y)
- IF x < y THEN
- Min = x
- ELSE
- Min = y
- END IF
- END FUNCTION
-