ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

usrheap.c
Go to the documentation of this file.
00001 /*
00002  *  ReactOS W32 Subsystem
00003  *  Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
00004  *
00005  *  This program is free software; you can redistribute it and/or modify
00006  *  it under the terms of the GNU General Public License as published by
00007  *  the Free Software Foundation; either version 2 of the License, or
00008  *  (at your option) any later version.
00009  *
00010  *  This program is distributed in the hope that it will be useful,
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  *  GNU General Public License for more details.
00014  *
00015  *  You should have received a copy of the GNU General Public License along
00016  *  with this program; if not, write to the Free Software Foundation, Inc.,
00017  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00018  */
00019 
00020 #include <win32k.h>
00021 
00022 #define NDEBUG
00023 #include <debug.h>
00024 
00025 
00026 static NTSTATUS APIENTRY
00027 IntUserHeapCommitRoutine(IN PVOID Base,
00028                          IN OUT PVOID *CommitAddress,
00029                          IN OUT PSIZE_T CommitSize)
00030 {
00031     PPROCESSINFO W32Process;
00032     PW32HEAP_USER_MAPPING Mapping;
00033     PVOID UserBase = NULL;
00034     NTSTATUS Status;
00035     SIZE_T Delta;
00036     PVOID UserCommitAddress;
00037 
00038     W32Process = PsGetCurrentProcessWin32Process();
00039 
00040     if (W32Process != NULL)
00041     {
00042         /* Search for the mapping */
00043         Mapping = &W32Process->HeapMappings;
00044         while (Mapping != NULL)
00045         {
00046             if (Mapping->KernelMapping == Base)
00047             {
00048                 UserBase = Mapping->UserMapping;
00049                 break;
00050             }
00051 
00052             Mapping = Mapping->Next;
00053         }
00054 
00055         ASSERT(UserBase != NULL);
00056     }
00057     else
00058     {
00059         SIZE_T ViewSize = 0;
00060         LARGE_INTEGER Offset;
00061         extern PSECTION_OBJECT GlobalUserHeapSection;
00062 
00063         /* HACK: This needs to be handled during startup only... */
00064         ASSERT(Base == (PVOID)GlobalUserHeap);
00065 
00066         /* Temporarily map it into user space */
00067         Offset.QuadPart = 0;
00068         Status = MmMapViewOfSection(GlobalUserHeapSection,
00069                                     PsGetCurrentProcess(),
00070                                     &UserBase,
00071                                     0,
00072                                     0,
00073                                     &Offset,
00074                                     &ViewSize,
00075                                     ViewUnmap,
00076                                     SEC_NO_CHANGE,
00077                                     PAGE_EXECUTE_READ); /* Would prefer PAGE_READONLY, but thanks to RTL heaps... */
00078 
00079         if (!NT_SUCCESS(Status))
00080             return Status;
00081     }
00082 
00083     /* Apply the commit address offset to the user base address */
00084     Delta = (SIZE_T) ((ULONG_PTR) (*CommitAddress) - (ULONG_PTR) (Base));
00085     UserCommitAddress = (PVOID) ((ULONG_PTR) (UserBase) + Delta);
00086 
00087     /* Perform the actual commit */
00088     Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
00089                                      &UserCommitAddress,
00090                                      0,
00091                                      CommitSize,
00092                                      MEM_COMMIT,
00093                                      PAGE_EXECUTE_READ);
00094 
00095     if (NT_SUCCESS(Status))
00096     {
00097         /* Determine the address to return */
00098         Delta = (SIZE_T) ((ULONG_PTR) (UserCommitAddress) - (ULONG_PTR) (UserBase));
00099         *CommitAddress = (PVOID) ((ULONG_PTR) (Base) + Delta);
00100     }
00101 
00102     if (W32Process == NULL)
00103     {
00104         MmUnmapViewOfSection(PsGetCurrentProcess(),
00105                              UserBase);
00106     }
00107 
00108     return Status;
00109 }
00110 
00111 static PWIN32HEAP
00112 IntUserHeapCreate(IN PSECTION_OBJECT SectionObject,
00113                   IN PVOID *SystemMappedBase,
00114                   IN ULONG HeapSize)
00115 {
00116     PVOID MappedView = NULL;
00117     LARGE_INTEGER Offset;
00118     SIZE_T ViewSize = PAGE_SIZE;
00119     RTL_HEAP_PARAMETERS Parameters = {0};
00120     PVOID pHeap;
00121     NTSTATUS Status;
00122 
00123     Offset.QuadPart = 0;
00124 
00125     /* Commit the first page before creating the heap! */
00126     Status = MmMapViewOfSection(SectionObject,
00127                                 PsGetCurrentProcess(),
00128                                 &MappedView,
00129                                 0,
00130                                 0,
00131                                 &Offset,
00132                                 &ViewSize,
00133                                 ViewUnmap,
00134                                 SEC_NO_CHANGE,
00135                                 PAGE_EXECUTE_READ); /* Would prefer PAGE_READONLY, but thanks to RTL heaps... */
00136     if (!NT_SUCCESS(Status))
00137         return NULL;
00138 
00139     Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
00140                                      &MappedView,
00141                                      0,
00142                                      &ViewSize,
00143                                      MEM_COMMIT,
00144                                      PAGE_EXECUTE_READ); /* Would prefer PAGE_READONLY, but thanks to RTL heaps... */
00145 
00146     MmUnmapViewOfSection(PsGetCurrentProcess(),
00147                          MappedView);
00148 
00149     if (!NT_SUCCESS(Status))
00150         return NULL;
00151 
00152     /* Create the heap, don't serialize in kmode! The caller is responsible
00153        to synchronize the heap! */
00154     Parameters.Length = sizeof(Parameters);
00155     Parameters.InitialCommit = ViewSize;
00156     Parameters.InitialReserve = (SIZE_T)HeapSize;
00157     Parameters.CommitRoutine = IntUserHeapCommitRoutine;
00158 
00159     pHeap = RtlCreateHeap(HEAP_ZERO_MEMORY | HEAP_NO_SERIALIZE,
00160                           *SystemMappedBase,
00161                           (SIZE_T)HeapSize,
00162                           ViewSize,
00163                           NULL,
00164                           &Parameters);
00165 
00166     return pHeap;
00167 }
00168 
00169 PWIN32HEAP
00170 UserCreateHeap(OUT PSECTION_OBJECT *SectionObject,
00171                IN OUT PVOID *SystemBase,
00172                IN SIZE_T HeapSize)
00173 {
00174     LARGE_INTEGER SizeHeap;
00175     PWIN32HEAP pHeap = NULL;
00176     NTSTATUS Status;
00177 
00178     SizeHeap.QuadPart = HeapSize;
00179 
00180     /* Create the section and map it into session space */
00181     Status = MmCreateSection((PVOID*)SectionObject,
00182                              SECTION_ALL_ACCESS,
00183                              NULL,
00184                              &SizeHeap,
00185                              PAGE_EXECUTE_READWRITE, /* Would prefer PAGE_READWRITE, but thanks to RTL heaps... */
00186                              SEC_RESERVE,
00187                              NULL,
00188                              NULL);
00189 
00190     if (!NT_SUCCESS(Status))
00191     {
00192         SetLastNtError(Status);
00193         return FALSE;
00194     }
00195 
00196     Status = MmMapViewInSystemSpace(*SectionObject,
00197                                     SystemBase,
00198                                     &HeapSize);
00199     if (!NT_SUCCESS(Status))
00200     {
00201         ObDereferenceObject(*SectionObject);
00202         *SectionObject = NULL;
00203 
00204         SetLastNtError(Status);
00205         return FALSE;
00206     }
00207 
00208     /* Create the heap */
00209     pHeap = IntUserHeapCreate(*SectionObject,
00210                               SystemBase,
00211                               HeapSize);
00212 
00213     if (pHeap == NULL)
00214     {
00215         ObDereferenceObject(*SectionObject);
00216         *SectionObject = NULL;
00217 
00218         SetLastNtError(STATUS_UNSUCCESSFUL);
00219     }
00220 
00221     return pHeap;
00222 }

Generated on Fri May 25 2012 04:36:51 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.