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 
8  Module Name: udf_rel.h
9 
10  Abstract:
11 
12     Contains udf related structures.
13 
14  Environment:
15 
16     Both kernel and user mode
17 
18 */
19 
20 #ifndef _UDF_REL_H_
21 #define _UDF_REL_H_
22 
23 #include "Include/platform.h"
24 #include "ecma_167.h"
25 
26 #ifdef UDF_LIMIT_DIR_SIZE
27 typedef uint8 uint_di;
28 #else //UDF_LIMIT_DIR_SIZE
29 typedef uint32 uint_di;
30 #endif //UDF_LIMIT_DIR_SIZE
31 
32 typedef struct _UDFTrackMap {
33     uint32 FirstLba;
34     uint32 LastLba;
35     uint32 NWA;
36     uint32 PacketSize;
37     uint32 Session;
38     uint8  TrackParam;
39     uint8  DataParam;
40     uint8  NWA_V;
41 
42     uint8  Flags;
43 #define     TrackMap_AllowCopyBit_variated     0x01
44 #define     TrackMap_CopyBit_variated          0x02
45 #define     TrackMap_Try_variation             0x04
46 #define     TrackMap_Use_variation             0x08
47 #define     TrackMap_FixFPAddressing           0x10
48 #define     TrackMap_FixMRWAddressing          0x20
49 
50     // are used only if FixFPAddressing is enabled
51     uint32 TrackFPOffset;
52     uint32 PacketFPOffset;
53 
54 } UDFTrackMap, *PUDFTrackMap;
55 
56 typedef struct _UDFSparingData
57 {
58     uint32     SparingLocation;
59     uint16     SparingPLength;
60 } UDFSparingData, *PUDFSparingData;
61 
62 #define PACK_MAPPING_THRESHOLD      (sizeof(EXTENT_MAP)*8)
63 
64 typedef struct _EXTENT_INFO {
65     uint32      Offset;
66     PEXTENT_MAP Mapping;
67     int64       Length;   // user data
68     BOOLEAN     Modified; // mapping
69     UCHAR       Flags;
70 /*
71     UCHAR       Reserved[2];
72     PVOID       Cache;
73 */
74 } EXTENT_INFO, *PEXTENT_INFO;
75 
76 #define EXTENT_FLAG_ALLOC_STD             0x00
77 #define EXTENT_FLAG_ALLOC_SEQUENTIAL      0x01
78 #define EXTENT_FLAG_ALLOC_MASK            0x03
79 #define EXTENT_FLAG_PREALLOCATED          0x80
80 #define EXTENT_FLAG_CUT_PREALLOCATED      0x40
81 #define EXTENT_FLAG_VERIFY                0x20
82 #define EXTENT_FLAG_2K_COMPAT             0x10
83 
84 typedef struct _UDFPartMap
85 {
86     uint32  UspaceBitmap; // Lba
87     uint32  FspaceBitmap; // Lba
88     uint32  AccessType;
89     uint32  PartitionRoot;
90     uint32  PartitionLen;
91     uint16  PartitionType;
92     uint16  PartitionNum;
93     uint16  VolumeSeqNum;
94 } UDFPartMap, *PUDFPartMap;
95 
96 
97 #define VDS_POS_PRIMARY_VOL_DESC    0
98 #define VDS_POS_UNALLOC_SPACE_DESC  1
99 #define VDS_POS_LOGICAL_VOL_DESC    2
100 #define VDS_POS_PARTITION_DESC      3
101 #define VDS_POS_IMP_USE_VOL_DESC    4
102 #define VDS_POS_VOL_DESC_PTR        5
103 #define VDS_POS_TERMINATING_DESC    6
104 #define VDS_POS_RECURSION_COUNTER   7
105 #define VDS_POS_LENGTH              8
106 
107 typedef struct _UDF_VDS_RECORD {
108     uint32 block;
109     uint32 volDescSeqNum;
110 } UDF_VDS_RECORD, *PUDF_VDS_RECORD;
111 
112 #define VRS_NSR02_FOUND         0x0001
113 #define VRS_NSR03_FOUND         0x0002
114 #define VRS_ISO9660_FOUND       0x0004
115 
116 #define EXTENT_MAP_GRAN         (8*sizeof(LONG_AD))
117 #define DIR_INDEX_MAP_GRAN      (8*sizeof(DIR_INDEX))
118 #define SHORT_AD_GRAN           (8*sizeof(SHORT_AD))
119 #define RELOC_MAP_GRAN          (8*sizeof(EXT_RELOCATION_ENTRY))
120 #define ALLOC_DESC_MAX_RECURSE  256
121 
122 struct _UDF_FILE_INFO;
123 struct _DIR_INDEX_ITEM;
124 
125 #define UDF_DIR_INDEX_MT PagedPool
126 #define UDF_FILENAME_MT PagedPool
127 
128 typedef struct _HASH_ENTRY {
129     uint32 hDos;                       // hash for Dos-name
130     uint32 hLfn;                       // hash for Upcased Lfn
131     uint32 hPosix;                     // hash for Posix Lfn
132 } HASH_ENTRY, *PHASH_ENTRY;
133 
134 typedef struct _DIR_INDEX_HDR {
135     uint_di     FirstFree;
136     uint_di     LastUsed;
137     uint_di     FrameCount;
138     uint_di     LastFrameCount;  // in items
139     uint_di     DelCount;
140     EXTENT_INFO FECharge;        // file entry charge
141     EXTENT_INFO FEChargeSDir;    // file entry charge for streams
142     ULONG       DIFlags;
143 //    struct _DIR_INDEX_ITEM* FrameList[0];
144 } DIR_INDEX_HDR, *PDIR_INDEX_HDR;
145 
146 // Initial location of directory data extent in IN_ICB
147 #define UDF_DI_FLAG_INIT_IN_ICB  (0x01)
148 
149 /**
150     This is an entry of file list. Each directory has such a list
151     for fast search & modification. This structure was introduced
152     because on-disk equivalents  have  variable  sizes  &  record
153     formats.
154 */
155 typedef struct _DIR_INDEX_ITEM {
156     // FSD-specific data
157 /**
158     Specifies the position of corresponding FileIdent inside  the
159     directory (on-disk).
160 */
161     uint32 Offset;                      // File Ident offset in extent
162 /**
163     Specifies on-disk size of FileIdent. 0 value  of  this  field
164     means that given entry has no on-disk representation  (ex.  -
165     pointer to the directory itself). In this case #Offset
166     value must be also 0.
167 */
168     uint32 Length;                      // Its length
169 /**
170     Points to file name in UnicodeString format.  NULL  value  of
171     this field is treated as list terminator.
172 */
173     UNICODE_STRING FName;              // Filename
174 /**
175     Specifies on-disk location of FileEntry associated  with  the
176     given file. This value should be used for unopened files.
177 */
178     lb_addr FileEntryLoc;              // pointer to FileEntry
179 /**
180     Cached value from FileIdent (see #FILE_IDENT_DESC)
181 */
182     uint8 FileCharacteristics;
183 /**
184     Set of flags. This is intended for internal use.
185     Valid flags:
186     - #UDF_FI_FLAG_FI_MODIFIED\n
187     Presence of this bit means that given FileIdent was  modified
188     & should be flushed.
189     - #UDF_FI_FLAG_SYS_ATTR\n
190     Presence of this bit means that  given  entry  of  file  list
191     contains valid file attributes & times in NT-specific format.
192     - #UDF_FI_FLAG_FI_INTERNAL\n
193     Presence of this bit means that given  entry  represents  the
194     file used for internal FS purposes & must be invisible.
195     - #UDF_FI_FLAG_LINKED\n
196     Presence of this bit means that related  FileEntry  has  more
197     than one FileIdent. It happends when we use HardLinks.
198 */
199     uint8 FI_Flags;                    // FileIdent-related flags
200 /**
201     Points to FileInfo structure for  opened  files.  This  field
202     must be NULL if the file is not opened.
203 */
204     struct _UDF_FILE_INFO* FileInfo;   // associated FileInfo (if opened)
205     // search hashes
206     HASH_ENTRY hashes;
207     // attributes (System-specific format)
208     uint32 SysAttr;
209     int64 CreationTime;
210     int64 LastWriteTime;
211     int64 LastAccessTime;
212     int64 ChangeTime;
213     int64 FileSize;
214     int64 AllocationSize;
215 } DIR_INDEX_ITEM, *PDIR_INDEX_ITEM;
216 /// FileIdent was  modified & should be flushed.
217 #define UDF_FI_FLAG_FI_MODIFIED  (0x01)
218 /// Given entry of file list contains valid file attributes & times in NT-specific format.
219 #define UDF_FI_FLAG_SYS_ATTR     (0x02)// cached flags in system-specific format
220 /// Given  entry  represents the file used for internal FS purposes & must be invisible
221 #define UDF_FI_FLAG_FI_INTERNAL  (0x04)
222 /// Related  FileEntry  has more than one FileIdent. It happends when we use HardLinks.
223 #define UDF_FI_FLAG_LINKED       (0x08)
224 
225 #define UDF_FI_FLAG_DOS          (0x10)// Lfn-style name is equal to DOS-style (case insensetive)
226 #define UDF_FI_FLAG_KEEP_NAME    (0x20)
227 
228 #define UDF_DATALOC_INFO_MT PagedPool
229 
230 /**
231     This structure describes  actual  data  location.  It  is  an
232     analogue (and a pair in this implementation) of NTRequiredFcb
233     structure.
234 
235     UDF FSD keeps list of all Dloc  structures  &  their  on-disk
236     representations. Before allocating new Dloc for newly  opened
237     file the FSD checks if the Dloc with the same Lba is  already
238     in memory. If it is  so  the  initiator  receive  pointer  to
239     existing structure instead of allocating new. This allows  to
240     handle HardLiks properly. When all references to  given  Dloc
241     has gone it  is  released.  In  case  of  file  deletion  the
242     association between Dloc & Lba is discarded, but Dloc is  not
243     released untill UDFCleanUpFile__() is called.  This  prevents
244     interference between deleted files & newly  created  ones  in
245     case of equal Lba of deleted & created FileEntries.
246 
247 */
248 
249 typedef struct _UDF_DATALOC_INFO {
250 
251 /**
252     NT-specific field. As soon as NT supports HardLink concept it
253     has own structure describing the file's actual data.
254 */
255     struct _UDFNTRequiredFCB* CommonFcb; // pointer to corresponding NtReqFcb
256 /**
257     Describes on-disk location of  user  data.  If  the  file  is
258     recorded using IN_ICB method this  structure  points  to  the
259     same LBA as #FELoc, but with non-zero offset  inside  logical
260     block
261 */
262     EXTENT_INFO DataLoc;               // user data
263 /**
264     Describes on-disk location of  allocation  descriptors.  They
265     are part of metadata  associated  with  given  file  If  this
266     structure is not initialized UDF assumes that  no  allocation
267     descriptors recorded for this file.  Usually  this  structure
268     points to the same LBA as #FELoc, but  with  non-zero  offset
269     inside  logical  block.  The  only  exception  is  for  files
270     recorded using IN_ICB method (see above). In such a case this
271     structure must be zero-filled
272 */
273 
274     EXTENT_INFO AllocLoc;              // allocation descriptors (if any)
275 /**
276     Describes on-disk location the  FileEntry.  This  is  on-disk
277     metadata block describing file location.
278 */
279     EXTENT_INFO FELoc;                 // file entry location
280 /**
281     Pointer to cached FileEntry. This field mush be valid  untill
282     all file instances are cleaned up (see UDFCleanUpFile__() and
283     #LinkRefCount).
284 */
285     tag*        FileEntry;             // file entry data
286     uint32      FileEntryLen;
287 /**
288     Set of flags. This is intended for internal use.
289     Valid flags:
290     - #UDF_FE_FLAG_FE_MODIFIED\n
291         Presence of this bit means that given FileEntry was modified &
292         should be flushed
293     - #UDF_FE_FLAG_HAS_SDIR\n
294         Presence of this bit means that given FileEntry has an associated
295         Stream Dir.
296     - #UDF_FE_FLAG_IS_SDIR\n
297         Presence of this bit means that given FileEntry represents a Stream Dir.
298 */
299     uint32      FE_Flags;              // FileEntry flags
300 /**
301     Counter of currently opened directory tree instances  (files)
302     pointing to given data. It is introduced because UDF supports
303     HardLink concept. UDF_DATALOC_INFO structure  should  not  be
304     released untill this field reaches zero.
305 */
306     uint32      LinkRefCount;
307 /**
308     Points to the list of files referenced  by  the  given  file.
309     This field is used for directories only. Otherwise its  value
310     should be NULL.
311 */
312     PDIR_INDEX_HDR DirIndex;           // for Directory objects only
313     struct _UDF_FILE_INFO* LinkedFileInfo;
314 /**
315     Points  to  the  FileInfo  describing   the   StreamDirectory
316     associated with the given file. If the file has no associated
317     StreamDirectory this field must bu NULL.
318 */
319     struct _UDF_FILE_INFO* SDirInfo;
320 } UDF_DATALOC_INFO, *PUDF_DATALOC_INFO;
321 
322 /// Was modified & should be flushed
323 #define UDF_FE_FLAG_FE_MODIFIED  (0x01)
324 /// File contains Stream Dir
325 #define UDF_FE_FLAG_HAS_SDIR     (0x02)
326 /// File is a StreamDir
327 #define UDF_FE_FLAG_IS_SDIR      (0x04)
328 /// Dir was modified & should be packed
329 #define UDF_FE_FLAG_DIR_MODIFIED (0x08)
330 /// File contains pointer to Deleted Stream Dir
331 #define UDF_FE_FLAG_HAS_DEL_SDIR (0x10)
332 /// File is Deleted Stream Dir
333 #define UDF_FE_FLAG_IS_DEL_SDIR  (0x20)
334 /// Dloc is being initialized, don't touch it now
335 #define UDF_FE_FLAG_UNDER_INIT   (0x40)
336 
337 
338 #define UDF_FILE_INFO_MT PagedPool
339 
340 
341 /**
342     This structure  describes  file  location  in  the  directory
343     tree.. It is an analogue (and a pair in this  implementation)
344     of Fcb structure.
345 */
346 typedef struct _UDF_FILE_INFO {
347 #ifdef VALIDATE_STRUCTURES
348 /**
349     Used for debug purposes. Each valid  FileInfo  structure  has
350     IntegrityTag set to zero. If the  routine  receives  FileInfo
351     with invalid IntegrityTag value the break occures.
352 */
353     uint32       IntegrityTag;
354 #endif
355 /**
356     Points to the NT structure describing file  instance  in  the
357     directory tree. Each file opened by NT has  Fcb  structure  &
358     associated FileInfo. If the file is opened  by  UDF  FSD  for
359     internal use this field may be NULL.  Each  Fcb  has  a  back
360     pointer to FileInfo, so both structures are accessable.
361 */
362     struct _UDFFileControlBlock* Fcb;  // pointer to corresponding Fcb (null if absent)
363 /**
364     Points to the structure describing  actual  data  location  &
365     file attributes. See #UDF_DATALOC_INFO for more information.
366 */
367     PUDF_DATALOC_INFO Dloc;            // actual data location descriptor
368 /**
369     Pointer to cached FileIdent. This field mush be valid  untill
370     the file is cleaned up (see UDFCleanUpFile__()).
371 */
372     PFILE_IDENT_DESC FileIdent;        // file ident data
373 /**
374     Length of the buffer allocated for FileIdent.
375 */
376     uint32       FileIdentLen;
377 /**
378     Points to FileInfo structure of the Parent Directory. If  the
379     file has no parent directory this field must be NULL.
380 */
381     struct _UDF_FILE_INFO* ParentFile; // parent (directory) if any
382 /**
383     Number of entry in the DirIndex of the parent  directory.  It
384     is used  for  fast  access  &  modification  of  the  parent.
385     FileInfo  with  index  equal  to  0  usually  describes   the
386     directory itself (file name is '.'  &  the  parent  is  given
387     directory itself). FileInfo with index  equal  to  1  usually
388     describes the parent (file name is '..'). Otherwise  FileInfo
389     describes a plain file or  directory.  If  the  file  has  no
390     parent this field must be 0.
391 */
392     uint_di      Index;                // index in parent directory
393 /**
394     Counter of open operations. Each  routine  opening  the  file
395     increments this counter, each  routine  closing  the  file  -
396     decrements. The FileInfo structure can't be  released  untill
397     this counter reachs zero.
398 */
399     uint32       RefCount;             // number of references
400 /**
401     Counter of open operations performed  for  subsequent  files.
402     Each routine opening the  file  increments  this  counter  in
403     parent FileInfo structure, each routine closing  the  file  -
404     decrements. The FileInfo structure can't be  released  untill
405     this counter reachs zero.
406 */
407     uint32       OpenCount;            // number of opened files in Dir
408     struct _UDF_FILE_INFO* NextLinkedFile; //
409     struct _UDF_FILE_INFO* PrevLinkedFile; //
410 
411     struct _FE_LIST_ENTRY*  ListPtr;
412 } UDF_FILE_INFO, *PUDF_FILE_INFO;
413 
414 typedef struct _FE_LIST_ENTRY {
415     PUDF_FILE_INFO FileInfo;
416     ULONG EntryRefCount;
417 } FE_LIST_ENTRY, *PFE_LIST_ENTRY;
418 
419 #define DOS_NAME_LEN 8
420 #define DOS_EXT_LEN 3
421 #define ILLEGAL_CHAR_MARK 0x005F
422 #define UNICODE_CRC_MARK  0x0023
423 #define UNICODE_PERIOD    0x002E
424 #define UNICODE_SPACE     0x0020
425 
426 #define LBA_OUT_OF_EXTENT       ((ULONG)(-1))
427 #define LBA_NOT_ALLOCATED       ((ULONG)(-2))
428 
429 typedef struct _EXT_RELOCATION_ENTRY {
430     uint32 extLength;
431     uint32 extLocation;
432     uint32 extRedir;
433 } EXT_RELOCATION_ENTRY, *PEXT_RELOCATION_ENTRY;
434 
435 typedef struct _UDF_DATALOC_INDEX {
436     uint32 Lba;
437     PUDF_DATALOC_INFO Dloc;
438 } UDF_DATALOC_INDEX, *PUDF_DATALOC_INDEX;
439 
440 typedef struct _UDF_DIR_SCAN_CONTEXT {
441     PUDF_FILE_INFO DirInfo;
442     PDIR_INDEX_HDR hDirNdx;
443     PDIR_INDEX_ITEM DirNdx;
444     uint32  frame;
445     uint_di j;
446     uint32  d;
447     uint_di i;
448 } UDF_DIR_SCAN_CONTEXT, *PUDF_DIR_SCAN_CONTEXT;
449 
450 typedef EXT_RELOCATION_ENTRY  EXT_RELOC_MAP;
451 typedef PEXT_RELOCATION_ENTRY PEXT_RELOC_MAP;
452 
453 typedef struct _UDF_ALLOCATION_CACHE_ITEM {
454     lba_t       ParentLocation;
455     uint32      Items;
456     EXTENT_INFO Ext;
457 } UDF_ALLOCATION_CACHE_ITEM, *PUDF_ALLOCATION_CACHE_ITEM;
458 
459 /*
460 #define MEM_DIR_HDR_TAG     (ULONG)"DirHdr"
461 #define MEM_DIR_NDX_TAG     (ULONG)"DirNdx"
462 #define MEM_DLOC_NDX_TAG    (ULONG)"DlocNdx"
463 #define MEM_DLOC_INF_TAG    (ULONG)"DlocInf"
464 #define MEM_FNAME_TAG       (ULONG)"FName"
465 #define MEM_FNAME16_TAG     (ULONG)"FName16"
466 #define MEM_FNAMECPY_TAG    (ULONG)"FNameC"
467 #define MEM_FE_TAG          (ULONG)"FE"
468 #define MEM_XFE_TAG         (ULONG)"xFE"
469 #define MEM_FID_TAG         (ULONG)"FID"
470 #define MEM_FINF_TAG        (ULONG)"FInf"
471 #define MEM_VATFINF_TAG     (ULONG)"FInfVat"
472 #define MEM_SDFINF_TAG      (ULONG)"SDirFInf"
473 #define MEM_EXTMAP_TAG      (ULONG)"ExtMap"
474 #define MEM_ALLOCDESC_TAG   (ULONG)"AllocDesc"
475 #define MEM_SHAD_TAG        (ULONG)"SHAD"
476 #define MEM_LNGAD_TAG       (ULONG)"LNGAD"
477 */
478 
479 #define MEM_DIR_HDR_TAG     'DirH'
480 #define MEM_DIR_NDX_TAG     'DirN'
481 #define MEM_DLOC_NDX_TAG    'Dloc'
482 #define MEM_DLOC_INF_TAG    'Dloc'
483 #define MEM_FNAME_TAG       'FNam'
484 #define MEM_FNAME16_TAG     'FNam'
485 #define MEM_FNAMECPY_TAG    'FNam'
486 #define MEM_FE_TAG          'FE'
487 #define MEM_XFE_TAG         'xFE"'
488 #define MEM_FID_TAG         'FID'
489 #define MEM_FINF_TAG        'FInf'
490 #define MEM_VATFINF_TAG     'FInf'
491 #define MEM_SDFINF_TAG      'SDir'
492 #define MEM_EXTMAP_TAG      'ExtM'
493 #define MEM_ALLOCDESC_TAG   'Allo'
494 #define MEM_SHAD_TAG        'SHAD'
495 #define MEM_LNGAD_TAG       'LNGA'
496 #define MEM_ALLOC_CACHE_TAG 'hcCA'
497 
498 #define UDF_DEFAULT_LAST_LBA_CD     276159
499 #define UDF_DEFAULT_LAST_LBA_DVD    0x23053f
500 #define UDF_DEFAULT_FE_CHARGE       128
501 #define UDF_DEFAULT_FE_CHARGE_SDIR  1
502 #define UDF_WRITE_MAX_RETRY         4
503 #define UDF_READ_MAX_RETRY          4
504 #define UDF_READY_MAX_RETRY         5
505 
506 #define ICB_FLAG_AD_DEFAULT_ALLOC_MODE     (UCHAR)(0xff)
507 
508 #define UDF_INVALID_LINK_COUNT      0xffff
509 #define UDF_MAX_LINK_COUNT          0x7fff
510 
511 #define UDF_MAX_EXTENT_LENGTH       (UDF_EXTENT_LENGTH_MASK & ~(2048-1))
512 
513 #define UDF_MAX_READ_REVISION       0x0260
514 #define UDF_MAX_WRITE_REVISION      0x0201
515 
516 #define UDF_MAX_LVID_CHAIN_LENGTH   1024
517 #define UDF_LVID_TTL                1024
518 
519 #define UDF_NO_EXTENT_MAP           ((PEXTENT_MAP)(ULONG_PTR)~0ULL)
520 
521 #define UDF_FLUSH_FLAGS_LITE        (0x80000000)
522 
523 #if defined UDF_DBG || defined _CONSOLE
524 //#define UDF_CHECK_DISK_ALLOCATION
525 
526 //#define UDF_TRACK_ONDISK_ALLOCATION
527 
528 //#define UDF_TRACK_ONDISK_ALLOCATION_OWNERS
529 //#define UDF_TRACK_ONDISK_ALLOCATION_OWNERS_INTERNAL
530 
531 //#define UDF_TRACK_EXTENT_TO_MAPPING
532 
533 //#define UDF_TRACK_ALLOC_FREE_EXTENT
534 
535 //#define UDF_CHECK_EXTENT_SIZE_ALIGNMENT
536 
537 // dependences:
538 
539 #ifdef UDF_TRACK_ALLOC_FREE_EXTENT
540   #define UDF_TRACK_EXTENT_TO_MAPPING
541 #endif //UDF_TRACK_ALLOC_FREE_EXTENT
542 
543 #endif //UDF_DBG
544 
545 typedef struct _UDF_VERIFY_CTX {
546     uint8*     StoredBitMap;
547     ULONG      ItemCount;
548     LIST_ENTRY vrfList;
549     ERESOURCE  VerifyLock;
550     KEVENT     vrfEvent;
551     uint32     WaiterCount;
552     uint32     QueuedCount;
553     BOOLEAN    VInited;
554 } UDF_VERIFY_CTX, *PUDF_VERIFY_CTX;
555 
556 #endif /* _UDF_REL_H_ */
557