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.

570 lines
14 KiB

  1. ;/*
  2. ; * Microsoft Confidential
  3. ; * Copyright (C) Microsoft Corporation 1991
  4. ; * All Rights Reserved.
  5. ; */
  6. ;*****************************************************************************
  7. ;*****************************************************************************
  8. ;UTILITY NAME: FORMAT.COM
  9. ;
  10. ;MODULE NAME: FOREXEC.SAL
  11. ;
  12. ;
  13. ;
  14. ; ��������������Ŀ
  15. ; �EXEC_FS_FORMAT�
  16. ; ����������������
  17. ; �
  18. ; �������Ŀ
  19. ; ôShrink�
  20. ; ���������
  21. ; �����������Ŀ
  22. ; ôSetup_EXEC�
  23. ; �������������
  24. ; ����������Ŀ ������������Ŀ
  25. ; ôEXEC_ArgV����������ĴEXEC_Program�
  26. ; ������������ ��������������
  27. ; �������������������Ŀ ������������Ŀ
  28. ; ôEXEC_Cur_Directory�ĴEXEC_Program�
  29. ; ��������������������� ��������������
  30. ; �������������Ŀ �������������������Ŀ ������������Ŀ
  31. ; ��EXEC_Routine�������ĴBuild_Path_And_EXEC�ĴEXEC_Program�
  32. ; �������������� ��������������������� ��������������
  33. ;
  34. ; Change List: AN000 - New code DOS 3.3 spec additions
  35. ; AC000 - Changed code DOS 3.3 spec additions
  36. ;*****************************************************************************
  37. ;*****************************************************************************
  38. title DOS 3.30 FORMAT EXEC Module
  39. IF1
  40. %OUT ASSEMBLING: DOS 3.3 FORMAT EXEC LOADER
  41. %OUT
  42. ENDIF
  43. code segment public para 'code'
  44. assume cs:code
  45. code ends
  46. ;*****************************************************************************
  47. ; Include files
  48. ;*****************************************************************************
  49. .xlist
  50. INCLUDE FORCHNG.INC
  51. INCLUDE FORMACRO.INC
  52. INCLUDE SYSCALL.INC
  53. INCLUDE FOREQU.INC
  54. .list
  55. ;*****************************************************************************
  56. ; Public Data
  57. ;*****************************************************************************
  58. Public Drive_Letter_Msg
  59. ;*****************************************************************************
  60. ; Public Routines
  61. ;*****************************************************************************
  62. IF FSExec
  63. Public EXEC_FS_Format
  64. ENDIF ;FSExec ;end /FS: conditional
  65. ;***************************************************************************
  66. ; External Data Declarations
  67. ;***************************************************************************
  68. extrn ExitStatus:Byte
  69. extrn Fatal_Error:Byte
  70. extrn FS_String_Buffer:Byte
  71. extrn msgEXECFailure:Byte
  72. extrn PSP_Segment:Word
  73. extrn DriveToFormat:byte
  74. ;**************************************************************************
  75. ; Structures
  76. ;**************************************************************************
  77. Exec_Block_Parms struc
  78. Segment_Env dw 0
  79. Offset_Command dw 0
  80. Segment_Command dw 0
  81. Offset_FCB1 dw 0
  82. Segment_FCB1 dw 0
  83. Offset_FCB2 dw 0
  84. Segment_FCB2 dw 0
  85. Exec_Block_Parms ends
  86. ;**************************************************************************
  87. ; Equates
  88. ;**************************************************************************
  89. String_Done equ 0
  90. No_Error equ 0
  91. Error equ 1
  92. Stderr equ 2
  93. Stack_Space equ 02eh ; IBM addition ROM paras
  94. ;**************************************************************************
  95. ; PSP Area
  96. ;**************************************************************************
  97. PSP segment public para 'DUMMY'
  98. org 2Ch
  99. PSP_ENV_SEGMENT label word
  100. FCB1 equ 5Ch
  101. FCB2 equ 6Ch
  102. org 80h
  103. Command_Line label byte
  104. PSP ends
  105. ;**************************************************************************
  106. ; Data Area
  107. ;**************************************************************************
  108. data segment public para 'DATA'
  109. assume ds:data,es:nothing
  110. Exec_Block Exec_Block_Parms <>
  111. EXEC_Path db 66 dup(0)
  112. Drive_Letter_Msg db "A:",0 ;Drive for exec fail message
  113. SP_Save dw ?
  114. SS_Save dw ?
  115. ;These next two should stay togather
  116. ; ---------------------------------------
  117. Path_String db "PATH="
  118. Len_Path_String equ $ - Path_String
  119. ;----------------------------------------
  120. ;These should stay togather
  121. ; ---------------------------------------
  122. Search_FORMAT db "FORMAT"
  123. Len_Search_FORMAT equ $ - Search_FORMAT
  124. Search_Format_End equ $
  125. ;----------------------------------------
  126. ;These next two should stay togather
  127. ; ---------------------------------------
  128. data ends
  129. ;**************************************************************************
  130. code segment public para 'code'
  131. assume cs:code,ds:data
  132. ;**************************************************************************
  133. ; Main Routine
  134. ;**************************************************************************
  135. IF FSExec ;if /FS: desired
  136. Procedure Exec_FS_Format
  137. Set_Data_Segment
  138. call Set_FCB1_Drive
  139. call Shrink
  140. mov al,ExitStatus ;Setblock fail?
  141. cmp al,Error
  142. JE $$IF1
  143. call Setup_Exec
  144. call Exec_Argv ;try exec from dir BASIC loaded
  145. mov al,ExitStatus
  146. cmp al,Error
  147. JNE $$IF2
  148. call Exec_Cur_Directory
  149. mov al,ExitStatus ;Try exec from cur directory
  150. cmp al,Error
  151. JNE $$IF2
  152. call EXEC_Routine
  153. mov al,ExitStatus
  154. cmp al,Error
  155. JNE $$IF2
  156. push ds ;save ds
  157. push si ;save si
  158. mov si,PSP_Segment ;get psp
  159. mov ds,si ;put psp in ds
  160. assume ds:PSP
  161. mov si,FCB1 ;ptr to 1st. FCB
  162. mov bl,byte ptr ds:[si] ;get drive ID
  163. pop si ;restore si
  164. pop ds ;restore ds
  165. Set_Data_Segment ;set segments
  166. cmp bl,0 ;Is it default drive?
  167. JNE $$IF3
  168. push ax ;Save exit code
  169. DOS_Call Get_Default_Drive ;Get the default drive
  170. add al,"A" ;Turn into drive letter
  171. mov Drive_Letter_Msg,al ;Save it in message
  172. pop ax ;Get return code back
  173. JMP SHORT $$EN3
  174. $$IF3:
  175. add bl,"A"-1 ;Convert to drive letter
  176. mov Drive_Letter_Msg,bl
  177. $$EN3:
  178. Message msgEXECFailure
  179. JMP SHORT $$EN2
  180. $$IF2:
  181. DOS_Call WaitProcess
  182. mov ExitStatus,al
  183. $$EN2:
  184. $$IF1:
  185. mov Fatal_Error,YES ;Not really, indicates FS used
  186. ret
  187. Exec_FS_Format endp
  188. ;****************************************************************************
  189. ; Shrink
  190. ;****************************************************************************
  191. Procedure Shrink
  192. mov ax,cs ;get code segment
  193. mov bx,ds ;get data segment
  194. sub ax,bx ;data seg size
  195. mov bx,ax ;save paras
  196. mov ax,offset End_Program ;Get the offset of end of loader
  197. mov cl,4 ;Div by 16 to get para's
  198. shr ax,cl
  199. add bx,ax ;add in code space
  200. add bx,Stack_Space ;adjust for stack
  201. add bx,11h ;give PSP space
  202. mov ax,PSP_Segment
  203. mov es,ax
  204. assume es:nothing
  205. DOS_Call SetBlock
  206. JNC $$IF9
  207. Message msgEXECFailure
  208. mov ExitStatus,Error ;Bad stuff, time to quit
  209. $$IF9:
  210. ret
  211. Shrink endp
  212. ;**************************************************************************
  213. ; Setup_Exec
  214. ;**************************************************************************
  215. Procedure Setup_Exec
  216. Set_Data_Segment
  217. mov ax,PSP_Segment ;Get segment of PSP
  218. mov ds,ax
  219. assume ds:PSP
  220. ;Setup dword pointer to command line to be passed
  221. mov es:Exec_Block.Segment_Command,ax ;Segment for command line
  222. mov es:Exec_Block.Offset_Command,offset ds:Command_Line
  223. ;Setup dword pointer to first FCB to be passed
  224. mov es:Exec_Block.Segment_FCB1,ax ;Segment for FCB1
  225. mov es:Exec_Block.Offset_FCB1,offset ds:FCB1 ;Offset of FCB at 05Ch
  226. ;Setup dword pointer to second FCB to be passed ;
  227. mov es:Exec_Block.Segment_FCB2,ax ;Segment for FCB2
  228. mov es:Exec_Block.Offset_FCB2,offset ds:FCB2 ;Offset of FCB at 06Ch
  229. ;Setup segment of Environment string, get from PSP ;
  230. mov ax,ds:PSP_Env_Segment
  231. mov es:Exec_Block.Segment_Env,ax
  232. Set_Data_Segment
  233. ret
  234. Setup_EXEC endp
  235. ;****************************************************************************
  236. ; Exec_Argv
  237. ;****************************************************************************
  238. ;
  239. ; Read the environment to get the Argv(0) string, which contains the drive,
  240. ; path and filename that was loaded for FORMAT.COM. This will be used to find
  241. ; the xxxxxfmt.exe, assuming that it is in the same location or path as
  242. ; FORMAT.COM
  243. ;
  244. Procedure EXEC_Argv
  245. Set_Data_Segment ;DS,ES = DATA
  246. cld
  247. mov ax,Exec_Block.Segment_Env ;Get the environment
  248. mov ds,ax ;Get addressability
  249. assume ds:nothing
  250. xor si,si ;Start at beginning
  251. $$DO11:
  252. $$DO12:
  253. inc si ;Get character
  254. cmp byte ptr [si-1],0 ;Find string seperator?
  255. JNE $$DO12
  256. inc si ;Get next char
  257. cmp byte ptr [si-1],0 ;Are we at Argv(0)? (00?)
  258. JNE $$DO11
  259. add si,2 ;Skip the word count
  260. mov di,si ;Save where string starts
  261. $$DO15: ;Find length of Argv(0) string
  262. inc si ;Get char
  263. cmp byte ptr [si-1],0 ;Is it the end?
  264. ;End found if 0 found
  265. JNE $$DO15
  266. mov cx,si ;Get number of bytes in string
  267. sub cx,di ;Put in cx reg for rep count
  268. mov si,di ;Point to path
  269. mov di,offset es:EXEC_Path ;Point to where to put it
  270. rep movsb ;Move the string
  271. Set_Data_Segment
  272. dec di ;Point at end of ArgV string
  273. std ;Look backwards
  274. $$DO17: ;Find 'FORMAT' in ARGV string
  275. mov cx,Len_Search_FORMAT ;Get length to compare
  276. mov si,offset Search_FORMAT_End-1 ;Look at comp string from end
  277. repe cmpsb ;See if same string
  278. JNE $$DO17
  279. mov si,offset FS_String_Buffer
  280. inc di ;DI = replacement point-1
  281. cld ;Set direction flag back
  282. mov cx,Len_FS_String_Buffer ;Length of string to move
  283. rep movsb ;Build part of the path
  284. call EXEC_Program
  285. ret
  286. EXEC_ArgV endp
  287. ;****************************************************************************
  288. ; EXEC_Program
  289. ;****************************************************************************
  290. Procedure EXEC_Program
  291. Set_Data_Segment
  292. mov ExitStatus,No_Error ;Setup to Exec the file
  293. mov dx,offset Exec_Path
  294. mov bx,offset Exec_Block
  295. mov al,0
  296. mov word ptr SP_Save,sp ;save sp
  297. mov word ptr SS_Save,ss ;save ss
  298. DOS_Call Exec
  299. cli ;turn off int's
  300. mov sp,word ptr SP_Save ;retrieve sp
  301. mov ss,word ptr SS_Save ;retrieve ss
  302. sti ;turn on int's
  303. ; $IF C ;CY means failure
  304. JNC $$IF19
  305. mov ExitStatus,Error ;Set error code
  306. ; $ENDIF
  307. $$IF19:
  308. ret
  309. EXEC_Program endp
  310. ;****************************************************************************
  311. ; EXEC_Routine
  312. ;****************************************************************************
  313. Procedure EXEC_Routine
  314. Set_Data_Segment
  315. mov ExitStatus,Error ;Assume the worst
  316. cld
  317. push ds
  318. mov ax,Exec_Block.Segment_Env ;Get the environment
  319. mov ds,ax ;Get addressability
  320. assume ds:nothing
  321. xor si,si ;Start at beginning
  322. ; $SEARCH
  323. $$DO21:
  324. cmp word ptr ds:[si],0 ;End of the Evironment?
  325. ; $EXITIF E ;Reached end, no more look
  326. JNE $$IF21
  327. ; $ORELSE ;Look for 'PATH=' in environment
  328. JMP SHORT $$SR21
  329. $$IF21:
  330. mov di,offset Path_String
  331. mov cx,Len_Path_String
  332. repe cmpsb
  333. ; $LEAVE E ;Found if EQ
  334. JE $$EN21
  335. ; $ENDLOOP ;Found PATH in environment
  336. JMP SHORT $$DO21
  337. $$EN21:
  338. call Build_Path_And_Exec
  339. ; $ENDSRCH
  340. $$SR21:
  341. pop ds
  342. ret
  343. EXEC_Routine endp
  344. ;****************************************************************************
  345. ; Build_Path_For_EXEC
  346. ;****************************************************************************
  347. Procedure Build_Path_And_Exec
  348. $$DO27:
  349. cmp byte ptr ds:[si],0 ;All path entries done?
  350. JE $$IF28
  351. mov di,offset EXEC_Path ;Point at where to put path
  352. mov byte ptr es:[di],0 ;End path just in case
  353. $$DO29:
  354. cmp byte ptr ds:[si],0 ;End of Path?
  355. JE $$EN29
  356. cmp byte ptr ds:[si],';' ;End of entry?
  357. JNE $$IF31
  358. inc si ;point to next character
  359. jmp EXIT_BPE_LOOP ;exit loop
  360. $$IF31:
  361. movsb ;Put char in path string
  362. JMP SHORT $$DO29
  363. $$EN29:
  364. EXIT_BPE_LOOP:
  365. ;Path filled in,get backslash
  366. cmp byte ptr ds:[si-1],0 ;Any path there?
  367. JE $$IF34
  368. ;Nope
  369. cmp byte ptr ds:[si-1],"\" ;Need a backslash? ;
  370. JE $$IF35
  371. mov byte ptr es:[di],"\" ;Yes, put one in ;
  372. inc di ;Line it up for next stuff
  373. inc si
  374. $$IF35:
  375. push si ;Save place in path
  376. push ds ;Save segment for environment
  377. push es ;Xchange ds/es
  378. pop ds
  379. mov si,offset FS_String_Buffer ;Fill in filename
  380. mov cx, Len_FS_String_Buffer
  381. rep movsb
  382. call Exec_Program
  383. cmp ExitStatus,No_Error ;E if EXEC okay
  384. pop ds ;Get Env segment back
  385. pop si ;Get place in path back
  386. $$IF34:
  387. $$IF28:
  388. JNE $$DO27
  389. ret
  390. Build_Path_And_EXEC Endp
  391. ;**************************************************************************
  392. ; Exec_Cur_Directory
  393. ;**************************************************************************
  394. Procedure Exec_Cur_Directory
  395. Set_Data_Segment
  396. mov si,offset FS_String_Buffer ;Setup path for current dir
  397. mov di,offset EXEC_Path
  398. mov cx,Len_FS_String_Buffer
  399. rep movsb
  400. call EXEC_Program
  401. ret
  402. EXEC_Cur_Directory endp
  403. ;=========================================================================
  404. ; Set_FCB1_Drive : This routine sets the 1st. byte of the FCB1,
  405. ; the drive identifier, to the default drive.
  406. ;=========================================================================
  407. Procedure Set_FCB1_Drive ;set drive ID
  408. push ds ;save ds
  409. push si ;save si
  410. mov si,PSP_Segment ;get segment of PSP
  411. mov ds,si ;put it in ds
  412. assume ds:PSP
  413. mov si,FCB1 ;ptr to FCB1
  414. mov byte ptr ds:[si],00h ;set drive ID to
  415. ; default drive
  416. pop si ;restore si
  417. pop ds ;restore ds
  418. Set_Data_Segment ;set up segmentation
  419. ret
  420. Set_FCB1_Drive endp
  421. ENDIF ;FSExec ;end /FS: conditional
  422. ;assembly
  423. ;**************************************************************************
  424. public End_Program
  425. End_Program label byte
  426. ;**************************************************************************
  427. code ends
  428. end
  429.