1 /*++
2
3 Copyright (c) 1989-2000 Microsoft Corporation
4
5 Module Name:
6
7 TimeSup.c
8
9 Abstract:
10
11 This module implements the Fat Time conversion support routines
12
13
14 --*/
15
16 #include "fatprocs.h"
17
18 #ifdef ALLOC_PRAGMA
19 #pragma alloc_text(PAGE, FatNtTimeToFatTime)
20 #pragma alloc_text(PAGE, FatFatDateToNtTime)
21 #pragma alloc_text(PAGE, FatFatTimeToNtTime)
22 #pragma alloc_text(PAGE, FatGetCurrentFatTime)
23 #endif
24
25 _Success_(return != FALSE)
26 BOOLEAN
FatNtTimeToFatTime(_In_ PIRP_CONTEXT IrpContext,_In_ PLARGE_INTEGER NtTime,_In_ BOOLEAN Rounding,_Out_ PFAT_TIME_STAMP FatTime,_Out_opt_ PUCHAR TenMsecs)27 FatNtTimeToFatTime (
28 _In_ PIRP_CONTEXT IrpContext,
29 _In_ PLARGE_INTEGER NtTime,
30 _In_ BOOLEAN Rounding,
31 _Out_ PFAT_TIME_STAMP FatTime,
32 _Out_opt_ PUCHAR TenMsecs
33 )
34
35 /*++
36
37 Routine Description:
38
39 This routine converts an NtTime value to its corresponding Fat time value.
40
41 Arguments:
42
43 NtTime - Supplies the Nt GMT Time value to convert from
44
45 Rounding - Indicates whether the NT time should be rounded up to a FAT boundary.
46 This should only be done *once* in the lifetime of a timestamp (important
47 for tunneling, which will cause a timestamp to pass through at least twice).
48 If true, rounded up. If false, rounded down to 10ms boundary. This obeys
49 the rules for non-creation time and creation times (respectively).
50
51 FatTime - Receives the equivalent Fat time value
52
53 TenMsecs - Optionally receive the number of tens of milliseconds the NtTime, after
54 any rounding, is greater than the FatTime
55
56 Return Value:
57
58 BOOLEAN - TRUE if the Nt time value is within the range of Fat's
59 time range, and FALSE otherwise
60
61 --*/
62
63 {
64 TIME_FIELDS TimeFields;
65
66 PAGED_CODE();
67
68 //
69 // Convert the input to the a time field record.
70 //
71
72 if (Rounding) {
73
74 //
75 // Add almost two seconds to round up to the nearest double second.
76 //
77
78 NtTime->QuadPart = NtTime->QuadPart + AlmostTwoSeconds;
79 }
80
81 ExSystemTimeToLocalTime( NtTime, NtTime );
82
83 RtlTimeToTimeFields( NtTime, &TimeFields );
84
85 //
86 // Check the range of the date found in the time field record
87 //
88
89 if ((TimeFields.Year < 1980) || (TimeFields.Year > (1980 + 127))) {
90
91 ExLocalTimeToSystemTime( NtTime, NtTime );
92
93 return FALSE;
94 }
95
96 //
97 // The year will fit in Fat so simply copy over the information
98 //
99
100 FatTime->Time.DoubleSeconds = (USHORT)(TimeFields.Second / 2);
101 FatTime->Time.Minute = (USHORT)(TimeFields.Minute);
102 FatTime->Time.Hour = (USHORT)(TimeFields.Hour);
103
104 FatTime->Date.Year = (USHORT)(TimeFields.Year - 1980);
105 FatTime->Date.Month = (USHORT)(TimeFields.Month);
106 FatTime->Date.Day = (USHORT)(TimeFields.Day);
107
108 if (TenMsecs) {
109
110 if (!Rounding) {
111
112 //
113 // If the number of seconds was not divisible by two, then there
114 // is another second of time (1 sec, 3 sec, etc.) Note we round down
115 // the number of milleconds onto tens of milleseconds boundaries.
116 //
117
118 #ifdef _MSC_VER
119 #pragma warning( push )
120 #pragma warning( disable: 4244 )
121 #endif
122 *TenMsecs = (TimeFields.Milliseconds / 10) +
123 ((TimeFields.Second % 2) * 100);
124 #ifdef _MSC_VER
125 #pragma warning( pop )
126 #endif
127 } else {
128
129 //
130 // If we rounded up, we have in effect changed the NT time. Therefore,
131 // it does not differ from the FAT time.
132 //
133
134 *TenMsecs = 0;
135 }
136 }
137
138 if (Rounding) {
139
140 //
141 // Slice off non-FAT boundary time and convert back to 64bit form
142 //
143
144 TimeFields.Milliseconds = 0;
145 TimeFields.Second -= TimeFields.Second % 2;
146
147 } else {
148
149 //
150 // Round down to 10ms boundary
151 //
152
153 TimeFields.Milliseconds -= TimeFields.Milliseconds % 10;
154 }
155
156 //
157 // Convert back to NT time
158 //
159
160 (VOID) RtlTimeFieldsToTime(&TimeFields, NtTime);
161
162 ExLocalTimeToSystemTime( NtTime, NtTime );
163
164 UNREFERENCED_PARAMETER( IrpContext );
165
166 return TRUE;
167 }
168
169
170 LARGE_INTEGER
FatFatDateToNtTime(_In_ PIRP_CONTEXT IrpContext,_In_ FAT_DATE FatDate)171 FatFatDateToNtTime (
172 _In_ PIRP_CONTEXT IrpContext,
173 _In_ FAT_DATE FatDate
174 )
175
176 /*++
177
178 Routine Description:
179
180 This routine converts a Fat datev value to its corresponding Nt GMT
181 Time value.
182
183 Arguments:
184
185 FatDate - Supplies the Fat Date to convert from
186
187 Return Value:
188
189 LARGE_INTEGER - Receives the corresponding Nt Time value
190
191 --*/
192
193 {
194 TIME_FIELDS TimeFields;
195 LARGE_INTEGER Time;
196
197 PAGED_CODE();
198
199 //
200 // Pack the input time/date into a time field record
201 //
202
203 TimeFields.Year = (USHORT)(FatDate.Year + 1980);
204 TimeFields.Month = (USHORT)(FatDate.Month);
205 TimeFields.Day = (USHORT)(FatDate.Day);
206 TimeFields.Hour = (USHORT)0;
207 TimeFields.Minute = (USHORT)0;
208 TimeFields.Second = (USHORT)0;
209 TimeFields.Milliseconds = (USHORT)0;
210
211 //
212 // Convert the time field record to Nt LARGE_INTEGER, and set it to zero
213 // if we were given a bogus time.
214 //
215
216 if (!RtlTimeFieldsToTime( &TimeFields, &Time )) {
217
218 Time.LowPart = 0;
219 Time.HighPart = 0;
220
221 } else {
222
223 ExLocalTimeToSystemTime( &Time, &Time );
224 }
225
226 return Time;
227
228 UNREFERENCED_PARAMETER( IrpContext );
229 }
230
231
232 LARGE_INTEGER
FatFatTimeToNtTime(_In_ PIRP_CONTEXT IrpContext,_In_ FAT_TIME_STAMP FatTime,_In_ UCHAR TenMilliSeconds)233 FatFatTimeToNtTime (
234 _In_ PIRP_CONTEXT IrpContext,
235 _In_ FAT_TIME_STAMP FatTime,
236 _In_ UCHAR TenMilliSeconds
237 )
238
239 /*++
240
241 Routine Description:
242
243 This routine converts a Fat time value pair to its corresponding Nt GMT
244 Time value.
245
246 Arguments:
247
248 FatTime - Supplies the Fat Time to convert from
249
250 TenMilliSeconds - A 10 Milisecond resolution
251
252 Return Value:
253
254 LARGE_INTEGER - Receives the corresponding Nt GMT Time value
255
256 --*/
257
258 {
259 TIME_FIELDS TimeFields;
260 LARGE_INTEGER Time;
261
262 PAGED_CODE();
263
264 //
265 // Pack the input time/date into a time field record
266 //
267
268 TimeFields.Year = (USHORT)(FatTime.Date.Year + 1980);
269 TimeFields.Month = (USHORT)(FatTime.Date.Month);
270 TimeFields.Day = (USHORT)(FatTime.Date.Day);
271 TimeFields.Hour = (USHORT)(FatTime.Time.Hour);
272 TimeFields.Minute = (USHORT)(FatTime.Time.Minute);
273 TimeFields.Second = (USHORT)(FatTime.Time.DoubleSeconds * 2);
274
275 if (TenMilliSeconds != 0) {
276
277 TimeFields.Second += (USHORT)(TenMilliSeconds / 100);
278 TimeFields.Milliseconds = (USHORT)((TenMilliSeconds % 100) * 10);
279
280 } else {
281
282 TimeFields.Milliseconds = (USHORT)0;
283 }
284
285 //
286 // If the second value is greater than 59 then we truncate it to 0.
287 // Note that this can't happen with a proper FAT timestamp.
288 //
289
290 if (TimeFields.Second > 59) {
291
292 TimeFields.Second = 0;
293 }
294
295 //
296 // Convert the time field record to Nt LARGE_INTEGER, and set it to zero
297 // if we were given a bogus time.
298 //
299
300 if (!RtlTimeFieldsToTime( &TimeFields, &Time )) {
301
302 Time.LowPart = 0;
303 Time.HighPart = 0;
304
305 } else {
306
307 ExLocalTimeToSystemTime( &Time, &Time );
308 }
309
310 return Time;
311
312 UNREFERENCED_PARAMETER( IrpContext );
313 }
314
315
316 FAT_TIME_STAMP
FatGetCurrentFatTime(_In_ PIRP_CONTEXT IrpContext)317 FatGetCurrentFatTime (
318 _In_ PIRP_CONTEXT IrpContext
319 )
320
321 /*++
322
323 Routine Description:
324
325 This routine returns the current system time in Fat time
326
327 Arguments:
328
329 Return Value:
330
331 FAT_TIME_STAMP - Receives the current system time
332
333 --*/
334
335 {
336 LARGE_INTEGER Time;
337 TIME_FIELDS TimeFields;
338 FAT_TIME_STAMP FatTime;
339
340 PAGED_CODE();
341
342 //
343 // Get the current system time, and map it into a time field record.
344 //
345
346 KeQuerySystemTime( &Time );
347
348 ExSystemTimeToLocalTime( &Time, &Time );
349
350 //
351 // Always add almost two seconds to round up to the nearest double second.
352 //
353
354 Time.QuadPart = Time.QuadPart + AlmostTwoSeconds;
355
356 (VOID)RtlTimeToTimeFields( &Time, &TimeFields );
357
358 //
359 // Now simply copy over the information
360 //
361
362 FatTime.Time.DoubleSeconds = (USHORT)(TimeFields.Second / 2);
363 FatTime.Time.Minute = (USHORT)(TimeFields.Minute);
364 FatTime.Time.Hour = (USHORT)(TimeFields.Hour);
365
366 FatTime.Date.Year = (USHORT)(TimeFields.Year - 1980);
367 FatTime.Date.Month = (USHORT)(TimeFields.Month);
368 FatTime.Date.Day = (USHORT)(TimeFields.Day);
369
370 UNREFERENCED_PARAMETER( IrpContext );
371
372 return FatTime;
373 }
374
375
376