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

blockdev.c
Go to the documentation of this file.
00001 /*
00002  * COPYRIGHT:        See COPYING in the top level directory
00003  * PROJECT:          ReactOS kernel
00004  * FILE:             drivers/fs/vfat/blockdev.c
00005  * PURPOSE:          Temporary sector reading support
00006  * PROGRAMMER:       David Welch (welch@cwcom.net)
00007  * UPDATE HISTORY:
00008  */
00009 
00010 /* INCLUDES *****************************************************************/
00011 
00012 #define NDEBUG
00013 #include "vfat.h"
00014 
00015 /* FUNCTIONS ***************************************************************/
00016 
00017 static IO_COMPLETION_ROUTINE VfatReadWritePartialCompletion;
00018 static NTSTATUS NTAPI
00019 VfatReadWritePartialCompletion (IN PDEVICE_OBJECT DeviceObject,
00020                 IN PIRP Irp,
00021                 IN PVOID Context)
00022 {
00023   PVFAT_IRP_CONTEXT IrpContext;
00024   PMDL Mdl;
00025 
00026   UNREFERENCED_PARAMETER(DeviceObject);
00027 
00028   DPRINT("VfatReadWritePartialCompletion() called\n");
00029 
00030   IrpContext = (PVFAT_IRP_CONTEXT)Context;
00031 
00032   while ((Mdl = Irp->MdlAddress))
00033     {
00034       Irp->MdlAddress = Mdl->Next;
00035       IoFreeMdl(Mdl);
00036     }
00037   if (Irp->PendingReturned)
00038     {
00039       IrpContext->Flags |= IRPCONTEXT_PENDINGRETURNED;
00040     }
00041   else
00042     {
00043       IrpContext->Flags &= ~IRPCONTEXT_PENDINGRETURNED;
00044     }
00045   if (!NT_SUCCESS(Irp->IoStatus.Status))
00046     {
00047       IrpContext->Irp->IoStatus.Status = Irp->IoStatus.Status;
00048     }
00049   if (0 == InterlockedDecrement((PLONG)&IrpContext->RefCount) &&
00050       IrpContext->Flags & IRPCONTEXT_PENDINGRETURNED)
00051     {
00052       KeSetEvent(&IrpContext->Event, IO_NO_INCREMENT, FALSE);
00053     }
00054   IoFreeIrp(Irp);
00055 
00056   DPRINT("VfatReadWritePartialCompletion() done\n");
00057 
00058   return STATUS_MORE_PROCESSING_REQUIRED;
00059 }
00060 
00061 NTSTATUS
00062 VfatReadDisk (IN PDEVICE_OBJECT pDeviceObject,
00063           IN PLARGE_INTEGER ReadOffset,
00064           IN ULONG ReadLength,
00065           IN OUT PUCHAR Buffer,
00066           IN BOOLEAN Override)
00067 {
00068   PIO_STACK_LOCATION Stack;
00069   PIRP Irp;
00070   IO_STATUS_BLOCK IoStatus;
00071   KEVENT event;
00072   NTSTATUS Status;
00073 
00074 again:
00075   KeInitializeEvent (&event, NotificationEvent, FALSE);
00076 
00077   DPRINT ("VfatReadDisk(pDeviceObject %p, Offset %I64x, Length %d, Buffer %p)\n",
00078       pDeviceObject, ReadOffset->QuadPart, ReadLength, Buffer);
00079 
00080   DPRINT ("Building synchronous FSD Request...\n");
00081   Irp = IoBuildSynchronousFsdRequest (IRP_MJ_READ,
00082                       pDeviceObject,
00083                       Buffer,
00084                       ReadLength,
00085                       ReadOffset,
00086                       &event,
00087                       &IoStatus);
00088   if (Irp == NULL)
00089     {
00090       DPRINT("IoBuildSynchronousFsdRequest failed\n");
00091       return(STATUS_UNSUCCESSFUL);
00092     }
00093 
00094   if (Override)
00095     {
00096       Stack = IoGetNextIrpStackLocation(Irp);
00097       Stack->Flags |= SL_OVERRIDE_VERIFY_VOLUME;
00098     }
00099 
00100   DPRINT ("Calling IO Driver... with irp %p\n", Irp);
00101   Status = IoCallDriver (pDeviceObject, Irp);
00102 
00103   DPRINT ("Waiting for IO Operation for %p\n", Irp);
00104   if (Status == STATUS_PENDING)
00105     {
00106       DPRINT ("Operation pending\n");
00107       KeWaitForSingleObject (&event, Suspended, KernelMode, FALSE, NULL);
00108       DPRINT ("Getting IO Status... for %p\n", Irp);
00109       Status = IoStatus.Status;
00110     }
00111 
00112   if (Status == STATUS_VERIFY_REQUIRED)
00113     {
00114       PDEVICE_OBJECT DeviceToVerify;
00115 
00116       DPRINT1 ("Media change detected!\n");
00117 
00118       /* Find the device to verify and reset the thread field to empty value again. */
00119       DeviceToVerify = IoGetDeviceToVerify (PsGetCurrentThread ());
00120       IoSetDeviceToVerify (PsGetCurrentThread (), NULL);
00121       Status = IoVerifyVolume (DeviceToVerify,
00122                                FALSE);
00123 
00124       if (NT_SUCCESS(Status))
00125         {
00126           DPRINT1 ("Volume verification successful; Reissuing read request\n");
00127           goto again;
00128         }
00129     }
00130 
00131   if (!NT_SUCCESS (Status))
00132     {
00133       DPRINT ("IO failed!!! VfatReadDisk : Error code: %x\n", Status);
00134       DPRINT ("(pDeviceObject %p, Offset %I64x, Size %d, Buffer %p\n",
00135           pDeviceObject, ReadOffset->QuadPart, ReadLength, Buffer);
00136       return (Status);
00137     }
00138   DPRINT ("Block request succeeded for %p\n", Irp);
00139   return (STATUS_SUCCESS);
00140 }
00141 
00142 NTSTATUS
00143 VfatReadDiskPartial (IN PVFAT_IRP_CONTEXT IrpContext,
00144              IN PLARGE_INTEGER ReadOffset,
00145              IN ULONG ReadLength,
00146              ULONG BufferOffset,
00147              IN BOOLEAN Wait)
00148 {
00149   PIRP Irp;
00150   PIO_STACK_LOCATION StackPtr;
00151   NTSTATUS Status;
00152   PVOID Buffer;
00153 
00154   DPRINT ("VfatReadDiskPartial(IrpContext %p, ReadOffset %I64x, ReadLength %d, BufferOffset %x, Wait %d)\n",
00155       IrpContext, ReadOffset->QuadPart, ReadLength, BufferOffset, Wait);
00156 
00157   DPRINT ("Building asynchronous FSD Request...\n");
00158 
00159   Buffer = (PCHAR)MmGetMdlVirtualAddress(IrpContext->Irp->MdlAddress) + BufferOffset;
00160 
00161 again:
00162   Irp = IoAllocateIrp(IrpContext->DeviceExt->StorageDevice->StackSize, TRUE);
00163   if (Irp == NULL)
00164     {
00165       DPRINT("IoAllocateIrp failed\n");
00166       return(STATUS_UNSUCCESSFUL);
00167     }
00168 
00169   Irp->UserIosb = NULL;
00170   Irp->Tail.Overlay.Thread = PsGetCurrentThread();
00171 
00172   StackPtr = IoGetNextIrpStackLocation(Irp);
00173   StackPtr->MajorFunction = IRP_MJ_READ;
00174   StackPtr->MinorFunction = 0;
00175   StackPtr->Flags = 0;
00176   StackPtr->Control = 0;
00177   StackPtr->DeviceObject = IrpContext->DeviceExt->StorageDevice;
00178   StackPtr->FileObject = NULL;
00179   StackPtr->CompletionRoutine = NULL;
00180   StackPtr->Parameters.Read.Length = ReadLength;
00181   StackPtr->Parameters.Read.ByteOffset = *ReadOffset;
00182 
00183   if (!IoAllocateMdl(Buffer, ReadLength, FALSE, FALSE, Irp))
00184     {
00185       DPRINT("IoAllocateMdl failed\n");
00186       IoFreeIrp(Irp);
00187       return STATUS_UNSUCCESSFUL;
00188     }
00189 
00190   IoBuildPartialMdl(IrpContext->Irp->MdlAddress, Irp->MdlAddress, Buffer, ReadLength);
00191 
00192   IoSetCompletionRoutine(Irp,
00193                          VfatReadWritePartialCompletion,
00194              IrpContext,
00195              TRUE,
00196              TRUE,
00197              TRUE);
00198 
00199   if (Wait)
00200     {
00201       KeInitializeEvent(&IrpContext->Event, NotificationEvent, FALSE);
00202       IrpContext->RefCount = 1;
00203     }
00204   else
00205     {
00206       InterlockedIncrement((PLONG)&IrpContext->RefCount);
00207     }
00208 
00209   DPRINT ("Calling IO Driver... with irp %p\n", Irp);
00210   Status = IoCallDriver (IrpContext->DeviceExt->StorageDevice, Irp);
00211 
00212   if (Wait && Status == STATUS_PENDING)
00213     {
00214       KeWaitForSingleObject(&IrpContext->Event, Executive, KernelMode, FALSE, NULL);
00215       Status = IrpContext->Irp->IoStatus.Status;
00216     }
00217 
00218   if (Status == STATUS_VERIFY_REQUIRED)
00219     {
00220       PDEVICE_OBJECT DeviceToVerify;
00221 
00222       DPRINT1 ("Media change detected!\n");
00223 
00224       /* Find the device to verify and reset the thread field to empty value again. */
00225       DeviceToVerify = IoGetDeviceToVerify (PsGetCurrentThread ());
00226       IoSetDeviceToVerify (PsGetCurrentThread (), NULL);
00227       Status = IoVerifyVolume (DeviceToVerify,
00228                                FALSE);
00229 
00230       if (NT_SUCCESS(Status))
00231         {
00232           DPRINT1 ("Volume verification successful; Reissuing read request\n");
00233           goto again;
00234         }
00235     }
00236 
00237   DPRINT("%x\n", Status);
00238   return Status;
00239 }
00240 
00241 
00242 NTSTATUS
00243 VfatWriteDiskPartial (IN PVFAT_IRP_CONTEXT IrpContext,
00244               IN PLARGE_INTEGER WriteOffset,
00245               IN ULONG WriteLength,
00246               IN ULONG BufferOffset,
00247               IN BOOLEAN Wait)
00248 {
00249   PIRP Irp;
00250   PIO_STACK_LOCATION StackPtr;
00251   NTSTATUS Status;
00252   PVOID Buffer;
00253 
00254   DPRINT ("VfatWriteDiskPartial(IrpContext %p, WriteOffset %I64x, WriteLength %d, BufferOffset %x, Wait %d)\n",
00255       IrpContext, WriteOffset->QuadPart, WriteLength, BufferOffset, Wait);
00256 
00257   Buffer = (PCHAR)MmGetMdlVirtualAddress(IrpContext->Irp->MdlAddress) + BufferOffset;
00258 
00259 again:
00260   DPRINT ("Building asynchronous FSD Request...\n");
00261   Irp = IoAllocateIrp(IrpContext->DeviceExt->StorageDevice->StackSize, TRUE);
00262   if (Irp == NULL)
00263     {
00264       DPRINT("IoAllocateIrp failed\n");
00265       return(STATUS_UNSUCCESSFUL);
00266     }
00267 
00268   Irp->UserIosb = NULL;
00269   Irp->Tail.Overlay.Thread = PsGetCurrentThread();
00270 
00271   StackPtr = IoGetNextIrpStackLocation(Irp);
00272   StackPtr->MajorFunction = IRP_MJ_WRITE;
00273   StackPtr->MinorFunction = 0;
00274   StackPtr->Flags = 0;
00275   StackPtr->Control = 0;
00276   StackPtr->DeviceObject = IrpContext->DeviceExt->StorageDevice;
00277   StackPtr->FileObject = NULL;
00278   StackPtr->CompletionRoutine = NULL;
00279   StackPtr->Parameters.Read.Length = WriteLength;
00280   StackPtr->Parameters.Read.ByteOffset = *WriteOffset;
00281 
00282   if (!IoAllocateMdl(Buffer, WriteLength, FALSE, FALSE, Irp))
00283     {
00284       DPRINT("IoAllocateMdl failed\n");
00285       IoFreeIrp(Irp);
00286       return STATUS_UNSUCCESSFUL;
00287     }
00288   IoBuildPartialMdl(IrpContext->Irp->MdlAddress, Irp->MdlAddress, Buffer, WriteLength);
00289 
00290   IoSetCompletionRoutine(Irp,
00291                          VfatReadWritePartialCompletion,
00292              IrpContext,
00293              TRUE,
00294              TRUE,
00295              TRUE);
00296 
00297   if (Wait)
00298     {
00299       KeInitializeEvent(&IrpContext->Event, NotificationEvent, FALSE);
00300       IrpContext->RefCount = 1;
00301     }
00302   else
00303     {
00304       InterlockedIncrement((PLONG)&IrpContext->RefCount);
00305     }
00306 
00307 
00308   DPRINT ("Calling IO Driver...\n");
00309   Status = IoCallDriver (IrpContext->DeviceExt->StorageDevice, Irp);
00310   if (Wait && Status == STATUS_PENDING)
00311     {
00312       KeWaitForSingleObject(&IrpContext->Event, Executive, KernelMode, FALSE, NULL);
00313       Status = IrpContext->Irp->IoStatus.Status;
00314     }
00315 
00316   if (Status == STATUS_VERIFY_REQUIRED)
00317     {
00318       PDEVICE_OBJECT DeviceToVerify;
00319 
00320       DPRINT1 ("Media change detected!\n");
00321 
00322       /* Find the device to verify and reset the thread field to empty value again. */
00323       DeviceToVerify = IoGetDeviceToVerify (PsGetCurrentThread ());
00324       IoSetDeviceToVerify (PsGetCurrentThread (), NULL);
00325       Status = IoVerifyVolume (DeviceToVerify,
00326                                FALSE);
00327 
00328       if (NT_SUCCESS(Status))
00329         {
00330           DPRINT1 ("Volume verification successful; Reissuing write request\n");
00331           goto again;
00332         }
00333     }
00334 
00335   return Status;
00336 }
00337 
00338 NTSTATUS
00339 VfatBlockDeviceIoControl (IN PDEVICE_OBJECT DeviceObject,
00340               IN ULONG CtlCode,
00341               IN PVOID InputBuffer OPTIONAL,
00342               IN ULONG InputBufferSize,
00343               IN OUT PVOID OutputBuffer OPTIONAL,
00344               IN OUT PULONG OutputBufferSize,
00345               IN BOOLEAN Override)
00346 {
00347   PIO_STACK_LOCATION Stack;
00348   KEVENT Event;
00349   PIRP Irp;
00350   IO_STATUS_BLOCK IoStatus;
00351   NTSTATUS Status;
00352 
00353   DPRINT("VfatBlockDeviceIoControl(DeviceObject %p, CtlCode %x, "
00354          "InputBuffer %p, InputBufferSize %x, OutputBuffer %p, "
00355          "OutputBufferSize %p (%x)\n", DeviceObject, CtlCode,
00356          InputBuffer, InputBufferSize, OutputBuffer, OutputBufferSize,
00357          OutputBufferSize ? *OutputBufferSize : 0);
00358 
00359 again:
00360   KeInitializeEvent (&Event, NotificationEvent, FALSE);
00361 
00362   DPRINT("Building device I/O control request ...\n");
00363   Irp = IoBuildDeviceIoControlRequest(CtlCode,
00364                       DeviceObject,
00365                       InputBuffer,
00366                       InputBufferSize,
00367                       OutputBuffer,
00368                       (OutputBufferSize) ? *OutputBufferSize : 0,
00369                       FALSE,
00370                       &Event,
00371                       &IoStatus);
00372   if (Irp == NULL)
00373     {
00374       DPRINT("IoBuildDeviceIoControlRequest failed\n");
00375       return STATUS_INSUFFICIENT_RESOURCES;
00376     }
00377 
00378   if (Override)
00379     {
00380       Stack = IoGetNextIrpStackLocation(Irp);
00381       Stack->Flags |= SL_OVERRIDE_VERIFY_VOLUME;
00382     }
00383 
00384   DPRINT ("Calling IO Driver... with irp %p\n", Irp);
00385   Status = IoCallDriver(DeviceObject, Irp);
00386 
00387   DPRINT ("Waiting for IO Operation for %p\n", Irp);
00388   if (Status == STATUS_PENDING)
00389     {
00390       DPRINT ("Operation pending\n");
00391       KeWaitForSingleObject (&Event, Suspended, KernelMode, FALSE, NULL);
00392       DPRINT ("Getting IO Status... for %p\n", Irp);
00393 
00394       Status = IoStatus.Status;
00395     }
00396     
00397   if (Status == STATUS_VERIFY_REQUIRED)
00398     {
00399       PDEVICE_OBJECT DeviceToVerify;
00400 
00401       DPRINT1 ("Media change detected!\n");
00402 
00403       /* Find the device to verify and reset the thread field to empty value again. */
00404       DeviceToVerify = IoGetDeviceToVerify (PsGetCurrentThread ());
00405       IoSetDeviceToVerify (PsGetCurrentThread (), NULL);
00406       Status = IoVerifyVolume (DeviceToVerify,
00407                                FALSE);
00408 
00409       if (NT_SUCCESS(Status))
00410         {
00411           DPRINT1 ("Volume verification successful; Reissuing IOCTL request\n");
00412           goto again;
00413         }
00414     }
00415 
00416   if (OutputBufferSize)
00417     {
00418       *OutputBufferSize = IoStatus.Information;
00419     }
00420 
00421   DPRINT("Returning Status %x\n", Status);
00422 
00423   return Status;
00424 }

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