Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

devctrl.c

Go to the documentation of this file.
00001 /*++ 00002 00003 Copyright (c) 1989 Microsoft Corporation 00004 00005 Module Name: 00006 00007 DevCtrl.c 00008 00009 Abstract: 00010 00011 This module implements the File System Device Control routines for Udfs 00012 called by the dispatch driver. 00013 00014 Author: 00015 00016 Dan Lovinger {DanLo] 28-Jan-1997 00017 00018 Revision History: 00019 00020 --*/ 00021 00022 #include "UdfProcs.h" 00023 00024 // 00025 // The Bug check file id for this module 00026 // 00027 00028 #define BugCheckFileId (UDFS_BUG_CHECK_DEVCTRL) 00029 00030 // 00031 // The local debug trace level 00032 // 00033 00034 #define Dbg (UDFS_DEBUG_LEVEL_DEVCTRL) 00035 00036 // 00037 // Local support routines 00038 // 00039 00040 NTSTATUS 00041 UdfDvdReadStructure ( 00042 IN PIRP_CONTEXT IrpContext, 00043 IN PIRP Irp, 00044 IN PFCB Fcb 00045 ); 00046 00047 NTSTATUS 00048 UdfDvdTransferKey ( 00049 IN PIRP_CONTEXT IrpContext, 00050 IN PIRP Irp, 00051 IN PFCB Fcb 00052 ); 00053 00054 NTSTATUS 00055 UdfDevCtrlCompletionRoutine ( 00056 IN PDEVICE_OBJECT DeviceObject, 00057 IN PIRP Irp, 00058 IN PVOID Contxt 00059 ); 00060 00061 #ifdef ALLOC_PRAGMA 00062 #pragma alloc_text(PAGE, UdfCommonDevControl) 00063 #pragma alloc_text(PAGE, UdfDvdReadStructure) 00064 #pragma alloc_text(PAGE, UdfDvdTransferKey) 00065 #endif 00066 00067 00068 NTSTATUS 00069 UdfCommonDevControl ( 00070 IN PIRP_CONTEXT IrpContext, 00071 IN PIRP Irp 00072 ) 00073 00074 /*++ 00075 00076 Routine Description: 00077 00078 This is the common routine for doing Device control operations called 00079 by both the fsd and fsp threads 00080 00081 Arguments: 00082 00083 Irp - Supplies the Irp to process 00084 00085 Return Value: 00086 00087 NTSTATUS - The return status for the operation 00088 00089 --*/ 00090 00091 { 00092 NTSTATUS Status; 00093 00094 TYPE_OF_OPEN TypeOfOpen; 00095 PFCB Fcb; 00096 PCCB Ccb; 00097 00098 PIO_STACK_LOCATION IrpSp; 00099 00100 PVOID TargetBuffer; 00101 00102 PAGED_CODE(); 00103 00104 // 00105 // Extract and decode the file object. 00106 // 00107 00108 IrpSp = IoGetCurrentIrpStackLocation( Irp ); 00109 00110 TypeOfOpen = UdfDecodeFileObject( IrpSp->FileObject, 00111 &Fcb, 00112 &Ccb ); 00113 00114 // 00115 // A few IOCTLs actually require some intervention on our part to 00116 // translate some information from file-based to device-based units. 00117 // 00118 00119 if (TypeOfOpen == UserFileOpen) { 00120 00121 switch (IrpSp->Parameters.DeviceIoControl.IoControlCode) { 00122 case IOCTL_DVD_READ_KEY: 00123 case IOCTL_DVD_SEND_KEY: 00124 00125 Status = UdfDvdTransferKey( IrpContext, Irp, Fcb ); 00126 break; 00127 00128 case IOCTL_DVD_READ_STRUCTURE: 00129 00130 Status = UdfDvdReadStructure( IrpContext, Irp, Fcb ); 00131 break; 00132 00133 case IOCTL_STORAGE_SET_READ_AHEAD: 00134 00135 // 00136 // We're just going to no-op this for now. 00137 // 00138 00139 Status = STATUS_SUCCESS; 00140 UdfCompleteRequest( IrpContext, Irp, Status ); 00141 break; 00142 00143 default: 00144 00145 Status = STATUS_INVALID_PARAMETER; 00146 UdfCompleteRequest( IrpContext, Irp, Status ); 00147 break; 00148 } 00149 00150 return Status; 00151 } 00152 00153 // 00154 // Now the only type of opens we accept are user volume opens. 00155 // 00156 00157 if (TypeOfOpen != UserVolumeOpen) { 00158 00159 UdfCompleteRequest( IrpContext, Irp, STATUS_INVALID_PARAMETER ); 00160 return STATUS_INVALID_PARAMETER; 00161 } 00162 00163 // 00164 // Handle the case of the disk type ourselves. We're really just going to 00165 // lie about this, but it is a good lie. 00166 // 00167 00168 if (IrpSp->Parameters.DeviceIoControl.IoControlCode == IOCTL_CDROM_DISK_TYPE) { 00169 00170 // 00171 // Verify the Vcb in this case to detect if the volume has changed. 00172 // 00173 00174 UdfVerifyVcb( IrpContext, Fcb->Vcb ); 00175 00176 // 00177 // Check the size of the output buffer. 00178 // 00179 00180 if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof( CDROM_DISK_DATA )) { 00181 00182 UdfCompleteRequest( IrpContext, Irp, STATUS_BUFFER_TOO_SMALL ); 00183 return STATUS_BUFFER_TOO_SMALL; 00184 } 00185 00186 // 00187 // Copy the data from the Vcb. 00188 // 00189 00190 ((PCDROM_DISK_DATA) Irp->AssociatedIrp.SystemBuffer)->DiskData = CDROM_DISK_DATA_TRACK; 00191 00192 Irp->IoStatus.Information = sizeof( CDROM_DISK_DATA ); 00193 UdfCompleteRequest( IrpContext, Irp, STATUS_SUCCESS ); 00194 return STATUS_SUCCESS; 00195 } 00196 00197 // 00198 // Copy the arguments and set up the completion routine 00199 // 00200 00201 IoCopyCurrentIrpStackLocationToNext( Irp ); 00202 00203 IoSetCompletionRoutine( Irp, 00204 UdfDevCtrlCompletionRoutine, 00205 NULL, 00206 TRUE, 00207 TRUE, 00208 TRUE ); 00209 00210 // 00211 // Send the request. 00212 // 00213 00214 Status = IoCallDriver( IrpContext->Vcb->TargetDeviceObject, Irp ); 00215 00216 // 00217 // Cleanup our Irp Context. The driver has completed the Irp. 00218 // 00219 00220 UdfCompleteRequest( IrpContext, NULL, STATUS_SUCCESS ); 00221 00222 return Status; 00223 } 00224 00225 00226 NTSTATUS 00227 UdfDvdTransferKey ( 00228 IN PIRP_CONTEXT IrpContext, 00229 IN PIRP Irp, 00230 IN PFCB Fcb 00231 ) 00232 00233 /*++ 00234 00235 Routine Description: 00236 00237 This routine handles the special form of the Dvd key negotiation IOCTLs 00238 performed in the context of a file. For these IOCTLs, the incoming parameter 00239 is in file-relative form, which must be translated to a device-relatvie form 00240 before it can continue. 00241 00242 Arguments: 00243 00244 Irp - Supplies the Irp to process 00245 00246 Fcb - Supplies the file being operated with 00247 00248 Return Value: 00249 00250 NTSTATUS - The return status for the operation 00251 00252 --*/ 00253 00254 { 00255 NTSTATUS Status = STATUS_INVALID_PARAMETER; 00256 PDVD_COPY_PROTECT_KEY TransferKey; 00257 00258 LARGE_INTEGER Offset; 00259 BOOLEAN Result; 00260 00261 PIO_STACK_LOCATION IrpSp; 00262 00263 // 00264 // Grab the input buffer and confirm basic validity. 00265 // 00266 00267 IrpSp = IoGetCurrentIrpStackLocation( Irp ); 00268 TransferKey = (PDVD_COPY_PROTECT_KEY) Irp->AssociatedIrp.SystemBuffer; 00269 00270 if (IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(DVD_COPY_PROTECT_KEY) || 00271 TransferKey->Parameters.TitleOffset.QuadPart > Fcb->FileSize.QuadPart) { 00272 00273 UdfCompleteRequest( IrpContext, Irp, Status ); 00274 return Status; 00275 } 00276 00277 // 00278 // Now, convert the file byte offset in the structure to a physical sector. 00279 // 00280 00281 Result = FsRtlLookupLargeMcbEntry( &Fcb->Mcb, 00282 LlSectorsFromBytes( Fcb->Vcb, TransferKey->Parameters.TitleOffset.QuadPart ), 00283 &Offset.QuadPart, 00284 NULL, 00285 NULL, 00286 NULL, 00287 NULL ); 00288 00289 // 00290 // If we failed the lookup, we know that this must be some form of unrecorded 00291 // extent on the media. This IOCTL is ill-defined at this point, so we have 00292 // to give up. 00293 // 00294 00295 if (!Result || Offset.QuadPart == -1) { 00296 00297 UdfCompleteRequest( IrpContext, Irp, Status ); 00298 return Status; 00299 } 00300 00301 // 00302 // The input is buffered from user space, so we know we can just rewrite it. 00303 // 00304 00305 TransferKey->Parameters.TitleOffset.QuadPart = LlBytesFromSectors( Fcb->Vcb, Offset.QuadPart ); 00306 00307 // 00308 // Copy the arguments and set up the completion routine 00309 // 00310 00311 IoCopyCurrentIrpStackLocationToNext( Irp ); 00312 00313 IoSetCompletionRoutine( Irp, 00314 UdfDevCtrlCompletionRoutine, 00315 NULL, 00316 TRUE, 00317 TRUE, 00318 TRUE ); 00319 00320 // 00321 // Send the request. 00322 // 00323 00324 Status = IoCallDriver( IrpContext->Vcb->TargetDeviceObject, Irp ); 00325 00326 // 00327 // Cleanup our Irp Context. The driver has completed the Irp. 00328 // 00329 00330 UdfCompleteRequest( IrpContext, NULL, STATUS_SUCCESS ); 00331 00332 return Status; 00333 } 00334 00335 00336 NTSTATUS 00337 UdfDvdReadStructure ( 00338 IN PIRP_CONTEXT IrpContext, 00339 IN PIRP Irp, 00340 IN PFCB Fcb 00341 00342 ) 00343 00344 /*++ 00345 00346 Routine Description: 00347 00348 This routine handles the special form of the Dvd structure reading IOCTLs 00349 performed in the context of a file. For these IOCTLs, the incoming parameter 00350 is in file-relative form, which must be translated to a device-relatvie form 00351 before it can continue. 00352 00353 Arguments: 00354 00355 Irp - Supplies the Irp to process 00356 00357 Fcb - Supplies the file being operated with 00358 00359 Return Value: 00360 00361 NTSTATUS - The return status for the operation 00362 00363 --*/ 00364 00365 { 00366 NTSTATUS Status = STATUS_INVALID_PARAMETER; 00367 PDVD_READ_STRUCTURE ReadStructure; 00368 00369 LARGE_INTEGER Offset; 00370 BOOLEAN Result; 00371 00372 PIO_STACK_LOCATION IrpSp; 00373 00374 // 00375 // Grab the input buffer and confirm basic validity. 00376 // 00377 00378 IrpSp = IoGetCurrentIrpStackLocation( Irp ); 00379 ReadStructure = (PDVD_READ_STRUCTURE) Irp->AssociatedIrp.SystemBuffer; 00380 00381 if (IrpSp->Parameters.DeviceIoControl.InputBufferLength != sizeof(DVD_READ_STRUCTURE)) { 00382 00383 UdfCompleteRequest( IrpContext, Irp, Status ); 00384 return Status; 00385 } 00386 00387 // 00388 // Now, convert the file byte offset in the structure to a physical sector. 00389 // 00390 00391 Result = FsRtlLookupLargeMcbEntry( &Fcb->Mcb, 00392 LlSectorsFromBytes( Fcb->Vcb, ReadStructure->BlockByteOffset.QuadPart ), 00393 &Offset.QuadPart, 00394 NULL, 00395 NULL, 00396 NULL, 00397 NULL ); 00398 00399 // 00400 // If we failed the lookup, we know that this must be some form of unrecorded 00401 // extent on the media. This IOCTL is ill-defined at this point, so we have 00402 // to give up. 00403 // 00404 00405 if (!Result || Offset.QuadPart == -1) { 00406 00407 UdfCompleteRequest( IrpContext, Irp, Status ); 00408 return Status; 00409 } 00410 00411 // 00412 // The input is buffered from user space, so we know we can just rewrite it. 00413 // 00414 00415 ReadStructure->BlockByteOffset.QuadPart = LlBytesFromSectors( Fcb->Vcb, Offset.QuadPart ); 00416 00417 // 00418 // Copy the arguments and set up the completion routine 00419 // 00420 00421 IoCopyCurrentIrpStackLocationToNext( Irp ); 00422 00423 IoSetCompletionRoutine( Irp, 00424 UdfDevCtrlCompletionRoutine, 00425 NULL, 00426 TRUE, 00427 TRUE, 00428 TRUE ); 00429 00430 // 00431 // Send the request. 00432 // 00433 00434 Status = IoCallDriver( IrpContext->Vcb->TargetDeviceObject, Irp ); 00435 00436 // 00437 // Cleanup our Irp Context. The driver has completed the Irp. 00438 // 00439 00440 UdfCompleteRequest( IrpContext, NULL, STATUS_SUCCESS ); 00441 00442 return Status; 00443 } 00444 00445 00446 // 00447 // Local support routine 00448 // 00449 00450 NTSTATUS 00451 UdfDevCtrlCompletionRoutine ( 00452 IN PDEVICE_OBJECT DeviceObject, 00453 IN PIRP Irp, 00454 IN PVOID Contxt 00455 ) 00456 00457 { 00458 // 00459 // Add the hack-o-ramma to fix formats. 00460 // 00461 00462 if (Irp->PendingReturned) { 00463 00464 IoMarkIrpPending( Irp ); 00465 } 00466 00467 return STATUS_SUCCESS; 00468 00469 UNREFERENCED_PARAMETER( DeviceObject ); 00470 UNREFERENCED_PARAMETER( Contxt ); 00471 } 00472

Generated on Sat May 15 19:39:40 2004 for test by doxygen 1.3.7