xref: /reactos/drivers/filesystems/udfs/struct.h (revision 34593d93)
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 * File: struct.h
9 *
10 * Module: UDF File System Driver (Kernel mode execution only)
11 *
12 * Description:
13 *   This file contains structure definitions for the UDF file system
14 *   driver. Note that all structures are prefixed with the letters
15 *   "UDF". The structures are all aligned using normal alignment
16 *   used by the compiler (typically quad-word aligned).
17 *
18 *************************************************************************/
19 
20 #ifndef _UDF_STRUCTURES_H_
21 #define _UDF_STRUCTURES_H_
22 
23 
24 /**************************************************************************
25     some useful definitions
26 **************************************************************************/
27 
28 #include "Include/platform.h"
29 
30 /**************************************************************************
31     some empty typedefs defined here so we can reference them easily
32 **************************************************************************/
33 struct _UDFIdentifier;
34 struct _UDFObjectName;
35 struct _UDFContextControlBlock;
36 struct _UDFNTRequiredFCB;
37 struct _UDFDiskDependentFCB;
38 struct _UDFFileControlBlock;
39 struct _UDFVolumeControlBlock;
40 struct _UDFIrpContext;
41 struct _UDFIrpContextLite;
42 struct _UDF_FILE_INFO;
43 struct _UDFData;
44 struct _UDFEjectWaitContext;
45 struct _UDFFileIDCacheItem;
46 struct _SparingEntry;
47 struct _UDFTrackMap;
48 
49 /**************************************************************************
50  include udf related structures *here* (because we need definition of Fcb)
51 **************************************************************************/
52 #include "udf_info/udf_rel.h"
53 
54 /**************************************************************************
55     each structure has a unique "node type" or signature associated with it
56 **************************************************************************/
57 #define UDF_NODE_TYPE_NT_REQ_FCB            ((CSHORT)(0xfcb0))
58 #define UDF_NODE_TYPE_OBJECT_NAME           (0xfdecba01)
59 #define UDF_NODE_TYPE_CCB                   (0xfdecba02)
60 #define UDF_NODE_TYPE_FCB                   (0xfdecba03)
61 #define UDF_NODE_TYPE_VCB                   (0xfdecba04)
62 #define UDF_NODE_TYPE_IRP_CONTEXT           (0xfdecba05)
63 #define UDF_NODE_TYPE_GLOBAL_DATA           (0xfdecba06)
64 #define UDF_NODE_TYPE_FILTER_DEVOBJ         (0xfdecba07)
65 #define UDF_NODE_TYPE_UDFFS_DEVOBJ          (0xfdecba08)
66 #define UDF_NODE_TYPE_IRP_CONTEXT_LITE      (0xfdecba09)
67 #define UDF_NODE_TYPE_UDFFS_DRVOBJ          (0xfdecba0a)
68 
69 /**************************************************************************
70     every structure has a node type, and a node size associated with it.
71     The node type serves as a signature field. The size is used for
72     consistency checking ...
73 **************************************************************************/
74 typedef struct _UDFIdentifier {
75     uint32      NodeType;           // a 32 bit identifier for the structure
76     uint32      NodeSize;           // computed as sizeof(structure)
77 } UDFIdentifier, *PtrUDFIdentifier;
78 
79 /**************************************************************************
80     Every open on-disk object must have a name associated with it
81     This name has two components:
82     (a) the path-name (prefix) that leads to this on-disk object
83     (b) the name of the object itself
84     Note that with multiply linked objects, a single object might be
85     associated with more than one name structure.
86     This UDF FSD does not correctly support multiply linked objects.
87 
88     This structure must be quad-word aligned because it is zone allocated.
89 **************************************************************************/
90 typedef struct _UDFObjectName {
91     UDFIdentifier                       NodeIdentifier;
92     uint32                              ObjectNameFlags;
93     // an absolute pathname of the object is stored below
94     UNICODE_STRING                      ObjectName;
95 } UDFObjectName, *PtrUDFObjectName;
96 
97 #define     UDF_OBJ_NAME_NOT_FROM_ZONE               (0x80000000)
98 
99 /**************************************************************************
100     Each file open instance is represented by a context control block.
101     For each successful create/open request; a file object and a CCB will
102     be created.
103     For open operations performed internally by the FSD, there may not
104     exist file objects; but a CCB will definitely be created.
105 
106     This structure must be quad-word aligned because it is zone allocated.
107 **************************************************************************/
108 typedef struct _UDFContextControlBlock {
109     UDFIdentifier                       NodeIdentifier;
110     // ptr to the associated FCB
111     struct _UDFFileControlBlock *Fcb;
112     // all CCB structures for a FCB are linked together
113     LIST_ENTRY                          NextCCB;
114     // each CCB is associated with a file object
115     PFILE_OBJECT                        FileObject;
116     // flags (see below) associated with this CCB
117     uint32                              CCBFlags;
118     // current index in directory is required sometimes
119     ULONG                               CurrentIndex;
120     // if this CCB represents a directory object open, we may
121     //  need to maintain a search pattern
122     PUNICODE_STRING                     DirectorySearchPattern;
123     HASH_ENTRY                          hashes;
124     ULONG                               TreeLength;
125     // Acces rights previously granted to caller's thread
126     ACCESS_MASK                         PreviouslyGrantedAccess;
127 } UDFCCB, *PtrUDFCCB;
128 
129 
130 /**************************************************************************
131     the following CCBFlags values are relevant. These flag
132     values are bit fields; therefore we can test whether
133     a bit position is set (1) or not set (0).
134 **************************************************************************/
135 
136 // some on-disk file/directories are opened by UDF itself
137 //  as opposed to being opened on behalf of a user process
138 #define UDF_CCB_OPENED_BY_UDF                   (0x00000001)
139 // the file object specified synchronous access at create/open time.
140 //  this implies that UDF must maintain the current byte offset
141 #define UDF_CCB_OPENED_FOR_SYNC_ACCESS          (0x00000002)
142 // file object specified sequential access for this file
143 #define UDF_CCB_OPENED_FOR_SEQ_ACCESS           (0x00000004)
144 // the CCB has had an IRP_MJ_CLEANUP issued on it. we must
145 //  no longer allow the file object / CCB to be used in I/O requests.
146 #define UDF_CCB_CLEANED                         (0x00000008)
147 // if we were invoked via the fast i/o path to perform file i/o;
148 //  we should set the CCB access/modification time at cleanup
149 #define UDF_CCB_ACCESSED                        (0x00000010)
150 #define UDF_CCB_MODIFIED                        (0x00000020)
151 // if an application process set the file date time, we must
152 //  honor that request and *not* overwrite the values at cleanup
153 #define UDF_CCB_ACCESS_TIME_SET                 (0x00000040)
154 #define UDF_CCB_MODIFY_TIME_SET                 (0x00000080)
155 #define UDF_CCB_CREATE_TIME_SET                 (0x00000100)
156 #define UDF_CCB_WRITE_TIME_SET                  (0x00000200)
157 #define UDF_CCB_ATTRIBUTES_SET                  (0x00020000)
158 
159 #define UDF_CCB_CASE_SENSETIVE                  (0x00000400)
160 
161 #ifndef UDF_READ_ONLY_BUILD
162 #define UDF_CCB_DELETE_ON_CLOSE                 (0x00000800)
163 #endif //UDF_READ_ONLY_BUILD
164 
165 // this CCB was allocated for a "volume open" operation
166 #define UDF_CCB_VOLUME_OPEN                     (0x00001000)
167 #define UDF_CCB_MATCH_ALL                       (0x00002000)
168 #define UDF_CCB_WILDCARD_PRESENT                (0x00004000)
169 #define UDF_CCB_CAN_BE_8_DOT_3                  (0x00008000)
170 #define UDF_CCB_READ_ONLY                       (0x00010000)
171 //#define UDF_CCB_ATTRIBUTES_SET                (0x00020000) // see above
172 
173 #define UDF_CCB_FLUSHED                         (0x20000000)
174 #define UDF_CCB_VALID                           (0x40000000)
175 #define UDF_CCB_NOT_FROM_ZONE                   (0x80000000)
176 
177 
178 /**************************************************************************
179     each open file/directory/volume is represented by a file control block.
180 
181     Each FCB can logically be divided into two:
182     (a) a structure that must have a field of type FSRTL_COMMON_FCB_HEADER
183          as the first field in the structure.
184          This portion should also contain other structures/resources required
185          by the NT Cache Manager
186          We will call this structure the "NT Required" FCB. Note that this
187          portion of the FCB must be allocated from non-paged pool.
188     (b) the remainder of the FCB is dependent upon the particular FSD
189          requirements.
190          This portion of the FCB could possibly be allocated from paged
191          memory, though in the UDF FSD, it will always be allocated
192          from non-paged pool.
193 
194     FCB structures are protected by the MainResource as well as the
195     PagingIoResource. Of course, if the FSD implementation requires
196     it, we can associate other syncronization structures with the
197     FCB.
198 
199     These structures must be quad-word aligned because they are zone-allocated.
200 **************************************************************************/
201 
202 typedef struct _UDFNTRequiredFCB {
203 
204     FSRTL_COMMON_FCB_HEADER             CommonFCBHeader;
205     SECTION_OBJECT_POINTERS             SectionObject;
206     FILE_LOCK                           FileLock;
207     ERESOURCE                           MainResource;
208     ERESOURCE                           PagingIoResource;
209     // we will maintain some time information here to make our life easier
210     LARGE_INTEGER                       CreationTime;
211     LARGE_INTEGER                       LastAccessTime;
212     LARGE_INTEGER                       LastWriteTime;
213     LARGE_INTEGER                       ChangeTime;
214     // NT requires that a file system maintain and honor the various
215     //  SHARE_ACCESS modes ...
216     SHARE_ACCESS                        FCBShareAccess;
217     // This counter is used to prevent unexpected structure releases
218     ULONG                               CommonRefCount;
219     PSECURITY_DESCRIPTOR                SecurityDesc;
220     ULONG                               NtReqFCBFlags;
221     // to identify the lazy writer thread(s) we will grab and store
222     //  the thread id here when a request to acquire resource(s)
223     //  arrives ..
224     uint32                              LazyWriterThreadID;
225     UCHAR                               AcqSectionCount;
226     UCHAR                               AcqFlushCount;
227 #ifdef DBG
228     PFILE_OBJECT                        FileObject;
229 #endif //DBG
230     PETHREAD                            CloseThread;
231 } UDFNTRequiredFCB, *PtrUDFNTRequiredFCB;
232 
233 #define     UDF_NTREQ_FCB_SD_MODIFIED   (0x00000001)
234 #define     UDF_NTREQ_FCB_INLIST        (0x00000002)
235 #define     UDF_NTREQ_FCB_DELETED       (0x00000004)
236 #define     UDF_NTREQ_FCB_MODIFIED      (0x00000008)
237 #define     UDF_NTREQ_FCB_VALID         (0x40000000)
238 
239 /**************************************************************************/
240 
241 #define UDF_FCB_MT NonPagedPool
242 
243 /***************************************************/
244 /*****************  W A R N I N G  *****************/
245 /***************************************************/
246 
247 /***************************************************/
248 /*      DO NOT FORGET TO UPDATE VCB's HEADER !     */
249 /***************************************************/
250 
251 typedef struct _UDFFileControlBlock {
252     UDFIdentifier                       NodeIdentifier;
253     // we will not embed the "NT Required FCB" here, 'cause we dislike
254     // troubles with Hard(&Symbolic) Links
255     PtrUDFNTRequiredFCB                 NTRequiredFCB;
256     // UDF related data
257     PUDF_FILE_INFO                      FileInfo;
258     // this FCB belongs to some mounted logical volume
259     struct _UDFVolumeControlBlock*      Vcb;
260     // to be able to access all open file(s) for a volume, we will
261     //  link all FCB structures for a logical volume together
262     LIST_ENTRY                          NextFCB;
263     // some state information for the FCB is maintained using the
264     //  flags field
265     uint32                              FCBFlags;
266     // all CCB's for this particular FCB are linked off the following
267     //  list head.
268     LIST_ENTRY                          NextCCB;
269     // whenever a file stream has a create/open operation performed,
270     //  the Reference count below is incremented AND the OpenHandle count
271     //  below is also incremented.
272     //  When an IRP_MJ_CLEANUP is received, the OpenHandle count below
273     //  is decremented.
274     //  When an IRP_MJ_CLOSE is received, the Reference count below is
275     //  decremented.
276     //  When the Reference count goes down to zero, the FCB can be de-allocated.
277     //  Note that a zero Reference count implies a zero OpenHandle count.
278     //  But when we have mapped data, we can receive no IRP_MJ_CLOSE
279     //  In this case OpenHandleCount may reach zero, but ReferenceCount may
280     //  be non-zero.
281     uint32                              ReferenceCount;
282     uint32                              OpenHandleCount;
283     uint32                              CachedOpenHandleCount;
284     // for the UDF fsd, there exists a 1-1 correspondence between a
285     //  full object pathname and a FCB
286     PtrUDFObjectName                    FCBName;
287     ERESOURCE                           CcbListResource;
288 
289     struct _UDFFileControlBlock*        ParentFcb;
290     // Pointer to IrpContextLite in delayed queue.
291     struct _UDFIrpContextLite*          IrpContextLite;
292     uint32                              CcbCount;
293 } UDFFCB, *PtrUDFFCB;
294 
295 /**************************************************************************
296     the following FCBFlags values are relevant. These flag
297     values are bit fields; therefore we can test whether
298     a bit position is set (1) or not set (0).
299 **************************************************************************/
300 #define     UDF_FCB_VALID                               (0x00000002)
301 
302 #define     UDF_FCB_PAGE_FILE                           (0x00000004)
303 #define     UDF_FCB_DIRECTORY                           (0x00000008)
304 #define     UDF_FCB_ROOT_DIRECTORY                      (0x00000010)
305 #define     UDF_FCB_WRITE_THROUGH                       (0x00000020)
306 #define     UDF_FCB_MAPPED                              (0x00000040)
307 #define     UDF_FCB_FAST_IO_READ_IN_PROGESS             (0x00000080)
308 #define     UDF_FCB_FAST_IO_WRITE_IN_PROGESS            (0x00000100)
309 #define     UDF_FCB_DELETE_ON_CLOSE                     (0x00000200)
310 #define     UDF_FCB_MODIFIED                            (0x00000400)
311 #define     UDF_FCB_ACCESSED                            (0x00000800)
312 #define     UDF_FCB_READ_ONLY                           (0x00001000)
313 #define     UDF_FCB_DELAY_CLOSE                         (0x00002000)
314 #define     UDF_FCB_DELETED                             (0x00004000)
315 
316 #define     UDF_FCB_INITIALIZED_CCB_LIST_RESOURCE       (0x00008000)
317 #define     UDF_FCB_POSTED_RENAME                       (0x00010000)
318 
319 #define     UDF_FCB_DELETE_PARENT                       (0x10000000)
320 #define     UDF_FCB_NOT_FROM_ZONE                       (0x80000000)
321 
322 /**************************************************************************
323     A logical volume is represented with the following structure.
324     This structure is allocated as part of the device extension
325     for a device object that this FSD will create, to represent
326     the mounted logical volume.
327 
328 **************************************************************************/
329 
330 #define _BROWSE_UDF_
331 
332 // Common UDF-related definitions
333 #include "Include/udf_common.h"
334 
335 // One for root
336 #define         UDF_RESIDUAL_REFERENCE              (2)
337 
338 // input flush flags
339 #define         UDF_FLUSH_FLAGS_BREAKABLE           (0x00000001)
340 // see also udf_rel.h
341 #define         UDF_FLUSH_FLAGS_LITE                (0x80000000)
342 // output flush flags
343 #define         UDF_FLUSH_FLAGS_INTERRUPTED         (0x00000001)
344 
345 #define         UDF_MAX_BG_WRITERS                  16
346 
347 typedef struct _FILTER_DEV_EXTENSION {
348     UDFIdentifier   NodeIdentifier;
349     PFILE_OBJECT    fileObject;
350     PDEVICE_OBJECT  lowerFSDeviceObject;
351 } FILTER_DEV_EXTENSION, *PFILTER_DEV_EXTENSION;
352 
353 typedef struct _UDFFS_DEV_EXTENSION {
354     UDFIdentifier   NodeIdentifier;
355 } UDFFS_DEV_EXTENSION, *PUDFFS_DEV_EXTENSION;
356 /**************************************************************************
357     The IRP context encapsulates the current request. This structure is
358     used in the "common" dispatch routines invoked either directly in
359     the context of the original requestor, or indirectly in the context
360     of a system worker thread.
361 **************************************************************************/
362 typedef struct _UDFIrpContext {
363     UDFIdentifier                   NodeIdentifier;
364     uint32                          IrpContextFlags;
365     // copied from the IRP
366     uint8                           MajorFunction;
367     // copied from the IRP
368     uint8                           MinorFunction;
369     // to queue this IRP for asynchronous processing
370     WORK_QUEUE_ITEM                 WorkQueueItem;
371     // the IRP for which this context structure was created
372     PIRP                            Irp;
373     // the target of the request (obtained from the IRP)
374     PDEVICE_OBJECT                  TargetDeviceObject;
375     // if an exception occurs, we will store the code here
376     NTSTATUS                        SavedExceptionCode;
377     // For queued close operation we save Fcb
378     _UDFFileControlBlock            *Fcb;
379     ULONG                           TreeLength;
380     PMDL                            PtrMdl;
381     PCHAR                           TransitionBuffer;
382     // support for delayed close
383 } UDFIrpContext, *PtrUDFIrpContext;
384 
385 #define         UDF_IRP_CONTEXT_CAN_BLOCK           (0x00000001)
386 #define         UDF_IRP_CONTEXT_WRITE_THROUGH       (0x00000002)
387 #define         UDF_IRP_CONTEXT_EXCEPTION           (0x00000004)
388 #define         UDF_IRP_CONTEXT_DEFERRED_WRITE      (0x00000008)
389 #define         UDF_IRP_CONTEXT_ASYNC_PROCESSING    (0x00000010)
390 #define         UDF_IRP_CONTEXT_NOT_TOP_LEVEL       (0x00000020)
391 #define         UDF_IRP_CONTEXT_FLAG_DISABLE_POPUPS (0x00000040)
392 #define         UDF_IRP_CONTEXT_FLUSH_REQUIRED      (0x00000080)
393 #define         UDF_IRP_CONTEXT_FLUSH2_REQUIRED     (0x00000100)
394 #define         UDF_IRP_CONTEXT_READ_ONLY           (0x00010000)
395 #define         UDF_IRP_CONTEXT_RES1_ACQ            (0x01000000)
396 #define         UDF_IRP_CONTEXT_RES2_ACQ            (0x02000000)
397 #define         UDF_IRP_CONTEXT_FORCED_POST         (0x20000000)
398 #define         UDF_IRP_CONTEXT_BUFFER_LOCKED       (0x40000000)
399 #define         UDF_IRP_CONTEXT_NOT_FROM_ZONE       (0x80000000)
400 
401 /**************************************************************************
402     Following structure is used to queue a request to the delayed close queue.
403     This structure should be the minimum block allocation size.
404 **************************************************************************/
405 typedef struct _UDFIrpContextLite {
406     UDFIdentifier                   NodeIdentifier;
407     //  Fcb for the file object being closed.
408     _UDFFileControlBlock            *Fcb;
409     //  List entry to attach to delayed close queue.
410     LIST_ENTRY                      DelayedCloseLinks;
411     //  User reference count for the file object being closed.
412     //ULONG                           UserReference;
413     //  Real device object.  This represents the physical device closest to the media.
414     PDEVICE_OBJECT                  RealDevice;
415     ULONG                           TreeLength;
416     uint32                          IrpContextFlags;
417 } UDFIrpContextLite, *PtrUDFIrpContextLite;
418 
419 
420 
421 
422 // a default size of the number of pages of non-paged pool allocated
423 //  for each of the zones ...
424 
425 //  Note that the values are absolutely arbitrary, the only information
426 //  worth using from the values themselves is that they increase for
427 //  larger systems (i.e. systems with more memory)
428 #define     UDF_DEFAULT_ZONE_SIZE_SMALL_SYSTEM          (0x4)
429 #define     UDF_DEFAULT_ZONE_SIZE_MEDIUM_SYSTEM         (0x8)
430 #define     UDF_DEFAULT_ZONE_SIZE_LARGE_SYSTEM          (0xc)
431 
432 // another simplistic (brain dead ? :-) method used is to simply double
433 //  the values for a "server" machine
434 
435 //  So, for all you guys who "modified" the registry ;-) to change the
436 //  wkstation into a server, tough luck !
437 #define     UDF_NTAS_MULTIPLE                               (0x2)
438 
439 typedef struct _UDFEjectWaitContext {
440     PVCB    Vcb;
441 
442     BOOLEAN SoftEjectReq;
443     UCHAR   Padding0[3];
444 
445     KEVENT  StopReq;
446     PKEVENT WaiterStopped;
447     WORK_QUEUE_ITEM EjectReqWorkQueueItem;
448 
449     GET_EVENT_USER_OUT EjectReqBuffer;
450     UCHAR   PaddingEvt[(0x40 - sizeof(GET_EVENT_USER_OUT)) & 0x0f];
451 
452     GET_CAPABILITIES_USER_OUT DevCap;
453     UCHAR   PaddingDevCap[(0x40 - sizeof(GET_CAPABILITIES_USER_OUT)) & 0x0f];
454 
455     GET_LAST_ERROR_USER_OUT Error;
456     UCHAR   PaddingError[(0x40 - sizeof(GET_LAST_ERROR_USER_OUT)) & 0x0f];
457 
458     ULONG   Zero;
459 } UDFEjectWaitContext, *PUDFEjectWaitContext;
460 
461 typedef struct _UDFBGWriteContext {
462     PVCB  Vcb;
463     PVOID Buffer;     // Target buffer
464     ULONG Length;
465     ULONG Lba;
466     ULONG WrittenBytes;
467     BOOLEAN FreeBuffer;
468     WORK_QUEUE_ITEM WorkQueueItem;
469 } UDFBGWriteContext, *PUDFBGWriteContext;
470 
471 //  Define the file system statistics struct.  Vcb->Statistics points to an
472 //  array of these (one per processor) and they must be 64 byte aligned to
473 //  prevent cache line tearing.
474 typedef struct _FILE_SYSTEM_STATISTICS {
475     //  This contains the actual data.
476     FILESYSTEM_STATISTICS Common;
477     FAT_STATISTICS Fat;
478     //  Pad this structure to a multiple of 64 bytes.
479     UCHAR Pad[64-(sizeof(FILESYSTEM_STATISTICS)+sizeof(FAT_STATISTICS))%64];
480 } FILE_SYSTEM_STATISTICS, *PFILE_SYSTEM_STATISTICS;
481 
482 //
483 typedef struct _UDFFileIDCacheItem {
484     LONGLONG Id;
485     UNICODE_STRING FullName;
486     BOOLEAN CaseSens;
487 } UDFFileIDCacheItem, *PUDFFileIDCacheItem;
488 
489 #define DIRTY_PAGE_LIMIT   32
490 
491 #endif /* _UDF_STRUCTURES_H_ */ // has this file been included?
492 
493