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.

1028 lines
26 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. #pragma prefast(suppress: 308, "Realloc is allowed to lose this pointer")
  198. p = RtlReAllocateHeap( BaseHeap, MAKE_TAG( LMEM_TAG ) | Flags, p, uBytes );
  199. }
  200. if (p != NULL) {
  201. HandleEntry->Object = p;
  202. HandleEntry->Flags &= ~BASE_HANDLE_DISCARDED;
  203. }
  204. else {
  205. hMem = NULL;
  206. SetLastError( ERROR_NOT_ENOUGH_MEMORY );
  207. }
  208. }
  209. }
  210. }
  211. else
  212. if (!(uFlags & LMEM_MODIFY)) {
  213. #pragma prefast(suppress: 308, "Realloc is allowed to lose this pointer")
  214. hMem = RtlReAllocateHeap( BaseHeap, MAKE_TAG( LMEM_TAG ) | Flags, (PVOID)hMem, uBytes );
  215. if (hMem == NULL) {
  216. SetLastError( ERROR_NOT_ENOUGH_MEMORY );
  217. }
  218. }
  219. }
  220. except (EXCEPTION_EXECUTE_HANDLER) {
  221. hMem = NULL;
  222. BaseSetLastNTError( GetExceptionCode() );
  223. }
  224. RtlUnlockHeap( BaseHeap );
  225. return( (LPSTR)hMem );
  226. }
  227. PVOID
  228. WINAPI
  229. LocalLock(
  230. HLOCAL hMem
  231. )
  232. {
  233. PBASE_HANDLE_TABLE_ENTRY HandleEntry;
  234. LPSTR p;
  235. if ((ULONG_PTR)hMem & BASE_HANDLE_MARK_BIT) {
  236. RtlLockHeap( BaseHeap );
  237. try {
  238. HandleEntry = (PBASE_HANDLE_TABLE_ENTRY)
  239. CONTAINING_RECORD( hMem, BASE_HANDLE_TABLE_ENTRY, Object );
  240. if (!RtlIsValidHandle( &BaseHeapHandleTable, (PRTL_HANDLE_TABLE_ENTRY)HandleEntry )) {
  241. #if DBG
  242. DbgPrint( "*** LocalLock( %lx ) - invalid handle\n", hMem );
  243. BaseHeapBreakPoint();
  244. #endif
  245. SetLastError( ERROR_INVALID_HANDLE );
  246. p = NULL;
  247. }
  248. else {
  249. p = HandleEntry->Object;
  250. if (p != NULL) {
  251. if (HandleEntry->LockCount++ == LMEM_LOCKCOUNT) {
  252. HandleEntry->LockCount--;
  253. }
  254. }
  255. else {
  256. SetLastError( ERROR_DISCARDED );
  257. }
  258. }
  259. }
  260. except (EXCEPTION_EXECUTE_HANDLER) {
  261. p = NULL;
  262. BaseSetLastNTError( GetExceptionCode() );
  263. }
  264. RtlUnlockHeap( BaseHeap );
  265. return( p );
  266. }
  267. else {
  268. if ( (ULONG_PTR)hMem >= SystemRangeStart ) {
  269. return NULL;
  270. }
  271. return( (LPSTR)hMem );
  272. }
  273. }
  274. HLOCAL
  275. WINAPI
  276. LocalHandle(
  277. LPCVOID pMem
  278. )
  279. {
  280. HANDLE Handle;
  281. ULONG Flags;
  282. RtlLockHeap( BaseHeap );
  283. try {
  284. Handle = NULL;
  285. if (!RtlGetUserInfoHeap( BaseHeap, HEAP_NO_SERIALIZE, (LPVOID)pMem, &Handle, &Flags )) {
  286. SetLastError( ERROR_INVALID_HANDLE );
  287. }
  288. else
  289. if (Handle == NULL || !(Flags & BASE_HEAP_FLAG_MOVEABLE)) {
  290. Handle = (HANDLE)pMem;
  291. }
  292. }
  293. except (EXCEPTION_EXECUTE_HANDLER) {
  294. BaseSetLastNTError( GetExceptionCode() );
  295. }
  296. RtlUnlockHeap( BaseHeap );
  297. return( Handle );
  298. }
  299. BOOL
  300. WINAPI
  301. LocalUnlock(
  302. HLOCAL hMem
  303. )
  304. {
  305. PBASE_HANDLE_TABLE_ENTRY HandleEntry;
  306. BOOL Result;
  307. Result = FALSE;
  308. if ((ULONG_PTR)hMem & BASE_HANDLE_MARK_BIT) {
  309. RtlLockHeap( BaseHeap );
  310. try {
  311. HandleEntry = (PBASE_HANDLE_TABLE_ENTRY)
  312. CONTAINING_RECORD( hMem, BASE_HANDLE_TABLE_ENTRY, Object );
  313. if (!RtlIsValidHandle( &BaseHeapHandleTable, (PRTL_HANDLE_TABLE_ENTRY)HandleEntry )) {
  314. #if DBG
  315. DbgPrint( "*** LocalUnlock( %lx ) - invalid handle\n", hMem );
  316. BaseHeapBreakPoint();
  317. #endif
  318. SetLastError( ERROR_INVALID_HANDLE );
  319. }
  320. else
  321. if (HandleEntry->LockCount-- == 0) {
  322. HandleEntry->LockCount++;
  323. SetLastError( ERROR_NOT_LOCKED );
  324. }
  325. else
  326. if (HandleEntry->LockCount != 0) {
  327. Result = TRUE;
  328. }
  329. else {
  330. SetLastError( NO_ERROR );
  331. }
  332. }
  333. except (EXCEPTION_EXECUTE_HANDLER) {
  334. BaseSetLastNTError( GetExceptionCode() );
  335. }
  336. RtlUnlockHeap( BaseHeap );
  337. }
  338. else {
  339. SetLastError( ERROR_NOT_LOCKED );
  340. }
  341. return( Result );
  342. }
  343. SIZE_T
  344. WINAPI
  345. LocalSize(
  346. HLOCAL hMem
  347. )
  348. {
  349. PBASE_HANDLE_TABLE_ENTRY HandleEntry;
  350. PVOID Handle;
  351. ULONG Flags;
  352. SIZE_T uSize;
  353. uSize = MAXULONG_PTR;
  354. Flags = 0;
  355. RtlLockHeap( BaseHeap );
  356. try {
  357. if (!((ULONG_PTR)hMem & BASE_HANDLE_MARK_BIT)) {
  358. Handle = NULL;
  359. if (!RtlGetUserInfoHeap( BaseHeap, Flags, hMem, &Handle, &Flags )) {
  360. }
  361. else
  362. if (Handle == NULL || !(Flags & BASE_HEAP_FLAG_MOVEABLE)) {
  363. uSize = RtlSizeHeap( BaseHeap, HEAP_NO_SERIALIZE, (PVOID)hMem );
  364. }
  365. else {
  366. hMem = Handle;
  367. }
  368. }
  369. if ((ULONG_PTR)hMem & BASE_HANDLE_MARK_BIT) {
  370. HandleEntry = (PBASE_HANDLE_TABLE_ENTRY)
  371. CONTAINING_RECORD( hMem, BASE_HANDLE_TABLE_ENTRY, Object );
  372. if (!RtlIsValidHandle( &BaseHeapHandleTable, (PRTL_HANDLE_TABLE_ENTRY)HandleEntry )) {
  373. #if DBG
  374. DbgPrint( "*** LocalSize( %lx ) - invalid handle\n", hMem );
  375. BaseHeapBreakPoint();
  376. #endif
  377. SetLastError( ERROR_INVALID_HANDLE );
  378. }
  379. else
  380. if (HandleEntry->Flags & BASE_HANDLE_DISCARDED) {
  381. uSize = HandleEntry->Size;
  382. }
  383. else {
  384. uSize = RtlSizeHeap( BaseHeap, HEAP_NO_SERIALIZE, HandleEntry->Object );
  385. }
  386. }
  387. }
  388. except (EXCEPTION_EXECUTE_HANDLER) {
  389. BaseSetLastNTError( GetExceptionCode() );
  390. }
  391. RtlUnlockHeap( BaseHeap );
  392. if (uSize == MAXULONG_PTR) {
  393. SetLastError( ERROR_INVALID_HANDLE );
  394. return 0;
  395. }
  396. else {
  397. return uSize;
  398. }
  399. }
  400. UINT
  401. WINAPI
  402. LocalFlags(
  403. HLOCAL hMem
  404. )
  405. {
  406. PBASE_HANDLE_TABLE_ENTRY HandleEntry;
  407. HANDLE Handle;
  408. ULONG Flags;
  409. UINT uFlags;
  410. uFlags = LMEM_INVALID_HANDLE;
  411. RtlLockHeap( BaseHeap );
  412. try {
  413. if (!((ULONG_PTR)hMem & BASE_HANDLE_MARK_BIT)) {
  414. Handle = NULL;
  415. Flags = 0;
  416. if (!RtlGetUserInfoHeap( BaseHeap, Flags, hMem, &Handle, &Flags )) {
  417. }
  418. else
  419. if (Handle == NULL || !(Flags & BASE_HEAP_FLAG_MOVEABLE)) {
  420. uFlags = 0;
  421. }
  422. else {
  423. hMem = Handle;
  424. }
  425. }
  426. if ((ULONG_PTR)hMem & BASE_HANDLE_MARK_BIT) {
  427. HandleEntry = (PBASE_HANDLE_TABLE_ENTRY)
  428. CONTAINING_RECORD( hMem, BASE_HANDLE_TABLE_ENTRY, Object );
  429. if (RtlIsValidHandle( &BaseHeapHandleTable, (PRTL_HANDLE_TABLE_ENTRY)HandleEntry )) {
  430. uFlags = HandleEntry->LockCount & LMEM_LOCKCOUNT;
  431. if (HandleEntry->Flags & BASE_HANDLE_DISCARDED) {
  432. uFlags |= LMEM_DISCARDED;
  433. }
  434. if (HandleEntry->Flags & BASE_HANDLE_DISCARDABLE) {
  435. uFlags |= LMEM_DISCARDABLE;
  436. }
  437. }
  438. }
  439. if (uFlags == LMEM_INVALID_HANDLE) {
  440. #if DBG
  441. DbgPrint( "*** LocalFlags( %lx ) - invalid handle\n", hMem );
  442. BaseHeapBreakPoint();
  443. #endif
  444. SetLastError( ERROR_INVALID_HANDLE );
  445. }
  446. }
  447. except (EXCEPTION_EXECUTE_HANDLER) {
  448. BaseSetLastNTError( GetExceptionCode() );
  449. }
  450. RtlUnlockHeap( BaseHeap );
  451. return( uFlags );
  452. }
  453. HLOCAL
  454. WINAPI
  455. LocalFree(
  456. HLOCAL hMem
  457. )
  458. {
  459. PBASE_HANDLE_TABLE_ENTRY HandleEntry;
  460. LPSTR p;
  461. try {
  462. if (!((ULONG_PTR)hMem & BASE_HANDLE_MARK_BIT)) {
  463. if (RtlFreeHeap( BaseHeap,
  464. 0,
  465. (PVOID)hMem
  466. )
  467. ) {
  468. return NULL;
  469. }
  470. else {
  471. SetLastError( ERROR_INVALID_HANDLE );
  472. return hMem;
  473. }
  474. }
  475. }
  476. except (EXCEPTION_EXECUTE_HANDLER) {
  477. BaseSetLastNTError( GetExceptionCode() );
  478. return hMem;
  479. }
  480. RtlLockHeap( BaseHeap );
  481. try {
  482. if ((ULONG_PTR)hMem & BASE_HANDLE_MARK_BIT) {
  483. HandleEntry = (PBASE_HANDLE_TABLE_ENTRY)
  484. CONTAINING_RECORD( hMem, BASE_HANDLE_TABLE_ENTRY, Object );
  485. if (!RtlIsValidHandle( &BaseHeapHandleTable, (PRTL_HANDLE_TABLE_ENTRY)HandleEntry )) {
  486. #if DBG
  487. DbgPrint( "*** LocalFree( %lx ) - invalid handle\n", hMem );
  488. BaseHeapBreakPoint();
  489. #endif
  490. SetLastError( ERROR_INVALID_HANDLE );
  491. p = NULL;
  492. }
  493. else {
  494. #if DBG
  495. if (HandleEntry->LockCount != 0) {
  496. DbgPrint( "BASE: LocalFree called with a locked object.\n" );
  497. BaseHeapBreakPoint();
  498. }
  499. #endif
  500. p = HandleEntry->Object;
  501. RtlFreeHandle( &BaseHeapHandleTable, (PRTL_HANDLE_TABLE_ENTRY)HandleEntry );
  502. if (p == NULL) {
  503. hMem = NULL;
  504. }
  505. }
  506. }
  507. else {
  508. p = (LPSTR)hMem;
  509. }
  510. if (p != NULL) {
  511. if (RtlFreeHeap( BaseHeap, HEAP_NO_SERIALIZE, p )) {
  512. hMem = NULL;
  513. }
  514. else {
  515. SetLastError( ERROR_INVALID_HANDLE );
  516. }
  517. }
  518. }
  519. except (EXCEPTION_EXECUTE_HANDLER) {
  520. BaseSetLastNTError( GetExceptionCode() );
  521. }
  522. RtlUnlockHeap( BaseHeap );
  523. return( hMem );
  524. }
  525. SIZE_T
  526. WINAPI
  527. LocalCompact(
  528. UINT uMinFree
  529. )
  530. {
  531. return RtlCompactHeap( BaseHeap, 0 );
  532. }
  533. SIZE_T
  534. WINAPI
  535. LocalShrink(
  536. HLOCAL hMem,
  537. UINT cbNewSize
  538. )
  539. {
  540. return RtlCompactHeap( BaseHeap, 0 );
  541. }
  542. HANDLE
  543. WINAPI
  544. HeapCreate(
  545. DWORD flOptions,
  546. SIZE_T dwInitialSize,
  547. SIZE_T dwMaximumSize
  548. )
  549. {
  550. HANDLE hHeap;
  551. ULONG GrowthThreshold;
  552. ULONG Flags;
  553. Flags = (flOptions & (HEAP_GENERATE_EXCEPTIONS | HEAP_NO_SERIALIZE)) | HEAP_CLASS_1;
  554. GrowthThreshold = 0;
  555. if (dwMaximumSize < BASE_SYSINFO.PageSize) {
  556. if (dwMaximumSize == 0) {
  557. GrowthThreshold = BASE_SYSINFO.PageSize * 16;
  558. Flags |= HEAP_GROWABLE;
  559. }
  560. else {
  561. dwMaximumSize = BASE_SYSINFO.PageSize;
  562. }
  563. }
  564. if (GrowthThreshold == 0 && dwInitialSize > dwMaximumSize) {
  565. dwMaximumSize = dwInitialSize;
  566. }
  567. hHeap = (HANDLE)RtlCreateHeap( Flags,
  568. NULL,
  569. dwMaximumSize,
  570. dwInitialSize,
  571. 0,
  572. NULL
  573. );
  574. if (hHeap == NULL) {
  575. SetLastError( ERROR_NOT_ENOUGH_MEMORY );
  576. }
  577. return( hHeap );
  578. }
  579. BOOL
  580. WINAPI
  581. HeapDestroy(
  582. HANDLE hHeap
  583. )
  584. {
  585. if (RtlDestroyHeap( (PVOID)hHeap ) == NULL ) {
  586. return( TRUE );
  587. }
  588. else {
  589. SetLastError( ERROR_INVALID_HANDLE );
  590. return( FALSE );
  591. }
  592. }
  593. BOOL
  594. WINAPI
  595. HeapExtend(
  596. HANDLE hHeap,
  597. DWORD dwFlags,
  598. LPVOID lpBase,
  599. DWORD dwBytes
  600. )
  601. {
  602. NTSTATUS Status;
  603. Status = RtlExtendHeap( hHeap, dwFlags, lpBase, dwBytes );
  604. if (NT_SUCCESS( Status )) {
  605. return TRUE;
  606. }
  607. else {
  608. BaseSetLastNTError( Status );
  609. }
  610. return FALSE;
  611. }
  612. WINBASEAPI
  613. DWORD
  614. WINAPI
  615. HeapCreateTagsW(
  616. HANDLE hHeap,
  617. DWORD dwFlags,
  618. LPCWSTR lpTagPrefix,
  619. LPCWSTR lpTagNames
  620. )
  621. {
  622. return RtlCreateTagHeap( hHeap, dwFlags, (PWSTR)lpTagPrefix, (PWSTR)lpTagNames );
  623. }
  624. WINBASEAPI
  625. LPCWSTR
  626. WINAPI
  627. HeapQueryTagW(
  628. HANDLE hHeap,
  629. DWORD dwFlags,
  630. WORD wTagIndex,
  631. BOOL bResetCounters,
  632. LPHEAP_TAG_INFO TagInfo
  633. )
  634. {
  635. ASSERT( sizeof(RTL_HEAP_TAG_INFO) == sizeof(HEAP_TAG_INFO) );
  636. return RtlQueryTagHeap( hHeap,
  637. dwFlags,
  638. wTagIndex,
  639. (BOOLEAN)bResetCounters,
  640. (PRTL_HEAP_TAG_INFO)TagInfo
  641. );
  642. }
  643. BOOL
  644. WINAPI
  645. HeapSummary(
  646. HANDLE hHeap,
  647. DWORD dwFlags,
  648. LPHEAP_SUMMARY lpSummary
  649. )
  650. {
  651. NTSTATUS Status;
  652. RTL_HEAP_USAGE HeapInfo;
  653. if (lpSummary->cb != sizeof( *lpSummary )) {
  654. SetLastError( ERROR_INVALID_PARAMETER );
  655. return FALSE;
  656. }
  657. HeapInfo.Length = sizeof( HeapInfo );
  658. Status = RtlUsageHeap( hHeap,
  659. dwFlags & ~(HEAP_USAGE_ALLOCATED_BLOCKS |
  660. HEAP_USAGE_FREE_BUFFER
  661. ),
  662. &HeapInfo
  663. );
  664. if (NT_SUCCESS( Status )) {
  665. lpSummary->cbAllocated = HeapInfo.BytesAllocated;
  666. lpSummary->cbCommitted = HeapInfo.BytesCommitted;
  667. return TRUE;
  668. }
  669. else {
  670. BaseSetLastNTError( Status );
  671. return FALSE;
  672. }
  673. }
  674. BOOL
  675. WINAPI
  676. HeapUsage(
  677. HANDLE hHeap,
  678. DWORD dwFlags,
  679. BOOL bFirstCall,
  680. BOOL bLastCall,
  681. PHEAP_USAGE lpUsage
  682. )
  683. {
  684. NTSTATUS Status;
  685. if (lpUsage->cb != sizeof( *lpUsage ) || (bFirstCall & bLastCall)) {
  686. SetLastError( ERROR_INVALID_PARAMETER );
  687. return FALSE;
  688. }
  689. dwFlags &= ~(HEAP_USAGE_ALLOCATED_BLOCKS |
  690. HEAP_USAGE_FREE_BUFFER
  691. );
  692. if (bLastCall) {
  693. dwFlags |= HEAP_USAGE_FREE_BUFFER;
  694. }
  695. else {
  696. dwFlags |= HEAP_USAGE_ALLOCATED_BLOCKS;
  697. if (bFirstCall) {
  698. RtlZeroMemory( (&lpUsage->cb)+1, sizeof( *lpUsage ) - sizeof( lpUsage->cb ) );
  699. }
  700. }
  701. ASSERT( sizeof(RTL_HEAP_USAGE) == sizeof(HEAP_USAGE) );
  702. Status = RtlUsageHeap( hHeap, dwFlags, (PRTL_HEAP_USAGE)lpUsage );
  703. if (NT_SUCCESS( Status )) {
  704. if (Status == STATUS_MORE_ENTRIES) {
  705. return TRUE;
  706. }
  707. else {
  708. SetLastError( NO_ERROR );
  709. return FALSE;
  710. }
  711. }
  712. else {
  713. BaseSetLastNTError( Status );
  714. return FALSE;
  715. }
  716. }
  717. BOOL
  718. WINAPI
  719. HeapValidate(
  720. HANDLE hHeap,
  721. DWORD dwFlags,
  722. LPVOID lpMem
  723. )
  724. {
  725. return RtlValidateHeap( hHeap, dwFlags, lpMem );
  726. }
  727. HANDLE
  728. WINAPI
  729. GetProcessHeap( VOID )
  730. {
  731. return RtlProcessHeap();
  732. }
  733. WINBASEAPI
  734. DWORD
  735. WINAPI
  736. GetProcessHeaps(
  737. DWORD NumberOfHeaps,
  738. PHANDLE ProcessHeaps
  739. )
  740. {
  741. return RtlGetProcessHeaps( NumberOfHeaps, ProcessHeaps );
  742. }
  743. WINBASEAPI
  744. SIZE_T
  745. WINAPI
  746. HeapCompact(
  747. HANDLE hHeap,
  748. DWORD dwFlags
  749. )
  750. {
  751. return RtlCompactHeap( hHeap, dwFlags );
  752. }
  753. WINBASEAPI
  754. BOOL
  755. WINAPI
  756. HeapLock(
  757. HANDLE hHeap
  758. )
  759. {
  760. return RtlLockHeap( hHeap );
  761. }
  762. WINBASEAPI
  763. BOOL
  764. WINAPI
  765. HeapUnlock(
  766. HANDLE hHeap
  767. )
  768. {
  769. return RtlUnlockHeap( hHeap );
  770. }
  771. WINBASEAPI
  772. BOOL
  773. WINAPI
  774. HeapWalk(
  775. HANDLE hHeap,
  776. LPPROCESS_HEAP_ENTRY lpEntry
  777. )
  778. {
  779. RTL_HEAP_WALK_ENTRY Entry;
  780. NTSTATUS Status;
  781. if (lpEntry->lpData == NULL) {
  782. Entry.DataAddress = NULL;
  783. Status = RtlWalkHeap( hHeap, &Entry );
  784. }
  785. else {
  786. Entry.DataAddress = lpEntry->lpData;
  787. Entry.SegmentIndex = lpEntry->iRegionIndex;
  788. if (lpEntry->wFlags & PROCESS_HEAP_REGION) {
  789. Entry.Flags = RTL_HEAP_SEGMENT;
  790. }
  791. else
  792. if (lpEntry->wFlags & PROCESS_HEAP_UNCOMMITTED_RANGE) {
  793. Entry.Flags = RTL_HEAP_UNCOMMITTED_RANGE;
  794. Entry.DataSize = lpEntry->cbData;
  795. }
  796. else
  797. if (lpEntry->wFlags & PROCESS_HEAP_ENTRY_BUSY) {
  798. Entry.Flags = RTL_HEAP_BUSY;
  799. }
  800. else {
  801. Entry.Flags = 0;
  802. }
  803. Status = RtlWalkHeap( hHeap, &Entry );
  804. }
  805. if (NT_SUCCESS( Status )) {
  806. lpEntry->lpData = Entry.DataAddress;
  807. lpEntry->cbData = (DWORD)Entry.DataSize;
  808. lpEntry->cbOverhead = Entry.OverheadBytes;
  809. lpEntry->iRegionIndex = Entry.SegmentIndex;
  810. if (Entry.Flags & RTL_HEAP_BUSY) {
  811. lpEntry->wFlags = PROCESS_HEAP_ENTRY_BUSY;
  812. if (Entry.Flags & BASE_HEAP_FLAG_DDESHARE) {
  813. lpEntry->wFlags |= PROCESS_HEAP_ENTRY_DDESHARE;
  814. }
  815. if (Entry.Flags & BASE_HEAP_FLAG_MOVEABLE) {
  816. lpEntry->wFlags |= PROCESS_HEAP_ENTRY_MOVEABLE;
  817. lpEntry->Block.hMem = (HLOCAL)Entry.Block.Settable;
  818. }
  819. memset( lpEntry->Block.dwReserved, 0, sizeof( lpEntry->Block.dwReserved ) );
  820. }
  821. else
  822. if (Entry.Flags & RTL_HEAP_SEGMENT) {
  823. lpEntry->wFlags = PROCESS_HEAP_REGION;
  824. lpEntry->Region.dwCommittedSize = Entry.Segment.CommittedSize;
  825. lpEntry->Region.dwUnCommittedSize = Entry.Segment.UnCommittedSize;
  826. lpEntry->Region.lpFirstBlock = Entry.Segment.FirstEntry;
  827. lpEntry->Region.lpLastBlock = Entry.Segment.LastEntry;
  828. }
  829. else
  830. if (Entry.Flags & RTL_HEAP_UNCOMMITTED_RANGE) {
  831. lpEntry->wFlags = PROCESS_HEAP_UNCOMMITTED_RANGE;
  832. memset( &lpEntry->Region, 0, sizeof( lpEntry->Region ) );
  833. }
  834. else {
  835. lpEntry->wFlags = 0;
  836. }
  837. return TRUE;
  838. }
  839. else {
  840. BaseSetLastNTError( Status );
  841. return FALSE;
  842. }
  843. }
  844. WINBASEAPI
  845. BOOL
  846. WINAPI
  847. HeapSetInformation (
  848. IN HANDLE HeapHandle,
  849. IN HEAP_INFORMATION_CLASS HeapInformationClass,
  850. IN PVOID HeapInformation OPTIONAL,
  851. IN SIZE_T HeapInformationLength OPTIONAL
  852. )
  853. {
  854. NTSTATUS Status;
  855. Status = RtlSetHeapInformation( (PVOID)HeapHandle,
  856. HeapInformationClass,
  857. HeapInformation,
  858. HeapInformationLength );
  859. if (NT_SUCCESS( Status )) {
  860. return TRUE;
  861. }
  862. else {
  863. BaseSetLastNTError( Status );
  864. }
  865. return FALSE;
  866. }
  867. WINBASEAPI
  868. BOOL
  869. WINAPI
  870. HeapQueryInformation (
  871. IN HANDLE HeapHandle,
  872. IN HEAP_INFORMATION_CLASS HeapInformationClass,
  873. OUT PVOID HeapInformation OPTIONAL,
  874. IN SIZE_T HeapInformationLength OPTIONAL,
  875. OUT PSIZE_T ReturnLength OPTIONAL
  876. )
  877. {
  878. NTSTATUS Status;
  879. Status = RtlQueryHeapInformation( (PVOID)HeapHandle,
  880. HeapInformationClass,
  881. HeapInformation,
  882. HeapInformationLength,
  883. ReturnLength );
  884. if (NT_SUCCESS( Status )) {
  885. return TRUE;
  886. }
  887. else {
  888. BaseSetLastNTError( Status );
  889. }
  890. return FALSE;
  891. }
  892. #if DBG
  893. VOID
  894. BaseHeapBreakPoint( VOID )
  895. {
  896. if (NtCurrentPeb()->BeingDebugged)
  897. {
  898. #if i386
  899. _asm { int 3 }
  900. #else
  901. DbgBreakPoint();
  902. #endif
  903. }
  904. }
  905. #endif