1 /*++ 2 3 Copyright (c) 1989-2000 Microsoft Corporation 4 5 Module Name: 6 7 CdProcs.h 8 9 Abstract: 10 11 This module defines all of the globally used procedures in the Cdfs 12 file system. 13 14 15 --*/ 16 17 #ifndef _CDPROCS_ 18 #define _CDPROCS_ 19 20 #ifdef _MSC_VER 21 #pragma warning( disable: 4127 ) // conditional expression is constant 22 23 #pragma warning( push ) 24 #pragma warning( disable: 4201 ) // nonstandard extension used : nameless struct/union 25 #pragma warning( disable: 4214 ) // nonstandard extension used : bit field types 26 #endif 27 28 #include <ntifs.h> 29 30 #include <ntddcdrm.h> 31 #include <ntdddisk.h> 32 #include <ntddscsi.h> 33 #ifdef __REACTOS__ 34 #include <pseh/pseh2.h> 35 #endif 36 37 #ifndef INLINE 38 #define INLINE __inline 39 #endif 40 41 #include "nodetype.h" 42 #include "cd.h" 43 #include "cdstruc.h" 44 #include "cddata.h" 45 46 #ifdef CDFS_TELEMETRY_DATA 47 48 #include <winmeta.h> 49 #include <TraceLoggingProvider.h> 50 #include <telemetry\MicrosoftTelemetry.h> 51 52 #endif // CDFS_TELEMETRY_DATA 53 54 #ifdef _MSC_VER 55 #pragma warning( pop ) 56 #endif 57 58 //**** x86 compiler bug **** 59 60 #if defined(_M_IX86) 61 #undef Int64ShraMod32 62 #define Int64ShraMod32(a, b) ((LONGLONG)(a) >> (b)) 63 #endif 64 65 #ifndef Min 66 #define Min(a, b) ((a) < (b) ? (a) : (b)) 67 #endif 68 69 #ifndef Max 70 #define Max(a, b) ((a) > (b) ? (a) : (b)) 71 #endif 72 73 // 74 // Here are the different pool tags. 75 // 76 77 #define TAG_CCB 'ccdC' // Ccb 78 #define TAG_CDROM_TOC 'ctdC' // TOC 79 #define TAG_DIRENT_NAME 'nddC' // CdName in dirent 80 #define TAG_ENUM_EXPRESSION 'eedC' // Search expression for enumeration 81 #define TAG_FCB_DATA 'dfdC' // Data Fcb 82 #define TAG_FCB_INDEX 'ifdC' // Index Fcb 83 #define TAG_FCB_NONPAGED 'nfdC' // Nonpaged Fcb 84 #define TAG_FCB_TABLE 'tfdC' // Fcb Table entry 85 #define TAG_FILE_NAME 'nFdC' // Filename buffer 86 #define TAG_GEN_SHORT_NAME 'sgdC' // Generated short name 87 #define TAG_IO_BUFFER 'fbdC' // Temporary IO buffer 88 #define TAG_IO_CONTEXT 'oidC' // Io context for async reads 89 #define TAG_IRP_CONTEXT 'cidC' // Irp Context 90 #define TAG_IRP_CONTEXT_LITE 'lidC' // Irp Context lite 91 #define TAG_MCB_ARRAY 'amdC' // Mcb array 92 #define TAG_PATH_ENTRY_NAME 'nPdC' // CdName in path entry 93 #define TAG_PREFIX_ENTRY 'epdC' // Prefix Entry 94 #define TAG_PREFIX_NAME 'npdC' // Prefix Entry name 95 #define TAG_SPANNING_PATH_TABLE 'psdC' // Buffer for spanning path table 96 #define TAG_UPCASE_NAME 'nudC' // Buffer for upcased name 97 #define TAG_VOL_DESC 'dvdC' // Buffer for volume descriptor 98 #define TAG_VPB 'pvdC' // Vpb allocated in filesystem 99 100 // 101 // Tag all of our allocations if tagging is turned on 102 // 103 104 #ifdef POOL_TAGGING 105 106 #undef FsRtlAllocatePool 107 #undef FsRtlAllocatePoolWithQuota 108 #define FsRtlAllocatePool(a,b) FsRtlAllocatePoolWithTag(a,b,'sfdC') 109 #define FsRtlAllocatePoolWithQuota(a,b) FsRtlAllocatePoolWithQuotaTag(a,b,'sfdC') 110 111 #endif // POOL_TAGGING 112 113 114 // 115 // File access check routine, implemented in AcChkSup.c 116 // 117 118 // 119 // BOOLEAN 120 // CdIllegalFcbAccess ( 121 // _In_ PIRP_CONTEXT IrpContext, 122 // _In_ TYPE_OF_OPEN TypeOfOpen, 123 // _In_ ACCESS_MASK DesiredAccess 124 // ); 125 // 126 127 #define CdIllegalFcbAccess(IC,T,DA) ( \ 128 BooleanFlagOn( (DA), \ 129 ((T) != UserVolumeOpen ? \ 130 (FILE_WRITE_ATTRIBUTES | \ 131 FILE_WRITE_DATA | \ 132 FILE_WRITE_EA | \ 133 FILE_ADD_FILE | \ 134 FILE_ADD_SUBDIRECTORY | \ 135 FILE_APPEND_DATA) : 0) | \ 136 FILE_DELETE_CHILD | \ 137 DELETE | \ 138 WRITE_DAC )) 139 140 141 // 142 // Allocation support routines, implemented in AllocSup.c 143 // 144 // These routines are for querying allocation on individual streams. 145 // 146 147 _Requires_lock_held_(_Global_critical_region_) 148 VOID 149 CdLookupAllocation ( 150 _In_ PIRP_CONTEXT IrpContext, 151 _In_ PFCB Fcb, 152 _In_ LONGLONG FileOffset, 153 _Out_ PLONGLONG DiskOffset, 154 _Out_ PULONG ByteCount 155 ); 156 157 VOID 158 CdAddAllocationFromDirent ( 159 _In_ PIRP_CONTEXT IrpContext, 160 _Inout_ PFCB Fcb, 161 _In_ ULONG McbEntryOffset, 162 _In_ LONGLONG StartingFileOffset, 163 _In_ PDIRENT Dirent 164 ); 165 166 VOID 167 CdAddInitialAllocation ( 168 _In_ PIRP_CONTEXT IrpContext, 169 _Inout_ PFCB Fcb, 170 _In_ ULONG StartingBlock, 171 _In_ LONGLONG DataLength 172 ); 173 174 VOID 175 CdTruncateAllocation ( 176 _In_ PIRP_CONTEXT IrpContext, 177 _Inout_ PFCB Fcb, 178 _In_ LONGLONG StartingFileOffset 179 ); 180 181 _At_(Fcb->NodeByteSize, _In_range_(>=, FIELD_OFFSET( FCB, FcbType ))) 182 VOID 183 CdInitializeMcb ( 184 _In_ PIRP_CONTEXT IrpContext, 185 _Inout_updates_bytes_(Fcb->NodeByteSize) PFCB Fcb 186 ); 187 188 _At_(Fcb->NodeByteSize, _In_range_(>=, FIELD_OFFSET( FCB, FcbType ))) 189 _When_(Fcb->NodeTypeCode == CDFS_NTC_FCB_PATH_TABLE, _At_(Fcb->NodeByteSize, _In_range_(==, SIZEOF_FCB_INDEX))) 190 _When_(Fcb->NodeTypeCode == CDFS_NTC_FCB_INDEX, _At_(Fcb->NodeByteSize, _In_range_(==, SIZEOF_FCB_INDEX))) 191 _When_(Fcb->NodeTypeCode == CDFS_NTC_FCB_DATA, _At_(Fcb->NodeByteSize, _In_range_(==, SIZEOF_FCB_DATA))) 192 VOID 193 CdUninitializeMcb ( 194 _In_ PIRP_CONTEXT IrpContext, 195 _Inout_updates_bytes_(Fcb->NodeByteSize) PFCB Fcb 196 ); 197 198 199 // 200 // Buffer control routines for data caching, implemented in CacheSup.c 201 // 202 203 VOID 204 CdCreateInternalStream ( 205 _In_ PIRP_CONTEXT IrpContext, 206 _In_ PVCB Vcb, 207 _Inout_ PFCB Fcb, 208 _In_ PUNICODE_STRING Name 209 ); 210 211 VOID 212 CdDeleteInternalStream ( 213 _In_ PIRP_CONTEXT IrpContext, 214 _Inout_ PFCB Fcb 215 ); 216 217 NTSTATUS 218 CdCompleteMdl ( 219 _In_ PIRP_CONTEXT IrpContext, 220 _Inout_ PIRP Irp 221 ); 222 223 _Requires_lock_held_(_Global_critical_region_) 224 NTSTATUS 225 CdPurgeVolume ( 226 _In_ PIRP_CONTEXT IrpContext, 227 _In_ PVCB Vcb, 228 _In_ BOOLEAN DismountUnderway 229 ); 230 231 static /* ReactOS Change: GCC "multiple definition" */ 232 INLINE /* GCC only accepts __inline as the first modifier */ 233 VOID 234 CdVerifyOrCreateDirStreamFile ( 235 _In_ PIRP_CONTEXT IrpContext, 236 _In_ PFCB Fcb 237 ) 238 { 239 // 240 // Unsafe test to see if call / lock neccessary. 241 // 242 243 if (NULL == Fcb->FileObject) { 244 245 CdCreateInternalStream( IrpContext, 246 Fcb->Vcb, 247 Fcb, 248 &Fcb->FileNamePrefix.ExactCaseName.FileName); 249 } 250 } 251 252 253 // 254 // VOID 255 // CdUnpinData ( 256 // _In_ PIRP_CONTEXT IrpContext, 257 // _Inout_ PBCB *Bcb 258 // ); 259 // 260 261 #define CdUnpinData(IC,B) \ 262 if (*(B) != NULL) { CcUnpinData( *(B) ); *(B) = NULL; } 263 264 265 // 266 // Device I/O routines, implemented in DevIoSup.c 267 // 268 // These routines perform the actual device read and writes. They only affect 269 // the on disk structure and do not alter any other data structures. 270 // 271 272 _Requires_lock_held_(_Global_critical_region_) 273 VOID 274 CdFreeDirCache ( 275 _In_ PIRP_CONTEXT IrpContext 276 ); 277 278 _Requires_lock_held_(_Global_critical_region_) 279 NTSTATUS 280 CdNonCachedRead ( 281 _In_ PIRP_CONTEXT IrpContext, 282 _In_ PFCB Fcb, 283 _In_ LONGLONG StartingOffset, 284 _In_ ULONG ByteCount 285 ); 286 287 _Requires_lock_held_(_Global_critical_region_) 288 NTSTATUS 289 CdNonCachedXARead ( 290 _In_ PIRP_CONTEXT IrpContext, 291 _In_ PFCB Fcb, 292 _In_ LONGLONG StartingOffset, 293 _In_ ULONG ByteCount 294 ); 295 296 _Requires_lock_held_(_Global_critical_region_) 297 NTSTATUS 298 CdVolumeDasdWrite ( 299 _In_ PIRP_CONTEXT IrpContext, 300 _In_ PFCB Fcb, 301 _In_ LONGLONG StartingOffset, 302 _In_ ULONG ByteCount 303 ); 304 305 BOOLEAN 306 CdReadSectors ( 307 _In_ PIRP_CONTEXT IrpContext, 308 _In_ LONGLONG StartingOffset, 309 _In_ ULONG ByteCount, 310 _In_ BOOLEAN ReturnError, 311 _Out_writes_bytes_(ByteCount) PVOID Buffer, 312 _In_ PDEVICE_OBJECT TargetDeviceObject 313 ); 314 315 NTSTATUS 316 CdCreateUserMdl ( 317 _In_ PIRP_CONTEXT IrpContext, 318 _In_ ULONG BufferLength, 319 _In_ BOOLEAN RaiseOnError, 320 _In_ LOCK_OPERATION Operation 321 ); 322 323 NTSTATUS 324 FASTCALL 325 CdPerformDevIoCtrl ( 326 _In_ PIRP_CONTEXT IrpContext, 327 _In_ ULONG IoControlCode, 328 _In_ PDEVICE_OBJECT Device, 329 _Out_writes_bytes_opt_(OutputBufferLength) PVOID OutputBuffer, 330 _In_ ULONG OutputBufferLength, 331 _In_ BOOLEAN InternalDeviceIoControl, 332 _In_ BOOLEAN OverrideVerify, 333 _Out_opt_ PIO_STATUS_BLOCK Iosb 334 ); 335 336 NTSTATUS 337 CdPerformDevIoCtrlEx ( 338 _In_ PIRP_CONTEXT IrpContext, 339 _In_ ULONG IoControlCode, 340 _In_ PDEVICE_OBJECT Device, 341 _In_reads_bytes_opt_(InputBufferLength) PVOID InputBuffer, 342 _In_ ULONG InputBufferLength, 343 _Out_writes_bytes_opt_(OutputBufferLength) PVOID OutputBuffer, 344 _In_ ULONG OutputBufferLength, 345 _In_ BOOLEAN InternalDeviceIoControl, 346 _In_ BOOLEAN OverrideVerify, 347 _Out_opt_ PIO_STATUS_BLOCK Iosb 348 ); 349 350 NTSTATUS 351 CdHijackIrpAndFlushDevice ( 352 _In_ PIRP_CONTEXT IrpContext, 353 _Inout_ PIRP Irp, 354 _In_ PDEVICE_OBJECT TargetDeviceObject 355 ); 356 357 358 // 359 // VOID 360 // CdMapUserBuffer ( 361 // _In_ PIRP_CONTEXT IrpContext 362 // _Out_ PVOID UserBuffer 363 // ); 364 // 365 // Returns pointer to sys address. Will raise on failure. 366 // 367 // 368 // VOID 369 // CdLockUserBuffer ( 370 // _Inout_ PIRP_CONTEXT IrpContext, 371 // _In_ ULONG BufferLength 372 // ); 373 // 374 375 #ifndef __REACTOS__ 376 #define CdMapUserBuffer(IC, UB) { \ 377 *(UB) = (PVOID) ( ((IC)->Irp->MdlAddress == NULL) ? \ 378 (IC)->Irp->UserBuffer : \ 379 (MmGetSystemAddressForMdlSafe( (IC)->Irp->MdlAddress, NormalPagePriority | MdlMappingNoExecute))); \ 380 if (NULL == *(UB)) { \ 381 CdRaiseStatus( (IC), STATUS_INSUFFICIENT_RESOURCES); \ 382 } \ 383 } 384 385 #else 386 #define CdMapUserBuffer(IC, UB) { \ 387 *(UB) = (PVOID) ( ((IC)->Irp->MdlAddress == NULL) ? \ 388 (IC)->Irp->UserBuffer : \ 389 (MmGetSystemAddressForMdlSafe( (IC)->Irp->MdlAddress, NormalPagePriority))); \ 390 if (NULL == *(UB)) { \ 391 CdRaiseStatus( (IC), STATUS_INSUFFICIENT_RESOURCES); \ 392 } \ 393 } 394 395 #endif 396 397 398 #define CdLockUserBuffer(IC,BL,OP) { \ 399 if ((IC)->Irp->MdlAddress == NULL) { \ 400 (VOID) CdCreateUserMdl( (IC), (BL), TRUE, (OP) ); \ 401 } \ 402 } 403 404 405 // 406 // Dirent support routines, implemented in DirSup.c 407 // 408 409 VOID 410 CdLookupDirent ( 411 _In_ PIRP_CONTEXT IrpContext, 412 _In_ PFCB Fcb, 413 _In_ ULONG DirentOffset, 414 _Out_ PDIRENT_ENUM_CONTEXT DirContext 415 ); 416 417 BOOLEAN 418 CdLookupNextDirent ( 419 _In_ PIRP_CONTEXT IrpContext, 420 _In_ PFCB Fcb, 421 _In_ PDIRENT_ENUM_CONTEXT CurrentDirContext, 422 _Inout_ PDIRENT_ENUM_CONTEXT NextDirContext 423 ); 424 425 _At_(Dirent->CdTime, _Post_notnull_) 426 VOID 427 CdUpdateDirentFromRawDirent ( 428 _In_ PIRP_CONTEXT IrpContext, 429 _In_ PFCB Fcb, 430 _In_ PDIRENT_ENUM_CONTEXT DirContext, 431 _Inout_ PDIRENT Dirent 432 ); 433 434 VOID 435 CdUpdateDirentName ( 436 _In_ PIRP_CONTEXT IrpContext, 437 _Inout_ PDIRENT Dirent, 438 _In_ ULONG IgnoreCase 439 ); 440 441 _Success_(return != FALSE) BOOLEAN 442 CdFindFile ( 443 _In_ PIRP_CONTEXT IrpContext, 444 _In_ PFCB Fcb, 445 _In_ PCD_NAME Name, 446 _In_ BOOLEAN IgnoreCase, 447 _Inout_ PFILE_ENUM_CONTEXT FileContext, 448 _Out_ PCD_NAME *MatchingName 449 ); 450 451 BOOLEAN 452 CdFindDirectory ( 453 _In_ PIRP_CONTEXT IrpContext, 454 _In_ PFCB Fcb, 455 _In_ PCD_NAME Name, 456 _In_ BOOLEAN IgnoreCase, 457 _Inout_ PFILE_ENUM_CONTEXT FileContext 458 ); 459 460 _At_(FileContext->ShortName.FileName.MaximumLength, _In_range_(>=, BYTE_COUNT_8_DOT_3)) 461 BOOLEAN 462 CdFindFileByShortName ( 463 _In_ PIRP_CONTEXT IrpContext, 464 _In_ PFCB Fcb, 465 _In_ PCD_NAME Name, 466 _In_ BOOLEAN IgnoreCase, 467 _In_ ULONG ShortNameDirentOffset, 468 _Inout_ PFILE_ENUM_CONTEXT FileContext 469 ); 470 471 BOOLEAN 472 CdLookupNextInitialFileDirent ( 473 _In_ PIRP_CONTEXT IrpContext, 474 _In_ PFCB Fcb, 475 _Inout_ PFILE_ENUM_CONTEXT FileContext 476 ); 477 478 VOID 479 CdLookupLastFileDirent ( 480 _In_ PIRP_CONTEXT IrpContext, 481 _In_ PFCB Fcb, 482 _In_ PFILE_ENUM_CONTEXT FileContext 483 ); 484 485 VOID 486 CdCleanupFileContext ( 487 _In_ PIRP_CONTEXT IrpContext, 488 _In_ PFILE_ENUM_CONTEXT FileContext 489 ); 490 491 // 492 // VOID 493 // CdInitializeFileContext ( 494 // _In_ PIRP_CONTEXT IrpContext, 495 // _Out_ PFILE_ENUM_CONTEXT FileContext 496 // ); 497 // 498 // 499 // VOID 500 // CdInitializeDirent ( 501 // _In_ PIRP_CONTEXT IrpContext, 502 // _Out_ PDIRENT Dirent 503 // ); 504 // 505 // VOID 506 // CdInitializeDirContext ( 507 // _In_ PIRP_CONTEXT IrpContext, 508 // _Out_ PDIRENT_ENUM_CONTEXT DirContext 509 // ); 510 // 511 // VOID 512 // CdCleanupDirent ( 513 // _In_ PIRP_CONTEXT IrpContext, 514 // _Inout_ PDIRENT Dirent 515 // ); 516 // 517 // VOID 518 // CdCleanupDirContext ( 519 // _In_ PIRP_CONTEXT IrpContext, 520 // _Inout_ PDIRENT_ENUM_CONTEXT DirContext 521 // ); 522 // 523 // VOID 524 // CdLookupInitialFileDirent ( 525 // _In_ PIRP_CONTEXT IrpContext, 526 // _In_ PFCB Fcb, 527 // _Out_ PFILE_ENUM_CONTEXT FileContext, 528 // _In_ ULONG DirentOffset 529 // ); 530 // 531 532 #define CdInitializeFileContext(IC,FC) { \ 533 RtlZeroMemory( FC, sizeof( FILE_ENUM_CONTEXT )); \ 534 (FC)->PriorDirent = &(FC)->Dirents[0]; \ 535 (FC)->InitialDirent = &(FC)->Dirents[1]; \ 536 (FC)->CurrentDirent = &(FC)->Dirents[2]; \ 537 (FC)->ShortName.FileName.MaximumLength = BYTE_COUNT_8_DOT_3; \ 538 (FC)->ShortName.FileName.Buffer = (FC)->ShortNameBuffer; \ 539 } 540 541 #define CdInitializeDirent(IC,D) \ 542 RtlZeroMemory( D, sizeof( DIRENT )) 543 544 #define CdInitializeDirContext(IC,DC) \ 545 RtlZeroMemory( DC, sizeof( DIRENT_ENUM_CONTEXT )) 546 547 #define CdCleanupDirent(IC,D) { \ 548 if (FlagOn( (D)->Flags, DIRENT_FLAG_ALLOC_BUFFER )) { \ 549 CdFreePool( &(D)->CdFileName.FileName.Buffer ); \ 550 } \ 551 } 552 553 #define CdCleanupDirContext(IC,DC) \ 554 CdUnpinData( (IC), &(DC)->Bcb ) 555 556 #define CdLookupInitialFileDirent(IC,F,FC,DO) \ 557 CdLookupDirent( IC, \ 558 F, \ 559 DO, \ 560 &(FC)->InitialDirent->DirContext ); \ 561 CdUpdateDirentFromRawDirent( IC, \ 562 F, \ 563 &(FC)->InitialDirent->DirContext, \ 564 &(FC)->InitialDirent->Dirent ) 565 566 567 // 568 // The following routines are used to manipulate the fscontext fields 569 // of the file object, implemented in FilObSup.c 570 // 571 572 // 573 // Type of opens. FilObSup.c depends on this order. 574 // 575 576 typedef enum _TYPE_OF_OPEN { 577 578 UnopenedFileObject = 0, 579 StreamFileOpen, 580 UserVolumeOpen, 581 UserDirectoryOpen, 582 UserFileOpen, 583 BeyondValidType 584 585 } TYPE_OF_OPEN; 586 typedef TYPE_OF_OPEN *PTYPE_OF_OPEN; 587 588 _When_(TypeOfOpen == UnopenedFileObject, _At_(Fcb, _In_opt_)) 589 _When_(TypeOfOpen != UnopenedFileObject, _At_(Fcb, _In_)) 590 VOID 591 CdSetFileObject ( 592 _In_ PIRP_CONTEXT IrpContext, 593 _Inout_ PFILE_OBJECT FileObject, 594 _In_ TYPE_OF_OPEN TypeOfOpen, 595 PFCB Fcb, 596 _In_opt_ PCCB Ccb 597 ); 598 599 _When_(return == UnopenedFileObject, _At_(*Fcb, _Post_null_)) 600 _When_(return != UnopenedFileObject, _At_(Fcb, _Outptr_)) 601 _When_(return == UnopenedFileObject, _At_(*Ccb, _Post_null_)) 602 _When_(return != UnopenedFileObject, _At_(Ccb, _Outptr_)) 603 TYPE_OF_OPEN 604 CdDecodeFileObject ( 605 _In_ PIRP_CONTEXT IrpContext, 606 _In_ PFILE_OBJECT FileObject, 607 PFCB *Fcb, 608 PCCB *Ccb 609 ); 610 611 TYPE_OF_OPEN 612 CdFastDecodeFileObject ( 613 _In_ PFILE_OBJECT FileObject, 614 _Out_ PFCB *Fcb 615 ); 616 617 618 // 619 // Name support routines, implemented in NameSup.c 620 // 621 622 _Post_satisfies_(_Old_(CdName->FileName.Length) >= 623 CdName->FileName.Length + CdName->VersionString.Length) 624 VOID 625 CdConvertNameToCdName ( 626 _In_ PIRP_CONTEXT IrpContext, 627 _Inout_ PCD_NAME CdName 628 ); 629 630 VOID 631 CdConvertBigToLittleEndian ( 632 _In_ PIRP_CONTEXT IrpContext, 633 _In_reads_bytes_(ByteCount) PCHAR BigEndian, 634 _In_ ULONG ByteCount, 635 _Out_writes_bytes_(ByteCount) PCHAR LittleEndian 636 ); 637 638 VOID 639 CdUpcaseName ( 640 _In_ PIRP_CONTEXT IrpContext, 641 _In_ PCD_NAME Name, 642 _Inout_ PCD_NAME UpcaseName 643 ); 644 645 VOID 646 CdDissectName ( 647 _In_ PIRP_CONTEXT IrpContext, 648 _Inout_ PUNICODE_STRING RemainingName, 649 _Out_ PUNICODE_STRING FinalName 650 ); 651 652 BOOLEAN 653 CdIsLegalName ( 654 _In_ PIRP_CONTEXT IrpContext, 655 _In_ PUNICODE_STRING FileName 656 ); 657 658 BOOLEAN 659 CdIs8dot3Name ( 660 _In_ PIRP_CONTEXT IrpContext, 661 _In_ UNICODE_STRING FileName 662 ); 663 664 VOID 665 CdGenerate8dot3Name ( 666 _In_ PIRP_CONTEXT IrpContext, 667 _In_ PUNICODE_STRING FileName, 668 _In_ ULONG DirentOffset, 669 _Out_writes_bytes_to_(BYTE_COUNT_8_DOT_3, *ShortByteCount) PWCHAR ShortFileName, 670 _Out_ PUSHORT ShortByteCount 671 ); 672 673 BOOLEAN 674 CdIsNameInExpression ( 675 _In_ PIRP_CONTEXT IrpContext, 676 _In_ PCD_NAME CurrentName, 677 _In_ PCD_NAME SearchExpression, 678 _In_ ULONG WildcardFlags, 679 _In_ BOOLEAN CheckVersion 680 ); 681 682 ULONG 683 CdShortNameDirentOffset ( 684 _In_ PIRP_CONTEXT IrpContext, 685 _In_ PUNICODE_STRING Name 686 ); 687 688 FSRTL_COMPARISON_RESULT 689 CdFullCompareNames ( 690 _In_ PIRP_CONTEXT IrpContext, 691 _In_ PUNICODE_STRING NameA, 692 _In_ PUNICODE_STRING NameB 693 ); 694 695 696 // 697 // Filesystem control operations. Implemented in Fsctrl.c 698 // 699 700 _Requires_lock_held_(_Global_critical_region_) 701 _Requires_lock_held_(Vcb->VcbResource) 702 NTSTATUS 703 CdLockVolumeInternal ( 704 _In_ PIRP_CONTEXT IrpContext, 705 _Inout_ PVCB Vcb, 706 _In_opt_ PFILE_OBJECT FileObject 707 ); 708 709 NTSTATUS 710 CdUnlockVolumeInternal ( 711 _In_ PIRP_CONTEXT IrpContext, 712 _Inout_ PVCB Vcb, 713 _In_opt_ PFILE_OBJECT FileObject 714 ); 715 716 717 // 718 // Path table enumeration routines. Implemented in PathSup.c 719 // 720 721 VOID 722 CdLookupPathEntry ( 723 _In_ PIRP_CONTEXT IrpContext, 724 _In_ ULONG PathEntryOffset, 725 _In_ ULONG Ordinal, 726 _In_ BOOLEAN VerifyBounds, 727 _Inout_ PCOMPOUND_PATH_ENTRY CompoundPathEntry 728 ); 729 730 BOOLEAN 731 CdLookupNextPathEntry ( 732 _In_ PIRP_CONTEXT IrpContext, 733 _Inout_ PPATH_ENUM_CONTEXT PathContext, 734 _Inout_ PPATH_ENTRY PathEntry 735 ); 736 737 _Success_(return != FALSE) 738 BOOLEAN 739 CdFindPathEntry ( 740 _In_ PIRP_CONTEXT IrpContext, 741 _In_ PFCB ParentFcb, 742 _In_ PCD_NAME DirName, 743 _In_ BOOLEAN IgnoreCase, 744 _Inout_ PCOMPOUND_PATH_ENTRY CompoundPathEntry 745 ); 746 747 VOID 748 CdUpdatePathEntryName ( 749 _In_ PIRP_CONTEXT IrpContext, 750 _Inout_ PPATH_ENTRY PathEntry, 751 _In_ BOOLEAN IgnoreCase 752 ); 753 754 // 755 // VOID 756 // CdInitializeCompoundPathEntry ( 757 // _In_ PIRP_CONTEXT IrpContext, 758 // _Out_ PCOMPOUND_PATH_ENTRY CompoundPathEntry 759 // ); 760 // 761 // VOID 762 // CdCleanupCompoundPathEntry ( 763 // _In_ PIRP_CONTEXT IrpContext, 764 // _Out_ PCOMPOUND_PATH_ENTRY CompoundPathEntry 765 // ); 766 // 767 768 #define CdInitializeCompoundPathEntry(IC,CP) \ 769 RtlZeroMemory( CP, sizeof( COMPOUND_PATH_ENTRY )) 770 771 #define CdCleanupCompoundPathEntry(IC,CP) { \ 772 CdUnpinData( (IC), &(CP)->PathContext.Bcb ); \ 773 if ((CP)->PathContext.AllocatedData) { \ 774 CdFreePool( &(CP)->PathContext.Data ); \ 775 } \ 776 if (FlagOn( (CP)->PathEntry.Flags, PATH_ENTRY_FLAG_ALLOC_BUFFER )) { \ 777 CdFreePool( &(CP)->PathEntry.CdDirName.FileName.Buffer ); \ 778 } \ 779 } 780 781 782 // 783 // Largest matching prefix searching routines, implemented in PrefxSup.c 784 // 785 786 VOID 787 CdInsertPrefix ( 788 _In_ PIRP_CONTEXT IrpContext, 789 _Inout_ PFCB Fcb, 790 _In_ PCD_NAME Name, 791 _In_ BOOLEAN IgnoreCase, 792 _In_ BOOLEAN ShortNameMatch, 793 _Inout_ PFCB ParentFcb 794 ); 795 796 VOID 797 CdRemovePrefix ( 798 _In_ PIRP_CONTEXT IrpContext, 799 _Inout_ PFCB Fcb 800 ); 801 802 _Requires_lock_held_(_Global_critical_region_) 803 VOID 804 CdFindPrefix ( 805 _In_ PIRP_CONTEXT IrpContext, 806 _Inout_ PFCB *CurrentFcb, 807 _Inout_ PUNICODE_STRING RemainingName, 808 _In_ BOOLEAN IgnoreCase 809 ); 810 811 812 // 813 // Synchronization routines. Implemented in Resrcsup.c 814 // 815 // The following routines/macros are used to synchronize the in-memory structures. 816 // 817 // Routine/Macro Synchronizes Subsequent 818 // 819 // CdAcquireCdData Volume Mounts/Dismounts,Vcb Queue CdReleaseCdData 820 // CdAcquireVcbExclusive Vcb for open/close CdReleaseVcb 821 // CdAcquireVcbShared Vcb for open/close CdReleaseVcb 822 // CdAcquireAllFiles Locks out operations to all files CdReleaseAllFiles 823 // CdAcquireFileExclusive Locks out file operations CdReleaseFile 824 // CdAcquireFileShared Files for file operations CdReleaseFile 825 // CdAcquireFcbExclusive Fcb for open/close CdReleaseFcb 826 // CdAcquireFcbShared Fcb for open/close CdReleaseFcb 827 // CdLockCdData Fields in CdData CdUnlockCdData 828 // CdLockVcb Vcb fields, FcbReference, FcbTable CdUnlockVcb 829 // CdLockFcb Fcb fields, prefix table, Mcb CdUnlockFcb 830 // 831 832 typedef enum _TYPE_OF_ACQUIRE { 833 834 AcquireExclusive, 835 AcquireShared, 836 AcquireSharedStarveExclusive 837 838 } TYPE_OF_ACQUIRE, *PTYPE_OF_ACQUIRE; 839 840 _Requires_lock_held_(_Global_critical_region_) 841 _When_(Type == AcquireExclusive && return != FALSE, _Acquires_exclusive_lock_(*Resource)) 842 _When_(Type == AcquireShared && return != FALSE, _Acquires_shared_lock_(*Resource)) 843 _When_(Type == AcquireSharedStarveExclusive && return != FALSE, _Acquires_shared_lock_(*Resource)) 844 _When_(IgnoreWait == FALSE, _Post_satisfies_(return == TRUE)) 845 BOOLEAN 846 CdAcquireResource ( 847 _In_ PIRP_CONTEXT IrpContext, 848 _Inout_ PERESOURCE Resource, 849 _In_ BOOLEAN IgnoreWait, 850 _In_ TYPE_OF_ACQUIRE Type 851 ); 852 853 // 854 // BOOLEAN 855 // CdAcquireCdData ( 856 // _In_ PIRP_CONTEXT IrpContext 857 // ); 858 // 859 // VOID 860 // CdReleaseCdData ( 861 // _In_ PIRP_CONTEXT IrpContext 862 // ); 863 // 864 // BOOLEAN 865 // CdAcquireVcbExclusive ( 866 // _In_ PIRP_CONTEXT IrpContext, 867 // _Inout_ PVCB Vcb, 868 // _In_ BOOLEAN IgnoreWait 869 // ); 870 // 871 // BOOLEAN 872 // CdAcquireVcbShared ( 873 // _In_ PIRP_CONTEXT IrpContext, 874 // _Inout_ PVCB Vcb, 875 // _In_ BOOLEAN IgnoreWait 876 // ); 877 // 878 // VOID 879 // CdReleaseVcb ( 880 // _In_ PIRP_CONTEXT IrpContext, 881 // _Inout_ PVCB Vcb 882 // ); 883 // 884 // VOID 885 // CdAcquireAllFiles ( 886 // _In_ PIRP_CONTEXT, 887 // _In_ PVCB Vcb 888 // ); 889 // 890 // VOID 891 // CdReleaseAllFiles ( 892 // _In_ PIRP_CONTEXT, 893 // _In_ PVCB Vcb 894 // ); 895 // 896 // VOID 897 // CdAcquireFileExclusive ( 898 // _In_ PIRP_CONTEXT IrpContext, 899 // _Inout_ PFCB Fcb, 900 // ); 901 // 902 // VOID 903 // CdAcquireFileShared ( 904 // _In_ PIRP_CONTEXT IrpContext, 905 // _Inout_ PFCB Fcb 906 // ); 907 // 908 // VOID 909 // CdReleaseFile ( 910 // _In_ PIRP_CONTEXT IrpContext, 911 // _Inout_ PFCB Fcb 912 // ); 913 // 914 // BOOLEAN 915 // CdAcquireFcbExclusive ( 916 // _In_ PIRP_CONTEXT IrpContext, 917 // _Inout_ PFCB Fcb, 918 // _In_ BOOLEAN IgnoreWait 919 // ); 920 // 921 // BOOLEAN 922 // CdAcquireFcbShared ( 923 // _In_ PIRP_CONTEXT IrpContext, 924 // _Inout_ PFCB Fcb, 925 // _In_ BOOLEAN IgnoreWait 926 // ); 927 // 928 // BOOLEAN 929 // CdReleaseFcb ( 930 // _In_ PIRP_CONTEXT IrpContext, 931 // _Inout_ PFCB Fcb 932 // ); 933 // 934 // VOID 935 // CdLockCdData ( 936 // ); 937 // 938 // VOID 939 // CdUnlockCdData ( 940 // ); 941 // 942 // VOID 943 // CdLockVcb ( 944 // _In_ PIRP_CONTEXT IrpContext 945 // ); 946 // 947 // VOID 948 // CdUnlockVcb ( 949 // _In_ PIRP_CONTEXT IrpContext 950 // ); 951 // 952 // VOID 953 // CdLockFcb ( 954 // _In_ PIRP_CONTEXT IrpContext, 955 // _Inout_ PFCB Fcb 956 // ); 957 // 958 // VOID 959 // CdUnlockFcb ( 960 // _In_ PIRP_CONTEXT IrpContext, 961 // _Inout_ PFCB Fcb 962 // ); 963 // 964 965 966 #define CdAcquireCacheForRead( IC) \ 967 ExAcquireResourceSharedLite( &(IC)->Vcb->SectorCacheResource, TRUE) 968 969 #define CdAcquireCacheForUpdate( IC) \ 970 ExAcquireResourceExclusiveLite( &(IC)->Vcb->SectorCacheResource, TRUE) 971 972 #define CdReleaseCache( IC) \ 973 ExReleaseResourceLite( &(IC)->Vcb->SectorCacheResource); 974 975 #define CdConvertCacheToShared( IC) \ 976 ExConvertExclusiveToSharedLite( &(IC)->Vcb->SectorCacheResource); 977 978 #define CdAcquireCdData(IC) \ 979 ExAcquireResourceExclusiveLite( &CdData.DataResource, TRUE ) 980 981 #define CdReleaseCdData(IC) \ 982 ExReleaseResourceLite( &CdData.DataResource ) 983 984 #define CdAcquireVcbExclusive(IC,V,I) \ 985 CdAcquireResource( (IC), &(V)->VcbResource, (I), AcquireExclusive ) 986 987 #define CdAcquireVcbShared(IC,V,I) \ 988 CdAcquireResource( (IC), &(V)->VcbResource, (I), AcquireShared ) 989 990 #define CdReleaseVcb(IC,V) \ 991 ExReleaseResourceLite( &(V)->VcbResource ) 992 993 #define CdAcquireAllFiles(IC,V) \ 994 CdAcquireResource( (IC), &(V)->FileResource, FALSE, AcquireExclusive ) 995 996 #define CdReleaseAllFiles(IC,V) \ 997 ExReleaseResourceLite( &(V)->FileResource ) 998 999 #define CdAcquireFileExclusive(IC,F) \ 1000 CdAcquireResource( (IC), (F)->Resource, FALSE, AcquireExclusive ) 1001 1002 #define CdAcquireFileShared(IC,F) \ 1003 CdAcquireResource( (IC), (F)->Resource, FALSE, AcquireShared ) 1004 1005 #define CdAcquireFileSharedStarveExclusive(IC,F) \ 1006 CdAcquireResource( (IC), (F)->Resource, FALSE, AcquireSharedStarveExclusive ) 1007 1008 #define CdReleaseFile(IC,F) \ 1009 ExReleaseResourceLite( (F)->Resource ) 1010 1011 #define CdAcquireFcbExclusive(IC,F,I) \ 1012 CdAcquireResource( (IC), &(F)->FcbNonpaged->FcbResource, (I), AcquireExclusive ) 1013 1014 #define CdAcquireFcbShared(IC,F,I) \ 1015 CdAcquireResource( (IC), &(F)->FcbNonpaged->FcbResource, (I), AcquireShared ) 1016 1017 #define CdReleaseFcb(IC,F) \ 1018 ExReleaseResourceLite( &(F)->FcbNonpaged->FcbResource ) 1019 1020 #define CdLockCdData() \ 1021 ExAcquireFastMutex( &CdData.CdDataMutex ); \ 1022 CdData.CdDataLockThread = PsGetCurrentThread() 1023 1024 #define CdUnlockCdData() \ 1025 CdData.CdDataLockThread = NULL; \ 1026 ExReleaseFastMutex( &CdData.CdDataMutex ) 1027 1028 #define CdLockVcb(IC,V) \ 1029 ExAcquireFastMutex( &(V)->VcbMutex ); \ 1030 NT_ASSERT( NULL == (V)->VcbLockThread); \ 1031 (V)->VcbLockThread = PsGetCurrentThread() 1032 1033 #define CdUnlockVcb(IC,V) \ 1034 NT_ASSERT( NULL != (V)->VcbLockThread); \ 1035 (V)->VcbLockThread = NULL; \ 1036 ExReleaseFastMutex( &(V)->VcbMutex ) 1037 1038 #if defined(_PREFAST_) 1039 1040 _Success_(return) 1041 _IRQL_saves_global_(OldIrql, FastMutex) 1042 BOOLEAN DummySaveIrql(_Inout_ PFAST_MUTEX FastMutex); 1043 1044 _Success_(return) 1045 _IRQL_restores_global_(OldIrql, FastMutex) 1046 BOOLEAN DummyRestoreIrql(_Inout_ PFAST_MUTEX FastMutex); 1047 #endif // _PREFAST_ 1048 1049 #define CdLockFcb(IC,F) { \ 1050 PVOID _CurrentThread = PsGetCurrentThread(); \ 1051 if (_CurrentThread != (F)->FcbLockThread) { \ 1052 ExAcquireFastMutex( &(F)->FcbNonpaged->FcbMutex ); \ 1053 NT_ASSERT( (F)->FcbLockCount == 0 ); \ 1054 _Analysis_assume_( (F)->FcbLockCount == 0 ); \ 1055 (F)->FcbLockThread = _CurrentThread; \ 1056 } \ 1057 else \ 1058 { \ 1059 _Analysis_assume_lock_held_( (F)->FcbNonpaged->FcbMutex ); \ 1060 _Analysis_assume_(FALSE != DummySaveIrql(&(F)->FcbNonpaged->FcbMutex)); \ 1061 } \ 1062 (F)->FcbLockCount += 1; \ 1063 } 1064 1065 #define CdUnlockFcb(IC,F) { \ 1066 (F)->FcbLockCount -= 1; \ 1067 if ((F)->FcbLockCount == 0) { \ 1068 (F)->FcbLockThread = NULL; \ 1069 ExReleaseFastMutex( &(F)->FcbNonpaged->FcbMutex ); \ 1070 } \ 1071 else \ 1072 { \ 1073 _Analysis_assume_lock_not_held_( (F)->FcbNonpaged->FcbMutex ); \ 1074 _Analysis_assume_(FALSE != DummyRestoreIrql(&(F)->FcbNonpaged->FcbMutex)); \ 1075 } \ 1076 } 1077 1078 // 1079 // The following macro is used to retrieve the oplock structure within 1080 // the Fcb. This structure was moved to the advanced Fcb header 1081 // in Win8. 1082 // 1083 1084 #if (NTDDI_VERSION >= NTDDI_WIN8) 1085 1086 #define CdGetFcbOplock(F) &(F)->Header.Oplock 1087 1088 #else 1089 1090 #define CdGetFcbOplock(F) &(F)->Oplock 1091 1092 #endif 1093 1094 BOOLEAN 1095 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ 1096 CdNoopAcquire ( 1097 _In_ PVOID Fcb, 1098 _In_ BOOLEAN Wait 1099 ); 1100 1101 VOID 1102 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ 1103 CdNoopRelease ( 1104 _In_ PVOID Fcb 1105 ); 1106 1107 _Requires_lock_held_(_Global_critical_region_) 1108 _When_(return!=0, _Acquires_shared_lock_(*Fcb->Resource)) 1109 BOOLEAN 1110 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ 1111 CdAcquireForCache ( 1112 _Inout_ PFCB Fcb, 1113 _In_ BOOLEAN Wait 1114 ); 1115 1116 _Requires_lock_held_(_Global_critical_region_) 1117 _Releases_lock_(*Fcb->Resource) 1118 VOID 1119 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ 1120 CdReleaseFromCache ( 1121 _Inout_ PFCB Fcb 1122 ); 1123 1124 _Requires_lock_held_(_Global_critical_region_) 1125 NTSTATUS 1126 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ 1127 CdFilterCallbackAcquireForCreateSection ( 1128 _In_ PFS_FILTER_CALLBACK_DATA CallbackData, 1129 _Unreferenced_parameter_ PVOID *CompletionContext 1130 ); 1131 1132 _Function_class_(FAST_IO_RELEASE_FILE) 1133 _Requires_lock_held_(_Global_critical_region_) 1134 VOID 1135 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ 1136 CdReleaseForCreateSection ( 1137 _In_ PFILE_OBJECT FileObject 1138 ); 1139 1140 1141 // 1142 // In-memory structure support routines. Implemented in StrucSup.c 1143 // 1144 1145 VOID 1146 CdInitializeVcb ( 1147 _In_ PIRP_CONTEXT IrpContext, 1148 _Inout_ PVCB Vcb, 1149 _In_ __drv_aliasesMem PDEVICE_OBJECT TargetDeviceObject, 1150 _In_ __drv_aliasesMem PVPB Vpb, 1151 _In_ __drv_aliasesMem PCDROM_TOC_LARGE CdromToc, 1152 _In_ ULONG TocLength, 1153 _In_ ULONG TocTrackCount, 1154 _In_ ULONG TocDiskFlags, 1155 _In_ ULONG BlockFactor, 1156 _In_ ULONG MediaChangeCount 1157 ); 1158 1159 VOID 1160 CdUpdateVcbFromVolDescriptor ( 1161 _In_ PIRP_CONTEXT IrpContext, 1162 _Inout_ PVCB Vcb, 1163 _In_reads_bytes_opt_(SECTOR_SIZE) PCHAR RawIsoVd 1164 ); 1165 1166 VOID 1167 CdDeleteVcb ( 1168 _In_ PIRP_CONTEXT IrpContext, 1169 _Inout_ PVCB Vcb 1170 ); 1171 1172 PFCB 1173 CdCreateFcb ( 1174 _In_ PIRP_CONTEXT IrpContext, 1175 _In_ FILE_ID FileId, 1176 _In_ NODE_TYPE_CODE NodeTypeCode, 1177 _Out_opt_ PBOOLEAN FcbExisted 1178 ); 1179 1180 VOID 1181 CdInitializeFcbFromPathEntry ( 1182 _In_ PIRP_CONTEXT IrpContext, 1183 _Inout_ PFCB Fcb, 1184 _In_opt_ PFCB ParentFcb, 1185 _In_ PPATH_ENTRY PathEntry 1186 ); 1187 1188 VOID 1189 CdInitializeFcbFromFileContext ( 1190 _In_ PIRP_CONTEXT IrpContext, 1191 _Inout_ PFCB Fcb, 1192 _In_ PFCB ParentFcb, 1193 _In_ PFILE_ENUM_CONTEXT FileContext 1194 ); 1195 1196 PCCB 1197 CdCreateCcb ( 1198 _In_ PIRP_CONTEXT IrpContext, 1199 _In_ PFCB Fcb, 1200 _In_ ULONG Flags 1201 ); 1202 1203 VOID 1204 CdDeleteCcb ( 1205 _In_ PIRP_CONTEXT IrpContext, 1206 _In_ __drv_freesMem( Pool ) PCCB Ccb 1207 ); 1208 1209 _When_(RaiseOnError || return, _At_(Fcb->FileLock, _Post_notnull_)) 1210 _When_(RaiseOnError, _At_(IrpContext, _Pre_notnull_)) 1211 BOOLEAN 1212 CdCreateFileLock ( 1213 _In_opt_ PIRP_CONTEXT IrpContext, 1214 _Inout_ PFCB Fcb, 1215 _In_ BOOLEAN RaiseOnError 1216 ); 1217 1218 VOID 1219 CdDeleteFileLock ( 1220 _In_ PIRP_CONTEXT IrpContext, 1221 _Inout_ PFILE_LOCK FileLock 1222 ); 1223 1224 _Ret_valid_ PIRP_CONTEXT 1225 CdCreateIrpContext ( 1226 _In_ PIRP Irp, 1227 _In_ BOOLEAN Wait 1228 ); 1229 1230 VOID 1231 CdCleanupIrpContext ( 1232 _In_ PIRP_CONTEXT IrpContext, 1233 _In_ BOOLEAN Post 1234 ); 1235 1236 VOID 1237 CdInitializeStackIrpContext ( 1238 _Out_ PIRP_CONTEXT IrpContext, 1239 _In_ PIRP_CONTEXT_LITE IrpContextLite 1240 ); 1241 1242 // 1243 // PIRP_CONTEXT_LITE 1244 // CdCreateIrpContextLite ( 1245 // _In_ PIRP_CONTEXT IrpContext 1246 // ); 1247 // 1248 // VOID 1249 // CdFreeIrpContextLite ( 1250 // _Inout_ PIRP_CONTEXT_LITE IrpContextLite 1251 // ); 1252 // 1253 1254 #define CdCreateIrpContextLite(IC) \ 1255 ExAllocatePoolWithTag( CdNonPagedPool, sizeof( IRP_CONTEXT_LITE ), TAG_IRP_CONTEXT_LITE ) 1256 1257 #define CdFreeIrpContextLite(ICL) \ 1258 CdFreePool( &(ICL) ) 1259 1260 _Requires_lock_held_(_Global_critical_region_) 1261 VOID 1262 CdTeardownStructures ( 1263 _In_ PIRP_CONTEXT IrpContext, 1264 _Inout_ PFCB StartingFcb, 1265 _Out_ PBOOLEAN RemovedStartingFcb 1266 ); 1267 1268 // 1269 // VOID 1270 // CdIncrementCleanupCounts ( 1271 // _In_ PIRP_CONTEXT IrpContext, 1272 // _Inout_ PFCB Fcb 1273 // ); 1274 // 1275 // VOID 1276 // CdDecrementCleanupCounts ( 1277 // _In_ PIRP_CONTEXT IrpContext, 1278 // _Inout_ PFCB Fcb 1279 // ); 1280 // 1281 // VOID 1282 // CdIncrementReferenceCounts ( 1283 // _In_ PIRP_CONTEXT IrpContext, 1284 // _Inout_ PFCB Fcb, 1285 // _In_ ULONG ReferenceCount 1286 // _In_ ULONG UserReferenceCount 1287 // ); 1288 // 1289 // VOID 1290 // CdDecrementReferenceCounts ( 1291 // _In_ PIRP_CONTEXT IrpContext, 1292 // _Inout_ PFCB Fcb, 1293 // _In_ ULONG ReferenceCount 1294 // _In_ ULONG UserReferenceCount 1295 // ); 1296 // 1297 // VOID 1298 // CdIncrementFcbReference ( 1299 // _In_ PIRP_CONTEXT IrpContext, 1300 // _Inout_ PFCB Fcb 1301 // ); 1302 // 1303 // VOID 1304 // CdDecrementFcbReference ( 1305 // _In_ PIRP_CONTEXT IrpContext, 1306 // _Inout_ PFCB Fcb 1307 // ); 1308 // 1309 1310 #define CdIncrementCleanupCounts(IC,F) { \ 1311 ASSERT_LOCKED_VCB( (F)->Vcb ); \ 1312 (F)->FcbCleanup += 1; \ 1313 (F)->Vcb->VcbCleanup += 1; \ 1314 } 1315 1316 #define CdDecrementCleanupCounts(IC,F) { \ 1317 ASSERT_LOCKED_VCB( (F)->Vcb ); \ 1318 (F)->FcbCleanup -= 1; \ 1319 (F)->Vcb->VcbCleanup -= 1; \ 1320 } 1321 1322 #define CdIncrementReferenceCounts(IC,F,C,UC) { \ 1323 ASSERT_LOCKED_VCB( (F)->Vcb ); \ 1324 (F)->FcbReference += (C); \ 1325 (F)->FcbUserReference += (UC); \ 1326 (F)->Vcb->VcbReference += (C); \ 1327 (F)->Vcb->VcbUserReference += (UC); \ 1328 } 1329 1330 #define CdDecrementReferenceCounts(IC,F,C,UC) { \ 1331 ASSERT_LOCKED_VCB( (F)->Vcb ); \ 1332 (F)->FcbReference -= (C); \ 1333 (F)->FcbUserReference -= (UC); \ 1334 (F)->Vcb->VcbReference -= (C); \ 1335 (F)->Vcb->VcbUserReference -= (UC); \ 1336 } 1337 1338 // 1339 // PCD_IO_CONTEXT 1340 // CdAllocateIoContext ( 1341 // ); 1342 // 1343 // VOID 1344 // CdFreeIoContext ( 1345 // PCD_IO_CONTEXT IoContext 1346 // ); 1347 // 1348 1349 #define CdAllocateIoContext() \ 1350 FsRtlAllocatePoolWithTag( CdNonPagedPool, \ 1351 sizeof( CD_IO_CONTEXT ), \ 1352 TAG_IO_CONTEXT ) 1353 1354 #define CdFreeIoContext(IO) CdFreePool( (PVOID) &(IO) ) /* ReactOS Change: GCC "passing argument 1 from incompatible pointer type" */ 1355 1356 PFCB 1357 CdLookupFcbTable ( 1358 _In_ PIRP_CONTEXT IrpContext, 1359 _In_ PVCB Vcb, 1360 _In_ FILE_ID FileId 1361 ); 1362 1363 PFCB 1364 CdGetNextFcb ( 1365 _In_ PIRP_CONTEXT IrpContext, 1366 _In_ PVCB Vcb, 1367 _In_ PVOID *RestartKey 1368 ); 1369 1370 NTSTATUS 1371 CdProcessToc ( 1372 _In_ PIRP_CONTEXT IrpContext, 1373 _In_ PDEVICE_OBJECT TargetDeviceObject, 1374 _In_ PCDROM_TOC_LARGE CdromToc, 1375 _Inout_ PULONG Length, 1376 _Out_ PULONG TrackCount, 1377 _Inout_ PULONG DiskFlags 1378 ); 1379 1380 // 1381 // For debugging purposes we sometimes want to allocate our structures from nonpaged 1382 // pool so that in the kernel debugger we can walk all the structures. 1383 // 1384 1385 #define CdPagedPool PagedPool 1386 #ifndef __REACTOS__ 1387 #define CdNonPagedPool NonPagedPoolNx 1388 #define CdNonPagedPoolCacheAligned NonPagedPoolNxCacheAligned 1389 #else 1390 #define CdNonPagedPool NonPagedPool 1391 #define CdNonPagedPoolCacheAligned NonPagedPoolCacheAligned 1392 #endif 1393 1394 1395 // 1396 // Verification support routines. Contained in verfysup.c 1397 // 1398 1399 static /* ReactOS Change: GCC "multiple definition" */ 1400 INLINE 1401 BOOLEAN 1402 CdOperationIsDasdOpen ( 1403 _In_ PIRP_CONTEXT IrpContext 1404 ) 1405 { 1406 PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( IrpContext->Irp); 1407 1408 return ((IrpContext->MajorFunction == IRP_MJ_CREATE) && 1409 (IrpSp->FileObject->FileName.Length == 0) && 1410 (IrpSp->FileObject->RelatedFileObject == NULL)); 1411 } 1412 1413 _Requires_lock_held_(_Global_critical_region_) 1414 NTSTATUS 1415 CdPerformVerify ( 1416 _Inout_ PIRP_CONTEXT IrpContext, 1417 _Inout_ PIRP Irp, 1418 _In_ PDEVICE_OBJECT DeviceToVerify 1419 ); 1420 1421 _Requires_lock_held_(_Global_critical_region_) 1422 BOOLEAN 1423 CdCheckForDismount ( 1424 _In_ PIRP_CONTEXT IrpContext, 1425 _Inout_ PVCB Vcb, 1426 _In_ BOOLEAN Force 1427 ); 1428 1429 BOOLEAN 1430 CdMarkDevForVerifyIfVcbMounted ( 1431 _Inout_ PVCB Vcb 1432 ); 1433 1434 VOID 1435 CdVerifyVcb ( 1436 _In_ PIRP_CONTEXT IrpContext, 1437 _Inout_ PVCB Vcb 1438 ); 1439 1440 BOOLEAN 1441 CdVerifyFcbOperation ( 1442 _In_opt_ PIRP_CONTEXT IrpContext, 1443 _In_ PFCB Fcb 1444 ); 1445 1446 _Requires_lock_held_(_Global_critical_region_) 1447 BOOLEAN 1448 CdDismountVcb ( 1449 _In_ PIRP_CONTEXT IrpContext, 1450 _Inout_ PVCB Vcb 1451 ); 1452 1453 1454 // 1455 // Macros to abstract device verify flag changes. 1456 // 1457 1458 #define CdUpdateMediaChangeCount( V, C) (V)->MediaChangeCount = (C) 1459 #define CdUpdateVcbCondition( V, C) (V)->VcbCondition = (C) 1460 1461 #define CdMarkRealDevForVerify( DO) SetFlag( (DO)->Flags, DO_VERIFY_VOLUME) 1462 1463 #define CdMarkRealDevVerifyOk( DO) ClearFlag( (DO)->Flags, DO_VERIFY_VOLUME) 1464 1465 1466 #define CdRealDevNeedsVerify( DO) BooleanFlagOn( (DO)->Flags, DO_VERIFY_VOLUME) 1467 1468 // 1469 // BOOLEAN 1470 // CdIsRawDevice ( 1471 // _In_ PIRP_CONTEXT IrpContext, 1472 // _In_ NTSTATUS Status 1473 // ); 1474 // 1475 1476 #define CdIsRawDevice(IC,S) ( \ 1477 ((S) == STATUS_DEVICE_NOT_READY) || \ 1478 ((S) == STATUS_NO_MEDIA_IN_DEVICE) \ 1479 ) 1480 1481 1482 // 1483 // Work queue routines for posting and retrieving an Irp, implemented in 1484 // workque.c 1485 // 1486 1487 _Requires_lock_held_(_Global_critical_region_) 1488 NTSTATUS 1489 CdFsdPostRequest ( 1490 _Inout_ PIRP_CONTEXT IrpContext, 1491 _Inout_ PIRP Irp 1492 ); 1493 1494 _Requires_lock_held_(_Global_critical_region_) 1495 VOID 1496 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ 1497 CdPrePostIrp ( 1498 _Inout_ PIRP_CONTEXT IrpContext, 1499 _Inout_ PIRP Irp 1500 ); 1501 1502 _Requires_lock_held_(_Global_critical_region_) 1503 VOID 1504 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ 1505 CdOplockComplete ( 1506 _Inout_ PIRP_CONTEXT IrpContext, 1507 _Inout_ PIRP Irp 1508 ); 1509 1510 1511 // 1512 // Miscellaneous support routines 1513 // 1514 1515 // 1516 // This macro returns TRUE if a flag in a set of flags is on and FALSE 1517 // otherwise 1518 // 1519 1520 /* GCC complains about multi-line comments. 1521 //#ifndef BooleanFlagOn 1522 //#define BooleanFlagOn(F,SF) ( \ 1523 // (BOOLEAN)(((F) & (SF)) != 0) \ 1524 //) 1525 //#endif 1526 1527 //#ifndef SetFlag 1528 //#define SetFlag(Flags,SingleFlag) { \ 1529 // (Flags) |= (SingleFlag); \ 1530 //} 1531 //#endif 1532 1533 //#ifndef ClearFlag 1534 //#define ClearFlag(Flags,SingleFlag) { \ 1535 // (Flags) &= ~(SingleFlag); \ 1536 //} 1537 //#endif 1538 */ 1539 1540 // 1541 // CAST 1542 // Add2Ptr ( 1543 // _In_ PVOID Pointer, 1544 // _In_ ULONG Increment 1545 // _In_ (CAST) 1546 // ); 1547 // 1548 // ULONG 1549 // PtrOffset ( 1550 // _In_ PVOID BasePtr, 1551 // _In_ PVOID OffsetPtr 1552 // ); 1553 // 1554 1555 #define Add2Ptr(PTR,INC,CAST) ((CAST)((PUCHAR)(PTR) + (INC))) 1556 1557 #define PtrOffset(BASE,OFFSET) ((ULONG)((ULONG_PTR)(OFFSET) - (ULONG_PTR)(BASE))) 1558 1559 // 1560 // This macro takes a pointer (or ulong) and returns its rounded up word 1561 // value 1562 // 1563 1564 #define WordAlign(Ptr) ( \ 1565 ((((ULONG)(Ptr)) + 1) & 0xfffffffe) \ 1566 ) 1567 1568 // 1569 // This macro takes a pointer (or ulong) and returns its rounded up longword 1570 // value 1571 // 1572 1573 #define LongAlign(Ptr) ( \ 1574 ((((ULONG)(Ptr)) + 3) & 0xfffffffc) \ 1575 ) 1576 1577 // 1578 // This macro takes a pointer (or ulong) and returns its rounded up quadword 1579 // value 1580 // 1581 1582 #define QuadAlign(Ptr) ( \ 1583 ((((ULONG)(Ptr)) + 7) & 0xfffffff8) \ 1584 ) 1585 1586 // 1587 // The following macros round up and down to sector boundaries. 1588 // 1589 1590 #define SectorAlign(L) ( \ 1591 ((((ULONG)(L)) + (SECTOR_SIZE - 1)) & ~(SECTOR_SIZE - 1)) \ 1592 ) 1593 1594 #define LlSectorAlign(L) ( \ 1595 ((((LONGLONG)(L)) + (SECTOR_SIZE - 1)) & ~(SECTOR_SIZE - 1)) \ 1596 ) 1597 1598 #define SectorTruncate(L) ( \ 1599 ((ULONG)(L)) & ~(SECTOR_SIZE - 1) \ 1600 ) 1601 1602 #define LlSectorTruncate(L) ( \ 1603 ((LONGLONG)(L)) & ~(SECTOR_SIZE - 1) \ 1604 ) 1605 1606 #define BytesFromSectors(L) ( \ 1607 ((ULONG) (L)) << SECTOR_SHIFT \ 1608 ) 1609 1610 #define SectorsFromBytes(L) ( \ 1611 ((ULONG) (L)) >> SECTOR_SHIFT \ 1612 ) 1613 1614 static /* ReactOS Change: GCC "multiple definition" */ 1615 INLINE 1616 ULONG 1617 SectorsFromLlBytes( 1618 ULONGLONG Bytes 1619 ) { 1620 1621 return (ULONG)(Bytes >> SECTOR_SHIFT); 1622 } 1623 1624 #define LlBytesFromSectors(L) ( \ 1625 Int64ShllMod32( (LONGLONG)(L), SECTOR_SHIFT ) \ 1626 ) 1627 1628 #define LlSectorsFromBytes(L) ( \ 1629 Int64ShraMod32( (LONGLONG)(L), SECTOR_SHIFT ) \ 1630 ) 1631 1632 #define SectorOffset(L) ( \ 1633 ((ULONG)(ULONG_PTR) (L)) & SECTOR_MASK \ 1634 ) 1635 1636 #define SectorBlockOffset(V,LB) ( \ 1637 ((ULONG) (LB)) & ((V)->BlocksPerSector - 1) \ 1638 ) 1639 1640 #define BytesFromBlocks(V,B) ( \ 1641 (ULONG) (B) << (V)->BlockToByteShift \ 1642 ) 1643 1644 #define LlBytesFromBlocks(V,B) ( \ 1645 Int64ShllMod32( (LONGLONG) (B), (V)->BlockToByteShift ) \ 1646 ) 1647 1648 #define BlockAlign(V,L) ( \ 1649 ((ULONG)(L) + (V)->BlockMask) & (V)->BlockInverseMask \ 1650 ) 1651 1652 // 1653 // Carefully make sure the mask is sign extended to 64bits 1654 // 1655 1656 #define LlBlockAlign(V,L) ( \ 1657 ((LONGLONG)(L) + (V)->BlockMask) & (LONGLONG)((LONG)(V)->BlockInverseMask) \ 1658 ) 1659 1660 #define BlockOffset(V,L) ( \ 1661 ((ULONG) (L)) & (V)->BlockMask \ 1662 ) 1663 1664 #define RawSectorAlign( B) ((((B)+(RAW_SECTOR_SIZE - 1)) / RAW_SECTOR_SIZE) * RAW_SECTOR_SIZE) 1665 1666 // 1667 // The following types and macros are used to help unpack the packed and 1668 // misaligned fields found in the Bios parameter block 1669 // 1670 1671 typedef union _UCHAR1 { 1672 UCHAR Uchar[1]; 1673 UCHAR ForceAlignment; 1674 } UCHAR1, *PUCHAR1; 1675 1676 typedef union _UCHAR2 { 1677 UCHAR Uchar[2]; 1678 USHORT ForceAlignment; 1679 } UCHAR2, *PUCHAR2; 1680 1681 typedef union _UCHAR4 { 1682 UCHAR Uchar[4]; 1683 ULONG ForceAlignment; 1684 } UCHAR4, *PUCHAR4; 1685 1686 typedef union _USHORT2 { 1687 USHORT Ushort[2]; 1688 ULONG ForceAlignment; 1689 } USHORT2, *PUSHORT2; 1690 1691 // 1692 // This macro copies an unaligned src byte to an aligned dst byte 1693 // 1694 1695 #define CopyUchar1(Dst,Src) { \ 1696 *((UCHAR1 *)(Dst)) = *((UNALIGNED UCHAR1 *)(Src)); \ 1697 } 1698 1699 // 1700 // This macro copies an unaligned src word to an aligned dst word 1701 // 1702 1703 #define CopyUchar2(Dst,Src) { \ 1704 *((UCHAR2 *)(Dst)) = *((UNALIGNED UCHAR2 *)(Src)); \ 1705 } 1706 1707 // 1708 // This macro copies an unaligned src longword to an aligned dsr longword 1709 // 1710 1711 #define CopyUchar4(Dst,Src) { \ 1712 *((UCHAR4 *)(Dst)) = *((UNALIGNED UCHAR4 *)(Src)); \ 1713 } 1714 1715 // 1716 // This macro copies an unaligned src longword to an aligned dsr longword 1717 // accessing the source on a word boundary. 1718 // 1719 1720 #define CopyUshort2(Dst,Src) { \ 1721 *((USHORT2 *)(Dst)) = *((UNALIGNED USHORT2 *)(Src));\ 1722 } 1723 1724 // 1725 // This macro copies an unaligned src longword to a dst longword, 1726 // performing an little/big endian swap. 1727 // 1728 1729 #define SwapCopyUchar4(Dst,Src) { \ 1730 *((UNALIGNED UCHAR1 *)(Dst)) = *((UNALIGNED UCHAR1 *)(Src) + 3); \ 1731 *((UNALIGNED UCHAR1 *)(Dst) + 1) = *((UNALIGNED UCHAR1 *)(Src) + 2); \ 1732 *((UNALIGNED UCHAR1 *)(Dst) + 2) = *((UNALIGNED UCHAR1 *)(Src) + 1); \ 1733 *((UNALIGNED UCHAR1 *)(Dst) + 3) = *((UNALIGNED UCHAR1 *)(Src)); \ 1734 } 1735 1736 VOID 1737 CdLbnToMmSsFf ( 1738 _In_ ULONG Blocks, 1739 _Out_writes_(3) PUCHAR Msf 1740 ); 1741 1742 // 1743 // Following routines handle entry in and out of the filesystem. They are 1744 // contained in CdData.c 1745 // 1746 1747 _IRQL_requires_max_(APC_LEVEL) 1748 __drv_dispatchType(DRIVER_DISPATCH) 1749 __drv_dispatchType(IRP_MJ_CREATE) 1750 __drv_dispatchType(IRP_MJ_CLOSE) 1751 __drv_dispatchType(IRP_MJ_READ) 1752 __drv_dispatchType(IRP_MJ_WRITE) 1753 __drv_dispatchType(IRP_MJ_QUERY_INFORMATION) 1754 __drv_dispatchType(IRP_MJ_SET_INFORMATION) 1755 __drv_dispatchType(IRP_MJ_QUERY_VOLUME_INFORMATION) 1756 __drv_dispatchType(IRP_MJ_DIRECTORY_CONTROL) 1757 __drv_dispatchType(IRP_MJ_FILE_SYSTEM_CONTROL) 1758 __drv_dispatchType(IRP_MJ_DEVICE_CONTROL) 1759 __drv_dispatchType(IRP_MJ_LOCK_CONTROL) 1760 __drv_dispatchType(IRP_MJ_CLEANUP) 1761 __drv_dispatchType(IRP_MJ_PNP) 1762 __drv_dispatchType(IRP_MJ_SHUTDOWN) 1763 NTSTATUS 1764 NTAPI 1765 CdFsdDispatch ( 1766 _In_ PDEVICE_OBJECT DeviceObject, 1767 _Inout_ PIRP Irp 1768 ); 1769 1770 // DRIVER_DISPATCH CdFsdDispatch; 1771 1772 LONG 1773 CdExceptionFilter ( 1774 _Inout_ PIRP_CONTEXT IrpContext, 1775 _In_ PEXCEPTION_POINTERS ExceptionPointer 1776 ); 1777 1778 _Requires_lock_held_(_Global_critical_region_) 1779 NTSTATUS 1780 CdProcessException ( 1781 _In_opt_ PIRP_CONTEXT IrpContext, 1782 _Inout_ PIRP Irp, 1783 _In_ NTSTATUS ExceptionCode 1784 ); 1785 1786 VOID 1787 CdCompleteRequest ( 1788 _Inout_opt_ PIRP_CONTEXT IrpContext, 1789 _Inout_opt_ PIRP Irp, 1790 _In_ NTSTATUS Status 1791 ); 1792 1793 // 1794 // VOID 1795 // CdRaiseStatus ( 1796 // _In_ PRIP_CONTEXT IrpContext, 1797 // _In_ NT_STATUS Status 1798 // ); 1799 // 1800 // VOID 1801 // CdNormalizeAndRaiseStatus ( 1802 // _In_ PRIP_CONTEXT IrpContext, 1803 // _In_ NT_STATUS Status 1804 // ); 1805 // 1806 1807 #if 0 1808 #define AssertVerifyDevice(C, S) \ 1809 NT_ASSERT( (C) == NULL || \ 1810 FlagOn( (C)->Flags, IRP_CONTEXT_FLAG_IN_FSP ) || \ 1811 !((S) == STATUS_VERIFY_REQUIRED && \ 1812 IoGetDeviceToVerify( PsGetCurrentThread() ) == NULL )); 1813 1814 #define AssertVerifyDeviceIrp(I) \ 1815 NT_ASSERT( (I) == NULL || \ 1816 !(((I)->IoStatus.Status) == STATUS_VERIFY_REQUIRED && \ 1817 ((I)->Tail.Overlay.Thread == NULL || \ 1818 IoGetDeviceToVerify( (I)->Tail.Overlay.Thread ) == NULL ))); 1819 #else 1820 #define AssertVerifyDevice(C, S) 1821 #define AssertVerifyDeviceIrp(I) 1822 #endif 1823 1824 1825 #ifdef CD_SANITY 1826 1827 DECLSPEC_NORETURN 1828 VOID 1829 CdRaiseStatusEx ( 1830 _In_ PIRP_CONTEXT IrpContext, 1831 _In_ NTSTATUS Status, 1832 _In_ BOOLEAN NormalizeStatus, 1833 _In_opt_ ULONG FileId, 1834 _In_opt_ ULONG Line 1835 ); 1836 1837 #else 1838 1839 INLINE 1840 DECLSPEC_NORETURN 1841 VOID 1842 CdRaiseStatusEx( 1843 _In_ PIRP_CONTEXT IrpContext, 1844 _In_ NTSTATUS Status, 1845 _In_ BOOLEAN NormalizeStatus, 1846 _In_ ULONG Fileid, 1847 _In_ ULONG Line 1848 ) 1849 { 1850 if (NormalizeStatus) { 1851 1852 IrpContext->ExceptionStatus = FsRtlNormalizeNtstatus( Status, STATUS_UNEXPECTED_IO_ERROR); 1853 } 1854 else { 1855 1856 IrpContext->ExceptionStatus = Status; 1857 } 1858 1859 IrpContext->RaisedAtLineFile = (Fileid << 16) | Line; 1860 1861 ExRaiseStatus( IrpContext->ExceptionStatus ); 1862 } 1863 1864 #endif 1865 1866 #define CdRaiseStatus( IC, S) CdRaiseStatusEx( (IC), (S), FALSE, BugCheckFileId, __LINE__); 1867 #define CdNormalizeAndRaiseStatus( IC, S) CdRaiseStatusEx( (IC), (S), TRUE, BugCheckFileId, __LINE__); 1868 1869 // 1870 // Following are the fast entry points. 1871 // 1872 1873 // _Success_(return != FALSE) 1874 // BOOLEAN 1875 // CdFastQueryBasicInfo ( 1876 // _In_ PFILE_OBJECT FileObject, 1877 // _In_ BOOLEAN Wait, 1878 // _Out_ PFILE_BASIC_INFORMATION Buffer, 1879 // _Out_ PIO_STATUS_BLOCK IoStatus, 1880 // _In_ PDEVICE_OBJECT DeviceObject 1881 // ); 1882 1883 FAST_IO_QUERY_BASIC_INFO CdFastQueryBasicInfo; 1884 1885 // _Success_(return != FALSE) 1886 // BOOLEAN 1887 // CdFastQueryStdInfo ( 1888 // _In_ PFILE_OBJECT FileObject, 1889 // _In_ BOOLEAN Wait, 1890 // _Out_ PFILE_STANDARD_INFORMATION Buffer, 1891 // _Out_ PIO_STATUS_BLOCK IoStatus, 1892 // _In_ PDEVICE_OBJECT DeviceObject 1893 // ); 1894 1895 FAST_IO_QUERY_STANDARD_INFO CdFastQueryStdInfo; 1896 1897 // BOOLEAN 1898 // CdFastLock ( 1899 // _In_ PFILE_OBJECT FileObject, 1900 // _In_ PLARGE_INTEGER FileOffset, 1901 // _In_ PLARGE_INTEGER Length, 1902 // _In_ PEPROCESS ProcessId, 1903 // _In_ ULONG Key, 1904 // _In_ BOOLEAN FailImmediately, 1905 // _In_ BOOLEAN ExclusiveLock, 1906 // _Out_ PIO_STATUS_BLOCK IoStatus, 1907 // _In_ PDEVICE_OBJECT DeviceObject 1908 // ); 1909 1910 FAST_IO_LOCK CdFastLock; 1911 1912 // BOOLEAN 1913 // CdFastUnlockSingle ( 1914 // _In_ PFILE_OBJECT FileObject, 1915 // _In_ PLARGE_INTEGER FileOffset, 1916 // _In_ PLARGE_INTEGER Length, 1917 // _In_ PEPROCESS ProcessId, 1918 // _In_ ULONG Key, 1919 // _Out_ PIO_STATUS_BLOCK IoStatus, 1920 // _In_ PDEVICE_OBJECT DeviceObject 1921 // ); 1922 1923 FAST_IO_UNLOCK_SINGLE CdFastUnlockSingle; 1924 1925 // BOOLEAN 1926 // CdFastUnlockAll ( 1927 // _In_ PFILE_OBJECT FileObject, 1928 // _In_ PEPROCESS ProcessId, 1929 // _Out_ PIO_STATUS_BLOCK IoStatus, 1930 // _In_ PDEVICE_OBJECT DeviceObject 1931 // ); 1932 1933 FAST_IO_UNLOCK_ALL CdFastUnlockAll; 1934 1935 // BOOLEAN 1936 // CdFastUnlockAllByKey ( 1937 // _In_ PFILE_OBJECT FileObject, 1938 // _In_ PVOID ProcessId, 1939 // _In_ ULONG Key, 1940 // _Out_ PIO_STATUS_BLOCK IoStatus, 1941 // _In_ PDEVICE_OBJECT DeviceObject 1942 // ); 1943 1944 FAST_IO_UNLOCK_ALL_BY_KEY CdFastUnlockAllByKey; 1945 1946 // BOOLEAN 1947 // CdFastIoCheckIfPossible ( 1948 // _In_ PFILE_OBJECT FileObject, 1949 // _In_ PLARGE_INTEGER FileOffset, 1950 // _In_ ULONG Length, 1951 // _In_ BOOLEAN Wait, 1952 // _In_ ULONG LockKey, 1953 // _In_ BOOLEAN CheckForReadOperation, 1954 // _Out_ PIO_STATUS_BLOCK IoStatus, 1955 // _In_ PDEVICE_OBJECT DeviceObject 1956 // ); 1957 1958 FAST_IO_CHECK_IF_POSSIBLE CdFastIoCheckIfPossible; 1959 1960 // _Success_(return != FALSE) 1961 // BOOLEAN 1962 // CdFastQueryNetworkInfo ( 1963 // _In_ PFILE_OBJECT FileObject, 1964 // _In_ BOOLEAN Wait, 1965 // _Out_ PFILE_NETWORK_OPEN_INFORMATION Buffer, 1966 // _Out_ PIO_STATUS_BLOCK IoStatus, 1967 // _In_ PDEVICE_OBJECT DeviceObject 1968 // ); 1969 1970 FAST_IO_QUERY_NETWORK_OPEN_INFO CdFastQueryNetworkInfo; 1971 1972 // 1973 // Following are the routines to handle the top level thread logic. 1974 // 1975 1976 VOID 1977 CdSetThreadContext ( 1978 _Inout_ PIRP_CONTEXT IrpContext, 1979 _In_ PTHREAD_CONTEXT ThreadContext 1980 ); 1981 1982 1983 // 1984 // VOID 1985 // CdRestoreThreadContext ( 1986 // _Inout_ PIRP_CONTEXT IrpContext 1987 // ); 1988 // 1989 1990 #define CdRestoreThreadContext(IC) \ 1991 (IC)->ThreadContext->Cdfs = 0; \ 1992 IoSetTopLevelIrp( (IC)->ThreadContext->SavedTopLevelIrp ); \ 1993 (IC)->ThreadContext = NULL 1994 1995 ULONG 1996 CdSerial32 ( 1997 _In_reads_bytes_(ByteCount) PCHAR Buffer, 1998 _In_ ULONG ByteCount 1999 ); 2000 2001 // 2002 // The following macro is used to determine if an FSD thread can block 2003 // for I/O or wait for a resource. It returns TRUE if the thread can 2004 // block and FALSE otherwise. This attribute can then be used to call 2005 // the FSD & FSP common work routine with the proper wait value. 2006 // 2007 2008 #define CanFsdWait(I) IoIsOperationSynchronous(I) 2009 2010 // 2011 // The following macro is used to set the fast i/o possible bits in the 2012 // FsRtl header. 2013 // 2014 // FastIoIsNotPossible - If the Fcb is bad or there are oplocks on the file. 2015 // 2016 // FastIoIsQuestionable - If there are file locks. 2017 // 2018 // FastIoIsPossible - In all other cases. 2019 // 2020 // 2021 2022 #define CdIsFastIoPossible(F) ((BOOLEAN) \ 2023 ((((F)->Vcb->VcbCondition != VcbMounted ) || \ 2024 !FsRtlOplockIsFastIoPossible( CdGetFcbOplock(F) )) ? \ 2025 \ 2026 FastIoIsNotPossible : \ 2027 \ 2028 ((((F)->FileLock != NULL) && FsRtlAreThereCurrentFileLocks( (F)->FileLock )) ? \ 2029 \ 2030 FastIoIsQuestionable : \ 2031 \ 2032 FastIoIsPossible)) \ 2033 ) 2034 2035 2036 // 2037 // The FSP level dispatch/main routine. This is the routine that takes 2038 // IRP's off of the work queue and calls the appropriate FSP level 2039 // work routine. 2040 // 2041 2042 // VOID 2043 // CdFspDispatch ( // implemented in FspDisp.c 2044 // _Inout_ PIRP_CONTEXT IrpContext 2045 // ); 2046 2047 WORKER_THREAD_ROUTINE CdFspDispatch; 2048 2049 VOID 2050 CdFspClose ( // implemented in Close.c 2051 _In_opt_ PVCB Vcb 2052 ); 2053 2054 // 2055 // The following routines are the entry points for the different operations 2056 // based on the IrpSp major functions. 2057 // 2058 2059 _Requires_lock_held_(_Global_critical_region_) 2060 NTSTATUS 2061 CdCommonCreate ( // Implemented in Create.c 2062 _Inout_ PIRP_CONTEXT IrpContext, 2063 _Inout_ PIRP Irp 2064 ); 2065 2066 _Requires_lock_held_(_Global_critical_region_) 2067 NTSTATUS 2068 CdCommonClose ( // Implemented in Close.c 2069 _Inout_ PIRP_CONTEXT IrpContext, 2070 _Inout_ PIRP Irp 2071 ); 2072 2073 _Requires_lock_held_(_Global_critical_region_) 2074 NTSTATUS 2075 CdCommonRead ( // Implemented in Read.c 2076 _Inout_ PIRP_CONTEXT IrpContext, 2077 _Inout_ PIRP Irp 2078 ); 2079 2080 _Requires_lock_held_(_Global_critical_region_) 2081 NTSTATUS 2082 CdCommonWrite ( // Implemented in Write.c 2083 _Inout_ PIRP_CONTEXT IrpContext, 2084 _Inout_ PIRP Irp 2085 ); 2086 2087 _Requires_lock_held_(_Global_critical_region_) 2088 NTSTATUS 2089 CdCommonQueryInfo ( // Implemented in FileInfo.c 2090 _Inout_ PIRP_CONTEXT IrpContext, 2091 _Inout_ PIRP Irp 2092 ); 2093 2094 _Requires_lock_held_(_Global_critical_region_) 2095 NTSTATUS 2096 CdCommonSetInfo ( // Implemented in FileInfo.c 2097 _Inout_ PIRP_CONTEXT IrpContext, 2098 _Inout_ PIRP Irp 2099 ); 2100 2101 _Requires_lock_held_(_Global_critical_region_) 2102 NTSTATUS 2103 CdCommonQueryVolInfo ( // Implemented in VolInfo.c 2104 _Inout_ PIRP_CONTEXT IrpContext, 2105 _Inout_ PIRP Irp 2106 ); 2107 2108 _Requires_lock_held_(_Global_critical_region_) 2109 NTSTATUS 2110 CdCommonDirControl ( // Implemented in DirCtrl.c 2111 _Inout_ PIRP_CONTEXT IrpContext, 2112 _Inout_ PIRP Irp 2113 ); 2114 2115 _Requires_lock_held_(_Global_critical_region_) 2116 NTSTATUS 2117 CdCommonFsControl ( // Implemented in FsCtrl.c 2118 _Inout_ PIRP_CONTEXT IrpContext, 2119 _Inout_ PIRP Irp 2120 ); 2121 2122 NTSTATUS 2123 CdCommonDevControl ( // Implemented in DevCtrl.c 2124 _Inout_ PIRP_CONTEXT IrpContext, 2125 _Inout_ PIRP Irp 2126 ); 2127 2128 NTSTATUS 2129 CdCommonLockControl ( // Implemented in LockCtrl.c 2130 _Inout_ PIRP_CONTEXT IrpContext, 2131 _Inout_ PIRP Irp 2132 ); 2133 2134 _Requires_lock_held_(_Global_critical_region_) 2135 NTSTATUS 2136 CdCommonCleanup ( // Implemented in Cleanup.c 2137 _Inout_ PIRP_CONTEXT IrpContext, 2138 _Inout_ PIRP Irp 2139 ); 2140 2141 _Requires_lock_held_(_Global_critical_region_) 2142 NTSTATUS 2143 CdCommonPnp ( // Implemented in Pnp.c 2144 _Inout_ PIRP_CONTEXT IrpContext, 2145 _Inout_ PIRP Irp 2146 ); 2147 2148 _Requires_lock_held_(_Global_critical_region_) 2149 NTSTATUS 2150 CdCommonShutdown ( // Implemented in Shutdown.c 2151 _Inout_ PIRP_CONTEXT IrpContext, 2152 _Inout_ PIRP Irp 2153 ); 2154 2155 2156 2157 // 2158 // The following macros are used to establish the semantics needed 2159 // to do a return from within a try-finally clause. As a rule every 2160 // try clause must end with a label call try_exit. For example, 2161 // 2162 // try { 2163 // : 2164 // : 2165 // 2166 // try_exit: NOTHING; 2167 // } finally { 2168 // 2169 // : 2170 // : 2171 // } 2172 // 2173 // Every return statement executed inside of a try clause should use the 2174 // try_return macro. If the compiler fully supports the try-finally construct 2175 // then the macro should be 2176 // 2177 // #define try_return(S) { return(S); } 2178 // 2179 // If the compiler does not support the try-finally construct then the macro 2180 // should be 2181 // 2182 // #define try_return(S) { S; goto try_exit; } 2183 // 2184 2185 #ifndef __REACTOS__ 2186 #define try_return(S) { S; goto try_exit; } 2187 #define try_leave(S) { S; leave; } 2188 #else 2189 #define try_return(S) { S; goto try_exit; } 2190 #define try_leave(S) { S; _SEH2_LEAVE; } 2191 #endif 2192 2193 // 2194 // Encapsulate safe pool freeing 2195 // 2196 /* ReactOS Change: GCC "passing argument 1 of CdFreePool from incompatible pointer type" */ 2197 #define CdFreePool(x) _CdFreePool((PVOID*)(x)) 2198 2199 static /* ReactOS Change: GCC "multiple definition" */ 2200 INLINE 2201 VOID 2202 _CdFreePool( 2203 _Inout_ _At_(*Pool, __drv_freesMem(Mem) _Post_null_) PVOID *Pool 2204 ) 2205 { 2206 if (*Pool != NULL) { 2207 2208 ExFreePool(*Pool); 2209 *Pool = NULL; 2210 } 2211 } 2212 2213 #ifdef CDFS_TELEMETRY_DATA 2214 2215 // 2216 // CDFS Telemetry. Current implementation uses the Telemetry TraceLogging APIs. 2217 // 2218 // The Telemetry TraceLoggingWrite() routines use a lot of stack space. We must 2219 // therefor wrap all our telemetry points with our own routines, and add a guard to 2220 // make sure there's enough stack space to call these routines. 2221 // 2222 // These telemetry routines should not be called on high-performance code paths. 2223 // 2224 2225 TRACELOGGING_DECLARE_PROVIDER( CdTelemetryProvider ); 2226 2227 VOID 2228 CdInitializeTelemetry ( 2229 VOID 2230 ); 2231 2232 DECLSPEC_NOINLINE 2233 VOID 2234 CdTelemetryMount ( 2235 __in PGUID VolumeGuid, 2236 __in NTSTATUS Status, 2237 __in PVCB Vcb 2238 ); 2239 2240 // 2241 // Every additional argument passed to TraceLoggingWrite() consumes an additional 2242 // 16 to 32 bytes extra stack space. Having 512 bytes reserved space should be 2243 // sufficient for up to 20 arguments or so. This will be less of course if our 2244 // wrapper routines also declare their own local variables. 2245 // 2246 2247 #define CDFS_TELEMETRY_STACK_THRESHOLD_DEFAULT 512 // for "small" telemetry points 2248 #define CDFS_TELEMETRY_STACK_THRESHOLD_LARGE 2048 // for "large" telemetry points 2249 2250 INLINE 2251 BOOLEAN 2252 CdTelemetryGuard ( 2253 __in ULONG StackSpaceNeeded ) 2254 /*++ 2255 2256 Routine Description: 2257 2258 This routine returns TRUE only when: 2259 2260 1) There is an ETW listener, AND 2261 2) There is enough free stack space to safely call the Telemetry TraceLogging APIs 2262 2263 We'll also count how many times there wasn't enough stack space, and include this 2264 value as part of the periodic cdfs Telemetry. 2265 2266 Arguments: 2267 2268 StackSpaceNeeded - Stack space needed in bytes 2269 2270 --*/ 2271 { 2272 ASSERT( IoGetRemainingStackSize() >= StackSpaceNeeded ); 2273 2274 if (CdTelemetryProvider->LevelPlus1 <= 5) { 2275 2276 // 2277 // Bail out early if there are no ETW listeners 2278 // 2279 2280 return FALSE; 2281 } 2282 2283 if (IoGetRemainingStackSize() < StackSpaceNeeded) { 2284 2285 // 2286 // Count how many times it was unsafe to generate telemetry because of 2287 // not enough stack space. 2288 // 2289 2290 InterlockedIncrement( &CdTelemetryData.MissedTelemetryPoints ); 2291 2292 return FALSE; 2293 } 2294 2295 return TRUE; 2296 } 2297 2298 #define CdTelemetryMountSafe( VolumeGuid, Status, Vcb ) \ 2299 if (CdTelemetryGuard( CDFS_TELEMETRY_STACK_THRESHOLD_LARGE )) { \ 2300 CdTelemetryMount( VolumeGuid, Status, Vcb ); \ 2301 } 2302 2303 #if DBG 2304 #define CDFS_TELEMETRY_PERIODIC_INTERVAL CdTelemetryData.PeriodicInterval 2305 #else 2306 #define CDFS_TELEMETRY_PERIODIC_INTERVAL INTERVAL_ONE_DAY 2307 #endif 2308 2309 #else // CDFS_TELEMETRY_DATA 2310 2311 // 2312 // When CDFS_TELEMETRY_DATA is not defined then the CdTelemetry___Safe() routines 2313 // expand to nothing. This minimizes the cdfs.sys binary footprint. This also 2314 // means that the places where these Safe() routines are called do not 2315 // have to have to be surrounded by #ifdef CDFS_TELEMETRY_DATA .. #endif 2316 // 2317 2318 2319 #define CdTelemetryMountSafe( ... ) NOTHING 2320 2321 #endif // CDFS_TELEMETRY_DATA 2322 2323 #endif // _CDPROCS_ 2324 2325 2326