update for HEAD-2003091401
[reactos.git] / drivers / fs / vfat / vfat.h
1 /* $Id$ */
2
3 #include <ddk/ntifs.h>
4
5 #define ROUND_UP(N, S) ((((N) + (S) - 1) / (S)) * (S))
6 #define ROUND_DOWN(N, S) ((N) - ((N) % (S)))
7
8 struct _BootSector
9 {
10   unsigned char  magic0, res0, magic1;
11   unsigned char  OEMName[8];
12   unsigned short BytesPerSector;
13   unsigned char  SectorsPerCluster;
14   unsigned short ReservedSectors;
15   unsigned char  FATCount;
16   unsigned short RootEntries, Sectors;
17   unsigned char  Media;
18   unsigned short FATSectors, SectorsPerTrack, Heads;
19   unsigned long  HiddenSectors, SectorsHuge;
20   unsigned char  Drive, Res1, Sig;
21   unsigned long  VolumeID;
22   unsigned char  VolumeLabel[11], SysType[8];
23   unsigned char  Res2[446];
24   unsigned long  Signatur1;
25 } __attribute__((packed));
26
27 struct _BootSector32
28 {
29   unsigned char  magic0, res0, magic1;                  // 0
30   unsigned char  OEMName[8];                            // 3
31   unsigned short BytesPerSector;                        // 11
32   unsigned char  SectorsPerCluster;                     // 13
33   unsigned short ReservedSectors;                       // 14
34   unsigned char  FATCount;                              // 16
35   unsigned short RootEntries, Sectors;                  // 17
36   unsigned char  Media;                                 // 21
37   unsigned short FATSectors, SectorsPerTrack, Heads;    // 22
38   unsigned long  HiddenSectors, SectorsHuge;            // 28
39   unsigned long  FATSectors32;                          // 36
40   unsigned short ExtFlag;                               // 40
41   unsigned short FSVersion;                             // 42
42   unsigned long  RootCluster;                           // 44
43   unsigned short FSInfoSector;                          // 48
44   unsigned short BootBackup;                            // 50
45   unsigned char  Res3[12];                              // 52
46   unsigned char  Drive;                                 // 64
47   unsigned char  Res4;                                  // 65
48   unsigned char  ExtBootSignature;                      // 66
49   unsigned long  VolumeID;                              // 67
50   unsigned char  VolumeLabel[11], SysType[8];           // 71
51   unsigned char  Res2[418];                             // 90
52   unsigned long  Signature1;                            // 508
53 } __attribute__((packed));
54
55 struct _FsInfoSector
56 {
57   unsigned long  ExtBootSignature2;                     // 0
58   unsigned char  Res6[480];                             // 4
59   unsigned long  FSINFOSignature;                       // 484
60   unsigned long  FreeCluster;                           // 488
61   unsigned long  NextCluster;                           // 492
62   unsigned char  Res7[12];                              // 496
63   unsigned long  Signatur2;                             // 508
64 } __attribute__((packed));
65
66 typedef struct _BootSector BootSector;
67
68 #define VFAT_CASE_LOWER_BASE    8                       // base is lower case
69 #define VFAT_CASE_LOWER_EXT     16                      // extension is lower case
70
71 struct _FATDirEntry
72 {
73   unsigned char  Filename[8], Ext[3];
74   unsigned char  Attrib;
75   unsigned char  lCase;
76   unsigned char  CreationTimeMs;
77   unsigned short CreationTime,CreationDate,AccessDate;
78   unsigned short FirstClusterHigh;                      // higher
79   unsigned short UpdateTime;                            //time create/update
80   unsigned short UpdateDate;                            //date create/update
81   unsigned short FirstCluster;
82   unsigned long  FileSize;
83 } __attribute__((packed));
84
85 typedef struct _FATDirEntry FATDirEntry, FAT_DIR_ENTRY, *PFAT_DIR_ENTRY;
86
87 struct _slot
88 {
89   unsigned char id;               // sequence number for slot
90   WCHAR  name0_4[5];              // first 5 characters in name
91   unsigned char attr;             // attribute byte
92   unsigned char reserved;         // always 0
93   unsigned char alias_checksum;   // checksum for 8.3 alias
94   WCHAR  name5_10[6];             // 6 more characters in name
95   unsigned char start[2];         // starting cluster number
96   WCHAR  name11_12[2];            // last 2 characters in name
97 } __attribute__((packed));
98
99
100 typedef struct _slot slot;
101
102 #define BLOCKSIZE 512
103
104 #define FAT16 (1)
105 #define FAT12 (2)
106 #define FAT32 (3)
107
108 #define VCB_VOLUME_LOCKED       0x0001
109 #define VCB_DISMOUNT_PENDING    0x0002
110
111 typedef struct
112 {
113   ULONG VolumeID;
114   ULONG FATStart;
115   ULONG FATCount;
116   ULONG FATSectors;
117   ULONG rootDirectorySectors;
118   ULONG rootStart;
119   ULONG dataStart;
120   ULONG RootCluster;
121   ULONG SectorsPerCluster;
122   ULONG BytesPerSector;
123   ULONG BytesPerCluster;
124   ULONG NumberOfClusters;
125   ULONG FatType;
126   ULONG Sectors;
127 } FATINFO, *PFATINFO;
128
129 struct _VFATFCB;
130
131 typedef struct _HASHENTRY
132 {
133   ULONG Hash;
134   struct _VFATFCB* self;
135   struct _HASHENTRY* next;
136 }
137 HASHENTRY;
138
139 #define FCB_HASH_TABLE_SIZE 1024
140
141 typedef struct
142 {
143   ERESOURCE DirResource;
144   ERESOURCE FatResource;
145
146   KSPIN_LOCK FcbListLock;
147   LIST_ENTRY FcbListHead;
148
149   PDEVICE_OBJECT StorageDevice;
150   PFILE_OBJECT FATFileObject;
151   FATINFO FatInfo;
152   ULONG LastAvailableCluster;
153   ULONG AvailableClusters;
154   BOOLEAN AvailableClustersValid;
155   ULONG Flags;  
156   struct _VFATFCB * VolumeFcb;
157   struct _HASHENTRY* FcbHashTable[FCB_HASH_TABLE_SIZE];
158
159   LIST_ENTRY VolumeListEntry;
160 } DEVICE_EXTENSION, *PDEVICE_EXTENSION, VCB, *PVCB;
161
162 typedef struct
163 {
164   PDRIVER_OBJECT DriverObject;
165   PDEVICE_OBJECT DeviceObject;
166   ULONG Flags;
167   ERESOURCE VolumeListLock;
168   LIST_ENTRY VolumeListHead;
169   NPAGED_LOOKASIDE_LIST FcbLookasideList;
170   NPAGED_LOOKASIDE_LIST CcbLookasideList;
171   NPAGED_LOOKASIDE_LIST IrpContextLookasideList;
172 } VFAT_GLOBAL_DATA, *PVFAT_GLOBAL_DATA;
173
174 extern PVFAT_GLOBAL_DATA VfatGlobalData;
175
176 #define FCB_CACHE_INITIALIZED   0x0001
177 #define FCB_DELETE_PENDING      0x0002
178 #define FCB_IS_FAT              0x0004
179 #define FCB_IS_PAGE_FILE        0x0008
180 #define FCB_IS_VOLUME           0x0010
181
182 typedef struct _VFATFCB
183 {
184   /* FCB header required by ROS/NT */
185   FSRTL_COMMON_FCB_HEADER RFCB;
186   SECTION_OBJECT_POINTERS SectionObjectPointers;
187   ERESOURCE MainResource;
188   ERESOURCE PagingIoResource;
189   /* end FCB header required by ROS/NT */
190
191   /* */
192   FATDirEntry entry;
193
194   /* point on filename (250 chars max) in PathName */
195   WCHAR *ObjectName;
196
197   /* path+filename 260 max */
198   WCHAR PathName[MAX_PATH];
199
200   /* short file name */
201   WCHAR ShortName[14];
202
203   /* */
204   LONG RefCount;
205
206   /* List of FCB's for this volume */
207   LIST_ENTRY FcbListEntry;
208
209   /* pointer to the parent fcb */
210   struct _VFATFCB* parentFcb;
211
212   /* Flags for the fcb */
213   ULONG Flags;
214
215   /* pointer to the file object which has initialized the fcb */
216   PFILE_OBJECT FileObject;
217
218   /* Directory index for the short name entry */
219   ULONG dirIndex;
220
221   /* Directory index where the long name starts */
222   ULONG startIndex;
223
224   /* Share access for the file object */
225   SHARE_ACCESS FCBShareAccess;
226
227   /* Entry into the hash table for the path + long name */
228   HASHENTRY Hash;
229
230   /* Entry into the hash table for the path + short name */
231   HASHENTRY ShortHash;
232
233   /* List of byte-range locks for this file */
234   FILE_LOCK FileLock;
235
236 } VFATFCB, *PVFATFCB;
237
238 typedef struct _VFATCCB
239 {
240   LARGE_INTEGER  CurrentByteOffset;
241   /* for DirectoryControl */
242   ULONG Entry;
243   /* for DirectoryControl */
244   PWCHAR DirectorySearchPattern;
245   ULONG LastCluster;
246   ULONG LastOffset;
247
248 } VFATCCB, *PVFATCCB;
249
250 #ifndef TAG
251 #define TAG(A, B, C, D) (ULONG)(((A)<<0) + ((B)<<8) + ((C)<<16) + ((D)<<24))
252 #endif
253
254 #define TAG_CCB TAG('V', 'C', 'C', 'B')
255 #define TAG_FCB TAG('V', 'F', 'C', 'B')
256 #define TAG_IRP TAG('V', 'I', 'R', 'P')
257
258 #define ENTRIES_PER_SECTOR (BLOCKSIZE / sizeof(FATDirEntry))
259
260 typedef struct __DOSTIME
261 {
262    WORD Second:5;
263    WORD Minute:6;
264    WORD Hour:5;
265 }
266 DOSTIME, *PDOSTIME;
267
268 typedef struct __DOSDATE
269 {
270    WORD Day:5;
271    WORD Month:4;
272    WORD Year:5;
273 }
274 DOSDATE, *PDOSDATE;
275
276 #define IRPCONTEXT_CANWAIT  0x0001
277
278 typedef struct
279 {
280    PIRP Irp;
281    PDEVICE_OBJECT DeviceObject;
282    PDEVICE_EXTENSION DeviceExt;
283    ULONG Flags;
284    WORK_QUEUE_ITEM WorkQueueItem;
285    PIO_STACK_LOCATION Stack;
286    UCHAR MajorFunction;
287    UCHAR MinorFunction;
288    PFILE_OBJECT FileObject;
289 } VFAT_IRP_CONTEXT, *PVFAT_IRP_CONTEXT;
290
291 /*  ------------------------------------------------------  shutdown.c  */
292
293 NTSTATUS STDCALL VfatShutdown (PDEVICE_OBJECT DeviceObject,
294                                PIRP Irp);
295
296 /*  --------------------------------------------------------  volume.c  */
297
298 NTSTATUS VfatQueryVolumeInformation (PVFAT_IRP_CONTEXT IrpContext);
299
300 NTSTATUS VfatSetVolumeInformation (PVFAT_IRP_CONTEXT IrpContext);
301
302 /*  ------------------------------------------------------  blockdev.c  */
303
304 NTSTATUS VfatReadDisk(IN PDEVICE_OBJECT pDeviceObject,
305                       IN PLARGE_INTEGER ReadOffset,
306                       IN ULONG ReadLength,
307                       IN PUCHAR Buffer);
308
309 NTSTATUS VfatWriteDisk(IN PDEVICE_OBJECT pDeviceObject,
310                        IN PLARGE_INTEGER WriteOffset,
311                        IN ULONG WriteLength,
312                        IN PUCHAR Buffer);
313
314 NTSTATUS VfatBlockDeviceIoControl (IN PDEVICE_OBJECT DeviceObject,
315                                    IN ULONG CtlCode,
316                                    IN PVOID InputBuffer,
317                                    IN ULONG InputBufferSize,
318                                    IN OUT PVOID OutputBuffer, 
319                                    IN OUT PULONG pOutputBufferSize);
320
321 /*  -----------------------------------------------------------  dir.c  */
322
323 NTSTATUS VfatDirectoryControl (PVFAT_IRP_CONTEXT);
324
325 BOOL FsdDosDateTimeToFileTime (WORD wDosDate,
326                                WORD wDosTime,
327                                TIME *FileTime);
328
329 BOOL FsdFileTimeToDosDateTime (TIME *FileTime,
330                                WORD *pwDosDate,
331                                WORD *pwDosTime);
332
333 /*  --------------------------------------------------------  create.c  */
334
335 NTSTATUS VfatCreate (PVFAT_IRP_CONTEXT IrpContext);
336
337 NTSTATUS VfatOpenFile (PDEVICE_EXTENSION DeviceExt,
338                        PFILE_OBJECT FileObject,
339                        PWSTR FileName);
340
341 NTSTATUS FindFile (PDEVICE_EXTENSION DeviceExt,
342                    PVFATFCB Fcb,
343                    PVFATFCB Parent,
344                    PWSTR FileToFind,
345                    PULONG pDirIndex,
346                    PULONG pDirIndex2);
347
348 VOID vfat8Dot3ToString (PFAT_DIR_ENTRY pEntry,
349                         PWSTR pName);
350
351 NTSTATUS ReadVolumeLabel(PDEVICE_EXTENSION DeviceExt,
352                          PVPB Vpb);
353
354 BOOLEAN IsDeletedEntry (PVOID Block,
355                         ULONG Offset);
356
357 BOOLEAN IsLastEntry (PVOID Block,
358                      ULONG Offset);
359
360 /*  ---------------------------------------------------------  close.c  */
361
362 NTSTATUS VfatClose (PVFAT_IRP_CONTEXT IrpContext);
363
364 NTSTATUS VfatCloseFile(PDEVICE_EXTENSION DeviceExt,
365                        PFILE_OBJECT FileObject);
366
367 /*  -------------------------------------------------------  cleanup.c  */
368
369 NTSTATUS VfatCleanup (PVFAT_IRP_CONTEXT IrpContext);
370
371 /*  ---------------------------------------------------------  fsctl.c  */
372
373 NTSTATUS VfatFileSystemControl (PVFAT_IRP_CONTEXT IrpContext);
374
375 /*  ---------------------------------------------------------  finfo.c  */
376
377 NTSTATUS VfatQueryInformation (PVFAT_IRP_CONTEXT IrpContext);
378
379 NTSTATUS VfatSetInformation (PVFAT_IRP_CONTEXT IrpContext);
380
381 NTSTATUS
382 VfatSetAllocationSizeInformation(PFILE_OBJECT FileObject, 
383                                  PVFATFCB Fcb,
384                                  PDEVICE_EXTENSION DeviceExt,
385                                  PLARGE_INTEGER AllocationSize);
386
387 /*  ---------------------------------------------------------  iface.c  */
388
389 NTSTATUS STDCALL DriverEntry (PDRIVER_OBJECT DriverObject,
390                               PUNICODE_STRING RegistryPath);
391
392 /*  ---------------------------------------------------------  dirwr.c  */
393
394 NTSTATUS VfatAddEntry (PDEVICE_EXTENSION DeviceExt,
395                        PFILE_OBJECT pFileObject,
396                        ULONG RequestedOptions,UCHAR ReqAttr);
397
398 NTSTATUS VfatUpdateEntry (PDEVICE_EXTENSION DeviceExt,
399                           PFILE_OBJECT pFileObject);
400
401 NTSTATUS delEntry(PDEVICE_EXTENSION,
402                   PFILE_OBJECT);
403
404 /*  --------------------------------------------------------  string.c  */
405
406 BOOLEAN wstrcmpjoki (PWSTR s1,
407                      PWSTR s2);
408
409 PWCHAR vfatGetNextPathElement (PWCHAR  pFileName);
410
411 VOID vfatWSubString (PWCHAR pTarget,
412                      const PWCHAR pSource,
413                      size_t pLength);
414
415 BOOL  vfatIsFileNameValid (PWCHAR pFileName);
416
417 /*  -----------------------------------------------------------  fat.c  */
418
419 NTSTATUS OffsetToCluster (PDEVICE_EXTENSION DeviceExt,
420                           ULONG FirstCluster,
421                           ULONG FileOffset,
422                           PULONG Cluster,
423                           BOOLEAN Extend);
424
425 ULONGLONG ClusterToSector (PDEVICE_EXTENSION DeviceExt,
426                            ULONG Cluster);
427
428 NTSTATUS GetNextCluster (PDEVICE_EXTENSION DeviceExt,
429                          ULONG CurrentCluster,
430                          PULONG NextCluster,
431                          BOOLEAN Extend);
432
433 NTSTATUS CountAvailableClusters (PDEVICE_EXTENSION DeviceExt,
434                                  PLARGE_INTEGER Clusters);
435
436 NTSTATUS
437 WriteCluster(PDEVICE_EXTENSION DeviceExt,
438              ULONG ClusterToWrite,
439              ULONG NewValue);
440
441 /*  ------------------------------------------------------  direntry.c  */
442
443 ULONG  vfatDirEntryGetFirstCluster (PDEVICE_EXTENSION  pDeviceExt,
444                                     PFAT_DIR_ENTRY  pDirEntry);
445
446 BOOL  vfatIsDirEntryDeleted (FATDirEntry * pFatDirEntry);
447
448 BOOL  vfatIsDirEntryVolume (FATDirEntry * pFatDirEntry);
449
450 BOOL  vfatIsDirEntryEndMarker (FATDirEntry * pFatDirEntry);
451
452 VOID vfatGetDirEntryName (PFAT_DIR_ENTRY pDirEntry,
453                           PWSTR  pEntryName);
454
455 NTSTATUS vfatGetNextDirEntry(PVOID * pContext,
456                              PVOID * pPage,
457                              IN PVFATFCB pDirFcb,
458                              IN OUT PULONG pDirIndex,
459                              OUT PWSTR pFileName,
460                              OUT PFAT_DIR_ENTRY pDirEntry,
461                              OUT PULONG pStartIndex);
462
463 /*  -----------------------------------------------------------  fcb.c  */
464
465 PVFATFCB vfatNewFCB (PWCHAR pFileName);
466
467 VOID vfatDestroyFCB (PVFATFCB  pFCB);
468
469 VOID vfatDestroyCCB(PVFATCCB pCcb);
470
471 VOID vfatGrabFCB (PDEVICE_EXTENSION  pVCB,
472                   PVFATFCB  pFCB);
473
474 VOID vfatReleaseFCB (PDEVICE_EXTENSION  pVCB,
475                      PVFATFCB  pFCB);
476
477 VOID vfatAddFCBToTable (PDEVICE_EXTENSION  pVCB,
478                         PVFATFCB  pFCB);
479
480 PVFATFCB vfatGrabFCBFromTable (PDEVICE_EXTENSION  pDeviceExt,
481                                PWSTR  pFileName);
482
483 PVFATFCB vfatMakeRootFCB (PDEVICE_EXTENSION  pVCB);
484
485 PVFATFCB vfatOpenRootFCB (PDEVICE_EXTENSION  pVCB);
486
487 BOOL vfatFCBIsDirectory (PVFATFCB FCB);
488
489 BOOL vfatFCBIsRoot(PVFATFCB FCB);
490
491 NTSTATUS vfatAttachFCBToFileObject (PDEVICE_EXTENSION  vcb,
492                                     PVFATFCB  fcb,
493                                     PFILE_OBJECT  fileObject);
494
495 NTSTATUS vfatDirFindFile (PDEVICE_EXTENSION  pVCB,
496                           PVFATFCB  parentFCB,
497                           PWSTR  elementName,
498                           PVFATFCB * fileFCB);
499
500 NTSTATUS vfatGetFCBForFile (PDEVICE_EXTENSION  pVCB,
501                             PVFATFCB  *pParentFCB,
502                             PVFATFCB  *pFCB,
503                             const PWSTR  pFileName);
504
505 NTSTATUS vfatMakeFCBFromDirEntry (PVCB  vcb,
506                                   PVFATFCB  directoryFCB,
507                                   PWSTR  longName,
508                                   PFAT_DIR_ENTRY  dirEntry,
509                                   ULONG startIndex,
510                                   ULONG dirIndex,
511                                   PVFATFCB * fileFCB);
512
513 /*  ------------------------------------------------------------  rw.c  */
514
515 NTSTATUS VfatRead (PVFAT_IRP_CONTEXT IrpContext);
516
517 NTSTATUS VfatWrite (PVFAT_IRP_CONTEXT IrpContext);
518
519 NTSTATUS NextCluster(PDEVICE_EXTENSION DeviceExt,
520                      ULONG FirstCluster,
521                      PULONG CurrentCluster,
522                      BOOLEAN Extend);
523
524 /*  -----------------------------------------------------------  misc.c  */
525
526 NTSTATUS VfatQueueRequest(PVFAT_IRP_CONTEXT IrpContext);
527
528 PVFAT_IRP_CONTEXT VfatAllocateIrpContext(PDEVICE_OBJECT DeviceObject,
529                                          PIRP Irp);
530
531 VOID VfatFreeIrpContext(PVFAT_IRP_CONTEXT IrpContext);
532
533 NTSTATUS STDCALL VfatBuildRequest (PDEVICE_OBJECT DeviceObject,
534                                    PIRP Irp);
535
536 PVOID VfatGetUserBuffer(IN PIRP);
537
538 NTSTATUS VfatLockUserBuffer(IN PIRP, IN ULONG,
539                             IN LOCK_OPERATION);
540
541 NTSTATUS 
542 VfatSetExtendedAttributes(PFILE_OBJECT FileObject, 
543                           PVOID Ea,
544                           ULONG EaLength);
545 /*  ------------------------------------------------------------- flush.c  */
546
547 NTSTATUS VfatFlush(PVFAT_IRP_CONTEXT IrpContext);
548
549 NTSTATUS VfatFlushVolume(PDEVICE_EXTENSION DeviceExt, PVFATFCB VolumeFcb);
550
551 /* EOF */