Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenio.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 /* INCLUDES *****************************************************************/ 00046 00047 #include <ntoskrnl.h> 00048 #include "newmm.h" 00049 #define NDEBUG 00050 #include <debug.h> 00051 #include <reactos/exeformat.h> 00052 00053 #if defined (ALLOC_PRAGMA) 00054 #pragma alloc_text(INIT, MmCreatePhysicalMemorySection) 00055 #pragma alloc_text(INIT, MmInitSectionImplementation) 00056 #endif 00057 00058 KEVENT CcpLazyWriteEvent; 00059 00060 PDEVICE_OBJECT 00061 NTAPI 00062 MmGetDeviceObjectForFile(IN PFILE_OBJECT FileObject) 00063 { 00064 return IoGetRelatedDeviceObject(FileObject); 00065 } 00066 00067 /* 00068 00069 Note: 00070 This completion function is really required. Paging io completion does almost 00071 nothing, including freeing the mdls. 00072 00073 */ 00074 NTSTATUS 00075 NTAPI 00076 MiSimpleReadComplete(PDEVICE_OBJECT DeviceObject, 00077 PIRP Irp, 00078 PVOID Context) 00079 { 00080 PMDL Mdl = Irp->MdlAddress; 00081 00082 /* Unlock MDL Pages, page 167. */ 00083 DPRINT("MiSimpleReadComplete %p\n", Irp); 00084 while (Mdl) 00085 { 00086 DPRINT("MDL Unlock %p\n", Mdl); 00087 MmUnlockPages(Mdl); 00088 Mdl = Mdl->Next; 00089 } 00090 00091 /* Check if there's an MDL */ 00092 while ((Mdl = Irp->MdlAddress)) 00093 { 00094 /* Clear all of them */ 00095 Irp->MdlAddress = Mdl->Next; 00096 IoFreeMdl(Mdl); 00097 } 00098 00099 return STATUS_SUCCESS; 00100 } 00101 00102 /* 00103 00104 MiSimpleRead is a convenience function that provides either paging or non 00105 paging reads. The caching and mm systems use this in paging mode, where 00106 a completion function is required as above. The Paging BOOLEAN determines 00107 whether the read is issued as a paging read or as an ordinary buffered read. 00108 00109 */ 00110 00111 NTSTATUS 00112 NTAPI 00113 MiSimpleRead(PFILE_OBJECT FileObject, 00114 PLARGE_INTEGER FileOffset, 00115 PVOID Buffer, 00116 ULONG Length, 00117 BOOLEAN Paging, 00118 PIO_STATUS_BLOCK ReadStatus) 00119 { 00120 NTSTATUS Status; 00121 PIRP Irp = NULL; 00122 KEVENT ReadWait; 00123 PDEVICE_OBJECT DeviceObject; 00124 PIO_STACK_LOCATION IrpSp; 00125 00126 ASSERT(FileObject); 00127 ASSERT(FileOffset); 00128 ASSERT(Buffer); 00129 ASSERT(ReadStatus); 00130 00131 DeviceObject = MmGetDeviceObjectForFile(FileObject); 00132 ReadStatus->Status = STATUS_INTERNAL_ERROR; 00133 ReadStatus->Information = 0; 00134 00135 ASSERT(DeviceObject); 00136 00137 DPRINT("PAGING READ: FileObject %p <%wZ> Offset %08x%08x Length %d\n", 00138 FileObject, 00139 &FileObject->FileName, 00140 FileOffset->HighPart, 00141 FileOffset->LowPart, 00142 Length); 00143 00144 KeInitializeEvent(&ReadWait, NotificationEvent, FALSE); 00145 00146 Irp = IoBuildAsynchronousFsdRequest(IRP_MJ_READ, 00147 DeviceObject, 00148 Buffer, 00149 Length, 00150 FileOffset, 00151 ReadStatus); 00152 00153 if (!Irp) 00154 { 00155 return STATUS_NO_MEMORY; 00156 } 00157 00158 Irp->Flags |= (Paging ? IRP_PAGING_IO | IRP_SYNCHRONOUS_PAGING_IO | IRP_NOCACHE : 0) | IRP_SYNCHRONOUS_API; 00159 00160 Irp->UserEvent = &ReadWait; 00161 Irp->Tail.Overlay.OriginalFileObject = FileObject; 00162 Irp->Tail.Overlay.Thread = PsGetCurrentThread(); 00163 IrpSp = IoGetNextIrpStackLocation(Irp); 00164 IrpSp->Control |= SL_INVOKE_ON_SUCCESS | SL_INVOKE_ON_ERROR; 00165 IrpSp->FileObject = FileObject; 00166 IrpSp->CompletionRoutine = MiSimpleReadComplete; 00167 00168 /* Non paging case, the FileObject will be dereferenced at completion */ 00169 if (!Paging) 00170 ObReferenceObject(FileObject); 00171 00172 Status = IoCallDriver(DeviceObject, Irp); 00173 if (Status == STATUS_PENDING) 00174 { 00175 DPRINT("KeWaitForSingleObject(&ReadWait)\n"); 00176 if (!NT_SUCCESS(KeWaitForSingleObject(&ReadWait, 00177 Suspended, 00178 KernelMode, 00179 FALSE, 00180 NULL))) 00181 { 00182 DPRINT1("Warning: Failed to wait for synchronous IRP\n"); 00183 ASSERT(FALSE); 00184 return Status; 00185 } 00186 } 00187 00188 DPRINT("Paging IO Done: %08x\n", ReadStatus->Status); 00189 Status = ReadStatus->Status == STATUS_END_OF_FILE ? STATUS_SUCCESS : ReadStatus->Status; 00190 return Status; 00191 } 00192 00193 /* 00194 00195 Convenience function for writing from kernel space. This issues a paging 00196 write in all cases. 00197 00198 */ 00199 00200 NTSTATUS 00201 NTAPI 00202 _MiSimpleWrite(PFILE_OBJECT FileObject, 00203 PLARGE_INTEGER FileOffset, 00204 PVOID Buffer, 00205 ULONG Length, 00206 PIO_STATUS_BLOCK ReadStatus, 00207 const char *File, 00208 int Line) 00209 { 00210 NTSTATUS Status; 00211 PIRP Irp = NULL; 00212 KEVENT ReadWait; 00213 PDEVICE_OBJECT DeviceObject; 00214 PIO_STACK_LOCATION IrpSp; 00215 00216 ASSERT(FileObject); 00217 ASSERT(FileOffset); 00218 ASSERT(Buffer); 00219 ASSERT(ReadStatus); 00220 00221 DeviceObject = MmGetDeviceObjectForFile(FileObject); 00222 ASSERT(DeviceObject); 00223 00224 DPRINT("PAGING WRITE: FileObject %x <%wZ> Offset %x Length %d (%s:%d)\n", 00225 FileObject, 00226 &FileObject->FileName, 00227 FileOffset->LowPart, 00228 Length, 00229 File, 00230 Line); 00231 00232 KeInitializeEvent(&ReadWait, NotificationEvent, FALSE); 00233 00234 Irp = IoBuildAsynchronousFsdRequest(IRP_MJ_WRITE, 00235 DeviceObject, 00236 Buffer, 00237 Length, 00238 FileOffset, 00239 ReadStatus); 00240 00241 if (!Irp) 00242 { 00243 return STATUS_NO_MEMORY; 00244 } 00245 00246 Irp->Flags = IRP_PAGING_IO | IRP_SYNCHRONOUS_PAGING_IO | IRP_NOCACHE | IRP_SYNCHRONOUS_API; 00247 00248 Irp->UserEvent = &ReadWait; 00249 Irp->Tail.Overlay.OriginalFileObject = FileObject; 00250 Irp->Tail.Overlay.Thread = PsGetCurrentThread(); 00251 IrpSp = IoGetNextIrpStackLocation(Irp); 00252 IrpSp->Control |= SL_INVOKE_ON_SUCCESS | SL_INVOKE_ON_ERROR; 00253 IrpSp->FileObject = FileObject; 00254 IrpSp->CompletionRoutine = MiSimpleReadComplete; 00255 00256 DPRINT("Call Driver\n"); 00257 Status = IoCallDriver(DeviceObject, Irp); 00258 DPRINT("Status %x\n", Status); 00259 00260 if (Status == STATUS_PENDING) 00261 { 00262 DPRINT("KeWaitForSingleObject(&ReadWait)\n"); 00263 if (!NT_SUCCESS(KeWaitForSingleObject(&ReadWait, 00264 Suspended, 00265 KernelMode, 00266 FALSE, 00267 NULL))) 00268 { 00269 DPRINT1("Warning: Failed to wait for synchronous IRP\n"); 00270 ASSERT(FALSE); 00271 return Status; 00272 } 00273 } 00274 00275 DPRINT("Paging IO Done: %08x\n", ReadStatus->Status); 00276 return ReadStatus->Status; 00277 } 00278 00279 extern KEVENT MpwThreadEvent; 00280 FAST_MUTEX MiWriteMutex; 00281 00282 /* 00283 00284 Function which uses MiSimpleWrite to write back a single page to a file. 00285 The page in question does not need to be mapped. This function could be 00286 made a bit more efficient by avoiding the copy and making a system space 00287 mdl. 00288 00289 */ 00290 00291 NTSTATUS 00292 NTAPI 00293 _MiWriteBackPage(PFILE_OBJECT FileObject, 00294 PLARGE_INTEGER FileOffset, 00295 ULONG Length, 00296 PFN_NUMBER Page, 00297 const char *File, 00298 int Line) 00299 { 00300 NTSTATUS Status; 00301 PVOID Hyperspace; 00302 IO_STATUS_BLOCK Iosb; 00303 KIRQL OldIrql; 00304 PVOID PageBuffer = ExAllocatePool(NonPagedPool, PAGE_SIZE); 00305 00306 if (!PageBuffer) return STATUS_NO_MEMORY; 00307 00308 Hyperspace = MiMapPageInHyperSpace(PsGetCurrentProcess(), Page, &OldIrql); 00309 if (!Hyperspace) 00310 { 00311 ExFreePool(PageBuffer); 00312 return STATUS_NO_MEMORY; 00313 } 00314 RtlCopyMemory(PageBuffer, Hyperspace, PAGE_SIZE); 00315 MiUnmapPageInHyperSpace(PsGetCurrentProcess(), Hyperspace, OldIrql); 00316 00317 DPRINT("MiWriteBackPage(%wZ,%08x%08x,%s:%d)\n", 00318 &FileObject->FileName, 00319 FileOffset->u.HighPart, 00320 FileOffset->u.LowPart, 00321 File, 00322 Line); 00323 00324 Status = MiSimpleWrite(FileObject, 00325 FileOffset, 00326 PageBuffer, 00327 Length, 00328 &Iosb); 00329 00330 ExFreePool(PageBuffer); 00331 00332 if (!NT_SUCCESS(Status)) 00333 { 00334 DPRINT1("MiSimpleWrite failed (%x)\n", Status); 00335 } 00336 00337 return Status; 00338 } Generated on Sun May 27 2012 04:27:44 for ReactOS by
1.7.6.1
|