test: udfs/devctrl.c File Reference

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

# devctrl.c File Reference

`#include "UdfProcs.h"`

Go to the source code of this file.

## Defines

#define | BugCheckFileId (UDFS_BUG_CHECK_DEVCTRL)
#define | Dbg (UDFS_DEBUG_LEVEL_DEVCTRL)

## Functions

NTSTATUS | UdfDvdReadStructure (IN PIRP_CONTEXT IrpContext, IN PIRP Irp, IN PFCB Fcb)
NTSTATUS | UdfDvdTransferKey (IN PIRP_CONTEXT IrpContext, IN PIRP Irp, IN PFCB Fcb)
NTSTATUS | UdfDevCtrlCompletionRoutine (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Contxt)
NTSTATUS | UdfCommonDevControl (IN PIRP_CONTEXT IrpContext, IN PIRP Irp)

## Define Documentation

#define BugCheckFileId (UDFS_BUG_CHECK_DEVCTRL)

| Definition at line 28 of file udfs/devctrl.c.

#define Dbg (UDFS_DEBUG_LEVEL_DEVCTRL)

| Definition at line 34 of file udfs/devctrl.c.

## Function Documentation

NTSTATUS UdfCommonDevControl | ( | IN PIRP_CONTEXT | IrpContext,
|  | IN PIRP | Irp
| ) |

Definition at line 69 of file udfs/devctrl.c.

References _IRP::AssociatedIrp, _IO_STACK_LOCATION::FileObject, IoCallDriver, IoCopyCurrentIrpStackLocationToNext, IoGetCurrentIrpStackLocation, IoSetCompletionRoutine, _IRP::IoStatus, Irp, NTSTATUS(), NULL, PAGED_CODE, _IO_STACK_LOCATION::Parameters, Status, TRUE, TYPE_OF_OPEN, UdfCompleteRequest(), UdfDecodeFileObject(), UdfDevCtrlCompletionRoutine(), UdfDvdReadStructure(), UdfDvdTransferKey(), UdfVerifyVcb(), UserFileOpen, UserVolumeOpen, and _FCB::Vcb.

Referenced by UdfFsdDispatch(), and UdfFspDispatch().

    00076                    :
    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 }

NTSTATUS UdfDevCtrlCompletionRoutine | ( | IN PDEVICE_OBJECT | DeviceObject,
|  | IN PIRP | Irp,
|  | IN PVOID | Contxt
| ) |

Definition at line 451 of file udfs/devctrl.c.

References IoMarkIrpPending, Irp, and _IRP::PendingReturned.

Referenced by UdfCommonDevControl(), UdfDvdReadStructure(), and UdfDvdTransferKey().

    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 }

NTSTATUS UdfDvdReadStructure | ( | IN PIRP_CONTEXT | IrpContext,
|  | IN PIRP | Irp,
|  | IN PFCB | Fcb
| ) |

Definition at line 337 of file udfs/devctrl.c.

References _IRP::AssociatedIrp, FsRtlLookupLargeMcbEntry(), IoCallDriver, IoCopyCurrentIrpStackLocationToNext, IoGetCurrentIrpStackLocation, IoSetCompletionRoutine, Irp, LlBytesFromSectors, LlSectorsFromBytes, NTSTATUS(), NULL, Offset, _IO_STACK_LOCATION::Parameters, Status, TRUE, UdfCompleteRequest(), and UdfDevCtrlCompletionRoutine().

Referenced by UdfCommonDevControl().

    00346                    :
    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 }

NTSTATUS UdfDvdTransferKey | ( | IN PIRP_CONTEXT | IrpContext,
|  | IN PIRP | Irp,
|  | IN PFCB | Fcb
| ) |

Definition at line 227 of file udfs/devctrl.c.

References _IRP::AssociatedIrp, FsRtlLookupLargeMcbEntry(), IoCallDriver, IoCopyCurrentIrpStackLocationToNext, IoGetCurrentIrpStackLocation, IoSetCompletionRoutine, Irp, LlBytesFromSectors, LlSectorsFromBytes, NTSTATUS(), NULL, Offset, _IO_STACK_LOCATION::Parameters, Status, TRUE, UdfCompleteRequest(), and UdfDevCtrlCompletionRoutine().

Referenced by UdfCommonDevControl().

    00235                    :
    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 }