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.

865 lines
17 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. EmulateHeap.cpp
  5. Abstract:
  6. This SHIM is for the layer and it emulates the Win9x heap manager. In fact,
  7. much of the code is adapted from the Win9x sources .\heap.c and .\lmem.c.
  8. This SHIM hooks all the heap allocation/deallocation functions including
  9. the local/global functions.
  10. Notes:
  11. This is a general purpose shim.
  12. History:
  13. 11/16/2000 prashkud & linstev Created
  14. --*/
  15. #include "precomp.h"
  16. IMPLEMENT_SHIM_BEGIN(EmulateHeap)
  17. #include "ShimHookMacro.h"
  18. APIHOOK_ENUM_BEGIN
  19. APIHOOK_ENUM_ENTRY(HeapCreate)
  20. APIHOOK_ENUM_ENTRY(HeapDestroy)
  21. APIHOOK_ENUM_ENTRY(HeapValidate)
  22. APIHOOK_ENUM_ENTRY(HeapCompact)
  23. APIHOOK_ENUM_ENTRY(HeapWalk)
  24. APIHOOK_ENUM_ENTRY(HeapLock)
  25. APIHOOK_ENUM_ENTRY(HeapUnlock)
  26. APIHOOK_ENUM_ENTRY(GetProcessHeap)
  27. APIHOOK_ENUM_ENTRY(LocalAlloc)
  28. APIHOOK_ENUM_ENTRY(LocalFree)
  29. APIHOOK_ENUM_ENTRY(LocalReAlloc)
  30. APIHOOK_ENUM_ENTRY(LocalLock)
  31. APIHOOK_ENUM_ENTRY(LocalUnlock)
  32. APIHOOK_ENUM_ENTRY(LocalHandle)
  33. APIHOOK_ENUM_ENTRY(LocalSize)
  34. APIHOOK_ENUM_ENTRY(LocalFlags)
  35. APIHOOK_ENUM_ENTRY(GlobalAlloc)
  36. APIHOOK_ENUM_ENTRY(GlobalFree)
  37. APIHOOK_ENUM_ENTRY(GlobalReAlloc)
  38. APIHOOK_ENUM_ENTRY(GlobalLock)
  39. APIHOOK_ENUM_ENTRY(GlobalUnlock)
  40. APIHOOK_ENUM_ENTRY(GlobalHandle)
  41. APIHOOK_ENUM_ENTRY(GlobalSize)
  42. APIHOOK_ENUM_ENTRY(GlobalFlags)
  43. APIHOOK_ENUM_ENTRY(RtlAllocateHeap)
  44. APIHOOK_ENUM_ENTRY(RtlReAllocateHeap)
  45. APIHOOK_ENUM_ENTRY(RtlFreeHeap)
  46. APIHOOK_ENUM_ENTRY(RtlSizeHeap)
  47. APIHOOK_ENUM_END
  48. extern "C" {
  49. BOOL _HeapInit();
  50. HANDLE _HeapCreate(DWORD flOptions, SIZE_T dwInitialSize, SIZE_T dwMaximumSize);
  51. BOOL _HeapDestroy(HANDLE hHeap);
  52. LPVOID _HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes);
  53. LPVOID _HeapReAlloc(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem, SIZE_T dwBytes);
  54. BOOL _HeapFree(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem);
  55. DWORD _HeapSize(HANDLE hHeap, DWORD dwFlags, LPCVOID lpMem);
  56. HLOCAL APIENTRY _LocalAlloc(UINT dwFlags, UINT dwBytes);
  57. HLOCAL APIENTRY _LocalFree(HLOCAL hMem);
  58. LPVOID _LocalReAlloc(LPVOID lpMem, SIZE_T dwBytes, UINT uFlags);
  59. LPVOID _LocalLock(HLOCAL hMem);
  60. BOOL _LocalUnlock(HLOCAL hMem);
  61. HANDLE _LocalHandle(LPCVOID hMem);
  62. UINT _LocalSize(HLOCAL hMem);
  63. UINT _LocalFlags(HLOCAL hMem);
  64. HANDLE _GetProcessHeap(void);
  65. BOOL _IsOurHeap(HANDLE hHeap);
  66. BOOL _IsOurLocalHeap(HANDLE hMem);
  67. BOOL _IsOnOurHeap(LPCVOID lpMem);
  68. }
  69. /*++
  70. Helper functions so as not to bloat the stubs.
  71. --*/
  72. BOOL UseOurHeap(HANDLE hHeap, LPCVOID lpMem)
  73. {
  74. return (_IsOurHeap(hHeap) || ((hHeap == RtlProcessHeap()) && _IsOnOurHeap(lpMem)));
  75. }
  76. BOOL ValidateNTHeap(HANDLE hHeap, LPCVOID lpMem)
  77. {
  78. BOOL bRet = FALSE;
  79. __try
  80. {
  81. bRet = ORIGINAL_API(HeapValidate)(hHeap, 0, lpMem);
  82. }
  83. __except(EXCEPTION_EXECUTE_HANDLER)
  84. {
  85. LOGN( eDbgLevelError, "[ValidateHeap] %08lx:%08lx is invalid", hHeap, lpMem);
  86. }
  87. return bRet;
  88. }
  89. /*++
  90. Stub APIs.
  91. --*/
  92. LPVOID
  93. APIHOOK(RtlAllocateHeap)(
  94. HANDLE hHeap,
  95. DWORD dwFlags,
  96. SIZE_T dwBytes
  97. )
  98. {
  99. if (_IsOurHeap(hHeap))
  100. {
  101. return _HeapAlloc(hHeap, dwFlags, dwBytes);
  102. }
  103. else
  104. {
  105. DPFN( eDbgLevelInfo, "NTHEAP: RtlAllocateHeap");
  106. return ORIGINAL_API(RtlAllocateHeap)(hHeap, dwFlags, dwBytes);
  107. }
  108. }
  109. HANDLE
  110. APIHOOK(HeapCreate)(
  111. DWORD flOptions,
  112. SIZE_T dwInitialSize,
  113. SIZE_T dwMaximumSize
  114. )
  115. {
  116. return _HeapCreate(flOptions, dwInitialSize, dwMaximumSize);
  117. }
  118. LPVOID
  119. APIHOOK(RtlReAllocateHeap)(
  120. HANDLE hHeap,
  121. DWORD dwFlags,
  122. LPVOID lpMem,
  123. SIZE_T dwBytes
  124. )
  125. {
  126. LPVOID uRet = FALSE;
  127. if (UseOurHeap(hHeap, lpMem))
  128. {
  129. uRet = _HeapReAlloc(hHeap, dwFlags, lpMem, dwBytes);
  130. }
  131. else
  132. {
  133. DPFN( eDbgLevelInfo, "NTHEAP: RtlReAllocateHeap");
  134. if (ValidateNTHeap(hHeap, lpMem))
  135. {
  136. uRet = ORIGINAL_API(RtlReAllocateHeap)(hHeap, dwFlags, lpMem, dwBytes);
  137. }
  138. }
  139. return uRet;
  140. }
  141. BOOL
  142. APIHOOK(RtlFreeHeap)(
  143. HANDLE hHeap,
  144. DWORD dwFlags,
  145. LPVOID lpMem
  146. )
  147. {
  148. BOOL bRet = FALSE;
  149. if (UseOurHeap(hHeap, lpMem))
  150. {
  151. bRet = _HeapFree(hHeap, dwFlags, lpMem);
  152. }
  153. else
  154. {
  155. DPFN( eDbgLevelInfo, "NTHEAP: RtlFreeHeap");
  156. if (ValidateNTHeap(hHeap, lpMem))
  157. {
  158. bRet = ORIGINAL_API(RtlFreeHeap)(hHeap, dwFlags, lpMem);
  159. }
  160. }
  161. return bRet;
  162. }
  163. HANDLE
  164. APIHOOK(GetProcessHeap)(VOID)
  165. {
  166. return _GetProcessHeap();
  167. }
  168. BOOL
  169. APIHOOK(HeapDestroy)(HANDLE hHeap)
  170. {
  171. if (_IsOurHeap(hHeap))
  172. {
  173. return _HeapDestroy(hHeap);
  174. }
  175. else
  176. {
  177. DPFN( eDbgLevelInfo, "NTHEAP: HeapDestroy");
  178. return ORIGINAL_API(HeapDestroy)(hHeap);
  179. }
  180. }
  181. DWORD
  182. APIHOOK(RtlSizeHeap)(
  183. HANDLE hHeap,
  184. DWORD dwFlags,
  185. LPCVOID lpMem
  186. )
  187. {
  188. BOOL bRet = FALSE;
  189. if (UseOurHeap(hHeap, lpMem))
  190. {
  191. bRet = _HeapSize(hHeap, dwFlags, lpMem);
  192. }
  193. else
  194. {
  195. DPFN( eDbgLevelInfo, "NTHEAP: RtlSizeHeap");
  196. if (ValidateNTHeap(hHeap, lpMem))
  197. {
  198. bRet = ORIGINAL_API(RtlSizeHeap)(hHeap, dwFlags, lpMem);
  199. }
  200. }
  201. return bRet;
  202. }
  203. BOOL
  204. APIHOOK(HeapValidate)(
  205. HANDLE hHeap,
  206. DWORD dwFlags,
  207. LPCVOID lpMem
  208. )
  209. {
  210. BOOL bRet = FALSE;
  211. if (UseOurHeap(hHeap, lpMem))
  212. {
  213. // Win9x return values
  214. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  215. bRet = -1;
  216. }
  217. else
  218. {
  219. DPFN( eDbgLevelInfo, "NTHEAP: HeapValidate");
  220. __try
  221. {
  222. bRet = ORIGINAL_API(HeapValidate)(hHeap, dwFlags, lpMem);
  223. }
  224. __except(EXCEPTION_EXECUTE_HANDLER)
  225. {
  226. LOGN( eDbgLevelError, "[HeapValidate] %08lx:%08lx is invalid", hHeap, lpMem);
  227. }
  228. }
  229. return bRet;
  230. }
  231. HLOCAL
  232. APIHOOK(LocalAlloc)(
  233. UINT uFlags,
  234. SIZE_T uBytes
  235. )
  236. {
  237. return _LocalAlloc(uFlags, uBytes);
  238. }
  239. HLOCAL
  240. APIHOOK(LocalFree)(
  241. HLOCAL hMem
  242. )
  243. {
  244. HLOCAL hRet = NULL;
  245. if (_IsOurLocalHeap(hMem))
  246. {
  247. hRet = _LocalFree(hMem);
  248. }
  249. else
  250. {
  251. DPFN( eDbgLevelInfo, "NTHEAP: LocalFree %08lx", hMem);
  252. __try
  253. {
  254. hRet = ORIGINAL_API(LocalFree)(hMem);
  255. }
  256. __except(EXCEPTION_EXECUTE_HANDLER)
  257. {
  258. LOGN( eDbgLevelError,
  259. "[LocalFree] Exception: Invalid Pointer %08lx", hMem);
  260. }
  261. }
  262. return hRet;
  263. }
  264. HLOCAL
  265. APIHOOK(LocalReAlloc)(
  266. HLOCAL hMem,
  267. SIZE_T uBytes,
  268. UINT uFlags
  269. )
  270. {
  271. HLOCAL hRet = NULL;
  272. if (_IsOurLocalHeap(hMem))
  273. {
  274. hRet = _LocalReAlloc(hMem, uBytes, uFlags);
  275. }
  276. else
  277. {
  278. DPFN( eDbgLevelInfo, "NTHEAP: LocalReAlloc %08lx", hMem);
  279. __try
  280. {
  281. hRet = ORIGINAL_API(LocalReAlloc)(hMem, uBytes, uFlags);
  282. }
  283. __except(EXCEPTION_EXECUTE_HANDLER)
  284. {
  285. LOGN( eDbgLevelError,
  286. "[LocalReAlloc] Exception: Invalid Pointer %08lx", hMem);
  287. }
  288. }
  289. return hRet;
  290. }
  291. LPVOID
  292. APIHOOK(LocalLock)(
  293. HLOCAL hMem
  294. )
  295. {
  296. LPVOID pRet = NULL;
  297. if (_IsOurLocalHeap(hMem))
  298. {
  299. pRet = _LocalLock(hMem);
  300. }
  301. else
  302. {
  303. DPFN( eDbgLevelInfo, "NTHEAP: LocalLock %08lx", hMem);
  304. __try
  305. {
  306. pRet = ORIGINAL_API(LocalLock)(hMem);
  307. }
  308. __except(EXCEPTION_EXECUTE_HANDLER)
  309. {
  310. LOGN( eDbgLevelError,
  311. "[LocalLock] Exception: Invalid Pointer %08lx", hMem);
  312. }
  313. }
  314. return pRet;
  315. }
  316. BOOL
  317. APIHOOK(LocalUnlock)(
  318. HLOCAL hMem
  319. )
  320. {
  321. BOOL bRet = FALSE;
  322. if (_IsOurLocalHeap(hMem))
  323. {
  324. bRet = _LocalUnlock(hMem);
  325. }
  326. else
  327. {
  328. DPFN( eDbgLevelInfo, "NTHEAP: LocalUnlock %08lx", hMem);
  329. __try
  330. {
  331. bRet = ORIGINAL_API(LocalUnlock)(hMem);
  332. }
  333. __except(EXCEPTION_EXECUTE_HANDLER)
  334. {
  335. LOGN( eDbgLevelError,
  336. "[LocalUnLock] Exception: Invalid Pointer %08lx", hMem);
  337. }
  338. }
  339. return bRet;
  340. }
  341. HANDLE
  342. APIHOOK(LocalHandle)(
  343. LPCVOID hMem
  344. )
  345. {
  346. HANDLE hRet = NULL;
  347. if (_IsOurLocalHeap((HANDLE)hMem))
  348. {
  349. hRet = _LocalHandle(hMem);
  350. }
  351. else
  352. {
  353. DPFN( eDbgLevelInfo, "NTHEAP: LocalHandle %08lx", hMem);
  354. __try
  355. {
  356. hRet = ORIGINAL_API(LocalHandle)(hMem);
  357. }
  358. __except(EXCEPTION_EXECUTE_HANDLER)
  359. {
  360. LOGN( eDbgLevelError,
  361. "[LocalHandle] Exception: Invalid Pointer %08lx", hMem);
  362. }
  363. }
  364. return hRet;
  365. }
  366. UINT
  367. APIHOOK(LocalSize)(
  368. HLOCAL hMem
  369. )
  370. {
  371. UINT uRet = 0;
  372. if (_IsOurLocalHeap(hMem))
  373. {
  374. uRet = _LocalSize(hMem);
  375. }
  376. else
  377. {
  378. DPFN( eDbgLevelInfo, "NTHEAP: LocalSize %08lx", hMem);
  379. __try
  380. {
  381. uRet = ORIGINAL_API(LocalSize)(hMem);
  382. }
  383. __except(EXCEPTION_EXECUTE_HANDLER)
  384. {
  385. LOGN( eDbgLevelError,
  386. "[LocalSize] Exception: Invalid Pointer %08lx", hMem);
  387. }
  388. }
  389. return uRet;
  390. }
  391. UINT
  392. APIHOOK(LocalFlags)(
  393. HLOCAL hMem
  394. )
  395. {
  396. UINT uRet = 0;
  397. if (_IsOurLocalHeap(hMem))
  398. {
  399. uRet = _LocalFlags(hMem);
  400. }
  401. else
  402. {
  403. DPFN( eDbgLevelInfo, "NTHEAP: LocalFlags %08lx", hMem);
  404. __try
  405. {
  406. uRet = ORIGINAL_API(LocalFlags)(hMem);
  407. }
  408. __except(EXCEPTION_EXECUTE_HANDLER)
  409. {
  410. LOGN( eDbgLevelError,
  411. "[LocalFlags] Exception: Invalid Pointer %08lx", hMem);
  412. }
  413. }
  414. return uRet;
  415. }
  416. HGLOBAL
  417. APIHOOK(GlobalAlloc)(
  418. UINT uFlags,
  419. SIZE_T uBytes
  420. )
  421. {
  422. uFlags = (((uFlags & GMEM_ZEROINIT) ? LMEM_ZEROINIT : 0 ) |
  423. ((uFlags & GMEM_MOVEABLE) ? LMEM_MOVEABLE : 0 ) |
  424. ((uFlags & GMEM_FIXED) ? LMEM_FIXED : 0 ));
  425. return _LocalAlloc(uFlags, uBytes);
  426. }
  427. HGLOBAL
  428. APIHOOK(GlobalFree)(
  429. HGLOBAL hMem
  430. )
  431. {
  432. HGLOBAL hRet = NULL;
  433. if (_IsOurLocalHeap(hMem))
  434. {
  435. hRet = _LocalFree(hMem);
  436. }
  437. else
  438. {
  439. DPFN( eDbgLevelInfo, "NTHEAP: GlobalFree %08lx", hMem);
  440. __try
  441. {
  442. hRet = ORIGINAL_API(GlobalFree)(hMem);
  443. }
  444. __except(EXCEPTION_EXECUTE_HANDLER)
  445. {
  446. LOGN( eDbgLevelError,
  447. "[GlobalFree] Exception: Invalid Pointer %08lx", hMem);
  448. }
  449. }
  450. return hRet;
  451. }
  452. HGLOBAL
  453. APIHOOK(GlobalReAlloc)(
  454. HGLOBAL hMem,
  455. SIZE_T uBytes,
  456. UINT uFlags
  457. )
  458. {
  459. UINT uLocalFlags =
  460. (((uFlags & GMEM_ZEROINIT) ? LMEM_ZEROINIT : 0 ) |
  461. ((uFlags & GMEM_MOVEABLE) ? LMEM_MOVEABLE : 0 ) |
  462. ((uFlags & GMEM_FIXED) ? LMEM_FIXED : 0 ));
  463. HLOCAL hRet = NULL;
  464. if (_IsOurLocalHeap(hMem))
  465. {
  466. hRet = _LocalReAlloc(hMem, uBytes, uLocalFlags);
  467. }
  468. else
  469. {
  470. DPFN( eDbgLevelInfo, "NTHEAP: GlobalReAlloc %08lx", hMem);
  471. __try
  472. {
  473. hRet = ORIGINAL_API(GlobalReAlloc)(hMem, uBytes, uFlags);
  474. }
  475. __except(EXCEPTION_EXECUTE_HANDLER)
  476. {
  477. LOGN( eDbgLevelError,
  478. "[GlobalReAlloc] Exception: Invalid Pointer %08lx", hMem);
  479. }
  480. }
  481. return hRet;
  482. }
  483. LPVOID
  484. APIHOOK(GlobalLock)(
  485. HGLOBAL hMem
  486. )
  487. {
  488. LPVOID pRet = NULL;
  489. if (_IsOurLocalHeap(hMem))
  490. {
  491. pRet = _LocalLock(hMem);
  492. }
  493. else
  494. {
  495. DPFN( eDbgLevelInfo, "NTHEAP: GlobalLock %08lx", hMem);
  496. __try
  497. {
  498. pRet = ORIGINAL_API(GlobalLock)(hMem);
  499. }
  500. __except(EXCEPTION_EXECUTE_HANDLER)
  501. {
  502. LOGN( eDbgLevelError,
  503. "[GlobalLock] Exception: Invalid Pointer %08lx", hMem);
  504. }
  505. }
  506. return pRet;
  507. }
  508. BOOL
  509. APIHOOK(GlobalUnlock)(
  510. HGLOBAL hMem
  511. )
  512. {
  513. BOOL bRet = FALSE;
  514. if (_IsOurLocalHeap(hMem))
  515. {
  516. bRet = _LocalUnlock(hMem);
  517. }
  518. else
  519. {
  520. DPFN( eDbgLevelInfo, "NTHEAP: GlobalUnlock %08lx", hMem);
  521. __try
  522. {
  523. bRet = ORIGINAL_API(GlobalUnlock)(hMem);
  524. }
  525. __except(EXCEPTION_EXECUTE_HANDLER)
  526. {
  527. LOGN( eDbgLevelError,
  528. "[GlobalUnLock] Exception: Invalid Pointer %08lx", hMem);
  529. }
  530. }
  531. return bRet;
  532. }
  533. HANDLE
  534. APIHOOK(GlobalHandle)(
  535. LPCVOID hMem
  536. )
  537. {
  538. HANDLE hRet = NULL;
  539. if (_IsOurLocalHeap((HANDLE)hMem))
  540. {
  541. hRet = _LocalHandle(hMem);
  542. }
  543. else
  544. {
  545. DPFN( eDbgLevelInfo, "NTHEAP: GlobalHandle %08lx", hMem);
  546. __try
  547. {
  548. hRet = ORIGINAL_API(GlobalHandle)(hMem);
  549. }
  550. __except(EXCEPTION_EXECUTE_HANDLER)
  551. {
  552. LOGN( eDbgLevelError,
  553. "[GlobalHandle] Exception: Invalid Pointer %08lx for Heap",
  554. hMem);
  555. }
  556. }
  557. return hRet;
  558. }
  559. UINT
  560. APIHOOK(GlobalSize)(
  561. HGLOBAL hMem
  562. )
  563. {
  564. UINT uRet = 0;
  565. if (_IsOurLocalHeap(hMem))
  566. {
  567. uRet = _LocalSize(hMem);
  568. }
  569. else
  570. {
  571. DPFN( eDbgLevelInfo, "NTHEAP: GlobalSize %08lx", hMem);
  572. __try
  573. {
  574. uRet = ORIGINAL_API(GlobalSize)(hMem);
  575. }
  576. __except(EXCEPTION_EXECUTE_HANDLER)
  577. {
  578. LOGN( eDbgLevelError,
  579. "[GlobalSize] Exception: Invalid Pointer %08lx for Heap",
  580. hMem);
  581. }
  582. }
  583. return uRet;
  584. }
  585. UINT
  586. APIHOOK(GlobalFlags)(
  587. HGLOBAL hMem
  588. )
  589. {
  590. UINT uRet = 0;
  591. if (_IsOurLocalHeap(hMem))
  592. {
  593. uRet = _LocalFlags(hMem);
  594. // Convert the flags
  595. UINT uNewRet = uRet;
  596. uRet = 0;
  597. if (uNewRet & LMEM_DISCARDABLE)
  598. {
  599. uRet |= GMEM_DISCARDABLE;
  600. }
  601. if (uNewRet & LMEM_DISCARDED)
  602. {
  603. uRet |= GMEM_DISCARDED;
  604. }
  605. }
  606. else
  607. {
  608. DPFN( eDbgLevelInfo, "NTHEAP: GlobalFlags %08lx", hMem);
  609. __try
  610. {
  611. uRet = ORIGINAL_API(GlobalFlags)(hMem);
  612. }
  613. __except(EXCEPTION_EXECUTE_HANDLER)
  614. {
  615. LOGN( eDbgLevelError,
  616. "[GlobalFlags] Exception: Invalid Pointer %08lx for Heap",
  617. hMem);
  618. }
  619. }
  620. return uRet;
  621. }
  622. UINT
  623. APIHOOK(HeapCompact)(
  624. HANDLE hHeap,
  625. DWORD dwFlags
  626. )
  627. {
  628. if (_IsOurHeap(hHeap))
  629. {
  630. // Win9x return values
  631. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  632. return 0;
  633. }
  634. else
  635. {
  636. DPFN( eDbgLevelInfo, "NTHEAP: HeapCompact");
  637. return ORIGINAL_API(HeapCompact)(hHeap, dwFlags);
  638. }
  639. }
  640. BOOL
  641. APIHOOK(HeapWalk)(
  642. HANDLE hHeap,
  643. LPPROCESS_HEAP_ENTRY pEntry
  644. )
  645. {
  646. if (_IsOurHeap(hHeap))
  647. {
  648. // Win9x return values
  649. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  650. return 0;
  651. }
  652. else
  653. {
  654. DPFN( eDbgLevelInfo, "NTHEAP: HeapWalk");
  655. return ORIGINAL_API(HeapWalk)(hHeap, pEntry);
  656. }
  657. }
  658. BOOL
  659. APIHOOK(HeapLock)(
  660. HANDLE hHeap
  661. )
  662. {
  663. if (_IsOurHeap(hHeap))
  664. {
  665. // Win9x return values
  666. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  667. return 0;
  668. }
  669. else
  670. {
  671. DPFN( eDbgLevelInfo, "NTHEAP: HeapLock");
  672. return ORIGINAL_API(HeapLock)(hHeap);
  673. }
  674. }
  675. BOOL
  676. APIHOOK(HeapUnlock)(
  677. HANDLE hHeap
  678. )
  679. {
  680. if (_IsOurHeap(hHeap))
  681. {
  682. // Win9x return values
  683. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  684. return 0;
  685. }
  686. else
  687. {
  688. DPFN( eDbgLevelInfo, "NTHEAP: HeapUnlock");
  689. return ORIGINAL_API(HeapUnlock)(hHeap);
  690. }
  691. }
  692. /*++
  693. Register hooked functions
  694. --*/
  695. BOOL
  696. NOTIFY_FUNCTION(
  697. DWORD fdwReason
  698. )
  699. {
  700. BOOL bRet = TRUE;
  701. if (fdwReason == DLL_PROCESS_ATTACH)
  702. {
  703. bRet = _HeapInit();
  704. if (bRet)
  705. {
  706. LOGN(eDbgLevelInfo, "[NotifyFn] Win9x heap manager initialized");
  707. }
  708. else
  709. {
  710. LOGN(eDbgLevelError, "[NotifyFn] Win9x heap manager initialization failed!");
  711. }
  712. }
  713. return bRet;
  714. }
  715. HOOK_BEGIN
  716. CALL_NOTIFY_FUNCTION
  717. APIHOOK_ENTRY(KERNEL32.DLL, HeapCreate)
  718. APIHOOK_ENTRY(KERNEL32.DLL, HeapDestroy)
  719. APIHOOK_ENTRY(KERNEL32.DLL, HeapValidate)
  720. APIHOOK_ENTRY(KERNEL32.DLL, HeapCompact)
  721. APIHOOK_ENTRY(KERNEL32.DLL, HeapWalk)
  722. APIHOOK_ENTRY(KERNEL32.DLL, HeapLock)
  723. APIHOOK_ENTRY(KERNEL32.DLL, HeapUnlock)
  724. APIHOOK_ENTRY(KERNEL32.DLL, GetProcessHeap)
  725. APIHOOK_ENTRY(KERNEL32.DLL, LocalAlloc)
  726. APIHOOK_ENTRY(KERNEL32.DLL, LocalFree)
  727. APIHOOK_ENTRY(KERNEL32.DLL, LocalReAlloc)
  728. APIHOOK_ENTRY(KERNEL32.DLL, LocalLock)
  729. APIHOOK_ENTRY(KERNEL32.DLL, LocalUnlock)
  730. APIHOOK_ENTRY(KERNEL32.DLL, LocalHandle)
  731. APIHOOK_ENTRY(KERNEL32.DLL, LocalSize)
  732. APIHOOK_ENTRY(KERNEL32.DLL, LocalFlags)
  733. APIHOOK_ENTRY(KERNEL32.DLL, GlobalAlloc)
  734. APIHOOK_ENTRY(KERNEL32.DLL, GlobalFree)
  735. APIHOOK_ENTRY(KERNEL32.DLL, GlobalReAlloc)
  736. APIHOOK_ENTRY(KERNEL32.DLL, GlobalLock)
  737. APIHOOK_ENTRY(KERNEL32.DLL, GlobalUnlock)
  738. APIHOOK_ENTRY(KERNEL32.DLL, GlobalHandle)
  739. APIHOOK_ENTRY(KERNEL32.DLL, GlobalSize)
  740. APIHOOK_ENTRY(KERNEL32.DLL, GlobalFlags)
  741. APIHOOK_ENTRY(NTDLL.DLL, RtlAllocateHeap)
  742. APIHOOK_ENTRY(NTDLL.DLL, RtlReAllocateHeap)
  743. APIHOOK_ENTRY(NTDLL.DLL, RtlFreeHeap)
  744. APIHOOK_ENTRY(NTDLL.DLL, RtlSizeHeap)
  745. HOOK_END
  746. IMPLEMENT_SHIM_END