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.

1026 lines
25 KiB

  1. /*++
  2. Copyright (c) 1990 Microsoft Corporation
  3. Module Name:
  4. lmem.c
  5. Abstract:
  6. This module contains the Win32 Local Memory Management APIs
  7. Author:
  8. Steve Wood (stevewo) 24-Sep-1990
  9. Revision History:
  10. --*/
  11. #include "basedll.h"
  12. void
  13. BaseDllInitializeMemoryManager( VOID )
  14. {
  15. BaseHeap = RtlProcessHeap();
  16. RtlInitializeHandleTable( 0xFFFF,
  17. sizeof( BASE_HANDLE_TABLE_ENTRY ),
  18. &BaseHeapHandleTable
  19. );
  20. NtQuerySystemInformation(SystemRangeStartInformation,
  21. &SystemRangeStart,
  22. sizeof(SystemRangeStart),
  23. NULL);
  24. }
  25. #if i386
  26. #pragma optimize("y",off)
  27. #endif
  28. HLOCAL
  29. WINAPI
  30. LocalAlloc(
  31. UINT uFlags,
  32. SIZE_T uBytes
  33. )
  34. {
  35. PBASE_HANDLE_TABLE_ENTRY HandleEntry;
  36. HANDLE hMem;
  37. ULONG Flags;
  38. LPSTR p;
  39. if (uFlags & ~LMEM_VALID_FLAGS) {
  40. SetLastError( ERROR_INVALID_PARAMETER );
  41. return( NULL );
  42. }
  43. Flags = 0;
  44. if (uFlags & LMEM_ZEROINIT) {
  45. Flags |= HEAP_ZERO_MEMORY;
  46. }
  47. if (!(uFlags & LMEM_MOVEABLE)) {
  48. p = RtlAllocateHeap( BaseHeap,
  49. MAKE_TAG( LMEM_TAG ) | Flags,
  50. uBytes
  51. );
  52. if (p == NULL) {
  53. SetLastError( ERROR_NOT_ENOUGH_MEMORY );
  54. }
  55. return( p );
  56. }
  57. RtlLockHeap( BaseHeap );
  58. Flags |= HEAP_NO_SERIALIZE | HEAP_SETTABLE_USER_VALUE | BASE_HEAP_FLAG_MOVEABLE;
  59. try {
  60. p = NULL;
  61. HandleEntry = (PBASE_HANDLE_TABLE_ENTRY)RtlAllocateHandle( &BaseHeapHandleTable, NULL );
  62. if (HandleEntry == NULL) {
  63. SetLastError( ERROR_NOT_ENOUGH_MEMORY );
  64. goto Fail;
  65. }
  66. hMem = (HANDLE)&HandleEntry->Object;
  67. if (uBytes != 0) {
  68. p = (LPSTR)RtlAllocateHeap( BaseHeap, MAKE_TAG( LMEM_TAG ) | Flags, uBytes );
  69. if (p == NULL) {
  70. HandleEntry->Flags = RTL_HANDLE_ALLOCATED;
  71. RtlFreeHandle( &BaseHeapHandleTable, (PRTL_HANDLE_TABLE_ENTRY)HandleEntry );
  72. HandleEntry = NULL;
  73. SetLastError( ERROR_NOT_ENOUGH_MEMORY );
  74. }
  75. else {
  76. RtlSetUserValueHeap( BaseHeap, HEAP_NO_SERIALIZE, p, hMem );
  77. }
  78. }
  79. else {
  80. p = NULL;
  81. }
  82. Fail: ;
  83. }
  84. except (EXCEPTION_EXECUTE_HANDLER) {
  85. p = NULL;
  86. BaseSetLastNTError( GetExceptionCode() );
  87. }
  88. RtlUnlockHeap( BaseHeap );
  89. if (HandleEntry != NULL) {
  90. if (HandleEntry->Object = p) {
  91. HandleEntry->Flags = RTL_HANDLE_ALLOCATED;
  92. }
  93. else {
  94. HandleEntry->Flags = RTL_HANDLE_ALLOCATED | BASE_HANDLE_DISCARDED;
  95. }
  96. if (uFlags & LMEM_DISCARDABLE) {
  97. HandleEntry->Flags |= BASE_HANDLE_DISCARDABLE;
  98. }
  99. if (uFlags & LMEM_MOVEABLE) {
  100. HandleEntry->Flags |= BASE_HANDLE_MOVEABLE;
  101. }
  102. p = (LPSTR)hMem;
  103. }
  104. return( (HANDLE)p );
  105. }
  106. HLOCAL
  107. WINAPI
  108. LocalReAlloc(
  109. HLOCAL hMem,
  110. SIZE_T uBytes,
  111. UINT uFlags
  112. )
  113. {
  114. PBASE_HANDLE_TABLE_ENTRY HandleEntry;
  115. LPSTR p;
  116. ULONG Flags;
  117. if ((uFlags & ~(LMEM_VALID_FLAGS | LMEM_MODIFY)) ||
  118. ((uFlags & LMEM_DISCARDABLE) && !(uFlags & LMEM_MODIFY))
  119. ) {
  120. #if DBG
  121. DbgPrint( "*** LocalReAlloc( %lx ) - invalid flags\n", uFlags );
  122. BaseHeapBreakPoint();
  123. #endif
  124. SetLastError( ERROR_INVALID_PARAMETER );
  125. return( NULL );
  126. }
  127. Flags = 0;
  128. if (uFlags & LMEM_ZEROINIT) {
  129. Flags |= HEAP_ZERO_MEMORY;
  130. }
  131. if (!(uFlags & LMEM_MOVEABLE)) {
  132. Flags |= HEAP_REALLOC_IN_PLACE_ONLY;
  133. }
  134. RtlLockHeap( BaseHeap );
  135. Flags |= HEAP_NO_SERIALIZE;
  136. try {
  137. if ((ULONG_PTR)hMem & BASE_HANDLE_MARK_BIT) {
  138. HandleEntry = (PBASE_HANDLE_TABLE_ENTRY)
  139. CONTAINING_RECORD( hMem, BASE_HANDLE_TABLE_ENTRY, Object );
  140. if (!RtlIsValidHandle( &BaseHeapHandleTable, (PRTL_HANDLE_TABLE_ENTRY)HandleEntry )) {
  141. #if DBG
  142. DbgPrint( "*** LocalReAlloc( %lx ) - invalid handle\n", hMem );
  143. BaseHeapBreakPoint();
  144. #endif
  145. SetLastError( ERROR_INVALID_HANDLE );
  146. hMem = NULL;
  147. }
  148. else
  149. if (uFlags & LMEM_MODIFY) {
  150. if (uFlags & LMEM_DISCARDABLE) {
  151. HandleEntry->Flags |= BASE_HANDLE_DISCARDABLE;
  152. }
  153. else {
  154. HandleEntry->Flags &= ~BASE_HANDLE_DISCARDABLE;
  155. }
  156. }
  157. else {
  158. p = HandleEntry->Object;
  159. if (uBytes == 0) {
  160. hMem = NULL;
  161. if (p != NULL) {
  162. if ((uFlags & LMEM_MOVEABLE) && HandleEntry->LockCount == 0) {
  163. if (RtlFreeHeap( BaseHeap, Flags | HEAP_NO_SERIALIZE, p )) {
  164. HandleEntry->Object = NULL;
  165. HandleEntry->Flags |= BASE_HANDLE_DISCARDED;
  166. hMem = (HANDLE)&HandleEntry->Object;
  167. }
  168. }
  169. else {
  170. #if DBG
  171. DbgPrint( "*** LocalReAlloc( %lx ) - failing with locked handle\n", &HandleEntry->Object );
  172. BaseHeapBreakPoint();
  173. #endif
  174. }
  175. }
  176. else {
  177. hMem = (HANDLE)&HandleEntry->Object;
  178. }
  179. }
  180. else {
  181. Flags |= HEAP_SETTABLE_USER_VALUE | BASE_HEAP_FLAG_MOVEABLE;
  182. if (p == NULL) {
  183. p = RtlAllocateHeap( BaseHeap, MAKE_TAG( LMEM_TAG ) | Flags, uBytes );
  184. if (p != NULL) {
  185. RtlSetUserValueHeap( BaseHeap, HEAP_NO_SERIALIZE, p, hMem );
  186. }
  187. }
  188. else {
  189. if (!(uFlags & LMEM_MOVEABLE) &&
  190. HandleEntry->LockCount != 0
  191. ) {
  192. Flags |= HEAP_REALLOC_IN_PLACE_ONLY;
  193. }
  194. else {
  195. Flags &= ~HEAP_REALLOC_IN_PLACE_ONLY;
  196. }
  197. p = RtlReAllocateHeap( BaseHeap, MAKE_TAG( LMEM_TAG ) | Flags, p, uBytes );
  198. }
  199. if (p != NULL) {
  200. HandleEntry->Object = p;
  201. HandleEntry->Flags &= ~BASE_HANDLE_DISCARDED;
  202. }
  203. else {
  204. hMem = NULL;
  205. SetLastError( ERROR_NOT_ENOUGH_MEMORY );
  206. }
  207. }
  208. }
  209. }
  210. else
  211. if (!(uFlags & LMEM_MODIFY)) {
  212. hMem = RtlReAllocateHeap( BaseHeap, MAKE_TAG( LMEM_TAG ) | Flags, (PVOID)hMem, uBytes );
  213. if (hMem == NULL) {
  214. SetLastError( ERROR_NOT_ENOUGH_MEMORY );
  215. }
  216. }
  217. }
  218. except (EXCEPTION_EXECUTE_HANDLER) {
  219. hMem = NULL;
  220. BaseSetLastNTError( GetExceptionCode() );
  221. }
  222. RtlUnlockHeap( BaseHeap );
  223. return( (LPSTR)hMem );
  224. }
  225. PVOID
  226. WINAPI
  227. LocalLock(
  228. HLOCAL hMem
  229. )
  230. {
  231. PBASE_HANDLE_TABLE_ENTRY HandleEntry;
  232. LPSTR p;
  233. if ((ULONG_PTR)hMem & BASE_HANDLE_MARK_BIT) {
  234. RtlLockHeap( BaseHeap );
  235. try {
  236. HandleEntry = (PBASE_HANDLE_TABLE_ENTRY)
  237. CONTAINING_RECORD( hMem, BASE_HANDLE_TABLE_ENTRY, Object );
  238. if (!RtlIsValidHandle( &BaseHeapHandleTable, (PRTL_HANDLE_TABLE_ENTRY)HandleEntry )) {
  239. #if DBG
  240. DbgPrint( "*** LocalLock( %lx ) - invalid handle\n", hMem );
  241. BaseHeapBreakPoint();
  242. #endif
  243. SetLastError( ERROR_INVALID_HANDLE );
  244. p = NULL;
  245. }
  246. else {
  247. p = HandleEntry->Object;
  248. if (p != NULL) {
  249. if (HandleEntry->LockCount++ == LMEM_LOCKCOUNT) {
  250. HandleEntry->LockCount--;
  251. }
  252. }
  253. else {
  254. SetLastError( ERROR_DISCARDED );
  255. }
  256. }
  257. }
  258. except (EXCEPTION_EXECUTE_HANDLER) {
  259. p = NULL;
  260. BaseSetLastNTError( GetExceptionCode() );
  261. }
  262. RtlUnlockHeap( BaseHeap );
  263. return( p );
  264. }
  265. else {
  266. if ( (ULONG_PTR)hMem >= SystemRangeStart ) {
  267. return NULL;
  268. }
  269. return( (LPSTR)hMem );
  270. }
  271. }
  272. HLOCAL
  273. WINAPI
  274. LocalHandle(
  275. LPCVOID pMem
  276. )
  277. {
  278. HANDLE Handle;
  279. ULONG Flags;
  280. RtlLockHeap( BaseHeap );
  281. try {
  282. Handle = NULL;
  283. if (!RtlGetUserInfoHeap( BaseHeap, HEAP_NO_SERIALIZE, (LPVOID)pMem, &Handle, &Flags )) {
  284. SetLastError( ERROR_INVALID_HANDLE );
  285. }
  286. else
  287. if (Handle == NULL || !(Flags & BASE_HEAP_FLAG_MOVEABLE)) {
  288. Handle = (HANDLE)pMem;
  289. }
  290. }
  291. except (EXCEPTION_EXECUTE_HANDLER) {
  292. BaseSetLastNTError( GetExceptionCode() );
  293. }
  294. RtlUnlockHeap( BaseHeap );
  295. return( Handle );
  296. }
  297. BOOL
  298. WINAPI
  299. LocalUnlock(
  300. HLOCAL hMem
  301. )
  302. {
  303. PBASE_HANDLE_TABLE_ENTRY HandleEntry;
  304. BOOL Result;
  305. Result = FALSE;
  306. if ((ULONG_PTR)hMem & BASE_HANDLE_MARK_BIT) {
  307. RtlLockHeap( BaseHeap );
  308. try {
  309. HandleEntry = (PBASE_HANDLE_TABLE_ENTRY)
  310. CONTAINING_RECORD( hMem, BASE_HANDLE_TABLE_ENTRY, Object );
  311. if (!RtlIsValidHandle( &BaseHeapHandleTable, (PRTL_HANDLE_TABLE_ENTRY)HandleEntry )) {
  312. #if DBG
  313. DbgPrint( "*** LocalUnlock( %lx ) - invalid handle\n", hMem );
  314. BaseHeapBreakPoint();
  315. #endif
  316. SetLastError( ERROR_INVALID_HANDLE );
  317. }
  318. else
  319. if (HandleEntry->LockCount-- == 0) {
  320. HandleEntry->LockCount++;
  321. SetLastError( ERROR_NOT_LOCKED );
  322. }
  323. else
  324. if (HandleEntry->LockCount != 0) {
  325. Result = TRUE;
  326. }
  327. else {
  328. SetLastError( NO_ERROR );
  329. }
  330. }
  331. except (EXCEPTION_EXECUTE_HANDLER) {
  332. BaseSetLastNTError( GetExceptionCode() );
  333. }
  334. RtlUnlockHeap( BaseHeap );
  335. }
  336. else {
  337. SetLastError( ERROR_NOT_LOCKED );
  338. }
  339. return( Result );
  340. }
  341. SIZE_T
  342. WINAPI
  343. LocalSize(
  344. HLOCAL hMem
  345. )
  346. {
  347. PBASE_HANDLE_TABLE_ENTRY HandleEntry;
  348. PVOID Handle;
  349. ULONG Flags;
  350. SIZE_T uSize;
  351. uSize = MAXULONG_PTR;
  352. Flags = 0;
  353. RtlLockHeap( BaseHeap );
  354. try {
  355. if (!((ULONG_PTR)hMem & BASE_HANDLE_MARK_BIT)) {
  356. Handle = NULL;
  357. if (!RtlGetUserInfoHeap( BaseHeap, Flags, hMem, &Handle, &Flags )) {
  358. }
  359. else
  360. if (Handle == NULL || !(Flags & BASE_HEAP_FLAG_MOVEABLE)) {
  361. uSize = RtlSizeHeap( BaseHeap, HEAP_NO_SERIALIZE, (PVOID)hMem );
  362. }
  363. else {
  364. hMem = Handle;
  365. }
  366. }
  367. if ((ULONG_PTR)hMem & BASE_HANDLE_MARK_BIT) {
  368. HandleEntry = (PBASE_HANDLE_TABLE_ENTRY)
  369. CONTAINING_RECORD( hMem, BASE_HANDLE_TABLE_ENTRY, Object );
  370. if (!RtlIsValidHandle( &BaseHeapHandleTable, (PRTL_HANDLE_TABLE_ENTRY)HandleEntry )) {
  371. #if DBG
  372. DbgPrint( "*** LocalSize( %lx ) - invalid handle\n", hMem );
  373. BaseHeapBreakPoint();
  374. #endif
  375. SetLastError( ERROR_INVALID_HANDLE );
  376. }
  377. else
  378. if (HandleEntry->Flags & BASE_HANDLE_DISCARDED) {
  379. uSize = HandleEntry->Size;
  380. }
  381. else {
  382. uSize = RtlSizeHeap( BaseHeap, HEAP_NO_SERIALIZE, HandleEntry->Object );
  383. }
  384. }
  385. }
  386. except (EXCEPTION_EXECUTE_HANDLER) {
  387. BaseSetLastNTError( GetExceptionCode() );
  388. }
  389. RtlUnlockHeap( BaseHeap );
  390. if (uSize == MAXULONG_PTR) {
  391. SetLastError( ERROR_INVALID_HANDLE );
  392. return 0;
  393. }
  394. else {
  395. return uSize;
  396. }
  397. }
  398. UINT
  399. WINAPI
  400. LocalFlags(
  401. HLOCAL hMem
  402. )
  403. {
  404. PBASE_HANDLE_TABLE_ENTRY HandleEntry;
  405. HANDLE Handle;
  406. ULONG Flags;
  407. UINT uFlags;
  408. uFlags = LMEM_INVALID_HANDLE;
  409. RtlLockHeap( BaseHeap );
  410. try {
  411. if (!((ULONG_PTR)hMem & BASE_HANDLE_MARK_BIT)) {
  412. Handle = NULL;
  413. Flags = 0;
  414. if (!RtlGetUserInfoHeap( BaseHeap, Flags, hMem, &Handle, &Flags )) {
  415. }
  416. else
  417. if (Handle == NULL || !(Flags & BASE_HEAP_FLAG_MOVEABLE)) {
  418. uFlags = 0;
  419. }
  420. else {
  421. hMem = Handle;
  422. }
  423. }
  424. if ((ULONG_PTR)hMem & BASE_HANDLE_MARK_BIT) {
  425. HandleEntry = (PBASE_HANDLE_TABLE_ENTRY)
  426. CONTAINING_RECORD( hMem, BASE_HANDLE_TABLE_ENTRY, Object );
  427. if (RtlIsValidHandle( &BaseHeapHandleTable, (PRTL_HANDLE_TABLE_ENTRY)HandleEntry )) {
  428. uFlags = HandleEntry->LockCount & LMEM_LOCKCOUNT;
  429. if (HandleEntry->Flags & BASE_HANDLE_DISCARDED) {
  430. uFlags |= LMEM_DISCARDED;
  431. }
  432. if (HandleEntry->Flags & BASE_HANDLE_DISCARDABLE) {
  433. uFlags |= LMEM_DISCARDABLE;
  434. }
  435. }
  436. }
  437. if (uFlags == LMEM_INVALID_HANDLE) {
  438. #if DBG
  439. DbgPrint( "*** LocalFlags( %lx ) - invalid handle\n", hMem );
  440. BaseHeapBreakPoint();
  441. #endif
  442. SetLastError( ERROR_INVALID_HANDLE );
  443. }
  444. }
  445. except (EXCEPTION_EXECUTE_HANDLER) {
  446. BaseSetLastNTError( GetExceptionCode() );
  447. }
  448. RtlUnlockHeap( BaseHeap );
  449. return( uFlags );
  450. }
  451. HLOCAL
  452. WINAPI
  453. LocalFree(
  454. HLOCAL hMem
  455. )
  456. {
  457. PBASE_HANDLE_TABLE_ENTRY HandleEntry;
  458. LPSTR p;
  459. try {
  460. if (!((ULONG_PTR)hMem & BASE_HANDLE_MARK_BIT)) {
  461. if (RtlFreeHeap( BaseHeap,
  462. 0,
  463. (PVOID)hMem
  464. )
  465. ) {
  466. return NULL;
  467. }
  468. else {
  469. SetLastError( ERROR_INVALID_HANDLE );
  470. return hMem;
  471. }
  472. }
  473. }
  474. except (EXCEPTION_EXECUTE_HANDLER) {
  475. BaseSetLastNTError( GetExceptionCode() );
  476. return hMem;
  477. }
  478. RtlLockHeap( BaseHeap );
  479. try {
  480. if ((ULONG_PTR)hMem & BASE_HANDLE_MARK_BIT) {
  481. HandleEntry = (PBASE_HANDLE_TABLE_ENTRY)
  482. CONTAINING_RECORD( hMem, BASE_HANDLE_TABLE_ENTRY, Object );
  483. if (!RtlIsValidHandle( &BaseHeapHandleTable, (PRTL_HANDLE_TABLE_ENTRY)HandleEntry )) {
  484. #if DBG
  485. DbgPrint( "*** LocalFree( %lx ) - invalid handle\n", hMem );
  486. BaseHeapBreakPoint();
  487. #endif
  488. SetLastError( ERROR_INVALID_HANDLE );
  489. p = NULL;
  490. }
  491. else {
  492. #if DBG
  493. if (HandleEntry->LockCount != 0) {
  494. DbgPrint( "BASE: LocalFree called with a locked object.\n" );
  495. BaseHeapBreakPoint();
  496. }
  497. #endif
  498. p = HandleEntry->Object;
  499. RtlFreeHandle( &BaseHeapHandleTable, (PRTL_HANDLE_TABLE_ENTRY)HandleEntry );
  500. if (p == NULL) {
  501. hMem = NULL;
  502. }
  503. }
  504. }
  505. else {
  506. p = (LPSTR)hMem;
  507. }
  508. if (p != NULL) {
  509. if (RtlFreeHeap( BaseHeap, HEAP_NO_SERIALIZE, p )) {
  510. hMem = NULL;
  511. }
  512. else {
  513. SetLastError( ERROR_INVALID_HANDLE );
  514. }
  515. }
  516. }
  517. except (EXCEPTION_EXECUTE_HANDLER) {
  518. BaseSetLastNTError( GetExceptionCode() );
  519. }
  520. RtlUnlockHeap( BaseHeap );
  521. return( hMem );
  522. }
  523. SIZE_T
  524. WINAPI
  525. LocalCompact(
  526. UINT uMinFree
  527. )
  528. {
  529. return RtlCompactHeap( BaseHeap, 0 );
  530. }
  531. SIZE_T
  532. WINAPI
  533. LocalShrink(
  534. HLOCAL hMem,
  535. UINT cbNewSize
  536. )
  537. {
  538. return RtlCompactHeap( BaseHeap, 0 );
  539. }
  540. HANDLE
  541. WINAPI
  542. HeapCreate(
  543. DWORD flOptions,
  544. SIZE_T dwInitialSize,
  545. SIZE_T dwMaximumSize
  546. )
  547. {
  548. HANDLE hHeap;
  549. ULONG GrowthThreshold;
  550. ULONG Flags;
  551. Flags = (flOptions & (HEAP_GENERATE_EXCEPTIONS | HEAP_NO_SERIALIZE)) | HEAP_CLASS_1;
  552. GrowthThreshold = 0;
  553. if (dwMaximumSize < BASE_SYSINFO.PageSize) {
  554. if (dwMaximumSize == 0) {
  555. GrowthThreshold = BASE_SYSINFO.PageSize * 16;
  556. Flags |= HEAP_GROWABLE;
  557. }
  558. else {
  559. dwMaximumSize = BASE_SYSINFO.PageSize;
  560. }
  561. }
  562. if (GrowthThreshold == 0 && dwInitialSize > dwMaximumSize) {
  563. dwMaximumSize = dwInitialSize;
  564. }
  565. hHeap = (HANDLE)RtlCreateHeap( Flags,
  566. NULL,
  567. dwMaximumSize,
  568. dwInitialSize,
  569. 0,
  570. NULL
  571. );
  572. if (hHeap == NULL) {
  573. SetLastError( ERROR_NOT_ENOUGH_MEMORY );
  574. }
  575. return( hHeap );
  576. }
  577. BOOL
  578. WINAPI
  579. HeapDestroy(
  580. HANDLE hHeap
  581. )
  582. {
  583. if (RtlDestroyHeap( (PVOID)hHeap ) == NULL ) {
  584. return( TRUE );
  585. }
  586. else {
  587. SetLastError( ERROR_INVALID_HANDLE );
  588. return( FALSE );
  589. }
  590. }
  591. BOOL
  592. WINAPI
  593. HeapExtend(
  594. HANDLE hHeap,
  595. DWORD dwFlags,
  596. LPVOID lpBase,
  597. DWORD dwBytes
  598. )
  599. {
  600. NTSTATUS Status;
  601. Status = RtlExtendHeap( hHeap, dwFlags, lpBase, dwBytes );
  602. if (NT_SUCCESS( Status )) {
  603. return TRUE;
  604. }
  605. else {
  606. BaseSetLastNTError( Status );
  607. }
  608. return FALSE;
  609. }
  610. WINBASEAPI
  611. DWORD
  612. WINAPI
  613. HeapCreateTagsW(
  614. HANDLE hHeap,
  615. DWORD dwFlags,
  616. LPCWSTR lpTagPrefix,
  617. LPCWSTR lpTagNames
  618. )
  619. {
  620. return RtlCreateTagHeap( hHeap, dwFlags, (PWSTR)lpTagPrefix, (PWSTR)lpTagNames );
  621. }
  622. WINBASEAPI
  623. LPCWSTR
  624. WINAPI
  625. HeapQueryTagW(
  626. HANDLE hHeap,
  627. DWORD dwFlags,
  628. WORD wTagIndex,
  629. BOOL bResetCounters,
  630. LPHEAP_TAG_INFO TagInfo
  631. )
  632. {
  633. ASSERT( sizeof(RTL_HEAP_TAG_INFO) == sizeof(HEAP_TAG_INFO) );
  634. return RtlQueryTagHeap( hHeap,
  635. dwFlags,
  636. wTagIndex,
  637. (BOOLEAN)bResetCounters,
  638. (PRTL_HEAP_TAG_INFO)TagInfo
  639. );
  640. }
  641. BOOL
  642. WINAPI
  643. HeapSummary(
  644. HANDLE hHeap,
  645. DWORD dwFlags,
  646. LPHEAP_SUMMARY lpSummary
  647. )
  648. {
  649. NTSTATUS Status;
  650. RTL_HEAP_USAGE HeapInfo;
  651. if (lpSummary->cb != sizeof( *lpSummary )) {
  652. SetLastError( ERROR_INVALID_PARAMETER );
  653. return FALSE;
  654. }
  655. HeapInfo.Length = sizeof( HeapInfo );
  656. Status = RtlUsageHeap( hHeap,
  657. dwFlags & ~(HEAP_USAGE_ALLOCATED_BLOCKS |
  658. HEAP_USAGE_FREE_BUFFER
  659. ),
  660. &HeapInfo
  661. );
  662. if (NT_SUCCESS( Status )) {
  663. lpSummary->cbAllocated = HeapInfo.BytesAllocated;
  664. lpSummary->cbCommitted = HeapInfo.BytesCommitted;
  665. return TRUE;
  666. }
  667. else {
  668. BaseSetLastNTError( Status );
  669. return FALSE;
  670. }
  671. }
  672. BOOL
  673. WINAPI
  674. HeapUsage(
  675. HANDLE hHeap,
  676. DWORD dwFlags,
  677. BOOL bFirstCall,
  678. BOOL bLastCall,
  679. PHEAP_USAGE lpUsage
  680. )
  681. {
  682. NTSTATUS Status;
  683. if (lpUsage->cb != sizeof( *lpUsage ) || (bFirstCall & bLastCall)) {
  684. SetLastError( ERROR_INVALID_PARAMETER );
  685. return FALSE;
  686. }
  687. dwFlags &= ~(HEAP_USAGE_ALLOCATED_BLOCKS |
  688. HEAP_USAGE_FREE_BUFFER
  689. );
  690. if (bLastCall) {
  691. dwFlags |= HEAP_USAGE_FREE_BUFFER;
  692. }
  693. else {
  694. dwFlags |= HEAP_USAGE_ALLOCATED_BLOCKS;
  695. if (bFirstCall) {
  696. RtlZeroMemory( (&lpUsage->cb)+1, sizeof( *lpUsage ) - sizeof( lpUsage->cb ) );
  697. }
  698. }
  699. ASSERT( sizeof(RTL_HEAP_USAGE) == sizeof(HEAP_USAGE) );
  700. Status = RtlUsageHeap( hHeap, dwFlags, (PRTL_HEAP_USAGE)lpUsage );
  701. if (NT_SUCCESS( Status )) {
  702. if (Status == STATUS_MORE_ENTRIES) {
  703. return TRUE;
  704. }
  705. else {
  706. SetLastError( NO_ERROR );
  707. return FALSE;
  708. }
  709. }
  710. else {
  711. BaseSetLastNTError( Status );
  712. return FALSE;
  713. }
  714. }
  715. BOOL
  716. WINAPI
  717. HeapValidate(
  718. HANDLE hHeap,
  719. DWORD dwFlags,
  720. LPVOID lpMem
  721. )
  722. {
  723. return RtlValidateHeap( hHeap, dwFlags, lpMem );
  724. }
  725. HANDLE
  726. WINAPI
  727. GetProcessHeap( VOID )
  728. {
  729. return RtlProcessHeap();
  730. }
  731. WINBASEAPI
  732. DWORD
  733. WINAPI
  734. GetProcessHeaps(
  735. DWORD NumberOfHeaps,
  736. PHANDLE ProcessHeaps
  737. )
  738. {
  739. return RtlGetProcessHeaps( NumberOfHeaps, ProcessHeaps );
  740. }
  741. WINBASEAPI
  742. SIZE_T
  743. WINAPI
  744. HeapCompact(
  745. HANDLE hHeap,
  746. DWORD dwFlags
  747. )
  748. {
  749. return RtlCompactHeap( hHeap, dwFlags );
  750. }
  751. WINBASEAPI
  752. BOOL
  753. WINAPI
  754. HeapLock(
  755. HANDLE hHeap
  756. )
  757. {
  758. return RtlLockHeap( hHeap );
  759. }
  760. WINBASEAPI
  761. BOOL
  762. WINAPI
  763. HeapUnlock(
  764. HANDLE hHeap
  765. )
  766. {
  767. return RtlUnlockHeap( hHeap );
  768. }
  769. WINBASEAPI
  770. BOOL
  771. WINAPI
  772. HeapWalk(
  773. HANDLE hHeap,
  774. LPPROCESS_HEAP_ENTRY lpEntry
  775. )
  776. {
  777. RTL_HEAP_WALK_ENTRY Entry;
  778. NTSTATUS Status;
  779. if (lpEntry->lpData == NULL) {
  780. Entry.DataAddress = NULL;
  781. Status = RtlWalkHeap( hHeap, &Entry );
  782. }
  783. else {
  784. Entry.DataAddress = lpEntry->lpData;
  785. Entry.SegmentIndex = lpEntry->iRegionIndex;
  786. if (lpEntry->wFlags & PROCESS_HEAP_REGION) {
  787. Entry.Flags = RTL_HEAP_SEGMENT;
  788. }
  789. else
  790. if (lpEntry->wFlags & PROCESS_HEAP_UNCOMMITTED_RANGE) {
  791. Entry.Flags = RTL_HEAP_UNCOMMITTED_RANGE;
  792. Entry.DataSize = lpEntry->cbData;
  793. }
  794. else
  795. if (lpEntry->wFlags & PROCESS_HEAP_ENTRY_BUSY) {
  796. Entry.Flags = RTL_HEAP_BUSY;
  797. }
  798. else {
  799. Entry.Flags = 0;
  800. }
  801. Status = RtlWalkHeap( hHeap, &Entry );
  802. }
  803. if (NT_SUCCESS( Status )) {
  804. lpEntry->lpData = Entry.DataAddress;
  805. lpEntry->cbData = (DWORD)Entry.DataSize;
  806. lpEntry->cbOverhead = Entry.OverheadBytes;
  807. lpEntry->iRegionIndex = Entry.SegmentIndex;
  808. if (Entry.Flags & RTL_HEAP_BUSY) {
  809. lpEntry->wFlags = PROCESS_HEAP_ENTRY_BUSY;
  810. if (Entry.Flags & BASE_HEAP_FLAG_DDESHARE) {
  811. lpEntry->wFlags |= PROCESS_HEAP_ENTRY_DDESHARE;
  812. }
  813. if (Entry.Flags & BASE_HEAP_FLAG_MOVEABLE) {
  814. lpEntry->wFlags |= PROCESS_HEAP_ENTRY_MOVEABLE;
  815. lpEntry->Block.hMem = (HLOCAL)Entry.Block.Settable;
  816. }
  817. memset( lpEntry->Block.dwReserved, 0, sizeof( lpEntry->Block.dwReserved ) );
  818. }
  819. else
  820. if (Entry.Flags & RTL_HEAP_SEGMENT) {
  821. lpEntry->wFlags = PROCESS_HEAP_REGION;
  822. lpEntry->Region.dwCommittedSize = Entry.Segment.CommittedSize;
  823. lpEntry->Region.dwUnCommittedSize = Entry.Segment.UnCommittedSize;
  824. lpEntry->Region.lpFirstBlock = Entry.Segment.FirstEntry;
  825. lpEntry->Region.lpLastBlock = Entry.Segment.LastEntry;
  826. }
  827. else
  828. if (Entry.Flags & RTL_HEAP_UNCOMMITTED_RANGE) {
  829. lpEntry->wFlags = PROCESS_HEAP_UNCOMMITTED_RANGE;
  830. memset( &lpEntry->Region, 0, sizeof( lpEntry->Region ) );
  831. }
  832. else {
  833. lpEntry->wFlags = 0;
  834. }
  835. return TRUE;
  836. }
  837. else {
  838. BaseSetLastNTError( Status );
  839. return FALSE;
  840. }
  841. }
  842. WINBASEAPI
  843. BOOL
  844. WINAPI
  845. HeapSetInformation (
  846. IN PVOID HeapHandle,
  847. IN HEAP_INFORMATION_CLASS HeapInformationClass,
  848. IN PVOID HeapInformation OPTIONAL,
  849. IN SIZE_T HeapInformationLength OPTIONAL
  850. )
  851. {
  852. NTSTATUS Status;
  853. Status = RtlSetHeapInformation( HeapHandle,
  854. HeapInformationClass,
  855. HeapInformation,
  856. HeapInformationLength );
  857. if (NT_SUCCESS( Status )) {
  858. return TRUE;
  859. }
  860. else {
  861. BaseSetLastNTError( Status );
  862. }
  863. return FALSE;
  864. }
  865. WINBASEAPI
  866. BOOL
  867. WINAPI
  868. HeapQueryInformation (
  869. IN PVOID HeapHandle,
  870. IN HEAP_INFORMATION_CLASS HeapInformationClass,
  871. OUT PVOID HeapInformation OPTIONAL,
  872. IN SIZE_T HeapInformationLength OPTIONAL,
  873. OUT PSIZE_T ReturnLength OPTIONAL
  874. )
  875. {
  876. NTSTATUS Status;
  877. Status = RtlQueryHeapInformation( HeapHandle,
  878. HeapInformationClass,
  879. HeapInformation,
  880. HeapInformationLength,
  881. ReturnLength );
  882. if (NT_SUCCESS( Status )) {
  883. return TRUE;
  884. }
  885. else {
  886. BaseSetLastNTError( Status );
  887. }
  888. return FALSE;
  889. }
  890. #if DBG
  891. VOID
  892. BaseHeapBreakPoint( VOID )
  893. {
  894. if (NtCurrentPeb()->BeingDebugged)
  895. {
  896. #if i386
  897. _asm { int 3 }
  898. #else
  899. DbgBreakPoint();
  900. #endif
  901. }
  902. }
  903. #endif