Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1179 lines
30 KiB

  1. ;/*
  2. ; * Microsoft Confidential
  3. ; * Copyright (C) Microsoft Corporation 1991
  4. ; * All Rights Reserved.
  5. ; */
  6. Title E2BINIT(EXE2BIN)
  7. ;*****************************************************************************
  8. ; Loader for EXE files under 86-DOS
  9. ; VER 1.5
  10. ; 05/21/82 Added rev number
  11. ; VER 1.6
  12. ; 07/01/82 A little less choosy about size matches
  13. ; VER 2.0 M.A.U
  14. ; 10/08/82 Modified to use new 2.0 system calls for file i/o
  15. ; Ver 2.1 M.A.U
  16. ; 10/27/82 Added the DOS version check
  17. ; Ver 2.2 MZ
  18. ; 8/30/83 Fixed command line parsing
  19. ; Ver 2.3 EE
  20. ; 10-12-83 More fixes to command line parsing
  21. ; Ver 2.4 NP
  22. ; 10/17/83 Use Printf for messages
  23. ; Ver 2.5 MZ Fix LOCATE sss D: problem
  24. ; 04/09/87 Add PARSER and MESSAGE RETRIEVER
  25. ; Ver 4.00 DRM
  26. ;
  27. ; M001 MD 12/27/90 Removed special checks for ambiguous
  28. ; file names
  29. ;*****************************************************************************
  30. INCLUDE SYSMSG.INC
  31. MSG_UTILNAME <EXE2BIN> ;AN000;
  32. subttl Main Code Area ;AN000;
  33. page
  34. ; The following switch allows use with the "old linker", which put a version
  35. ; number where the new linker puts the number of bytes used in the last page.
  36. ; If enabled, this will cause a test for 0004 at this location (the old linker
  37. ; version number), and if equal, change it to 200H so all of the last page
  38. ; will be used.
  39. OLDLINK EQU 0 ;1 to enable, 0 to disable
  40. CODE SEGMENT PARA PUBLIC 'CODE' ;AN000;
  41. CODE ENDS ;AN000;
  42. DATA SEGMENT PARA PUBLIC 'DATA' ;AN000;
  43. DATA ENDS ;AN000;
  44. STACK SEGMENT PARA PUBLIC 'STACK' ;AN000;
  45. STACK ENDS ;AN000;
  46. ZLOAD SEGMENT PARA PUBLIC 'ZLOAD' ;AN000;
  47. ZLOAD ENDS ;AN000;
  48. DATA SEGMENT PARA PUBLIC 'DATA' ;AN000;
  49. MSG_SERVICES <MSGDATA> ;AN000;
  50. Command_Line_Buffer db 128 dup(0) ;AN000;
  51. Command_Line_Length equ $ - Command_Line_Buffer ;AN000;
  52. Fatal_Error db 0 ;AN000;
  53. Command_Line db NO
  54. rev db "2.4"
  55. file1_ext db ".EXE",00h
  56. file2_ext db ".BIN",00h
  57. per11 db 0 ;AN000;
  58. per2 db 0
  59. per22 db 0 ;AN000;
  60. update equ 0 ;AN000;
  61. noupdate equ -1 ;AN000;
  62. file1 db (64+13) dup(?)
  63. fnptr dw offset file1 ; Ptr to filename in file1
  64. handle1 dw 1 dup(?)
  65. file2 db (64+13) dup(?)
  66. f2cspot dw offset file2 ; Ptr to spot in file2, file1 maybe added
  67. name2_given db 1 ;1-> atleast the file2 name is present
  68. ext2_given db 0 ;1-> full file2 spec given
  69. file2_given db 0 ; is TRUE if user specified atleast a
  70. ; drive, or path (or full name)
  71. handle2 dw 1 dup(?)
  72. dma_buf db 80h dup(0) ; DMA transfer buffer
  73. INBUF DB 5,0
  74. DB 5 DUP(?)
  75. ;The following locations must be defined for storing the header:
  76. RUNVAR LABEL BYTE ;Start of RUN variables
  77. RELPT DW ?
  78. LASTP LABEL WORD
  79. RELSEG DW ?
  80. SIZ LABEL WORD ;Share these locations
  81. PAGES DW ?
  82. RELCNT DW ?
  83. HEADSIZ DW ?
  84. DW ?
  85. LOADLOW DW ?
  86. INITSS DW ?
  87. INITSP DW ?
  88. DW ?
  89. INITIP DW ?
  90. INITCS DW ?
  91. RELTAB DW ?
  92. RUNVARSIZ EQU $-RUNVAR
  93. DBCS_Vector_Off dw 0 ;AN000;
  94. DBCS_Vector_Seg dw 0 ;AN000;
  95. parse_ptr DW ?
  96. DATA ENDS
  97. STACK SEGMENT PARA PUBLIC 'STACK'
  98. DB (362 - 80h) + 80H DUP (?) ; (362 - 80h) is IBMs ROM requirement
  99. ; (New - Old) == size of growth
  100. STACK ENDS
  101. ;
  102. ZLOAD SEGMENT PARA PUBLIC 'ZLOAD'
  103. db ?
  104. ZLOAD ENDS
  105. LOAD EQU ZLOAD
  106. ;
  107. ;
  108. ;*****************************************************************************
  109. ; Include files
  110. ;*****************************************************************************
  111. ;
  112. .xlist
  113. INCLUDE DOSSYM.INC ; also versiona.inc ;AN000;
  114. INCLUDE SYSCALL.INC ;AN000;
  115. INCLUDE E2BMACRO.INC ;AN000;
  116. INCLUDE E2BEQU.INC ;AN000;
  117. INCLUDE E2BTABLE.INC ;AN000;
  118. INCLUDE E2BPARSE.INC ;AN000;
  119. include version.inc
  120. .list
  121. CODE SEGMENT PARA PUBLIC 'CODE'
  122. assume cs:CODE,ds:DATA,es:NOTHING,SS:STACK ;AN000;
  123. psp_ptr dw 1 dup(?) ;AN000;
  124. ;
  125. ;*****************************************************************************
  126. ; SysDisplayMsg Declarations
  127. ;*****************************************************************************
  128. ;
  129. .xlist
  130. MSG_SERVICES <LOADmsg> ;AN000;
  131. MSG_SERVICES <DISPLAYmsg,CHARmsg> ;AN000;
  132. MSG_SERVICES <EXE2BIN.CLA,EXE2BIN.CLB> ;AN000;
  133. MSG_SERVICES <EXE2BIN.CL1,EXE2BIN.CL2> ;AN000;
  134. MSG_SERVICES <EXE2BIN.CTL> ;AN000;
  135. .list
  136. ;
  137. ;*****************************************************************************
  138. ; External Routine Declarations
  139. ;*****************************************************************************
  140. ;
  141. public SysDispMsg ;AN000;
  142. public SysLoadMsg ;AN000;
  143. ;*****************************************************************************
  144. ;Routine name: Main_Init
  145. ;*****************************************************************************
  146. ;
  147. ;Description: Main control routine for init section
  148. ;
  149. ;Called Procedures: Message (macro)
  150. ; Check_DOS_Version
  151. ; Init_Input_Output
  152. ; Validate_Target_Drive
  153. ; Hook_CNTRL_C
  154. ;
  155. ;Input: None
  156. ;
  157. ;Output: None
  158. ;
  159. ;Change History: Created 6/22/87 DM
  160. ;
  161. ;*****************************************************************************
  162. procedure Main_Init near ; ;AN000;
  163. ASSUME DS:NOTHING ; THIS IS WHAT dos GIVES YOU ;AN000;
  164. ASSUME ES:NOTHING ;AN000;
  165. PUSH DS ;AN000;
  166. mov psp_ptr,ds ;AN000;
  167. XOR AX,AX ;AN000;
  168. PUSH AX ;Push return address to DS:0 ;AN000;
  169. MOV AX,SEG DATA ;SET UP ADDRESSABILITY TO ;AN000;
  170. MOV DS,AX ; THE DATA SEGMENT ;AN000;
  171. ASSUME DS:DATA ;TELL ASSEMBLER WHAT I JUST DID ;AN000;
  172. mov Fatal_Error,No ;Init the error flag ;AN000;
  173. call Init_Input_Output ;Setup messages and parse ;AN000;
  174. cmp Fatal_Error,Yes ;Error occur? ;AN000;
  175. ; $IF NE ;Nope, keep going ;AN000;
  176. JE $$IF1
  177. call LOCATE ;Go do the real program ;AN000;
  178. ; $ENDIF ;AN000;
  179. $$IF1:
  180. xor al,al ;AN000;
  181. Dos_call Exit ;AN000;
  182. int 20h ;If other exit fails ;AN000;
  183. Main_Init endp ;AN000;
  184. ;*****************************************************************************
  185. ;Routine name: Init_Input_Output
  186. ;*****************************************************************************
  187. ;
  188. ;Description: Initialize messages, Parse command line, allocate memory as
  189. ; needed. If there is a /FS switch, go handle it first as
  190. ; syntax of IFS format may be different from FAT format.
  191. ;
  192. ;Called Procedures: Preload_Messages
  193. ; Parse_For_FS_Switch
  194. ; Parse_Command_Line
  195. ; Interpret_Parse
  196. ;
  197. ;Change History: Created 6/22/87 DM
  198. ;
  199. ;Input: PSP command line at 81h and length at 80h
  200. ; Fatal_Error = No
  201. ;
  202. ;Output: Fatal_Error = YES/NO
  203. ;
  204. ;*****************************************************************************
  205. procedure Init_Input_Output near ;AN000;
  206. call Preload_Messages ;Load up message retriever ;AN000;
  207. cmp Fatal_Error,YES ;Quit? ;AN000;
  208. ; $IF NE ;Nope, keep going ;AN000;
  209. JE $$IF3
  210. call Parse_Command_Line ;Parse in command line input ;AN000;
  211. ; $ENDIF ;AN000;
  212. $$IF3:
  213. ret ;AN000;
  214. Init_Input_Output endp ;AN000;
  215. ;*****************************************************************************
  216. ;Routine name: Preload_Messages
  217. ;*****************************************************************************
  218. ;
  219. ;Description: Preload messages using common message retriever routines.
  220. ;
  221. ;Called Procedures: SysLoadMsg
  222. ;
  223. ;
  224. ;Change History: Created 6/22/87 DM
  225. ;
  226. ;Input: Fatal_Error = NO
  227. ;
  228. ;Output: Fatal_Error = YES/NO
  229. ;
  230. ;*****************************************************************************
  231. procedure Preload_Messages near ;AN000;
  232. call SYSLOADMSG ;Preload the messages ;AN000;
  233. ; $IF C ;Error? ;AN000;
  234. JNC $$IF5
  235. call SYSDISPMSG ;AN000;
  236. mov fatal_error, YES ;AN000;
  237. ; $ENDIF ;AN000;
  238. $$IF5:
  239. ret ;AN000;
  240. Preload_Messages endp ;AN000;
  241. ;*****************************************************************************
  242. ;Routine name: Parse_Command_Line
  243. ;*****************************************************************************
  244. ;
  245. ;Description: Parses command line.
  246. ;
  247. ;Called Procedures: Message (macro)
  248. ; Sysparse
  249. ;
  250. ;Change History: Created 6/22/87 DM
  251. ;
  252. ;Input: Fatal_Error = NO
  253. ;
  254. ;Output: Fatal_Error = YES/NO
  255. ;
  256. ;*****************************************************************************
  257. Procedure Parse_Command_Line ;AN000;
  258. push ds ;AN000;
  259. mov ds,psp_ptr ;AN000;
  260. ASSUME DS:NOTHING ;AN000;
  261. mov si,Command_Line_Parms ;AN000;
  262. mov ax,seg command_line_table ;AN000;
  263. push es ;AN000;
  264. mov es,ax ;AN000;
  265. ASSUME ES:NOTHING ;AN000;
  266. mov di,offset Command_Line_Table ;AN000;
  267. xor cx,cx ;AN000;
  268. PUBLIC MainParseLoop
  269. MainParseLoop:
  270. ; $DO ;AN000;
  271. $$DO7:
  272. xor dx,dx ;AN000;
  273. mov es:parse_ptr,si
  274. call Sysparse ;AN000;
  275. cmp ax,No_Error ;AN000;
  276. ; $IF E ;AN000;
  277. JNE $$IF8
  278. ; Check if /? switch entered.
  279. ; If so, display the options help message
  280. ; and set for exit.
  281. ;
  282. ; This gives the user the info they want,
  283. ; without all the other possible error messages.
  284. ;
  285. ; 4/18/90 c-PaulB
  286. cmp es:[sw_synonym1], offset sw1_s1 ; /?
  287. jne CheckSW1Done ; skip this if not
  288. call DisplayOptions ; else display msg
  289. mov es:[Fatal_Error], YES ; set flag to stop
  290. jmp ParseCLExit ; and bail out now
  291. CheckSW1Done:
  292. push ax ;AN000;
  293. push bx ;AN000;
  294. push ds ;AN000;
  295. push es ;AN000;
  296. push si ;AN000;
  297. push di ;AN000;
  298. cmp cx,1 ;AN000;
  299. ; $IF E ;AN000;
  300. JNE $$IF9
  301. mov ax,seg rb_string1_off ;AN000;
  302. mov ds,ax ;AN000;
  303. ASSUME DS:NOTHING ;AN000;
  304. mov si,offset rb_string1_off ;AN000;
  305. mov ax,ds:[si] ;AN000;
  306. mov bx,ax ;AN000;
  307. mov ax,ds:[si+2] ;AN000;
  308. mov ds,ax ;AN000;
  309. ASSUME DS:NOTHING ;AN000;
  310. mov si,bx ;AN000;
  311. mov ax,seg file1 ;AN000;
  312. mov es,ax ;AN000;
  313. ASSUME ES:NOTHING ;AN000;
  314. mov di,offset file1 ;AN000;
  315. call copyfs ;AN000;
  316. ; $ELSE ;AN000;
  317. JMP SHORT $$EN9
  318. $$IF9:
  319. mov ax,seg rb_string2_off ;AN000;
  320. mov ds,ax ;AN000;
  321. ASSUME DS:NOTHING ;AN000;
  322. mov si,offset rb_string2_off ;AN000;
  323. mov ax,ds:[si] ;AN000;
  324. mov bx,ax ;AN000;
  325. mov ax,ds:[si+2] ;AN000;
  326. mov ds,ax ;AN000;
  327. ASSUME DS:NOTHING ;AN000;
  328. mov si,bx ;AN000;
  329. mov ax,seg file2 ;AN000;
  330. mov es,ax ;AN000;
  331. ASSUME ES:NOTHING ;AN000;
  332. mov di,offset file2 ;AN000;
  333. call copyfs ;AN000;
  334. ; $ENDIF ;AN000;
  335. $$EN9:
  336. pop di ;AN000;
  337. pop si ;AN000;
  338. pop es ;AN000;
  339. ASSUME ES:NOTHING ;AN000;
  340. pop ds ;AN000;
  341. ASSUME DS:NOTHING ;AN000;
  342. pop bx ;AN000;
  343. pop ax ;AN000;
  344. ; $ENDIF ;AN000;
  345. $$IF8:
  346. cmp ax,No_Error ;AN000;
  347. ; $ENDDO NE ;AN000;
  348. JE $$DO7
  349. cmp ax,End_of_Parse ;Check for parse error ;AN000;
  350. ; $IF NE ;AN000;
  351. JE $$IF14
  352. push ax ;AN001;
  353. mov ax,es:parse_ptr ;AN001;
  354. mov es:parsoff,ax ;AN001;
  355. mov es:parseg,ds ;AN001;
  356. mov byte ptr ds:[si],0 ;AN001;
  357. pop ax ;AN001;
  358. parse_message ;Must enter file name ;AN000;
  359. mov es:Fatal_Error,YES ;Indicate death! ;AN000;
  360. ; $ENDIF ;AN000;
  361. $$IF14:
  362. ParseCLExit:
  363. pop es ;AN000;
  364. ASSUME ES:NOTHING ;AN000;
  365. pop ds ;AN000;
  366. ASSUME DS:DATA ;AN000;
  367. ret ;AN000;
  368. Parse_Command_Line endp ;AN000;
  369. ;*****************************************************************************
  370. ;Routine name: Parse_Command_Line
  371. ;*****************************************************************************
  372. ;
  373. ;Description: Displays options help message lines.
  374. ;
  375. ;Called Procedures: Display_Interface
  376. ;
  377. ;Change History: Created 5/2/90 c-PaulB
  378. ;
  379. ;Input: No value passed.
  380. ;
  381. ;Output: No value returned.
  382. ;
  383. ;*****************************************************************************
  384. Procedure DisplayOptions
  385. mov dx, offset msgOptions ; get options msg
  386. DO_Loop:
  387. call Display_Interface ; and show it
  388. cmp word ptr es:[msgOptions], MSG_OPTIONS_LAST ; last msg?
  389. je DO_Done ; done if so
  390. inc word ptr es:[msgOptions] ; else get next msg
  391. jmp short DO_Loop ; and go do it
  392. DO_Done:
  393. ret
  394. DisplayOptions endp
  395. ;*****************************************************************************
  396. INCLUDE PARSE.ASM
  397. ;*****************************************************************************
  398. procedure LOCATE near
  399. push ds ;AN000;
  400. ASSUME ES:NOTHING ; THIS IS THE WAY IT GETS HERE! ;AN000;
  401. mov ax,es ; ES -> PSP ;AN000;
  402. mov ds,ax ; DS -> PSP ;AN000;
  403. ASSUME DS:NOTHING ;AN000;
  404. MOV SI,offset file1
  405. MOV BX,SEG DATA
  406. MOV ES,BX
  407. assume es:data ;AN000;
  408. MOV BX,WORD PTR DS:[2] ;Get size of memory
  409. ;-----------------------------------------------------------------------;
  410. ;
  411. ; The rules for the arguments are:
  412. ; File 1:
  413. ; If no extention is present, .EXE is used.
  414. ; File 2:
  415. ; If no drive is present in file2, use the one from file1
  416. ; If no path is specified, then use current dir
  417. ; If no filename is specified, use the filename from file1
  418. ; If no extention is present in file2, .BIN is used
  419. ;
  420. ;----- Get the first file name
  421. push ds ;AN000;
  422. push es ;AN000;
  423. ASSUME ES:DATA ;AN000;
  424. pop ds ;AN000;
  425. ASSUME DS:DATA ;AN000;
  426. sj01:
  427. mov si,offset file1 ; d = file1;
  428. mov per11,0 ; assume no extension on file1;AC000;
  429. ;******************************************************************************
  430. sj0:
  431. lodsb ; while (!IsBlank(c=*p++)) {
  432. cmp al,0
  433. JE SJ2
  434. call dbcs_check ; see if a dbcs character ;AN000;
  435. jc dbcs_1 ; dbcs character, go load another char ;AN000;
  436. cmp al,'\' ; if (c == '\\' || c == ':') {
  437. jnz sj05
  438. mov per11,update ;AC000;
  439. mov fnptr,si ; fnptr = ptr to slash
  440. sj05:
  441. cmp al,':' ; if (c == '\\' || c == ':') {
  442. jnz checkper1
  443. mov per11,update ;AC000;
  444. mov fnptr,si ; fnptr = ptr to slash
  445. checkper1:
  446. cmp al,'.' ; if (c == '.')
  447. jne sj0 ; ;M001
  448. mov per11,noupdate ; set file1 to have extension ;AN000;
  449. jmp short sj0 ; ;M001
  450. ;M001 - code removed
  451. dbcs_1: ; ;AN000;
  452. lodsb ; load another character and got to ;AN000;
  453. jmp short sj0 ; the start again. ;AN000;
  454. ;******************************************************************************
  455. sj2:
  456. get_second:
  457. ;----- Get the second file name
  458. ; Initially we assume that user has not given any file2 spec. Then if we find
  459. ; that user has entered something, then file2_given is made to TRUE;
  460. ; Once file2_given is TRUE, then we assume that user has given atleast a name
  461. ; i.e. name2_given = 1 but ext2_given = 0;
  462. ; if we find that user has given just a drive: then name2_given is made to FALSE
  463. ; The logic then simplifies to :
  464. ; if (!file2_given)
  465. ; copy file1 and add .BIN ext and try to open
  466. ; else { /* file2 given */
  467. ; if (!name2_given)
  468. ; copy name from file1 and .BIN as extn ; try to open
  469. ; else { /* name2 also given */
  470. ; do find_first
  471. ; if (file_not_found)
  472. ; add extn .BIN if needed and try to open
  473. ; else if (it is subdir) {
  474. ; add '\' to it;
  475. ; add the file1 name and .BIN
  476. ; go for file open
  477. ; }
  478. ; } /* else name2 given*/
  479. ; } /* else file2 given */
  480. MOV SI,offset file1
  481. mov di,offset file2 ; d = file2
  482. ;******************************************************************************
  483. sj3:
  484. cmp word ptr [di],00 ; check to see if first character of
  485. je sj32 ; file2 is a null. ;AN000;
  486. mov file2_given,1 ; user has given atleast a partial
  487. ; spec for file2
  488. mov si,offset file2 ; set pointer to file2
  489. ;******************************************************************************
  490. sj31:
  491. lodsb ; If file2 first character is not a
  492. mov f2cspot,si
  493. cmp al,0 ; null, this loop will check to see
  494. JZ maycopy ; the file has an extension assigned;AN000;
  495. call dbcs_check ; to it. If not it will set per2 to ;AN000;
  496. jc dbcs_2 ; go load another byte ;AN000;
  497. cmp al,'\'
  498. jnz checkper6
  499. cmp byte ptr [si],0 ; end of file2 spec ?
  500. jne sj31 ; no, go get next char
  501. mov name2_given,0 ; copy from file1
  502. checkper6:
  503. cmp al,':' ; if (c == '\\' || c == ':') {
  504. jnz checkper4
  505. cmp byte ptr [si],0 ; end of file2 spec ?
  506. jne sj31 ; no, go get next char
  507. mov name2_given,0 ; no name; copy from file1
  508. checkper4: ; there is an extension already.
  509. cmp al,'.' ;
  510. jne sj31 ; M001
  511. mov ext2_given,1 ; M001 - code removed
  512. jmp short sj31 ; M001
  513. ; M001 - code removed
  514. dbcs_2: ;
  515. lodsb ;load another character and got to ;AN000;
  516. jmp short sj31 ;the start again. ;AN000;
  517. ;******************************************************************************
  518. ; we get here only if user specified something - a drive, just a name or
  519. ; even the full spec
  520. ; check if we have to copy the name
  521. maycopy:
  522. cmp name2_given,1 ; did the user give a name
  523. je sj5 ; yes, go check for the existence
  524. dec f2cspot
  525. mov di,f2cspot
  526. sj32:
  527. ; There is no second filename so
  528. mov si,fnptr ;AN000;
  529. ;******************************************************************************
  530. copy1to2: ;AN000;
  531. lodsb ; This loop is executed when there is ;AN000;
  532. cmp al,0 ; no file2 specified on the command ;AN000;
  533. JZ SJ5 ; line. It will copy the file1 name ;AN000;
  534. call dbcs_check ; check for dbcs character ;AN000;
  535. jc dbcs_3 ; got a dbcs character, go copy. ;AN000;
  536. cmp al,'.' ; extension. The defult extension ;AN000;
  537. je sj5 ; of .BIN will be added in check_ext. ;AN000;
  538. stosb ;AN000;
  539. jmp short copy1to2 ;AN000;
  540. dbcs_3:
  541. stosb ; Got a dbcs character. Copy ;AN000;
  542. lodsb ; two characters and then go to ;AN000;
  543. stosb ; next character in filename. ;AN000;
  544. jmp short copy1to2 ;AN000; ;AN000;
  545. ;******************************************************************************
  546. sj5:
  547. ; mov byte ptr es:[di],00h ; *d = 0;
  548. cmp file2_given,1 ; if the user specified some path
  549. jne check_ext ; we need to check it; else
  550. cmp name2_given,1 ; add .BIN and try to open file2
  551. jne check_ext ; (at this point we have the name)
  552. mov ah,Set_DMA ; Use find_first to see if file2 is
  553. mov dx,offset dma_buf ; a directory. If it isn't, go to
  554. int 21h ; set f2cspot to point to the spot
  555. mov ah,Find_First ; right after the backslash, and
  556. mov dx,offset file2 ; fall through to no_second so that
  557. mov cx,-1 ; file1's name will be added to file2.
  558. int 21h
  559. jc check_ext
  560. test dma_buf+21,00010000b
  561. jNZ DoDirectory
  562. jmp short Check_Ext
  563. DoDirectory:
  564. mov AL,'\'
  565. mov di,f2cspot
  566. dec di
  567. stosb
  568. inc f2cspot
  569. mov name2_given,0 ; so that we will copy file1.ext to
  570. mov ext2_given,0 ; file2; we also have to copy ext
  571. jmp maycopy ;
  572. ;----- Check that files have an extension, otherwise set default
  573. check_ext:
  574. cmp per11,noupdate ; if (ext2_given == NULL) { ;AC000;
  575. jz file1_ok
  576. mov di,offset file1 ; d = file1;
  577. mov si,offset file1_ext ; s = ".EXE";
  578. call strcat ; strcat (d, s);
  579. file1_ok: ; }
  580. cmp ext2_given,1 ; if (ext2_given == NULL) { ;AC000;
  581. je file2_ok
  582. mov di,offset file2 ; d = file2;
  583. mov si,offset file2_ext ; s = ".BIN";
  584. call strcat ; strcat (d, s);
  585. jmp short file2_ok ; }
  586. ;-----------------------------------------------------------------------;
  587. file2_ok:
  588. mov dx,offset file1
  589. mov ax,(open SHL 8) + 0 ;for reading only
  590. INT 21H ;Open input file
  591. jc bad_file
  592. mov [handle1],ax
  593. jmp short exeload
  594. bad_file:
  595. jmp DosError
  596. BADEXE:
  597. pop ds
  598. ASSUME DS:nothing ;AN000;
  599. MESSAGE msgNoConvert ;AC000;
  600. jmp getout ;AN000;
  601. ReadError:
  602. jmp DosError
  603. EXELOAD:
  604. ASSUME DS:DATA ;AN000;
  605. MOV DX,OFFSET RUNVAR ;Read header in here
  606. MOV CX,RUNVARSIZ ;Amount of header info we need
  607. push bx
  608. mov bx,[handle1]
  609. MOV AH,read
  610. INT 21H ;Read in header
  611. pop bx
  612. jc ReadError
  613. CMP [RELPT],5A4DH ;Check signature word
  614. JNZ BADEXE
  615. MOV AX,[HEADSIZ] ;size of header in paragraphs
  616. ADD AX,31 ;Round up first
  617. CMP AX,1000H ;Must not be >=64K
  618. JAE TOOBIG
  619. AND AX,NOT 31
  620. MOV CL,4
  621. SHL AX,CL ;Header size in bytes
  622. push dx
  623. push cx
  624. push ax
  625. push bx
  626. mov dx,ax
  627. xor cx,cx
  628. mov al,0
  629. mov bx,[handle1]
  630. mov ah,lseek
  631. int 21h
  632. jc LseekError
  633. pop bx
  634. pop ax
  635. pop cx
  636. pop dx
  637. XCHG AL,AH
  638. SHR AX,1 ;Convert to pages
  639. MOV DX,[PAGES] ;Total size of file in 512-byte pages
  640. SUB DX,AX ;Size of program in pages
  641. CMP DX,80H ;Fit in 64K? (128 * 512 = 64k)
  642. JAE TOOBIG
  643. XCHG DH,DL
  644. SHL DX,1 ;Convert pages to bytes
  645. MOV AX,[LASTP] ;Get count of bytes in last page
  646. OR AX,AX ;If zero, use all of last page
  647. JZ WHOLEP
  648. IF OLDLINK
  649. CMP AX,4 ;Produced by old linker?
  650. JZ WHOLEP ;If so, use all of last page too
  651. ENDIF
  652. SUB DX,200H ;Subtract last page
  653. ADD DX,AX ;Add in byte count for last page
  654. WHOLEP:
  655. MOV [SIZ],DX
  656. ADD DX,15
  657. SHR DX,CL ;Convert bytes to paragraphs
  658. MOV BP,SEG LOAD
  659. ADD DX,BP ;Size + start = minimum memory (paragr.)
  660. CMP DX,BX ;Enough memory?
  661. JA TOOBIG
  662. MOV AX,[INITSS]
  663. OR AX,[INITSP]
  664. OR AX,[INITCS]
  665. JMP short ERRORNZ
  666. TOOBIG:
  667. pop ds
  668. ASSUME DS:NOTHING ;AN000;
  669. MESSAGE msgOutOfMemory ;AN000;
  670. jmp getout ;AN000;
  671. LseekError:
  672. jmp DosError
  673. ERRORNZ:
  674. ASSUME DS:DATA ;AN000;
  675. jz xj
  676. JMP BADEXE ;AC000; For ptm P475;
  677. xj: MOV AX,[INITIP]
  678. OR AX,AX ;If IP=0, do binary fix
  679. JZ BINFIX
  680. CMP AX,100H ;COM file must be set up for CS:100
  681. JNZ ERRORNZ
  682. push dx
  683. push cx
  684. push ax
  685. push bx
  686. mov dx,100h ;chop off first 100h
  687. xor cx,cx
  688. mov al,1 ;seek from current position
  689. mov bx,[handle1]
  690. mov ah,lseek
  691. int 21h
  692. jc LseekError
  693. pop bx
  694. pop ax
  695. pop cx
  696. pop dx
  697. SUB [SIZ],AX ;And count decreased size
  698. CMP [RELCNT],0 ;Must have no fixups
  699. JNZ ERRORNZ
  700. BINFIX:
  701. XOR BX,BX ;Initialize fixup segment
  702. ;See if segment fixups needed
  703. CMP [RELCNT],0
  704. JZ LOADEXE
  705. GETSEG:
  706. pop ds
  707. ASSUME DS:NOTHING ;AN000;
  708. MESSAGE msgFixUp ;AN000;
  709. PUSH DS
  710. PUSH ES
  711. POP DS
  712. ASSUME DS:DATA ;AN000;
  713. MOV AH,STD_CON_STRING_INPUT
  714. MOV DX,OFFSET INBUF
  715. INT 21H ;Get user response
  716. MOV SI,OFFSET INBUF+2
  717. ;;dcl;; MOV BYTE PTR [SI-1],0 ;Any digits?
  718. cmp BYTE PTR [SI-1],0 ;Any digits? ;AC000;
  719. JZ GETSEG
  720. DIGLP:
  721. LODSB
  722. SUB AL,"0"
  723. JC DIGERR
  724. CMP AL,10
  725. JB HAVDIG
  726. AND AL,5FH ;Convert to upper case
  727. SUB AL,7
  728. CMP AL,10
  729. JB DIGERR
  730. CMP AL,10H
  731. JAE DIGERR
  732. HAVDIG:
  733. SHL BX,1
  734. SHL BX,1
  735. SHL BX,1
  736. SHL BX,1
  737. OR BL,AL
  738. JMP DIGLP
  739. DIGERR:
  740. CMP BYTE PTR [SI-1],0DH ;Is last char. a CR?
  741. JNZ GETSEG
  742. LOADEXE:
  743. XCHG BX,BP ;BX has LOAD, BP has fixup
  744. MOV CX,[SIZ]
  745. MOV AH,read
  746. push di
  747. mov di,[handle1]
  748. PUSH DS
  749. MOV DS,BX
  750. ASSUME DS:NOTHING ;AN000;
  751. XOR DX,DX
  752. push bx
  753. mov bx,di
  754. INT 21H ;Read in up to 64K
  755. pop bx
  756. POP DS
  757. ASSUME DS:DATA ;AN000;
  758. pop di
  759. Jnc HAVEXE ;Did we get it all?
  760. jmp DosError
  761. LseekError2:
  762. jmp DosError
  763. HAVEXE:
  764. ASSUME DS:DATA ;AN000;
  765. CMP [RELCNT],0 ;Any fixups to do?
  766. JZ STORE
  767. MOV AX,[RELTAB] ;Get position of table
  768. push dx
  769. push cx
  770. push ax
  771. push bx
  772. mov dx,ax
  773. xor cx,cx
  774. mov al,0
  775. mov bx,[handle1]
  776. mov ah,lseek
  777. int 21h
  778. jc LseekError2
  779. pop bx
  780. pop ax
  781. pop cx
  782. pop dx
  783. MOV DX,OFFSET RELPT ;4-byte buffer for relocation address
  784. RELOC:
  785. MOV DX,OFFSET RELPT ;4-byte buffer for relocation address
  786. MOV CX,4
  787. MOV AH,read
  788. push bx
  789. mov bx,[handle1]
  790. INT 21H ;Read in one relocation pointer
  791. pop bx
  792. Jnc RDCMP
  793. jmp short DosError
  794. RDCMP:
  795. MOV DI,[RELPT] ;Get offset of relocation pointer
  796. MOV AX,[RELSEG] ;Get segment
  797. ADD AX,BX ;Bias segment with actual load segment
  798. MOV ES,AX
  799. ASSUME ES:NOTHING ;AN000;
  800. ADD ES:[DI],BP ;Relocate
  801. DEC [RELCNT] ;Count off
  802. JNZ RELOC
  803. STORE:
  804. MOV AH,CREAT
  805. MOV DX,OFFSET file2
  806. xor cx,cx
  807. INT 21H
  808. Jc MKERR
  809. mov [handle2],ax
  810. MOV CX,[SIZ]
  811. MOV AH,write
  812. push di
  813. mov di,[handle2]
  814. PUSH DS
  815. MOV DS,BX
  816. ASSUME DS:NOTHING ;AN000;
  817. XOR DX,DX ;Address 0 in segment
  818. push bx
  819. mov bx,di
  820. INT 21H
  821. pop bx
  822. POP DS
  823. ASSUME DS:DATA ;AN000;
  824. pop di
  825. Jc WRTERR ;Must be zero if more to come
  826. cmp AX,CX
  827. jnz NOROOM
  828. MOV AH,CLOSE
  829. push bx
  830. mov bx,[handle2]
  831. INT 21H
  832. jc CloseError
  833. pop bx
  834. pop ds
  835. pop ds
  836. ASSUME DS:NOTHING ;AN000;
  837. RET
  838. ;*******************************************************************************
  839. NOROOM: ; ;AN000;
  840. ASSUME DS:DATA ;AN000;
  841. MOV AH,CLOSE ; Close the file here ;AN000;
  842. push bx ; ;AN000;
  843. mov bx,[handle2] ; ;AN000;
  844. INT 21H ; ;AN000;
  845. jc CloseError ; If error let extend messages get it;AN000;
  846. pop bx ; ;AN000;
  847. mov ah,UNLINK ; Delete the file because it did ;AN000;
  848. MOV DX,OFFSET file2 ; not get written correctly. ;AN000;
  849. INT 21H ; ;AN000;
  850. jc CloseError ; If error let extend messages get it;AN000;
  851. pop ds ; ;AN000;
  852. ASSUME DS:NOTHING ; ;AN000;
  853. message msgNoDiskSpace ; Put out insufficient disk space ;AN000;
  854. jmp short getout ; message ;AN000;
  855. RET ; return to main_init ;AN000;
  856. ;*******************************************************************************
  857. WRTERR: ;AN000;
  858. MKERR: ;AN000;
  859. CloseError: ;AN000;
  860. public DosError ;AN000;
  861. DosError: ;AN000;
  862. mov es:FileNameSegment,ds ; save for opens, creates, ;AN000;
  863. mov es:FileNameOffset,dx ;AN000;
  864. mov bx,0 ; get the extended error code ;AN000;
  865. mov ah,059h ;AN000;
  866. int 21h ;AN000;
  867. mov si,offset ds:Sublist_msg_exterror ;AC001;
  868. extend_message ;AN001;
  869. pop ds ;AN001;
  870. getout: ;AN000;
  871. pop ds ;AN000;
  872. ASSUME DS:NOTHING ;AN000;
  873. ret ;AN000;
  874. LOCATE ENDP
  875. ;----- concatenate two strings
  876. strcat proc near ; while (*d)
  877. cmp byte ptr [di],0
  878. jz atend
  879. inc di ; d++;
  880. jmp strcat
  881. atend: ; while (*d++ = *s++)
  882. lodsb
  883. stosb
  884. or al,al ; ;
  885. jnz atend
  886. ret
  887. strcat endp
  888. ;----- Find the first non-ignorable char, return carry if CR found
  889. kill_bl proc near
  890. cld
  891. sj10: ; while ( *p != 13 &&
  892. lodsb
  893. CMP AL,13 ; IsBlank (*p++))
  894. JZ BreakOut
  895. CALL IsBlank
  896. JZ SJ10 ; ;
  897. BreakOut:
  898. dec si ; p--;
  899. cmp al,0dh ; return *p == 13;
  900. clc
  901. jne sj11
  902. stc
  903. sj11:
  904. ret
  905. kill_bl endp
  906. IsBlank proc near
  907. cmp al,00 ;AN000;
  908. retz ;AN000;
  909. cmp al,13
  910. retz
  911. cmp al,' ' ; space
  912. retz
  913. cmp al,9 ; tab
  914. retz
  915. cmp al,',' ; comma
  916. retz
  917. cmp al,';' ; semicolon
  918. retz
  919. cmp al,'+' ; plus
  920. retz
  921. cmp al,10 ; line feed
  922. retz
  923. cmp al,'=' ; equal sign
  924. return
  925. IsBlank Endp
  926. procedure copyfs near
  927. push ax ;AN000;
  928. ; $do ; while we have filespec ;AN000;
  929. $$DO16:
  930. lodsb ; move byte to al ;AN000;
  931. cmp al,0 ; see if we are at ;AN000;
  932. ; the end of the
  933. ; filespec
  934. ; $leave e ; exit while loop ;AN000;
  935. JE $$EN16
  936. stosb ; move byte to path_name ;AN000;
  937. ; $enddo ; end do while ;AN000;
  938. JMP SHORT $$DO16
  939. $$EN16:
  940. stosb ;AN000;
  941. pop ax ;AN000;
  942. ret ;AN000;
  943. copyfs endp ;AN000;
  944. procedure dbcs_check near
  945. push ds ;Save registers ;AC000;
  946. push si ; " " " " ;AC000;
  947. push ax ; " " " " ;AC000;
  948. push ds ; " " " " ;AC000;
  949. pop es ;Establish addressability;AC000;
  950. cmp byte ptr es:DBCS_VECTOR,Yes ;Have we set this yet? ;AC000;
  951. push ax ;Save input character ;AC000;
  952. ; $IF NE ;Nope ;AN000;
  953. JE $$IF19
  954. mov al,0 ;Get DBCS environment vectors;AC000;
  955. DOS_Call Hongeul ; " " " " ;AC000;
  956. mov byte ptr es:DBCS_VECTOR,YES ;Indicate we've got vector;AC000;
  957. mov es:DBCS_Vector_Off,si ;Save the vector ;AC000;
  958. mov ax,ds ; ;AC000;
  959. mov es:DBCS_Vector_Seg,ax ; ;AC000;
  960. ; $ENDIF ; for next time in ;AC000;
  961. $$IF19:
  962. pop ax ;Restore input character;AC000;
  963. mov si,es:DBCS_Vector_Seg ;Get saved vector pointer;AC000;
  964. mov ds,si ; ;AC000;
  965. mov si,es:DBCS_Vector_Off ; ;AC000;
  966. ; $SEARCH ;Check all the vectors ;AC000;
  967. $$DO21:
  968. cmp word ptr ds:[si],End_Of_Vector ;End of vector table? ;AC000;
  969. ; $LEAVE E ;Yes, done ;AC000;
  970. JE $$EN21
  971. cmp al,ds:[si] ;See if char is in vector;AC000;
  972. ; $EXITIF AE,AND ;If >= to lower, and ;AC000;
  973. JNAE $$IF21
  974. cmp al,ds:[si+1] ; =< than higher range ;AC000;
  975. ; $EXITIF BE ; then DBCS character ;AC000;
  976. JNBE $$IF21
  977. stc ;Set CY to indicate DBCS;AC000;
  978. ; $ORELSE ;Not in range, check next;AC000;
  979. JMP SHORT $$SR21
  980. $$IF21:
  981. add si,DBCS_Vector_Size ;Get next DBCS vector ;AC000;
  982. ; $ENDLOOP ;We didn't find DBCS chaR;AC000;
  983. JMP SHORT $$DO21
  984. $$EN21:
  985. clc ;Clear CY for exit ;AC000;
  986. ; $ENDSRCH ; ;AC000;
  987. $$SR21:
  988. pop ax ;Restore registers ;AC000;
  989. pop si ; " " " " ;AC000;
  990. pop ds ;Restore data segment ;AC000;
  991. ret ; ;AC000;
  992. ret ;AN000;
  993. dbcs_check endp ;AN000;
  994. CODE ends
  995. end main_init ;AC000;
  996.