From aff67aa676dad6bebabdcfc5b3ea656adb34a118 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 1 May 2026 05:07:34 +0000 Subject: [PATCH 01/86] Initial plan From 8556073fec34c562dda5fabfc9b848c6374f043e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 1 May 2026 05:23:04 +0000 Subject: [PATCH 02/86] Apply all open UDFS PRs: #62, #108, #193, #216, #218, #269, #277, #283, #302, #304, #306, #308, #310, #316, #335, #339 Agent-Logs-Url: https://github.com/Zero3K20/reactos/sessions/c135164e-e9f3-4164-ba64-d04f8a2dd19a Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/CMakeLists.txt | 74 +-- .../{Sys_spec_lib.cpp => Sys_spec_lib.c} | 12 +- .../filesystems/udfs/Include/Sys_spec_lib.h | 2 +- .../Include/{mem_tools.cpp => mem_tools.c} | 73 +-- drivers/filesystems/udfs/Include/mem_tools.h | 8 +- .../udfs/Include/{phys_lib.cpp => phys_lib.c} | 52 +- drivers/filesystems/udfs/Include/phys_lib.h | 4 +- .../udfs/Include/{regtools.cpp => regtools.c} | 10 +- .../Include/{string_lib.cpp => string_lib.c} | 59 +- drivers/filesystems/udfs/Include/udf_reg.h | 1 + .../udfs/{cleanup.cpp => cleanup.c} | 441 ++++++++----- .../filesystems/udfs/{close.cpp => close.c} | 5 +- .../filesystems/udfs/{create.cpp => create.c} | 38 +- .../udfs/{devcntrl.cpp => devcntrl.c} | 26 +- .../udfs/{dircntrl.cpp => dircntrl.c} | 15 +- .../udfs/{env_spec.cpp => env_spec.c} | 379 ++++++++--- .../filesystems/udfs/{fastio.cpp => fastio.c} | 2 +- .../udfs/{fileinfo.cpp => fileinfo.c} | 22 +- .../udfs/{filobsup.cpp => filobsup.c} | 0 .../filesystems/udfs/{flush.cpp => flush.c} | 41 +- .../udfs/{fscntrl.cpp => fscntrl.c} | 67 +- .../udfs/{lockctrl.cpp => lockctrl.c} | 0 drivers/filesystems/udfs/{mem.cpp => mem.c} | 2 +- drivers/filesystems/udfs/{misc.cpp => misc.c} | 25 +- .../udfs/{namesup.cpp => namesup.c} | 0 drivers/filesystems/udfs/{pnp.cpp => pnp.c} | 8 +- .../udfs/{prefxsup.cpp => prefxsup.c} | 12 +- drivers/filesystems/udfs/protos.h | 21 +- drivers/filesystems/udfs/{read.cpp => read.c} | 39 +- .../udfs/{secursup.cpp => secursup.c} | 2 +- .../udfs/{shutdown.cpp => shutdown.c} | 3 +- .../udfs/{strucsup.cpp => strucsup.c} | 41 +- drivers/filesystems/udfs/struct.h | 86 ++- .../udfs/{sys_spec.cpp => sys_spec.c} | 2 +- .../udfs/{udf_dbg.cpp => udf_dbg.c} | 2 +- drivers/filesystems/udfs/udf_dbg.h | 26 +- .../udfs/udf_info/{alloc.cpp => alloc.c} | 169 +++-- .../udfs/udf_info/{dirtree.cpp => dirtree.c} | 12 +- drivers/filesystems/udfs/udf_info/ecma_167.h | 7 + .../udfs/udf_info/{extent.cpp => extent.c} | 142 +++- .../udfs/udf_info/{mount.cpp => mount.c} | 288 ++++---- .../udf_info/{phys_eject.cpp => phys_eject.c} | 0 .../udf_info/{physical.cpp => physical.c} | 2 +- .../udfs/udf_info/{remap.cpp => remap.c} | 15 +- .../udf_info/{udf_info.cpp => udf_info.c} | 252 ++++--- drivers/filesystems/udfs/udf_info/udf_info.h | 616 +++++++++++++++++- drivers/filesystems/udfs/udf_info/udf_rel.h | 4 + .../udfs/{udfdata.cpp => udfdata.c} | 4 +- drivers/filesystems/udfs/udffs.h | 16 +- .../udfs/{udfinit.cpp => udfinit.c} | 10 +- drivers/filesystems/udfs/udfs_reg.inf | 2 +- drivers/filesystems/udfs/unload.c | 24 + drivers/filesystems/udfs/unload.cpp | 53 -- .../udfs/{verfysup.cpp => verfysup.c} | 6 +- .../udfs/{volinfo.cpp => volinfo.c} | 12 +- .../filesystems/udfs/{write.cpp => write.c} | 42 +- 56 files changed, 2302 insertions(+), 974 deletions(-) rename drivers/filesystems/udfs/Include/{Sys_spec_lib.cpp => Sys_spec_lib.c} (99%) rename drivers/filesystems/udfs/Include/{mem_tools.cpp => mem_tools.c} (97%) rename drivers/filesystems/udfs/Include/{phys_lib.cpp => phys_lib.c} (98%) rename drivers/filesystems/udfs/Include/{regtools.cpp => regtools.c} (97%) rename drivers/filesystems/udfs/Include/{string_lib.cpp => string_lib.c} (73%) rename drivers/filesystems/udfs/{cleanup.cpp => cleanup.c} (57%) rename drivers/filesystems/udfs/{close.cpp => close.c} (99%) rename drivers/filesystems/udfs/{create.cpp => create.c} (99%) rename drivers/filesystems/udfs/{devcntrl.cpp => devcntrl.c} (93%) rename drivers/filesystems/udfs/{dircntrl.cpp => dircntrl.c} (97%) rename drivers/filesystems/udfs/{env_spec.cpp => env_spec.c} (50%) rename drivers/filesystems/udfs/{fastio.cpp => fastio.c} (99%) rename drivers/filesystems/udfs/{fileinfo.cpp => fileinfo.c} (99%) rename drivers/filesystems/udfs/{filobsup.cpp => filobsup.c} (100%) rename drivers/filesystems/udfs/{flush.cpp => flush.c} (95%) rename drivers/filesystems/udfs/{fscntrl.cpp => fscntrl.c} (97%) rename drivers/filesystems/udfs/{lockctrl.cpp => lockctrl.c} (100%) rename drivers/filesystems/udfs/{mem.cpp => mem.c} (93%) rename drivers/filesystems/udfs/{misc.cpp => misc.c} (98%) rename drivers/filesystems/udfs/{namesup.cpp => namesup.c} (100%) rename drivers/filesystems/udfs/{pnp.cpp => pnp.c} (99%) rename drivers/filesystems/udfs/{prefxsup.cpp => prefxsup.c} (99%) rename drivers/filesystems/udfs/{read.cpp => read.c} (94%) rename drivers/filesystems/udfs/{secursup.cpp => secursup.c} (99%) rename drivers/filesystems/udfs/{shutdown.cpp => shutdown.c} (98%) rename drivers/filesystems/udfs/{strucsup.cpp => strucsup.c} (97%) rename drivers/filesystems/udfs/{sys_spec.cpp => sys_spec.c} (95%) rename drivers/filesystems/udfs/{udf_dbg.cpp => udf_dbg.c} (99%) rename drivers/filesystems/udfs/udf_info/{alloc.cpp => alloc.c} (85%) rename drivers/filesystems/udfs/udf_info/{dirtree.cpp => dirtree.c} (99%) rename drivers/filesystems/udfs/udf_info/{extent.cpp => extent.c} (94%) rename drivers/filesystems/udfs/udf_info/{mount.cpp => mount.c} (92%) rename drivers/filesystems/udfs/udf_info/{phys_eject.cpp => phys_eject.c} (100%) rename drivers/filesystems/udfs/udf_info/{physical.cpp => physical.c} (95%) rename drivers/filesystems/udfs/udf_info/{remap.cpp => remap.c} (96%) rename drivers/filesystems/udfs/udf_info/{udf_info.cpp => udf_info.c} (96%) rename drivers/filesystems/udfs/{udfdata.cpp => udfdata.c} (99%) rename drivers/filesystems/udfs/{udfinit.cpp => udfinit.c} (97%) create mode 100644 drivers/filesystems/udfs/unload.c delete mode 100644 drivers/filesystems/udfs/unload.cpp rename drivers/filesystems/udfs/{verfysup.cpp => verfysup.c} (99%) rename drivers/filesystems/udfs/{volinfo.cpp => volinfo.c} (99%) rename drivers/filesystems/udfs/{write.cpp => write.c} (97%) diff --git a/drivers/filesystems/udfs/CMakeLists.txt b/drivers/filesystems/udfs/CMakeLists.txt index 1ae3d50d9b070..e1cc34d04db02 100644 --- a/drivers/filesystems/udfs/CMakeLists.txt +++ b/drivers/filesystems/udfs/CMakeLists.txt @@ -2,43 +2,43 @@ include_directories(Include) list(APPEND SOURCE - udf_info/alloc.cpp - udf_info/dirtree.cpp - udf_info/extent.cpp - udf_info/mount.cpp - udf_info/phys_eject.cpp - udf_info/physical.cpp - udf_info/remap.cpp - udf_info/udf_info.cpp - cleanup.cpp - close.cpp - create.cpp - devcntrl.cpp - dircntrl.cpp - env_spec.cpp - fastio.cpp - fileinfo.cpp - flush.cpp - fscntrl.cpp - lockctrl.cpp - mem.cpp - misc.cpp - namesup.cpp - prefxsup.cpp - pnp.cpp - read.cpp - secursup.cpp - shutdown.cpp - sys_spec.cpp - udf_dbg.cpp - udfinit.cpp - unload.cpp - verfysup.cpp - volinfo.cpp - write.cpp - strucsup.cpp - filobsup.cpp - udfdata.cpp + udf_info/alloc.c + udf_info/dirtree.c + udf_info/extent.c + udf_info/mount.c + udf_info/phys_eject.c + udf_info/physical.c + udf_info/remap.c + udf_info/udf_info.c + cleanup.c + close.c + create.c + devcntrl.c + dircntrl.c + env_spec.c + fastio.c + fileinfo.c + flush.c + fscntrl.c + lockctrl.c + mem.c + misc.c + namesup.c + prefxsup.c + pnp.c + read.c + secursup.c + shutdown.c + sys_spec.c + udf_dbg.c + udfinit.c + unload.c + verfysup.c + volinfo.c + write.c + strucsup.c + filobsup.c + udfdata.c udffs.h) add_library(udfs MODULE ${SOURCE} udffs.rc) diff --git a/drivers/filesystems/udfs/Include/Sys_spec_lib.cpp b/drivers/filesystems/udfs/Include/Sys_spec_lib.c similarity index 99% rename from drivers/filesystems/udfs/Include/Sys_spec_lib.cpp rename to drivers/filesystems/udfs/Include/Sys_spec_lib.c index b740b6a8a9e73..b56ed59d687a6 100644 --- a/drivers/filesystems/udfs/Include/Sys_spec_lib.cpp +++ b/drivers/filesystems/udfs/Include/Sys_spec_lib.c @@ -150,10 +150,10 @@ UDFAttributesToUDF( IN ULONG NTAttr ) { - PULONG attr; //permissions - PUSHORT Flags; - PUCHAR Type; - PUCHAR FCharact; + PULONG attr = NULL; //permissions + PUSHORT Flags = NULL; + PUCHAR Type = NULL; + PUCHAR FCharact = NULL; NTAttr &= UDF_VALID_FILE_ATTRIBUTES; @@ -240,7 +240,7 @@ UDFFileDirInfoToNT( PEXTENDED_FILE_ENTRY ExFileEntry; USHORT Ident; BOOLEAN ReadSizes = FALSE; - NTSTATUS status; + NTSTATUS status = STATUS_SUCCESS; PFCB Fcb; UDFPrint(("@=%#x, FileDirNdx %x\n", &Vcb, FileDirNdx)); @@ -575,7 +575,7 @@ UDFDoesOSAllowFileToBeTargetForRename__( IN PUDF_FILE_INFO FileInfo ) { - NTSTATUS RC; + NTSTATUS RC = STATUS_SUCCESS; if (UDFIsADirectory(FileInfo)) return STATUS_ACCESS_DENIED; diff --git a/drivers/filesystems/udfs/Include/Sys_spec_lib.h b/drivers/filesystems/udfs/Include/Sys_spec_lib.h index 7187ab6e0371b..696022e2d2d4c 100644 --- a/drivers/filesystems/udfs/Include/Sys_spec_lib.h +++ b/drivers/filesystems/udfs/Include/Sys_spec_lib.h @@ -104,7 +104,7 @@ __inline LARGE_INTEGER UDFMakeLargeInteger(LONGLONG value) { #define UDFGetNTFileId(Vcb, fi) \ UDFMakeLargeInteger((((fi)->Dloc->FELoc.Mapping[0].extLocation - UDFPartStart(Vcb, -2)) + \ - ((LONGLONG)Vcb<<32))) + ((LONGLONG)(ULONG_PTR)Vcb<<32))) #define UnicodeIsPrint(a) RtlIsValidOemCharacter(&(a)) diff --git a/drivers/filesystems/udfs/Include/mem_tools.cpp b/drivers/filesystems/udfs/Include/mem_tools.c similarity index 97% rename from drivers/filesystems/udfs/Include/mem_tools.cpp rename to drivers/filesystems/udfs/Include/mem_tools.c index 7b9a8bf8ea499..3912ee1659c87 100644 --- a/drivers/filesystems/udfs/Include/mem_tools.cpp +++ b/drivers/filesystems/udfs/Include/mem_tools.c @@ -6,25 +6,12 @@ #ifdef MY_USE_INTERNAL_MEMMANAGER -#ifdef _X86_ - __inline VOID DbgTouch(IN PVOID addr) { - __asm { - mov eax,addr - mov al,[byte ptr eax] - } + volatile UCHAR a = ((volatile UCHAR*)addr)[0]; + (void)a; } -#else // NO X86 optimization , use generic C/C++ - -__inline VOID DbgTouch(IN PVOID addr) -{ - UCHAR a = ((PUCHAR)addr)[0]; -} - -#endif // _X86_ - //MEM_ALLOC_DESC Allocs[MY_HEAP_MAX_BLOCKS]; MEM_FRAME_ALLOC_DESC FrameList[MY_HEAP_MAX_FRAMES]; @@ -47,15 +34,15 @@ ERESOURCE FrameLock; #define InitLockMemoryManager() ExInitializeResourceLite(&FrameLock) #define DeinitLockMemoryManager() ExDeleteResourceLite(&FrameLock) #endif //MEM_LOCK_BY_SPINLOCK -ULONG FrameCount; -ULONG LastFrame; +ULONG FrameCount = 0; +ULONG LastFrame = 0; BOOLEAN MyMemInitialized = FALSE; #define MyAllocIsFrameFree(FrameList, i) \ (!(FrameList[i].LastUsed || FrameList[i].FirstFree)) #ifdef UDF_DBG -ULONG MemTotalAllocated; +ULONG MemTotalAllocated = 0; PCHAR BreakAddr; VOID @@ -64,7 +51,7 @@ MyAllocDumpDescr( ULONG i ) { - BOOLEAN Used; + BOOLEAN Used = FALSE; Used = (Allocs[i].Len & MY_HEAP_FLAG_USED) ? TRUE : FALSE; UDFPrint(("block %x \t%s addr %x len %x \t", i, Used ? "used" : "free", Allocs[i].Addr, (Allocs[i].Len) & MY_HEAP_FLAG_LEN_MASK)); @@ -93,11 +80,11 @@ MyAllocDumpFrame( ULONG Frame ) { - ULONG i; + ULONG i = 0; PMEM_ALLOC_DESC Allocs; Allocs = FrameList[Frame].Frame; ULONG k=0; - BOOLEAN Used; + BOOLEAN Used = FALSE; #ifdef DUMP_MEM_FRAMES if (!MyDumpMem) #endif //DUMP_MEM_FRAMES @@ -132,7 +119,7 @@ MyAllocDumpFrames( VOID ) { - ULONG i; + ULONG i = 0; for(i=0;i> 1; @@ -933,7 +920,7 @@ MyAllocInit(VOID) VOID MyAllocRelease(VOID) { - ULONG i; + ULONG i = 0; PMEM_ALLOC_DESC Allocs; if (!MyMemInitialized) diff --git a/drivers/filesystems/udfs/Include/mem_tools.h b/drivers/filesystems/udfs/Include/mem_tools.h index fa06ad9708fb5..c240fdce60bca 100644 --- a/drivers/filesystems/udfs/Include/mem_tools.h +++ b/drivers/filesystems/udfs/Include/mem_tools.h @@ -198,13 +198,13 @@ VOID inline MyFreePool__(PVOID addr) { // ULONG i; newaddr = (PCHAR)addr; if (!newaddr) { - __asm int 3; + __debugbreak(); return; } /* for(i=0; iextLength; i++, RelocExtent++) { - ULONG _ReadBytes; + ULONG _ReadBytes = 0; rLba = RelocExtent->extLocation; if (rLba >= (Vcb->CDR_Mode ? Vcb->NWA : Vcb->LastLBA + 1)) { RtlZeroMemory(Buffer, _ReadBytes = RelocExtent->extLength); @@ -437,7 +437,7 @@ UDFPrepareForWriteOperation( { #ifdef _UDF_STRUCTURES_H_ if (Vcb->BSBM_Bitmap) { - ULONG i; + ULONG i = 0; for(i=0; iBSBM_Bitmap), Lba+i)) { UDFPrint(("W: Known BB @ %#x\n", Lba)); @@ -485,15 +485,15 @@ UDFDetermineVolumeLayout( PULONG SessionEndLba ) { - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; CDROM_TOC_LARGE* toc = NULL; CDROM_TOC_SESSION_DATA* LastSes = NULL; - ULONG LocalTrackCount; - ULONG TocEntry; + ULONG LocalTrackCount = 0; + ULONG TocEntry = 0; void* TempBuffer = NULL; - ULONG OldTrkNum; - ULONG TrkNum; - ULONG ReadBytes; + ULONG OldTrkNum = 0; + ULONG TrkNum = 0; + ULONG ReadBytes = 0; SIZE_T i, len; *SessionStartLba = 0; @@ -911,8 +911,8 @@ UDFGetDiskInfo( try_return(RC); } - ULONG SessionStart; - ULONG SessionEnd; + ULONG SessionStart = 0; + ULONG SessionEnd = 0; RC = UDFDetermineVolumeLayout(IrpContext, DeviceObject, Vcb, &SessionStart, &SessionEnd); @@ -976,7 +976,7 @@ try_exit: NOTHING; UDFPrint(("UDF: Last LBA in last session: %x\n",Vcb->LastLBA)); UDFPrint(("UDF: First writable LBA (NWA) in last session: %x\n",Vcb->NWA)); UDFPrint(("UDF: Last available LBA beyond end of last session: %x\n",Vcb->LastPossibleLBA)); - UDFPrint(("UDF: blocks per frame: %x\n",1 << Vcb->WCacheBlocksPerFrameSh)); + UDFPrint(("UDF: blocks per frame: %x\n", Vcb->WriteBlockSize >> Vcb->SectorShift)); UDFPrint(("UDF: Flags: %s%s\n", Vcb->VcbState & UDF_VCB_FLAGS_RAW_DISK ? "RAW " : "", Vcb->VcbState & VCB_STATE_VOLUME_READ_ONLY ? "R/O " : "WR " @@ -1006,7 +1006,7 @@ UDFPrepareForReadOperation( #ifdef _UDF_STRUCTURES_H_ if (Vcb->BSBM_Bitmap) { - ULONG i; + ULONG i = 0; for(i=0; iBSBM_Bitmap), Lba+i)) { UDFPrint(("R: Known BB @ %#x\n", Lba)); @@ -1056,8 +1056,8 @@ UDFReadInSector( ) { int8* tmp_buff; - NTSTATUS status; - ULONG _ReadBytes; + NTSTATUS status = STATUS_SUCCESS; + ULONG _ReadBytes = 0; (*ReadBytes) = 0; @@ -1095,9 +1095,8 @@ UDFReadData( { uint32 i, l, Lba, BS=Vcb->SectorSize; uint32 BSh=Vcb->SectorShift; - NTSTATUS status; + NTSTATUS status = STATUS_SUCCESS; ULONG _ReadBytes = 0; - uint32 to_read; (*ReadBytes) = 0; if (!Length) return STATUS_SUCCESS; @@ -1117,17 +1116,16 @@ UDFReadData( } // read sector_size-aligned part i = Length >> BSh; - while(i) { - to_read = min(i, 64); - status = UDFReadSectors(IrpContext, Vcb, Translate, Lba, to_read, Direct, Buffer, &_ReadBytes); + if (i) { + status = UDFReadSectors(IrpContext, Vcb, Translate, Lba, i, Direct, Buffer, &_ReadBytes); (*ReadBytes) += _ReadBytes; if (!NT_SUCCESS(status)) { return status; } - Buffer += to_read<Modified || (Vcb->IntegrityType == INTEGRITY_TYPE_CLOSE)) { UDFSetModified(Vcb); @@ -1187,9 +1185,9 @@ UDFWriteInSector( ) { int8* tmp_buff; - NTSTATUS status; + NTSTATUS status = STATUS_SUCCESS; SIZE_T _WrittenBytes; - ULONG ReadBytes; + ULONG ReadBytes = 0; if (!Vcb->Modified) { UDFSetModified(Vcb); @@ -1252,7 +1250,7 @@ UDFWriteData( { uint32 i, l, Lba, BS=Vcb->SectorSize; uint32 BSh=Vcb->SectorShift; - NTSTATUS status; + NTSTATUS status = STATUS_SUCCESS; SIZE_T _WrittenBytes; (*WrittenBytes) = 0; diff --git a/drivers/filesystems/udfs/Include/phys_lib.h b/drivers/filesystems/udfs/Include/phys_lib.h index 747b95450acf7..19203d202daa5 100644 --- a/drivers/filesystems/udfs/Include/phys_lib.h +++ b/drivers/filesystems/udfs/Include/phys_lib.h @@ -15,7 +15,7 @@ UDFTRead( SIZE_T Length, ULONG LBA, PULONG ReadBytes, - ULONG Flags = 0 + ULONG Flags ); NTSTATUS @@ -26,7 +26,7 @@ UDFTWrite( IN SIZE_T Length, IN ULONG LBA, OUT PSIZE_T WrittenBytes, - IN ULONG Flags = 0 + IN ULONG Flags ); #define PH_TMP_BUFFER 1 diff --git a/drivers/filesystems/udfs/Include/regtools.cpp b/drivers/filesystems/udfs/Include/regtools.c similarity index 97% rename from drivers/filesystems/udfs/Include/regtools.cpp rename to drivers/filesystems/udfs/Include/regtools.c index 1b75c0c07eb3e..d8a227074c64f 100644 --- a/drivers/filesystems/udfs/Include/regtools.cpp +++ b/drivers/filesystems/udfs/Include/regtools.c @@ -17,7 +17,7 @@ RegTGetKeyHandle( { OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING NameString; - NTSTATUS status; + NTSTATUS status = STATUS_SUCCESS; //UDFPrint(("RegTGetKeyHandle: h=%x, %S\n", hRootKey, KeyName)); @@ -107,8 +107,8 @@ RegTGetDwordValue( UNICODE_STRING NameString; PKEY_VALUE_PARTIAL_INFORMATION ValInfo; #endif //WIN_32_MODE - ULONG len; - NTSTATUS status; + ULONG len = 0; + NTSTATUS status = STATUS_SUCCESS; HKEY hKey; BOOLEAN retval = FALSE; BOOLEAN free_h = FALSE; @@ -198,8 +198,8 @@ RegTGetStringValue( UNICODE_STRING NameString; PKEY_VALUE_PARTIAL_INFORMATION ValInfo; #endif //USER_MODE - ULONG len; - NTSTATUS status; + ULONG len = 0; + NTSTATUS status = STATUS_SUCCESS; HKEY hKey; BOOLEAN retval = FALSE; BOOLEAN free_h = FALSE; diff --git a/drivers/filesystems/udfs/Include/string_lib.cpp b/drivers/filesystems/udfs/Include/string_lib.c similarity index 73% rename from drivers/filesystems/udfs/Include/string_lib.cpp rename to drivers/filesystems/udfs/Include/string_lib.c index 1750feb27ff16..2e6e4e8afa7c4 100644 --- a/drivers/filesystems/udfs/Include/string_lib.cpp +++ b/drivers/filesystems/udfs/Include/string_lib.c @@ -12,7 +12,7 @@ MyRtlCompareMemory( ULONG len ) { - ULONG i; + ULONG i = 0; for(i=0; iLength != s2->Length) return (-1); i = memcmp(s1->Buffer, s2->Buffer, (s1->Length) ? (s1->Length) : (s2->Length)); @@ -65,34 +65,14 @@ RtlAppendUnicodeToString( ) { PWCHAR tmp; - USHORT i; - -#ifdef _X86_ - - __asm push ebx - __asm push esi - __asm xor ebx,ebx - __asm mov esi,Str2 -Scan_1: - __asm cmp [word ptr esi+ebx],0 - __asm je EO_Scan - __asm add ebx,2 - __asm jmp Scan_1 -EO_Scan: - __asm mov i,bx - __asm pop esi - __asm pop ebx - -#else // NO X86 optimization, use generic C/C++ + ULONG i; i=0; - while(Str2[i]) { + while(Str2[i] && i < (MAXUSHORT / sizeof(WCHAR))) { i++; } i *= sizeof(WCHAR); -#endif // _X86_ - tmp = Str1->Buffer; ASSERT(Str1->MaximumLength); if ((Str1->Length+i+sizeof(WCHAR)) > Str1->MaximumLength) { @@ -102,13 +82,13 @@ RtlAppendUnicodeToString( memcpy(tmp2, tmp, Str1->MaximumLength); ExFreePool(tmp); tmp = tmp2; - Str1->MaximumLength = STRING_BUFFER_ALIGN(i + sizeof(WCHAR))*2; + Str1->MaximumLength = (USHORT)(STRING_BUFFER_ALIGN(i + sizeof(WCHAR))*2); Str1->Buffer = tmp; } RtlCopyMemory(((PCHAR)tmp)+Str1->Length, Str2, i); i+=Str1->Length; tmp[(i / sizeof(WCHAR))] = 0; - Str1->Length = i; + Str1->Length = (USHORT)i; return STATUS_SUCCESS; @@ -126,35 +106,16 @@ MyInitUnicodeString( ) { - USHORT i; - -#ifdef _X86_ - - __asm push ebx - __asm push esi - __asm xor ebx,ebx - __asm mov esi,Str2 -Scan_1: - __asm cmp [word ptr esi+ebx],0 - __asm je EO_Scan - __asm add ebx,2 - __asm jmp Scan_1 -EO_Scan: - __asm mov i,bx - __asm pop esi - __asm pop ebx - -#else // NO X86 optimization, use generic C/C++ + ULONG i; i=0; - while(Str2[i]) { + while(Str2[i] && i < (MAXUSHORT / sizeof(WCHAR))) { i++; } i *= sizeof(WCHAR); -#endif // _X86_ - - Str1->MaximumLength = STRING_BUFFER_ALIGN((Str1->Length = i) + sizeof(WCHAR)); + Str1->Length = (USHORT)i; + Str1->MaximumLength = (USHORT)STRING_BUFFER_ALIGN(i + sizeof(WCHAR)); Str1->Buffer = (PWCHAR)MyAllocatePool__(NonPagedPool, Str1->MaximumLength); if (!Str1->Buffer) return STATUS_INSUFFICIENT_RESOURCES; diff --git a/drivers/filesystems/udfs/Include/udf_reg.h b/drivers/filesystems/udfs/Include/udf_reg.h index 46002b71cfde0..32d15648b04b9 100644 --- a/drivers/filesystems/udfs/Include/udf_reg.h +++ b/drivers/filesystems/udfs/Include/udf_reg.h @@ -7,6 +7,7 @@ #ifndef __DWUDF_REGISTRY__H__ #define __DWUDF_REGISTRY__H__ + #define UDF_BM_FLUSH_PERIOD_NAME L"BitmapFlushPeriod" #define UDF_TREE_FLUSH_PERIOD_NAME L"DirTreeFlushPeriod" #define UDF_NO_UPDATE_PERIOD_NAME L"MaxNoUpdatePeriod" diff --git a/drivers/filesystems/udfs/cleanup.cpp b/drivers/filesystems/udfs/cleanup.c similarity index 57% rename from drivers/filesystems/udfs/cleanup.cpp rename to drivers/filesystems/udfs/cleanup.c index 4a42b7da33427..e07a968acddb8 100644 --- a/drivers/filesystems/udfs/cleanup.cpp +++ b/drivers/filesystems/udfs/cleanup.c @@ -50,6 +50,7 @@ UDFCommonCleanup( { IO_STATUS_BLOCK IoStatus; NTSTATUS RC = STATUS_SUCCESS; + NTSTATUS RC2 = STATUS_SUCCESS; PFILE_OBJECT FileObject = NULL; PFCB Fcb = NULL; PCCB Ccb = NULL; @@ -77,13 +78,13 @@ UDFCommonCleanup( return STATUS_SUCCESS; } - // Get the file object out of the Irp and decode the type of open. + // Get the file object out of the Irp and decode the type of open. FileObject = IoGetCurrentIrpStackLocation(Irp)->FileObject; TypeOfOpen = UDFDecodeFileObject(FileObject, &Fcb, &Ccb); - // No work here for either an UnopenedFile object or a StreamFileObject. + // No work here for either an UnopenedFile object or a StreamFileObject. if (TypeOfOpen <= StreamFileOpen) { @@ -152,8 +153,10 @@ UDFCommonCleanup( if (FileObject->Flags & FO_CACHE_SUPPORTED) { // we've cached close - InterlockedDecrement((PLONG)&Fcb->CachedOpenHandleCount); + InterlockedDecrement(&Fcb->CachedOpenHandleCount); } + ASSERT(Fcb->FcbCleanup <= (Fcb->FcbReference-1)); + MmPrint((" CcUninitializeCacheMap()\n")); CcUninitializeCacheMap(FileObject, NULL, NULL); @@ -171,29 +174,30 @@ UDFCommonCleanup( AcquiredVcb = TRUE; } - // Acquire current object only - // Parent is acquired later only for delete operations (Child → Parent order) + // Acquire parent object + if (Fcb->FileInfo->ParentFile) { + UDF_CHECK_PAGING_IO_RESOURCE(Fcb->FileInfo->ParentFile->Fcb); + UDFAcquireResourceExclusive(&(Fcb->FileInfo->ParentFile->Fcb->FcbNonpaged->FcbResource), TRUE); + } else { + UDFAcquireResourceShared(&(Vcb->VcbResource), TRUE); + } + AcquiredParentFCB = TRUE; + // Acquire current object UDF_CHECK_PAGING_IO_RESOURCE(Fcb); - UDFAcquireFcbExclusive(IrpContext, Fcb, FALSE); + UDFAcquireResourceExclusive(&Fcb->FcbNonpaged->FcbResource, TRUE); AcquiredFCB = TRUE; // Decrement the cleanup counts in the Vcb and Fcb. - // Also decrement LCB reference count. UDFLockVcb(IrpContext, Vcb); UDFDecrementCleanupCounts(IrpContext, Fcb); - if (Ccb->Lcb) { - ASSERT(Ccb->Lcb->Reference > 0); - Ccb->Lcb->Reference--; - } UDFUnlockVcb(IrpContext, Vcb); if (FileObject->Flags & FO_CACHE_SUPPORTED) { // we've cached close - InterlockedDecrement((PLONG)&Fcb->CachedOpenHandleCount); + InterlockedDecrement(&Fcb->CachedOpenHandleCount); } - // No ASSERT on FcbCleanup vs FcbReference here - FcbCleanup - // can be temporarily bumped by try-lock reordering in create.cpp + ASSERT(Fcb->FcbCleanup <= (Fcb->FcbReference-1)); // check if Ccb being cleaned up has DeleteOnClose flag set if (Ccb->Flags & UDF_CCB_DELETE_ON_CLOSE) { @@ -224,147 +228,181 @@ UDFCommonCleanup( // get Link count lc = UDFGetFileLinkCount(Fcb->FileInfo); - NextFileInfo = Fcb->FileInfo; - - // Attempt delete if this is the last cleanup and DELETE_ON_CLOSE is set - if ((Fcb->FcbState & UDF_FCB_DELETE_ON_CLOSE) && + if ( (Fcb->FcbState & UDF_FCB_DELETE_ON_CLOSE) && !(Fcb->FcbCleanup)) { - - BOOLEAN DeleteAttempted = FALSE; - // This can be useful for Streams, those were brutally deleted // (together with parent object) ASSERT(!(Fcb->FcbState & UDF_FCB_ROOT_DIRECTORY)); FileObject->DeletePending = TRUE; - // Check if directory is non-empty — if so, discard delete - if ((Fcb->FcbState & UDF_FCB_DIRECTORY) && - !UDFIsDirEmpty__(NextFileInfo)) { + // we should mark all streams of the file being deleted + // for deletion too, if there are no more Links to + // main data stream + if ((lc <= 1) && + !UDFIsSDirDeleted(Fcb->FileInfo->Dloc->SDirInfo)) { + RC = UDFMarkStreamsForDeletion(IrpContext, Vcb, Fcb, TRUE); // Delete + } + // we can release these resources 'cause UDF_FCB_DELETE_ON_CLOSE + // flag is already set & the file can't be opened + UDF_CHECK_PAGING_IO_RESOURCE(Fcb); + UDFReleaseResource(&Fcb->FcbNonpaged->FcbResource); + AcquiredFCB = FALSE; + if (Fcb->FileInfo->ParentFile) { + UDF_CHECK_PAGING_IO_RESOURCE(Fcb->ParentFcb); + UDFReleaseResource(&Fcb->ParentFcb->FcbNonpaged->FcbResource); + } else { + UDFReleaseResource(&Vcb->VcbResource); + } + AcquiredParentFCB = FALSE; + UDFReleaseResource(&(Vcb->VcbResource)); + AcquiredVcb = FALSE; - Fcb->FcbState &= ~UDF_FCB_DELETE_ON_CLOSE; + // Make system to issue last Close request + // for our Target ... - } else { +#ifdef UDF_DELAYED_CLOSE + UDFFspClose(Fcb->Vcb); +#endif //UDF_DELAYED_CLOSE - DeleteAttempted = TRUE; + UDFAcquireResourceShared(&Vcb->VcbResource, TRUE); + AcquiredVcb = TRUE; + if (Fcb->FileInfo->ParentFile) { + UDF_CHECK_PAGING_IO_RESOURCE(Fcb->ParentFcb); + UDFAcquireResourceExclusive(&(Fcb->ParentFcb->FcbNonpaged->FcbResource), TRUE); + } else { + UDFAcquireResourceShared(&Vcb->VcbResource, TRUE); + } + AcquiredParentFCB = TRUE; + UDF_CHECK_PAGING_IO_RESOURCE(Fcb); + UDFAcquireResourceExclusive(&Fcb->FcbNonpaged->FcbResource, TRUE); + AcquiredFCB = TRUE; + + // we should set file sizes to zero if there are no more + // links to this file + if (lc <= 1) { + // Synchronize here with paging IO + UDFAcquireResourceExclusive(&Fcb->FcbNonpaged->FcbPagingIoResource, TRUE); + // set file size to zero (for system cache manager) +// Fcb->CommonFCBHeader.ValidDataLength.QuadPart = + Fcb->Header.FileSize.QuadPart = + Fcb->Header.ValidDataLength.QuadPart = 0; + CcSetFileSizes(FileObject, (PCC_FILE_SIZES)&Fcb->Header.AllocationSize); + + UDFReleaseResource(&Fcb->FcbNonpaged->FcbPagingIoResource); + } + } - // Mark all streams for deletion if no more links - if ((lc <= 1) && - !UDFIsSDirDeleted(Fcb->FileInfo->Dloc->SDirInfo)) { - RC = UDFMarkStreamsForDeletion(IrpContext, Vcb, Fcb, TRUE); // Delete - } +#ifdef UDF_DELAYED_CLOSE + if ((Fcb->FcbReference == 1) && + /*(Fcb->NodeIdentifier.NodeType != UDF_NODE_TYPE_VCB) &&*/ // see above + (!(Fcb->FcbState & UDF_FCB_DELETE_ON_CLOSE)) ) { + Fcb->FcbState |= UDF_FCB_DELAY_CLOSE; + } +#endif //UDF_DELAYED_CLOSE - // Acquire parent for delete operation (after current — child first order) - if (Fcb->FileInfo->ParentFile) { - UDF_CHECK_PAGING_IO_RESOURCE(Fcb->ParentFcb); - UDFAcquireFcbExclusive(IrpContext, Fcb->ParentFcb, FALSE); - AcquiredParentFCB = TRUE; - } + NextFileInfo = Fcb->FileInfo; - // Note: do NOT set file sizes to zero here before unlink. - // If unlink fails (STATUS_CANNOT_DELETE), the file stays visible - // with FSize=0 — other threads see truncated data. + // do we need to delete it now ? + if ( (Fcb->FcbState & UDF_FCB_DELETE_ON_CLOSE) && + !(Fcb->FcbCleanup)) { - // Mark parent object for deletion if requested - if ((Fcb->FcbState & UDF_FCB_DELETE_PARENT) && - Fcb->ParentFcb) { - ASSERT(!(Fcb->ParentFcb->FcbState & UDF_FCB_ROOT_DIRECTORY)); - Fcb->ParentFcb->FcbState |= UDF_FCB_DELETE_ON_CLOSE; + // can we do it ? + if (Fcb->FcbState & UDF_FCB_DIRECTORY) { + ASSERT(!(Fcb->FcbState & UDF_FCB_ROOT_DIRECTORY)); + if (!UDFIsDirEmpty__(NextFileInfo)) { + // forget about it + Fcb->FcbState &= ~UDF_FCB_DELETE_ON_CLOSE; + goto DiscardDelete; } - - // Flush file. It is required by UDFUnlinkFile__() - RC = UDFFlushFile__(IrpContext, Vcb, NextFileInfo); - if (!NT_SUCCESS(RC)) { - AdPrint(("Error flushing file !!!\n")); + } else + if (lc <= 1) { + // Synchronize here with paging IO + BOOLEAN AcquiredPagingIo = FALSE; + AcquiredPagingIo = UDFAcquireResourceExclusiveWithCheck(&Fcb->FcbNonpaged->FcbPagingIoResource); + // set file size to zero (for UdfInfo package) + // we should not do this for directories and linked files + UDFResizeFile__(IrpContext, Vcb, NextFileInfo, 0); + if (AcquiredPagingIo) { + UDFReleaseResource(&Fcb->FcbNonpaged->FcbPagingIoResource); } - - // Try to unlink - RC = UDFUnlinkFile__(IrpContext, Vcb, NextFileInfo, TRUE); - - if (RC == STATUS_CANNOT_DELETE) { - - if (NextFileInfo->Dloc && - NextFileInfo->Dloc->SDirInfo && - NextFileInfo->Dloc->SDirInfo->Fcb) { - - // Can't delete file with open streams — pretend deleted. - // Streams will trigger parent deletion on their cleanup. - BrutePoint(); - if (!UDFIsSDirDeleted(NextFileInfo->Dloc->SDirInfo)) { - UDFPretendFileDeleted__(Vcb, Fcb->FileInfo); - } - - } else { - - // Can't delete due to references/permissions/other. - BrutePoint(); - ForcedCleanUp = TRUE; - Fcb->FcbState |= UDF_FCB_DELETED; - // Remove LCB from parent's splay trees immediately. - // Parent is held exclusive (AcquiredParentFCB). - if (Ccb->Lcb && Ccb->Lcb->ParentFcb) { - UdfRemoveNameLinks(Ccb->Lcb->ParentFcb, Ccb->Lcb); - } - RC = STATUS_SUCCESS; + } + // mark parent object for deletion if requested + if ((Fcb->FcbState & UDF_FCB_DELETE_PARENT) && + Fcb->ParentFcb) { + ASSERT(!(Fcb->ParentFcb->FcbState & UDF_FCB_ROOT_DIRECTORY)); + Fcb->ParentFcb->FcbState |= UDF_FCB_DELETE_ON_CLOSE; + } + // flush file. It is required by UDFUnlinkFile__() + RC = UDFFlushFile__(IrpContext, Vcb, NextFileInfo); + if (!NT_SUCCESS(RC)) { + AdPrint(("Error flushing file !!!\n")); + } + // try to unlink + if ((RC = UDFUnlinkFile__(IrpContext, Vcb, NextFileInfo, TRUE)) == STATUS_CANNOT_DELETE) { + // If we can't delete file with Streams due to references, + // mark SDir & Streams + // for Deletion. We shall also set DELETE_PARENT flag to + // force Deletion of the current file later... when curently + // opened Streams would be cleaned up. + + // WARNING! We should keep SDir & Streams if there is a + // link to this file + if (NextFileInfo->Dloc && + NextFileInfo->Dloc->SDirInfo && + NextFileInfo->Dloc->SDirInfo->Fcb) { + + BrutePoint(); + if (!UDFIsSDirDeleted(NextFileInfo->Dloc->SDirInfo)) { +// RC = UDFMarkStreamsForDeletion(Vcb, Fcb, TRUE); // Delete +//#ifdef UDF_ALLOW_PRETEND_DELETED + UDFPretendFileDeleted__(Vcb, Fcb->FileInfo); +//#endif //UDF_ALLOW_PRETEND_DELETED } + goto NotifyDelete; } else { - - // Unlink completed (success or other error) — mark as deleted - ASSERT(!(Fcb->FcbState & UDF_FCB_ROOT_DIRECTORY)); - ForcedCleanUp = TRUE; - if (NT_SUCCESS(RC)) - Fcb->FcbState &= ~UDF_FCB_DELETE_ON_CLOSE; - Fcb->FcbState |= UDF_FCB_DELETED; - // Remove LCB from parent's splay trees immediately. - // Parent is held exclusive (AcquiredParentFCB). - if (Ccb->Lcb && Ccb->Lcb->ParentFcb) { - UdfRemoveNameLinks(Ccb->Lcb->ParentFcb, Ccb->Lcb); - } - // Note: do NOT call CcSetFileSizes(0) here. - // CcUninitializeCacheMap with TruncateSize=0 below (ForcedCleanUp path) - // already purges the cache. Setting Fcb->Header.FileSize=0 here would - // leave a stale FCB with FSize=0 in the prefix table — if the FCB is - // reused (e.g., by rename), the renamed file appears as 0-byte. - RC = STATUS_SUCCESS; + // Getting here means that we can't delete file because of + // References/PemissionsDenied/Smth.Else, + // but not Linked+OpenedStream + BrutePoint(); +// RC = STATUS_SUCCESS; + goto DiscardDelete_1; } + } else { +DiscardDelete_1: + // We have got an ugly ERROR, or + // file is deleted, so forget about it + ASSERT(!(Fcb->FcbState & UDF_FCB_ROOT_DIRECTORY)); + ForcedCleanUp = TRUE; + if (NT_SUCCESS(RC)) + Fcb->FcbState &= ~UDF_FCB_DELETE_ON_CLOSE; + Fcb->FcbState |= UDF_FCB_DELETED; + RC = STATUS_SUCCESS; } - - if (DeleteAttempted) { - // Prevent SetEOF operations on completely deleted data streams - if (lc < 1) { - Fcb->NtReqFCBFlags |= UDF_NTREQ_FCB_DELETED; - } - // Report that we have removed an entry. - if (UDFIsAStream(NextFileInfo)) { - UDFNotifyReportChange( IrpContext, Vcb, NextFileInfo->Fcb, - FILE_NOTIFY_CHANGE_STREAM_NAME, - FILE_ACTION_REMOVED_STREAM, - Ccb->Lcb, FileObject); - } else { - UDFNotifyReportChange( IrpContext, Vcb, NextFileInfo->Fcb, - UDFIsADirectory(NextFileInfo) ? FILE_NOTIFY_CHANGE_DIR_NAME : FILE_NOTIFY_CHANGE_FILE_NAME, - FILE_ACTION_REMOVED, - Ccb->Lcb, FileObject); - } +NotifyDelete: + // We should prevent SetEOF operations on completly + // deleted data streams + if (lc < 1) { + Fcb->NtReqFCBFlags |= UDF_NTREQ_FCB_DELETED; + } + // Report that we have removed an entry. + if (UDFIsAStream(NextFileInfo)) { + UDFNotifyFullReportChange( Vcb, NextFileInfo->Fcb, + FILE_NOTIFY_CHANGE_STREAM_NAME, + FILE_ACTION_REMOVED_STREAM); } else { - // Delete discarded (e.g. non-empty directory) — notify modification - UDFNotifyReportChange( IrpContext, Vcb, NextFileInfo->Fcb, - ((Ccb->Flags & UDF_CCB_ACCESS_TIME_SET) ? FILE_NOTIFY_CHANGE_LAST_ACCESS : 0) | - ((Ccb->Flags & UDF_CCB_WRITE_TIME_SET) ? (FILE_NOTIFY_CHANGE_ATTRIBUTES | FILE_NOTIFY_CHANGE_LAST_WRITE) : 0) | - 0, - UDFIsAStream(NextFileInfo) ? FILE_ACTION_MODIFIED_STREAM : FILE_ACTION_MODIFIED, - Ccb->Lcb, FileObject); + UDFNotifyFullReportChange( Vcb, NextFileInfo->Fcb, + UDFIsADirectory(NextFileInfo) ? FILE_NOTIFY_CHANGE_DIR_NAME : FILE_NOTIFY_CHANGE_FILE_NAME, + FILE_ACTION_REMOVED); } - - } else if (Fcb->FcbState & UDF_FCB_DELETE_ON_CLOSE) { - - // DELETE_ON_CLOSE is set but FcbCleanup > 0 (other handles still open) - UDFNotifyReportChange( IrpContext, Vcb, NextFileInfo->Fcb, + } else + if (Fcb->FcbState & UDF_FCB_DELETE_ON_CLOSE) { +DiscardDelete: + UDFNotifyFullReportChange( Vcb, NextFileInfo->Fcb, ((Ccb->Flags & UDF_CCB_ACCESS_TIME_SET) ? FILE_NOTIFY_CHANGE_LAST_ACCESS : 0) | ((Ccb->Flags & UDF_CCB_WRITE_TIME_SET) ? (FILE_NOTIFY_CHANGE_ATTRIBUTES | FILE_NOTIFY_CHANGE_LAST_WRITE) : 0) | 0, - UDFIsAStream(NextFileInfo) ? FILE_ACTION_MODIFIED_STREAM : FILE_ACTION_MODIFIED, - Ccb->Lcb, FileObject); + UDFIsAStream(NextFileInfo) ? FILE_ACTION_MODIFIED_STREAM : FILE_ACTION_MODIFIED); } if (Fcb->FcbState & UDF_FCB_DIRECTORY) { @@ -422,7 +460,7 @@ UDFCommonCleanup( /* MmPrint((" CcPurgeCacheSection()\n")); CcPurgeCacheSection(&Fcb->SectionObject, NULL, 0, FALSE);*/ } - // we needn't Flush here. It will be done in UDFCloseFile__ + // we needn't Flush here. It will be done in UDFCloseFileInfoChain() } // Update FileTimes & Attrs @@ -437,7 +475,7 @@ UDFCommonCleanup( KeQuerySystemTime((PLARGE_INTEGER)&NtTime); // Check if we should set ARCHIVE bit & LastWriteTime if (FileObject->Flags & FO_FILE_MODIFIED) { - ULONG Attr; + ULONG Attr = 0; PDIR_INDEX_ITEM DirNdx; DirNdx = UDFDirIndex(UDFGetDirIndexByFileInfo(NextFileInfo), NextFileInfo->Index); ASSERT(DirNdx); @@ -472,19 +510,17 @@ UDFCommonCleanup( if (UDFIsAStream(Fcb->FileInfo)) { - UDFNotifyReportChange(IrpContext, Vcb, + UDFNotifyFullReportChange(Vcb, Fcb, FILE_NOTIFY_CHANGE_STREAM_SIZE, - FILE_ACTION_MODIFIED_STREAM, - Ccb->Lcb, FileObject); + FILE_ACTION_MODIFIED_STREAM); } else { - UDFNotifyReportChange(IrpContext, Vcb, + UDFNotifyFullReportChange(Vcb, Fcb, FILE_NOTIFY_CHANGE_SIZE, - FILE_ACTION_MODIFIED, - Ccb->Lcb, FileObject); + FILE_ACTION_MODIFIED); } } @@ -509,19 +545,6 @@ UDFCommonCleanup( } } - // Flush FE (File Entry) to disk on last cleanup of non-deleted files. - // This prevents a race in UDFTeardownStructures where the FCB is removed - // from the FCB table (line ~497) before UDFFlushFile__ writes the FE to - // disk (line ~520). Without this, a concurrent open between those two - // points reads stale FE from disk with informationLength=0. - if (!Fcb->FcbCleanup && - !ForcedCleanUp && - !(Fcb->FcbState & UDF_FCB_DELETED) && - !(Vcb->VcbState & VCB_STATE_VOLUME_READ_ONLY) && - NextFileInfo) { - UDFFlushFile__(IrpContext, Vcb, NextFileInfo); - } - if (!(Fcb->FcbState & UDF_FCB_DIRECTORY) && ForcedCleanUp) { // flush system cache @@ -533,20 +556,23 @@ UDFCommonCleanup( } // release resources now. - UDFReleaseFcb(IrpContext, Fcb); + // they'll be acquired in UDFCloseFileInfoChain() + UDF_CHECK_PAGING_IO_RESOURCE(Fcb); + UDFReleaseResource(&Fcb->FcbNonpaged->FcbResource); AcquiredFCB = FALSE; - if (AcquiredParentFCB && Fcb->FileInfo->ParentFile) { - UDFReleaseFcb(IrpContext, Fcb->FileInfo->ParentFile->Fcb); - AcquiredParentFCB = FALSE; + if (Fcb->FileInfo->ParentFile) { + UDF_CHECK_PAGING_IO_RESOURCE(Fcb->FileInfo->ParentFile->Fcb); + UDFReleaseResource(&Fcb->FileInfo->ParentFile->Fcb->FcbNonpaged->FcbResource); + } else { + UDFReleaseResource(&Vcb->VcbResource); } - - // Close the target file's FileInfo - this decrements FileInfo->RefCount - // Parent FileInfo references are now handled by LCB mechanism in UDFTeardownStructures + AcquiredParentFCB = FALSE; + // close the chain ASSERT(AcquiredVcb); - if (NextFileInfo) { - UDFCloseFile__(IrpContext, Vcb, NextFileInfo); - } + RC2 = UDFCloseFileInfoChain(IrpContext, Vcb, NextFileInfo, Ccb->TreeLength, TRUE); + if (NT_SUCCESS(RC)) + RC = RC2; Ccb->Flags |= UDF_CCB_CLEANED; @@ -564,15 +590,21 @@ try_exit: NOTHING; } _SEH2_FINALLY { if (AcquiredFCB) { - UDFReleaseFcb(IrpContext, Fcb); + UDF_CHECK_PAGING_IO_RESOURCE(Fcb); + UDFReleaseResource(&Fcb->FcbNonpaged->FcbResource); } - if (AcquiredParentFCB && Fcb->FileInfo->ParentFile) { - UDFReleaseFcb(IrpContext, Fcb->FileInfo->ParentFile->Fcb); + if (AcquiredParentFCB) { + if (Fcb->FileInfo->ParentFile) { + UDF_CHECK_PAGING_IO_RESOURCE(Fcb->FileInfo->ParentFile->Fcb); + UDFReleaseResource(&Fcb->FileInfo->ParentFile->Fcb->FcbNonpaged->FcbResource); + } else { + UDFReleaseResource(&Vcb->VcbResource); + } } if (AcquiredVcb) { - UDFReleaseVcb(IrpContext, Vcb); + UDFReleaseResource(&Vcb->VcbResource); AcquiredVcb = FALSE; } @@ -590,6 +622,85 @@ try_exit: NOTHING; return(RC); } // end UDFCommonCleanup() +/* + This routine walks through the tree to RootDir & + calls UDFCloseFile__() for each file instance + imho, Useful feature + */ +NTSTATUS +UDFCloseFileInfoChain( + IN PIRP_CONTEXT IrpContext, + IN PVCB Vcb, + IN PUDF_FILE_INFO fi, + IN ULONG TreeLength, + IN BOOLEAN VcbAcquired + ) +{ + PUDF_FILE_INFO ParentFI; + PFCB Fcb; + PFCB ParentFcb = NULL; + NTSTATUS RC = STATUS_SUCCESS; + NTSTATUS RC2 = STATUS_SUCCESS; + + // we can't process Tree until we can acquire Vcb + if (!VcbAcquired) + UDFAcquireResourceShared(&(Vcb->VcbResource),TRUE); + + AdPrint(("UDFCloseFileInfoChain\n")); + for(; TreeLength && fi; TreeLength--) { + + // close parent chain (if any) + // if we started path parsing not from RootDir on Create, + // we would never get RootDir here + ValidateFileInfo(fi); + + // acquire parent + if ((ParentFI = fi->ParentFile)) { + ParentFcb = fi->Fcb->ParentFcb; + ASSERT(ParentFcb); + UDF_CHECK_PAGING_IO_RESOURCE(ParentFcb); + UDFAcquireResourceExclusive(&ParentFcb->FcbNonpaged->FcbResource, TRUE); + ASSERT_FCB(ParentFcb); + } else { + AdPrint(("Acquiring VCB...\n")); + UDFAcquireResourceShared(&Vcb->VcbResource, TRUE); + AdPrint(("Done\n")); + } + // acquire current file/dir + // we must assure that no more threads try to reuse this object + if ((Fcb = fi->Fcb)) { + UDF_CHECK_PAGING_IO_RESOURCE(Fcb); + UDFAcquireResourceExclusive(&Fcb->FcbNonpaged->FcbResource, TRUE); + ASSERT(Fcb->FcbReference >= fi->RefCount); + RC2 = UDFCloseFile__(IrpContext, Vcb, fi); + if (!NT_SUCCESS(RC2)) + RC = RC2; + ASSERT(Fcb->FcbReference > fi->RefCount); + UDF_CHECK_PAGING_IO_RESOURCE(Fcb); + UDFReleaseResource(&Fcb->FcbNonpaged->FcbResource); + } else { + BrutePoint(); + RC2 = UDFCloseFile__(IrpContext, Vcb, fi); + if (!NT_SUCCESS(RC2)) + RC = RC2; + } + + if (ParentFI) { + UDF_CHECK_PAGING_IO_RESOURCE(ParentFcb); + UDFReleaseResource(&ParentFcb->FcbNonpaged->FcbResource); + } else { + UDFReleaseResource(&Vcb->VcbResource); + } + fi = ParentFI; + } + + if (!VcbAcquired) + UDFReleaseResource(&Vcb->VcbResource); + + return RC; + +} // end UDFCloseFileInfoChain() + VOID UDFAutoUnlock ( IN PVCB Vcb diff --git a/drivers/filesystems/udfs/close.cpp b/drivers/filesystems/udfs/close.c similarity index 99% rename from drivers/filesystems/udfs/close.cpp rename to drivers/filesystems/udfs/close.c index 88b74886c080c..77564a4927e56 100644 --- a/drivers/filesystems/udfs/close.cpp +++ b/drivers/filesystems/udfs/close.c @@ -168,6 +168,7 @@ UDFCommonClose( try_return(RC = STATUS_SUCCESS); } + if ((Vcb->VcbCleanup == 0) && (Vcb->VcbCondition != VcbMounted)) { @@ -470,7 +471,7 @@ Return Value: --*/ { - BOOLEAN RemovedFcb; + BOOLEAN RemovedFcb = FALSE; PAGED_CODE(); @@ -560,7 +561,7 @@ Return Value: THREAD_CONTEXT ThreadContext = {0}; PFCB Fcb; - ULONG UserReference; + ULONG UserReference = 0; ULONG VcbHoldCount = 0; PVCB CurrentVcb = NULL; diff --git a/drivers/filesystems/udfs/create.cpp b/drivers/filesystems/udfs/create.c similarity index 99% rename from drivers/filesystems/udfs/create.cpp rename to drivers/filesystems/udfs/create.c index 8518dcf82256f..6f1fb2ff97564 100644 --- a/drivers/filesystems/udfs/create.cpp +++ b/drivers/filesystems/udfs/create.c @@ -128,6 +128,7 @@ try_exit: NOTHING; } // end UDFSupersedeOrOverwriteFile() + /************************************************************************* * * Function: UDFOpenExistingFcb() @@ -997,6 +998,7 @@ try_exit: NOTHING; * *************************************************************************/ static + VOID UDFNormalizeStreamSuffix( IN PIRP_CONTEXT IrpContext, @@ -1020,6 +1022,7 @@ UDFNormalizeStreamSuffix( return; } + // Check if there's a second ':' at all — if so, it's an unknown stream type PWCHAR buf = Name->Buffer; USHORT len = Name->Length / sizeof(WCHAR); @@ -1030,6 +1033,7 @@ UDFNormalizeStreamSuffix( } } + /************************************************************************* * * Function: UDFCommonCreate() @@ -1289,6 +1293,8 @@ UDFCommonCreate( _SEH2_TRY { + + // Verify that the Vcb is not in an unusable condition. This routine // will raise if not usable. @@ -1360,15 +1366,19 @@ UDFCommonCreate( CreateDisposition == FILE_OVERWRITE_IF || CreateDisposition == FILE_CREATE) { + try_return(Status = STATUS_ACCESS_DENIED); + } CurrentFcb = Vcb->VolumeDasdFcb; // Acquire the Fcb exclusively before completing the open + UDFAcquireFcbExclusive(IrpContext, CurrentFcb, FALSE); + Status = UDFCompleteFcbOpen(IrpContext, IrpSp, Vcb, @@ -1379,7 +1389,9 @@ UDFCommonCreate( FALSE, // VcbLocked FILE_OPENED); // DesiredInformation + try_return(Status); + } if (UDFIllegalFcbAccess(Vcb, DesiredAccess)) { @@ -1406,10 +1418,12 @@ UDFCommonCreate( try_return(Status = STATUS_ACCESS_DENIED); } + try_return(Status = UDFOpenObjectByFileId(IrpContext, IrpSp, Vcb, &CurrentFcb)); + } // @@ -1504,7 +1518,9 @@ UDFCommonCreate( try_return(Status = STATUS_OBJECT_NAME_INVALID); } if (StreamOpen && !UDFIsStreamsSupported(Vcb)) { + try_return(Status = STATUS_OBJECT_NAME_INVALID); + } // RemainingName was set by UDFNormalizeFileNames to point to the relative path @@ -1846,6 +1862,7 @@ UDFCommonCreate( Status = STATUS_OBJECT_NAME_NOT_FOUND; } } + if (NT_SUCCESS(Status)) { // Re-inject stream name: next iteration will search // for FinalName within the stream directory. @@ -1864,6 +1881,7 @@ UDFCommonCreate( &NewFileInfo, &PtrNewFcb); if (NT_SUCCESS(Status)) { LastGoodFileInfo = NewFileInfo; + } else { // FCB setup failed — close stream dir and exit UDFCloseFile__(IrpContext, Vcb, StreamDirInfo); @@ -2027,9 +2045,11 @@ UDFCommonCreate( // ... and exit with error try_return(Status); } + // Note: With LCB model, FcbReference is not incremented during path traversal, // so no decrement is needed here (removed the old InterlockedDecrement). Status = STATUS_SUCCESS; + ASSERT(!OpenTargetDirectory); // Restore PtrNewFcb/NewFileInfo from last good state. // The stream dir branch didn't open anything in this iteration, @@ -2079,8 +2099,10 @@ UDFCommonCreate( // FILE_CREATED, allocation size, attributes, and notification are // all handled inside UDFOpenExistingFcb via CreateDisposition == FILE_CREATE. + LastGoodFileInfo = NewFileInfo; try_return(Status); + } // **************** @@ -2159,10 +2181,12 @@ UDFCommonCreate( // thread can have the file stream open at this time. RelatedFileInfo = OldRelatedFileInfo; + Status = UDFCreateFile__(IrpContext, Vcb, IgnoreCase, &FinalName, 0, 0, UdfIsExtendedFESupported(Vcb), (CreateDisposition == FILE_CREATE), RelatedFileInfo, &NewFileInfo); if (!NT_SUCCESS(Status)) { + AdPrint((" Creation error\n")); try_return(Status); } @@ -2211,6 +2235,8 @@ UDFCommonCreate( } LastGoodFileInfo = NewFileInfo; + + UDFNotifyReportChange(IrpContext, Vcb, NewFileInfo->Fcb, UDFIsADirectory(NewFileInfo) ? FILE_NOTIFY_CHANGE_DIR_NAME : FILE_NOTIFY_CHANGE_FILE_NAME, FILE_ACTION_ADDED, @@ -2243,11 +2269,15 @@ UDFCommonCreate( } LastGoodFileInfo = NewFileInfo; + + // PHASE 2: Create stream file in the stream directory RelatedFileInfo = NewFileInfo; + StreamName.Buffer++; StreamName.Length -= sizeof(WCHAR); Status = UDFCreateFile__(IrpContext, Vcb, IgnoreCase, &StreamName, 0, 0, + UdfIsExtendedFESupported(Vcb), (CreateDisposition == FILE_CREATE), RelatedFileInfo, &NewFileInfo); if (!NT_SUCCESS(Status)) { @@ -2372,8 +2402,10 @@ try_exit: NOTHING; if (NT_SUCCESS(Status) && PtrNewFcb) { + if (DeleteOnClose) { ASSERT(!(PtrNewFcb->FcbState & UDF_FCB_ROOT_DIRECTORY)); + } if (StreamOpen) { @@ -2832,6 +2864,7 @@ UDFCompleteFcbOpen( if (!(Ccb = UDFCreateCcb())) { + return STATUS_INSUFFICIENT_RESOURCES; } @@ -2839,6 +2872,7 @@ UDFCompleteFcbOpen( _SEH2_TRY { + if (AddedAccess) { ClearFlag(DesiredAccess, AddedAccess); @@ -2998,7 +3032,7 @@ UDFCompleteFcbOpen( IrpSp->FileObject->Flags |= FO_NO_INTERMEDIATE_BUFFERING; } else { IrpSp->FileObject->Flags |= FO_CACHE_SUPPORTED; - InterlockedIncrement((PLONG)&Fcb->CachedOpenHandleCount); + InterlockedIncrement(&Fcb->CachedOpenHandleCount); } } else if (TypeOfOpen == UserVolumeOpen) { @@ -3018,6 +3052,7 @@ UDFCompleteFcbOpen( Fcb->FcbState &= ~UDF_FCB_DELAY_CLOSE; + // Increment all reference counts here when CCB is successfully created. // If VcbLocked is TRUE, caller already holds VcbMutex - use simple ++. // If VcbLocked is FALSE, acquire VcbMutex for atomicity. @@ -3026,6 +3061,7 @@ UDFCompleteFcbOpen( UDFLockVcb(IrpContext, Fcb->Vcb); } + // Cleanup counts: Fcb->FcbCleanup++; Fcb->Vcb->VcbCleanup++; diff --git a/drivers/filesystems/udfs/devcntrl.cpp b/drivers/filesystems/udfs/devcntrl.c similarity index 93% rename from drivers/filesystems/udfs/devcntrl.cpp rename to drivers/filesystems/udfs/devcntrl.c index dd0bb0a651baf..adb9cff4e497a 100644 --- a/drivers/filesystems/udfs/devcntrl.cpp +++ b/drivers/filesystems/udfs/devcntrl.c @@ -96,16 +96,24 @@ UdfIsVolumeModifyingScsiOp( NTSTATUS UDFCommonDevControl(PIRP_CONTEXT IrpContext, PIRP Irp) { + BOOLEAN FcbAcquired = FALSE; BOOLEAN DeviceAcquired = FALSE; BOOLEAN IsOpticalWriteRModeActive = FALSE; PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); + BOOLEAN CanWait = FALSE; PCDB Cdb = NULL; PVCB Vcb; PFCB Fcb; PCCB Ccb; - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; TYPE_OF_OPEN TypeOfOpen; - ULONG IoControlCode; + ULONG IoControlCode = 0; + + PAGED_CODE(); + + UDFPrint(("UDFCommonDevControl\n")); + UDFPrint(("Irp = %p\n", Irp)); + UDFPrint(("MinorFunction = %08lx\n", IrpSp->MinorFunction)); PAGED_CODE(); @@ -127,10 +135,13 @@ UDFCommonDevControl(PIRP_CONTEXT IrpContext, PIRP Irp) IsOpticalWriteRModeActive = TRUE; } + CanWait = FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT); + if (TypeOfOpen == UserFileOpen) { UDF_CHECK_PAGING_IO_RESOURCE(Fcb); - UDFAcquireFcbShared(IrpContext, Fcb, FALSE); + UDFAcquireResourceShared(&Fcb->FcbNonpaged->FcbResource, CanWait); + FcbAcquired = TRUE; _SEH2_TRY { @@ -173,7 +184,10 @@ UDFCommonDevControl(PIRP_CONTEXT IrpContext, PIRP Irp) if (DeviceAcquired) UDFReleaseDevice(IrpContext, Vcb, NULL); - UDFReleaseFcb(IrpContext, Fcb); + if (FcbAcquired) { + UDF_CHECK_PAGING_IO_RESOURCE(Fcb); + UDFReleaseResource(&Fcb->FcbNonpaged->FcbResource); + } } _SEH2_END; return Status; @@ -218,7 +232,7 @@ UDFCommonDevControl(PIRP_CONTEXT IrpContext, PIRP Irp) if (!FlagOn(Vcb->VcbState, VCB_STATE_PNP_NOTIFICATION)) { - UDFAcquireVcbExclusive(IrpContext, Vcb, FALSE); + UDFAcquireResourceExclusive(&Vcb->VcbResource, CanWait); if (Vcb->VcbCondition == VcbMounted && FALSE /*IsWritableOpticalMedia()*/) { @@ -233,7 +247,7 @@ UDFCommonDevControl(PIRP_CONTEXT IrpContext, PIRP Irp) } } - UDFReleaseVcb(IrpContext, Vcb); + UDFReleaseResource(&(Vcb->VcbResource)); } break; diff --git a/drivers/filesystems/udfs/dircntrl.cpp b/drivers/filesystems/udfs/dircntrl.c similarity index 97% rename from drivers/filesystems/udfs/dircntrl.cpp rename to drivers/filesystems/udfs/dircntrl.c index c9b2f7d62cf64..b936ba42ba371 100644 --- a/drivers/filesystems/udfs/dircntrl.cpp +++ b/drivers/filesystems/udfs/dircntrl.c @@ -156,9 +156,9 @@ UDFQueryDirectory( BOOLEAN FirstTimeQuery = FALSE; LONG NextMatch = 0; LONG PrevMatch = -1; - ULONG CurrentOffset; - ULONG BaseLength; - ULONG FileNameBytes; + ULONG CurrentOffset = 0; + ULONG BaseLength = 0; + ULONG FileNameBytes = 0; ULONG Information = 0; ULONG LastOffset = 0; BOOLEAN AtLeastOneFound = FALSE; @@ -168,7 +168,7 @@ UDFQueryDirectory( PFILE_BOTH_DIR_INFORMATION BothDirInformation = NULL; // Pointer in callers buffer PFILE_NAMES_INFORMATION NamesInfo; PFILE_ID_BOTH_DIR_INFORMATION IdBothDirInfo = NULL; - ULONG BytesRemainingInBuffer; + ULONG BytesRemainingInBuffer = 0; PHASH_ENTRY cur_hashes = NULL; PDIR_INDEX_ITEM DirNdx; // do some pre-init... @@ -279,7 +279,10 @@ UDFQueryDirectory( // check whether we need to store this search pattern in // the CCB. if (Ccb->DirectorySearchPattern) { - MyFreePool__(Ccb->DirectorySearchPattern->Buffer); + if (Ccb->DirectorySearchPattern->Buffer) { + MyFreePool__(Ccb->DirectorySearchPattern->Buffer); + Ccb->DirectorySearchPattern->Buffer = NULL; + } MyFreePool__(Ccb->DirectorySearchPattern); Ccb->DirectorySearchPattern = NULL; } @@ -297,6 +300,8 @@ UDFQueryDirectory( Ccb->DirectorySearchPattern->MaximumLength = PtrSearchPattern->MaximumLength; Ccb->DirectorySearchPattern->Buffer = (PWCHAR)MyAllocatePool__(NonPagedPool,PtrSearchPattern->MaximumLength); if (!(Ccb->DirectorySearchPattern->Buffer)) { + MyFreePool__(Ccb->DirectorySearchPattern); + Ccb->DirectorySearchPattern = NULL; try_return(RC = STATUS_INSUFFICIENT_RESOURCES); } RtlCopyMemory(Ccb->DirectorySearchPattern->Buffer,PtrSearchPattern->Buffer, diff --git a/drivers/filesystems/udfs/env_spec.cpp b/drivers/filesystems/udfs/env_spec.c similarity index 50% rename from drivers/filesystems/udfs/env_spec.cpp rename to drivers/filesystems/udfs/env_spec.c index 52e1cb5382576..d480750c14407 100644 --- a/drivers/filesystems/udfs/env_spec.cpp +++ b/drivers/filesystems/udfs/env_spec.c @@ -19,6 +19,12 @@ // define the file specific bug-check id #define UDF_BUG_CHECK_ID UDF_FILE_ENV_SPEC +// Maximum size of a single NonPagedPool I/O chunk (1 MB). +// Splitting large transfers into chunks allows them to succeed on systems +// with limited RAM (e.g. 64 MB), where a single large NonPagedPool allocation +// or a single MmProbeAndLockPages call over the full buffer would fail. +#define UDF_MAX_IO_CHUNK_SIZE (1024 * 1024) + #ifdef DBG ULONG UDF_SIMULATE_WRITES=0; #endif //DBG @@ -111,7 +117,7 @@ UDFSyncCompletionRoutine2( Expected Interrupt Level (for execution) : - <= IRQL_DISPATCH_LEVEL + <= APC_LEVEL (MmProbeAndLockPages requires IRQL <= APC_LEVEL) Return Value: STATUS_SUCCESS/Error @@ -129,29 +135,118 @@ UDFPhReadSynchronous( { NTSTATUS RC = STATUS_SUCCESS; LARGE_INTEGER ROffset; - PUDF_PH_CALL_CONTEXT Context; - PIRP Irp; - PIO_STACK_LOCATION IrpSp; - KIRQL CurIrql = KeGetCurrentIrql(); - PVOID IoBuf = NULL; - PVCB Vcb = NULL; - ROffset.QuadPart = Offset; (*ReadBytes) = 0; -/* - // DEBUG !!! - Flags |= PH_TMP_BUFFER; -*/ - if (Flags & PH_TMP_BUFFER) { - IoBuf = Buffer; - } else { - IoBuf = DbgAllocatePoolWithTag(NonPagedPool, ByteCount, 'bNWD'); + + // MmProbeAndLockPages requires IRQL <= APC_LEVEL. + if (KeGetCurrentIrql() > APC_LEVEL) { + UDFPrint((" UDFPhReadSynchronous: called above APC_LEVEL\n")); + ASSERT(FALSE); + return STATUS_INVALID_DEVICE_STATE; } - if (!IoBuf) { - UDFPrint((" !IoBuf\n")); - return STATUS_INSUFFICIENT_RESOURCES; + + if (!(Flags & PH_TMP_BUFFER)) { + // Non-TMP path: issue I/O in NonPagedPool chunks so that large transfers + // (e.g. >= 64 MB) succeed on systems with limited RAM. Each chunk is at + // most UDF_MAX_IO_CHUNK_SIZE bytes, which can always be satisfied by a + // small NonPagedPool allocation. MmBuildMdlForNonPagedPool is used so + // that MmProbeAndLockPages (which could fail under memory pressure) is + // never called on the full transfer buffer. + ULONG BytesLeft = ByteCount; + ULONG BytesDone = 0; + + while (BytesLeft > 0) { + ULONG ChunkSize = min(BytesLeft, UDF_MAX_IO_CHUNK_SIZE); + PVOID ChunkBuf = DbgAllocatePoolWithTag(NonPagedPool, ChunkSize, 'bNWD'); + if (!ChunkBuf) { + RC = STATUS_INSUFFICIENT_RESOURCES; + break; + } + + PUDF_PH_CALL_CONTEXT ChunkCtx = (PUDF_PH_CALL_CONTEXT)MyAllocatePool__(NonPagedPool, sizeof(UDF_PH_CALL_CONTEXT)); + if (!ChunkCtx) { + DbgFreePool(ChunkBuf); + RC = STATUS_INSUFFICIENT_RESOURCES; + break; + } + KeInitializeEvent(&ChunkCtx->event, NotificationEvent, FALSE); + + ROffset.QuadPart = Offset + (LONGLONG)BytesDone; + + // Use MmCreateMdl + MmBuildMdlForNonPagedPool: no page-locking is + // needed for NonPagedPool, so this path works at any memory pressure. + PMDL ChunkMdl = MmCreateMdl(NULL, ChunkBuf, ChunkSize); + if (!ChunkMdl) { + MyFreePool__(ChunkCtx); + DbgFreePool(ChunkBuf); + RC = STATUS_INSUFFICIENT_RESOURCES; + break; + } + MmBuildMdlForNonPagedPool(ChunkMdl); + + PIRP ChunkIrp = IoAllocateIrp(DeviceObject->StackSize, FALSE); + if (!ChunkIrp) { + IoFreeMdl(ChunkMdl); + MyFreePool__(ChunkCtx); + DbgFreePool(ChunkBuf); + RC = STATUS_INSUFFICIENT_RESOURCES; + break; + } + ChunkIrp->MdlAddress = ChunkMdl; + ChunkIrp->UserIosb = &ChunkCtx->IosbToUse; + ChunkIrp->UserEvent = NULL; + ChunkIrp->RequestorMode = KernelMode; + ChunkIrp->Tail.Overlay.Thread = PsGetCurrentThread(); + IoSetCompletionRoutine(ChunkIrp, &UDFAsyncCompletionRoutine, ChunkCtx, TRUE, TRUE, TRUE); + + // Setup the next IRP stack location. + PIO_STACK_LOCATION IrpSp = IoGetNextIrpStackLocation(ChunkIrp); + IrpSp->MajorFunction = IRP_MJ_READ; + IrpSp->Parameters.Read.Length = ChunkSize; + IrpSp->Parameters.Read.ByteOffset = ROffset; + + if (FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WRITE_THROUGH)) { + SetFlag(IrpSp->Flags, SL_WRITE_THROUGH); + } + SetFlag(IrpSp->Flags, SL_OVERRIDE_VERIFY_VOLUME); + + RC = IoCallDriver(DeviceObject, ChunkIrp); + // ChunkIrp and ChunkMdl are freed by UDFAsyncCompletionRoutine. + + if (RC == STATUS_PENDING) { + DbgWaitForSingleObject(&ChunkCtx->event, NULL); + RC = ChunkCtx->IosbToUse.Status; + if (RC == STATUS_DATA_OVERRUN) RC = STATUS_SUCCESS; + } + + if (NT_SUCCESS(RC)) { + ULONG ChunkRead = (ULONG)ChunkCtx->IosbToUse.Information; + RtlCopyMemory((PUCHAR)Buffer + BytesDone, ChunkBuf, ChunkRead); + *ReadBytes += ChunkRead; + BytesDone += ChunkRead; + BytesLeft -= ChunkRead; + + MyFreePool__(ChunkCtx); + DbgFreePool(ChunkBuf); + + // Short read: stop iterating. + if (ChunkRead < ChunkSize) break; + } else { + MyFreePool__(ChunkCtx); + DbgFreePool(ChunkBuf); + break; + } + } + + return RC; } - Context = (PUDF_PH_CALL_CONTEXT)MyAllocatePool__( NonPagedPool, sizeof(UDF_PH_CALL_CONTEXT) ); + + // PH_TMP_BUFFER path: Buffer is already a NonPagedPool buffer from the caller. + // Use a single IRP for the whole transfer (these are always small, e.g. one sector). + PVOID IoBuf = Buffer; + PIRP Irp; + PIO_STACK_LOCATION IrpSp; + PUDF_PH_CALL_CONTEXT Context = (PUDF_PH_CALL_CONTEXT)MyAllocatePool__( NonPagedPool, sizeof(UDF_PH_CALL_CONTEXT) ); if (!Context) { UDFPrint((" !Context\n")); try_return(RC = STATUS_INSUFFICIENT_RESOURCES); @@ -159,30 +254,55 @@ UDFPhReadSynchronous( // Create notification event object to be used to signal the request completion. KeInitializeEvent(&(Context->event), NotificationEvent, FALSE); - if (TRUE || CurIrql > PASSIVE_LEVEL) { - Irp = IoBuildAsynchronousFsdRequest(IRP_MJ_READ, DeviceObject, IoBuf, - ByteCount, &ROffset, &(Context->IosbToUse) ); - if (!Irp) { - UDFPrint((" !irp Async\n")); + { + // Use MmCreateMdl instead of IoAllocateMdl so that large buffers + // (> ~64 MB) are not rejected on Windows XP/Server 2003, where + // IoAllocateMdl returns NULL when the MDL size exceeds MAXUSHORT. + // MmProbeAndLockPages (like IoBuildAsynchronousFsdRequest does) sets + // MDL_PAGES_LOCKED without MDL_SOURCE_IS_NONPAGED_POOL, making + // MmUnlockPages safe in the async completion routine. + PMDL Mdl = MmCreateMdl(NULL, IoBuf, ByteCount); + if (!Mdl) { + UDFPrint((" !Mdl\n")); try_return(RC = STATUS_INSUFFICIENT_RESOURCES); } - MmPrint((" Alloc async Irp MDL=%x, ctx=%x\n", Irp->MdlAddress, Context)); - IoSetCompletionRoutine(Irp, &UDFAsyncCompletionRoutine, - Context, TRUE, TRUE, TRUE ); - } else { - Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ, DeviceObject, IoBuf, - ByteCount, &ROffset, &(Context->event), &(Context->IosbToUse) ); + NTSTATUS LockStatus = STATUS_SUCCESS; + _SEH2_TRY { + // IoWriteAccess: for READ we write data from disk into the buffer. + MmProbeAndLockPages(Mdl, KernelMode, IoWriteAccess); + } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { + LockStatus = _SEH2_GetExceptionCode(); + } _SEH2_END; + if (!NT_SUCCESS(LockStatus)) { + UDFPrint((" !MmProbeAndLockPages read\n")); + IoFreeMdl(Mdl); + try_return(RC = LockStatus); + } + Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE); if (!Irp) { - UDFPrint((" !irp Sync\n")); + UDFPrint((" !irp\n")); + MmUnlockPages(Mdl); + IoFreeMdl(Mdl); try_return(RC = STATUS_INSUFFICIENT_RESOURCES); } + Irp->MdlAddress = Mdl; + Irp->UserIosb = &(Context->IosbToUse); + Irp->UserEvent = NULL; + Irp->RequestorMode = KernelMode; + Irp->Tail.Overlay.Thread = PsGetCurrentThread(); MmPrint((" Alloc Irp MDL=%x, ctx=%x\n", Irp->MdlAddress, Context)); + IoSetCompletionRoutine(Irp, &UDFAsyncCompletionRoutine, + Context, TRUE, TRUE, TRUE); } // Setup the next IRP stack location in the associated Irp for the disk // driver beneath us. + ROffset.QuadPart = Offset; IrpSp = IoGetNextIrpStackLocation(Irp); + IrpSp->MajorFunction = IRP_MJ_READ; + IrpSp->Parameters.Read.Length = ByteCount; + IrpSp->Parameters.Read.ByteOffset = ROffset; // If this Irp is the result of a WriteThough operation, // tell the device to write it through. @@ -201,21 +321,14 @@ UDFPhReadSynchronous( if ((RC = Context->IosbToUse.Status) == STATUS_DATA_OVERRUN) { RC = STATUS_SUCCESS; } -// *ReadBytes = Context->IosbToUse.Information; - } else { -// *ReadBytes = irp->IoStatus.Information; } if (NT_SUCCESS(RC)) { (*ReadBytes) = Context->IosbToUse.Information; } - if (!(Flags & PH_TMP_BUFFER)) { - RtlCopyMemory(Buffer, IoBuf, *ReadBytes); - } try_exit: NOTHING; if (Context) MyFreePool__(Context); - if (IoBuf && !(Flags & PH_TMP_BUFFER)) DbgFreePool(IoBuf); return(RC); } // end UDFPhReadSynchronous() @@ -230,7 +343,7 @@ try_exit: NOTHING; Expected Interrupt Level (for execution) : - <= IRQL_DISPATCH_LEVEL + <= APC_LEVEL (MmProbeAndLockPages requires IRQL <= APC_LEVEL) Return Value: STATUS_SUCCESS/Error @@ -247,12 +360,6 @@ UDFPhWriteSynchronous( { NTSTATUS RC = STATUS_SUCCESS; LARGE_INTEGER ROffset; - PUDF_PH_CALL_CONTEXT Context = NULL; - PIRP irp; - KIRQL CurIrql = KeGetCurrentIrql(); - PVOID IoBuf = NULL; - - PVCB Vcb = NULL; #ifdef DBG if (UDF_SIMULATE_WRITES) { @@ -269,39 +376,166 @@ UDFPhWriteSynchronous( } #endif //DBG - ROffset.QuadPart = Offset; (*WrittenBytes) = 0; - // Utilizing a temporary buffer to circumvent the situation where the IO buffer contains TransitionPage pages. - // This typically occurs during IRP_NOCACHE. Otherwise, an assert occurs within IoBuildAsynchronousFsdRequest. - if (Flags & PH_TMP_BUFFER) { - IoBuf = Buffer; - } else { - IoBuf = DbgAllocatePool(NonPagedPool, ByteCount); - if (!IoBuf) try_return (RC = STATUS_INSUFFICIENT_RESOURCES); - RtlCopyMemory(IoBuf, Buffer, ByteCount); + // MmProbeAndLockPages requires IRQL <= APC_LEVEL. + if (KeGetCurrentIrql() > APC_LEVEL) { + UDFPrint((" UDFPhWriteSynchronous: called above APC_LEVEL\n")); + ASSERT(FALSE); + return STATUS_INVALID_DEVICE_STATE; } - Context = (PUDF_PH_CALL_CONTEXT)MyAllocatePool__( NonPagedPool, sizeof(UDF_PH_CALL_CONTEXT) ); + if (!(Flags & PH_TMP_BUFFER)) { + // Non-TMP path: issue I/O in NonPagedPool chunks so that large transfers + // (e.g. >= 64 MB) succeed on systems with limited RAM. Each chunk is at + // most UDF_MAX_IO_CHUNK_SIZE bytes, which can always be satisfied by a + // small NonPagedPool allocation. MmBuildMdlForNonPagedPool is used so + // that MmProbeAndLockPages (which could fail under memory pressure) is + // never called on the full transfer buffer. + ULONG BytesLeft = ByteCount; + ULONG BytesDone = 0; + + while (BytesLeft > 0) { + ULONG ChunkSize = min(BytesLeft, UDF_MAX_IO_CHUNK_SIZE); + PVOID ChunkBuf = DbgAllocatePoolWithTag(NonPagedPool, ChunkSize, 'bNWD'); + if (!ChunkBuf) { + RC = STATUS_INSUFFICIENT_RESOURCES; + break; + } + RtlCopyMemory(ChunkBuf, (PUCHAR)Buffer + BytesDone, ChunkSize); + + PUDF_PH_CALL_CONTEXT ChunkCtx = (PUDF_PH_CALL_CONTEXT)MyAllocatePool__(NonPagedPool, sizeof(UDF_PH_CALL_CONTEXT)); + if (!ChunkCtx) { + DbgFreePool(ChunkBuf); + RC = STATUS_INSUFFICIENT_RESOURCES; + break; + } + KeInitializeEvent(&ChunkCtx->event, NotificationEvent, FALSE); + + ROffset.QuadPart = Offset + (LONGLONG)BytesDone; + + // Use MmCreateMdl + MmBuildMdlForNonPagedPool: no page-locking is + // needed for NonPagedPool, so this path works at any memory pressure. + PMDL ChunkMdl = MmCreateMdl(NULL, ChunkBuf, ChunkSize); + if (!ChunkMdl) { + MyFreePool__(ChunkCtx); + DbgFreePool(ChunkBuf); + RC = STATUS_INSUFFICIENT_RESOURCES; + break; + } + MmBuildMdlForNonPagedPool(ChunkMdl); + + PIRP ChunkIrp = IoAllocateIrp(DeviceObject->StackSize, FALSE); + if (!ChunkIrp) { + IoFreeMdl(ChunkMdl); + MyFreePool__(ChunkCtx); + DbgFreePool(ChunkBuf); + RC = STATUS_INSUFFICIENT_RESOURCES; + break; + } + ChunkIrp->MdlAddress = ChunkMdl; + ChunkIrp->UserIosb = &ChunkCtx->IosbToUse; + ChunkIrp->UserEvent = NULL; + ChunkIrp->RequestorMode = KernelMode; + ChunkIrp->Tail.Overlay.Thread = PsGetCurrentThread(); + IoSetCompletionRoutine(ChunkIrp, &UDFAsyncCompletionRoutine, ChunkCtx, TRUE, TRUE, TRUE); + + // Setup the next IRP stack location. + PIO_STACK_LOCATION IrpSp = IoGetNextIrpStackLocation(ChunkIrp); + IrpSp->MajorFunction = IRP_MJ_WRITE; + IrpSp->Parameters.Write.Length = ChunkSize; + IrpSp->Parameters.Write.ByteOffset = ROffset; + SetFlag(IrpSp->Flags, SL_OVERRIDE_VERIFY_VOLUME); + + RC = IoCallDriver(DeviceObject, ChunkIrp); + // ChunkIrp and ChunkMdl are freed by UDFAsyncCompletionRoutine. + + if (RC == STATUS_PENDING) { + DbgWaitForSingleObject(&ChunkCtx->event, NULL); + RC = ChunkCtx->IosbToUse.Status; + if (RC == STATUS_DATA_OVERRUN) RC = STATUS_SUCCESS; + } + + if (NT_SUCCESS(RC)) { + ULONG ChunkWritten = (ULONG)ChunkCtx->IosbToUse.Information; + *WrittenBytes += ChunkWritten; + BytesDone += ChunkWritten; + BytesLeft -= ChunkWritten; + + MyFreePool__(ChunkCtx); + DbgFreePool(ChunkBuf); + + // Short write: stop iterating. + if (ChunkWritten < ChunkSize) break; + } else { + MyFreePool__(ChunkCtx); + DbgFreePool(ChunkBuf); + break; + } + } + + if (!NT_SUCCESS(RC)) { + UDFPrint(("WriteError\n")); + } + return RC; + } + + // PH_TMP_BUFFER path: Buffer is already a NonPagedPool buffer from the caller. + // Use a single IRP for the whole transfer (these are always small, e.g. one sector). + PVOID IoBuf = Buffer; + ROffset.QuadPart = Offset; + PIRP irp; + PUDF_PH_CALL_CONTEXT Context = (PUDF_PH_CALL_CONTEXT)MyAllocatePool__( NonPagedPool, sizeof(UDF_PH_CALL_CONTEXT) ); if (!Context) try_return (RC = STATUS_INSUFFICIENT_RESOURCES); // Create notification event object to be used to signal the request completion. KeInitializeEvent(&(Context->event), NotificationEvent, FALSE); - if (TRUE || CurIrql > PASSIVE_LEVEL) { - irp = IoBuildAsynchronousFsdRequest(IRP_MJ_WRITE, DeviceObject, IoBuf, - ByteCount, &ROffset, &(Context->IosbToUse) ); - if (!irp) try_return(RC = STATUS_INSUFFICIENT_RESOURCES); - MmPrint((" Alloc async Irp MDL=%x, ctx=%x\n", irp->MdlAddress, Context)); - IoSetCompletionRoutine( irp, &UDFAsyncCompletionRoutine, - Context, TRUE, TRUE, TRUE ); - } else { - irp = IoBuildSynchronousFsdRequest(IRP_MJ_WRITE, DeviceObject, IoBuf, - ByteCount, &ROffset, &(Context->event), &(Context->IosbToUse) ); - if (!irp) try_return(RC = STATUS_INSUFFICIENT_RESOURCES); - MmPrint((" Alloc Irp MDL=%x\n, ctx=%x", irp->MdlAddress, Context)); + { + // Use MmCreateMdl instead of IoAllocateMdl so that large buffers + // (> ~64 MB) are not rejected on Windows XP/Server 2003, where + // IoAllocateMdl returns NULL when the MDL size exceeds MAXUSHORT. + // MmProbeAndLockPages (like IoBuildAsynchronousFsdRequest does) sets + // MDL_PAGES_LOCKED without MDL_SOURCE_IS_NONPAGED_POOL, making + // MmUnlockPages safe in the async completion routine. + PMDL Mdl = MmCreateMdl(NULL, IoBuf, ByteCount); + if (!Mdl) { + UDFPrint((" !Mdl\n")); + try_return(RC = STATUS_INSUFFICIENT_RESOURCES); + } + NTSTATUS LockStatus = STATUS_SUCCESS; + _SEH2_TRY { + // IoReadAccess: for WRITE we read data from the buffer to send to disk. + MmProbeAndLockPages(Mdl, KernelMode, IoReadAccess); + } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { + LockStatus = _SEH2_GetExceptionCode(); + } _SEH2_END; + if (!NT_SUCCESS(LockStatus)) { + UDFPrint((" !MmProbeAndLockPages write\n")); + IoFreeMdl(Mdl); + try_return(RC = LockStatus); + } + irp = IoAllocateIrp(DeviceObject->StackSize, FALSE); + if (!irp) { + UDFPrint((" !irp\n")); + MmUnlockPages(Mdl); + IoFreeMdl(Mdl); + try_return(RC = STATUS_INSUFFICIENT_RESOURCES); + } + irp->MdlAddress = Mdl; + irp->UserIosb = &(Context->IosbToUse); + irp->UserEvent = NULL; + irp->RequestorMode = KernelMode; + irp->Tail.Overlay.Thread = PsGetCurrentThread(); + MmPrint((" Alloc Irp MDL=%x, ctx=%x\n", irp->MdlAddress, Context)); + IoSetCompletionRoutine(irp, &UDFAsyncCompletionRoutine, + Context, TRUE, TRUE, TRUE); } - (IoGetNextIrpStackLocation(irp))->Flags |= SL_OVERRIDE_VERIFY_VOLUME; + PIO_STACK_LOCATION IrpSp = IoGetNextIrpStackLocation(irp); + IrpSp->MajorFunction = IRP_MJ_WRITE; + IrpSp->Parameters.Write.Length = ByteCount; + IrpSp->Parameters.Write.ByteOffset = ROffset; + SetFlag(IrpSp->Flags, SL_OVERRIDE_VERIFY_VOLUME); RC = IoCallDriver(DeviceObject, irp); if (RC == STATUS_PENDING) { @@ -309,9 +543,6 @@ UDFPhWriteSynchronous( if ((RC = Context->IosbToUse.Status) == STATUS_DATA_OVERRUN) { RC = STATUS_SUCCESS; } -// *WrittenBytes = Context->IosbToUse.Information; - } else { -// *WrittenBytes = irp->IoStatus.Information; } if (NT_SUCCESS(RC)) { (*WrittenBytes) = Context->IosbToUse.Information; @@ -320,7 +551,6 @@ UDFPhWriteSynchronous( try_exit: NOTHING; if (Context) MyFreePool__(Context); - if (IoBuf && !(Flags & PH_TMP_BUFFER)) DbgFreePool(IoBuf); if (!NT_SUCCESS(RC)) { UDFPrint(("WriteError\n")); } @@ -342,7 +572,7 @@ UDFTSendIOCTL( ) { NTSTATUS RC = STATUS_SUCCESS; - BOOLEAN Acquired; + BOOLEAN Acquired = FALSE; Acquired = UDFAcquireResourceExclusiveWithCheck(&(Vcb->IoResource)); @@ -556,5 +786,6 @@ UDFNotifyReportChange( if (PathAllocated && FullPath.Buffer) { ExFreePool(FullPath.Buffer); } + } diff --git a/drivers/filesystems/udfs/fastio.cpp b/drivers/filesystems/udfs/fastio.c similarity index 99% rename from drivers/filesystems/udfs/fastio.cpp rename to drivers/filesystems/udfs/fastio.c index 9bdbac17b3f40..caf6f8dcf6672 100644 --- a/drivers/filesystems/udfs/fastio.cpp +++ b/drivers/filesystems/udfs/fastio.c @@ -899,7 +899,7 @@ UDFFastIoAcqModWrite( // For embedded data files, acquire exclusive since data shares sector with metadata // For normal files, shared is enough - BOOLEAN Acquired; + BOOLEAN Acquired = FALSE; if (Fcb->FcbState & UDF_FCB_EMBEDDED_DATA) { Acquired = UDFAcquireResourceExclusive(&Fcb->FcbNonpaged->FcbResource, FALSE); } else { diff --git a/drivers/filesystems/udfs/fileinfo.cpp b/drivers/filesystems/udfs/fileinfo.c similarity index 99% rename from drivers/filesystems/udfs/fileinfo.cpp rename to drivers/filesystems/udfs/fileinfo.c index 92fcd88eaf98e..9b5977e6fa684 100644 --- a/drivers/filesystems/udfs/fileinfo.cpp +++ b/drivers/filesystems/udfs/fileinfo.c @@ -1683,12 +1683,12 @@ UDFSetEndOfFileInfo( // reference file to pretend that it is opened UDFReferenceFile__(Fcb->FileInfo); - InterlockedIncrement((PLONG)&Fcb->FcbReference); + InterlockedIncrement(&Fcb->FcbReference); // perform resize operation RC = UDFResizeFile__(IrpContext, Vcb, Fcb->FileInfo, PtrBuffer->EndOfFile.QuadPart); // dereference file UDFCloseFile__(IrpContext, Vcb, Fcb->FileInfo); - InterlockedDecrement((PLONG)&Fcb->FcbReference); + InterlockedDecrement(&Fcb->FcbReference); // update values in NtReqFcb Fcb->Header.FileSize.QuadPart = // NtReqFcb->CommonFCBHeader.ValidDataLength.QuadPart = @@ -1713,12 +1713,12 @@ UDFSetEndOfFileInfo( // Perform directory entry modifications. Release any on-disk // space we may need to in the process. UDFReferenceFile__(Fcb->FileInfo); - InterlockedIncrement((PLONG)&Fcb->FcbReference); + InterlockedIncrement(&Fcb->FcbReference); // perform resize operation RC = UDFResizeFile__(IrpContext, Vcb, Fcb->FileInfo, PtrBuffer->EndOfFile.QuadPart); // dereference file UDFCloseFile__(IrpContext, Vcb, Fcb->FileInfo); - InterlockedDecrement((PLONG)&Fcb->FcbReference); + InterlockedDecrement(&Fcb->FcbReference); ModifiedAllocSize = TRUE; TruncatedFile = TRUE; @@ -1840,17 +1840,20 @@ UDFPrepareForRenameMoveLink( // There is a pair of objects among input dirs & // one of them is a parent of another. Sequential resource // acquisition may lead to deadlock due to concurrent + // cleanup operations or UDFTeardownStructures() - InterlockedIncrement((PLONG)&Vcb->VcbReference); + + InterlockedIncrement(&Vcb->VcbReference); (*SingleDir) = ((Dir1 == Dir2) && (Dir1->Fcb)); if (!(*SingleDir) || (UDFGetFileLinkCount(File1) != 1)) { - InterlockedDecrement((PLONG)&Vcb->VcbReference); + InterlockedDecrement(&Vcb->VcbReference); } else { - InterlockedDecrement((PLONG)&Vcb->VcbReference); + InterlockedDecrement(&Vcb->VcbReference); + // Child-first lock ordering // File1 (child) first, Dir1 (parent) second @@ -1858,6 +1861,7 @@ UDFPrepareForRenameMoveLink( UDFAcquireFcbExclusive(IrpContext, File1->Fcb, TRUE); (*AcquiredFcb1) = TRUE; + UDF_CHECK_PAGING_IO_RESOURCE(Dir1->Fcb); UDFAcquireFcbExclusive(IrpContext, Dir1->Fcb, TRUE); (*AcquiredDir1) = TRUE; @@ -2284,6 +2288,7 @@ UDFSetRenameInfo( ? FILE_NOTIFY_CHANGE_DIR_NAME : FILE_NOTIFY_CHANGE_FILE_NAME; + // Step 1: Notify OLD location (LCB still points to old parent) // Use FileObject->FileName — stable path independent of LCB chain if (SingleDir && !ReplaceIfExists) { @@ -2292,8 +2297,10 @@ UDFSetRenameInfo( } else { UDFNotifyReportChange(IrpContext, Vcb, Fcb, Filter, FILE_ACTION_REMOVED, Ccb->Lcb, FileObject); + } + // Step 2: Move LCB to new parent and update name if (Ccb->Lcb) { RC = UDFRenameMovePrefix(IrpContext, Ccb->Lcb, &NewName, @@ -2306,6 +2313,7 @@ UDFSetRenameInfo( // Step 3: Update FCB parent pointer for cross-directory rename if (!SingleDir) { Fcb->ParentFcb = TargetDirInfo->Fcb; + } // Step 4: Notify NEW location (LCB now points to new parent) diff --git a/drivers/filesystems/udfs/filobsup.cpp b/drivers/filesystems/udfs/filobsup.c similarity index 100% rename from drivers/filesystems/udfs/filobsup.cpp rename to drivers/filesystems/udfs/filobsup.c diff --git a/drivers/filesystems/udfs/flush.cpp b/drivers/filesystems/udfs/flush.c similarity index 95% rename from drivers/filesystems/udfs/flush.cpp rename to drivers/filesystems/udfs/flush.c index 65240f50e2a7e..205c6676d8f25 100644 --- a/drivers/filesystems/udfs/flush.cpp +++ b/drivers/filesystems/udfs/flush.c @@ -112,9 +112,11 @@ UDFCommonFlush( // action we take. if ((Fcb == Fcb->Vcb->VolumeDasdFcb) || (Fcb->FcbState & UDF_FCB_ROOT_DIRECTORY)) { +#ifdef UDF_DELAYED_CLOSE UDFFspClose(Vcb); +#endif //UDF_DELAYED_CLOSE - UDFAcquireVcbExclusive(IrpContext, Vcb, FALSE); + UDFAcquireResourceExclusive(&(Vcb->VcbResource), TRUE); AcquiredVCB = TRUE; // The caller wishes to flush all files for the mounted // logical volume. The flush volume routine below should simply @@ -127,7 +129,7 @@ UDFCommonFlush( UDFFlushVolume(IrpContext, Vcb); - UDFReleaseVcb(IrpContext, Vcb); + UDFReleaseResource(&(Vcb->VcbResource)); AcquiredVCB = FALSE; try_return(Status); @@ -137,18 +139,16 @@ UDFCommonFlush( Vcb = Fcb->Vcb; ASSERT(Vcb); - // Child-first lock ordering - UDF_CHECK_PAGING_IO_RESOURCE(Fcb); - UDFAcquireFcbExclusive(IrpContext, Fcb, FALSE); - AcquiredFCB = TRUE; - - // Parent second (needed for DirIndex modification in UDFSetFileSizeInDirNdx) if (Fcb->FileInfo->ParentFile && Fcb->FileInfo->ParentFile->Fcb) { UDF_CHECK_PAGING_IO_RESOURCE(Fcb->FileInfo->ParentFile->Fcb); - UDFAcquireFcbExclusive(IrpContext, Fcb->FileInfo->ParentFile->Fcb, FALSE); + UDFAcquireResourceExclusive(&Fcb->FileInfo->ParentFile->Fcb->FcbNonpaged->FcbResource, TRUE); AcquiredParentFcb = TRUE; } + UDF_CHECK_PAGING_IO_RESOURCE(Fcb); + UDFAcquireResourceExclusive(&Fcb->FcbNonpaged->FcbResource, TRUE); + AcquiredFCB = TRUE; + // Request the Cache Manager to perform a flush operation. // Further, instruct the Cache Manager that we wish to flush the // entire file stream. @@ -168,25 +168,26 @@ try_exit: NOTHING; } _SEH2_FINALLY { - // Release in reverse order of acquisition (parent first, then child) - if (AcquiredParentFcb) { - UDFReleaseFcb(IrpContext, Fcb->FileInfo->ParentFile->Fcb); - AcquiredParentFcb = FALSE; - } - if (AcquiredFCB) { - UDFReleaseFcb(IrpContext, Fcb); + UDF_CHECK_PAGING_IO_RESOURCE(Fcb); + UDFReleaseResource(&Fcb->FcbNonpaged->FcbResource); AcquiredFCB = FALSE; } + if (AcquiredParentFcb) { + UDF_CHECK_PAGING_IO_RESOURCE(Fcb->FileInfo->ParentFile->Fcb); + UDFReleaseResource(&Fcb->FileInfo->ParentFile->Fcb->FcbNonpaged->FcbResource); + AcquiredParentFcb = FALSE; + } + if (AcquiredVCB) { - UDFReleaseVcb(IrpContext, Vcb); + UDFReleaseResource(&Vcb->VcbResource); AcquiredVCB = FALSE; } if (!_SEH2_AbnormalTermination()) { - NTSTATUS DriverStatus; + NTSTATUS DriverStatus = STATUS_SUCCESS; // Get the next stack location, and copy over the stack location @@ -304,7 +305,7 @@ UDFFlushAFile( _SEH2_TRY { if (SetArchive && (Fcb->Vcb->CompatFlags & UDF_VCB_IC_UPDATE_ARCH_BIT)) { - ULONG Attr; + ULONG Attr = 0; PDIR_INDEX_ITEM DirNdx; DirNdx = UDFDirIndex(UDFGetDirIndexByFileInfo(Fcb->FileInfo), Fcb->FileInfo->Index); // Archive bit @@ -626,7 +627,7 @@ Return Value: { KEVENT Event; - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; PIO_STACK_LOCATION NextIrpSp; PAGED_CODE(); diff --git a/drivers/filesystems/udfs/fscntrl.cpp b/drivers/filesystems/udfs/fscntrl.c similarity index 97% rename from drivers/filesystems/udfs/fscntrl.cpp rename to drivers/filesystems/udfs/fscntrl.c index 74982610e6a43..4a91bd427ef55 100644 --- a/drivers/filesystems/udfs/fscntrl.cpp +++ b/drivers/filesystems/udfs/fscntrl.c @@ -49,7 +49,7 @@ UDFCommonFsControl( PIRP Irp ) { - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); PAGED_CODE(); @@ -108,7 +108,7 @@ UDFUserFsCtrlRequest( PIRP Irp ) { - NTSTATUS RC; + NTSTATUS RC = STATUS_SUCCESS; PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); // Case on the control code. @@ -277,7 +277,7 @@ UDFMountVolume( IN PIRP Irp ) { - NTSTATUS RC; + NTSTATUS RC = STATUS_SUCCESS; PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); PDEVICE_OBJECT DeviceObjectWeTalkTo = IrpSp->Parameters.MountVolume.DeviceObject; PVPB Vpb = IrpSp->Parameters.MountVolume.Vpb; @@ -288,7 +288,7 @@ UDFMountVolume( DEVICE_TYPE FsDeviceType; BOOLEAN RestoreDoVerify = FALSE; BOOLEAN RemovableMedia = TRUE; - BOOLEAN SetDoVerifyOnFail; + BOOLEAN SetDoVerifyOnFail = FALSE; BOOLEAN VcbAcquired = FALSE; BOOLEAN DeviceNotTouched = TRUE; DISK_GEOMETRY DiskGeometry; @@ -471,7 +471,7 @@ UDFMountVolume( // but simply cleanup and return error, Vcb->VcbReference // will be decremented during cleanup. Thus anyway it must // stay 1 unchanged here - //InterlockedDecrement((PLONG)&Vcb->VcbReference); + //InterlockedDecrement(&Vcb->VcbReference); UDFCloseResidual(IrpContext, Vcb); Vcb->VcbReference = 1; @@ -525,7 +525,7 @@ try_exit: NOTHING; } // Make sure there is no Vcb since it could go away if (Vcb->VcbReference) - InterlockedDecrement((PLONG)&Vcb->VcbReference); + InterlockedDecrement(&Vcb->VcbReference); // This procedure will also delete the volume device object if (UDFDismountVcb(IrpContext, Vcb, FALSE)) { UDFReleaseResource( &(Vcb->VcbResource) ); @@ -575,7 +575,7 @@ UDFCloseResidual( { // Deinitialize Non-alloc file if (Vcb->VcbReference) - InterlockedDecrement((PLONG)&Vcb->VcbReference); + InterlockedDecrement(&Vcb->VcbReference); UDFPrint(("UDFCloseResidual: NonAllocFileInfo %x\n", Vcb->NonAllocFileInfo)); if (Vcb->NonAllocFileInfo) { UDFCloseFile__(IrpContext, Vcb, Vcb->NonAllocFileInfo); @@ -650,7 +650,7 @@ UDFCloseResidual( } // Remove root FCB reference in vcb if (Vcb->VcbReference) - InterlockedDecrement((PLONG)&Vcb->VcbReference); + InterlockedDecrement(&Vcb->VcbReference); Vcb->RootIndexFcb = NULL; } } // end UDFCloseResidual() @@ -669,16 +669,19 @@ UDFCleanupVCB( MyFreeMemoryAndPointer(Vcb->Partitions); MyFreeMemoryAndPointer(Vcb->LVid); - MyFreeMemoryAndPointer(Vcb->Vat); + if (Vcb->Vat) { + UDFFreeChunked(Vcb->Vat); + Vcb->Vat = NULL; + } MyFreeMemoryAndPointer(Vcb->SparingTable); if (Vcb->FSBM_Bitmap) { - DbgFreePool(Vcb->FSBM_Bitmap); + UDFFreeChunked(Vcb->FSBM_Bitmap); Vcb->FSBM_Bitmap = NULL; } if (Vcb->BSBM_Bitmap) { - DbgFreePool(Vcb->BSBM_Bitmap); + UDFFreeChunked(Vcb->BSBM_Bitmap); Vcb->BSBM_Bitmap = NULL; } #ifdef UDF_TRACK_ONDISK_ALLOCATION_OWNERS @@ -688,7 +691,7 @@ UDFCleanupVCB( } #endif //UDF_TRACK_ONDISK_ALLOCATION_OWNERS if (Vcb->FSBM_OldBitmap) { - DbgFreePool(Vcb->FSBM_OldBitmap); + UDFFreeChunked(Vcb->FSBM_OldBitmap); Vcb->FSBM_OldBitmap = NULL; } @@ -886,7 +889,7 @@ UDFLockVolume( IN PIRP Irp ) { - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; PVCB Vcb; PFCB Fcb; PCCB Ccb; @@ -981,7 +984,7 @@ Return Value: --*/ { - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; KIRQL SavedIrql; NTSTATUS FinalStatus = (FileObject? STATUS_ACCESS_DENIED: STATUS_DEVICE_BUSY); ULONG RemainingUserReferences = (FileObject? 1: 0); @@ -1071,7 +1074,7 @@ UDFUnlockVolume( IN PIRP Irp ) { - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); PVCB Vcb; PFCB Fcb; @@ -1135,7 +1138,7 @@ UDFDismountVolume( IN PIRP Irp ) { - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; KIRQL SavedIrql; PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); @@ -1261,16 +1264,16 @@ UDFGetVolumeBitmap( PFCB Fcb; PCCB Ccb; PVCB Vcb = IrpContext->Vcb; - ULONG BytesToCopy; - ULONG TotalClusters; - ULONG StartingCluster; - ULONG DesiredClusters; - ULONG InputBufferLength; - ULONG OutputBufferLength; + ULONG BytesToCopy = 0; + ULONG TotalClusters = 0; + ULONG StartingCluster = 0; + ULONG DesiredClusters = 0; + ULONG InputBufferLength = 0; + ULONG OutputBufferLength = 0; LARGE_INTEGER StartingLcn; PVOLUME_BITMAP_BUFFER OutputBuffer; ULONG i, lim; - PULONG FSBM; + PULONG FSBM = NULL; BOOLEAN VcbAcquired = FALSE; ASSERT_VCB(Vcb); @@ -1411,13 +1414,13 @@ UDFGetRetrievalPointers( IN PIRP Irp ) { - NTSTATUS RC; + NTSTATUS RC = STATUS_SUCCESS; PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); PUDF_FILE_INFO FileInfo; - ULONG InputBufferLength; - ULONG OutputBufferLength; + ULONG InputBufferLength = 0; + ULONG OutputBufferLength = 0; PRETRIEVAL_POINTERS_BUFFER OutputBuffer; PSTARTING_VCN_INPUT_BUFFER InputBuffer; @@ -1431,10 +1434,10 @@ UDFGetRetrievalPointers( TYPE_OF_OPEN TypeOfOpen; PEXTENT_MAP SubMapping = NULL; - ULONG SubExtInfoSz; - ULONG i; - ULONG LBS; - ULONG LBSh; + ULONG SubExtInfoSz = 0; + ULONG i = 0; + ULONG LBS = 0; + ULONG LBSh = 0; UDFPrint(("UDFGetRetrievalPointers\n")); @@ -1572,7 +1575,7 @@ UDFIsVolumeDirty( IN PIRP Irp ) { - PULONG VolumeState; + PULONG VolumeState = NULL; PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); PCCB Ccb; PFCB Fcb; @@ -1663,7 +1666,7 @@ UDFInvalidateVolumes( IN PIRP Irp ) { - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); UDFPrint(("UDFInvalidateVolumes\n")); diff --git a/drivers/filesystems/udfs/lockctrl.cpp b/drivers/filesystems/udfs/lockctrl.c similarity index 100% rename from drivers/filesystems/udfs/lockctrl.cpp rename to drivers/filesystems/udfs/lockctrl.c diff --git a/drivers/filesystems/udfs/mem.cpp b/drivers/filesystems/udfs/mem.c similarity index 93% rename from drivers/filesystems/udfs/mem.cpp rename to drivers/filesystems/udfs/mem.c index 072602c852327..301ead0d8ba72 100644 --- a/drivers/filesystems/udfs/mem.cpp +++ b/drivers/filesystems/udfs/mem.c @@ -8,4 +8,4 @@ // define the file specific bug-check id #define UDF_BUG_CHECK_ID UDF_FILE_MEM -#include "Include/mem_tools.cpp" +#include "Include/mem_tools.c" diff --git a/drivers/filesystems/udfs/misc.cpp b/drivers/filesystems/udfs/misc.c similarity index 98% rename from drivers/filesystems/udfs/misc.cpp rename to drivers/filesystems/udfs/misc.c index 75765fe90ce48..bb15714b9b1f5 100644 --- a/drivers/filesystems/udfs/misc.cpp +++ b/drivers/filesystems/udfs/misc.c @@ -60,7 +60,7 @@ UDFExceptionFilter( PEXCEPTION_POINTERS ExceptionPointer ) { - NTSTATUS ExceptionCode; + NTSTATUS ExceptionCode = STATUS_SUCCESS; ASSERT_OPTIONAL_IRP_CONTEXT(IrpContext); @@ -188,7 +188,7 @@ UDFProcessException( } else if ((ExceptionCode == STATUS_VERIFY_REQUIRED) && FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_TOP_LEVEL) && - KeAreAllApcsDisabled()) { + (KeGetCurrentIrql() >= APC_LEVEL)) { ExceptionCode = UDFFsdPostRequest(IrpContext, Irp); } @@ -733,7 +733,7 @@ Return Value: { PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); - BOOLEAN RemovedFcb; + BOOLEAN RemovedFcb = FALSE; PAGED_CODE(); @@ -967,7 +967,7 @@ UDFFspDispatch( { THREAD_CONTEXT ThreadContext = { 0 }; PIRP_CONTEXT IrpContext = (PIRP_CONTEXT)Context; - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; PIRP Irp = IrpContext->Irp; PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); @@ -1486,8 +1486,8 @@ UDFSetModified( IN PVCB Vcb ) { - if (InterlockedIncrement((PLONG) & (Vcb->Modified)) & 0x80000000) - Vcb->Modified = 2; + if (InterlockedIncrement(&Vcb->Modified) & 0x80000000) + InterlockedExchange(&Vcb->Modified, 2); } // end UDFSetModified() VOID @@ -1495,7 +1495,7 @@ UDFPreClrModified( IN PVCB Vcb ) { - Vcb->Modified = 1; + InterlockedExchange(&Vcb->Modified, 1); } // end UDFPreClrModified() VOID @@ -1504,7 +1504,7 @@ UDFClrModified( ) { UDFPrint(("ClrModified\n")); - InterlockedDecrement((PLONG)&Vcb->Modified); + InterlockedDecrement(&Vcb->Modified); } // end UDFClrModified() NTSTATUS @@ -1524,7 +1524,10 @@ UDFToggleMediaEjectDisable ( } else { - Vcb->VcbState ^= UDF_VCB_FLAGS_MEDIA_LOCKED; + if (PreventRemoval) + InterlockedOr((volatile LONG*)&Vcb->VcbState, UDF_VCB_FLAGS_MEDIA_LOCKED); + else + InterlockedAnd((volatile LONG*)&Vcb->VcbState, ~UDF_VCB_FLAGS_MEDIA_LOCKED); } Prevent.PreventMediaRemoval = PreventRemoval; @@ -1742,7 +1745,7 @@ Return Value: { BOOLEAN Wait = FALSE; - BOOLEAN Acquired; + BOOLEAN Acquired = FALSE; PAGED_CODE(); // We look first at the IgnoreWait flag, next at the flag in the Irp @@ -1867,5 +1870,5 @@ UDFWaitForIoAtEof( return TRUE; } -#include "Include/regtools.cpp" +#include "Include/regtools.c" diff --git a/drivers/filesystems/udfs/namesup.cpp b/drivers/filesystems/udfs/namesup.c similarity index 100% rename from drivers/filesystems/udfs/namesup.cpp rename to drivers/filesystems/udfs/namesup.c diff --git a/drivers/filesystems/udfs/pnp.cpp b/drivers/filesystems/udfs/pnp.c similarity index 99% rename from drivers/filesystems/udfs/pnp.cpp rename to drivers/filesystems/udfs/pnp.c index 55b1e02f0eeb3..1569d5312da4d 100644 --- a/drivers/filesystems/udfs/pnp.cpp +++ b/drivers/filesystems/udfs/pnp.c @@ -228,7 +228,7 @@ Return Value: --*/ { - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; KEVENT Event; BOOLEAN VcbPresent = TRUE; @@ -399,7 +399,7 @@ Return Value: --*/ { - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; KEVENT Event; BOOLEAN VcbPresent = TRUE; @@ -542,7 +542,7 @@ Return Value: --*/ { - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; KEVENT Event; BOOLEAN VcbPresent = TRUE; @@ -660,7 +660,7 @@ Return Value: --*/ { - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; PAGED_CODE(); diff --git a/drivers/filesystems/udfs/prefxsup.cpp b/drivers/filesystems/udfs/prefxsup.c similarity index 99% rename from drivers/filesystems/udfs/prefxsup.cpp rename to drivers/filesystems/udfs/prefxsup.c index 5bc2a4ff3aeda..7c1b0223a243d 100644 --- a/drivers/filesystems/udfs/prefxsup.cpp +++ b/drivers/filesystems/udfs/prefxsup.c @@ -577,7 +577,7 @@ UDFAcquirePrefix( // Increment parent refs immediately after LCB creation. // These will be decremented in UDFTeardownStructures when LCB is removed. // - InterlockedIncrement((PLONG)&ParentFcb->FcbReference); + InterlockedIncrement(&ParentFcb->FcbReference); if (ParentFcb->FileInfo) { UDFReferenceFile__(ParentFcb->FileInfo); } @@ -609,7 +609,7 @@ UDFReleasePrefix( ASSERT(Lcb->NodeIdentifier.NodeTypeCode == UDF_NODE_TYPE_LCB); ASSERT(Lcb->Reference > 0); - InterlockedDecrement((PLONG)&Lcb->Reference); + InterlockedDecrement(&Lcb->Reference); } // end UDFReleasePrefix() @@ -899,7 +899,7 @@ UDFReleasePrefixImmediate( // // Decrement reference // - NewRef = InterlockedDecrement((PLONG)&Lcb->Reference); + NewRef = InterlockedDecrement(&Lcb->Reference); if (NewRef > 0) { // @@ -925,7 +925,7 @@ UDFReleasePrefixImmediate( // if (ParentFcb) { ASSERT(ParentFcb->FcbReference > 0); - InterlockedDecrement((PLONG)&ParentFcb->FcbReference); + InterlockedDecrement(&ParentFcb->FcbReference); // // Close parent's FileInfo if requested @@ -1314,14 +1314,14 @@ UDFRenameMovePrefix( // Adjust reference counts if (OldParentFcb) { ASSERT(OldParentFcb->FcbReference > 0); - InterlockedDecrement((PLONG)&OldParentFcb->FcbReference); + InterlockedDecrement(&OldParentFcb->FcbReference); if (OldParentFileInfo && OldParentFcb->Vcb) { UDFCloseFile__(IrpContext, OldParentFcb->Vcb, OldParentFileInfo); } } - InterlockedIncrement((PLONG)&NewParentFcb->FcbReference); + InterlockedIncrement(&NewParentFcb->FcbReference); if (NewParentFcb->FileInfo) { UDFReferenceFile__(NewParentFcb->FileInfo); diff --git a/drivers/filesystems/udfs/protos.h b/drivers/filesystems/udfs/protos.h index acaa3cd52b8b4..c9d3b961797c9 100644 --- a/drivers/filesystems/udfs/protos.h +++ b/drivers/filesystems/udfs/protos.h @@ -693,6 +693,8 @@ UDFFastUnlockAllByKey( * Prototypes for the file misc.cpp *************************************************************************/ + + _IRQL_requires_max_(APC_LEVEL) __drv_dispatchType(DRIVER_DISPATCH) __drv_dispatchType(IRP_MJ_CREATE) @@ -868,6 +870,8 @@ UDFInsertFcbIntoTable( _In_ PFCB Fcb ); + + _Ret_valid_ PIRP_CONTEXT UDFCreateIrpContext( _In_ PIRP Irp, @@ -1047,7 +1051,7 @@ UDFCommonShutdown( /************************************************************************* * Prototypes for the file UDFinit.cpp *************************************************************************/ -extern "C" NTSTATUS NTAPI DriverEntry( +NTSTATUS NTAPI DriverEntry( PDRIVER_OBJECT DriverObject, // created by the I/O sub-system PUNICODE_STRING RegistryPath); // path to the registry key @@ -1337,6 +1341,8 @@ enum TYPE_OF_ACQUIRE { }; +typedef enum TYPE_OF_ACQUIRE TYPE_OF_ACQUIRE; + _Requires_lock_held_(_Global_critical_region_) _When_(Type == AcquireExclusive && return != FALSE, _Acquires_exclusive_lock_(*Resource)) _When_(Type == AcquireShared && return != FALSE, _Acquires_shared_lock_(*Resource)) @@ -1380,10 +1386,13 @@ UDFAcquireResource( #define UDFAcquirePagingIoExclusive(IC,F) \ UDFAcquireResource((IC), (F)->Header.PagingIoResource, FALSE, AcquireExclusive) +#define UDFAcquirePagingIoShared(IC,F) \ + UDFAcquireResource((IC), (F)->Header.PagingIoResource, FALSE, AcquireShared) + #define UDFReleasePagingIo(IC,F) \ ExReleaseResourceLite((F)->Header.PagingIoResource) -inline +static inline ULONG UDFHighBit( ULONG Word @@ -1407,7 +1416,7 @@ UDFHighBit( #define SectorSize(V) ((V)->SectorSize) -inline +static inline ULONG SectorAlign( PVCB Vcb, @@ -1417,7 +1426,7 @@ SectorAlign( return (Length + (Vcb->SectorSize - 1)) & ~(Vcb->SectorSize - 1); } -inline +static inline ULONGLONG LlSectorAlign( PVCB Vcb, @@ -1439,7 +1448,7 @@ UDFSetThreadContext( (IC)->ThreadContext = NULL -inline +static inline BOOLEAN UdfIsExtendedFESupported( _In_ PVCB Vcb ) @@ -1447,7 +1456,7 @@ BOOLEAN UdfIsExtendedFESupported( return Vcb->NSRDesc == VRS_NSR03_FOUND; } -inline +static inline BOOLEAN UDFIsStreamsSupported( _In_ PVCB Vcb ) diff --git a/drivers/filesystems/udfs/read.cpp b/drivers/filesystems/udfs/read.c similarity index 94% rename from drivers/filesystems/udfs/read.cpp rename to drivers/filesystems/udfs/read.c index c920331dee579..202f91d30f53a 100644 --- a/drivers/filesystems/udfs/read.cpp +++ b/drivers/filesystems/udfs/read.c @@ -56,8 +56,8 @@ UDFCommonRead( PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); LONGLONG StartingOffset; LONGLONG ByteRange; - ULONG ReadLength; - ULONG ByteCount; + ULONG ReadLength = 0; + ULONG ByteCount = 0; ULONG NumberBytesRead = 0; LONGLONG FileSize; TYPE_OF_OPEN TypeOfOpen; @@ -66,12 +66,13 @@ UDFCommonRead( PVCB Vcb = NULL; BOOLEAN VcbAcquired = FALSE; BOOLEAN FcbAcquired = FALSE; + BOOLEAN PagingIoResourceAcquired = FALSE; PVOID SystemBuffer = NULL; - BOOLEAN Wait; - BOOLEAN PagingIo; - BOOLEAN NonCachedIo; - BOOLEAN SynchronousIo; + BOOLEAN Wait = FALSE; + BOOLEAN PagingIo = FALSE; + BOOLEAN NonCachedIo = FALSE; + BOOLEAN SynchronousIo = FALSE; // Read request byte range visualization: // @@ -154,9 +155,16 @@ UDFCommonRead( // Acquire the appropriate FCB resource shared if (PagingIo) { - + // Don't offload jobs when doing paging IO - otherwise this can lead to + // deadlocks in CcCopyRead. + Wait = true; UDFAcquireFcbSharedStarveExclusive(IrpContext, Fcb, FALSE); FcbAcquired = TRUE; + // Acquire PagingIo resource shared to serialize with writes that hold + // it exclusively while modifying the extent mapping (UDFResizeExtent). + // This prevents a use-after-free when iterating DataLoc.Mapping. + UDFAcquirePagingIoShared(IrpContext, Fcb); + PagingIoResourceAcquired = TRUE; } else { @@ -309,6 +317,7 @@ UDFCommonRead( Status = UDFReadFile__(IrpContext, Vcb, Fcb->FileInfo, StartingOffset, ByteCount, FALSE, (PCHAR)SystemBuffer, &NumberBytesRead); + /* // AFAIU, CacheManager wants this: if (!NT_SUCCESS(RC)) { NumberBytesRead = 0; @@ -406,6 +415,9 @@ try_exit: NOTHING; } _SEH2_FINALLY { + if (PagingIoResourceAcquired) { + UDFReleasePagingIo(IrpContext, Fcb); + } if (FcbAcquired) { UDFReleaseFcb(IrpContext, Fcb); @@ -523,9 +535,11 @@ UDFLockUserBuffer( // Is a MDL already present in the IRP if (!IrpContext->Irp->MdlAddress) { - // This will place allocated Mdl to Irp - if (!(Mdl = IoAllocateMdl(IrpContext->Irp->UserBuffer, BufferLength, FALSE, FALSE, IrpContext->Irp))) { - + // Use MmCreateMdl instead of IoAllocateMdl so that large buffers + // (> ~64 MB) are not rejected on Windows XP/Server 2003, where + // IoAllocateMdl returns NULL when the MDL size exceeds MAXUSHORT. + Mdl = MmCreateMdl(NULL, IrpContext->Irp->UserBuffer, BufferLength); + if (!Mdl) { return(RC = STATUS_INSUFFICIENT_RESOURCES); } @@ -542,10 +556,13 @@ UDFLockUserBuffer( } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { IoFreeMdl(Mdl); - IrpContext->Irp->MdlAddress = NULL; RC = STATUS_INVALID_USER_BUFFER; } _SEH2_END; + + if (NT_SUCCESS(RC)) { + IrpContext->Irp->MdlAddress = Mdl; + } } return(RC); diff --git a/drivers/filesystems/udfs/secursup.cpp b/drivers/filesystems/udfs/secursup.c similarity index 99% rename from drivers/filesystems/udfs/secursup.cpp rename to drivers/filesystems/udfs/secursup.c index 8328d7599e110..94484697ef2b8 100644 --- a/drivers/filesystems/udfs/secursup.cpp +++ b/drivers/filesystems/udfs/secursup.c @@ -29,7 +29,7 @@ UDFCheckAccessRights( USHORT ShareAccess ) { - NTSTATUS RC; + NTSTATUS RC = STATUS_SUCCESS; BOOLEAN ROCheck = FALSE; // Check attr compatibility diff --git a/drivers/filesystems/udfs/shutdown.cpp b/drivers/filesystems/udfs/shutdown.c similarity index 98% rename from drivers/filesystems/udfs/shutdown.cpp rename to drivers/filesystems/udfs/shutdown.c index 93dd97b067f36..69f2f33f08842 100644 --- a/drivers/filesystems/udfs/shutdown.cpp +++ b/drivers/filesystems/udfs/shutdown.c @@ -173,14 +173,13 @@ UDFCommonShutdown( IoUnregisterFileSystem(UdfData.UDFDeviceObject_CD); if (UdfData.UDFDeviceObject_CD) { IoDeleteDevice(UdfData.UDFDeviceObject_CD); - UdfData.UDFDeviceObject_CD = NULL; } IoUnregisterFileSystem(UdfData.UDFDeviceObject_HDD); if (UdfData.UDFDeviceObject_HDD) { IoDeleteDevice(UdfData.UDFDeviceObject_HDD); - UdfData.UDFDeviceObject_HDD = NULL; } + UDFCompleteRequest(IrpContext, Irp, STATUS_SUCCESS); } _SEH2_END; // end of "__finally" processing diff --git a/drivers/filesystems/udfs/strucsup.cpp b/drivers/filesystems/udfs/strucsup.c similarity index 97% rename from drivers/filesystems/udfs/strucsup.cpp rename to drivers/filesystems/udfs/strucsup.c index 6e746f30fc8a4..9f5804bae6fcc 100644 --- a/drivers/filesystems/udfs/strucsup.cpp +++ b/drivers/filesystems/udfs/strucsup.c @@ -144,10 +144,13 @@ Return Value: ExInitializeResourceLite(&FcbNonpaged->FcbPagingIoResource); ExInitializeResourceLite(&FcbNonpaged->FcbResource); + ExInitializeResourceLite(&FcbNonpaged->CcbListResource); ExInitializeFastMutex(&FcbNonpaged->FcbMutex); ExInitializeFastMutex(&FcbNonpaged->AdvancedFcbHeaderMutex); ExInitializeFastMutex(&FcbNonpaged->FcbFastMutex); + ExInitializeResourceLite(&FcbNonpaged->CcbListResource); + return FcbNonpaged; } @@ -175,11 +178,23 @@ Return Value: { PAGED_CODE(); - + UNREFERENCED_PARAMETER(IrpContext); - + + // Acquire each resource exclusively to drain any active holders before + // calling ExDeleteResourceLite. Freeing a pool block that still contains + // an active ERESOURCE triggers Driver Verifier bugcheck 0xC4/0xD2. + ExAcquireResourceExclusiveLite(&FcbNonpaged->FcbPagingIoResource, TRUE); + ExReleaseResourceLite(&FcbNonpaged->FcbPagingIoResource); + + ExAcquireResourceExclusiveLite(&FcbNonpaged->FcbResource, TRUE); + ExReleaseResourceLite(&FcbNonpaged->FcbResource); + ExDeleteResourceLite(&FcbNonpaged->FcbResource); ExDeleteResourceLite(&FcbNonpaged->FcbPagingIoResource); + ExDeleteResourceLite(&FcbNonpaged->CcbListResource); + + UDFDeallocateFcbNonpaged(FcbNonpaged); @@ -293,8 +308,8 @@ Return Value: if (Vcb != NULL) { - InterlockedDecrement( (LONG*)&Vcb->VcbReference ); - InterlockedDecrement( (LONG*)&Vcb->VcbUserReference ); + InterlockedDecrement(&Vcb->VcbReference ); + InterlockedDecrement(&Vcb->VcbUserReference ); } return; @@ -458,7 +473,7 @@ UDFTeardownStructures( if (ParentFcb->FileInfo) { UDFCloseFile__(IrpContext, Vcb, ParentFcb->FileInfo); } - InterlockedDecrement((PLONG)&ParentFcb->FcbReference); + InterlockedDecrement(&ParentFcb->FcbReference); UDFUnlockVcb(IrpContext, Vcb); } @@ -765,7 +780,7 @@ Return Value: { PFCB NewFcb; - BOOLEAN LocalFcbExisted; + BOOLEAN LocalFcbExisted = FALSE; PAGED_CODE(); @@ -902,10 +917,12 @@ UDFInitializeFCB( Fcb->FcbReference = 0; Fcb->FcbCleanup = 0; + // Initialize file name cache synchronization Fcb->FcbLockThread = NULL; Fcb->FcbLockCount = 0; + Fcb->Vcb = Vcb; return STATUS_SUCCESS; @@ -1076,6 +1093,7 @@ UDFInitializeVCB( ExInitializeResourceLite(&Vcb->VcbResource); ExInitializeResourceLite(&Vcb->BitMapResource1); + ExInitializeResourceLite(&Vcb->DlocResource); ExInitializeResourceLite(&Vcb->DlocResource2); ExInitializeResourceLite(&Vcb->FlushResource); @@ -1162,6 +1180,7 @@ UDFInitializeVCB( // TRUE, // We will use pinned access. // &(UDFGlobalData.CacheMgrCallBacks), Vcb); + Vcb->SectorSize = DiskGeometry->BytesPerSector; Vcb->SectorShift = UDFHighBit(DiskGeometry->BytesPerSector); Vcb->MediaChangeCount = MediaChangeCount; @@ -1175,13 +1194,15 @@ UDFInitializeVCB( } _SEH2_END; } // end UDFInitializeVCB() + + NTSTATUS UDFCompleteMount( IN PIRP_CONTEXT IrpContext, IN PVCB Vcb ) { - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; UNICODE_STRING LocalPath; ULONG LastSector = 0; BOOLEAN UnlockVcb = FALSE; @@ -1274,7 +1295,7 @@ UDFCompleteMount( UDFInsertFcbIntoTable(IrpContext, Vcb->RootIndexFcb); // this is a part of UDF_RESIDUAL_REFERENCE - InterlockedIncrement((PLONG)&Vcb->VcbReference); + InterlockedIncrement(&Vcb->VcbReference); Vcb->RootIndexFcb->FcbCleanup = 1; Vcb->RootIndexFcb->FcbReference = 1; @@ -1314,7 +1335,7 @@ UDFCompleteMount( UDFCleanUpFile__(Vcb, Vcb->NonAllocFileInfo); Vcb->NonAllocFileInfo = NULL; // this was a part of UDF_RESIDUAL_REFERENCE - InterlockedDecrement((PLONG)&Vcb->VcbReference); + InterlockedDecrement(&Vcb->VcbReference); unwind_1: // UDFCloseResidual() will clean up everything @@ -1383,7 +1404,7 @@ UDFCompleteMount( UDFPreClrModified(Vcb); UDFClrModified(Vcb); // this is a part of UDF_RESIDUAL_REFERENCE - InterlockedIncrement((PLONG)&Vcb->VcbReference); + InterlockedIncrement(&Vcb->VcbReference); // Start initializing the fields contained in the Header. diff --git a/drivers/filesystems/udfs/struct.h b/drivers/filesystems/udfs/struct.h index 74c032224266d..1a08e4215a59e 100644 --- a/drivers/filesystems/udfs/struct.h +++ b/drivers/filesystems/udfs/struct.h @@ -38,6 +38,22 @@ struct IO_CONTEXT; struct IRP_CONTEXT; struct LCB; +/* C typedef aliases – allow plain name usage without the 'struct' keyword */ +typedef struct IRP_CONTEXT_LITE IRP_CONTEXT_LITE; +typedef struct IO_CONTEXT IO_CONTEXT; +typedef struct IRP_CONTEXT IRP_CONTEXT; +typedef struct LCB LCB; +typedef struct UDFIdentifier UDFIdentifier; +typedef struct UDFObjectName UDFObjectName; +typedef struct CCB CCB; +typedef struct FCB_NONPAGED FCB_NONPAGED; +typedef struct FCB_DATA FCB_DATA; +typedef struct FCB_INDEX FCB_INDEX; +typedef struct FCB FCB; +typedef struct VCB VCB; +typedef struct VOLUME_DEVICE_OBJECT VOLUME_DEVICE_OBJECT; +typedef struct THREAD_CONTEXT THREAD_CONTEXT; + /************************************************************************** every structure has a node type, and a node size associated with it. The node type serves as a signature field. The size is used for @@ -48,8 +64,7 @@ struct UDFIdentifier { NODE_BYTE_SIZE NodeByteSize; // computed as sizeof(structure) }; -static_assert(sizeof(UDFIdentifier) == offsetof(FSRTL_ADVANCED_FCB_HEADER, Flags), - "UDFIdentifier size mismatch with NodeTypeCode and NodeByteSize in FSRTL_ADVANCED_FCB_HEADER"); +C_ASSERT(sizeof(UDFIdentifier) == offsetof(FSRTL_ADVANCED_FCB_HEADER, Flags)); /************************************************************************** Every open on-disk object must have a name associated with it @@ -68,7 +83,7 @@ struct UDFObjectName { // an absolute pathname of the object is stored below UNICODE_STRING ObjectName; }; -using PtrUDFObjectName = UDFObjectName*; +typedef UDFObjectName* PtrUDFObjectName; /************************************************************************** Each file open instance is represented by a context control block. @@ -107,7 +122,7 @@ struct CCB { PUNICODE_STRING DirectorySearchPattern; HASH_ENTRY hashes; }; -using PCCB = CCB*; +typedef CCB* PCCB; #define CCB_FLAG_IGNORE_CASE (0x00000004) // the CCB has had an IRP_MJ_CLEANUP issued on it. we must @@ -151,6 +166,8 @@ struct FCB_NONPAGED { ERESOURCE FcbPagingIoResource; + ERESOURCE CcbListResource; + // This is the FastMutex for this Fcb. FAST_MUTEX FcbMutex; @@ -165,7 +182,7 @@ struct FCB_NONPAGED { FAST_MUTEX FcbFastMutex; }; -using PFCB_NONPAGED = FCB_NONPAGED*; +typedef FCB_NONPAGED* PFCB_NONPAGED; /************************************************************************** each open file/directory/volume is represented by a file control block. @@ -206,11 +223,11 @@ using PFCB_NONPAGED = FCB_NONPAGED*; /***************************************************/ struct FCB_DATA { - + UCHAR Placeholder; }; struct FCB_INDEX { - + UCHAR Placeholder; }; struct FCB { @@ -245,10 +262,10 @@ struct FCB { // But when we have mapped data, we can receive no IRP_MJ_CLOSE // In this case OpenHandleCount may reach zero, but ReferenceCount may // be non-zero. - ULONG FcbReference; - ULONG FcbCleanup; - ULONG CachedOpenHandleCount; - ULONG FcbUserReference; + LONG FcbReference; + LONG FcbCleanup; + LONG CachedOpenHandleCount; + LONG FcbUserReference; // State flags for this Fcb. @@ -312,7 +329,7 @@ struct FCB { FCB_INDEX FcbIndex; }; }; -using PFCB = FCB*; +typedef FCB* PFCB; #define SIZEOF_FCB_DATA \ (FIELD_OFFSET(FCB, FcbType) + sizeof(FCB_DATA)) @@ -355,7 +372,7 @@ using PFCB = FCB*; **************************************************************************/ -enum UDFFSD_MEDIA_TYPE { +typedef enum UDFFSD_MEDIA_TYPE { MediaUnknown = 0, MediaHdd, MediaCdr, @@ -365,7 +382,7 @@ enum UDFFSD_MEDIA_TYPE { MediaFloppy, MediaDvdr, MediaDvdrw -}; +} UDFFSD_MEDIA_TYPE; //*************************************************************************** // LCB (Link Control Block) @@ -398,7 +415,7 @@ struct LCB { ULONGLONG InitialOffset; // +0x38 Initial offset // Reference count (incremented by CCB, decremented on cleanup) - ULONG Reference; // +0x40 Reference count + LONG Reference; // +0x40 Reference count // LCB flags ULONG Flags; // +0x44 LCB flags @@ -439,7 +456,7 @@ struct LCB { UNICODE_STRING FileName; // +0xE8 File name }; -using PLCB = LCB*; +typedef LCB* PLCB; // LCB Flags #define UDF_LCB_FLAG_POOL_ALLOCATED 0x00000001 // Allocated from pool (not lookaside) @@ -465,14 +482,14 @@ using PLCB = LCB*; // VCB (Volume Control Block) //*************************************************************************** -enum VCB_CONDITION { +typedef enum VCB_CONDITION { VcbNotMounted = 0, VcbMountInProgress, VcbMounted, VcbInvalid, VcbDismountInProgress -}; +} VCB_CONDITION; struct VCB { @@ -481,11 +498,11 @@ struct VCB { // Condition flag for the Vcb. VCB_CONDITION VcbCondition; - ULONG VcbCleanup; - ULONG VcbReference; - ULONG VcbUserReference; - ULONG VcbResidualReference; - ULONG VcbResidualUserReference; + LONG VcbCleanup; + LONG VcbReference; + LONG VcbUserReference; + LONG VcbResidualReference; + LONG VcbResidualUserReference; ERESOURCE FlushResource; // Link into queue of Vcb's in the CdData structure. We will create a union with @@ -653,12 +670,12 @@ struct VCB { uint16 minUDFWriteRev; uint16 maxUDFWriteRev; // file/dir counters for Mac OS - uint32 numFiles; - uint32 numDirs; + LONG numFiles; + LONG numDirs; // VAT uint32 InitVatCount; uint32 VatCount; - uint32* Vat; + PCHAR Vat; uint32 VatPartNdx; PUDF_FILE_INFO VatFileInfo; // sparing table @@ -692,7 +709,7 @@ struct VCB { ULONG VDS2; ULONG VDS2_Len; - ULONG Modified; + LONG Modified; // System Stream Dir PUDF_FILE_INFO SysSDirFileInfo; @@ -727,6 +744,13 @@ struct VCB { uint32 CompatFlags; + // LBA of the most recently allocated File Entry sector. Updated on every + // successful UDFAllocateFESpace call and used as a secondary locality probe + // when the primary window (around the parent directory FE) finds no free + // blocks. Also used by UDFResizeExtent as a locality hint when appending a + // new fragment to an extent. Purely a performance hint; 0 means unused. + uint32 LastAllocatedFELba; + // Fcb table. Synchronized with FcbTableMutex. RTL_GENERIC_TABLE FcbTable; @@ -736,7 +760,7 @@ struct VCB { PVPB SwapVpb; }; -using PVCB = VCB*; +typedef VCB* PVCB; // One for root #define UDFS_BASE_RESIDUAL_REFERENCE (4)//(6) @@ -810,7 +834,7 @@ struct THREAD_CONTEXT { // will store the IrpContext for the request in this stack location. IRP_CONTEXT* TopLevelIrpContext; }; -using PTHREAD_CONTEXT = THREAD_CONTEXT*; +typedef THREAD_CONTEXT* PTHREAD_CONTEXT; /************************************************************************** The IRP context encapsulates the current request. This structure is @@ -854,7 +878,7 @@ struct IRP_CONTEXT { VCB* Vcb; }; -using PIRP_CONTEXT = IRP_CONTEXT*; +typedef IRP_CONTEXT* PIRP_CONTEXT; #define IRP_CONTEXT_FLAG_ON_STACK (0x00000001) #define IRP_CONTEXT_FLAG_MORE_PROCESSING (0x00000002) @@ -919,7 +943,7 @@ struct IRP_CONTEXT_LITE { // Real device object. This represents the physical device closest to the media. PDEVICE_OBJECT RealDevice; }; -using PIRP_CONTEXT_LITE = IRP_CONTEXT_LITE*; +typedef IRP_CONTEXT_LITE* PIRP_CONTEXT_LITE; /************************************************************************** we will store all of our global variables in one structure. diff --git a/drivers/filesystems/udfs/sys_spec.cpp b/drivers/filesystems/udfs/sys_spec.c similarity index 95% rename from drivers/filesystems/udfs/sys_spec.cpp rename to drivers/filesystems/udfs/sys_spec.c index e9a11ab152817..df66b8c66f22e 100644 --- a/drivers/filesystems/udfs/sys_spec.cpp +++ b/drivers/filesystems/udfs/sys_spec.c @@ -20,6 +20,6 @@ // define the file specific bug-check id #define UDF_BUG_CHECK_ID UDF_FILE_SYS_SPEC -#include "Include/Sys_spec_lib.cpp" +#include "Include/Sys_spec_lib.c" //#include "Include/tools.cpp" diff --git a/drivers/filesystems/udfs/udf_dbg.cpp b/drivers/filesystems/udfs/udf_dbg.c similarity index 99% rename from drivers/filesystems/udfs/udf_dbg.cpp rename to drivers/filesystems/udfs/udf_dbg.c index 0d16f8280a41e..547252df0c8b8 100644 --- a/drivers/filesystems/udfs/udf_dbg.cpp +++ b/drivers/filesystems/udfs/udf_dbg.c @@ -134,7 +134,7 @@ DbgWaitForSingleObject_( PLARGE_INTEGER to; LARGE_INTEGER dto; // LARGE_INTEGER cto; - NTSTATUS RC; + NTSTATUS RC = STATUS_SUCCESS; ULONG c = 20; dto.QuadPart = -5LL*1000000LL*10LL; // 5 sec diff --git a/drivers/filesystems/udfs/udf_dbg.h b/drivers/filesystems/udfs/udf_dbg.h index 63fc430bc3c83..82cf81e61e41a 100644 --- a/drivers/filesystems/udfs/udf_dbg.h +++ b/drivers/filesystems/udfs/udf_dbg.h @@ -120,13 +120,7 @@ DbgWaitForSingleObject_( #ifdef UDF_DBG -#ifdef _X86_ -// This is an illegal use of INT3 -#define UDFBreakPoint() { __asm int 3 } -#else // _X86_ - -#define UDFBreakPoint() DbgBreakPoint() -#endif // _X86_ +#define UDFBreakPoint() __debugbreak() #ifdef BRUTE #define BrutePoint() UDFBreakPoint() @@ -189,26 +183,12 @@ VOID DebugFreePool(PVOID addr); #define ValidateFileInfo(fi) {} #endif -#if defined (_X86_) && defined (_MSC_VER) - -__inline VOID UDFTouch(IN PVOID addr) -{ - __asm { - mov eax,addr - mov al,[byte ptr eax] - } -} - -#else // NO X86 optimization , use generic C/C++ - __inline VOID UDFTouch(IN PVOID addr) { - UCHAR a = ((PUCHAR)addr)[0]; - a = a; + UCHAR a = *((volatile UCHAR*)addr); + UNREFERENCED_PARAMETER(a); } -#endif // _X86_ - #else // UDF_DBG #define DbgAllocatePool(x,y) ExAllocatePoolWithTag(x,y,'Fnwd') diff --git a/drivers/filesystems/udfs/udf_info/alloc.cpp b/drivers/filesystems/udfs/udf_info/alloc.c similarity index 85% rename from drivers/filesystems/udfs/udf_info/alloc.cpp rename to drivers/filesystems/udfs/udf_info/alloc.c index 530d6b168767e..e8747e1284a88 100644 --- a/drivers/filesystems/udfs/udf_info/alloc.cpp +++ b/drivers/filesystems/udfs/udf_info/alloc.c @@ -261,39 +261,98 @@ UDFGetBitmapLen( return 0;//(Offs == Lim); } - BOOLEAN bit = UDFGetBit(Bitmap, Offs); - SIZE_T i=Offs>>5; - SIZE_T len=0; - uint8 j=(uint8)(Offs&31); - uint8 lLim=(uint8)(Lim&31); + if (!UDFIsChunked(Bitmap)) { + BOOLEAN bit = UDFGetBit(Bitmap, Offs); + SIZE_T i = Offs >> 5; + SIZE_T len = 0; + uint8 j = (uint8)(Offs & 31); + uint8 lLim = (uint8)(Lim & 31); + uint32 a; - Lim = Lim>>5; + Lim = Lim >> 5; - ASSERT((bit == 0) || (bit == 1)); + ASSERT((bit == 0) || (bit == 1)); - uint32 a; + a = Bitmap[i] >> j; - a = Bitmap[i] >> j; + while(i <= Lim) { - while(i<=Lim) { + while( j < ((i>=1; + j++; + } + j=0; +SkipFullWord: + i++; + a = Bitmap[i]; - while( j < ((i>=1; - j++; + if (i> 3)) >> (Offs & 7) & 1); + SIZE_T i = Offs; + SIZE_T len = 0; + PUDF_CHUNKED_BUF Chunked = UDFGetChunked(Bitmap); + UCHAR bitPattern = bit ? 0xFFu : 0x00u; /* full-byte sentinel */ - if (i> 3); + ULONG chunkIdx = byteIdx >> UDF_CHUNK_SHIFT; + + if (!Chunked->Chunks[chunkIdx]) { + /* Null chunk is all-zero bits. */ + if (bit != 0) + return len; /* looking for 1-bits – none here, stop */ + /* All bits in this chunk are 0 and match; consume the whole chunk. */ + SIZE_T chunkEndBit = (SIZE_T)(chunkIdx + 1) << (UDF_CHUNK_SHIFT + 3); + SIZE_T advance = min(chunkEndBit, Lim) - i; + len += advance; + i += advance; + continue; + } + + /* Chunk is allocated; scan byte-by-byte within it. */ + { + PUCHAR chunkData = (PUCHAR)Chunked->Chunks[chunkIdx]; + SIZE_T chunkEndBit = (SIZE_T)(chunkIdx + 1) << (UDF_CHUNK_SHIFT + 3); + SIZE_T limitBit = min(chunkEndBit, Lim); + + while (i < limitBit) { + ULONG bOff = (ULONG)(i & 7); + ULONG bIdx = (ULONG)(i >> 3) & UDF_CHUNK_MASK; + UCHAR b = chunkData[bIdx]; + + /* Full-byte fast path */ + if (bOff == 0 && (i + 8) <= limitBit) { + if (b == bitPattern) { + len += 8; + i += 8; + continue; + } + /* Mixed byte: fall through to bit loop */ + } + + /* Bit-by-bit for partial or mixed bytes */ + while (bOff < 8 && i < limitBit) { + if ((BOOLEAN)((b >> bOff) & 1) != bit) + return len; + len++; + i++; + bOff++; + } } } } @@ -515,15 +574,17 @@ UDFMarkBadSpaceAsUsed( IN ULONG len ) { - uint32 j; -#define BIT_C (sizeof(Vcb->BSBM_Bitmap[0])*8) - len = (lba+len+BIT_C-1)/BIT_C; + uint32 StartByteIndex, ByteSpanLength; + + StartByteIndex = lba >> 3; + ByteSpanLength = ((lba + len + 7) >> 3) - StartByteIndex; + UDFPrint(("UDFMarkBadSpaceAsUsed: lba=%x len=%x StartByteIndex=%x ByteSpanLength=%x BSBM=%p\n", + lba, len, StartByteIndex, ByteSpanLength, Vcb->BSBM_Bitmap)); if (Vcb->BSBM_Bitmap) { - for(j=lba/BIT_C; jFSBM_Bitmap[j] &= ~Vcb->BSBM_Bitmap[j]; - } + // FSBM uses bit=1=USED semantics; OR the bad-block bitmap in so bad blocks + // are marked as used (bit=1 in FSBM), preventing them from being allocated. + UDFChunkedOrMemory(Vcb->FSBM_Bitmap, Vcb->BSBM_Bitmap, StartByteIndex, ByteSpanLength); } -#undef BIT_C } // UDFMarkBadSpaceAsUsed() /* @@ -546,7 +607,7 @@ UDFMarkSpaceAsXXXNoProtect_( uint32 root; BOOLEAN asUsed = (asXXX == AS_USED || (asXXX & AS_BAD)); #ifdef UDF_TRACK_ONDISK_ALLOCATION - BOOLEAN bit_before, bit_after; + BOOLEAN bit_before = FALSE, bit_after = FALSE; #endif //UDF_TRACK_ONDISK_ALLOCATION UDF_CHECK_BITMAP_RESOURCE(Vcb); @@ -620,9 +681,9 @@ UDFMarkSpaceAsXXXNoProtect_( // mark logical blocks in VAT as used for(j=0;jVat[lba-root+j] == UDF_VAT_FREE_ENTRY) && + if ((UDFVatGetEntry(Vcb->Vat, lba-root+j) == UDF_VAT_FREE_ENTRY) && (lba > Vcb->LastLBA)) { - Vcb->Vat[lba-root+j] = 0x7fffffff; + UDFVatSetEntry(Vcb->Vat, lba-root+j, 0x7fffffff); } } } @@ -650,7 +711,7 @@ UDFMarkSpaceAsXXXNoProtect_( // this operation can decrease resulting VAT size for(j=0;jVat[lba-root+j] = UDF_VAT_FREE_ENTRY; + UDFVatSetEntry(Vcb->Vat, lba-root+j, UDF_VAT_FREE_ENTRY); } } // mark discarded extent as Not-Alloc-Not-Rec to @@ -833,15 +894,35 @@ UDFGetPartFreeSpace( IN uint32 partNum ) { - uint32 lim/*, len=1*/; - uint32 s=0; - uint32 j; - PUCHAR cur = (PUCHAR)(Vcb->FSBM_Bitmap); - - lim = (UDFPartEnd(Vcb,partNum)+7)/8; - for(j=(UDFPartStart(Vcb,partNum)+7)/8; j= endBit) { + return 0; } + + for (i = startBit; (i < endBit) && (i & 7); i++) { + if (UDFGetFreeBit(Vcb->FSBM_Bitmap, i)) + s++; + } + + ASSERT((i & 7) == 0); + for (; i + 7 < endBit; i += 8) { + // FSBM uses bit=1=USED semantics: count zero bits (= free blocks). + // For null chunks UDFChunkedGetByte returns 0; ~0 = 0xFF; bit_count_tab[0xFF] = 8. + s += bit_count_tab[(UCHAR)(~UDFChunkedGetByte(Vcb->FSBM_Bitmap, i >> 3))]; + } + + for (; i < endBit; i++) { + if (UDFGetFreeBit(Vcb->FSBM_Bitmap, i)) + s++; + } + return s; } // end UDFGetPartFreeSpace() diff --git a/drivers/filesystems/udfs/udf_info/dirtree.cpp b/drivers/filesystems/udfs/udf_info/dirtree.c similarity index 99% rename from drivers/filesystems/udfs/udf_info/dirtree.cpp rename to drivers/filesystems/udfs/udf_info/dirtree.c index e4ed3534956e4..0781210004644 100644 --- a/drivers/filesystems/udfs/udf_info/dirtree.cpp +++ b/drivers/filesystems/udfs/udf_info/dirtree.c @@ -102,8 +102,8 @@ UDFDirIndexFree( uint32 k; PDIR_INDEX_ITEM* FrameList; - FrameList = (PDIR_INDEX_ITEM*)(hDirNdx+1); if (!hDirNdx) return; + FrameList = (PDIR_INDEX_ITEM*)(hDirNdx+1); for(k=0; kFrameCount; k++, FrameList++) { if (*FrameList) MyFreePool__(*FrameList); } @@ -398,9 +398,11 @@ UDFBuildHashEntry( UName.MaximumLength = Name->Length; UName.Buffer = (PWCHAR)FsRtlAllocatePoolWithTag(NonPagedPool, UName.MaximumLength, TAG_FILE_NAME); - RtlUpcaseUnicodeString(&UName, Name, FALSE); - hashes->hLfn = crc32((uint8*)(UName.Buffer), UName.Length); - ExFreePoolWithTag(UName.Buffer, TAG_FILE_NAME); + if (UName.Buffer) { + RtlUpcaseUnicodeString(&UName, Name, FALSE); + hashes->hLfn = crc32((uint8*)(UName.Buffer), UName.Length); + ExFreePoolWithTag(UName.Buffer, TAG_FILE_NAME); + } } if (Mask & HASH_DOS) { @@ -685,6 +687,8 @@ UDFIndexDirectory( } // end UDFIndexDirectory() + + /* This routine rebuilds tags for all entries from Dir. */ diff --git a/drivers/filesystems/udfs/udf_info/ecma_167.h b/drivers/filesystems/udfs/udf_info/ecma_167.h index 6ca06a7c47fc2..7e4ebc9c9f064 100644 --- a/drivers/filesystems/udfs/udf_info/ecma_167.h +++ b/drivers/filesystems/udfs/udf_info/ecma_167.h @@ -772,5 +772,12 @@ typedef EXTENDED_FILE_ENTRY ExtendedFileEntry; #pragma pack(pop) +typedef struct VolStructDesc VolStructDesc; +typedef struct BeginningExtendedAreaDesc BeginningExtendedAreaDesc; +typedef struct TerminatingExtendedAreaDesc TerminatingExtendedAreaDesc; +typedef struct PrimaryVolDesc PrimaryVolDesc; +typedef struct AnchorVolDescPtr AnchorVolDescPtr; +typedef struct VolDescPtr VolDescPtr; + #endif /* __ECMA_167_H__ */ diff --git a/drivers/filesystems/udfs/udf_info/extent.cpp b/drivers/filesystems/udfs/udf_info/extent.c similarity index 94% rename from drivers/filesystems/udfs/udf_info/extent.cpp rename to drivers/filesystems/udfs/udf_info/extent.c index f76d82b4577c0..4d0d9b927f22d 100644 --- a/drivers/filesystems/udfs/udf_info/extent.cpp +++ b/drivers/filesystems/udfs/udf_info/extent.c @@ -1324,6 +1324,8 @@ UDFBuildExtAllocDescs( } // end UDFBuildExtAllocDescs()*/ + + NTSTATUS UDFInitAllocationCache( IN PVCB Vcb, @@ -1490,9 +1492,18 @@ UDFFlushAllCachedAllocations( return STATUS_SUCCESS; } // end UDFFlushAllCachedAllocations() +// Half-width (in blocks/sectors) of the locality search window used by +// UDFAllocateFESpace. A ±LOCALITY_WINDOW_BLOCKS range is searched around +// the parent directory's FE before falling back to a full-partition search. +// 8192 sectors covers 4 MiB at 512 B/sector or 32 MiB at 4 KiB/sector. +#define LOCALITY_WINDOW_BLOCKS 8192 + /* This routine allocates space for FE of the file being created. - Allocates a single block from the partition bitmap. + Uses locality-based allocation: tries to place the new FE near the + parent directory's FE to reduce seeks and keep related metadata + physically close on disk. + Falls back to a full partition search if no space is found nearby. */ NTSTATUS UDFAllocateFESpace( @@ -1504,9 +1515,94 @@ UDFAllocateFESpace( IN uint32 Len ) { - UNREFERENCED_PARAMETER(DirInfo); - return UDFAllocFreeExtent(IrpContext, Vcb, Len, - UDFPartStart(Vcb, PartNum), UDFPartEnd(Vcb, PartNum), FEExtInfo, EXTENT_FLAG_VERIFY); + uint32 p_start = UDFPartStart(Vcb, PartNum); + uint32 p_end = UDFPartEnd(Vcb, PartNum); + NTSTATUS status; + + AdPrint(("UDFAllocateFESpace: Part %x, [%x..%x], Len %x\n", + PartNum, p_start, p_end, Len)); + + // --- Probe 1: locality window around the parent directory's FE. --- + // This keeps related metadata close together on disk, reducing seeks. + uint32 primary_l1 = p_start, primary_l2 = p_end; // remember probe-1 window + if (DirInfo && + DirInfo->Dloc && + DirInfo->Dloc->FELoc.Mapping && + DirInfo->Dloc->FELoc.Mapping[0].extLocation) { + + uint32 fe_loc = DirInfo->Dloc->FELoc.Mapping[0].extLocation; + uint32 l1, l2; + + AdPrint((" locality: DirFE @%x\n", fe_loc)); + + // Guard against fe_loc falling outside [p_start, p_end] before + // doing unsigned subtraction; if it does, skip locality and fall + // back to the full-partition search below. + if (fe_loc >= p_start && fe_loc <= p_end) { + l1 = ((fe_loc - p_start) > LOCALITY_WINDOW_BLOCKS) ? (fe_loc - LOCALITY_WINDOW_BLOCKS) : p_start; + l2 = ((p_end - fe_loc) > LOCALITY_WINDOW_BLOCKS) ? (fe_loc + LOCALITY_WINDOW_BLOCKS) : p_end; + + AdPrint((" locality window [%x..%x]\n", l1, l2)); + + primary_l1 = l1; + primary_l2 = l2; + + status = UDFAllocFreeExtent(IrpContext, Vcb, Len, l1, l2, FEExtInfo, EXTENT_FLAG_VERIFY); + if (NT_SUCCESS(status)) { + AdPrint((" locality hit: allocated @%x\n", + FEExtInfo->Mapping ? FEExtInfo->Mapping[0].extLocation : 0)); + Vcb->LastAllocatedFELba = FEExtInfo->Mapping[0].extLocation; + return status; + } + AdPrint((" locality miss (%x), trying secondary hint\n", status)); + } else { + AdPrint((" locality: DirFE @%x out of partition [%x..%x], skipping\n", + fe_loc, p_start, p_end)); + } + } else { + AdPrint((" locality: no DirInfo, trying secondary hint\n")); + } + + // --- Probe 2: locality window around the most recently allocated FE. --- + // When the area around the parent FE is fully occupied (e.g. root-level + // files created right after UDF bootstrap structures), this secondary hint + // keeps new FEs close to the last known free region instead of triggering + // a full-partition bitmap scan. + { + uint32 hint = Vcb->LastAllocatedFELba; + if (hint && hint >= p_start && hint <= p_end) { + uint32 l1 = ((hint - p_start) > LOCALITY_WINDOW_BLOCKS) ? (hint - LOCALITY_WINDOW_BLOCKS) : p_start; + uint32 l2 = ((p_end - hint) > LOCALITY_WINDOW_BLOCKS) ? (hint + LOCALITY_WINDOW_BLOCKS) : p_end; + + // Skip if the secondary window offers no new search territory + // beyond the primary window (i.e., secondary ⊆ primary), to + // avoid a pointless duplicate bitmap walk. + // Condition: search only when at least one side of the secondary + // window extends past the primary window boundary. + if (l1 < primary_l1 || l2 > primary_l2) { + AdPrint((" secondary locality window [%x..%x]\n", l1, l2)); + status = UDFAllocFreeExtent(IrpContext, Vcb, Len, l1, l2, FEExtInfo, EXTENT_FLAG_VERIFY); + if (NT_SUCCESS(status)) { + AdPrint((" secondary locality hit: allocated @%x\n", + FEExtInfo->Mapping ? FEExtInfo->Mapping[0].extLocation : 0)); + Vcb->LastAllocatedFELba = FEExtInfo->Mapping[0].extLocation; + return status; + } + AdPrint((" secondary locality miss (%x), falling back to full search\n", status)); + } + } + } + + // --- Probe 3: full partition search --- + AdPrint((" full partition search [%x..%x]\n", p_start, p_end)); + status = UDFAllocFreeExtent(IrpContext, Vcb, Len, + p_start, p_end, FEExtInfo, EXTENT_FLAG_VERIFY); + if (NT_SUCCESS(status)) { + Vcb->LastAllocatedFELba = FEExtInfo->Mapping[0].extLocation; + } + AdPrint(("UDFAllocateFESpace: result %x, loc %x\n", + status, (NT_SUCCESS(status) && FEExtInfo->Mapping) ? FEExtInfo->Mapping[0].extLocation : 0)); + return status; } // end UDFAllocateFESpace() /* @@ -1519,7 +1615,9 @@ UDFFreeFESpace( IN PEXTENT_INFO FEExtInfo ) { + UNREFERENCED_PARAMETER(DirInfo); + UDFMarkSpaceAsXXX(Vcb, 0, FEExtInfo->Mapping, AS_DISCARDED); // free FEExtInfo->Mapping[0].extLocation = 0; FEExtInfo->Mapping[0].extLength = (EXTENT_NOT_RECORDED_NOT_ALLOCATED << 30); @@ -2228,11 +2326,37 @@ UDFResizeExtent( (ExtInfo->Flags & EXTENT_FLAG_ALLOC_MASK) == EXTENT_FLAG_ALLOC_SEQUENTIAL) { AdPrint(("Resize tune for SEQUENTIAL i/o\n")); } - status = UDFAllocFreeExtent(IrpContext, Vcb, Length - l, - UDFPartStart(Vcb, PartNum), - UDFPartEnd(Vcb, PartNum), - &TmpExtInf, - ExtInfo->Flags /*& EXTENT_FLAG_ALLOC_MASK*/); + { + uint32 p_start = UDFPartStart(Vcb, PartNum); + uint32 p_end = UDFPartEnd(Vcb, PartNum); + + // --- Locality probe: try near LastAllocatedFELba first. --- + // Directory data extents benefit from being placed close to + // the recently allocated FE sectors so that the first write + // to the directory does not require a full-partition bitmap + // scan. Fall back to the full-partition search on miss. + uint32 hint = Vcb->LastAllocatedFELba; + if (hint && hint >= p_start && hint <= p_end) { + uint32 l1 = ((hint - p_start) > LOCALITY_WINDOW_BLOCKS) ? (hint - LOCALITY_WINDOW_BLOCKS) : p_start; + uint32 l2 = ((p_end - hint) > LOCALITY_WINDOW_BLOCKS) ? (hint + LOCALITY_WINDOW_BLOCKS) : p_end; + AdPrint(("Resize locality window [%x..%x]\n", l1, l2)); + status = UDFAllocFreeExtent(IrpContext, Vcb, Length - l, + l1, l2, + &TmpExtInf, + ExtInfo->Flags /*& EXTENT_FLAG_ALLOC_MASK*/); + } else { + status = STATUS_UNSUCCESSFUL; + } + + if (!NT_SUCCESS(status)) { + // Fall back to full-partition search. + AdPrint(("Resize full search [%x..%x]\n", p_start, p_end)); + status = UDFAllocFreeExtent(IrpContext, Vcb, Length - l, + p_start, p_end, + &TmpExtInf, + ExtInfo->Flags /*& EXTENT_FLAG_ALLOC_MASK*/); + } + } if (!NT_SUCCESS(status)) { UDFPrint(("UDFResizeExtent: UDFAllocFreeExtent() failed (%x)\n", status)); return status; diff --git a/drivers/filesystems/udfs/udf_info/mount.cpp b/drivers/filesystems/udfs/udf_info/mount.c similarity index 92% rename from drivers/filesystems/udfs/udf_info/mount.cpp rename to drivers/filesystems/udfs/udf_info/mount.c index 62fa4048fc624..179c878c76826 100644 --- a/drivers/filesystems/udfs/udf_info/mount.cpp +++ b/drivers/filesystems/udfs/udf_info/mount.c @@ -57,14 +57,14 @@ UDFPrepareXSpaceBitmap( IN OUT uint32* XSl ) { - uint32 BS, j, LBS; + uint32 j, LBS; uint32 plen; - NTSTATUS status; + NTSTATUS status = STATUS_SUCCESS; EXTENT_MAP TmpExt; lb_addr locAddr; int8* _XSBM; uint16 Ident; - ULONG ReadBytes; + ULONG ReadBytes = 0; uint32 RefPartNum; if (!(XSpaceBitmap->extLength)) { @@ -77,11 +77,11 @@ UDFPrepareXSpaceBitmap( locAddr.partitionReferenceNum = (uint16)RefPartNum; plen = UDFPartStart(Vcb, RefPartNum) + UDFPartLen(Vcb, RefPartNum); - BS = Vcb->SectorSize; + LBS = Vcb->SectorSize; *XSl = sizeof(SPACE_BITMAP_DESC) + ((plen+7)>>3); - _XSBM = (int8*)DbgAllocatePool(NonPagedPool, (*XSl + BS - 1) & ~(BS-1) ); + _XSBM = UDFAllocChunked(*XSl); *XSBM = _XSBM; switch (XSpaceBitmap->extLength >> 30) { @@ -138,25 +138,33 @@ UDFPrepareXSpaceBitmap( switch (XSpaceBitmap->extLength >> 30) { case EXTENT_RECORDED_ALLOCATED: { - // read descriptor & bitmap - if ((!NT_SUCCESS(status = UDFReadTagged(IrpContext, Vcb, *XSBM, (j = TmpExt.extLocation), - locAddr.logicalBlockNum, &Ident))) || - (Ident != TID_SPACE_BITMAP_DESC) || - (!NT_SUCCESS(status = UDFReadExtent(IrpContext, Vcb, XSBMExtInfo, 0, *XSl, FALSE, *XSBM, &ReadBytes))) ) { - if (NT_SUCCESS(status)) { + // Validate the descriptor tag with a temporary flat sector buffer, + // then read the full extent directly into the chunked bitmap buffer. + int8* tmpTag = (int8*)DbgAllocatePool(NonPagedPool, LBS); + if (!tmpTag) { + status = STATUS_INSUFFICIENT_RESOURCES; + } else { + status = UDFReadTagged(IrpContext, Vcb, tmpTag, (j = TmpExt.extLocation), + locAddr.logicalBlockNum, &Ident); + DbgFreePool(tmpTag); + if (NT_SUCCESS(status) && Ident != TID_SPACE_BITMAP_DESC) { BrutePoint(); status = STATUS_FILE_CORRUPT_ERROR; } + if (NT_SUCCESS(status)) { + status = UDFReadExtentIntoChunked(IrpContext, Vcb, XSBMExtInfo, + 0, *XSl, FALSE, *XSBM, &ReadBytes); + } + } + if (!NT_SUCCESS(status)) { if (XSBMExtInfo->Mapping) { MyFreePool__(XSBMExtInfo->Mapping); XSBMExtInfo->Mapping = NULL; } - DbgFreePool(*XSBM); + UDFFreeChunked(*XSBM); *XSl = 0; *XSBM = NULL; return status; - } else { -// BrutePoint(); } return STATUS_SUCCESS; } @@ -169,10 +177,21 @@ UDFPrepareXSpaceBitmap( #endif } - PSPACE_BITMAP_DESC XSDesc = (PSPACE_BITMAP_DESC)(*XSBM); + // Fresh allocation for a not-yet-recorded bitmap: set up the descriptor header. + // Chunks are zero-initialised on allocation; no RtlZeroMemory needed. + PSPACE_BITMAP_DESC XSDesc = (PSPACE_BITMAP_DESC)UDFChunkedGetOrAllocBytePtr(*XSBM, 0); + if (!XSDesc) { + if (XSBMExtInfo->Mapping) { + MyFreePool__(XSBMExtInfo->Mapping); + XSBMExtInfo->Mapping = NULL; + } + UDFFreeChunked(*XSBM); + *XSBM = NULL; + *XSl = 0; + return STATUS_INSUFFICIENT_RESOURCES; + } XSpaceBitmap->extLength = (*XSl + LBS -1) & ~(LBS-1); - RtlZeroMemory(*XSBM, *XSl); XSDesc->descTag.tagIdent = TID_SPACE_BITMAP_DESC; UDFSetUpTag(Vcb, &(XSDesc->descTag), 0, XSpaceBitmap->extPosition, 0); XSDesc->numOfBits = plen; @@ -197,8 +216,6 @@ UDFUpdateXSpaceBitmaps( int8* bad_bm; int8* old_bm; int8* new_bm; - int8* fpart_bm; - int8* upart_bm; NTSTATUS status, status2; int8* USBM=NULL; int8* FSBM=NULL; @@ -228,7 +245,7 @@ UDFUpdateXSpaceBitmaps( // try to recover insufficient resources if (USl && USBMExtInfo.Mapping) { USl -= sizeof(SPACE_BITMAP_DESC); - status = UDFWriteExtent(IrpContext, Vcb, &USBMExtInfo, sizeof(SPACE_BITMAP_DESC), USl, FALSE, new_bm, &WrittenBytes); + status = UDFWriteExtentFromChunked(IrpContext, Vcb, &USBMExtInfo, sizeof(SPACE_BITMAP_DESC), USl, FALSE, new_bm, &WrittenBytes); #ifdef UDF_DBG } else { UDFPrint(("Can't update USBM\n")); @@ -238,7 +255,7 @@ UDFUpdateXSpaceBitmaps( if (FSl && FSBMExtInfo.Mapping) { FSl -= sizeof(SPACE_BITMAP_DESC); - status2 = UDFWriteExtent(IrpContext, Vcb, &FSBMExtInfo, sizeof(SPACE_BITMAP_DESC), FSl, FALSE, new_bm, &WrittenBytes); + status2 = UDFWriteExtentFromChunked(IrpContext, Vcb, &FSBMExtInfo, sizeof(SPACE_BITMAP_DESC), FSl, FALSE, new_bm, &WrittenBytes); } else { status2 = status; UDFPrint(("Can't update FSBM\n")); @@ -246,8 +263,13 @@ UDFUpdateXSpaceBitmaps( if (FSBMExtInfo.Mapping) MyFreePool__(FSBMExtInfo.Mapping); } else { // normal way to record BitMaps - if (USBM) upart_bm = USBM + sizeof(SPACE_BITMAP_DESC); - if (FSBM) fpart_bm = FSBM + sizeof(SPACE_BITMAP_DESC); + // USBM and FSBM are chunked on-disk output buffers using the UDF on-disk + // convention (bit=1=free/unallocated, bit=0=used/allocated), indexed from + // bit offset sizeof(SPACE_BITMAP_DESC)*8 to skip past the descriptor header. + // new_bm = Vcb->FSBM_Bitmap and old_bm = Vcb->FSBM_OldBitmap are chunked + // FSBM buffers using the internal bit=1=USED / bit=0=FREE convention. + // Use raw UDFGetBit/UDFSetBit/UDFClrBit directly, not the UDFGetFreeBit/ + // UDFSetFreeBit wrappers, to avoid confusion between the two conventions. pend = min(pstart + plen, Vcb->FSBM_BitCount); d=1; @@ -256,32 +278,33 @@ UDFUpdateXSpaceBitmaps( for(i=pstart; iSparingTableModified) return STATUS_SUCCESS; @@ -616,6 +639,8 @@ UDFUpdateLogicalVol( status = UDFUpdateSparingTable(IrpContext, Vcb); + + lvd = (LogicalVolDesc*)MyAllocatePool__(NonPagedPool, max(Vcb->SectorSize, sizeof(LogicalVolDesc)) ); if (!lvd) { @@ -679,7 +704,7 @@ UDFUpdateVDS( IN uint32 flags ) { - NTSTATUS status; + NTSTATUS status = STATUS_SUCCESS; int8* Buf = (int8*)DbgAllocatePool(NonPagedPool,Vcb->SectorSize); UDF_VDS_RECORD vds[VDS_POS_LENGTH]; uint32 i,j; @@ -813,7 +838,7 @@ UDFUpdateVolIdent( { #define CUR_IDENT_SZ (sizeof(pvoldesc->volIdent)) PrimaryVolDesc* pvoldesc = (PrimaryVolDesc*)MyAllocatePool__(NonPagedPool, max(Vcb->SectorSize, sizeof(PrimaryVolDesc)) ); - NTSTATUS status; + NTSTATUS status = STATUS_SUCCESS; dstring CS0[CUR_IDENT_SZ]; uint16 ident; SIZE_T WrittenBytes; @@ -962,7 +987,7 @@ UDFUmount__( UDF_CHECK_BITMAP_RESOURCE(Vcb); // check if we should update BM - if (Vcb->FSBM_ByteCount == RtlCompareMemory(Vcb->FSBM_Bitmap, Vcb->FSBM_OldBitmap, Vcb->FSBM_ByteCount)) { + if (Vcb->FSBM_ByteCount == UDFChunkedCompareMemory(Vcb->FSBM_Bitmap, Vcb->FSBM_OldBitmap, Vcb->FSBM_ByteCount)) { flags &= ~1; } else { flags |= 1; @@ -984,7 +1009,7 @@ UDFUmount__( } if (flags & 1) - RtlCopyMemory(Vcb->FSBM_OldBitmap, Vcb->FSBM_Bitmap, Vcb->FSBM_ByteCount); + UDFChunkedCopyMemory(Vcb->FSBM_OldBitmap, Vcb->FSBM_Bitmap, Vcb->FSBM_ByteCount); //skip_update_bitmap: @@ -1013,7 +1038,7 @@ UDFFindAnchorVolumeDescriptor( uint16 ident; uint32 i; uint32 LastBlock; - NTSTATUS status; + NTSTATUS status = STATUS_SUCCESS; int8* Buf = (int8*)MyAllocatePool__(NonPagedPool, ROUND_TO_PAGES(SectorAlign(Vcb, sizeof(AnchorVolDescPtr)))); @@ -1086,9 +1111,9 @@ UDFFindVRS( uint32 offset; uint32 retStat = 0; uint32 BeginOffset = Vcb->FirstLBA; - NTSTATUS RC; + NTSTATUS RC = STATUS_SUCCESS; int8* buffer = (int8*)MyAllocatePool__(NonPagedPool,Vcb->SectorSize); - ULONG ReadBytes; + ULONG ReadBytes = 0; if (!buffer) return 0; // Relative to First LBA in Last Session @@ -1619,15 +1644,14 @@ UDFAddXSpaceBitmap( ) { int8* tmp; - int8* tmp_bm; - uint32 i, lim, j, lba, l, lim2, l2, k; + uint32 i, lim, j, lba, l, lim2; lb_addr locAddr; - NTSTATUS status; + NTSTATUS status = STATUS_SUCCESS; uint16 Ident; uint32 flags; SIZE_T Length; - ULONG ReadBytes; - BOOLEAN bit_set; + ULONG ReadBytes = 0; + BOOLEAN bit_set = FALSE; UDF_CHECK_BITMAP_RESOURCE(Vcb); UDFPrint(("UDFAddXSpaceBitmap: at block=%x, partition=%d\n", @@ -1638,11 +1662,14 @@ UDFAddXSpaceBitmap( i=UDFPartStart(Vcb, RefPartNum); flags = bm->extLength >> 30; if (!flags /*|| flags == EXTENT_NOT_RECORDED_ALLOCATED*/) { - tmp = (int8*)DbgAllocatePool(NonPagedPool, max(Length, Vcb->SectorSize)); + + // Use a single sector buffer to avoid allocating the entire ~64MB bitmap at once. + tmp = (int8*)DbgAllocatePool(NonPagedPool, Vcb->SectorSize); + if (!tmp) return STATUS_INSUFFICIENT_RESOURCES; locAddr.partitionReferenceNum = (uint16)RefPartNum; locAddr.logicalBlockNum = bm->extPosition; - // read header of the Bitmap + // read header of the Bitmap (first sector - also verifies the tag) if (!NT_SUCCESS(status = UDFReadTagged(IrpContext, Vcb, tmp, lba = UDFPartLbaToPhys(Vcb, &locAddr), locAddr.logicalBlockNum, &Ident))) { err_addxsbm_1: @@ -1654,27 +1681,59 @@ UDFAddXSpaceBitmap( goto err_addxsbm_1; } - // read the whole Bitmap - if (!NT_SUCCESS(status = UDFReadData(IrpContext, Vcb, FALSE, ((uint64)lba)<SectorShift, Length, FALSE, tmp, &ReadBytes))) - goto err_addxsbm_1; - lim = min(i + (lim2 = ((PSPACE_BITMAP_DESC)tmp)->numOfBits), Vcb->FSBM_BitCount); - tmp_bm = tmp + sizeof(SPACE_BITMAP_DESC); + // Process the on-disk bitmap sector by sector to avoid a large flat allocation. + // The SPACE_BITMAP_DESC header occupies the first sizeof(SPACE_BITMAP_DESC) bytes; + // bitmap data follows immediately in the same sector and continues in subsequent ones. + lim2 = ((PSPACE_BITMAP_DESC)tmp)->numOfBits; + lim = min(i + lim2, Vcb->FSBM_BitCount); j = 0; - for(;(l = UDFGetBitmapLen((uint32*)tmp_bm, j, lim2)) && (iFSBM_Bitmap, i); - UDFSetFreeBitOwner(Vcb, i); + l = sizeof(SPACE_BITMAP_DESC); // byte offset within current sector where data begins + { + SIZE_T extByteOffset = 0; + for (;;) { + // Process all bitmap bytes in the current sector + while (l < (uint32)Vcb->SectorSize && j < lim2 && i < lim) { + uint8 bval = (uint8)tmp[l]; + uint32 bitsLeft = min(8u, lim2 - j); + if (bval == 0x00 && bitsLeft == 8 && (i & 7) == 0) { + // Fast path: all 8 on-disk bits are 0 = all used. + // Set all 8 FSBM bits to 1 (used) in one byte write. + UDFChunkedSetByte(Vcb->FSBM_Bitmap, i >> 3, 0xFF); +#ifdef UDF_TRACK_ONDISK_ALLOCATION_OWNERS + for (uint32 b = 0; b < 8; b++) { + UDFSetUsedBitOwner(Vcb, i + b, 0); + } +#endif + j += 8; + i += 8; + } else { + for (uint32 b = 0; b < bitsLeft && i < lim; b++, j++, i++) { + if (!((bval >> b) & 1)) { + // on-disk bit=0 → sector is used → set FSBM bit to 1 + UDFSetUsedBit(Vcb->FSBM_Bitmap, i); + } else { + // on-disk bit=1 → sector is free → FSBM bit stays 0, no-op + UDFSetFreeBitOwner(Vcb, i); + } + } + } + l++; + } + if (j >= lim2 || i >= lim) break; + // Advance to the next sector of the extent + extByteOffset += Vcb->SectorSize; + if (extByteOffset >= Length) break; + { + ULONG readLen = (ULONG)min((SIZE_T)Vcb->SectorSize, Length - extByteOffset); + if (!NT_SUCCESS(status = UDFReadData(IrpContext, Vcb, FALSE, + ((uint64)lba << Vcb->SectorShift) + extByteOffset, + readLen, FALSE, tmp, &ReadBytes))) + goto err_addxsbm_1; } - i++; + l = 0; // next sectors have no header; start from byte 0 + } - j += l; } DbgFreePool(tmp); /* } else if ((bm->extLength >> 30) == EXTENT_NOT_RECORDED_ALLOCATED) { @@ -1699,15 +1758,13 @@ UDFVerifyXSpaceBitmap( ) { int8* tmp; -// int8* tmp_bm; -// uint32 i, l2, k, lim, j, lim2; uint32 lba; lb_addr locAddr; - NTSTATUS status; + NTSTATUS status = STATUS_SUCCESS; uint16 Ident; uint32 flags; uint32 Length; - ULONG ReadBytes; + ULONG ReadBytes = 0; // BOOLEAN bit_set; UDF_CHECK_BITMAP_RESOURCE(Vcb); @@ -1718,7 +1775,10 @@ UDFVerifyXSpaceBitmap( // i=UDFPartStart(Vcb, RefPartNum); flags = bm->extLength >> 30; if (!flags /*|| flags == EXTENT_NOT_RECORDED_ALLOCATED*/) { - tmp = (int8*)DbgAllocatePool(NonPagedPool, max(Length, Vcb->SectorSize)); + + // Only need one sector to verify the space bitmap descriptor tag. + tmp = (int8*)DbgAllocatePool(NonPagedPool, Vcb->SectorSize); + if (!tmp) return STATUS_INSUFFICIENT_RESOURCES; locAddr.partitionReferenceNum = (uint16)RefPartNum; locAddr.logicalBlockNum = bm->extPosition; @@ -1734,46 +1794,8 @@ UDFVerifyXSpaceBitmap( status = STATUS_DISK_CORRUPT_ERROR; goto err_vfyxsbm_1; } - // read the whole Bitmap - if (!NT_SUCCESS(status = UDFReadData(IrpContext, Vcb, FALSE, ((uint64)lba)<SectorShift, Length, FALSE, tmp, &ReadBytes))) - goto err_vfyxsbm_1; -// lim = min(i + ((lim2 = ((PSPACE_BITMAP_DESC)tmp)->numOfBits) << Vcb->LB2B_Bits), Vcb->FSBM_BitCount); -// tmp_bm = tmp + sizeof(SPACE_BITMAP_DESC); -// j = 0; -/* for(;(l = UDFGetBitmapLen((uint32*)tmp_bm, j, lim2)) && (iLB2B_Bits; - // ...and mark them - if (bm_type == UDF_FSPACE_BM) { - bit_set = UDFGetFreeBit(tmp_bm, j); - for(k=0;(kFSBM_Bitmap, i); - UDFSetFreeBitOwner(Vcb, i); - UDFSetZeroBit(Vcb->ZSBM_Bitmap, i); - } else { - // USED block - UDFClrZeroBit(Vcb->ZSBM_Bitmap, i); - } - i++; - } - } else { - bit_set = UDFGetZeroBit(tmp_bm, j); - for(k=0;(kZSBM_Bitmap, i); - } else { - // DATA block - UDFClrZeroBit(Vcb->ZSBM_Bitmap, i); - } - i++; - } - } - j += l; - }*/ + DbgFreePool(tmp); /* } else if ((bm->extLength >> 30) == EXTENT_NOT_RECORDED_ALLOCATED) { i=Vcb->Partitions[RefPartNum].PartitionRoot; @@ -1798,7 +1820,7 @@ UDFDelXSpaceBitmap( int8* tmp, tmp_bm; uint32 i, lim, j; lb_addr locAddr; - NTSTATUS status; + NTSTATUS status = STATUS_SUCCESS; uint16 Ident; uint32 flags; uint32 Length; @@ -1853,7 +1875,7 @@ UDFVerifyFreeSpaceBitmap( IN uint32 Lba // UnallocSpaceDesc ) { - NTSTATUS status; + NTSTATUS status = STATUS_SUCCESS; uint32 i, l; uint16 Ident; int8* AllocDesc; @@ -1949,7 +1971,7 @@ UDFBuildFreeSpaceBitmap( IN uint32 Lba // UnallocSpaceDesc ) { - NTSTATUS status; + NTSTATUS status = STATUS_SUCCESS; uint32 i, l; uint16 Ident; int8* AllocDesc; @@ -1959,10 +1981,15 @@ UDFBuildFreeSpaceBitmap( if (!(Vcb->FSBM_Bitmap)) { // init Bitmap buffer if necessary - Vcb->FSBM_Bitmap = (int8*)DbgAllocatePool(NonPagedPool, (i = (Vcb->LastPossibleLBA+1+7)>>3) ); - if (!(Vcb->FSBM_Bitmap)) return STATUS_INSUFFICIENT_RESOURCES; - RtlZeroMemory(Vcb->FSBM_Bitmap, i); + i = (Vcb->LastPossibleLBA+1+7)>>3; + UDFPrint(("UDFBuildFreeSpaceBitmap: allocating FSBM_Bitmap ByteCount=%x BitCount=%x\n", i, Vcb->LastPossibleLBA+1)); + Vcb->FSBM_Bitmap = UDFAllocChunked((i = (Vcb->LastPossibleLBA+1+7)>>3)); + if (!(Vcb->FSBM_Bitmap)) { + UDFPrint(("UDFBuildFreeSpaceBitmap: FSBM_Bitmap alloc failed\n")); + return STATUS_INSUFFICIENT_RESOURCES; + } + #ifdef UDF_TRACK_ONDISK_ALLOCATION_OWNERS Vcb->FSBM_Bitmap_owners = (uint32*)DbgAllocatePool(NonPagedPool, (Vcb->LastPossibleLBA+1)*sizeof(uint32)); @@ -2068,7 +2095,7 @@ UDFLoadPartDesc( { PartitionDesc *p = (PartitionDesc *)Buf; uint32 i; - NTSTATUS RC; + NTSTATUS RC = STATUS_SUCCESS; BOOLEAN Found = FALSE; UDFPrint(("UDF: Pard Descr:\n")); UDFPrint((" volDescSeqNum = %x\n", p->volDescSeqNum)); @@ -2169,7 +2196,7 @@ UDFVerifyPartDesc( { PartitionDesc *p = (PartitionDesc *)Buf; uint32 i; - NTSTATUS RC; + NTSTATUS RC = STATUS_SUCCESS; BOOLEAN Found = FALSE; UDFPrint(("UDF: Verify Part Descr:\n")); UDFPrint((" volDescSeqNum = %x\n", p->volDescSeqNum)); @@ -2284,7 +2311,7 @@ UDFReadVDS( IN int8* Buf ) { - NTSTATUS status; + NTSTATUS status = STATUS_SUCCESS; GenericDesc* gd; BOOLEAN done=FALSE; uint32 vdsn; @@ -2724,7 +2751,7 @@ UDFFindLastFileSet( IN OUT PFILE_SET_DESC FileSetDesc ) { - NTSTATUS status; + NTSTATUS status = STATUS_SUCCESS; uint32 relLocExt = Addr->logicalBlockNum; uint32 locExt = UDFPartLbaToPhys(Vcb, Addr); uint16 Ident; @@ -2768,14 +2795,14 @@ UDFLoadSparingTable( { PSPARING_MAP RelocMap; PSPARING_MAP NewRelocMap; - NTSTATUS status; + NTSTATUS status = STATUS_SUCCESS; uint32 i=0, BC, BC2; PSPARING_TABLE SparTable; uint32 TabSize, NewSize; - ULONG ReadBytes; + ULONG ReadBytes = 0; uint32 SparTableLoc; uint32 n,m; - BOOLEAN merged; + BOOLEAN merged = FALSE; Vcb->SparingCountFree = -1; @@ -2959,9 +2986,13 @@ UDFGetDiskInfoAndVerify( UDFLoadFileset(Vcb,FileSetDesc, &(Vcb->RootLbAddr), &(Vcb->SysStreamLbAddr)); - Vcb->FSBM_OldBitmap = (int8*)DbgAllocatePool(NonPagedPool, Vcb->FSBM_ByteCount); - if (!(Vcb->FSBM_OldBitmap)) try_return(RC = STATUS_INSUFFICIENT_RESOURCES); - RtlCopyMemory(Vcb->FSBM_OldBitmap, Vcb->FSBM_Bitmap, Vcb->FSBM_ByteCount); + Vcb->FSBM_OldBitmap = UDFAllocChunked(Vcb->FSBM_ByteCount); + if (!(Vcb->FSBM_OldBitmap)) { + UDFPrint(("UDFGetDiskInfoAndVerify: FSBM_OldBitmap alloc failed (ByteCount=%x)\n", Vcb->FSBM_ByteCount)); + try_return(RC = STATUS_INSUFFICIENT_RESOURCES); + } + UDFPrint(("UDFGetDiskInfoAndVerify: snapshotting FSBM_OldBitmap ByteCount=%x\n", Vcb->FSBM_ByteCount)); + UDFChunkedCopyMemory(Vcb->FSBM_OldBitmap, Vcb->FSBM_Bitmap, Vcb->FSBM_ByteCount); try_exit: NOTHING; } _SEH2_FINALLY { @@ -2971,4 +3002,3 @@ try_exit: NOTHING; return(RC); } // end UDFGetDiskInfoAndVerify() - diff --git a/drivers/filesystems/udfs/udf_info/phys_eject.cpp b/drivers/filesystems/udfs/udf_info/phys_eject.c similarity index 100% rename from drivers/filesystems/udfs/udf_info/phys_eject.cpp rename to drivers/filesystems/udfs/udf_info/phys_eject.c diff --git a/drivers/filesystems/udfs/udf_info/physical.cpp b/drivers/filesystems/udfs/udf_info/physical.c similarity index 95% rename from drivers/filesystems/udfs/udf_info/physical.cpp rename to drivers/filesystems/udfs/udf_info/physical.c index 1ba8a147f02f1..9468996cacd37 100644 --- a/drivers/filesystems/udfs/udf_info/physical.cpp +++ b/drivers/filesystems/udfs/udf_info/physical.c @@ -17,5 +17,5 @@ // define the file specific bug-check id #define UDF_BUG_CHECK_ID UDF_FILE_PHYSICAL -#include "Include/phys_lib.cpp" +#include "Include/phys_lib.c" diff --git a/drivers/filesystems/udfs/udf_info/remap.cpp b/drivers/filesystems/udfs/udf_info/remap.c similarity index 96% rename from drivers/filesystems/udfs/udf_info/remap.cpp rename to drivers/filesystems/udfs/udf_info/remap.c index 72a4079b07021..6361daace6f51 100644 --- a/drivers/filesystems/udfs/udf_info/remap.cpp +++ b/drivers/filesystems/udfs/udf_info/remap.c @@ -29,8 +29,8 @@ UDFCheckArea( ) { uint8* buff; - NTSTATUS RC; - ULONG ReadBytes; + NTSTATUS RC = STATUS_SUCCESS; + ULONG ReadBytes = 0; uint32 i, d; BOOLEAN ext_ok = TRUE; EXTENT_MAP Map[2]; @@ -218,15 +218,14 @@ UDFRelocateSector( } } else if (Vcb->Vat) { // use VAT for relocation - uint32* Map = Vcb->Vat; uint32 root; // check if given Lba lays in the partition covered by VAT if (Lba >= Vcb->NWA) return Vcb->NWA; if (Lba < (root = Vcb->Partitions[Vcb->VatPartNdx].PartitionRoot)) return Lba; - Map = &(Vcb->Vat[(i = Lba - root)]); - if ((i < Vcb->VatCount) && (i=(*Map)) ) { + i = Lba - root; + if ((i < Vcb->VatCount) && (i = UDFVatGetEntry(Vcb->Vat, i)) ) { if (i != UDF_VAT_FREE_ENTRY) { return i + root; } else { @@ -267,14 +266,12 @@ UDFAreSectorsRelocated( } else if (Vcb->Vat) { // use VAT for relocation uint32 i, root, j; - uint32* Map; if (Lba < (root = Vcb->Partitions[Vcb->VatPartNdx].PartitionRoot)) return FALSE; if (Lba+BlockCount >= Vcb->NWA) return TRUE; - Map = &(Vcb->Vat[Lba-root/*+i*/]); - for(i=0; iVat, Lba-root+i)) && (j != Lba-root+i) && ((j != UDF_VAT_FREE_ENTRY) || ((Lba+i) < Vcb->LastLBA))) return TRUE; diff --git a/drivers/filesystems/udfs/udf_info/udf_info.cpp b/drivers/filesystems/udfs/udf_info/udf_info.c similarity index 96% rename from drivers/filesystems/udfs/udf_info/udf_info.cpp rename to drivers/filesystems/udfs/udf_info/udf_info.c index e9556aa93de31..ec363f2d9f2ae 100644 --- a/drivers/filesystems/udfs/udf_info/udf_info.cpp +++ b/drivers/filesystems/udfs/udf_info/udf_info.c @@ -18,31 +18,16 @@ #define UDF_BUG_CHECK_ID UDF_FILE_UDF_INFO -#ifdef _X86_ -static const int8 valid_char_arr[] = - {1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, - 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, - 1,0,1,0, 0,0,0,0, 0,0,1,1, 1,0,0,1, - 0,0,0,0, 0,0,0,0, 0,0,1,1, 1,1,1,1, - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // @ABCDE.... - 0,0,0,0, 0,0,0,0, 0,0,0,1, 1,1,0,0, // ....Z[/]^_ - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // `abcde.... - 0,0,0,0, 0,0,0,0, 0,0,0,1, 1,1,0,1, // ....z{|}~ - - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, - 1,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0}; -#else // NO X86 optimization , use generic C/C++ static const char valid_char_arr[] = {"*/:?\"<>|\\"}; -#endif // _X86_ #define DOS_CRC_MODULUS 41 #define hexChar crcChar + +// Minimum number of sectors to pre-allocate for a new directory data extent. +// Amortises per-sector cold-write spikes across many file additions. +// The effective pre-allocation is max(2*t, UDF_DIR_PREALLOC_MIN_SECTORS * +// SectorSize) rounded up to a WriteBlockSize boundary. +#define UDF_DIR_PREALLOC_MIN_SECTORS 8 static const char crcChar[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ#_~-@"; /* Used to convert hex digits to ASCII for readability. */ @@ -286,7 +271,7 @@ UDFReadFileEntry( IN OUT uint16* Ident ) { - NTSTATUS status; + NTSTATUS status = STATUS_SUCCESS; if (!NT_SUCCESS(status = UDFReadTagged(IrpContext, Vcb, (int8*)FileEntry, UDFPartLbaToPhys(Vcb,&(Icb->extLocation)), @@ -352,7 +337,7 @@ UDFIsIllegalChar( IN PUDF_FILE_INFO FileInfo ) { - BOOLEAN KeepIntact; + BOOLEAN KeepIntact = FALSE; KeepIntact = (FileInfo && (FileInfo->Index < 2)); UDFDOSName(Vcb, DosName, UdfName, KeepIntact); @@ -916,7 +901,7 @@ UDFBuildFileEntry( ) { PFILE_ENTRY FileEntry; - NTSTATUS status; + NTSTATUS status = STATUS_SUCCESS; // EntityID* eID; uint32 l; EXTENT_INFO _FEExtInfo; @@ -1549,10 +1534,10 @@ UDFWriteFile__( ) { int64 t, elen; - NTSTATUS status; + NTSTATUS status = STATUS_SUCCESS; int8* OldInIcb = NULL; ValidateFileInfo(FileInfo); - ULONG ReadBytes; + ULONG ReadBytes = 0; SIZE_T _WrittenBytes; PUDF_DATALOC_INFO Dloc; // unwind staff @@ -1587,7 +1572,9 @@ UDFWriteFile__( elen - Dloc->DataLoc.Offset, Dloc->DataLoc.Length)); UDFSetFileSize(FileInfo, t); + Dloc->DataLoc.Modified = TRUE; + Dloc->DataLoc.Length = t; return UDFWriteExtent(IrpContext, Vcb, &Dloc->DataLoc, Offset, Length, Direct, Buffer, WrittenBytes); } @@ -1612,10 +1599,12 @@ UDFWriteFile__( ((PFILE_ENTRY)(Dloc->FileEntry))->icbTag.flags |= ICB_FLAG_AD_SHORT; WasInIcb = TRUE; // Clear embedded data flag since file is no longer in ICB mode + // Fcb may be NULL during directory operations (FCB not yet created) if (FileInfo->Fcb) { FileInfo->Fcb->FcbState &= ~UDF_FCB_EMBEDDED_DATA; } + } // increase extent ExtPrint((" %s %s %s\n", @@ -1623,8 +1612,16 @@ UDFWriteFile__( WasInIcb ? "In-Icb" : "", Vcb->LowFreeSpace ? "LowSpace" : "")); if (UDFIsADirectory(FileInfo) && !WasInIcb && !Vcb->LowFreeSpace) { + // Pre-allocate directory data extents in larger chunks to amortise + // per-sector cold-write spikes across many file additions. + // The pre-allocation size is at least UDF_DIR_PREALLOC_MIN_SECTORS + // sectors (safety net for small WriteBlockSize configurations) and + // is always rounded up to a full WriteBlockSize boundary. + uint64 prealloc = max((uint64)t * 2, + (uint64)Vcb->SectorSize * UDF_DIR_PREALLOC_MIN_SECTORS); + prealloc = (prealloc + Vcb->WriteBlockSize - 1) & ~(ULONGLONG)(Vcb->WriteBlockSize - 1); FileInfo->Dloc->DataLoc.Flags |= EXTENT_FLAG_ALLOC_SEQUENTIAL; - status = UDFResizeExtent(IrpContext, Vcb, PartNum, (t*2+Vcb->WriteBlockSize-1) & ~(ULONGLONG)(Vcb->WriteBlockSize-1), FALSE, &(Dloc->DataLoc)); + status = UDFResizeExtent(IrpContext, Vcb, PartNum, prealloc, FALSE, &(Dloc->DataLoc)); if (NT_SUCCESS(status)) { AdPrint((" preallocated space for Dir\n")); FileInfo->Dloc->DataLoc.Flags |= EXTENT_FLAG_PREALLOCATED; @@ -1681,7 +1678,9 @@ UDFWriteFile__( return status; UDFSetFileSize(FileInfo, t); Dloc->DataLoc.Modified = TRUE; + ASSERT(UDFGetFileSize(FileInfo) <= UDFGetExtentLength(FileInfo->Dloc->DataLoc.Mapping)); + return STATUS_SUCCESS; } // end UDFWriteFile__() @@ -1705,8 +1704,8 @@ UDFUnlinkFile__( PDIR_INDEX_HDR hDirNdx; PDIR_INDEX_HDR hCurDirNdx; PDIR_INDEX_ITEM DirNdx; - NTSTATUS status; - BOOLEAN IsSDir; + NTSTATUS status = STATUS_SUCCESS; + BOOLEAN IsSDir = FALSE; AdPrint(("UDFUnlinkFile__:\n")); if (!FileInfo) return STATUS_SUCCESS; @@ -1894,7 +1893,7 @@ UDFUnlinkAllFilesInDir( PDIR_INDEX_HDR hCurDirNdx; PDIR_INDEX_ITEM CurDirNdx; PUDF_FILE_INFO FileInfo; - NTSTATUS status; + NTSTATUS status = STATUS_SUCCESS; uint_di i; hCurDirNdx = DirInfo->Dloc->DirIndex; @@ -1959,7 +1958,7 @@ UDFOpenFile__( IN uint_di* IndexToOpen ) { - NTSTATUS status; + NTSTATUS status = STATUS_SUCCESS; uint_di i=0; EXTENT_AD FEExt; uint16 Ident; @@ -1967,7 +1966,7 @@ UDFOpenFile__( PDIR_INDEX_ITEM DirNdx; PUDF_FILE_INFO FileInfo; PUDF_FILE_INFO ParFileInfo; - ULONG ReadBytes; + ULONG ReadBytes = 0; *_FileInfo = NULL; if (!hDirNdx) return STATUS_NOT_A_DIRECTORY; @@ -2298,7 +2297,7 @@ UDFOpenRootFile__( ) { uint32 RootLBA; - NTSTATUS status; + NTSTATUS status = STATUS_SUCCESS; // uint32 PartNum = RootLoc->partitionReferenceNum; uint32 LBS = Vcb->SectorSize; uint16 Ident; @@ -2380,8 +2379,8 @@ UDFCleanUpFile__( { PUDF_DATALOC_INFO Dloc; uint32 lc = 0; - BOOLEAN IsASDir; - BOOLEAN KeepDloc; + BOOLEAN IsASDir = FALSE; + BOOLEAN KeepDloc = FALSE; PDIR_INDEX_ITEM DirNdx = NULL, DirNdx2; BOOLEAN Parallel = FALSE; BOOLEAN Linked = FALSE; @@ -2604,24 +2603,31 @@ UDFCleanUpFile__( } #endif //UDF_TRACK_ONDISK_ALLOCATION if (FileInfo->Dloc->DirIndex) { + PDIR_INDEX_HDR tmpDirIndex; uint_di i; - for(i=2; (DirNdx = UDFDirIndex(Dloc->DirIndex,i)); i++) { + tmpDirIndex = Dloc->DirIndex; + Dloc->DirIndex = NULL; + for(i=2; (DirNdx = UDFDirIndex(tmpDirIndex,i)); i++) { ASSERT(!DirNdx->FileInfo); - if (DirNdx->FName.Buffer) + if (DirNdx->FName.Buffer) { MyFreePool__(DirNdx->FName.Buffer); + DirNdx->FName.Buffer = NULL; + } } - UDFDirIndexFree(Dloc->DirIndex); - Dloc->DirIndex = NULL; + UDFDirIndexFree(tmpDirIndex); #ifdef UDF_TRACK_ONDISK_ALLOCATION UDFIndexDirectory(Vcb, FileInfo); if (FileInfo->Dloc->DirIndex) { - for(i=2; DirNdx = UDFDirIndex(Dloc->DirIndex,i); i++) { + tmpDirIndex = Dloc->DirIndex; + Dloc->DirIndex = NULL; + for(i=2; (DirNdx = UDFDirIndex(tmpDirIndex,i)); i++) { ASSERT(!DirNdx->FileInfo); - if (DirNdx->FName.Buffer) + if (DirNdx->FName.Buffer) { MyFreePool__(DirNdx->FName.Buffer); + DirNdx->FName.Buffer = NULL; + } } - UDFDirIndexFree(Dloc->DirIndex); - Dloc->DirIndex = NULL; + UDFDirIndexFree(tmpDirIndex); } #endif //UDF_TRACK_ONDISK_ALLOCATION } @@ -2752,7 +2758,7 @@ UDFCreateFile__( { uint32 l, d; uint_di i, j; - NTSTATUS status; + NTSTATUS status = STATUS_SUCCESS; LONG_AD FEicb; UDF_DIR_SCAN_CONTEXT ScanContext; PDIR_INDEX_HDR hDirNdx = DirInfo->Dloc->DirIndex; @@ -2761,7 +2767,7 @@ UDFCreateFile__( PUDF_FILE_INFO FileInfo; *_FileInfo = NULL; BOOLEAN undel = FALSE; - ULONG ReadBytes; + ULONG ReadBytes = 0; SIZE_T WrittenBytes; // BOOLEAN PackDir = FALSE; BOOLEAN FEAllocated = FALSE; @@ -3000,8 +3006,15 @@ UDFCreateFile__( FileInfo->Dloc->DataLoc.Mapping[0].extLength &= UDF_EXTENT_LENGTH_MASK; FileInfo->Dloc->DataLoc.Modified = TRUE; FileInfo->Dloc->FELoc.Mapping[0].extLength &= UDF_EXTENT_LENGTH_MASK; - // zero sector for FileEntry + // Mark the FE sector as newly allocated so that UDFFlushFE writes the + // full sector (FE content + zero padding) in a single call instead of + // the previous two-step sequence (explicit zero-write here followed by + // a read-modify-write inside UDFWriteInSector). CDR media still needs + // the explicit zero-write because UDFFlushFE skips the padded path in + // that mode. if (!Vcb->CDR_Mode) { + FileInfo->Dloc->FE_Flags |= UDF_FE_FLAG_NEW_SECTOR; + } else { status = UDFWriteData(IrpContext, Vcb, TRUE, ((int64)(FileInfo->Dloc->FELoc.Mapping[0].extLocation)) << Vcb->SectorShift, LBS, FALSE, Vcb->ZBuffer, &WrittenBytes); if (!NT_SUCCESS(status)) { UDFFlushFI(IrpContext, Vcb, FileInfo, PartNum); @@ -3131,7 +3144,7 @@ UDFPadLastSector( PEXTENT_MAP Extent = ExtInfo->Mapping; // Extent array SIZE_T to_write, WrittenBytes; uint32 Lba, sect_offs, flags; - NTSTATUS status; + NTSTATUS status = STATUS_SUCCESS; // Length should not be zero int64 Offset = ExtInfo->Length + ExtInfo->Offset; // data is sector-size-aligned, we needn't any padding @@ -3185,7 +3198,7 @@ UDFCloseFile__( return STATUS_SUCCESS; } PUDF_FILE_INFO DirInfo = FileInfo->ParentFile; - NTSTATUS status; + NTSTATUS status = STATUS_SUCCESS; uint32 PartNum; if (FileInfo->RefCount) { InterlockedDecrement((PLONG)&FileInfo->RefCount); @@ -3344,7 +3357,7 @@ UDFRenameMoveFile__( ) { PUDF_FILE_INFO FileInfo2; - NTSTATUS status; + NTSTATUS status = STATUS_SUCCESS; PDIR_INDEX_ITEM DirNdx1; PDIR_INDEX_ITEM DirNdx2; uint_di i,j; @@ -3572,7 +3585,7 @@ UDFRecordDirectory__( IN OUT PUDF_FILE_INFO DirInfo // source (opened) ) { - NTSTATUS status; + NTSTATUS status = STATUS_SUCCESS; LONG_AD FEicb; UDF_FILE_INFO FileInfo; UDF_DATALOC_INFO Dloc; @@ -3584,6 +3597,8 @@ UDFRecordDirectory__( // validate DirInfo ValidateFileInfo(DirInfo); + AdPrint(("UDFRecordDirectory__: FE @%x\n", + DirInfo->Dloc ? DirInfo->Dloc->FELoc.Mapping[0].extLocation : 0)); if (DirInfo->ParentFile && UDFIsAStreamDir(DirInfo->ParentFile)) return STATUS_ACCESS_DENIED; // file should be empty @@ -3610,6 +3625,7 @@ UDFRecordDirectory__( lba = DirInfo->Dloc->FELoc.Mapping[0].extLocation; ASSERT(lba); PartNum = UDFGetRefPartNumByPhysLba(Vcb, lba); + AdPrint((" lba %x, PartNum %x\n", lba, PartNum)); FEicb.extLength = Vcb->SectorSize; FEicb.extLocation.logicalBlockNum = UDFPhysLbaToPart(Vcb, PartNum, lba); FEicb.extLocation.partitionReferenceNum = (uint16)PartNum; @@ -3628,16 +3644,38 @@ UDFRecordDirectory__( Vcb, &(FileInfo.FileIdent->descTag), (uint16)(FileInfo.FileIdentLen), FEicb.extLocation.logicalBlockNum, 0); FileInfo.Dloc->DataLoc.Flags |= EXTENT_FLAG_VERIFY; // for metadata // flush + AdPrint((" writing parent FID, len %x\n", FileInfo.FileIdentLen)); status = UDFWriteFile__(IrpContext, Vcb, DirInfo, 0, FileInfo.FileIdentLen, FALSE, (int8*)(FileInfo.FileIdent), &WrittenBytes); // status = UDFFlushFI(Vcb, &FileInfo, PartNum); + ASSERT(UDFGetFileSize(DirInfo) <= UDFGetExtentLength(DirInfo->Dloc->DataLoc.Mapping)); + MyFreePool__(FileInfo.FileIdent); - if (!NT_SUCCESS(status)) return status; + if (!NT_SUCCESS(status)) { + AdPrint((" UDFWriteFile__ failed %x\n", status)); + return status; + } + AdPrint((" UDFWriteFile__ OK, written %x bytes\n", (ULONG)WrittenBytes)); if (CurDirNdx) CurDirNdx->FileCharacteristics = DirInfo->FileIdent->fileCharacteristics; - return UDFIndexDirectory(IrpContext, Vcb, DirInfo); + AdPrint((" calling UDFIndexDirectory\n")); + status = UDFIndexDirectory(IrpContext, Vcb, DirInfo); + if (!NT_SUCCESS(status)) { + AdPrint((" UDFIndexDirectory failed %x\n", status)); + return status; + } + AdPrint((" UDFIndexDirectory OK, calling UDFFlushFE\n")); + // The FE was already written by UDFCreateFile__'s UDFFlushFE as a regular + // empty file. UDFWriteFile__ above modified DataLoc (new allocation, + // non-zero informationLength) and the in-memory FE now has + // fileType = UDF_FILE_TYPE_DIRECTORY. Flush the FE now so that the + // on-disk copy is consistent; without this a crash before close would + // leave a corrupt regular-empty-file FE on disk. + status = UDFFlushFE(IrpContext, Vcb, DirInfo, PartNum); + AdPrint(("UDFRecordDirectory__: done, status %x\n", status)); + return status; } // end UDFRecordDirectory__() /* @@ -3651,9 +3689,9 @@ UDFResizeFile__( IN int64 NewLength ) { - ULONG ReadBytes; + ULONG ReadBytes = 0; SIZE_T WrittenBytes; - NTSTATUS status; + NTSTATUS status = STATUS_SUCCESS; uint32 PartNum; int8* OldInIcb = NULL; PEXTENT_MAP NewMap; @@ -3733,10 +3771,12 @@ UDFResizeFile__( ((PFILE_ENTRY)(FileInfo->Dloc->FileEntry))->icbTag.flags &= ~ICB_FLAG_ALLOC_MASK; ((PFILE_ENTRY)(FileInfo->Dloc->FileEntry))->icbTag.flags |= ICB_FLAG_AD_IN_ICB; // Set embedded data flag since file is now in ICB mode + // Fcb may be NULL during directory operations (FCB not yet created) if (FileInfo->Fcb) { FileInfo->Fcb->FcbState |= UDF_FCB_EMBEDDED_DATA; } + // init new data location descriptors FileInfo->Dloc->DataLoc.Mapping = NewMap; RtlZeroMemory((int8*)(FileInfo->Dloc->DataLoc.Mapping), 2*sizeof(EXTENT_MAP)); @@ -3768,8 +3808,10 @@ UDFResizeFile__( UDFSetFileSize(FileInfo, NewLength); } + ASSERT(UDFGetFileSize(FileInfo) <= UDFGetExtentLength(FileInfo->Dloc->DataLoc.Mapping)); + return status; } // end UDFResizeFile__() @@ -3784,11 +3826,11 @@ UDFLoadVAT( ) { lb_addr VatFELoc; - NTSTATUS status; + NTSTATUS status = STATUS_SUCCESS; PUDF_FILE_INFO VatFileInfo; uint32 len, i=0, j, to_read; uint32 Offset, hdrOffset; - ULONG ReadBytes; + ULONG ReadBytes = 0; uint32 root; uint16 PartNum; // uint32 VatFirstLba = 0; @@ -3897,7 +3939,7 @@ UDFLoadVAT( goto err_vat_15; } // read VAT & remember old version - Vcb->Vat = (uint32*)DbgAllocatePool(NonPagedPool, (Vcb->LastPossibleLBA+1)*sizeof(uint32) ); + Vcb->Vat = (PCHAR)DbgAllocatePool(NonPagedPool, (Vcb->LastPossibleLBA+1)*sizeof(uint32) ); if (!Vcb->Vat) { goto err_vat_15_2; } @@ -3924,7 +3966,7 @@ UDFLoadVAT( // contain _relative_ addresses len = Vcb->NWA - root; for(i=0; i<=len; i++) { - Vcb->Vat[i] = i; + UDFVatSetEntry(Vcb->Vat, i, i); } RtlCopyMemory(Vcb->Vat, VatOldData+Offset, to_read); Vcb->InitVatCount = @@ -3932,10 +3974,10 @@ UDFLoadVAT( Vcb->VatPartNdx = PartNdx; Vcb->CDR_Mode = TRUE; len = Vcb->VatCount; - RtlFillMemory(&(Vcb->Vat[Vcb->NWA-root]), (Vcb->LastPossibleLBA-Vcb->NWA+1)*sizeof(uint32), 0xff); + RtlFillMemory(&(((uint32*)Vcb->Vat)[Vcb->NWA-root]), (Vcb->LastPossibleLBA-Vcb->NWA+1)*sizeof(uint32), 0xff); // sync VAT and FSBM for(i=0; iVat[i] == UDF_VAT_FREE_ENTRY) { + if (((uint32*)Vcb->Vat)[i] == UDF_VAT_FREE_ENTRY) { UDFSetFreeBit(Vcb->FSBM_Bitmap, root+i); } } @@ -3971,7 +4013,7 @@ UDFReadFileEA( ) { PFILE_ENTRY FileEntry; - NTSTATUS status; + NTSTATUS status = STATUS_SUCCESS; if (FileDirNdx->FileInfo) { FileEntry = (PFILE_ENTRY)(FileDirNdx->FileInfo->Dloc->FileEntry); @@ -4056,7 +4098,7 @@ UDFFlushFE( ) { int8* NewAllocDescs; - NTSTATUS status; + NTSTATUS status = STATUS_SUCCESS; SIZE_T WrittenBytes; uint16 AllocMode; uint32 lba; @@ -4090,7 +4132,9 @@ UDFFlushFE( return status; } #ifdef UDF_DBG + ASSERT(UDFGetFileSize(FileInfo) <= UDFGetExtentLength(FileInfo->Dloc->DataLoc.Mapping)); + AllocMode = ((PFILE_ENTRY)(FileInfo->Dloc->FileEntry))->icbTag.flags & ICB_FLAG_ALLOC_MASK; #endif // UDF_DBG // initiate update of lengthAllocDescs @@ -4120,7 +4164,9 @@ UDFFlushFE( ASSERT(UDFGetExtentLength(FileInfo->Dloc->DataLoc.Mapping) == 0); } else { + ASSERT(UDFGetFileSize(FileInfo) <= UDFGetExtentLength(FileInfo->Dloc->DataLoc.Mapping)); + } #endif // UDF_DBG } @@ -4180,10 +4226,46 @@ UDFFlushFE( UDFPhysLbaToPart(Vcb, PartNum, lba), 0); } } - status = UDFWriteExtent( - IrpContext, - Vcb, &FileInfo->Dloc->FELoc, 0, (uint32)(FileInfo->Dloc->FELoc.Length), FALSE, - (int8 *)(FileInfo->Dloc->FileEntry), &WrittenBytes); + // Write the FE to disk. When the FE sector was freshly allocated in + // this file-creation call (UDF_FE_FLAG_NEW_SECTOR is set), write the + // full sector as a single zero-padded buffer. This replaces the + // previous three-step sequence (zero-write the sector in + // UDFCreateFile__, then read-before-write inside UDFWriteInSector when + // the FE is smaller than a full sector) with a single write I/O. + { + BOOLEAN newSector = !!(FileInfo->Dloc->FE_Flags & UDF_FE_FLAG_NEW_SECTOR); + uint32 feLen = (uint32)(FileInfo->Dloc->FELoc.Length); + uint32 LBS_fe = Vcb->SectorSize; + FileInfo->Dloc->FE_Flags &= ~UDF_FE_FLAG_NEW_SECTOR; + + if (newSector && feLen < LBS_fe) { + // Allocate a sector-sized staging buffer, copy the FE into the + // beginning, and zero-fill the rest so the trailing bytes are + // clean without a separate read-modify-write. + int8* padBuf = (int8*)MyAllocatePool__(NonPagedPool, LBS_fe); + if (padBuf) { + RtlCopyMemory(padBuf, FileInfo->Dloc->FileEntry, feLen); + RtlZeroMemory(padBuf + feLen, LBS_fe - feLen); + SIZE_T _wb = 0; + status = UDFWriteData(IrpContext, Vcb, TRUE, + ((int64)lba) << Vcb->SectorShift, LBS_fe, FALSE, padBuf, &_wb); + WrittenBytes = _wb; + MyFreePool__(padBuf); + } else { + // Pool exhausted; fall through to the regular path which + // may do a read-modify-write but is always correct. + status = UDFWriteExtent( + IrpContext, + Vcb, &FileInfo->Dloc->FELoc, 0, feLen, FALSE, + (int8 *)(FileInfo->Dloc->FileEntry), &WrittenBytes); + } + } else { + status = UDFWriteExtent( + IrpContext, + Vcb, &FileInfo->Dloc->FELoc, 0, feLen, FALSE, + (int8 *)(FileInfo->Dloc->FileEntry), &WrittenBytes); + } + } if (!NT_SUCCESS(status)) { UDFPrint((" FlushFE: UDFWriteExtent(2) failed (%x)\n", status)); if (status == STATUS_DEVICE_DATA_ERROR) { @@ -4263,7 +4345,7 @@ UDFFlushFI( { PUDF_FILE_INFO DirInfo = FileInfo->ParentFile; PDIR_INDEX_ITEM DirNdx; - NTSTATUS status; + NTSTATUS status = STATUS_SUCCESS; SIZE_T WrittenBytes; // use WrittenBytes variable to store LBA of FI to be recorded #define lba WrittenBytes @@ -4334,7 +4416,7 @@ UDFFlushFile__( ValidateFileInfo(FileInfo); if (!FileInfo) return STATUS_SUCCESS; - NTSTATUS status; + NTSTATUS status = STATUS_SUCCESS; uint32 PartNum; ASSERT(FileInfo->Dloc->FELoc.Mapping[0].extLocation); @@ -4579,12 +4661,12 @@ UDFReadTagged( uint16 *Ident ) { - NTSTATUS RC; + NTSTATUS RC = STATUS_SUCCESS; tag* PTag = (tag*)Buf; // icbtag* Icb = (icbtag*)(Buf+1); uint8 checksum; unsigned int i; - ULONG ReadBytes; + ULONG ReadBytes = 0; int8* tb; // Read the block @@ -4668,7 +4750,7 @@ UDFHardLinkFile__( ) { PUDF_FILE_INFO FileInfo2; - NTSTATUS status; + NTSTATUS status = STATUS_SUCCESS; PDIR_INDEX_ITEM DirNdx1; PDIR_INDEX_ITEM DirNdx2; uint_di i; @@ -4823,7 +4905,7 @@ UDFCreateRootFile__( OUT PUDF_FILE_INFO* _FileInfo ) { - NTSTATUS status; + NTSTATUS status = STATUS_SUCCESS; LONG_AD FEicb; PUDF_FILE_INFO FileInfo; *_FileInfo = NULL; @@ -4882,7 +4964,7 @@ UDFCreateStreamDir__( // any pointers ) { - NTSTATUS status; + NTSTATUS status = STATUS_SUCCESS; PUDF_FILE_INFO SDirInfo; uint16 Ident; @@ -4968,7 +5050,7 @@ UDFOpenStreamDir__( // any pointers ) { - NTSTATUS status; + NTSTATUS status = STATUS_SUCCESS; PUDF_FILE_INFO SDirInfo; PUDF_FILE_INFO ParSDirInfo; uint16 Ident; @@ -5040,8 +5122,8 @@ UDFRecordVAT( uint32 to_read; uint32 hdrOffset, hdrOffsetNew; uint32 hdrLen; - NTSTATUS status; - ULONG ReadBytes; + NTSTATUS status = STATUS_SUCCESS; + ULONG ReadBytes = 0; SIZE_T WrittenBytes; uint32 len; uint16 PartNdx = (uint16)Vcb->VatPartNdx; @@ -5062,7 +5144,7 @@ UDFRecordVAT( uint32 OldLen; EntityID* eID; - if (!(Vat = Vcb->Vat) || !VatFileInfo) return STATUS_INVALID_PARAMETER; + if (!(Vat = (uint32*)Vcb->Vat) || !VatFileInfo) return STATUS_INVALID_PARAMETER; // Disable VAT-based translation Vcb->Vat = NULL; // sync VAT and FSBM @@ -5181,7 +5263,9 @@ UDFRecordVAT( UDFWriteData(IrpContext, Vcb, TRUE, ((uint64)Vcb->NWA) << Vcb->SectorShift, 1, FALSE, Old, &WrittenBytes); PacketOffset++; } else { - Vcb->Vat = (uint32*)(New+Offset); + + Vcb->Vat = (PCHAR)(New+Offset); + Vcb->Vat = NULL; } VatFileInfo->Dloc->FELoc.Mapping[0].extLocation = @@ -5203,7 +5287,9 @@ UDFRecordVAT( if (!NT_SUCCESS(status)) return status; // update VAT with locations of not flushed blocks if (PacketOffset) { - Vcb->Vat = (uint32*)(New+Offset); + + Vcb->Vat = (PCHAR)(New+Offset); + Vcb->Vat = NULL; } @@ -5339,7 +5425,7 @@ UDFUpdateVAT( for(i=0; i= Vcb->VatCount) Vcb->VatCount = CurLba+1; - Vcb->Vat[CurLba] = NWA; + ((uint32*)Vcb->Vat)[CurLba] = NWA; } return STATUS_SUCCESS; } // end UDFUpdateVAT() @@ -5358,8 +5444,8 @@ UDFConvertFEToExtended( PEXTENDED_FILE_ENTRY ExFileEntry; PFILE_ENTRY FileEntry; uint32 Length, NewLength, l; - NTSTATUS status; - ULONG ReadBytes; + NTSTATUS status = STATUS_SUCCESS; + ULONG ReadBytes = 0; SIZE_T WrittenBytes; if (!FileInfo) return STATUS_INVALID_PARAMETER; @@ -5466,7 +5552,7 @@ UDFPretendFileDeleted__( { AdPrint(("UDFPretendFileDeleted__:\n")); - NTSTATUS RC; + NTSTATUS RC = STATUS_SUCCESS; PDIR_INDEX_HDR hDirNdx = UDFGetDirIndexByFileInfo(FileInfo); if (!hDirNdx) return STATUS_CANNOT_DELETE; PDIR_INDEX_ITEM DirNdx = UDFDirIndex(hDirNdx, FileInfo->Index); diff --git a/drivers/filesystems/udfs/udf_info/udf_info.h b/drivers/filesystems/udfs/udf_info/udf_info.h index d68b0d6437f3f..59b7b42517631 100644 --- a/drivers/filesystems/udfs/udf_info/udf_info.h +++ b/drivers/filesystems/udfs/udf_info/udf_info.h @@ -1388,28 +1388,600 @@ UDFDirIndex( #define CheckAddr(addr) {ASSERT((uint32)(addr) & 0x80000000);} -#define UDFGetBit(arr, bit) ( (BOOLEAN) ( ((((uint32*)(arr))[(bit)>>5]) >> ((bit)&31)) &1 ) ) -#define UDFSetBit(arr, bit) ( (((uint32*)(arr))[(bit)>>5]) |= (((uint32)1) << ((bit)&31)) ) -#define UDFClrBit(arr, bit) ( (((uint32*)(arr))[(bit)>>5]) &= (~(((uint32)1) << ((bit)&31))) ) - -#define UDFSetBits(arr, bit, bc) \ -{uint32 j; \ - for(j=0;jSignature == UDF_CHUNKED_BUF_SIGNATURE); +} + +__inline +PUDF_CHUNKED_BUF +UDFGetChunked( + IN PVOID Bitmap + ) +{ + return (PUDF_CHUNKED_BUF)(((ULONG_PTR)Bitmap) & ~UDF_CHUNKED_PTR_TAG); +} + +__inline +PCHAR +UDFTagChunked( + IN PUDF_CHUNKED_BUF Bitmap + ) +{ + return (PCHAR)(((ULONG_PTR)Bitmap) | UDF_CHUNKED_PTR_TAG); +} + +__inline +PUCHAR +UDFChunkedGetBytePtr( + IN PVOID Bitmap, + IN ULONG ByteIndex + ) +{ + PUDF_CHUNKED_BUF Chunked; + + if (!UDFIsChunked(Bitmap)) { + return &((PUCHAR)Bitmap)[ByteIndex]; + } + + Chunked = UDFGetChunked(Bitmap); + if (!Chunked->Chunks[ByteIndex >> UDF_CHUNK_SHIFT]) { + /* Fixed-size zero page – size is independent of UDF_CHUNK_SIZE so that + * changing UDF_CHUNK_SHIFT does not inflate the driver binary. The + * static assertion below guards against UDF_CHUNK_SIZE ever exceeding + * this buffer. Callers may only read up to + * UDFChunkedGetContiguousLength() bytes from the returned pointer, which + * is at most UDF_CHUNK_SIZE bytes. */ + static const UCHAR ZeroChunk[4096] = {0}; + C_ASSERT(UDF_CHUNK_SIZE <= sizeof(ZeroChunk)); + return (PUCHAR)&ZeroChunk[ByteIndex & UDF_CHUNK_MASK]; + } + return &((PUCHAR)(Chunked->Chunks[ByteIndex >> UDF_CHUNK_SHIFT]))[ByteIndex & UDF_CHUNK_MASK]; +} + +__inline +PUCHAR +UDFChunkedGetOrAllocBytePtr( + IN PVOID Bitmap, + IN ULONG ByteIndex + ) +{ + PUDF_CHUNKED_BUF Chunked; + ULONG ChunkIdx; + ULONG ChunkLength; + PCHAR Chunk; + + if (!UDFIsChunked(Bitmap)) { + return &((PUCHAR)Bitmap)[ByteIndex]; + } + + Chunked = UDFGetChunked(Bitmap); + ChunkIdx = ByteIndex >> UDF_CHUNK_SHIFT; + if (!Chunked->Chunks[ChunkIdx]) { + ChunkLength = min((ULONG)UDF_CHUNK_SIZE, Chunked->ByteCount - (ChunkIdx << UDF_CHUNK_SHIFT)); + // PagedPool is intentional: chunked bitmap chunks are only ever dereferenced + // at PASSIVE_LEVEL (under Vcb resource locks), so paged memory is safe and + // avoids exhausting the much-smaller NonPagedPool for large bitmaps. + Chunk = (PCHAR)DbgAllocatePool(PagedPool, ChunkLength); + if (!Chunk) { + UDFPrint(("UDFChunkedGetOrAllocBytePtr: chunk[%x] alloc failed\n", ChunkIdx)); + return NULL; + } + RtlZeroMemory(Chunk, ChunkLength); + Chunked->Chunks[ChunkIdx] = Chunk; + } + return &((PUCHAR)(Chunked->Chunks[ChunkIdx]))[ByteIndex & UDF_CHUNK_MASK]; +} + +__inline +ULONG +UDFChunkedGetContiguousLength( + IN PVOID Bitmap, + IN ULONG ByteIndex + ) +{ + if (!UDFIsChunked(Bitmap)) { + return MAXULONG; + } + return UDF_CHUNK_SIZE - (ByteIndex & UDF_CHUNK_MASK); +} + +__inline +UCHAR +UDFChunkedGetByte( + IN PVOID Bitmap, + IN ULONG ByteIndex + ) +{ + return *(UDFChunkedGetBytePtr(Bitmap, ByteIndex)); +} + +__inline +VOID +UDFChunkedSetByte( + IN PVOID Bitmap, + IN ULONG ByteIndex, + IN UCHAR Value + ) +{ + PUCHAR pByte = UDFChunkedGetOrAllocBytePtr(Bitmap, ByteIndex); + if (pByte) *pByte = Value; +} + +__inline +VOID +UDFChunkedSetBit( + IN PVOID Bitmap, + IN ULONG BitIndex + ) +{ + PUCHAR pByte = UDFChunkedGetOrAllocBytePtr(Bitmap, BitIndex >> 3); + if (pByte) (*pByte) |= (UCHAR)(1 << (BitIndex & 7)); +} + +__inline +VOID +UDFChunkedClearBit( + IN PVOID Bitmap, + IN ULONG BitIndex + ) +{ + PUCHAR pByte; + if (UDFIsChunked(Bitmap) && !UDFGetChunked(Bitmap)->Chunks[(BitIndex >> 3) >> UDF_CHUNK_SHIFT]) + return; // chunk not allocated; bit is already 0 (cleared), no-op + pByte = UDFChunkedGetBytePtr(Bitmap, BitIndex >> 3); + (*pByte) &= (UCHAR)(~(1 << (BitIndex & 7))); +} + +__inline +PCHAR +UDFAllocChunked( + IN ULONG ByteCount + ) +{ + ULONG ChunkCount; + SIZE_T HeaderLength; + PUDF_CHUNKED_BUF Chunked; + + UDFPrint(("UDFAllocChunked: ByteCount=%x\n", ByteCount)); + + if (!ByteCount) + return NULL; + + ChunkCount = (ByteCount + UDF_CHUNK_MASK) >> UDF_CHUNK_SHIFT; + HeaderLength = sizeof(UDF_CHUNKED_BUF) + (ChunkCount - 1) * sizeof(PCHAR); + + UDFPrint(("UDFAllocChunked: ChunkCount=%x HeaderLength=%x\n", ChunkCount, (ULONG)HeaderLength)); + + Chunked = (PUDF_CHUNKED_BUF)DbgAllocatePool(NonPagedPool, HeaderLength); + if (!Chunked) { + UDFPrint(("UDFAllocChunked: header alloc failed\n")); + return NULL; + } + + ASSERT((((ULONG_PTR)Chunked) & UDF_CHUNKED_PTR_TAG) == 0); + RtlZeroMemory(Chunked, HeaderLength); + Chunked->Signature = UDF_CHUNKED_BUF_SIGNATURE; + Chunked->ByteCount = ByteCount; + Chunked->ChunkCount = ChunkCount; + + // Chunks are NOT pre-allocated; they are lazily allocated on first write + // via UDFChunkedGetOrAllocBytePtr, keeping boot-time memory usage minimal. + + UDFPrint(("UDFAllocChunked: done (lazy), header=%p tagged=%p\n", Chunked, UDFTagChunked(Chunked))); + return UDFTagChunked(Chunked); +} + +__inline +VOID +UDFFreeChunked( + IN PCHAR Bitmap + ) +{ + ULONG i; + PUDF_CHUNKED_BUF Chunked; + + UDFPrint(("UDFFreeChunked: Bitmap=%p\n", Bitmap)); + + if (!Bitmap) + return; + + if (!UDFIsChunked(Bitmap)) { + UDFPrint(("UDFFreeChunked: flat bitmap, freeing directly\n")); + DbgFreePool(Bitmap); + return; + } + + Chunked = UDFGetChunked(Bitmap); + UDFPrint(("UDFFreeChunked: chunked header=%p ChunkCount=%x\n", Chunked, Chunked->ChunkCount)); + for (i = 0; i < Chunked->ChunkCount; i++) { + if (Chunked->Chunks[i]) { + UDFPrint(("UDFFreeChunked: freeing chunk[%x]=%p\n", i, Chunked->Chunks[i])); + DbgFreePool(Chunked->Chunks[i]); + } + } + DbgFreePool(Chunked); + UDFPrint(("UDFFreeChunked: done\n")); +} + +__inline +VOID +UDFChunkedFillMemory( + IN PCHAR Bitmap, + IN ULONG ByteIndex, + IN ULONG ByteCount, + IN UCHAR Value + ) +{ + ULONG i = 0; + ULONG c; + PUCHAR ptr; + + if (!UDFIsChunked(Bitmap)) { + RtlFillMemory(Bitmap + ByteIndex, ByteCount, Value); + return; + } + while (i < ByteCount) { + c = min(UDFChunkedGetContiguousLength(Bitmap, ByteIndex + i), ByteCount - i); + if (Value == 0) { + // Zero-fill: null chunks are already all-zero (free by default in FSBM). + // Skip allocation if this chunk has never been written. + ULONG chunkIdx = (ByteIndex + i) >> UDF_CHUNK_SHIFT; + if (!UDFGetChunked(Bitmap)->Chunks[chunkIdx]) { + i += c; + continue; + } + } + ptr = UDFChunkedGetOrAllocBytePtr(Bitmap, ByteIndex + i); + if (ptr) RtlFillMemory(ptr, c, Value); + i += c; + } +} + +/* + * UDFChunkedSetBitRange - set BitCount bits starting at BitStart. + * + * For the chunked case this avoids the per-bit chunk-pointer lookup that the + * old UDFSetBits loop caused. Instead it touches at most three byte-level + * accesses (leading partial byte, bulk fill, trailing partial byte), making + * large-range operations O(bytes) rather than O(bits). + */ +__inline +VOID +UDFChunkedSetBitRange( + IN PVOID Bitmap, + IN ULONG BitStart, + IN ULONG BitCount + ) +{ + ULONG firstByte, lastByte; + ULONG firstBit, lastBit; + PUCHAR pByte; + + if (!BitCount) + return; + + firstBit = BitStart & 7; + lastBit = (BitStart + BitCount - 1) & 7; + firstByte = BitStart >> 3; + lastByte = (BitStart + BitCount - 1) >> 3; + + if (firstByte == lastByte) { + /* All bits within one byte */ + UCHAR mask = (UCHAR)((0xFFU << firstBit) & (0xFFU >> (7 - lastBit))); + pByte = UDFChunkedGetOrAllocBytePtr(Bitmap, firstByte); + if (pByte) *pByte |= mask; + return; + } + + /* Leading partial byte */ + if (firstBit) { + pByte = UDFChunkedGetOrAllocBytePtr(Bitmap, firstByte); + if (pByte) *pByte |= (UCHAR)(0xFFU << firstBit); + firstByte++; + } + + /* Trailing partial byte */ + if (lastBit != 7) { + pByte = UDFChunkedGetOrAllocBytePtr(Bitmap, lastByte); + if (pByte) *pByte |= (UCHAR)(0xFFU >> (7 - lastBit)); + lastByte--; + } + + /* Bulk fill of complete bytes */ + if (firstByte <= lastByte) { + UDFChunkedFillMemory((PCHAR)Bitmap, firstByte, lastByte - firstByte + 1, 0xFF); + } +} + +/* + * UDFChunkedClrBitRange - clear BitCount bits starting at BitStart. + * + * Symmetric to UDFChunkedSetBitRange. Unallocated (null) chunks are already + * all-zero so they are skipped without allocation. + */ +__inline +VOID +UDFChunkedClrBitRange( + IN PVOID Bitmap, + IN ULONG BitStart, + IN ULONG BitCount + ) +{ + ULONG firstByte, lastByte; + ULONG firstBit, lastBit; + BOOLEAN isChunked; + PUCHAR pByte; + + if (!BitCount) + return; + + firstBit = BitStart & 7; + lastBit = (BitStart + BitCount - 1) & 7; + firstByte = BitStart >> 3; + lastByte = (BitStart + BitCount - 1) >> 3; + isChunked = UDFIsChunked(Bitmap); + + if (firstByte == lastByte) { + UCHAR mask = (UCHAR)((0xFFU << firstBit) & (0xFFU >> (7 - lastBit))); + /* Null chunk means bits are already 0 – no-op */ + if (isChunked && !UDFGetChunked(Bitmap)->Chunks[firstByte >> UDF_CHUNK_SHIFT]) + return; + pByte = UDFChunkedGetBytePtr(Bitmap, firstByte); + *pByte &= (UCHAR)~mask; + return; + } + + /* Leading partial byte */ + if (firstBit) { + if (!isChunked || UDFGetChunked(Bitmap)->Chunks[firstByte >> UDF_CHUNK_SHIFT]) { + pByte = UDFChunkedGetBytePtr(Bitmap, firstByte); + *pByte &= (UCHAR)(~(0xFFU << firstBit)); + } + firstByte++; + } + + /* Trailing partial byte */ + if (lastBit != 7) { + if (!isChunked || UDFGetChunked(Bitmap)->Chunks[lastByte >> UDF_CHUNK_SHIFT]) { + pByte = UDFChunkedGetBytePtr(Bitmap, lastByte); + *pByte &= (UCHAR)(~(0xFFU >> (7 - lastBit))); + } + lastByte--; + } + + /* Bulk zero of complete bytes – UDFChunkedFillMemory skips null chunks */ + if (firstByte <= lastByte) { + UDFChunkedFillMemory((PCHAR)Bitmap, firstByte, lastByte - firstByte + 1, 0x00); + } +} + +__inline +uint32 +UDFVatGetEntry( + IN PCHAR Vat, + IN ULONG idx + ) +{ + return *(uint32*)UDFChunkedGetBytePtr(Vat, idx * sizeof(uint32)); +} + +__inline +VOID +UDFVatSetEntry( + IN PCHAR Vat, + IN ULONG idx, + IN uint32 val + ) +{ + PUCHAR pByte = UDFChunkedGetOrAllocBytePtr(Vat, idx * sizeof(uint32)); + if (pByte) *(uint32*)pByte = val; +} + +__inline +VOID +UDFChunkedCopyMemory( + IN PCHAR Destination, + IN PCHAR Source, + IN ULONG Length + ) +{ + ULONG i = 0; + ULONG c1, c2, c; + PUCHAR dst; + PUCHAR src; + + if (!UDFIsChunked(Destination) && !UDFIsChunked(Source)) { + RtlCopyMemory(Destination, Source, Length); + return; + } + while (i < Length) { + src = UDFChunkedGetBytePtr(Source, i); + c1 = UDFChunkedGetContiguousLength(Destination, i); + c2 = UDFChunkedGetContiguousLength(Source, i); + c = min(min(c1, c2), Length - i); + dst = UDFChunkedGetOrAllocBytePtr(Destination, i); + if (dst) RtlCopyMemory(dst, src, c); + i += c; + } +} + +__inline +ULONG +UDFChunkedCompareMemory( + IN PCHAR Buffer1, + IN PCHAR Buffer2, + IN ULONG Length + ) +{ + ULONG i; + + if (!UDFIsChunked(Buffer1) && !UDFIsChunked(Buffer2)) + return (ULONG)RtlCompareMemory(Buffer1, Buffer2, Length); + for (i = 0; i < Length; i++) { + if (UDFChunkedGetByte(Buffer1, i) != UDFChunkedGetByte(Buffer2, i)) + return i; + } + return Length; +} + +__inline +VOID +UDFChunkedAndNotMemory( + IN PCHAR Destination, + IN PCHAR Source, + IN ULONG StartByte, + IN ULONG ByteCount + ) +{ + ULONG i = 0; + ULONG c1, c2, c, j; + PUCHAR dst; + PUCHAR src; + while (i < ByteCount) { + src = UDFChunkedGetBytePtr(Source, StartByte + i); + c1 = UDFChunkedGetContiguousLength(Destination, StartByte + i); + c2 = UDFChunkedGetContiguousLength(Source, StartByte + i); + c = min(min(c1, c2), ByteCount - i); + dst = UDFChunkedGetOrAllocBytePtr(Destination, StartByte + i); + if (dst) { + for (j = 0; j < c; j++) { + dst[j] &= (UCHAR)(~src[j]); + } + } + i += c; + } +} + +// UDFChunkedOrMemory: Destination |= Source (byte-by-byte over [StartByte, StartByte+ByteCount)). +// Used to OR bad-block bitmap (BSBM) into the free-space bitmap (FSBM) so that bad blocks +// are marked as used (bit=1) in the FSBM. Source bytes that are zero are skipped so that no +// destination chunk is allocated unless at least one source bit is set. +__inline +VOID +UDFChunkedOrMemory( + IN PCHAR Destination, + IN PCHAR Source, + IN ULONG StartByte, + IN ULONG ByteCount + ) +{ + ULONG i; + PUCHAR dst; + UCHAR s; + for (i = 0; i < ByteCount; i++) { + s = *UDFChunkedGetBytePtr(Source, StartByte + i); + if (s == 0) + continue; // no bits to OR in; skip destination chunk allocation + dst = UDFChunkedGetOrAllocBytePtr(Destination, StartByte + i); + if (dst) *dst |= s; + } +} + +__inline +NTSTATUS +UDFReadExtentIntoChunked( + IN PIRP_CONTEXT IrpContext, + IN PVCB Vcb, + IN PEXTENT_INFO ExtInfo, + IN int64 Offset, + IN ULONG Length, + IN BOOLEAN Direct, + IN PCHAR Bitmap, + OUT PULONG ReadBytes + ) +{ + NTSTATUS status = STATUS_SUCCESS; + ULONG off = 0, c, _ReadBytes; + *ReadBytes = 0; + while (off < Length) { + PUCHAR ptr; + c = min(UDFChunkedGetContiguousLength(Bitmap, off), Length - off); + ptr = UDFChunkedGetOrAllocBytePtr(Bitmap, off); + if (!ptr) { status = STATUS_INSUFFICIENT_RESOURCES; break; } + status = UDFReadExtent(IrpContext, Vcb, ExtInfo, Offset + off, c, Direct, + (int8*)ptr, &_ReadBytes); + if (!NT_SUCCESS(status)) break; + *ReadBytes += _ReadBytes; + off += c; + } + return status; +} + +__inline +NTSTATUS +UDFWriteExtentFromChunked( + IN PIRP_CONTEXT IrpContext, + IN PVCB Vcb, + IN PEXTENT_INFO ExtInfo, + IN int64 Offset, + IN ULONG Length, + IN BOOLEAN Direct, + IN PCHAR Bitmap, + OUT PSIZE_T WrittenBytes + ) +{ + NTSTATUS status = STATUS_SUCCESS; + ULONG off = 0, c; + SIZE_T _WrittenBytes; + *WrittenBytes = 0; + while (off < Length) { + c = min(UDFChunkedGetContiguousLength(Bitmap, off), Length - off); + status = UDFWriteExtent(IrpContext, Vcb, ExtInfo, Offset + off, c, Direct, + (int8*)UDFChunkedGetBytePtr(Bitmap, off), &_WrittenBytes); + if (!NT_SUCCESS(status)) break; + *WrittenBytes += _WrittenBytes; + off += c; + } + return status; +} + +#define UDFGetBit(arr, bit) ( UDFIsChunked((arr)) ? \ + (BOOLEAN)((UDFChunkedGetByte((arr), (ULONG)((bit)>>3)) >> ((bit)&7)) & 1) : \ + (BOOLEAN)((((uint32*)(arr))[(bit)>>5] >> ((bit)&31) & 1)) ) +#define UDFSetBit(arr, bit) do { if (UDFIsChunked((arr))) UDFChunkedSetBit((arr), (ULONG)(bit)); \ + else (((uint32*)(arr))[(bit)>>5]) |= (((uint32)1) << ((bit)&31)); } while (0) +#define UDFClrBit(arr, bit) do { if (UDFIsChunked((arr))) UDFChunkedClearBit((arr), (ULONG)(bit)); \ + else (((uint32*)(arr))[(bit)>>5]) &= (~(((uint32)1) << ((bit)&31))); } while (0) + +#define UDFSetBits(arr, bit, bc) UDFChunkedSetBitRange((arr), (ULONG)(bit), (ULONG)(bc)) + +#define UDFClrBits(arr, bit, bc) UDFChunkedClrBitRange((arr), (ULONG)(bit), (ULONG)(bc)) + +// FSBM_Bitmap uses inverted bit semantics: bit=1 means USED, bit=0 means FREE. +// Null (unallocated) chunks are implicitly all-zero = all FREE, so chunk allocation +// is only triggered when marking blocks as USED — keeping memory usage minimal even +// on mostly-free large disks. +#define UDFGetUsedBit(arr,bit) UDFGetBit(arr,bit) +#define UDFGetFreeBit(arr,bit) (!UDFGetBit(arr,bit)) +#define UDFSetUsedBit(arr,bit) UDFSetBit(arr,bit) +#define UDFSetFreeBit(arr,bit) UDFClrBit(arr,bit) +#define UDFSetUsedBits(arr,bit,bc) UDFSetBits(arr,bit,bc) +#define UDFSetFreeBits(arr,bit,bc) UDFClrBits(arr,bit,bc) #define UDFGetBadBit(arr,bit) UDFGetBit(arr,bit) diff --git a/drivers/filesystems/udfs/udf_info/udf_rel.h b/drivers/filesystems/udfs/udf_info/udf_rel.h index cefcb3b8c2d0c..5ee2ef1c3e34f 100644 --- a/drivers/filesystems/udfs/udf_info/udf_rel.h +++ b/drivers/filesystems/udfs/udf_info/udf_rel.h @@ -325,6 +325,10 @@ typedef struct _UDF_DATALOC_INFO { #define UDF_FE_FLAG_IS_DEL_SDIR (0x20) /// Dloc is being initialized, don't touch it now #define UDF_FE_FLAG_UNDER_INIT (0x40) +/// FE sector is freshly allocated; UDFFlushFE must write it zero-padded +/// to the full sector size to avoid a separate zero-init write followed by +/// a read-modify-write. Cleared by UDFFlushFE after the padded write. +#define UDF_FE_FLAG_NEW_SECTOR (0x80) #define UDF_FILE_INFO_MT PagedPool diff --git a/drivers/filesystems/udfs/udfdata.cpp b/drivers/filesystems/udfs/udfdata.c similarity index 99% rename from drivers/filesystems/udfs/udfdata.cpp rename to drivers/filesystems/udfs/udfdata.c index d1674b7727e54..ee60b53dcf61a 100644 --- a/drivers/filesystems/udfs/udfdata.cpp +++ b/drivers/filesystems/udfs/udfdata.c @@ -76,13 +76,13 @@ Return Value: { THREAD_CONTEXT ThreadContext = {0}; PIRP_CONTEXT IrpContext = NULL; - BOOLEAN Wait; + BOOLEAN Wait = FALSE; #ifdef UDF_SANITY PVOID PreviousTopLevel; #endif - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; #if DBG diff --git a/drivers/filesystems/udfs/udffs.h b/drivers/filesystems/udfs/udffs.h index 272046b907e62..1e6d1dd80382c 100644 --- a/drivers/filesystems/udfs/udffs.h +++ b/drivers/filesystems/udfs/udffs.h @@ -19,8 +19,6 @@ #pragma warning(disable : 28172) -/**************** OPTIONS *****************/ - //#define UDF_LIMIT_NAME_LEN //#define UDF_LIMIT_DIR_SIZE @@ -34,7 +32,6 @@ #endif //UDF_LIMIT_NAME_LEN //#define UDF_ASYNC_IO - #define UDF_ALLOW_FRAG_AD // Read ahead amount used for normal data files @@ -91,6 +88,11 @@ typedef FILE_ID *PFILE_ID; #undef MdlMappingNoExecute #define MdlMappingNoExecute 0 #define NonPagedPoolNx NonPagedPool +// POOL_NX_ALLOCATION (0x200) is a Windows 8+ flag not recognized on XP-based +// systems. Passing it to ExInitialize*LookasideList would result in an invalid +// pool type on Windows XP / POSReady 2009. +#undef POOL_NX_ALLOCATION +#define POOL_NX_ALLOCATION 0 #endif // #define NDEBUG @@ -117,6 +119,13 @@ extern UDFData UdfData; #include "Include/Sys_spec_lib.h" +#if !defined(UDF_DBG) +#define UDFPrint(Args) +#else +#define UDFPrint(Args) KdPrint(Args) +#endif +#define UDFPrintErr(Args) KdPrint(Args) + #include "udf_info/udf_info.h" #include "protos.h" @@ -177,7 +186,6 @@ UDFIllegalFcbAccess( #define UDFPrint(Args) KdPrint(Args) #endif #define UDFPrintErr(Args) KdPrint(Args) - #define UDFAcquireDeviceShared(IrpContext, Vcb, ResourceThreadId) \ ((void)0) /* No operation - CD/DVD write modes not currently supported */ diff --git a/drivers/filesystems/udfs/udfinit.cpp b/drivers/filesystems/udfs/udfinit.c similarity index 97% rename from drivers/filesystems/udfs/udfinit.cpp rename to drivers/filesystems/udfs/udfinit.c index 657034565142c..8f92b303b284b 100644 --- a/drivers/filesystems/udfs/udfinit.cpp +++ b/drivers/filesystems/udfs/udfinit.c @@ -210,8 +210,11 @@ DriverEntry( FilterCallbacks.PreAcquireForSectionSynchronization = UDFFilterCallbackAcquireForCreateSection; RC = FsRtlRegisterFileSystemFilterCallbacks(DriverObject, &FilterCallbacks); - if (!NT_SUCCESS(RC)) - try_return(RC); + if (!NT_SUCCESS(RC)) { + // On Windows XP, this call may fail. Treat as non-fatal. + UDFPrint(("UDF: FsRtlRegisterFileSystemFilterCallbacks failed with %x, continuing\n", RC)); + RC = STATUS_SUCCESS; + } UDFPrint(("UDF: Create CD dev obj\n")); if (!NT_SUCCESS(RC = UDFCreateFsDeviceObject(UDF_FS_NAME_CD, @@ -234,11 +237,13 @@ DriverEntry( if (UdfData.UDFDeviceObject_CD) { UDFPrint(("UDFCreateFsDeviceObject: IoRegisterFileSystem() for CD\n")); IoRegisterFileSystem(UdfData.UDFDeviceObject_CD); + ObReferenceObject(UdfData.UDFDeviceObject_CD); } if (UdfData.UDFDeviceObject_HDD) { UDFPrint(("UDFCreateFsDeviceObject: IoRegisterFileSystem() for HDD\n")); IoRegisterFileSystem(UdfData.UDFDeviceObject_HDD); + ObReferenceObject(UdfData.UDFDeviceObject_HDD); } RC = STATUS_SUCCESS; @@ -270,6 +275,7 @@ DriverEntry( IoDeleteDevice(UdfData.UDFDeviceObject_HDD); UdfData.UDFDeviceObject_HDD = NULL; } + } } _SEH2_END; diff --git a/drivers/filesystems/udfs/udfs_reg.inf b/drivers/filesystems/udfs/udfs_reg.inf index 2822dbdce371c..bb289578eb551 100644 --- a/drivers/filesystems/udfs/udfs_reg.inf +++ b/drivers/filesystems/udfs/udfs_reg.inf @@ -3,5 +3,5 @@ HKLM,"SYSTEM\CurrentControlSet\Services\Udfs","ErrorControl",0x00010001,0x00000001 HKLM,"SYSTEM\CurrentControlSet\Services\Udfs","Group",0x00000000,"File System" HKLM,"SYSTEM\CurrentControlSet\Services\Udfs","ImagePath",0x00020000,"system32\drivers\udfs.sys" -HKLM,"SYSTEM\CurrentControlSet\Services\Udfs","Start",0x00010001,0x00000001 +HKLM,"SYSTEM\CurrentControlSet\Services\Udfs","Start",0x00010001,0x00000003 HKLM,"SYSTEM\CurrentControlSet\Services\Udfs","Type",0x00010001,0x00000002 diff --git a/drivers/filesystems/udfs/unload.c b/drivers/filesystems/udfs/unload.c new file mode 100644 index 0000000000000..c1ffae1967529 --- /dev/null +++ b/drivers/filesystems/udfs/unload.c @@ -0,0 +1,24 @@ +//////////////////////////////////////////////////////////////////// +// Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine +// All rights reserved +// This file was released under the GPLv2 on June 2015. +//////////////////////////////////////////////////////////////////// +#include "udffs.h" + +VOID +NTAPI +UDFDriverUnload( + IN PDRIVER_OBJECT DriverObject + ) +{ + UDFPrint(("UDF: Unloading!!\n")); + + // Release the object references we took in DriverEntry after + // IoRegisterFileSystem, matching Fastfat's FatUnload pattern. + if (UdfData.UDFDeviceObject_CD) { + ObDereferenceObject(UdfData.UDFDeviceObject_CD); + } + if (UdfData.UDFDeviceObject_HDD) { + ObDereferenceObject(UdfData.UDFDeviceObject_HDD); + } +} diff --git a/drivers/filesystems/udfs/unload.cpp b/drivers/filesystems/udfs/unload.cpp deleted file mode 100644 index 33dc5a5d16d57..0000000000000 --- a/drivers/filesystems/udfs/unload.cpp +++ /dev/null @@ -1,53 +0,0 @@ -//////////////////////////////////////////////////////////////////// -// Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine -// All rights reserved -// This file was released under the GPLv2 on June 2015. -//////////////////////////////////////////////////////////////////// -#include "udffs.h" - -VOID -NTAPI -UDFDriverUnload( - IN PDRIVER_OBJECT DriverObject - ) -{ -// UNICODE_STRING uniWin32NameString; - LARGE_INTEGER delay; - - // - // All *THIS* driver needs to do is to delete the device object and the - // symbolic link between our device name and the Win32 visible name. - // - // Almost every other driver ever written would need to do a - // significant amount of work here deallocating stuff. - // - - UDFPrint( ("UDF: Unloading!!\n") ); - - // prevent mount oparations - UdfData.Flags |= UDF_DATA_FLAGS_SHUTDOWN; - - // wait for all volumes to be dismounted - delay.QuadPart = 10*1000*1000*10; - while(TRUE) { - UDFPrint(("Poll...\n")); - KeDelayExecutionThread(KernelMode, FALSE, &delay); - } - - // Create counted string version of our Win32 device name. - - -// RtlInitUnicodeString( &uniWin32NameString, DOS_DEVICE_NAME ); - - - // Delete the link from our device name to a name in the Win32 namespace. - - -// IoDeleteSymbolicLink( &uniWin32NameString ); - - - // Finally delete our device object - - -// IoDeleteDevice( DriverObject->DeviceObject ); -} diff --git a/drivers/filesystems/udfs/verfysup.cpp b/drivers/filesystems/udfs/verfysup.c similarity index 99% rename from drivers/filesystems/udfs/verfysup.cpp rename to drivers/filesystems/udfs/verfysup.c index 015af5a6b423b..5111b0da8a420 100644 --- a/drivers/filesystems/udfs/verfysup.cpp +++ b/drivers/filesystems/udfs/verfysup.c @@ -89,7 +89,7 @@ UDFVerifyVcb( IO_STATUS_BLOCK Iosb; ULONG MediaChangeCount = 0; BOOLEAN ForceVerify = FALSE; - BOOLEAN DevMarkedForVerify; + BOOLEAN DevMarkedForVerify = FALSE; ASSERT(ExIsResourceAcquiredExclusiveLite(&Vcb->VcbResource) || ExIsResourceAcquiredSharedLite(&Vcb->VcbResource)); @@ -263,7 +263,7 @@ UDFVerifyVolume( PVCB NewVcb = NULL; IO_STATUS_BLOCK Iosb; ULONG MediaChangeCount = 0; - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; BOOLEAN ReleaseVcb = FALSE; PAGED_CODE(); @@ -736,7 +736,7 @@ UDFDismountVcb( BOOLEAN VcbPresent = TRUE; KIRQL SavedIrql; - BOOLEAN FinalReference; + BOOLEAN FinalReference = FALSE; ASSERT_EXCLUSIVE_CDDATA; ASSERT_EXCLUSIVE_VCB(Vcb); diff --git a/drivers/filesystems/udfs/volinfo.cpp b/drivers/filesystems/udfs/volinfo.c similarity index 99% rename from drivers/filesystems/udfs/volinfo.cpp rename to drivers/filesystems/udfs/volinfo.c index c6ab4d3da9bf9..b5a39cbcf73f8 100644 --- a/drivers/filesystems/udfs/volinfo.cpp +++ b/drivers/filesystems/udfs/volinfo.c @@ -91,7 +91,7 @@ UDFCommonQueryVolInfo( { NTSTATUS Status = STATUS_INVALID_PARAMETER; PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp ); - ULONG Length; + ULONG Length = 0; PVCB Vcb; TYPE_OF_OPEN TypeOfOpen; PFCB Fcb; @@ -206,8 +206,8 @@ UDFQueryFsVolumeInfo( IN OUT PULONG Length ) { - ULONG BytesToCopy; - NTSTATUS Status; + ULONG BytesToCopy = 0; + NTSTATUS Status = STATUS_SUCCESS; PAGED_CODE(); @@ -403,11 +403,11 @@ UDFQueryFsAttributeInfo( IN OUT PULONG Length ) { - ULONG BytesToCopy; + ULONG BytesToCopy = 0; NTSTATUS Status = STATUS_SUCCESS; PCWSTR FsTypeTitle; - ULONG FsTypeTitleLen; + ULONG FsTypeTitleLen = 0; PAGED_CODE(); UDFPrint((" UDFQueryFsAttributeInfo: \n")); @@ -464,7 +464,7 @@ UDFCommonSetVolInfo( { NTSTATUS Status = STATUS_INVALID_PARAMETER; PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); - ULONG Length; + ULONG Length = 0; FS_INFORMATION_CLASS FsInformationClass; PVOID Buffer; TYPE_OF_OPEN TypeOfOpen; diff --git a/drivers/filesystems/udfs/write.cpp b/drivers/filesystems/udfs/write.c similarity index 97% rename from drivers/filesystems/udfs/write.cpp rename to drivers/filesystems/udfs/write.c index 076e5a6cbe305..08be52c6831de 100644 --- a/drivers/filesystems/udfs/write.cpp +++ b/drivers/filesystems/udfs/write.c @@ -44,9 +44,11 @@ UDFCommonWrite( NTSTATUS Status = STATUS_SUCCESS; PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); LONGLONG StartingOffset; + ULONG ByteCount; LONGLONG ByteRange; ULONG TruncatedLength; + SIZE_T NumberBytesWritten = 0; PFILE_OBJECT FileObject = NULL; TYPE_OF_OPEN TypeOfOpen; @@ -62,6 +64,8 @@ UDFCommonWrite( BOOLEAN MainResourceAcquired = FALSE; BOOLEAN VcbAcquired = FALSE; + + BOOLEAN Wait = FALSE; BOOLEAN PagingIo = FALSE; BOOLEAN NonCachedIo = FALSE; @@ -73,6 +77,7 @@ UDFCommonWrite( BOOLEAN ZeroBlock = FALSE; BOOLEAN ZeroBlockDone = FALSE; + // Examine our input parameters to determine if this is noncached and/or // a paging io operation. @@ -81,6 +86,7 @@ UDFCommonWrite( NonCachedIo = FlagOn(Irp->Flags, IRP_NOCACHE); SynchronousIo = FlagOn(IrpSp->FileObject->Flags, FO_SYNCHRONOUS_IO); + FileObject = IrpSp->FileObject; // Extract and decode the file object. @@ -101,6 +107,8 @@ UDFCommonWrite( ASSERT_FCB(Fcb); ASSERT_VCB(Vcb); + + // Check if this volume has already been shut down. If it has, fail // this write request. @@ -138,8 +146,10 @@ UDFCommonWrite( StartingOffset = IrpSp->Parameters.Write.ByteOffset.QuadPart; ByteCount = IrpSp->Parameters.Write.Length; + ByteRange = StartingOffset + ByteCount; + Irp->IoStatus.Information = 0; // Check if writing to end of file (FILE_WRITE_TO_END_OF_FILE = -1) @@ -216,6 +226,8 @@ UDFCommonWrite( // I dislike the idea of writing to not locked media if (!(Vcb->VcbState & VCB_STATE_LOCKED)) { try_return(Status = STATUS_ACCESS_DENIED); + + } // Acquire the volume resource exclusive @@ -330,6 +342,9 @@ UDFCommonWrite( // Acquire the appropriate FCB resource if (PagingIo) { + // Don't offload jobs when doing paging IO - otherwise this can lead to + // deadlocks in CcCopyWrite. + Wait = true; // For PagingIo: FcbResource already acquired by UDFAcqLazyWrite/UDFFastIoAcqModWrite // callback before this function is called @@ -397,7 +412,7 @@ UDFCommonWrite( !RecursiveWriteThrough && !IsLazyWriteThread) { - BOOLEAN ExtendFS; + BOOLEAN ExtendFS = FALSE; ExtendFS = (StartingOffset + TruncatedLength > Fcb->Header.FileSize.QuadPart); @@ -408,7 +423,9 @@ UDFCommonWrite( try_return(Status = STATUS_PENDING); // CanWait = TRUE; + UDFAcquirePagingIoExclusive(IrpContext, Fcb); + PagingIoResourceAcquired = TRUE; if (ExtendFS) { @@ -428,8 +445,15 @@ UDFCommonWrite( } } - UDFReleasePagingIo(IrpContext, Fcb); - PagingIoResourceAcquired = FALSE; + // For cached I/O, release now so that CcCopyWrite-triggered + // paging reads (which acquire PagingIoResource shared) do + // not deadlock against our exclusive hold. + // For non-cached I/O, keep it held through UDFWriteFile__ to + // protect against concurrent paging reads seeing a freed mapping. + if (!NonCachedIo) { + UDFReleasePagingIo(IrpContext, Fcb); + PagingIoResourceAcquired = FALSE; + } if (CcIsFileCached(FileObject)) { if (ExtendFS) { @@ -560,7 +584,7 @@ UDFCommonWrite( // Send the request to lower level drivers if (!Wait) { - UDFPrint(("UDFCommonWrite: Post physical write %x bytes at %x\n", TruncatedLength, StartingOffset.LowPart)); + UDFPrint(("UDFCommonWrite: Post physical write %x bytes at %x\n", TruncatedLength, (ULONG)StartingOffset)); try_return(Status = STATUS_PENDING); } @@ -577,6 +601,7 @@ UDFCommonWrite( } Fcb->NtReqFCBFlags |= UDF_NTREQ_FCB_MODIFIED; + // Acquire PagingIoResource exclusive to serialize with // UDFMarkAllocatedAsRecorded which may free and replace // ExtInfo->Mapping during NOT_RECORDED -> RECORDED conversion. @@ -588,6 +613,7 @@ UDFCommonWrite( PagingIoResourceAcquired = TRUE; } + Status = UDFWriteFile__(IrpContext, Vcb, Fcb->FileInfo, StartingOffset, TruncatedLength, FALSE, (PCHAR)SystemBuffer, &NumberBytesWritten); @@ -652,6 +678,7 @@ try_exit: NOTHING; // Release any resources acquired here ... if (PagingIoResourceAcquired) { + UDFReleasePagingIo(IrpContext, Fcb); } @@ -661,6 +688,7 @@ try_exit: NOTHING; if (VcbAcquired) { UDFReleaseVcb(IrpContext, Vcb); + } } _SEH2_END; // end of "__finally" processing @@ -732,9 +760,9 @@ UDFPurgeCacheEx_( PFILE_OBJECT FileObject ) { - ULONG Off_l; + ULONG Off_l = 0; #ifdef USE_CcCopyWrite_TO_ZERO - ULONG PgLen; + ULONG PgLen = 0; #endif //USE_CcCopyWrite_TO_ZERO // We'll just purge cache section here, @@ -897,7 +925,7 @@ UDFZeroData ( LARGE_INTEGER ZeroStart = {0,0}; LARGE_INTEGER BeyondZeroEnd = {0,0}; - BOOLEAN Finished; + BOOLEAN Finished = FALSE; PAGED_CODE(); From 7cffc5c9b640c91f43cd91cd1d155b8b26c37cf1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 1 May 2026 06:04:50 +0000 Subject: [PATCH 03/86] Apply PR #312: no-op macro cleanup, word-at-a-time bitmap check, SearchStart advance Agent-Logs-Url: https://github.com/Zero3K20/reactos/sessions/733f211e-58cf-4005-b7ad-5cae71101dea Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/Include/mem_tools.c | 8 +- drivers/filesystems/udfs/udf_dbg.h | 40 ++++---- drivers/filesystems/udfs/udf_info/alloc.c | 97 ++++++++++---------- drivers/filesystems/udfs/udffs.h | 2 + 4 files changed, 77 insertions(+), 70 deletions(-) diff --git a/drivers/filesystems/udfs/Include/mem_tools.c b/drivers/filesystems/udfs/Include/mem_tools.c index 3912ee1659c87..3eda665b30971 100644 --- a/drivers/filesystems/udfs/Include/mem_tools.c +++ b/drivers/filesystems/udfs/Include/mem_tools.c @@ -26,7 +26,7 @@ InitLockMemoryManager() { KeInitializeSpinLock(&FrameLock); return STATUS_SUCCESS; } -#define DeinitLockMemoryManager() {NOTHING;} +#define DeinitLockMemoryManager() ((void)0) #else //MEM_LOCK_BY_SPINLOCK ERESOURCE FrameLock; #define LockMemoryManager() ExAcquireResourceExclusiveLite(&FrameLock, TRUE) @@ -171,9 +171,9 @@ MyAllocCheck( //#endif //CHECK_ALLOC_FRAMES #else -#define MyAllocDumpFrame(a) {} -#define MyAllocCheck(a) {} -#define MyAllocDumpFrames() {} +#define MyAllocDumpFrame(a) ((void)0) +#define MyAllocCheck(a) ((void)0) +#define MyAllocDumpFrames() ((void)0) #endif // UDF_DBG diff --git a/drivers/filesystems/udfs/udf_dbg.h b/drivers/filesystems/udfs/udf_dbg.h index 82cf81e61e41a..deae569d3e7a8 100644 --- a/drivers/filesystems/udfs/udf_dbg.h +++ b/drivers/filesystems/udfs/udf_dbg.h @@ -61,13 +61,13 @@ #ifdef USE_KD_PRINT #define KdPrint(_x_) DbgPrint _x_ #else - #define KdPrint(a) {NOTHING;} + #define KdPrint(a) ((void)0) #endif //USE_KD_PRINT #ifdef USE_MM_PRINT #define MmPrint(_x_) DbgPrint _x_ #else - #define MmPrint(_x_) {NOTHING;} + #define MmPrint(_x_) ((void)0) #endif //USE_MM_PRINT #ifdef USE_TIME_PRINT @@ -80,29 +80,29 @@ #ifdef USE_AD_PRINT #define AdPrint(_x_) {DbgPrint("Thrd:%x:",PsGetCurrentThread());DbgPrint _x_;} #else - #define AdPrint(_x_) {NOTHING;} + #define AdPrint(_x_) ((void)0) #endif #ifdef USE_TH_PRINT #define ThPrint(_x_) {DbgPrint("Thrd:%x:",PsGetCurrentThread());DbgPrint _x_;} #else - #define ThPrint(_x_) {NOTHING;} + #define ThPrint(_x_) ((void)0) #endif #ifdef UDF_DUMP_EXTENT #define ExtPrint(_x_) KdPrint(_x_) #else - #define ExtPrint(_x_) {NOTHING;} + #define ExtPrint(_x_) ((void)0) #endif #else // defined UDF_DBG || defined PRINT_ALWAYS - #define MmPrint(_x_) {NOTHING;} - #define TmPrint(_x_) {NOTHING;} - #define PerfPrint(_x_) {NOTHING;} - #define AdPrint(_x_) {NOTHING;} - #define ThPrint(_x_) {NOTHING;} - #define ExtPrint(_x_) {NOTHING;} + #define MmPrint(_x_) ((void)0) + #define TmPrint(_x_) ((void)0) + #define PerfPrint(_x_) ((void)0) + #define AdPrint(_x_) ((void)0) + #define ThPrint(_x_) ((void)0) + #define ExtPrint(_x_) ((void)0) #endif // defined UDF_DBG || defined PRINT_ALWAYS @@ -125,13 +125,13 @@ DbgWaitForSingleObject_( #ifdef BRUTE #define BrutePoint() UDFBreakPoint() #else -#define BrutePoint() {} +#define BrutePoint() ((void)0) #endif // BRUTE #ifdef CHECK_REF_COUNTS #define ASSERT_REF(_a_) ASSERT(_a_) #else -#define ASSERT_REF(_a_) {NOTHING;} +#define ASSERT_REF(_a_) ((void)0) #endif //CHECK_REF_COUNTS #ifdef TRACK_SYS_ALLOCS @@ -180,7 +180,7 @@ VOID DebugFreePool(PVOID addr); } #else -#define ValidateFileInfo(fi) {} +#define ValidateFileInfo(fi) ((void)0) #endif __inline VOID UDFTouch(IN PVOID addr) @@ -199,13 +199,13 @@ __inline VOID UDFTouch(IN PVOID addr) #define DbgCopyMemory(d, s, l) RtlCopyMemory(d, s, l) #define DbgCompareMemory(d, s, l) RtlCompareMemory(d, s, l) -#define ASSERT_REF(_a_) {NOTHING;} +#define ASSERT_REF(_a_) ((void)0) -#define UDFBreakPoint() {} -#define BrutePoint() {} -#define ValidateFileInfo(fi) {} +#define UDFBreakPoint() ((void)0) +#define BrutePoint() ((void)0) +#define ValidateFileInfo(fi) ((void)0) -#define UDFTouch(addr) {} +#define UDFTouch(addr) ((void)0) #endif // UDF_DBG @@ -225,7 +225,7 @@ if ((a)!=NULL) { \ #else -#define KdDump(a,b) {} +#define KdDump(a,b) ((void)0) #endif // UDF_DBG diff --git a/drivers/filesystems/udfs/udf_info/alloc.c b/drivers/filesystems/udfs/udf_info/alloc.c index e8747e1284a88..25b93ed990690 100644 --- a/drivers/filesystems/udfs/udf_info/alloc.c +++ b/drivers/filesystems/udfs/udf_info/alloc.c @@ -467,6 +467,7 @@ UDFCheckSpaceAllocation_( uint32 i=0; uint32 lba, j, len, BS, BSh; BOOLEAN asUsed = (asXXX == AS_USED); + uint32* BitmapPtr = (uint32*)(Vcb->FSBM_Bitmap); if (!Map) return; @@ -527,39 +528,56 @@ UDFCheckSpaceAllocation_( len = Vcb->LastPossibleLBA - lba; } - // mark frag as XXX (see asUsed parameter) - if (asUsed) { + // --- SPEED OPTIMIZATION: Word-at-a-time verification --- + // Instead of bit-by-bit, we check 32 blocks per CPU instruction. + j = 0; + while (j < len) { + // Fast Path: Check 32 blocks if aligned on a 32-bit boundary + if (((lba + j) & 31) == 0 && (len - j) >= 32) { + uint32 CurrentWord = BitmapPtr[(lba + j) >> 5]; + + if (asUsed) { + // In UDF, 0 = Used. We expect the whole word to be 0x00000000. + if (CurrentWord == 0) { + j += 32; + continue; + } + } else { + // In UDF, 1 = Free. We expect the whole word to be 0xFFFFFFFF. + if (CurrentWord == 0xFFFFFFFF) { + j += 32; + continue; + } + } + // If the word check fails, we fall through to the bit-checker below + // to identify exactly which block is inconsistent. + } - ASSERT(len); - for(j=0;j Vcb->LastPossibleLBA) { + // Fallback: Individual bit check (for tails or if an inconsistency is found) + if (asUsed) { + if (lba + j > Vcb->LastPossibleLBA) { BrutePoint(); - AdPrint(("USED Mapping covers block(s) beyond media @%x\n",lba+j)); break; } - if (!UDFGetUsedBit(Vcb->FSBM_Bitmap, lba+j)) { + if (!UDFGetUsedBit(Vcb->FSBM_Bitmap, lba + j)) { BrutePoint(); - AdPrint(("USED Mapping covers FREE block(s) @%x\n",lba+j)); + AdPrint(("USED Mapping covers FREE block @ %x\n", lba + j)); break; } - } - - } else { - - ASSERT(len); - for(j=0;j Vcb->LastPossibleLBA) { + } else { + if (lba + j > Vcb->LastPossibleLBA) { BrutePoint(); - AdPrint(("USED Mapping covers block(s) beyond media @%x\n",lba+j)); break; } - if (!UDFGetFreeBit(Vcb->FSBM_Bitmap, lba+j)) { + if (!UDFGetFreeBit(Vcb->FSBM_Bitmap, lba + j)) { BrutePoint(); - AdPrint(("FREE Mapping covers USED block(s) @%x\n",lba+j)); + AdPrint(("FREE Mapping covers USED block @ %x\n", lba + j)); break; } } + j++; } + // --- END OPTIMIZATION --- i++; } @@ -664,21 +682,17 @@ UDFMarkSpaceAsXXXNoProtect_( bit_after = UDFGetBit(Vcb->FSBM_Bitmap, lba+len); #endif //UDF_TRACK_ONDISK_ALLOCATION - // mark frag as XXX (see asUsed parameter) + // --- SPEED OPTIMIZATION START --- + // Instead of bit-loops, we use the optimized SetBits/FreeBits + // which should ideally be mapped to RtlFillMemory for large spans. if (asUsed) { -/* for(j=0;jFSBM_Bitmap, lba+j); - }*/ ASSERT(len); + // Fast Path: If we are marking a large span as used (bits = 1) + // UDFSetUsedBits handles the bit-shifting logic. UDFSetUsedBits(Vcb->FSBM_Bitmap, lba, len); -#ifdef UDF_TRACK_ONDISK_ALLOCATION - for(j=0;jFSBM_Bitmap, lba+j)); - } -#endif //UDF_TRACK_ONDISK_ALLOCATION + // VAT handling (This loop is slow but only runs for UDF 1.50/Vat-based media) if (Vcb->Vat) { - // mark logical blocks in VAT as used for(j=0;jVat, lba-root+j) == UDF_VAT_FREE_ENTRY) && @@ -688,16 +702,10 @@ UDFMarkSpaceAsXXXNoProtect_( } } } else { -/* for(j=0;jFSBM_Bitmap, lba+j); - }*/ ASSERT(len); + // Fast Path: Mark space as free (bits = 0) UDFSetFreeBits(Vcb->FSBM_Bitmap, lba, len); -#ifdef UDF_TRACK_ONDISK_ALLOCATION - for(j=0;jFSBM_Bitmap, lba+j)); - } -#endif //UDF_TRACK_ONDISK_ALLOCATION + if (asXXX & AS_BAD) { UDFSetBits(Vcb->BSBM_Bitmap, lba, len); } @@ -706,25 +714,19 @@ UDFMarkSpaceAsXXXNoProtect_( if (asXXX & AS_DISCARDED) { UDFUnmapRange(Vcb, lba, len); } + if (Vcb->Vat) { - // mark logical blocks in VAT as free - // this operation can decrease resulting VAT size for(j=0;jVat, lba-root+j, UDF_VAT_FREE_ENTRY); } } - // mark discarded extent as Not-Alloc-Not-Rec to - // prevent writes there + + // Optimization for the Map itself Map[i].extLength = (len << BSh) | (EXTENT_NOT_RECORDED_NOT_ALLOCATED << 30); Map[i].extLocation = 0; } - -#ifdef UDF_TRACK_ONDISK_ALLOCATION - if (lba) - ASSERT(bit_before == UDFGetBit(Vcb->FSBM_Bitmap, lba-1)); - ASSERT(bit_after == UDFGetBit(Vcb->FSBM_Bitmap, lba+len)); -#endif //UDF_TRACK_ONDISK_ALLOCATION + // --- SPEED OPTIMIZATION END --- i++; } @@ -816,6 +818,9 @@ UDFAllocFreeExtent_( // probably we have the opportunity to do it Ext.extLength = len< Date: Fri, 1 May 2026 13:35:42 +0000 Subject: [PATCH 04/86] Fix C typedef forward-declaration errors from C++ to C conversion (PR #304) Agent-Logs-Url: https://github.com/Zero3K20/reactos/sessions/b756d727-b575-4691-98ee-81d66d3c4b08 Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/struct.h | 3 +++ drivers/filesystems/udfs/udf_info/ecma_167.h | 6 ++++++ drivers/filesystems/udfs/udf_info/osta_misc.h | 7 +++++++ 3 files changed, 16 insertions(+) diff --git a/drivers/filesystems/udfs/struct.h b/drivers/filesystems/udfs/struct.h index 1a08e4215a59e..41c290f8edf2b 100644 --- a/drivers/filesystems/udfs/struct.h +++ b/drivers/filesystems/udfs/struct.h @@ -31,6 +31,9 @@ /************************************************************************** include udf related structures *here* (because we need definition of Fcb) **************************************************************************/ +/* FCB is defined later in this file; pre-declare it so udf_rel.h can use FCB* */ +struct FCB; +typedef struct FCB FCB; #include "udf_info/udf_rel.h" struct IRP_CONTEXT_LITE; diff --git a/drivers/filesystems/udfs/udf_info/ecma_167.h b/drivers/filesystems/udfs/udf_info/ecma_167.h index 7e4ebc9c9f064..1b1990d47ceb7 100644 --- a/drivers/filesystems/udfs/udf_info/ecma_167.h +++ b/drivers/filesystems/udfs/udf_info/ecma_167.h @@ -778,6 +778,12 @@ typedef struct TerminatingExtendedAreaDesc TerminatingExtendedAreaDesc; typedef struct PrimaryVolDesc PrimaryVolDesc; typedef struct AnchorVolDescPtr AnchorVolDescPtr; typedef struct VolDescPtr VolDescPtr; +typedef struct ImpUseVolDesc ImpUseVolDesc; +typedef struct PartitionDesc PartitionDesc; +typedef struct LogicalVolDesc LogicalVolDesc; +typedef struct GenericPartitionMap GenericPartitionMap; +typedef struct LogicalVolIntegrityDesc LogicalVolIntegrityDesc; +typedef struct LogicalVolHeaderDesc LogicalVolHeaderDesc; #endif /* __ECMA_167_H__ */ diff --git a/drivers/filesystems/udfs/udf_info/osta_misc.h b/drivers/filesystems/udfs/udf_info/osta_misc.h index f9813bfb321c7..c8628fba514c0 100644 --- a/drivers/filesystems/udfs/udf_info/osta_misc.h +++ b/drivers/filesystems/udfs/udf_info/osta_misc.h @@ -350,4 +350,11 @@ typedef UID_MAPPING_TABLE* PUID_MAPPING_TABLE; #pragma pack(pop) +typedef struct LogicalVolIntegrityDescImpUse LogicalVolIntegrityDescImpUse; +typedef struct ImpUseVolDescImpUse ImpUseVolDescImpUse; +typedef struct UdfPartitionMap2 UdfPartitionMap2; +typedef struct VirtualAllocationTable15 VirtualAllocationTable15; +typedef struct VirtualAllocationTable20 VirtualAllocationTable20; +typedef struct FidADImpUse FidADImpUse; + #endif /* _OSTA_MISC_H */ From 6d1a8092c87497d9e058c1ccf6a29d389b48a104 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 1 May 2026 13:48:02 +0000 Subject: [PATCH 05/86] Fix remaining C build errors: remove C++ default params and fix DbgPrint signature Agent-Logs-Url: https://github.com/Zero3K20/reactos/sessions/9779df76-ba39-4fe0-992c-e8299fd022bb Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/cleanup.c | 2 +- drivers/filesystems/udfs/create.c | 10 +++++----- drivers/filesystems/udfs/flush.c | 2 +- drivers/filesystems/udfs/fscntrl.c | 6 +++--- drivers/filesystems/udfs/protos.h | 10 +++++----- drivers/filesystems/udfs/shutdown.c | 2 +- drivers/filesystems/udfs/strucsup.c | 4 ++-- drivers/filesystems/udfs/udf_dbg.h | 2 +- drivers/filesystems/udfs/udf_info/mount.c | 2 +- drivers/filesystems/udfs/udf_info/phys_eject.c | 2 +- drivers/filesystems/udfs/udf_info/udf_info.c | 18 +++++++++--------- drivers/filesystems/udfs/udf_info/udf_info.h | 2 +- drivers/filesystems/udfs/write.c | 2 +- 13 files changed, 32 insertions(+), 32 deletions(-) diff --git a/drivers/filesystems/udfs/cleanup.c b/drivers/filesystems/udfs/cleanup.c index e07a968acddb8..3599c7715a47a 100644 --- a/drivers/filesystems/udfs/cleanup.c +++ b/drivers/filesystems/udfs/cleanup.c @@ -333,7 +333,7 @@ UDFCommonCleanup( Fcb->ParentFcb->FcbState |= UDF_FCB_DELETE_ON_CLOSE; } // flush file. It is required by UDFUnlinkFile__() - RC = UDFFlushFile__(IrpContext, Vcb, NextFileInfo); + RC = UDFFlushFile__(IrpContext, Vcb, NextFileInfo, 0); if (!NT_SUCCESS(RC)) { AdPrint(("Error flushing file !!!\n")); } diff --git a/drivers/filesystems/udfs/create.c b/drivers/filesystems/udfs/create.c index 6f1fb2ff97564..822dc865cdfea 100644 --- a/drivers/filesystems/udfs/create.c +++ b/drivers/filesystems/udfs/create.c @@ -2001,7 +2001,7 @@ UDFCommonCreate( if ((Status != STATUS_FILE_IS_A_DIRECTORY) && (Status != STATUS_NOT_A_DIRECTORY) && (Status != STATUS_ACCESS_DENIED)) { - UDFFlushFile__(IrpContext, Vcb, NewFileInfo); + UDFFlushFile__(IrpContext, Vcb, NewFileInfo, 0); UDFUnlinkFile__(IrpContext, Vcb, NewFileInfo, TRUE); } // UDFCloseFile__ is handled by the finally block. @@ -2090,7 +2090,7 @@ UDFCommonCreate( (Status != STATUS_FILE_IS_A_DIRECTORY) && (Status != STATUS_NOT_A_DIRECTORY) && (Status != STATUS_ACCESS_DENIED)) { - UDFFlushFile__(IrpContext, Vcb, NewFileInfo); + UDFFlushFile__(IrpContext, Vcb, NewFileInfo, 0); UDFUnlinkFile__(IrpContext, Vcb, NewFileInfo, TRUE); } try_return(Status); @@ -2207,7 +2207,7 @@ UDFCommonCreate( if ((Status != STATUS_FILE_IS_A_DIRECTORY) && (Status != STATUS_NOT_A_DIRECTORY) && (Status != STATUS_ACCESS_DENIED)) { - UDFFlushFile__(IrpContext, Vcb, NewFileInfo); + UDFFlushFile__(IrpContext, Vcb, NewFileInfo, 0); UDFUnlinkFile__(IrpContext, Vcb, NewFileInfo, TRUE); } UDFCloseFile__(IrpContext, Vcb, NewFileInfo); @@ -2308,7 +2308,7 @@ UDFCommonCreate( (Status != STATUS_FILE_IS_A_DIRECTORY) && (Status != STATUS_NOT_A_DIRECTORY) && (Status != STATUS_ACCESS_DENIED)) { - UDFFlushFile__(IrpContext, Vcb, NewFileInfo); + UDFFlushFile__(IrpContext, Vcb, NewFileInfo, 0); UDFUnlinkFile__(IrpContext, Vcb, NewFileInfo, TRUE); } if (NewFileInfo) { @@ -2822,7 +2822,7 @@ UDFCompleteFcbOpen( // Flush the volume and make sure all of the user references // are gone. - Status = UDFFlushVolume(IrpContext, Vcb); + Status = UDFFlushVolume(IrpContext, Vcb, 0); if (!NT_SUCCESS(Status)) { diff --git a/drivers/filesystems/udfs/flush.c b/drivers/filesystems/udfs/flush.c index 205c6676d8f25..83c0ba81dc738 100644 --- a/drivers/filesystems/udfs/flush.c +++ b/drivers/filesystems/udfs/flush.c @@ -127,7 +127,7 @@ UDFCommonFlush( UDFVerifyVcb(IrpContext, Vcb); - UDFFlushVolume(IrpContext, Vcb); + UDFFlushVolume(IrpContext, Vcb, 0); UDFReleaseResource(&(Vcb->VcbResource)); AcquiredVCB = FALSE; diff --git a/drivers/filesystems/udfs/fscntrl.c b/drivers/filesystems/udfs/fscntrl.c index 4a91bd427ef55..b7b3444f48d4b 100644 --- a/drivers/filesystems/udfs/fscntrl.c +++ b/drivers/filesystems/udfs/fscntrl.c @@ -1000,7 +1000,7 @@ Return Value: // remaining after the purge then we can allow the volume to be locked. // - UDFFlushVolume(IrpContext, Vcb); + UDFFlushVolume(IrpContext, Vcb, 0); //CdPurgeVolume( IrpContext, Vcb, FALSE ); // @@ -1184,7 +1184,7 @@ UDFDismountVolume( } else { - UDFFlushVolume(IrpContext, Vcb); + UDFFlushVolume(IrpContext, Vcb, 0); // Invalidate the volume right now. // @@ -1810,7 +1810,7 @@ UDFInvalidateVolumes( UDFAcquireVcbExclusive(IrpContext, Vcb, FALSE); - UDFFlushVolume(IrpContext, Vcb); + UDFFlushVolume(IrpContext, Vcb, 0); UDFDoDismountSequence(Vcb, FALSE); diff --git a/drivers/filesystems/udfs/protos.h b/drivers/filesystems/udfs/protos.h index c9d3b961797c9..cbabb21436fd7 100644 --- a/drivers/filesystems/udfs/protos.h +++ b/drivers/filesystems/udfs/protos.h @@ -512,7 +512,7 @@ ULONG UDFFlushAFile( IN PFCB Fcb, IN PCCB Ccb, OUT PIO_STATUS_BLOCK PtrIoStatus, - IN ULONG FlushFlags = 0 + IN ULONG FlushFlags ); ULONG @@ -521,14 +521,14 @@ UDFFlushADirectory( IN PVCB Vcb, IN PUDF_FILE_INFO FI, OUT PIO_STATUS_BLOCK PtrIoStatus, - ULONG FlushFlags = 0 + ULONG FlushFlags ); NTSTATUS UDFFlushVolume( PIRP_CONTEXT IrpContext, PVCB Vcb, - ULONG FlushFlags = 0 + ULONG FlushFlags ); extern NTSTATUS NTAPI UDFFlushCompletion( @@ -538,7 +538,7 @@ PVOID Context); extern BOOLEAN UDFFlushIsBreaking( IN PVCB Vcb, -IN ULONG FlushFlags = 0); +IN ULONG FlushFlags); extern VOID UDFFlushTryBreak( IN PVCB Vcb); @@ -929,7 +929,7 @@ UDFReadRegKeys( extern ULONG UDFGetRegParameter( IN PVCB Vcb, IN PCWSTR Name, - IN ULONG DefValue = 0); + IN ULONG DefValue); VOID UDFDeleteVCB( diff --git a/drivers/filesystems/udfs/shutdown.c b/drivers/filesystems/udfs/shutdown.c index 69f2f33f08842..ab0c904500a6b 100644 --- a/drivers/filesystems/udfs/shutdown.c +++ b/drivers/filesystems/udfs/shutdown.c @@ -109,7 +109,7 @@ UDFCommonShutdown( UDFAcquireVcbExclusive(IrpContext, Vcb, FALSE); - UDFFlushVolume(IrpContext, Vcb); + UDFFlushVolume(IrpContext, Vcb, 0); ASSERT(CONTAINING_RECORD(IoGetCurrentIrpStackLocation(Irp)->DeviceObject, VOLUME_DEVICE_OBJECT, diff --git a/drivers/filesystems/udfs/strucsup.c b/drivers/filesystems/udfs/strucsup.c index 9f5804bae6fcc..fcc48ff135a93 100644 --- a/drivers/filesystems/udfs/strucsup.c +++ b/drivers/filesystems/udfs/strucsup.c @@ -525,14 +525,14 @@ UDFTeardownStructures( // no more references... current file/dir MUST DIE!!! if (Delete) { UDFReferenceFile__(CurrentFcb->FileInfo); - UDFFlushFile__(IrpContext, Vcb, CurrentFcb->FileInfo); + UDFFlushFile__(IrpContext, Vcb, CurrentFcb->FileInfo, 0); UDFUnlinkFile__(IrpContext, Vcb, CurrentFcb->FileInfo, TRUE); UDFCloseFile__(IrpContext, Vcb, CurrentFcb->FileInfo); CurrentFcb->FcbState |= UDF_FCB_DELETED; Delete = FALSE; } else if (!(CurrentFcb->FcbState & UDF_FCB_DELETED)) { - UDFFlushFile__(IrpContext, Vcb, CurrentFcb->FileInfo); + UDFFlushFile__(IrpContext, Vcb, CurrentFcb->FileInfo, 0); } else { // File is already deleted - clear Modified flags without flushing to disk. diff --git a/drivers/filesystems/udfs/udf_dbg.h b/drivers/filesystems/udfs/udf_dbg.h index deae569d3e7a8..476876991c723 100644 --- a/drivers/filesystems/udfs/udf_dbg.h +++ b/drivers/filesystems/udfs/udf_dbg.h @@ -49,7 +49,7 @@ ULONG _cdecl DbgPrint( - PCH Format, + PCSTR Format, ... ); diff --git a/drivers/filesystems/udfs/udf_info/mount.c b/drivers/filesystems/udfs/udf_info/mount.c index 179c878c76826..094df88f2c40a 100644 --- a/drivers/filesystems/udfs/udf_info/mount.c +++ b/drivers/filesystems/udfs/udf_info/mount.c @@ -936,7 +936,7 @@ UDFUpdateNonAllocated( } UDFPackMapping(Vcb, DataLoc); DataLoc->Length = UDFGetExtentLength(DataLoc->Mapping); - UDFFlushFile__(IrpContext, Vcb, Vcb->NonAllocFileInfo); + UDFFlushFile__(IrpContext, Vcb, Vcb->NonAllocFileInfo, 0); // ensure that BAD space is marked as USED UDFMarkSpaceAsXXX(Vcb, 0, &(DataLoc->Mapping[0]), AS_USED); // mark as used diff --git a/drivers/filesystems/udfs/udf_info/phys_eject.c b/drivers/filesystems/udfs/udf_info/phys_eject.c index 2a7a794d27839..d07ccedf10ef0 100644 --- a/drivers/filesystems/udfs/udf_info/phys_eject.c +++ b/drivers/filesystems/udfs/udf_info/phys_eject.c @@ -28,7 +28,7 @@ UDFDoDismountSequence( ULONG i; // flush system cache - UDFFlushVolume(NULL, Vcb); + UDFFlushVolume(NULL, Vcb, 0); UDFPrint(("UDFDoDismountSequence:\n")); delay.QuadPart = -1000000; // 0.1 sec diff --git a/drivers/filesystems/udfs/udf_info/udf_info.c b/drivers/filesystems/udfs/udf_info/udf_info.c index ec363f2d9f2ae..f693fb67098bb 100644 --- a/drivers/filesystems/udfs/udf_info/udf_info.c +++ b/drivers/filesystems/udfs/udf_info/udf_info.c @@ -1814,7 +1814,7 @@ UDFUnlinkFile__( PUDF_FILE_INFO SFileInfo; // ... try to open it if (Dloc->SDirInfo) { - UDFFlushFile__(IrpContext, Vcb, FileInfo); + UDFFlushFile__(IrpContext, Vcb, FileInfo, 0); return STATUS_CANNOT_DELETE; } // open SDir @@ -1825,7 +1825,7 @@ UDFUnlinkFile__( cleanup_SDir: UDFCleanUpFile__(Vcb, SFileInfo); if (SFileInfo) MyFreePool__(SFileInfo); - UDFFlushFile__(IrpContext, Vcb, FileInfo); + UDFFlushFile__(IrpContext, Vcb, FileInfo, 0); return status; } SDirInfo = Dloc->SDirInfo; @@ -1839,7 +1839,7 @@ UDFUnlinkFile__( goto cleanup_SDir; } // delete SDir - UDFFlushFile__(IrpContext, Vcb, SDirInfo); + UDFFlushFile__(IrpContext, Vcb, SDirInfo, 0); AdPrint((" ")); UDFUnlinkFile__(IrpContext, Vcb, SDirInfo, TRUE); // close SDir @@ -1860,7 +1860,7 @@ UDFUnlinkFile__( // do deltree for Streams status = UDFUnlinkAllFilesInDir(IrpContext, Vcb, FileInfo); if (!NT_SUCCESS(status)) { - UDFFlushFile__(IrpContext, Vcb, FileInfo); + UDFFlushFile__(IrpContext, Vcb, FileInfo, 0); return status; } // update parent FileInfo @@ -1873,7 +1873,7 @@ UDFUnlinkFile__( UDFDecFileLinkCount(FileInfo->ParentFile); } // flush file - UDFFlushFile__(IrpContext, Vcb, FileInfo); + UDFFlushFile__(IrpContext, Vcb, FileInfo, 0); UDFUnlinkDloc(Vcb, Dloc); // free allocation UDFFreeFileAllocation(Vcb, DirInfo, FileInfo); @@ -1928,7 +1928,7 @@ UDFUnlinkAllFilesInDir( return status; } - UDFFlushFile__(IrpContext, Vcb, FileInfo); + UDFFlushFile__(IrpContext, Vcb, FileInfo, 0); AdPrint((" ")); UDFUnlinkFile__(IrpContext, Vcb, FileInfo, TRUE); UDFCloseFile__(IrpContext, Vcb, FileInfo); @@ -3498,7 +3498,7 @@ UDFRenameMoveFile__( // unlink source FileIdent if (!NT_SUCCESS(status = UDFUnlinkFile__(IrpContext, Vcb, FileInfo, FALSE))) { // kill newly created entry - UDFFlushFile__(IrpContext, Vcb, FileInfo2); + UDFFlushFile__(IrpContext, Vcb, FileInfo2, 0); UDFUnlinkFile__(IrpContext, Vcb, FileInfo2, TRUE); UDFCloseFile__(IrpContext, Vcb, FileInfo2); UDFCleanUpFile__(Vcb, FileInfo2); @@ -5277,7 +5277,7 @@ UDFRecordVAT( UDFPhysLbaToPart(Vcb, PartNum, VatFileInfo->Dloc->DataLoc.Mapping[0].extLocation); // record data if (NT_SUCCESS(status = UDFWriteFile__(IrpContext, Vcb, VatFileInfo, 0, VatLen + hdrLen, FALSE, New, &WrittenBytes))) { - status = UDFFlushFile__(IrpContext, Vcb, VatFileInfo); + status = UDFFlushFile__(IrpContext, Vcb, VatFileInfo, 0); } return status; } @@ -5385,7 +5385,7 @@ UDFRecordVAT( UDFPhysLbaToPart(Vcb, PartNum, VatFileInfo->Dloc->FELoc.Mapping[0].extLocation); VatFileInfo->Dloc->DataLoc.Modified = TRUE; - status = UDFFlushFile__(IrpContext, Vcb, VatFileInfo); + status = UDFFlushFile__(IrpContext, Vcb, VatFileInfo, 0); if (!NT_SUCCESS(status)) return status; diff --git a/drivers/filesystems/udfs/udf_info/udf_info.h b/drivers/filesystems/udfs/udf_info/udf_info.h index 59b7b42517631..559cc6e422aa8 100644 --- a/drivers/filesystems/udfs/udf_info/udf_info.h +++ b/drivers/filesystems/udfs/udf_info/udf_info.h @@ -1023,7 +1023,7 @@ UDFFlushFile__( IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo, - IN ULONG FlushFlags = 0 + IN ULONG FlushFlags ); // check if the file is flushed diff --git a/drivers/filesystems/udfs/write.c b/drivers/filesystems/udfs/write.c index 08be52c6831de..08625832bd459 100644 --- a/drivers/filesystems/udfs/write.c +++ b/drivers/filesystems/udfs/write.c @@ -237,7 +237,7 @@ UDFCommonWrite( // I dislike the idea of writing to mounted media too, but M$ has another point of view... if (Vcb->VcbCondition == VcbMounted) { // flush system cache - UDFFlushVolume(IrpContext, Vcb); + UDFFlushVolume(IrpContext, Vcb, 0); } // Forward the request to the lower level driver From 54da39bcda44d9db5832a685387b0daa9811ed27 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 1 May 2026 13:55:38 +0000 Subject: [PATCH 06/86] Fix mount.c build errors: add missing typedefs and fix comma-expression bug Agent-Logs-Url: https://github.com/Zero3K20/reactos/sessions/a5eae383-5191-4ad1-bb09-3a158b17b47f Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/udf_info/ecma_167.h | 4 ++++ drivers/filesystems/udfs/udf_info/mount.c | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/filesystems/udfs/udf_info/ecma_167.h b/drivers/filesystems/udfs/udf_info/ecma_167.h index 1b1990d47ceb7..9351f214fb160 100644 --- a/drivers/filesystems/udfs/udf_info/ecma_167.h +++ b/drivers/filesystems/udfs/udf_info/ecma_167.h @@ -782,6 +782,10 @@ typedef struct ImpUseVolDesc ImpUseVolDesc; typedef struct PartitionDesc PartitionDesc; typedef struct LogicalVolDesc LogicalVolDesc; typedef struct GenericPartitionMap GenericPartitionMap; +typedef struct GenericPartitionMap1 GenericPartitionMap1; +typedef struct GenericPartitionMap2 GenericPartitionMap2; +typedef struct TerminatingDesc TerminatingDesc; +typedef struct GenericDesc GenericDesc; typedef struct LogicalVolIntegrityDesc LogicalVolIntegrityDesc; typedef struct LogicalVolHeaderDesc LogicalVolHeaderDesc; diff --git a/drivers/filesystems/udfs/udf_info/mount.c b/drivers/filesystems/udfs/udf_info/mount.c index 094df88f2c40a..45d672c236036 100644 --- a/drivers/filesystems/udfs/udf_info/mount.c +++ b/drivers/filesystems/udfs/udf_info/mount.c @@ -2757,7 +2757,8 @@ UDFFindLastFileSet( uint16 Ident; uint32 relPrevExt, prevExt; - relPrevExt, prevExt = NULL; + relPrevExt = 0; + prevExt = 0; FileSetDesc->nextExt.extLength = 1; // ;) // walk through FileSet chain // we've just pre-init'd extent length to read 1st FileSet From 47acc64c865d75c6917438564117d5f3356824b7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 1 May 2026 14:06:16 +0000 Subject: [PATCH 07/86] Fix extent.c C4028: correct PSHORT_AD and PEXT_AD types in udf_info.h declarations Agent-Logs-Url: https://github.com/Zero3K20/reactos/sessions/ebc171ec-d894-483b-92b9-7a3bbe2511da Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/udf_info/udf_info.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/filesystems/udfs/udf_info/udf_info.h b/drivers/filesystems/udfs/udf_info/udf_info.h index 559cc6e422aa8..4951f793d136b 100644 --- a/drivers/filesystems/udfs/udf_info/udf_info.h +++ b/drivers/filesystems/udfs/udf_info/udf_info.h @@ -160,8 +160,8 @@ UDFShortAllocDescToMapping( IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN uint32 PartNum, - IN PLONG_AD AllocDesc, - IN uint32 AllocDescLength, + IN PSHORT_AD AllocDescs, + IN uint32 AllocDescsLength, IN uint32 SubCallCount, OUT PEXTENT_INFO AllocLoc ); @@ -182,7 +182,7 @@ PEXTENT_MAP UDFExtAllocDescToMapping( IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, - IN PLONG_AD AllocDesc, + IN PEXT_AD AllocDesc, IN uint32 AllocDescLength, IN uint32 SubCallCount, OUT PEXTENT_INFO AllocLoc From 25d50be36123198989f3b54add9d425242e69fea Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 1 May 2026 14:20:09 +0000 Subject: [PATCH 08/86] Fix phys_lib.c: swap NULL/0 for UDFPhSendIOCTL, add missing Flags arg to UDFTRead/UDFTWrite Agent-Logs-Url: https://github.com/Zero3K20/reactos/sessions/0d84cb7e-ce11-48a4-a3e8-4302a82c69f7 Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/Include/phys_lib.c | 8 ++++---- drivers/filesystems/udfs/write.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/filesystems/udfs/Include/phys_lib.c b/drivers/filesystems/udfs/Include/phys_lib.c index 693ebf154233d..6d60e058e5c70 100644 --- a/drivers/filesystems/udfs/Include/phys_lib.c +++ b/drivers/filesystems/udfs/Include/phys_lib.c @@ -796,14 +796,14 @@ UDFGetBlockSize( if (UDFGetDevType(DeviceObject) == FILE_DEVICE_DISK) { UDFPrint(("UDFGetBlockSize: HDD\n")); RC = UDFPhSendIOCTL(IOCTL_DISK_GET_DRIVE_GEOMETRY_EX,DeviceObject, - 0,NULL, + NULL,0, &DiskGeometryEx,sizeof(DISK_GEOMETRY_EX), TRUE,NULL ); if (!NT_SUCCESS(RC)) try_return(RC); RC = UDFPhSendIOCTL(IOCTL_DISK_GET_PARTITION_INFO,DeviceObject, - 0,NULL, + NULL,0, &PartitionInfo,sizeof(PARTITION_INFORMATION), TRUE,NULL ); if (!NT_SUCCESS(RC)) { @@ -1036,7 +1036,7 @@ UDFReadSectors( OUT PULONG ReadBytes ) { - return UDFTRead(IrpContext, Vcb, Buffer, BCount*Vcb->SectorSize, Lba, ReadBytes); + return UDFTRead(IrpContext, Vcb, Buffer, BCount*Vcb->SectorSize, Lba, ReadBytes, 0); } // end UDFReadSectors() /* @@ -1165,7 +1165,7 @@ UDFWriteSectors( Vcb->LastLBA = Lba+BCount-1; } - status = UDFTWrite(IrpContext, Vcb, Buffer, BCount<SectorShift, Lba, WrittenBytes); + status = UDFTWrite(IrpContext, Vcb, Buffer, BCount<SectorShift, Lba, WrittenBytes, 0); ASSERT(NT_SUCCESS(status)); return status; diff --git a/drivers/filesystems/udfs/write.c b/drivers/filesystems/udfs/write.c index 08625832bd459..49490632fbfc6 100644 --- a/drivers/filesystems/udfs/write.c +++ b/drivers/filesystems/udfs/write.c @@ -255,7 +255,7 @@ UDFCommonWrite( // Perform actual Write Status = UDFTWrite(IrpContext, Vcb, SystemBuffer, ByteCount, (ULONG)(StartingOffset >> Vcb->SectorShift), - &NumberBytesWritten); + &NumberBytesWritten, 0); UDFUnlockCallersBuffer(IrpContext, Irp, SystemBuffer); try_return(Status); } From 5f862aebb3926f2ec1023cb1f02c1896ce9d8057 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 1 May 2026 14:25:53 +0000 Subject: [PATCH 09/86] Fix udf_info.c: replace NULL with STATUS_INVALID_PARAMETER in UDFReadTagged Agent-Logs-Url: https://github.com/Zero3K20/reactos/sessions/4d1a7656-4ccf-4d3c-82be-020dfa0139d7 Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/udf_info/udf_info.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/filesystems/udfs/udf_info/udf_info.c b/drivers/filesystems/udfs/udf_info/udf_info.c index f693fb67098bb..d67f04de8977a 100644 --- a/drivers/filesystems/udfs/udf_info/udf_info.c +++ b/drivers/filesystems/udfs/udf_info/udf_info.c @@ -4671,7 +4671,7 @@ UDFReadTagged( // Read the block if (Block == 0xFFFFFFFF) - return NULL; + return STATUS_INVALID_PARAMETER; _SEH2_TRY { RC = UDFReadSectors(IrpContext, Vcb, FALSE, Block, 1, FALSE, Buf, &ReadBytes); From 81891218d64b048ce8ee66f0385db959430f0b1c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 1 May 2026 14:39:32 +0000 Subject: [PATCH 10/86] Fix cleanup.c build errors: UDFNotifyFullReportChange, forward decl, TreeLength Agent-Logs-Url: https://github.com/Zero3K20/reactos/sessions/080184ba-6d7d-4a73-b3be-29deef3acbf1 Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/cleanup.c | 36 +++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/drivers/filesystems/udfs/cleanup.c b/drivers/filesystems/udfs/cleanup.c index 3599c7715a47a..20eeed62c5766 100644 --- a/drivers/filesystems/udfs/cleanup.c +++ b/drivers/filesystems/udfs/cleanup.c @@ -26,6 +26,15 @@ UDFAutoUnlock ( IN PVCB Vcb ); +NTSTATUS +UDFCloseFileInfoChain( + IN PIRP_CONTEXT IrpContext, + IN PVCB Vcb, + IN PUDF_FILE_INFO fi, + IN ULONG TreeLength, + IN BOOLEAN VcbAcquired + ); + /************************************************************************* * * Function: UDFCommonCleanup() @@ -387,22 +396,25 @@ UDFCommonCleanup( } // Report that we have removed an entry. if (UDFIsAStream(NextFileInfo)) { - UDFNotifyFullReportChange( Vcb, NextFileInfo->Fcb, + UDFNotifyReportChange( IrpContext, Vcb, NextFileInfo->Fcb, FILE_NOTIFY_CHANGE_STREAM_NAME, - FILE_ACTION_REMOVED_STREAM); + FILE_ACTION_REMOVED_STREAM, + Ccb->Lcb, FileObject); } else { - UDFNotifyFullReportChange( Vcb, NextFileInfo->Fcb, + UDFNotifyReportChange( IrpContext, Vcb, NextFileInfo->Fcb, UDFIsADirectory(NextFileInfo) ? FILE_NOTIFY_CHANGE_DIR_NAME : FILE_NOTIFY_CHANGE_FILE_NAME, - FILE_ACTION_REMOVED); + FILE_ACTION_REMOVED, + Ccb->Lcb, FileObject); } } else if (Fcb->FcbState & UDF_FCB_DELETE_ON_CLOSE) { DiscardDelete: - UDFNotifyFullReportChange( Vcb, NextFileInfo->Fcb, + UDFNotifyReportChange( IrpContext, Vcb, NextFileInfo->Fcb, ((Ccb->Flags & UDF_CCB_ACCESS_TIME_SET) ? FILE_NOTIFY_CHANGE_LAST_ACCESS : 0) | ((Ccb->Flags & UDF_CCB_WRITE_TIME_SET) ? (FILE_NOTIFY_CHANGE_ATTRIBUTES | FILE_NOTIFY_CHANGE_LAST_WRITE) : 0) | 0, - UDFIsAStream(NextFileInfo) ? FILE_ACTION_MODIFIED_STREAM : FILE_ACTION_MODIFIED); + UDFIsAStream(NextFileInfo) ? FILE_ACTION_MODIFIED_STREAM : FILE_ACTION_MODIFIED, + Ccb->Lcb, FileObject); } if (Fcb->FcbState & UDF_FCB_DIRECTORY) { @@ -510,17 +522,19 @@ UDFCommonCleanup( if (UDFIsAStream(Fcb->FileInfo)) { - UDFNotifyFullReportChange(Vcb, + UDFNotifyReportChange(IrpContext, Vcb, Fcb, FILE_NOTIFY_CHANGE_STREAM_SIZE, - FILE_ACTION_MODIFIED_STREAM); + FILE_ACTION_MODIFIED_STREAM, + Ccb->Lcb, FileObject); } else { - UDFNotifyFullReportChange(Vcb, + UDFNotifyReportChange(IrpContext, Vcb, Fcb, FILE_NOTIFY_CHANGE_SIZE, - FILE_ACTION_MODIFIED); + FILE_ACTION_MODIFIED, + Ccb->Lcb, FileObject); } } @@ -570,7 +584,7 @@ UDFCommonCleanup( AcquiredParentFCB = FALSE; // close the chain ASSERT(AcquiredVcb); - RC2 = UDFCloseFileInfoChain(IrpContext, Vcb, NextFileInfo, Ccb->TreeLength, TRUE); + RC2 = UDFCloseFileInfoChain(IrpContext, Vcb, NextFileInfo, 0xFFFF /* walk entire chain */, TRUE); if (NT_SUCCESS(RC)) RC = RC2; From f05fa120e81f2a8f06ff415a52872406b64b6adb Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 1 May 2026 14:45:36 +0000 Subject: [PATCH 11/86] fscntrl.c: replace C++ 'auto RealDevice' with explicit PDEVICE_OBJECT declaration Agent-Logs-Url: https://github.com/Zero3K20/reactos/sessions/3a37c9ce-21c8-4dca-81c1-05a12a12accb Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/fscntrl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/filesystems/udfs/fscntrl.c b/drivers/filesystems/udfs/fscntrl.c index b7b3444f48d4b..8d6c14e9eb5b0 100644 --- a/drivers/filesystems/udfs/fscntrl.c +++ b/drivers/filesystems/udfs/fscntrl.c @@ -292,11 +292,12 @@ UDFMountVolume( BOOLEAN VcbAcquired = FALSE; BOOLEAN DeviceNotTouched = TRUE; DISK_GEOMETRY DiskGeometry; + PDEVICE_OBJECT RealDevice; ASSERT(IrpSp); UDFPrint(("\n !!! UDFMountVolume\n")); - auto RealDevice = Vpb->RealDevice; + RealDevice = Vpb->RealDevice; SetDoVerifyOnFail = UDFRealDevNeedsVerify(RealDevice); From 27bd82173e37d90ec762ff992b9d3425e73acdbb Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 1 May 2026 14:52:56 +0000 Subject: [PATCH 12/86] [UDFS] Replace lowercase false/true with FALSE/TRUE Agent-Logs-Url: https://github.com/Zero3K20/reactos/sessions/94067976-cbbd-4b6b-82d8-7f7842c0f6e4 Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/misc.c | 2 +- drivers/filesystems/udfs/read.c | 2 +- drivers/filesystems/udfs/write.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/filesystems/udfs/misc.c b/drivers/filesystems/udfs/misc.c index bb15714b9b1f5..3d98abd3a47d4 100644 --- a/drivers/filesystems/udfs/misc.c +++ b/drivers/filesystems/udfs/misc.c @@ -501,7 +501,7 @@ UDFCreateIrpContext( } // TODO: fix - if (false && IrpSp->FileObject != NULL) { + if (FALSE && IrpSp->FileObject != NULL) { PFILE_OBJECT FileObject = IrpSp->FileObject; diff --git a/drivers/filesystems/udfs/read.c b/drivers/filesystems/udfs/read.c index 202f91d30f53a..ff88dcd36e288 100644 --- a/drivers/filesystems/udfs/read.c +++ b/drivers/filesystems/udfs/read.c @@ -157,7 +157,7 @@ UDFCommonRead( if (PagingIo) { // Don't offload jobs when doing paging IO - otherwise this can lead to // deadlocks in CcCopyRead. - Wait = true; + Wait = TRUE; UDFAcquireFcbSharedStarveExclusive(IrpContext, Fcb, FALSE); FcbAcquired = TRUE; // Acquire PagingIo resource shared to serialize with writes that hold diff --git a/drivers/filesystems/udfs/write.c b/drivers/filesystems/udfs/write.c index 49490632fbfc6..d98faefab4b1c 100644 --- a/drivers/filesystems/udfs/write.c +++ b/drivers/filesystems/udfs/write.c @@ -344,7 +344,7 @@ UDFCommonWrite( if (PagingIo) { // Don't offload jobs when doing paging IO - otherwise this can lead to // deadlocks in CcCopyWrite. - Wait = true; + Wait = TRUE; // For PagingIo: FcbResource already acquired by UDFAcqLazyWrite/UDFFastIoAcqModWrite // callback before this function is called From 66ab02a5adf0fd7cbb527d02dd82b6a0abff6b3e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 1 May 2026 14:57:51 +0000 Subject: [PATCH 13/86] Fix C++ syntax in strucsup.c: FILE_ID FileId{} -> FileId = {0}, RTL_CONSTANT_STRING assignments -> RtlInitUnicodeString Agent-Logs-Url: https://github.com/Zero3K20/reactos/sessions/232e4524-cbc5-4cd7-a9c7-13163d6ffa5c Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/strucsup.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/filesystems/udfs/strucsup.c b/drivers/filesystems/udfs/strucsup.c index fcc48ff135a93..a4232ae3ecdbe 100644 --- a/drivers/filesystems/udfs/strucsup.c +++ b/drivers/filesystems/udfs/strucsup.c @@ -1206,7 +1206,7 @@ UDFCompleteMount( UNICODE_STRING LocalPath; ULONG LastSector = 0; BOOLEAN UnlockVcb = FALSE; - FILE_ID FileId{}; + FILE_ID FileId = { 0 }; PAGED_CODE(); @@ -1326,7 +1326,7 @@ UDFCompleteMount( // Open Unallocatable space stream // Generally, it should be placed in SystemStreamDirectory, but some // stupid apps think that RootDirectory is much better place.... :(( - LocalPath = RTL_CONSTANT_STRING(UDF_FN_NON_ALLOCATABLE); + RtlInitUnicodeString(&LocalPath, UDF_FN_NON_ALLOCATABLE); Status = UDFOpenFile__(IrpContext, Vcb, FALSE, TRUE, &LocalPath, Vcb->RootIndexFcb->FileInfo, &Vcb->NonAllocFileInfo, NULL); if (!NT_SUCCESS(Status) && (Status != STATUS_OBJECT_NAME_NOT_FOUND)) { @@ -1349,7 +1349,7 @@ UDFCompleteMount( UDFDirIndex(UDFGetDirIndexByFileInfo(Vcb->NonAllocFileInfo), Vcb->NonAllocFileInfo->Index)->FI_Flags |= UDF_FI_FLAG_FI_INTERNAL; } else { /* try to read Non-allocatable from alternate locations */ - LocalPath = RTL_CONSTANT_STRING(UDF_FN_NON_ALLOCATABLE_2); + RtlInitUnicodeString(&LocalPath, UDF_FN_NON_ALLOCATABLE_2); Status = UDFOpenFile__(IrpContext, Vcb, FALSE, TRUE, &LocalPath, Vcb->RootIndexFcb->FileInfo, &(Vcb->NonAllocFileInfo), NULL); if (!NT_SUCCESS(Status) && (Status != STATUS_OBJECT_NAME_NOT_FOUND)) { goto unwind_1; @@ -1359,7 +1359,7 @@ UDFCompleteMount( UDFDirIndex(UDFGetDirIndexByFileInfo(Vcb->NonAllocFileInfo), Vcb->NonAllocFileInfo->Index)->FI_Flags |= UDF_FI_FLAG_FI_INTERNAL; } else if (Vcb->SysSDirFileInfo) { - LocalPath = RTL_CONSTANT_STRING(UDF_SN_NON_ALLOCATABLE); + RtlInitUnicodeString(&LocalPath, UDF_SN_NON_ALLOCATABLE); Status = UDFOpenFile__(IrpContext, Vcb, FALSE, TRUE, &LocalPath, Vcb->SysSDirFileInfo , &(Vcb->NonAllocFileInfo), NULL); if (!NT_SUCCESS(Status) && (Status != STATUS_OBJECT_NAME_NOT_FOUND)) { goto unwind_1; @@ -1378,7 +1378,7 @@ UDFCompleteMount( /* Read SN UID mapping */ if (Vcb->SysSDirFileInfo) { - LocalPath = RTL_CONSTANT_STRING(UDF_SN_UID_MAPPING); + RtlInitUnicodeString(&LocalPath, UDF_SN_UID_MAPPING); Status = UDFOpenFile__(IrpContext, Vcb, FALSE, TRUE, &LocalPath, Vcb->SysSDirFileInfo , &Vcb->UniqueIDMapFileInfo, NULL); From 0b67b5f88ea2fd46e4e44658e87bf4a44c48c708 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 1 May 2026 15:15:20 +0000 Subject: [PATCH 14/86] Fix PFN_LIST_CORRUPT: skip MmUnlockPages on MDL_SOURCE_IS_NONPAGED_POOL MDLs Agent-Logs-Url: https://github.com/Zero3K20/reactos/sessions/654a7532-6789-4f2b-aa63-ef44735286a9 Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/env_spec.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/filesystems/udfs/env_spec.c b/drivers/filesystems/udfs/env_spec.c index d480750c14407..75a771a92e889 100644 --- a/drivers/filesystems/udfs/env_spec.c +++ b/drivers/filesystems/udfs/env_spec.c @@ -46,11 +46,17 @@ UDFAsyncCompletionRoutine( Context->IosbToUse = Irp->IoStatus; #if 1 - // Unlock pages that are described by MDL (if any)... + // Unlock pages that are described by MDL (if any). + // MDLs built with MmBuildMdlForNonPagedPool have MDL_SOURCE_IS_NONPAGED_POOL + // set; those pages were never locked so MmUnlockPages must NOT be called on + // them (it would decrement PFN reference counts that were never incremented, + // causing PFN_LIST_CORRUPT / bugcheck 0x4E with Arg1=7). Mdl = Irp->MdlAddress; while(Mdl) { MmPrint((" Unlock MDL=%x\n", Mdl)); - MmUnlockPages(Mdl); + if (!(Mdl->MdlFlags & MDL_SOURCE_IS_NONPAGED_POOL)) { + MmUnlockPages(Mdl); + } Mdl = Mdl->Next; } // ... and free MDL From cd3213fda9ccfa64bdeb91e03c99f7a7857485b3 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 1 May 2026 21:42:25 +0000 Subject: [PATCH 15/86] Apply PR #344: fix access denied on SetRenameInformation for directories/files Agent-Logs-Url: https://github.com/Zero3K20/reactos/sessions/9fd63780-7517-4780-8b0c-c3cf1175ac3c Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/fileinfo.c | 71 +---------------------------- drivers/filesystems/udfs/protos.h | 5 -- 2 files changed, 2 insertions(+), 74 deletions(-) diff --git a/drivers/filesystems/udfs/fileinfo.c b/drivers/filesystems/udfs/fileinfo.c index 9b5977e6fa684..48f7b94023418 100644 --- a/drivers/filesystems/udfs/fileinfo.c +++ b/drivers/filesystems/udfs/fileinfo.c @@ -1869,61 +1869,6 @@ UDFPrepareForRenameMoveLink( return STATUS_SUCCESS; } // end UDFPrepareForRenameMoveLink() -/* - Check if a directory subtree has any open handles (FcbCleanup != 0). - Iterative depth-first walk via ChildLcbQueue — no recursion, kernel-safe. - Returns TRUE if subtree is clean (no open handles), FALSE otherwise. -*/ -BOOLEAN -UDFCheckDirOpenHandles( - IN PFCB DirectoryFcb - ) -{ - PFCB CheckFcb = DirectoryFcb; - PLIST_ENTRY CheckLink = CheckFcb->ChildLcbQueue.Flink; - - while (CheckFcb != NULL) { - - // Process all children at current level - while (CheckLink != &CheckFcb->ChildLcbQueue) { - PLCB ChildLcb = CONTAINING_RECORD(CheckLink, LCB, ParentFcbLinks); - PFCB ChildFcb = ChildLcb->ChildFcb; - CheckLink = CheckLink->Flink; - - if (!ChildFcb) continue; - - if (ChildFcb->FcbCleanup != 0) { - return FALSE; - } - - // If child is a directory with children, descend into it - if ((ChildFcb->FcbState & UDF_FCB_DIRECTORY) && - !IsListEmpty(&ChildFcb->ChildLcbQueue)) { - CheckFcb = ChildFcb; - CheckLink = CheckFcb->ChildLcbQueue.Flink; - } - } - - // Back to root — done - if (CheckFcb == DirectoryFcb) break; - - // Ascend: find our LCB in parent, advance to next sibling - PLIST_ENTRY ParentLink; - for (ParentLink = CheckFcb->ParentLcbQueue.Flink; - ParentLink != &CheckFcb->ParentLcbQueue; - ParentLink = ParentLink->Flink) { - PLCB ParentLcb = CONTAINING_RECORD(ParentLink, LCB, ChildFcbLinks); - if (ParentLcb->ParentFcb) { - CheckFcb = ParentLcb->ParentFcb; - CheckLink = ParentLcb->ParentFcbLinks.Flink; - break; - } - } - } - - return TRUE; -} - /* Rename or move file */ @@ -2113,12 +2058,6 @@ UDFSetRenameInfo( } } - // check if the source file is in use - if (Fcb->FcbCleanup > 1) { - - try_return (RC = STATUS_ACCESS_DENIED); - } - ASSERT(Fcb->FcbCleanup); ASSERT(!Fcb->IrpContextLite); @@ -2126,12 +2065,6 @@ UDFSetRenameInfo( try_return (RC = STATUS_ACCESS_DENIED); } - // For directories: check that no descendant has open handles. - if ((Fcb->FcbState & UDF_FCB_DIRECTORY) && - !UDFCheckDirOpenHandles(Fcb)) { - try_return (RC = STATUS_ACCESS_DENIED); - } - // Check if renaming to stream name - only allowed for streams if (!TargetFileObject && NewName.Length >= sizeof(WCHAR) && NewName.Buffer[0] == L':') { @@ -2145,8 +2078,8 @@ UDFSetRenameInfo( // checks DirNdx->FileInfo != NULL for each child — blocks if any // child has a cached FileInfo structure, even with FcbCleanup=0 // (no user handles). This is too strict for rename/move where file - // data stays intact. The subtree is already validated above via - // UDFCheckDirOpenHandles which checks FcbCleanup (user handles). + // data stays intact: UDF files are addressed by physical ICB location, + // so moving a directory does not invalidate open handles to files inside. { // Note: With LCB model, FcbReference may not always be >= RefCount diff --git a/drivers/filesystems/udfs/protos.h b/drivers/filesystems/udfs/protos.h index cbabb21436fd7..49a5910c31ab0 100644 --- a/drivers/filesystems/udfs/protos.h +++ b/drivers/filesystems/udfs/protos.h @@ -445,11 +445,6 @@ UDFSetEndOfFileInfo( IN PFILE_END_OF_FILE_INFORMATION PtrBuffer ); -BOOLEAN -UDFCheckDirOpenHandles( - IN PFCB DirectoryFcb - ); - NTSTATUS UDFSetRenameInfo( IN PIRP_CONTEXT IrpContext, From 23631ce391cbd73a948a05aa84f27ccb54b7ab4a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 1 May 2026 22:22:53 +0000 Subject: [PATCH 16/86] UDFS: Add FileAttributeTagInformation support to fix SteamCMD download failures Agent-Logs-Url: https://github.com/Zero3K20/reactos/sessions/4b68d73a-2ca2-4654-b5ed-a4cc5df666f0 Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/fileinfo.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/drivers/filesystems/udfs/fileinfo.c b/drivers/filesystems/udfs/fileinfo.c index 48f7b94023418..09600d4e41dfa 100644 --- a/drivers/filesystems/udfs/fileinfo.c +++ b/drivers/filesystems/udfs/fileinfo.c @@ -123,6 +123,24 @@ UDFCommonQueryInfo( case FileAlternateNameInformation: Status = UDFGetAltNameInformation(Fcb, (PFILE_NAME_INFORMATION)Buffer, &Length); break; + case FileAttributeTagInformation: + { + PFILE_ATTRIBUTE_TAG_INFORMATION TagInfo = (PFILE_ATTRIBUTE_TAG_INFORMATION)Buffer; + + if (Length < (LONG)sizeof(FILE_ATTRIBUTE_TAG_INFORMATION)) { + Status = STATUS_BUFFER_TOO_SMALL; + break; + } + + TagInfo->FileAttributes = Fcb->FileAttributes; + if (!TagInfo->FileAttributes) { + TagInfo->FileAttributes = FILE_ATTRIBUTE_NORMAL; + } + // UDF does not support reparse points + TagInfo->ReparseTag = 0; + Length -= sizeof(FILE_ATTRIBUTE_TAG_INFORMATION); + } + break; //TODO: impl // case FileCompressionInformation: // // Status = UDFGetCompressionInformation(...); From 64f7e881420bbc6623e7afcae69741896b238279 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 1 May 2026 22:57:01 +0000 Subject: [PATCH 17/86] UDFS: Skip locality window when allocation exceeds window capacity Agent-Logs-Url: https://github.com/Zero3K20/reactos/sessions/6c1b21b5-d670-4dc8-bc8f-fcc24c3b9d6f Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/udf_info/extent.c | 23 +++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/drivers/filesystems/udfs/udf_info/extent.c b/drivers/filesystems/udfs/udf_info/extent.c index 4d0d9b927f22d..6ad9486e226fb 100644 --- a/drivers/filesystems/udfs/udf_info/extent.c +++ b/drivers/filesystems/udfs/udf_info/extent.c @@ -2335,15 +2335,28 @@ UDFResizeExtent( // the recently allocated FE sectors so that the first write // to the directory does not require a full-partition bitmap // scan. Fall back to the full-partition search on miss. + // + // Guard: only attempt the locality probe when the requested + // size fits within the window. UDFAllocFreeExtent_ rejects + // requests larger than (SearchLim - SearchStart) instantly + // with STATUS_DISK_FULL, so skipping here avoids a spurious + // DISK_FULL print and the unnecessary bitmap-lock round-trip. uint32 hint = Vcb->LastAllocatedFELba; if (hint && hint >= p_start && hint <= p_end) { uint32 l1 = ((hint - p_start) > LOCALITY_WINDOW_BLOCKS) ? (hint - LOCALITY_WINDOW_BLOCKS) : p_start; uint32 l2 = ((p_end - hint) > LOCALITY_WINDOW_BLOCKS) ? (hint + LOCALITY_WINDOW_BLOCKS) : p_end; - AdPrint(("Resize locality window [%x..%x]\n", l1, l2)); - status = UDFAllocFreeExtent(IrpContext, Vcb, Length - l, - l1, l2, - &TmpExtInf, - ExtInfo->Flags /*& EXTENT_FLAG_ALLOC_MASK*/); + uint32 windowBlocks = l2 - l1; + uint32 neededBlocks = (uint32)(((Length - l) + LBS - 1) >> BSh); + if (neededBlocks <= windowBlocks) { + AdPrint(("Resize locality window [%x..%x]\n", l1, l2)); + status = UDFAllocFreeExtent(IrpContext, Vcb, Length - l, + l1, l2, + &TmpExtInf, + ExtInfo->Flags /*& EXTENT_FLAG_ALLOC_MASK*/); + } else { + AdPrint(("Resize locality skip (need %x > window %x blocks)\n", neededBlocks, windowBlocks)); + status = STATUS_UNSUCCESSFUL; + } } else { status = STATUS_UNSUCCESSFUL; } From 8eb42912be343d7c1afc7b0fd5b6e34d1b21cdf2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 1 May 2026 23:06:47 +0000 Subject: [PATCH 18/86] plan: remove locality window entirely, always use full partition search Agent-Logs-Url: https://github.com/Zero3K20/reactos/sessions/8a8a134c-fdc1-4098-ad13-d447ccb72d4a Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/udf_info/alloc.c | 50 +++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/drivers/filesystems/udfs/udf_info/alloc.c b/drivers/filesystems/udfs/udf_info/alloc.c index 25b93ed990690..1a03631aa6f43 100644 --- a/drivers/filesystems/udfs/udf_info/alloc.c +++ b/drivers/filesystems/udfs/udf_info/alloc.c @@ -931,6 +931,56 @@ UDFGetPartFreeSpace( return s; } // end UDFGetPartFreeSpace() +/* + Returns the number of free blocks in the bit range [startBit, endBit). + If EarlyExitThreshold is non-zero, stops counting as soon as the + accumulated count reaches that value -- this makes the common "do we + have at least N free blocks?" check O(N/8) instead of O(windowSize/8). +*/ +uint32 +__fastcall +UDFGetRangeFreeBlocks( + IN PVCB Vcb, + IN uint32 startBit, + IN uint32 endBit, + IN uint32 EarlyExitThreshold + ) +{ + uint32 i; + uint32 s = 0; + + if (startBit >= endBit) + return 0; + + /* Leading partial byte */ + for (i = startBit; (i < endBit) && (i & 7); i++) { + if (UDFGetFreeBit(Vcb->FSBM_Bitmap, i)) { + s++; + if (EarlyExitThreshold && s >= EarlyExitThreshold) + return s; + } + } + + /* Bulk byte scan */ + ASSERT((i & 7) == 0); + for (; i + 7 < endBit; i += 8) { + s += bit_count_tab[(UCHAR)(~UDFChunkedGetByte(Vcb->FSBM_Bitmap, i >> 3))]; + if (EarlyExitThreshold && s >= EarlyExitThreshold) + return s; + } + + /* Trailing partial byte */ + for (; i < endBit; i++) { + if (UDFGetFreeBit(Vcb->FSBM_Bitmap, i)) { + s++; + if (EarlyExitThreshold && s >= EarlyExitThreshold) + return s; + } + } + + return s; +} // end UDFGetRangeFreeBlocks() + int64 __fastcall UDFGetFreeSpace( From 7fa228df3254beec7bc2fef8e7fdaa57c1dae0af Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 1 May 2026 23:09:38 +0000 Subject: [PATCH 19/86] udfs: check incremental free space needed for SetAllocationInformation Agent-Logs-Url: https://github.com/Zero3K20/reactos/sessions/1719bb77-c269-40d9-ab66-0134f1159c37 Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/fileinfo.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/filesystems/udfs/fileinfo.c b/drivers/filesystems/udfs/fileinfo.c index 09600d4e41dfa..6db7393bf33ab 100644 --- a/drivers/filesystems/udfs/fileinfo.c +++ b/drivers/filesystems/udfs/fileinfo.c @@ -1486,7 +1486,8 @@ UDFSetAllocationInfo( // Yes. Do the FSD specific stuff i.e. increase reserved // space on disk. - if (((LONGLONG)UDFGetFreeSpace(Vcb) << Vcb->SectorShift) < Buffer->AllocationSize.QuadPart) { + if (((LONGLONG)UDFGetFreeSpace(Vcb) << Vcb->SectorShift) < + (Buffer->AllocationSize.QuadPart - Fcb->Header.AllocationSize.QuadPart)) { try_return(RC = STATUS_DISK_FULL); } // RC = STATUS_SUCCESS; From a20ec26980a892b57abcc2284b053f9cda06d317 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 1 May 2026 23:18:49 +0000 Subject: [PATCH 20/86] udfs: expand locality window to fit requested allocation size in UDFResizeExtent Agent-Logs-Url: https://github.com/Zero3K20/reactos/sessions/fdbefea7-c8fa-4829-b9f9-29019967d94f Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/udf_info/extent.c | 25 +++++++++++----------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/drivers/filesystems/udfs/udf_info/extent.c b/drivers/filesystems/udfs/udf_info/extent.c index 6ad9486e226fb..f23cdec871e37 100644 --- a/drivers/filesystems/udfs/udf_info/extent.c +++ b/drivers/filesystems/udfs/udf_info/extent.c @@ -2343,20 +2343,19 @@ UDFResizeExtent( // DISK_FULL print and the unnecessary bitmap-lock round-trip. uint32 hint = Vcb->LastAllocatedFELba; if (hint && hint >= p_start && hint <= p_end) { - uint32 l1 = ((hint - p_start) > LOCALITY_WINDOW_BLOCKS) ? (hint - LOCALITY_WINDOW_BLOCKS) : p_start; - uint32 l2 = ((p_end - hint) > LOCALITY_WINDOW_BLOCKS) ? (hint + LOCALITY_WINDOW_BLOCKS) : p_end; - uint32 windowBlocks = l2 - l1; + // Expand the window to cover the full requested size so + // that large SetAllocationInformation requests also + // benefit from the locality hint instead of falling back + // to a full-partition search immediately. uint32 neededBlocks = (uint32)(((Length - l) + LBS - 1) >> BSh); - if (neededBlocks <= windowBlocks) { - AdPrint(("Resize locality window [%x..%x]\n", l1, l2)); - status = UDFAllocFreeExtent(IrpContext, Vcb, Length - l, - l1, l2, - &TmpExtInf, - ExtInfo->Flags /*& EXTENT_FLAG_ALLOC_MASK*/); - } else { - AdPrint(("Resize locality skip (need %x > window %x blocks)\n", neededBlocks, windowBlocks)); - status = STATUS_UNSUCCESSFUL; - } + uint32 halfWindow = (neededBlocks > LOCALITY_WINDOW_BLOCKS) ? neededBlocks : LOCALITY_WINDOW_BLOCKS; + uint32 l1 = ((hint - p_start) > halfWindow) ? (hint - halfWindow) : p_start; + uint32 l2 = ((p_end - hint) > halfWindow) ? (hint + halfWindow) : p_end; + AdPrint(("Resize locality window [%x..%x] (need %x blocks)\n", l1, l2, neededBlocks)); + status = UDFAllocFreeExtent(IrpContext, Vcb, Length - l, + l1, l2, + &TmpExtInf, + ExtInfo->Flags /*& EXTENT_FLAG_ALLOC_MASK*/); } else { status = STATUS_UNSUCCESSFUL; } From 9f5e0bd02af2da21014bb8323f43f5d71c31d140 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 1 May 2026 23:24:23 +0000 Subject: [PATCH 21/86] Revert "plan: remove locality window entirely, always use full partition search" Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/udf_info/alloc.c | 50 ----------------------- 1 file changed, 50 deletions(-) diff --git a/drivers/filesystems/udfs/udf_info/alloc.c b/drivers/filesystems/udfs/udf_info/alloc.c index 1a03631aa6f43..25b93ed990690 100644 --- a/drivers/filesystems/udfs/udf_info/alloc.c +++ b/drivers/filesystems/udfs/udf_info/alloc.c @@ -931,56 +931,6 @@ UDFGetPartFreeSpace( return s; } // end UDFGetPartFreeSpace() -/* - Returns the number of free blocks in the bit range [startBit, endBit). - If EarlyExitThreshold is non-zero, stops counting as soon as the - accumulated count reaches that value -- this makes the common "do we - have at least N free blocks?" check O(N/8) instead of O(windowSize/8). -*/ -uint32 -__fastcall -UDFGetRangeFreeBlocks( - IN PVCB Vcb, - IN uint32 startBit, - IN uint32 endBit, - IN uint32 EarlyExitThreshold - ) -{ - uint32 i; - uint32 s = 0; - - if (startBit >= endBit) - return 0; - - /* Leading partial byte */ - for (i = startBit; (i < endBit) && (i & 7); i++) { - if (UDFGetFreeBit(Vcb->FSBM_Bitmap, i)) { - s++; - if (EarlyExitThreshold && s >= EarlyExitThreshold) - return s; - } - } - - /* Bulk byte scan */ - ASSERT((i & 7) == 0); - for (; i + 7 < endBit; i += 8) { - s += bit_count_tab[(UCHAR)(~UDFChunkedGetByte(Vcb->FSBM_Bitmap, i >> 3))]; - if (EarlyExitThreshold && s >= EarlyExitThreshold) - return s; - } - - /* Trailing partial byte */ - for (; i < endBit; i++) { - if (UDFGetFreeBit(Vcb->FSBM_Bitmap, i)) { - s++; - if (EarlyExitThreshold && s >= EarlyExitThreshold) - return s; - } - } - - return s; -} // end UDFGetRangeFreeBlocks() - int64 __fastcall UDFGetFreeSpace( From d12cafc911f7a8048ea2c62afdb96437f078bee3 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 2 May 2026 01:31:55 +0000 Subject: [PATCH 22/86] Apply PR #346: replace locality window with BitmapSearchHint roving pointer in alloc.c Agent-Logs-Url: https://github.com/Zero3K20/reactos/sessions/d6dc60b1-2014-42b3-89fd-578ad73aa8ce Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/struct.h | 10 +- drivers/filesystems/udfs/udf_info/alloc.c | 35 ++++- drivers/filesystems/udfs/udf_info/extent.c | 150 ++------------------- 3 files changed, 42 insertions(+), 153 deletions(-) diff --git a/drivers/filesystems/udfs/struct.h b/drivers/filesystems/udfs/struct.h index 41c290f8edf2b..f7ac37d663539 100644 --- a/drivers/filesystems/udfs/struct.h +++ b/drivers/filesystems/udfs/struct.h @@ -704,6 +704,7 @@ struct VCB { PCHAR FSBM_OldBitmap; // 0 - free, 1 - used ULONG BitmapModified; + ULONG BitmapSearchHint; // LBA hint for next free space search (roving pointer) PCHAR BSBM_Bitmap; // 0 - normal, 1 - bad-block // pointers to Volume Descriptor Sequences @@ -747,15 +748,6 @@ struct VCB { uint32 CompatFlags; - // LBA of the most recently allocated File Entry sector. Updated on every - // successful UDFAllocateFESpace call and used as a secondary locality probe - // when the primary window (around the parent directory FE) finds no free - // blocks. Also used by UDFResizeExtent as a locality hint when appending a - // new fragment to an extent. Purely a performance hint; 0 means unused. - uint32 LastAllocatedFELba; - - // Fcb table. Synchronized with FcbTableMutex. - RTL_GENERIC_TABLE FcbTable; // Preallocated VPB for swapout, so we are not forced to consider diff --git a/drivers/filesystems/udfs/udf_info/alloc.c b/drivers/filesystems/udfs/udf_info/alloc.c index 25b93ed990690..d414cd263d261 100644 --- a/drivers/filesystems/udfs/udf_info/alloc.c +++ b/drivers/filesystems/udfs/udf_info/alloc.c @@ -788,6 +788,7 @@ UDFAllocFreeExtent_( EXTENT_AD Ext; PEXTENT_MAP Map = NULL; uint32 len, LBS, BSh, blen; + uint32 EffectiveSearchStart; LBS = Vcb->SectorSize; BSh = Vcb->SectorShift; @@ -803,11 +804,31 @@ UDFAllocFreeExtent_( if (blen > (SearchLim - SearchStart)) { goto no_free_space_err; } + + // Use the bitmap search hint for allocation locality: start near the last + // allocation to avoid scanning already-used space at the start of the partition. + // The hint is only valid when it falls within [SearchStart, SearchLim); any + // out-of-range value is silently ignored and the full range is scanned instead. + EffectiveSearchStart = SearchStart; + if (Vcb->BitmapSearchHint >= SearchStart && Vcb->BitmapSearchHint < SearchLim) { + EffectiveSearchStart = Vcb->BitmapSearchHint; + AdPrint((" BitmapSearchHint applied: hint @%x, effective start @%x\n", + Vcb->BitmapSearchHint, EffectiveSearchStart)); + } + // walk through the free space bitmap & find a single extent or a set of // frags giving in sum the Length specified while(blen) { - Ext.extLocation = UDFFindMinSuitableExtent(Vcb, blen, SearchStart, - SearchLim, &len, AllocFlags); + Ext.extLocation = UDFFindMinSuitableExtent(Vcb, blen, EffectiveSearchStart, + SearchLim, &len, AllocFlags); + if (!len && EffectiveSearchStart > SearchStart) { + // Nothing found from the hint onward; fall back to a full-range search + AdPrint((" BitmapSearchHint: no free space from @%x, falling back to full scan from @%x\n", + EffectiveSearchStart, SearchStart)); + EffectiveSearchStart = SearchStart; + Ext.extLocation = UDFFindMinSuitableExtent(Vcb, blen, SearchStart, + SearchLim, &len, AllocFlags); + } if (len >= blen) { // complete search @@ -843,12 +864,16 @@ UDFAllocFreeExtent_( AdPrint(("newly allocated extent contains BB\n")); UDFMarkSpaceAsXXXNoProtect(Vcb, 0, ExtInfo->Mapping, AS_DISCARDED); // free UDFMarkBadSpaceAsUsed(Vcb, Ext.extLocation, Ext.extLength >> BSh); // bad -> bad+used - // roll back + // Advance past the bad blocks and roll back the length + EffectiveSearchStart = Ext.extLocation + (Ext.extLength >> BSh); blen += Ext.extLength>>BSh; continue; } } + // Advance the search position past the just-allocated extent + EffectiveSearchStart = Ext.extLocation + (Ext.extLength >> BSh); + Ext.extLength |= EXTENT_NOT_RECORDED_ALLOCATED << 30; if (!(ExtInfo->Mapping)) { // create new @@ -884,6 +909,10 @@ UDFAllocFreeExtent_( return STATUS_INSUFFICIENT_RESOURCES; } } + // Persist the search position for future allocations (success path only; + // failure paths all return before reaching here via no_free_space_err). + AdPrint((" BitmapSearchHint updated: @%x -> @%x\n", Vcb->BitmapSearchHint, EffectiveSearchStart)); + Vcb->BitmapSearchHint = EffectiveSearchStart; UDFReleaseResource(&(Vcb->BitMapResource1)); ExtInfo->Length = Length; return STATUS_SUCCESS; diff --git a/drivers/filesystems/udfs/udf_info/extent.c b/drivers/filesystems/udfs/udf_info/extent.c index f23cdec871e37..f1b288d72df27 100644 --- a/drivers/filesystems/udfs/udf_info/extent.c +++ b/drivers/filesystems/udfs/udf_info/extent.c @@ -1492,18 +1492,9 @@ UDFFlushAllCachedAllocations( return STATUS_SUCCESS; } // end UDFFlushAllCachedAllocations() -// Half-width (in blocks/sectors) of the locality search window used by -// UDFAllocateFESpace. A ±LOCALITY_WINDOW_BLOCKS range is searched around -// the parent directory's FE before falling back to a full-partition search. -// 8192 sectors covers 4 MiB at 512 B/sector or 32 MiB at 4 KiB/sector. -#define LOCALITY_WINDOW_BLOCKS 8192 - /* This routine allocates space for FE of the file being created. - Uses locality-based allocation: tries to place the new FE near the - parent directory's FE to reduce seeks and keep related metadata - physically close on disk. - Falls back to a full partition search if no space is found nearby. + Allocates a single block from the partition bitmap. */ NTSTATUS UDFAllocateFESpace( @@ -1515,94 +1506,9 @@ UDFAllocateFESpace( IN uint32 Len ) { - uint32 p_start = UDFPartStart(Vcb, PartNum); - uint32 p_end = UDFPartEnd(Vcb, PartNum); - NTSTATUS status; - - AdPrint(("UDFAllocateFESpace: Part %x, [%x..%x], Len %x\n", - PartNum, p_start, p_end, Len)); - - // --- Probe 1: locality window around the parent directory's FE. --- - // This keeps related metadata close together on disk, reducing seeks. - uint32 primary_l1 = p_start, primary_l2 = p_end; // remember probe-1 window - if (DirInfo && - DirInfo->Dloc && - DirInfo->Dloc->FELoc.Mapping && - DirInfo->Dloc->FELoc.Mapping[0].extLocation) { - - uint32 fe_loc = DirInfo->Dloc->FELoc.Mapping[0].extLocation; - uint32 l1, l2; - - AdPrint((" locality: DirFE @%x\n", fe_loc)); - - // Guard against fe_loc falling outside [p_start, p_end] before - // doing unsigned subtraction; if it does, skip locality and fall - // back to the full-partition search below. - if (fe_loc >= p_start && fe_loc <= p_end) { - l1 = ((fe_loc - p_start) > LOCALITY_WINDOW_BLOCKS) ? (fe_loc - LOCALITY_WINDOW_BLOCKS) : p_start; - l2 = ((p_end - fe_loc) > LOCALITY_WINDOW_BLOCKS) ? (fe_loc + LOCALITY_WINDOW_BLOCKS) : p_end; - - AdPrint((" locality window [%x..%x]\n", l1, l2)); - - primary_l1 = l1; - primary_l2 = l2; - - status = UDFAllocFreeExtent(IrpContext, Vcb, Len, l1, l2, FEExtInfo, EXTENT_FLAG_VERIFY); - if (NT_SUCCESS(status)) { - AdPrint((" locality hit: allocated @%x\n", - FEExtInfo->Mapping ? FEExtInfo->Mapping[0].extLocation : 0)); - Vcb->LastAllocatedFELba = FEExtInfo->Mapping[0].extLocation; - return status; - } - AdPrint((" locality miss (%x), trying secondary hint\n", status)); - } else { - AdPrint((" locality: DirFE @%x out of partition [%x..%x], skipping\n", - fe_loc, p_start, p_end)); - } - } else { - AdPrint((" locality: no DirInfo, trying secondary hint\n")); - } - - // --- Probe 2: locality window around the most recently allocated FE. --- - // When the area around the parent FE is fully occupied (e.g. root-level - // files created right after UDF bootstrap structures), this secondary hint - // keeps new FEs close to the last known free region instead of triggering - // a full-partition bitmap scan. - { - uint32 hint = Vcb->LastAllocatedFELba; - if (hint && hint >= p_start && hint <= p_end) { - uint32 l1 = ((hint - p_start) > LOCALITY_WINDOW_BLOCKS) ? (hint - LOCALITY_WINDOW_BLOCKS) : p_start; - uint32 l2 = ((p_end - hint) > LOCALITY_WINDOW_BLOCKS) ? (hint + LOCALITY_WINDOW_BLOCKS) : p_end; - - // Skip if the secondary window offers no new search territory - // beyond the primary window (i.e., secondary ⊆ primary), to - // avoid a pointless duplicate bitmap walk. - // Condition: search only when at least one side of the secondary - // window extends past the primary window boundary. - if (l1 < primary_l1 || l2 > primary_l2) { - AdPrint((" secondary locality window [%x..%x]\n", l1, l2)); - status = UDFAllocFreeExtent(IrpContext, Vcb, Len, l1, l2, FEExtInfo, EXTENT_FLAG_VERIFY); - if (NT_SUCCESS(status)) { - AdPrint((" secondary locality hit: allocated @%x\n", - FEExtInfo->Mapping ? FEExtInfo->Mapping[0].extLocation : 0)); - Vcb->LastAllocatedFELba = FEExtInfo->Mapping[0].extLocation; - return status; - } - AdPrint((" secondary locality miss (%x), falling back to full search\n", status)); - } - } - } - - // --- Probe 3: full partition search --- - AdPrint((" full partition search [%x..%x]\n", p_start, p_end)); - status = UDFAllocFreeExtent(IrpContext, Vcb, Len, - p_start, p_end, FEExtInfo, EXTENT_FLAG_VERIFY); - if (NT_SUCCESS(status)) { - Vcb->LastAllocatedFELba = FEExtInfo->Mapping[0].extLocation; - } - AdPrint(("UDFAllocateFESpace: result %x, loc %x\n", - status, (NT_SUCCESS(status) && FEExtInfo->Mapping) ? FEExtInfo->Mapping[0].extLocation : 0)); - return status; + UNREFERENCED_PARAMETER(DirInfo); + return UDFAllocFreeExtent(IrpContext, Vcb, Len, + UDFPartStart(Vcb, PartNum), UDFPartEnd(Vcb, PartNum), FEExtInfo, EXTENT_FLAG_VERIFY); } // end UDFAllocateFESpace() /* @@ -2326,49 +2232,11 @@ UDFResizeExtent( (ExtInfo->Flags & EXTENT_FLAG_ALLOC_MASK) == EXTENT_FLAG_ALLOC_SEQUENTIAL) { AdPrint(("Resize tune for SEQUENTIAL i/o\n")); } - { - uint32 p_start = UDFPartStart(Vcb, PartNum); - uint32 p_end = UDFPartEnd(Vcb, PartNum); - - // --- Locality probe: try near LastAllocatedFELba first. --- - // Directory data extents benefit from being placed close to - // the recently allocated FE sectors so that the first write - // to the directory does not require a full-partition bitmap - // scan. Fall back to the full-partition search on miss. - // - // Guard: only attempt the locality probe when the requested - // size fits within the window. UDFAllocFreeExtent_ rejects - // requests larger than (SearchLim - SearchStart) instantly - // with STATUS_DISK_FULL, so skipping here avoids a spurious - // DISK_FULL print and the unnecessary bitmap-lock round-trip. - uint32 hint = Vcb->LastAllocatedFELba; - if (hint && hint >= p_start && hint <= p_end) { - // Expand the window to cover the full requested size so - // that large SetAllocationInformation requests also - // benefit from the locality hint instead of falling back - // to a full-partition search immediately. - uint32 neededBlocks = (uint32)(((Length - l) + LBS - 1) >> BSh); - uint32 halfWindow = (neededBlocks > LOCALITY_WINDOW_BLOCKS) ? neededBlocks : LOCALITY_WINDOW_BLOCKS; - uint32 l1 = ((hint - p_start) > halfWindow) ? (hint - halfWindow) : p_start; - uint32 l2 = ((p_end - hint) > halfWindow) ? (hint + halfWindow) : p_end; - AdPrint(("Resize locality window [%x..%x] (need %x blocks)\n", l1, l2, neededBlocks)); - status = UDFAllocFreeExtent(IrpContext, Vcb, Length - l, - l1, l2, - &TmpExtInf, - ExtInfo->Flags /*& EXTENT_FLAG_ALLOC_MASK*/); - } else { - status = STATUS_UNSUCCESSFUL; - } - - if (!NT_SUCCESS(status)) { - // Fall back to full-partition search. - AdPrint(("Resize full search [%x..%x]\n", p_start, p_end)); - status = UDFAllocFreeExtent(IrpContext, Vcb, Length - l, - p_start, p_end, - &TmpExtInf, - ExtInfo->Flags /*& EXTENT_FLAG_ALLOC_MASK*/); - } - } + status = UDFAllocFreeExtent(IrpContext, Vcb, Length - l, + UDFPartStart(Vcb, PartNum), + UDFPartEnd(Vcb, PartNum), + &TmpExtInf, + ExtInfo->Flags /*& EXTENT_FLAG_ALLOC_MASK*/); if (!NT_SUCCESS(status)) { UDFPrint(("UDFResizeExtent: UDFAllocFreeExtent() failed (%x)\n", status)); return status; From 7a345e81e9aa3e7bea119ff062de1a5a69306c9f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 2 May 2026 01:33:14 +0000 Subject: [PATCH 23/86] alloc.c: clamp EffectiveSearchStart to SearchLim to prevent out-of-range hint persistence Agent-Logs-Url: https://github.com/Zero3K20/reactos/sessions/d6dc60b1-2014-42b3-89fd-578ad73aa8ce Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/udf_info/alloc.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/filesystems/udfs/udf_info/alloc.c b/drivers/filesystems/udfs/udf_info/alloc.c index d414cd263d261..eb53e7dade5ef 100644 --- a/drivers/filesystems/udfs/udf_info/alloc.c +++ b/drivers/filesystems/udfs/udf_info/alloc.c @@ -866,6 +866,8 @@ UDFAllocFreeExtent_( UDFMarkBadSpaceAsUsed(Vcb, Ext.extLocation, Ext.extLength >> BSh); // bad -> bad+used // Advance past the bad blocks and roll back the length EffectiveSearchStart = Ext.extLocation + (Ext.extLength >> BSh); + if (EffectiveSearchStart > SearchLim) + EffectiveSearchStart = SearchLim; blen += Ext.extLength>>BSh; continue; } @@ -873,6 +875,8 @@ UDFAllocFreeExtent_( // Advance the search position past the just-allocated extent EffectiveSearchStart = Ext.extLocation + (Ext.extLength >> BSh); + if (EffectiveSearchStart > SearchLim) + EffectiveSearchStart = SearchLim; Ext.extLength |= EXTENT_NOT_RECORDED_ALLOCATED << 30; if (!(ExtInfo->Mapping)) { @@ -911,6 +915,9 @@ UDFAllocFreeExtent_( } // Persist the search position for future allocations (success path only; // failure paths all return before reaching here via no_free_space_err). + // Clamp to SearchLim so an out-of-range hint is silently ignored next call. + if (EffectiveSearchStart > SearchLim) + EffectiveSearchStart = SearchLim; AdPrint((" BitmapSearchHint updated: @%x -> @%x\n", Vcb->BitmapSearchHint, EffectiveSearchStart)); Vcb->BitmapSearchHint = EffectiveSearchStart; UDFReleaseResource(&(Vcb->BitMapResource1)); From ac796d5068ca30e8ec63ddff78cc192864f7f479 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 2 May 2026 04:13:49 +0000 Subject: [PATCH 24/86] udfs: fix Lcb->Reference never decremented on file close causing rename failure Agent-Logs-Url: https://github.com/Zero3K20/reactos/sessions/3f32037a-407f-4751-9450-55cf06f81b01 Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/cleanup.c | 9 +++++++++ drivers/filesystems/udfs/create.c | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/filesystems/udfs/cleanup.c b/drivers/filesystems/udfs/cleanup.c index 20eeed62c5766..073f3afc4a6ee 100644 --- a/drivers/filesystems/udfs/cleanup.c +++ b/drivers/filesystems/udfs/cleanup.c @@ -588,6 +588,15 @@ UDFCommonCleanup( if (NT_SUCCESS(RC)) RC = RC2; + // Decrement the LCB open reference count that was incremented in + // UDFCommonCreate. Without this, Lcb->Reference stays non-zero after + // the handle is closed, and UDFSetRenameInfo incorrectly treats the + // file as still open (StaleLcb->Reference != 0), returning + // STATUS_ACCESS_DENIED for every rename targeting it. + if (Ccb->Lcb) { + UDFReleasePrefix(IrpContext, Ccb->Lcb); + } + Ccb->Flags |= UDF_CCB_CLEANED; // We must clean up the share access at this time, since we may not diff --git a/drivers/filesystems/udfs/create.c b/drivers/filesystems/udfs/create.c index 822dc865cdfea..75aa28a695885 100644 --- a/drivers/filesystems/udfs/create.c +++ b/drivers/filesystems/udfs/create.c @@ -3078,7 +3078,7 @@ UDFCompleteFcbOpen( Fcb->Vcb->VcbUserReference++; // Increment LCB reference count. - // This reference will be decremented in cleanup.cpp. + // This reference will be decremented in cleanup.c (UDFCommonCleanup). if (Ccb->Lcb) { Ccb->Lcb->Reference++; } From d3a4718f87373935fac517b6d6f8a72b976f9d81 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 2 May 2026 05:19:03 +0000 Subject: [PATCH 25/86] udfs: remove incorrect FcbReference assertions in UDFCloseFileInfoChain Agent-Logs-Url: https://github.com/Zero3K20/reactos/sessions/da2d8c5e-7a22-49b8-a48e-d8f534da735b Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/cleanup.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/filesystems/udfs/cleanup.c b/drivers/filesystems/udfs/cleanup.c index 073f3afc4a6ee..c486283762d3b 100644 --- a/drivers/filesystems/udfs/cleanup.c +++ b/drivers/filesystems/udfs/cleanup.c @@ -694,11 +694,12 @@ UDFCloseFileInfoChain( if ((Fcb = fi->Fcb)) { UDF_CHECK_PAGING_IO_RESOURCE(Fcb); UDFAcquireResourceExclusive(&Fcb->FcbNonpaged->FcbResource, TRUE); - ASSERT(Fcb->FcbReference >= fi->RefCount); + // Note: FcbReference may be less than fi->RefCount for intermediate + // directories opened during path traversal without a CCB (FcbReference=0, + // fi->RefCount=1 from UDFReferenceFile__). Do not assert FcbReference here. RC2 = UDFCloseFile__(IrpContext, Vcb, fi); if (!NT_SUCCESS(RC2)) RC = RC2; - ASSERT(Fcb->FcbReference > fi->RefCount); UDF_CHECK_PAGING_IO_RESOURCE(Fcb); UDFReleaseResource(&Fcb->FcbNonpaged->FcbResource); } else { From 39b87be76cd3b37d90ff2513369ff624efb7805b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 2 May 2026 05:40:22 +0000 Subject: [PATCH 26/86] udfs: guard CcFlushCache with SharedCacheMap != NULL to fix BUGCHECK 0x18 on Windows 7 On Windows 7, calling CcFlushCache() when SharedCacheMap is NULL (but DataSectionObject is still non-NULL from a prior cached open) causes CcFlushCache to fall through to MmFlushSection -> MiFlushSectionInternal, which dereferences the stale backing file object of the previously-closed cached open. If that file object's reference count has already reached 0, ObDereferenceObjectDeferDeleteWithTag triggers BUGCHECK 0x18 (REFERENCE_BY_POINTER). DataSectionObject can remain non-NULL for some time after CcUninitializeCacheMap is called because the Memory Manager manages the section lifetime asynchronously, while SharedCacheMap is cleared immediately when the last cached handle is uninitialised. Checking SharedCacheMap != NULL before calling CcFlushCache (and UDFZeroData, which calls CcZeroData and also requires an active cache map) prevents the stale-section flush in all three call sites: - cleanup.c: flush during file cleanup on the last close - create.c: flush during non-cached open when no cached handles remain - flush.c: flush during an explicit flush IRP Agent-Logs-Url: https://github.com/Zero3K20/reactos/sessions/394dc848-53b4-4a6f-9f7e-7efcaab03452 Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/cleanup.c | 9 +++++---- drivers/filesystems/udfs/create.c | 3 ++- drivers/filesystems/udfs/flush.c | 3 ++- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/filesystems/udfs/cleanup.c b/drivers/filesystems/udfs/cleanup.c index c486283762d3b..3e809537f975a 100644 --- a/drivers/filesystems/udfs/cleanup.c +++ b/drivers/filesystems/udfs/cleanup.c @@ -437,10 +437,11 @@ UDFCommonCleanup( // handles later. We ignore any I/O errors from the flush. // We shall not flush deleted files RC = STATUS_SUCCESS; - if ( LastNonCached - || - (!Fcb->FcbCleanup && - !ForcedCleanUp) ) { + if (( LastNonCached + || + (!Fcb->FcbCleanup && + !ForcedCleanUp) ) && + Fcb->FcbNonpaged->SegmentObject.SharedCacheMap) { LONGLONG OldFileSize, NewFileSize; diff --git a/drivers/filesystems/udfs/create.c b/drivers/filesystems/udfs/create.c index 75aa28a695885..f111e53704b8a 100644 --- a/drivers/filesystems/udfs/create.c +++ b/drivers/filesystems/udfs/create.c @@ -255,7 +255,8 @@ UDFOpenExistingFcb( if (FlagOn(Options, FILE_NO_INTERMEDIATE_BUFFERING) && !((*PtrNewFcb)->CachedOpenHandleCount) && - ((*PtrNewFcb)->FcbNonpaged->SegmentObject.DataSectionObject) ) { + ((*PtrNewFcb)->FcbNonpaged->SegmentObject.DataSectionObject) && + ((*PtrNewFcb)->FcbNonpaged->SegmentObject.SharedCacheMap) ) { // If this is a non-cached open, and there are no open cached // handles, but there is still a data section, attempt a flush // and purge operation to avoid cache coherency overhead later. diff --git a/drivers/filesystems/udfs/flush.c b/drivers/filesystems/udfs/flush.c index 83c0ba81dc738..ddd6d90a60332 100644 --- a/drivers/filesystems/udfs/flush.c +++ b/drivers/filesystems/udfs/flush.c @@ -267,7 +267,8 @@ UDFFlushAFile( // Flush File _SEH2_TRY { if ((Fcb->CachedOpenHandleCount || !Fcb->FcbCleanup) && - Fcb->FcbNonpaged->SegmentObject.DataSectionObject) { + Fcb->FcbNonpaged->SegmentObject.DataSectionObject && + Fcb->FcbNonpaged->SegmentObject.SharedCacheMap) { if (!(Fcb->NtReqFCBFlags & UDF_NTREQ_FCB_DELETED) && (Fcb->NtReqFCBFlags & UDF_NTREQ_FCB_MODIFIED)) { From acb857cc6d0c3ce61d08ac15f0b041f50aed4c2b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 2 May 2026 06:06:51 +0000 Subject: [PATCH 27/86] udfs/cleanup: Guard CcSetFileSizes with CcIsFileCached to fix BSOD 0x18 Agent-Logs-Url: https://github.com/Zero3K20/reactos/sessions/ad9cfd0d-678b-4895-ac20-0c42ae1d896b Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/cleanup.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/filesystems/udfs/cleanup.c b/drivers/filesystems/udfs/cleanup.c index 3e809537f975a..bf1ef1c3836b7 100644 --- a/drivers/filesystems/udfs/cleanup.c +++ b/drivers/filesystems/udfs/cleanup.c @@ -295,7 +295,9 @@ UDFCommonCleanup( // Fcb->CommonFCBHeader.ValidDataLength.QuadPart = Fcb->Header.FileSize.QuadPart = Fcb->Header.ValidDataLength.QuadPart = 0; - CcSetFileSizes(FileObject, (PCC_FILE_SIZES)&Fcb->Header.AllocationSize); + if (CcIsFileCached(FileObject)) { + CcSetFileSizes(FileObject, (PCC_FILE_SIZES)&Fcb->Header.AllocationSize); + } UDFReleaseResource(&Fcb->FcbNonpaged->FcbPagingIoResource); } From 34ce6df0cee1200dd44526a2e736a88d7746b05e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 2 May 2026 07:18:36 +0000 Subject: [PATCH 28/86] udfs: fix assertion failures and type corruption in extent/alloc-desc handling Agent-Logs-Url: https://github.com/Zero3K20/reactos/sessions/787784a2-823f-4cdf-9a3b-2e023f941439 Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/cleanup.c | 1 + drivers/filesystems/udfs/udf_info/extent.c | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/filesystems/udfs/cleanup.c b/drivers/filesystems/udfs/cleanup.c index bf1ef1c3836b7..2946cb3f193a4 100644 --- a/drivers/filesystems/udfs/cleanup.c +++ b/drivers/filesystems/udfs/cleanup.c @@ -293,6 +293,7 @@ UDFCommonCleanup( UDFAcquireResourceExclusive(&Fcb->FcbNonpaged->FcbPagingIoResource, TRUE); // set file size to zero (for system cache manager) // Fcb->CommonFCBHeader.ValidDataLength.QuadPart = + Fcb->Header.AllocationSize.QuadPart = Fcb->Header.FileSize.QuadPart = Fcb->Header.ValidDataLength.QuadPart = 0; if (CcIsFileCached(FileObject)) { diff --git a/drivers/filesystems/udfs/udf_info/extent.c b/drivers/filesystems/udfs/udf_info/extent.c index f1b288d72df27..0c3daf0a5d5ad 100644 --- a/drivers/filesystems/udfs/udf_info/extent.c +++ b/drivers/filesystems/udfs/udf_info/extent.c @@ -338,7 +338,7 @@ UDFShortAllocDescToMapping( // record information about this frag locAddr.logicalBlockNum = AllocDesc->extPosition; - AllocExt.extLength = len; + AllocExt.extLength = (len + Vcb->SectorSize - 1) & ~(Vcb->SectorSize - 1); AllocExt.extLocation = UDFPartLbaToPhys(Vcb, &locAddr); if (AllocExt.extLocation == LBA_OUT_OF_EXTENT) { UDFPrint(("bad address\n")); @@ -498,7 +498,7 @@ UDFLongAllocDescToMapping( return NULL; } // record information about this frag - AllocExt.extLength = len; + AllocExt.extLength = (len + Vcb->SectorSize - 1) & ~(Vcb->SectorSize - 1); AllocExt.extLocation = UDFPartLbaToPhys(Vcb,&(AllocDesc[i].extLocation)); if (AllocExt.extLocation == LBA_OUT_OF_EXTENT) { UDFPrint(("bad address\n")); @@ -635,7 +635,7 @@ UDFExtAllocDescToMapping( return NULL; } // record information about this frag - AllocExt.extLength = len; + AllocExt.extLength = (len + Vcb->SectorSize - 1) & ~(Vcb->SectorSize - 1); AllocExt.extLocation = UDFPartLbaToPhys(Vcb,&(AllocDesc[i].extLocation)); if (AllocExt.extLocation == LBA_OUT_OF_EXTENT) { UDFPrint(("bad address\n")); @@ -1577,7 +1577,7 @@ UDFMarkAllocatedAsRecorded( (i == ((UDFGetMappingLength(Extent) / sizeof(EXTENT_MAP)) - 2)) && TRUE) { // make optimization for sequentially written files - Extent[i-1].extLength += Extent[i].extLength; + Extent[i-1].extLength += Extent[i].extLength & UDF_EXTENT_LENGTH_MASK; Extent[i].extLocation = 0; Extent[i].extLength = 0; } else { From 677791b97a19baa9c667091f3810ca54beb5a28b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 2 May 2026 17:40:07 +0000 Subject: [PATCH 29/86] udfs: Fix duplicate CcbListResource initialization in UDFCreateFcbNonpaged Agent-Logs-Url: https://github.com/Zero3K20/reactos/sessions/1b43f586-c51f-496e-8ed1-ade360700b40 env_spec: prefer direct-lock I/O over bounce buffers; shrink fallback chunk to 64 KB Agent-Logs-Url: https://github.com/Zero3K20/reactos/sessions/3fa66ff3-1b53-43fd-833f-1a3917974d4c Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> Revert "env_spec: prefer direct-lock I/O over bounce buffers; shrink fallback chunk to 64 KB" This reverts commit d3fdee23b4b456a1c644695966b576041c47d528. env_spec: fix comment wording per review feedback Agent-Logs-Url: https://github.com/Zero3K20/reactos/sessions/3fa66ff3-1b53-43fd-833f-1a3917974d4c Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> Revert "env_spec: fix comment wording per review feedback" This reverts commit e0db3c411461466632c625341b4c2961d5e59cfe. Co-Authored-By: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/strucsup.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/filesystems/udfs/strucsup.c b/drivers/filesystems/udfs/strucsup.c index a4232ae3ecdbe..3395822747ed8 100644 --- a/drivers/filesystems/udfs/strucsup.c +++ b/drivers/filesystems/udfs/strucsup.c @@ -149,8 +149,6 @@ Return Value: ExInitializeFastMutex(&FcbNonpaged->AdvancedFcbHeaderMutex); ExInitializeFastMutex(&FcbNonpaged->FcbFastMutex); - ExInitializeResourceLite(&FcbNonpaged->CcbListResource); - return FcbNonpaged; } From c25c319c2054f0d1626027b1a89cfae0be2b90e5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 3 May 2026 19:41:15 +0000 Subject: [PATCH 30/86] udfs: fix assertion failure in UDFCommonCreate error path when CurrentFcb != LastGoodFileInfo->Fcb Agent-Logs-Url: https://github.com/Zero3K20/reactos/sessions/30bc9d30-6715-4d18-becb-7fdf3da0e3d0 Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/create.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/drivers/filesystems/udfs/create.c b/drivers/filesystems/udfs/create.c index f111e53704b8a..2d244f54a1237 100644 --- a/drivers/filesystems/udfs/create.c +++ b/drivers/filesystems/udfs/create.c @@ -2498,13 +2498,20 @@ try_exit: NOTHING; // // Teardown partial FCB structures. - // Protect PreviousFcb from deletion via FcbReference bump — + // CurrentFcb is always the exclusively-held FCB — use it directly. + // Protect PreviousFcb from deletion via FcbReference bump: // TeardownStructures walks parent chain and may free parents. // + // Note: CurrentFcb may differ from LastGoodFileInfo->Fcb when + // UDFOpenObjectFromDirContext advances CurrentFcb to the final + // component FCB in step 4 before PerformUserOpen fails. + // - ASSERT(!LastGoodFileInfo || !LastGoodFileInfo->Fcb || CurrentFcb == LastGoodFileInfo->Fcb); - - if (Vcb && (PtrNewFcb != Vcb->RootIndexFcb) && LastGoodFileInfo) { + // Guard against tearing down the root index FCB: use CurrentFcb + // (the exclusively-locked FCB we are about to tear down) rather + // than PtrNewFcb (the output of a successful open, which may be + // NULL or different from CurrentFcb in the error path). + if (Vcb && CurrentFcb && (CurrentFcb != Vcb->RootIndexFcb)) { BOOLEAN ProtectedPreviousFcb = FALSE; if (PreviousFcb && PreviousFcb != CurrentFcb) { @@ -2515,7 +2522,7 @@ try_exit: NOTHING; } BOOLEAN RemovedFcb = FALSE; - UDFTeardownStructures(IrpContext, LastGoodFileInfo->Fcb, FALSE, &RemovedFcb); + UDFTeardownStructures(IrpContext, CurrentFcb, FALSE, &RemovedFcb); if (RemovedFcb) { if (PreviousFcb == CurrentFcb) { @@ -2530,8 +2537,6 @@ try_exit: NOTHING; UDFUnlockVcb(IrpContext, Vcb); } - } else { - ASSERT(!LastGoodFileInfo); } } From 613258a2cd6331ff75b32b3564fd841eb6dc0876 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 4 May 2026 00:13:00 +0000 Subject: [PATCH 31/86] Apply PR #193 new commits: Start=4 and devaction.c FS driver bypass Agent-Logs-Url: https://github.com/Zero3K20/reactos/sessions/9bbc2cc1-89ba-40d5-8449-5e3bb59abaa5 Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/udfs_reg.inf | 2 +- ntoskrnl/io/pnpmgr/devaction.c | 31 +++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/drivers/filesystems/udfs/udfs_reg.inf b/drivers/filesystems/udfs/udfs_reg.inf index bb289578eb551..53bba23b17afa 100644 --- a/drivers/filesystems/udfs/udfs_reg.inf +++ b/drivers/filesystems/udfs/udfs_reg.inf @@ -3,5 +3,5 @@ HKLM,"SYSTEM\CurrentControlSet\Services\Udfs","ErrorControl",0x00010001,0x00000001 HKLM,"SYSTEM\CurrentControlSet\Services\Udfs","Group",0x00000000,"File System" HKLM,"SYSTEM\CurrentControlSet\Services\Udfs","ImagePath",0x00020000,"system32\drivers\udfs.sys" -HKLM,"SYSTEM\CurrentControlSet\Services\Udfs","Start",0x00010001,0x00000003 +HKLM,"SYSTEM\CurrentControlSet\Services\Udfs","Start",0x00010001,0x00000004 HKLM,"SYSTEM\CurrentControlSet\Services\Udfs","Type",0x00010001,0x00000002 diff --git a/ntoskrnl/io/pnpmgr/devaction.c b/ntoskrnl/io/pnpmgr/devaction.c index 28079f76c6aeb..3c67ef75e6c3a 100644 --- a/ntoskrnl/io/pnpmgr/devaction.c +++ b/ntoskrnl/io/pnpmgr/devaction.c @@ -435,6 +435,37 @@ PiAttachFilterDriversCallback( // TODO: take into account other start types (like SERVICE_DEMAND_START) if (startType >= DisableLoad) { + // File system drivers and recognizer drivers are not loaded via the PnP + // device "Service" path. They register themselves via IoRegisterFileSystem + // and are loaded on demand by the file system recognizer (fs_rec) using + // ZwLoadDriver, which does not check the Start type. Allow the volume + // device to continue starting so that IopMountVolume can still be called + // and the recognizer can load the driver (e.g. UDFS with Start=4). + ULONG driverType = 0; + NTSTATUS typeStatus = IopGetRegistryValue(serviceHandle, L"Type", &kvInfo); + if (NT_SUCCESS(typeStatus)) + { + if (kvInfo->Type == REG_DWORD) + { + RtlMoveMemory(&driverType, + (PVOID)((ULONG_PTR)kvInfo + kvInfo->DataOffset), + sizeof(driverType)); + } + // If the Type value is not a DWORD, driverType stays 0 (unknown), + // which will fall through to the normal disabled-service handling below. + ExFreePool(kvInfo); + } + + if (driverType == SERVICE_FILE_SYSTEM_DRIVER || driverType == SERVICE_RECOGNIZER_DRIVER) + { + // Skip PnP loading for file system drivers; the file system + // recognizer will load the driver when a matching volume is accessed. + DPRINT("Service \"%wZ\" is a file system driver with start type %u, " + "skipping PnP load\n", &serviceName, startType); + Status = STATUS_SUCCESS; + goto Cleanup; + } + if (!(context->DeviceNode->Flags & DNF_HAS_PROBLEM)) { PiSetDevNodeProblem(context->DeviceNode, CM_PROB_DISABLED_SERVICE); From f8509535b81e7efb1715d13d3e93c30a160359ca Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 12 May 2026 01:45:06 +0000 Subject: [PATCH 32/86] Replace PR #193 with PR #358: Group=Boot File System, Start=0x3, remove devaction.c FS bypass Agent-Logs-Url: https://github.com/Zero3K20/reactos/sessions/cb88f5dc-0a5d-435b-80ea-a89015a544bf Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/udfs_reg.inf | 4 ++-- ntoskrnl/io/pnpmgr/devaction.c | 31 --------------------------- 2 files changed, 2 insertions(+), 33 deletions(-) diff --git a/drivers/filesystems/udfs/udfs_reg.inf b/drivers/filesystems/udfs/udfs_reg.inf index 53bba23b17afa..532ecdcdbf918 100644 --- a/drivers/filesystems/udfs/udfs_reg.inf +++ b/drivers/filesystems/udfs/udfs_reg.inf @@ -1,7 +1,7 @@ ; UDF Filesystem driver [AddReg] HKLM,"SYSTEM\CurrentControlSet\Services\Udfs","ErrorControl",0x00010001,0x00000001 -HKLM,"SYSTEM\CurrentControlSet\Services\Udfs","Group",0x00000000,"File System" +HKLM,"SYSTEM\CurrentControlSet\Services\Udfs","Group",0x00000000,"Boot File System" HKLM,"SYSTEM\CurrentControlSet\Services\Udfs","ImagePath",0x00020000,"system32\drivers\udfs.sys" -HKLM,"SYSTEM\CurrentControlSet\Services\Udfs","Start",0x00010001,0x00000004 +HKLM,"SYSTEM\CurrentControlSet\Services\Udfs","Start",0x00010001,0x00000003 HKLM,"SYSTEM\CurrentControlSet\Services\Udfs","Type",0x00010001,0x00000002 diff --git a/ntoskrnl/io/pnpmgr/devaction.c b/ntoskrnl/io/pnpmgr/devaction.c index 3c67ef75e6c3a..28079f76c6aeb 100644 --- a/ntoskrnl/io/pnpmgr/devaction.c +++ b/ntoskrnl/io/pnpmgr/devaction.c @@ -435,37 +435,6 @@ PiAttachFilterDriversCallback( // TODO: take into account other start types (like SERVICE_DEMAND_START) if (startType >= DisableLoad) { - // File system drivers and recognizer drivers are not loaded via the PnP - // device "Service" path. They register themselves via IoRegisterFileSystem - // and are loaded on demand by the file system recognizer (fs_rec) using - // ZwLoadDriver, which does not check the Start type. Allow the volume - // device to continue starting so that IopMountVolume can still be called - // and the recognizer can load the driver (e.g. UDFS with Start=4). - ULONG driverType = 0; - NTSTATUS typeStatus = IopGetRegistryValue(serviceHandle, L"Type", &kvInfo); - if (NT_SUCCESS(typeStatus)) - { - if (kvInfo->Type == REG_DWORD) - { - RtlMoveMemory(&driverType, - (PVOID)((ULONG_PTR)kvInfo + kvInfo->DataOffset), - sizeof(driverType)); - } - // If the Type value is not a DWORD, driverType stays 0 (unknown), - // which will fall through to the normal disabled-service handling below. - ExFreePool(kvInfo); - } - - if (driverType == SERVICE_FILE_SYSTEM_DRIVER || driverType == SERVICE_RECOGNIZER_DRIVER) - { - // Skip PnP loading for file system drivers; the file system - // recognizer will load the driver when a matching volume is accessed. - DPRINT("Service \"%wZ\" is a file system driver with start type %u, " - "skipping PnP load\n", &serviceName, startType); - Status = STATUS_SUCCESS; - goto Cleanup; - } - if (!(context->DeviceNode->Flags & DNF_HAS_PROBLEM)) { PiSetDevNodeProblem(context->DeviceNode, CM_PROB_DISABLED_SERVICE); From df1f304b10a103cb40876fec17006231ecc0553f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 12 May 2026 04:38:22 +0000 Subject: [PATCH 33/86] [FS_REC] Fix UDF recognition for 512-byte sector devices + add AVDP fallback (ac2b3462, dea32b7a) Agent-Logs-Url: https://github.com/Zero3K20/reactos/sessions/ca62b88d-427c-4ef5-bb44-a74dbdd0e273 Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/fs_rec/fs_rec.h | 3 +++ drivers/filesystems/fs_rec/udfs.c | 37 ++++++++++++++++++++++++++++- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/drivers/filesystems/fs_rec/fs_rec.h b/drivers/filesystems/fs_rec/fs_rec.h index db3112b06c78c..bd78691a9ca5e 100644 --- a/drivers/filesystems/fs_rec/fs_rec.h +++ b/drivers/filesystems/fs_rec/fs_rec.h @@ -137,6 +137,9 @@ typedef struct BIOS_PARAMETER_BLOCK USHORT BackupBootSector; } BIOS_PARAMETER_BLOCK, *PBIOS_PARAMETER_BLOCK; +/* UDFS Tag Identifier for Anchor Volume Descriptor Pointer (ECMA-167 7.2) */ +#define UDFS_TAG_ID_AVDP 0x0002 + /* UDFS Structures */ #include typedef struct _TAG diff --git a/drivers/filesystems/fs_rec/udfs.c b/drivers/filesystems/fs_rec/udfs.c index 655b6ea28c627..c2bf6af10da43 100644 --- a/drivers/filesystems/fs_rec/udfs.c +++ b/drivers/filesystems/fs_rec/udfs.c @@ -29,7 +29,12 @@ FsRecIsUdfsVolume(IN PDEVICE_OBJECT DeviceObject, int i; PAGED_CODE(); - Offset.QuadPart = 16 * SectorSize; + /* Per ECMA-167 section 8.4.1, the Volume Recognition Sequence starts at + * a fixed byte offset of 32768, regardless of the physical sector size. + * Using 16 * SectorSize is only correct for 2048-byte sectors (CD-ROM); + * for 512-byte sector devices (e.g. VHDs) it gives 8192 instead of 32768, + * causing the VRS to be missed entirely. */ + Offset.QuadPart = UDFS_VRS_START_OFFSET; for (i = 0; i < 16; i++) { if (!FsRecReadBlock(DeviceObject, @@ -55,6 +60,7 @@ FsRecIsUdfsVolume(IN PDEVICE_OBJECT DeviceObject, { DPRINT("NSR03 found\n"); ret = TRUE; + break; } if (!strncmp((const char*)VolumeStructDesc->Ident, @@ -63,6 +69,7 @@ FsRecIsUdfsVolume(IN PDEVICE_OBJECT DeviceObject, { DPRINT("NSR02 found\n"); ret = TRUE; + break; } if (!strncmp((const char*)VolumeStructDesc->Ident, @@ -98,6 +105,34 @@ FsRecIsUdfsVolume(IN PDEVICE_OBJECT DeviceObject, if (VolumeStructDesc) ExFreePool(VolumeStructDesc); + + /* If the VRS scan did not find an NSR descriptor, fall back to checking + * for the Anchor Volume Descriptor Pointer at sector 256. This covers + * disks where the VRS is absent or could not be read, and mirrors the + * detection approach used by the UDFS driver itself. */ + if (!ret) + { + PAVDP AnchorVDP = NULL; + + Offset.QuadPart = (LONGLONG)UDFS_AVDP_SECTOR * SectorSize; + if (FsRecReadBlock(DeviceObject, + &Offset, + sizeof(AVDP), + SectorSize, + (PVOID *)&AnchorVDP, + NULL)) + { + /* Tag identifier 2 = Anchor Volume Descriptor Pointer (ECMA-167 7.2) */ + if (AnchorVDP->DescriptorTag.Identifier == UDFS_TAG_ID_AVDP && + AnchorVDP->DescriptorTag.Location == UDFS_AVDP_SECTOR) + { + DPRINT("AVDP found at sector 256\n"); + ret = TRUE; + } + ExFreePool(AnchorVDP); + } + } + return ret; } From 40b7fe2ef14733bb0cf73bdd16b64165532f20d2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 12 May 2026 04:56:32 +0000 Subject: [PATCH 34/86] udfs: fix UDFGetFreeSpace reporting full partition as free on read-only volumes (DVD-ROMs) Agent-Logs-Url: https://github.com/Zero3K20/reactos/sessions/d42a2507-4032-485e-82e5-d5d3c3dedd5d Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/udf_info/alloc.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/filesystems/udfs/udf_info/alloc.c b/drivers/filesystems/udfs/udf_info/alloc.c index eb53e7dade5ef..18b48ef289a5b 100644 --- a/drivers/filesystems/udfs/udf_info/alloc.c +++ b/drivers/filesystems/udfs/udf_info/alloc.c @@ -979,13 +979,12 @@ UDFGetFreeSpace( if (!Vcb->CDR_Mode) { for(i=0;iPartitionMaps;i++) { -/* lim = UDFPartEnd(Vcb,i); - for(j=UDFPartStart(Vcb,i); jPartitions[i].AccessType < PARTITION_ACCESS_WO) + continue; s += UDFGetPartFreeSpace(Vcb, i); } } else { From 219cfd727f464cda3dada0871c424400f60cac2b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 12 May 2026 06:47:13 +0000 Subject: [PATCH 35/86] udfs: fix SectorSize=0 crash in UDFGetBlockSize during volume verify Agent-Logs-Url: https://github.com/Zero3K20/reactos/sessions/d440dbd3-69c0-45aa-b83c-3a5d3878b3cf Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/Include/phys_lib.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/drivers/filesystems/udfs/Include/phys_lib.c b/drivers/filesystems/udfs/Include/phys_lib.c index 6d60e058e5c70..8ff92d37d02e5 100644 --- a/drivers/filesystems/udfs/Include/phys_lib.c +++ b/drivers/filesystems/udfs/Include/phys_lib.c @@ -829,6 +829,21 @@ UDFGetBlockSize( } } + /* Initialize SectorSize/SectorShift from the device geometry if not already set. + * This is required in the verify path where NewVcb is zero-initialized: + * UDFDetermineVolumeLayout allocates a buffer of Vcb->SectorSize bytes, and + * the disk-path LastLBA calculation shifts by Vcb->SectorShift, so both must + * be valid before either calculation is performed. */ + if (!Vcb->SectorSize) { + ULONG BytesPerSector = DiskGeometryEx.Geometry.BytesPerSector; + if (!BytesPerSector) { + /* Fallback: 2048 for optical media, 512 for HDD */ + BytesPerSector = (UDFGetDevType(DeviceObject) == FILE_DEVICE_DISK) ? 512 : 2048; + } + Vcb->SectorSize = BytesPerSector; + Vcb->SectorShift = UDFHighBit(BytesPerSector); + } + if ( UDFGetDevType(DeviceObject) == FILE_DEVICE_DISK || FALSE) { From 6daacbf9f4c49f5592cbcbfaf26bbe01e3a96610 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 12 May 2026 14:11:02 +0000 Subject: [PATCH 36/86] udfs: pass no input buffer to CDROM_GET_DRIVE_GEOMETRY_EX Agent-Logs-Url: https://github.com/Zero3K20/reactos/sessions/c28021fe-3d14-4f05-bb5a-52c5286a3bcd Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/Include/phys_lib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/filesystems/udfs/Include/phys_lib.c b/drivers/filesystems/udfs/Include/phys_lib.c index 8ff92d37d02e5..51bd13f754c56 100644 --- a/drivers/filesystems/udfs/Include/phys_lib.c +++ b/drivers/filesystems/udfs/Include/phys_lib.c @@ -818,7 +818,7 @@ UDFGetBlockSize( } } else { RC = UDFPhSendIOCTL(IOCTL_CDROM_GET_DRIVE_GEOMETRY_EX,DeviceObject, - &DiskGeometryEx,sizeof(DISK_GEOMETRY_EX), + NULL,0, &DiskGeometryEx,sizeof(DISK_GEOMETRY_EX), TRUE,NULL ); From 163275a95a2185f5ffdc4567c835be98119f9a1c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 12 May 2026 20:46:07 +0000 Subject: [PATCH 37/86] UDFS: derive HDD LastLBA from partition length Agent-Logs-Url: https://github.com/Zero3K20/reactos/sessions/6189eb4f-af04-44f5-a033-63c989164ff9 Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/Include/phys_lib.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/filesystems/udfs/Include/phys_lib.c b/drivers/filesystems/udfs/Include/phys_lib.c index 51bd13f754c56..877a9dd52d3ec 100644 --- a/drivers/filesystems/udfs/Include/phys_lib.c +++ b/drivers/filesystems/udfs/Include/phys_lib.c @@ -847,9 +847,20 @@ UDFGetBlockSize( if ( UDFGetDevType(DeviceObject) == FILE_DEVICE_DISK || FALSE) { + ULONGLONG LastLbaSource; + Vcb->FirstLBA=0;//(ULONG)(PartitionInfo->StartingOffset.QuadPart >> Vcb->BlockSizeBits); + + LastLbaSource = PartitionInfo.PartitionLength.QuadPart; + if (!LastLbaSource) { + LastLbaSource = DiskGeometryEx.DiskSize.QuadPart; + } + if (LastLbaSource < Vcb->SectorSize) { + try_return(RC = STATUS_UNRECOGNIZED_VOLUME); + } + Vcb->LastPossibleLBA = - Vcb->LastLBA = (uint32)(DiskGeometryEx.DiskSize.QuadPart >> Vcb->SectorShift)/* + Vcb->FirstLBA*/ - 1; + Vcb->LastLBA = (uint32)(LastLbaSource >> Vcb->SectorShift)/* + Vcb->FirstLBA*/ - 1; } else { Vcb->FirstLBA=0; if (NT_SUCCESS(RC)) { From 3acc3e4cc87d9b4187006353757a8de955f38e7e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 12 May 2026 23:17:15 +0000 Subject: [PATCH 38/86] UDFS: revert broken HDD LastLBA change, keep underflow guard Agent-Logs-Url: https://github.com/Zero3K20/reactos/sessions/87bd9b2f-93dd-41bd-8622-a5c3fdb5d88e Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/Include/phys_lib.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/drivers/filesystems/udfs/Include/phys_lib.c b/drivers/filesystems/udfs/Include/phys_lib.c index 877a9dd52d3ec..373cb070b5eb4 100644 --- a/drivers/filesystems/udfs/Include/phys_lib.c +++ b/drivers/filesystems/udfs/Include/phys_lib.c @@ -847,20 +847,12 @@ UDFGetBlockSize( if ( UDFGetDevType(DeviceObject) == FILE_DEVICE_DISK || FALSE) { - ULONGLONG LastLbaSource; - Vcb->FirstLBA=0;//(ULONG)(PartitionInfo->StartingOffset.QuadPart >> Vcb->BlockSizeBits); - - LastLbaSource = PartitionInfo.PartitionLength.QuadPart; - if (!LastLbaSource) { - LastLbaSource = DiskGeometryEx.DiskSize.QuadPart; - } - if (LastLbaSource < Vcb->SectorSize) { + if (DiskGeometryEx.DiskSize.QuadPart < Vcb->SectorSize) { try_return(RC = STATUS_UNRECOGNIZED_VOLUME); } - Vcb->LastPossibleLBA = - Vcb->LastLBA = (uint32)(LastLbaSource >> Vcb->SectorShift)/* + Vcb->FirstLBA*/ - 1; + Vcb->LastLBA = (uint32)(DiskGeometryEx.DiskSize.QuadPart >> Vcb->SectorShift)/* + Vcb->FirstLBA*/ - 1; } else { Vcb->FirstLBA=0; if (NT_SUCCESS(RC)) { From 72e209ff45299093a90a315da8197a3acf92b959 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 13 May 2026 13:55:34 +0000 Subject: [PATCH 39/86] Initialize IRP operation flags in UDFS physical I/O paths Agent-Logs-Url: https://github.com/Zero3K20/reactos/sessions/df16baaf-239d-44bf-bf03-3c5d518ae955 Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/env_spec.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/filesystems/udfs/env_spec.c b/drivers/filesystems/udfs/env_spec.c index 75a771a92e889..8d37c7b0f411d 100644 --- a/drivers/filesystems/udfs/env_spec.c +++ b/drivers/filesystems/udfs/env_spec.c @@ -198,6 +198,7 @@ UDFPhReadSynchronous( RC = STATUS_INSUFFICIENT_RESOURCES; break; } + ChunkIrp->Flags = IRP_READ_OPERATION; ChunkIrp->MdlAddress = ChunkMdl; ChunkIrp->UserIosb = &ChunkCtx->IosbToUse; ChunkIrp->UserEvent = NULL; @@ -291,6 +292,7 @@ UDFPhReadSynchronous( IoFreeMdl(Mdl); try_return(RC = STATUS_INSUFFICIENT_RESOURCES); } + Irp->Flags = IRP_READ_OPERATION; Irp->MdlAddress = Mdl; Irp->UserIosb = &(Context->IosbToUse); Irp->UserEvent = NULL; @@ -439,6 +441,7 @@ UDFPhWriteSynchronous( RC = STATUS_INSUFFICIENT_RESOURCES; break; } + ChunkIrp->Flags = IRP_WRITE_OPERATION; ChunkIrp->MdlAddress = ChunkMdl; ChunkIrp->UserIosb = &ChunkCtx->IosbToUse; ChunkIrp->UserEvent = NULL; @@ -527,6 +530,7 @@ UDFPhWriteSynchronous( IoFreeMdl(Mdl); try_return(RC = STATUS_INSUFFICIENT_RESOURCES); } + irp->Flags = IRP_WRITE_OPERATION; irp->MdlAddress = Mdl; irp->UserIosb = &(Context->IosbToUse); irp->UserEvent = NULL; @@ -794,4 +798,3 @@ UDFNotifyReportChange( } } - From 2ebd4745fe5bb5332c21cc42d725f0144f9fb394 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 13 May 2026 13:56:28 +0000 Subject: [PATCH 40/86] Align UDFS IRP local naming in write path Agent-Logs-Url: https://github.com/Zero3K20/reactos/sessions/df16baaf-239d-44bf-bf03-3c5d518ae955 Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/env_spec.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/filesystems/udfs/env_spec.c b/drivers/filesystems/udfs/env_spec.c index 8d37c7b0f411d..6c3dc228f1322 100644 --- a/drivers/filesystems/udfs/env_spec.c +++ b/drivers/filesystems/udfs/env_spec.c @@ -493,7 +493,7 @@ UDFPhWriteSynchronous( // Use a single IRP for the whole transfer (these are always small, e.g. one sector). PVOID IoBuf = Buffer; ROffset.QuadPart = Offset; - PIRP irp; + PIRP Irp; PUDF_PH_CALL_CONTEXT Context = (PUDF_PH_CALL_CONTEXT)MyAllocatePool__( NonPagedPool, sizeof(UDF_PH_CALL_CONTEXT) ); if (!Context) try_return (RC = STATUS_INSUFFICIENT_RESOURCES); // Create notification event object to be used to signal the request completion. @@ -523,30 +523,30 @@ UDFPhWriteSynchronous( IoFreeMdl(Mdl); try_return(RC = LockStatus); } - irp = IoAllocateIrp(DeviceObject->StackSize, FALSE); - if (!irp) { + Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE); + if (!Irp) { UDFPrint((" !irp\n")); MmUnlockPages(Mdl); IoFreeMdl(Mdl); try_return(RC = STATUS_INSUFFICIENT_RESOURCES); } - irp->Flags = IRP_WRITE_OPERATION; - irp->MdlAddress = Mdl; - irp->UserIosb = &(Context->IosbToUse); - irp->UserEvent = NULL; - irp->RequestorMode = KernelMode; - irp->Tail.Overlay.Thread = PsGetCurrentThread(); - MmPrint((" Alloc Irp MDL=%x, ctx=%x\n", irp->MdlAddress, Context)); - IoSetCompletionRoutine(irp, &UDFAsyncCompletionRoutine, + Irp->Flags = IRP_WRITE_OPERATION; + Irp->MdlAddress = Mdl; + Irp->UserIosb = &(Context->IosbToUse); + Irp->UserEvent = NULL; + Irp->RequestorMode = KernelMode; + Irp->Tail.Overlay.Thread = PsGetCurrentThread(); + MmPrint((" Alloc Irp MDL=%x, ctx=%x\n", Irp->MdlAddress, Context)); + IoSetCompletionRoutine(Irp, &UDFAsyncCompletionRoutine, Context, TRUE, TRUE, TRUE); } - PIO_STACK_LOCATION IrpSp = IoGetNextIrpStackLocation(irp); + PIO_STACK_LOCATION IrpSp = IoGetNextIrpStackLocation(Irp); IrpSp->MajorFunction = IRP_MJ_WRITE; IrpSp->Parameters.Write.Length = ByteCount; IrpSp->Parameters.Write.ByteOffset = ROffset; SetFlag(IrpSp->Flags, SL_OVERRIDE_VERIFY_VOLUME); - RC = IoCallDriver(DeviceObject, irp); + RC = IoCallDriver(DeviceObject, Irp); if (RC == STATUS_PENDING) { DbgWaitForSingleObject(&(Context->event), NULL); From b564a9a005828782d37cbc37a923722b9bbb4711 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 13 May 2026 13:56:58 +0000 Subject: [PATCH 41/86] Fix IRP debug print naming in UDFS write path Agent-Logs-Url: https://github.com/Zero3K20/reactos/sessions/df16baaf-239d-44bf-bf03-3c5d518ae955 Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/env_spec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/filesystems/udfs/env_spec.c b/drivers/filesystems/udfs/env_spec.c index 6c3dc228f1322..abb2b61320492 100644 --- a/drivers/filesystems/udfs/env_spec.c +++ b/drivers/filesystems/udfs/env_spec.c @@ -287,7 +287,7 @@ UDFPhReadSynchronous( } Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE); if (!Irp) { - UDFPrint((" !irp\n")); + UDFPrint((" !Irp\n")); MmUnlockPages(Mdl); IoFreeMdl(Mdl); try_return(RC = STATUS_INSUFFICIENT_RESOURCES); From aaac78c1a2b8e15710ba2c3813b408e222f5b7fc Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 13 May 2026 13:57:47 +0000 Subject: [PATCH 42/86] Update remaining IRP debug label casing Agent-Logs-Url: https://github.com/Zero3K20/reactos/sessions/df16baaf-239d-44bf-bf03-3c5d518ae955 Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/env_spec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/filesystems/udfs/env_spec.c b/drivers/filesystems/udfs/env_spec.c index abb2b61320492..88d690c7d7310 100644 --- a/drivers/filesystems/udfs/env_spec.c +++ b/drivers/filesystems/udfs/env_spec.c @@ -525,7 +525,7 @@ UDFPhWriteSynchronous( } Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE); if (!Irp) { - UDFPrint((" !irp\n")); + UDFPrint((" !Irp\n")); MmUnlockPages(Mdl); IoFreeMdl(Mdl); try_return(RC = STATUS_INSUFFICIENT_RESOURCES); From 9313fcdf305c5db7e07060e9b83f915f5b2e3586 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 13 May 2026 18:05:06 +0000 Subject: [PATCH 43/86] Add verbose UDFS physical I/O and IOCTL tracing Agent-Logs-Url: https://github.com/Zero3K20/reactos/sessions/5274b055-44d9-4500-b288-f64614cb9a29 Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/env_spec.c | 39 ++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/drivers/filesystems/udfs/env_spec.c b/drivers/filesystems/udfs/env_spec.c index 88d690c7d7310..d7460df69ed15 100644 --- a/drivers/filesystems/udfs/env_spec.c +++ b/drivers/filesystems/udfs/env_spec.c @@ -40,7 +40,12 @@ UDFAsyncCompletionRoutine( IN PVOID Contxt ) { - UDFPrint(("UDFAsyncCompletionRoutine ctx=%x\n", Contxt)); + UDFPrint(("UDFAsyncCompletionRoutine: ctx=%x Irp=%x Status=%8.8x Info=%Iu IrpFlags=%8.8x\n", + Contxt, + Irp, + Irp->IoStatus.Status, + Irp->IoStatus.Information, + Irp->Flags)); PUDF_PH_CALL_CONTEXT Context = (PUDF_PH_CALL_CONTEXT)Contxt; PMDL Mdl, NextMdl; @@ -142,6 +147,9 @@ UDFPhReadSynchronous( NTSTATUS RC = STATUS_SUCCESS; LARGE_INTEGER ROffset; + UDFPrint(("UDFPhReadSynchronous: DevObj=%x Buffer=%x ByteCount=%lu Offset=%I64x Flags=%8.8x\n", + DeviceObject, Buffer, ByteCount, Offset, Flags)); + (*ReadBytes) = 0; // MmProbeAndLockPages requires IRQL <= APC_LEVEL. @@ -217,6 +225,8 @@ UDFPhReadSynchronous( } SetFlag(IrpSp->Flags, SL_OVERRIDE_VERIFY_VOLUME); + UDFPrint(("UDFPhReadSynchronous(chunk): Irp=%x Offset=%I64x Length=%lu IrpFlags=%8.8x SpFlags=%8.8x\n", + ChunkIrp, ROffset.QuadPart, ChunkSize, ChunkIrp->Flags, IrpSp->Flags)); RC = IoCallDriver(DeviceObject, ChunkIrp); // ChunkIrp and ChunkMdl are freed by UDFAsyncCompletionRoutine. @@ -225,6 +235,8 @@ UDFPhReadSynchronous( RC = ChunkCtx->IosbToUse.Status; if (RC == STATUS_DATA_OVERRUN) RC = STATUS_SUCCESS; } + UDFPrint(("UDFPhReadSynchronous(chunk): completion Status=%8.8x IosbStatus=%8.8x Info=%Iu\n", + RC, ChunkCtx->IosbToUse.Status, ChunkCtx->IosbToUse.Information)); if (NT_SUCCESS(RC)) { ULONG ChunkRead = (ULONG)ChunkCtx->IosbToUse.Information; @@ -322,6 +334,8 @@ UDFPhReadSynchronous( SetFlag(IrpSp->Flags, SL_OVERRIDE_VERIFY_VOLUME); + UDFPrint(("UDFPhReadSynchronous(single): Irp=%x Offset=%I64x Length=%lu IrpFlags=%8.8x SpFlags=%8.8x\n", + Irp, ROffset.QuadPart, ByteCount, Irp->Flags, IrpSp->Flags)); RC = IoCallDriver(DeviceObject, Irp); if (RC == STATUS_PENDING) { @@ -330,6 +344,8 @@ UDFPhReadSynchronous( RC = STATUS_SUCCESS; } } + UDFPrint(("UDFPhReadSynchronous(single): completion Status=%8.8x IosbStatus=%8.8x Info=%Iu\n", + RC, Context->IosbToUse.Status, Context->IosbToUse.Information)); if (NT_SUCCESS(RC)) { (*ReadBytes) = Context->IosbToUse.Information; } @@ -369,6 +385,9 @@ UDFPhWriteSynchronous( NTSTATUS RC = STATUS_SUCCESS; LARGE_INTEGER ROffset; + UDFPrint(("UDFPhWriteSynchronous: DevObj=%x Buffer=%x ByteCount=%lu Offset=%I64x Flags=%8.8x\n", + DeviceObject, Buffer, ByteCount, Offset, Flags)); + #ifdef DBG if (UDF_SIMULATE_WRITES) { /* FIXME ReactOS @@ -456,6 +475,8 @@ UDFPhWriteSynchronous( IrpSp->Parameters.Write.ByteOffset = ROffset; SetFlag(IrpSp->Flags, SL_OVERRIDE_VERIFY_VOLUME); + UDFPrint(("UDFPhWriteSynchronous(chunk): Irp=%x Offset=%I64x Length=%lu IrpFlags=%8.8x SpFlags=%8.8x\n", + ChunkIrp, ROffset.QuadPart, ChunkSize, ChunkIrp->Flags, IrpSp->Flags)); RC = IoCallDriver(DeviceObject, ChunkIrp); // ChunkIrp and ChunkMdl are freed by UDFAsyncCompletionRoutine. @@ -464,6 +485,8 @@ UDFPhWriteSynchronous( RC = ChunkCtx->IosbToUse.Status; if (RC == STATUS_DATA_OVERRUN) RC = STATUS_SUCCESS; } + UDFPrint(("UDFPhWriteSynchronous(chunk): completion Status=%8.8x IosbStatus=%8.8x Info=%Iu\n", + RC, ChunkCtx->IosbToUse.Status, ChunkCtx->IosbToUse.Information)); if (NT_SUCCESS(RC)) { ULONG ChunkWritten = (ULONG)ChunkCtx->IosbToUse.Information; @@ -546,6 +569,8 @@ UDFPhWriteSynchronous( IrpSp->Parameters.Write.Length = ByteCount; IrpSp->Parameters.Write.ByteOffset = ROffset; SetFlag(IrpSp->Flags, SL_OVERRIDE_VERIFY_VOLUME); + UDFPrint(("UDFPhWriteSynchronous(single): Irp=%x Offset=%I64x Length=%lu IrpFlags=%8.8x SpFlags=%8.8x\n", + Irp, ROffset.QuadPart, ByteCount, Irp->Flags, IrpSp->Flags)); RC = IoCallDriver(DeviceObject, Irp); if (RC == STATUS_PENDING) { @@ -554,6 +579,8 @@ UDFPhWriteSynchronous( RC = STATUS_SUCCESS; } } + UDFPrint(("UDFPhWriteSynchronous(single): completion Status=%8.8x IosbStatus=%8.8x Info=%Iu\n", + RC, Context->IosbToUse.Status, Context->IosbToUse.Information)); if (NT_SUCCESS(RC)) { (*WrittenBytes) = Context->IosbToUse.Information; } @@ -635,7 +662,8 @@ UDFPhSendIOCTL( PUDF_PH_CALL_CONTEXT Context; LARGE_INTEGER timeout; - UDFPrint(("UDFPhDevIOCTL: Code %8x \n",IoControlCode)); + UDFPrint(("UDFPhDevIOCTL: Code=%8x DevObj=%x InLen=%lu OutLen=%lu OverrideVerify=%u\n", + IoControlCode, DeviceObject, InputBufferLength, OutputBufferLength, OverrideVerify)); Context = (PUDF_PH_CALL_CONTEXT)MyAllocatePool__( NonPagedPool, sizeof(UDF_PH_CALL_CONTEXT) ); if (!Context) return STATUS_INSUFFICIENT_RESOURCES; @@ -661,6 +689,7 @@ UDFPhSendIOCTL( } RC = IoCallDriver(DeviceObject, irp); + UDFPrint(("UDFPhDevIOCTL: IoCallDriver returned %8.8x\n", RC)); if (RC == STATUS_PENDING) { ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL); @@ -682,12 +711,14 @@ UDFPhSendIOCTL( if ((RC = Context->IosbToUse.Status) == STATUS_DATA_OVERRUN) { RC = STATUS_SUCCESS; } - UDFPrint(("Exit wait state on evt %x, status %8.8x\n", Context, RC)); + UDFPrint(("Exit wait state on evt %x, status %8.8x, iosb=%8.8x info=%Iu\n", + Context, RC, Context->IosbToUse.Status, Context->IosbToUse.Information)); /* if (Iosb) { (*Iosb) = Context->IosbToUse; }*/ } else { - UDFPrint(("No wait completion on evt %x\n", Context)); + UDFPrint(("No wait completion on evt %x, iosb=%8.8x info=%Iu\n", + Context, Context->IosbToUse.Status, Context->IosbToUse.Information)); /* if (Iosb) { (*Iosb) = irp->IoStatus; }*/ From 443823dc3e5a815767fa7add50540a70601f8ec9 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 13 May 2026 18:05:35 +0000 Subject: [PATCH 44/86] Add broader UDFS mount and device-control diagnostics Agent-Logs-Url: https://github.com/Zero3K20/reactos/sessions/5274b055-44d9-4500-b288-f64614cb9a29 Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/devcntrl.c | 27 +++++++++++++++++++++++++-- drivers/filesystems/udfs/fscntrl.c | 9 +++++++++ 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/drivers/filesystems/udfs/devcntrl.c b/drivers/filesystems/udfs/devcntrl.c index adb9cff4e497a..b238ecc6f16d7 100644 --- a/drivers/filesystems/udfs/devcntrl.c +++ b/drivers/filesystems/udfs/devcntrl.c @@ -128,6 +128,11 @@ UDFCommonDevControl(PIRP_CONTEXT IrpContext, PIRP Irp) ASSERT_VCB(Vcb); IoControlCode = IrpSp->Parameters.DeviceIoControl.IoControlCode; + UDFPrint(("UDFCommonDevControl: Ioctl=%8.8lx InLen=%lu OutLen=%lu TypeOfOpen=%lu\n", + IoControlCode, + IrpSp->Parameters.DeviceIoControl.InputBufferLength, + IrpSp->Parameters.DeviceIoControl.OutputBufferLength, + TypeOfOpen)); if (FlagOn(Vcb->VcbState, VCB_STATE_RMW_INITIALIZED) || FlagOn(Vcb->VcbState, VCB_STATE_SEQUENCE_CACHE)) { @@ -358,7 +363,11 @@ UDFCommonDevControl(PIRP_CONTEXT IrpContext, PIRP Irp) DeviceAcquired = TRUE; } + UDFPrint(("UDFCommonDevControl: forwarding Ioctl=%8.8lx to Target=%x\n", + IoControlCode, Vcb->TargetDeviceObject)); Status = IoCallDriver(Vcb->TargetDeviceObject, Irp); + UDFPrint(("UDFCommonDevControl: IoCallDriver returned %8.8lx for Ioctl=%8.8lx\n", + Status, IoControlCode)); if (DeviceAcquired) UDFReleaseDevice(IrpContext, Vcb, NULL); @@ -376,6 +385,21 @@ UDFDevCtrlCompletionRoutine ( ) { + PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); + ULONG IoctlCode = 0; + + if (IrpSp->MajorFunction == IRP_MJ_DEVICE_CONTROL || + IrpSp->MajorFunction == IRP_MJ_INTERNAL_DEVICE_CONTROL) { + IoctlCode = IrpSp->Parameters.DeviceIoControl.IoControlCode; + } + UDFPrint(("UDFDevCtrlCompletionRoutine: Irp=%x Major=%x Ioctl=%8.8lx Pending=%u Status=%8.8x Info=%Iu\n", + Irp, + IrpSp->MajorFunction, + IoctlCode, + Irp->PendingReturned, + Irp->IoStatus.Status, + Irp->IoStatus.Information)); + // Add the hack-o-ramma to fix formats. if (Irp->PendingReturned) { @@ -383,8 +407,7 @@ UDFDevCtrlCompletionRoutine ( IoMarkIrpPending(Irp); } - return STATUS_SUCCESS; - UNREFERENCED_PARAMETER(DeviceObject); UNREFERENCED_PARAMETER(Contxt); + return STATUS_SUCCESS; } diff --git a/drivers/filesystems/udfs/fscntrl.c b/drivers/filesystems/udfs/fscntrl.c index 8d6c14e9eb5b0..cdfdc5223671d 100644 --- a/drivers/filesystems/udfs/fscntrl.c +++ b/drivers/filesystems/udfs/fscntrl.c @@ -296,6 +296,11 @@ UDFMountVolume( ASSERT(IrpSp); UDFPrint(("\n !!! UDFMountVolume\n")); + UDFPrint(("UDFMountVolume: DeviceObject=%x RealDevice=%x DeviceType=%x RealType=%x\n", + DeviceObjectWeTalkTo, + Vpb->RealDevice, + DeviceObjectWeTalkTo->DeviceType, + Vpb->RealDevice ? Vpb->RealDevice->DeviceType : 0)); RealDevice = Vpb->RealDevice; @@ -332,6 +337,8 @@ UDFMountVolume( &MediaChangeCount, sizeof(ULONG), TRUE, &Iosb); + UDFPrint(("UDFMountVolume: CHECK_VERIFY RC=%8.8x IosbStatus=%8.8x IosbInfo=%Iu MediaChangeCount=%lu\n", + RC, Iosb.Status, Iosb.Information, MediaChangeCount)); if (!NT_SUCCESS(RC)) { @@ -347,6 +354,8 @@ UDFMountVolume( &DiskGeometry, sizeof(DISK_GEOMETRY), TRUE, NULL); + UDFPrint(("UDFMountVolume: GET_DRIVE_GEOMETRY RC=%8.8x BytesPerSector=%lu MediaType=%x\n", + RC, DiskGeometry.BytesPerSector, DiskGeometry.MediaType)); if (!NT_SUCCESS(RC)) { From a26160694a95fac0b2e20234b84af394f2c303a6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 13 May 2026 18:06:09 +0000 Subject: [PATCH 45/86] Normalize UDFS debug print format specifiers Agent-Logs-Url: https://github.com/Zero3K20/reactos/sessions/5274b055-44d9-4500-b288-f64614cb9a29 Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/devcntrl.c | 4 ++-- drivers/filesystems/udfs/env_spec.c | 28 ++++++++++++++-------------- drivers/filesystems/udfs/fscntrl.c | 4 ++-- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/filesystems/udfs/devcntrl.c b/drivers/filesystems/udfs/devcntrl.c index b238ecc6f16d7..61679b4b1e391 100644 --- a/drivers/filesystems/udfs/devcntrl.c +++ b/drivers/filesystems/udfs/devcntrl.c @@ -392,13 +392,13 @@ UDFDevCtrlCompletionRoutine ( IrpSp->MajorFunction == IRP_MJ_INTERNAL_DEVICE_CONTROL) { IoctlCode = IrpSp->Parameters.DeviceIoControl.IoControlCode; } - UDFPrint(("UDFDevCtrlCompletionRoutine: Irp=%x Major=%x Ioctl=%8.8lx Pending=%u Status=%8.8x Info=%Iu\n", + UDFPrint(("UDFDevCtrlCompletionRoutine: Irp=%x Major=%x Ioctl=%8.8lx Pending=%u Status=%8.8x Info=%lx\n", Irp, IrpSp->MajorFunction, IoctlCode, Irp->PendingReturned, Irp->IoStatus.Status, - Irp->IoStatus.Information)); + (ULONG)Irp->IoStatus.Information)); // Add the hack-o-ramma to fix formats. diff --git a/drivers/filesystems/udfs/env_spec.c b/drivers/filesystems/udfs/env_spec.c index d7460df69ed15..0c63ca3d3529d 100644 --- a/drivers/filesystems/udfs/env_spec.c +++ b/drivers/filesystems/udfs/env_spec.c @@ -40,11 +40,11 @@ UDFAsyncCompletionRoutine( IN PVOID Contxt ) { - UDFPrint(("UDFAsyncCompletionRoutine: ctx=%x Irp=%x Status=%8.8x Info=%Iu IrpFlags=%8.8x\n", + UDFPrint(("UDFAsyncCompletionRoutine: ctx=%x Irp=%x Status=%8.8x Info=%lx IrpFlags=%8.8x\n", Contxt, Irp, Irp->IoStatus.Status, - Irp->IoStatus.Information, + (ULONG)Irp->IoStatus.Information, Irp->Flags)); PUDF_PH_CALL_CONTEXT Context = (PUDF_PH_CALL_CONTEXT)Contxt; PMDL Mdl, NextMdl; @@ -235,8 +235,8 @@ UDFPhReadSynchronous( RC = ChunkCtx->IosbToUse.Status; if (RC == STATUS_DATA_OVERRUN) RC = STATUS_SUCCESS; } - UDFPrint(("UDFPhReadSynchronous(chunk): completion Status=%8.8x IosbStatus=%8.8x Info=%Iu\n", - RC, ChunkCtx->IosbToUse.Status, ChunkCtx->IosbToUse.Information)); + UDFPrint(("UDFPhReadSynchronous(chunk): completion Status=%8.8x IosbStatus=%8.8x Info=%lx\n", + RC, ChunkCtx->IosbToUse.Status, (ULONG)ChunkCtx->IosbToUse.Information)); if (NT_SUCCESS(RC)) { ULONG ChunkRead = (ULONG)ChunkCtx->IosbToUse.Information; @@ -344,8 +344,8 @@ UDFPhReadSynchronous( RC = STATUS_SUCCESS; } } - UDFPrint(("UDFPhReadSynchronous(single): completion Status=%8.8x IosbStatus=%8.8x Info=%Iu\n", - RC, Context->IosbToUse.Status, Context->IosbToUse.Information)); + UDFPrint(("UDFPhReadSynchronous(single): completion Status=%8.8x IosbStatus=%8.8x Info=%lx\n", + RC, Context->IosbToUse.Status, (ULONG)Context->IosbToUse.Information)); if (NT_SUCCESS(RC)) { (*ReadBytes) = Context->IosbToUse.Information; } @@ -485,8 +485,8 @@ UDFPhWriteSynchronous( RC = ChunkCtx->IosbToUse.Status; if (RC == STATUS_DATA_OVERRUN) RC = STATUS_SUCCESS; } - UDFPrint(("UDFPhWriteSynchronous(chunk): completion Status=%8.8x IosbStatus=%8.8x Info=%Iu\n", - RC, ChunkCtx->IosbToUse.Status, ChunkCtx->IosbToUse.Information)); + UDFPrint(("UDFPhWriteSynchronous(chunk): completion Status=%8.8x IosbStatus=%8.8x Info=%lx\n", + RC, ChunkCtx->IosbToUse.Status, (ULONG)ChunkCtx->IosbToUse.Information)); if (NT_SUCCESS(RC)) { ULONG ChunkWritten = (ULONG)ChunkCtx->IosbToUse.Information; @@ -579,8 +579,8 @@ UDFPhWriteSynchronous( RC = STATUS_SUCCESS; } } - UDFPrint(("UDFPhWriteSynchronous(single): completion Status=%8.8x IosbStatus=%8.8x Info=%Iu\n", - RC, Context->IosbToUse.Status, Context->IosbToUse.Information)); + UDFPrint(("UDFPhWriteSynchronous(single): completion Status=%8.8x IosbStatus=%8.8x Info=%lx\n", + RC, Context->IosbToUse.Status, (ULONG)Context->IosbToUse.Information)); if (NT_SUCCESS(RC)) { (*WrittenBytes) = Context->IosbToUse.Information; } @@ -711,14 +711,14 @@ UDFPhSendIOCTL( if ((RC = Context->IosbToUse.Status) == STATUS_DATA_OVERRUN) { RC = STATUS_SUCCESS; } - UDFPrint(("Exit wait state on evt %x, status %8.8x, iosb=%8.8x info=%Iu\n", - Context, RC, Context->IosbToUse.Status, Context->IosbToUse.Information)); + UDFPrint(("Exit wait state on evt %x, status %8.8x, iosb=%8.8x info=%lx\n", + Context, RC, Context->IosbToUse.Status, (ULONG)Context->IosbToUse.Information)); /* if (Iosb) { (*Iosb) = Context->IosbToUse; }*/ } else { - UDFPrint(("No wait completion on evt %x, iosb=%8.8x info=%Iu\n", - Context, Context->IosbToUse.Status, Context->IosbToUse.Information)); + UDFPrint(("No wait completion on evt %x, iosb=%8.8x info=%lx\n", + Context, Context->IosbToUse.Status, (ULONG)Context->IosbToUse.Information)); /* if (Iosb) { (*Iosb) = irp->IoStatus; }*/ diff --git a/drivers/filesystems/udfs/fscntrl.c b/drivers/filesystems/udfs/fscntrl.c index cdfdc5223671d..2eb1fd54ca2ff 100644 --- a/drivers/filesystems/udfs/fscntrl.c +++ b/drivers/filesystems/udfs/fscntrl.c @@ -337,8 +337,8 @@ UDFMountVolume( &MediaChangeCount, sizeof(ULONG), TRUE, &Iosb); - UDFPrint(("UDFMountVolume: CHECK_VERIFY RC=%8.8x IosbStatus=%8.8x IosbInfo=%Iu MediaChangeCount=%lu\n", - RC, Iosb.Status, Iosb.Information, MediaChangeCount)); + UDFPrint(("UDFMountVolume: CHECK_VERIFY RC=%8.8x IosbStatus=%8.8x IosbInfo=%lx MediaChangeCount=%lu\n", + RC, Iosb.Status, (ULONG)Iosb.Information, MediaChangeCount)); if (!NT_SUCCESS(RC)) { From 31d9e9e6bd2cf3902904473b060c64de9c74d088 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 13 May 2026 18:06:38 +0000 Subject: [PATCH 46/86] Move unreferenced parameter markers in completion routine Agent-Logs-Url: https://github.com/Zero3K20/reactos/sessions/5274b055-44d9-4500-b288-f64614cb9a29 Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/devcntrl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/filesystems/udfs/devcntrl.c b/drivers/filesystems/udfs/devcntrl.c index 61679b4b1e391..8cc7659b87747 100644 --- a/drivers/filesystems/udfs/devcntrl.c +++ b/drivers/filesystems/udfs/devcntrl.c @@ -387,6 +387,8 @@ UDFDevCtrlCompletionRoutine ( { PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); ULONG IoctlCode = 0; + UNREFERENCED_PARAMETER(DeviceObject); + UNREFERENCED_PARAMETER(Contxt); if (IrpSp->MajorFunction == IRP_MJ_DEVICE_CONTROL || IrpSp->MajorFunction == IRP_MJ_INTERNAL_DEVICE_CONTROL) { @@ -407,7 +409,5 @@ UDFDevCtrlCompletionRoutine ( IoMarkIrpPending(Irp); } - UNREFERENCED_PARAMETER(DeviceObject); - UNREFERENCED_PARAMETER(Contxt); return STATUS_SUCCESS; } From 89d8617234e8af9a769f384ba5cd7c1b706f4709 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 13 May 2026 18:07:39 +0000 Subject: [PATCH 47/86] Use pointer-safe format specifiers in new UDFS traces Agent-Logs-Url: https://github.com/Zero3K20/reactos/sessions/5274b055-44d9-4500-b288-f64614cb9a29 Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/devcntrl.c | 4 ++-- drivers/filesystems/udfs/env_spec.c | 18 +++++++++--------- drivers/filesystems/udfs/fscntrl.c | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/filesystems/udfs/devcntrl.c b/drivers/filesystems/udfs/devcntrl.c index 8cc7659b87747..6b2337c8b2b0b 100644 --- a/drivers/filesystems/udfs/devcntrl.c +++ b/drivers/filesystems/udfs/devcntrl.c @@ -363,7 +363,7 @@ UDFCommonDevControl(PIRP_CONTEXT IrpContext, PIRP Irp) DeviceAcquired = TRUE; } - UDFPrint(("UDFCommonDevControl: forwarding Ioctl=%8.8lx to Target=%x\n", + UDFPrint(("UDFCommonDevControl: forwarding Ioctl=%8.8lx to Target=%p\n", IoControlCode, Vcb->TargetDeviceObject)); Status = IoCallDriver(Vcb->TargetDeviceObject, Irp); UDFPrint(("UDFCommonDevControl: IoCallDriver returned %8.8lx for Ioctl=%8.8lx\n", @@ -394,7 +394,7 @@ UDFDevCtrlCompletionRoutine ( IrpSp->MajorFunction == IRP_MJ_INTERNAL_DEVICE_CONTROL) { IoctlCode = IrpSp->Parameters.DeviceIoControl.IoControlCode; } - UDFPrint(("UDFDevCtrlCompletionRoutine: Irp=%x Major=%x Ioctl=%8.8lx Pending=%u Status=%8.8x Info=%lx\n", + UDFPrint(("UDFDevCtrlCompletionRoutine: Irp=%p Major=%u Ioctl=%8.8lx Pending=%u Status=%8.8x Info=%lx\n", Irp, IrpSp->MajorFunction, IoctlCode, diff --git a/drivers/filesystems/udfs/env_spec.c b/drivers/filesystems/udfs/env_spec.c index 0c63ca3d3529d..ae1bd3049b2c4 100644 --- a/drivers/filesystems/udfs/env_spec.c +++ b/drivers/filesystems/udfs/env_spec.c @@ -40,7 +40,7 @@ UDFAsyncCompletionRoutine( IN PVOID Contxt ) { - UDFPrint(("UDFAsyncCompletionRoutine: ctx=%x Irp=%x Status=%8.8x Info=%lx IrpFlags=%8.8x\n", + UDFPrint(("UDFAsyncCompletionRoutine: ctx=%p Irp=%p Status=%8.8x Info=%lx IrpFlags=%8.8x\n", Contxt, Irp, Irp->IoStatus.Status, @@ -93,7 +93,7 @@ UDFSyncCompletionRoutine( IN PVOID Contxt ) { - UDFPrint(("UDFSyncCompletionRoutine ctx=%x\n", Contxt)); + UDFPrint(("UDFSyncCompletionRoutine ctx=%p\n", Contxt)); PUDF_PH_CALL_CONTEXT Context = (PUDF_PH_CALL_CONTEXT)Contxt; Context->IosbToUse = Irp->IoStatus; @@ -147,7 +147,7 @@ UDFPhReadSynchronous( NTSTATUS RC = STATUS_SUCCESS; LARGE_INTEGER ROffset; - UDFPrint(("UDFPhReadSynchronous: DevObj=%x Buffer=%x ByteCount=%lu Offset=%I64x Flags=%8.8x\n", + UDFPrint(("UDFPhReadSynchronous: DevObj=%p Buffer=%p ByteCount=%lu Offset=%I64x Flags=%8.8x\n", DeviceObject, Buffer, ByteCount, Offset, Flags)); (*ReadBytes) = 0; @@ -225,7 +225,7 @@ UDFPhReadSynchronous( } SetFlag(IrpSp->Flags, SL_OVERRIDE_VERIFY_VOLUME); - UDFPrint(("UDFPhReadSynchronous(chunk): Irp=%x Offset=%I64x Length=%lu IrpFlags=%8.8x SpFlags=%8.8x\n", + UDFPrint(("UDFPhReadSynchronous(chunk): Irp=%p Offset=%I64x Length=%lu IrpFlags=%8.8x SpFlags=%8.8x\n", ChunkIrp, ROffset.QuadPart, ChunkSize, ChunkIrp->Flags, IrpSp->Flags)); RC = IoCallDriver(DeviceObject, ChunkIrp); // ChunkIrp and ChunkMdl are freed by UDFAsyncCompletionRoutine. @@ -334,7 +334,7 @@ UDFPhReadSynchronous( SetFlag(IrpSp->Flags, SL_OVERRIDE_VERIFY_VOLUME); - UDFPrint(("UDFPhReadSynchronous(single): Irp=%x Offset=%I64x Length=%lu IrpFlags=%8.8x SpFlags=%8.8x\n", + UDFPrint(("UDFPhReadSynchronous(single): Irp=%p Offset=%I64x Length=%lu IrpFlags=%8.8x SpFlags=%8.8x\n", Irp, ROffset.QuadPart, ByteCount, Irp->Flags, IrpSp->Flags)); RC = IoCallDriver(DeviceObject, Irp); @@ -385,7 +385,7 @@ UDFPhWriteSynchronous( NTSTATUS RC = STATUS_SUCCESS; LARGE_INTEGER ROffset; - UDFPrint(("UDFPhWriteSynchronous: DevObj=%x Buffer=%x ByteCount=%lu Offset=%I64x Flags=%8.8x\n", + UDFPrint(("UDFPhWriteSynchronous: DevObj=%p Buffer=%p ByteCount=%lu Offset=%I64x Flags=%8.8x\n", DeviceObject, Buffer, ByteCount, Offset, Flags)); #ifdef DBG @@ -475,7 +475,7 @@ UDFPhWriteSynchronous( IrpSp->Parameters.Write.ByteOffset = ROffset; SetFlag(IrpSp->Flags, SL_OVERRIDE_VERIFY_VOLUME); - UDFPrint(("UDFPhWriteSynchronous(chunk): Irp=%x Offset=%I64x Length=%lu IrpFlags=%8.8x SpFlags=%8.8x\n", + UDFPrint(("UDFPhWriteSynchronous(chunk): Irp=%p Offset=%I64x Length=%lu IrpFlags=%8.8x SpFlags=%8.8x\n", ChunkIrp, ROffset.QuadPart, ChunkSize, ChunkIrp->Flags, IrpSp->Flags)); RC = IoCallDriver(DeviceObject, ChunkIrp); // ChunkIrp and ChunkMdl are freed by UDFAsyncCompletionRoutine. @@ -569,7 +569,7 @@ UDFPhWriteSynchronous( IrpSp->Parameters.Write.Length = ByteCount; IrpSp->Parameters.Write.ByteOffset = ROffset; SetFlag(IrpSp->Flags, SL_OVERRIDE_VERIFY_VOLUME); - UDFPrint(("UDFPhWriteSynchronous(single): Irp=%x Offset=%I64x Length=%lu IrpFlags=%8.8x SpFlags=%8.8x\n", + UDFPrint(("UDFPhWriteSynchronous(single): Irp=%p Offset=%I64x Length=%lu IrpFlags=%8.8x SpFlags=%8.8x\n", Irp, ROffset.QuadPart, ByteCount, Irp->Flags, IrpSp->Flags)); RC = IoCallDriver(DeviceObject, Irp); @@ -662,7 +662,7 @@ UDFPhSendIOCTL( PUDF_PH_CALL_CONTEXT Context; LARGE_INTEGER timeout; - UDFPrint(("UDFPhDevIOCTL: Code=%8x DevObj=%x InLen=%lu OutLen=%lu OverrideVerify=%u\n", + UDFPrint(("UDFPhDevIOCTL: Code=%8x DevObj=%p InLen=%lu OutLen=%lu OverrideVerify=%u\n", IoControlCode, DeviceObject, InputBufferLength, OutputBufferLength, OverrideVerify)); Context = (PUDF_PH_CALL_CONTEXT)MyAllocatePool__( NonPagedPool, sizeof(UDF_PH_CALL_CONTEXT) ); diff --git a/drivers/filesystems/udfs/fscntrl.c b/drivers/filesystems/udfs/fscntrl.c index 2eb1fd54ca2ff..fe8ea52537a07 100644 --- a/drivers/filesystems/udfs/fscntrl.c +++ b/drivers/filesystems/udfs/fscntrl.c @@ -296,7 +296,7 @@ UDFMountVolume( ASSERT(IrpSp); UDFPrint(("\n !!! UDFMountVolume\n")); - UDFPrint(("UDFMountVolume: DeviceObject=%x RealDevice=%x DeviceType=%x RealType=%x\n", + UDFPrint(("UDFMountVolume: DeviceObject=%p RealDevice=%p DeviceType=%x RealType=%x\n", DeviceObjectWeTalkTo, Vpb->RealDevice, DeviceObjectWeTalkTo->DeviceType, From efaea6781f3f4a6b55aa38788ea024f83c1e6037 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 13 May 2026 18:08:20 +0000 Subject: [PATCH 48/86] Address review nits in verbose UDFS diagnostics Agent-Logs-Url: https://github.com/Zero3K20/reactos/sessions/5274b055-44d9-4500-b288-f64614cb9a29 Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/devcntrl.c | 4 ++-- drivers/filesystems/udfs/env_spec.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/filesystems/udfs/devcntrl.c b/drivers/filesystems/udfs/devcntrl.c index 6b2337c8b2b0b..12cbfeea2fae9 100644 --- a/drivers/filesystems/udfs/devcntrl.c +++ b/drivers/filesystems/udfs/devcntrl.c @@ -385,10 +385,10 @@ UDFDevCtrlCompletionRoutine ( ) { - PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); - ULONG IoctlCode = 0; UNREFERENCED_PARAMETER(DeviceObject); UNREFERENCED_PARAMETER(Contxt); + PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); + ULONG IoctlCode = 0; if (IrpSp->MajorFunction == IRP_MJ_DEVICE_CONTROL || IrpSp->MajorFunction == IRP_MJ_INTERNAL_DEVICE_CONTROL) { diff --git a/drivers/filesystems/udfs/env_spec.c b/drivers/filesystems/udfs/env_spec.c index ae1bd3049b2c4..7c52f9e071e61 100644 --- a/drivers/filesystems/udfs/env_spec.c +++ b/drivers/filesystems/udfs/env_spec.c @@ -40,7 +40,7 @@ UDFAsyncCompletionRoutine( IN PVOID Contxt ) { - UDFPrint(("UDFAsyncCompletionRoutine: ctx=%p Irp=%p Status=%8.8x Info=%lx IrpFlags=%8.8x\n", + UDFPrint(("UDFAsyncCompletionRoutine: ctx=%p Irp=%p Status=%8.8x IosbInfo=%lx IrpFlags=%8.8x\n", Contxt, Irp, Irp->IoStatus.Status, From 49b920fe002c09654289372f7efadefa50b4b098 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 13 May 2026 18:09:09 +0000 Subject: [PATCH 49/86] Harden completion diagnostics against invalid stack access Agent-Logs-Url: https://github.com/Zero3K20/reactos/sessions/5274b055-44d9-4500-b288-f64614cb9a29 Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/devcntrl.c | 11 +---------- drivers/filesystems/udfs/env_spec.c | 17 ++++++++++++++++- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/drivers/filesystems/udfs/devcntrl.c b/drivers/filesystems/udfs/devcntrl.c index 12cbfeea2fae9..e372f998e7793 100644 --- a/drivers/filesystems/udfs/devcntrl.c +++ b/drivers/filesystems/udfs/devcntrl.c @@ -387,17 +387,8 @@ UDFDevCtrlCompletionRoutine ( { UNREFERENCED_PARAMETER(DeviceObject); UNREFERENCED_PARAMETER(Contxt); - PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); - ULONG IoctlCode = 0; - - if (IrpSp->MajorFunction == IRP_MJ_DEVICE_CONTROL || - IrpSp->MajorFunction == IRP_MJ_INTERNAL_DEVICE_CONTROL) { - IoctlCode = IrpSp->Parameters.DeviceIoControl.IoControlCode; - } - UDFPrint(("UDFDevCtrlCompletionRoutine: Irp=%p Major=%u Ioctl=%8.8lx Pending=%u Status=%8.8x Info=%lx\n", + UDFPrint(("UDFDevCtrlCompletionRoutine: Irp=%p Pending=%u Status=%8.8x Info=%lx\n", Irp, - IrpSp->MajorFunction, - IoctlCode, Irp->PendingReturned, Irp->IoStatus.Status, (ULONG)Irp->IoStatus.Information)); diff --git a/drivers/filesystems/udfs/env_spec.c b/drivers/filesystems/udfs/env_spec.c index 7c52f9e071e61..73c1b17b33648 100644 --- a/drivers/filesystems/udfs/env_spec.c +++ b/drivers/filesystems/udfs/env_spec.c @@ -40,6 +40,11 @@ UDFAsyncCompletionRoutine( IN PVOID Contxt ) { + if (!Irp) { + UDFPrint(("UDFAsyncCompletionRoutine: ctx=%p Irp=NULL\n", Contxt)); + return STATUS_MORE_PROCESSING_REQUIRED; + } + UDFPrint(("UDFAsyncCompletionRoutine: ctx=%p Irp=%p Status=%8.8x IosbInfo=%lx IrpFlags=%8.8x\n", Contxt, Irp, @@ -93,7 +98,17 @@ UDFSyncCompletionRoutine( IN PVOID Contxt ) { - UDFPrint(("UDFSyncCompletionRoutine ctx=%p\n", Contxt)); + if (!Irp) { + UDFPrint(("UDFSyncCompletionRoutine: ctx=%p Irp=NULL\n", Contxt)); + return STATUS_SUCCESS; + } + + UDFPrint(("UDFSyncCompletionRoutine: ctx=%p Irp=%p Status=%8.8x IosbInfo=%lx IrpFlags=%8.8x\n", + Contxt, + Irp, + Irp->IoStatus.Status, + (ULONG)Irp->IoStatus.Information, + Irp->Flags)); PUDF_PH_CALL_CONTEXT Context = (PUDF_PH_CALL_CONTEXT)Contxt; Context->IosbToUse = Irp->IoStatus; From 23008e440a38900d785c19353305e3c1fae0d1f0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 13 May 2026 18:09:48 +0000 Subject: [PATCH 50/86] Add NULL guards in verbose completion logging Agent-Logs-Url: https://github.com/Zero3K20/reactos/sessions/5274b055-44d9-4500-b288-f64614cb9a29 Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/devcntrl.c | 6 ++++++ drivers/filesystems/udfs/env_spec.c | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/filesystems/udfs/devcntrl.c b/drivers/filesystems/udfs/devcntrl.c index e372f998e7793..665ca64f2231f 100644 --- a/drivers/filesystems/udfs/devcntrl.c +++ b/drivers/filesystems/udfs/devcntrl.c @@ -387,6 +387,12 @@ UDFDevCtrlCompletionRoutine ( { UNREFERENCED_PARAMETER(DeviceObject); UNREFERENCED_PARAMETER(Contxt); + + if (!Irp) { + UDFPrint(("UDFDevCtrlCompletionRoutine: Irp=NULL\n")); + return STATUS_SUCCESS; + } + UDFPrint(("UDFDevCtrlCompletionRoutine: Irp=%p Pending=%u Status=%8.8x Info=%lx\n", Irp, Irp->PendingReturned, diff --git a/drivers/filesystems/udfs/env_spec.c b/drivers/filesystems/udfs/env_spec.c index 73c1b17b33648..b467dff15e476 100644 --- a/drivers/filesystems/udfs/env_spec.c +++ b/drivers/filesystems/udfs/env_spec.c @@ -42,7 +42,7 @@ UDFAsyncCompletionRoutine( { if (!Irp) { UDFPrint(("UDFAsyncCompletionRoutine: ctx=%p Irp=NULL\n", Contxt)); - return STATUS_MORE_PROCESSING_REQUIRED; + return STATUS_SUCCESS; } UDFPrint(("UDFAsyncCompletionRoutine: ctx=%p Irp=%p Status=%8.8x IosbInfo=%lx IrpFlags=%8.8x\n", From aab970d9ab9c4a862fef88d8be6fc334f6a78f89 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 13 May 2026 18:10:27 +0000 Subject: [PATCH 51/86] Fail fast on unexpected NULL IRP in debug completions Agent-Logs-Url: https://github.com/Zero3K20/reactos/sessions/5274b055-44d9-4500-b288-f64614cb9a29 Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/devcntrl.c | 3 ++- drivers/filesystems/udfs/env_spec.c | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/filesystems/udfs/devcntrl.c b/drivers/filesystems/udfs/devcntrl.c index 665ca64f2231f..b185a3025e14a 100644 --- a/drivers/filesystems/udfs/devcntrl.c +++ b/drivers/filesystems/udfs/devcntrl.c @@ -390,7 +390,8 @@ UDFDevCtrlCompletionRoutine ( if (!Irp) { UDFPrint(("UDFDevCtrlCompletionRoutine: Irp=NULL\n")); - return STATUS_SUCCESS; + ASSERT(FALSE); + return STATUS_INVALID_PARAMETER; } UDFPrint(("UDFDevCtrlCompletionRoutine: Irp=%p Pending=%u Status=%8.8x Info=%lx\n", diff --git a/drivers/filesystems/udfs/env_spec.c b/drivers/filesystems/udfs/env_spec.c index b467dff15e476..f52322c458d3a 100644 --- a/drivers/filesystems/udfs/env_spec.c +++ b/drivers/filesystems/udfs/env_spec.c @@ -42,7 +42,8 @@ UDFAsyncCompletionRoutine( { if (!Irp) { UDFPrint(("UDFAsyncCompletionRoutine: ctx=%p Irp=NULL\n", Contxt)); - return STATUS_SUCCESS; + ASSERT(FALSE); + return STATUS_INVALID_PARAMETER; } UDFPrint(("UDFAsyncCompletionRoutine: ctx=%p Irp=%p Status=%8.8x IosbInfo=%lx IrpFlags=%8.8x\n", @@ -100,7 +101,8 @@ UDFSyncCompletionRoutine( { if (!Irp) { UDFPrint(("UDFSyncCompletionRoutine: ctx=%p Irp=NULL\n", Contxt)); - return STATUS_SUCCESS; + ASSERT(FALSE); + return STATUS_INVALID_PARAMETER; } UDFPrint(("UDFSyncCompletionRoutine: ctx=%p Irp=%p Status=%8.8x IosbInfo=%lx IrpFlags=%8.8x\n", From 3d2741c2a124b7a48a2659a13a60bc79d34124d8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 13 May 2026 18:11:05 +0000 Subject: [PATCH 52/86] Use completion-safe return values in NULL-IRP guards Agent-Logs-Url: https://github.com/Zero3K20/reactos/sessions/5274b055-44d9-4500-b288-f64614cb9a29 Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/devcntrl.c | 2 +- drivers/filesystems/udfs/env_spec.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/filesystems/udfs/devcntrl.c b/drivers/filesystems/udfs/devcntrl.c index b185a3025e14a..5e871b2928fd3 100644 --- a/drivers/filesystems/udfs/devcntrl.c +++ b/drivers/filesystems/udfs/devcntrl.c @@ -391,7 +391,7 @@ UDFDevCtrlCompletionRoutine ( if (!Irp) { UDFPrint(("UDFDevCtrlCompletionRoutine: Irp=NULL\n")); ASSERT(FALSE); - return STATUS_INVALID_PARAMETER; + return STATUS_SUCCESS; } UDFPrint(("UDFDevCtrlCompletionRoutine: Irp=%p Pending=%u Status=%8.8x Info=%lx\n", diff --git a/drivers/filesystems/udfs/env_spec.c b/drivers/filesystems/udfs/env_spec.c index f52322c458d3a..9fa5b6ee1c10c 100644 --- a/drivers/filesystems/udfs/env_spec.c +++ b/drivers/filesystems/udfs/env_spec.c @@ -43,7 +43,7 @@ UDFAsyncCompletionRoutine( if (!Irp) { UDFPrint(("UDFAsyncCompletionRoutine: ctx=%p Irp=NULL\n", Contxt)); ASSERT(FALSE); - return STATUS_INVALID_PARAMETER; + return STATUS_SUCCESS; } UDFPrint(("UDFAsyncCompletionRoutine: ctx=%p Irp=%p Status=%8.8x IosbInfo=%lx IrpFlags=%8.8x\n", @@ -102,7 +102,7 @@ UDFSyncCompletionRoutine( if (!Irp) { UDFPrint(("UDFSyncCompletionRoutine: ctx=%p Irp=NULL\n", Contxt)); ASSERT(FALSE); - return STATUS_INVALID_PARAMETER; + return STATUS_SUCCESS; } UDFPrint(("UDFSyncCompletionRoutine: ctx=%p Irp=%p Status=%8.8x IosbInfo=%lx IrpFlags=%8.8x\n", From 13cdcce6569868b545e2039f88007ab542d523cb Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 13 May 2026 18:12:14 +0000 Subject: [PATCH 53/86] Align verbose diagnostic naming and IOCTL format specifiers Agent-Logs-Url: https://github.com/Zero3K20/reactos/sessions/5274b055-44d9-4500-b288-f64614cb9a29 Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/devcntrl.c | 12 ++++++------ drivers/filesystems/udfs/env_spec.c | 24 ++++++++++++------------ 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/filesystems/udfs/devcntrl.c b/drivers/filesystems/udfs/devcntrl.c index 5e871b2928fd3..3bfff06e9b2bb 100644 --- a/drivers/filesystems/udfs/devcntrl.c +++ b/drivers/filesystems/udfs/devcntrl.c @@ -33,7 +33,7 @@ NTAPI UDFDevCtrlCompletionRoutine ( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, - IN PVOID Contxt + IN PVOID Context ); NTSTATUS @@ -128,7 +128,7 @@ UDFCommonDevControl(PIRP_CONTEXT IrpContext, PIRP Irp) ASSERT_VCB(Vcb); IoControlCode = IrpSp->Parameters.DeviceIoControl.IoControlCode; - UDFPrint(("UDFCommonDevControl: Ioctl=%8.8lx InLen=%lu OutLen=%lu TypeOfOpen=%lu\n", + UDFPrint(("UDFCommonDevControl: Ioctl=%8.8x InLen=%lu OutLen=%lu TypeOfOpen=%lu\n", IoControlCode, IrpSp->Parameters.DeviceIoControl.InputBufferLength, IrpSp->Parameters.DeviceIoControl.OutputBufferLength, @@ -363,10 +363,10 @@ UDFCommonDevControl(PIRP_CONTEXT IrpContext, PIRP Irp) DeviceAcquired = TRUE; } - UDFPrint(("UDFCommonDevControl: forwarding Ioctl=%8.8lx to Target=%p\n", + UDFPrint(("UDFCommonDevControl: forwarding Ioctl=%8.8x to Target=%p\n", IoControlCode, Vcb->TargetDeviceObject)); Status = IoCallDriver(Vcb->TargetDeviceObject, Irp); - UDFPrint(("UDFCommonDevControl: IoCallDriver returned %8.8lx for Ioctl=%8.8lx\n", + UDFPrint(("UDFCommonDevControl: IoCallDriver returned %8.8lx for Ioctl=%8.8x\n", Status, IoControlCode)); if (DeviceAcquired) @@ -381,12 +381,12 @@ NTAPI UDFDevCtrlCompletionRoutine ( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, - IN PVOID Contxt + IN PVOID Context ) { UNREFERENCED_PARAMETER(DeviceObject); - UNREFERENCED_PARAMETER(Contxt); + UNREFERENCED_PARAMETER(Context); if (!Irp) { UDFPrint(("UDFDevCtrlCompletionRoutine: Irp=NULL\n")); diff --git a/drivers/filesystems/udfs/env_spec.c b/drivers/filesystems/udfs/env_spec.c index 9fa5b6ee1c10c..78141173d853c 100644 --- a/drivers/filesystems/udfs/env_spec.c +++ b/drivers/filesystems/udfs/env_spec.c @@ -37,25 +37,25 @@ NTAPI UDFAsyncCompletionRoutine( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, - IN PVOID Contxt + IN PVOID Context ) { if (!Irp) { - UDFPrint(("UDFAsyncCompletionRoutine: ctx=%p Irp=NULL\n", Contxt)); + UDFPrint(("UDFAsyncCompletionRoutine: ctx=%p Irp=NULL\n", Context)); ASSERT(FALSE); return STATUS_SUCCESS; } UDFPrint(("UDFAsyncCompletionRoutine: ctx=%p Irp=%p Status=%8.8x IosbInfo=%lx IrpFlags=%8.8x\n", - Contxt, + Context, Irp, Irp->IoStatus.Status, (ULONG)Irp->IoStatus.Information, Irp->Flags)); - PUDF_PH_CALL_CONTEXT Context = (PUDF_PH_CALL_CONTEXT)Contxt; + PUDF_PH_CALL_CONTEXT CallContext = (PUDF_PH_CALL_CONTEXT)Context; PMDL Mdl, NextMdl; - Context->IosbToUse = Irp->IoStatus; + CallContext->IosbToUse = Irp->IoStatus; #if 1 // Unlock pages that are described by MDL (if any). // MDLs built with MmBuildMdlForNonPagedPool have MDL_SOURCE_IS_NONPAGED_POOL @@ -81,11 +81,11 @@ UDFAsyncCompletionRoutine( Irp->MdlAddress = NULL; IoFreeIrp(Irp); - KeSetEvent( &(Context->event), 0, FALSE ); + KeSetEvent( &(CallContext->event), 0, FALSE ); return STATUS_MORE_PROCESSING_REQUIRED; #else - KeSetEvent( &(Context->event), 0, FALSE ); + KeSetEvent( &(CallContext->event), 0, FALSE ); return STATUS_SUCCESS; #endif @@ -96,24 +96,24 @@ NTAPI UDFSyncCompletionRoutine( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, - IN PVOID Contxt + IN PVOID Context ) { if (!Irp) { - UDFPrint(("UDFSyncCompletionRoutine: ctx=%p Irp=NULL\n", Contxt)); + UDFPrint(("UDFSyncCompletionRoutine: ctx=%p Irp=NULL\n", Context)); ASSERT(FALSE); return STATUS_SUCCESS; } UDFPrint(("UDFSyncCompletionRoutine: ctx=%p Irp=%p Status=%8.8x IosbInfo=%lx IrpFlags=%8.8x\n", - Contxt, + Context, Irp, Irp->IoStatus.Status, (ULONG)Irp->IoStatus.Information, Irp->Flags)); - PUDF_PH_CALL_CONTEXT Context = (PUDF_PH_CALL_CONTEXT)Contxt; + PUDF_PH_CALL_CONTEXT CallContext = (PUDF_PH_CALL_CONTEXT)Context; - Context->IosbToUse = Irp->IoStatus; + CallContext->IosbToUse = Irp->IoStatus; //KeSetEvent( &(Context->event), 0, FALSE ); return STATUS_SUCCESS; From 17cea6bdd2ad1881bd16399d2d0a3425d25d0881 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 13 May 2026 21:08:00 +0000 Subject: [PATCH 54/86] Add verbose ATAPI diagnostic prints for CHS overflow and IDE_STATUS_ERROR Agent-Logs-Url: https://github.com/Zero3K20/reactos/sessions/b057a1e9-0add-4efd-a679-a47ed2f3aac0 Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/storage/ide/atapi/atapi.c | 103 +++++++++++++++++++----------- 1 file changed, 65 insertions(+), 38 deletions(-) diff --git a/drivers/storage/ide/atapi/atapi.c b/drivers/storage/ide/atapi/atapi.c index 19b8a0ee44793..0c591253f1aa3 100644 --- a/drivers/storage/ide/atapi/atapi.c +++ b/drivers/storage/ide/atapi/atapi.c @@ -3616,6 +3616,14 @@ Return Value: if (statusByte & IDE_STATUS_ERROR) { + UCHAR errorByte = ScsiPortReadPortUchar((PUCHAR)baseIoAddress1 + 1); + + DebugPrint((1, + "AtapiInterrupt: IDE_STATUS_ERROR - status %02x error %02x Cdb[0] %02x\n", + statusByte, + errorByte, + srb->Cdb[0])); + if (srb->Cdb[0] != SCSIOP_REQUEST_SENSE) { // @@ -4571,10 +4579,14 @@ Return Value: ((PCDB)Srb->Cdb)->CDB10.LogicalBlockByte1 << 16 | ((PCDB)Srb->Cdb)->CDB10.LogicalBlockByte0 << 24; - DebugPrint((2, - "IdeReadWrite: Starting sector is %x, Number of bytes %x\n", + DebugPrint((1, + "IdeReadWrite: LBA %lx, Bytes %x, SPT %u, Heads %u, Cyls %u, Cap %04x\n", startingSector, - Srb->DataTransferLength)); + Srb->DataTransferLength, + deviceExtension->IdentifyData[Srb->TargetId].SectorsPerTrack, + deviceExtension->IdentifyData[Srb->TargetId].NumberOfHeads, + deviceExtension->IdentifyData[Srb->TargetId].NumberOfCylinders, + deviceExtension->IdentifyData[Srb->TargetId].Capabilities)); // // Set up sector number register. @@ -4587,16 +4599,27 @@ Return Value: // Set up cylinder low register. // - cylinderLow = (UCHAR)(startingSector / (deviceExtension->IdentifyData[Srb->TargetId].SectorsPerTrack * - deviceExtension->IdentifyData[Srb->TargetId].NumberOfHeads)); + { + ULONG cylinder = startingSector / (deviceExtension->IdentifyData[Srb->TargetId].SectorsPerTrack * + deviceExtension->IdentifyData[Srb->TargetId].NumberOfHeads); + + if (cylinder > 0xFFFF) { + DebugPrint((1, + "IdeReadWrite: WARNING - cylinder %lx overflows 16-bit CHS range (LBA %lx)\n", + cylinder, + startingSector)); + } + + cylinderLow = (UCHAR)(cylinder & 0xFF); + cylinderHigh = (UCHAR)((cylinder >> 8) & 0xFF); + } + ScsiPortWritePortUchar(&baseIoAddress1->CylinderLow,cylinderLow); // // Set up cylinder high register. // - cylinderHigh = (UCHAR)((startingSector / (deviceExtension->IdentifyData[Srb->TargetId].SectorsPerTrack * - deviceExtension->IdentifyData[Srb->TargetId].NumberOfHeads)) >> 8); ScsiPortWritePortUchar(&baseIoAddress1->CylinderHigh,cylinderHigh); // @@ -4607,11 +4630,10 @@ Return Value: deviceExtension->IdentifyData[Srb->TargetId].NumberOfHeads) |((Srb->TargetId & 0x1) << 4) | 0xA0); ScsiPortWritePortUchar(&baseIoAddress1->DriveSelect,drvSelect); - DebugPrint((2, - "IdeReadWrite: Cylinder %x Head %x Sector %x\n", - startingSector / - (deviceExtension->IdentifyData[Srb->TargetId].SectorsPerTrack * - deviceExtension->IdentifyData[Srb->TargetId].NumberOfHeads), + DebugPrint((1, + "IdeReadWrite: CylHi %02x CylLo %02x Head %x Sector %x\n", + cylinderHigh, + cylinderLow, (startingSector / deviceExtension->IdentifyData[Srb->TargetId].SectorsPerTrack) % deviceExtension->IdentifyData[Srb->TargetId].NumberOfHeads, @@ -4792,10 +4814,14 @@ Return Value: ((PCDB)Srb->Cdb)->CDB10.LogicalBlockByte1 << 16 | ((PCDB)Srb->Cdb)->CDB10.LogicalBlockByte0 << 24; - DebugPrint((3, - "IdeVerify: Starting sector %x. Number of blocks %x\n", + DebugPrint((1, + "IdeVerify: LBA %lx, Blocks %x, SPT %u, Heads %u, Cyls %u, Cap %04x\n", startingSector, - ((PCDB)Srb->Cdb)->CDB10.TransferBlocksLsb)); + ((PCDB)Srb->Cdb)->CDB10.TransferBlocksLsb, + deviceExtension->IdentifyData[Srb->TargetId].SectorsPerTrack, + deviceExtension->IdentifyData[Srb->TargetId].NumberOfHeads, + deviceExtension->IdentifyData[Srb->TargetId].NumberOfCylinders, + deviceExtension->IdentifyData[Srb->TargetId].Capabilities)); sectorCount = (USHORT)(((PCDB)Srb->Cdb)->CDB10.TransferBlocksMsb << 8 | ((PCDB)Srb->Cdb)->CDB10.TransferBlocksLsb ); @@ -4853,22 +4879,34 @@ Return Value: deviceExtension->IdentifyData[Srb->TargetId].SectorsPerTrack) + 1)); // - // Set up cylinder low register. + // Set up cylinder low and high registers. // - ScsiPortWritePortUchar(&baseIoAddress1->CylinderLow, - (UCHAR)(startingSector / - (deviceExtension->IdentifyData[Srb->TargetId].SectorsPerTrack * - deviceExtension->IdentifyData[Srb->TargetId].NumberOfHeads))); + { + ULONG cylinder = startingSector / + (deviceExtension->IdentifyData[Srb->TargetId].SectorsPerTrack * + deviceExtension->IdentifyData[Srb->TargetId].NumberOfHeads); - // - // Set up cylinder high register. - // + if (cylinder > 0xFFFF) { + DebugPrint((1, + "IdeVerify: WARNING - cylinder %lx overflows 16-bit CHS range (LBA %lx)\n", + cylinder, + startingSector)); + } - ScsiPortWritePortUchar(&baseIoAddress1->CylinderHigh, - (UCHAR)((startingSector / - (deviceExtension->IdentifyData[Srb->TargetId].SectorsPerTrack * - deviceExtension->IdentifyData[Srb->TargetId].NumberOfHeads)) >> 8)); + ScsiPortWritePortUchar(&baseIoAddress1->CylinderLow, (UCHAR)(cylinder & 0xFF)); + ScsiPortWritePortUchar(&baseIoAddress1->CylinderHigh, (UCHAR)((cylinder >> 8) & 0xFF)); + + DebugPrint((1, + "IdeVerify: CylHi %02x CylLo %02x Head %x Sector %x\n", + (UCHAR)((cylinder >> 8) & 0xFF), + (UCHAR)(cylinder & 0xFF), + (startingSector / + deviceExtension->IdentifyData[Srb->TargetId].SectorsPerTrack) % + deviceExtension->IdentifyData[Srb->TargetId].NumberOfHeads, + startingSector % + deviceExtension->IdentifyData[Srb->TargetId].SectorsPerTrack + 1)); + } // // Set up head and drive select register. @@ -4880,17 +4918,6 @@ Return Value: deviceExtension->IdentifyData[Srb->TargetId].NumberOfHeads) | ((Srb->TargetId & 0x1) << 4) | 0xA0)); - DebugPrint((2, - "IdeVerify: Cylinder %x Head %x Sector %x\n", - startingSector / - (deviceExtension->IdentifyData[Srb->TargetId].SectorsPerTrack * - deviceExtension->IdentifyData[Srb->TargetId].NumberOfHeads), - (startingSector / - deviceExtension->IdentifyData[Srb->TargetId].SectorsPerTrack) % - deviceExtension->IdentifyData[Srb->TargetId].NumberOfHeads, - startingSector % - deviceExtension->IdentifyData[Srb->TargetId].SectorsPerTrack + 1)); - // // Send verify command. From a304bbc0d9061a9c48569d06589b97899431543f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 13 May 2026 21:08:26 +0000 Subject: [PATCH 55/86] Fix UDFGetBlockSize to use PartitionLength instead of DiskSize for LastLBA Agent-Logs-Url: https://github.com/Zero3K20/reactos/sessions/b057a1e9-0add-4efd-a679-a47ed2f3aac0 Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/Include/phys_lib.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/drivers/filesystems/udfs/Include/phys_lib.c b/drivers/filesystems/udfs/Include/phys_lib.c index 373cb070b5eb4..866a9905752a6 100644 --- a/drivers/filesystems/udfs/Include/phys_lib.c +++ b/drivers/filesystems/udfs/Include/phys_lib.c @@ -851,8 +851,23 @@ UDFGetBlockSize( if (DiskGeometryEx.DiskSize.QuadPart < Vcb->SectorSize) { try_return(RC = STATUS_UNRECOGNIZED_VOLUME); } - Vcb->LastPossibleLBA = - Vcb->LastLBA = (uint32)(DiskGeometryEx.DiskSize.QuadPart >> Vcb->SectorShift)/* + Vcb->FirstLBA*/ - 1; + // Use the partition length to bound LastLBA. DiskGeometryEx.DiskSize + // reflects the whole physical disk, which can be much larger than the + // actual partition (e.g. a sparse/dynamic 256 GB virtual disk image with + // a small UDF volume at the start). Using DiskSize causes UDFFindAnchor + // to probe blocks far beyond the written area, generating DEVICE_ERRORs + // in legacy CHS-only ATA drivers that cannot address such large LBAs. + { + ULONGLONG volSize = (PartitionInfo.PartitionLength.QuadPart > 0) + ? PartitionInfo.PartitionLength.QuadPart + : DiskGeometryEx.DiskSize.QuadPart; + UDFPrint(("UDFGetBlockSize: DiskSize=%I64x PartitionLength=%I64x => volSize=%I64x\n", + DiskGeometryEx.DiskSize.QuadPart, + PartitionInfo.PartitionLength.QuadPart, + volSize)); + Vcb->LastPossibleLBA = + Vcb->LastLBA = (uint32)(volSize >> Vcb->SectorShift) - 1; + } } else { Vcb->FirstLBA=0; if (NT_SUCCESS(RC)) { From a9c2179501325664f4e05237192d60a8f1138aaa Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 13 May 2026 21:09:35 +0000 Subject: [PATCH 56/86] Lower verbose per-I/O prints to level 2; keep overflow warning and error at level 1 Agent-Logs-Url: https://github.com/Zero3K20/reactos/sessions/b057a1e9-0add-4efd-a679-a47ed2f3aac0 Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/storage/ide/atapi/atapi.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/storage/ide/atapi/atapi.c b/drivers/storage/ide/atapi/atapi.c index 0c591253f1aa3..808a8973496aa 100644 --- a/drivers/storage/ide/atapi/atapi.c +++ b/drivers/storage/ide/atapi/atapi.c @@ -4579,7 +4579,7 @@ Return Value: ((PCDB)Srb->Cdb)->CDB10.LogicalBlockByte1 << 16 | ((PCDB)Srb->Cdb)->CDB10.LogicalBlockByte0 << 24; - DebugPrint((1, + DebugPrint((2, "IdeReadWrite: LBA %lx, Bytes %x, SPT %u, Heads %u, Cyls %u, Cap %04x\n", startingSector, Srb->DataTransferLength, @@ -4630,7 +4630,7 @@ Return Value: deviceExtension->IdentifyData[Srb->TargetId].NumberOfHeads) |((Srb->TargetId & 0x1) << 4) | 0xA0); ScsiPortWritePortUchar(&baseIoAddress1->DriveSelect,drvSelect); - DebugPrint((1, + DebugPrint((2, "IdeReadWrite: CylHi %02x CylLo %02x Head %x Sector %x\n", cylinderHigh, cylinderLow, @@ -4814,7 +4814,7 @@ Return Value: ((PCDB)Srb->Cdb)->CDB10.LogicalBlockByte1 << 16 | ((PCDB)Srb->Cdb)->CDB10.LogicalBlockByte0 << 24; - DebugPrint((1, + DebugPrint((2, "IdeVerify: LBA %lx, Blocks %x, SPT %u, Heads %u, Cyls %u, Cap %04x\n", startingSector, ((PCDB)Srb->Cdb)->CDB10.TransferBlocksLsb, @@ -4897,7 +4897,7 @@ Return Value: ScsiPortWritePortUchar(&baseIoAddress1->CylinderLow, (UCHAR)(cylinder & 0xFF)); ScsiPortWritePortUchar(&baseIoAddress1->CylinderHigh, (UCHAR)((cylinder >> 8) & 0xFF)); - DebugPrint((1, + DebugPrint((2, "IdeVerify: CylHi %02x CylLo %02x Head %x Sector %x\n", (UCHAR)((cylinder >> 8) & 0xFF), (UCHAR)(cylinder & 0xFF), From c47c83765f34ea2d9e837c942107f3e331b6eb7c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 14 May 2026 20:00:43 +0000 Subject: [PATCH 57/86] Revert "Lower verbose per-I/O prints to level 2; keep overflow warning and error at level 1" This reverts commit a9c2179501325664f4e05237192d60a8f1138aaa. Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/storage/ide/atapi/atapi.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/storage/ide/atapi/atapi.c b/drivers/storage/ide/atapi/atapi.c index 808a8973496aa..0c591253f1aa3 100644 --- a/drivers/storage/ide/atapi/atapi.c +++ b/drivers/storage/ide/atapi/atapi.c @@ -4579,7 +4579,7 @@ Return Value: ((PCDB)Srb->Cdb)->CDB10.LogicalBlockByte1 << 16 | ((PCDB)Srb->Cdb)->CDB10.LogicalBlockByte0 << 24; - DebugPrint((2, + DebugPrint((1, "IdeReadWrite: LBA %lx, Bytes %x, SPT %u, Heads %u, Cyls %u, Cap %04x\n", startingSector, Srb->DataTransferLength, @@ -4630,7 +4630,7 @@ Return Value: deviceExtension->IdentifyData[Srb->TargetId].NumberOfHeads) |((Srb->TargetId & 0x1) << 4) | 0xA0); ScsiPortWritePortUchar(&baseIoAddress1->DriveSelect,drvSelect); - DebugPrint((2, + DebugPrint((1, "IdeReadWrite: CylHi %02x CylLo %02x Head %x Sector %x\n", cylinderHigh, cylinderLow, @@ -4814,7 +4814,7 @@ Return Value: ((PCDB)Srb->Cdb)->CDB10.LogicalBlockByte1 << 16 | ((PCDB)Srb->Cdb)->CDB10.LogicalBlockByte0 << 24; - DebugPrint((2, + DebugPrint((1, "IdeVerify: LBA %lx, Blocks %x, SPT %u, Heads %u, Cyls %u, Cap %04x\n", startingSector, ((PCDB)Srb->Cdb)->CDB10.TransferBlocksLsb, @@ -4897,7 +4897,7 @@ Return Value: ScsiPortWritePortUchar(&baseIoAddress1->CylinderLow, (UCHAR)(cylinder & 0xFF)); ScsiPortWritePortUchar(&baseIoAddress1->CylinderHigh, (UCHAR)((cylinder >> 8) & 0xFF)); - DebugPrint((2, + DebugPrint((1, "IdeVerify: CylHi %02x CylLo %02x Head %x Sector %x\n", (UCHAR)((cylinder >> 8) & 0xFF), (UCHAR)(cylinder & 0xFF), From 98444b2f1a543b750897b029b193f7a4d822c5e7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 14 May 2026 20:00:44 +0000 Subject: [PATCH 58/86] Revert "Fix UDFGetBlockSize to use PartitionLength instead of DiskSize for LastLBA" This reverts commit a304bbc0d9061a9c48569d06589b97899431543f. Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/Include/phys_lib.c | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/drivers/filesystems/udfs/Include/phys_lib.c b/drivers/filesystems/udfs/Include/phys_lib.c index 866a9905752a6..373cb070b5eb4 100644 --- a/drivers/filesystems/udfs/Include/phys_lib.c +++ b/drivers/filesystems/udfs/Include/phys_lib.c @@ -851,23 +851,8 @@ UDFGetBlockSize( if (DiskGeometryEx.DiskSize.QuadPart < Vcb->SectorSize) { try_return(RC = STATUS_UNRECOGNIZED_VOLUME); } - // Use the partition length to bound LastLBA. DiskGeometryEx.DiskSize - // reflects the whole physical disk, which can be much larger than the - // actual partition (e.g. a sparse/dynamic 256 GB virtual disk image with - // a small UDF volume at the start). Using DiskSize causes UDFFindAnchor - // to probe blocks far beyond the written area, generating DEVICE_ERRORs - // in legacy CHS-only ATA drivers that cannot address such large LBAs. - { - ULONGLONG volSize = (PartitionInfo.PartitionLength.QuadPart > 0) - ? PartitionInfo.PartitionLength.QuadPart - : DiskGeometryEx.DiskSize.QuadPart; - UDFPrint(("UDFGetBlockSize: DiskSize=%I64x PartitionLength=%I64x => volSize=%I64x\n", - DiskGeometryEx.DiskSize.QuadPart, - PartitionInfo.PartitionLength.QuadPart, - volSize)); - Vcb->LastPossibleLBA = - Vcb->LastLBA = (uint32)(volSize >> Vcb->SectorShift) - 1; - } + Vcb->LastPossibleLBA = + Vcb->LastLBA = (uint32)(DiskGeometryEx.DiskSize.QuadPart >> Vcb->SectorShift)/* + Vcb->FirstLBA*/ - 1; } else { Vcb->FirstLBA=0; if (NT_SUCCESS(RC)) { From 5b8d79f56ac8b3fe440d0cdd1e80303b8040441a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 14 May 2026 20:00:44 +0000 Subject: [PATCH 59/86] Revert "Add verbose ATAPI diagnostic prints for CHS overflow and IDE_STATUS_ERROR" This reverts commit 17cea6bdd2ad1881bd16399d2d0a3425d25d0881. Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/storage/ide/atapi/atapi.c | 103 +++++++++++------------------- 1 file changed, 38 insertions(+), 65 deletions(-) diff --git a/drivers/storage/ide/atapi/atapi.c b/drivers/storage/ide/atapi/atapi.c index 0c591253f1aa3..19b8a0ee44793 100644 --- a/drivers/storage/ide/atapi/atapi.c +++ b/drivers/storage/ide/atapi/atapi.c @@ -3616,14 +3616,6 @@ Return Value: if (statusByte & IDE_STATUS_ERROR) { - UCHAR errorByte = ScsiPortReadPortUchar((PUCHAR)baseIoAddress1 + 1); - - DebugPrint((1, - "AtapiInterrupt: IDE_STATUS_ERROR - status %02x error %02x Cdb[0] %02x\n", - statusByte, - errorByte, - srb->Cdb[0])); - if (srb->Cdb[0] != SCSIOP_REQUEST_SENSE) { // @@ -4579,14 +4571,10 @@ Return Value: ((PCDB)Srb->Cdb)->CDB10.LogicalBlockByte1 << 16 | ((PCDB)Srb->Cdb)->CDB10.LogicalBlockByte0 << 24; - DebugPrint((1, - "IdeReadWrite: LBA %lx, Bytes %x, SPT %u, Heads %u, Cyls %u, Cap %04x\n", + DebugPrint((2, + "IdeReadWrite: Starting sector is %x, Number of bytes %x\n", startingSector, - Srb->DataTransferLength, - deviceExtension->IdentifyData[Srb->TargetId].SectorsPerTrack, - deviceExtension->IdentifyData[Srb->TargetId].NumberOfHeads, - deviceExtension->IdentifyData[Srb->TargetId].NumberOfCylinders, - deviceExtension->IdentifyData[Srb->TargetId].Capabilities)); + Srb->DataTransferLength)); // // Set up sector number register. @@ -4599,27 +4587,16 @@ Return Value: // Set up cylinder low register. // - { - ULONG cylinder = startingSector / (deviceExtension->IdentifyData[Srb->TargetId].SectorsPerTrack * - deviceExtension->IdentifyData[Srb->TargetId].NumberOfHeads); - - if (cylinder > 0xFFFF) { - DebugPrint((1, - "IdeReadWrite: WARNING - cylinder %lx overflows 16-bit CHS range (LBA %lx)\n", - cylinder, - startingSector)); - } - - cylinderLow = (UCHAR)(cylinder & 0xFF); - cylinderHigh = (UCHAR)((cylinder >> 8) & 0xFF); - } - + cylinderLow = (UCHAR)(startingSector / (deviceExtension->IdentifyData[Srb->TargetId].SectorsPerTrack * + deviceExtension->IdentifyData[Srb->TargetId].NumberOfHeads)); ScsiPortWritePortUchar(&baseIoAddress1->CylinderLow,cylinderLow); // // Set up cylinder high register. // + cylinderHigh = (UCHAR)((startingSector / (deviceExtension->IdentifyData[Srb->TargetId].SectorsPerTrack * + deviceExtension->IdentifyData[Srb->TargetId].NumberOfHeads)) >> 8); ScsiPortWritePortUchar(&baseIoAddress1->CylinderHigh,cylinderHigh); // @@ -4630,10 +4607,11 @@ Return Value: deviceExtension->IdentifyData[Srb->TargetId].NumberOfHeads) |((Srb->TargetId & 0x1) << 4) | 0xA0); ScsiPortWritePortUchar(&baseIoAddress1->DriveSelect,drvSelect); - DebugPrint((1, - "IdeReadWrite: CylHi %02x CylLo %02x Head %x Sector %x\n", - cylinderHigh, - cylinderLow, + DebugPrint((2, + "IdeReadWrite: Cylinder %x Head %x Sector %x\n", + startingSector / + (deviceExtension->IdentifyData[Srb->TargetId].SectorsPerTrack * + deviceExtension->IdentifyData[Srb->TargetId].NumberOfHeads), (startingSector / deviceExtension->IdentifyData[Srb->TargetId].SectorsPerTrack) % deviceExtension->IdentifyData[Srb->TargetId].NumberOfHeads, @@ -4814,14 +4792,10 @@ Return Value: ((PCDB)Srb->Cdb)->CDB10.LogicalBlockByte1 << 16 | ((PCDB)Srb->Cdb)->CDB10.LogicalBlockByte0 << 24; - DebugPrint((1, - "IdeVerify: LBA %lx, Blocks %x, SPT %u, Heads %u, Cyls %u, Cap %04x\n", + DebugPrint((3, + "IdeVerify: Starting sector %x. Number of blocks %x\n", startingSector, - ((PCDB)Srb->Cdb)->CDB10.TransferBlocksLsb, - deviceExtension->IdentifyData[Srb->TargetId].SectorsPerTrack, - deviceExtension->IdentifyData[Srb->TargetId].NumberOfHeads, - deviceExtension->IdentifyData[Srb->TargetId].NumberOfCylinders, - deviceExtension->IdentifyData[Srb->TargetId].Capabilities)); + ((PCDB)Srb->Cdb)->CDB10.TransferBlocksLsb)); sectorCount = (USHORT)(((PCDB)Srb->Cdb)->CDB10.TransferBlocksMsb << 8 | ((PCDB)Srb->Cdb)->CDB10.TransferBlocksLsb ); @@ -4879,34 +4853,22 @@ Return Value: deviceExtension->IdentifyData[Srb->TargetId].SectorsPerTrack) + 1)); // - // Set up cylinder low and high registers. + // Set up cylinder low register. // - { - ULONG cylinder = startingSector / - (deviceExtension->IdentifyData[Srb->TargetId].SectorsPerTrack * - deviceExtension->IdentifyData[Srb->TargetId].NumberOfHeads); - - if (cylinder > 0xFFFF) { - DebugPrint((1, - "IdeVerify: WARNING - cylinder %lx overflows 16-bit CHS range (LBA %lx)\n", - cylinder, - startingSector)); - } + ScsiPortWritePortUchar(&baseIoAddress1->CylinderLow, + (UCHAR)(startingSector / + (deviceExtension->IdentifyData[Srb->TargetId].SectorsPerTrack * + deviceExtension->IdentifyData[Srb->TargetId].NumberOfHeads))); - ScsiPortWritePortUchar(&baseIoAddress1->CylinderLow, (UCHAR)(cylinder & 0xFF)); - ScsiPortWritePortUchar(&baseIoAddress1->CylinderHigh, (UCHAR)((cylinder >> 8) & 0xFF)); + // + // Set up cylinder high register. + // - DebugPrint((1, - "IdeVerify: CylHi %02x CylLo %02x Head %x Sector %x\n", - (UCHAR)((cylinder >> 8) & 0xFF), - (UCHAR)(cylinder & 0xFF), - (startingSector / - deviceExtension->IdentifyData[Srb->TargetId].SectorsPerTrack) % - deviceExtension->IdentifyData[Srb->TargetId].NumberOfHeads, - startingSector % - deviceExtension->IdentifyData[Srb->TargetId].SectorsPerTrack + 1)); - } + ScsiPortWritePortUchar(&baseIoAddress1->CylinderHigh, + (UCHAR)((startingSector / + (deviceExtension->IdentifyData[Srb->TargetId].SectorsPerTrack * + deviceExtension->IdentifyData[Srb->TargetId].NumberOfHeads)) >> 8)); // // Set up head and drive select register. @@ -4918,6 +4880,17 @@ Return Value: deviceExtension->IdentifyData[Srb->TargetId].NumberOfHeads) | ((Srb->TargetId & 0x1) << 4) | 0xA0)); + DebugPrint((2, + "IdeVerify: Cylinder %x Head %x Sector %x\n", + startingSector / + (deviceExtension->IdentifyData[Srb->TargetId].SectorsPerTrack * + deviceExtension->IdentifyData[Srb->TargetId].NumberOfHeads), + (startingSector / + deviceExtension->IdentifyData[Srb->TargetId].SectorsPerTrack) % + deviceExtension->IdentifyData[Srb->TargetId].NumberOfHeads, + startingSector % + deviceExtension->IdentifyData[Srb->TargetId].SectorsPerTrack + 1)); + // // Send verify command. From 43aa3d8e9c916aaceb3bf52dd1c4619139bce559 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 14 May 2026 20:00:44 +0000 Subject: [PATCH 60/86] Revert "Align verbose diagnostic naming and IOCTL format specifiers" This reverts commit 13cdcce6569868b545e2039f88007ab542d523cb. Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/devcntrl.c | 12 ++++++------ drivers/filesystems/udfs/env_spec.c | 24 ++++++++++++------------ 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/filesystems/udfs/devcntrl.c b/drivers/filesystems/udfs/devcntrl.c index 3bfff06e9b2bb..5e871b2928fd3 100644 --- a/drivers/filesystems/udfs/devcntrl.c +++ b/drivers/filesystems/udfs/devcntrl.c @@ -33,7 +33,7 @@ NTAPI UDFDevCtrlCompletionRoutine ( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, - IN PVOID Context + IN PVOID Contxt ); NTSTATUS @@ -128,7 +128,7 @@ UDFCommonDevControl(PIRP_CONTEXT IrpContext, PIRP Irp) ASSERT_VCB(Vcb); IoControlCode = IrpSp->Parameters.DeviceIoControl.IoControlCode; - UDFPrint(("UDFCommonDevControl: Ioctl=%8.8x InLen=%lu OutLen=%lu TypeOfOpen=%lu\n", + UDFPrint(("UDFCommonDevControl: Ioctl=%8.8lx InLen=%lu OutLen=%lu TypeOfOpen=%lu\n", IoControlCode, IrpSp->Parameters.DeviceIoControl.InputBufferLength, IrpSp->Parameters.DeviceIoControl.OutputBufferLength, @@ -363,10 +363,10 @@ UDFCommonDevControl(PIRP_CONTEXT IrpContext, PIRP Irp) DeviceAcquired = TRUE; } - UDFPrint(("UDFCommonDevControl: forwarding Ioctl=%8.8x to Target=%p\n", + UDFPrint(("UDFCommonDevControl: forwarding Ioctl=%8.8lx to Target=%p\n", IoControlCode, Vcb->TargetDeviceObject)); Status = IoCallDriver(Vcb->TargetDeviceObject, Irp); - UDFPrint(("UDFCommonDevControl: IoCallDriver returned %8.8lx for Ioctl=%8.8x\n", + UDFPrint(("UDFCommonDevControl: IoCallDriver returned %8.8lx for Ioctl=%8.8lx\n", Status, IoControlCode)); if (DeviceAcquired) @@ -381,12 +381,12 @@ NTAPI UDFDevCtrlCompletionRoutine ( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, - IN PVOID Context + IN PVOID Contxt ) { UNREFERENCED_PARAMETER(DeviceObject); - UNREFERENCED_PARAMETER(Context); + UNREFERENCED_PARAMETER(Contxt); if (!Irp) { UDFPrint(("UDFDevCtrlCompletionRoutine: Irp=NULL\n")); diff --git a/drivers/filesystems/udfs/env_spec.c b/drivers/filesystems/udfs/env_spec.c index 78141173d853c..9fa5b6ee1c10c 100644 --- a/drivers/filesystems/udfs/env_spec.c +++ b/drivers/filesystems/udfs/env_spec.c @@ -37,25 +37,25 @@ NTAPI UDFAsyncCompletionRoutine( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, - IN PVOID Context + IN PVOID Contxt ) { if (!Irp) { - UDFPrint(("UDFAsyncCompletionRoutine: ctx=%p Irp=NULL\n", Context)); + UDFPrint(("UDFAsyncCompletionRoutine: ctx=%p Irp=NULL\n", Contxt)); ASSERT(FALSE); return STATUS_SUCCESS; } UDFPrint(("UDFAsyncCompletionRoutine: ctx=%p Irp=%p Status=%8.8x IosbInfo=%lx IrpFlags=%8.8x\n", - Context, + Contxt, Irp, Irp->IoStatus.Status, (ULONG)Irp->IoStatus.Information, Irp->Flags)); - PUDF_PH_CALL_CONTEXT CallContext = (PUDF_PH_CALL_CONTEXT)Context; + PUDF_PH_CALL_CONTEXT Context = (PUDF_PH_CALL_CONTEXT)Contxt; PMDL Mdl, NextMdl; - CallContext->IosbToUse = Irp->IoStatus; + Context->IosbToUse = Irp->IoStatus; #if 1 // Unlock pages that are described by MDL (if any). // MDLs built with MmBuildMdlForNonPagedPool have MDL_SOURCE_IS_NONPAGED_POOL @@ -81,11 +81,11 @@ UDFAsyncCompletionRoutine( Irp->MdlAddress = NULL; IoFreeIrp(Irp); - KeSetEvent( &(CallContext->event), 0, FALSE ); + KeSetEvent( &(Context->event), 0, FALSE ); return STATUS_MORE_PROCESSING_REQUIRED; #else - KeSetEvent( &(CallContext->event), 0, FALSE ); + KeSetEvent( &(Context->event), 0, FALSE ); return STATUS_SUCCESS; #endif @@ -96,24 +96,24 @@ NTAPI UDFSyncCompletionRoutine( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, - IN PVOID Context + IN PVOID Contxt ) { if (!Irp) { - UDFPrint(("UDFSyncCompletionRoutine: ctx=%p Irp=NULL\n", Context)); + UDFPrint(("UDFSyncCompletionRoutine: ctx=%p Irp=NULL\n", Contxt)); ASSERT(FALSE); return STATUS_SUCCESS; } UDFPrint(("UDFSyncCompletionRoutine: ctx=%p Irp=%p Status=%8.8x IosbInfo=%lx IrpFlags=%8.8x\n", - Context, + Contxt, Irp, Irp->IoStatus.Status, (ULONG)Irp->IoStatus.Information, Irp->Flags)); - PUDF_PH_CALL_CONTEXT CallContext = (PUDF_PH_CALL_CONTEXT)Context; + PUDF_PH_CALL_CONTEXT Context = (PUDF_PH_CALL_CONTEXT)Contxt; - CallContext->IosbToUse = Irp->IoStatus; + Context->IosbToUse = Irp->IoStatus; //KeSetEvent( &(Context->event), 0, FALSE ); return STATUS_SUCCESS; From c31d79f3c37dd205cc7cff7aacfa7718c869707b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 14 May 2026 20:00:45 +0000 Subject: [PATCH 61/86] Revert "Use completion-safe return values in NULL-IRP guards" This reverts commit 3d2741c2a124b7a48a2659a13a60bc79d34124d8. Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/devcntrl.c | 2 +- drivers/filesystems/udfs/env_spec.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/filesystems/udfs/devcntrl.c b/drivers/filesystems/udfs/devcntrl.c index 5e871b2928fd3..b185a3025e14a 100644 --- a/drivers/filesystems/udfs/devcntrl.c +++ b/drivers/filesystems/udfs/devcntrl.c @@ -391,7 +391,7 @@ UDFDevCtrlCompletionRoutine ( if (!Irp) { UDFPrint(("UDFDevCtrlCompletionRoutine: Irp=NULL\n")); ASSERT(FALSE); - return STATUS_SUCCESS; + return STATUS_INVALID_PARAMETER; } UDFPrint(("UDFDevCtrlCompletionRoutine: Irp=%p Pending=%u Status=%8.8x Info=%lx\n", diff --git a/drivers/filesystems/udfs/env_spec.c b/drivers/filesystems/udfs/env_spec.c index 9fa5b6ee1c10c..f52322c458d3a 100644 --- a/drivers/filesystems/udfs/env_spec.c +++ b/drivers/filesystems/udfs/env_spec.c @@ -43,7 +43,7 @@ UDFAsyncCompletionRoutine( if (!Irp) { UDFPrint(("UDFAsyncCompletionRoutine: ctx=%p Irp=NULL\n", Contxt)); ASSERT(FALSE); - return STATUS_SUCCESS; + return STATUS_INVALID_PARAMETER; } UDFPrint(("UDFAsyncCompletionRoutine: ctx=%p Irp=%p Status=%8.8x IosbInfo=%lx IrpFlags=%8.8x\n", @@ -102,7 +102,7 @@ UDFSyncCompletionRoutine( if (!Irp) { UDFPrint(("UDFSyncCompletionRoutine: ctx=%p Irp=NULL\n", Contxt)); ASSERT(FALSE); - return STATUS_SUCCESS; + return STATUS_INVALID_PARAMETER; } UDFPrint(("UDFSyncCompletionRoutine: ctx=%p Irp=%p Status=%8.8x IosbInfo=%lx IrpFlags=%8.8x\n", From 9c21520388a8974c48a8fbe8656f97ca073f46ab Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 14 May 2026 20:00:45 +0000 Subject: [PATCH 62/86] Revert "Fail fast on unexpected NULL IRP in debug completions" This reverts commit aab970d9ab9c4a862fef88d8be6fc334f6a78f89. Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/devcntrl.c | 3 +-- drivers/filesystems/udfs/env_spec.c | 6 ++---- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/filesystems/udfs/devcntrl.c b/drivers/filesystems/udfs/devcntrl.c index b185a3025e14a..665ca64f2231f 100644 --- a/drivers/filesystems/udfs/devcntrl.c +++ b/drivers/filesystems/udfs/devcntrl.c @@ -390,8 +390,7 @@ UDFDevCtrlCompletionRoutine ( if (!Irp) { UDFPrint(("UDFDevCtrlCompletionRoutine: Irp=NULL\n")); - ASSERT(FALSE); - return STATUS_INVALID_PARAMETER; + return STATUS_SUCCESS; } UDFPrint(("UDFDevCtrlCompletionRoutine: Irp=%p Pending=%u Status=%8.8x Info=%lx\n", diff --git a/drivers/filesystems/udfs/env_spec.c b/drivers/filesystems/udfs/env_spec.c index f52322c458d3a..b467dff15e476 100644 --- a/drivers/filesystems/udfs/env_spec.c +++ b/drivers/filesystems/udfs/env_spec.c @@ -42,8 +42,7 @@ UDFAsyncCompletionRoutine( { if (!Irp) { UDFPrint(("UDFAsyncCompletionRoutine: ctx=%p Irp=NULL\n", Contxt)); - ASSERT(FALSE); - return STATUS_INVALID_PARAMETER; + return STATUS_SUCCESS; } UDFPrint(("UDFAsyncCompletionRoutine: ctx=%p Irp=%p Status=%8.8x IosbInfo=%lx IrpFlags=%8.8x\n", @@ -101,8 +100,7 @@ UDFSyncCompletionRoutine( { if (!Irp) { UDFPrint(("UDFSyncCompletionRoutine: ctx=%p Irp=NULL\n", Contxt)); - ASSERT(FALSE); - return STATUS_INVALID_PARAMETER; + return STATUS_SUCCESS; } UDFPrint(("UDFSyncCompletionRoutine: ctx=%p Irp=%p Status=%8.8x IosbInfo=%lx IrpFlags=%8.8x\n", From afcf6a2b221ff893da1a01de72e54d6cee297baf Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 14 May 2026 20:00:45 +0000 Subject: [PATCH 63/86] Revert "Add NULL guards in verbose completion logging" This reverts commit 23008e440a38900d785c19353305e3c1fae0d1f0. Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/devcntrl.c | 6 ------ drivers/filesystems/udfs/env_spec.c | 2 +- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/filesystems/udfs/devcntrl.c b/drivers/filesystems/udfs/devcntrl.c index 665ca64f2231f..e372f998e7793 100644 --- a/drivers/filesystems/udfs/devcntrl.c +++ b/drivers/filesystems/udfs/devcntrl.c @@ -387,12 +387,6 @@ UDFDevCtrlCompletionRoutine ( { UNREFERENCED_PARAMETER(DeviceObject); UNREFERENCED_PARAMETER(Contxt); - - if (!Irp) { - UDFPrint(("UDFDevCtrlCompletionRoutine: Irp=NULL\n")); - return STATUS_SUCCESS; - } - UDFPrint(("UDFDevCtrlCompletionRoutine: Irp=%p Pending=%u Status=%8.8x Info=%lx\n", Irp, Irp->PendingReturned, diff --git a/drivers/filesystems/udfs/env_spec.c b/drivers/filesystems/udfs/env_spec.c index b467dff15e476..73c1b17b33648 100644 --- a/drivers/filesystems/udfs/env_spec.c +++ b/drivers/filesystems/udfs/env_spec.c @@ -42,7 +42,7 @@ UDFAsyncCompletionRoutine( { if (!Irp) { UDFPrint(("UDFAsyncCompletionRoutine: ctx=%p Irp=NULL\n", Contxt)); - return STATUS_SUCCESS; + return STATUS_MORE_PROCESSING_REQUIRED; } UDFPrint(("UDFAsyncCompletionRoutine: ctx=%p Irp=%p Status=%8.8x IosbInfo=%lx IrpFlags=%8.8x\n", From 40d8ce0bdae6f0dd829128e863d5e049a96f618b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 14 May 2026 20:00:45 +0000 Subject: [PATCH 64/86] Revert "Harden completion diagnostics against invalid stack access" This reverts commit 49b920fe002c09654289372f7efadefa50b4b098. Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/devcntrl.c | 11 ++++++++++- drivers/filesystems/udfs/env_spec.c | 17 +---------------- 2 files changed, 11 insertions(+), 17 deletions(-) diff --git a/drivers/filesystems/udfs/devcntrl.c b/drivers/filesystems/udfs/devcntrl.c index e372f998e7793..12cbfeea2fae9 100644 --- a/drivers/filesystems/udfs/devcntrl.c +++ b/drivers/filesystems/udfs/devcntrl.c @@ -387,8 +387,17 @@ UDFDevCtrlCompletionRoutine ( { UNREFERENCED_PARAMETER(DeviceObject); UNREFERENCED_PARAMETER(Contxt); - UDFPrint(("UDFDevCtrlCompletionRoutine: Irp=%p Pending=%u Status=%8.8x Info=%lx\n", + PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); + ULONG IoctlCode = 0; + + if (IrpSp->MajorFunction == IRP_MJ_DEVICE_CONTROL || + IrpSp->MajorFunction == IRP_MJ_INTERNAL_DEVICE_CONTROL) { + IoctlCode = IrpSp->Parameters.DeviceIoControl.IoControlCode; + } + UDFPrint(("UDFDevCtrlCompletionRoutine: Irp=%p Major=%u Ioctl=%8.8lx Pending=%u Status=%8.8x Info=%lx\n", Irp, + IrpSp->MajorFunction, + IoctlCode, Irp->PendingReturned, Irp->IoStatus.Status, (ULONG)Irp->IoStatus.Information)); diff --git a/drivers/filesystems/udfs/env_spec.c b/drivers/filesystems/udfs/env_spec.c index 73c1b17b33648..7c52f9e071e61 100644 --- a/drivers/filesystems/udfs/env_spec.c +++ b/drivers/filesystems/udfs/env_spec.c @@ -40,11 +40,6 @@ UDFAsyncCompletionRoutine( IN PVOID Contxt ) { - if (!Irp) { - UDFPrint(("UDFAsyncCompletionRoutine: ctx=%p Irp=NULL\n", Contxt)); - return STATUS_MORE_PROCESSING_REQUIRED; - } - UDFPrint(("UDFAsyncCompletionRoutine: ctx=%p Irp=%p Status=%8.8x IosbInfo=%lx IrpFlags=%8.8x\n", Contxt, Irp, @@ -98,17 +93,7 @@ UDFSyncCompletionRoutine( IN PVOID Contxt ) { - if (!Irp) { - UDFPrint(("UDFSyncCompletionRoutine: ctx=%p Irp=NULL\n", Contxt)); - return STATUS_SUCCESS; - } - - UDFPrint(("UDFSyncCompletionRoutine: ctx=%p Irp=%p Status=%8.8x IosbInfo=%lx IrpFlags=%8.8x\n", - Contxt, - Irp, - Irp->IoStatus.Status, - (ULONG)Irp->IoStatus.Information, - Irp->Flags)); + UDFPrint(("UDFSyncCompletionRoutine ctx=%p\n", Contxt)); PUDF_PH_CALL_CONTEXT Context = (PUDF_PH_CALL_CONTEXT)Contxt; Context->IosbToUse = Irp->IoStatus; From e084b30c203ee558359b923bddb53a3ff3a859b0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 14 May 2026 20:00:46 +0000 Subject: [PATCH 65/86] Revert "Address review nits in verbose UDFS diagnostics" This reverts commit efaea6781f3f4a6b55aa38788ea024f83c1e6037. Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/devcntrl.c | 4 ++-- drivers/filesystems/udfs/env_spec.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/filesystems/udfs/devcntrl.c b/drivers/filesystems/udfs/devcntrl.c index 12cbfeea2fae9..6b2337c8b2b0b 100644 --- a/drivers/filesystems/udfs/devcntrl.c +++ b/drivers/filesystems/udfs/devcntrl.c @@ -385,10 +385,10 @@ UDFDevCtrlCompletionRoutine ( ) { - UNREFERENCED_PARAMETER(DeviceObject); - UNREFERENCED_PARAMETER(Contxt); PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); ULONG IoctlCode = 0; + UNREFERENCED_PARAMETER(DeviceObject); + UNREFERENCED_PARAMETER(Contxt); if (IrpSp->MajorFunction == IRP_MJ_DEVICE_CONTROL || IrpSp->MajorFunction == IRP_MJ_INTERNAL_DEVICE_CONTROL) { diff --git a/drivers/filesystems/udfs/env_spec.c b/drivers/filesystems/udfs/env_spec.c index 7c52f9e071e61..ae1bd3049b2c4 100644 --- a/drivers/filesystems/udfs/env_spec.c +++ b/drivers/filesystems/udfs/env_spec.c @@ -40,7 +40,7 @@ UDFAsyncCompletionRoutine( IN PVOID Contxt ) { - UDFPrint(("UDFAsyncCompletionRoutine: ctx=%p Irp=%p Status=%8.8x IosbInfo=%lx IrpFlags=%8.8x\n", + UDFPrint(("UDFAsyncCompletionRoutine: ctx=%p Irp=%p Status=%8.8x Info=%lx IrpFlags=%8.8x\n", Contxt, Irp, Irp->IoStatus.Status, From 3c481e84141156bdbd056564f7a35a8461be3d87 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 14 May 2026 20:00:46 +0000 Subject: [PATCH 66/86] Revert "Use pointer-safe format specifiers in new UDFS traces" This reverts commit 89d8617234e8af9a769f384ba5cd7c1b706f4709. Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/devcntrl.c | 4 ++-- drivers/filesystems/udfs/env_spec.c | 18 +++++++++--------- drivers/filesystems/udfs/fscntrl.c | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/filesystems/udfs/devcntrl.c b/drivers/filesystems/udfs/devcntrl.c index 6b2337c8b2b0b..8cc7659b87747 100644 --- a/drivers/filesystems/udfs/devcntrl.c +++ b/drivers/filesystems/udfs/devcntrl.c @@ -363,7 +363,7 @@ UDFCommonDevControl(PIRP_CONTEXT IrpContext, PIRP Irp) DeviceAcquired = TRUE; } - UDFPrint(("UDFCommonDevControl: forwarding Ioctl=%8.8lx to Target=%p\n", + UDFPrint(("UDFCommonDevControl: forwarding Ioctl=%8.8lx to Target=%x\n", IoControlCode, Vcb->TargetDeviceObject)); Status = IoCallDriver(Vcb->TargetDeviceObject, Irp); UDFPrint(("UDFCommonDevControl: IoCallDriver returned %8.8lx for Ioctl=%8.8lx\n", @@ -394,7 +394,7 @@ UDFDevCtrlCompletionRoutine ( IrpSp->MajorFunction == IRP_MJ_INTERNAL_DEVICE_CONTROL) { IoctlCode = IrpSp->Parameters.DeviceIoControl.IoControlCode; } - UDFPrint(("UDFDevCtrlCompletionRoutine: Irp=%p Major=%u Ioctl=%8.8lx Pending=%u Status=%8.8x Info=%lx\n", + UDFPrint(("UDFDevCtrlCompletionRoutine: Irp=%x Major=%x Ioctl=%8.8lx Pending=%u Status=%8.8x Info=%lx\n", Irp, IrpSp->MajorFunction, IoctlCode, diff --git a/drivers/filesystems/udfs/env_spec.c b/drivers/filesystems/udfs/env_spec.c index ae1bd3049b2c4..0c63ca3d3529d 100644 --- a/drivers/filesystems/udfs/env_spec.c +++ b/drivers/filesystems/udfs/env_spec.c @@ -40,7 +40,7 @@ UDFAsyncCompletionRoutine( IN PVOID Contxt ) { - UDFPrint(("UDFAsyncCompletionRoutine: ctx=%p Irp=%p Status=%8.8x Info=%lx IrpFlags=%8.8x\n", + UDFPrint(("UDFAsyncCompletionRoutine: ctx=%x Irp=%x Status=%8.8x Info=%lx IrpFlags=%8.8x\n", Contxt, Irp, Irp->IoStatus.Status, @@ -93,7 +93,7 @@ UDFSyncCompletionRoutine( IN PVOID Contxt ) { - UDFPrint(("UDFSyncCompletionRoutine ctx=%p\n", Contxt)); + UDFPrint(("UDFSyncCompletionRoutine ctx=%x\n", Contxt)); PUDF_PH_CALL_CONTEXT Context = (PUDF_PH_CALL_CONTEXT)Contxt; Context->IosbToUse = Irp->IoStatus; @@ -147,7 +147,7 @@ UDFPhReadSynchronous( NTSTATUS RC = STATUS_SUCCESS; LARGE_INTEGER ROffset; - UDFPrint(("UDFPhReadSynchronous: DevObj=%p Buffer=%p ByteCount=%lu Offset=%I64x Flags=%8.8x\n", + UDFPrint(("UDFPhReadSynchronous: DevObj=%x Buffer=%x ByteCount=%lu Offset=%I64x Flags=%8.8x\n", DeviceObject, Buffer, ByteCount, Offset, Flags)); (*ReadBytes) = 0; @@ -225,7 +225,7 @@ UDFPhReadSynchronous( } SetFlag(IrpSp->Flags, SL_OVERRIDE_VERIFY_VOLUME); - UDFPrint(("UDFPhReadSynchronous(chunk): Irp=%p Offset=%I64x Length=%lu IrpFlags=%8.8x SpFlags=%8.8x\n", + UDFPrint(("UDFPhReadSynchronous(chunk): Irp=%x Offset=%I64x Length=%lu IrpFlags=%8.8x SpFlags=%8.8x\n", ChunkIrp, ROffset.QuadPart, ChunkSize, ChunkIrp->Flags, IrpSp->Flags)); RC = IoCallDriver(DeviceObject, ChunkIrp); // ChunkIrp and ChunkMdl are freed by UDFAsyncCompletionRoutine. @@ -334,7 +334,7 @@ UDFPhReadSynchronous( SetFlag(IrpSp->Flags, SL_OVERRIDE_VERIFY_VOLUME); - UDFPrint(("UDFPhReadSynchronous(single): Irp=%p Offset=%I64x Length=%lu IrpFlags=%8.8x SpFlags=%8.8x\n", + UDFPrint(("UDFPhReadSynchronous(single): Irp=%x Offset=%I64x Length=%lu IrpFlags=%8.8x SpFlags=%8.8x\n", Irp, ROffset.QuadPart, ByteCount, Irp->Flags, IrpSp->Flags)); RC = IoCallDriver(DeviceObject, Irp); @@ -385,7 +385,7 @@ UDFPhWriteSynchronous( NTSTATUS RC = STATUS_SUCCESS; LARGE_INTEGER ROffset; - UDFPrint(("UDFPhWriteSynchronous: DevObj=%p Buffer=%p ByteCount=%lu Offset=%I64x Flags=%8.8x\n", + UDFPrint(("UDFPhWriteSynchronous: DevObj=%x Buffer=%x ByteCount=%lu Offset=%I64x Flags=%8.8x\n", DeviceObject, Buffer, ByteCount, Offset, Flags)); #ifdef DBG @@ -475,7 +475,7 @@ UDFPhWriteSynchronous( IrpSp->Parameters.Write.ByteOffset = ROffset; SetFlag(IrpSp->Flags, SL_OVERRIDE_VERIFY_VOLUME); - UDFPrint(("UDFPhWriteSynchronous(chunk): Irp=%p Offset=%I64x Length=%lu IrpFlags=%8.8x SpFlags=%8.8x\n", + UDFPrint(("UDFPhWriteSynchronous(chunk): Irp=%x Offset=%I64x Length=%lu IrpFlags=%8.8x SpFlags=%8.8x\n", ChunkIrp, ROffset.QuadPart, ChunkSize, ChunkIrp->Flags, IrpSp->Flags)); RC = IoCallDriver(DeviceObject, ChunkIrp); // ChunkIrp and ChunkMdl are freed by UDFAsyncCompletionRoutine. @@ -569,7 +569,7 @@ UDFPhWriteSynchronous( IrpSp->Parameters.Write.Length = ByteCount; IrpSp->Parameters.Write.ByteOffset = ROffset; SetFlag(IrpSp->Flags, SL_OVERRIDE_VERIFY_VOLUME); - UDFPrint(("UDFPhWriteSynchronous(single): Irp=%p Offset=%I64x Length=%lu IrpFlags=%8.8x SpFlags=%8.8x\n", + UDFPrint(("UDFPhWriteSynchronous(single): Irp=%x Offset=%I64x Length=%lu IrpFlags=%8.8x SpFlags=%8.8x\n", Irp, ROffset.QuadPart, ByteCount, Irp->Flags, IrpSp->Flags)); RC = IoCallDriver(DeviceObject, Irp); @@ -662,7 +662,7 @@ UDFPhSendIOCTL( PUDF_PH_CALL_CONTEXT Context; LARGE_INTEGER timeout; - UDFPrint(("UDFPhDevIOCTL: Code=%8x DevObj=%p InLen=%lu OutLen=%lu OverrideVerify=%u\n", + UDFPrint(("UDFPhDevIOCTL: Code=%8x DevObj=%x InLen=%lu OutLen=%lu OverrideVerify=%u\n", IoControlCode, DeviceObject, InputBufferLength, OutputBufferLength, OverrideVerify)); Context = (PUDF_PH_CALL_CONTEXT)MyAllocatePool__( NonPagedPool, sizeof(UDF_PH_CALL_CONTEXT) ); diff --git a/drivers/filesystems/udfs/fscntrl.c b/drivers/filesystems/udfs/fscntrl.c index fe8ea52537a07..2eb1fd54ca2ff 100644 --- a/drivers/filesystems/udfs/fscntrl.c +++ b/drivers/filesystems/udfs/fscntrl.c @@ -296,7 +296,7 @@ UDFMountVolume( ASSERT(IrpSp); UDFPrint(("\n !!! UDFMountVolume\n")); - UDFPrint(("UDFMountVolume: DeviceObject=%p RealDevice=%p DeviceType=%x RealType=%x\n", + UDFPrint(("UDFMountVolume: DeviceObject=%x RealDevice=%x DeviceType=%x RealType=%x\n", DeviceObjectWeTalkTo, Vpb->RealDevice, DeviceObjectWeTalkTo->DeviceType, From ad31fa085e63f089afec7e2c7f3c739f90a1bef3 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 14 May 2026 20:00:46 +0000 Subject: [PATCH 67/86] Revert "Move unreferenced parameter markers in completion routine" This reverts commit 31d9e9e6bd2cf3902904473b060c64de9c74d088. Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/devcntrl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/filesystems/udfs/devcntrl.c b/drivers/filesystems/udfs/devcntrl.c index 8cc7659b87747..61679b4b1e391 100644 --- a/drivers/filesystems/udfs/devcntrl.c +++ b/drivers/filesystems/udfs/devcntrl.c @@ -387,8 +387,6 @@ UDFDevCtrlCompletionRoutine ( { PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); ULONG IoctlCode = 0; - UNREFERENCED_PARAMETER(DeviceObject); - UNREFERENCED_PARAMETER(Contxt); if (IrpSp->MajorFunction == IRP_MJ_DEVICE_CONTROL || IrpSp->MajorFunction == IRP_MJ_INTERNAL_DEVICE_CONTROL) { @@ -409,5 +407,7 @@ UDFDevCtrlCompletionRoutine ( IoMarkIrpPending(Irp); } + UNREFERENCED_PARAMETER(DeviceObject); + UNREFERENCED_PARAMETER(Contxt); return STATUS_SUCCESS; } From 09f7b3a1a4399ab6c56bdf5e0d331d1e16321c20 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 14 May 2026 20:00:47 +0000 Subject: [PATCH 68/86] Revert "Normalize UDFS debug print format specifiers" This reverts commit a26160694a95fac0b2e20234b84af394f2c303a6. Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/devcntrl.c | 4 ++-- drivers/filesystems/udfs/env_spec.c | 28 ++++++++++++++-------------- drivers/filesystems/udfs/fscntrl.c | 4 ++-- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/filesystems/udfs/devcntrl.c b/drivers/filesystems/udfs/devcntrl.c index 61679b4b1e391..b238ecc6f16d7 100644 --- a/drivers/filesystems/udfs/devcntrl.c +++ b/drivers/filesystems/udfs/devcntrl.c @@ -392,13 +392,13 @@ UDFDevCtrlCompletionRoutine ( IrpSp->MajorFunction == IRP_MJ_INTERNAL_DEVICE_CONTROL) { IoctlCode = IrpSp->Parameters.DeviceIoControl.IoControlCode; } - UDFPrint(("UDFDevCtrlCompletionRoutine: Irp=%x Major=%x Ioctl=%8.8lx Pending=%u Status=%8.8x Info=%lx\n", + UDFPrint(("UDFDevCtrlCompletionRoutine: Irp=%x Major=%x Ioctl=%8.8lx Pending=%u Status=%8.8x Info=%Iu\n", Irp, IrpSp->MajorFunction, IoctlCode, Irp->PendingReturned, Irp->IoStatus.Status, - (ULONG)Irp->IoStatus.Information)); + Irp->IoStatus.Information)); // Add the hack-o-ramma to fix formats. diff --git a/drivers/filesystems/udfs/env_spec.c b/drivers/filesystems/udfs/env_spec.c index 0c63ca3d3529d..d7460df69ed15 100644 --- a/drivers/filesystems/udfs/env_spec.c +++ b/drivers/filesystems/udfs/env_spec.c @@ -40,11 +40,11 @@ UDFAsyncCompletionRoutine( IN PVOID Contxt ) { - UDFPrint(("UDFAsyncCompletionRoutine: ctx=%x Irp=%x Status=%8.8x Info=%lx IrpFlags=%8.8x\n", + UDFPrint(("UDFAsyncCompletionRoutine: ctx=%x Irp=%x Status=%8.8x Info=%Iu IrpFlags=%8.8x\n", Contxt, Irp, Irp->IoStatus.Status, - (ULONG)Irp->IoStatus.Information, + Irp->IoStatus.Information, Irp->Flags)); PUDF_PH_CALL_CONTEXT Context = (PUDF_PH_CALL_CONTEXT)Contxt; PMDL Mdl, NextMdl; @@ -235,8 +235,8 @@ UDFPhReadSynchronous( RC = ChunkCtx->IosbToUse.Status; if (RC == STATUS_DATA_OVERRUN) RC = STATUS_SUCCESS; } - UDFPrint(("UDFPhReadSynchronous(chunk): completion Status=%8.8x IosbStatus=%8.8x Info=%lx\n", - RC, ChunkCtx->IosbToUse.Status, (ULONG)ChunkCtx->IosbToUse.Information)); + UDFPrint(("UDFPhReadSynchronous(chunk): completion Status=%8.8x IosbStatus=%8.8x Info=%Iu\n", + RC, ChunkCtx->IosbToUse.Status, ChunkCtx->IosbToUse.Information)); if (NT_SUCCESS(RC)) { ULONG ChunkRead = (ULONG)ChunkCtx->IosbToUse.Information; @@ -344,8 +344,8 @@ UDFPhReadSynchronous( RC = STATUS_SUCCESS; } } - UDFPrint(("UDFPhReadSynchronous(single): completion Status=%8.8x IosbStatus=%8.8x Info=%lx\n", - RC, Context->IosbToUse.Status, (ULONG)Context->IosbToUse.Information)); + UDFPrint(("UDFPhReadSynchronous(single): completion Status=%8.8x IosbStatus=%8.8x Info=%Iu\n", + RC, Context->IosbToUse.Status, Context->IosbToUse.Information)); if (NT_SUCCESS(RC)) { (*ReadBytes) = Context->IosbToUse.Information; } @@ -485,8 +485,8 @@ UDFPhWriteSynchronous( RC = ChunkCtx->IosbToUse.Status; if (RC == STATUS_DATA_OVERRUN) RC = STATUS_SUCCESS; } - UDFPrint(("UDFPhWriteSynchronous(chunk): completion Status=%8.8x IosbStatus=%8.8x Info=%lx\n", - RC, ChunkCtx->IosbToUse.Status, (ULONG)ChunkCtx->IosbToUse.Information)); + UDFPrint(("UDFPhWriteSynchronous(chunk): completion Status=%8.8x IosbStatus=%8.8x Info=%Iu\n", + RC, ChunkCtx->IosbToUse.Status, ChunkCtx->IosbToUse.Information)); if (NT_SUCCESS(RC)) { ULONG ChunkWritten = (ULONG)ChunkCtx->IosbToUse.Information; @@ -579,8 +579,8 @@ UDFPhWriteSynchronous( RC = STATUS_SUCCESS; } } - UDFPrint(("UDFPhWriteSynchronous(single): completion Status=%8.8x IosbStatus=%8.8x Info=%lx\n", - RC, Context->IosbToUse.Status, (ULONG)Context->IosbToUse.Information)); + UDFPrint(("UDFPhWriteSynchronous(single): completion Status=%8.8x IosbStatus=%8.8x Info=%Iu\n", + RC, Context->IosbToUse.Status, Context->IosbToUse.Information)); if (NT_SUCCESS(RC)) { (*WrittenBytes) = Context->IosbToUse.Information; } @@ -711,14 +711,14 @@ UDFPhSendIOCTL( if ((RC = Context->IosbToUse.Status) == STATUS_DATA_OVERRUN) { RC = STATUS_SUCCESS; } - UDFPrint(("Exit wait state on evt %x, status %8.8x, iosb=%8.8x info=%lx\n", - Context, RC, Context->IosbToUse.Status, (ULONG)Context->IosbToUse.Information)); + UDFPrint(("Exit wait state on evt %x, status %8.8x, iosb=%8.8x info=%Iu\n", + Context, RC, Context->IosbToUse.Status, Context->IosbToUse.Information)); /* if (Iosb) { (*Iosb) = Context->IosbToUse; }*/ } else { - UDFPrint(("No wait completion on evt %x, iosb=%8.8x info=%lx\n", - Context, Context->IosbToUse.Status, (ULONG)Context->IosbToUse.Information)); + UDFPrint(("No wait completion on evt %x, iosb=%8.8x info=%Iu\n", + Context, Context->IosbToUse.Status, Context->IosbToUse.Information)); /* if (Iosb) { (*Iosb) = irp->IoStatus; }*/ diff --git a/drivers/filesystems/udfs/fscntrl.c b/drivers/filesystems/udfs/fscntrl.c index 2eb1fd54ca2ff..cdfdc5223671d 100644 --- a/drivers/filesystems/udfs/fscntrl.c +++ b/drivers/filesystems/udfs/fscntrl.c @@ -337,8 +337,8 @@ UDFMountVolume( &MediaChangeCount, sizeof(ULONG), TRUE, &Iosb); - UDFPrint(("UDFMountVolume: CHECK_VERIFY RC=%8.8x IosbStatus=%8.8x IosbInfo=%lx MediaChangeCount=%lu\n", - RC, Iosb.Status, (ULONG)Iosb.Information, MediaChangeCount)); + UDFPrint(("UDFMountVolume: CHECK_VERIFY RC=%8.8x IosbStatus=%8.8x IosbInfo=%Iu MediaChangeCount=%lu\n", + RC, Iosb.Status, Iosb.Information, MediaChangeCount)); if (!NT_SUCCESS(RC)) { From f2f5d33c47b473323cb3e5d3bf056bd6427d7ffd Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 14 May 2026 20:00:47 +0000 Subject: [PATCH 69/86] Revert "Add broader UDFS mount and device-control diagnostics" This reverts commit 443823dc3e5a815767fa7add50540a70601f8ec9. Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/devcntrl.c | 27 ++------------------------- drivers/filesystems/udfs/fscntrl.c | 9 --------- 2 files changed, 2 insertions(+), 34 deletions(-) diff --git a/drivers/filesystems/udfs/devcntrl.c b/drivers/filesystems/udfs/devcntrl.c index b238ecc6f16d7..adb9cff4e497a 100644 --- a/drivers/filesystems/udfs/devcntrl.c +++ b/drivers/filesystems/udfs/devcntrl.c @@ -128,11 +128,6 @@ UDFCommonDevControl(PIRP_CONTEXT IrpContext, PIRP Irp) ASSERT_VCB(Vcb); IoControlCode = IrpSp->Parameters.DeviceIoControl.IoControlCode; - UDFPrint(("UDFCommonDevControl: Ioctl=%8.8lx InLen=%lu OutLen=%lu TypeOfOpen=%lu\n", - IoControlCode, - IrpSp->Parameters.DeviceIoControl.InputBufferLength, - IrpSp->Parameters.DeviceIoControl.OutputBufferLength, - TypeOfOpen)); if (FlagOn(Vcb->VcbState, VCB_STATE_RMW_INITIALIZED) || FlagOn(Vcb->VcbState, VCB_STATE_SEQUENCE_CACHE)) { @@ -363,11 +358,7 @@ UDFCommonDevControl(PIRP_CONTEXT IrpContext, PIRP Irp) DeviceAcquired = TRUE; } - UDFPrint(("UDFCommonDevControl: forwarding Ioctl=%8.8lx to Target=%x\n", - IoControlCode, Vcb->TargetDeviceObject)); Status = IoCallDriver(Vcb->TargetDeviceObject, Irp); - UDFPrint(("UDFCommonDevControl: IoCallDriver returned %8.8lx for Ioctl=%8.8lx\n", - Status, IoControlCode)); if (DeviceAcquired) UDFReleaseDevice(IrpContext, Vcb, NULL); @@ -385,21 +376,6 @@ UDFDevCtrlCompletionRoutine ( ) { - PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); - ULONG IoctlCode = 0; - - if (IrpSp->MajorFunction == IRP_MJ_DEVICE_CONTROL || - IrpSp->MajorFunction == IRP_MJ_INTERNAL_DEVICE_CONTROL) { - IoctlCode = IrpSp->Parameters.DeviceIoControl.IoControlCode; - } - UDFPrint(("UDFDevCtrlCompletionRoutine: Irp=%x Major=%x Ioctl=%8.8lx Pending=%u Status=%8.8x Info=%Iu\n", - Irp, - IrpSp->MajorFunction, - IoctlCode, - Irp->PendingReturned, - Irp->IoStatus.Status, - Irp->IoStatus.Information)); - // Add the hack-o-ramma to fix formats. if (Irp->PendingReturned) { @@ -407,7 +383,8 @@ UDFDevCtrlCompletionRoutine ( IoMarkIrpPending(Irp); } + return STATUS_SUCCESS; + UNREFERENCED_PARAMETER(DeviceObject); UNREFERENCED_PARAMETER(Contxt); - return STATUS_SUCCESS; } diff --git a/drivers/filesystems/udfs/fscntrl.c b/drivers/filesystems/udfs/fscntrl.c index cdfdc5223671d..8d6c14e9eb5b0 100644 --- a/drivers/filesystems/udfs/fscntrl.c +++ b/drivers/filesystems/udfs/fscntrl.c @@ -296,11 +296,6 @@ UDFMountVolume( ASSERT(IrpSp); UDFPrint(("\n !!! UDFMountVolume\n")); - UDFPrint(("UDFMountVolume: DeviceObject=%x RealDevice=%x DeviceType=%x RealType=%x\n", - DeviceObjectWeTalkTo, - Vpb->RealDevice, - DeviceObjectWeTalkTo->DeviceType, - Vpb->RealDevice ? Vpb->RealDevice->DeviceType : 0)); RealDevice = Vpb->RealDevice; @@ -337,8 +332,6 @@ UDFMountVolume( &MediaChangeCount, sizeof(ULONG), TRUE, &Iosb); - UDFPrint(("UDFMountVolume: CHECK_VERIFY RC=%8.8x IosbStatus=%8.8x IosbInfo=%Iu MediaChangeCount=%lu\n", - RC, Iosb.Status, Iosb.Information, MediaChangeCount)); if (!NT_SUCCESS(RC)) { @@ -354,8 +347,6 @@ UDFMountVolume( &DiskGeometry, sizeof(DISK_GEOMETRY), TRUE, NULL); - UDFPrint(("UDFMountVolume: GET_DRIVE_GEOMETRY RC=%8.8x BytesPerSector=%lu MediaType=%x\n", - RC, DiskGeometry.BytesPerSector, DiskGeometry.MediaType)); if (!NT_SUCCESS(RC)) { From dcb5fa445c8b5f501e70b505390e6c7c5f8235bc Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 14 May 2026 20:00:47 +0000 Subject: [PATCH 70/86] Revert "Add verbose UDFS physical I/O and IOCTL tracing" This reverts commit 9313fcdf305c5db7e07060e9b83f915f5b2e3586. Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/env_spec.c | 39 +++-------------------------- 1 file changed, 4 insertions(+), 35 deletions(-) diff --git a/drivers/filesystems/udfs/env_spec.c b/drivers/filesystems/udfs/env_spec.c index d7460df69ed15..88d690c7d7310 100644 --- a/drivers/filesystems/udfs/env_spec.c +++ b/drivers/filesystems/udfs/env_spec.c @@ -40,12 +40,7 @@ UDFAsyncCompletionRoutine( IN PVOID Contxt ) { - UDFPrint(("UDFAsyncCompletionRoutine: ctx=%x Irp=%x Status=%8.8x Info=%Iu IrpFlags=%8.8x\n", - Contxt, - Irp, - Irp->IoStatus.Status, - Irp->IoStatus.Information, - Irp->Flags)); + UDFPrint(("UDFAsyncCompletionRoutine ctx=%x\n", Contxt)); PUDF_PH_CALL_CONTEXT Context = (PUDF_PH_CALL_CONTEXT)Contxt; PMDL Mdl, NextMdl; @@ -147,9 +142,6 @@ UDFPhReadSynchronous( NTSTATUS RC = STATUS_SUCCESS; LARGE_INTEGER ROffset; - UDFPrint(("UDFPhReadSynchronous: DevObj=%x Buffer=%x ByteCount=%lu Offset=%I64x Flags=%8.8x\n", - DeviceObject, Buffer, ByteCount, Offset, Flags)); - (*ReadBytes) = 0; // MmProbeAndLockPages requires IRQL <= APC_LEVEL. @@ -225,8 +217,6 @@ UDFPhReadSynchronous( } SetFlag(IrpSp->Flags, SL_OVERRIDE_VERIFY_VOLUME); - UDFPrint(("UDFPhReadSynchronous(chunk): Irp=%x Offset=%I64x Length=%lu IrpFlags=%8.8x SpFlags=%8.8x\n", - ChunkIrp, ROffset.QuadPart, ChunkSize, ChunkIrp->Flags, IrpSp->Flags)); RC = IoCallDriver(DeviceObject, ChunkIrp); // ChunkIrp and ChunkMdl are freed by UDFAsyncCompletionRoutine. @@ -235,8 +225,6 @@ UDFPhReadSynchronous( RC = ChunkCtx->IosbToUse.Status; if (RC == STATUS_DATA_OVERRUN) RC = STATUS_SUCCESS; } - UDFPrint(("UDFPhReadSynchronous(chunk): completion Status=%8.8x IosbStatus=%8.8x Info=%Iu\n", - RC, ChunkCtx->IosbToUse.Status, ChunkCtx->IosbToUse.Information)); if (NT_SUCCESS(RC)) { ULONG ChunkRead = (ULONG)ChunkCtx->IosbToUse.Information; @@ -334,8 +322,6 @@ UDFPhReadSynchronous( SetFlag(IrpSp->Flags, SL_OVERRIDE_VERIFY_VOLUME); - UDFPrint(("UDFPhReadSynchronous(single): Irp=%x Offset=%I64x Length=%lu IrpFlags=%8.8x SpFlags=%8.8x\n", - Irp, ROffset.QuadPart, ByteCount, Irp->Flags, IrpSp->Flags)); RC = IoCallDriver(DeviceObject, Irp); if (RC == STATUS_PENDING) { @@ -344,8 +330,6 @@ UDFPhReadSynchronous( RC = STATUS_SUCCESS; } } - UDFPrint(("UDFPhReadSynchronous(single): completion Status=%8.8x IosbStatus=%8.8x Info=%Iu\n", - RC, Context->IosbToUse.Status, Context->IosbToUse.Information)); if (NT_SUCCESS(RC)) { (*ReadBytes) = Context->IosbToUse.Information; } @@ -385,9 +369,6 @@ UDFPhWriteSynchronous( NTSTATUS RC = STATUS_SUCCESS; LARGE_INTEGER ROffset; - UDFPrint(("UDFPhWriteSynchronous: DevObj=%x Buffer=%x ByteCount=%lu Offset=%I64x Flags=%8.8x\n", - DeviceObject, Buffer, ByteCount, Offset, Flags)); - #ifdef DBG if (UDF_SIMULATE_WRITES) { /* FIXME ReactOS @@ -475,8 +456,6 @@ UDFPhWriteSynchronous( IrpSp->Parameters.Write.ByteOffset = ROffset; SetFlag(IrpSp->Flags, SL_OVERRIDE_VERIFY_VOLUME); - UDFPrint(("UDFPhWriteSynchronous(chunk): Irp=%x Offset=%I64x Length=%lu IrpFlags=%8.8x SpFlags=%8.8x\n", - ChunkIrp, ROffset.QuadPart, ChunkSize, ChunkIrp->Flags, IrpSp->Flags)); RC = IoCallDriver(DeviceObject, ChunkIrp); // ChunkIrp and ChunkMdl are freed by UDFAsyncCompletionRoutine. @@ -485,8 +464,6 @@ UDFPhWriteSynchronous( RC = ChunkCtx->IosbToUse.Status; if (RC == STATUS_DATA_OVERRUN) RC = STATUS_SUCCESS; } - UDFPrint(("UDFPhWriteSynchronous(chunk): completion Status=%8.8x IosbStatus=%8.8x Info=%Iu\n", - RC, ChunkCtx->IosbToUse.Status, ChunkCtx->IosbToUse.Information)); if (NT_SUCCESS(RC)) { ULONG ChunkWritten = (ULONG)ChunkCtx->IosbToUse.Information; @@ -569,8 +546,6 @@ UDFPhWriteSynchronous( IrpSp->Parameters.Write.Length = ByteCount; IrpSp->Parameters.Write.ByteOffset = ROffset; SetFlag(IrpSp->Flags, SL_OVERRIDE_VERIFY_VOLUME); - UDFPrint(("UDFPhWriteSynchronous(single): Irp=%x Offset=%I64x Length=%lu IrpFlags=%8.8x SpFlags=%8.8x\n", - Irp, ROffset.QuadPart, ByteCount, Irp->Flags, IrpSp->Flags)); RC = IoCallDriver(DeviceObject, Irp); if (RC == STATUS_PENDING) { @@ -579,8 +554,6 @@ UDFPhWriteSynchronous( RC = STATUS_SUCCESS; } } - UDFPrint(("UDFPhWriteSynchronous(single): completion Status=%8.8x IosbStatus=%8.8x Info=%Iu\n", - RC, Context->IosbToUse.Status, Context->IosbToUse.Information)); if (NT_SUCCESS(RC)) { (*WrittenBytes) = Context->IosbToUse.Information; } @@ -662,8 +635,7 @@ UDFPhSendIOCTL( PUDF_PH_CALL_CONTEXT Context; LARGE_INTEGER timeout; - UDFPrint(("UDFPhDevIOCTL: Code=%8x DevObj=%x InLen=%lu OutLen=%lu OverrideVerify=%u\n", - IoControlCode, DeviceObject, InputBufferLength, OutputBufferLength, OverrideVerify)); + UDFPrint(("UDFPhDevIOCTL: Code %8x \n",IoControlCode)); Context = (PUDF_PH_CALL_CONTEXT)MyAllocatePool__( NonPagedPool, sizeof(UDF_PH_CALL_CONTEXT) ); if (!Context) return STATUS_INSUFFICIENT_RESOURCES; @@ -689,7 +661,6 @@ UDFPhSendIOCTL( } RC = IoCallDriver(DeviceObject, irp); - UDFPrint(("UDFPhDevIOCTL: IoCallDriver returned %8.8x\n", RC)); if (RC == STATUS_PENDING) { ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL); @@ -711,14 +682,12 @@ UDFPhSendIOCTL( if ((RC = Context->IosbToUse.Status) == STATUS_DATA_OVERRUN) { RC = STATUS_SUCCESS; } - UDFPrint(("Exit wait state on evt %x, status %8.8x, iosb=%8.8x info=%Iu\n", - Context, RC, Context->IosbToUse.Status, Context->IosbToUse.Information)); + UDFPrint(("Exit wait state on evt %x, status %8.8x\n", Context, RC)); /* if (Iosb) { (*Iosb) = Context->IosbToUse; }*/ } else { - UDFPrint(("No wait completion on evt %x, iosb=%8.8x info=%Iu\n", - Context, Context->IosbToUse.Status, Context->IosbToUse.Information)); + UDFPrint(("No wait completion on evt %x\n", Context)); /* if (Iosb) { (*Iosb) = irp->IoStatus; }*/ From 5470e0160d0e68c9fc7a536b87e012b683c87da0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 14 May 2026 20:00:47 +0000 Subject: [PATCH 71/86] Revert "Update remaining IRP debug label casing" This reverts commit aaac78c1a2b8e15710ba2c3813b408e222f5b7fc. Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/env_spec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/filesystems/udfs/env_spec.c b/drivers/filesystems/udfs/env_spec.c index 88d690c7d7310..abb2b61320492 100644 --- a/drivers/filesystems/udfs/env_spec.c +++ b/drivers/filesystems/udfs/env_spec.c @@ -525,7 +525,7 @@ UDFPhWriteSynchronous( } Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE); if (!Irp) { - UDFPrint((" !Irp\n")); + UDFPrint((" !irp\n")); MmUnlockPages(Mdl); IoFreeMdl(Mdl); try_return(RC = STATUS_INSUFFICIENT_RESOURCES); From dee3ef7244f757b66a0057bd033f7d6eb4148a13 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 14 May 2026 20:00:48 +0000 Subject: [PATCH 72/86] Revert "Fix IRP debug print naming in UDFS write path" This reverts commit b564a9a005828782d37cbc37a923722b9bbb4711. Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/env_spec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/filesystems/udfs/env_spec.c b/drivers/filesystems/udfs/env_spec.c index abb2b61320492..6c3dc228f1322 100644 --- a/drivers/filesystems/udfs/env_spec.c +++ b/drivers/filesystems/udfs/env_spec.c @@ -287,7 +287,7 @@ UDFPhReadSynchronous( } Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE); if (!Irp) { - UDFPrint((" !Irp\n")); + UDFPrint((" !irp\n")); MmUnlockPages(Mdl); IoFreeMdl(Mdl); try_return(RC = STATUS_INSUFFICIENT_RESOURCES); From 37f638c24c6659bbc2b74ca85a082d0af13e3191 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 14 May 2026 20:00:48 +0000 Subject: [PATCH 73/86] Revert "Align UDFS IRP local naming in write path" This reverts commit 2ebd4745fe5bb5332c21cc42d725f0144f9fb394. Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/env_spec.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/filesystems/udfs/env_spec.c b/drivers/filesystems/udfs/env_spec.c index 6c3dc228f1322..8d37c7b0f411d 100644 --- a/drivers/filesystems/udfs/env_spec.c +++ b/drivers/filesystems/udfs/env_spec.c @@ -493,7 +493,7 @@ UDFPhWriteSynchronous( // Use a single IRP for the whole transfer (these are always small, e.g. one sector). PVOID IoBuf = Buffer; ROffset.QuadPart = Offset; - PIRP Irp; + PIRP irp; PUDF_PH_CALL_CONTEXT Context = (PUDF_PH_CALL_CONTEXT)MyAllocatePool__( NonPagedPool, sizeof(UDF_PH_CALL_CONTEXT) ); if (!Context) try_return (RC = STATUS_INSUFFICIENT_RESOURCES); // Create notification event object to be used to signal the request completion. @@ -523,30 +523,30 @@ UDFPhWriteSynchronous( IoFreeMdl(Mdl); try_return(RC = LockStatus); } - Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE); - if (!Irp) { + irp = IoAllocateIrp(DeviceObject->StackSize, FALSE); + if (!irp) { UDFPrint((" !irp\n")); MmUnlockPages(Mdl); IoFreeMdl(Mdl); try_return(RC = STATUS_INSUFFICIENT_RESOURCES); } - Irp->Flags = IRP_WRITE_OPERATION; - Irp->MdlAddress = Mdl; - Irp->UserIosb = &(Context->IosbToUse); - Irp->UserEvent = NULL; - Irp->RequestorMode = KernelMode; - Irp->Tail.Overlay.Thread = PsGetCurrentThread(); - MmPrint((" Alloc Irp MDL=%x, ctx=%x\n", Irp->MdlAddress, Context)); - IoSetCompletionRoutine(Irp, &UDFAsyncCompletionRoutine, + irp->Flags = IRP_WRITE_OPERATION; + irp->MdlAddress = Mdl; + irp->UserIosb = &(Context->IosbToUse); + irp->UserEvent = NULL; + irp->RequestorMode = KernelMode; + irp->Tail.Overlay.Thread = PsGetCurrentThread(); + MmPrint((" Alloc Irp MDL=%x, ctx=%x\n", irp->MdlAddress, Context)); + IoSetCompletionRoutine(irp, &UDFAsyncCompletionRoutine, Context, TRUE, TRUE, TRUE); } - PIO_STACK_LOCATION IrpSp = IoGetNextIrpStackLocation(Irp); + PIO_STACK_LOCATION IrpSp = IoGetNextIrpStackLocation(irp); IrpSp->MajorFunction = IRP_MJ_WRITE; IrpSp->Parameters.Write.Length = ByteCount; IrpSp->Parameters.Write.ByteOffset = ROffset; SetFlag(IrpSp->Flags, SL_OVERRIDE_VERIFY_VOLUME); - RC = IoCallDriver(DeviceObject, Irp); + RC = IoCallDriver(DeviceObject, irp); if (RC == STATUS_PENDING) { DbgWaitForSingleObject(&(Context->event), NULL); From 4e39b41ea9a1ecbf0a76ae67d161e5a75793d080 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 14 May 2026 20:00:48 +0000 Subject: [PATCH 74/86] Revert "Initialize IRP operation flags in UDFS physical I/O paths" This reverts commit 72e209ff45299093a90a315da8197a3acf92b959. Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/env_spec.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/filesystems/udfs/env_spec.c b/drivers/filesystems/udfs/env_spec.c index 8d37c7b0f411d..75a771a92e889 100644 --- a/drivers/filesystems/udfs/env_spec.c +++ b/drivers/filesystems/udfs/env_spec.c @@ -198,7 +198,6 @@ UDFPhReadSynchronous( RC = STATUS_INSUFFICIENT_RESOURCES; break; } - ChunkIrp->Flags = IRP_READ_OPERATION; ChunkIrp->MdlAddress = ChunkMdl; ChunkIrp->UserIosb = &ChunkCtx->IosbToUse; ChunkIrp->UserEvent = NULL; @@ -292,7 +291,6 @@ UDFPhReadSynchronous( IoFreeMdl(Mdl); try_return(RC = STATUS_INSUFFICIENT_RESOURCES); } - Irp->Flags = IRP_READ_OPERATION; Irp->MdlAddress = Mdl; Irp->UserIosb = &(Context->IosbToUse); Irp->UserEvent = NULL; @@ -441,7 +439,6 @@ UDFPhWriteSynchronous( RC = STATUS_INSUFFICIENT_RESOURCES; break; } - ChunkIrp->Flags = IRP_WRITE_OPERATION; ChunkIrp->MdlAddress = ChunkMdl; ChunkIrp->UserIosb = &ChunkCtx->IosbToUse; ChunkIrp->UserEvent = NULL; @@ -530,7 +527,6 @@ UDFPhWriteSynchronous( IoFreeMdl(Mdl); try_return(RC = STATUS_INSUFFICIENT_RESOURCES); } - irp->Flags = IRP_WRITE_OPERATION; irp->MdlAddress = Mdl; irp->UserIosb = &(Context->IosbToUse); irp->UserEvent = NULL; @@ -798,3 +794,4 @@ UDFNotifyReportChange( } } + From cdaa9bcf283a56672a43999356aef8acb8275549 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 14 May 2026 17:10:54 +0000 Subject: [PATCH 75/86] [UDFS] avoid CDROM geometry EX query during mount size detection Agent-Logs-Url: https://github.com/Zero3K20/reactos/sessions/0cdc3ae9-4a85-4fc5-8e54-a1dca64f4934 Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/Include/phys_lib.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/filesystems/udfs/Include/phys_lib.c b/drivers/filesystems/udfs/Include/phys_lib.c index 373cb070b5eb4..0cc63382826b4 100644 --- a/drivers/filesystems/udfs/Include/phys_lib.c +++ b/drivers/filesystems/udfs/Include/phys_lib.c @@ -791,6 +791,7 @@ UDFGetBlockSize( { NTSTATUS RC = STATUS_SUCCESS; DISK_GEOMETRY_EX DiskGeometryEx; + DISK_GEOMETRY DiskGeometry; PARTITION_INFORMATION PartitionInfo; if (UDFGetDevType(DeviceObject) == FILE_DEVICE_DISK) { @@ -817,9 +818,9 @@ UDFGetBlockSize( try_return(RC = STATUS_UNRECOGNIZED_VOLUME); } } else { - RC = UDFPhSendIOCTL(IOCTL_CDROM_GET_DRIVE_GEOMETRY_EX,DeviceObject, - NULL,0, - &DiskGeometryEx,sizeof(DISK_GEOMETRY_EX), + RC = UDFPhSendIOCTL(IOCTL_CDROM_GET_DRIVE_GEOMETRY,DeviceObject, + &DiskGeometry,sizeof(DISK_GEOMETRY), + &DiskGeometry,sizeof(DISK_GEOMETRY), TRUE,NULL ); if (RC == STATUS_DEVICE_NOT_READY) { @@ -856,9 +857,9 @@ UDFGetBlockSize( } else { Vcb->FirstLBA=0; if (NT_SUCCESS(RC)) { - Vcb->LastLBA = (uint32)(DiskGeometryEx.Geometry.Cylinders.QuadPart * - DiskGeometryEx.Geometry.TracksPerCylinder * - DiskGeometryEx.Geometry.SectorsPerTrack - 1); + Vcb->LastLBA = (uint32)(DiskGeometry.Cylinders.QuadPart * + DiskGeometry.TracksPerCylinder * + DiskGeometry.SectorsPerTrack - 1); if (Vcb->LastLBA == 0x7fffffff) { ASSERT(FALSE); } From c943f4f7da3cf4c7baec587445cb6d8cd0cbb45c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 14 May 2026 17:23:14 +0000 Subject: [PATCH 76/86] [UDFS] Fix HDD mount drive-size query to use plain geometry IOCTL Agent-Logs-Url: https://github.com/Zero3K20/reactos/sessions/1304d48c-6a6e-4822-bd07-433915b2af7b Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/Include/phys_lib.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/drivers/filesystems/udfs/Include/phys_lib.c b/drivers/filesystems/udfs/Include/phys_lib.c index 0cc63382826b4..cd2ec3c013ef1 100644 --- a/drivers/filesystems/udfs/Include/phys_lib.c +++ b/drivers/filesystems/udfs/Include/phys_lib.c @@ -790,15 +790,14 @@ UDFGetBlockSize( ) { NTSTATUS RC = STATUS_SUCCESS; - DISK_GEOMETRY_EX DiskGeometryEx; DISK_GEOMETRY DiskGeometry; PARTITION_INFORMATION PartitionInfo; if (UDFGetDevType(DeviceObject) == FILE_DEVICE_DISK) { UDFPrint(("UDFGetBlockSize: HDD\n")); - RC = UDFPhSendIOCTL(IOCTL_DISK_GET_DRIVE_GEOMETRY_EX,DeviceObject, + RC = UDFPhSendIOCTL(IOCTL_DISK_GET_DRIVE_GEOMETRY,DeviceObject, NULL,0, - &DiskGeometryEx,sizeof(DISK_GEOMETRY_EX), + &DiskGeometry,sizeof(DISK_GEOMETRY), TRUE,NULL ); if (!NT_SUCCESS(RC)) @@ -836,7 +835,7 @@ UDFGetBlockSize( * the disk-path LastLBA calculation shifts by Vcb->SectorShift, so both must * be valid before either calculation is performed. */ if (!Vcb->SectorSize) { - ULONG BytesPerSector = DiskGeometryEx.Geometry.BytesPerSector; + ULONG BytesPerSector = DiskGeometry.BytesPerSector; if (!BytesPerSector) { /* Fallback: 2048 for optical media, 512 for HDD */ BytesPerSector = (UDFGetDevType(DeviceObject) == FILE_DEVICE_DISK) ? 512 : 2048; @@ -848,12 +847,9 @@ UDFGetBlockSize( if ( UDFGetDevType(DeviceObject) == FILE_DEVICE_DISK || FALSE) { - Vcb->FirstLBA=0;//(ULONG)(PartitionInfo->StartingOffset.QuadPart >> Vcb->BlockSizeBits); - if (DiskGeometryEx.DiskSize.QuadPart < Vcb->SectorSize) { - try_return(RC = STATUS_UNRECOGNIZED_VOLUME); - } + Vcb->FirstLBA=0;//(ULONG)(PartitionInfo->StartingOffset.QuadPart >> Vcb->SectorShift); Vcb->LastPossibleLBA = - Vcb->LastLBA = (uint32)(DiskGeometryEx.DiskSize.QuadPart >> Vcb->SectorShift)/* + Vcb->FirstLBA*/ - 1; + Vcb->LastLBA = (uint32)(PartitionInfo.PartitionLength.QuadPart >> Vcb->SectorShift)/* + Vcb->FirstLBA*/ - 1; } else { Vcb->FirstLBA=0; if (NT_SUCCESS(RC)) { From ada2c1dd2083effaebf9f8660be0b3ca1086db23 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 14 May 2026 21:43:40 +0000 Subject: [PATCH 77/86] Use DiskGeometry for UDFS LastLBA on disk path Agent-Logs-Url: https://github.com/Zero3K20/reactos/sessions/1f3edd4c-1628-4e54-9b5e-22bbc239ebe0 Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/Include/phys_lib.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/filesystems/udfs/Include/phys_lib.c b/drivers/filesystems/udfs/Include/phys_lib.c index cd2ec3c013ef1..6318a57fa8591 100644 --- a/drivers/filesystems/udfs/Include/phys_lib.c +++ b/drivers/filesystems/udfs/Include/phys_lib.c @@ -849,7 +849,9 @@ UDFGetBlockSize( FALSE) { Vcb->FirstLBA=0;//(ULONG)(PartitionInfo->StartingOffset.QuadPart >> Vcb->SectorShift); Vcb->LastPossibleLBA = - Vcb->LastLBA = (uint32)(PartitionInfo.PartitionLength.QuadPart >> Vcb->SectorShift)/* + Vcb->FirstLBA*/ - 1; + Vcb->LastLBA = (uint32)(DiskGeometry.Cylinders.QuadPart * + DiskGeometry.TracksPerCylinder * + DiskGeometry.SectorsPerTrack - 1); } else { Vcb->FirstLBA=0; if (NT_SUCCESS(RC)) { From 582e88245b0e0ff44384e447fc44367c4f86cae4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 14 May 2026 21:44:52 +0000 Subject: [PATCH 78/86] Guard DiskGeometry LastLBA conversion overflow Agent-Logs-Url: https://github.com/Zero3K20/reactos/sessions/1f3edd4c-1628-4e54-9b5e-22bbc239ebe0 Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/Include/phys_lib.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/filesystems/udfs/Include/phys_lib.c b/drivers/filesystems/udfs/Include/phys_lib.c index 6318a57fa8591..47ff758a6dfeb 100644 --- a/drivers/filesystems/udfs/Include/phys_lib.c +++ b/drivers/filesystems/udfs/Include/phys_lib.c @@ -792,6 +792,7 @@ UDFGetBlockSize( NTSTATUS RC = STATUS_SUCCESS; DISK_GEOMETRY DiskGeometry; PARTITION_INFORMATION PartitionInfo; + uint64 TotalSectors; if (UDFGetDevType(DeviceObject) == FILE_DEVICE_DISK) { UDFPrint(("UDFGetBlockSize: HDD\n")); @@ -848,10 +849,13 @@ UDFGetBlockSize( UDFGetDevType(DeviceObject) == FILE_DEVICE_DISK || FALSE) { Vcb->FirstLBA=0;//(ULONG)(PartitionInfo->StartingOffset.QuadPart >> Vcb->SectorShift); - Vcb->LastPossibleLBA = - Vcb->LastLBA = (uint32)(DiskGeometry.Cylinders.QuadPart * + TotalSectors = (uint64)(DiskGeometry.Cylinders.QuadPart * DiskGeometry.TracksPerCylinder * - DiskGeometry.SectorsPerTrack - 1); + DiskGeometry.SectorsPerTrack); + if (!TotalSectors || TotalSectors > ((uint64)MAXULONG + 1)) + try_return(RC = STATUS_UNRECOGNIZED_VOLUME); + Vcb->LastLBA = (uint32)(TotalSectors - 1); + Vcb->LastPossibleLBA = Vcb->LastLBA; } else { Vcb->FirstLBA=0; if (NT_SUCCESS(RC)) { From 2c5c025e7887fd66889e77718fdcf911131b1a36 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 14 May 2026 21:45:35 +0000 Subject: [PATCH 79/86] Refine LastLBA bounds check logic Agent-Logs-Url: https://github.com/Zero3K20/reactos/sessions/1f3edd4c-1628-4e54-9b5e-22bbc239ebe0 Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/Include/phys_lib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/filesystems/udfs/Include/phys_lib.c b/drivers/filesystems/udfs/Include/phys_lib.c index 47ff758a6dfeb..90aae2d680708 100644 --- a/drivers/filesystems/udfs/Include/phys_lib.c +++ b/drivers/filesystems/udfs/Include/phys_lib.c @@ -852,7 +852,7 @@ UDFGetBlockSize( TotalSectors = (uint64)(DiskGeometry.Cylinders.QuadPart * DiskGeometry.TracksPerCylinder * DiskGeometry.SectorsPerTrack); - if (!TotalSectors || TotalSectors > ((uint64)MAXULONG + 1)) + if (TotalSectors == 0 || (TotalSectors - 1) > (uint64)MAXULONG) try_return(RC = STATUS_UNRECOGNIZED_VOLUME); Vcb->LastLBA = (uint32)(TotalSectors - 1); Vcb->LastPossibleLBA = Vcb->LastLBA; From 47d60ea4db6a22f74ce58043cb35401667c8f8fb Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 14 May 2026 21:46:15 +0000 Subject: [PATCH 80/86] Clarify 64-bit geometry multiplication and bounds Agent-Logs-Url: https://github.com/Zero3K20/reactos/sessions/1f3edd4c-1628-4e54-9b5e-22bbc239ebe0 Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/Include/phys_lib.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/filesystems/udfs/Include/phys_lib.c b/drivers/filesystems/udfs/Include/phys_lib.c index 90aae2d680708..b013d79f0fcdf 100644 --- a/drivers/filesystems/udfs/Include/phys_lib.c +++ b/drivers/filesystems/udfs/Include/phys_lib.c @@ -849,10 +849,10 @@ UDFGetBlockSize( UDFGetDevType(DeviceObject) == FILE_DEVICE_DISK || FALSE) { Vcb->FirstLBA=0;//(ULONG)(PartitionInfo->StartingOffset.QuadPart >> Vcb->SectorShift); - TotalSectors = (uint64)(DiskGeometry.Cylinders.QuadPart * - DiskGeometry.TracksPerCylinder * - DiskGeometry.SectorsPerTrack); - if (TotalSectors == 0 || (TotalSectors - 1) > (uint64)MAXULONG) + TotalSectors = ((uint64)DiskGeometry.Cylinders.QuadPart * + (uint64)DiskGeometry.TracksPerCylinder * + (uint64)DiskGeometry.SectorsPerTrack); + if (TotalSectors == 0 || TotalSectors > ((uint64)MAXULONG + 1)) try_return(RC = STATUS_UNRECOGNIZED_VOLUME); Vcb->LastLBA = (uint32)(TotalSectors - 1); Vcb->LastPossibleLBA = Vcb->LastLBA; From e8103e7c59c6f48b20259f534efddc1d93fff87c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 14 May 2026 22:54:57 +0000 Subject: [PATCH 81/86] UDFS: restore HDD LastLBA disk-geometry block style Agent-Logs-Url: https://github.com/Zero3K20/reactos/sessions/c5103d4d-e9e8-490b-84f8-f7a9375b3f32 Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/Include/phys_lib.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/filesystems/udfs/Include/phys_lib.c b/drivers/filesystems/udfs/Include/phys_lib.c index b013d79f0fcdf..6318a57fa8591 100644 --- a/drivers/filesystems/udfs/Include/phys_lib.c +++ b/drivers/filesystems/udfs/Include/phys_lib.c @@ -792,7 +792,6 @@ UDFGetBlockSize( NTSTATUS RC = STATUS_SUCCESS; DISK_GEOMETRY DiskGeometry; PARTITION_INFORMATION PartitionInfo; - uint64 TotalSectors; if (UDFGetDevType(DeviceObject) == FILE_DEVICE_DISK) { UDFPrint(("UDFGetBlockSize: HDD\n")); @@ -849,13 +848,10 @@ UDFGetBlockSize( UDFGetDevType(DeviceObject) == FILE_DEVICE_DISK || FALSE) { Vcb->FirstLBA=0;//(ULONG)(PartitionInfo->StartingOffset.QuadPart >> Vcb->SectorShift); - TotalSectors = ((uint64)DiskGeometry.Cylinders.QuadPart * - (uint64)DiskGeometry.TracksPerCylinder * - (uint64)DiskGeometry.SectorsPerTrack); - if (TotalSectors == 0 || TotalSectors > ((uint64)MAXULONG + 1)) - try_return(RC = STATUS_UNRECOGNIZED_VOLUME); - Vcb->LastLBA = (uint32)(TotalSectors - 1); - Vcb->LastPossibleLBA = Vcb->LastLBA; + Vcb->LastPossibleLBA = + Vcb->LastLBA = (uint32)(DiskGeometry.Cylinders.QuadPart * + DiskGeometry.TracksPerCylinder * + DiskGeometry.SectorsPerTrack - 1); } else { Vcb->FirstLBA=0; if (NT_SUCCESS(RC)) { From 1ca061f5cd40d7414239ea2b8fe98e1d8042cb8e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 14 May 2026 22:55:42 +0000 Subject: [PATCH 82/86] UDFS: keep prior LastLBA style with minimal geometry safety Agent-Logs-Url: https://github.com/Zero3K20/reactos/sessions/c5103d4d-e9e8-490b-84f8-f7a9375b3f32 Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/Include/phys_lib.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/filesystems/udfs/Include/phys_lib.c b/drivers/filesystems/udfs/Include/phys_lib.c index 6318a57fa8591..80ee2799e0228 100644 --- a/drivers/filesystems/udfs/Include/phys_lib.c +++ b/drivers/filesystems/udfs/Include/phys_lib.c @@ -792,6 +792,7 @@ UDFGetBlockSize( NTSTATUS RC = STATUS_SUCCESS; DISK_GEOMETRY DiskGeometry; PARTITION_INFORMATION PartitionInfo; + uint64 TotalSectors; if (UDFGetDevType(DeviceObject) == FILE_DEVICE_DISK) { UDFPrint(("UDFGetBlockSize: HDD\n")); @@ -848,10 +849,13 @@ UDFGetBlockSize( UDFGetDevType(DeviceObject) == FILE_DEVICE_DISK || FALSE) { Vcb->FirstLBA=0;//(ULONG)(PartitionInfo->StartingOffset.QuadPart >> Vcb->SectorShift); + TotalSectors = ((uint64)DiskGeometry.Cylinders.QuadPart * + (uint64)DiskGeometry.TracksPerCylinder * + (uint64)DiskGeometry.SectorsPerTrack); + if (!TotalSectors) + try_return(RC = STATUS_UNRECOGNIZED_VOLUME); Vcb->LastPossibleLBA = - Vcb->LastLBA = (uint32)(DiskGeometry.Cylinders.QuadPart * - DiskGeometry.TracksPerCylinder * - DiskGeometry.SectorsPerTrack - 1); + Vcb->LastLBA = (uint32)(TotalSectors - 1); } else { Vcb->FirstLBA=0; if (NT_SUCCESS(RC)) { From 8f703cf6341a5886fd186395d636cab545e95acd Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 14 May 2026 23:05:24 +0000 Subject: [PATCH 83/86] UDFS: restore old-style HDD LastLBA expression using DiskGeometry Agent-Logs-Url: https://github.com/Zero3K20/reactos/sessions/08661851-ab7b-4a17-b3f5-4a57a224f3c3 Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/Include/phys_lib.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/drivers/filesystems/udfs/Include/phys_lib.c b/drivers/filesystems/udfs/Include/phys_lib.c index 80ee2799e0228..31e4644abd23d 100644 --- a/drivers/filesystems/udfs/Include/phys_lib.c +++ b/drivers/filesystems/udfs/Include/phys_lib.c @@ -792,7 +792,6 @@ UDFGetBlockSize( NTSTATUS RC = STATUS_SUCCESS; DISK_GEOMETRY DiskGeometry; PARTITION_INFORMATION PartitionInfo; - uint64 TotalSectors; if (UDFGetDevType(DeviceObject) == FILE_DEVICE_DISK) { UDFPrint(("UDFGetBlockSize: HDD\n")); @@ -849,13 +848,11 @@ UDFGetBlockSize( UDFGetDevType(DeviceObject) == FILE_DEVICE_DISK || FALSE) { Vcb->FirstLBA=0;//(ULONG)(PartitionInfo->StartingOffset.QuadPart >> Vcb->SectorShift); - TotalSectors = ((uint64)DiskGeometry.Cylinders.QuadPart * - (uint64)DiskGeometry.TracksPerCylinder * - (uint64)DiskGeometry.SectorsPerTrack); - if (!TotalSectors) - try_return(RC = STATUS_UNRECOGNIZED_VOLUME); Vcb->LastPossibleLBA = - Vcb->LastLBA = (uint32)(TotalSectors - 1); + Vcb->LastLBA = (uint32)((((uint64)DiskGeometry.Cylinders.QuadPart * + (uint64)DiskGeometry.TracksPerCylinder * + (uint64)DiskGeometry.SectorsPerTrack * + (uint64)DiskGeometry.BytesPerSector) >> Vcb->SectorShift)/* + Vcb->FirstLBA*/ - 1); } else { Vcb->FirstLBA=0; if (NT_SUCCESS(RC)) { From fe55561a3097cdf5e2f85ea0f99a342597d44424 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 14 May 2026 23:23:17 +0000 Subject: [PATCH 84/86] UDFS: restore distinct HDD LastLBA DiskGeometry path Agent-Logs-Url: https://github.com/Zero3K20/reactos/sessions/fe81238c-602c-466b-9e8f-634db02fd208 Co-authored-by: Zero3K20 <258969903+Zero3K20@users.noreply.github.com> --- drivers/filesystems/udfs/Include/phys_lib.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/filesystems/udfs/Include/phys_lib.c b/drivers/filesystems/udfs/Include/phys_lib.c index 31e4644abd23d..42d121bff5a43 100644 --- a/drivers/filesystems/udfs/Include/phys_lib.c +++ b/drivers/filesystems/udfs/Include/phys_lib.c @@ -792,6 +792,7 @@ UDFGetBlockSize( NTSTATUS RC = STATUS_SUCCESS; DISK_GEOMETRY DiskGeometry; PARTITION_INFORMATION PartitionInfo; + uint64 DiskSize; if (UDFGetDevType(DeviceObject) == FILE_DEVICE_DISK) { UDFPrint(("UDFGetBlockSize: HDD\n")); @@ -844,15 +845,14 @@ UDFGetBlockSize( Vcb->SectorShift = UDFHighBit(BytesPerSector); } - if ( - UDFGetDevType(DeviceObject) == FILE_DEVICE_DISK || - FALSE) { + if (UDFGetDevType(DeviceObject) == FILE_DEVICE_DISK) { Vcb->FirstLBA=0;//(ULONG)(PartitionInfo->StartingOffset.QuadPart >> Vcb->SectorShift); + DiskSize = ((uint64)DiskGeometry.Cylinders.QuadPart * + (uint64)DiskGeometry.TracksPerCylinder * + (uint64)DiskGeometry.SectorsPerTrack * + (uint64)DiskGeometry.BytesPerSector); Vcb->LastPossibleLBA = - Vcb->LastLBA = (uint32)((((uint64)DiskGeometry.Cylinders.QuadPart * - (uint64)DiskGeometry.TracksPerCylinder * - (uint64)DiskGeometry.SectorsPerTrack * - (uint64)DiskGeometry.BytesPerSector) >> Vcb->SectorShift)/* + Vcb->FirstLBA*/ - 1); + Vcb->LastLBA = (uint32)((DiskSize >> Vcb->SectorShift)/* + Vcb->FirstLBA*/ - 1); } else { Vcb->FirstLBA=0; if (NT_SUCCESS(RC)) { From 91c46c98fefb680cebfc9948ac76bbf6b02ddd7b Mon Sep 17 00:00:00 2001 From: Zero3K20 Date: Thu, 14 May 2026 20:16:43 -0400 Subject: [PATCH 85/86] Reverted latest phys_lib.c changes --- drivers/filesystems/udfs/Include/phys_lib.c | 35 ++++++++++----------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/drivers/filesystems/udfs/Include/phys_lib.c b/drivers/filesystems/udfs/Include/phys_lib.c index 42d121bff5a43..b9db73e9c59f9 100644 --- a/drivers/filesystems/udfs/Include/phys_lib.c +++ b/drivers/filesystems/udfs/Include/phys_lib.c @@ -790,15 +790,14 @@ UDFGetBlockSize( ) { NTSTATUS RC = STATUS_SUCCESS; - DISK_GEOMETRY DiskGeometry; + DISK_GEOMETRY_EX DiskGeometryEx; PARTITION_INFORMATION PartitionInfo; - uint64 DiskSize; if (UDFGetDevType(DeviceObject) == FILE_DEVICE_DISK) { UDFPrint(("UDFGetBlockSize: HDD\n")); - RC = UDFPhSendIOCTL(IOCTL_DISK_GET_DRIVE_GEOMETRY,DeviceObject, + RC = UDFPhSendIOCTL(IOCTL_DISK_GET_DRIVE_GEOMETRY_EX,DeviceObject, NULL,0, - &DiskGeometry,sizeof(DISK_GEOMETRY), + &DiskGeometryEx,sizeof(DISK_GEOMETRY_EX), TRUE,NULL ); if (!NT_SUCCESS(RC)) @@ -818,9 +817,9 @@ UDFGetBlockSize( try_return(RC = STATUS_UNRECOGNIZED_VOLUME); } } else { - RC = UDFPhSendIOCTL(IOCTL_CDROM_GET_DRIVE_GEOMETRY,DeviceObject, - &DiskGeometry,sizeof(DISK_GEOMETRY), - &DiskGeometry,sizeof(DISK_GEOMETRY), + RC = UDFPhSendIOCTL(IOCTL_CDROM_GET_DRIVE_GEOMETRY_EX,DeviceObject, + NULL,0, + &DiskGeometryEx,sizeof(DISK_GEOMETRY_EX), TRUE,NULL ); if (RC == STATUS_DEVICE_NOT_READY) { @@ -836,7 +835,7 @@ UDFGetBlockSize( * the disk-path LastLBA calculation shifts by Vcb->SectorShift, so both must * be valid before either calculation is performed. */ if (!Vcb->SectorSize) { - ULONG BytesPerSector = DiskGeometry.BytesPerSector; + ULONG BytesPerSector = DiskGeometryEx.Geometry.BytesPerSector; if (!BytesPerSector) { /* Fallback: 2048 for optical media, 512 for HDD */ BytesPerSector = (UDFGetDevType(DeviceObject) == FILE_DEVICE_DISK) ? 512 : 2048; @@ -845,20 +844,18 @@ UDFGetBlockSize( Vcb->SectorShift = UDFHighBit(BytesPerSector); } - if (UDFGetDevType(DeviceObject) == FILE_DEVICE_DISK) { - Vcb->FirstLBA=0;//(ULONG)(PartitionInfo->StartingOffset.QuadPart >> Vcb->SectorShift); - DiskSize = ((uint64)DiskGeometry.Cylinders.QuadPart * - (uint64)DiskGeometry.TracksPerCylinder * - (uint64)DiskGeometry.SectorsPerTrack * - (uint64)DiskGeometry.BytesPerSector); + if ( + UDFGetDevType(DeviceObject) == FILE_DEVICE_DISK || + FALSE) { + Vcb->FirstLBA=0;//(ULONG)(PartitionInfo->StartingOffset.QuadPart >> Vcb->BlockSizeBits); Vcb->LastPossibleLBA = - Vcb->LastLBA = (uint32)((DiskSize >> Vcb->SectorShift)/* + Vcb->FirstLBA*/ - 1); + Vcb->LastLBA = (uint32)(DiskGeometryEx.DiskSize.QuadPart >> Vcb->SectorShift)/* + Vcb->FirstLBA*/ - 1; } else { Vcb->FirstLBA=0; if (NT_SUCCESS(RC)) { - Vcb->LastLBA = (uint32)(DiskGeometry.Cylinders.QuadPart * - DiskGeometry.TracksPerCylinder * - DiskGeometry.SectorsPerTrack - 1); + Vcb->LastLBA = (uint32)(DiskGeometryEx.Geometry.Cylinders.QuadPart * + DiskGeometryEx.Geometry.TracksPerCylinder * + DiskGeometryEx.Geometry.SectorsPerTrack - 1); if (Vcb->LastLBA == 0x7fffffff) { ASSERT(FALSE); } @@ -1302,4 +1299,4 @@ UDFWriteData( (*WrittenBytes) += _WrittenBytes; return status; -} // end UDFWriteData() +} // end UDFWriteData() \ No newline at end of file From b3e2a85ebf9ef6423c3e786795a7625c0159b5c0 Mon Sep 17 00:00:00 2001 From: Zero3K20 Date: Thu, 14 May 2026 20:22:42 -0400 Subject: [PATCH 86/86] Change DiskGeometryEx and related IOCTL to the older variant --- drivers/filesystems/udfs/Include/phys_lib.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/filesystems/udfs/Include/phys_lib.c b/drivers/filesystems/udfs/Include/phys_lib.c index b9db73e9c59f9..4f67e9c952e4d 100644 --- a/drivers/filesystems/udfs/Include/phys_lib.c +++ b/drivers/filesystems/udfs/Include/phys_lib.c @@ -790,14 +790,14 @@ UDFGetBlockSize( ) { NTSTATUS RC = STATUS_SUCCESS; - DISK_GEOMETRY_EX DiskGeometryEx; + DISK_GEOMETRY DiskGeometry; PARTITION_INFORMATION PartitionInfo; if (UDFGetDevType(DeviceObject) == FILE_DEVICE_DISK) { UDFPrint(("UDFGetBlockSize: HDD\n")); - RC = UDFPhSendIOCTL(IOCTL_DISK_GET_DRIVE_GEOMETRY_EX,DeviceObject, + RC = UDFPhSendIOCTL(IOCTL_DISK_GET_DRIVE_GEOMETRY,DeviceObject, NULL,0, - &DiskGeometryEx,sizeof(DISK_GEOMETRY_EX), + &DiskGeometry,sizeof(DISK_GEOMETRY), TRUE,NULL ); if (!NT_SUCCESS(RC)) @@ -817,9 +817,9 @@ UDFGetBlockSize( try_return(RC = STATUS_UNRECOGNIZED_VOLUME); } } else { - RC = UDFPhSendIOCTL(IOCTL_CDROM_GET_DRIVE_GEOMETRY_EX,DeviceObject, + RC = UDFPhSendIOCTL(IOCTL_CDROM_GET_DRIVE_GEOMETRY,DeviceObject, NULL,0, - &DiskGeometryEx,sizeof(DISK_GEOMETRY_EX), + &DiskGeometry,sizeof(DISK_GEOMETRY), TRUE,NULL ); if (RC == STATUS_DEVICE_NOT_READY) { @@ -835,7 +835,7 @@ UDFGetBlockSize( * the disk-path LastLBA calculation shifts by Vcb->SectorShift, so both must * be valid before either calculation is performed. */ if (!Vcb->SectorSize) { - ULONG BytesPerSector = DiskGeometryEx.Geometry.BytesPerSector; + ULONG BytesPerSector = DiskGeometry.Geometry.BytesPerSector; if (!BytesPerSector) { /* Fallback: 2048 for optical media, 512 for HDD */ BytesPerSector = (UDFGetDevType(DeviceObject) == FILE_DEVICE_DISK) ? 512 : 2048; @@ -849,13 +849,13 @@ UDFGetBlockSize( FALSE) { Vcb->FirstLBA=0;//(ULONG)(PartitionInfo->StartingOffset.QuadPart >> Vcb->BlockSizeBits); Vcb->LastPossibleLBA = - Vcb->LastLBA = (uint32)(DiskGeometryEx.DiskSize.QuadPart >> Vcb->SectorShift)/* + Vcb->FirstLBA*/ - 1; + Vcb->LastLBA = (uint32)(DiskGeometry.DiskSize.QuadPart >> Vcb->SectorShift)/* + Vcb->FirstLBA*/ - 1; } else { Vcb->FirstLBA=0; if (NT_SUCCESS(RC)) { - Vcb->LastLBA = (uint32)(DiskGeometryEx.Geometry.Cylinders.QuadPart * - DiskGeometryEx.Geometry.TracksPerCylinder * - DiskGeometryEx.Geometry.SectorsPerTrack - 1); + Vcb->LastLBA = (uint32)(DiskGeometry.Geometry.Cylinders.QuadPart * + DiskGeometry.Geometry.TracksPerCylinder * + DiskGeometry.Geometry.SectorsPerTrack - 1); if (Vcb->LastLBA == 0x7fffffff) { ASSERT(FALSE); }