woainit.asm
上传用户:xiaoan1112
上传日期:2013-04-11
资源大小:19621k
文件大小:44k
源码类别:

操作系统开发

开发平台:

Visual C++

  1. ;/*
  2. ; *                      Microsoft Confidential
  3. ; *                      Copyright (C) Microsoft Corporation 1985-1991
  4. ; *                      All Rights Reserved.
  5. ; */
  6. ;----------------------------------------------------------------------------;
  7. ; This file has most of the initialization code. All the procedures in this  ;
  8. ; file are needed only during the initialization phase and are defined in a  ;
  9. ; main code segment. WOA will ignore this segment when it does swapping etc  ;
  10. ; as all of the code in this segment id discardable in any case.             ;
  11. ;                                                                            ;
  12. ; History:      ;
  13. ;      ;
  14. ;  Fri June-15-1990. -by-  Amit Chatterjee [amitc]      ;
  15. ;  Adapted for the Dos Task Switcher.      ;
  16. ;      ;
  17. ;        Thu May-03-1990.   -by-  Amit Chatterjee [amitc]      ;
  18. ;        Created for Windows. (Added the History legend)          ;
  19. ;----------------------------------------------------------------------------;
  20. ?win = 0
  21. ?DF = 1
  22. .xlist
  23. include cmacros.inc
  24. include woasegs.inc
  25. include macros.mac
  26. include njmp.mac
  27. include woaerr.inc
  28. include woakeys.inc
  29. include dosx.inc
  30. include grabber.inc
  31. include woaswch.inc
  32. .list
  33. .8086 ;must have to run on 8086s too.
  34. ;----------------------------------------------------------------------------;
  35. ; define the external function calls.      ;
  36. ;----------------------------------------------------------------------------;
  37. ;-------------------------------------------------------;
  38. ; external FAR OLDAPP procedures.                       ;
  39. ;-------------------------------------------------------;
  40. ;----------------------------------------------------------------------------;
  41. sBegin Data
  42. ;-------------------------------------------------;
  43. ; declare all external data seg variables.        ;
  44. ;-------------------------------------------------;
  45. externB DataSegEnd ;end of _DATA segment
  46. externB EmsFlag ;EMS present or not.
  47. externB XmsFlag ;XMS present or not
  48. externB SwitcherColors ;colors for switcher screen
  49. externB WoaSwap1Path ;first swap path.
  50. externB WoaSwap2Path ;second swap path.
  51. externW Swap1MinK ;min size to be left on 1st path
  52. externW Swap2MinK ;min size to be left on 2nd path
  53. externB ErrorType ;WOA error type
  54. externW hApp ;window handle for this instance
  55. externB CurrentPathId ;swap path id for current AP.
  56. externB StartRestartId ;start or restart
  57. externW HighMemXmsHandle  ;handle of the high mem XMS block
  58. externW  StubSegSize    ;size of real mode stub segment
  59. externW  WoaCsSize ;size of protected mode code seg
  60. externW  WoaDsSize ;size of winoldap data segment
  61. externD XmsBankSize      ;size of XMS to be allocated
  62. externW XmsHeapWalkSel ;scratch selector for walking xms heap
  63. externW  WoaStubSel ;sel for current loaction of stub code
  64. externW ArenaWalkSel     ;temp selector for walkimg arena chain
  65. externW ArenaRWSel     ;temp sel for reading/writing arenas
  66. externW  AppXmsBaseSel ;selector to base of apps XMS block
  67. externB DosAppSwapFileName ;app swap file name
  68. externW  DosAppNumber ;app number to be run in this instance
  69. externB FileTemplate ;for deleting files
  70. externB WoaSwapFilePrefix    ;'~WOA'
  71. externB   DiskSwap1Drive      ;swap drive index for drive 1
  72. externB   DiskSwap2Drive      ;swap drive index for drive 1
  73. externD lpXmsControl ;XMS control function address
  74. externW AppMinMem ;minimum memory required
  75. externW AppMinXmsK ;minimum XMS memory required
  76. externW AppMaxXmsK ;maximum xms required
  77. externW LowMemSel ;pointer to start of block
  78. externB LowMemBlockType ;type of the low mem block
  79. externW LowMemArenaSel ;pointer to its arena
  80. externW LowMemParaSize ;size of available low memory in para
  81. externD HighMemSize ;size of available high heap
  82. externW WoaPDBSeg ;WOA's PSP
  83. externW SegResizeBlock ;block to resize in real mode
  84. externW SizeReservedArea  ;size of area reserved area at heap st.
  85. externW UsableLowHeapSel ;sel/seg for reusable part of low heap
  86. externW SegAfterReservedArea ;segment after the reserved area
  87. externW StartScreenLines ;startup no of screen lines
  88. externB SwitcherID ;ID of this switcher (bits 14 & 15)
  89. ;-------------------------------------------------------;
  90. ; define any locally used constants. ;
  91. ;-------------------------------------------------------;
  92. ;-------------------------------------------------------;
  93. ; define any external constants.        ;
  94. ;-------------------------------------------------------;
  95. externA   IS_WINOLDAP_ACTIVE ;(WOAMGR.ASM)
  96. ;------------------------------------------------------;
  97. ; define public names.        ;
  98. ;------------------------------------------------------;
  99. public GetSegmentLimits
  100. sEnd Data
  101. ;----------------------------------------------------------------------------;
  102. ; declare external FAR Winoldap procedures.      ;
  103. ;----------------------------------------------------------------------------;
  104. externFP ErrorHandler ;(WOAMGR.ASM)
  105. externFP FarCopyBasicSwap1FileName      ;(WOAMGR.ASM)
  106. externFP FarCopyBasicSwap2FileName      ;(WOAMGR.ASM)
  107. externFP FarAppendUniqueNumber ;(WOAMGR.ASM)
  108. ;----------------------------------------------------------------------------;
  109. ; Declare the the code segment and any labels that we want to refernce in it;
  110. ;----------------------------------------------------------------------------;
  111. ;-------------------------------------------------;
  112. ; define external data references.   ;
  113. ;-------------------------------------------------;
  114. sBegin Code
  115. externB CodeSegEnd ;end of _TEXT segment
  116. sEnd  Code
  117. sBegin StubSeg
  118. ;----------------------------------------------------------------------------;
  119. ; declare external data refernces.      ;
  120. ;----------------------------------------------------------------------------;
  121. externB WoaGrabberName ;(WOARLM.ASM)
  122. externB WoaGrabberSwapPath ;(WOARLM.ASM)
  123. externB WoaPath ;(WOARLM.ASM)
  124. externB WoaParams ;(WOARLM.ASM)
  125. externB WoaFcb1 ;(WOARLM.ASM)
  126. externB WoaFcb2 ;(WOARLM.ASM)
  127. externB Woa6fValue ;(WOARLM.ASM)
  128. externB WoaIrq9Global ;(WOARLM.ASM)
  129. externB WoaNetAsyncSwitching ;(WOARLM.ASM)
  130. externW WoaCpuType ;(WOARLM.ASM)
  131. externW WoaFileEntrySize ;(WOARLM.ASM)
  132. externB WoaBehavior ;(WOARLM.ASM)
  133. externB WoaHotKeys ;(WOARLM.ASM)
  134. externW WoaStartScreenLines ;(WOARLM.ASM)
  135. externB WoaAltTabDisabled ;(WOARLM.ASM)
  136. externB WoaShftAltTabDisabled ;(WOARLM.ASM)
  137. externB WoaAltEscDisabled ;(WOARLM.ASM)
  138. externB WoaShftAltEscDisabled ;(WOARLM.ASM)
  139. externB WoaCtrlEscDisabled ;(WOARLM.ASM)
  140. externB WoaSwitcherID ;(WOARLM.ASM)
  141. sEnd StubSeg
  142. ;----------------------------------------------------------------------------;
  143. sBegin StubSeg
  144. ; InitStartLine MUST be at the very start of the one time initialization code,
  145. ; it is the address which will be used to discard the one time initialization
  146. ; code after itis done.
  147. public InitStartLine
  148. InitStartLine equ $ ;MAKE ME FIRST!  Everything after this will
  149. ;  be discarded after initialization
  150. externB XmsStartLine ;start of XMS handler in real mode stub
  151. externB StubSegEnd ;end of _WOARLMSEG segment
  152. ;-------------------------------------------------;
  153. ; define local entry points                       ;
  154. ;-------------------------------------------------;
  155.   assumes cs,StubSeg
  156. assumes ds,Data
  157. assumes es,nothing
  158. ;----------------------------------------------------------------------------;
  159. ; define temporary strings.      ;
  160. ;----------------------------------------------------------------------------;
  161. szEmsName db 'EMMXXXX0' ;EMM device name
  162. ;----------------------------------------------------------------------------;
  163. ; define local constants.      ;
  164. ;----------------------------------------------------------------------------;
  165. CMD_LINE_PARAM_LEN equ 2 ;length of command line param
  166. VALID_CMD_LINE_PARAM equ 0FE20H ;valid parameter
  167. ;----------------------------------------------------------------------------;
  168. ; include the HELP text message. This is a separate file for international   ;
  169. ; conversions.      ;
  170. ;----------------------------------------------------------------------------;
  171. include woahelp.inc
  172. ;----------------------------------------------------------------------------;
  173. ; ParseCommandLine:      ;
  174. ;      ;
  175. ; DOSSWAP expects a special parameter from the DOSSHELL which tells it that  ;
  176. ; it is being run from the SHELL and not from a DOS prompt. This is actually ;
  177. ; a space followed by a special character which is kinda difficult to type   ;
  178. ; in from the keyboard (At this point it is 0FEH, 08H would probably have    ;
  179. ; been the best!). If we do not find this special parameter, we will print   ;
  180. ; out a help text and exit.      ;
  181. ;----------------------------------------------------------------------------;
  182. cProc ParseCommandLine,<FAR,PASCAL,PUBLIC>
  183. cBegin
  184. ; command line shoule be at DS:80H.
  185. mov si,80h ;default DTA address
  186. lodsb ;get length of command line 
  187. cmp al,CMD_LINE_PARAM_LEN ;is it the length that we expect ?
  188. jnz PCL_PrintHelpText ;no, print help text and exit
  189. ; check the validity of the parameter.
  190. lodsw ;get the next two words
  191. .errnz CMD_LINE_PARAM_LEN - 2
  192. cmp ax,VALID_CMD_LINE_PARAM ;is it the one that we expect ?
  193. jz PCL_Ret ;yes, carry is clear too.
  194. PCL_PrintHelpText:
  195. ; we don't expect any parameters. Simply print an error message an exit
  196. push ds ;save
  197. push cs
  198. pop ds ;ds points has stub seg
  199. mov dx, StubSegOFFSET HelpText
  200. mov ah,9
  201. int 21h ;print help message
  202. pop ds ;restore
  203. stc ;error exit, but no error code
  204. PCL_Ret:
  205. cEnd
  206. ;----------------------------------------------------------------------------;
  207. ; InitializeWoa:      ;
  208. ;      ;
  209. ; This routine setus up some WOA variables by reafing SYSTEM.INI etc. This   ;
  210. ; code is executed only once and the advantage of having it in a separate    ;
  211. ; code segment is that we will ignore all the code in this segment after     ;
  212. ; the initializations are done.                                              ;
  213. ;----------------------------------------------------------------------------;
  214. cProc InitializeWoa,<FAR,PASCAL,PUBLIC>
  215. parmW StartRestart ;start or restart
  216. cBegin
  217. ;----------------------------------------------------------------------------;
  218. ; find out if EMS is present or not, setting flag appropriately.         ;
  219. ;----------------------------------------------------------------------------;
  220. mov ax,3567h ;want to get INT 67 vector
  221. int 21h ;ES:BX has the vector
  222. mov di,10 ;want to inspect offset 10
  223. mov si,StubSegOFFSET szEmsName ;DS:SI points to exepected name
  224. mov cx,8 ;need to compare 8 bytes
  225. cld ;set proper direction flag
  226. push ds ;save
  227. smov ds,cs ;load code
  228. repz cmpsb      ;compare names
  229. pop ds ;restore
  230. jnz @f ;names do not match, driver absent
  231. mov EmsFlag,0ffh ;EMS driver prsent
  232. @@:
  233. ;----------------------------------------------------------------------------;
  234. ; Parse the FCBS in the command line for the EXEC call.      ;
  235. ;----------------------------------------------------------------------------;
  236. cmp StartRestart,1 ;if restart
  237. jz @f ;skip this
  238. mov si,StubSegOFFSET WoaParams+1 ;point to the parameters
  239. mov di,StubSegOFFSET Woafcb1  ;fill in the first FCB 
  240. smov es,cs ;all in same segment
  241. mov ax,2901h
  242. int 21h ;PARSE DOS call
  243. call find_next_arg ;looks for further args
  244. jnz @f ;no second parameter
  245. mov di,StubSegOFFSET Woafcb2
  246. mov ax,2901h
  247. int 21h ;parse and fill in fcb2
  248. @@:
  249. ; deal with memory requirements.
  250. cCall AllocateXms ;allocate all of XMS if HIMEM is loaded
  251. ; check for extended memory requirements, if the requirements are not 
  252. ; satisfied, invoke the error handler and never return.
  253. cCall CheckXmsRequirements ;XMS memory requirement tests
  254. ; now get the sizes of various segments etc.
  255. ; get the limit fields and save them
  256. call GetSegmentLimits ;set segment limits -- sets StubSegSize
  257. cmp StartRestart,0 ;is it start ?
  258. jnz @f ;yes
  259. ; now test to see if the applications conventional and extended mode memory 
  260. ; requirements can be satisfied or not. If memory requrements cannot be met, 
  261. ; the following routine will never return
  262. call IsThereEnoughMemory ;check conventional/XMS mem requirements
  263. @@:
  264. clc ;no error
  265. cEnd
  266. ;----------------------------------------------------------------------------;
  267. ; IsThereEnoughMemory:      ;
  268. ;      ;
  269. ; This routine checks to see if enough memory can be released to meet the    ;
  270. ; apllications conventional.      ;
  271. ;----------------------------------------------------------------------------;
  272. IsThereEnoughMemory proc near
  273. xor ax,ax ;initialize size of resident area
  274. ; now in the resident area of conventional memory the main code and data
  275. ; segments will allways be resident in real mode winoldap (this is not true for
  276. ; protected mode winoldap). So initialize the size of the real mode resident 
  277. ; area with the size of the main code and data segments.
  278. mov ax,WoaCsSize ;size of the main code segment
  279. add ax,WoaDsSize ;add in the size of the data segment
  280. ;----------------------------------------------------------------------------;
  281. ; code independent of real or protected mode.      ;
  282. ;----------------------------------------------------------------------------;
  283. ; now check convetional memory requirements.
  284. mov bx,AppMinMem ;get minimum req. in KB
  285. cmp bx,0 ;was minimum limit specified ?
  286. jz ThereIsEnoughMemory ;memory requirements will be met
  287. ; get the size of the stub segment
  288. add ax,StubSegSize ;size of the stub seg
  289. ; bx has the minimum memory required in Kbytes, we need to mutiply that by 64
  290. ; to get the number of paragraphs.
  291. shiftr ax,4 ;get number of paragraphs
  292. inc ax ;round up
  293. shiftl bx,6 ;ax has min requirement in paragraphs
  294. ; if there is not enough memory to run the application, get out and complain
  295. neg ax ;need to subtract from total memory
  296. add ax,LowMemParaSize ;size of low heap area
  297. cmp bx,ax ;is there enough memory
  298. jbe ThereIsEnoughMemory ;yes there is
  299. ; we cannot run the appilaction
  300. mov ErrorType,ER_LOW_MEMORY ;error type
  301. jmp ErrorHandler ;get out
  302. ThereIsEnoughMemory:
  303. ret
  304. IsThereEnoughMemory  endp
  305. ;----------------------------------------------------------------------------;
  306. ; GetSegmentLimits:              ;
  307. ;      ;
  308. ; This routine gets the limits of the various winoldap segments. It also     ;
  309. ; obtains the sel values for the block allocated to the switcher by Dos and  ;
  310. ; also it's size and a sel for it's arena.      ;
  311. ;----------------------------------------------------------------------------;
  312. GetSegmentLimits  proc near
  313. push es ;save
  314. mov ax,CodeOFFSET CodeSegEnd;end label in _TEXT segment
  315. add ax,15 ;take into next para
  316. and ax,0fff0h ;paragraph allign
  317. mov WoaCsSize,ax ;save it
  318. mov ax,DataOFFSET DataSegEnd;end label in _DATA segment
  319. add ax,15 ;take into next para
  320. and ax,0fff0h ;paragraph allign
  321. mov WoaDsSize,ax
  322. ; if the XMS handler is not needed we will discard it.
  323. mov bx,StubSegOFFSET InitStartLine ;discardable code line
  324. mov ax,wptr XmsBankSize ;if there is an XMS requirement
  325. or ax,wptr [XmsBankSize+2] ;  the XMS handler can't be
  326. jnz @f
  327. mov bx,StubSegOFFSET XmsStartLine ;discard XMS code
  328. @@:
  329. add bx,15 ;take into next para
  330. and bx,0fff0h ;paragraph allign
  331. mov StubSegSize,bx ;usable stub area
  332. pop es ;restore es
  333. mov ah,62h ;get PSP
  334. int 21h ;BX has the PSP segment
  335. mov WoaPDBSeg,bx ;save it
  336. mov LowMemSel,bx ;save it
  337. dec bx ;point to the arena
  338. mov LowMemArenaSel,bx ;save it
  339. push es ;save
  340. mov es,bx ;point to the arena
  341. mov ax,es:[3] ;get the size of block in paragraphs
  342. mov LowMemParaSize,ax ;save it
  343. mov al,es:[0] ;get the block type
  344. mov LowMemBlockType,al ;save it too
  345. pop es ;restore
  346. ; save the sel for the block that will be resized.
  347. mov ax,LowMemSel ;selector for the block
  348. mov SegResizeBlock,ax ;save it.
  349. ; get the maximum of the 3 segments.
  350. mov ax,_TEXT ;get code segment
  351. mov bx,WoaCsSize ;and its size
  352. cmp ax,DGROUP ;compare with DS seg
  353. ja @f ;no need to swap
  354. mov ax,DGROUP ;load ds
  355. mov bx,WoaDsSize ;load ds's size
  356. @@:
  357. cmp ax,_WOARLMSEG ;comapare with stub
  358. ja @f ;no need to swap
  359. mov ax,_WOARLMSEG ;load stub seg
  360. mov bx,StubSegSize ;and its size
  361. @@:
  362. shiftr bx,4 ;convert to para
  363. add ax,bx ;get to end of segment
  364. sub ax,LowMemSel ;subtract the PSP seg
  365. mov SizeReservedArea,ax ;size of reserved area
  366. add ax,LowMemSel ;segment where stub seg will be loaded
  367. mov SegAfterReservedArea,ax ;address of segment after reserved area
  368. mov UsableLowHeapSel,ax ;seg for usable area
  369. ret
  370. GetSegmentLimits endp
  371. ;----------------------------------------------------------------------------;
  372. ; CheckXmsRequirements:      ;
  373. ;      ;
  374. ; If no XMS memory is required by the application, a flag would be set to    ;
  375. ; indicate that.      ;
  376. ;      ;
  377. ; If XMS is required but no XMS driver is loaded we will exit and report the ;
  378. ; error.      ;
  379. ;      ;
  380. ; We will then find out details about the XMS block allocated for the high   ;
  381. ; heap and find out whether we can meet the oldapps requiremsts.      ;
  382. ;----------------------------------------------------------------------------;
  383. cProc CheckXmsRequirements,<NEAR,PUBLIC,PASCAL>
  384. cBegin
  385. ;----------------------------------------------------------------------------;
  386. ; real mode specific code. In real mode we need the address of the XMS contr-;
  387. ; -ol fuction, so get the address and save it.      ;
  388. ;      ;
  389. ; (note: this instance may not need any XMS memory, but this instance may    ;
  390. ;  later handle some old app which does need XMS and will then be needing    ;
  391. ;  the address of the control function).      ;
  392. ;----------------------------------------------------------------------------;
  393. cmp AppMinXmsK,0 ;is there any requirement ?
  394. jnz XmsMemoryDesired ;yes
  395. ; as no xms memory is required, set the XMS flag off.
  396. mov wptr [XmsBankSize],0 ;no XMS memory needed
  397. mov wptr [XmsBankSize+2],0  ;reset hiword too
  398. jmp short CheckXmsReqRet ;go back.
  399. XmsMemoryDesired:
  400. ; test to see if XMS driver is loaded.
  401. mov ErrorType,ER_NO_XMS_DRV ;anticipating no XMS driver
  402. cmp XmsFlag,0ffh ;driver loaded ?
  403. njnz NearErrorHandler ;no xms driver loaded
  404. ; XMS driver is loaded, check to see if we can support apps requirements.
  405. mov cx,wptr [HighMemSize+2]
  406. mov dx,wptr [HighMemSize] ;CX:DX has size of high heap block
  407. ; get the number of K bytes this amounts to.
  408. mov dl,dh ;divide by 256
  409. mov dh,cl
  410. mov cl,ch
  411. xor ch,ch ;we have divided by 256, now by 4
  412. shr cx,1 ;get lsb into carry
  413. rcr dx,1 ;get it into dx
  414. shr cx,1 ;get lsb into carry
  415. rcr dx,1 ;CX:DX has mem available in K
  416. or cx,cx ;if cx > 0 we have enough
  417. jnz GrantXmsMemory ;enough is available
  418. mov ErrorType,ER_LOW_XMS_MEM;anticipate not enough memory
  419. cmp AppMinXmsK,-1 ;all of memory needed ?
  420. jz AllOfXmsNeeded ;yes
  421. cmp dx,AppMinXmsK ;compare with min requirement
  422. njb NearErrorHandler ;not enough for minimum requirement
  423. GrantXmsMemory:
  424. ; we have made sure that minimum requirement is met, but we must try to grant
  425. ; the maximum requirement.
  426. mov ax,AppMaxXmsK ;this is what we want to give
  427. cmp ax,-1 ;do we need all ?
  428. jz AllOfXmsNeeded ;yes
  429. cmp dx,AppMaxXmsK ;compare with max requirement.
  430. jbe AllOfXmsNeeded ;availabe is < desired, grant all
  431. jmp short SetXmsRequired ;set up size to be granted
  432. AllOfXmsNeeded:
  433. ;----------------------------------------------------------------------------;
  434. ; In real mode, DX has the size of the XMS block rounded down to a K.      ;
  435. ;----------------------------------------------------------------------------;
  436. mov ax,dx ;all of XMS to be granted
  437. ;----------------------------------------------------------------------------;
  438. SetXmsRequired:
  439. mov bx,1024 ;need to do Kilo to byte conversion
  440. mul bx ;DX:AX has apps xms bank size
  441. SaveXmsSize:
  442. mov wptr [XmsBankSize+2],dx ;save high word
  443. mov wptr [XmsBankSize],ax ;save low word
  444. CheckXmsReqRet:
  445. cEnd
  446. ;----------------------------------------------------------------------------;
  447. ; AllocateXms:      ;
  448. ;      ;
  449. ; This routine gets the information about the XMS block to use. The XMS block;
  450. ; handle is will be saved in the global switch structure by the first inst.  ;
  451. ; of the switcher (it would be 0 otherwise) and all other instances would use;
  452. ; it to get the size.      ;
  453. ;----------------------------------------------------------------------------;
  454. cProc AllocateXms,<NEAR,PUBLIC,PASCAL>,<es,di>
  455. cBegin
  456. ; check to see if XMS driver is installed or not.
  457. mov XmsFlag,0 ;assume no xms.
  458. mov ax,4300h ;installation check
  459. int 2fh
  460. cmp al,80h ;failure ?
  461. njne AllocateXmsRet ;yes, no driver installed.
  462. mov XmsFlag,0ffh ;XMS exists
  463. ; get the XMS entry point address.
  464. push es ;will get thrashed
  465. mov ax,4310h ;code to get the address
  466. int 2fh ;address in es:bx
  467. mov wptr [lpXmsControl+2],es;save segment of control function
  468. mov wptr [lpXmsControl],bx ;save the offset
  469. pop es ;restore
  470. ; get a pointer to the global switch structure and find out whether a privious
  471. ; instance had allocated the block or not.
  472. mov ax,4a05h ;opcode
  473. mov si,CGET_GLOBAL_SWITCH_DATA
  474. int 2fh ;dx:ax has the long pointer
  475. mov es,dx ;load it into es
  476. mov     di,ax ;es:di -> info structure
  477. mov dx,es:[di].XMS_Handle ;get the stored handle
  478. or dx,dx ;if zero then not allocated.
  479. jz DoAllocateXMS ;must allocate it.
  480. ; the XMS block has already been allocated, save the handle and get the size.
  481. mov HighMemXmsHandle,dx ;save the handle
  482. mov ax,wptr es:[di][0].XMS_Size
  483. mov word ptr [HighMemSize],ax;save low word of size
  484. mov ax,wptr es:[di][2].XMS_Size
  485. mov word ptr [HighMemSize+2],ax;save high word
  486. jmp short AllocateXMSRet ;done.
  487. DoAllocateXMS:
  488. ; get the size of the largest available block.
  489. mov ah,08h ;query amt. of free memory
  490. call lpXmsControl ;AX has largest free block size in K
  491. cmp bl,80h ;error ?
  492. jz AllocateXmsRet ;no XMS available
  493. cmp bl,81h ;error ?
  494. jz AllocateXmsRet ;no XMS available
  495. ; allocate the block and get it's handle.
  496. push ax ;save the size of the largest block.
  497. mov dx,ax ;requested size = size of largest block
  498. mov ah,09h ;allocate XMS block
  499. call lpXmsControl ;AX has largest free block size in K
  500. or ax,ax ;failed ?
  501. pop ax ;get back size
  502. jz AllocateXmsRet ;allocation failed.
  503. ; save the handle and the size of the block.
  504. mov HighMemXmsHandle,dx ;save the handle
  505. mov bx,1024 ;need size in KB
  506. xor dx,dx ;clear out before mul
  507. mul bx ;dx:ax has size in bytes
  508. mov word ptr [HighMemSize],ax;save low word of size
  509. mov word ptr [HighMemSize+2],dx;save high word
  510. ; now save the block information in the global structure.
  511. mov wptr es:[di][0].XMS_Size,ax
  512. mov wptr es:[di][2].XMS_Size,dx
  513. mov dx,HighMemXmsHandle ;get the handle
  514. mov es:[di].XMS_Handle,dx ;save it
  515. ; finally lock the block.
  516. mov ah,0ch ;lock XMS block
  517. call lpXmsControl ;AX has largest free block size in K
  518. AllocateXmsRet:
  519. cEnd
  520. ;----------------------------------------------------------------------------;
  521. ; GetSizeFromArena:      ;
  522. ;       ;
  523. ; This routine will be assembled only in real mode and it looks into the     ;
  524. ; arena associated with a segment whose values in in ax and returns the size ;
  525. ; in bytes in AX.      ;
  526. ;----------------------------------------------------------------------------;
  527. GetSizeFromArena  proc  near
  528. dec ax ;get to the arena
  529. mov es,ax ;have es pointing to arena
  530. mov ax,es:[3] ;get the size in paragraphs
  531. shiftl ax,4 ;get it in bytes
  532. ret
  533. GetSizeFromArena endp
  534. ;----------------------------------------------------------------------------;
  535. ; GetSwapFilePathPrefix:      ;
  536. ;      ;
  537. ; This routine gets the path prefix for the swap files to be used.       ;
  538. ;              ;
  539. ; . If the [NowWindowsAppf] section in SYSTEM.INI has an entry specifi-;
  540. ;         -ed for the key, 'swapdisk=', then that will be the path for temp  ;
  541. ;         files,else              ;
  542. ; . the 'GetTempFileName' function is invoked to get the complete      ;
  543. ;   path name of the temp drive and part of the name upto the unique   ;
  544. ;         number is extracted from it.      ;
  545. ;----------------------------------------------------------------------------;
  546. GetSwapFilePathPrefix  proc  near
  547. cld ;do not take chances with this
  548. ; copy the paths. First the first swap path
  549. mov si,DataOFFSET WoaSwapFilePrefix
  550. mov di,DataOFFSET WoaSwap1Path
  551. call AppendDsSiToDsDi
  552. ; now the second swap path.
  553. mov si,DataOFFSET WoaSwapFilePrefix
  554. mov di,DataOFFSET WoaSwap2Path
  555. call AppendDsSiToDsDi
  556. ; prepare the grabber swap file name from the second swap path
  557. mov di,DataOFFSET DosAppSwapFileName;prepare name here
  558. call FarCopyBasicSwap2FileName;copy the name until the unique num
  559. mov ax,0ffeeh ;irrelevant, grabber will redo this
  560. call FarAppendUniqueNumber ;just have a win style file name
  561. mov si,DataOFFSET DosAppSwapFileName
  562. mov di,StubSegOFFSET WoaGrabberSwapPath
  563. push es ;save
  564. smov es,ds ;es:si ppints to file name
  565. call CopyEsSiToCsDi ;copy over to the stubsegment
  566. pop es
  567. ret
  568. GetSwapFilePathPrefix endp
  569. ;----------------------------------------------------------------------------;
  570. ; AppendDsSiToDsDi:      ;
  571. ;      ;
  572. ; Appends the strung at DS:SI to the string at ES:DI and makes sure that the ;
  573. ; composite string end with a ''      ;
  574. ;----------------------------------------------------------------------------;
  575. AppendDsSiToDsDi proc near
  576. ; first get to the end of the path.
  577. push es
  578. smov es,ds ;es=ds
  579. @@:
  580. mov al,es:[di] ;get the next byte
  581. inc di ;next byte
  582. or al,al ;NULL ?
  583. jnz @b ;no.
  584. sub di,2 ;go back to last character
  585. mov     al,es:[di] ;get the last character
  586. cmp al,'' ;path separator ?
  587. jz @f ;yes
  588. mov al,'' ;load it, zero in high byte
  589. @@:
  590. stosb ;append a path separator
  591. ; now copy the path prefix.
  592. @@:
  593. lodsb ;get the next byte
  594. stosb ;save it
  595. or al,al ;NULL copied ?
  596. jnz @b ;no.
  597. pop es ;restore
  598. ret
  599. AppendDsSiToDsDi endp
  600. ;----------------------------------------------------------------------------;
  601. ; GetSwapFileInformation:      ;
  602. ;      ;
  603. ; Gets information for building up swap file names.      ;
  604. ;----------------------------------------------------------------------------;
  605. cProc GetSwapFileInformation,<NEAR,PUBLIC,PASCAL>,<si,di>
  606. cBegin
  607. ; get the path prefix to be used for all swap files.
  608. call GetSwapFilePathPrefix ;get the prefix
  609. ; obtain the drive letter for the swap drive from the basic swap name. 
  610. mov al,WoaSwap1Path ;get the first letter
  611. and al,0dfh ;convert to upper case
  612. mov DiskSwap1Drive,al ;save
  613. mov al,WoaSwap2Path ;get the first letter
  614. and al,0dfh ;convert to upper case
  615. mov DiskSwap2Drive,al ;save
  616. cEnd
  617. ;----------------------------------------------------------------------------;
  618. ; find_next_arg:      ;
  619. ;                Takes ES:SI over DOS delimiters and if poitions it to point ;
  620. ; to the next valid dos argument, or resturns NZ if end of line is reached   ;
  621. ;----------------------------------------------------------------------------;
  622. find_next_arg proc near
  623. push ds ;save
  624. smov ds,es ;load it in ds:si
  625. find_next_arg_1:
  626. lodsb ;get the next byte
  627. cmp al,0dh ;end of command line?
  628. je no_more_args ;there is no second argument
  629. call delim ;is this a DOS delimiter?
  630. jz find_next_arg_1 ;yes, skip over it
  631. dec si ;point to this char
  632. xor al,al         ; set zero flag
  633. jmp short find_next_arg_ret
  634. no_more_args:
  635. dec si
  636. or al,al ;If end then AL is non zero
  637. find_next_arg_ret:
  638. pop ds ;restore
  639. ret
  640. find_next_arg endp
  641. delim proc near
  642. cmp al,' ' ;space ?
  643. jz delim_ret
  644. cmp al,'='
  645. jz delim_Ret
  646. cmp al,',' ;comma ?
  647. jz delim_ret
  648. cmp al,';' ;semicolon ?
  649. jz delim_ret
  650. cmp al,09H ;tab
  651. jz delim_ret
  652. cmp al,0AH ; Line Feed
  653. delim_ret:
  654. ret
  655. Delim endp
  656. ;----------------------------------------------------------------------------;
  657. ; GetCompleteFileName:      ;
  658. ;      ;
  659. ; This routine takes a long pointer to a complete or partial file name and   ;
  660. ; returns the complete file name in the same buffer. If the file cannot be   ;
  661. ; found, AX will be set to -1. Also it assumes that the file name with the   ;
  662. ; NULL terminator is not more than 64 characters long.      ;
  663. ;----------------------------------------------------------------------------;
  664. cProc GetCompleteFileName,<NEAR,PUBLIC,PASCAL>
  665. parmD lpName ;input file name
  666. cBegin
  667. cld ;do not take chances with this
  668. cEnd
  669. ;----------------------------------------------------------------------------;
  670. ; DeleteTempFiles:      ;
  671. ;      ;
  672. ; This routine goes through a sequence of find first/find next calls and     ;
  673. ; deletes all woa and grabber left over temp files if any. The current DTA   ;
  674. ; address is saved and this routine uses a DTA on the stack for these calls  ;
  675. ;      ;
  676. ;  The grabber files will not be deleted if we have an instance of Windows   ;
  677. ;  3.0 winoldap active or if this is not the first instance of the switcher. ;
  678. ;                ;
  679. ; The grabber swap files can only be in the second swap path (the grabbers   ;
  680. ; do not support two swap paths and Winoldap lets the grabber know only of   ;
  681. ; the second swap path.). There will thus be 3 groups to delete (woa swap    ;
  682. ; files in two swap paths and grabber swap file groups in the second path).  ;
  683. ;----------------------------------------------------------------------------;
  684. cProc DeleteTempFiles,<NEAR,PUBLIC,PASCAL>,<es,si,di>
  685. localD CurrentDta ;saves current DTA address here
  686. localV NewDta,128 ;used for find/first and find next.
  687. cBegin
  688. ; get and save the current DTA address
  689. mov ah,2fh ;get DTA address call
  690. int 21h ;es:bx has the current address
  691. mov seg_CurrentDta,es ;save segment
  692. mov off_CurrentDta,bx ;save offset
  693. ; set the new DTA address to stack.
  694. lea dx,NewDta ;will have it here on stack.
  695. push ds ;save
  696. smov ds,ss ;ds:dx is the new DTA area
  697. mov ah,1ah ;set DTA address
  698. int 21h ;new DTA on stack
  699. pop ds ;restore
  700. ; now delete the WOA temp files.
  701. mov cx,3 ;3  chains to delete
  702. DeleteAChain:
  703. ; get the template of the next chain based on the value of cx:
  704. ; CX = 3 implies woa files in second path, CX = 2 implies grabber files in
  705. ; second path and CX = 1 implies woa files in first path.
  706. ; We should not try to delete grabber files if the SwitcherID is not 1 or if
  707. ; Windows 3.0 winoldap is active.
  708. cmp cx,2 ;trying to delete grabber files ?
  709. jnz DTF_OkToDeleteChain ;no.
  710. cmp SwitcherID,1 ;first instance of switcher ?
  711. jnz DTF_SkipThisChain ;no, do not delete grabber files
  712. ; check to see if another winoldap is active as a real mode stub.
  713. mov ax,IS_WINOLDAP_ACTIVE ;woa traps this in real mode
  714. int 2fh ;see if woa is in chain
  715. or ax,ax ;is woa active as a stub ?
  716. jz      DTF_SkipThisChain ;yes, donot delete any files
  717. DTF_OkToDeleteChain:
  718. call GetTempFileTemplate ;ds:dx has the file name template
  719. push cx ;save
  720. mov cx,3 ;include hidden and read-only files
  721. mov ah,4eh ;find first call
  722. int 21h ;get the first in chain
  723. jc DoNextChain ;no such file
  724. DeleteTheFile:
  725. ; recreate the complete path-file name from the file name that we just found
  726. pop cx ;restore loop index
  727. push cx ;save it back
  728. call CopyBasicTempPrefix ;get the basic temp prefix
  729. sub di,4 ;back over '~DOS'
  730. lea si,NewDta+1eh ;file name here
  731. push ds ;save
  732. smov ds,ss ;ds:dx has the file to delete
  733. ; now copy the file name over to complete the path file name
  734. @@:
  735. lodsb ;get the next character of file name
  736. stosb ;copy it
  737. or al,al ;are we done ?
  738. jnz @b ;no.
  739. ; now delete the file after setting normal attributes.
  740. pop ds ;restore ds
  741. mov ax,4301h ;set file attributes
  742. xor cx,cx ;normal attributes
  743. int 21h ;normal attributes set
  744. mov ah,41h ;delete file code
  745. int 21h ;one file deleteted
  746. mov ah,4fh ;find next file in chain
  747. int 21h ;did we get another
  748. jc DoNextChain ;no.
  749. jmp short DeleteTheFile ;delete this and look for more
  750. DoNextChain:
  751. pop cx ;get back count
  752. DTF_SkipThisChain:
  753. loop DeleteAChain ;delete this chain too.
  754. ; now set back the original DTA address and go back.
  755. push ds ;save
  756. mov dx,off_CurrentDta ;old dta offset
  757. mov ds,seg_CurrentDta ;old dta segment
  758. mov ah,1ah ;set DTA code
  759. int 21h ;DTA address restored
  760. pop ds ;restore data segment
  761. DeleteTempFilesRet:
  762. cEnd
  763. ;------------------------------------------;
  764. ; get template for temp files based on the ;
  765. ; value of CX.    ;
  766. ; CX = 3 => woa temp files in swap path2   ;
  767. ; CX = 2 => grb temp files in swap path2   ;
  768. ; CX = 1 => woa temp files in swap path1   ;
  769. ;------------------------------------------;
  770. GetTempFileTemplate proc near
  771. call CopyBasicTempPrefix ;get the basic path prefix
  772. cmp cx,2 ;grabber template ?
  773. jz GetGrbTemplate ;get grabbers file template
  774. ; now append a nibble for the switcher ID.
  775. mov al,SwitcherID ;get the ID
  776. and al,0fh ;only a nibble of ID
  777. add al,30h ;convert numbers to ascii
  778. cmp al,'9' ;did we go above 9 ?
  779. jbe GTFT_ALHasAscii ;no, we are ok.
  780. add al,7h ;convert to (A-F)
  781. GTFT_ALHasAscii:
  782. stosb ;save it
  783. mov ax,'.*' ;follow it up with '*.*'
  784. stosw ;save it
  785. mov ax,'*' ;ah will have terminating NULL
  786. stosw ;template created
  787. mov dx,DataOFFSET FileTemplate
  788. ret
  789. GetGrbTemplate:
  790. sub di,3 ;step back over 'DOS'
  791. mov ax,'RG' ;nedd to have 'GRB' instead
  792. stosw ;'GR' saved
  793. mov al,'B' ;last part of 'GRB'
  794. stosb ;initial part done.
  795. mov ax,'.*' ;follow it up with '*.*'
  796. stosw ;save it
  797. mov ax,'*' ;ah will have terminating NULL
  798. stosw ;template created
  799. mov dx,DataOFFSET FileTemplate
  800. ret
  801. GetTempFileTemplate  endp
  802. ;--------------------------------------------;
  803. ; gets the basic swap path prefix based on   ;
  804. ; the value of cx. CX = 2 or 3 implies use   ;
  805. ; swap path 2, CX = 1 implies use path 1     ;
  806. ;--------------------------------------------;
  807. CopyBasicTempPrefix proc near
  808. mov di,DataOFFSET FileTemplate
  809. test cx,2 ;2 or 3 
  810. jnz @f ;yes.
  811. call FarCopyBasicSwap1FileName;get prefix for path 1
  812. ret
  813. @@:
  814. call FarCopyBasicSwap2FileName;get prefix for path 2
  815. ret
  816. CopyBasicTempPrefix endp
  817. ;----------------------------------------------------------------------------;
  818. ; GetSwitcherInfo:      ;
  819. ;        ;
  820. ; Gets info from the global switch structure.      ;
  821. ;----------------------------------------------------------------------------;
  822. cProc GetSwitcherInfo,<FAR,PUBLIC,PASCAL>,<es>
  823. localD OtherSwitcherAddr ;call in address of the 'other' switcher
  824. cBegin
  825. ; get a pointer to the global block.
  826. mov ax,4a05h ;opcode
  827. mov si,CGET_GLOBAL_SWITCH_DATA
  828. int 2fh ;dx:ax has the long pointer
  829. mov es,dx ;load it into es
  830. mov di,ax ;es:di -> info structure
  831. ; scan through the list and if all ProgramID's are zero, then reset the
  832. ; Id_Serial field.
  833. lea si,[di].Program_List ;es:si points to the first program entry
  834. mov cx,MAX_NUM_PROGRAMS ;get the max number of entries
  835. xor ax,ax ;will build a count here
  836. LoopAllEntries:
  837. test es:[si].Program_Flags,F_FREE
  838. jnz ContinueLoop ;this is a free entry
  839. cmp es:[si].Program_Id,0 ;has this been run before ?
  840. jnz OutOfLoop ;yes, break out of loop
  841. ContinueLoop:
  842. add si, SIZE Switch_Entry ;es:si -> next program
  843. inc ax ;one more fresh entry obtained
  844. loop LoopAllEntries ;continue lloking
  845. OutOfLoop:
  846. cmp ax,MAX_NUM_PROGRAMS ;all entries fresh ?
  847. jb @f ;no.
  848. mov es:[di].Id_Serial,0 ;reset this.
  849. @@:
  850. ; copy the SwitcherId from the global structure.
  851. mov al,es:[di].Switcher_Id ;ID allocated to this swicher
  852. mov SwitcherID,al ;save it.
  853. ; get a pointer to the first program in the list.
  854. lea si,[di].Program_List ;start of array
  855. xor ah,ah ;clear out high byte
  856. mov al,es:[di].First_In_List;get index of first entry
  857. mov bl,SIZE Switch_Entry ;size of each entry
  858. mul bl ;ax has start offset
  859. add si,ax ;es:si -> first program in list.
  860. ; copy program related variables.
  861. mov ax,es:[si].Conv_Req ;get conventional memory requirements
  862. mov AppMinMem,ax ;save minimum memory required
  863. mov ax,es:[si].XMS_Req ;amount of xms required
  864. mov AppMinXmsK,ax ;save as min xms requirement
  865. mov ax,es:[si].XMS_Want ;xms desired
  866. mov AppMaxXmsK,ax ;save it
  867. ; if AppMaxXmsK is < AppMinXmsK, set it to AppMinXmsK.
  868. cmp ax,AppMinXmsK ;ax could be -1 too.
  869. jae @f ;all is fine
  870. mov ax,AppMinXmsK ;minimum
  871. mov AppMaxXmsK,ax ;save it
  872. @@:
  873. ; copy global variables and flags from the switch_info structure.
  874. xor ah,ah ;reset
  875. mov al,es:[di].Num_Lines ;start up no of screen lines
  876. ; if the screen lines is zero, we must get it from the BIOS area
  877.   or al,al ;uninitialized ?
  878. jnz @f ;no.
  879. push es ;save
  880. mov bx,40h ;bios data area
  881. mov es,bx ;es points to BIOS data segment
  882. mov bx,84h ;location where screen lines saved
  883. mov al,es:[bx] ;get the no of screen lines
  884. inc ax ;actually it is one more
  885. pop es ;restore
  886. @@:
  887. mov cs:[WoaStartScreenLines],ax;save it
  888. mov StartScreenLines,ax ;save a local copy too.
  889. mov al,es:[di].Screen_Back ;back ground screen color
  890. mov [SwitcherColors],al ;save it
  891. mov al,es:[di].Title_Back ;title back ground color
  892. mov [SwitcherColors+1],al ;save it
  893. mov al,es:[di].Title_Fore ;title text color
  894. mov [SwitcherColors+2],al ;save it
  895. mov ax,es:[di].CPU_Type ;get the CPU type
  896. mov cs:[WoaCpuType],ax ;save it
  897. mov ax,es:[di].SFT_Size ;get the file entry size
  898. mov cs:[WoaFileEntrySize],ax;save it
  899. ; set the global flags
  900. mov al,es:[di].Global_Flags ;get the global flags
  901. mov cs:[Woa6fValue],0   ;assume int 6f not to be done
  902. test al,GF_INT_6F_TOBE_DONE ;int 6f to be done ?
  903. jz @f ;no.
  904. mov cs:[Woa6fValue],0ffh ;int 6f to be done.
  905. @@:
  906. mov cs:[WoaIrq9Global],0 ;assume IRQ 9 to be handled globally
  907. test al,GF_IRQ9_GLOBAL ;is IRQ 9 global ?
  908. jnz @f ;yes
  909. mov cs:[WoaIrq9Global],0ffh ;don't handle IRQ 9
  910. @@:
  911. mov cs:[WoaNetAsyncSwitching],0 ;assume cannot switch out on async net
  912. test al,GF_NET_ASYNC_SWITCH_OK;is it ok to switch out ?
  913. jz @f ;no
  914. mov cs:[WoaNetAsyncSwitching],0ffh ;ok to switch out
  915. @@:
  916. ; copy various behaviour bits and hot key states.
  917. mov cs:[WoaBehavior],0  ;initialize
  918. mov cs:[WoaHotKeys],0 ;initialize
  919. mov ax,es:[si].Program_Flags
  920. and al,F_NO_SWITCH+F_GRAPHICS+F_NO_PAUSE
  921. mov cs:[WoaBehavior],al  ;save it
  922. and ax,F_NO_ALT_TAB+F_NO_ALT_ESC+F_NO_CTRL_ESC
  923. mov cs:[WoaHotkeys],ah ;save
  924. ; also set bytes in the local hot key list for keys that are disabled.
  925. test ax,F_NO_ALT_TAB ;ALT+TAB disabled ?
  926. jz @f ;no.
  927. mov cs:[WoaAltTabDisabled],0ffh
  928. mov cs:[WoaShftAltTabDisabled],0ffh
  929. @@:
  930. test ax,F_NO_ALT_ESC ;ALT+ESC disabled ?
  931. jz @f ;no.
  932. mov cs:[WoaAltEscDisabled],0ffh
  933. mov cs:[WoaShftAltEscDisabled],0ffh
  934. @@:
  935. test ax,F_NO_CTRL_ESC     ;ALT+ESC disabled ?
  936. jz @f ;no.
  937. mov cs:[WoaCtrlEscDisabled],0ffh
  938. @@:
  939. ; copy the swither ID.
  940. mov al,SwitcherID ;get the ID
  941. mov cs:[WoaSwitcherID],al ;pass it on
  942. ; now copy the program name.
  943. push di ;save
  944. push si ;save program entry pointer
  945. mov di,StubSegOFFSET WoaPath;save program name here.
  946. lea si,[si].Program_Name ;es:si -> program name
  947. call CopyEsSiToCsDi ;copy the name .
  948. pop si ;get back start of entry
  949. pop di ;restore.
  950. ; now copy the parameters
  951. push di ;save
  952. push si ;save program entry pointer
  953. lea si,[di].Parameters ;es:si -> parametsrs
  954. mov di,StubSegOFFSET WoaParams;command parameters
  955. call CopyEsSiToCsDi ;copy the name .
  956. pop si ;get back start of entry
  957. pop di ;restore.
  958. ; get the program ID and the path ID.
  959. mov al,es:[si].Path_Id ;get the path ID
  960. mov CurrentPathId,al ;save it
  961. mov ax,es:[si].Program_Id ;id for the app
  962. mov hApp,ax ;save it.
  963. mov StartRestartId,al ;start if 0 else restart
  964. or ax,ax ;is it a fresh start ?
  965. jnz @f ;no.      
  966. ; build the DosAppNumber.
  967. mov ax,es:[di].Id_Serial ;get the serial id
  968. mov DosAppNumber,ax ;save it.
  969. inc ax ;increment it
  970. mov es:[di].Id_Serial,ax ;update it.
  971. ; build the hApp id. This is basically the slot in the global structure where
  972. ; the program details have been built. Or in otherwords, it is First_In_List.
  973. ; we also need to combine the SwitcherID with it.
  974. mov ah,SwitcherID ;get the ID
  975. shiftl ah,4 ;only four 4 bits are significant
  976. mov al,es:[di].First_In_List;rest of the task id
  977. mov hApp,ax ;app's id
  978. mov es:[si].Program_Id,ax ;save it
  979. @@:
  980. ; get the grabber file name.
  981. mov si,di ;es:si -> SwitchInfo structure
  982. push si ;save
  983. lea si,es:[si].Grabber_Name ;es:si -> points to the grabber name
  984. mov di,StubSegOFFSET WoaGrabberName;will copy grabber name here
  985. call CopyEsSiToCsDi ;copy the name .
  986. pop si ;es:si -> SwitchInfo
  987. ; copy the two swap file paths.
  988. push si ;save
  989. lea si,es:[si].Swap_Path1 ;es:si -> points to the swap path
  990. mov di,DataOFFSET WoaSwap1Path;will copy path here
  991. call CopyEsSiToDsDi ;copy the name .
  992. pop si ;restore pointer to entry
  993. push si ;save
  994. lea si,es:[si].Swap_Path2 ;es:si -> points to the swap path
  995. mov di,DataOFFSET WoaSwap2Path;will copy path here
  996. call CopyEsSiToDsDi ;copy the name .
  997. pop si ;restore pointer to entry
  998. ; load the minimum space information for the two swap paths.
  999. mov ax,es:[si].Min_Path1 ;min space for path 1
  1000. mov Swap1MinK,ax ;save it
  1001. mov ax,es:[si].Min_Path2 ;min space for path 2
  1002. mov Swap2MinK,ax ;save it
  1003. ; get information about swap file.      
  1004. call GetSwapFileInformation       
  1005. ; If DosAppNumber is 0 and this is not a restart, we must delete all 
  1006. ; temporary files
  1007. cmp DosAppNumber,0 ;first app ?
  1008. jnz @f ;no.
  1009. cmp StartRestartID,0 ;if tart
  1010. jnz @f ;delete files.
  1011. cCall DeleteTempFiles ;delete all temporary files.
  1012. @@:
  1013. clc ;successful completion of routine
  1014. jmp short GetSwitcherInfoRet
  1015. GetSwitcherInfoErr:
  1016. stc ;error, cannot proceed
  1017. GetSwitcherInfoRet:
  1018. cEnd
  1019. ;----------------------------------------------------------------------------;
  1020. ; CopyEsSiToDsDi:      ;
  1021. ;      ;
  1022. ; Copies a NULL terminated string from es:si to ds:si.      ;
  1023. ;----------------------------------------------------------------------------;
  1024. CopyEsSiToDsDi proc near
  1025. mov al,es:[si] ;load a byte
  1026. mov ds:[di],al ;save it
  1027. inc si ;bump src ptr
  1028. inc di ;bump target ptr
  1029. or al,al ;NULL copied ?
  1030. jnz CopyEsSiToDsDi ;continue
  1031. ret ;done
  1032. CopyEsSiToDsDi endp
  1033. ;----------------------------------------------------------------------------;
  1034. ; CopyEsSiToCsDi:      ;
  1035. ;      ;
  1036. ; Copies a NULL terminated string from es:si to cs:si.      ;
  1037. ;----------------------------------------------------------------------------;
  1038. CopyEsSiToCsDi proc near
  1039. mov al,es:[si] ;load a byte
  1040. mov cs:[di],al ;save it
  1041. inc si ;bump src ptr
  1042. inc di ;bump target ptr
  1043. or al,al ;NULL copied ?
  1044. jnz CopyEsSiToCsDi ;continue
  1045. ret ;done
  1046. CopyEsSiToCsDi endp
  1047. ;----------------------------------------------------------------------------;
  1048. ; NearErrorHanlder:      ;
  1049. ;      ;
  1050. ; From here we jump into the main code segment error handler.      ;
  1051. ;----------------------------------------------------------------------------;
  1052. NearErrorHandler:
  1053. jmp ErrorHandler ;hApp jump into _TEXT segment
  1054. ;----------------------------------------------------------------------------;
  1055. sEnd StubSeg
  1056. end