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

io.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.