test: heap.c Source File

Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

# heap.c

Go to the documentation of this file.

    00001 /****************************** Module Header ******************************\
    00002 * Module Name: heap.c
    00003 *
    00004 * Copyright (c) 1985 - 1999, Microsoft Corporation
    00005 *
    00006 * This module contains kernel-mode heap management code.
    00007 *
    00008 * History:
    00009 * 03-16-95 JimA         Created.
    00010 \***************************************************************************/
    00011
    00012 #include "precomp.h"
    00013 #pragma hdrstop
    00014
    00015 NTSTATUS UserCommitDesktopMemory(
    00016     PVOID pBase,
    00017     PVOID *ppCommit,
    00018     PSIZE_T pCommitSize)
    00019 {
    00020     PDESKTOPVIEW    pdv;
    00021     DWORD           dwCommitOffset;
    00022     PWINDOWSTATION  pwinsta;
    00023     PDESKTOP        pdesk;
    00024     PBYTE           pUserBase;
    00025     int             dCommit;
    00026     NTSTATUS        Status;
    00027     ETHREAD         *Thread = PsGetCurrentThread();
    00028
    00029     /*
    00030      * If this is a system thread, we have no view of the desktop
    00031      * and must map it in.  Fortunately, this does not happen often.
    00032      *
    00033      * We use the Thread variable because IS_SYSTEM_THREAD is a macro
    00034      * that multiply resolves the parameter.
    00035      */
    00036     if (IS_SYSTEM_THREAD(Thread)) {
    00037
    00038         /*
    00039          * Find the desktop that owns the section.
    00040          */
    00041         for (pwinsta = grpWinStaList; pwinsta; pwinsta = pwinsta->rpwinstaNext) {
    00042             for (pdesk = pwinsta->rpdeskList; pdesk; pdesk = pdesk->rpdeskNext) {
    00043                 if (pdesk->pDeskInfo->pvDesktopBase == pBase)
    00044                     goto FoundIt;
    00045             }
    00046         }
    00047 FoundIt:
    00048         if (pwinsta == NULL) {
    00049             RIPMSG3(RIP_ERROR, "UserCommitDesktopMemory failed: pBase %#p, ppCommit %#p, pCommitSize %d",
    00050                     pBase, ppCommit, *pCommitSize);
    00051             return STATUS_NO_MEMORY;
    00052         }
    00053
    00054         /*
    00055          * Map the section into the current process and commit the
    00056          * first page of the section.
    00057          */
    00058         dwCommitOffset = (ULONG)((PBYTE)*ppCommit - (PBYTE)pBase);
    00059         Status = CommitReadOnlyMemory(pdesk->hsectionDesktop, pCommitSize,
    00060                     dwCommitOffset, &dCommit);
    00061         if (NT_SUCCESS(Status)) {
    00062             *ppCommit = (PBYTE)*ppCommit + dCommit;
    00063         }
    00064     } else {
    00065
    00066         /*
    00067          * Find the current process' view of the desktop
    00068          */
    00069         for (pdv = PpiCurrent()->pdvList; pdv != NULL; pdv = pdv->pdvNext) {
    00070             if (pdv->pdesk->pDeskInfo->pvDesktopBase == pBase)
    00071                 break;
    00072         }
    00073
    00074         /*
    00075          * 254954: If we didn't find a desktop view then map the desktop view
    00076          * to the current process.
    00077          */
    00078         if (pdv == NULL) {
    00079             /*
    00080              * Find the desktop that owns the section.
    00081              */
    00082             for (pwinsta = grpWinStaList; pwinsta; pwinsta = pwinsta->rpwinstaNext) {
    00083                 for (pdesk = pwinsta->rpdeskList; pdesk; pdesk = pdesk->rpdeskNext) {
    00084                     if (pdesk->pDeskInfo->pvDesktopBase == pBase)
    00085                         goto FoundTheDesktop;
    00086                 }
    00087             }
    00088
    00089 FoundTheDesktop:
    00090             if (pwinsta == NULL) {
    00091                 RIPMSG3(RIP_ERROR, "UserCommitDesktopMemory failed: pBase %#p, ppCommit %#p, pCommitSize %d",
    00092                         pBase, ppCommit, *pCommitSize);
    00093                 return STATUS_NO_MEMORY;
    00094             }
    00095
    00096             UserAssert(pdesk != NULL);
    00097
    00098             /*
    00099              * Map the desktop into the current process
    00100              */
    00101             try {
    00102                 MapDesktop(ObOpenHandle, PsGetCurrentProcess(), pdesk, 0, 1);
    00103             } except (W32ExceptionHandler(TRUE, RIP_WARNING)) {
    00104
    00105                   RIPMSG2(RIP_WARNING, "UserCommitDesktopMemory: Could't map pdesk %#p in ppi %#p",
    00106                         pdesk, PpiCurrent());
    00107                 return STATUS_NO_MEMORY;
    00108             }
    00109
    00110             pdv = GetDesktopView(PpiCurrent(), pdesk);
    00111         }
    00112
    00113         UserAssert(pdv != NULL);
    00114
    00115         /*
    00116          * Commit the memory
    00117          */
    00118         pUserBase = (PVOID)((PBYTE)*ppCommit - pdv->ulClientDelta);
    00119         Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
    00120                                         &pUserBase,
    00121                                         0,
    00122                                         pCommitSize,
    00123                                         MEM_COMMIT,
    00124                                         PAGE_EXECUTE_READ
    00125                                         );
    00126         if (NT_SUCCESS(Status))
    00127             *ppCommit = (PVOID)((PBYTE)pUserBase + pdv->ulClientDelta);
    00128     }
    00129
    00130     return Status;
    00131 }
    00132
    00133 NTSTATUS UserCommitSharedMemory(
    00134     PVOID  pBase,
    00135     PVOID *ppCommit,
    00136     PSIZE_T pCommitSize)
    00137 {
    00138     ULONG_PTR   ulClientDelta;
    00139     DWORD       dwCommitOffset;
    00140     PBYTE       pUserBase;
    00141     NTSTATUS    Status;
    00142     PEPROCESS   Process;
    00143     int         dCommit;
    00144
    00145 #if DBG
    00146     if (pBase != Win32HeapGetHandle(gpvSharedAlloc)) {
    00147         RIPMSG0(RIP_WARNING, "pBase != gpvSharedAlloc");
    00148     }
    00149 #else
    00150     UNREFERENCED_PARAMETER(pBase);
    00151 #endif
    00152
    00153     Process = PsGetCurrentProcess();
    00154
    00155     ValidateProcessSessionId(Process);
    00156
    00157     if (Process->Win32Process == NULL ||
    00158         ((PPROCESSINFO)Process->Win32Process)->pClientBase == NULL) {
    00159
    00160         dwCommitOffset = (ULONG)((PBYTE)*ppCommit - (PBYTE)gpvSharedBase);
    00161         Status = CommitReadOnlyMemory(
    00162                 ghSectionShared, pCommitSize, dwCommitOffset, &dCommit);
    00163
    00164         if (NT_SUCCESS(Status)) {
    00165             *ppCommit = (PBYTE) *ppCommit + dCommit;
    00166         }
    00167     } else {
    00168
    00169         /*
    00170          * Commit the memory
    00171          */
    00172         ulClientDelta = (ULONG_PTR)((PBYTE)gpvSharedBase - (PBYTE)(PpiCurrent()->pClientBase));
    00173         pUserBase = (PVOID)((PBYTE)*ppCommit - ulClientDelta);
    00174         Status = ZwAllocateVirtualMemory(
    00175                          NtCurrentProcess(),
    00176                          &pUserBase,
    00177                          0,
    00178                          pCommitSize,
    00179                          MEM_COMMIT,
    00180                          PAGE_EXECUTE_READ);
    00181         if (NT_SUCCESS(Status)) {
    00182             *ppCommit = (PVOID)((PBYTE)pUserBase + ulClientDelta);
    00183         }
    00184     }
    00185
    00186     return Status;
    00187 }
    00188
    00189 PWIN32HEAP UserCreateHeap(
    00190     HANDLE                      hSection,
    00191     ULONG                       ulViewOffset,
    00192     PVOID                       pvBaseAddress,
    00193     DWORD                       dwSize,
    00194     PRTL_HEAP_COMMIT_ROUTINE    pfnCommit)
    00195 {
    00196     PVOID pUserBase;
    00197     SIZE_T ulViewSize;
    00198     LARGE_INTEGER liOffset;
    00199     PEPROCESS Process = PsGetCurrentProcess();
    00200     RTL_HEAP_PARAMETERS HeapParams;
    00201     NTSTATUS Status;
    00202     ULONG HeapFlags;
    00203
    00204     /*
    00205      * Map the section into the current process and commit the
    00206      * first page of the section.
    00207      */
    00208     ulViewSize        = 0;
    00209     liOffset.LowPart  = ulViewOffset;
    00210     liOffset.HighPart = 0;
    00211     pUserBase         = NULL;
    00212
    00213     Status = MmMapViewOfSection(
    00214                     hSection,
    00215                     Process,
    00216                     &pUserBase,
    00217                     0,
    00218                     PAGE_SIZE,
    00219                     &liOffset,
    00220                     &ulViewSize,
    00221                     ViewUnmap,
    00222                     SEC_NO_CHANGE,
    00223                     PAGE_EXECUTE_READ);
    00224
    00225     if (!NT_SUCCESS(Status))
    00226         return NULL;
    00227
    00228     MmUnmapViewOfSection(Process, pUserBase);
    00229
    00230     /*
    00231      * We now have a committed page to create the heap in.
    00232      */
    00233     RtlZeroMemory(&HeapParams, sizeof(HeapParams));
    00234
    00235     HeapParams.Length         = sizeof(HeapParams);
    00236     HeapParams.InitialCommit  = PAGE_SIZE;
    00237     HeapParams.InitialReserve = dwSize;
    00238     HeapParams.CommitRoutine  = pfnCommit;
    00239
    00240     UserAssert(HeapParams.InitialCommit < dwSize);
    00241
    00242
    00243     HeapFlags = HEAP_NO_SERIALIZE | HEAP_ZERO_MEMORY;
    00244
    00245 #if DBG
    00246     HeapFlags |= HEAP_TAIL_CHECKING_ENABLED;
    00247 #endif // DBG
    00248
    00249     return Win32HeapCreate("UH_HEAD",
    00250                            "UH_TAIL",
    00251                            HeapFlags,
    00252                            pvBaseAddress,
    00253                            dwSize,
    00254                            PAGE_SIZE,
    00255                            NULL,
    00256                            &HeapParams);
    00257 }