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