00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
#include "UdfProcs.h"
00023
00024
00025
00026
00027
00028 #define BugCheckFileId (UDFS_BUG_CHECK_DEVCTRL)
00029
00030
00031
00032
00033
00034 #define Dbg (UDFS_DEBUG_LEVEL_DEVCTRL)
00035
00036
00037
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
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
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
00106
00107
00108 IrpSp =
IoGetCurrentIrpStackLocation(
Irp );
00109
00110 TypeOfOpen =
UdfDecodeFileObject( IrpSp->
FileObject,
00111 &Fcb,
00112 &Ccb );
00113
00114
00115
00116
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
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
00155
00156
00157
if (TypeOfOpen !=
UserVolumeOpen) {
00158
00159
UdfCompleteRequest( IrpContext,
Irp, STATUS_INVALID_PARAMETER );
00160
return STATUS_INVALID_PARAMETER;
00161 }
00162
00163
00164
00165
00166
00167
00168
if (IrpSp->
Parameters.DeviceIoControl.IoControlCode == IOCTL_CDROM_DISK_TYPE) {
00169
00170
00171
00172
00173
00174
UdfVerifyVcb( IrpContext, Fcb->
Vcb );
00175
00176
00177
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
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
00199
00200
00201
IoCopyCurrentIrpStackLocationToNext(
Irp );
00202
00203
IoSetCompletionRoutine(
Irp,
00204
UdfDevCtrlCompletionRoutine,
00205
NULL,
00206
TRUE,
00207
TRUE,
00208
TRUE );
00209
00210
00211
00212
00213
00214
Status =
IoCallDriver( IrpContext->Vcb->TargetDeviceObject,
Irp );
00215
00216
00217
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
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
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
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
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
00291
00292
00293
00294
00295
if (!Result ||
Offset.QuadPart == -1) {
00296
00297
UdfCompleteRequest( IrpContext,
Irp,
Status );
00298
return Status;
00299 }
00300
00301
00302
00303
00304
00305 TransferKey->Parameters.TitleOffset.QuadPart =
LlBytesFromSectors( Fcb->Vcb,
Offset.QuadPart );
00306
00307
00308
00309
00310
00311
IoCopyCurrentIrpStackLocationToNext(
Irp );
00312
00313
IoSetCompletionRoutine(
Irp,
00314
UdfDevCtrlCompletionRoutine,
00315
NULL,
00316
TRUE,
00317
TRUE,
00318
TRUE );
00319
00320
00321
00322
00323
00324
Status =
IoCallDriver( IrpContext->Vcb->TargetDeviceObject,
Irp );
00325
00326
00327
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
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
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
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
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
00401
00402
00403
00404
00405
if (!Result ||
Offset.QuadPart == -1) {
00406
00407
UdfCompleteRequest( IrpContext,
Irp,
Status );
00408
return Status;
00409 }
00410
00411
00412
00413
00414
00415 ReadStructure->BlockByteOffset.QuadPart =
LlBytesFromSectors( Fcb->Vcb,
Offset.QuadPart );
00416
00417
00418
00419
00420
00421
IoCopyCurrentIrpStackLocationToNext(
Irp );
00422
00423
IoSetCompletionRoutine(
Irp,
00424
UdfDevCtrlCompletionRoutine,
00425
NULL,
00426
TRUE,
00427
TRUE,
00428
TRUE );
00429
00430
00431
00432
00433
00434
Status =
IoCallDriver( IrpContext->Vcb->TargetDeviceObject,
Irp );
00435
00436
00437
00438
00439
00440
UdfCompleteRequest( IrpContext,
NULL, STATUS_SUCCESS );
00441
00442
return Status;
00443 }
00444
00445
00446
00447
00448
00449
00450
NTSTATUS
00451 UdfDevCtrlCompletionRoutine (
00452 IN
PDEVICE_OBJECT DeviceObject,
00453 IN
PIRP Irp,
00454 IN PVOID Contxt
00455 )
00456
00457 {
00458
00459
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