Source code of Windows XP (NT5)
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.

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