ReactOS  0.4.14-dev-49-gfb4591c
reqtools.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1998-2005 ReactOS Team (and the authors from the programmers section)
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  *
19  * PROJECT: ReactOS kernel
20  * FILE: ntoskrnl/cache/section/reqtools.c
21  * PURPOSE: Implements section objects
22  *
23  * PROGRAMMERS: Rex Jolliff
24  * David Welch
25  * Eric Kohl
26  * Emanuele Aliberti
27  * Eugene Ingerman
28  * Casper Hornstrup
29  * KJK::Hyperion
30  * Guido de Jong
31  * Ge van Geldorp
32  * Royce Mitchell III
33  * Filip Navara
34  * Aleksey Bragin
35  * Jason Filby
36  * Thomas Weidenmueller
37  * Gunnar Andre' Dalsnes
38  * Mike Nordell
39  * Alex Ionescu
40  * Gregor Anich
41  * Steven Edwards
42  * Herve Poussineau
43  */
44 
45 /*
46  This file contains functions used by fault.c to do blocking resource
47  acquisition. To call one of these functions, fill out your
48  MM_REQUIRED_RESOURCES with a pointer to the desired function and configure
49  the other members as below.
50  */
51 
52 /* INCLUDES *****************************************************************/
53 
54 #include <ntoskrnl.h>
55 #include "newmm.h"
56 #define NDEBUG
57 #include <debug.h>
58 
59 #define DPRINTC DPRINT
60 
61 VOID
62 NTAPI
64 
65 /*
66 
67 Blocking function to acquire zeroed pages from the balancer.
68 
69 Upon entry:
70 
71 Required->Amount: Number of pages to acquire
72 Required->Consumer: consumer to charge the page to
73 
74 Upon return:
75 
76 Required->Pages[0..Amount]: Allocated pages.
77 
78 The function fails unless all requested pages can be allocated.
79 
80  */
82 NTAPI
86 {
87  ULONG i;
89 
90  for (i = 0; i < Required->Amount; i++)
91  {
92  DPRINTC("MiGetOnePage(%s:%d)\n", Required->File, Required->Line);
94  TRUE,
95  &Required->Page[i]);
96  if (!NT_SUCCESS(Status))
97  {
98  while (i > 0)
99  {
101  Required->Page[i-1]);
102  i--;
103  }
104  return Status;
105  }
106  }
107 
108  return Status;
109 }
110 
111 /*
112 
113 Blocking function to read (part of) a page from a file.
114 
115 Upon entry:
116 
117 Required->Context: a FILE_OBJECT to read
118 Required->Consumer: consumer to charge the page to
119 Required->FileOffset: Offset to read at
120 Required->Amount: Number of bytes to read (0 -> 4096)
121 
122 Upon return:
123 
124 Required->Page[Required->Offset]: The allocated and read in page
125 
126 The indicated page is filled to Required->Amount with file data and zeroed
127 afterward.
128 
129  */
130 
131 NTSTATUS
132 NTAPI
135  PMM_REQUIRED_RESOURCES RequiredResources)
136 {
137  PFILE_OBJECT FileObject = RequiredResources->Context;
138  PPFN_NUMBER Page = &RequiredResources->Page[RequiredResources->Offset];
139  PLARGE_INTEGER FileOffset = &RequiredResources->FileOffset;
141  PVOID PageBuf = NULL;
142  KEVENT Event;
143  IO_STATUS_BLOCK IOSB;
144  UCHAR MdlBase[sizeof(MDL) + sizeof(ULONG)];
145  PMDL Mdl = (PMDL)MdlBase;
146  KIRQL OldIrql;
147 
148  DPRINTC("Pulling page %I64x from %wZ to %Ix\n",
149  FileOffset->QuadPart,
150  &FileObject->FileName,
151  *Page);
152 
153  Status = MmRequestPageMemoryConsumer(RequiredResources->Consumer,
154  TRUE,
155  Page);
156 
157  if (!NT_SUCCESS(Status))
158  {
159  DPRINT1("Status: %x\n", Status);
160  return Status;
161  }
162 
164  MmBuildMdlFromPages(Mdl, Page);
165  Mdl->MdlFlags |= MDL_PAGES_LOCKED;
166 
168  Status = IoPageRead(FileObject, Mdl, FileOffset, &Event, &IOSB);
169  if (Status == STATUS_PENDING)
170  {
172  Status = IOSB.Status;
173  }
174  if (Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA)
175  {
176  MmUnmapLockedPages (Mdl->MappedSystemVa, Mdl);
177  }
178 
179  PageBuf = MiMapPageInHyperSpace(PsGetCurrentProcess(), *Page, &OldIrql);
180  if (!PageBuf)
181  {
182  MmReleasePageMemoryConsumer(RequiredResources->Consumer, *Page);
183  return STATUS_NO_MEMORY;
184  }
185 
186  RtlZeroMemory((PCHAR)PageBuf+RequiredResources->Amount,
187  PAGE_SIZE-RequiredResources->Amount);
188 
190 
191  DPRINT("Read Status %x (Page %x)\n", Status, *Page);
192 
193  if (!NT_SUCCESS(Status))
194  {
195  MmReleasePageMemoryConsumer(RequiredResources->Consumer, *Page);
196  DPRINT("Status: %x\n", Status);
197  return Status;
198  }
199 
200  return STATUS_SUCCESS;
201 }
202 
203 /*
204 
205 Blocking function to read a swap page into a memory page.
206 
207 Upon entry:
208 
209 Required->Consumer: consumer to charge the page to
210 Required->SwapEntry: swap entry to use
211 
212 Upon return:
213 
214 Required->Page[Required->Offset]: Populated page
215 
216 */
217 
218 NTSTATUS
219 NTAPI
223 {
225 
227  TRUE,
228  &Resources->Page[Resources->Offset]);
229  if (!NT_SUCCESS(Status))
230  {
231  DPRINT1("MmRequestPageMemoryConsumer failed, status = %x\n", Status);
232  return Status;
233  }
234 
235  Status = MmReadFromSwapPage(Resources->SwapEntry,
236  Resources->Page[Resources->Offset]);
237  if (!NT_SUCCESS(Status))
238  {
239  DPRINT1("MmReadFromSwapPage failed, status = %x\n", Status);
240  return Status;
241  }
242 
244  Resources->SwapEntry);
245 
246  DPRINT1("MiSwapInPage(%x,%x)\n",
247  Resources->Page[Resources->Offset],
248  Resources->SwapEntry);
249 
250  return Status;
251 }
252 
253 /*
254 
255 A way to write a page without a lock acquired using the same blocking mechanism
256 as resource acquisition.
257 
258 Upon entry:
259 
260 Required->Page[Required->Offset]: Page to write
261 Required->Context: FILE_OBJECT to write to
262 Required->FileOffset: offset to write at
263 
264 This always does a paging write with whole page size. Note that paging IO
265 doesn't change the valid data length of a file.
266 
267 */
268 
269 NTSTATUS
270 NTAPI
274 {
275  DPRINT1("MiWriteFilePage(%x,%x)\n",
276  Required->Page[Required->Offset],
277  Required->FileOffset.LowPart);
278 
279  return MiWriteBackPage(Required->Context,
280  &Required->FileOffset,
281  PAGE_SIZE,
282  Required->Page[Required->Offset]);
283 }
signed char * PCHAR
Definition: retypes.h:7
#define TRUE
Definition: types.h:120
#define MmInitializeMdl(_MemoryDescriptorList, _BaseVa, _Length)
_In_ ULONG _In_ PHYSICAL_ADDRESS _Inout_ PULONG AddressSpace
Definition: iofuncs.h:2268
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS NTAPI MmReleasePageMemoryConsumer(ULONG Consumer, PFN_NUMBER Page)
Definition: balance.c:97
NTSTATUS NTAPI MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN MyWait, PPFN_NUMBER AllocatedPage)
Definition: balance.c:229
NTSTATUS NTAPI IoPageRead(IN PFILE_OBJECT FileObject, IN PMDL Mdl, IN PLARGE_INTEGER Offset, IN PKEVENT Event, IN PIO_STATUS_BLOCK StatusBlock)
Definition: iofunc.c:1199
NTSTATUS NTAPI MmReadFromSwapPage(SWAPENTRY SwapEntry, PFN_NUMBER Page)
Definition: pagefile.c:194
PVOID PMDL
Definition: usb.h:39
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
#define MDL_MAPPED_TO_SYSTEM_VA
Definition: mmtypes.h:18
UCHAR KIRQL
Definition: env_spec_w32.h:591
ULONG * PPFN_NUMBER
Definition: ke.h:8
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
PFN_NUMBER Page[2]
Definition: newmm.h:90
VOID NTAPI MmUnmapLockedPages(IN PVOID BaseAddress, IN PMDL Mdl)
Definition: mdlsup.c:841
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:435
#define PsGetCurrentProcess
Definition: psfuncs.h:17
PVOID NTAPI MiMapPageInHyperSpace(IN PEPROCESS Process, IN PFN_NUMBER Page, IN PKIRQL OldIrql)
Definition: hypermap.c:30
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
NTSTATUS NTAPI MiWriteFilePage(PMMSUPPORT AddressSpace, PMEMORY_AREA MemoryArea, PMM_REQUIRED_RESOURCES Required)
Definition: reqtools.c:271
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:593
#define MDL_PAGES_LOCKED
Definition: mmtypes.h:19
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
NTSTATUS NTAPI MiSwapInPage(PMMSUPPORT AddressSpace, PMEMORY_AREA MemoryArea, PMM_REQUIRED_RESOURCES Resources)
Definition: reqtools.c:220
VOID NTAPI MmBuildMdlFromPages(PMDL Mdl, PPFN_NUMBER Pages)
Definition: pagefile.c:98
* PFILE_OBJECT
Definition: iotypes.h:1955
VOID NTAPI MiUnmapPageInHyperSpace(IN PEPROCESS Process, IN PVOID Address, IN KIRQL OldIrql)
Definition: hypermap.c:93
unsigned char UCHAR
Definition: xmlstorage.h:181
MDL
Definition: mmtypes.h:117
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
#define PAGE_SIZE
Definition: env_spec_w32.h:49
Status
Definition: gdiplustypes.h:24
NTSTATUS NTAPI MiGetOnePage(PMMSUPPORT AddressSpace, PMEMORY_AREA MemoryArea, PMM_REQUIRED_RESOURCES Required)
Definition: reqtools.c:83
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:151
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
#define DPRINT1
Definition: precomp.h:8
#define DPRINTC
Definition: reqtools.c:59
VOID NTAPI MmSetSavedSwapEntryPage(PFN_NUMBER Page, SWAPENTRY SavedSwapEntry)
Definition: freelist.c:454
LARGE_INTEGER FileOffset
Definition: newmm.h:88
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
struct _MEMORY_AREA struct _MM_REQUIRED_RESOURCES * Required
Definition: newmm.h:66
return STATUS_SUCCESS
Definition: btrfs.c:2966
NTSTATUS NTAPI MiReadFilePage(PMMSUPPORT AddressSpace, PMEMORY_AREA MemoryArea, PMM_REQUIRED_RESOURCES RequiredResources)
Definition: reqtools.c:133
#define MiWriteBackPage(F, O, L, P)
Definition: newmm.h:209