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.

1449 lines
27 KiB

  1. /*++
  2. Copyright (c) 1995-2001 Microsoft Corporation
  3. Module Name:
  4. heapdbg.c
  5. Abstract:
  6. Domain Name System (DNS) Library
  7. Heap debugging routines.
  8. Author:
  9. Jim Gilroy (jamesg) January 31, 1995
  10. Revision History:
  11. --*/
  12. #include "local.h"
  13. #include "heapdbg.h"
  14. //
  15. // locking
  16. //
  17. #define LOCK_HEAP(p) EnterCriticalSection( &p->ListCs )
  18. #define UNLOCK_HEAP(p) LeaveCriticalSection( &p->ListCs )
  19. //
  20. // Heap
  21. //
  22. // Debug heap routines allow heap to be specified by caller of
  23. // each routine, or by having heap global.
  24. // If global, the heap handle may be supplied to initialization
  25. // routine OR created internally.
  26. //
  27. #define HEAP_DBG_DEFAULT_CREATE_FLAGS \
  28. ( HEAP_GROWABLE | \
  29. HEAP_GENERATE_EXCEPTIONS | \
  30. HEAP_TAIL_CHECKING_ENABLED | \
  31. HEAP_FREE_CHECKING_ENABLED | \
  32. HEAP_CREATE_ALIGN_16 | \
  33. HEAP_CLASS_1 )
  34. //
  35. // Dnslib using this heap
  36. //
  37. PHEAP_BLOB g_pDnslibHeapBlob;
  38. HEAP_BLOB g_DnslibHeapBlob;
  39. //
  40. // Heap Header / Trailer Flags
  41. //
  42. #define HEAP_CODE 0xdddddddd
  43. #define HEAP_CODE_ACTIVE 0xaaaaaaaa
  44. #define HEAP_CODE_FREE 0xeeeeeeee
  45. //
  46. // Heap Trailer from Header
  47. //
  48. #define HEAP_TRAILER(_head_) \
  49. ( (PHEAP_TRAILER) ( \
  50. (PCHAR)(_head_) \
  51. + (_head_)->AllocSize \
  52. - sizeof(HEAP_TRAILER) ) )
  53. //
  54. // Private protos
  55. //
  56. VOID
  57. DbgHeapValidateHeader(
  58. IN PHEAP_HEADER h
  59. );
  60. //
  61. // Private utilities
  62. //
  63. INT
  64. DbgHeapFindAllocSize(
  65. IN INT iRequestSize
  66. )
  67. /*++
  68. Routine Description:
  69. Determines actual size of debug alloc.
  70. Adds in sizes of DWORD aligned header and trailer.
  71. Arguments:
  72. iRequestSize - requested allocation size
  73. Return Value:
  74. None
  75. --*/
  76. {
  77. register INT imodSize;
  78. //
  79. // find DWORD multiple size of original alloc,
  80. // this is required so debug trailer will be DWORD aligned
  81. //
  82. imodSize = iRequestSize % sizeof(DWORD);
  83. if ( imodSize )
  84. {
  85. imodSize = sizeof(DWORD) - imodSize;
  86. }
  87. imodSize += iRequestSize + sizeof(HEAP_HEADER) + sizeof(HEAP_TRAILER);
  88. ASSERT( ! (imodSize % sizeof(DWORD)) );
  89. return( imodSize );
  90. }
  91. PVOID
  92. DbgHeapSetHeaderAlloc(
  93. IN OUT PHEAP_BLOB pHeap,
  94. IN OUT PHEAP_HEADER h,
  95. IN INT iSize,
  96. IN LPSTR pszFile,
  97. IN DWORD dwLine
  98. )
  99. /*++
  100. Routine Description:
  101. Sets/Resets heap globals and heap header info.
  102. Arguments:
  103. h - ptr to new memory block
  104. iSize - size allocated
  105. Return Value:
  106. None
  107. --*/
  108. {
  109. PHEAP_TRAILER t;
  110. INT allocSize;
  111. ASSERT( iSize > 0 );
  112. //
  113. // determine actual alloc
  114. //
  115. allocSize = DbgHeapFindAllocSize( iSize );
  116. //
  117. // update heap info globals
  118. //
  119. pHeap->AllocMem += allocSize;
  120. pHeap->CurrentMem += allocSize;
  121. pHeap->AllocCount++;
  122. pHeap->CurrentCount++;
  123. //
  124. // fill in header
  125. //
  126. h->HeapCodeBegin = HEAP_CODE;
  127. h->AllocCount = pHeap->AllocCount;
  128. h->AllocSize = allocSize;
  129. h->RequestSize = iSize;
  130. h->LineNo = dwLine;
  131. h->FileName = pszFile;
  132. #if 0
  133. allocSize = strlen(pszFile) - HEAP_HEADER_FILE_SIZE;
  134. if ( allocSize > 0 )
  135. {
  136. pszFile = &pszFile[ allocSize ];
  137. }
  138. strncpy(
  139. h->FileName,
  140. pszFile,
  141. HEAP_HEADER_FILE_SIZE );
  142. #endif
  143. h->AllocTime = GetCurrentTime();
  144. h->CurrentMem = pHeap->CurrentMem;
  145. h->CurrentCount = pHeap->CurrentCount;
  146. h->HeapCodeEnd = HEAP_CODE_ACTIVE;
  147. //
  148. // fill in trailer
  149. //
  150. t = HEAP_TRAILER( h );
  151. t->HeapCodeBegin = h->HeapCodeBegin;
  152. t->AllocCount = h->AllocCount;
  153. t->AllocSize = h->AllocSize;
  154. t->HeapCodeEnd = h->HeapCodeEnd;
  155. //
  156. // attach to alloc list
  157. //
  158. LOCK_HEAP(pHeap);
  159. InsertTailList( &pHeap->ListHead, &h->ListEntry );
  160. UNLOCK_HEAP(pHeap);
  161. //
  162. // return ptr to user memory
  163. // - first byte past header
  164. //
  165. return( h+1 );
  166. }
  167. PHEAP_HEADER
  168. DbgHeapSetHeaderFree(
  169. IN OUT PHEAP_BLOB pHeap,
  170. IN OUT PVOID pMem
  171. )
  172. /*++
  173. Routine Description:
  174. Resets heap globals and heap header info for free.
  175. Arguments:
  176. pMem - ptr to user memory to free
  177. Return Value:
  178. Ptr to block to be freed.
  179. --*/
  180. {
  181. register PHEAP_HEADER h;
  182. //
  183. // validate memory block -- get ptr to header
  184. //
  185. h = Dns_DbgHeapValidateMemory( pMem, TRUE );
  186. //
  187. // get blob if not passed in
  188. //
  189. if ( !pHeap )
  190. {
  191. pHeap = h->pHeap;
  192. }
  193. //
  194. // remove from current allocs list
  195. //
  196. LOCK_HEAP(pHeap);
  197. RemoveEntryList( &h->ListEntry );
  198. UNLOCK_HEAP(pHeap);
  199. //
  200. // update heap info globals
  201. //
  202. pHeap->CurrentMem -= h->AllocSize;
  203. pHeap->FreeMem += h->AllocSize;
  204. pHeap->FreeCount++;
  205. pHeap->CurrentCount--;
  206. //
  207. // reset header
  208. //
  209. h->HeapCodeEnd = HEAP_CODE_FREE;
  210. HEAP_TRAILER(h)->HeapCodeBegin = HEAP_CODE_FREE;
  211. //
  212. // return ptr to block to be freed
  213. //
  214. return( h );
  215. }
  216. //
  217. // Heap Init\Cleanup
  218. //
  219. DNS_STATUS
  220. Dns_HeapInitialize(
  221. OUT PHEAP_BLOB pHeap,
  222. IN HANDLE hHeap,
  223. IN DWORD dwCreateFlags,
  224. IN BOOL fUseHeaders,
  225. IN BOOL fResetDnslib,
  226. IN BOOL fFullHeapChecks,
  227. IN DWORD dwException,
  228. IN DWORD dwDefaultFlags,
  229. IN PSTR pszDefaultFileName,
  230. IN DWORD dwDefaultFileLine
  231. )
  232. /*++
  233. Routine Description:
  234. Initialize heap debugging.
  235. MUST call this routine before using DbgHeapMessage routines.
  236. Arguments:
  237. pHeap -- heap blob to setup
  238. hHeap -- heap to use
  239. dwCreateFlags -- flags to RtlCreateHeap() if creating
  240. fUseHeaders -- use headers and trailers for full debug
  241. fResetDnslib -- reset dnslib heap to use these routines
  242. fFullHeapChecks -- flag, TRUE for full heap checks
  243. dwException -- exception to raise if out of heap
  244. dwDefaultFlags -- heap flags for simple alloc\free
  245. pszDefaultFileName -- file name for simple alloc\free
  246. dwDefaultFileLine -- file line# for simple alloc\free
  247. Return Value:
  248. None.
  249. --*/
  250. {
  251. DNSDBG( TRACE, (
  252. "Dns_DbgHeapInit( %p )\n",
  253. pHeap ));
  254. //
  255. // zero heap blob
  256. //
  257. RtlZeroMemory(
  258. pHeap,
  259. sizeof(*pHeap) );
  260. // alloc list
  261. // - alloc list head
  262. // - critical section to protect list operations
  263. InitializeListHead( &pHeap->ListHead );
  264. if ( fUseHeaders )
  265. {
  266. DNS_STATUS status = RtlInitializeCriticalSection( &pHeap->ListCs );
  267. if ( status != NO_ERROR )
  268. {
  269. return status;
  270. }
  271. }
  272. //
  273. // heap
  274. // can either
  275. // - always get heap in each call
  276. // - use heap caller supplies here
  277. // - create a heap here
  278. //
  279. // to use simple dnslib compatible calls we must have
  280. // a known heap, so must get one created here
  281. // DCR: not sure this is TRUE, process heap may work
  282. // g_hDnsHeap left NULL
  283. //
  284. if ( hHeap )
  285. {
  286. pHeap->hHeap = hHeap;
  287. }
  288. else
  289. {
  290. pHeap->hHeap = RtlCreateHeap(
  291. dwCreateFlags
  292. ? dwCreateFlags
  293. : HEAP_DBG_DEFAULT_CREATE_FLAGS,
  294. NULL, // no base specified
  295. 0, // default reserve size
  296. 0, // default commit size
  297. NULL, // no lock
  298. NULL // no parameters
  299. );
  300. if ( !pHeap->hHeap )
  301. {
  302. return DNS_ERROR_NO_MEMORY;
  303. }
  304. pHeap->fCreated = TRUE;
  305. }
  306. pHeap->Tag = HEAP_CODE_ACTIVE;
  307. // set globals
  308. // - full heap checks before all heap operations?
  309. // - raise exception on alloc failure?
  310. pHeap->fHeaders = fUseHeaders;
  311. pHeap->fCheckAll = fFullHeapChecks;
  312. pHeap->FailureException = dwException;
  313. // set globals for simple allocator
  314. pHeap->DefaultFlags = dwDefaultFlags;
  315. pHeap->pszDefaultFile = pszDefaultFileName;
  316. pHeap->DefaultLine = dwDefaultFileLine;
  317. // reset dnslib heap routines to use debug heap
  318. if ( fResetDnslib )
  319. {
  320. if ( fUseHeaders )
  321. {
  322. Dns_LibHeapReset(
  323. Dns_DbgHeapAlloc,
  324. Dns_DbgHeapRealloc,
  325. Dns_DbgHeapFree );
  326. }
  327. else
  328. {
  329. Dns_LibHeapReset(
  330. Dns_HeapAlloc,
  331. Dns_HeapRealloc,
  332. Dns_HeapFree );
  333. }
  334. g_pDnslibHeapBlob = pHeap;
  335. }
  336. return NO_ERROR;
  337. }
  338. VOID
  339. Dns_HeapCleanup(
  340. IN OUT PHEAP_BLOB pHeap
  341. )
  342. /*++
  343. Routine Description:
  344. Cleanup.
  345. Arguments:
  346. None.
  347. Return Value:
  348. None.
  349. --*/
  350. {
  351. DNSDBG( TRACE, ( "Dns_HeapCleanup( %p )\n", pHeap ));
  352. // if not initialized -- do nothing
  353. if ( !pHeap )
  354. {
  355. return;
  356. }
  357. if ( pHeap->Tag != HEAP_CODE_ACTIVE )
  358. {
  359. DNS_ASSERT( pHeap->Tag == HEAP_CODE_ACTIVE );
  360. return;
  361. }
  362. DNS_ASSERT( pHeap->hHeap );
  363. // if created heap, destroy it
  364. if ( pHeap->fCreated )
  365. {
  366. RtlDestroyHeap( pHeap->hHeap );
  367. }
  368. // cleanup critical section
  369. if ( pHeap->fHeaders )
  370. {
  371. RtlDeleteCriticalSection( &pHeap->ListCs );
  372. }
  373. // tag as invalid
  374. pHeap->Tag = HEAP_CODE_FREE;
  375. }
  376. //
  377. // Heap Validation
  378. //
  379. VOID
  380. DbgHeapValidateHeader(
  381. IN PHEAP_HEADER h
  382. )
  383. /*++
  384. Routine Description:
  385. Validates heap header.
  386. Arguments:
  387. h - ptr to header of block
  388. Return Value:
  389. None.
  390. --*/
  391. {
  392. register PHEAP_TRAILER t;
  393. //
  394. // extract trailer
  395. //
  396. t = HEAP_TRAILER( h );
  397. //
  398. // verify header
  399. //
  400. if ( h->HeapCodeBegin != HEAP_CODE
  401. ||
  402. h->HeapCodeEnd != HEAP_CODE_ACTIVE )
  403. {
  404. DNSDBG( HEAPDBG, (
  405. "Invalid memory block at %p -- invalid header.\n",
  406. h ));
  407. if ( h->HeapCodeEnd == HEAP_CODE_FREE )
  408. {
  409. DNSDBG( HEAPDBG, (
  410. "ERROR: Previous freed memory.\n" ));
  411. }
  412. goto Invalid;
  413. }
  414. //
  415. // match header, trailer alloc number
  416. //
  417. if ( h->HeapCodeBegin != t->HeapCodeBegin
  418. ||
  419. h->AllocCount != t->AllocCount
  420. ||
  421. h->AllocSize != t->AllocSize
  422. ||
  423. h->HeapCodeEnd != t->HeapCodeEnd )
  424. {
  425. DNSDBG( HEAPDBG, (
  426. "Invalid memory block at %p -- header / trailer mismatch.\n",
  427. h ));
  428. goto Invalid;
  429. }
  430. return;
  431. Invalid:
  432. DNSDBG( ANY, (
  433. "Validation failure, in heap blob %p\n",
  434. h->pHeap ));
  435. Dns_DbgHeapHeaderPrint( h, t );
  436. ASSERT( FALSE );
  437. Dns_DbgHeapGlobalInfoPrint( h->pHeap );
  438. Dns_DbgHeapDumpAllocList( h->pHeap );
  439. ASSERT( FALSE );
  440. return;
  441. }
  442. PHEAP_HEADER
  443. Dns_DbgHeapValidateMemory(
  444. IN PVOID pMem,
  445. IN BOOL fAtHeader
  446. )
  447. /*++
  448. Routine Description:
  449. Validates users heap pointer, and returns actual.
  450. Note: This memory MUST have been allocated by THESE MEMORY routines.
  451. Arguments:
  452. pMem - ptr to memory to validate
  453. fAtHeader - TRUE if pMem is known to be immediately after a head header,
  454. otherwise this function will search backwards through memory starting
  455. at pMem looking for a valid heap header
  456. Return Value:
  457. Pointer to actual heap pointer.
  458. --*/
  459. {
  460. register PHEAP_HEADER pheader;
  461. //
  462. // Get pointer to heap header.
  463. //
  464. pheader = (PHEAP_HEADER) pMem - 1;
  465. if ( !fAtHeader )
  466. {
  467. int iterations = 32 * 1024;
  468. //
  469. // Back up from pMem a DWORD at a time looking for HEAP_CODE.
  470. // If we don't find one, eventually we will generate an exception,
  471. // which will be interesting. This could be handled, but for now
  472. // this loop will just walk to past the start of valid memory.
  473. //
  474. while ( 1 )
  475. {
  476. //
  477. // Break if we've found the heap header.
  478. //
  479. if ( pheader->HeapCodeBegin == HEAP_CODE &&
  480. ( pheader->HeapCodeEnd == HEAP_CODE_ACTIVE ||
  481. pheader->HeapCodeEnd == HEAP_CODE_FREE ) )
  482. {
  483. break;
  484. }
  485. //
  486. // Sanity check: too many iterations?
  487. //
  488. if ( ( --iterations ) == 0 )
  489. {
  490. ASSERT( iterations > 0 );
  491. return NULL;
  492. }
  493. //
  494. // Back up another DWORD.
  495. //
  496. pheader = ( PHEAP_HEADER ) ( ( PBYTE ) pheader - 4 );
  497. }
  498. }
  499. //
  500. // Verify header and trailer.
  501. //
  502. DbgHeapValidateHeader( pheader );
  503. return pheader;
  504. }
  505. VOID
  506. Dns_DbgHeapValidateAllocList(
  507. IN OUT PHEAP_BLOB pHeap
  508. )
  509. /*++
  510. Routine Description:
  511. Dumps header information for all nodes in alloc list.
  512. Arguments:
  513. None
  514. Return Value:
  515. None
  516. --*/
  517. {
  518. PLIST_ENTRY pentry;
  519. DNSDBG( TRACE, (
  520. "Dns_DbgHeapValidateAllocList( %p )\n",
  521. pHeap ));
  522. if ( !pHeap->fHeaders )
  523. {
  524. DNS_ASSERT( pHeap->fHeaders );
  525. return;
  526. }
  527. //
  528. // loop through all outstanding alloc's, validating each one
  529. //
  530. LOCK_HEAP(pHeap);
  531. pentry = pHeap->ListHead.Flink;
  532. while( pentry != &pHeap->ListHead )
  533. {
  534. DbgHeapValidateHeader( HEAP_HEADER_FROM_LIST_ENTRY(pentry) );
  535. pentry = pentry->Flink;
  536. }
  537. UNLOCK_HEAP(pHeap);
  538. }
  539. //
  540. // Heap Printing
  541. //
  542. VOID
  543. Dns_DbgHeapGlobalInfoPrint(
  544. IN PHEAP_BLOB pHeap
  545. )
  546. /*++
  547. Routine Description:
  548. Prints global heap info.
  549. Arguments:
  550. None
  551. Return Value:
  552. None
  553. --*/
  554. {
  555. DNS_PRINT((
  556. "Debug Heap Information:\n"
  557. "\tHeap Blob = %p\n"
  558. "\tHandle = %p\n"
  559. "\tDebug headers = %d\n"
  560. "\tDnslib redirect = %d\n"
  561. "\tFull checks = %d\n"
  562. "\tFlags = %08x\n"
  563. "\tStats ---------------\n"
  564. "\tMemory Allocated = %d\n"
  565. "\tMemory Freed = %d\n"
  566. "\tMemory Current = %d\n"
  567. "\tAlloc Count = %d\n"
  568. "\tFree Count = %d\n"
  569. "\tCurrent Count = %d\n",
  570. pHeap,
  571. pHeap->hHeap,
  572. pHeap->fHeaders,
  573. pHeap->fDnsLib,
  574. pHeap->fCheckAll,
  575. pHeap->DefaultFlags,
  576. pHeap->AllocMem,
  577. pHeap->FreeMem,
  578. pHeap->CurrentMem,
  579. pHeap->AllocCount,
  580. pHeap->FreeCount,
  581. pHeap->CurrentCount
  582. ));
  583. }
  584. VOID
  585. Dns_DbgHeapHeaderPrint(
  586. IN PHEAP_HEADER h,
  587. IN PHEAP_TRAILER t
  588. )
  589. /*++
  590. Routine Description:
  591. Prints heap header and trailer.
  592. Arguments:
  593. None
  594. Return Value:
  595. None
  596. --*/
  597. {
  598. if ( h )
  599. {
  600. DNSDBG( HEAPDBG, (
  601. "Heap Header at %p:\n"
  602. "\tHeapCodeBegin = %08lx\n"
  603. "\tAllocCount = %d\n"
  604. "\tAllocSize = %d\n"
  605. "\tRequestSize = %d\n"
  606. "\tHeapBlob = %p\n"
  607. "\tFileName = %s\n"
  608. "\tLineNo = %d\n"
  609. "\tAllocTime = %d\n"
  610. "\tCurrentMem = %d\n"
  611. "\tCurrentCount = %d\n"
  612. "\tHeapCodeEnd = %08lx\n",
  613. h,
  614. h->HeapCodeBegin,
  615. h->AllocCount,
  616. h->AllocSize,
  617. h->RequestSize,
  618. h->pHeap,
  619. h->FileName,
  620. h->LineNo,
  621. h->AllocTime / 1000,
  622. h->CurrentMem,
  623. h->CurrentCount,
  624. h->HeapCodeEnd
  625. ));
  626. }
  627. if ( t )
  628. {
  629. DNSDBG( HEAPDBG, (
  630. "Heap Trailer at %p:\n"
  631. "\tHeapCodeBegin = %08lx\n"
  632. "\tAllocCount = %d\n"
  633. "\tAllocSize = %d\n"
  634. "\tHeapCodeEnd = %08lx\n",
  635. t,
  636. t->HeapCodeBegin,
  637. t->AllocCount,
  638. t->AllocSize,
  639. t->HeapCodeEnd
  640. ));
  641. }
  642. }
  643. VOID
  644. Dns_DbgHeapDumpAllocList(
  645. IN PHEAP_BLOB pHeap
  646. )
  647. /*++
  648. Routine Description:
  649. Dumps header information for all nodes in alloc list.
  650. Arguments:
  651. None
  652. Return Value:
  653. None
  654. --*/
  655. {
  656. PLIST_ENTRY pentry;
  657. PHEAP_HEADER phead;
  658. if ( !pHeap->fHeaders )
  659. {
  660. DNSDBG( HEAPDBG, ( "Non-debug heap -- no alloc list!\n" ));
  661. return;
  662. }
  663. //
  664. // loop through all outstanding alloc's, dumping output
  665. //
  666. LOCK_HEAP(pHeap);
  667. DNSDBG( HEAPDBG, ( "Dumping Alloc List:\n" ));
  668. pentry = pHeap->ListHead.Flink;
  669. while( pentry != &pHeap->ListHead )
  670. {
  671. phead = HEAP_HEADER_FROM_LIST_ENTRY( pentry );
  672. Dns_DbgHeapHeaderPrint(
  673. phead,
  674. HEAP_TRAILER( phead )
  675. );
  676. pentry = pentry->Flink;
  677. }
  678. DNSDBG( HEAPDBG, ( "End Dump of Alloc List.\n" ));
  679. UNLOCK_HEAP(pHeap);
  680. }
  681. //
  682. // Full debug heap routines
  683. //
  684. PVOID
  685. Dns_DbgHeapAllocEx(
  686. IN OUT PHEAP_BLOB pHeap,
  687. IN DWORD dwFlags,
  688. IN INT iSize,
  689. IN LPSTR pszFile,
  690. IN DWORD dwLine
  691. )
  692. /*++
  693. Routine Description:
  694. Allocates memory.
  695. Arguments:
  696. iSize - number of bytes to allocate
  697. Return Value:
  698. Pointer to memory allocated.
  699. NULL if allocation fails.
  700. --*/
  701. {
  702. register PHEAP_HEADER h;
  703. INT allocSize;
  704. DNSDBG( HEAP2, (
  705. "Dns_DbgHeapAlloc( %p, %d )\n",
  706. pHeap, iSize ));
  707. //
  708. // full heap check?
  709. //
  710. IF_DNSDBG( HEAP_CHECK )
  711. {
  712. Dns_DbgHeapValidateAllocList( pHeap );
  713. }
  714. if ( iSize <= 0 )
  715. {
  716. DNSDBG( ANY, ( "Invalid alloc size = %d\n", iSize ));
  717. DNS_ASSERT( FALSE );
  718. return( NULL );
  719. }
  720. //
  721. // allocate memory
  722. //
  723. // first add heap header to size
  724. //
  725. allocSize = DbgHeapFindAllocSize( iSize );
  726. h = (PHEAP_HEADER) RtlAllocateHeap(
  727. pHeap->hHeap,
  728. dwFlags
  729. ? dwFlags
  730. : pHeap->DefaultFlags,
  731. allocSize );
  732. if ( ! h )
  733. {
  734. Dns_DbgHeapGlobalInfoPrint( pHeap );
  735. return NULL;
  736. }
  737. //
  738. // setup header / globals for new alloc
  739. //
  740. // return ptr to first byte after header
  741. //
  742. return DbgHeapSetHeaderAlloc(
  743. pHeap,
  744. h,
  745. iSize,
  746. pszFile,
  747. dwLine
  748. );
  749. }
  750. PVOID
  751. Dns_DbgHeapReallocEx(
  752. IN OUT PHEAP_BLOB pHeap,
  753. IN DWORD dwFlags,
  754. IN OUT PVOID pMem,
  755. IN INT iSize,
  756. IN LPSTR pszFile,
  757. IN DWORD dwLine
  758. )
  759. /*++
  760. Routine Description:
  761. Reallocates memory
  762. Arguments:
  763. pMem - ptr to existing memory to reallocated
  764. iSize - number of bytes to reallocate
  765. Return Value:
  766. Pointer to memory allocated.
  767. NULL if allocation fails.
  768. --*/
  769. {
  770. register PHEAP_HEADER h;
  771. register PHEAP_HEADER pnew;
  772. INT previousSize;
  773. INT allocSize;
  774. //
  775. // full heap check?
  776. //
  777. IF_DNSDBG( HEAP_CHECK )
  778. {
  779. Dns_DbgHeapValidateAllocList( pHeap );
  780. }
  781. if ( iSize <= 0 )
  782. {
  783. DNSDBG( HEAPDBG, ( "Invalid realloc size = %d\n", iSize ));
  784. return( NULL );
  785. }
  786. //
  787. // validate memory
  788. //
  789. // extract pointer to actual alloc'd block
  790. // mark as free, and reset globals appropriately
  791. //
  792. h = DbgHeapSetHeaderFree( pHeap, pMem );
  793. //
  794. // reallocate memory
  795. //
  796. // first add heap header to size
  797. //
  798. allocSize = DbgHeapFindAllocSize( iSize );
  799. pnew = (PHEAP_HEADER) RtlReAllocateHeap(
  800. pHeap->hHeap,
  801. dwFlags
  802. ? dwFlags
  803. : pHeap->DefaultFlags,
  804. h,
  805. allocSize );
  806. if ( ! pnew )
  807. {
  808. Dns_DbgHeapGlobalInfoPrint( pHeap );
  809. return( NULL );
  810. }
  811. //
  812. // setup header / globals for realloc
  813. //
  814. // return ptr to first byte after header
  815. //
  816. return DbgHeapSetHeaderAlloc(
  817. pHeap,
  818. pnew,
  819. iSize,
  820. pszFile,
  821. dwLine
  822. );
  823. }
  824. VOID
  825. Dns_DbgHeapFreeEx(
  826. IN OUT PHEAP_BLOB pHeap,
  827. IN DWORD dwFlags,
  828. IN OUT PVOID pMem
  829. )
  830. /*++
  831. Routine Description:
  832. Frees memory
  833. Note: This memory MUST have been allocated by DbgHeap routines.
  834. Arguments:
  835. pMem - ptr to memory to be freed
  836. Return Value:
  837. None.
  838. --*/
  839. {
  840. register PHEAP_HEADER h;
  841. DNSDBG( HEAP2, (
  842. "Dns_DbgHeapFreeEx( %p, %p )\n",
  843. pHeap, pMem ));
  844. //
  845. // validate header
  846. //
  847. // reset heap header / globals for free
  848. //
  849. h = DbgHeapSetHeaderFree( pHeap, pMem );
  850. //
  851. // get blob
  852. //
  853. if ( !pHeap )
  854. {
  855. pHeap = h->pHeap;
  856. }
  857. //
  858. // full heap check?
  859. //
  860. IF_DNSDBG( HEAP_CHECK )
  861. {
  862. Dns_DbgHeapValidateAllocList( pHeap );
  863. }
  864. RtlFreeHeap(
  865. pHeap->hHeap,
  866. dwFlags
  867. ? dwFlags
  868. : pHeap->DefaultFlags,
  869. h );
  870. }
  871. //
  872. // Dnslib memory compatible versions
  873. //
  874. // Heap routines with simple function signature that matches
  875. // the dnslib routines and allows DnsLib memory routines to
  876. // be redirected to these routines through Dns_LibHeapReset().
  877. //
  878. // Note: to use these functions, must have specified at particular
  879. // heap to use.
  880. //
  881. PVOID
  882. Dns_DbgHeapAlloc(
  883. IN INT iSize
  884. )
  885. {
  886. return Dns_DbgHeapAllocEx(
  887. g_pDnslibHeapBlob,
  888. 0,
  889. iSize,
  890. NULL,
  891. 0 );
  892. }
  893. PVOID
  894. Dns_DbgHeapRealloc(
  895. IN OUT PVOID pMem,
  896. IN INT iSize
  897. )
  898. {
  899. return Dns_DbgHeapReallocEx(
  900. g_pDnslibHeapBlob,
  901. 0,
  902. pMem,
  903. iSize,
  904. NULL,
  905. 0
  906. );
  907. }
  908. VOID
  909. Dns_DbgHeapFree(
  910. IN OUT PVOID pMem
  911. )
  912. {
  913. Dns_DbgHeapFreeEx(
  914. g_pDnslibHeapBlob,
  915. 0,
  916. pMem );
  917. }
  918. //
  919. // Non debug header versions
  920. //
  921. // These allow you to use a private heap with some of the features
  922. // of the debug heap
  923. // - same initialization
  924. // - specifying individual heap
  925. // - redirection of dnslib (without building your own routines)
  926. // - alloc and free counts
  927. // but without the overhead of the headers.
  928. //
  929. PVOID
  930. Dns_HeapAllocEx(
  931. IN OUT PHEAP_BLOB pHeap,
  932. IN DWORD dwFlags,
  933. IN INT iSize
  934. )
  935. /*++
  936. Routine Description:
  937. Allocates memory.
  938. Arguments:
  939. pHeap - heap to use
  940. dwFlags - flags
  941. iSize - number of bytes to allocate
  942. Return Value:
  943. Pointer to memory allocated.
  944. NULL if allocation fails.
  945. --*/
  946. {
  947. PVOID p;
  948. DNSDBG( HEAP2, (
  949. "Dns_HeapAlloc( %p, %d )\n",
  950. pHeap, iSize ));
  951. //
  952. // allocate memory
  953. //
  954. p = (PHEAP_HEADER) RtlAllocateHeap(
  955. pHeap->hHeap,
  956. dwFlags
  957. ? dwFlags
  958. : pHeap->DefaultFlags,
  959. iSize );
  960. if ( p )
  961. {
  962. pHeap->AllocCount++;
  963. pHeap->CurrentCount++;
  964. }
  965. return p;
  966. }
  967. PVOID
  968. Dns_HeapReallocEx(
  969. IN OUT PHEAP_BLOB pHeap,
  970. IN DWORD dwFlags,
  971. IN OUT PVOID pMem,
  972. IN INT iSize
  973. )
  974. /*++
  975. Routine Description:
  976. Reallocates memory
  977. Arguments:
  978. pMem - ptr to existing memory to reallocated
  979. iSize - number of bytes to reallocate
  980. Return Value:
  981. Pointer to memory allocated.
  982. NULL if allocation fails.
  983. --*/
  984. {
  985. PVOID p;
  986. INT previousSize;
  987. INT allocSize;
  988. //
  989. // reallocate memory
  990. //
  991. // first add heap header to size
  992. //
  993. p = RtlReAllocateHeap(
  994. pHeap->hHeap,
  995. dwFlags
  996. ? dwFlags
  997. : pHeap->DefaultFlags,
  998. pMem,
  999. iSize );
  1000. if ( p )
  1001. {
  1002. pHeap->AllocCount++;
  1003. pHeap->FreeCount++;
  1004. }
  1005. return p;
  1006. }
  1007. VOID
  1008. Dns_HeapFreeEx(
  1009. IN OUT PHEAP_BLOB pHeap,
  1010. IN DWORD dwFlags,
  1011. IN OUT PVOID pMem
  1012. )
  1013. /*++
  1014. Routine Description:
  1015. Frees memory
  1016. Note: This memory MUST have been allocated by DbgHeap routines.
  1017. Arguments:
  1018. pMem - ptr to memory to be freed
  1019. Return Value:
  1020. None.
  1021. --*/
  1022. {
  1023. DNSDBG( HEAP2, (
  1024. "Dns_HeapFreeEx( %p, %p )\n",
  1025. pHeap, pMem ));
  1026. RtlFreeHeap(
  1027. pHeap->hHeap,
  1028. dwFlags
  1029. ? dwFlags
  1030. : pHeap->DefaultFlags,
  1031. pMem );
  1032. pHeap->FreeCount++;
  1033. pHeap->CurrentCount--;
  1034. }
  1035. //
  1036. // Dnslib memory compatible versions
  1037. //
  1038. // Heap routines with simple function signature that matches
  1039. // the dnslib routines and allows DnsLib memory routines to
  1040. // be redirected to these routines through Dns_LibHeapReset().
  1041. //
  1042. // Note: to use these functions, must have specified at particular
  1043. // heap to use.
  1044. //
  1045. PVOID
  1046. Dns_HeapAlloc(
  1047. IN INT iSize
  1048. )
  1049. {
  1050. return Dns_HeapAllocEx(
  1051. g_pDnslibHeapBlob,
  1052. 0,
  1053. iSize );
  1054. }
  1055. PVOID
  1056. Dns_HeapRealloc(
  1057. IN OUT PVOID pMem,
  1058. IN INT iSize
  1059. )
  1060. {
  1061. return Dns_HeapReallocEx(
  1062. g_pDnslibHeapBlob,
  1063. 0,
  1064. pMem,
  1065. iSize );
  1066. }
  1067. VOID
  1068. Dns_HeapFree(
  1069. IN OUT PVOID pMem
  1070. )
  1071. {
  1072. Dns_HeapFreeEx(
  1073. g_pDnslibHeapBlob,
  1074. 0,
  1075. pMem );
  1076. }
  1077. //
  1078. // End heapdbg.c
  1079. //