home *** CD-ROM | disk | FTP | other *** search
/ The Equalizer BBS / equalizer-bbs-collection_2004.zip / equalizer-bbs-collection / DEMOSCENE-STUFF / BKISSSRC.ZIP / JLIBHOST.ASM < prev    next >
Assembly Source File  |  1994-02-17  |  42KB  |  892 lines

  1. ideal
  2. jumps
  3. model huge
  4. stack 1024
  5.  
  6. MAJORVER = 1        ;\ file format version 1.3
  7. MINORVER = 3        ;/
  8. MAXFILES = 50       ;maximum number of files allowed in library
  9. BUFFERSIZE = 4096   ;size of transfer buffer in bytes (less than 64k)
  10. FILES = 30          ;maximum number of 'FILES' in CONFIG.SYS to track
  11.  
  12.  
  13. ;******************
  14. ;*** structures ***
  15. ;******************
  16. STRUC ParmBlock
  17.         EnvSgmt     DW  0
  18.         CmdTail     DD  0
  19.         FCB_1       DD  0
  20.         FCB_2       DD  0
  21.         ExecAddr    DD  0
  22.         PgmStack    DD  0
  23. ENDS ParmBlock
  24. STRUC FCB
  25.         Filename    DB  11 DUP (' ')
  26.         Reserved    DB  5 DUP (0)
  27. ENDS FCB
  28. STRUC LibFile
  29.         Fileattr    DB  0
  30.         Filetime    DW  0
  31.         Filedate    DW  0
  32.         Filesize    DD  0
  33.         Filename    DB  13 DUP (0)
  34.         Fileoffset  DD  0
  35. ENDS LibFile
  36. STRUC DTA
  37.         DriveLetter DB  0                   ;+00 byte
  38.         Wildcard    DB  11 DUP (' ')        ;+01 byte(11)
  39.         AttrSearch  DB  0                   ;+0C byte
  40.         Reserved1   DW  0                   ;+0D word
  41.         Reserved2   DW  0                   ;+0F word
  42.         Reserved3   DW  0                   ;+11 word
  43.         Reserved4   DW  0                   ;+13 word
  44.         AttrFound   DB  0                   ;+15 byte
  45.         TimeFound   DW  0                   ;+16 word
  46.         DateFound   DW  0                   ;+18 word
  47.         SizeFound   DD  0                   ;+1A dword
  48.         FileFound   DB  13 DUP (' ')        ;+1E byte(13)
  49. ENDS DTA
  50.  
  51.  
  52.  
  53. ;**************
  54. ;*** macros ***
  55. ;**************
  56. MACRO ErrorMessage ErrorName,ErrorText
  57.     LOCAL @@Message,@@Quit
  58.     PROC    ErrorName
  59.             mov ah,9
  60.             push cs
  61.             pop ds
  62.             mov dx,offset @@Message
  63.             int 21h
  64.             cmp [Handle],0FFFFh
  65.             jz @@Quit
  66.             mov ah,3Eh
  67.             mov bx,[Handle]
  68.             int 21h
  69. @@Quit:     mov ax,4CFFh
  70.             int 21h
  71. @@Message   DB  '***Error*** ',ErrorText,0Dh,0Ah,'$'
  72.     ENDP    ErrorName
  73. ENDM ErrorMessage
  74. MACRO MAKEUPPERCASE letter
  75.     LOCAL @@NotLower
  76.     cmp letter,'a'
  77.     jb @@NotLower
  78.     cmp letter,'z'
  79.     ja @@NotLower
  80.     sub letter,'a'-'A'
  81. @@NotLower:
  82. ENDM MAKEUPPERCASE
  83.  
  84.  
  85.  
  86. SEGMENT     Code
  87.             ASSUME CS:Code, DS:Code
  88. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  89. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  90. ;░░░░░░░░░░░░░░░░░░░░░░░░░ Initialization ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  91. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  92. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  93. PROC        Start
  94.             mov [cs:PSPsegment],es
  95.             push cs                         ;\
  96.             pop ds                          ; \
  97.             mov ah,9                        ;  > display our greeting
  98.             mov dx,offset Hello             ; /
  99.             int 21h                         ;/
  100.             mov ah,30h                      ;\
  101.             int 21h                         ; \ make sure we have DOS 2.x +
  102.             cmp al,3                        ; /
  103.             jb OldDOSversion                ;/
  104.  
  105.             mov ax,[cs:PSPsegment]          ;\
  106.             mov es,ax                       ; \
  107.             mov bx,zzzzzseg                 ;  \
  108.             sub bx,ax                       ;   \ reduce memory overhead
  109.             add bx,2                        ;   /
  110.             mov ah,4Ah                      ;  /
  111.             int 21h                         ; /
  112.             jc ErrorChangingMemory          ;/
  113.             mov ah,49h                      ;\
  114.             mov es,[cs:PSPsegment]          ; \
  115.             mov es,[word es:002Ch]          ;  > free our environment space
  116.             int 21h                         ; /
  117.             jc ErrorChangingMemory          ;/
  118.             call ParseCommandLine           ;\ check the command line
  119.             jc NoCommandLine                ;/
  120.  
  121.             ;*** Reading of the JLIB file header ***
  122.             mov ax,3D00h                    ;\
  123.             push cs                         ; \
  124.             pop ds                          ;  \
  125.             mov dx,offset LibName           ;   > try to open the library file
  126.             int 21h                         ;  /
  127.             jc BadLibName                   ; /
  128.             mov [Handle],ax                 ;/
  129. ;-------- 1.3 changes start here
  130.             mov ax,-4                       ;\
  131.             cwd                             ; \
  132.             mov cx,dx                       ;  \
  133.             mov dx,ax                       ;   > seek to 4 bytes before end
  134.             mov ax,4202h                    ;  /
  135.             mov bx,[Handle]                 ; /
  136.             int 21h                         ;/
  137.             mov ah,3Fh                      ;\
  138.             mov bx,[Handle]                 ; \
  139.             mov cx,4                        ;  > read in the offset to start
  140.             mov dx,offset HeaderOffset      ; /
  141.             int 21h                         ;/
  142.             mov ax,4202h                    ;\
  143.             mov bx,[Handle]                 ; \
  144.             xor cx,cx                       ;  > find out length of total file
  145.             xor dx,dx                       ; /
  146.             int 21h                         ;/
  147.             sub ax,[word HeaderOffset+0]    ;\
  148.             sbb dx,[word HeaderOffset+2]    ; \ compute offset to start of JLIB
  149.             mov [word HeaderOffset+0],ax    ; /
  150.             mov [word HeaderOffset+2],dx    ;/
  151.             mov ax,4200h                    ;\
  152.             mov bx,[Handle]                 ; \
  153.             mov cx,[word HeaderOffset+2]    ;  > seek to start of JLIB
  154.             mov dx,[word HeaderOffset+0]    ; /
  155.             int 21h                         ;/
  156. ;-------- 1.3 changes end here
  157.             mov ah,3Fh                      ;\
  158.             mov bx,[Handle]                 ; \
  159.             mov cx,6                        ;  \ read in signature and
  160.             mov dx,offset Buffer            ;  / file version number
  161.             int 21h                         ; /
  162.             jc FileError                    ;/
  163.             cmp [word Buffer],'LJ'          ;\
  164.             jnz BadSignature                ; \
  165.             cmp [word Buffer+2],'bi'        ;  \ check the signarure and
  166.             jnz BadSignature                ;  / file version number
  167.             cmp [word Buffer+4],MINORVER*256+MAJORVER
  168.             jnz BadSignature                ;/
  169.             mov ah,3Fh                      ;\
  170.             mov bx,[Handle]                 ; \
  171.             mov cx,2                        ;  \ read in number of files
  172.             mov dx,offset NumFiles          ;  / contained in the library
  173.             int 21h                         ; /
  174.             jc FileError                    ;/
  175.             mov cx,[NumFiles]               ;\
  176.             cmp cx,MAXFILES                 ; > check the limit of files
  177.             ja TooManyFiles                 ;/
  178.             mov ah,3Fh                      ;\
  179.             mov bx,[Handle]                 ; \
  180.             mov cx,4                        ;  \ read in the offset to the
  181.             mov dx,offset Transfer          ;  / directory structures
  182.             int 21h                         ; /
  183.             jc FileError                    ;/
  184.             mov ax,4200h                    ;\
  185.             mov bx,[Handle]                 ; \
  186.             mov cx,[word Transfer+2]        ;  \ seek to the beginning of
  187.             mov dx,[word Transfer+0]        ;  / the file structures
  188. ;-------- 1.3 changes start here
  189.             add dx,[word HeaderOffset+0]
  190.             adc cx,[word HeaderOffset+2]
  191. ;-------- 1.3 changes end here
  192.             int 21h                         ; /
  193.             jc FileError                    ;/
  194.             mov cx,[NumFiles]               ;\
  195.             mov dx,offset FileStats         ; \
  196. @@Read:     push cx dx                      ;  \
  197.             mov ah,3Fh                      ;   |
  198.             mov bx,[Handle]                 ;   |
  199.             mov cx,size LibFile             ;   | read in the directory
  200.             int 21h                         ;   | information for each file
  201.             jc FileError                    ;   |
  202.             pop dx cx                       ;  /
  203.             add dx,size LibFile             ; /
  204.             loop @@Read                     ;/
  205.             mov ah,3Eh                      ;\
  206.             mov bx,[Handle]                 ; \ close the library file
  207.             mov [Handle],-1                 ; /
  208.             int 21h                         ;/
  209.  
  210.  
  211.             ;*** Installation of handler and execution of child ***
  212.             mov ax,3521h                    ;\
  213.             int 21h                         ; \ save the old int 21 vector
  214.             mov [word OldInt21+0],bx        ; /
  215.             mov [word OldInt21+2],es        ;/
  216.             mov ax,2521h                    ;\
  217.             mov dx,seg NewInt21             ; \
  218.             mov ds,dx                       ;  > hook our routine onto int 21
  219.             mov dx,offset NewInt21          ; /
  220.             int 21h                         ;/
  221.             mov ah,9                        ;\
  222.             push cs                         ; \
  223.             pop ds                          ;  > display a message
  224.             mov dx,offset NowRunning        ; /
  225.             int 21h                         ;/
  226.             mov [word StackPTR+0],sp        ;\ save the stack for later
  227.             mov [word StackPTR+2],ss        ;/
  228.             mov ax,4B00h                    ;load and execute program
  229.             mov dx,seg ProgramName          ;\
  230.             mov ds,dx                       ; > DS:DX ==> ASCIIZ program name
  231.             mov dx,offset ProgramName       ;/
  232.             mov bx,seg MyParmBlock          ;\
  233.             mov es,bx                       ; > ES:BX ==> parameter block
  234.             mov bx,offset MyParmBlock       ;/
  235.             mov [word MyParmBlock+offset (ParmBlock).EnvSgmt],0
  236.             mov [word MyParmBlock+0+offset (ParmBlock).CmdTail],offset CommandTail
  237.             mov [word MyParmBlock+2+offset (ParmBlock).CmdTail],seg CommandTail
  238.             mov [word MyParmBlock+0+offset (ParmBlock).FCB_1],offset MyFCB_1
  239.             mov [word MyParmBlock+2+offset (ParmBlock).FCB_1],seg MyFCB_1
  240.             mov [word MyParmBlock+0+offset (ParmBlock).FCB_2],offset MyFCB_2
  241.             mov [word MyParmBlock+2+offset (ParmBlock).FCB_2],seg MyFCB_2
  242.             int 21h                         ;call DOS
  243.             cli                             ;\
  244.             mov sp,[word cs:StackPTR+0]     ; \
  245.             mov ss,[word cs:StackPTR+2]     ;  \  recover all of our
  246.             sti                             ;   > important registers
  247.             mov ax,cs                       ;  /
  248.             mov es,ax                       ; /
  249.             mov ds,ax                       ;/
  250.             pushf                           ;save the flags
  251.             mov ah,9                        ;\
  252.             push cs                         ; \
  253.             pop ds                          ;  > display a message
  254.             mov dx,offset WelcomeBack       ; /
  255.             int 21h                         ;/
  256.             push ds                         ;\
  257.             mov ax,2521h                    ; \
  258.             lds dx,[cs:OldInt21]            ;  > restore the int 21h vector
  259.             int 21h                         ; /
  260.             pop ds                          ;/
  261.             popf                            ;restore the flags
  262.             jc ExecutionErr                 ;handle the child's flags
  263.             mov ax,4C00h                    ;\ terminate program
  264.             int 21h                         ;/
  265. ENDP        Start
  266. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  267. ;copy and parse the filename on the command line into the 'LibName' variable
  268. ;return with carry set if no command line specified
  269. PROC        ParseCommandLine
  270.             cld                         ;clear direction flag
  271.             push cs                     ;\ set ES to CS
  272.             pop es                      ;/
  273.             mov ds,[cs:PSPsegment]      ;\ DS:SI ==> source
  274.             mov si,80h                  ;/
  275.             lodsb                       ;\
  276.             xor cx,cx                   ; > CX = length of command line
  277.             mov cl,al                   ;/
  278.             mov [byte cs:LibName],0     ;\
  279.             mov [byte cs:ProgramName],0 ; > blank out all strings
  280.             mov [byte cs:CommandTail],0 ;/
  281.  
  282. @@SkipDiv1: jcxz @@Done                 ;\
  283.             lodsb                       ; \
  284.             dec cx                      ;  > skip first divider
  285.             cmp al,' '                  ; /
  286.             jbe @@SkipDiv1              ;/
  287.  
  288.             mov di,offset LibName       ;\
  289. @@CopyLib:  stosb                       ; \
  290.             jcxz @@LibDone              ;  \
  291.             lodsb                       ;   \
  292.             dec cx                      ;    > copy out the library name
  293.             cmp al,' '                  ;   /
  294.             ja @@CopyLib                ;  /
  295. @@LibDone:  xor al,al                   ; /
  296.             stosb                       ;/
  297.  
  298. @@SkipDiv2: jcxz @@Done                 ;\
  299.             lodsb                       ; \
  300.             dec cx                      ;  > skip second divider
  301.             cmp al,' '                  ; /
  302.             jbe @@SkipDiv2              ;/
  303.  
  304.             mov di,offset ProgramName   ;\
  305. @@CopyProg: stosb                       ; \
  306.             jcxz @@ProgDone             ;  \
  307.             lodsb                       ;   \
  308.             dec cx                      ;    > copy out the EXE name
  309.             cmp al,' '                  ;   /
  310.             ja @@CopyProg               ;  /
  311. @@ProgDone: xor al,al                   ; /
  312.             stosb                       ;/
  313.  
  314. @@SkipDiv3: jcxz @@Done                 ;\
  315.             lodsb                       ; \
  316.             dec cx                      ;  > skip third divider
  317.             cmp al,' '                  ; /
  318.             jbe @@SkipDiv3              ;/
  319.  
  320.             dec si                      ;\
  321.             inc cx                      ; \
  322.             jcxz @@Done                 ;  \
  323.             mov di,offset CommandTail   ;   \
  324.             mov al,cl                   ;    > copy out the command tail,
  325.             stosb                       ;   /  if it's present
  326.             rep movsb                   ;  /
  327.             mov al,0Dh                  ; /
  328.             stosb                       ;/
  329.  
  330. @@Done:     cmp [byte cs:LibName],0     ;\
  331.             jz @@Nothing                ; \
  332.             cmp [byte cs:ProgramName],0 ;  \
  333.             jz @@Nothing                ;   \ return with CF set if there
  334.             clc                         ;   / wasn't a LibName or an EXE name
  335.             ret                         ;  /
  336. @@Nothing:  stc                         ; /
  337.             ret                         ;/
  338. ENDP        ParseCommandLine
  339. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  340. ;the following data is used only during initialization of program
  341. Hello       DB  'JLIBHOST.COM -- JLib File Host, v','0'+MAJORVER,'.','0'+MINORVER,0Dh,0Ah
  342.             DB  'by  _______  /',0Dh,0Ah
  343.             DB  '       /    /      ┌──┌┐  │─┬─┌──┌─┐┌─┐┌─┐o┌──┌──┌──',0Dh,0Ah
  344.             DB  '      /    /       ├─ │└─┐│ │ ├─ ├┬┘├─┘├┬┘│└─┐├─ └─┐',0Dh,0Ah
  345.             DB  '/____/    /_____   └──│  └┘ │ └──│ \│  │ \│──┘└────┘',0Dh,0Ah
  346.             DB  0Dh,0Ah,'$'
  347. NowRunning  DB  'Now running under a JLIB Host environment.',0Dh,0Ah,'$'
  348. WelcomeBack DB  'Welcome back to reality.',0Dh,0Ah,'$'
  349. PSPsegment  DW  0                   ;our PSP segment
  350. StackPTR    DD  0                   ;saved stack pointer
  351. MyParmBlock ParmBlock <>            ;\
  352. MyFCB_1     FCB <>                  ; \
  353. MyFCB_2     FCB <>                  ;  > used for executing child process
  354. ProgramName DB  80 DUP (0)          ; /
  355. CommandTail DB  0,127 DUP (0Dh)     ;/
  356. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  357. ;the following are all of the error messages, each created using a macro
  358. ErrorMessage ErrorChangingMemory,'Error during memory management.'
  359. ErrorMessage OldDOSversion,'This requires DOS 2.0 or higher.'
  360. ErrorMessage NoCommandLine,<'Bad command line syntax.',0Dh,0Ah,9,'JLIBHOST «libname.JLB» «program.EXE» «parameters»'>
  361. ErrorMessage BadLibName,'Error opening specified library.'
  362. ErrorMessage BadSignature,'Bad library format.'
  363. ErrorMessage TooManyFiles,'Too many files in library.'
  364. ErrorMessage FileError,'Error during file I/O.'
  365. ErrorMessage ExecutionErr,'Error during execution of child process.'
  366. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  367. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  368. ;░░░░░░░░░░░░░░░░░░░░ Library functions ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  369. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  370. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  371. ;the following data is needed by the library functions to access files
  372. OldInt21    DD 0                        ;old interrupt vector
  373. LibName     DB 80 DUP (0)               ;full filename of library file
  374. Handle      DW 0FFFFh                   ;
  375. Handle2     DW 0FFFFh                   ;
  376. NumFiles    DW 0                        ;number of files in library
  377. FileStats   LibFile MAXFILES DUP (<>)   ;file info structures of each file
  378. Buffer      DB 13 DUP (0)               ;
  379. Wildcard    DB 13 DUP (0)               ;\   last defined wildcard
  380. MasterAttr  DW 0                        ; \  original search attribute
  381. HandleNext  DB 0                        ;  > if next FindNext should be caught
  382. LastMatch   DW 0                        ; /  number of last match
  383. MasterWild  DB 80 DUP (0)               ;/   original search wildcard
  384. HandleList  DW FILES DUP (0)            ;list of which handles are what
  385. Transfer    DB BUFFERSIZE DUP (0)       ;transfer buffer (for dumping files)
  386. HeaderOffset DD 0                       ;offset to start of JLIB file
  387. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  388. ;capitalize filename, make sure there's a period, only allow 8 characters
  389. ;for the base name and 3 characters for the extension, doesn't allow
  390. ;characters after an asterick
  391. ;
  392. ;           DS:DX ==> ASCIIZ filename
  393. ;returns:   prepared filename is in 'Buffer'
  394. ;           ZF set if no filename passed (null name)
  395. PROC        FixFileName
  396.             push si bx ax                   ;save what we'll modify
  397.             mov si,dx                       ;DS:SI ==> source name
  398.             cmp [byte ds:si],0              ;\ quit with ZF set, if there's
  399.             jz @@Quit                       ;/ nothing given to us
  400. @@FindEnd:  inc si                          ;\
  401.             cmp [byte ds:si],0              ; > seek to the end of the name
  402.             jnz @@FindEnd                   ;/
  403.             std                             ;\
  404. @@FindStart:lodsb                           ; \
  405.             cmp si,dx                       ;  \
  406.             jz @@GotStart                   ;   | seek back to
  407.             cmp al,'\'                      ;   | the start of
  408.             jz @@IncOne                     ;   | the base name
  409.             cmp al,':'                      ;  /
  410.             jnz @@FindStart                 ; /
  411. @@IncOne:   add si,2                        ;/
  412. @@GotStart: mov bx,offset Buffer            ;CS:BX ==> place for final name
  413.             cld                             ;go forward, now
  414.             mov ah,8                        ;only copy 8 bytes for the base
  415. @@Basename: mov al,[byte ds:si]             ;\
  416.             or al,al                        ; \ load a byte, handling it
  417.             jz @@AddDot                     ; / if it's a NULL
  418.             inc si                          ;/
  419.             cmp al,'.'                      ;if we've found a period, start
  420.             jz @@AddDot                     ;  working on the extension
  421.             MAKEUPPERCASE al                ;\
  422.             mov [byte cs:bx],al             ; > make uppercase and store
  423.             inc bx                          ;/
  424.             cmp al,'*'                      ;if we've found an asterick, then
  425.             jz @@Ignore                     ;  ignore all up to period or end
  426.             dec ah                          ;\ only copy 8 characters
  427.             jnz @@Basename                  ;/
  428. @@Ignore:   mov al,[byte ds:si]             ;\
  429.             or al,al                        ; \
  430.             jz @@AddDot                     ;  \ skip until a NULL or a
  431.             inc si                          ;  / period is encountered
  432.             cmp al,'.'                      ; /
  433.             jnz @@Ignore                    ;/
  434. @@AddDot:   mov [byte cs:bx],'.'            ;\ tack on a period
  435.             inc bx                          ;/
  436.             mov ah,3                        ;only copy 3 bytes for the ext
  437. @@Extension:lodsb                           ;\  load a byte and handle
  438.             or al,al                        ; > it if it's a NULL
  439.             jz @@Done                       ;/
  440.             MAKEUPPERCASE al                ;\
  441.             mov [byte cs:bx],al             ; > make uppercase and store it
  442.             inc bx                          ;/
  443.             cmp al,'*'                      ;\ if we copied a '*', then there
  444.             jz @@Done                       ;/ shouldn't be anything after it
  445.             dec ah                          ;\ only copy 3 characters
  446.             jnz @@Extension                 ;/
  447. @@Done:     mov [byte cs:bx],0              ;\ terminate it with a NULL
  448.             or al,1               ;clear ZF ;/
  449. @@Quit:     pop ax bx si                    ;restore everything
  450.             ret                             ;return
  451. ENDP        FixFileName
  452. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  453. ;locates a file structure that matches identically to a specified file
  454. ;
  455. ;           ASCIIZ filename to match is in 'Buffer'
  456. ;returns:   SI ==> appropiate structure
  457. ;           AX = file number (0 based)
  458. ;           carry set if not found
  459. PROC        MatchFile
  460.             push di bx cx dx
  461.             xor ax,ax
  462.             mov si,offset FileStats
  463.             mov cx,[cs:NumFiles]
  464.             mov di,offset Buffer
  465. @@NewFile:  xor bx,bx
  466. @@Compare:  mov dl,[byte cs:si+bx+offset (LibFile).Filename]
  467.             or dl,dl
  468.             jz @@GotIt
  469.             cmp dl,[byte cs:di+bx]
  470.             jnz @@Next
  471.             inc bx
  472.             jmp @@Compare
  473. @@Next:     add si,size LibFile
  474.             inc ax
  475.             loop @@NewFile
  476.             stc                     ;signal error
  477.             jmp @@Quit
  478. @@GotIt:    clc                     ;signal success
  479. @@Quit:     pop dx cx bx di
  480.             ret
  481. ENDP        MatchFile
  482. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  483. ;locates a file structure that matches a specified wildcard
  484. ;
  485. ;           ASCIIZ wildcard to match is in 'Wildcard'
  486. ;           AX = file number from last call (-1 for first time)
  487. ;returns:   if CF clear then
  488. ;               SI ==> appropiate structure
  489. ;               AX = file number (0 based)
  490. ;           else
  491. ;               no more matching files or invalid starting number
  492. ;           endif
  493. PROC        MatchWild
  494.             push di bx cx dx bp
  495.             mov bx,ax                   ;\
  496.             inc bx                      ; \ make sure the start value is okay
  497.             cmp bx,[cs:NumFiles]        ; /
  498.             jae @@NoMore                ;/
  499.             inc ax                      ;AX = first entry to check
  500.             push ax                     ;\
  501.             mov bx,size LibFile         ; \
  502.             mul bx                      ;  \ SI ==> first structure to check
  503.             mov si,offset FileStats     ;  /
  504.             add si,ax                   ; /
  505.             pop ax                      ;/
  506.             mov cx,[cs:NumFiles]        ;\
  507.             sub cx,ax                   ; > CX = number of files to check
  508.             inc cx                      ;/
  509.             mov di,offset Wildcard      ;DI ==> wildcard string
  510. @@NewFile:  xor bx,bx
  511.             mov bp,offset (LibFile).Filename
  512. @@Compare:  mov dl,[byte cs:di+bx]      ;DL = wildcard letter
  513.             mov dh,[byte cs:si+bp]      ;DH = filename letter
  514.             inc bx
  515.             inc bp
  516.             cmp dl,'.'                  ;\
  517.             jz @@GotDot                 ; \
  518.             cmp dh,'.'                  ;  \
  519.             jnz @@NoDot                 ;   > period ('.')
  520. @@GotDot:   cmp dl,dh                   ;  /
  521.             jnz @@NoMatch               ; /
  522.             jmp @@Compare               ;/
  523. @@NoDot:    or dl,dl                    ;\
  524.             jz @@GotNull                ; \
  525.             or dh,dh                    ;  \
  526.             jnz @@NoNull                ;   > null (0h)
  527. @@GotNull:  cmp dh,dl                   ;  /
  528.             jz @@Found                  ; /
  529.             jmp @@NoMatch               ;/
  530. @@NoNull:   cmp dl,'?'                  ;\ question mark ('?')
  531.             jz @@Compare                ;/
  532.             cmp dl,'*'                  ;\
  533.             jnz @@NotStar               ; \
  534. @@Ignore:   mov dl,[byte cs:si+bp]      ;  \
  535.             cmp dl,'.'                  ;   |
  536.             jz @@Compare                ;   | asterick ('*')
  537.             or dl,dl                    ;   |
  538.             jz @@Compare                ;  /
  539.             inc bp                      ; /
  540.             jmp @@Ignore                ;/
  541. @@NotStar:  cmp dl,dh                   ;\ if it matches up, then go
  542.             jz @@Compare                ;/ on to the next character
  543. @@NoMatch:  add si,size LibFile         ;point to the next structure
  544.             inc ax                      ;increment our counter
  545.             loop @@NewFile              ;loop until we've searched all
  546. @@NoMore:   pop bp dx cx bx di          ;\
  547.             stc                         ; > quit unsucessfully
  548.             ret                         ;/
  549. @@Found:    pop bp dx cx bx di          ;\
  550.             clc                         ; > quit sucessfully
  551.             ret                         ;/
  552. ENDP        MatchWild
  553. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  554. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  555. ;░░░░░░░░░░░░░░░░░░░░ Interrupt handlers ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  556. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  557. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  558. PROC        NewInt21 FAR
  559.             cmp ah,3Dh
  560.             jz OpenFile
  561.             cmp ah,3Eh
  562.             jz CloseFile
  563.             cmp ah,4Eh
  564.             jz FindFirst
  565.             cmp ah,4Fh
  566.             jz FindNext
  567.             cmp ah,4Bh
  568.             jz Execute
  569.  
  570.             jmp [dword cs:OldInt21]
  571. ENDP        NewInt21
  572. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  573. ;           AL = access mode (0 = read, 1 = write, 2 = read/write)
  574. ;           DS:DX ==> ASCIIZ filename
  575. ;returns:   AX = file handle
  576. ;
  577. ;(to temporarily dump a file to disk, set AX = 0, DS:DX ==> filename)
  578. ;(will return an internal pointer in AX to be passed to CloseFile later)
  579. ;(if -1 is returned, then the file is not contained in the library)
  580. ;(remember to pushf before far calling this routine to simulate an interrupt)
  581. PROC        OpenFile FAR
  582.             push ds es bx cx dx si di ax
  583.             call FixFileName
  584.             jz @@CallOld
  585.             call MatchFile
  586.             jc @@CallOld
  587.  
  588.             ;*** Open up the library and dump out the file requested ***
  589.             mov ax,3D00h                            ;\
  590.             push cs                                 ; \
  591.             pop ds                                  ;  \
  592.             mov dx,offset LibName                   ;   \ reopen the library
  593.             pushf                                   ;   /
  594.             call [dword cs:OldInt21]                ;  /
  595.             jc @@CallOld                            ; /
  596.             mov [Handle],ax                         ;/
  597.             mov ax,4200h                            ;\
  598.             mov bx,[Handle]                         ; \
  599.             mov cx,[word si+2+LibFile.FileOffset]   ;  \ position the pointer
  600.             mov dx,[word si+0+LibFile.FileOffset]   ;  /
  601. ;-------- 1.3 changes start here
  602.             add dx,[word HeaderOffset+0]
  603.             adc cx,[word HeaderOffset+2]
  604. ;-------- 1.3 changes start here
  605.             pushf                                   ; /
  606.             call [dword cs:OldInt21]                ;/
  607.             mov ah,3Ch                              ;\
  608.             xor cx,cx                               ; \
  609.             mov dx,si                               ;  \
  610.             add dx,offset (LibFile).Filename        ;   > create the file
  611.             pushf                                   ;  /
  612.             call [dword cs:OldInt21]                ; /
  613.             mov [Handle2],ax                        ;/
  614.             mov cx,[word si+0+LibFile.FileSize]     ;\ DX:CX ==> size to copy
  615.             mov dx,[word si+2+LibFile.FileSize]     ;/
  616. @@CopyLoop: or dx,dx                                ;\
  617.             jnz @@CopyBig                           ; \
  618.             cmp cx,BUFFERSIZE                       ;  \
  619.             jbe @@CopySmall                         ;   \
  620. @@CopyBig:  push cx dx                              ;    |
  621.             mov ah,3Fh                              ;    |
  622.             mov bx,[Handle]                         ;    |
  623.             mov cx,BUFFERSIZE                       ;    |
  624.             mov dx,offset Transfer                  ;    |
  625.             pushf                                   ;    |
  626.             call [dword cs:OldInt21]                ;    |
  627.             mov ah,40h                              ;    |
  628.             mov bx,[Handle2]                        ;    |
  629.             mov cx,BUFFERSIZE                       ;    |
  630.             mov dx,offset Transfer                  ;    | dump the data from
  631.             pushf                                   ;    | the library into a
  632.             call [dword cs:OldInt21]                ;    | separate file
  633.             pop dx cx                               ;    | (a decompression
  634.             sub cx,BUFFERSIZE                       ;    | scheme could be
  635.             sbb dx,0                                ;    | implemented here
  636.             jmp @@CopyLoop                          ;    | if transparent file 
  637. @@CopySmall:jcxz @@CopyDone                         ;    | compression were to
  638.             push cx                                 ;    | be added)
  639.             mov ah,3Fh                              ;    |
  640.             mov bx,[Handle]                         ;    |
  641.             mov dx,offset Transfer                  ;    |
  642.             pushf                                   ;    |
  643.             call [dword cs:OldInt21]                ;    |
  644.             mov ah,40h                              ;    |
  645.             mov bx,[Handle2]                        ;    |
  646.             pop cx                                  ;   /
  647.             mov dx,offset Transfer                  ;  /
  648.             pushf                                   ; /
  649.             call [dword cs:OldInt21]                ;/
  650. @@CopyDone: mov ah,3Eh                              ;\
  651.             mov bx,[Handle]                         ; \
  652.             mov [Handle],-1                         ;  > close the library
  653.             pushf                                   ; /
  654.             call [dword cs:OldInt21]                ;/
  655.             mov ah,3Eh                              ;\
  656.             mov bx,[Handle2]                        ; \
  657.             mov [Handle2],-1                        ;  > close the output
  658.             pushf                                   ; /
  659.             call [dword cs:OldInt21]                ;/
  660.  
  661.  
  662.             ;*** let DOS open the temporary file ***
  663.             pop ax
  664.             cmp ah,3Dh              ;check to see if it's an internal call
  665.             jnz @@Internal          ;   if yes -- then just return a pointer
  666.             mov dx,si
  667.             add dx,offset (LibFile).Filename
  668.             pushf
  669.             call [dword cs:OldInt21]
  670.             mov di,ax
  671.             shl di,1
  672.             add di,offset HandleList
  673.             mov [word di],si
  674.             pop di si dx cx bx es ds
  675.             ret 2
  676. @@Internal: mov ax,si
  677.             pop di si dx cx bx es ds
  678.             ret 2
  679. @@CallOld:  pop ax di si dx cx bx es ds
  680.             cmp ah,3Dh
  681.             jz @@CallOld2
  682.             mov ax,-1
  683.             ret 2
  684. @@CallOld2: jmp [dword cs:OldInt21]
  685. ENDP        OpenFile
  686. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  687. ;           BX = file handle
  688. ;
  689. ;(to delete an internally dumped, temporary file, set AX = 0, SI = pointer)
  690. ;(if a -1 is passed in SI, this function has no effect)
  691. ;(remember to pushf before far calling this routine to simulate an interrupt)
  692. PROC        CloseFile FAR
  693.             push ax bx cx dx si di ds es
  694.  
  695.             cmp ah,3Eh
  696.             jnz @@Internal
  697.  
  698.             ;*** if it's ours, set SI to its structure, else call DOS ***
  699.             mov di,bx
  700.             shl di,1
  701.             add di,offset HandleList
  702.             cmp [word cs:di],0
  703.             jz @@CallOld
  704.             mov si,[word cs:di]
  705.             mov [word cs:di],0
  706.  
  707.             ;*** close the file ***
  708.             mov ah,3Eh
  709.             pushf
  710.             call [dword cs:OldInt21]
  711.  
  712. @@Internal: ;*** and delete the temporary file ***
  713.             cmp si,-1
  714.             jz @@Quit
  715.             mov ah,41h
  716.             push cs
  717.             pop ds
  718.             mov dx,si
  719.             add dx,offset (LibFile).Filename
  720.             int 21h
  721.  
  722. @@Quit:     pop es ds di si dx cx bx ax
  723.             clc
  724.             ret 2
  725. @@CallOld:  pop es ds di si dx cx bx ax
  726.             jmp [dword cs:OldInt21]
  727. ENDP        CloseFile
  728. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  729. ;           CX = attributes to search for
  730. ;           DS:DX ==> ASCIIZ filespec
  731. ;returns:   AX = error code, if CF set
  732. ;           DTA contains search information
  733. PROC        FindFirst FAR
  734.             push ds es ax bx cx dx si di
  735.  
  736.             mov [cs:MasterAttr],cx          ;save original search attribute
  737.             mov si,dx                       ;\
  738.             mov di,offset MasterWild        ; \
  739.             push cs                         ;  \
  740.             pop es                          ;   \ save the original wildcard
  741.             mov cx,79                       ;   /
  742.             rep movsb                       ;  /
  743.             xor al,al                       ; /
  744.             stosb                           ;/
  745.             call FixFileName                ;\ process and parse the filespec
  746.             jz @@CallOld                    ;/
  747.             cld                             ;\
  748.             mov ax,cs                       ; \
  749.             mov ds,ax                       ;  |
  750.             mov es,ax                       ;  | transfer the wildcard
  751.             mov si,offset Buffer            ;  | into storage
  752.             mov di,offset Wildcard          ;  |
  753.             mov cx,12                       ; /
  754.             rep movsb                       ;/
  755.             mov ah,2Fh                      ;\
  756.             pushf                           ; > ES:BX ==> current DTA
  757.             call [dword cs:OldInt21]        ;/
  758.             mov di,bx                       ;\
  759.             mov cx,size DTA                 ; \ blank out the DTA
  760.             xor al,al                       ; /
  761.             rep stosb                       ;/
  762.             mov ax,-1                       ;\
  763.             call MatchWild                  ; \  do the search and save
  764.             jc @@CallOld                    ;  > what is needed to continue
  765.             mov [cs:LastMatch],ax           ; /  where we left off
  766.             mov [cs:HandleNext],1           ;/
  767.             mov di,bx                       ;\
  768.             add di,offset (DTA).AttrFound   ; \ copy over the stats about
  769.             mov cx,22                       ; / the file into the DTA
  770.             rep movsb                       ;/
  771.             pop di si dx cx bx ax es ds     ;\
  772.             clc                             ; > return with a successful find
  773.             ret 2                           ;/
  774. @@CallOld:  mov [cs:HandleNext],0           ;\
  775.             pop di si dx cx bx ax es ds     ; > start searching thru DOS
  776.             jmp [dword cs:OldInt21]         ;/
  777. ENDP        FindFirst
  778. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  779. PROC        FindNext FAR
  780.             push ds dx es ax bx cx si di
  781.  
  782.             cmp [cs:HandleNext],0           ;\ if we're not supposed to
  783.             jz @@CallOld                    ;/ handle this, then don't
  784.             mov ax,[cs:LastMatch]           ;\
  785.             call MatchWild                  ; \ continue searching, then save
  786.             jc @@StartOld                   ; / what's needed to continue
  787.             mov [cs:LastMatch],ax           ;/
  788.             push cs                         ;\ DS:SI ==> file structure
  789.             pop ds                          ;/
  790.             mov ah,2Fh                      ;\
  791.             pushf                           ; > ES:BX ==> current DTA
  792.             call [dword cs:OldInt21]        ;/
  793.             mov di,bx                       ;\
  794.             mov cx,size DTA                 ; \ blank out the DTA
  795.             xor al,al                       ; /
  796.             rep stosb                       ;/
  797.             mov di,bx                       ;\
  798.             add di,offset (DTA).AttrFound   ; \ copy over the stats about
  799.             mov cx,22                       ; / the file into the DTA
  800.             rep movsb                       ;/
  801.             pop di si cx bx ax es dx ds     ;\
  802.             clc                             ; > return with a successful find
  803.             ret 2                           ;/
  804. @@StartOld: mov [cs:HandleNext],0           ;\
  805.             pop di si cx bx ax es           ; \
  806.             mov ah,4Eh                      ;  \
  807.             mov cx,[cs:MasterAttr]          ;   \
  808.             push cs                         ;    \
  809.             pop ds                          ;     > start searching thru DOS
  810.             mov dx,offset MasterWild        ;    /
  811.             pushf                           ;   /
  812.             call [dword cs:OldInt21]        ;  /
  813.             pop dx ds                       ; /
  814.             ret 2                           ;/
  815. @@CallOld:  pop di si cx bx ax es dx ds     ;\ continue searching thru DOS
  816.             jmp [dword cs:OldInt21]         ;/
  817. ENDP        FindNext
  818. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  819. ;           DS:DX ==> ASCIIZ filename to run
  820. ;           ES:BX ==> Parameter block for exec function
  821. ;returns:   AX = error code, if CF set
  822. PROC        Execute FAR
  823.             mov [cs:@@Temp],si
  824.             mov si,[cs:ExecSavePtr]
  825.             cmp si,MaxExecNests*size ExecSaveType
  826.             jae @@Error
  827.             add [cs:ExecSavePtr],size ExecSaveType
  828.  
  829.             ;temporarily dump out the file
  830.             push ax
  831.             xor ax,ax
  832.             pushf
  833.             call OpenFile
  834.             mov [cs:offset ExecSave+si+offset (ExecSaveType).FilePointer],ax
  835.             pop ax
  836.  
  837.             ;let DOS execute it
  838.             mov [word cs:offset ExecSave+si+0+offset (ExecSaveType).StackPointer],sp
  839.             mov [word cs:offset ExecSave+si+2+offset (ExecSaveType).StackPointer],ss
  840.             mov si,[cs:@@Temp]
  841.             pushf                       ;\ simulate an int 21h to old handler
  842.             call [dword cs:OldInt21]    ;/
  843.             ;get the system back to normality
  844.             cli
  845.             mov [cs:@@Temp],si
  846.             mov si,[cs:ExecSavePtr]
  847.             mov sp,[word cs:offset ExecSave+si-size ExecSaveType+0+offset (ExecSaveType).StackPointer]
  848.             mov ss,[word cs:offset ExecSave+si-size ExecSaveType+2+offset (ExecSaveType).StackPointer]
  849.             pushf
  850.             push ax
  851.             sti
  852.  
  853.             ;delete our temporary file
  854.             xor ax,ax
  855.             mov si,[cs:offset ExecSave+si-size ExecSaveType+offset (ExecSaveType).FilePointer]
  856.             pushf
  857.             call CloseFile
  858.  
  859.             ;deallocate this program's slot on our stack
  860.             sub [cs:ExecSavePtr],size ExecSaveType
  861.  
  862.             ;return (with current flag settings)
  863.             pop ax
  864.             popf
  865.             mov si,[cs:@@Temp]
  866.             ret 2
  867. @@Error:    stc
  868.             mov ax,5        ;return with 'access denied'
  869.             ret 2
  870. @@Temp      dw ?
  871. ENDP        Execute
  872. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  873. MaxExecNests = 10
  874. ExecSavePtr dw 0
  875. struc       ExecSaveType
  876.             StackPointer dd ?
  877.             FilePointer dw ?
  878. ends        ExecSaveType
  879. ExecSave    ExecSaveType MaxExecNests dup (<>)
  880. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  881. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  882. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  883. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  884. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  885. ENDS        Code
  886.  
  887. SEGMENT     zzzzzseg
  888.             DB 16 DUP(?)
  889. ENDS        zzzzzseg
  890.  
  891.             END     Start
  892.