[CDFS]
[reactos.git] / reactos / drivers / filesystems / fastfat_new / fullfat.c
1 /*
2 * PROJECT: ReactOS FAT file system driver
3 * LICENSE: GNU GPLv3 as published by the Free Software Foundation
4 * FILE: drivers/filesystems/fastfat/fullfat.c
5 * PURPOSE: FullFAT integration routines
6 * PROGRAMMERS: Aleksey Bragin (aleksey@reactos.org)
7 */
8
9 /* INCLUDES *****************************************************************/
10
11 #define NDEBUG
12 #include "fastfat.h"
13
14 /* GLOBALS ******************************************************************/
15
16 #define TAG_FULLFAT 'FLUF'
17
18 /* FUNCTIONS ****************************************************************/
19
20 VOID *
21 FF_Malloc(FF_T_UINT32 allocSize)
22 {
23 return ExAllocatePoolWithTag(PagedPool, allocSize, TAG_FULLFAT);
24 }
25
26 VOID
27 FF_Free(VOID *pBuffer)
28 {
29 ExFreePoolWithTag(pBuffer, TAG_FULLFAT);
30 }
31
32 FF_T_SINT32
33 FatWriteBlocks(FF_T_UINT8 *pBuffer, FF_T_UINT32 SectorAddress, FF_T_UINT32 Count, void *pParam)
34 {
35 DPRINT1("FatWriteBlocks %p %d %d %p\n", pBuffer, SectorAddress, Count, pParam);
36
37 return 0;
38 }
39
40 FF_T_SINT32
41 FatReadBlocks(FF_T_UINT8 *DestBuffer, FF_T_UINT32 SectorAddress, FF_T_UINT32 Count, void *pParam)
42 {
43 LARGE_INTEGER Offset;
44 //PVOID Buffer;
45 PVCB Vcb = (PVCB)pParam;
46 //PBCB Bcb;
47 ULONG SectorSize = 512; // FIXME: hardcoding 512 is bad
48 IO_STATUS_BLOCK IoSb;
49
50 DPRINT("FatReadBlocks %p %d %d %p\n", DestBuffer, SectorAddress, Count, pParam);
51
52 /* Calculate the offset */
53 Offset.QuadPart = Int32x32To64(SectorAddress, SectorSize);
54 #if 0
55 if (!CcMapData(Vcb->StreamFileObject,
56 &Offset,
57 Count * SectorSize,
58 TRUE,
59 &Bcb,
60 &Buffer))
61 {
62 ASSERT(FALSE);
63 /* Mapping failed */
64 return 0;
65 }
66
67 /* Copy data to the buffer */
68 RtlCopyMemory(DestBuffer, Buffer, Count * SectorSize);
69
70 /* Unpin unneeded data */
71 CcUnpinData(Bcb);
72 #else
73 CcCopyRead(Vcb->StreamFileObject, &Offset, Count * SectorSize, TRUE, DestBuffer, &IoSb);
74 #endif
75
76 /* Return amount of read data in sectors */
77 return Count;
78 }
79
80 FF_FILE *FF_OpenW(FF_IOMAN *pIoman, PUNICODE_STRING pathW, FF_T_UINT8 Mode, FF_ERROR *pError)
81 {
82 OEM_STRING AnsiName;
83 CHAR AnsiNameBuf[512];
84 NTSTATUS Status;
85
86 /* Convert the name to ANSI */
87 AnsiName.Buffer = AnsiNameBuf;
88 AnsiName.Length = 0;
89 AnsiName.MaximumLength = sizeof(AnsiNameBuf);
90 RtlZeroMemory(AnsiNameBuf, sizeof(AnsiNameBuf));
91 Status = RtlUpcaseUnicodeStringToCountedOemString(&AnsiName, pathW, FALSE);
92 if (!NT_SUCCESS(Status))
93 {
94 ASSERT(FALSE);
95 }
96
97 DPRINT1("Opening '%s'\n", AnsiName.Buffer);
98
99 /* Call FullFAT's handler */
100 return FF_Open(pIoman, AnsiName.Buffer, Mode, pError);
101 }
102
103 FORCEINLINE
104 VOID
105 FatDateTimeToSystemTime(OUT PLARGE_INTEGER SystemTime,
106 IN PFAT_DATETIME FatDateTime,
107 IN UCHAR TenMs OPTIONAL)
108 {
109 TIME_FIELDS TimeFields;
110
111 /* Setup time fields */
112 TimeFields.Year = FatDateTime->Date.Year + 1980;
113 TimeFields.Month = FatDateTime->Date.Month;
114 TimeFields.Day = FatDateTime->Date.Day;
115 TimeFields.Hour = FatDateTime->Time.Hour;
116 TimeFields.Minute = FatDateTime->Time.Minute;
117 TimeFields.Second = (FatDateTime->Time.DoubleSeconds << 1);
118
119 /* Adjust up to 10 milliseconds
120 * if the parameter was supplied
121 */
122 if (ARGUMENT_PRESENT(TenMs))
123 {
124 TimeFields.Second += TenMs / 100;
125 TimeFields.Milliseconds = (TenMs % 100) * 10;
126 }
127 else
128 {
129 TimeFields.Milliseconds = 0;
130 }
131
132 /* Fix seconds value that might get beyoud the bound */
133 if (TimeFields.Second > 59) TimeFields.Second = 0;
134
135 /* Perform ceonversion to system time if possible */
136 if (RtlTimeFieldsToTime(&TimeFields, SystemTime))
137 {
138 /* Convert to system time */
139 ExLocalTimeToSystemTime(SystemTime, SystemTime);
140 }
141 else
142 {
143 /* Set to default time if conversion failed */
144 *SystemTime = FatGlobalData.DefaultFileTime;
145 }
146 }
147
148 // TODO: Make it a helper around FullFAT library
149 VOID
150 NTAPI
151 FatQueryFileTimes(OUT PLARGE_INTEGER FileTimes,
152 IN PDIR_ENTRY Dirent)
153 {
154 /* Convert LastWriteTime */
155 FatDateTimeToSystemTime(&FileTimes[FileLastWriteTime],
156 &Dirent->LastWriteDateTime,
157 0);
158 /* All other time fileds are valid (according to MS)
159 * only if Win31 compatability mode is set.
160 */
161 if (FatGlobalData.Win31FileSystem)
162 {
163 /* We can avoid calling conversion routine
164 * if time in dirent is 0 or equals to already
165 * known time (LastWriteTime).
166 */
167 if (Dirent->CreationDateTime.Value == 0)
168 {
169 /* Set it to default time */
170 FileTimes[FileCreationTime] = FatGlobalData.DefaultFileTime;
171 }
172 else if (Dirent->CreationDateTime.Value
173 == Dirent->LastWriteDateTime.Value)
174 {
175 /* Assign the already known time */
176 FileTimes[FileCreationTime] = FileTimes[FileLastWriteTime];
177 /* Adjust milliseconds from extra dirent field */
178 FileTimes[FileCreationTime].QuadPart
179 += (ULONG) Dirent->CreationTimeTenMs * 100000;
180 }
181 else
182 {
183 /* Perform conversion */
184 FatDateTimeToSystemTime(&FileTimes[FileCreationTime],
185 &Dirent->CreationDateTime,
186 Dirent->CreationTimeTenMs);
187 }
188 if (Dirent->LastAccessDate.Value == 0)
189 {
190 /* Set it to default time */
191 FileTimes[FileLastAccessTime] = FatGlobalData.DefaultFileTime;
192 }
193 else if (Dirent->LastAccessDate.Value
194 == Dirent->LastWriteDateTime.Date.Value)
195 {
196 /* Assign the already known time */
197 FileTimes[FileLastAccessTime] = FileTimes[FileLastWriteTime];
198 }
199 else
200 {
201 /* Perform conversion */
202 FAT_DATETIME LastAccessDateTime;
203
204 LastAccessDateTime.Date.Value = Dirent->LastAccessDate.Value;
205 LastAccessDateTime.Time.Value = 0;
206 FatDateTimeToSystemTime(&FileTimes[FileLastAccessTime],
207 &LastAccessDateTime,
208 0);
209 }
210 }
211 }
212
213 /* EOF */