ReactOS  0.4.14-dev-593-g1793dcc
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 
24 VOID
25 NTAPI
27 {
28  BaseHeap = RtlGetProcessHeap();
30  sizeof(BASE_HEAP_HANDLE_ENTRY),
34  sizeof(SystemRangeStart),
35  NULL);
36 }
37 
38 /* PUBLIC FUNCTIONS ***********************************************************/
39 
40 /*
41  * @implemented
42  */
43 HANDLE
44 WINAPI
46  SIZE_T dwInitialSize,
47  SIZE_T dwMaximumSize)
48 {
49  HANDLE hRet;
50  ULONG Flags;
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  */
83 BOOL
84 WINAPI
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  */
98 HANDLE
99 WINAPI
101 {
102  /* Call the RTL API */
103  return RtlGetProcessHeap();
104 }
105 
106 /*
107  * @implemented
108  */
109 DWORD
110 WINAPI
111 GetProcessHeaps(DWORD NumberOfHeaps,
112  PHANDLE ProcessHeaps)
113 {
114  /* Call the RTL API */
115  return RtlGetProcessHeaps(NumberOfHeaps, ProcessHeaps);
116 }
117 
118 /*
119  * @implemented
120  */
121 BOOL
122 WINAPI
124 {
125  /* Call the RTL API */
126  return RtlLockHeap(hHeap);
127 }
128 
129 /*
130  * @implemented
131  */
132 BOOL
133 WINAPI
135 {
136  /* Call the RTL API */
137  return RtlUnlockHeap(hHeap);
138 }
139 
140 /*
141  * @implemented
142  */
143 SIZE_T
144 WINAPI
146 {
147  /* Call the RTL API */
148  return RtlCompactHeap(hHeap, dwFlags);
149 }
150 
151 /*
152  * @implemented
153  */
154 BOOL
155 WINAPI
157  DWORD dwFlags,
158  LPCVOID lpMem)
159 {
160  /* Call the RTL API */
161  return RtlValidateHeap(hHeap, dwFlags, (PVOID)lpMem);
162 }
163 
164 /*
165  * @implemented
166  */
167 DWORD
168 WINAPI
170  DWORD dwFlags,
171  PWSTR lpTagName,
172  PWSTR lpTagSubName)
173 {
174  /* Call the RTL API */
175  return RtlCreateTagHeap(hHeap,
176  dwFlags,
177  lpTagName,
178  lpTagSubName);
179 }
180 
181 /*
182  * @implemented
183  */
184 DWORD
185 WINAPI
187  DWORD dwFlags,
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  */
209 PWSTR
210 WINAPI
212  DWORD dwFlags,
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  */
228 BOOL
229 WINAPI
231  DWORD dwFlags,
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  */
257 BOOL
258 WINAPI
260  DWORD dwFlags,
261  DWORD Unknown,
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  */
289 BOOL
290 WINAPI
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  */
312 BOOL
313 WINAPI
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,
326  ReturnLength);
327 
328  if (!NT_SUCCESS(Status))
329  {
331  return FALSE;
332  }
333 
334  return TRUE;
335 }
336 
337 /*
338  * @implemented
339  */
340 BOOL
341 WINAPI
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  */
366 HGLOBAL
367 NTAPI
369  SIZE_T dwBytes)
370 {
371  ULONG Flags = 0;
372  PVOID Ptr = NULL;
373  HANDLE hMemory;
374  PBASE_HEAP_HANDLE_ENTRY HandleEntry;
375  BASE_TRACE_ALLOC(dwBytes, uFlags);
376  ASSERT(BaseHeap);
377 
378  /* Make sure the flags are valid */
379  if (uFlags & ~GMEM_VALID_FLAGS)
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 */
465  if (uFlags & GMEM_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  */
496 SIZE_T
497 NTAPI
499 {
500  /* Call the RTL Heap Manager */
501  return RtlCompactHeap(BaseHeap, 0);
502 }
503 
504 /*
505  * @implemented
506  */
507 VOID
508 NTAPI
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  */
518 UINT
519 NTAPI
521 {
522  PBASE_HEAP_HANDLE_ENTRY HandleEntry;
523  HANDLE Handle = NULL;
524  ULONG Flags = 0;
526 
527  /* Start by locking the heap */
529  _SEH2_TRY
530  {
531  /* Check if this is a simple RTL Heap Managed block */
532  if (!((ULONG_PTR)hMem & BASE_HEAP_IS_HANDLE_ENTRY))
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  */
609 HGLOBAL
610 NTAPI
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 */
618  if (!((ULONG_PTR)hMem & BASE_HEAP_IS_HANDLE_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 */
637  _SEH2_TRY
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  */
703 HGLOBAL
704 NTAPI
706 {
707  HANDLE Handle = NULL;
708  ULONG Flags;
709 
710  /* Lock the heap */
712  _SEH2_TRY
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  */
753 LPVOID
754 NTAPI
756 {
757  PBASE_HEAP_HANDLE_ENTRY HandleEntry;
758  LPVOID Ptr;
759 
760  /* Check if this was a simple allocated heap entry */
761  if (!((ULONG_PTR)hMem & BASE_HEAP_IS_HANDLE_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 */
777  _SEH2_TRY
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 
823 HGLOBAL
824 NTAPI
826  SIZE_T dwBytes,
827  UINT uFlags)
828 {
829  PBASE_HEAP_HANDLE_ENTRY HandleEntry;
830  HANDLE Handle;
831  LPVOID Ptr;
832  ULONG Flags = 0;
833 
834  /* Throw out invalid flags */
836  {
838  return NULL;
839  }
840 
841  /* Throw out invalid combo */
842  if ((uFlags & GMEM_DISCARDABLE) && !(uFlags & GMEM_MODIFY))
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 */
859  if (((ULONG_PTR)hMem & BASE_HEAP_IS_HANDLE_ENTRY))
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 */
876  if (uFlags & GMEM_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 */
901  if (RtlFreeHeap(BaseHeap, Flags, Ptr))
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 */
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 */
1068  hMem = RtlReAllocateHeap(BaseHeap,
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  */
1088 SIZE_T
1089 NTAPI
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 */
1105  if (RtlGetUserInfoHeap(BaseHeap, Flags, hMem, &Handle, &Flags))
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 */
1156  dwSize = MAXULONG_PTR;
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  */
1177 VOID
1178 NTAPI
1180 {
1181  /* If the handle is valid, unlock it */
1182  if (hMem != INVALID_HANDLE_VALUE) GlobalUnlock(hMem);
1183 }
1184 
1185 /*
1186  * @implemented
1187  */
1188 BOOL
1189 NTAPI
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  */
1248 BOOL
1249 NTAPI
1251 {
1252  /* This is simply an unlock */
1253  return GlobalUnlock(hMem);
1254 }
1255 
1256 /*
1257  * @implemented
1258  */
1259 LPVOID
1260 NTAPI
1262 {
1263  /* This is just a lock */
1264  return GlobalLock(hMem);
1265 }
1266 
1267 /*
1268  * @implemented
1269  */
1270 BOOL
1271 NTAPI
1273 {
1274  SYSTEM_PERFORMANCE_INFORMATION PerformanceInfo;
1275  VM_COUNTERS VmCounters;
1276  QUOTA_LIMITS QuotaLimits;
1277  ULONGLONG PageFile, PhysicalMemory;
1278 
1279  if (lpBuffer->dwLength != sizeof(*lpBuffer))
1280  {
1282  return FALSE;
1283  }
1284 
1285  /* Query performance information */
1287  &PerformanceInfo,
1288  sizeof(PerformanceInfo),
1289  NULL);
1290 
1291  /* Calculate memory load */
1293  PerformanceInfo.AvailablePages) * 100) /
1295 
1296  /* Save physical memory */
1299  lpBuffer->ullTotalPhys = PhysicalMemory;
1300 
1301  /* Now save available physical memory */
1302  PhysicalMemory = PerformanceInfo.AvailablePages *
1304  lpBuffer->ullAvailPhys = PhysicalMemory;
1305 
1306  /* Query VM and Quota Limits */
1309  &QuotaLimits,
1310  sizeof(QUOTA_LIMITS),
1311  NULL);
1314  &VmCounters,
1315  sizeof(VM_COUNTERS),
1316  NULL);
1317 
1318  /* Save the commit limit */
1319  lpBuffer->ullTotalPageFile = min(QuotaLimits.PagefileLimit,
1320  PerformanceInfo.CommitLimit);
1321  lpBuffer->ullTotalPageFile *= BaseStaticServerData->SysInfo.PageSize;
1322 
1323  /* Calculate how many pages are left */
1324  PageFile = PerformanceInfo.CommitLimit - PerformanceInfo.CommittedPages;
1325 
1326  /* Save the total */
1327  lpBuffer->ullAvailPageFile = min(PageFile,
1328  QuotaLimits.PagefileLimit -
1329  VmCounters.PagefileUsage);
1330  lpBuffer->ullAvailPageFile *= BaseStaticServerData->SysInfo.PageSize;
1331 
1332  /* Now calculate the total virtual space */
1335 
1336  /* And finally the available virtual space */
1337  lpBuffer->ullAvailVirtual = lpBuffer->ullTotalVirtual - VmCounters.VirtualSize;
1338  lpBuffer->ullAvailExtendedVirtual = 0;
1339 
1340  return TRUE;
1341 }
1342 
1343 /*
1344  * @implemented
1345  */
1346 VOID
1347 NTAPI
1349 {
1350  MEMORYSTATUSEX lpBufferEx;
1351 
1352  /* Call the extended function */
1353  lpBufferEx.dwLength = sizeof(MEMORYSTATUSEX);
1354  if (GlobalMemoryStatusEx(&lpBufferEx))
1355  {
1356  /* Reset the right size and fill out the information */
1357  lpBuffer->dwLength = sizeof(MEMORYSTATUS);
1358  lpBuffer->dwMemoryLoad = lpBufferEx.dwMemoryLoad;
1359  lpBuffer->dwTotalPhys = (SIZE_T)min(lpBufferEx.ullTotalPhys, MAXULONG_PTR);
1360  lpBuffer->dwAvailPhys = (SIZE_T)min(lpBufferEx.ullAvailPhys, MAXULONG_PTR);
1361  lpBuffer->dwTotalPageFile = (SIZE_T)min(lpBufferEx.ullTotalPageFile, MAXULONG_PTR);
1362  lpBuffer->dwAvailPageFile = (SIZE_T)min(lpBufferEx.ullAvailPageFile, MAXULONG_PTR);
1363  lpBuffer->dwTotalVirtual = (SIZE_T)min(lpBufferEx.ullTotalVirtual, MAXULONG_PTR);
1364  lpBuffer->dwAvailVirtual = (SIZE_T)min(lpBufferEx.ullAvailVirtual, MAXULONG_PTR);
1365  }
1366 }
1367 
1368 /*
1369  * @implemented
1370  */
1371 HLOCAL
1372 NTAPI
1374  SIZE_T dwBytes)
1375 {
1376  ULONG Flags = 0;
1377  PVOID Ptr = NULL;
1378  HANDLE hMemory;
1379  PBASE_HEAP_HANDLE_ENTRY HandleEntry;
1380  BASE_TRACE_ALLOC(dwBytes, uFlags);
1381  ASSERT(BaseHeap);
1382 
1383  /* Make sure the flags are valid */
1384  if (uFlags & ~LMEM_VALID_FLAGS)
1385  {
1386  /* They aren't, fail */
1389  return NULL;
1390  }
1391 
1392  /* Convert ZEROINIT */
1394 
1395  /* Check if we're not movable, which means pointer-based heap */
1396  if (!(uFlags & LMEM_MOVEABLE))
1397  {
1398  /* Allocate heap for it */
1399  Ptr = RtlAllocateHeap(BaseHeap, Flags, dwBytes);
1401  return Ptr;
1402  }
1403 
1404  /* This is heap based, so lock it in first */
1406 
1407  /*
1408  * Disable locking, enable custom flags, and write the
1409  * movable flag (deprecated)
1410  */
1414 
1415  /* Allocate the handle */
1416  HandleEntry = BaseHeapAllocEntry();
1417  if (!HandleEntry)
1418  {
1419  /* Fail */
1420  hMemory = NULL;
1423  goto Quickie;
1424  }
1425 
1426  /* Get the object and make sure we have size */
1427  hMemory = &HandleEntry->Object;
1428  if (dwBytes)
1429  {
1430  /* Allocate the actual memory for it */
1431  Ptr = RtlAllocateHeap(BaseHeap, Flags, dwBytes);
1432  BASE_TRACE_PTR(HandleEntry, Ptr);
1433  if (!Ptr)
1434  {
1435  /* We failed, manually set the allocate flag and free the handle */
1436  HandleEntry->Flags = RTL_HANDLE_VALID;
1437  BaseHeapFreeEntry(HandleEntry);
1438 
1439  /* For the cleanup case */
1440  HandleEntry = NULL;
1441  }
1442  else
1443  {
1444  /* All worked well, save our heap entry */
1446  }
1447  }
1448 
1449 Quickie:
1450  /* Cleanup! First unlock the heap */
1452 
1453  /* Check if a handle was allocated */
1454  if (HandleEntry)
1455  {
1456  /* Set the pointer and allocated flag */
1457  HandleEntry->Object = Ptr;
1458  HandleEntry->Flags = RTL_HANDLE_VALID;
1459  if (!Ptr)
1460  {
1461  /* We don't have a valid pointer, but so reuse this handle */
1462  HandleEntry->Flags |= BASE_HEAP_ENTRY_FLAG_REUSE;
1463  }
1464 
1465  /* Check if the handle is discardable */
1466  if (uFlags & GMEM_DISCARDABLE)
1467  {
1468  /* Save it in the handle entry */
1469  HandleEntry->Flags |= BASE_HEAP_ENTRY_FLAG_REUSABLE;
1470  }
1471 
1472  /* Check if the handle is moveable */
1473  if (uFlags & GMEM_MOVEABLE)
1474  {
1475  /* Save it in the handle entry */
1476  HandleEntry->Flags |= BASE_HEAP_ENTRY_FLAG_MOVABLE;
1477  }
1478 
1479  /* Set the pointer */
1480  Ptr = hMemory;
1481  }
1482 
1483  /* Return the pointer */
1484  return Ptr;
1485 }
1486 
1487 /*
1488  * @implemented
1489  */
1490 SIZE_T
1491 NTAPI
1492 LocalCompact(UINT dwMinFree)
1493 {
1494  /* Call the RTL Heap Manager */
1495  return RtlCompactHeap(BaseHeap, 0);
1496 }
1497 
1498 /*
1499  * @implemented
1500  */
1501 UINT
1502 NTAPI
1504 {
1505  PBASE_HEAP_HANDLE_ENTRY HandleEntry;
1506  HANDLE Handle = NULL;
1507  ULONG Flags = 0;
1509 
1510  /* Start by locking the heap */
1512 
1513  /* Check if this is a simple RTL Heap Managed block */
1514  if (!((ULONG_PTR)hMem & BASE_HEAP_IS_HANDLE_ENTRY))
1515  {
1516  /* Then we'll query RTL Heap */
1518  BASE_TRACE_PTR(Handle, hMem);
1519 
1520  /*
1521  * Check if RTL Heap didn't find a handle associated with us or
1522  * said that this heap isn't movable, which means something we're
1523  * really not a handle-based heap.
1524  */
1525  if (!(Handle) || !(Flags & BASE_HEAP_FLAG_MOVABLE))
1526  {
1527  /* Then set the flags to 0 */
1528  uFlags = 0;
1529  }
1530  else
1531  {
1532  /* Otherwise we're handle-based, so get the internal handle */
1533  hMem = Handle;
1534  }
1535  }
1536 
1537  /* Check if the handle is actually an entry in our table */
1539  {
1540  /* Then get the entry */
1541  HandleEntry = BaseHeapGetEntry(hMem);
1542  BASE_TRACE_HANDLE(HandleEntry, hMem);
1543 
1544  /* Make sure it's a valid handle */
1545  if (BaseHeapValidateEntry(HandleEntry))
1546  {
1547  /* Get the lock count first */
1548  uFlags = HandleEntry->LockCount & LMEM_LOCKCOUNT;
1549 
1550  /* Now check if it's discardable */
1551  if (HandleEntry->Flags & BASE_HEAP_ENTRY_FLAG_REUSABLE)
1552  {
1553  /* Set the Win32 Flag */
1555  }
1556 
1557  /* Now check if it's discarded */
1558  if (HandleEntry->Flags & BASE_HEAP_ENTRY_FLAG_REUSE)
1559  /* Set the Win32 Flag */
1561  }
1562  }
1563 
1564  /* Check if by now, we still haven't gotten any useful flags */
1566 
1567  /* All done! Unlock heap and return Win32 Flags */
1569  return uFlags;
1570 }
1571 
1572 /*
1573  * @implemented
1574  */
1575 HLOCAL
1576 NTAPI
1578 {
1579  /* This is identical to a Global Free */
1580  return GlobalFree(hMem);
1581 }
1582 
1583 /*
1584  * @implemented
1585  */
1586 HLOCAL
1587 NTAPI
1589 {
1590  /* This is identical to a Global Handle */
1591  return GlobalHandle(pMem);
1592 }
1593 
1594 /*
1595  * @implemented
1596  */
1597 LPVOID
1598 NTAPI
1600 {
1601  /* This is the same as a GlobalLock, assuming these never change */
1603  return GlobalLock(hMem);
1604 }
1605 
1606 HLOCAL
1607 NTAPI
1609  SIZE_T dwBytes,
1610  UINT uFlags)
1611 {
1612  PBASE_HEAP_HANDLE_ENTRY HandleEntry;
1613  LPVOID Ptr;
1614  ULONG Flags = 0;
1615 
1616  /* Convert ZEROINIT */
1618 
1619  /* If this wasn't a movable heap, then we MUST re-alloc in place */
1621 
1622  /* Lock the heap and disable built-in locking in the RTL Heap functions */
1625 
1626  /* Check if this is a simple handle-based block */
1627  if (((ULONG_PTR)hMem & BASE_HEAP_IS_HANDLE_ENTRY))
1628  {
1629  /* Get the entry */
1630  HandleEntry = BaseHeapGetEntry(hMem);
1631  BASE_TRACE_HANDLE(HandleEntry, hMem);
1632 
1633  /* Make sure the handle is valid */
1634  if (!BaseHeapValidateEntry(HandleEntry))
1635  {
1636  /* Fail */
1639  hMem = NULL;
1640  }
1641  else if (uFlags & LMEM_MODIFY)
1642  {
1643  /* User is changing flags... check if the memory was discardable */
1644  if (uFlags & LMEM_DISCARDABLE)
1645  {
1646  /* Then set the flag */
1647  HandleEntry->Flags |= BASE_HEAP_ENTRY_FLAG_REUSABLE;
1648  }
1649  else
1650  {
1651  /* Otherwise, remove the flag */
1652  HandleEntry->Flags &= ~BASE_HEAP_ENTRY_FLAG_REUSABLE;
1653  }
1654  }
1655  else
1656  {
1657  /* Otherwise, get the object and check if we have no size */
1658  Ptr = HandleEntry->Object;
1659  if (!dwBytes)
1660  {
1661  /* Clear the handle and check for a pointer */
1662  hMem = NULL;
1663  if (Ptr)
1664  {
1665  /* Make sure the handle isn't locked */
1666  if ((uFlags & LMEM_MOVEABLE) && !(HandleEntry->LockCount))
1667  {
1668  /* Free the current heap */
1670 
1671  /* Free the handle */
1672  HandleEntry->Object = NULL;
1673  HandleEntry->Flags |= BASE_HEAP_ENTRY_FLAG_REUSE;
1674 
1675  /* Get the object pointer */
1676  hMem = &HandleEntry->Object;
1677  }
1678  }
1679  else
1680  {
1681  /* Otherwise just return the object pointer */
1682  hMem = &HandleEntry->Object;
1683  }
1684  }
1685  else
1686  {
1687  /* Otherwise, we're allocating, so set the new flags needed */
1689  if (!Ptr)
1690  {
1691  /* We don't have a base, so allocate one */
1692  Ptr = RtlAllocateHeap(BaseHeap, Flags, dwBytes);
1694  if (Ptr)
1695  {
1696  /* Allocation succeeded, so save our entry */
1699  Ptr,
1700  hMem);
1701  }
1702  }
1703  else
1704  {
1705  /*
1706  * If it's not movable or currently locked, we MUST allocate
1707  * in-place!
1708  */
1709  if (!(uFlags & LMEM_MOVEABLE) && (HandleEntry->LockCount))
1710  {
1711  /* Set the flag */
1713  }
1714  else
1715  {
1716  /* Otherwise clear the flag if we set it previously */
1718  }
1719 
1720  /* And do the re-allocation */
1721  Ptr = RtlReAllocateHeap(BaseHeap, Flags, Ptr, dwBytes);
1722  }
1723 
1724  /* Make sure we have a pointer by now */
1725  if (Ptr)
1726  {
1727  /* Write it in the handle entry and mark it in use */
1728  HandleEntry->Object = Ptr;
1729  HandleEntry->Flags &= ~BASE_HEAP_ENTRY_FLAG_REUSE;
1730  }
1731  else
1732  {
1733  /* Otherwise we failed */
1734  hMem = NULL;
1736  }
1737  }
1738  }
1739  }
1740  else if (!(uFlags & LMEM_MODIFY))
1741  {
1742  /* Otherwise, this is a simple RTL Managed Heap, so just call it */
1743  hMem = RtlReAllocateHeap(BaseHeap,
1745  hMem,
1746  dwBytes);
1747  if (!hMem)
1748  {
1749  /* Fail */
1752  }
1753  }
1754 
1755  /* All done, unlock the heap and return the pointer */
1757  return hMem;
1758 }
1759 
1760 /*
1761  * @implemented
1762  */
1763 SIZE_T
1764 WINAPI
1766  UINT cbNewSize)
1767 {
1768  /* Call RTL */
1769  return RtlCompactHeap(BaseHeap, 0);
1770 }
1771 
1772 /*
1773  * @implemented
1774  */
1775 SIZE_T
1776 NTAPI
1778 {
1779  /* This is the same as a Global Size */
1780  return GlobalSize(hMem);
1781 }
1782 
1783 /*
1784  * @implemented
1785  */
1786 BOOL
1787 NTAPI
1789 {
1790  PBASE_HEAP_HANDLE_ENTRY HandleEntry;
1791  BOOL RetVal = TRUE;
1792 
1793  /* Check if this was a simple allocated heap entry */
1794  if (!((ULONG_PTR)hMem & BASE_HEAP_IS_HANDLE_ENTRY))
1795  {
1796  /* Fail, because LocalUnlock is not supported on LMEM_FIXED allocations */
1798  return FALSE;
1799  }
1800 
1801  /* Otherwise, lock the heap */
1803 
1804  /* Get the handle entry */
1805  HandleEntry = BaseHeapGetEntry(hMem);
1806  BASE_TRACE_HANDLE(HandleEntry, hMem);
1807  _SEH2_TRY
1808  {
1809  /* Make sure it's valid */
1810  if (!BaseHeapValidateEntry(HandleEntry))
1811  {
1812  /* It's not, fail */
1815  RetVal = FALSE;
1816  }
1817  else
1818  {
1819  /* Otherwise, decrement lock count, unless we're already at 0*/
1820  if (!HandleEntry->LockCount--)
1821  {
1822  /* In which case we simply lock it back and fail */
1823  HandleEntry->LockCount++;
1825  RetVal = FALSE;
1826  }
1827  else if (!HandleEntry->LockCount)
1828  {
1829  /* Nothing to unlock */
1831  RetVal = FALSE;
1832  }
1833  }
1834  }
1836  {
1838  RetVal = FALSE;
1839  }
1840  _SEH2_END;
1841 
1842  /* All done. Unlock the heap and return the pointer */
1844  return RetVal;
1845 }
1846 
1847 /* EOF */
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
#define BaseHeapFreeEntry(he)
Definition: baseheap.h:116
#define RTL_HANDLE_VALID
Definition: rtltypes.h:372
IN CINT OUT PVOID IN ULONG OUT PULONG ReturnLength
Definition: dumpinfo.c:39
#define HEAP_CLASS_1
Definition: nt_native.h:1711
#define IN
Definition: typedefs.h:38
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
NTSYSAPI NTSTATUS NTAPI NtQuerySystemInformation(IN SYSTEM_INFORMATION_CLASS SystemInfoClass, OUT PVOID SystemInfoBuffer, IN ULONG SystemInfoBufferSize, OUT PULONG BytesReturned OPTIONAL)
HGLOBAL NTAPI GlobalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:368
#define BaseHeapAllocEntry()
Definition: baseheap.h:104
BOOL NTAPI LocalUnlock(HLOCAL hMem)
Definition: heapmem.c:1788
HGLOBAL NTAPI GlobalReAlloc(HGLOBAL hMem, SIZE_T dwBytes, UINT uFlags)
Definition: heapmem.c:825
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
PBASE_STATIC_SERVER_DATA BaseStaticServerData
Definition: dllmain.c:19
#define HEAP_NO_SERIALIZE
Definition: nt_native.h:1692
ULONG_PTR SystemRangeStart
Definition: heapmem.c:20
NTSYSAPI VOID NTAPI RtlInitializeHandleTable(_In_ ULONG TableSize, _In_ ULONG HandleSize, _In_ PRTL_HANDLE_TABLE HandleTable)
HANDLE WINAPI HeapCreate(DWORD flOptions, SIZE_T dwInitialSize, SIZE_T dwMaximumSize)
Definition: heapmem.c:45
uint16_t * PWSTR
Definition: typedefs.h:54
#define LMEM_LOCKCOUNT
Definition: winbase.h:360
#define BASE_HEAP_ENTRY_FLAG_REUSE
Definition: baseheap.h:85
_Must_inspect_result_ _In_ USAGE _In_ USHORT _In_ USAGE Usage
Definition: hidpi.h:382
UINT NTAPI GlobalFlags(HGLOBAL hMem)
Definition: heapmem.c:520
NTSYSAPI NTSTATUS WINAPI RtlSetHeapInformation(HANDLE, HEAP_INFORMATION_CLASS, PVOID, SIZE_T)
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
#define ERROR_INVALID_HANDLE
Definition: compat.h:88
VOID NTAPI GlobalFix(HGLOBAL hMem)
Definition: heapmem.c:509
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
NTSTATUS NTAPI NtQueryInformationProcess(IN HANDLE ProcessHandle, IN PROCESSINFOCLASS ProcessInformationClass, OUT PVOID ProcessInformation, IN ULONG ProcessInformationLength, OUT PULONG ReturnLength OPTIONAL)
Definition: query.c:59
NTSYSAPI BOOLEAN WINAPI RtlLockHeap(HANDLE)
#define GMEM_INVALID_HANDLE
Definition: winbase.h:305
SIZE_T PagefileUsage
Definition: winternl.h:1614
PWSTR NTAPI RtlQueryTagHeap(IN PVOID HeapHandle, IN ULONG Flags, IN USHORT TagIndex, IN BOOLEAN ResetCounters, OUT PRTL_HEAP_TAG_INFO HeapTagInfo)
Definition: heap.c:3859
#define GMEM_DISCARDED
Definition: winbase.h:304
#define MAXULONG_PTR
Definition: basetsd.h:103
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define INVALID_HANDLE_VALUE
Definition: compat.h:399
#define BASE_TRACE_HANDLE(x, y)
Definition: baseheap.h:53
BOOL WINAPI HeapValidate(HANDLE hHeap, DWORD dwFlags, LPCVOID lpMem)
Definition: heapmem.c:156
#define BASE_TRACE_ALLOC(x, y)
Definition: baseheap.h:44
HGLOBAL NTAPI GlobalHandle(LPCVOID pMem)
Definition: heapmem.c:705
SIZE_T VirtualSize
Definition: winternl.h:1606
DWORD WINAPI GetProcessHeaps(DWORD NumberOfHeaps, PHANDLE ProcessHeaps)
Definition: heapmem.c:111
SIZE_T NTAPI LocalSize(HLOCAL hMem)
Definition: heapmem.c:1777
UINT uFlags
Definition: api.c:59
HANDLE WINAPI GetProcessHeap(VOID)
Definition: heapmem.c:100
#define NO_ERROR
Definition: dderror.h:5
NTSYSAPI PVOID WINAPI RtlReAllocateHeap(HANDLE, ULONG, PVOID, SIZE_T)
Definition: heap.c:2561
#define LMEM_DISCARDED
Definition: winbase.h:357
#define DWORD
Definition: nt_native.h:44
#define HEAP_SETTABLE_USER_VALUE
Definition: nt_native.h:1704
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:263
NTSYSAPI NTSTATUS WINAPI RtlQueryHeapInformation(HANDLE, HEAP_INFORMATION_CLASS, PVOID, SIZE_T, PSIZE_T)
#define BASE_TRACE_ALLOC2(x)
Definition: baseheap.h:47
_SEH2_TRY
Definition: create.c:4250
uint32_t ULONG_PTR
Definition: typedefs.h:63
SIZE_T NTAPI GlobalSize(HGLOBAL hMem)
Definition: heapmem.c:1090
BOOL WINAPI HeapDestroy(HANDLE hHeap)
Definition: heapmem.c:85
struct _QUOTA_LIMITS QUOTA_LIMITS
NTSYSAPI BOOLEAN WINAPI RtlValidateHeap(HANDLE, ULONG, LPCVOID)
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
BOOLEAN NTAPI RtlSetUserValueHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID BaseAddress, IN PVOID UserValue)
Definition: heap.c:3664
NTSYSAPI ULONG WINAPI RtlCompactHeap(HANDLE, ULONG)
Definition: heap.c:2968
NTSYSAPI ULONG WINAPI RtlGetProcessHeaps(ULONG, HANDLE *)
Definition: heap.c:3627
ULONG_PTR * PSIZE_T
Definition: typedefs.h:78
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define BASE_TRACE_PTR(x, y)
Definition: baseheap.h:50
unsigned int BOOL
Definition: ntddk_ex.h:94
#define LMEM_DISCARDABLE
Definition: winbase.h:353
VOID NTAPI BaseDllInitializeMemoryManager(VOID)
Definition: heapmem.c:26
static TAGREF LPCWSTR LPDWORD LPVOID lpBuffer
Definition: db.cpp:173
ULONG OldSize
Definition: baseheap.h:75
RTL_HANDLE_TABLE BaseHeapHandleTable
Definition: heapmem.c:18
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define GMEM_DISCARDABLE
Definition: winbase.h:296
ULONG NTAPI RtlCreateTagHeap(IN HANDLE HeapHandle, IN ULONG Flags, IN PWSTR TagName, IN PWSTR TagSubName)
Definition: heap.c:3884
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
BOOL WINAPI HeapSetInformation(HANDLE HeapHandle, HEAP_INFORMATION_CLASS HeapInformationClass, PVOID HeapInformation OPTIONAL, SIZE_T HeapInformationLength OPTIONAL)
Definition: heapmem.c:342
NTSYSAPI PVOID NTAPI RtlDestroyHeap(IN PVOID HeapHandle)
SIZE_T WINAPI LocalShrink(HLOCAL hMem, UINT cbNewSize)
Definition: heapmem.c:1765
#define C_ASSERT(e)
Definition: intsafe.h:79
DWORD BaseSetLastNTError(IN NTSTATUS Status)
Definition: reactos.cpp:166
#define SystemPerformanceInformation
Definition: memtest.h:87
LPVOID NTAPI GlobalWire(HGLOBAL hMem)
Definition: heapmem.c:1261
BOOLEAN NTAPI RtlGetUserInfoHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID BaseAddress, OUT PVOID *UserValue, OUT PULONG UserFlags)
Definition: heap.c:3781
struct _MEMORYSTATUS MEMORYSTATUS
#define NtCurrentProcess()
Definition: nt_native.h:1657
SYSTEM_BASIC_INFORMATION SysInfo
Definition: base.h:122
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
BOOL WINAPI HeapWalk(HANDLE hHeap, LPPROCESS_HEAP_ENTRY lpEntry)
Definition: heapmem.c:291
_In_ HANDLE Handle
Definition: extypes.h:390
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
#define LMEM_INVALID_HANDLE
Definition: winbase.h:359
#define LMEM_VALID_FLAGS
Definition: winbase.h:361
#define LMEM_ZEROINIT
Definition: winbase.h:356
if(!(yy_init))
Definition: macro.lex.yy.c:714
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
BOOL NTAPI GlobalUnWire(HGLOBAL hMem)
Definition: heapmem.c:1250
uint64_t ULONGLONG
Definition: typedefs.h:65
SIZE_T NTAPI LocalCompact(UINT dwMinFree)
Definition: heapmem.c:1492
#define WINAPI
Definition: msvc.h:6
#define HEAP_GROWABLE
Definition: nt_native.h:1693
#define LMEM_MOVEABLE
Definition: winbase.h:350
unsigned short WORD
Definition: ntddk_ex.h:93
PVOID HANDLE
Definition: typedefs.h:71
unsigned long DWORD
Definition: ntddk_ex.h:95
HGLOBAL NTAPI GlobalFree(HGLOBAL hMem)
Definition: heapmem.c:611
#define SetLastError(x)
Definition: compat.h:417
BOOL WINAPI HeapSummary(HANDLE hHeap, DWORD dwFlags, PVOID Summary)
Definition: heapmem.c:230
#define BaseHeapGetEntry(h)
Definition: baseheap.h:107
BOOL WINAPI HeapUsage(HANDLE hHeap, DWORD dwFlags, DWORD Unknown, DWORD Unknown2, IN PVOID Usage)
Definition: heapmem.c:259
#define GMEM_VALID_FLAGS
Definition: winbase.h:307
VOID NTAPI GlobalMemoryStatus(LPMEMORYSTATUS lpBuffer)
Definition: heapmem.c:1348
BOOL WINAPI HeapLock(HANDLE hHeap)
Definition: heapmem.c:123
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
Definition: baseheap.h:68
DWORD WINAPI HeapCreateTagsW(HANDLE hHeap, DWORD dwFlags, PWSTR lpTagName, PWSTR lpTagSubName)
Definition: heapmem.c:169
LPVOID NTAPI GlobalLock(HGLOBAL hMem)
Definition: heapmem.c:755
#define BASE_HEAP_FLAG_MOVABLE
Definition: baseheap.h:98
#define BASE_HEAP_ENTRY_FLAG_MOVABLE
Definition: baseheap.h:83
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:414
NTSYSAPI NTSTATUS WINAPI RtlWalkHeap(HANDLE, PVOID)
PVOID Object
Definition: baseheap.h:74
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)
SIZE_T WINAPI HeapCompact(HANDLE hHeap, DWORD dwFlags)
Definition: heapmem.c:145
NTSYSAPI SIZE_T NTAPI RtlSizeHeap(_In_ PVOID HeapHandle, _In_ ULONG Flags, _In_ PVOID MemoryPointer)
Definition: winbase.h:1228
#define STATUS_MORE_ENTRIES
Definition: udferr_usr.h:124
NTSYSAPI BOOLEAN WINAPI RtlUnlockHeap(HANDLE)
Definition: heap.c:3027
#define BASE_HEAP_IS_HANDLE_ENTRY
Definition: baseheap.h:91
HANDLE BaseHeap
Definition: heapmem.c:19
Status
Definition: gdiplustypes.h:24
NTSYSAPI ULONG WINAPI RtlNtStatusToDosError(NTSTATUS)
ULONG_PTR SIZE_T
Definition: typedefs.h:78
_SEH2_END
Definition: create.c:4424
SIZE_T NTAPI GlobalCompact(DWORD dwMinFree)
Definition: heapmem.c:498
HLOCAL NTAPI LocalReAlloc(HLOCAL hMem, SIZE_T dwBytes, UINT uFlags)
Definition: heapmem.c:1608
BOOL WINAPI HeapUnlock(HANDLE hHeap)
Definition: heapmem.c:134
#define LMEM_MODIFY
Definition: winbase.h:358
#define BASE_TRACE_FAILURE()
Definition: baseheap.h:59
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1577
DWORD WINAPI HeapExtend(HANDLE hHeap, DWORD dwFlags, PVOID BaseAddress, DWORD dwBytes)
Definition: heapmem.c:186
#define BASE_HEAP_ENTRY_FLAG_REUSABLE
Definition: baseheap.h:84
LPVOID NTAPI LocalLock(HLOCAL hMem)
Definition: heapmem.c:1599
#define BaseHeapValidateEntry(he)
Definition: baseheap.h:113
#define GMEM_MODIFY
Definition: winbase.h:292
BOOL WINAPI IsBadReadPtr(IN LPCVOID lp, IN UINT_PTR ucb)
Definition: except.c:807
BOOL WINAPI HeapQueryInformation(HANDLE HeapHandle, HEAP_INFORMATION_CLASS HeapInformationClass, PVOID HeapInformation OPTIONAL, SIZE_T HeapInformationLength OPTIONAL, PSIZE_T ReturnLength OPTIONAL)
Definition: heapmem.c:314
#define min(a, b)
Definition: monoChain.cc:55
unsigned int UINT
Definition: ndis.h:50
PWSTR WINAPI HeapQueryTagW(HANDLE hHeap, DWORD dwFlags, WORD wTagIndex, BOOL bResetCounters, PVOID lpTagInfo)
Definition: heapmem.c:211
BOOL NTAPI GlobalUnlock(HGLOBAL hMem)
Definition: heapmem.c:1190
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
UINT NTAPI LocalFlags(HLOCAL hMem)
Definition: heapmem.c:1503
#define GMEM_DDESHARE
Definition: winbase.h:295
#define DPRINT1
Definition: precomp.h:8
CONST void * LPCVOID
Definition: windef.h:191
VOID NTAPI GlobalUnfix(HGLOBAL hMem)
Definition: heapmem.c:1179
unsigned int ULONG
Definition: retypes.h:1
USHORT LockCount
Definition: baseheap.h:71
#define BASE_HEAP_ENTRY_FLAG_DDESHARE
Definition: baseheap.h:86
enum _HEAP_INFORMATION_CLASS HEAP_INFORMATION_CLASS
BOOL NTAPI GlobalMemoryStatusEx(LPMEMORYSTATUSEX lpBuffer)
Definition: heapmem.c:1272
USHORT Flags
Definition: baseheap.h:70
HLOCAL NTAPI LocalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:1373
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
_In_ PATHOBJ _In_ CLIPOBJ _In_ BRUSHOBJ _In_ POINTL _In_ MIX _In_ FLONG flOptions
Definition: winddi.h:3591
HLOCAL NTAPI LocalHandle(LPCVOID pMem)
Definition: heapmem.c:1588
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
#define ERROR_NOT_LOCKED
Definition: winerror.h:230
#define BASE_TRACE_DEALLOC(x)
Definition: baseheap.h:56
#define HEAP_GENERATE_EXCEPTIONS
Definition: nt_native.h:1694
#define GMEM_LOCKCOUNT
Definition: winbase.h:306
#define HEAP_REALLOC_IN_PLACE_ONLY
Definition: nt_native.h:1696
#define GMEM_MOVEABLE
Definition: winbase.h:291
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:54
#define GMEM_ZEROINIT
Definition: winbase.h:303
#define ERROR_DISCARDED
Definition: winerror.h:229
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68