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.

1615 lines
33 KiB

  1. TITLE RESAUX - support routines for resource manager
  2. .xlist
  3. include kernel.inc
  4. include newexe.inc
  5. include tdb.inc
  6. include protect.inc
  7. .list
  8. ifdef WOW
  9. WOW_OPTIMIZE_PRELOADRESOURCE = 1
  10. endif
  11. externA __AHINCR
  12. externFP _lclose
  13. externFP GlobalFree
  14. externFP GlobalLock
  15. externFP GlobalUnlock
  16. externFP GlobalFlags
  17. externFP GlobalReAlloc
  18. externFP GlobalHandle
  19. externFP GetExePtr
  20. externFP MyOpenFile
  21. externFP FarMyUpper
  22. ;externFP GlobalAlloc
  23. externFP lstrlen
  24. externFP lstrOriginal
  25. externFP Int21Handler
  26. externFP AllocSelector
  27. externFP FreeSelector
  28. externFP LongPtrAdd
  29. ifdef WOW
  30. externFP WOWFreeResource
  31. endif
  32. ifdef WOW_OPTIMIZE_PRELOADRESOURCE
  33. externFP LongPtrAddWOW
  34. externFP AllocSelectorWOW
  35. endif
  36. if KDEBUG
  37. externFP OutputDebugString
  38. endif
  39. DataBegin
  40. externW Win_PDB
  41. if KDEBUG
  42. externB fLoadTrace
  43. endif
  44. DataEnd
  45. sBegin CODE
  46. assumes CS,CODE
  47. assumes DS,NOTHING
  48. assumes ES,NOTHING
  49. externNP MyAlloc
  50. externNP MyLock
  51. externNP GetOwner
  52. externNP SetOwner
  53. externNP GetCachedFileHandle
  54. externNP CloseCachedFileHandle
  55. externFP AllocSelectorArray
  56. externFP set_discarded_sel_owner
  57. externNP SetResourceOwner
  58. externNP AllocResSelArray
  59. ifdef WOW
  60. externFP hMemCpy
  61. externFP _HREAD
  62. externW gdtdsc
  63. endif
  64. ;-----------------------------------------------------------------------;
  65. ; ;
  66. ; DirectResAlloc - This allocates memory for creating cursors and icons;
  67. ; "on the fly". ;
  68. ; ;
  69. ; Arguments: ;
  70. ; parmW hinstance ; Identifies the instance that allocates ;
  71. ; parmW resFlags ; Flags to be used in memory allocation ;
  72. ; parmW nBytes ; The size of the memory to be allocated ;
  73. ; ;
  74. ; Returns: ;
  75. ; ;
  76. ; Error Returns: ;
  77. ; AX = 0 ;
  78. ; ;
  79. ; Registers Preserved: ;
  80. ; ;
  81. ; Registers Destroyed: ;
  82. ; ;
  83. ; Calls: ;
  84. ; ;
  85. ; History: ;
  86. ; ;
  87. ; Fri 06 Jan 1989 -- Written by Sankar. ;
  88. ; ;
  89. ;-----------------------------------------------------------------------;
  90. cProc DirectResAlloc, <PUBLIC, FAR>, <si,di>
  91. parmW hInstance
  92. parmW resFlags
  93. parmW nBytes
  94. cBegin
  95. cCall GetExePtr, <hInstance>
  96. or ax, ax
  97. jz err_end
  98. push ax ; Save ptr to EXE header
  99. xor bx, bx
  100. cCall MyResAlloc, <ax, resFlags, nBytes, bx>
  101. xchg ax,dx
  102. pop cx ; restore exe header address
  103. or ax,ax
  104. jz err_end
  105. cCall SetOwner,<ax,cx>
  106. xchg ax,dx
  107. err_end:
  108. cEnd
  109. cProc MyResAlloc,<PUBLIC,NEAR>
  110. parmW hExe
  111. parmW resFlags
  112. parmW nBytes
  113. parmW nAlign
  114. cBegin
  115. mov bx,resFlags ; Allocate memory for
  116. or bl,NSTYPE or RNMOVE ; non-code, non-data segment
  117. cCall MyAlloc,<bx,nBytes,nAlign>
  118. test dl,GA_FIXED
  119. jnz mysox
  120. mov bx,dx
  121. HtoS bx ; Make it ring 1
  122. lar cx, bx
  123. jnz mysox
  124. test ch, 80h ; Present?
  125. jnz mysox
  126. int 3
  127. mov es, hExe ; Set limit to the owner ie. hExe.
  128. cCall set_discarded_sel_owner
  129. mysox:
  130. xchg ax,dx
  131. cEnd
  132. cProc IAllocResource,<PUBLIC,FAR>,<si>
  133. parmW hResFile
  134. parmW hResInfo
  135. parmD newSize
  136. cBegin
  137. cCall GetExePtr,<hResFile>
  138. or ax,ax
  139. jz arx
  140. mov es,ax
  141. push es ; Save exe header address
  142. mov si,hResInfo
  143. push es ; push hexe
  144. mov bx,es:[si].rn_flags
  145. or bl,NSTYPE ; non-code, non-data segment
  146. push bx ; push flags
  147. push es:[si].rn_length ; push default size
  148. mov bx,es:[ne_rsrctab]
  149. mov cx,es:[bx].rs_align
  150. mov dx,OFF_newSize
  151. or dx,SEG_newSize ; Want a different size?
  152. jz ar1 ; No, continue
  153. pop dx ; Yes discard default size
  154. push cx ; Save alignment shift
  155. mov dx,newSize.hi ; Round up new size by alignment
  156. xor ax,ax
  157. not ax
  158. shl ax,cl
  159. not ax
  160. add ax,newSize.lo
  161. adc dx, 0
  162. ar0:
  163. shr dx,1 ; convert to alignment units
  164. rcr ax,1
  165. loop ar0
  166. pop cx ; Restore alignment shift
  167. push ax ; Push new size
  168. ar1:
  169. cmp es:[si].rn_handle,0 ; Already a handle?
  170. je ar2 ; No, continue
  171. pop ax ; AX = length
  172. add sp,4 ; ignore flags and hExe
  173. xor dx,dx
  174. jcxz ma3
  175. ma2:
  176. shl ax,1
  177. rcl dx,1
  178. loop ma2
  179. ma3:
  180. xor cx,cx
  181. cCall GlobalReAlloc,<es:[si].rn_handle,dxax,cx>
  182. cwd ; zero dx (may not be needed)
  183. or ax,ax ; did it fail?
  184. jz ar3
  185. cCall GlobalHandle,<ax>
  186. jmps ar3
  187. ar2:
  188. push cx ; push alignment shift count
  189. cCall MyResAlloc ; rn_flags, rn_length, rs_align
  190. ar3:
  191. xchg ax,dx
  192. pop cx ; restore exe header address
  193. or ax,ax
  194. jz arx
  195. cCall SetOwner,<ax,cx>
  196. xchg ax,dx
  197. arx:
  198. or ax, ax
  199. jnz @F
  200. KernelLogError DBF_WARNING,ERR_ALLOCRES,"AllocResource failed"
  201. xor ax, ax ; Restore the NULL value in ax
  202. @@:
  203. mov cx,ax
  204. cEnd
  205. cProc ResAlloc,<PUBLIC,FAR>,<si,di>
  206. parmD pResInfo
  207. parmW fh
  208. parmW isfh
  209. ifdef WOW_OPTIMIZE_PRELOADRESOURCE
  210. parmW hiResOffset
  211. parmW loResOffset
  212. endif
  213. localW hres
  214. cBegin
  215. xor ax,ax
  216. cCall IAllocResource,<pResInfo,ax,ax>
  217. les si,pResInfo
  218. mov hres,ax ; Returns handle in AX
  219. mov ax,dx ; Segment address in DX
  220. mov bx,es:[ne_rsrctab]
  221. mov cx,es:[bx].rs_align
  222. mov dx,es:[si].rn_length
  223. xor bx,bx
  224. cmp hres,bx
  225. ; jnz ra1
  226. jz rax
  227. ra1: shl dx,1
  228. rcl bx,1
  229. loop ra1
  230. push ds
  231. mov cx,dx
  232. mov si, bx ; Save hi word of length
  233. mov bx,fh
  234. cmp isfh,bx ; is bx a file handle?
  235. je ra2 ; if so, load from file
  236. ifdef WOW
  237. ifdef WOW_OPTIMIZE_PRELOADRESOURCE
  238. cmp hiResOffset, 0
  239. jz @F
  240. push ax
  241. mov al, __AHINCR
  242. mul byte ptr hiResOffset
  243. add bx,ax
  244. pop ax
  245. @@:
  246. cCall hMemCpy,<ax,0,bx,loResOffset,si,cx>
  247. else
  248. cCall hMemCpy,<ax,0,bx,0,si,cx>
  249. endif
  250. jmps ra3
  251. ra2:
  252. cCall _hRead,<bx,ax,0,si,cx>
  253. cmp dx, si ; If we didn't read what we wanted
  254. jnz rafail ; then fail
  255. cmp ax, cx
  256. jnz rafail
  257. else ; NOT WOW
  258. cCall CopyResource,<ax,bx,si,cx>
  259. jmps ra3
  260. ra2:
  261. cCall ReadResource,<ax,bx,si,cx>
  262. jc rafail
  263. endif ; WOW
  264. ra3:
  265. pop ds
  266. ra4:
  267. mov ax,hres
  268. jmps rax
  269. rafail:
  270. mov bx,ds
  271. pop ds
  272. rafail2:
  273. cCall GlobalFree,<hres>
  274. if KDEBUG
  275. push es
  276. mov bx,SEG_pResInfo
  277. mov es,bx
  278. xor bx,bx
  279. KernelLogError <DBF_WARNING>,ERR_BADRESREAD,"Unable to read resource from @ES:BX"
  280. pop es
  281. endif
  282. xor ax,ax
  283. rax:
  284. cEnd
  285. cProc CopyResource,<PUBLIC,NEAR>
  286. parmW DestSeg
  287. parmW SrcSeg
  288. parmD nBytes
  289. cBegin
  290. push es
  291. mov ds, SrcSeg ; bx is segment of resource
  292. mov es, DestSeg
  293. xor si, si
  294. xor di, di
  295. cld
  296. rc_next:
  297. mov cx, 8000h
  298. cmp word ptr [nBytes+2], 0
  299. clc ; No odd byte to copy
  300. jne big_copy
  301. mov cx, word ptr [nBytes]
  302. shr cx, 1 ; Word count
  303. big_copy:
  304. rep movsw
  305. rcl cx, 1 ; Rescue low bit
  306. rep movsb ; Any odd byte
  307. dec word ptr [nBytes+2]
  308. js rc_done
  309. mov ax, ds
  310. add ax, __AHINCR
  311. mov ds, ax
  312. mov ax, es
  313. add ax, __AHINCR
  314. mov es, ax
  315. jmp rc_next
  316. rc_done:
  317. pop es
  318. cEnd
  319. cProc ReadResource,<PUBLIC,NEAR>
  320. parmW DestSeg
  321. parmW fh
  322. parmD nBytes
  323. cBegin
  324. mov bx, fh
  325. xor dx, dx
  326. mov ds, DestSeg
  327. mov di, word ptr nBytes
  328. mov si, word ptr [nBytes+2]
  329. around_again:
  330. mov cx, 8000h
  331. or si, si
  332. jnz big_xfer
  333. cmp di, cx
  334. jae big_xfer
  335. mov cx, di
  336. big_xfer:
  337. mov ah, 3Fh
  338. DOSCALL
  339. jc rrfail
  340. cmp ax, cx
  341. jne rrfail
  342. sub di, cx
  343. sbb si, 0
  344. jnz incr_address
  345. or di, di
  346. jz rrdone
  347. incr_address:
  348. add dx, cx
  349. jnc around_again
  350. mov ax, ds
  351. add ax, __AHINCR
  352. mov ds, ax
  353. jmp around_again
  354. rrfail:
  355. stc
  356. jmps rrx
  357. rrdone:
  358. clc
  359. rrx:
  360. cEnd
  361. cProc IAccessResource,<PUBLIC,FAR>
  362. parmW hResFile
  363. parmW hResInfo
  364. cBegin
  365. xor ax, ax
  366. cCall InternalAccessResource,<hResFile,hResInfo,ax>
  367. cEnd
  368. cProc InternalAccessResource,<PUBLIC>
  369. parmW hResFile
  370. parmW hResInfo
  371. parmW CachedFile
  372. cBegin
  373. cCall GetExePtr,<hResFile>
  374. mov es,ax
  375. mov bx, hResInfo
  376. mov ax,es:[bx].rn_flags
  377. push es:[bx].rn_length
  378. push es:[bx].rn_offset
  379. mov dx,es:[ne_pfileinfo]
  380. mov bx,es:[ne_rsrctab]
  381. mov cx,es:[bx].rs_align
  382. push cx
  383. push es
  384. cmp CachedFile, 0
  385. je open_it
  386. mov cx, -1
  387. cCall GetCachedFileHandle,<es,cx,cx>
  388. mov bx, ax
  389. jmps got_fh
  390. open_it:
  391. if SHARE_AWARE
  392. mov bx,OF_REOPEN or OF_VERIFY or OF_NO_INHERIT or OF_SHARE_DENY_WRITE
  393. else
  394. mov bx,OF_REOPEN or OF_VERIFY or OF_NO_INHERIT
  395. endif
  396. regptr esdx,es,dx
  397. push es
  398. push dx
  399. cCall MyOpenFile,<esdx,esdx,bx> ; returns handle in ax & bx
  400. pop dx
  401. pop es
  402. ;;; cmp ax, -1 ; Success?
  403. ;;; jne got_fh ; yes.
  404. ;;; ; no, try compatibility mode
  405. ;;; mov bx,OF_REOPEN or OF_VERIFY or OF_NO_INHERIT
  406. ;;; regptr esdx,es,dx
  407. ;;; cCall MyOpenFile,<esdx,esdx,bx> ; returns handle in ax & bx
  408. got_fh:
  409. pop es
  410. pop cx
  411. pop dx
  412. inc ax
  413. jnz ra2c
  414. pop dx
  415. ra2b:
  416. mov bx,-1
  417. jmps ra2x
  418. ra2c:
  419. xor ax,ax
  420. push cx
  421. AR_shift:
  422. shl dx,1
  423. rcl ax,1
  424. loop AR_shift
  425. mov cx,ax
  426. mov ax,4200h
  427. DOSCALL
  428. pop cx
  429. pop dx
  430. jc ra2b
  431. xor ax,ax
  432. AR_shift1:
  433. shl dx,1
  434. rcl ax,1
  435. loop AR_shift1
  436. mov cx,ax ; CX:DX is size of resource
  437. ra2x:
  438. mov ax,bx ; AX and BX are file handle
  439. cEnd
  440. cProc ILockResource,<PUBLIC,FAR>,<si>
  441. parmW hres
  442. localD lpfn
  443. cBegin
  444. mov ax,hres ; Get object handle
  445. or ax,ax
  446. jnz short_rel
  447. lrfail0:
  448. jmp lrfail
  449. short_rel:
  450. ifdef WOW
  451. test ax, GA_WOWHANDLE ; should we call WOW32 FreeResource?
  452. jnz @f
  453. jmp lrfail
  454. @@:
  455. endif; WOW
  456. cCall GlobalLock,<ax> ; Attempt to lock it
  457. jcxz yawn
  458. jmp lrx
  459. yawn:
  460. mov bx,hres ; Failed, is it fixed?
  461. test bl,GA_FIXED
  462. jnz lrfail0 ; Yes, fail all the way
  463. HtoS bx
  464. ; On WOW we don't copy the owner to the real LDT since it is slow to call
  465. ; the NT Kernel, so we read our copy of it directly.
  466. ; see set_discarded_sel_owner mattfe mar 23 93
  467. push cx
  468. lar cx, bx
  469. pop cx
  470. jnz lrfail0 ; NZ -> LAR failed
  471. mov es,cs:gdtdsc
  472. and bl, not 7
  473. mov bx,es:[bx].dsc_owner
  474. mov es,bx
  475. assumes es,nothing
  476. cmp es:[ne_magic],NEMAGIC ; Does owner point to EXE header?
  477. jne lrfail ; No, fail.
  478. mov bx,es:[ne_rsrctab] ; Yes, scan resource table
  479. cmp es:[ne_restab],bx ; Is there a resource table?
  480. je lrfail ; No, just free the global object
  481. push ds
  482. SetKernelDS
  483. pop ds
  484. assumes ds, nothing
  485. mov dx,hres ; Yes, look for this handle
  486. add bx,SIZE NEW_RSRC ; Point to first resource type
  487. lrloop0:
  488. cmp es:[bx].rt_id,ax ; End of table?
  489. je lrfail ; Yes, just return failure
  490. lea si,[bx].rt_proc ; Remember address of type proc.
  491. mov cx,es:[bx].rt_nres
  492. add bx,SIZE RSRC_TYPEINFO ; Point to first resource of this type
  493. lrloop:
  494. cmp es:[bx].rn_handle,dx ; Is this the one?
  495. je lr3 ; Yes, go see if type proc to call
  496. add bx,SIZE RSRC_NAMEINFO ; No, point to next resource
  497. loop lrloop ; Any more resources for this type?
  498. jmps lrloop0 ; No, advance to next type
  499. lr3:
  500. cmp word ptr es:[si+2],0 ; Was there a proc defined for this type
  501. je lrfail ; No, return failure.
  502. if KDEBUG
  503. jmp PrintInfo
  504. PrintedInfo:
  505. endif
  506. push ds ; preserve these registers across call
  507. push es
  508. push bx
  509. mov ax,word ptr es:[si] ; set up proc addr to call on stack
  510. mov word ptr lpfn,ax
  511. mov ax,word ptr es:[si]+2
  512. mov word ptr lpfn+2,ax
  513. mov cx,es ; cx = es for later push
  514. mov ax,ss ; Zap segment registers so he can't
  515. mov es,ax ; diddle DS
  516. mov ds,ax
  517. cCall lpfn,<dx,cx,bx> ; Yes, call proc to reload
  518. xchg ax,cx ; cx = result
  519. jcxz @F ; skip lock if NULL
  520. cCall GlobalLock,<cx> ; Attempt to lock result
  521. @@:
  522. pop bx
  523. pop es
  524. pop ds
  525. jcxz lrfail
  526. or byte ptr es:[bx].rn_flags,RNLOADED ; Mark loaded
  527. jmps lrx
  528. lrfail: ; Here to return failure.
  529. KernelLogError DBF_WARNING,ERR_LOCKRES,"LockResource failed"
  530. xor ax,ax
  531. cwd
  532. lrx:
  533. cEnd
  534. if KDEBUG
  535. RCTypes:
  536. db 'Custom', 0
  537. db 'Cursor', 0
  538. db 'Bitmap', 0
  539. db 'Icon', 0
  540. db 'Menu', 0
  541. db 'Dialog', 0
  542. db 'String', 0
  543. db 'FontDir', 0
  544. db 'Font', 0
  545. db 'Accelerator', 0
  546. db 'RCData', 0
  547. db 'Type11', 0
  548. db 'GroupCursor', 0
  549. db 'Type13', 0
  550. db 'GroupIcon', 0
  551. db 0
  552. PrintInfo:
  553. pusha
  554. mov cx, word ptr es:[si][rt_id-rt_proc]
  555. and ch, not 80h
  556. mov si, offset RCTypes
  557. pi_1: inc si
  558. pi_2: cmp byte ptr cs:[si], 0
  559. jnz pi_1
  560. inc si
  561. cmp byte ptr cs:[si], 0
  562. loopnz pi_2
  563. jnz @F
  564. mov si, offset RCTypes
  565. @@:
  566. mov ax, es:[bx].rn_id
  567. ; test ah, 80h
  568. ; jz pi_name
  569. and ah, not 80h
  570. krDebugOut <DEB_TRACE or DEB_krLoadSeg>, "%es0: reading resource @CS:SI.#ax"
  571. ; jmps pi_done
  572. ;pi_name:
  573. ; int 3
  574. ; krDebugOut <DEB_TRACE or DEB_krLoadSeg>, "%es0: reading resource @CS:SI.@ES:AX"
  575. ;pi_done:
  576. popa
  577. jmp PrintedInfo
  578. endif
  579. cProc IFreeResource,<PUBLIC,FAR>,<ds,si>
  580. parmW hres
  581. cBegin
  582. mov ax,hres ; Get segment address of resource
  583. or ax,ax
  584. jz frxj
  585. ifdef WOW
  586. test ax, GA_WOWHANDLE ; should we call WOW32 FreeResource?
  587. jnz @f
  588. cCall WOWFreeResource,<ax> ; you bet !
  589. xor ax, ax
  590. jmp frxx
  591. @@:
  592. endif; WOW
  593. cCall MyLock,<ax>
  594. or ax,ax ; Discarded or invalid handle?
  595. jnz fr0a ; No, continue
  596. mov bx,hres
  597. test bl,GA_FIXED
  598. jnz fr2 ; Return NULL
  599. HtoS bx ; Fix RPL so we can do LAR
  600. lar cx, bx
  601. jnz fr2 ; LAR failed, return NULL
  602. test ch, 80h ; Present?
  603. jnz fr2 ; yes, return NULL
  604. ; On WOW we don't copy the owner to the real LDT since it is slow to call
  605. ; the NT Kernel, so we read our copy of it directly.
  606. ; see set_discarded_sel_owner mattfe mar 23 93
  607. mov ds,cs:gdtdsc
  608. and bl, not 7
  609. mov cx,ds:[bx].dsc_owner
  610. mov ds,cx
  611. jmps fr0b
  612. frxj:
  613. jmps frx
  614. fr0a:
  615. cCall GetOwner,<ax>
  616. mov ds,ax
  617. xor ax,ax
  618. fr0b:
  619. cmp ds:[ne_magic],NEMAGIC ; Is it an exe header?
  620. jne fr1 ; No, just free the handle
  621. mov bx,ds:[ne_rsrctab]
  622. cmp ds:[ne_restab],bx ; Is there a resource table?
  623. je fr1 ; No, just free the handle
  624. mov dx,hres
  625. add bx,SIZE NEW_RSRC ; Point to first resource type
  626. frloop0:
  627. cmp ds:[bx].rt_id,ax ; End of table?
  628. je fr1 ; Yes, just free the handle
  629. mov cx,ds:[bx].rt_nres
  630. add bx,SIZE RSRC_TYPEINFO ; Point to first resource of this type
  631. frloop:
  632. cmp ds:[bx].rn_handle,dx ; Is this the one?
  633. je fr0 ; Yes, go decrement usage count
  634. add bx,SIZE RSRC_NAMEINFO ; No, point to next resource
  635. loop frloop ; Any more resources for this type?
  636. jmps frloop0 ; No, advance to next type
  637. fr0:
  638. cmp ds:[bx].rn_usage,ax ; Already zero?
  639. je fr1a ; Yes, then free this resource now
  640. dec ds:[bx].rn_usage ; Decrement use count
  641. jg frx ; Positive means still in use
  642. test ds:[bx].rn_flags,RNDISCARD ; Discardable?
  643. jnz fr2 ; Yes, let discard logic toss it
  644. fr1a:
  645. mov ds:[bx].rn_handle,ax ; o.w. free memory now
  646. and byte ptr ds:[bx].rn_flags,not RNLOADED ; Mark not loaded
  647. fr1:
  648. cCall GlobalFree,<hres> ; Free global object
  649. fr2:
  650. mov hres,ax
  651. frx:
  652. mov ax,hres ; Return zero if freed, hres o.w.
  653. frxx:
  654. cEnd
  655. cProc ISizeofResource,<PUBLIC,FAR>
  656. parmW hResFile
  657. parmW hResInfo
  658. cBegin
  659. cCall GetExePtr,<hResFile>
  660. mov es,ax
  661. mov bx,hResInfo
  662. mov ax,es:[bx].rn_length
  663. xor dx,dx
  664. mov bx,es:[ne_rsrctab]
  665. mov cx,es:[bx].rs_align
  666. sr0: shl ax,1
  667. rcl dx,1
  668. loop sr0
  669. cEnd
  670. cProc DefaultResourceHandler,<PUBLIC,FAR>,<si,di>
  671. parmW hRes
  672. parmW hResFile
  673. parmW hResInfo
  674. localW SavePDB
  675. cBegin
  676. cCall GetExePtr,<hResFile>
  677. or ax,ax
  678. jz drhx
  679. mov si,ax
  680. mov cx,hRes ; if hRes == NULL, we need to allocate.
  681. jcxz @F
  682. cCall GlobalHandle,<cx>
  683. or dx,dx ; Nothing to do for allocated resources
  684. jnz drhx
  685. @@:
  686. SetKernelDS
  687. mov ax, Win_PDB ; Save current PDB
  688. mov SavePDB, ax
  689. mov ax, 1
  690. cCall InternalAccessResource,<si,hResInfo,ax>
  691. mov di,ax
  692. inc ax
  693. jz drhx
  694. ifdef WOW_OPTIMIZE_PRELOADRESOURCE
  695. cCall ResAlloc,<si,hResInfo,di,di, 0, 0>
  696. else
  697. cCall ResAlloc,<si,hResInfo,di,di>
  698. endif
  699. push ax
  700. ;;; cCall _lclose,<di>
  701. push bx
  702. cCall CloseCachedFileHandle,<di>
  703. mov bx, SavePDB
  704. mov Win_PDB, bx ; Restore PDB
  705. pop bx
  706. pop ax
  707. drhx:
  708. cEnd
  709. ;-----------------------------------------------------------------------;
  710. ; LoadResource ;
  711. ; ;
  712. ; Called by each task ONCE to load a resource. ;
  713. ; If this is the VERY FIRST time this resource is loaded ;
  714. ; AND it is fixed, then the resource handler proc is called. ;
  715. ; AND it is discardable then only a handle is allocated. We wait ;
  716. ; until LockResource to actually load the resource. ;
  717. ; ;
  718. ; If the resource had been loaded by a previous task ;
  719. ; then we load it if it has been discarded. ;
  720. ; ;
  721. ; Arguments: ;
  722. ; HANDLE hResFile ;
  723. ; HANDLE hResInfo ;
  724. ; ;
  725. ; Returns: ;
  726. ; ;
  727. ; Error Returns: ;
  728. ; ;
  729. ; Registers Preserved: ;
  730. ; ;
  731. ; Registers Destroyed: ;
  732. ; ;
  733. ; Calls: ;
  734. ; ;
  735. ; History: ;
  736. ; ;
  737. ; Tue Jan 01, 1980 07:23:34p -by- David N. Weise [davidw] ;
  738. ; ReWrote it from C into assembly and added this nifty comment block. ;
  739. ;-----------------------------------------------------------------------;
  740. cProc ILoadResource,<PUBLIC,FAR>,<di,si>
  741. parmW hResFile
  742. parmW hResInfo
  743. localV DscBuf,DSC_LEN
  744. localD lpfn
  745. cBegin
  746. mov di,hResInfo ; DI = pName
  747. or di,di
  748. jnz got_a_hResInfo
  749. jmp lr_error_ret
  750. got_a_hResInfo:
  751. cCall GetExePtr,<hResFile>
  752. or ax,ax
  753. jnz got_a_resource_file
  754. jmp lr_error_ret
  755. got_a_resource_file:
  756. mov ds,ax ; DS = pExe
  757. mov si,ds:[ne_rsrctab] ; DS:SI = pRes
  758. cmp si,ds:[ne_restab]
  759. jnz got_a_resource_table
  760. jmp lr_error_ret
  761. got_a_resource_table:
  762. ; If first LoadResource on resource, then call resource handler proc
  763. ; associated with resource type.
  764. mov ax,[di].rn_usage
  765. or ax,ax
  766. jz maybe_load_it
  767. got_it: inc [di].rn_usage
  768. mov ax,[di].rn_handle
  769. jmp lr_ret
  770. ; IF
  771. ; 1) the resource is discardable
  772. ; 2) and has been loaded before
  773. ; 3) and has been FreeResource'd
  774. ; 4) but not yet discarded (See FreeResource for this madness!)
  775. ; THEN
  776. ; 1) the usage count is zero
  777. ; 2) it's still marked loaded
  778. ; 3) it's still in memory
  779. maybe_load_it:
  780. cmp ax,[di].rn_handle ; we know that ax == rn_usage == 0
  781. jz not_loaded_before
  782. test [di].rn_flags,RNLOADED
  783. jz load_it
  784. cCall GlobalFlags,<[di].rn_handle>
  785. test ah,HE_DISCARDED
  786. jz got_it
  787. jmps load_it
  788. not_loaded_before:
  789. test [di].rn_flags,RNDISCARD
  790. jz load_it
  791. ; Allocate a zero length object to get a handle.
  792. push si
  793. mov ax, [di].rn_length
  794. xor dx, dx
  795. mov bx, ds:ne_rsrctab
  796. mov cx, [bx].rs_align
  797. fred:
  798. shl ax, 1
  799. rcl dx, 1
  800. loop fred
  801. add ax, 15
  802. adc dx, 0
  803. mov cx, dx
  804. inc cx ; # selectors
  805. ;; WOW x86 only
  806. cCall AllocResSelArray,<cx,ds>
  807. jz no_sel
  808. StoH al
  809. no_sel:
  810. pop si
  811. mov [di].rn_handle,ax
  812. jmp got_it
  813. load_it:
  814. lea si,[si].SIZE new_rsrc ; DS:SI = pType
  815. lr_type_loop:
  816. cmp [si].rt_id,0
  817. jz lr_error_ret
  818. lea bx,[si].SIZE rsrc_typeinfo ; BX =pName1
  819. mov ax,word ptr [si].rt_proc[0]
  820. or ax,word ptr [si].rt_proc[2]
  821. jz lr_skip_name
  822. mov cx,[si].rt_nres
  823. jcxz lr_next_type
  824. lr_name_loop:
  825. cmp bx,di
  826. jnz lr_next_name
  827. push ds ; Zap segment registers to prevent
  828. mov ax,word ptr [si].rt_proc
  829. mov word ptr lpfn,ax
  830. mov ax,word ptr [si].rt_proc+2
  831. mov word ptr lpfn+2,ax
  832. push [di].rn_handle
  833. push hResFile
  834. push hResInfo
  835. mov ax,ss ; callee from trashing our DS.
  836. mov ds,ax
  837. mov es,ax
  838. call lpfn
  839. pop ds
  840. or ax,ax
  841. jz lr_ret
  842. mov [di].rn_handle,ax
  843. or [di].rn_flags,RNLOADED
  844. jmp got_it
  845. lr_next_name:
  846. add bx,SIZE rsrc_nameinfo
  847. loop lr_name_loop
  848. jmps lr_next_type
  849. lr_skip_name:
  850. mov ax,[si].rt_nres
  851. mov cx,SIZE rsrc_nameinfo
  852. mul cx
  853. add bx,ax
  854. lr_next_type:
  855. mov si,bx
  856. jmp lr_type_loop
  857. lr_error_ret:
  858. if KDEBUG
  859. xor bx,bx
  860. kerror ERR_BADRESFILE,<Error loading from resource file - >,ds,bx
  861. endif
  862. xor ax,ax
  863. lr_ret:
  864. cEnd
  865. sEnd CODE
  866. sBegin MISCCODE
  867. assumes CS,MISCCODE
  868. assumes DS,NOTHING
  869. assumes ES,NOTHING
  870. externNP MISCMapDStoDATA
  871. cProc GetResOrd,<PUBLIC,NEAR>,<si,di>
  872. parmW hResFile
  873. parmD lpszType
  874. parmD lpszName
  875. localW hRes
  876. cBegin
  877. cCall OrdinalOrString, <lpszType>
  878. mov si,ax
  879. cCall OrdinalOrString, <lpszName>
  880. mov di,ax
  881. gro_maybe_search_nametable:
  882. ;
  883. ; First see if we need to search the name table at all (if we have ordinals
  884. ; already, we don't need to do the search).
  885. ;
  886. xor ax,ax
  887. cmp si,ax
  888. jz gro_do_search_nametable
  889. or ax,di
  890. jnz gro_exit1 ; Both are ordinals - just exit
  891. or ax,seg_lpszName ; If lpszName is NULL, exit because
  892. jnz gro_do_search_nametable ; we have the type ordinal.
  893. gro_exit1:
  894. jmp gro_exit
  895. gro_do_search_nametable:
  896. cCall GetExePtr,<hResFile>
  897. mov es,ax
  898. mov bx,es:[ne_rsrctab]
  899. cmp bx,es:[ne_restab]
  900. jz gro_exit1
  901. add bx,SIZE new_rsrc
  902. gro_check_resource_type:
  903. cmp es:[bx].rt_id,0
  904. jz gro_exit1
  905. cmp es:[bx].rt_id,(RT_NAMETABLE OR RSORDID)
  906. jz gro_found_resource_table_entry
  907. mov cx,es:[bx].rt_nres
  908. add bx,SIZE RSRC_TYPEINFO
  909. ; add 12*nres to bx (12*size of resource)
  910. .errnz ((SIZE RSRC_NAMEINFO) - 12)
  911. shl cx,1
  912. shl cx,1
  913. add bx,cx
  914. shl cx,1
  915. add bx,cx
  916. jmps gro_check_resource_type
  917. gro_found_resource_table_entry:
  918. add bx,SIZE RSRC_TYPEINFO
  919. mov ax,es:[bx].rn_handle
  920. or ax,ax
  921. jnz gro_have_handle_nametable
  922. xor ax,ax
  923. mov dx,1
  924. mov bx,RT_NAMETABLE
  925. cCall <far ptr IFindResource>,<hResFile,ax,dx,ax,bx>
  926. or ax,ax
  927. jz gro_exit1
  928. push ds ; DS not even really used probably
  929. cCall MISCMapDStoDATA ; Hack, need DS pointing to something
  930. cCall ILoadResource,<hResFile,ax> ; with a handle
  931. pop ds
  932. or ax,ax
  933. jnz gro_have_handle_nametable
  934. gro_exit2:
  935. jmp gro_exit
  936. gro_have_handle_nametable:
  937. mov hRes,ax
  938. push ds ; DS not even really used probably
  939. cCall MISCMapDStoDATA ; Hack, need DS pointing to something
  940. cCall ILockResource,<ax> ; with a handle
  941. pop ds
  942. mov cx,ax
  943. or cx,dx
  944. jcxz gro_exit2
  945. mov es,dx ; es:bx is a pointer to resource
  946. mov bx,ax
  947. ;
  948. ; Now we have a pointer to the resource. Scan through the name table and
  949. ; find a match in the table with the passed type/name.
  950. ; SI = type ordinal, 0 if string type
  951. ; DI = name ordinal, 0 if string name
  952. ;
  953. gro_nametable_loop:
  954. or si,si
  955. jz gro_do_type_string_match
  956. cmp si,es:[bx].ntbl_idType
  957. jnz gro_next_nametable_entry
  958. jmps gro_do_name_match
  959. gro_do_type_string_match:
  960. push es ; Save pntbl
  961. push bx
  962. lea ax,es:[bx].ntbl_achTypeName
  963. push es
  964. push ax
  965. push seg_lpszType
  966. push off_lpszType
  967. call lstrOriginal ; compare against type name
  968. pop bx ; Restore pntbl
  969. pop es
  970. or ax,ax
  971. jnz gro_next_nametable_entry
  972. gro_do_name_match:
  973. or di,di
  974. jz gro_do_name_string_match
  975. cmp di,es:[bx].ntbl_idName
  976. jnz gro_next_nametable_entry
  977. jmps gro_found_nametable_match
  978. gro_do_name_string_match:
  979. cmp seg_lpszName, 0
  980. jne want_name
  981. mov si,es:[bx].ntbl_idType ; Hey man, can't check name!
  982. jmps gro_unlock_resource
  983. want_name:
  984. push es ; push pntbl for later restoration
  985. push bx
  986. push es ; push pntbl for later strcmp
  987. push bx
  988. lea ax,es:[bx].ntbl_achTypeName
  989. push es
  990. push ax
  991. call lstrlen ; get string length
  992. mov bx,sp ; Adjust pointer on stack to point
  993. add ss:[bx],ax ; past first string
  994. add word ptr ss:[bx],ntbl_achTypeName + 1
  995. push seg_lpszName
  996. push off_lpszName
  997. call lstrOriginal
  998. pop bx
  999. pop es
  1000. or ax,ax
  1001. jz gro_found_nametable_match
  1002. gro_next_nametable_entry:
  1003. add bx,es:[bx].ntbl_cbEntry
  1004. cmp es:[bx].ntbl_cbEntry,0
  1005. jnz gro_nametable_loop
  1006. jmps gro_unlock_resource
  1007. gro_found_nametable_match:
  1008. mov ax,es:[bx].ntbl_idType
  1009. test ax,RSORDID
  1010. jz gro_try_replace_name
  1011. mov si,ax
  1012. gro_try_replace_name:
  1013. mov ax,es:[bx].ntbl_idName
  1014. test ax,RSORDID
  1015. jz gro_unlock_resource
  1016. mov di,ax
  1017. gro_unlock_resource:
  1018. push hRes
  1019. call GlobalUnlock
  1020. gro_exit:
  1021. xor ax,ax
  1022. cwd
  1023. or ax,si
  1024. jz gro_test_name_ordinal
  1025. or ax,RSORDID
  1026. gro_test_name_ordinal:
  1027. or dx,di
  1028. jz gro_leave
  1029. or dx,RSORDID
  1030. gro_leave:
  1031. cEnd
  1032. cProc OrdinalOrString, <PUBLIC, NEAR>, <si>
  1033. parmD s
  1034. cBegin
  1035. les si,s
  1036. mov cx,si
  1037. mov ax,es
  1038. or ax,ax
  1039. jz codone
  1040. xor cx,cx ; sum = zero
  1041. cld
  1042. lods byte ptr es:[si] ; c = *pName++
  1043. cmp al,'#'
  1044. jne codone
  1045. coloop:
  1046. lods byte ptr es:[si] ; c = *pName++
  1047. or al,al ; if (!c) break;
  1048. jz codone
  1049. sub al,'0' ; if (!isdigit(c))
  1050. cmp al,9
  1051. ja codone ;
  1052. xor ah,ah
  1053. mov bx,ax ; sum = (sum * 10) + (c - '0')
  1054. mov al,10
  1055. mul cx
  1056. add ax,bx
  1057. mov cx,ax
  1058. jmp coloop
  1059. codone:
  1060. mov ax,cx
  1061. coexit:
  1062. cEnd
  1063. cProc CmpResStr,<PUBLIC,NEAR>,<ds,si>
  1064. parmD pRes
  1065. parmW id
  1066. parmD s
  1067. cBegin
  1068. mov ax,id
  1069. test ax,RSORDID
  1070. jnz crsneq
  1071. lds si,pRes
  1072. add si,ax
  1073. xor ax,ax
  1074. cld
  1075. lodsb
  1076. mov cx,ax
  1077. les bx,s
  1078. crsloop:
  1079. mov al,es:[bx]
  1080. inc bx
  1081. or al,al
  1082. jz crsneq
  1083. call FarMyUpper
  1084. mov ah,al
  1085. lodsb
  1086. cmp ah,al
  1087. jne crsneq
  1088. loop crsloop
  1089. xor ax,ax
  1090. cmp es:[bx],al
  1091. jne crsneq
  1092. not ax
  1093. jmps crsexit
  1094. crsneq:
  1095. xor ax,ax
  1096. crsexit:
  1097. cEnd
  1098. ;-----------------------------------------------------------------------;
  1099. ; SetResourceHandler ;
  1100. ; ;
  1101. ; Sets the resource handler for the given type. ;
  1102. ; ;
  1103. ; Note that the string pointed to can be the resource ID. In this ;
  1104. ; case the string should have the form #ID. ;
  1105. ; ;
  1106. ; If the seg of pointer = 0, then the offset is taken as the ID. ;
  1107. ; ;
  1108. ; Arguments: ;
  1109. ; HANDLE hResFile ;
  1110. ; char far *lpszType ;
  1111. ; FARPROC lpHandler ;
  1112. ; ;
  1113. ; Returns: ;
  1114. ; ;
  1115. ; Error Returns: ;
  1116. ; ;
  1117. ; Registers Preserved: ;
  1118. ; ;
  1119. ; Registers Destroyed: ;
  1120. ; ;
  1121. ; Calls: ;
  1122. ; GetExePtr ;
  1123. ; GetResOrd ;
  1124. ; CmpResStr ;
  1125. ; ;
  1126. ; History: ;
  1127. ; ;
  1128. ; Tue Jan 01, 1980 04:13:03p -by- David N. Weise [davidw] ;
  1129. ; ReWrote it from C into assembly and added this nifty comment block. ;
  1130. ;-----------------------------------------------------------------------;
  1131. cProc ISetResourceHandler,<PUBLIC,FAR>,<di,si>
  1132. parmW hResFile
  1133. parmD lpszType
  1134. parmD lpHandler
  1135. cBegin
  1136. cCall GetExePtr,<hResFile>
  1137. mov ds,ax ; DS = pExe
  1138. mov si,ds:[ne_rsrctab] ; DS:SI = pRes
  1139. cmp si,ds:[ne_restab]
  1140. jz srh_type_not_found ; No resources in this module!
  1141. ;
  1142. ; Pass the type string and NULL for the name string. AX = type ordinal, 0
  1143. ; if it doesn't exist.
  1144. ;
  1145. push hResFile
  1146. push seg_lpszType
  1147. push off_lpszType
  1148. xor ax,ax
  1149. push ax
  1150. push ax
  1151. call GetResOrd
  1152. lea di,[si].SIZE new_rsrc ; DS:DI = pType
  1153. srh_type_loop:
  1154. mov cx,[di].rt_id
  1155. jcxz srh_type_not_found
  1156. push ax ; typeord
  1157. or ax,ax
  1158. jz srh_compare_string
  1159. cmp ax,cx
  1160. jz srh_type_found
  1161. jmps srh_next_type
  1162. srh_compare_string:
  1163. cCall CmpResStr,<ds,si,cx,lpszType>
  1164. or ax,ax
  1165. jnz srh_type_found
  1166. srh_next_type:
  1167. mov ax,[di].rt_nres
  1168. mov cx,SIZE rsrc_nameinfo
  1169. mul cx
  1170. add ax, SIZE rsrc_typeinfo
  1171. add di,ax
  1172. pop ax
  1173. jmp srh_type_loop
  1174. srh_type_found:
  1175. pop ax ; clean stack
  1176. mov dx,word ptr lpHandler[2]
  1177. mov ax,word ptr lpHandler[0]
  1178. xchg dx,word ptr [di].rt_proc[2]
  1179. xchg ax,word ptr [di].rt_proc[0]
  1180. jmps srh_ret
  1181. srh_type_not_found:
  1182. xor ax,ax
  1183. xor dx,dx
  1184. srh_ret:
  1185. cEnd
  1186. ;-----------------------------------------------------------------------;
  1187. ; FindResource ;
  1188. ; ;
  1189. ; Returns a near pointer (into the module database) to the resource ;
  1190. ; description structure. ;
  1191. ; ;
  1192. ; Note that the string pointed to can be the resource ID. In this ;
  1193. ; case the string should have the form #ID. ;
  1194. ; ;
  1195. ; If the seg of pointer = 0, then the offset is taken as the ID. ;
  1196. ; ;
  1197. ; Arguments: ;
  1198. ; HANDLE hResFile ;
  1199. ; char far *lpszName ;
  1200. ; char far *lpszType ;
  1201. ; ;
  1202. ; Returns: ;
  1203. ; AX = near pointer to resource description structure. ;
  1204. ; ;
  1205. ; Error Returns: ;
  1206. ; AX = 0 ;
  1207. ; ;
  1208. ; Registers Preserved: ;
  1209. ; DI,SI,DS ;
  1210. ; ;
  1211. ; Registers Destroyed: ;
  1212. ; BX,CX,DX,ES ;
  1213. ; ;
  1214. ; Calls: ;
  1215. ; GetExePtr ;
  1216. ; GetResOrd ;
  1217. ; CmpResStr ;
  1218. ; ;
  1219. ; History: ;
  1220. ; ;
  1221. ; Tue Jan 01, 1980 10:00:15p -by- David N. Weise [davidw] ;
  1222. ; ReWrote it from C into assembly and added this nifty comment block. ;
  1223. ; Wed May 31, 1989 09:17:00a -by- Scott R. Ludwig [scottlu]
  1224. ; Rewrote so that string identifiers map to ordinals through an indirection
  1225. ; table called a 'name table'. For OS/2 .EXE Compatibility.
  1226. ;-----------------------------------------------------------------------;
  1227. cProc IFindResource,<PUBLIC,FAR>,<di,si>
  1228. parmW hResFile
  1229. parmD lpszName
  1230. parmD lpszType
  1231. localW typeord
  1232. localW nameord
  1233. cBegin
  1234. cCall GetExePtr,<hResFile>
  1235. mov ds,ax ; DS = pExe
  1236. mov si,ds:[ne_rsrctab] ; DS:SI = pRes
  1237. cmp si,ds:[ne_restab]
  1238. jz fr_error_ret
  1239. ;
  1240. ; Get resource ordinals. ax = type ordinal, dx = name ordinal. (0 if not
  1241. ; ordinals).
  1242. ;
  1243. cCall GetResOrd,<hResFile, lpszType, lpszName>
  1244. mov typeord,ax
  1245. mov nameord,dx
  1246. ; First find the resource type.
  1247. lea di,[si].SIZE new_rsrc ; DS:DI = pType
  1248. fr_type_loop:
  1249. mov cx,[di].rt_id
  1250. jcxz fr_error_ret
  1251. mov ax,typeord
  1252. or ax,ax
  1253. jz fr_compare_type_string
  1254. cmp ax,cx
  1255. jz fr_found_type
  1256. jmps fr_next_type
  1257. fr_compare_type_string:
  1258. cCall CmpResStr,<ds,si,cx,lpszType>
  1259. or ax,ax
  1260. jnz fr_found_type
  1261. fr_next_type:
  1262. mov ax,[di].rt_nres
  1263. mov cx,SIZE rsrc_nameinfo
  1264. mul cx
  1265. add ax,SIZE rsrc_typeinfo
  1266. add di,ax
  1267. jmp fr_type_loop
  1268. fr_found_type:
  1269. ; Now find the resource name.
  1270. mov cx,[di].rt_nres
  1271. lea di,[di].SIZE rsrc_typeinfo ; DS:DI = pName
  1272. fr_name_loop:
  1273. mov bx,nameord
  1274. or bx,bx
  1275. mov ax,[di].rn_id
  1276. jz fr_compare_name_string
  1277. cmp ax,bx
  1278. jz fr_found_name
  1279. jmps fr_next_name
  1280. fr_compare_name_string:
  1281. push cx
  1282. cCall CmpResStr,<ds,si,ax,lpszName>
  1283. pop cx
  1284. or ax,ax
  1285. jnz fr_found_name
  1286. fr_next_name:
  1287. add di,SIZE rsrc_nameinfo
  1288. loop fr_name_loop
  1289. fr_error_ret:
  1290. xor ax,ax
  1291. jmps fr_ret
  1292. fr_found_name:
  1293. mov ax,di
  1294. fr_ret:
  1295. cEnd
  1296. sEnd MISCCODE
  1297. sBegin NRESCODE
  1298. assumes CS,NRESCODE
  1299. assumes DS,NOTHING
  1300. assumes ES,NOTHING
  1301. cProc PreloadResources,<PUBLIC,NEAR>,<si,di>
  1302. parmW hExe
  1303. parmW fh
  1304. parmW hBlock
  1305. parmD FileOffset
  1306. ifdef WOW_OPTIMIZE_PRELOADRESOURCE
  1307. localW hiResOffset
  1308. localW loResOffset
  1309. endif
  1310. cBegin
  1311. mov es,hExe
  1312. xor bx,bx
  1313. mov si,es:[bx].ne_rsrctab
  1314. cmp es:[bx].ne_restab,si
  1315. jne prnotdone
  1316. prdonej:
  1317. jmp prdone
  1318. prnextj:
  1319. jmp prnext
  1320. prnotdone:
  1321. mov di,es:[si].rs_align
  1322. add si,SIZE new_rsrc
  1323. prtype:
  1324. cmp es:[si].rt_id,0
  1325. je prdonej
  1326. mov cx,es:[si].rt_nres
  1327. mov word ptr es:[si].rt_proc[0],codeOffset DefaultResourceHandler
  1328. mov word ptr es:[si].rt_proc[2],codeBase
  1329. add si,SIZE rsrc_typeinfo
  1330. prname:
  1331. push cx
  1332. mov ax,es:[si].rn_flags
  1333. ; cmp word ptr es:[ne_ver],4 ; Produced by version 4.0 LINK?
  1334. ; ja prname2
  1335. ; test ah,0Fh ; Is old discard field set?
  1336. ; jz prname1
  1337. ; or ax,RNDISCARD ; Yes, convert to bit
  1338. ;prname1:
  1339. ; and ax,not RNUNUSED ; Clear unused bits in 4.0 LINK files
  1340. prname2:
  1341. or ax,NENOTP
  1342. errnz <NENOTP - 8000h>
  1343. test es:[ne_flags],NENOTP
  1344. jnz prname4 ; Mark as EMSable if resource belongs
  1345. xor ax,NENOTP ; to a task.
  1346. prname4:
  1347. mov es:[si].rn_flags,ax
  1348. test al,RNPRELOAD
  1349. jz prnextj
  1350. mov cx, seg_FileOffset
  1351. or cx, off_FileOffset
  1352. jcxz PL_file
  1353. cmp di, 4 ; Must be at least paragraph aligned
  1354. jb PL_file
  1355. push es
  1356. cCall GlobalLock,<hBlock>
  1357. ifdef WOW_OPTIMIZE_PRELOADRESOURCE
  1358. mov ax,dx ; no need to alloc a selector. we will use the
  1359. ; the current one.
  1360. if KDEBUG
  1361. or ax, ax
  1362. jnz @F
  1363. int 3 ; // should never happen
  1364. @@:
  1365. endif
  1366. else
  1367. cCall AllocSelector,<dx>
  1368. endif
  1369. pop es
  1370. mov bx,es:[si].rn_offset
  1371. xor dx,dx
  1372. mov cx,di
  1373. PL_shift:
  1374. shl bx,1
  1375. rcl dx,1
  1376. loop PL_shift
  1377. sub bx, off_FileOffset
  1378. sbb dx, seg_FileOffset
  1379. ifdef WOW_OPTIMIZE_PRELOADRESOURCE
  1380. ; call to longptraddwow basically is a nop. it doesn't set the
  1381. ; descriptor. it is called 'cause it sets some registers.
  1382. mov hiResOffset, dx
  1383. mov loResOffset, bx
  1384. push ax
  1385. push es
  1386. cCall LongPtrAddWOW,<ax,cx,dx,bx, 0, 0> ; (cx is 0)
  1387. pop es
  1388. dec cx
  1389. cCall ResAlloc,<essi,dx,cx, hiResOffset, loResOffset>
  1390. pop cx
  1391. push ax
  1392. else
  1393. push ax
  1394. push es
  1395. cCall LongPtrAdd,<ax,cx,dx,bx> ; (cx is 0)
  1396. pop es
  1397. dec cx
  1398. cCall ResAlloc,<essi,dx,cx, 0, 0>
  1399. pop cx
  1400. push ax
  1401. cCall FreeSelector,<cx>
  1402. endif
  1403. cCall GlobalUnlock,<hBlock>
  1404. pop ax
  1405. jmps PL_loaded
  1406. PL_file:
  1407. mov dx,es:[si].rn_offset
  1408. xor ax,ax
  1409. mov cx,di
  1410. PL_shift1:
  1411. shl dx,1
  1412. rcl ax,1
  1413. loop PL_shift1
  1414. mov cx,ax
  1415. mov ax,4200h
  1416. mov bx,fh
  1417. DOSFCALL
  1418. ifdef WOW_OPTIMIZE_PRELOADRESOURCE
  1419. cCall ResAlloc,<essi,bx,bx, 0, 0>
  1420. else
  1421. cCall ResAlloc,<essi,bx,bx>
  1422. endif
  1423. PL_loaded:
  1424. mov es,hExe
  1425. mov es:[si].rn_handle,ax
  1426. prnext:
  1427. pop cx
  1428. add si,SIZE rsrc_nameinfo
  1429. dec cx
  1430. jz prtypej
  1431. jmp prname
  1432. prtypej:
  1433. jmp prtype
  1434. prdone:
  1435. cEnd
  1436. sEnd NRESCODE
  1437. end