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