1 //////////////////////////////////////////////////////////////////// 2 // Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine 3 // All rights reserved 4 // This file was released under the GPLv2 on June 2015. 5 //////////////////////////////////////////////////////////////////// 6 /************************************************************************* 7 * 8 * File: Devcntrl.cpp 9 * 10 * Module: UDF File System Driver (Kernel mode execution only) 11 * 12 * Description: 13 * Contains code to handle the "Device IOCTL" dispatch entry point. 14 * 15 *************************************************************************/ 16 17 #include "udffs.h" 18 19 #include "CDRW/scsi_port.h" 20 21 #define UDF_CURRENT_BUILD 123456789 22 23 // define the file specific bug-check id 24 #ifdef UDF_BUG_CHECK_ID 25 #undef UDF_BUG_CHECK_ID 26 #endif 27 #define UDF_BUG_CHECK_ID UDF_FILE_DEVICE_CONTROL 28 29 NTSTATUS 30 UDFGetFileAllocModeFromICB( 31 PtrUDFIrpContext PtrIrpContext, 32 PIRP Irp 33 ); 34 35 NTSTATUS 36 UDFSetFileAllocModeFromICB( 37 PtrUDFIrpContext IrpContext, 38 PIRP Irp 39 ); 40 41 NTSTATUS 42 UDFProcessLicenseKey( 43 PtrUDFIrpContext IrpContext, 44 PIRP Irp 45 ); 46 47 /*#if(_WIN32_WINNT < 0x0400) 48 #define IOCTL_REDIR_QUERY_PATH CTL_CODE(FILE_DEVICE_NETWORK_FILE_SYSTEM, 99, METHOD_NEITHER, FILE_ANY_ACCESS) 49 50 typedef struct _QUERY_PATH_REQUEST { 51 ULONG PathNameLength; 52 PIO_SECURITY_CONTEXT SecurityContext; 53 WCHAR FilePathName[1]; 54 } QUERY_PATH_REQUEST, *PQUERY_PATH_REQUEST; 55 56 typedef struct _QUERY_PATH_RESPONSE { 57 ULONG LengthAccepted; 58 } QUERY_PATH_RESPONSE, *PQUERY_PATH_RESPONSE; 59 60 #endif*/ 61 62 63 /************************************************************************* 64 * 65 * Function: UDFDeviceControl() 66 * 67 * Description: 68 * The I/O Manager will invoke this routine to handle a Device IOCTL 69 * request 70 * 71 * Expected Interrupt Level (for execution) : 72 * 73 * IRQL_PASSIVE_LEVEL (invocation at higher IRQL will cause execution 74 * to be deferred to a worker thread context) 75 * 76 * Return Value: STATUS_SUCCESS/Error 77 * 78 *************************************************************************/ 79 NTSTATUS 80 NTAPI 81 UDFDeviceControl( 82 PDEVICE_OBJECT DeviceObject, // the logical volume device object 83 PIRP Irp) // I/O Request Packet 84 { 85 NTSTATUS RC = STATUS_SUCCESS; 86 PtrUDFIrpContext PtrIrpContext = NULL; 87 BOOLEAN AreWeTopLevel = FALSE; 88 89 TmPrint(("UDFDeviceControl: \n")); 90 91 FsRtlEnterFileSystem(); 92 ASSERT(DeviceObject); 93 ASSERT(Irp); 94 95 // set the top level context 96 AreWeTopLevel = UDFIsIrpTopLevel(Irp); 97 //ASSERT(!UDFIsFSDevObj(DeviceObject)); 98 99 _SEH2_TRY { 100 101 // get an IRP context structure and issue the request 102 PtrIrpContext = UDFAllocateIrpContext(Irp, DeviceObject); 103 if(PtrIrpContext) { 104 RC = UDFCommonDeviceControl(PtrIrpContext, Irp); 105 } else { 106 RC = STATUS_INSUFFICIENT_RESOURCES; 107 Irp->IoStatus.Status = RC; 108 Irp->IoStatus.Information = 0; 109 // complete the IRP 110 IoCompleteRequest(Irp, IO_DISK_INCREMENT); 111 } 112 113 } _SEH2_EXCEPT(UDFExceptionFilter(PtrIrpContext, _SEH2_GetExceptionInformation())) { 114 115 RC = UDFExceptionHandler(PtrIrpContext, Irp); 116 117 UDFLogEvent(UDF_ERROR_INTERNAL_ERROR, RC); 118 } _SEH2_END; 119 120 if (AreWeTopLevel) { 121 IoSetTopLevelIrp(NULL); 122 } 123 124 FsRtlExitFileSystem(); 125 126 return(RC); 127 } // end UDFDeviceControl() 128 129 130 /************************************************************************* 131 * 132 * Function: UDFCommonDeviceControl() 133 * 134 * Description: 135 * The actual work is performed here. This routine may be invoked in one' 136 * of the two possible contexts: 137 * (a) in the context of a system worker thread 138 * (b) in the context of the original caller 139 * 140 * Expected Interrupt Level (for execution) : 141 * 142 * IRQL_PASSIVE_LEVEL 143 * 144 * Return Value: STATUS_SUCCESS/Error 145 * 146 *************************************************************************/ 147 NTSTATUS 148 NTAPI 149 UDFCommonDeviceControl( 150 PtrUDFIrpContext PtrIrpContext, 151 PIRP Irp 152 ) 153 { 154 NTSTATUS RC = STATUS_SUCCESS; 155 PIO_STACK_LOCATION IrpSp = NULL; 156 // PIO_STACK_LOCATION PtrNextIoStackLocation = NULL; 157 PFILE_OBJECT FileObject = NULL; 158 PtrUDFFCB Fcb = NULL; 159 PtrUDFCCB Ccb = NULL; 160 PVCB Vcb = NULL; 161 BOOLEAN CompleteIrp = FALSE; 162 ULONG IoControlCode = 0; 163 // PVOID BufferPointer = NULL; 164 BOOLEAN AcquiredVcb = FALSE; 165 BOOLEAN FSDevObj; 166 ULONG TrackNumber; 167 BOOLEAN UnsafeIoctl = TRUE; 168 UCHAR ScsiCommand; 169 PPREVENT_MEDIA_REMOVAL_USER_IN Buf = NULL; // FSD buffer 170 PCDB Cdb; 171 PCHAR CdbData; 172 PCHAR ModeSelectData; 173 174 UDFPrint(("UDFCommonDeviceControl\n")); 175 176 _SEH2_TRY { 177 // First, get a pointer to the current I/O stack location 178 IrpSp = IoGetCurrentIrpStackLocation(Irp); 179 ASSERT(IrpSp); 180 181 // Get the IoControlCode value 182 IoControlCode = IrpSp->Parameters.DeviceIoControl.IoControlCode; 183 184 FileObject = IrpSp->FileObject; 185 ASSERT(FileObject); 186 187 FSDevObj = UDFIsFSDevObj(PtrIrpContext->TargetDeviceObject); 188 189 if(FSDevObj) { 190 switch (IoControlCode) { 191 case IOCTL_UDF_DISABLE_DRIVER: 192 case IOCTL_UDF_INVALIDATE_VOLUMES: 193 case IOCTL_UDF_SET_NOTIFICATION_EVENT: 194 #ifndef UDF_READ_ONLY_BUILD 195 case IOCTL_UDF_SEND_LICENSE_KEY: 196 #endif //UDF_READ_ONLY_BUILD 197 case IOCTL_UDF_REGISTER_AUTOFORMAT: 198 break; 199 default: 200 UDFPrint(("UDFCommonDeviceControl: STATUS_INVALID_PARAMETER %x for FsDevObj\n", IoControlCode)); 201 CompleteIrp = TRUE; 202 try_return(RC = STATUS_INVALID_PARAMETER); 203 } 204 } else { 205 Ccb = (PtrUDFCCB)(FileObject->FsContext2); 206 if(!Ccb) { 207 UDFPrint((" !Ccb\n")); 208 goto ioctl_do_default; 209 } 210 ASSERT(Ccb); 211 Fcb = Ccb->Fcb; 212 ASSERT(Fcb); 213 214 // Check if the IOCTL is suitable for this type of File 215 if (Fcb->NodeIdentifier.NodeType == UDF_NODE_TYPE_VCB) { 216 // Everything is acceptable for Volume 217 Vcb = (PVCB)(Fcb); 218 } else { 219 Vcb = Fcb->Vcb; 220 CompleteIrp = TRUE; 221 // For files/disrs only the following are acceptable 222 switch (IoControlCode) { 223 case IOCTL_UDF_GET_RETRIEVAL_POINTERS: 224 case IOCTL_UDF_GET_FILE_ALLOCATION_MODE: 225 case IOCTL_UDF_SET_FILE_ALLOCATION_MODE: 226 break; 227 default: 228 UDFPrint(("UDFCommonDeviceControl: STATUS_INVALID_PARAMETER %x for File/Dir Obj\n", IoControlCode)); 229 try_return(RC = STATUS_INVALID_PARAMETER); 230 } 231 } 232 // check 'safe' IOCTLs 233 switch (IoControlCode) { 234 case IOCTL_CDROM_RAW_READ: 235 236 case IOCTL_CDROM_GET_DRIVE_GEOMETRY: 237 case IOCTL_DISK_GET_DRIVE_GEOMETRY: 238 case IOCTL_DISK_GET_PARTITION_INFO: 239 case IOCTL_DISK_GET_DRIVE_LAYOUT: 240 241 case IOCTL_CDROM_GET_DRIVE_GEOMETRY_EX: 242 case IOCTL_DISK_GET_PARTITION_INFO_EX: 243 case IOCTL_DISK_GET_DRIVE_LAYOUT_EX: 244 case IOCTL_DISK_GET_DRIVE_GEOMETRY_EX: 245 246 case IOCTL_STORAGE_CHECK_VERIFY: 247 case IOCTL_STORAGE_CHECK_VERIFY2: 248 case IOCTL_DISK_CHECK_VERIFY: 249 case IOCTL_CDROM_CHECK_VERIFY: 250 251 case IOCTL_CDROM_LOAD_MEDIA: 252 case IOCTL_DISK_LOAD_MEDIA: 253 case IOCTL_STORAGE_LOAD_MEDIA: 254 case IOCTL_STORAGE_LOAD_MEDIA2: 255 256 case IOCTL_CDROM_GET_CONFIGURATION: 257 case IOCTL_CDROM_GET_LAST_SESSION: 258 case IOCTL_CDROM_READ_TOC: 259 case IOCTL_CDROM_READ_TOC_EX: 260 case IOCTL_CDROM_PLAY_AUDIO_MSF: 261 case IOCTL_CDROM_READ_Q_CHANNEL: 262 case IOCTL_CDROM_PAUSE_AUDIO: 263 case IOCTL_CDROM_RESUME_AUDIO: 264 case IOCTL_CDROM_SEEK_AUDIO_MSF: 265 case IOCTL_CDROM_STOP_AUDIO: 266 case IOCTL_CDROM_GET_CONTROL: 267 case IOCTL_CDROM_GET_VOLUME: 268 case IOCTL_CDROM_SET_VOLUME: 269 270 case IOCTL_CDRW_SET_SPEED: 271 case IOCTL_CDRW_GET_CAPABILITIES: 272 case IOCTL_CDRW_GET_MEDIA_TYPE_EX: 273 case IOCTL_CDRW_GET_MEDIA_TYPE: 274 275 case IOCTL_DISK_GET_MEDIA_TYPES: 276 case IOCTL_STORAGE_GET_MEDIA_TYPES: 277 case IOCTL_STORAGE_GET_MEDIA_TYPES_EX: 278 279 case IOCTL_DISK_IS_WRITABLE: 280 281 case IOCTL_CDRW_GET_WRITE_MODE: 282 case IOCTL_CDRW_READ_TRACK_INFO: 283 case IOCTL_CDRW_READ_DISC_INFO: 284 case IOCTL_CDRW_BUFFER_CAPACITY: 285 case IOCTL_CDRW_GET_SIGNATURE: 286 case IOCTL_CDRW_TEST_UNIT_READY: 287 case IOCTL_CDRW_GET_LAST_ERROR: 288 case IOCTL_CDRW_MODE_SENSE: 289 case IOCTL_CDRW_LL_READ: 290 case IOCTL_CDRW_READ_ATIP: 291 case IOCTL_CDRW_READ_CD_TEXT: 292 case IOCTL_CDRW_READ_TOC_EX: 293 case IOCTL_CDRW_READ_FULL_TOC: 294 case IOCTL_CDRW_READ_PMA: 295 case IOCTL_CDRW_READ_SESSION_INFO: 296 case IOCTL_CDRW_GET_DEVICE_INFO: 297 case IOCTL_CDRW_GET_EVENT: 298 299 case IOCTL_DVD_READ_STRUCTURE: 300 301 case IOCTL_CDRW_GET_DEVICE_NAME: 302 case IOCTL_MOUNTDEV_QUERY_DEVICE_NAME: 303 304 case IOCTL_UDF_GET_RETRIEVAL_POINTERS: 305 case IOCTL_UDF_GET_SPEC_RETRIEVAL_POINTERS: 306 case IOCTL_UDF_GET_FILE_ALLOCATION_MODE: 307 case IOCTL_UDF_GET_VERSION: 308 case IOCTL_UDF_IS_VOLUME_JUST_MOUNTED: 309 case IOCTL_UDF_SET_OPTIONS: 310 // case : 311 312 case FSCTL_IS_VOLUME_DIRTY: 313 314 UnsafeIoctl = FALSE; 315 break; 316 } 317 318 if(IoControlCode != IOCTL_CDROM_DISK_TYPE) { 319 UDFAcquireResourceShared(&(Vcb->VCBResource), TRUE); 320 } else { 321 UDFAcquireResourceExclusive(&(Vcb->VCBResource), TRUE); 322 } 323 AcquiredVcb = TRUE; 324 } 325 326 UDFPrint(("UDF Irp %x, ctx %x, DevIoCtl %x\n", Irp, PtrIrpContext, IoControlCode)); 327 328 // We may wish to allow only volume open operations. 329 switch (IoControlCode) { 330 331 case IOCTL_SCSI_PASS_THROUGH_DIRECT: 332 case IOCTL_SCSI_PASS_THROUGH: 333 334 if(!Irp->AssociatedIrp.SystemBuffer) 335 goto ioctl_do_default; 336 337 if(IoControlCode == IOCTL_SCSI_PASS_THROUGH_DIRECT) { 338 Cdb = (PCDB)&(((PSCSI_PASS_THROUGH_DIRECT)(Irp->AssociatedIrp.SystemBuffer))->Cdb); 339 CdbData = (PCHAR)(((PSCSI_PASS_THROUGH_DIRECT)(Irp->AssociatedIrp.SystemBuffer))->DataBuffer); 340 } else { 341 Cdb = (PCDB)&(((PSCSI_PASS_THROUGH)(Irp->AssociatedIrp.SystemBuffer))->Cdb); 342 if(((PSCSI_PASS_THROUGH)(Irp->AssociatedIrp.SystemBuffer))->DataBufferOffset) { 343 CdbData = ((PCHAR)Cdb) + 344 ((PSCSI_PASS_THROUGH)(Irp->AssociatedIrp.SystemBuffer))->DataBufferOffset; 345 } else { 346 CdbData = NULL; 347 } 348 } 349 ScsiCommand = Cdb->CDB6.OperationCode; 350 351 if(ScsiCommand == SCSIOP_WRITE_CD) { 352 UDFPrint(("Write10, LBA %2.2x%2.2x%2.2x%2.2x\n", 353 Cdb->WRITE_CD.LBA[0], 354 Cdb->WRITE_CD.LBA[1], 355 Cdb->WRITE_CD.LBA[2], 356 Cdb->WRITE_CD.LBA[3] 357 )); 358 } else 359 if(ScsiCommand == SCSIOP_WRITE12) { 360 UDFPrint(("Write12, LBA %2.2x%2.2x%2.2x%2.2x\n", 361 Cdb->CDB12READWRITE.LBA[0], 362 Cdb->CDB12READWRITE.LBA[1], 363 Cdb->CDB12READWRITE.LBA[2], 364 Cdb->CDB12READWRITE.LBA[3] 365 )); 366 } else { 367 } 368 369 switch(ScsiCommand) { 370 case SCSIOP_MODE_SELECT: { 371 // PMODE_PARAMETER_HEADER ParamHdr = (PMODE_PARAMETER_HEADER)CdbData; 372 ModeSelectData = CdbData+4; 373 switch(ModeSelectData[0]) { 374 case MODE_PAGE_MRW2: 375 case MODE_PAGE_WRITE_PARAMS: 376 case MODE_PAGE_MRW: 377 UDFPrint(("Unsafe MODE_SELECT_6 via pass-through (%2.2x)\n", ModeSelectData[0])); 378 goto unsafe_direct_scsi_cmd; 379 } 380 break; } 381 382 case SCSIOP_MODE_SELECT10: { 383 // PMODE_PARAMETER_HEADER10 ParamHdr = (PMODE_PARAMETER_HEADER10)CdbData; 384 ModeSelectData = CdbData+8; 385 switch(ModeSelectData[0]) { 386 case MODE_PAGE_MRW2: 387 case MODE_PAGE_WRITE_PARAMS: 388 case MODE_PAGE_MRW: 389 UDFPrint(("Unsafe MODE_SELECT_10 via pass-through (%2.2x)\n", ModeSelectData[0])); 390 goto unsafe_direct_scsi_cmd; 391 } 392 break; } 393 394 case SCSIOP_RESERVE_TRACK: 395 case SCSIOP_SEND_CUE_SHEET: 396 case SCSIOP_SEND_DVD_STRUCTURE: 397 case SCSIOP_CLOSE_TRACK_SESSION: 398 case SCSIOP_FORMAT_UNIT: 399 case SCSIOP_WRITE6: 400 case SCSIOP_WRITE_CD: 401 case SCSIOP_BLANK: 402 case SCSIOP_WRITE12: 403 case SCSIOP_SET_STREAMING: 404 UDFPrint(("UDF Direct media modification via pass-through (%2.2x)\n", ScsiCommand)); 405 unsafe_direct_scsi_cmd: 406 if(!(Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_MOUNTED)) 407 goto ioctl_do_default; 408 409 UDFPrint(("Forget this volume\n")); 410 // Acquire Vcb resource (Shared -> Exclusive) 411 UDFInterlockedIncrement((PLONG)&(Vcb->VCBOpenCount)); 412 UDFReleaseResource(&(Vcb->VCBResource)); 413 414 if(!(Vcb->VCBFlags & UDF_VCB_FLAGS_RAW_DISK)) { 415 UDFCloseAllSystemDelayedInDir(Vcb, Vcb->RootDirFCB->FileInfo); 416 } 417 #ifdef UDF_DELAYED_CLOSE 418 // Acquire exclusive access to the Vcb. 419 UDFCloseAllDelayed(Vcb); 420 #endif //UDF_DELAYED_CLOSE 421 422 // allocate tmp buffer for FSD calls 423 Buf = (PPREVENT_MEDIA_REMOVAL_USER_IN)MyAllocatePool__(NonPagedPool, sizeof(PREVENT_MEDIA_REMOVAL_USER_IN)); 424 if(!Buf) 425 try_return(RC = STATUS_INSUFFICIENT_RESOURCES); 426 427 UDFAcquireResourceExclusive(&(Vcb->VCBResource), TRUE); 428 AcquiredVcb = TRUE; 429 UDFInterlockedDecrement((PLONG)&(Vcb->VCBOpenCount)); 430 431 UDFDoDismountSequence(Vcb, Buf, FALSE); 432 MyFreePool__(Buf); 433 Buf = NULL; 434 Vcb->MediaLockCount = 0; 435 436 Vcb->VCBFlags &= ~UDF_VCB_FLAGS_VOLUME_MOUNTED; 437 Vcb->WriteSecurity = FALSE; 438 439 // Release the Vcb resource. 440 UDFReleaseResource(&(Vcb->VCBResource)); 441 AcquiredVcb = FALSE; 442 // disable Eject Request Waiter if any 443 UDFStopEjectWaiter(Vcb); 444 445 // Make sure, that volume will never be quick-remounted 446 // It is very important for ChkUdf utility and 447 // some CD-recording libraries 448 Vcb->SerialNumber--; 449 450 UDFPrint(("Forgotten\n")); 451 452 goto notify_media_change; 453 454 case SCSIOP_START_STOP_UNIT: 455 case SCSIOP_DOORLOCK: 456 case SCSIOP_DOORUNLOCK: 457 case SCSIOP_MEDIUM_REMOVAL: 458 UDFPrint(("UDF Medium/Tray control IOCTL via pass-through\n")); 459 } 460 goto ioctl_do_default; 461 462 case IOCTL_CDRW_BLANK: 463 case IOCTL_CDRW_LL_WRITE: 464 case IOCTL_CDRW_FORMAT_UNIT: 465 466 notify_media_change: 467 /* Vcb->VCBFlags |= UDF_VCB_FLAGS_UNSAFE_IOCTL; 468 // Make sure, that volume will never be quick-remounted 469 // It is very important for ChkUdf utility and 470 // some CD-recording libraries 471 Vcb->SerialNumber--; 472 */ goto ioctl_do_default; 473 474 case IOCTL_UDF_REGISTER_AUTOFORMAT: { 475 476 UDFPrint(("UDF Register Autoformat\n")); 477 if(UDFGlobalData.AutoFormatCount) { 478 RC = STATUS_SHARING_VIOLATION; 479 } else { 480 UDFGlobalData.AutoFormatCount = FileObject; 481 RC = STATUS_SUCCESS; 482 } 483 CompleteIrp = TRUE; 484 Irp->IoStatus.Information = 0; 485 break; 486 } 487 488 case IOCTL_UDF_DISABLE_DRIVER: { 489 490 UDFPrint(("UDF Disable driver\n")); 491 IoUnregisterFileSystem(UDFGlobalData.UDFDeviceObject); 492 // Now, delete any device objects, etc. we may have created 493 if (UDFGlobalData.UDFDeviceObject) { 494 IoDeleteDevice(UDFGlobalData.UDFDeviceObject); 495 UDFGlobalData.UDFDeviceObject = NULL; 496 } 497 498 // free up any memory we might have reserved for zones/lookaside 499 // lists 500 if (UDFGlobalData.UDFFlags & UDF_DATA_FLAGS_ZONES_INITIALIZED) { 501 UDFDestroyZones(); 502 } 503 504 // delete the resource we may have initialized 505 if (UDFGlobalData.UDFFlags & UDF_DATA_FLAGS_RESOURCE_INITIALIZED) { 506 // un-initialize this resource 507 UDFDeleteResource(&(UDFGlobalData.GlobalDataResource)); 508 UDFClearFlag(UDFGlobalData.UDFFlags, UDF_DATA_FLAGS_RESOURCE_INITIALIZED); 509 } 510 RC = STATUS_SUCCESS; 511 CompleteIrp = TRUE; 512 Irp->IoStatus.Information = 0; 513 break; 514 } 515 case IOCTL_UDF_INVALIDATE_VOLUMES: { 516 UDFPrint(("UDF Invaidate volume\n")); 517 if(AcquiredVcb) { 518 UDFReleaseResource(&(Vcb->VCBResource)); 519 AcquiredVcb = FALSE; 520 } 521 RC = UDFInvalidateVolumes( PtrIrpContext, Irp ); 522 CompleteIrp = TRUE; 523 Irp->IoStatus.Information = 0; 524 break; 525 } 526 527 case IOCTL_UDF_SET_NOTIFICATION_EVENT: 528 { 529 if (IrpSp->Parameters.DeviceIoControl.InputBufferLength != sizeof(HANDLE)) 530 { 531 RC = STATUS_INVALID_PARAMETER; 532 } 533 else 534 { 535 HANDLE MountEventHandle = *(PHANDLE)Irp->AssociatedIrp.SystemBuffer; 536 if (MountEventHandle) 537 { 538 if (!UDFGlobalData.MountEvent) 539 { 540 RC = ObReferenceObjectByHandle( 541 MountEventHandle, 542 0, 543 NULL, 544 UserMode, 545 (PVOID *) &UDFGlobalData.MountEvent, 546 NULL); 547 548 if (!NT_SUCCESS(RC)) 549 { 550 UDFGlobalData.MountEvent = NULL; 551 } 552 } 553 else 554 { 555 RC = STATUS_INVALID_PARAMETER; 556 } 557 } 558 else 559 { 560 if (!UDFGlobalData.MountEvent) 561 { 562 RC = STATUS_INVALID_PARAMETER; 563 } 564 else 565 { 566 ObDereferenceObject(UDFGlobalData.MountEvent); 567 UDFGlobalData.MountEvent = NULL; 568 } 569 } 570 } 571 572 CompleteIrp = TRUE; 573 Irp->IoStatus.Information = 0; 574 break; 575 } 576 577 case IOCTL_UDF_IS_VOLUME_JUST_MOUNTED: 578 { 579 if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(BOOLEAN)) 580 { 581 RC = STATUS_INVALID_PARAMETER; 582 } 583 else 584 { 585 *(PBOOLEAN)Irp->AssociatedIrp.SystemBuffer = Vcb->IsVolumeJustMounted; 586 Vcb->IsVolumeJustMounted = FALSE; 587 } 588 589 CompleteIrp = TRUE; 590 Irp->IoStatus.Information = 0; 591 break; 592 } 593 594 595 //case FSCTL_GET_RETRIEVAL_POINTERS 596 case IOCTL_UDF_GET_RETRIEVAL_POINTERS: { 597 UDFPrint(("UDF: Get Retrieval Pointers\n")); 598 RC = UDFGetRetrievalPointers( PtrIrpContext, Irp, 0 ); 599 CompleteIrp = TRUE; 600 break; 601 } 602 case IOCTL_UDF_GET_SPEC_RETRIEVAL_POINTERS: { 603 UDFPrint(("UDF: Get Spec Retrieval Pointers\n")); 604 PUDF_GET_SPEC_RETRIEVAL_POINTERS_IN SpecRetrPointer; 605 SpecRetrPointer = (PUDF_GET_SPEC_RETRIEVAL_POINTERS_IN)(Irp->AssociatedIrp.SystemBuffer); 606 RC = UDFGetRetrievalPointers( PtrIrpContext, Irp, SpecRetrPointer->Special ); 607 CompleteIrp = TRUE; 608 break; 609 } 610 case IOCTL_UDF_GET_FILE_ALLOCATION_MODE: { 611 UDFPrint(("UDF: Get File Alloc mode (from ICB)\n")); 612 RC = UDFGetFileAllocModeFromICB( PtrIrpContext, Irp ); 613 CompleteIrp = TRUE; 614 break; 615 } 616 #ifndef UDF_READ_ONLY_BUILD 617 case IOCTL_UDF_SET_FILE_ALLOCATION_MODE: { 618 UDFPrint(("UDF: Set File Alloc mode\n")); 619 RC = UDFSetFileAllocModeFromICB( PtrIrpContext, Irp ); 620 CompleteIrp = TRUE; 621 break; 622 } 623 #endif //UDF_READ_ONLY_BUILD 624 case IOCTL_UDF_LOCK_VOLUME_BY_PID: 625 if(AcquiredVcb) { 626 UDFReleaseResource(&(Vcb->VCBResource)); 627 AcquiredVcb = FALSE; 628 } 629 RC = UDFLockVolume( PtrIrpContext, Irp, GetCurrentPID() ); 630 CompleteIrp = TRUE; 631 break; 632 case IOCTL_UDF_UNLOCK_VOLUME_BY_PID: 633 if(AcquiredVcb) { 634 UDFReleaseResource(&(Vcb->VCBResource)); 635 AcquiredVcb = FALSE; 636 } 637 RC = UDFUnlockVolume( PtrIrpContext, Irp, GetCurrentPID() ); 638 CompleteIrp = TRUE; 639 break; 640 #ifndef UDF_READ_ONLY_BUILD 641 case IOCTL_UDF_SEND_LICENSE_KEY: 642 RC = STATUS_SUCCESS; 643 644 Irp->IoStatus.Information = 0; 645 Irp->IoStatus.Status = STATUS_SUCCESS; 646 CompleteIrp = TRUE; 647 break; 648 #endif //UDF_READ_ONLY_BUILD 649 case IOCTL_UDF_GET_VERSION: { 650 651 PUDF_GET_VERSION_OUT udf_ver; 652 653 UDFPrint(("UDFUserFsCtrlRequest: IOCTL_UDF_GET_VERSION\n")); 654 655 Irp->IoStatus.Information = 0; 656 CompleteIrp = TRUE; 657 658 if(!IrpSp->Parameters.DeviceIoControl.OutputBufferLength) { 659 UDFPrint(("!OutputBufferLength\n")); 660 try_return(RC = STATUS_SUCCESS); 661 } 662 // Check the size of the output buffer. 663 if(IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(UDF_GET_VERSION_OUT)) { 664 UDFPrint(("OutputBufferLength < %x\n", sizeof(UDF_GET_VERSION_OUT))); 665 try_return(RC = STATUS_BUFFER_TOO_SMALL); 666 } 667 668 udf_ver = (PUDF_GET_VERSION_OUT)(Irp->AssociatedIrp.SystemBuffer); 669 if(!udf_ver) { 670 UDFPrint(("!udf_ver\n")); 671 try_return(RC = STATUS_INVALID_USER_BUFFER); 672 } 673 674 RtlZeroMemory(udf_ver, IrpSp->Parameters.DeviceIoControl.OutputBufferLength); 675 676 udf_ver->header.Length = sizeof(UDF_GET_VERSION_OUT); 677 udf_ver->header.DriverVersionMj = 0x00010005; 678 udf_ver->header.DriverVersionMn = 0x12; 679 udf_ver->header.DriverVersionBuild = UDF_CURRENT_BUILD; 680 681 udf_ver->FSVersionMj = Vcb->CurrentUDFRev >> 8; 682 udf_ver->FSVersionMn = Vcb->CurrentUDFRev & 0xff; 683 udf_ver->FSFlags = Vcb->UserFSFlags; 684 if( ((Vcb->origIntegrityType == INTEGRITY_TYPE_OPEN) && 685 (Vcb->CompatFlags & UDF_VCB_IC_DIRTY_RO)) 686 || 687 (Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_READ_ONLY) ) { 688 UDFPrint((" UDF_USER_FS_FLAGS_RO\n")); 689 udf_ver->FSFlags |= UDF_USER_FS_FLAGS_RO; 690 } 691 if(Vcb->VCBFlags & UDF_VCB_FLAGS_OUR_DEVICE_DRIVER) { 692 UDFPrint((" UDF_USER_FS_FLAGS_OUR_DRIVER\n")); 693 udf_ver->FSFlags |= UDF_USER_FS_FLAGS_OUR_DRIVER; 694 } 695 if(Vcb->VCBFlags & UDF_VCB_FLAGS_RAW_DISK) { 696 UDFPrint((" UDF_USER_FS_FLAGS_RAW\n")); 697 udf_ver->FSFlags |= UDF_USER_FS_FLAGS_RAW; 698 } 699 if(Vcb->VCBFlags & UDF_VCB_FLAGS_MEDIA_READ_ONLY) { 700 UDFPrint((" UDF_USER_FS_FLAGS_MEDIA_RO\n")); 701 udf_ver->FSFlags |= UDF_USER_FS_FLAGS_MEDIA_RO; 702 } 703 if(Vcb->FP_disc) { 704 UDFPrint((" UDF_USER_FS_FLAGS_FP\n")); 705 udf_ver->FSFlags |= UDF_USER_FS_FLAGS_FP; 706 } 707 udf_ver->FSCompatFlags = Vcb->CompatFlags; 708 709 udf_ver->FSCfgVersion = Vcb->CfgVersion; 710 711 Irp->IoStatus.Information = sizeof(UDF_GET_VERSION_OUT); 712 RC = STATUS_SUCCESS; 713 CompleteIrp = TRUE; 714 715 break; } 716 case IOCTL_UDF_SET_OPTIONS: { 717 718 PUDF_SET_OPTIONS_IN udf_opt; 719 BOOLEAN PrevVerifyOnWrite; 720 721 UDFPrint(("UDF: IOCTL_UDF_SET_OPTIONS\n")); 722 723 Irp->IoStatus.Information = 0; 724 CompleteIrp = TRUE; 725 726 if(IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(UDF_SET_OPTIONS_IN)) { 727 UDFPrint(("InputBufferLength < %x\n", sizeof(UDF_SET_OPTIONS_IN))); 728 try_return(RC = STATUS_BUFFER_TOO_SMALL); 729 } 730 731 udf_opt = (PUDF_SET_OPTIONS_IN)(Irp->AssociatedIrp.SystemBuffer); 732 if(!udf_opt) { 733 UDFPrint(("!udf_opt\n")); 734 try_return(RC = STATUS_INVALID_USER_BUFFER); 735 } 736 737 if((udf_opt->header.Flags & UDF_SET_OPTIONS_FLAG_MASK) != UDF_SET_OPTIONS_FLAG_TEMPORARY) { 738 UDFPrint(("invalid opt target\n")); 739 try_return(RC = STATUS_INVALID_PARAMETER); 740 } 741 742 if(AcquiredVcb) { 743 UDFReleaseResource(&(Vcb->VCBResource)); 744 AcquiredVcb = FALSE; 745 } 746 UDFAcquireResourceExclusive(&(Vcb->VCBResource), TRUE); 747 AcquiredVcb = TRUE; 748 749 PrevVerifyOnWrite = Vcb->VerifyOnWrite; 750 751 Vcb->Cfg = ((PUCHAR)(udf_opt)) + udf_opt->header.HdrLength; 752 Vcb->CfgLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength - offsetof(UDF_SET_OPTIONS_IN, Data); 753 UDFReadRegKeys(Vcb, TRUE /*update*/, TRUE /*cfg*/); 754 Vcb->Cfg = NULL; 755 Vcb->CfgLength = 0; 756 Vcb->CfgVersion++; 757 //UDFReadRegKeys(Vcb, TRUE /*update*/, TRUE); 758 if(PrevVerifyOnWrite != Vcb->VerifyOnWrite) { 759 if(Vcb->VerifyOnWrite) { 760 UDFVInit(Vcb); 761 } else { 762 WCacheFlushBlocks__(&(Vcb->FastCache), Vcb, 0, Vcb->LastLBA); 763 UDFVFlush(Vcb); 764 UDFVRelease(Vcb); 765 } 766 } 767 768 RC = STATUS_SUCCESS; 769 break; } 770 #if 0 771 case IOCTL_UDF_GET_OPTIONS_VERSION: { 772 773 PUDF_GET_OPTIONS_VERSION_OUT udf_opt_ver; 774 775 UDFPrint(("UDF: IOCTL_UDF_GET_OPTIONS_VERSION\n")); 776 777 Irp->IoStatus.Information = 0; 778 CompleteIrp = TRUE; 779 780 if(IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(UDF_GET_OPTIONS_VERSION_OUT)) { 781 UDFPrint(("OutputBufferLength < %x\n", sizeof(UDF_GET_OPTIONS_VERSION_OUT))); 782 try_return(RC = STATUS_BUFFER_TOO_SMALL); 783 } 784 785 udf_opt_ver = (PUDF_GET_OPTIONS_VERSION_OUT)(Irp->AssociatedIrp.SystemBuffer); 786 if(!udf_opt_ver) { 787 UDFPrint(("!udf_opt-ver\n")); 788 try_return(RC = STATUS_INVALID_USER_BUFFER); 789 } 790 /* 791 if(AcquiredVcb) { 792 UDFReleaseResource(&(Vcb->VCBResource)); 793 AcquiredVcb = FALSE; 794 } 795 UDFAcquireResourceShared(&(Vcb->VCBResource), TRUE); 796 AcquiredVcb = TRUE; 797 */ 798 udf_opt_ver->CfgVersion = Vcb->CfgVersion; 799 Irp->IoStatus.Information = sizeof(UDF_GET_OPTIONS_VERSION_OUT); 800 801 RC = STATUS_SUCCESS; 802 break; } 803 #endif //0 804 case IOCTL_CDRW_RESET_DRIVER: 805 806 UDFPrint(("UDF: IOCTL_CDRW_RESET_DRIVER\n")); 807 Vcb->MediaLockCount = 0; 808 Vcb->VCBFlags &= ~UDF_VCB_FLAGS_MEDIA_LOCKED; 809 goto ioctl_do_default; 810 811 case FSCTL_ALLOW_EXTENDED_DASD_IO: 812 813 UDFPrint(("UDFUserFsCtrlRequest: FSCTL_ALLOW_EXTENDED_DASD_IO\n")); 814 // DASD i/o is always permitted 815 // So, no-op this call 816 RC = STATUS_SUCCESS; 817 818 Irp->IoStatus.Information = 0; 819 Irp->IoStatus.Status = STATUS_SUCCESS; 820 CompleteIrp = TRUE; 821 break; 822 823 case FSCTL_IS_VOLUME_DIRTY: 824 825 UDFPrint(("UDFUserFsCtrlRequest: FSCTL_IS_VOLUME_DIRTY\n")); 826 // DASD i/o is always permitted 827 // So, no-op this call 828 RC = UDFIsVolumeDirty(PtrIrpContext, Irp); 829 CompleteIrp = TRUE; 830 break; 831 832 case IOCTL_STORAGE_EJECT_MEDIA: 833 case IOCTL_DISK_EJECT_MEDIA: 834 case IOCTL_CDROM_EJECT_MEDIA: { 835 836 UDFPrint(("UDF Reset/Eject request\n")); 837 // PPREVENT_MEDIA_REMOVAL_USER_IN Buf; 838 839 if(Vcb->EjectWaiter) { 840 UDFPrint((" Vcb->EjectWaiter present\n")); 841 Irp->IoStatus.Information = 0; 842 Vcb->EjectWaiter->SoftEjectReq = TRUE; 843 Vcb->SoftEjectReq = TRUE; 844 CompleteIrp = TRUE; 845 try_return(RC = STATUS_SUCCESS); 846 } 847 UDFPrint((" !Vcb->EjectWaiter\n")); 848 goto ioctl_do_default; 849 /* 850 Buf = (PPREVENT_MEDIA_REMOVAL_USER_IN)MyAllocatePool__(NonPagedPool, sizeof(PREVENT_MEDIA_REMOVAL_USER_IN)); 851 if(!Buf) try_return(RC = STATUS_INSUFFICIENT_RESOURCES); 852 // Acquire Vcb resource (Shared -> Exclusive) 853 UDFReleaseResource(&(Vcb->VCBResource)); 854 UDFAcquireResourceExclusive(&(Vcb->VCBResource), TRUE); 855 856 Vcb->Vpb->RealDevice->Flags |= DO_VERIFY_VOLUME; 857 Vcb->VCBFlags &= ~UDF_VCB_FLAGS_VOLUME_MOUNTED; 858 859 UDFDoDismountSequence(Vcb, Buf, IoControlCode == IOCTL_CDROM_EJECT_MEDIA); 860 // disable Eject Request Waiter if any 861 MyFreePool__(Buf); 862 // Release the Vcb resource. 863 UDFReleaseResource(&(Vcb->VCBResource)); 864 AcquiredVcb = FALSE; 865 UDFStopEjectWaiter(Vcb); 866 CompleteIrp = TRUE; 867 RC = STATUS_SUCCESS; 868 break;*/ 869 } 870 case IOCTL_CDROM_DISK_TYPE: { 871 872 UDFPrint(("UDF Cdrom Disk Type\n")); 873 CompleteIrp = TRUE; 874 // Verify the Vcb in this case to detect if the volume has changed. 875 Irp->IoStatus.Information = 0; 876 RC = UDFVerifyVcb(PtrIrpContext,Vcb); 877 if(!NT_SUCCESS(RC)) 878 try_return(RC); 879 880 // Check the size of the output buffer. 881 if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(CDROM_DISK_DATA_USER_OUT)) 882 try_return(RC = STATUS_BUFFER_TOO_SMALL); 883 884 // Copy the data from the Vcb. 885 ((PCDROM_DISK_DATA_USER_OUT)(Irp->AssociatedIrp.SystemBuffer))->DiskData = CDROM_DISK_DATA_TRACK; 886 for(TrackNumber=Vcb->FirstTrackNum; TrackNumber<Vcb->LastTrackNum; TrackNumber++) { 887 if((Vcb->TrackMap[TrackNumber].TrackParam & Trk_QSubChan_Type_Mask) == 888 Trk_QSubChan_Type_Audio) { 889 ((PCDROM_DISK_DATA_USER_OUT)(Irp->AssociatedIrp.SystemBuffer))->DiskData |= CDROM_DISK_AUDIO_TRACK; 890 break; 891 } 892 } 893 894 Irp->IoStatus.Information = sizeof(CDROM_DISK_DATA_USER_OUT); 895 RC = STATUS_SUCCESS; 896 break; 897 } 898 899 case IOCTL_CDRW_LOCK_DOOR: 900 case IOCTL_STORAGE_MEDIA_REMOVAL: 901 case IOCTL_DISK_MEDIA_REMOVAL: 902 case IOCTL_CDROM_MEDIA_REMOVAL: { 903 UDFPrint(("UDF Lock/Unlock\n")); 904 PPREVENT_MEDIA_REMOVAL_USER_IN buffer; // user supplied buffer 905 buffer = (PPREVENT_MEDIA_REMOVAL_USER_IN)(Irp->AssociatedIrp.SystemBuffer); 906 if(!buffer) { 907 if(!(Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_MOUNTED)) { 908 UDFPrint(("!mounted\n")); 909 goto ioctl_do_default; 910 } 911 UDFPrint(("abort\n")); 912 CompleteIrp = TRUE; 913 Irp->IoStatus.Information = 0; 914 UnsafeIoctl = FALSE; 915 RC = STATUS_INVALID_PARAMETER; 916 break; 917 } 918 if(!buffer->PreventMediaRemoval && 919 !Vcb->MediaLockCount) { 920 921 UDFPrint(("!locked + unlock req\n")); 922 if(!(Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_MOUNTED)) { 923 UDFPrint(("!mounted\n")); 924 goto ioctl_do_default; 925 } 926 #if 0 927 // allocate tmp buffer for FSD calls 928 Buf = (PPREVENT_MEDIA_REMOVAL_USER_IN)MyAllocatePool__(NonPagedPool, sizeof(PREVENT_MEDIA_REMOVAL_USER_IN)); 929 if(!Buf) 930 try_return(RC = STATUS_INSUFFICIENT_RESOURCES); 931 932 // Acquire Vcb resource (Shared -> Exclusive) 933 UDFInterlockedIncrement((PLONG)&(Vcb->VCBOpenCount)); 934 UDFReleaseResource(&(Vcb->VCBResource)); 935 936 #ifdef UDF_DELAYED_CLOSE 937 // Acquire exclusive access to the Vcb. 938 UDFCloseAllDelayed(Vcb); 939 #endif //UDF_DELAYED_CLOSE 940 941 UDFAcquireResourceExclusive(&(Vcb->VCBResource), TRUE); 942 UDFInterlockedDecrement((PLONG)&(Vcb->VCBOpenCount)); 943 944 UDFDoDismountSequence(Vcb, Buf, FALSE); 945 MyFreePool__(Buf); 946 Buf = NULL; 947 Vcb->MediaLockCount = 0; 948 // Release the Vcb resource. 949 UDFReleaseResource(&(Vcb->VCBResource)); 950 AcquiredVcb = FALSE; 951 // disable Eject Request Waiter if any 952 UDFStopEjectWaiter(Vcb); 953 #else 954 // just ignore 955 #endif 956 ignore_lock: 957 UDFPrint(("ignore lock/unlock\n")); 958 CompleteIrp = TRUE; 959 Irp->IoStatus.Information = 0; 960 RC = STATUS_SUCCESS; 961 break; 962 } 963 if(buffer->PreventMediaRemoval) { 964 UDFPrint(("lock req\n")); 965 Vcb->MediaLockCount++; 966 Vcb->VCBFlags |= UDF_VCB_FLAGS_MEDIA_LOCKED; 967 UnsafeIoctl = FALSE; 968 } else { 969 UDFPrint(("unlock req\n")); 970 if(Vcb->MediaLockCount) { 971 UDFPrint(("lock count %d\n", Vcb->MediaLockCount)); 972 UnsafeIoctl = FALSE; 973 Vcb->MediaLockCount--; 974 } 975 } 976 if(!(Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_MOUNTED)) { 977 UDFPrint(("!mounted\n")); 978 goto ioctl_do_default; 979 } 980 goto ignore_lock; 981 } 982 default: 983 984 UDFPrint(("default processing Irp %x, ctx %x, DevIoCtl %x\n", Irp, PtrIrpContext, IoControlCode)); 985 ioctl_do_default: 986 987 // make sure volume is Sync'ed BEFORE sending unsafe IOCTL 988 if(Vcb && UnsafeIoctl) { 989 UDFFlushLogicalVolume(NULL, NULL, Vcb, 0); 990 UDFPrint((" sync'ed\n")); 991 } 992 // Invoke the lower level driver in the chain. 993 //PtrNextIoStackLocation = IoGetNextIrpStackLocation(Irp); 994 //*PtrNextIoStackLocation = *IrpSp; 995 IoSkipCurrentIrpStackLocation(Irp); 996 /* 997 // Set a completion routine. 998 IoSetCompletionRoutine(Irp, UDFDevIoctlCompletion, PtrIrpContext, TRUE, TRUE, TRUE); 999 // Send the request. 1000 */ 1001 RC = IoCallDriver(Vcb->TargetDeviceObject, Irp); 1002 if(!CompleteIrp) { 1003 // since now we do not use IoSetCompletionRoutine() 1004 UDFReleaseIrpContext(PtrIrpContext); 1005 } 1006 break; 1007 } 1008 1009 if(Vcb && UnsafeIoctl) { 1010 UDFPrint((" set UnsafeIoctl\n")); 1011 Vcb->VCBFlags |= UDF_VCB_FLAGS_UNSAFE_IOCTL; 1012 } 1013 1014 try_exit: NOTHING; 1015 1016 } _SEH2_FINALLY { 1017 1018 if(AcquiredVcb) { 1019 UDFReleaseResource(&(Vcb->VCBResource)); 1020 AcquiredVcb = FALSE; 1021 } 1022 1023 if(Buf) { 1024 MyFreePool__(Buf); 1025 } 1026 1027 if (!_SEH2_AbnormalTermination() && 1028 CompleteIrp) { 1029 UDFPrint((" complete Irp %x, ctx %x, status %x, iolen %x\n", 1030 Irp, PtrIrpContext, RC, Irp->IoStatus.Information)); 1031 Irp->IoStatus.Status = RC; 1032 // complete the IRP 1033 IoCompleteRequest(Irp, IO_DISK_INCREMENT); 1034 // Release the IRP context 1035 UDFReleaseIrpContext(PtrIrpContext); 1036 } 1037 } _SEH2_END; 1038 1039 return(RC); 1040 } // end UDFCommonDeviceControl() 1041 1042 1043 /************************************************************************* 1044 * 1045 * Function: UDFDevIoctlCompletion() 1046 * 1047 * Description: 1048 * Completion routine. 1049 * 1050 * Expected Interrupt Level (for execution) : 1051 * 1052 * IRQL_PASSIVE_LEVEL 1053 * 1054 * Return Value: STATUS_SUCCESS 1055 * 1056 *************************************************************************/ 1057 NTSTATUS 1058 NTAPI 1059 UDFDevIoctlCompletion( 1060 PDEVICE_OBJECT PtrDeviceObject, 1061 PIRP Irp, 1062 VOID *Context) 1063 { 1064 /* PIO_STACK_LOCATION IrpSp = NULL; 1065 ULONG IoControlCode = 0;*/ 1066 PtrUDFIrpContext PtrIrpContext = (PtrUDFIrpContext)Context; 1067 1068 UDFPrint(("UDFDevIoctlCompletion Irp %x, ctx %x\n", Irp, Context)); 1069 if (Irp->PendingReturned) { 1070 UDFPrint((" IoMarkIrpPending\n")); 1071 IoMarkIrpPending(Irp); 1072 } 1073 1074 UDFReleaseIrpContext(PtrIrpContext); 1075 /* if(Irp->IoStatus.Status == STATUS_SUCCESS) { 1076 IrpSp = IoGetCurrentIrpStackLocation(Irp); 1077 IoControlCode = IrpSp->Parameters.DeviceIoControl.IoControlCode; 1078 1079 switch(IoControlCode) { 1080 case IOCTL_CDRW_RESET_DRIVER: { 1081 Vcb->MediaLockCount = 0; 1082 } 1083 } 1084 }*/ 1085 1086 return STATUS_SUCCESS; 1087 } // end UDFDevIoctlCompletion() 1088 1089 1090 /************************************************************************* 1091 * 1092 * Function: UDFHandleQueryPath() 1093 * 1094 * Description: 1095 * Handle the MUP request. 1096 * 1097 * Expected Interrupt Level (for execution) : 1098 * 1099 * IRQL_PASSIVE_LEVEL 1100 * 1101 * Return Value: STATUS_SUCCESS 1102 * 1103 *************************************************************************/ 1104 /*NTSTATUS UDFHandleQueryPath( 1105 VOID *BufferPointer) 1106 { 1107 NTSTATUS RC = STATUS_SUCCESS; 1108 PQUERY_PATH_REQUEST RequestBuffer = (PQUERY_PATH_REQUEST)BufferPointer; 1109 PQUERY_PATH_RESPONSE ReplyBuffer = (PQUERY_PATH_RESPONSE)BufferPointer; 1110 ULONG LengthOfNameToBeMatched = RequestBuffer->PathNameLength; 1111 ULONG LengthOfMatchedName = 0; 1112 WCHAR *NameToBeMatched = RequestBuffer->FilePathName; 1113 1114 UDFPrint(("UDFHandleQueryPath\n")); 1115 // So here we are. Simply check the name supplied. 1116 // We can use whatever algorithm we like to determine whether the 1117 // sent in name is acceptable. 1118 // The first character in the name is always a "\" 1119 // If we like the name sent in (probably, we will like a subset 1120 // of the name), set the matching length value in LengthOfMatchedName. 1121 1122 // if (FoundMatch) { 1123 // ReplyBuffer->LengthAccepted = LengthOfMatchedName; 1124 // } else { 1125 // RC = STATUS_OBJECT_NAME_NOT_FOUND; 1126 // } 1127 1128 return(RC); 1129 }*/ 1130 1131 NTSTATUS 1132 UDFGetFileAllocModeFromICB( 1133 PtrUDFIrpContext IrpContext, 1134 PIRP Irp 1135 ) 1136 { 1137 PEXTENDED_IO_STACK_LOCATION IrpSp = 1138 (PEXTENDED_IO_STACK_LOCATION)IoGetCurrentIrpStackLocation( Irp ); 1139 1140 // PVCB Vcb; 1141 PtrUDFFCB Fcb; 1142 PtrUDFCCB Ccb; 1143 PUDF_GET_FILE_ALLOCATION_MODE_OUT OutputBuffer; 1144 1145 UDFPrint(("UDFGetFileAllocModeFromICB\n")); 1146 1147 // Decode the file object, the only type of opens we accept are 1148 // user volume opens. 1149 Ccb = (PtrUDFCCB)(IrpSp->FileObject->FsContext2); 1150 Fcb = Ccb->Fcb; 1151 // Vcb = Fcb->Vcb; 1152 1153 Irp->IoStatus.Information = 0; 1154 if(IrpSp->Parameters.FileSystemControl.OutputBufferLength < sizeof(UDF_GET_FILE_ALLOCATION_MODE_OUT)) 1155 return STATUS_BUFFER_TOO_SMALL; 1156 1157 OutputBuffer = (PUDF_GET_FILE_ALLOCATION_MODE_OUT)(Irp->AssociatedIrp.SystemBuffer); 1158 if(!OutputBuffer) 1159 return STATUS_INVALID_USER_BUFFER; 1160 1161 OutputBuffer->AllocMode = UDFGetFileICBAllocMode__(Fcb->FileInfo); 1162 Irp->IoStatus.Information = sizeof(UDF_GET_FILE_ALLOCATION_MODE_OUT); 1163 1164 return STATUS_SUCCESS; 1165 } // end UDFGetFileAllocModeFromICB() 1166 1167 #ifndef UDF_READ_ONLY_BUILD 1168 NTSTATUS 1169 UDFSetFileAllocModeFromICB( 1170 PtrUDFIrpContext IrpContext, 1171 PIRP Irp 1172 ) 1173 { 1174 PEXTENDED_IO_STACK_LOCATION IrpSp = 1175 (PEXTENDED_IO_STACK_LOCATION)IoGetCurrentIrpStackLocation( Irp ); 1176 1177 PVCB Vcb; 1178 PtrUDFFCB Fcb; 1179 PtrUDFCCB Ccb; 1180 PUDF_SET_FILE_ALLOCATION_MODE_IN InputBuffer; 1181 NTSTATUS RC; 1182 UCHAR AllocMode; 1183 1184 UDFPrint(("UDFSetFileAllocModeFromICB\n")); 1185 1186 Ccb = (PtrUDFCCB)(IrpSp->FileObject->FsContext2); 1187 Fcb = Ccb->Fcb; 1188 Vcb = Fcb->Vcb; 1189 1190 Irp->IoStatus.Information = 0; 1191 if(IrpSp->Parameters.FileSystemControl.InputBufferLength < sizeof(UDF_SET_FILE_ALLOCATION_MODE_IN)) 1192 return STATUS_BUFFER_TOO_SMALL; 1193 1194 InputBuffer = (PUDF_SET_FILE_ALLOCATION_MODE_IN)(Irp->AssociatedIrp.SystemBuffer); 1195 if(!InputBuffer) 1196 return STATUS_INVALID_USER_BUFFER; 1197 1198 UDFFlushAFile(Fcb, Ccb, &(Irp->IoStatus), 0); 1199 RC = Irp->IoStatus.Status; 1200 if(!NT_SUCCESS(RC)) 1201 return RC; 1202 1203 if(InputBuffer->AllocMode != ICB_FLAG_AD_IN_ICB) { 1204 AllocMode = UDFGetFileICBAllocMode__(Fcb->FileInfo); 1205 if(AllocMode == ICB_FLAG_AD_IN_ICB) { 1206 RC = UDFConvertFEToNonInICB(Vcb, Fcb->FileInfo, InputBuffer->AllocMode); 1207 } else 1208 if(AllocMode != InputBuffer->AllocMode) { 1209 RC = STATUS_INVALID_PARAMETER; 1210 } else { 1211 RC = STATUS_SUCCESS; 1212 } 1213 } else { 1214 RC = STATUS_INVALID_PARAMETER; 1215 } 1216 1217 return STATUS_SUCCESS; 1218 } // end UDFSetFileAllocModeFromICB() 1219 #endif //UDF_READ_ONLY_BUILD 1220