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
UDFFindFile__(IN PVCB Vcb,IN BOOLEAN IgnoreCase,IN PUNICODE_STRING Name,IN PUDF_FILE_INFO DirInfo)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
UDFMarkAllocatedAsNotAllocated(IN PVCB Vcb,IN int64 Offset,IN uint32 Length,IN PEXTENT_INFO ExtInfo)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
UDFMarkRecordedAsAllocated(IN PVCB Vcb,IN int64 Offset,IN uint32 Length,IN PEXTENT_INFO ExtInfo)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
UDFReadFile__(IN PVCB Vcb,IN PUDF_FILE_INFO FileInfo,IN int64 Offset,IN SIZE_T Length,IN BOOLEAN Direct,OUT int8 * Buffer,OUT PSIZE_T ReadBytes)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
UDFReadFileLocation__(IN PVCB Vcb,IN PUDF_FILE_INFO FileInfo,IN int64 Offset,OUT PEXTENT_MAP * SubExtInfo,IN OUT uint32 * SubExtInfoSz,OUT int64 * NextOffset)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++
UDFDirIndex(IN PDIR_INDEX_HDR hDirNdx,IN uint_di i)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
UDFVIsStored(IN PVCB Vcb,IN lba_t lba)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