1 ////////////////////////////////////////////////////////////////////
2 // Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine
4 // This file was released under the GPLv2 on June 2015.
5 ////////////////////////////////////////////////////////////////////
6 /*************************************************************************
10 * Module: UDF File System Driver (Kernel mode execution only)
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).
18 *************************************************************************/
20 #ifndef _UDF_STRUCTURES_H_
21 #define _UDF_STRUCTURES_H_
24 /**************************************************************************
25 some useful definitions
26 **************************************************************************/
28 #include "Include/platform.h"
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
;
44 struct _UDFEjectWaitContext
;
45 struct _UDFFileIDCacheItem
;
49 /**************************************************************************
50 include udf related structures *here* (because we need definition of Fcb)
51 **************************************************************************/
52 #include "udf_info/udf_rel.h"
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)
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
;
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.
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
;
97 #define UDF_OBJ_NAME_NOT_FROM_ZONE (0x80000000)
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
103 For open operations performed internally by the FSD, there may not
104 exist file objects; but a CCB will definitely be created.
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
114 // each CCB is associated with a file object
115 PFILE_OBJECT FileObject
;
116 // flags (see below) associated with this CCB
118 // current index in directory is required sometimes
120 // if this CCB represents a directory object open, we may
121 // need to maintain a search pattern
122 PUNICODE_STRING DirectorySearchPattern
;
125 // Acces rights previously granted to caller's thread
126 ACCESS_MASK PreviouslyGrantedAccess
;
127 } UDFCCB
, *PtrUDFCCB
;
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 **************************************************************************/
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)
159 #define UDF_CCB_CASE_SENSETIVE (0x00000400)
161 #ifndef UDF_READ_ONLY_BUILD
162 #define UDF_CCB_DELETE_ON_CLOSE (0x00000800)
163 #endif //UDF_READ_ONLY_BUILD
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
173 #define UDF_CCB_FLUSHED (0x20000000)
174 #define UDF_CCB_VALID (0x40000000)
175 #define UDF_CCB_NOT_FROM_ZONE (0x80000000)
178 /**************************************************************************
179 each open file/directory/volume is represented by a file control block.
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
190 This portion of the FCB could possibly be allocated from paged
191 memory, though in the UDF FSD, it will always be allocated
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
199 These structures must be quad-word aligned because they are zone-allocated.
200 **************************************************************************/
202 typedef struct _UDFNTRequiredFCB
{
204 FSRTL_COMMON_FCB_HEADER CommonFCBHeader
;
205 SECTION_OBJECT_POINTERS SectionObject
;
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
;
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)
224 uint32 LazyWriterThreadID
;
225 UCHAR AcqSectionCount
;
228 PFILE_OBJECT FileObject
;
230 PETHREAD CloseThread
;
231 } UDFNTRequiredFCB
, *PtrUDFNTRequiredFCB
;
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)
239 /**************************************************************************/
241 #define UDF_FCB_MT NonPagedPool
243 /***************************************************/
244 /***************** W A R N I N G *****************/
245 /***************************************************/
247 /***************************************************/
248 /* DO NOT FORGET TO UPDATE VCB's HEADER ! */
249 /***************************************************/
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
;
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
263 // some state information for the FCB is maintained using the
266 // all CCB's for this particular FCB are linked off the following
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
274 // When an IRP_MJ_CLOSE is received, the Reference count below is
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
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
;
289 struct _UDFFileControlBlock
* ParentFcb
;
290 // Pointer to IrpContextLite in delayed queue.
291 struct _UDFIrpContextLite
* IrpContextLite
;
293 } UDFFCB
, *PtrUDFFCB
;
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)
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)
316 #define UDF_FCB_INITIALIZED_CCB_LIST_RESOURCE (0x00008000)
317 #define UDF_FCB_POSTED_RENAME (0x00010000)
319 #define UDF_FCB_DELETE_PARENT (0x10000000)
320 #define UDF_FCB_NOT_FROM_ZONE (0x80000000)
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.
328 **************************************************************************/
332 // Common UDF-related definitions
333 #include "Include/udf_common.h"
336 #define UDF_RESIDUAL_REFERENCE (2)
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)
345 #define UDF_MAX_BG_WRITERS 16
347 typedef struct _FILTER_DEV_EXTENSION
{
348 UDFIdentifier NodeIdentifier
;
349 PFILE_OBJECT fileObject
;
350 PDEVICE_OBJECT lowerFSDeviceObject
;
351 } FILTER_DEV_EXTENSION
, *PFILTER_DEV_EXTENSION
;
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
367 // copied from the IRP
369 // to queue this IRP for asynchronous processing
370 WORK_QUEUE_ITEM WorkQueueItem
;
371 // the IRP for which this context structure was created
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
;
381 PCHAR TransitionBuffer
;
382 // support for delayed close
383 } UDFIrpContext
, *PtrUDFIrpContext
;
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)
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
;
416 uint32 IrpContextFlags
;
417 } UDFIrpContextLite
, *PtrUDFIrpContextLite
;
422 // a default size of the number of pages of non-paged pool allocated
423 // for each of the zones ...
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)
432 // another simplistic (brain dead ? :-) method used is to simply double
433 // the values for a "server" machine
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)
439 typedef struct _UDFEjectWaitContext
{
442 BOOLEAN SoftEjectReq
;
446 PKEVENT WaiterStopped
;
447 WORK_QUEUE_ITEM EjectReqWorkQueueItem
;
449 GET_EVENT_USER_OUT EjectReqBuffer
;
450 UCHAR PaddingEvt
[(0x40 - sizeof(GET_EVENT_USER_OUT
)) & 0x0f];
452 GET_CAPABILITIES_USER_OUT DevCap
;
453 UCHAR PaddingDevCap
[(0x40 - sizeof(GET_CAPABILITIES_USER_OUT
)) & 0x0f];
455 GET_LAST_ERROR_USER_OUT Error
;
456 UCHAR PaddingError
[(0x40 - sizeof(GET_LAST_ERROR_USER_OUT
)) & 0x0f];
459 } UDFEjectWaitContext
, *PUDFEjectWaitContext
;
461 typedef struct _UDFBGWriteContext
{
463 PVOID Buffer
; // Target buffer
468 WORK_QUEUE_ITEM WorkQueueItem
;
469 } UDFBGWriteContext
, *PUDFBGWriteContext
;
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
;
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
;
483 typedef struct _UDFFileIDCacheItem
{
485 UNICODE_STRING FullName
;
487 } UDFFileIDCacheItem
, *PUDFFileIDCacheItem
;
489 #define DIRTY_PAGE_LIMIT 32
491 #endif /* _UDF_STRUCTURES_H_ */ // has this file been included?