1 /***************************************************************************
2  * Copyright (c) 2024 Microsoft Corporation
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the MIT License which is available at
6  * https://opensource.org/licenses/MIT.
7  *
8  * SPDX-License-Identifier: MIT
9  **************************************************************************/
10 
11 
12 /**************************************************************************/
13 /**************************************************************************/
14 /**                                                                       */
15 /** FileX Component                                                       */
16 /**                                                                       */
17 /**   System                                                              */
18 /**                                                                       */
19 /**************************************************************************/
20 /**************************************************************************/
21 
22 #define FX_SOURCE_CODE
23 
24 
25 /* Include necessary system files.  */
26 
27 #include "fx_api.h"
28 #include "fx_system.h"
29 
30 
31 /**************************************************************************/
32 /*                                                                        */
33 /*  FUNCTION                                               RELEASE        */
34 /*                                                                        */
35 /*    _fx_system_timer_entry                              PORTABLE C      */
36 /*                                                           6.1          */
37 /*  AUTHOR                                                                */
38 /*                                                                        */
39 /*    William E. Lamie, Microsoft Corporation                             */
40 /*                                                                        */
41 /*  DESCRIPTION                                                           */
42 /*                                                                        */
43 /*    This function is FileX system timer function.  It is called at the  */
44 /*    rate specified by FX_UPDATE_RATE_IN_SECONDS and is responsible for  */
45 /*    maintaining both the system date and time.                          */
46 /*                                                                        */
47 /*  INPUT                                                                 */
48 /*                                                                        */
49 /*    id                                    Not used                      */
50 /*                                                                        */
51 /*  OUTPUT                                                                */
52 /*                                                                        */
53 /*    None                                                                */
54 /*                                                                        */
55 /*  CALLS                                                                 */
56 /*                                                                        */
57 /*    None                                                                */
58 /*                                                                        */
59 /*  CALLED BY                                                             */
60 /*                                                                        */
61 /*    Application Initialization                                          */
62 /*                                                                        */
63 /*  RELEASE HISTORY                                                       */
64 /*                                                                        */
65 /*    DATE              NAME                      DESCRIPTION             */
66 /*                                                                        */
67 /*  05-19-2020     William E. Lamie         Initial Version 6.0           */
68 /*  09-30-2020     William E. Lamie         Modified comment(s),          */
69 /*                                            resulting in version 6.1    */
70 /*                                                                        */
71 /**************************************************************************/
_fx_system_timer_entry(ULONG id)72 VOID    _fx_system_timer_entry(ULONG id)
73 {
74 
75 UINT second;
76 UINT minute;
77 UINT hour;
78 UINT day;
79 UINT month;
80 UINT year;
81 
82 
83     /* Determine if the ID is valid.  */
84     if (id == FX_TIMER_ID)
85     {
86 
87         /* Break the current date time into separate fields for easier work!  */
88         second =  (_fx_system_time & FX_SECOND_MASK) * 2;
89         minute =  (_fx_system_time >> FX_MINUTE_SHIFT) & FX_MINUTE_MASK;
90         hour =    (_fx_system_time >> FX_HOUR_SHIFT) & FX_HOUR_MASK;
91         day =     _fx_system_date & FX_DAY_MASK;
92         month =   (_fx_system_date >> FX_MONTH_SHIFT) & FX_MONTH_MASK;
93         year =    ((_fx_system_date >> FX_YEAR_SHIFT) & FX_YEAR_MASK) + FX_BASE_YEAR;
94 
95         /* Now apply the "second" update.  */
96         second =  second + FX_UPDATE_RATE_IN_SECONDS;
97 
98         /* Determine if we need to adjust the minute field.  */
99         if (second > FX_MAXIMUM_SECOND)
100         {
101 
102             /* Yes, we need to adjust the minute field.  */
103             minute =  minute + second / 60;
104             second =  second % 60;
105 
106             /* Determine if we need to adjust the hour field.  */
107             if (minute > FX_MAXIMUM_MINUTE)
108             {
109 
110                 /* Yes, we need to adjust the hour field.  */
111                 hour =    hour + minute / 60;
112                 minute =  minute % 60;
113 
114                 /* Determine if we need to adjust the day field.  */
115                 if (hour > FX_MAXIMUM_HOUR)
116                 {
117 
118                     /* Yes, we need to adjust the day field.  */
119                     hour =  0;
120                     day++;
121 
122                     /* Determine if we need to adjust the month field.  */
123                     switch (month)
124                     {
125 
126                     case 1:                 /* January  */
127                     {
128 
129                         /* Check for end of the month.  */
130                         if (day > 31)
131                         {
132 
133                             /* Move to next month.  */
134                             day = 1;
135                             month++;
136                         }
137                         break;
138                     }
139 
140                     case 2:                 /* February  */
141                     {
142 
143                         /* Check for leap year.  We don't need to check for leap
144                            century her (century years divisible by 400) since 2000
145                            is and this FAT format only supports years to 2107. */
146                         if ((year % 4) == 0)
147                         {
148 
149                             /* Leap year in February... check for 29 days
150                                instead of 28.  */
151                             if (day > 29)
152                             {
153 
154                                 /* Adjust the month.  */
155                                 day =  1;
156                                 month++;
157                             }
158                         }
159                         else
160                         {
161 
162                             if (day > 28)
163                             {
164 
165                                 /* Adjust the month.  */
166                                 day = 1;
167                                 month++;
168                             }
169                         }
170                         break;
171                     }
172 
173                     case 3:                 /* March  */
174                     {
175 
176                         /* Check for end of the month.  */
177                         if (day > 31)
178                         {
179 
180                             /* Move to next month.  */
181                             day = 1;
182                             month++;
183                         }
184                         break;
185                     }
186 
187                     case 4:                 /* April  */
188                     {
189 
190                         /* Check for end of the month.  */
191                         if (day > 30)
192                         {
193 
194                             /* Move to next month.  */
195                             day = 1;
196                             month++;
197                         }
198                         break;
199                     }
200 
201                     case 5:                 /* May  */
202                     {
203 
204                         /* Check for end of the month.  */
205                         if (day > 31)
206                         {
207 
208                             /* Move to next month.  */
209                             day = 1;
210                             month++;
211                         }
212                         break;
213                     }
214 
215                     case 6:                 /* June */
216                     {
217 
218                         /* Check for end of the month.  */
219                         if (day > 30)
220                         {
221 
222                             /* Move to next month.  */
223                             day = 1;
224                             month++;
225                         }
226                         break;
227                     }
228 
229                     case 7:                 /* July */
230                     {
231 
232                         /* Check for end of the month.  */
233                         if (day > 31)
234                         {
235 
236                             /* Move to next month.  */
237                             day = 1;
238                             month++;
239                         }
240                         break;
241                     }
242 
243                     case 8:                 /* August */
244                     {
245 
246                         /* Check for end of the month.  */
247                         if (day > 31)
248                         {
249 
250                             /* Move to next month.  */
251                             day = 1;
252                             month++;
253                         }
254                         break;
255                     }
256 
257                     case 9:                 /* September */
258                     {
259 
260                         /* Check for end of the month.  */
261                         if (day > 30)
262                         {
263 
264                             /* Move to next month.  */
265                             day = 1;
266                             month++;
267                         }
268                         break;
269                     }
270 
271                     case 10:                /* October */
272                     {
273 
274                         /* Check for end of the month.  */
275                         if (day > 31)
276                         {
277 
278                             /* Move to next month.  */
279                             day = 1;
280                             month++;
281                         }
282                         break;
283                     }
284 
285                     case 11:                /* November */
286                     {
287 
288                         /* Check for end of the month.  */
289                         if (day > 30)
290                         {
291 
292                             /* Move to next month.  */
293                             day = 1;
294                             month++;
295                         }
296                         break;
297                     }
298 
299                     case 12:                /* December */
300                     {
301 
302                         /* Check for end of the month.  */
303                         if (day > 31)
304                         {
305 
306                             /* Move to next month.  */
307                             day = 1;
308                             month = 1;
309 
310                             /* Also move to next year.  */
311                             year++;
312 
313                             /* Check for a year that exceeds the representation
314                                in this format.  */
315                             if (year > FX_MAXIMUM_YEAR)
316                             {
317                                 return;
318                             }
319                         }
320                         break;
321                     }
322 
323                     default:                /* Invalid month!  */
324 
325                         return;             /* Skip updating date/time!  */
326                     }
327                 }
328             }
329         }
330 
331         /* Now apply the new setting to the internal representation.  */
332 
333         /* Set the system date.  */
334         _fx_system_date =  ((year - FX_BASE_YEAR) << FX_YEAR_SHIFT) |
335                             (month << FX_MONTH_SHIFT) | day;
336 
337         /* Set the new system time.  */
338         _fx_system_time  =  (hour << FX_HOUR_SHIFT) |
339                             (minute << FX_MINUTE_SHIFT) | (second / 2);
340     }
341 }
342 
343