ReactOS 0.4.16-dev-306-g647d351
heapmem.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Win32 Base API
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: dll/win32/kernel32/client/heapmem.c
5 * PURPOSE: Heap Memory APIs (wrappers for RtlHeap*)
6 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
7 */
8
9/* INCLUDES *******************************************************************/
10
11#include <k32.h>
12
13#define NDEBUG
14#include <debug.h>
15
16/* GLOBALS ********************************************************************/
17
21
22/* PRIVATE FUNCTIONS **********************************************************/
23
24VOID
27{
28 BaseHeap = RtlGetProcessHeap();
34 sizeof(SystemRangeStart),
35 NULL);
36}
37
38/* PUBLIC FUNCTIONS ***********************************************************/
39
40/*
41 * @implemented
42 */
46 SIZE_T dwInitialSize,
47 SIZE_T dwMaximumSize)
48{
49 HANDLE hRet;
51
52 /* Remove non-Win32 flags and tag this allocation */
55
56 /* Check if heap is growable and ensure max size is correct */
57 if (dwMaximumSize == 0)
59 else if (dwMaximumSize < BaseStaticServerData->SysInfo.PageSize &&
60 dwInitialSize > dwMaximumSize)
61 {
62 /* Max size is non-zero but less than page size which can't be correct.
63 Fix it up by bumping it to the initial size whatever it is. */
64 dwMaximumSize = dwInitialSize;
65 }
66
67 /* Call RTL Heap */
68 hRet = RtlCreateHeap(Flags,
69 NULL,
70 dwMaximumSize,
71 dwInitialSize,
72 NULL,
73 NULL);
74
75 /* Set the last error if we failed, and return the pointer */
77 return hRet;
78}
79
80/*
81 * @implemented
82 */
83BOOL
86{
87 /* Return TRUE if the heap was destroyed */
88 if (!RtlDestroyHeap(hHeap)) return TRUE;
89
90 /* Otherwise, we got the handle back, so fail */
92 return FALSE;
93}
94
95/*
96 * @implemented
97 */
101{
102 /* Call the RTL API */
103 return RtlGetProcessHeap();
104}
105
106/*
107 * @implemented
108 */
109DWORD
110WINAPI
111GetProcessHeaps(DWORD NumberOfHeaps,
112 PHANDLE ProcessHeaps)
113{
114 /* Call the RTL API */
115 return RtlGetProcessHeaps(NumberOfHeaps, ProcessHeaps);
116}
117
118/*
119 * @implemented
120 */
121BOOL
122WINAPI
124{
125 /* Call the RTL API */
126 return RtlLockHeap(hHeap);
127}
128
129/*
130 * @implemented
131 */
132BOOL
133WINAPI
135{
136 /* Call the RTL API */
137 return RtlUnlockHeap(hHeap);
138}
139
140/*
141 * @implemented
142 */
143SIZE_T
144WINAPI
146{
147 /* Call the RTL API */
148 return RtlCompactHeap(hHeap, dwFlags);
149}
150
151/*
152 * @implemented
153 */
154BOOL
155WINAPI
158 LPCVOID lpMem)
159{
160 /* Call the RTL API */
161 return RtlValidateHeap(hHeap, dwFlags, (PVOID)lpMem);
162}
163
164/*
165 * @implemented
166 */
167DWORD
168WINAPI
171 _In_opt_ PWSTR lpTagName,
172 _In_ PWSTR lpTagSubName)
173{
174 /* Call the RTL API */
175 return RtlCreateTagHeap(hHeap,
176 dwFlags,
177 lpTagName,
178 lpTagSubName);
179}
180
181/*
182 * @implemented
183 */
184DWORD
185WINAPI
189 DWORD dwBytes)
190{
192
193 /* Call the RTL API. Gone in Vista, so commented out. */
194 Status = STATUS_NOT_IMPLEMENTED; //RtlExtendHeap(hHeap, dwFlags, BaseAddress, dwBytes);
195 if (!NT_SUCCESS(Status))
196 {
197 /* We failed */
199 return FALSE;
200 }
201
202 /* Return success */
203 return TRUE;
204}
205
206/*
207 * @implemented
208 */
209PWSTR
210WINAPI
213 WORD wTagIndex,
214 BOOL bResetCounters,
215 PVOID lpTagInfo)
216{
217 /* Call the RTL API */
218 return RtlQueryTagHeap(hHeap,
219 dwFlags,
220 wTagIndex,
221 (BOOLEAN)bResetCounters,
222 lpTagInfo);
223}
224
225/*
226 * @implemented
227 */
228BOOL
229WINAPI
232 PVOID Summary)
233{
236
237 /* Fill in the length information */
238 Usage.Length = sizeof(Usage);
239
240 /* Call RTL. Gone in Vista, so commented out */
241 Status = STATUS_NOT_IMPLEMENTED; //RtlUsageHeap(hHeap, dwFlags, &Usage);
242 if (!NT_SUCCESS(Status))
243 {
244 /* We failed */
246 return FALSE;
247 }
248
249 /* FIXME: Summary == Usage?! */
250 RtlCopyMemory(Summary, &Usage, sizeof(Usage));
251 return TRUE;
252}
253
254/*
255 * @implemented
256 */
257BOOL
258WINAPI
262 DWORD Unknown2,
263 IN PVOID Usage)
264{
266
267 /* Call RTL. Gone in Vista, so commented out */
268 Status = STATUS_NOT_IMPLEMENTED; //RtlUsageHeap(hHeap, dwFlags, &Usage);
269 if (!NT_SUCCESS(Status))
270 {
271 /* We failed */
273 return FALSE;
274 }
275 else if (Status == STATUS_MORE_ENTRIES)
276 {
277 /* There are still more entries to parse */
278 return TRUE;
279 }
280
281 /* Otherwise, we're completely done, so we return FALSE, but NO_ERROR */
283 return FALSE;
284}
285
286/*
287 * @implemented
288 */
289BOOL
290WINAPI
292 LPPROCESS_HEAP_ENTRY lpEntry)
293{
295
296 DPRINT1("Warning, HeapWalk is calling RtlWalkHeap with Win32 parameters\n");
297
298 Status = RtlWalkHeap(hHeap, lpEntry);
299
300 if (!NT_SUCCESS(Status))
301 {
303 return FALSE;
304 }
305
306 return TRUE;
307}
308
309/*
310 * @implemented
311 */
312BOOL
313WINAPI
315 HEAP_INFORMATION_CLASS HeapInformationClass,
316 PVOID HeapInformation OPTIONAL,
317 SIZE_T HeapInformationLength OPTIONAL,
319{
321
322 Status = RtlQueryHeapInformation(HeapHandle,
323 HeapInformationClass,
324 HeapInformation,
325 HeapInformationLength,
327
328 if (!NT_SUCCESS(Status))
329 {
331 return FALSE;
332 }
333
334 return TRUE;
335}
336
337/*
338 * @implemented
339 */
340BOOL
341WINAPI
343 HEAP_INFORMATION_CLASS HeapInformationClass,
344 PVOID HeapInformation OPTIONAL,
345 SIZE_T HeapInformationLength OPTIONAL)
346{
348
349 Status = RtlSetHeapInformation(HeapHandle,
350 HeapInformationClass,
351 HeapInformation,
352 HeapInformationLength);
353
354 if (!NT_SUCCESS(Status))
355 {
357 return FALSE;
358 }
359
360 return TRUE;
361}
362
363/*
364 * @implemented
365 */
367NTAPI
369 SIZE_T dwBytes)
370{
371 ULONG Flags = 0;
372 PVOID Ptr = NULL;
374 PBASE_HEAP_HANDLE_ENTRY HandleEntry;
375 BASE_TRACE_ALLOC(dwBytes, uFlags);
377
378 /* Make sure the flags are valid */
380 {
381 /* They aren't, fail */
384 return NULL;
385 }
386
387 /* Convert ZEROINIT */
389
390 /* Check if we're not movable, which means pointer-based heap */
391 if (!(uFlags & GMEM_MOVEABLE))
392 {
393 /* Check if this is DDESHARE (deprecated) */
395
396 /* Allocate heap for it */
397 Ptr = RtlAllocateHeap(BaseHeap, Flags, dwBytes ? dwBytes : 1);
400 return Ptr;
401 }
402
403 /* This is heap based, so lock it in first */
405
406 /*
407 * Disable locking, enable custom flags, and write the
408 * movable flag (deprecated)
409 */
413
414 /* Allocate the handle */
415 HandleEntry = BaseHeapAllocEntry();
416 if (!HandleEntry)
417 {
418 /* Fail */
419 hMemory = NULL;
422 }
423 else
424 {
425 /* Get the object and make sure we have size */
426 hMemory = &HandleEntry->Object;
427 if (dwBytes)
428 {
429 /* Allocate the actual memory for it */
430 Ptr = RtlAllocateHeap(BaseHeap, Flags, dwBytes);
431 BASE_TRACE_PTR(HandleEntry, Ptr);
432 if (!Ptr)
433 {
434 /* We failed, manually set the allocate flag and free the handle */
435 HandleEntry->Flags = RTL_HANDLE_VALID;
436 BaseHeapFreeEntry(HandleEntry);
437
438 /* For the cleanup case */
439 HandleEntry = NULL;
440 }
441 else
442 {
443 /* All worked well, save our heap entry */
445 }
446 }
447 }
448
449 /* Cleanup! First unlock the heap */
451
452 /* Check if a handle was allocated */
453 if (HandleEntry)
454 {
455 /* Set the pointer and allocated flag */
456 HandleEntry->Object = Ptr;
457 HandleEntry->Flags = RTL_HANDLE_VALID;
458 if (!Ptr)
459 {
460 /* We don't have a valid pointer, but so reuse this handle */
461 HandleEntry->Flags |= BASE_HEAP_ENTRY_FLAG_REUSE;
462 }
463
464 /* Check if the handle is discardable */
466 {
467 /* Save it in the handle entry */
468 HandleEntry->Flags |= BASE_HEAP_ENTRY_FLAG_REUSABLE;
469 }
470
471 /* Check if the handle is moveable */
472 if (uFlags & GMEM_MOVEABLE)
473 {
474 /* Save it in the handle entry */
475 HandleEntry->Flags |= BASE_HEAP_ENTRY_FLAG_MOVABLE;
476 }
477
478 /* Check if the handle is DDE Shared */
479 if (uFlags & GMEM_DDESHARE)
480 {
481 /* Save it in the handle entry */
482 HandleEntry->Flags |= BASE_HEAP_ENTRY_FLAG_DDESHARE;
483 }
484
485 /* Set the pointer */
486 Ptr = hMemory;
487 }
488
489 /* Return the pointer */
490 return Ptr;
491}
492
493/*
494 * @implemented
495 */
496SIZE_T
497NTAPI
499{
500 /* Call the RTL Heap Manager */
501 return RtlCompactHeap(BaseHeap, 0);
502}
503
504/*
505 * @implemented
506 */
507VOID
508NTAPI
510{
511 /* Lock the memory if it the handle is valid */
512 if (INVALID_HANDLE_VALUE != hMem) GlobalLock(hMem);
513}
514
515/*
516 * @implemented
517 */
518UINT
519NTAPI
521{
522 PBASE_HEAP_HANDLE_ENTRY HandleEntry;
524 ULONG Flags = 0;
526
527 /* Start by locking the heap */
530 {
531 /* Check if this is a simple RTL Heap Managed block */
533 {
534 /* Then we'll query RTL Heap */
536 BASE_TRACE_PTR(Handle, hMem);
537
538 /*
539 * Check if RTL Heap didn't find a handle associated with us or
540 * said that this heap isn't movable, which means something we're
541 * really not a handle-based heap.
542 */
543 if (!(Handle) || !(Flags & BASE_HEAP_FLAG_MOVABLE))
544 {
545 /* Then set the flags to 0 */
546 uFlags = 0;
547 }
548 else
549 {
550 /* Otherwise we're handle-based, so get the internal handle */
551 hMem = Handle;
552 }
553 }
554
555 /* Check if the handle is actually an entry in our table */
557 {
558 /* Then get the entry */
559 HandleEntry = BaseHeapGetEntry(hMem);
560 BASE_TRACE_HANDLE(HandleEntry, hMem);
561
562 /* Make sure it's a valid handle */
563 if (BaseHeapValidateEntry(HandleEntry))
564 {
565 /* Get the lock count first */
566 uFlags = HandleEntry->LockCount & GMEM_LOCKCOUNT;
567
568 /* Now check if it's discardable */
569 if (HandleEntry->Flags & BASE_HEAP_ENTRY_FLAG_REUSABLE)
570 {
571 /* Set the Win32 Flag */
573 }
574
575 /* Check if it's DDE Shared */
576 if (HandleEntry->Flags & BASE_HEAP_ENTRY_FLAG_DDESHARE)
577 {
578 /* Set the Win32 Flag */
580 }
581
582 /* Now check if it's discarded */
583 if (HandleEntry->Flags & BASE_HEAP_ENTRY_FLAG_REUSE)
584 {
585 /* Set the Win32 Flag */
587 }
588 }
589 }
590
591 /* Check if by now, we still haven't gotten any useful flags */
593 }
595 {
596 /* Set the exception code */
598 }
599 _SEH2_END;
600
601 /* All done! Unlock heap and return Win32 Flags */
603 return uFlags;
604}
605
606/*
607 * @implemented
608 */
610NTAPI
612{
613 PBASE_HEAP_HANDLE_ENTRY HandleEntry;
614 LPVOID Ptr;
615 BASE_TRACE_DEALLOC(hMem);
616
617 /* Check if this was a simple allocated heap entry */
619 {
620 /* Free it with the RTL Heap Manager */
621 if (RtlFreeHeap(BaseHeap, 0, hMem))
622 {
623 /* Return NULL since there's no handle */
624 return NULL;
625 }
626 else
627 {
628 /* Otherwise fail */
631 return hMem;
632 }
633 }
634
635 /* It's a handle probably, so lock the heap */
638 {
639 /* Make sure that this is an entry in our handle database */
641 {
642 /* Get the entry */
643 HandleEntry = BaseHeapGetEntry(hMem);
644 BASE_TRACE_HANDLE(HandleEntry, hMem);
645
646 /* Make sure the handle is valid */
647 if (!BaseHeapValidateEntry(HandleEntry))
648 {
649 /* It's not, fail */
651 Ptr = NULL;
652 }
653 else
654 {
655 /* It's valid, so get the pointer */
656 Ptr = HandleEntry->Object;
657
658 /* Free this handle */
659 BaseHeapFreeEntry(HandleEntry);
660
661 /* If the pointer is 0, then we don't have a handle either */
662 if (!Ptr) hMem = NULL;
663 }
664 }
665 else
666 {
667 /* Otherwise, reuse the handle as a pointer */
669 Ptr = hMem;
670 }
671
672 /* Check if we got here with a valid heap pointer */
673 if (Ptr)
674 {
675 /* Free it with the RTL Heap Manager */
677 {
678 /* Everything worked */
679 hMem = NULL;
680 }
681 else
682 {
683 /* This wasn't a real heap handle */
685 }
686 }
687 }
689 {
690 /* Set the exception code */
692 }
693 _SEH2_END;
694
695 /* We're done, so unlock the heap and return the handle */
697 return hMem;
698}
699
700/*
701 * @implemented
702 */
704NTAPI
706{
708 ULONG Flags;
709
710 /* Lock the heap */
713 {
714 /* Query RTL Heap */
717 (PVOID)pMem,
718 &Handle,
719 &Flags))
720 {
721 /* RTL Heap Manager does not know about this heap */
723 }
724 else
725 {
726 /*
727 * Check if RTL Heap didn't find a handle for us or said that
728 * this heap isn't movable.
729 */
730 BASE_TRACE_PTR(Handle, pMem);
731 if (!(Handle) || !(Flags & BASE_HEAP_FLAG_MOVABLE))
732 {
733 /* We're actually handle-based, so the pointer is a handle */
734 Handle = (HANDLE)pMem;
735 }
736 }
737 }
739 {
740 /* Set the exception code */
742 }
743 _SEH2_END;
744
745 /* All done, unlock the heap and return the handle */
747 return Handle;
748}
749
750/*
751 * @implemented
752 */
753LPVOID
754NTAPI
756{
757 PBASE_HEAP_HANDLE_ENTRY HandleEntry;
758 LPVOID Ptr;
759
760 /* Check if this was a simple allocated heap entry */
762 {
763 /* Make sure it's not a kernel or invalid address */
764 if ((hMem >= (HGLOBAL)SystemRangeStart) || (IsBadReadPtr(hMem, 1)))
765 {
766 /* Signal an error */
768 return NULL;
769 }
770
771 /* It's all good */
772 return hMem;
773 }
774
775 /* Otherwise, lock the heap */
778 {
779 /* Get the handle entry */
780 HandleEntry = BaseHeapGetEntry(hMem);
781 BASE_TRACE_HANDLE(HandleEntry, hMem);
782
783 /* Make sure it's valid */
784 if (!BaseHeapValidateEntry(HandleEntry))
785 {
786 /* It's not, fail */
789 Ptr = NULL;
790 }
791 else
792 {
793 /* Otherwise, get the pointer */
794 Ptr = HandleEntry->Object;
795 if (Ptr)
796 {
797 /* Increase the lock count, unless we've went too far */
798 if (HandleEntry->LockCount++ == GMEM_LOCKCOUNT)
799 {
800 /* In which case we simply unlock once */
801 HandleEntry->LockCount--;
802 }
803 }
804 else
805 {
806 /* The handle is still there but the memory was already freed */
808 }
809 }
810 }
812 {
814 Ptr = NULL;
815 }
816 _SEH2_END;
817
818 /* All done. Unlock the heap and return the pointer */
820 return Ptr;
821}
822
824NTAPI
826 SIZE_T dwBytes,
827 UINT uFlags)
828{
829 PBASE_HEAP_HANDLE_ENTRY HandleEntry;
831 LPVOID Ptr;
832 ULONG Flags = 0;
833
834 /* Throw out invalid flags */
836 {
838 return NULL;
839 }
840
841 /* Throw out invalid combo */
843 {
845 return NULL;
846 }
847
848 /* Convert ZEROINIT */
850
851 /* If this wasn't a movable heap, then we MUST re-alloc in place */
853
854 /* Lock the heap and disable built-in locking in the RTL Heap functions */
857
858 /* Check if this is a simple handle-based block */
860 {
861 /* Get the entry */
862 HandleEntry = BaseHeapGetEntry(hMem);
863 BASE_TRACE_HANDLE(HandleEntry, hMem);
864
865 /* Make sure the handle is valid */
866 if (!BaseHeapValidateEntry(HandleEntry))
867 {
868 /* Fail */
871 hMem = NULL;
872 }
873 else if (uFlags & GMEM_MODIFY)
874 {
875 /* User is changing flags... check if the memory was discardable */
877 {
878 /* Then set the flag */
879 HandleEntry->Flags |= BASE_HEAP_ENTRY_FLAG_REUSABLE;
880 }
881 else
882 {
883 /* Otherwise, remove the flag */
884 HandleEntry->Flags &= ~BASE_HEAP_ENTRY_FLAG_REUSABLE;
885 }
886 }
887 else
888 {
889 /* Otherwise, get the object and check if we have no size */
890 Ptr = HandleEntry->Object;
891 if (!dwBytes)
892 {
893 /* Clear the handle and check for a pointer */
894 hMem = NULL;
895 if (Ptr)
896 {
897 /* Make sure the handle isn't locked */
898 if ((uFlags & GMEM_MOVEABLE) && !(HandleEntry->LockCount))
899 {
900 /* Free the current heap */
902 {
903 /* Free the handle */
904 HandleEntry->Object = NULL;
905 HandleEntry->Flags |= BASE_HEAP_ENTRY_FLAG_REUSE;
906
907 /* Get the object pointer */
908 hMem = &HandleEntry->Object;
909 }
910 }
911 }
912 else
913 {
914 /* Otherwise just return the object pointer */
915 hMem = &HandleEntry->Object;
916 }
917 }
918 else
919 {
920 /* Otherwise, we're allocating, so set the new flags needed */
922 if (!Ptr)
923 {
924 /* We don't have a base, so allocate one */
925 Ptr = RtlAllocateHeap(BaseHeap, Flags, dwBytes);
927 if (Ptr)
928 {
929 /* Allocation succeeded, so save our entry */
932 Ptr,
933 hMem);
934 }
935 }
936 else
937 {
938 /*
939 * If it's not movable or currently locked, we MUST allocate
940 * in-place!
941 */
942 if (!(uFlags & GMEM_MOVEABLE) && (HandleEntry->LockCount))
943 {
944 /* Set the flag */
946 }
947 else
948 {
949 /* Otherwise clear the flag if we set it previously */
950 Flags &= ~HEAP_REALLOC_IN_PLACE_ONLY;
951 }
952
953 /* Do the re-allocation. No need to save the entry again */
954 Ptr = RtlReAllocateHeap(BaseHeap, Flags, Ptr, dwBytes);
955 }
956
957 /* Make sure we have a pointer by now */
958 if (Ptr)
959 {
960 /* Write it in the handle entry and mark it in use */
961 HandleEntry->Object = Ptr;
962 HandleEntry->Flags &= ~BASE_HEAP_ENTRY_FLAG_REUSE;
963 }
964 else
965 {
966 /* Otherwise we failed */
967 hMem = NULL;
969 }
970 }
971 }
972 }
973 else if (uFlags & GMEM_MODIFY)
974 {
975 /* This is not a handle-based heap and the caller wants it to be one */
976 if (uFlags & GMEM_MOVEABLE)
977 {
978 /* Get information on its current state */
979 Handle = hMem;
982 hMem,
983 &Handle,
984 NULL))
985 {
986 /*
987 * Check if the handle matches the pointer or the moveable flag
988 * isn't there, which is what we expect since it currently isn't.
989 */
990 if ((Handle == hMem) || !(Flags & BASE_HEAP_FLAG_MOVABLE))
991 {
992 /* Allocate a handle for it */
993 HandleEntry = BaseHeapAllocEntry();
994 if (!HandleEntry)
995 {
996 /* No entry could be allocated */
999 return NULL;
1000 }
1001
1002 /* Calculate the size of the current heap */
1003 dwBytes = RtlSizeHeap(BaseHeap, HEAP_NO_SERIALIZE, hMem);
1004
1005 /* Set the movable flag */
1007
1008 /* Now allocate the actual heap for it */
1009 HandleEntry->Object = RtlAllocateHeap(BaseHeap,
1010 Flags,
1011 dwBytes);
1012 BASE_TRACE_PTR(HandleEntry->Object, HandleEntry);
1013 if (!HandleEntry->Object)
1014 {
1015 /*
1016 * We failed, manually set the allocate flag and
1017 * free the handle
1018 */
1019 HandleEntry->Flags = RTL_HANDLE_VALID;
1020 BaseHeapFreeEntry(HandleEntry);
1021
1022 /* For the cleanup case */
1024 HandleEntry = NULL;
1026 }
1027 else
1028 {
1029 /* Otherwise, copy the new heap and free the old one */
1030 RtlMoveMemory(HandleEntry->Object, hMem, dwBytes);
1032
1033 /* Select the heap pointer */
1034 hMem = (HANDLE)&HandleEntry->Object;
1035
1036 /* Initialize the count and default flags */
1037 HandleEntry->LockCount = 0;
1038 HandleEntry->Flags = RTL_HANDLE_VALID |
1040
1041 /* Check if it's also discardable */
1043 {
1044 /* Set the internal flag */
1045 HandleEntry->Flags |= BASE_HEAP_ENTRY_FLAG_REUSABLE;
1046 }
1047
1048 /* Check if it's also DDE Shared */
1049 if (uFlags & GMEM_DDESHARE)
1050 {
1051 /* Set the internal flag */
1052 HandleEntry->Flags |= BASE_HEAP_ENTRY_FLAG_DDESHARE;
1053 }
1054
1055 /* Allocation succeeded, so save our entry */
1058 HandleEntry->Object,
1059 hMem);
1060 }
1061 }
1062 }
1063 }
1064 }
1065 else
1066 {
1067 /* Otherwise, this is a simple RTL Managed Heap, so just call it */
1070 hMem,
1071 dwBytes);
1072 if (!hMem)
1073 {
1074 /* Fail */
1077 }
1078 }
1079
1080 /* All done, unlock the heap and return the pointer */
1082 return hMem;
1083}
1084
1085/*
1086 * @implemented
1087 */
1088SIZE_T
1089NTAPI
1091{
1092 PBASE_HEAP_HANDLE_ENTRY HandleEntry;
1093 PVOID Handle = NULL;
1094 ULONG Flags = 0;
1096
1097 /* Lock the heap */
1099 _SEH2_TRY
1100 {
1101 /* Check if this is a simple RTL Heap Managed block */
1102 if (!((ULONG_PTR)hMem & BASE_HEAP_IS_HANDLE_ENTRY))
1103 {
1104 /* Then we'll query RTL Heap */
1106 {
1107 BASE_TRACE_PTR(Handle, hMem);
1108 /*
1109 * Check if RTL Heap didn't give us a handle or said that this
1110 * heap isn't movable.
1111 */
1112 if (!(Handle) || !(Flags & BASE_HEAP_FLAG_MOVABLE))
1113 {
1114 /* We're not a handle heap, so use the generic call */
1116 }
1117 else
1118 {
1119 /* We're a handle heap so get the internal handle */
1120 hMem = Handle;
1121 }
1122 }
1123 }
1124
1125 /* Make sure that this is an entry in our handle database */
1127 {
1128 /* Get the entry */
1129 HandleEntry = BaseHeapGetEntry(hMem);
1130 BASE_TRACE_HANDLE(HandleEntry, hMem);
1131
1132 /* Make sure the handle is valid */
1133 if (!BaseHeapValidateEntry(HandleEntry))
1134 {
1135 /* Fail */
1138 }
1139 else if (HandleEntry->Flags & BASE_HEAP_ENTRY_FLAG_REUSE)
1140 {
1141 /* We've reused this block, but we've saved the size for you */
1142 dwSize = HandleEntry->OldSize;
1143 }
1144 else
1145 {
1146 /* Otherwise, query RTL about it */
1149 HandleEntry->Object);
1150 }
1151 }
1152 }
1154 {
1155 /* Set failure for later */
1157 }
1158 _SEH2_END;
1159
1160 /* Check if by now, we still haven't gotten any useful size */
1161 if (dwSize == MAXULONG_PTR)
1162 {
1163 /* Fail */
1166 dwSize = 0;
1167 }
1168
1169 /* All done! Unlock heap and return the size */
1171 return dwSize;
1172}
1173
1174/*
1175 * @implemented
1176 */
1177VOID
1178NTAPI
1180{
1181 /* If the handle is valid, unlock it */
1182 if (hMem != INVALID_HANDLE_VALUE) GlobalUnlock(hMem);
1183}
1184
1185/*
1186 * @implemented
1187 */
1188BOOL
1189NTAPI
1191{
1192 PBASE_HEAP_HANDLE_ENTRY HandleEntry;
1193 BOOL RetVal = TRUE;
1194
1195 /* Check if this was a simple allocated heap entry */
1196 if (!((ULONG_PTR)hMem & BASE_HEAP_IS_HANDLE_ENTRY)) return RetVal;
1197
1198 /* Otherwise, lock the heap */
1200
1201 /* Get the handle entry */
1202 HandleEntry = BaseHeapGetEntry(hMem);
1203 BASE_TRACE_HANDLE(HandleEntry, hMem);
1204
1205 _SEH2_TRY
1206 {
1207 /* Make sure it's valid */
1208 if (!BaseHeapValidateEntry(HandleEntry))
1209 {
1210 /* It's not, fail */
1213 RetVal = FALSE;
1214 }
1215 else
1216 {
1217 /* Otherwise, decrement lock count, unless we're already at 0*/
1218 if (!HandleEntry->LockCount--)
1219 {
1220 /* In which case we simply lock it back and fail */
1221 HandleEntry->LockCount++;
1223 RetVal = FALSE;
1224 }
1225 else if (!HandleEntry->LockCount)
1226 {
1227 /* Nothing to unlock */
1229 RetVal = FALSE;
1230 }
1231 }
1232 }
1234 {
1236 RetVal = FALSE;
1237 }
1238 _SEH2_END;
1239
1240 /* All done. Unlock the heap and return the pointer */
1242 return RetVal;
1243}
1244
1245/*
1246 * @implemented
1247 */
1248BOOL
1249NTAPI
1251{
1252 /* This is simply an unlock */
1253 return GlobalUnlock(hMem);
1254}
1255
1256/*
1257 * @implemented
1258 */
1259LPVOID
1260NTAPI
1262{
1263 /* This is just a lock */
1264 return GlobalLock(hMem);
1265}
1266
1267/*
1268 * @implemented
1269 */
1270BOOL
1271NTAPI
1273{
1274 SYSTEM_PERFORMANCE_INFORMATION PerformanceInfo;
1275 VM_COUNTERS VmCounters;
1276 QUOTA_LIMITS QuotaLimits;
1277 ULONGLONG PageFile, PhysicalMemory;
1279
1280 if (lpBuffer->dwLength != sizeof(*lpBuffer))
1281 {
1283 return FALSE;
1284 }
1285
1286 /* Query performance information */
1288 &PerformanceInfo,
1289 sizeof(PerformanceInfo),
1290 NULL);
1291 if (!NT_SUCCESS(Status))
1292 {
1294 return FALSE;
1295 }
1296
1297 /* Calculate memory load */
1299 PerformanceInfo.AvailablePages) * 100) /
1301
1302 /* Save physical memory */
1305 lpBuffer->ullTotalPhys = PhysicalMemory;
1306
1307 /* Now save available physical memory */
1308 PhysicalMemory = PerformanceInfo.AvailablePages *
1310 lpBuffer->ullAvailPhys = PhysicalMemory;
1311
1312 /* Query VM and Quota Limits */
1315 &QuotaLimits,
1316 sizeof(QUOTA_LIMITS),
1317 NULL);
1318 if (!NT_SUCCESS(Status))
1319 {
1321 return FALSE;
1322 }
1323
1326 &VmCounters,
1327 sizeof(VM_COUNTERS),
1328 NULL);
1329 if (!NT_SUCCESS(Status))
1330 {
1332 return FALSE;
1333 }
1334
1335 /* Save the commit limit */
1336 lpBuffer->ullTotalPageFile = min(QuotaLimits.PagefileLimit,
1337 PerformanceInfo.CommitLimit);
1338 lpBuffer->ullTotalPageFile *= BaseStaticServerData->SysInfo.PageSize;
1339
1340 /* Calculate how many pages are left */
1341 PageFile = PerformanceInfo.CommitLimit - PerformanceInfo.CommittedPages;
1342
1343 /* Save the total */
1344 lpBuffer->ullAvailPageFile = min(PageFile,
1345 QuotaLimits.PagefileLimit -
1346 VmCounters.PagefileUsage);
1347 lpBuffer->ullAvailPageFile *= BaseStaticServerData->SysInfo.PageSize;
1348
1349 /* Now calculate the total virtual space */
1352
1353 /* And finally the available virtual space */
1354 lpBuffer->ullAvailVirtual = lpBuffer->ullTotalVirtual - VmCounters.VirtualSize;
1355 lpBuffer->ullAvailExtendedVirtual = 0;
1356
1357 return TRUE;
1358}
1359
1360/*
1361 * @implemented
1362 */
1363VOID
1364NTAPI
1366{
1367 MEMORYSTATUSEX lpBufferEx;
1368
1369 /* Call the extended function */
1370 lpBufferEx.dwLength = sizeof(MEMORYSTATUSEX);
1371 if (GlobalMemoryStatusEx(&lpBufferEx))
1372 {
1373 /* Reset the right size and fill out the information */
1374 lpBuffer->dwLength = sizeof(MEMORYSTATUS);
1375 lpBuffer->dwMemoryLoad = lpBufferEx.dwMemoryLoad;
1376 lpBuffer->dwTotalPhys = (SIZE_T)min(lpBufferEx.ullTotalPhys, MAXULONG_PTR);
1377 lpBuffer->dwAvailPhys = (SIZE_T)min(lpBufferEx.ullAvailPhys, MAXULONG_PTR);
1378 lpBuffer->dwTotalPageFile = (SIZE_T)min(lpBufferEx.ullTotalPageFile, MAXULONG_PTR);
1379 lpBuffer->dwAvailPageFile = (SIZE_T)min(lpBufferEx.ullAvailPageFile, MAXULONG_PTR);
1380 lpBuffer->dwTotalVirtual = (SIZE_T)min(lpBufferEx.ullTotalVirtual, MAXULONG_PTR);
1381 lpBuffer->dwAvailVirtual = (SIZE_T)min(lpBufferEx.ullAvailVirtual, MAXULONG_PTR);
1382 }
1383}
1384
1385/*
1386 * @implemented
1387 */
1388HLOCAL
1389NTAPI
1391 SIZE_T dwBytes)
1392{
1393 ULONG Flags = 0;
1394 PVOID Ptr = NULL;
1396 PBASE_HEAP_HANDLE_ENTRY HandleEntry;
1397 BASE_TRACE_ALLOC(dwBytes, uFlags);
1399
1400 /* Make sure the flags are valid */
1401 if (uFlags & ~LMEM_VALID_FLAGS)
1402 {
1403 /* They aren't, fail */
1406 return NULL;
1407 }
1408
1409 /* Convert ZEROINIT */
1411
1412 /* Check if we're not movable, which means pointer-based heap */
1413 if (!(uFlags & LMEM_MOVEABLE))
1414 {
1415 /* Allocate heap for it */
1416 Ptr = RtlAllocateHeap(BaseHeap, Flags, dwBytes);
1418 return Ptr;
1419 }
1420
1421 /* This is heap based, so lock it in first */
1423
1424 /*
1425 * Disable locking, enable custom flags, and write the
1426 * movable flag (deprecated)
1427 */
1431
1432 /* Allocate the handle */
1433 HandleEntry = BaseHeapAllocEntry();
1434 if (!HandleEntry)
1435 {
1436 /* Fail */
1437 hMemory = NULL;
1440 goto Quickie;
1441 }
1442
1443 /* Get the object and make sure we have size */
1444 hMemory = &HandleEntry->Object;
1445 if (dwBytes)
1446 {
1447 /* Allocate the actual memory for it */
1448 Ptr = RtlAllocateHeap(BaseHeap, Flags, dwBytes);
1449 BASE_TRACE_PTR(HandleEntry, Ptr);
1450 if (!Ptr)
1451 {
1452 /* We failed, manually set the allocate flag and free the handle */
1453 HandleEntry->Flags = RTL_HANDLE_VALID;
1454 BaseHeapFreeEntry(HandleEntry);
1455
1456 /* For the cleanup case */
1457 HandleEntry = NULL;
1458 }
1459 else
1460 {
1461 /* All worked well, save our heap entry */
1463 }
1464 }
1465
1466Quickie:
1467 /* Cleanup! First unlock the heap */
1469
1470 /* Check if a handle was allocated */
1471 if (HandleEntry)
1472 {
1473 /* Set the pointer and allocated flag */
1474 HandleEntry->Object = Ptr;
1475 HandleEntry->Flags = RTL_HANDLE_VALID;
1476 if (!Ptr)
1477 {
1478 /* We don't have a valid pointer, but so reuse this handle */
1479 HandleEntry->Flags |= BASE_HEAP_ENTRY_FLAG_REUSE;
1480 }
1481
1482 /* Check if the handle is discardable */
1484 {
1485 /* Save it in the handle entry */
1486 HandleEntry->Flags |= BASE_HEAP_ENTRY_FLAG_REUSABLE;
1487 }
1488
1489 /* Check if the handle is moveable */
1490 if (uFlags & GMEM_MOVEABLE)
1491 {
1492 /* Save it in the handle entry */
1493 HandleEntry->Flags |= BASE_HEAP_ENTRY_FLAG_MOVABLE;
1494 }
1495
1496 /* Set the pointer */
1497 Ptr = hMemory;
1498 }
1499
1500 /* Return the pointer */
1501 return Ptr;
1502}
1503
1504/*
1505 * @implemented
1506 */
1507SIZE_T
1508NTAPI
1510{
1511 /* Call the RTL Heap Manager */
1512 return RtlCompactHeap(BaseHeap, 0);
1513}
1514
1515/*
1516 * @implemented
1517 */
1518UINT
1519NTAPI
1521{
1522 PBASE_HEAP_HANDLE_ENTRY HandleEntry;
1523 HANDLE Handle = NULL;
1524 ULONG Flags = 0;
1526
1527 /* Start by locking the heap */
1529
1530 /* Check if this is a simple RTL Heap Managed block */
1531 if (!((ULONG_PTR)hMem & BASE_HEAP_IS_HANDLE_ENTRY))
1532 {
1533 /* Then we'll query RTL Heap */
1535 BASE_TRACE_PTR(Handle, hMem);
1536
1537 /*
1538 * Check if RTL Heap didn't find a handle associated with us or
1539 * said that this heap isn't movable, which means something we're
1540 * really not a handle-based heap.
1541 */
1542 if (!(Handle) || !(Flags & BASE_HEAP_FLAG_MOVABLE))
1543 {
1544 /* Then set the flags to 0 */
1545 uFlags = 0;
1546 }
1547 else
1548 {
1549 /* Otherwise we're handle-based, so get the internal handle */
1550 hMem = Handle;
1551 }
1552 }
1553
1554 /* Check if the handle is actually an entry in our table */
1556 {
1557 /* Then get the entry */
1558 HandleEntry = BaseHeapGetEntry(hMem);
1559 BASE_TRACE_HANDLE(HandleEntry, hMem);
1560
1561 /* Make sure it's a valid handle */
1562 if (BaseHeapValidateEntry(HandleEntry))
1563 {
1564 /* Get the lock count first */
1565 uFlags = HandleEntry->LockCount & LMEM_LOCKCOUNT;
1566
1567 /* Now check if it's discardable */
1568 if (HandleEntry->Flags & BASE_HEAP_ENTRY_FLAG_REUSABLE)
1569 {
1570 /* Set the Win32 Flag */
1572 }
1573
1574 /* Now check if it's discarded */
1575 if (HandleEntry->Flags & BASE_HEAP_ENTRY_FLAG_REUSE)
1576 /* Set the Win32 Flag */
1578 }
1579 }
1580
1581 /* Check if by now, we still haven't gotten any useful flags */
1583
1584 /* All done! Unlock heap and return Win32 Flags */
1586 return uFlags;
1587}
1588
1589/*
1590 * @implemented
1591 */
1592HLOCAL
1593NTAPI
1595{
1596 /* This is identical to a Global Free */
1597 return GlobalFree(hMem);
1598}
1599
1600/*
1601 * @implemented
1602 */
1603HLOCAL
1604NTAPI
1606{
1607 /* This is identical to a Global Handle */
1608 return GlobalHandle(pMem);
1609}
1610
1611/*
1612 * @implemented
1613 */
1614LPVOID
1615NTAPI
1617{
1618 /* This is the same as a GlobalLock, assuming these never change */
1620 return GlobalLock(hMem);
1621}
1622
1623HLOCAL
1624NTAPI
1626 SIZE_T dwBytes,
1627 UINT uFlags)
1628{
1629 PBASE_HEAP_HANDLE_ENTRY HandleEntry;
1630 LPVOID Ptr;
1631 ULONG Flags = 0;
1632
1633 /* Convert ZEROINIT */
1635
1636 /* If this wasn't a movable heap, then we MUST re-alloc in place */
1638
1639 /* Lock the heap and disable built-in locking in the RTL Heap functions */
1642
1643 /* Check if this is a simple handle-based block */
1645 {
1646 /* Get the entry */
1647 HandleEntry = BaseHeapGetEntry(hMem);
1648 BASE_TRACE_HANDLE(HandleEntry, hMem);
1649
1650 /* Make sure the handle is valid */
1651 if (!BaseHeapValidateEntry(HandleEntry))
1652 {
1653 /* Fail */
1656 hMem = NULL;
1657 }
1658 else if (uFlags & LMEM_MODIFY)
1659 {
1660 /* User is changing flags... check if the memory was discardable */
1662 {
1663 /* Then set the flag */
1664 HandleEntry->Flags |= BASE_HEAP_ENTRY_FLAG_REUSABLE;
1665 }
1666 else
1667 {
1668 /* Otherwise, remove the flag */
1669 HandleEntry->Flags &= ~BASE_HEAP_ENTRY_FLAG_REUSABLE;
1670 }
1671 }
1672 else
1673 {
1674 /* Otherwise, get the object and check if we have no size */
1675 Ptr = HandleEntry->Object;
1676 if (!dwBytes)
1677 {
1678 /* Clear the handle and check for a pointer */
1679 hMem = NULL;
1680 if (Ptr)
1681 {
1682 /* Make sure the handle isn't locked */
1683 if ((uFlags & LMEM_MOVEABLE) && !(HandleEntry->LockCount))
1684 {
1685 /* Free the current heap */
1687
1688 /* Free the handle */
1689 HandleEntry->Object = NULL;
1690 HandleEntry->Flags |= BASE_HEAP_ENTRY_FLAG_REUSE;
1691
1692 /* Get the object pointer */
1693 hMem = &HandleEntry->Object;
1694 }
1695 }
1696 else
1697 {
1698 /* Otherwise just return the object pointer */
1699 hMem = &HandleEntry->Object;
1700 }
1701 }
1702 else
1703 {
1704 /* Otherwise, we're allocating, so set the new flags needed */
1706 if (!Ptr)
1707 {
1708 /* We don't have a base, so allocate one */
1709 Ptr = RtlAllocateHeap(BaseHeap, Flags, dwBytes);
1711 if (Ptr)
1712 {
1713 /* Allocation succeeded, so save our entry */
1716 Ptr,
1717 hMem);
1718 }
1719 }
1720 else
1721 {
1722 /*
1723 * If it's not movable or currently locked, we MUST allocate
1724 * in-place!
1725 */
1726 if (!(uFlags & LMEM_MOVEABLE) && (HandleEntry->LockCount))
1727 {
1728 /* Set the flag */
1730 }
1731 else
1732 {
1733 /* Otherwise clear the flag if we set it previously */
1734 Flags &= ~HEAP_REALLOC_IN_PLACE_ONLY;
1735 }
1736
1737 /* And do the re-allocation */
1738 Ptr = RtlReAllocateHeap(BaseHeap, Flags, Ptr, dwBytes);
1739 }
1740
1741 /* Make sure we have a pointer by now */
1742 if (Ptr)
1743 {
1744 /* Write it in the handle entry and mark it in use */
1745 HandleEntry->Object = Ptr;
1746 HandleEntry->Flags &= ~BASE_HEAP_ENTRY_FLAG_REUSE;
1747 }
1748 else
1749 {
1750 /* Otherwise we failed */
1751 hMem = NULL;
1753 }
1754 }
1755 }
1756 }
1757 else if (!(uFlags & LMEM_MODIFY))
1758 {
1759 /* Otherwise, this is a simple RTL Managed Heap, so just call it */
1762 hMem,
1763 dwBytes);
1764 if (!hMem)
1765 {
1766 /* Fail */
1769 }
1770 }
1771
1772 /* All done, unlock the heap and return the pointer */
1774 return hMem;
1775}
1776
1777/*
1778 * @implemented
1779 */
1780SIZE_T
1781WINAPI
1783 UINT cbNewSize)
1784{
1785 /* Call RTL */
1786 return RtlCompactHeap(BaseHeap, 0);
1787}
1788
1789/*
1790 * @implemented
1791 */
1792SIZE_T
1793NTAPI
1795{
1796 /* This is the same as a Global Size */
1797 return GlobalSize(hMem);
1798}
1799
1800/*
1801 * @implemented
1802 */
1803BOOL
1804NTAPI
1806{
1807 PBASE_HEAP_HANDLE_ENTRY HandleEntry;
1808 BOOL RetVal = TRUE;
1809
1810 /* Check if this was a simple allocated heap entry */
1811 if (!((ULONG_PTR)hMem & BASE_HEAP_IS_HANDLE_ENTRY))
1812 {
1813 /* Fail, because LocalUnlock is not supported on LMEM_FIXED allocations */
1815 return FALSE;
1816 }
1817
1818 /* Otherwise, lock the heap */
1820
1821 /* Get the handle entry */
1822 HandleEntry = BaseHeapGetEntry(hMem);
1823 BASE_TRACE_HANDLE(HandleEntry, hMem);
1824 _SEH2_TRY
1825 {
1826 /* Make sure it's valid */
1827 if (!BaseHeapValidateEntry(HandleEntry))
1828 {
1829 /* It's not, fail */
1832 RetVal = FALSE;
1833 }
1834 else
1835 {
1836 /* Otherwise, decrement lock count, unless we're already at 0*/
1837 if (!HandleEntry->LockCount--)
1838 {
1839 /* In which case we simply lock it back and fail */
1840 HandleEntry->LockCount++;
1842 RetVal = FALSE;
1843 }
1844 else if (!HandleEntry->LockCount)
1845 {
1846 /* Nothing to unlock */
1848 RetVal = FALSE;
1849 }
1850 }
1851 }
1853 {
1855 RetVal = FALSE;
1856 }
1857 _SEH2_END;
1858
1859 /* All done. Unlock the heap and return the pointer */
1861 return RetVal;
1862}
1863
1864/* EOF */
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
#define BaseHeapAllocEntry()
Definition: baseheap.h:104
#define BASE_TRACE_DEALLOC(x)
Definition: baseheap.h:56
#define BASE_TRACE_FAILURE()
Definition: baseheap.h:59
#define BASE_HEAP_ENTRY_FLAG_REUSE
Definition: baseheap.h:85
#define BaseHeapGetEntry(h)
Definition: baseheap.h:107
#define BASE_HEAP_FLAG_MOVABLE
Definition: baseheap.h:98
#define BASE_TRACE_ALLOC(x, y)
Definition: baseheap.h:44
#define BASE_TRACE_HANDLE(x, y)
Definition: baseheap.h:53
#define BASE_HEAP_ENTRY_FLAG_MOVABLE
Definition: baseheap.h:83
#define BASE_HEAP_IS_HANDLE_ENTRY
Definition: baseheap.h:91
#define BASE_TRACE_ALLOC2(x)
Definition: baseheap.h:47
#define BaseHeapFreeEntry(he)
Definition: baseheap.h:116
#define BaseHeapValidateEntry(he)
Definition: baseheap.h:113
#define BASE_TRACE_PTR(x, y)
Definition: baseheap.h:50
#define BASE_HEAP_ENTRY_FLAG_REUSABLE
Definition: baseheap.h:84
#define BASE_HEAP_ENTRY_FLAG_DDESHARE
Definition: baseheap.h:86
#define MAXULONG_PTR
Definition: basetsd.h:103
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:590
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:608
#define STATUS_NOT_IMPLEMENTED
Definition: d3dkmdt.h:42
static TAGREF LPCWSTR LPDWORD LPVOID lpBuffer
Definition: db.cpp:175
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define NO_ERROR
Definition: dderror.h:5
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
UINT uFlags
Definition: api.c:59
#define GetProcessHeap()
Definition: compat.h:736
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define SetLastError(x)
Definition: compat.h:752
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
PBASE_STATIC_SERVER_DATA BaseStaticServerData
Definition: dllmain.c:19
BOOL WINAPI IsBadReadPtr(IN LPCVOID lp, IN UINT_PTR ucb)
Definition: except.c:805
IN CINT OUT PVOID IN ULONG OUT PULONG ReturnLength
Definition: dumpinfo.c:43
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
WDFMEMORY hMemory
ULONG Handle
Definition: gdb_input.c:15
Status
Definition: gdiplustypes.h:25
LPVOID NTAPI GlobalWire(HGLOBAL hMem)
Definition: heapmem.c:1261
BOOL WINAPI HeapQueryInformation(HANDLE HeapHandle, HEAP_INFORMATION_CLASS HeapInformationClass, PVOID HeapInformation OPTIONAL, SIZE_T HeapInformationLength OPTIONAL, PSIZE_T ReturnLength OPTIONAL)
Definition: heapmem.c:314
VOID NTAPI BaseDllInitializeMemoryManager(VOID)
Definition: heapmem.c:26
HGLOBAL NTAPI GlobalHandle(LPCVOID pMem)
Definition: heapmem.c:705
LPVOID NTAPI GlobalLock(HGLOBAL hMem)
Definition: heapmem.c:755
HANDLE WINAPI HeapCreate(DWORD flOptions, SIZE_T dwInitialSize, SIZE_T dwMaximumSize)
Definition: heapmem.c:45
HGLOBAL NTAPI GlobalFree(HGLOBAL hMem)
Definition: heapmem.c:611
HGLOBAL NTAPI GlobalReAlloc(HGLOBAL hMem, SIZE_T dwBytes, UINT uFlags)
Definition: heapmem.c:825
UINT NTAPI GlobalFlags(HGLOBAL hMem)
Definition: heapmem.c:520
HLOCAL NTAPI LocalReAlloc(HLOCAL hMem, SIZE_T dwBytes, UINT uFlags)
Definition: heapmem.c:1625
SIZE_T WINAPI HeapCompact(HANDLE hHeap, DWORD dwFlags)
Definition: heapmem.c:145
SIZE_T WINAPI LocalShrink(HLOCAL hMem, UINT cbNewSize)
Definition: heapmem.c:1782
BOOL NTAPI GlobalUnWire(HGLOBAL hMem)
Definition: heapmem.c:1250
BOOL NTAPI GlobalUnlock(HGLOBAL hMem)
Definition: heapmem.c:1190
HLOCAL NTAPI LocalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:1390
DWORD WINAPI HeapExtend(HANDLE hHeap, DWORD dwFlags, PVOID BaseAddress, DWORD dwBytes)
Definition: heapmem.c:186
BOOL WINAPI HeapLock(HANDLE hHeap)
Definition: heapmem.c:123
LPVOID NTAPI LocalLock(HLOCAL hMem)
Definition: heapmem.c:1616
BOOL NTAPI LocalUnlock(HLOCAL hMem)
Definition: heapmem.c:1805
BOOL WINAPI HeapValidate(HANDLE hHeap, DWORD dwFlags, LPCVOID lpMem)
Definition: heapmem.c:156
PWSTR WINAPI HeapQueryTagW(HANDLE hHeap, DWORD dwFlags, WORD wTagIndex, BOOL bResetCounters, PVOID lpTagInfo)
Definition: heapmem.c:211
BOOL WINAPI HeapUnlock(HANDLE hHeap)
Definition: heapmem.c:134
SIZE_T NTAPI LocalCompact(UINT dwMinFree)
Definition: heapmem.c:1509
ULONG_PTR SystemRangeStart
Definition: heapmem.c:20
VOID NTAPI GlobalMemoryStatus(LPMEMORYSTATUS lpBuffer)
Definition: heapmem.c:1365
BOOL WINAPI HeapSetInformation(HANDLE HeapHandle, HEAP_INFORMATION_CLASS HeapInformationClass, PVOID HeapInformation OPTIONAL, SIZE_T HeapInformationLength OPTIONAL)
Definition: heapmem.c:342
VOID NTAPI GlobalUnfix(HGLOBAL hMem)
Definition: heapmem.c:1179
BOOL WINAPI HeapDestroy(HANDLE hHeap)
Definition: heapmem.c:85
RTL_HANDLE_TABLE BaseHeapHandleTable
Definition: heapmem.c:18
HANDLE BaseHeap
Definition: heapmem.c:19
SIZE_T NTAPI LocalSize(HLOCAL hMem)
Definition: heapmem.c:1794
BOOL WINAPI HeapWalk(HANDLE hHeap, LPPROCESS_HEAP_ENTRY lpEntry)
Definition: heapmem.c:291
BOOL WINAPI HeapUsage(HANDLE hHeap, DWORD dwFlags, DWORD Unknown, DWORD Unknown2, IN PVOID Usage)
Definition: heapmem.c:259
HLOCAL NTAPI LocalHandle(LPCVOID pMem)
Definition: heapmem.c:1605
VOID NTAPI GlobalFix(HGLOBAL hMem)
Definition: heapmem.c:509
UINT NTAPI LocalFlags(HLOCAL hMem)
Definition: heapmem.c:1520
BOOL WINAPI HeapSummary(HANDLE hHeap, DWORD dwFlags, PVOID Summary)
Definition: heapmem.c:230
HGLOBAL NTAPI GlobalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:368
SIZE_T NTAPI GlobalCompact(DWORD dwMinFree)
Definition: heapmem.c:498
SIZE_T NTAPI GlobalSize(HGLOBAL hMem)
Definition: heapmem.c:1090
DWORD WINAPI GetProcessHeaps(DWORD NumberOfHeaps, PHANDLE ProcessHeaps)
Definition: heapmem.c:111
DWORD WINAPI HeapCreateTagsW(_In_ HANDLE hHeap, _In_ DWORD dwFlags, _In_opt_ PWSTR lpTagName, _In_ PWSTR lpTagSubName)
Definition: heapmem.c:169
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1594
BOOL NTAPI GlobalMemoryStatusEx(LPMEMORYSTATUSEX lpBuffer)
Definition: heapmem.c:1272
_Must_inspect_result_ _In_ USAGE _In_ USHORT _In_ USAGE Usage
Definition: hidpi.h:384
@ Unknown
Definition: i8042prt.h:114
NTSYSAPI PVOID WINAPI RtlReAllocateHeap(HANDLE, ULONG, PVOID, SIZE_T)
Definition: heap.c:2686
NTSYSAPI ULONG WINAPI RtlGetProcessHeaps(ULONG, HANDLE *)
NTSYSAPI NTSTATUS WINAPI RtlWalkHeap(HANDLE, PVOID)
NTSYSAPI BOOLEAN WINAPI RtlValidateHeap(HANDLE, ULONG, LPCVOID)
@ ProcessVmCounters
Definition: winternl.h:859
@ ProcessQuotaLimits
Definition: winternl.h:857
NTSYSAPI NTSTATUS WINAPI RtlSetHeapInformation(HANDLE, HEAP_INFORMATION_CLASS, PVOID, SIZE_T)
NTSYSAPI BOOLEAN WINAPI RtlUnlockHeap(HANDLE)
Definition: heap.c:3162
NTSYSAPI ULONG WINAPI RtlNtStatusToDosError(NTSTATUS)
NTSYSAPI NTSTATUS WINAPI RtlQueryHeapInformation(HANDLE, HEAP_INFORMATION_CLASS, PVOID, SIZE_T, PSIZE_T)
NTSYSAPI BOOLEAN WINAPI RtlLockHeap(HANDLE)
NTSYSAPI ULONG WINAPI RtlCompactHeap(HANDLE, ULONG)
Definition: heap.c:3103
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
#define C_ASSERT(e)
Definition: intsafe.h:73
if(dx< 0)
Definition: linetemp.h:194
struct _QUOTA_LIMITS QUOTA_LIMITS
#define SystemPerformanceInformation
Definition: memtest.h:87
#define ASSERT(a)
Definition: mode.c:44
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:56
#define min(a, b)
Definition: monoChain.cc:55
unsigned int UINT
Definition: ndis.h:50
@ SystemRangeStartInformation
Definition: extypes.h:267
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
NTSYSAPI VOID NTAPI RtlInitializeHandleTable(_In_ ULONG TableSize, _In_ ULONG HandleSize, _In_ PRTL_HANDLE_TABLE HandleTable)
NTSYSAPI SIZE_T NTAPI RtlSizeHeap(_In_ PVOID HeapHandle, _In_ ULONG Flags, _In_ PVOID MemoryPointer)
#define RTL_HANDLE_VALID
Definition: rtltypes.h:376
enum _HEAP_INFORMATION_CLASS HEAP_INFORMATION_CLASS
#define _In_
Definition: no_sal2.h:158
#define _In_opt_
Definition: no_sal2.h:212
NTSYSAPI PVOID NTAPI RtlDestroyHeap(IN PVOID HeapHandle)
#define HEAP_CLASS_1
Definition: nt_native.h:1711
#define HEAP_GENERATE_EXCEPTIONS
Definition: nt_native.h:1694
NTSYSAPI PVOID NTAPI RtlCreateHeap(IN ULONG Flags, IN PVOID HeapBase OPTIONAL, IN ULONG ReserveSize OPTIONAL, IN ULONG CommitSize OPTIONAL, IN PVOID Lock OPTIONAL, IN PRTL_HEAP_PARAMETERS Parameters OPTIONAL)
#define NtCurrentProcess()
Definition: nt_native.h:1657
#define HEAP_GROWABLE
Definition: nt_native.h:1693
#define HEAP_SETTABLE_USER_VALUE
Definition: nt_native.h:1704
#define DWORD
Definition: nt_native.h:44
#define HEAP_REALLOC_IN_PLACE_ONLY
Definition: nt_native.h:1696
#define HEAP_NO_SERIALIZE
Definition: nt_native.h:1692
NTSTATUS NTAPI NtQueryInformationProcess(_In_ HANDLE ProcessHandle, _In_ PROCESSINFOCLASS ProcessInformationClass, _Out_ PVOID ProcessInformation, _In_ ULONG ProcessInformationLength, _Out_opt_ PULONG ReturnLength)
Definition: query.c:59
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:66
#define _SEH2_END
Definition: pseh2_64.h:155
#define _SEH2_TRY
Definition: pseh2_64.h:55
DWORD BaseSetLastNTError(IN NTSTATUS Status)
Definition: reactos.cpp:167
BOOLEAN NTAPI RtlGetUserInfoHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID BaseAddress, OUT PVOID *UserValue, OUT PULONG UserFlags)
Definition: heap.c:3934
PWSTR NTAPI RtlQueryTagHeap(IN PVOID HeapHandle, IN ULONG Flags, IN USHORT TagIndex, IN BOOLEAN ResetCounters, OUT PRTL_HEAP_TAG_INFO HeapTagInfo)
Definition: heap.c:4012
ULONG NTAPI RtlCreateTagHeap(_In_ HANDLE HeapHandle, _In_ ULONG Flags, _In_opt_ PWSTR TagName, _In_ PWSTR TagSubName)
Definition: heap.c:4037
BOOLEAN NTAPI RtlSetUserValueHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID BaseAddress, IN PVOID UserValue)
Definition: heap.c:3817
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
NTSYSAPI NTSTATUS NTAPI NtQuerySystemInformation(IN SYSTEM_INFORMATION_CLASS SystemInfoClass, OUT PVOID SystemInfoBuffer, IN ULONG SystemInfoBufferSize, OUT PULONG BytesReturned OPTIONAL)
Definition: baseheap.h:69
ULONG OldSize
Definition: baseheap.h:75
USHORT LockCount
Definition: baseheap.h:71
USHORT Flags
Definition: baseheap.h:70
PVOID Object
Definition: baseheap.h:74
SYSTEM_BASIC_INFORMATION SysInfo
Definition: base.h:130
Definition: winbase.h:1293
INT64 PagefileLimit
Definition: lsa.idl:291
SIZE_T VirtualSize
Definition: winternl.h:1606
SIZE_T PagefileUsage
Definition: winternl.h:1614
ULONG_PTR * PSIZE_T
Definition: typedefs.h:80
uint16_t * PWSTR
Definition: typedefs.h:56
#define NTAPI
Definition: typedefs.h:36
PVOID HANDLE
Definition: typedefs.h:73
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
uint32_t ULONG
Definition: typedefs.h:59
uint64_t ULONGLONG
Definition: typedefs.h:67
#define STATUS_MORE_ENTRIES
Definition: udferr_usr.h:124
#define LMEM_MOVEABLE
Definition: winbase.h:395
#define LMEM_ZEROINIT
Definition: winbase.h:401
#define GMEM_DISCARDABLE
Definition: winbase.h:325
#define GMEM_VALID_FLAGS
Definition: winbase.h:336
#define LMEM_DISCARDED
Definition: winbase.h:402
#define GMEM_LOCKCOUNT
Definition: winbase.h:335
struct _MEMORYSTATUS MEMORYSTATUS
#define GMEM_DISCARDED
Definition: winbase.h:333
#define LMEM_VALID_FLAGS
Definition: winbase.h:406
#define GMEM_INVALID_HANDLE
Definition: winbase.h:334
#define GMEM_ZEROINIT
Definition: winbase.h:332
#define GMEM_MODIFY
Definition: winbase.h:321
#define LMEM_INVALID_HANDLE
Definition: winbase.h:404
#define LMEM_DISCARDABLE
Definition: winbase.h:398
#define GMEM_MOVEABLE
Definition: winbase.h:320
#define GMEM_DDESHARE
Definition: winbase.h:324
#define LMEM_LOCKCOUNT
Definition: winbase.h:405
#define LMEM_MODIFY
Definition: winbase.h:403
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1176
_In_ PATHOBJ _In_ CLIPOBJ _In_ BRUSHOBJ _In_ POINTL _In_ MIX _In_ FLONG flOptions
Definition: winddi.h:3596
CONST void * LPCVOID
Definition: windef.h:191
#define WINAPI
Definition: msvc.h:6
#define ERROR_DISCARDED
Definition: winerror.h:229
#define ERROR_NOT_LOCKED
Definition: winerror.h:230
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170