1 //////////////////////////////////////////////////////////////////// 2 // Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine 3 // All rights reserved 4 // This file was released under the GPLv2 on June 2015. 5 //////////////////////////////////////////////////////////////////// 6 7 #ifndef __UDF_STRUCT_SUPPORT_H__ 8 #define __UDF_STRUCT_SUPPORT_H__ 9 10 #include "ecma_167.h" 11 #include "osta_misc.h" 12 #include "udf_rel.h" 13 #include "wcache.h" 14 15 // memory re-allocation (returns new buffer size) 16 uint32 UDFMemRealloc(IN int8* OldBuff, // old buffer 17 IN uint32 OldLength, // old buffer size 18 OUT int8** NewBuff, // address to store new pointer 19 IN uint32 NewLength); // required size 20 // convert offset in extent to Lba & calculate block parameters 21 // it also returns pointer to last valid entry & flags 22 uint32 23 UDFExtentOffsetToLba(IN PVCB Vcb, 24 IN PEXTENT_AD Extent, // Extent array 25 IN int64 Offset, // offset in extent 26 OUT uint32* SectorOffset, 27 OUT PSIZE_T AvailLength, // available data in this block 28 OUT uint32* Flags, 29 OUT uint32* Index); 30 31 // locate frag containing specified Lba in extent 32 ULONG 33 UDFLocateLbaInExtent( 34 IN PVCB Vcb, 35 IN PEXTENT_MAP Extent, // Extent array 36 IN lba_t lba 37 ); 38 39 // see udf_rel.h 40 //#define LBA_OUT_OF_EXTENT ((LONG)(-1)) 41 //#define LBA_NOT_ALLOCATED ((LONG)(-2)) 42 43 // read data at any offset from extent 44 OSSTATUS UDFReadExtent(IN PVCB Vcb, 45 IN PEXTENT_INFO ExtInfo, // Extent array 46 IN int64 Offset, // offset in extent 47 IN SIZE_T Length, 48 IN BOOLEAN Direct, 49 OUT int8* Buffer, 50 OUT PSIZE_T ReadBytes); 51 // builds mapping for specified amount of data at any offset from specified extent. 52 OSSTATUS 53 UDFReadExtentLocation(IN PVCB Vcb, 54 IN PEXTENT_INFO ExtInfo, // Extent array 55 IN int64 Offset, // offset in extent to start SubExtent from 56 OUT PEXTENT_MAP* _SubExtInfo, // SubExtent mapping array 57 IN OUT uint32* _SubExtInfoSz, // IN: maximum number fragments to get 58 // OUT: actually obtained fragments 59 OUT int64* _NextOffset // offset, caller can start from to continue 60 ); 61 // calculate total length of extent 62 int64 UDFGetExtentLength(IN PEXTENT_MAP Extent); // Extent array 63 // convert compressed Unicode to standard 64 void 65 __fastcall UDFDecompressUnicode(IN OUT PUNICODE_STRING UName, 66 IN uint8* CS0, 67 IN SIZE_T Length, 68 OUT uint16* valueCRC); 69 // calculate hashes for directory search 70 uint8 UDFBuildHashEntry(IN PVCB Vcb, 71 IN PUNICODE_STRING Name, 72 OUT PHASH_ENTRY hashes, 73 IN uint8 Mask); 74 75 #define HASH_POSIX 0x01 76 #define HASH_ULFN 0x02 77 #define HASH_DOS 0x04 78 #define HASH_ALL 0x07 79 #define HASH_KEEP_NAME 0x08 // keep DOS '.' and '..' intact 80 81 // get dirindex's frame 82 PDIR_INDEX_ITEM UDFDirIndexGetFrame(IN PDIR_INDEX_HDR hDirNdx, 83 IN uint32 Frame, 84 OUT uint32* FrameLen, 85 OUT uint_di* Index, 86 IN uint_di Rel); 87 // release DirIndex 88 void UDFDirIndexFree(PDIR_INDEX_HDR hDirNdx); 89 // grow DirIndex 90 OSSTATUS UDFDirIndexGrow(IN PDIR_INDEX_HDR* _hDirNdx, 91 IN uint_di d); 92 // truncate DirIndex 93 OSSTATUS UDFDirIndexTrunc(IN PDIR_INDEX_HDR* _hDirNdx, 94 IN uint_di d); 95 // init variables for scan (using knowledge about internal structure) 96 BOOLEAN UDFDirIndexInitScan(IN PUDF_FILE_INFO DirInfo, // 97 OUT PUDF_DIR_SCAN_CONTEXT Context, 98 IN uint_di Index); 99 // 100 PDIR_INDEX_ITEM UDFDirIndexScan(PUDF_DIR_SCAN_CONTEXT Context, 101 PUDF_FILE_INFO* _FileInfo); 102 // build directory index 103 OSSTATUS UDFIndexDirectory(IN PVCB Vcb, 104 IN OUT PUDF_FILE_INFO FileInfo); 105 // search for specified file in specified directory & 106 // returns corresponding offset in extent if found. 107 OSSTATUS UDFFindFile(IN PVCB Vcb, 108 IN BOOLEAN IgnoreCase, 109 IN BOOLEAN NotDeleted, 110 IN PUNICODE_STRING Name, 111 IN PUDF_FILE_INFO DirInfo, 112 IN OUT uint_di* Index); 113 114 __inline OSSTATUS UDFFindFile__(IN PVCB Vcb, 115 IN BOOLEAN IgnoreCase, 116 IN PUNICODE_STRING Name, 117 IN PUDF_FILE_INFO DirInfo) 118 { 119 if(!DirInfo->Dloc->DirIndex) 120 return STATUS_NOT_A_DIRECTORY; 121 uint_di i=0; 122 return UDFFindFile(Vcb, IgnoreCase, TRUE, Name, DirInfo, &i); 123 } 124 125 // calculate file mapping length (in bytes) including ZERO-terminator 126 uint32 UDFGetMappingLength(IN PEXTENT_MAP Extent); 127 // merge 2 sequencial file mappings 128 PEXTENT_MAP 129 __fastcall UDFMergeMappings(IN PEXTENT_MAP Extent, 130 IN PEXTENT_MAP Extent2); 131 // build file mapping according to ShortAllocDesc (SHORT_AD) array 132 PEXTENT_MAP UDFShortAllocDescToMapping(IN PVCB Vcb, 133 IN uint32 PartNum, 134 IN PLONG_AD AllocDesc, 135 IN uint32 AllocDescLength, 136 IN uint32 SubCallCount, 137 OUT PEXTENT_INFO AllocLoc); 138 // build file mapping according to LongAllocDesc (LONG_AD) array 139 PEXTENT_MAP UDFLongAllocDescToMapping(IN PVCB Vcb, 140 IN PLONG_AD AllocDesc, 141 IN uint32 AllocDescLength, 142 IN uint32 SubCallCount, 143 OUT PEXTENT_INFO AllocLoc); 144 // build file mapping according to ExtendedAllocDesc (EXT_AD) array 145 PEXTENT_MAP UDFExtAllocDescToMapping(IN PVCB Vcb, 146 IN PLONG_AD AllocDesc, 147 IN uint32 AllocDescLength, 148 IN uint32 SubCallCount, 149 OUT PEXTENT_INFO AllocLoc); 150 // build file mapping according to (Extended)FileEntry 151 PEXTENT_MAP UDFReadMappingFromXEntry(IN PVCB Vcb, 152 IN uint32 PartNum, 153 IN tag* XEntry, 154 IN OUT uint32* Offset, 155 OUT PEXTENT_INFO AllocLoc); 156 // read FileEntry described in FileIdentDesc 157 OSSTATUS UDFReadFileEntry(IN PVCB Vcb, 158 // IN PFILE_IDENT_DESC FileDesc, 159 IN long_ad* Icb, 160 IN OUT PFILE_ENTRY FileEntry, // here we can also get ExtendedFileEntry 161 IN OUT uint16* Ident); 162 // scan FileSet sequence & return last valid FileSet 163 OSSTATUS UDFFindLastFileSet(IN PVCB Vcb, 164 IN lb_addr *Addr, // Addr for the 1st FileSet 165 IN OUT PFILE_SET_DESC FileSetDesc); 166 // read all sparing tables & stores them in contiguos memory 167 OSSTATUS UDFLoadSparingTable(IN PVCB Vcb, 168 IN PSPARABLE_PARTITION_MAP PartMap); 169 // build mapping for extent 170 PEXTENT_MAP 171 __fastcall UDFExtentToMapping_(IN PEXTENT_AD Extent 172 #ifdef UDF_TRACK_EXTENT_TO_MAPPING 173 ,IN ULONG src, 174 IN ULONG line 175 #endif //UDF_TRACK_EXTENT_TO_MAPPING 176 ); 177 178 #ifdef UDF_TRACK_EXTENT_TO_MAPPING 179 #define UDFExtentToMapping(e) UDFExtentToMapping_(e, UDF_BUG_CHECK_ID, __LINE__) 180 #else //UDF_TRACK_EXTENT_TO_MAPPING 181 #define UDFExtentToMapping(e) UDFExtentToMapping_(e) 182 #endif //UDF_TRACK_EXTENT_TO_MAPPING 183 184 // This routine remaps sectors from bad packet 185 OSSTATUS 186 __fastcall UDFRemapPacket(IN PVCB Vcb, 187 IN uint32 Lba, 188 IN BOOLEAN RemapSpared); 189 190 // This routine releases sector mapping when entire packet is marked as free 191 OSSTATUS 192 __fastcall UDFUnmapRange(IN PVCB Vcb, 193 IN uint32 Lba, 194 IN uint32 BCount); 195 196 // return physical address for relocated sector 197 uint32 198 __fastcall UDFRelocateSector(IN PVCB Vcb, 199 IN uint32 Lba); 200 // check 201 BOOLEAN 202 __fastcall UDFAreSectorsRelocated(IN PVCB Vcb, 203 IN uint32 Lba, 204 IN uint32 BlockCount); 205 // build mapping for relocated extent 206 PEXTENT_MAP 207 __fastcall UDFRelocateSectors(IN PVCB Vcb, 208 IN uint32 Lba, 209 IN uint32 BlockCount); 210 // check for presence of given char among specified ones 211 BOOLEAN UDFUnicodeInString(IN uint8* string, 212 IN WCHAR ch); // Unicode char to search for. 213 // validate char 214 BOOLEAN 215 __fastcall UDFIsIllegalChar(IN WCHAR ch); 216 // translate udfName to dosName using OSTA compliant. 217 #define UDFDOSName__(Vcb, DosName, UdfName, FileInfo) \ 218 UDFDOSName(Vcb, DosName, UdfName, (FileInfo) && ((FileInfo)->Index < 2)); 219 220 void 221 __fastcall UDFDOSName(IN PVCB Vcb, 222 IN OUT PUNICODE_STRING DosName, 223 IN PUNICODE_STRING UdfName, 224 IN BOOLEAN KeepIntact); 225 226 void 227 __fastcall UDFDOSName201(IN OUT PUNICODE_STRING DosName, 228 IN PUNICODE_STRING UdfName, 229 IN BOOLEAN KeepIntact); 230 231 void 232 __fastcall UDFDOSName200(IN OUT PUNICODE_STRING DosName, 233 IN PUNICODE_STRING UdfName, 234 IN BOOLEAN KeepIntact, 235 IN BOOLEAN Mode150); 236 237 void 238 __fastcall UDFDOSName100(IN OUT PUNICODE_STRING DosName, 239 IN PUNICODE_STRING UdfName, 240 IN BOOLEAN KeepIntact); 241 242 // return length of bit-chain starting from Offs bit 243 #ifdef _X86_ 244 SIZE_T 245 __stdcall 246 UDFGetBitmapLen( 247 #else // NO X86 optimization , use generic C/C++ 248 SIZE_T UDFGetBitmapLen( 249 #endif // _X86_ 250 uint32* Bitmap, 251 SIZE_T Offs, 252 SIZE_T Lim); 253 // scan disc free space bitmap for minimal suitable extent 254 SIZE_T UDFFindMinSuitableExtent(IN PVCB Vcb, 255 IN uint32 Length, // in blocks 256 IN uint32 SearchStart, 257 IN uint32 SearchLim, 258 OUT uint32* MaxExtLen, 259 IN uint8 AllocFlags); 260 261 #ifdef UDF_CHECK_DISK_ALLOCATION 262 // mark space described by Mapping as Used/Freed (optionaly) 263 void UDFCheckSpaceAllocation_(IN PVCB Vcb, 264 IN PEXTENT_MAP Map, 265 IN uint32 asXXX 266 #ifdef UDF_TRACK_ONDISK_ALLOCATION 267 ,IN uint32 FE_lba, 268 IN uint32 BugCheckId, 269 IN uint32 Line 270 #endif //UDF_TRACK_ONDISK_ALLOCATION 271 ); 272 273 #ifdef UDF_TRACK_ONDISK_ALLOCATION 274 #define UDFCheckSpaceAllocation(Vcb, FileInfo, Map, asXXX) \ 275 UDFCheckSpaceAllocation_(Vcb, Map, asXXX, (uint32)FileInfo, UDF_BUG_CHECK_ID,__LINE__); 276 #else //UDF_TRACK_ONDISK_ALLOCATION 277 #define UDFCheckSpaceAllocation(Vcb, FileInfo, Map, asXXX) \ 278 UDFCheckSpaceAllocation_(Vcb, Map, asXXX); 279 #endif //UDF_TRACK_ONDISK_ALLOCATION 280 #else // UDF_CHECK_DISK_ALLOCATION 281 #define UDFCheckSpaceAllocation(Vcb, FileInfo, Map, asXXX) {;} 282 #endif //UDF_CHECK_DISK_ALLOCATION 283 284 // mark space described by Mapping as Used/Freed (optionaly) 285 // this routine doesn't acquire any resource 286 void 287 UDFMarkSpaceAsXXXNoProtect_( 288 IN PVCB Vcb, 289 IN PEXTENT_MAP Map, 290 IN uint32 asXXX 291 #ifdef UDF_TRACK_ONDISK_ALLOCATION 292 ,IN uint32 FE_lba, 293 IN uint32 BugCheckId, 294 IN uint32 Line 295 #endif //UDF_TRACK_ONDISK_ALLOCATION 296 ); 297 298 #ifdef UDF_TRACK_ONDISK_ALLOCATION 299 #define UDFMarkSpaceAsXXXNoProtect(Vcb, FileInfo, Map, asXXX) \ 300 UDFMarkSpaceAsXXXNoProtect_(Vcb, Map, asXXX, (uint32)FileInfo, UDF_BUG_CHECK_ID,__LINE__); 301 #else //UDF_TRACK_ONDISK_ALLOCATION 302 #define UDFMarkSpaceAsXXXNoProtect(Vcb, FileInfo, Map, asXXX) \ 303 UDFMarkSpaceAsXXXNoProtect_(Vcb, Map, asXXX); 304 #endif //UDF_TRACK_ONDISK_ALLOCATION 305 306 307 // mark space described by Mapping as Used/Freed (optionaly) 308 void UDFMarkSpaceAsXXX_(IN PVCB Vcb, 309 IN PEXTENT_MAP Map, 310 IN uint32 asXXX 311 #ifdef UDF_TRACK_ONDISK_ALLOCATION 312 ,IN uint32 FE_lba, 313 IN uint32 BugCheckId, 314 IN uint32 Line 315 #endif //UDF_TRACK_ONDISK_ALLOCATION 316 ); 317 318 #ifdef UDF_TRACK_ONDISK_ALLOCATION 319 #define UDFMarkSpaceAsXXX(Vcb, FileInfo, Map, asXXX) \ 320 UDFMarkSpaceAsXXX_(Vcb, Map, asXXX, (uint32)FileInfo, UDF_BUG_CHECK_ID,__LINE__); 321 #else //UDF_TRACK_ONDISK_ALLOCATION 322 #define UDFMarkSpaceAsXXX(Vcb, FileInfo, Map, asXXX) \ 323 UDFMarkSpaceAsXXX_(Vcb, Map, asXXX); 324 #endif //UDF_TRACK_ONDISK_ALLOCATION 325 326 #define AS_FREE 0x00 327 #define AS_USED 0x01 328 #define AS_DISCARDED 0x02 329 #define AS_BAD 0x04 330 331 // build mapping for Length bytes in FreeSpace 332 OSSTATUS UDFAllocFreeExtent_(IN PVCB Vcb, 333 IN int64 Length, 334 IN uint32 SearchStart, 335 IN uint32 SearchLim, 336 OUT PEXTENT_INFO Extent, 337 IN uint8 AllocFlags 338 #ifdef UDF_TRACK_ALLOC_FREE_EXTENT 339 ,IN uint32 src, 340 IN uint32 line 341 #endif //UDF_TRACK_ALLOC_FREE_EXTENT 342 ); 343 344 #ifdef UDF_TRACK_ALLOC_FREE_EXTENT 345 #define UDFAllocFreeExtent(v, l, ss, sl, e, af) UDFAllocFreeExtent_(v, l, ss, sl, e, af, UDF_BUG_CHECK_ID, __LINE__) 346 #else //UDF_TRACK_ALLOC_FREE_EXTENT 347 #define UDFAllocFreeExtent(v, l, ss, sl, e, af) UDFAllocFreeExtent_(v, l, ss, sl, e, af) 348 #endif //UDF_TRACK_ALLOC_FREE_EXTENT 349 // 350 351 uint32 __fastcall 352 UDFGetPartFreeSpace(IN PVCB Vcb, 353 IN uint32 partNum); 354 355 #define UDF_PREALLOC_CLASS_FE 0x00 356 #define UDF_PREALLOC_CLASS_DIR 0x01 357 358 // try to find cached allocation 359 OSSTATUS 360 UDFGetCachedAllocation( 361 IN PVCB Vcb, 362 IN uint32 ParentLocation, 363 OUT PEXTENT_INFO Ext, 364 OUT uint32* Items, // optional 365 IN uint32 AllocClass 366 ); 367 // put released pre-allocation to cache 368 OSSTATUS 369 UDFStoreCachedAllocation( 370 IN PVCB Vcb, 371 IN uint32 ParentLocation, 372 IN PEXTENT_INFO Ext, 373 IN uint32 Items, 374 IN uint32 AllocClass 375 ); 376 // discard all cached allocations 377 OSSTATUS 378 UDFFlushAllCachedAllocations( 379 IN PVCB Vcb, 380 IN uint32 AllocClass 381 ); 382 // allocate space for FE 383 OSSTATUS UDFAllocateFESpace(IN PVCB Vcb, 384 IN PUDF_FILE_INFO DirInfo, 385 IN uint32 PartNum, 386 IN PEXTENT_INFO FEExtInfo, 387 IN uint32 Len); 388 #ifndef UDF_READ_ONLY_BUILD 389 // free space FE's allocation 390 void UDFFreeFESpace(IN PVCB Vcb, 391 IN PUDF_FILE_INFO DirInfo, 392 IN PEXTENT_INFO FEExtInfo); 393 #endif //UDF_READ_ONLY_BUILD 394 395 #define FLUSH_FE_KEEP FALSE 396 #define FLUSH_FE_FOR_DEL TRUE 397 398 // flush FE charge 399 void UDFFlushFESpace(IN PVCB Vcb, 400 IN PUDF_DATALOC_INFO Dloc, 401 IN BOOLEAN Discard = FLUSH_FE_KEEP); 402 // discard file allocation 403 void UDFFreeFileAllocation(IN PVCB Vcb, 404 IN PUDF_FILE_INFO DirInfo, 405 IN PUDF_FILE_INFO FileInfo); 406 // convert physical address to logical in specified partition 407 uint32 UDFPhysLbaToPart(IN PVCB Vcb, 408 IN uint32 PartNum, 409 IN uint32 Addr); 410 /*#define UDFPhysLbaToPart(Vcb, PartNum, Addr) \ 411 ((Addr - Vcb->Partitions[PartNum].PartitionRoot) >> Vcb->LB2B_Bits)*/ 412 // initialize Tag structure. 413 void UDFSetUpTag(IN PVCB Vcb, 414 IN tag* Tag, 415 IN uint16 DataLen, 416 IN uint32 TagLoc); 417 // build content for AllocDesc sequence for specified extent 418 OSSTATUS UDFBuildShortAllocDescs(IN PVCB Vcb, 419 IN uint32 PartNum, 420 OUT int8** Buff, // data for AllocLoc 421 IN uint32 InitSz, 422 IN OUT PUDF_FILE_INFO FileInfo); 423 // build data for AllocDesc sequence for specified 424 OSSTATUS UDFBuildLongAllocDescs(IN PVCB Vcb, 425 IN uint32 PartNum, 426 OUT int8** Buff, // data for AllocLoc 427 IN uint32 InitSz, 428 IN OUT PUDF_FILE_INFO FileInfo); 429 // builds FileEntry & associated AllocDescs for specified extent. 430 OSSTATUS UDFBuildFileEntry(IN PVCB Vcb, 431 IN PUDF_FILE_INFO DirInfo, 432 IN PUDF_FILE_INFO FileInfo, 433 IN uint32 PartNum, 434 IN uint16 AllocMode, // short/long/ext/in-icb 435 IN uint32 ExtAttrSz, 436 IN BOOLEAN Extended/*, 437 OUT PFILE_ENTRY* FEBuff, 438 OUT uint32* FELen, 439 OUT PEXTENT_INFO FEExtInfo*/); 440 // find partition containing given physical sector 441 uint32 442 __fastcall UDFGetPartNumByPhysLba(IN PVCB Vcb, 443 IN uint32 Lba); 444 // add given bitmap to existing one 445 #define UDF_FSPACE_BM 0x00 446 #define UDF_ZSPACE_BM 0x01 447 448 OSSTATUS UDFAddXSpaceBitmap(IN PVCB Vcb, 449 IN uint32 PartNum, 450 IN PSHORT_AD bm, 451 IN ULONG bm_type); 452 // subtract given Bitmap to existing one 453 OSSTATUS UDFDelXSpaceBitmap(IN PVCB Vcb, 454 IN uint32 PartNum, 455 IN PSHORT_AD bm); 456 // build FreeSpaceBitmap (internal) according to media parameters & input data 457 OSSTATUS UDFBuildFreeSpaceBitmap(IN PVCB Vcb, 458 IN uint32 PartNdx, 459 IN PPARTITION_HEADER_DESC phd, 460 IN uint32 Lba); 461 // fill ExtentInfo for specified FileEntry 462 OSSTATUS UDFLoadExtInfo(IN PVCB Vcb, 463 IN PFILE_ENTRY fe, 464 IN PLONG_AD fe_loc, 465 IN OUT PEXTENT_INFO FExtInfo, 466 IN OUT PEXTENT_INFO AExtInfo); 467 // convert standard Unicode to compressed 468 void 469 __fastcall UDFCompressUnicode(IN PUNICODE_STRING UName, 470 IN OUT uint8** _CS0, 471 IN OUT PSIZE_T Length); 472 // build FileIdent for specified FileEntry. 473 OSSTATUS UDFBuildFileIdent(IN PVCB Vcb, 474 IN PUNICODE_STRING fn, 475 IN PLONG_AD FileEntryIcb, // virtual address of FileEntry 476 IN uint32 ImpUseLen, 477 OUT PFILE_IDENT_DESC* _FileId, 478 OUT uint32* FileIdLen); 479 // rebuild mapping on write attempts to Alloc-Not-Rec area. 480 OSSTATUS UDFMarkAllocatedAsRecorded(IN PVCB Vcb, 481 IN int64 Offset, 482 IN uint32 Length, 483 IN PEXTENT_INFO ExtInfo); // Extent array 484 // rebuild mapping on write attempts to Not-Alloc-Not-Rec area 485 OSSTATUS UDFMarkNotAllocatedAsAllocated(IN PVCB Vcb, 486 IN int64 Offset, 487 IN uint32 Length, 488 IN PEXTENT_INFO ExtInfo); // Extent array 489 OSSTATUS UDFMarkAllocatedAsNotXXX(IN PVCB Vcb, 490 IN int64 Offset, 491 IN uint32 Length, 492 IN PEXTENT_INFO ExtInfo, // Extent array 493 IN BOOLEAN Deallocate); 494 #ifdef DBG 495 __inline OSSTATUS UDFMarkAllocatedAsNotAllocated(IN PVCB Vcb, 496 IN int64 Offset, 497 IN uint32 Length, 498 IN PEXTENT_INFO ExtInfo) 499 { 500 return UDFMarkAllocatedAsNotXXX(Vcb, Offset, Length, ExtInfo, TRUE); 501 } 502 #else 503 #define UDFMarkAllocatedAsNotAllocated(Vcb, Off, Len, Ext) \ 504 UDFMarkAllocatedAsNotXXX(Vcb, Off, Len, Ext, TRUE) 505 #endif //DBG 506 507 #ifdef DBG 508 __inline OSSTATUS UDFMarkRecordedAsAllocated(IN PVCB Vcb, 509 IN int64 Offset, 510 IN uint32 Length, 511 IN PEXTENT_INFO ExtInfo) 512 { 513 return UDFMarkAllocatedAsNotXXX(Vcb, Offset, Length, ExtInfo, FALSE); 514 } 515 #else 516 #define UDFMarkRecordedAsAllocated(Vcb, Off, Len, Ext) \ 517 UDFMarkAllocatedAsNotXXX(Vcb, Off, Len, Ext, FALSE) 518 #endif //DBG 519 // write data at any offset from specified extent. 520 OSSTATUS UDFWriteExtent(IN PVCB Vcb, 521 IN PEXTENT_INFO ExtInfo, // Extent array 522 IN int64 Offset, // offset in extent 523 IN SIZE_T Length, 524 IN BOOLEAN Direct, // setting this flag delays flushing of given 525 // data to indefinite term 526 IN int8* Buffer, 527 OUT PSIZE_T WrittenBytes); 528 529 // deallocate/zero data at any offset from specified extent. 530 OSSTATUS UDFZeroExtent(IN PVCB Vcb, 531 IN PEXTENT_INFO ExtInfo, // Extent array 532 IN int64 Offset, // offset in extent 533 IN SIZE_T Length, 534 IN BOOLEAN Deallocate, // deallocate frag or just mark as unrecorded 535 IN BOOLEAN Direct, // setting this flag delays flushing of given 536 // data to indefinite term 537 OUT PSIZE_T WrittenBytes); 538 539 #define UDFZeroExtent__(Vcb, Ext, Off, Len, Dir, WB) \ 540 UDFZeroExtent(Vcb, Ext, Off, Len, FALSE, Dir, WB) 541 542 #define UDFSparseExtent__(Vcb, Ext, Off, Len, Dir, WB) \ 543 UDFZeroExtent(Vcb, Ext, Off, Len, TRUE, Dir, WB) 544 545 uint32 546 __fastcall UDFPartStart(PVCB Vcb, 547 uint32 PartNum); 548 uint32 549 __fastcall UDFPartEnd(PVCB Vcb, 550 uint32 PartNum); 551 // resize extent & associated mapping 552 OSSTATUS UDFResizeExtent(IN PVCB Vcb, 553 IN uint32 PartNum, 554 IN int64 Length, 555 IN BOOLEAN AlwaysInIcb, // must be TRUE for AllocDescs 556 OUT PEXTENT_INFO ExtInfo); 557 // (re)build AllocDescs data & resize associated extent 558 OSSTATUS UDFBuildAllocDescs(IN PVCB Vcb, 559 IN uint32 PartNum, 560 IN OUT PUDF_FILE_INFO FileInfo, 561 OUT int8** AllocData); 562 // set informationLength field in (Ext)FileEntry 563 void UDFSetFileSize(IN PUDF_FILE_INFO FileInfo, 564 IN int64 Size); 565 // sync cached FileSize from DirNdx and actual FileSize from FE 566 void UDFSetFileSizeInDirNdx(IN PVCB Vcb, 567 IN PUDF_FILE_INFO FileInfo, 568 IN int64* ASize); 569 // get informationLength field in (Ext)FileEntry 570 int64 UDFGetFileSize(IN PUDF_FILE_INFO FileInfo); 571 // 572 int64 UDFGetFileSizeFromDirNdx(IN PVCB Vcb, 573 IN PUDF_FILE_INFO FileInfo); 574 // set lengthAllocDesc field in (Ext)FileEntry 575 void UDFSetAllocDescLen(IN PVCB Vcb, 576 IN PUDF_FILE_INFO FileInfo); 577 // change fileLinkCount field in (Ext)FileEntry 578 void UDFChangeFileLinkCount(IN PUDF_FILE_INFO FileInfo, 579 IN BOOLEAN Increase); 580 #define UDFIncFileLinkCount(fi) UDFChangeFileLinkCount(fi, TRUE) 581 #define UDFDecFileLinkCount(fi) UDFChangeFileLinkCount(fi, FALSE) 582 // ee 583 void UDFSetEntityID_imp_(IN EntityID* eID, 584 IN uint8* Str, 585 IN uint32 Len); 586 587 // get fileLinkCount field from (Ext)FileEntry 588 uint16 UDFGetFileLinkCount(IN PUDF_FILE_INFO FileInfo); 589 #ifdef UDF_CHECK_UTIL 590 // set fileLinkCount field in (Ext)FileEntry 591 void 592 UDFSetFileLinkCount( 593 IN PUDF_FILE_INFO FileInfo, 594 uint16 LinkCount 595 ); 596 #endif //UDF_CHECK_UTIL 597 598 #define UDFSetEntityID_imp(eID, Str) \ 599 UDFSetEntityID_imp_(eID, (uint8*)(Str), sizeof(Str)); 600 // 601 void UDFReadEntityID_Domain(PVCB Vcb, 602 EntityID* eID); 603 // get lengthExtendedAttr field in (Ext)FileEntry 604 uint32 UDFGetFileEALength(IN PUDF_FILE_INFO FileInfo); 605 // set UniqueID field in (Ext)FileEntry 606 void UDFSetFileUID(IN PVCB Vcb, 607 IN PUDF_FILE_INFO FileInfo); 608 // get UniqueID field in (Ext)FileEntry 609 int64 UDFGetFileUID(IN PUDF_FILE_INFO FileInfo); 610 // change counters in LVID 611 void UDFChangeFileCounter(IN PVCB Vcb, 612 IN BOOLEAN FileCounter, 613 IN BOOLEAN Increase); 614 #define UDFIncFileCounter(Vcb) UDFChangeFileCounter(Vcb, TRUE, TRUE); 615 #define UDFDecFileCounter(Vcb) UDFChangeFileCounter(Vcb, TRUE, FALSE); 616 #define UDFIncDirCounter(Vcb) UDFChangeFileCounter(Vcb, FALSE, TRUE); 617 #define UDFDecDirCounter(Vcb) UDFChangeFileCounter(Vcb, FALSE, FALSE); 618 // write to file 619 OSSTATUS UDFWriteFile__(IN PVCB Vcb, 620 IN PUDF_FILE_INFO FileInfo, 621 IN int64 Offset, 622 IN SIZE_T Length, 623 IN BOOLEAN Direct, 624 IN int8* Buffer, 625 OUT PSIZE_T WrittenBytes); 626 // mark file as deleted & decrease file link counter. 627 OSSTATUS UDFUnlinkFile__(IN PVCB Vcb, 628 IN PUDF_FILE_INFO FileInfo, 629 IN BOOLEAN FreeSpace); 630 // delete all files in directory (FreeSpace = TRUE) 631 OSSTATUS UDFUnlinkAllFilesInDir(IN PVCB Vcb, 632 IN PUDF_FILE_INFO DirInfo); 633 // init UDF_FILE_INFO structure for specifiend file 634 OSSTATUS UDFOpenFile__(IN PVCB Vcb, 635 IN BOOLEAN IgnoreCase, 636 IN BOOLEAN NotDeleted, 637 IN PUNICODE_STRING fn, 638 IN PUDF_FILE_INFO DirInfo, 639 OUT PUDF_FILE_INFO* _FileInfo, 640 IN uint_di* IndexToOpen); 641 // init UDF_FILE_INFO structure for root directory 642 OSSTATUS UDFOpenRootFile__(IN PVCB Vcb, 643 IN lb_addr* RootLoc, 644 OUT PUDF_FILE_INFO FileInfo); 645 // free all memory blocks referenced by given FileInfo 646 uint32 UDFCleanUpFile__(IN PVCB Vcb, 647 IN PUDF_FILE_INFO FileInfo); 648 #define UDF_FREE_NOTHING 0x00 649 #define UDF_FREE_FILEINFO 0x01 650 #define UDF_FREE_DLOC 0x02 651 // create zero-sized file 652 OSSTATUS UDFCreateFile__(IN PVCB Vcb, 653 IN BOOLEAN IgnoreCase, 654 IN PUNICODE_STRING fn, 655 IN uint32 ExtAttrSz, 656 IN uint32 ImpUseLen, 657 IN BOOLEAN Extended, 658 IN BOOLEAN CreateNew, 659 IN OUT PUDF_FILE_INFO DirInfo, 660 OUT PUDF_FILE_INFO* _FileInfo); 661 // read data from file described with FileInfo 662 /* 663 This routine reads data from file described by FileInfo 664 */ 665 __inline 666 OSSTATUS UDFReadFile__(IN PVCB Vcb, 667 IN PUDF_FILE_INFO FileInfo, 668 IN int64 Offset, // offset in extent 669 IN SIZE_T Length, 670 IN BOOLEAN Direct, 671 OUT int8* Buffer, 672 OUT PSIZE_T ReadBytes) 673 { 674 ValidateFileInfo(FileInfo); 675 676 return UDFReadExtent(Vcb, &(FileInfo->Dloc->DataLoc), Offset, Length, Direct, Buffer, ReadBytes); 677 } // end UDFReadFile__()*/ 678 679 /* 680 This routine reads data from file described by FileInfo 681 */ 682 __inline 683 OSSTATUS UDFReadFileLocation__(IN PVCB Vcb, 684 IN PUDF_FILE_INFO FileInfo, 685 IN int64 Offset, // offset in extent to start SubExtent from 686 OUT PEXTENT_MAP* SubExtInfo, // SubExtent mapping array 687 IN OUT uint32* SubExtInfoSz, // IN: maximum number fragments to get 688 // OUT: actually obtained fragments 689 OUT int64* NextOffset // offset, caller can start from to continue 690 ) 691 { 692 ValidateFileInfo(FileInfo); 693 694 return UDFReadExtentLocation(Vcb, &(FileInfo->Dloc->DataLoc), Offset, SubExtInfo, SubExtInfoSz, NextOffset); 695 } // end UDFReadFile__()*/ 696 697 /* 698 #define UDFReadFile__(Vcb, FileInfo, Offset, Length, Direct, Buffer, ReadBytes) \ 699 (UDFReadExtent(Vcb, &((FileInfo)->Dloc->DataLoc), Offset, Length, Direct, Buffer, ReadBytes)) 700 */ 701 702 // zero data in file described by FileInfo 703 __inline 704 OSSTATUS UDFZeroFile__(IN PVCB Vcb, 705 IN PUDF_FILE_INFO FileInfo, 706 IN int64 Offset, // offset in extent 707 IN uint32 Length, 708 IN BOOLEAN Direct, 709 OUT uint32* ReadBytes); 710 // make sparse area in file described by FileInfo 711 __inline 712 OSSTATUS UDFSparseFile__(IN PVCB Vcb, 713 IN PUDF_FILE_INFO FileInfo, 714 IN int64 Offset, // offset in extent 715 IN uint32 Length, 716 IN BOOLEAN Direct, 717 OUT uint32* ReadBytes); 718 // pad sector tail with zeros 719 OSSTATUS UDFPadLastSector(IN PVCB Vcb, 720 IN PEXTENT_INFO ExtInfo); 721 // update AllocDesc sequence, FileIdent & FileEntry 722 OSSTATUS UDFCloseFile__(IN PVCB Vcb, 723 IN PUDF_FILE_INFO FileInfo); 724 // load specified bitmap. 725 OSSTATUS UDFPrepareXSpaceBitmap(IN PVCB Vcb, 726 IN OUT PSHORT_AD XSpaceBitmap, 727 IN OUT PEXTENT_INFO XSBMExtInfo, 728 IN OUT int8** XSBM, 729 IN OUT uint32* XSl); 730 // update Freed & Unallocated space bitmaps 731 OSSTATUS UDFUpdateXSpaceBitmaps(IN PVCB Vcb, 732 IN uint32 PartNum, 733 IN PPARTITION_HEADER_DESC phd); // partition header pointing to Bitmaps 734 // update Partition Desc & associated data structures 735 OSSTATUS UDFUpdatePartDesc(PVCB Vcb, 736 int8* Buf); 737 // update Logical volume integrity descriptor 738 OSSTATUS UDFUpdateLogicalVolInt(PVCB Vcb, 739 BOOLEAN Close); 740 // blank Unalloc Space Desc 741 OSSTATUS UDFUpdateUSpaceDesc(IN PVCB Vcb, 742 int8* Buf); 743 // update Volume Descriptor Sequence 744 OSSTATUS UDFUpdateVDS(IN PVCB Vcb, 745 IN uint32 block, 746 IN uint32 lastblock, 747 IN uint32 flags); 748 // rebuild & flushes all system areas 749 OSSTATUS UDFUmount__(IN PVCB Vcb); 750 // move file from DirInfo1 to DirInfo2 & renames it to fn 751 OSSTATUS UDFRenameMoveFile__(IN PVCB Vcb, 752 IN BOOLEAN IgnoreCase, 753 IN OUT BOOLEAN* Replace, // replace if destination file exists 754 IN PUNICODE_STRING fn, // destination 755 // IN uint32 ExtAttrSz, 756 IN OUT PUDF_FILE_INFO DirInfo1, 757 IN OUT PUDF_FILE_INFO DirInfo2, 758 IN OUT PUDF_FILE_INFO FileInfo); // source (opened) 759 // change file size (on disc) 760 OSSTATUS UDFResizeFile__(IN PVCB Vcb, 761 IN OUT PUDF_FILE_INFO FileInfo, 762 IN int64 NewLength); 763 // transform zero-sized file to directory 764 OSSTATUS UDFRecordDirectory__(IN PVCB Vcb, 765 IN OUT PUDF_FILE_INFO DirInfo); // source (opened) 766 // remove all DELETED entries from Dir & resize it. 767 #ifndef UDF_READ_ONLY_BUILD 768 OSSTATUS UDFPackDirectory__(IN PVCB Vcb, 769 IN OUT PUDF_FILE_INFO FileInfo); // source (opened) 770 // rebuild tags for all entries from Dir. 771 OSSTATUS 772 UDFReTagDirectory(IN PVCB Vcb, 773 IN OUT PUDF_FILE_INFO FileInfo); // source (opened) 774 #endif //UDF_READ_ONLY_BUILD 775 // load VAT. 776 OSSTATUS UDFLoadVAT(IN PVCB Vcb, 777 IN uint32 PartNdx); 778 // get volume free space 779 int64 780 __fastcall UDFGetFreeSpace(IN PVCB Vcb); 781 // get volume total space 782 int64 783 __fastcall UDFGetTotalSpace(IN PVCB Vcb); 784 // get DirIndex for specified FileInfo 785 PDIR_INDEX_HDR UDFGetDirIndexByFileInfo(IN PUDF_FILE_INFO FileInfo); 786 // check if the file has been found is deleted 787 /*BOOLEAN UDFIsDeleted(IN PDIR_INDEX_ITEM DirNdx);*/ 788 #define UDFIsDeleted(DirNdx) \ 789 (((DirNdx)->FileCharacteristics & FILE_DELETED) ? TRUE : FALSE) 790 // check Directory flag 791 /*BOOLEAN UDFIsADirectory(IN PUDF_FILE_INFO FileInfo);*/ 792 #define UDFIsADirectory(FileInfo) \ 793 (((FileInfo) && ((FileInfo)->Dloc) && ((FileInfo)->Dloc->DirIndex || ((FileInfo)->FileIdent && ((FileInfo)->FileIdent->fileCharacteristics & FILE_DIRECTORY)))) ? TRUE : FALSE) 794 // calculate actual allocation size 795 /*int64 UDFGetFileAllocationSize(IN PVCB Vcb, 796 IN PUDF_FILE_INFO FileInfo);*/ 797 #define UDFGetFileAllocationSize(Vcb, FileInfo) \ 798 (((FileInfo)->Dloc->DataLoc.Mapping) ? UDFGetExtentLength((FileInfo)->Dloc->DataLoc.Mapping) : Vcb->LBlockSize) 799 // check if the directory is empty 800 BOOLEAN UDFIsDirEmpty(IN PDIR_INDEX_HDR hCurDirNdx); 801 // flush FE 802 OSSTATUS UDFFlushFE(IN PVCB Vcb, 803 IN PUDF_FILE_INFO FileInfo, 804 IN uint32 PartNum); 805 // flush FI 806 OSSTATUS UDFFlushFI(IN PVCB Vcb, 807 IN PUDF_FILE_INFO FileInfo, 808 IN uint32 PartNum); 809 // flush all metadata & update counters 810 OSSTATUS UDFFlushFile__(IN PVCB Vcb, 811 IN PUDF_FILE_INFO FileInfo, 812 IN ULONG FlushFlags = 0); 813 // check if the file is flushed 814 #define UDFIsFlushed(FI) \ 815 ( FI && \ 816 !(FI->Dloc->FE_Flags & UDF_FE_FLAG_FE_MODIFIED) && \ 817 !(FI->Dloc->DataLoc.Modified) && \ 818 !(FI->Dloc->AllocLoc.Modified) &&\ 819 !(FI->Dloc->FELoc.Modified) && \ 820 !(UDFGetDirIndexByFileInfo(FI)[FI->Index].FI_Flags & UDF_FI_FLAG_FI_MODIFIED) ) 821 // compare opened directories 822 BOOLEAN UDFCompareFileInfo(IN PUDF_FILE_INFO f1, 823 IN PUDF_FILE_INFO f2); 824 // pack mappings 825 void 826 __fastcall UDFPackMapping(IN PVCB Vcb, 827 IN PEXTENT_INFO ExtInfo); // Extent array 828 // check if all the data is in cache. 829 BOOLEAN UDFIsExtentCached(IN PVCB Vcb, 830 IN PEXTENT_INFO ExtInfo, // Extent array 831 IN int64 Offset, // offset in extent 832 IN uint32 Length, 833 IN BOOLEAN ForWrite); 834 /*BOOLEAN UDFIsFileCached__(IN PVCB Vcb, 835 IN PUDF_FILE_INFO FileInfo, 836 IN int64 Offset, // offset in extent 837 IN uint32 Length, 838 IN BOOLEAN ForWrite);*/ 839 #define UDFIsFileCached__(Vcb, FileInfo, Offset, Length, ForWrite) \ 840 (UDFIsExtentCached(Vcb, &((FileInfo)->Dloc->DataLoc), Offset, Length, ForWrite)) 841 // check if specified sector belongs to a file 842 ULONG UDFIsBlockAllocated(IN void* _Vcb, 843 IN uint32 Lba); 844 // record VolIdent 845 OSSTATUS UDFUpdateVolIdent(IN PVCB Vcb, 846 IN UDF_VDS_RECORD Lba, 847 IN PUNICODE_STRING VolIdent); 848 // calculate checksum for unicode string (for DOS-names) 849 uint16 850 __fastcall UDFUnicodeCksum(PWCHAR s, 851 uint32 n); 852 //#define UDFUnicodeCksum(s,n) UDFCrc((uint8*)(s), (n)*sizeof(WCHAR)) 853 // 854 uint16 855 __fastcall 856 UDFUnicodeCksum150(PWCHAR s, 857 uint32 n); 858 859 uint32 860 __fastcall crc32(IN uint8* s, 861 IN uint32 len); 862 // calculate a 16-bit CRC checksum using ITU-T V.41 polynomial 863 uint16 864 __fastcall UDFCrc(IN uint8* Data, 865 IN SIZE_T Size); 866 // read the first block of a tagged descriptor & check it 867 OSSTATUS UDFReadTagged(IN PVCB Vcb, 868 IN int8* Buf, 869 IN uint32 Block, 870 IN uint32 Location, 871 OUT uint16 *Ident); 872 // get physycal Lba for partition-relative addr 873 uint32 874 __fastcall UDFPartLbaToPhys(IN PVCB Vcb, 875 IN lb_addr* Addr); 876 // look for Anchor(s) at all possible locations 877 lba_t UDFFindAnchor(PVCB Vcb); // Volume control block 878 // look for Volume recognition sequence 879 uint32 UDFFindVRS(PVCB Vcb); 880 // process Primary volume descriptor 881 void UDFLoadPVolDesc(PVCB Vcb, 882 int8* Buf); // pointer to buffer containing PVD 883 // 884 #define UDFGetLVIDiUse(Vcb) \ 885 ( ((Vcb) && (Vcb)->LVid) ? \ 886 ( (LogicalVolIntegrityDescImpUse*) \ 887 ( ((int8*)(Vcb->LVid+1)) + \ 888 Vcb->LVid->numOfPartitions*2*sizeof(uint32))) \ 889 : NULL) 890 891 // load Logical volume integrity descriptor 892 OSSTATUS UDFLoadLogicalVolInt(PDEVICE_OBJECT DeviceObject, 893 PVCB Vcb, 894 extent_ad loc); 895 // load Logical volume descriptor 896 OSSTATUS UDFLoadLogicalVol(PDEVICE_OBJECT DeviceObject, 897 PVCB Vcb, 898 int8* Buf, 899 lb_addr *fileset); 900 // process Partition descriptor 901 OSSTATUS UDFLoadPartDesc(PVCB Vcb, 902 int8* Buf); 903 // scan VDS & fill special array 904 OSSTATUS UDFReadVDS(IN PVCB Vcb, 905 IN uint32 block, 906 IN uint32 lastblock, 907 IN PUDF_VDS_RECORD vds, 908 IN int8* Buf); 909 // process a main/reserve volume descriptor sequence. 910 OSSTATUS UDFProcessSequence(IN PDEVICE_OBJECT DeviceObject, 911 IN PVCB Vcb, 912 IN uint32 block, 913 IN uint32 lastblock, 914 OUT lb_addr *fileset); 915 // Verifies a main/reserve volume descriptor sequence. 916 OSSTATUS UDFVerifySequence(IN PDEVICE_OBJECT DeviceObject, 917 IN PVCB Vcb, 918 IN uint32 block, 919 IN uint32 lastblock, 920 OUT lb_addr *fileset); 921 // remember some useful info about FileSet & RootDir location 922 void UDFLoadFileset(IN PVCB Vcb, 923 IN PFILE_SET_DESC fset, 924 OUT lb_addr *root, 925 OUT lb_addr *sysstream); 926 // load partition info 927 OSSTATUS UDFLoadPartition(IN PDEVICE_OBJECT DeviceObject, 928 IN PVCB Vcb, 929 OUT lb_addr *fileset); 930 // check if this is an UDF-formatted disk 931 OSSTATUS UDFGetDiskInfoAndVerify(IN PDEVICE_OBJECT DeviceObject, // the target device object 932 IN PVCB Vcb); // Volume control block from this DevObj 933 // create hard link for the file 934 OSSTATUS UDFHardLinkFile__(IN PVCB Vcb, 935 IN BOOLEAN IgnoreCase, 936 IN OUT BOOLEAN* Replace, // replace if destination file exists 937 IN PUNICODE_STRING fn, // destination 938 IN OUT PUDF_FILE_INFO DirInfo1, 939 IN OUT PUDF_FILE_INFO DirInfo2, 940 IN OUT PUDF_FILE_INFO FileInfo); // source (opened) 941 // 942 LONG UDFFindDloc(IN PVCB Vcb, 943 IN uint32 Lba); 944 // 945 LONG UDFFindFreeDloc(IN PVCB Vcb, 946 IN uint32 Lba); 947 // 948 OSSTATUS UDFAcquireDloc(IN PVCB Vcb, 949 IN PUDF_DATALOC_INFO Dloc); 950 // 951 OSSTATUS UDFReleaseDloc(IN PVCB Vcb, 952 IN PUDF_DATALOC_INFO Dloc); 953 // 954 OSSTATUS UDFStoreDloc(IN PVCB Vcb, 955 IN PUDF_FILE_INFO fi, 956 IN uint32 Lba); 957 // 958 OSSTATUS UDFRemoveDloc(IN PVCB Vcb, 959 IN PUDF_DATALOC_INFO Dloc); 960 // 961 OSSTATUS UDFUnlinkDloc(IN PVCB Vcb, 962 IN PUDF_DATALOC_INFO Dloc); 963 // 964 void UDFFreeDloc(IN PVCB Vcb, 965 IN PUDF_DATALOC_INFO Dloc); 966 // 967 void UDFRelocateDloc(IN PVCB Vcb, 968 IN PUDF_DATALOC_INFO Dloc, 969 IN uint32 NewLba); 970 // 971 void UDFReleaseDlocList(IN PVCB Vcb); 972 // 973 PUDF_FILE_INFO UDFLocateParallelFI(PUDF_FILE_INFO di, // parent FileInfo 974 uint_di i, // Index 975 PUDF_FILE_INFO fi); 976 // 977 PUDF_FILE_INFO UDFLocateAnyParallelFI(PUDF_FILE_INFO fi); // FileInfo to start search from 978 // 979 void UDFInsertLinkedFile(PUDF_FILE_INFO fi, // FileInfo to be added to chain 980 PUDF_FILE_INFO fi2); // any FileInfo fro the chain 981 // 982 OSSTATUS UDFCreateRootFile__(IN PVCB Vcb, 983 // IN uint16 AllocMode, // short/long/ext/in-icb // always in-ICB 984 IN uint32 PartNum, 985 IN uint32 ExtAttrSz, 986 IN uint32 ImpUseLen, 987 IN BOOLEAN Extended, 988 OUT PUDF_FILE_INFO* _FileInfo); 989 // try to create StreamDirectory associated with given file 990 OSSTATUS UDFCreateStreamDir__(IN PVCB Vcb, 991 IN PUDF_FILE_INFO FileInfo, // file containing stream-dir 992 OUT PUDF_FILE_INFO* _SDirInfo); 993 // 994 OSSTATUS UDFOpenStreamDir__(IN PVCB Vcb, 995 IN PUDF_FILE_INFO FileInfo, // file containing stream-dir 996 OUT PUDF_FILE_INFO* _SDirInfo); 997 // 998 #define UDFIsAStreamDir(FI) ((FI) && ((FI)->Dloc) && ((FI)->Dloc->FE_Flags & UDF_FE_FLAG_IS_SDIR)) 999 // 1000 #define UDFHasAStreamDir(FI) ((FI) && ((FI)->Dloc) && ((FI)->Dloc->FE_Flags & UDF_FE_FLAG_HAS_SDIR)) 1001 // 1002 #define UDFIsAStream(FI) ((FI) && UDFIsAStreamDir((FI)->ParentFile)) 1003 // 1004 #define UDFIsSDirDeleted(FI) ((FI) && (FI)->Dloc && ((FI)->Dloc->FE_Flags & UDF_FE_FLAG_IS_DEL_SDIR)) 1005 // Record updated VAT (if updated) 1006 OSSTATUS UDFRecordVAT(IN PVCB Vcb); 1007 // 1008 OSSTATUS UDFModifyVAT(IN PVCB Vcb, 1009 IN uint32 Lba, 1010 IN uint32 Length); 1011 // 1012 OSSTATUS UDFUpdateVAT(IN void* _Vcb, 1013 IN uint32 Lba, 1014 IN uint32* RelocTab, 1015 IN uint32 BCount); 1016 // 1017 OSSTATUS 1018 __fastcall UDFUnPackMapping(IN PVCB Vcb, 1019 IN PEXTENT_INFO ExtInfo); // Extent array 1020 // 1021 OSSTATUS UDFConvertFEToNonInICB(IN PVCB Vcb, 1022 IN PUDF_FILE_INFO FileInfo, 1023 IN uint8 NewAllocMode); 1024 // 1025 OSSTATUS UDFConvertFEToExtended(IN PVCB Vcb, 1026 IN PUDF_FILE_INFO FileInfo); 1027 // 1028 #define UDFGetPartNumByPartNdx(Vcb, pi) (Vcb->Partitions[pi].PartitionNum) 1029 // 1030 uint32 1031 __fastcall UDFPartLen(PVCB Vcb, 1032 uint32 PartNum); 1033 // 1034 OSSTATUS UDFPretendFileDeleted__(IN PVCB Vcb, 1035 IN PUDF_FILE_INFO FileInfo); 1036 1037 #define UDFStreamsSupported(Vcb) \ 1038 (Vcb->maxUDFWriteRev >= 0x0200) 1039 1040 #define UDFNtAclSupported(Vcb) \ 1041 (Vcb->maxUDFWriteRev >= 0x0200) 1042 1043 #define UDFReferenceFile__(fi) \ 1044 { \ 1045 UDFInterlockedIncrement((PLONG)&((fi)->RefCount)); \ 1046 UDFInterlockedIncrement((PLONG)&((fi)->Dloc->LinkRefCount)); \ 1047 if((fi)->ParentFile) { \ 1048 UDFInterlockedIncrement((PLONG)&((fi)->ParentFile->OpenCount)); \ 1049 } \ 1050 } 1051 1052 #define UDFReferenceFileEx__(fi,i) \ 1053 { \ 1054 UDFInterlockedExchangeAdd((PLONG)&((fi)->RefCount),i); \ 1055 UDFInterlockedExchangeAdd((PLONG)&((fi)->Dloc->LinkRefCount),i); \ 1056 if((fi)->ParentFile) { \ 1057 UDFInterlockedExchangeAdd((PLONG)&((fi)->ParentFile->OpenCount),i); \ 1058 } \ 1059 } 1060 1061 #define UDFDereferenceFile__(fi) \ 1062 { \ 1063 UDFInterlockedDecrement((PLONG)&((fi)->RefCount)); \ 1064 UDFInterlockedDecrement((PLONG)&((fi)->Dloc->LinkRefCount)); \ 1065 if((fi)->ParentFile) { \ 1066 UDFInterlockedDecrement((PLONG)&((fi)->ParentFile->OpenCount)); \ 1067 } \ 1068 } 1069 1070 #define UDFIsDirEmpty__(fi) UDFIsDirEmpty((fi)->Dloc->DirIndex) 1071 #define UDFIsDirOpened__(fi) (fi->OpenCount) 1072 1073 #define UDFSetFileAllocMode__(fi, mode) \ 1074 { \ 1075 (fi)->Dloc->DataLoc.Flags = \ 1076 ((fi)->Dloc->DataLoc.Flags & ~EXTENT_FLAG_ALLOC_MASK) | (mode & EXTENT_FLAG_ALLOC_MASK); \ 1077 } 1078 1079 #define UDFGetFileAllocMode__(fi) ((fi)->Dloc->DataLoc.Flags & EXTENT_FLAG_ALLOC_MASK) 1080 1081 #define UDFGetFileICBAllocMode__(fi) (((PFILE_ENTRY)((fi)->Dloc->FileEntry))->icbTag.flags & ICB_FLAG_ALLOC_MASK) 1082 1083 #ifndef UDF_LIMIT_DIR_SIZE // release 1084 #define UDF_DIR_INDEX_FRAME_SH 9 1085 #else // demo 1086 #define UDF_DIR_INDEX_FRAME_SH 7 1087 #endif 1088 1089 #define UDF_DIR_INDEX_FRAME ((uint_di)(1 << UDF_DIR_INDEX_FRAME_SH)) 1090 1091 #define UDF_DIR_INDEX_FRAME_GRAN (32) 1092 #define UDF_DIR_INDEX_FRAME_GRAN_MASK (UDF_DIR_INDEX_FRAME_GRAN-1) 1093 #define AlignDirIndex(n) ((n+UDF_DIR_INDEX_FRAME_GRAN_MASK) & ~(UDF_DIR_INDEX_FRAME_GRAN_MASK)) 1094 1095 #if defined _X86_ && !defined UDF_LIMIT_DIR_SIZE 1096 1097 PDIR_INDEX_ITEM 1098 __fastcall 1099 UDFDirIndex( 1100 IN PDIR_INDEX_HDR hDirNdx, 1101 IN uint32 i 1102 ); 1103 1104 #else // NO X86 optimization , use generic C/C++ 1105 __inline PDIR_INDEX_ITEM UDFDirIndex(IN PDIR_INDEX_HDR hDirNdx, 1106 IN uint_di i) 1107 { 1108 #ifdef UDF_LIMIT_DIR_SIZE 1109 if( hDirNdx && (i < hDirNdx->LastFrameCount)) 1110 return &( (((PDIR_INDEX_ITEM*)(hDirNdx+1))[0])[i] ); 1111 #else //UDF_LIMIT_DIR_SIZE 1112 uint_di j, k; 1113 if( hDirNdx && 1114 ((j = (i >> UDF_DIR_INDEX_FRAME_SH)) < (k = hDirNdx->FrameCount) ) && 1115 ((i = (i & (UDF_DIR_INDEX_FRAME-1))) < ((j < (k-1)) ? UDF_DIR_INDEX_FRAME : hDirNdx->LastFrameCount)) ) 1116 return &( (((PDIR_INDEX_ITEM*)(hDirNdx+1))[j])[i] ); 1117 #endif // UDF_LIMIT_DIR_SIZE 1118 return NULL; 1119 } 1120 #endif // _X86_ 1121 1122 #define UDFDirIndexGetLastIndex(di) ((((di)->FrameCount - 1) << UDF_DIR_INDEX_FRAME_SH) + (di)->LastFrameCount) 1123 1124 // arr - bit array, bit - number of bit 1125 #ifdef _X86_ 1126 1127 #ifdef _CONSOLE 1128 #define CheckAddr(addr) {ASSERT((uint32)(addr) > 0x1000);} 1129 #else 1130 #define CheckAddr(addr) {ASSERT((uint32)(addr) & 0x80000000);} 1131 #endif 1132 1133 #define UDFGetBit(arr, bit) UDFGetBit__((uint32*)(arr), bit) 1134 1135 BOOLEAN 1136 __fastcall 1137 UDFGetBit__( 1138 IN uint32* arr, 1139 IN uint32 bit 1140 ); 1141 1142 #define UDFSetBit(arr, bit) UDFSetBit__((uint32*)(arr), bit) 1143 1144 void 1145 __fastcall 1146 UDFSetBit__( 1147 IN uint32* arr, 1148 IN uint32 bit 1149 ); 1150 1151 #define UDFSetBits(arr, bit, bc) UDFSetBits__((uint32*)(arr), bit, bc) 1152 1153 void 1154 UDFSetBits__( 1155 IN uint32* arr, 1156 IN uint32 bit, 1157 IN uint32 bc 1158 ); 1159 1160 #define UDFClrBit(arr, bit) UDFClrBit__((uint32*)(arr), bit) 1161 1162 void 1163 __fastcall 1164 UDFClrBit__( 1165 IN uint32* arr, 1166 IN uint32 bit 1167 ); 1168 1169 #define UDFClrBits(arr, bit, bc) UDFClrBits__((uint32*)(arr), bit, bc) 1170 1171 void 1172 UDFClrBits__( 1173 IN uint32* arr, 1174 IN uint32 bit, 1175 IN uint32 bc 1176 ); 1177 1178 #else // NO X86 optimization , use generic C/C++ 1179 1180 #define UDFGetBit(arr, bit) ( (BOOLEAN) ( ((((uint32*)(arr))[(bit)>>5]) >> ((bit)&31)) &1 ) ) 1181 #define UDFSetBit(arr, bit) ( (((uint32*)(arr))[(bit)>>5]) |= (((uint32)1) << ((bit)&31)) ) 1182 #define UDFClrBit(arr, bit) ( (((uint32*)(arr))[(bit)>>5]) &= (~(((uint32)1) << ((bit)&31))) ) 1183 1184 #define UDFSetBits(arr, bit, bc) \ 1185 {uint32 j; \ 1186 for(j=0;j<bc;j++) { \ 1187 UDFSetBit(arr, (bit)+j); \ 1188 }} 1189 1190 #define UDFClrBits(arr, bit, bc) \ 1191 {uint32 j; \ 1192 for(j=0;j<bc;j++) { \ 1193 UDFClrBit(arr, (bit)+j); \ 1194 }} 1195 1196 #endif // _X86_ 1197 1198 #define UDFGetUsedBit(arr,bit) (!UDFGetBit(arr,bit)) 1199 #define UDFGetFreeBit(arr,bit) UDFGetBit(arr,bit) 1200 #define UDFSetUsedBit(arr,bit) UDFClrBit(arr,bit) 1201 #define UDFSetFreeBit(arr,bit) UDFSetBit(arr,bit) 1202 #define UDFSetUsedBits(arr,bit,bc) UDFClrBits(arr,bit,bc) 1203 #define UDFSetFreeBits(arr,bit,bc) UDFSetBits(arr,bit,bc) 1204 1205 #define UDFGetBadBit(arr,bit) UDFGetBit(arr,bit) 1206 1207 #define UDFGetZeroBit(arr,bit) UDFGetBit(arr,bit) 1208 #define UDFSetZeroBit(arr,bit) UDFSetBit(arr,bit) 1209 #define UDFClrZeroBit(arr,bit) UDFClrBit(arr,bit) 1210 #define UDFSetZeroBits(arr,bit,bc) UDFSetBits(arr,bit,bc) 1211 #define UDFClrZeroBits(arr,bit,bc) UDFClrBits(arr,bit,bc) 1212 1213 #if defined UDF_DBG || defined _CONSOLE 1214 #ifdef UDF_TRACK_ONDISK_ALLOCATION_OWNERS 1215 #define UDFSetFreeBitOwner(Vcb, i) (Vcb)->FSBM_Bitmap_owners[i] = 0; 1216 #define UDFSetUsedBitOwner(Vcb, i, o) (Vcb)->FSBM_Bitmap_owners[i] = o; 1217 #define UDFGetUsedBitOwner(Vcb, i) ((Vcb)->FSBM_Bitmap_owners[i]) 1218 #define UDFCheckUsedBitOwner(Vcb, i, o) { \ 1219 ASSERT(i<(Vcb)->FSBM_BitCount); \ 1220 if((Vcb)->FSBM_Bitmap_owners[i] != -1) { \ 1221 ASSERT((Vcb)->FSBM_Bitmap_owners[i] == o); \ 1222 } else { \ 1223 ASSERT((Vcb)->FSBM_Bitmap_owners[i] != 0); \ 1224 (Vcb)->FSBM_Bitmap_owners[i] = o; \ 1225 } \ 1226 } 1227 #define UDFCheckFreeBitOwner(Vcb, i) ASSERT((Vcb)->FSBM_Bitmap_owners[i] == 0); 1228 #else 1229 #define UDFSetFreeBitOwner(Vcb, i) 1230 #define UDFSetUsedBitOwner(Vcb, i, o) 1231 #define UDFCheckUsedBitOwner(Vcb, i, o) 1232 #define UDFCheckFreeBitOwner(Vcb, i) 1233 #endif //UDF_TRACK_ONDISK_ALLOCATION_OWNERS 1234 #else 1235 #define UDFSetFreeBitOwner(Vcb, i) 1236 #define UDFSetUsedBitOwner(Vcb, i, o) 1237 #define UDFCheckUsedBitOwner(Vcb, i, o) 1238 #define UDFCheckFreeBitOwner(Vcb, i) 1239 #endif //UDF_DBG 1240 1241 #ifdef UDF_TRACK_FS_STRUCTURES 1242 extern 1243 VOID 1244 UDFRegisterFsStructure( 1245 PVCB Vcb, 1246 uint32 Lba, 1247 uint32 Length // sectors 1248 ); 1249 #else //UDF_TRACK_FS_STRUCTURES 1250 #define UDFRegisterFsStructure(Vcb, Lba, Length) {NOTHING;} 1251 #endif //UDF_TRACK_FS_STRUCTURES 1252 1253 extern const char hexChar[]; 1254 1255 #define UDF_MAX_VERIFY_CACHE (8*1024*1024/2048) 1256 #define UDF_VERIFY_CACHE_LOW (4*1024*1024/2048) 1257 #define UDF_VERIFY_CACHE_GRAN (512*1024/2048) 1258 #define UDF_SYS_CACHE_STOP_THR (10*1024*1024/2048) 1259 1260 OSSTATUS 1261 UDFVInit( 1262 IN PVCB Vcb 1263 ); 1264 1265 VOID 1266 UDFVRelease( 1267 IN PVCB Vcb 1268 ); 1269 1270 #define PH_FORGET_VERIFIED 0x00800000 1271 #define PH_READ_VERIFY_CACHE 0x00400000 1272 #define PH_KEEP_VERIFY_CACHE 0x00200000 1273 1274 OSSTATUS 1275 UDFVWrite( 1276 IN PVCB Vcb, 1277 IN void* Buffer, // Target buffer 1278 IN uint32 BCount, 1279 IN uint32 LBA, 1280 // OUT PSIZE_T WrittenBytes, 1281 IN uint32 Flags 1282 ); 1283 1284 OSSTATUS 1285 UDFVRead( 1286 IN PVCB Vcb, 1287 IN void* Buffer, // Target buffer 1288 IN uint32 BCount, 1289 IN uint32 LBA, 1290 // OUT uint32* ReadBytes, 1291 IN uint32 Flags 1292 ); 1293 1294 OSSTATUS 1295 UDFVForget( 1296 IN PVCB Vcb, 1297 IN uint32 BCount, 1298 IN uint32 LBA, 1299 IN uint32 Flags 1300 ); 1301 1302 #define UFD_VERIFY_FLAG_FORCE 0x01 1303 #define UFD_VERIFY_FLAG_WAIT 0x02 1304 #define UFD_VERIFY_FLAG_BG 0x04 1305 #define UFD_VERIFY_FLAG_LOCKED 0x10 1306 1307 VOID 1308 UDFVVerify( 1309 IN PVCB Vcb, 1310 IN ULONG Flags 1311 ); 1312 1313 VOID 1314 UDFVFlush( 1315 IN PVCB Vcb 1316 ); 1317 1318 __inline 1319 BOOLEAN 1320 __fastcall UDFVIsStored( 1321 IN PVCB Vcb, 1322 IN lba_t lba 1323 ) 1324 { 1325 if(!Vcb->VerifyCtx.VInited) 1326 return FALSE; 1327 return UDFGetBit(Vcb->VerifyCtx.StoredBitMap, lba); 1328 } // end UDFVIsStored() 1329 1330 BOOLEAN 1331 __fastcall 1332 UDFCheckArea( 1333 IN PVCB Vcb, 1334 IN lba_t LBA, 1335 IN uint32 BCount 1336 ); 1337 1338 #endif // __UDF_STRUCT_SUPPORT_H__ 1339