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

mapping.c
Go to the documentation of this file.
00001 /*
00002  * COPYRIGHT:         See COPYING in the top level directory
00003  * PROJECT:           ReactOS kernel
00004  * PURPOSE:           Functions for mapping files and sections
00005  * FILE:              subsys/win32k/eng/device.c
00006  * PROGRAMER:         Timo Kreuzer (timo.kreuzer@reactos.org)
00007  */
00008 
00009 #include <win32k.h>
00010 
00011 #define NDEBUG
00012 #include <debug.h>
00013 
00014 // HACK!!!
00015 #define MmMapViewInSessionSpace MmMapViewInSystemSpace
00016 #define MmUnmapViewInSessionSpace MmUnmapViewInSystemSpace
00017 
00018 HANDLE ghSystem32Directory;
00019 HANDLE ghRootDirectory;
00020 
00021 PVOID
00022 NTAPI
00023 EngMapSectionView(
00024     _In_ HANDLE hSection,
00025     _In_ SIZE_T cjSize,
00026     _In_ ULONG cjOffset,
00027     _Out_ PHANDLE phSecure)
00028 {
00029     LARGE_INTEGER liSectionOffset;
00030     PVOID pvBaseAddress;
00031     NTSTATUS Status;
00032 
00033     /* Align the offset at allocation granularity and compensate for the size */
00034     liSectionOffset.QuadPart = cjOffset & ~(MM_ALLOCATION_GRANULARITY - 1);
00035     cjSize += cjOffset & (MM_ALLOCATION_GRANULARITY - 1);
00036 
00037     /* Map the section */
00038     Status = ZwMapViewOfSection(hSection,
00039                                 NtCurrentProcess(),
00040                                 &pvBaseAddress,
00041                                 0,
00042                                 cjSize,
00043                                 &liSectionOffset,
00044                                 &cjSize,
00045                                 ViewShare,
00046                                 0,
00047                                 PAGE_READWRITE);
00048     if (!NT_SUCCESS(Status))
00049     {
00050         DPRINT1("ZwMapViewOfSection failed (0x%lx)\n", Status);
00051         return NULL;
00052     }
00053 
00054     /* Secure the section memory */
00055     *phSecure = EngSecureMem(pvBaseAddress, cjSize);
00056     if (!*phSecure)
00057     {
00058         ZwUnmapViewOfSection(NtCurrentProcess(), pvBaseAddress);
00059         return NULL;
00060     }
00061 
00062     /* Return the address where the requested data starts */
00063     return (PUCHAR)pvBaseAddress + (cjOffset & (MM_ALLOCATION_GRANULARITY - 1));
00064 }
00065 
00066 VOID
00067 NTAPI
00068 EngUnmapSectionView(
00069     _In_ PVOID pvBits,
00070     _In_ ULONG cjOffset,
00071     _In_ HANDLE hSecure)
00072 {
00073     NTSTATUS Status;
00074 
00075     /* Unsecure the memory */
00076     EngUnsecureMem(hSecure);
00077 
00078     /* Calculate the real start of the section view */
00079     pvBits = (PUCHAR)pvBits - (cjOffset & (MM_ALLOCATION_GRANULARITY - 1));
00080 
00081     /* Unmap the section view */
00082     Status = MmUnmapViewOfSection(PsGetCurrentProcess(), pvBits);
00083     if (!NT_SUCCESS(Status))
00084     {
00085         DPRINT1("Could not unmap section view!\n");
00086     }
00087 }
00088 
00089 
00090 PVOID
00091 NTAPI
00092 EngCreateSection(
00093     IN ULONG fl,
00094     IN SIZE_T cjSize,
00095     IN ULONG ulTag)
00096 {
00097     NTSTATUS Status;
00098     PENGSECTION pSection;
00099     PVOID pvSectionObject;
00100     LARGE_INTEGER liSize;
00101 
00102     /* Allocate a section object */
00103     pSection = EngAllocMem(0, sizeof(ENGSECTION), 'stsU');
00104     if (!pSection) return NULL;
00105 
00106     liSize.QuadPart = cjSize;
00107     Status = MmCreateSection(&pvSectionObject,
00108                              SECTION_ALL_ACCESS,
00109                              NULL,
00110                              &liSize,
00111                              PAGE_READWRITE,
00112                              SEC_COMMIT,
00113                              NULL,
00114                              NULL);
00115     if (!NT_SUCCESS(Status))
00116     {
00117         DPRINT1("Failed to create a section Status=0x%x\n", Status);
00118         EngFreeMem(pSection);
00119         return NULL;
00120     }
00121 
00122     /* Set the fields of the section */
00123     pSection->ulTag = ulTag;
00124     pSection->pvSectionObject = pvSectionObject;
00125     pSection->pvMappedBase = NULL;
00126     pSection->cjViewSize = cjSize;
00127 
00128     return pSection;
00129 }
00130 
00131 
00132 BOOL
00133 APIENTRY
00134 EngMapSection(
00135     IN PVOID pvSection,
00136     IN BOOL bMap,
00137     IN HANDLE hProcess,
00138     OUT PVOID* pvBaseAddress)
00139 {
00140     NTSTATUS Status;
00141     PENGSECTION pSection = pvSection;
00142     PEPROCESS pepProcess;
00143 
00144     /* Get a pointer to the process */
00145     Status = ObReferenceObjectByHandle(hProcess,
00146                                        PROCESS_VM_OPERATION,
00147                                        NULL,
00148                                        KernelMode,
00149                                        (PVOID*)&pepProcess,
00150                                        NULL);
00151     if (!NT_SUCCESS(Status))
00152     {
00153         DPRINT1("Could not access process %p, Status=0x%lx\n", hProcess, Status);
00154         return FALSE;
00155     }
00156 
00157     if (bMap)
00158     {
00159         /* Make sure the section isn't already mapped */
00160         ASSERT(pSection->pvMappedBase == NULL);
00161 
00162         /* Map the section into the process address space */
00163         Status = MmMapViewOfSection(pSection->pvSectionObject,
00164                                     pepProcess,
00165                                     &pSection->pvMappedBase,
00166                                     0,
00167                                     pSection->cjViewSize,
00168                                     NULL,
00169                                     &pSection->cjViewSize,
00170                                     0,
00171                                     0,
00172                                     PAGE_READWRITE);
00173         if (!NT_SUCCESS(Status))
00174         {
00175             DPRINT1("Failed to map a section Status=0x%x\n", Status);
00176         }
00177     }
00178     else
00179     {
00180         /* Make sure the section is mapped */
00181         ASSERT(pSection->pvMappedBase);
00182 
00183         /* Unmap the section from the process address space */
00184         Status = MmUnmapViewOfSection(pepProcess, pSection->pvMappedBase);
00185         if (NT_SUCCESS(Status))
00186         {
00187             pSection->pvMappedBase = NULL;
00188         }
00189         else
00190         {
00191             DPRINT1("Failed to unmap a section @ &p Status=0x%x\n",
00192                     pSection->pvMappedBase, Status);
00193         }
00194     }
00195 
00196     /* Dereference the process */
00197     ObDereferenceObject(pepProcess);
00198 
00199     /* Set the new mapping base and return bool status */
00200     *pvBaseAddress = pSection->pvMappedBase;
00201     return NT_SUCCESS(Status);
00202 }
00203 
00204 BOOL
00205 APIENTRY
00206 EngFreeSectionMem(
00207     IN PVOID pvSection OPTIONAL,
00208     IN PVOID pvMappedBase OPTIONAL)
00209 {
00210     NTSTATUS Status;
00211     PENGSECTION pSection = pvSection;
00212     BOOL bResult = TRUE;
00213 
00214     /* Did the caller give us a mapping base? */
00215     if (pvMappedBase)
00216     {
00217         Status = MmUnmapViewInSessionSpace(pvMappedBase);
00218         if (!NT_SUCCESS(Status))
00219         {
00220             DPRINT1("MmUnmapViewInSessionSpace failed: 0x%lx\n", Status);
00221             bResult = FALSE;
00222         }
00223     }
00224 
00225     /* Check if we should free the section as well */
00226     if (pSection)
00227     {
00228         /* Dereference the kernel section */
00229         ObDereferenceObject(pSection->pvSectionObject);
00230 
00231         /* Finally free the section memory itself */
00232         EngFreeMem(pSection);
00233     }
00234 
00235     return bResult;
00236 }
00237 
00238 PVOID
00239 APIENTRY
00240 EngAllocSectionMem(
00241     OUT PVOID *ppvSection,
00242     IN ULONG fl,
00243     IN SIZE_T cjSize,
00244     IN ULONG ulTag)
00245 {
00246     NTSTATUS Status;
00247     PENGSECTION pSection;
00248 
00249     /* Check parameter */
00250     if (cjSize == 0) return NULL;
00251 
00252     /* Allocate a section object */
00253     pSection = EngCreateSection(fl, cjSize, ulTag);
00254     if (!pSection)
00255     {
00256         *ppvSection = NULL;
00257         return NULL;
00258     }
00259 
00260     /* Map the section in session space */
00261     Status = MmMapViewInSessionSpace(pSection->pvSectionObject,
00262                                      &pSection->pvMappedBase,
00263                                      &pSection->cjViewSize);
00264     if (!NT_SUCCESS(Status))
00265     {
00266         DPRINT1("Failed to map a section Status=0x%x\n", Status);
00267         *ppvSection = NULL;
00268         EngFreeSectionMem(pSection, NULL);
00269         return NULL;
00270     }
00271 
00272     if (fl & FL_ZERO_MEMORY)
00273     {
00274         RtlZeroMemory(pSection->pvMappedBase, cjSize);
00275     }
00276 
00277     /* Set section pointer and return base address */
00278     *ppvSection = pSection;
00279     return pSection->pvMappedBase;
00280 }
00281 
00282 
00283 PFILEVIEW
00284 NTAPI
00285 EngLoadModuleEx(
00286     LPWSTR pwsz,
00287     ULONG cjSizeOfModule,
00288     FLONG fl)
00289 {
00290     PFILEVIEW pFileView = NULL;
00291     OBJECT_ATTRIBUTES ObjectAttributes;
00292     HANDLE hRootDir;
00293     UNICODE_STRING ustrFileName;
00294     IO_STATUS_BLOCK IoStatusBlock;
00295     FILE_BASIC_INFORMATION FileInformation;
00296     HANDLE hFile;
00297     NTSTATUS Status;
00298     LARGE_INTEGER liSize;
00299 
00300     if (fl & FVF_FONTFILE)
00301     {
00302         pFileView = EngAllocMem(0, sizeof(FONTFILEVIEW), 'vffG');
00303     }
00304     else
00305     {
00306         pFileView = EngAllocMem(0, sizeof(FILEVIEW), 'liFg');
00307     }
00308 
00309     /* Check for success */
00310     if (!pFileView) return NULL;
00311 
00312     /* Check if the file is relative to system32 */
00313     if (fl & FVF_SYSTEMROOT)
00314     {
00315         hRootDir = ghSystem32Directory;
00316     }
00317     else
00318     {
00319         hRootDir = ghRootDirectory;
00320     }
00321 
00322     /* Initialize unicode string and object attributes */
00323     RtlInitUnicodeString(&ustrFileName, pwsz);
00324     InitializeObjectAttributes(&ObjectAttributes,
00325                                &ustrFileName,
00326                                OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE,
00327                                hRootDir,
00328                                NULL);
00329 
00330     /* Now open the file */
00331     Status = ZwCreateFile(&hFile,
00332                           FILE_READ_DATA,
00333                           &ObjectAttributes,
00334                           &IoStatusBlock,
00335                           NULL,
00336                           FILE_ATTRIBUTE_NORMAL,
00337                           0,
00338                           FILE_OPEN,
00339                           FILE_NON_DIRECTORY_FILE,
00340                           NULL,
00341                           0);
00342 
00343     Status = ZwQueryInformationFile(hFile,
00344                                     &IoStatusBlock,
00345                                     &FileInformation,
00346                                     sizeof(FILE_BASIC_INFORMATION),
00347                                     FileBasicInformation);
00348     if (NT_SUCCESS(Status))
00349     {
00350         pFileView->LastWriteTime = FileInformation.LastWriteTime;
00351     }
00352 
00353     /* Create a section from the file */
00354     liSize.QuadPart = cjSizeOfModule;
00355     Status = MmCreateSection(&pFileView->pSection,
00356                              SECTION_ALL_ACCESS,
00357                              NULL,
00358                              cjSizeOfModule ? &liSize : NULL,
00359                              fl & FVF_READONLY ? PAGE_EXECUTE_READ : PAGE_EXECUTE_READWRITE,
00360                              SEC_COMMIT,
00361                              hFile,
00362                              NULL);
00363 
00364     /* Close the file handle */
00365     ZwClose(hFile);
00366 
00367     if (!NT_SUCCESS(Status))
00368     {
00369         DPRINT1("Failed to create a section Status=0x%x\n", Status);
00370         EngFreeMem(pFileView);
00371         return NULL;
00372     }
00373 
00374 
00375     pFileView->pvKView = NULL;
00376     pFileView->pvViewFD = NULL;
00377     pFileView->cjView = 0;
00378 
00379     return pFileView;
00380 }
00381 
00382 HANDLE
00383 APIENTRY
00384 EngLoadModule(LPWSTR pwsz)
00385 {
00386     /* Forward to EngLoadModuleEx */
00387     return (HANDLE)EngLoadModuleEx(pwsz, 0, FVF_READONLY | FVF_SYSTEMROOT);
00388 }
00389 
00390 HANDLE
00391 APIENTRY
00392 EngLoadModuleForWrite(
00393     IN LPWSTR pwsz,
00394     IN ULONG  cjSizeOfModule)
00395 {
00396     /* Forward to EngLoadModuleEx */
00397     return (HANDLE)EngLoadModuleEx(pwsz, cjSizeOfModule, FVF_SYSTEMROOT);
00398 }
00399 
00400 PVOID
00401 APIENTRY
00402 EngMapModule(
00403     IN  HANDLE h,
00404     OUT PULONG pulSize)
00405 {
00406     PFILEVIEW pFileView = (PFILEVIEW)h;
00407     NTSTATUS Status;
00408 
00409     pFileView->cjView = 0;
00410 
00411     /* Map the section in session space */
00412     Status = MmMapViewInSessionSpace(pFileView->pSection,
00413                                      &pFileView->pvKView,
00414                                      &pFileView->cjView);
00415     if (!NT_SUCCESS(Status))
00416     {
00417         DPRINT1("Failed to map a section Status=0x%x\n", Status);
00418         *pulSize = 0;
00419         return NULL;
00420     }
00421 
00422     *pulSize = pFileView->cjView;
00423     return pFileView->pvKView;
00424 }
00425 
00426 VOID
00427 APIENTRY
00428 EngFreeModule(IN HANDLE h)
00429 {
00430     PFILEVIEW pFileView = (PFILEVIEW)h;
00431     NTSTATUS Status;
00432 
00433     /* Unmap the section */
00434     Status = MmUnmapViewInSessionSpace(pFileView->pvKView);
00435     if (!NT_SUCCESS(Status))
00436     {
00437         DPRINT1("MmUnmapViewInSessionSpace failed: 0x%lx\n", Status);
00438         ASSERT(FALSE);
00439     }
00440 
00441     /* Dereference the section */
00442     ObDereferenceObject(pFileView->pSection);
00443 
00444     /* Free the file view memory */
00445     EngFreeMem(pFileView);
00446 }
00447 
00448 PVOID
00449 APIENTRY
00450 EngMapFile(
00451     IN LPWSTR pwsz,
00452     IN ULONG cjSize,
00453     OUT ULONG_PTR *piFile)
00454 {
00455     HANDLE hModule;
00456     PVOID pvBase;
00457 
00458     /* Load the file */
00459     hModule = EngLoadModuleEx(pwsz, 0, 0);
00460     if (!hModule)
00461     {
00462         *piFile = 0;
00463         return NULL;
00464     }
00465 
00466     /* Map the file */
00467     pvBase = EngMapModule(hModule, &cjSize);
00468     if (!pvBase)
00469     {
00470         EngFreeModule(hModule);
00471         hModule = NULL;
00472     }
00473 
00474     /* Set iFile and return mapped base */
00475     *piFile = (ULONG_PTR)hModule;
00476     return pvBase;
00477 }
00478 
00479 BOOL
00480 APIENTRY
00481 EngUnmapFile(
00482     IN ULONG_PTR iFile)
00483 {
00484     HANDLE hModule = (HANDLE)iFile;
00485 
00486     EngFreeModule(hModule);
00487 
00488     return TRUE;
00489 }
00490 
00491 
00492 BOOL
00493 APIENTRY
00494 EngMapFontFileFD(
00495     IN  ULONG_PTR iFile,
00496     OUT PULONG    *ppjBuf,
00497     OUT ULONG     *pcjBuf)
00498 {
00499     // www.osr.com/ddk/graphics/gdifncs_0co7.htm
00500     UNIMPLEMENTED;
00501     return FALSE;
00502 }
00503 
00504 VOID
00505 APIENTRY
00506 EngUnmapFontFileFD(
00507     IN ULONG_PTR iFile)
00508 {
00509     // http://www.osr.com/ddk/graphics/gdifncs_6wbr.htm
00510     UNIMPLEMENTED;
00511 }
00512 
00513 BOOL
00514 APIENTRY
00515 EngMapFontFile(
00516     ULONG_PTR iFile,
00517     PULONG    *ppjBuf,
00518     ULONG     *pcjBuf)
00519 {
00520     // www.osr.com/ddk/graphics/gdifncs_3up3.htm
00521     return EngMapFontFileFD(iFile, ppjBuf, pcjBuf);
00522 }
00523 
00524 VOID
00525 APIENTRY
00526 EngUnmapFontFile(
00527     IN ULONG_PTR iFile)
00528 {
00529     // www.osr.com/ddk/graphics/gdifncs_09wn.htm
00530     EngUnmapFontFileFD(iFile);
00531 }

Generated on Sat May 26 2012 04:37:08 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.