Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenblockdev.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
1.7.6.1
|