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)
9 /* INCLUDES *****************************************************************/
14 /* GLOBALS ******************************************************************/
16 #define TAG_FULLFAT 'FLUF'
18 /* FUNCTIONS ****************************************************************/
21 FF_Malloc(FF_T_UINT32 allocSize
)
23 return ExAllocatePoolWithTag(PagedPool
, allocSize
, TAG_FULLFAT
);
27 FF_Free(VOID
*pBuffer
)
29 ExFreePoolWithTag(pBuffer
, TAG_FULLFAT
);
33 FatWriteBlocks(FF_T_UINT8
*pBuffer
, FF_T_UINT32 SectorAddress
, FF_T_UINT32 Count
, void *pParam
)
35 DPRINT1("FatWriteBlocks %p %d %d %p\n", pBuffer
, SectorAddress
, Count
, pParam
);
41 FatReadBlocks(FF_T_UINT8
*DestBuffer
, FF_T_UINT32 SectorAddress
, FF_T_UINT32 Count
, void *pParam
)
45 PVCB Vcb
= (PVCB
)pParam
;
47 ULONG SectorSize
= 512; // FIXME: hardcoding 512 is bad
50 DPRINT("FatReadBlocks %p %d %d %p\n", DestBuffer
, SectorAddress
, Count
, pParam
);
52 /* Calculate the offset */
53 Offset
.QuadPart
= Int32x32To64(SectorAddress
, SectorSize
);
55 if (!CcMapData(Vcb
->StreamFileObject
,
67 /* Copy data to the buffer */
68 RtlCopyMemory(DestBuffer
, Buffer
, Count
* SectorSize
);
70 /* Unpin unneeded data */
73 CcCopyRead(Vcb
->StreamFileObject
, &Offset
, Count
* SectorSize
, TRUE
, DestBuffer
, &IoSb
);
76 /* Return amount of read data in sectors */
80 FF_FILE
*FF_OpenW(FF_IOMAN
*pIoman
, PUNICODE_STRING pathW
, FF_T_UINT8 Mode
, FF_ERROR
*pError
)
83 CHAR AnsiNameBuf
[512];
86 /* Convert the name to ANSI */
87 AnsiName
.Buffer
= AnsiNameBuf
;
89 AnsiName
.MaximumLength
= sizeof(AnsiNameBuf
);
90 RtlZeroMemory(AnsiNameBuf
, sizeof(AnsiNameBuf
));
91 Status
= RtlUpcaseUnicodeStringToCountedOemString(&AnsiName
, pathW
, FALSE
);
92 if (!NT_SUCCESS(Status
))
97 DPRINT1("Opening '%s'\n", AnsiName
.Buffer
);
99 /* Call FullFAT's handler */
100 return FF_Open(pIoman
, AnsiName
.Buffer
, Mode
, pError
);
105 FatDateTimeToSystemTime(OUT PLARGE_INTEGER SystemTime
,
106 IN PFAT_DATETIME FatDateTime
,
107 IN UCHAR TenMs OPTIONAL
)
109 TIME_FIELDS TimeFields
;
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);
119 /* Adjust up to 10 milliseconds
120 * if the parameter was supplied
122 if (ARGUMENT_PRESENT(TenMs
))
124 TimeFields
.Second
+= TenMs
/ 100;
125 TimeFields
.Milliseconds
= (TenMs
% 100) * 10;
129 TimeFields
.Milliseconds
= 0;
132 /* Fix seconds value that might get beyoud the bound */
133 if (TimeFields
.Second
> 59) TimeFields
.Second
= 0;
135 /* Perform ceonversion to system time if possible */
136 if (RtlTimeFieldsToTime(&TimeFields
, SystemTime
))
138 /* Convert to system time */
139 ExLocalTimeToSystemTime(SystemTime
, SystemTime
);
143 /* Set to default time if conversion failed */
144 *SystemTime
= FatGlobalData
.DefaultFileTime
;
148 // TODO: Make it a helper around FullFAT library
151 FatQueryFileTimes(OUT PLARGE_INTEGER FileTimes
,
152 IN PDIR_ENTRY Dirent
)
154 /* Convert LastWriteTime */
155 FatDateTimeToSystemTime(&FileTimes
[FileLastWriteTime
],
156 &Dirent
->LastWriteDateTime
,
158 /* All other time fileds are valid (according to MS)
159 * only if Win31 compatability mode is set.
161 if (FatGlobalData
.Win31FileSystem
)
163 /* We can avoid calling conversion routine
164 * if time in dirent is 0 or equals to already
165 * known time (LastWriteTime).
167 if (Dirent
->CreationDateTime
.Value
== 0)
169 /* Set it to default time */
170 FileTimes
[FileCreationTime
] = FatGlobalData
.DefaultFileTime
;
172 else if (Dirent
->CreationDateTime
.Value
173 == Dirent
->LastWriteDateTime
.Value
)
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;
183 /* Perform conversion */
184 FatDateTimeToSystemTime(&FileTimes
[FileCreationTime
],
185 &Dirent
->CreationDateTime
,
186 Dirent
->CreationTimeTenMs
);
188 if (Dirent
->LastAccessDate
.Value
== 0)
190 /* Set it to default time */
191 FileTimes
[FileLastAccessTime
] = FatGlobalData
.DefaultFileTime
;
193 else if (Dirent
->LastAccessDate
.Value
194 == Dirent
->LastWriteDateTime
.Date
.Value
)
196 /* Assign the already known time */
197 FileTimes
[FileLastAccessTime
] = FileTimes
[FileLastWriteTime
];
201 /* Perform conversion */
202 FAT_DATETIME LastAccessDateTime
;
204 LastAccessDateTime
.Date
.Value
= Dirent
->LastAccessDate
.Value
;
205 LastAccessDateTime
.Time
.Value
= 0;
206 FatDateTimeToSystemTime(&FileTimes
[FileLastAccessTime
],