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

reqtools.c
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 1998-2005 ReactOS Team (and the authors from the programmers section)
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software
00016  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00017  *
00018  *
00019  * PROJECT:         ReactOS kernel
00020  * FILE:            ntoskrnl/mm/section.c
00021  * PURPOSE:         Implements section objects
00022  *
00023  * PROGRAMMERS:     Rex Jolliff
00024  *                  David Welch
00025  *                  Eric Kohl
00026  *                  Emanuele Aliberti
00027  *                  Eugene Ingerman
00028  *                  Casper Hornstrup
00029  *                  KJK::Hyperion
00030  *                  Guido de Jong
00031  *                  Ge van Geldorp
00032  *                  Royce Mitchell III
00033  *                  Filip Navara
00034  *                  Aleksey Bragin
00035  *                  Jason Filby
00036  *                  Thomas Weidenmueller
00037  *                  Gunnar Andre' Dalsnes
00038  *                  Mike Nordell
00039  *                  Alex Ionescu
00040  *                  Gregor Anich
00041  *                  Steven Edwards
00042  *                  Herve Poussineau
00043  */
00044 
00045 /*
00046   This file contains functions used by fault.c to do blocking resource
00047   acquisition.  To call one of these functions, fill out your
00048   MM_REQUIRED_RESOURCES with a pointer to the desired function and configure
00049   the other members as below.
00050  */
00051 
00052 /* INCLUDES *****************************************************************/
00053 
00054 #include <ntoskrnl.h>
00055 #include "newmm.h"
00056 #define NDEBUG
00057 #include <debug.h>
00058 
00059 #define DPRINTC DPRINT
00060 
00061 VOID
00062 NTAPI
00063 MmBuildMdlFromPages(PMDL Mdl, PPFN_NUMBER Pages);
00064 
00065 /*
00066 
00067 Blocking function to acquire zeroed pages from the balancer.
00068 
00069 Upon entry:
00070 
00071 Required->Amount: Number of pages to acquire
00072 Required->Consumer: consumer to charge the page to
00073 
00074 Upon return:
00075 
00076 Required->Pages[0..Amount]: Allocated pages.
00077 
00078 The function fails unless all requested pages can be allocated.
00079 
00080  */
00081 NTSTATUS
00082 NTAPI
00083 MiGetOnePage(PMMSUPPORT AddressSpace,
00084              PMEMORY_AREA MemoryArea,
00085              PMM_REQUIRED_RESOURCES Required)
00086 {
00087     ULONG i;
00088     NTSTATUS Status = STATUS_SUCCESS;
00089 
00090     for (i = 0; i < Required->Amount; i++)
00091     {
00092         DPRINTC("MiGetOnePage(%s:%d)\n", Required->File, Required->Line);
00093         Status = MmRequestPageMemoryConsumer(Required->Consumer,
00094                                              TRUE,
00095                                              &Required->Page[i]);
00096         if (!NT_SUCCESS(Status))
00097         {
00098             while (i > 0)
00099             {
00100                 MmReleasePageMemoryConsumer(Required->Consumer,
00101                                             Required->Page[i-1]);
00102                 i--;
00103             }
00104             return Status;
00105         }
00106     }
00107 
00108     return Status;
00109 }
00110 
00111 /*
00112 
00113 Blocking function to read (part of) a page from a file.
00114 
00115 Upon entry:
00116 
00117 Required->Context: a FILE_OBJECT to read
00118 Required->Consumer: consumer to charge the page to
00119 Required->FileOffset: Offset to read at
00120 Required->Amount: Number of bytes to read (0 -> 4096)
00121 
00122 Upon return:
00123 
00124 Required->Page[Required->Offset]: The allocated and read in page
00125 
00126 The indicated page is filled to Required->Amount with file data and zeroed
00127 afterward.
00128 
00129  */
00130 
00131 NTSTATUS
00132 NTAPI
00133 MiReadFilePage(PMMSUPPORT AddressSpace,
00134                PMEMORY_AREA MemoryArea,
00135                PMM_REQUIRED_RESOURCES RequiredResources)
00136 {
00137     PFILE_OBJECT FileObject = RequiredResources->Context;
00138     PPFN_NUMBER Page = &RequiredResources->Page[RequiredResources->Offset];
00139     PLARGE_INTEGER FileOffset = &RequiredResources->FileOffset;
00140     NTSTATUS Status;
00141     PVOID PageBuf = NULL;
00142     KEVENT Event;
00143     IO_STATUS_BLOCK IOSB;
00144     UCHAR MdlBase[sizeof(MDL) + sizeof(ULONG)];
00145     PMDL Mdl = (PMDL)MdlBase;
00146     KIRQL OldIrql;
00147 
00148     DPRINTC("Pulling page %08x%08x from %wZ to %x\n",
00149             FileOffset->u.HighPart,
00150             FileOffset->u.LowPart,
00151             &FileObject->FileName,
00152             Page);
00153 
00154     Status = MmRequestPageMemoryConsumer(RequiredResources->Consumer,
00155                                          TRUE,
00156                                          Page);
00157 
00158     if (!NT_SUCCESS(Status))
00159     {
00160         DPRINT1("Status: %x\n", Status);
00161         return Status;
00162     }
00163 
00164     MmInitializeMdl(Mdl, NULL, PAGE_SIZE);
00165     MmBuildMdlFromPages(Mdl, Page);
00166     Mdl->MdlFlags |= MDL_PAGES_LOCKED;
00167 
00168     KeInitializeEvent(&Event, NotificationEvent, FALSE);
00169     Status = IoPageRead(FileObject, Mdl, FileOffset, &Event, &IOSB);
00170     if (Status == STATUS_PENDING)
00171     {
00172         KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
00173         Status = IOSB.Status;
00174     }
00175     if (Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA)
00176     {
00177         MmUnmapLockedPages (Mdl->MappedSystemVa, Mdl);
00178     }
00179 
00180     PageBuf = MiMapPageInHyperSpace(PsGetCurrentProcess(), *Page, &OldIrql);
00181     if (!PageBuf)
00182     {
00183         MmReleasePageMemoryConsumer(RequiredResources->Consumer, *Page);
00184         return STATUS_NO_MEMORY;
00185     }
00186 
00187     RtlZeroMemory((PCHAR)PageBuf+RequiredResources->Amount,
00188                   PAGE_SIZE-RequiredResources->Amount);
00189 
00190     MiUnmapPageInHyperSpace(PsGetCurrentProcess(), PageBuf, OldIrql);
00191 
00192     DPRINT("Read Status %x (Page %x)\n", Status, *Page);
00193 
00194     if (!NT_SUCCESS(Status))
00195     {
00196         MmReleasePageMemoryConsumer(RequiredResources->Consumer, *Page);
00197         DPRINT("Status: %x\n", Status);
00198         return Status;
00199     }
00200 
00201     return STATUS_SUCCESS;
00202 }
00203 
00204 /*
00205 
00206 Blocking function to read a swap page into a memory page.
00207 
00208 Upon entry:
00209 
00210 Required->Consumer: consumer to charge the page to
00211 Required->SwapEntry: swap entry to use
00212 
00213 Upon return:
00214 
00215 Required->Page[Required->Offset]: Populated page
00216 
00217 */
00218 
00219 NTSTATUS
00220 NTAPI
00221 MiSwapInPage(PMMSUPPORT AddressSpace,
00222              PMEMORY_AREA MemoryArea,
00223              PMM_REQUIRED_RESOURCES Resources)
00224 {
00225     NTSTATUS Status;
00226 
00227     Status = MmRequestPageMemoryConsumer(Resources->Consumer,
00228                                          TRUE,
00229                                          &Resources->Page[Resources->Offset]);
00230     if (!NT_SUCCESS(Status))
00231     {
00232         DPRINT1("MmRequestPageMemoryConsumer failed, status = %x\n", Status);
00233         return Status;
00234     }
00235 
00236     Status = MmReadFromSwapPage(Resources->SwapEntry,
00237                                 Resources->Page[Resources->Offset]);
00238     if (!NT_SUCCESS(Status))
00239     {
00240         DPRINT1("MmReadFromSwapPage failed, status = %x\n", Status);
00241         return Status;
00242     }
00243 
00244     MmSetSavedSwapEntryPage(Resources->Page[Resources->Offset],
00245                             Resources->SwapEntry);
00246 
00247     DPRINT1("MiSwapInPage(%x,%x)\n",
00248             Resources->Page[Resources->Offset],
00249             Resources->SwapEntry);
00250 
00251     return Status;
00252 }
00253 
00254 /*
00255 
00256 A way to write a page without a lock acquired using the same blocking mechanism
00257 as resource acquisition.
00258 
00259 Upon entry:
00260 
00261 Required->Page[Required->Offset]: Page to write
00262 Required->Context: FILE_OBJECT to write to
00263 Required->FileOffset: offset to write at
00264 
00265 This always does a paging write with whole page size.  Note that paging IO
00266 doesn't change the valid data length of a file.
00267 
00268 */
00269 
00270 NTSTATUS
00271 NTAPI
00272 MiWriteFilePage(PMMSUPPORT AddressSpace,
00273                 PMEMORY_AREA MemoryArea,
00274                 PMM_REQUIRED_RESOURCES Required)
00275 {
00276     DPRINT1("MiWriteFilePage(%x,%x)\n",
00277             Required->Page[Required->Offset],
00278             Required->FileOffset.LowPart);
00279 
00280     return MiWriteBackPage(Required->Context,
00281                            &Required->FileOffset,
00282                            PAGE_SIZE,
00283                            Required->Page[Required->Offset]);
00284 }

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