:pserver:cvsanon@mok.lvcm.com:/CVS/ReactOS reactos
[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 long  BootBackup;                            // 50
45   unsigned char  Res3[10];                              // 54
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 _BootBackupSector
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 struct _FATDirEntry
69 {
70   unsigned char  Filename[8], Ext[3], Attrib, Res[2];
71   unsigned short CreationTime,CreationDate,AccessDate;
72   unsigned short FirstClusterHigh;                      // higher
73   unsigned short UpdateTime;                            //time create/update
74   unsigned short UpdateDate;                            //date create/update
75   unsigned short FirstCluster;
76   unsigned long  FileSize;
77 } __attribute__((packed));
78
79 typedef struct _FATDirEntry FATDirEntry, FAT_DIR_ENTRY, *PFAT_DIR_ENTRY;
80
81 struct _slot
82 {
83   unsigned char id;               // sequence number for slot
84   WCHAR  name0_4[5];              // first 5 characters in name
85   unsigned char attr;             // attribute byte
86   unsigned char reserved;         // always 0
87   unsigned char alias_checksum;   // checksum for 8.3 alias
88   WCHAR  name5_10[6];             // 6 more characters in name
89   unsigned char start[2];         // starting cluster number
90   WCHAR  name11_12[2];            // last 2 characters in name
91 } __attribute__((packed));
92
93
94 typedef struct _slot slot;
95
96 #define BLOCKSIZE 512
97
98 #define FAT16 (1)
99 #define FAT12 (2)
100 #define FAT32 (3)
101
102 #define VCB_VOLUME_LOCKED       0x0001
103 #define VCB_DISMOUNT_PENDING    0x0002
104
105 typedef struct
106 {
107   ULONG VolumeID;
108   ULONG FATStart;
109   ULONG FATCount;
110   ULONG FATSectors;
111   ULONG rootDirectorySectors;
112   ULONG rootStart;
113   ULONG dataStart;
114   ULONG RootCluster;
115   ULONG SectorsPerCluster;
116   ULONG BytesPerSector;
117   ULONG BytesPerCluster;
118   ULONG NumberOfClusters;
119   ULONG FatType;
120   ULONG Sectors;
121 } FATINFO, *PFATINFO;
122
123 struct _VFATFCB;
124
125 typedef struct
126 {
127   ERESOURCE DirResource;
128   ERESOURCE FatResource;
129
130   KSPIN_LOCK FcbListLock;
131   LIST_ENTRY FcbListHead;
132
133   PDEVICE_OBJECT StorageDevice;
134   PFILE_OBJECT FATFileObject;
135   FATINFO FatInfo;
136   ULONG LastAvailableCluster;
137   ULONG AvailableClusters;
138   BOOLEAN AvailableClustersValid;
139   ULONG Flags;  
140   struct _VFATFCB * VolumeFcb;
141 } DEVICE_EXTENSION, *PDEVICE_EXTENSION, VCB, *PVCB;
142
143 typedef struct
144 {
145   PDRIVER_OBJECT DriverObject;
146   PDEVICE_OBJECT DeviceObject;
147   ULONG Flags;
148 } VFAT_GLOBAL_DATA, *PVFAT_GLOBAL_DATA;
149
150 extern PVFAT_GLOBAL_DATA VfatGlobalData;
151
152 #define FCB_CACHE_INITIALIZED   0x0001
153 #define FCB_DELETE_PENDING      0x0002
154 #define FCB_IS_FAT              0x0004
155 #define FCB_IS_PAGE_FILE        0x0008
156 #define FCB_IS_VOLUME           0x0010
157 #define FCB_UPDATE_DIRENTRY     0x0020
158
159 typedef struct _VFATFCB
160 {
161   REACTOS_COMMON_FCB_HEADER RFCB;
162   SECTION_OBJECT_POINTERS SectionObjectPointers;
163   FATDirEntry entry;
164   /* point on filename (250 chars max) in PathName */
165   WCHAR *ObjectName;
166   /* path+filename 260 max */
167   WCHAR PathName[MAX_PATH];
168   LONG RefCount;
169   PDEVICE_EXTENSION pDevExt;
170   LIST_ENTRY FcbListEntry;
171   struct _VFATFCB* parentFcb;
172   ULONG Flags;
173   PFILE_OBJECT FileObject;
174   ULONG dirIndex;
175   ERESOURCE PagingIoResource;
176   ERESOURCE MainResource;
177   ULONG TimerCount;
178   SHARE_ACCESS FCBShareAccess;
179
180   /* Structure members used only for paging files. */
181   ULONG FatChainSize;
182   PULONG FatChain;
183 } VFATFCB, *PVFATFCB;
184
185 typedef struct _VFATCCB
186 {
187   VFATFCB *   pFcb;
188   LIST_ENTRY     NextCCB;
189   PFILE_OBJECT   PtrFileObject;
190   LARGE_INTEGER  CurrentByteOffset;
191   /* for DirectoryControl */
192   ULONG Entry;
193   /* for DirectoryControl */
194   PWCHAR DirectorySearchPattern;
195   ULONG LastCluster;
196   ULONG LastOffset;
197
198 } VFATCCB, *PVFATCCB;
199
200 #define TAG(A, B, C, D) (ULONG)(((A)<<0) + ((B)<<8) + ((C)<<16) + ((D)<<24))
201
202 #define TAG_CCB TAG('V', 'C', 'C', 'B')
203
204 #define ENTRIES_PER_SECTOR (BLOCKSIZE / sizeof(FATDirEntry))
205
206 typedef struct __DOSTIME
207 {
208    WORD Second:5;
209    WORD Minute:6;
210    WORD Hour:5;
211 }
212 DOSTIME, *PDOSTIME;
213
214 typedef struct __DOSDATE
215 {
216    WORD Day:5;
217    WORD Month:4;
218    WORD Year:5;
219 }
220 DOSDATE, *PDOSDATE;
221
222 #define IRPCONTEXT_CANWAIT  0x0001
223
224 typedef struct
225 {
226    PIRP Irp;
227    PDEVICE_OBJECT DeviceObject;
228    PDEVICE_EXTENSION DeviceExt;
229    ULONG Flags;
230    WORK_QUEUE_ITEM WorkQueueItem;
231    PIO_STACK_LOCATION Stack;
232    UCHAR MajorFunction;
233    UCHAR MinorFunction;
234    PFILE_OBJECT FileObject;
235 } VFAT_IRP_CONTEXT, *PVFAT_IRP_CONTEXT;
236
237 /*  ------------------------------------------------------  shutdown.c  */
238
239 NTSTATUS STDCALL VfatShutdown (PDEVICE_OBJECT DeviceObject,
240                                PIRP Irp);
241
242 /*  --------------------------------------------------------  volume.c  */
243
244 NTSTATUS VfatQueryVolumeInformation (PVFAT_IRP_CONTEXT IrpContext);
245
246 NTSTATUS VfatSetVolumeInformation (PVFAT_IRP_CONTEXT IrpContext);
247
248 /*  ------------------------------------------------------  blockdev.c  */
249
250 NTSTATUS VfatReadDisk(IN PDEVICE_OBJECT pDeviceObject,
251                       IN PLARGE_INTEGER ReadOffset,
252                       IN ULONG ReadLength,
253                       IN PUCHAR Buffer);
254
255 NTSTATUS VfatWriteDisk(IN PDEVICE_OBJECT pDeviceObject,
256                        IN PLARGE_INTEGER WriteOffset,
257                        IN ULONG WriteLength,
258                        IN PUCHAR Buffer);
259
260 NTSTATUS VfatBlockDeviceIoControl (IN PDEVICE_OBJECT DeviceObject,
261                                    IN ULONG CtlCode,
262                                    IN PVOID InputBuffer,
263                                    IN ULONG InputBufferSize,
264                                    IN OUT PVOID OutputBuffer, 
265                                    IN OUT PULONG pOutputBufferSize);
266
267 /*  -----------------------------------------------------------  dir.c  */
268
269 NTSTATUS VfatDirectoryControl (PVFAT_IRP_CONTEXT);
270
271 BOOL FsdDosDateTimeToFileTime (WORD wDosDate,
272                                WORD wDosTime,
273                                TIME *FileTime);
274
275 BOOL FsdFileTimeToDosDateTime (TIME *FileTime,
276                                WORD *pwDosDate,
277                                WORD *pwDosTime);
278
279 /*  --------------------------------------------------------  create.c  */
280
281 NTSTATUS VfatCreate (PVFAT_IRP_CONTEXT IrpContext);
282
283 NTSTATUS VfatOpenFile (PDEVICE_EXTENSION DeviceExt,
284                        PFILE_OBJECT FileObject,
285                        PWSTR FileName);
286
287 NTSTATUS FindFile (PDEVICE_EXTENSION DeviceExt,
288                    PVFATFCB Fcb,
289                    PVFATFCB Parent,
290                    PWSTR FileToFind,
291                    PULONG pDirIndex,
292                    PULONG pDirIndex2);
293
294 VOID vfat8Dot3ToString (PCHAR pBasename,
295                         PCHAR pExtension,
296                         PWSTR pName);
297
298 NTSTATUS ReadVolumeLabel(PDEVICE_EXTENSION DeviceExt,
299                          PVPB Vpb);
300
301 BOOLEAN IsDeletedEntry (PVOID Block,
302                         ULONG Offset);
303
304 BOOLEAN IsLastEntry (PVOID Block,
305                      ULONG Offset);
306
307 /*  ---------------------------------------------------------  close.c  */
308
309 NTSTATUS VfatClose (PVFAT_IRP_CONTEXT IrpContext);
310
311 NTSTATUS VfatCloseFile(PDEVICE_EXTENSION DeviceExt,
312                        PFILE_OBJECT FileObject);
313
314 /*  -------------------------------------------------------  cleanup.c  */
315
316 NTSTATUS VfatCleanup (PVFAT_IRP_CONTEXT IrpContext);
317
318 /*  ---------------------------------------------------------  fsctl.c  */
319
320 NTSTATUS VfatFileSystemControl (PVFAT_IRP_CONTEXT IrpContext);
321
322 /*  ---------------------------------------------------------  finfo.c  */
323
324 NTSTATUS VfatQueryInformation (PVFAT_IRP_CONTEXT IrpContext);
325
326 NTSTATUS VfatSetInformation (PVFAT_IRP_CONTEXT IrpContext);
327
328 NTSTATUS
329 VfatSetAllocationSizeInformation(PFILE_OBJECT FileObject, 
330                                  PVFATFCB Fcb,
331                                  PDEVICE_EXTENSION DeviceExt,
332                                  PLARGE_INTEGER AllocationSize);
333
334 /*  ---------------------------------------------------------  iface.c  */
335
336 NTSTATUS STDCALL DriverEntry (PDRIVER_OBJECT DriverObject,
337                               PUNICODE_STRING RegistryPath);
338
339 /*  ---------------------------------------------------------  dirwr.c  */
340
341 NTSTATUS VfatAddEntry (PDEVICE_EXTENSION DeviceExt,
342                        PFILE_OBJECT pFileObject,
343                        ULONG RequestedOptions,UCHAR ReqAttr);
344
345 NTSTATUS VfatUpdateEntry (PDEVICE_EXTENSION DeviceExt,
346                           PFILE_OBJECT pFileObject);
347
348 NTSTATUS delEntry(PDEVICE_EXTENSION,
349                   PFILE_OBJECT);
350
351 /*  --------------------------------------------------------  string.c  */
352
353 VOID vfat_initstr (wchar_t *wstr,
354                    ULONG wsize);
355
356 wchar_t* vfat_wcsncat (wchar_t * dest,
357                        const wchar_t * src,
358                        size_t wstart,
359                        size_t wcount);
360
361 wchar_t* vfat_wcsncpy (wchar_t * dest,
362                        const wchar_t *src,
363                        size_t wcount);
364
365 wchar_t* vfat_movstr (wchar_t *src,
366                       ULONG dpos,
367                       ULONG spos,
368                       ULONG len);
369
370 BOOLEAN wstrcmpi (PWSTR s1,
371                   PWSTR s2);
372
373 BOOLEAN wstrcmpjoki (PWSTR s1,
374                      PWSTR s2);
375
376 PWCHAR vfatGetNextPathElement (PWCHAR  pFileName);
377
378 VOID vfatWSubString (PWCHAR pTarget,
379                      const PWCHAR pSource,
380                      size_t pLength);
381
382 BOOL  vfatIsFileNameValid (PWCHAR pFileName);
383
384 /*  -----------------------------------------------------------  fat.c  */
385
386 NTSTATUS OffsetToCluster (PDEVICE_EXTENSION DeviceExt,
387                           PVFATFCB Fcb,
388                           ULONG FirstCluster,
389                           ULONG FileOffset,
390                           PULONG Cluster,
391                           BOOLEAN Extend);
392
393 ULONG ClusterToSector (PDEVICE_EXTENSION DeviceExt,
394                        ULONG Cluster);
395
396 NTSTATUS GetNextCluster (PDEVICE_EXTENSION DeviceExt,
397                          ULONG CurrentCluster,
398                          PULONG NextCluster,
399                          BOOLEAN Extend);
400
401 NTSTATUS GetNextSector (PDEVICE_EXTENSION DeviceExt,
402                         ULONG CurrentSector,
403                         PULONG NextSector,
404                         BOOLEAN Extend);
405
406 NTSTATUS CountAvailableClusters (PDEVICE_EXTENSION DeviceExt,
407                                  PLARGE_INTEGER Clusters);
408
409 /*  ------------------------------------------------------  direntry.c  */
410
411 ULONG  vfatDirEntryGetFirstCluster (PDEVICE_EXTENSION  pDeviceExt,
412                                     PFAT_DIR_ENTRY  pDirEntry);
413
414 BOOL  vfatIsDirEntryDeleted (FATDirEntry * pFatDirEntry);
415
416 BOOL  vfatIsDirEntryVolume (FATDirEntry * pFatDirEntry);
417
418 BOOL  vfatIsDirEntryEndMarker (FATDirEntry * pFatDirEntry);
419
420 VOID vfatGetDirEntryName (PFAT_DIR_ENTRY pDirEntry,
421                           PWSTR  pEntryName);
422
423 NTSTATUS  vfatGetNextDirEntry (PDEVICE_EXTENSION  pDeviceExt,
424                                PVFATFCB  pDirectoryFCB,
425                                ULONG * pDirectoryIndex,
426                                PWSTR pLongFileName,
427                                PFAT_DIR_ENTRY pDirEntry);
428
429 /*  -----------------------------------------------------------  fcb.c  */
430
431 PVFATFCB vfatNewFCB (PWCHAR pFileName);
432
433 VOID vfatDestroyFCB (PVFATFCB  pFCB);
434
435 VOID vfatGrabFCB (PDEVICE_EXTENSION  pVCB,
436                   PVFATFCB  pFCB);
437
438 VOID vfatReleaseFCB (PDEVICE_EXTENSION  pVCB,
439                      PVFATFCB  pFCB);
440
441 VOID vfatAddFCBToTable (PDEVICE_EXTENSION  pVCB,
442                         PVFATFCB  pFCB);
443
444 PVFATFCB vfatGrabFCBFromTable (PDEVICE_EXTENSION  pDeviceExt,
445                                PWSTR  pFileName);
446
447 PVFATFCB vfatMakeRootFCB (PDEVICE_EXTENSION  pVCB);
448
449 PVFATFCB vfatOpenRootFCB (PDEVICE_EXTENSION  pVCB);
450
451 BOOL vfatFCBIsDirectory (PDEVICE_EXTENSION pVCB,
452                          PVFATFCB FCB);
453
454 NTSTATUS vfatAttachFCBToFileObject (PDEVICE_EXTENSION  vcb,
455                                     PVFATFCB  fcb,
456                                     PFILE_OBJECT  fileObject);
457
458 NTSTATUS vfatDirFindFile (PDEVICE_EXTENSION  pVCB,
459                           PVFATFCB  parentFCB,
460                           PWSTR  elementName,
461                           PVFATFCB * fileFCB);
462
463 NTSTATUS vfatGetFCBForFile (PDEVICE_EXTENSION  pVCB,
464                             PVFATFCB  *pParentFCB,
465                             PVFATFCB  *pFCB,
466                             const PWSTR  pFileName);
467
468 NTSTATUS vfatMakeFCBFromDirEntry (PVCB  vcb,
469                                   PVFATFCB  directoryFCB,
470                                   PWSTR  longName,
471                                   PFAT_DIR_ENTRY  dirEntry,
472                                   ULONG dirIndex,
473                                   PVFATFCB * fileFCB);
474
475 /*  ------------------------------------------------------------  rw.c  */
476
477 NTSTATUS VfatRead (PVFAT_IRP_CONTEXT IrpContext);
478
479 NTSTATUS VfatWrite (PVFAT_IRP_CONTEXT IrpContext);
480
481 NTSTATUS VfatWriteFile (PDEVICE_EXTENSION DeviceExt,
482                         PFILE_OBJECT FileObject,
483                         PVOID Buffer,
484                         ULONG Length,
485                         ULONG WriteOffset,
486                         BOOLEAN NoCache,
487                         BOOLEAN PageIo);
488
489
490 NTSTATUS VfatReadFile (PDEVICE_EXTENSION DeviceExt,
491                        PFILE_OBJECT FileObject,
492                        PVOID Buffer, ULONG Length,
493                        ULONG ReadOffset,
494                        PULONG LengthRead,
495                        ULONG NoCache);
496
497 NTSTATUS NextCluster(PDEVICE_EXTENSION DeviceExt,
498                      PVFATFCB Fcb,
499                      ULONG FirstCluster,
500                      PULONG CurrentCluster,
501                      BOOLEAN Extend);
502
503 /*  -----------------------------------------------------------  misc.c  */
504
505 NTSTATUS VfatQueueRequest(PVFAT_IRP_CONTEXT IrpContext);
506
507 PVFAT_IRP_CONTEXT VfatAllocateIrpContext(PDEVICE_OBJECT DeviceObject,
508                                          PIRP Irp);
509
510 VOID VfatFreeIrpContext(PVFAT_IRP_CONTEXT IrpContext);
511
512 NTSTATUS STDCALL VfatBuildRequest (PDEVICE_OBJECT DeviceObject,
513                                    PIRP Irp);
514
515 PVOID VfatGetUserBuffer(IN PIRP);
516
517 NTSTATUS VfatLockUserBuffer(IN PIRP, IN ULONG,
518                             IN LOCK_OPERATION);
519
520 NTSTATUS 
521 VfatSetExtendedAttributes(PFILE_OBJECT FileObject, 
522                           PVOID Ea,
523                           ULONG EaLength);
524 /* EOF */