2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
14 #include <afsconfig.h>
15 #include <afs/param.h>
20 #include <WINNT/afsclass.h>
23 #define LOCAL_CRITSEC_COUNT
27 * VARIABLES __________________________________________________________________
31 #ifdef LOCAL_CRITSEC_COUNT
32 size_t cs_EnterCount = 0;
33 DWORD cs_ThreadID = 0;
36 size_t cRefreshAllReq = 0;
38 CRITICAL_SECTION *pcs = NULL;
39 BOOL fLongServerNames = FALSE;
43 static LPTSTR apszDays[] = {
44 TEXT("sun"), TEXT("mon"), TEXT("tue"),
45 TEXT("wed"), TEXT("thu"), TEXT("fri"), TEXT("sat")
50 * PROTOTYPES _________________________________________________________________
56 * ROUTINES ___________________________________________________________________
60 void AfsClass_InitCriticalSection (void)
64 pcs = New (CRITICAL_SECTION);
65 InitializeCriticalSection (pcs);
67 #ifdef LOCAL_CRITSEC_COUNT
74 LPCRITICAL_SECTION AfsClass_GetCriticalSection (void)
76 AfsClass_InitCriticalSection();
80 void AfsClass_Enter (void)
82 AfsClass_InitCriticalSection();
83 EnterCriticalSection (pcs);
85 #ifdef LOCAL_CRITSEC_COUNT
87 cs_ThreadID = GetCurrentThreadId();
91 void AfsClass_Leave (void)
93 #ifdef LOCAL_CRITSEC_COUNT
94 if (!ASSERT( cs_EnterCount > 0 ))
96 if (!ASSERT( cs_ThreadID == GetCurrentThreadId() ))
100 if (!ASSERT( pcs->RecursionCount > 0 ))
102 if (!ASSERT( pcs->OwningThread == (PVOID)GetCurrentThreadId() ))
105 LeaveCriticalSection (pcs);
108 int AfsClass_GetEnterCount (void)
110 #ifdef LOCAL_CRITSEC_COUNT
111 return (int)cs_EnterCount;
113 return pcs->RecursionCount;
117 void AfsClass_UnixTimeToSystemTime (LPSYSTEMTIME pst, ULONG ut, BOOL fElapsed)
121 memset (pst, 0x00, sizeof(SYSTEMTIME));
125 // A Unix time is the number of seconds since 1/1/1970.
126 // The first step in this conversion is to change that count-of-seconds
127 // into a count-of-100ns-intervals...
130 ldw.QuadPart = (LONGLONG)10000000 * (LONGLONG)ut;
132 // Then adjust the count to be a count-of-100ns-intervals since
133 // 1/1/1601, instead of 1/1/1970. That means adding a *big* number...
135 ldw.QuadPart += (LONGLONG)0x019DB1DED53E8000;
137 // Now the count is effectively a FILETIME, which we can convert
138 // to a SYSTEMTIME with a Win32 API.
141 ft.dwHighDateTime = (DWORD)ldw.HighPart;
142 ft.dwLowDateTime = (DWORD)ldw.LowPart;
143 FileTimeToSystemTime (&ft, pst);
149 pst->wDayOfWeek -= 1;
155 ULONG AfsClass_SystemTimeToUnixTime (LPSYSTEMTIME pst)
163 if (st.wYear == 1970)
167 if (!SystemTimeToFileTime (&st, &ft))
171 now.HighPart = (LONG)ft.dwHighDateTime;
172 now.LowPart = (ULONG)ft.dwLowDateTime;
174 LARGE_INTEGER offset;
175 offset.HighPart = 0x019db1de;
176 offset.LowPart = 0xd53e8000;
178 LARGE_INTEGER result;
179 result.QuadPart = (now.QuadPart - offset.QuadPart) / 10000000;
180 return (ULONG)result.LowPart;
184 void AfsClass_ElapsedTimeToSeconds (ULONG *pcSeconds, LPSYSTEMTIME pet)
189 *pcSeconds += pet->wSecond;
190 *pcSeconds += pet->wMinute * 60L;
191 *pcSeconds += pet->wHour * 60L * 60L;
192 *pcSeconds += pet->wDay * 60L * 60L * 24L;
197 double AfsClass_FileTimeToDouble (FILETIME *pft)
200 rc = (double)pft->dwHighDateTime * (double)0x100000000;
201 rc += (double)pft->dwLowDateTime;
206 void AfsClass_RequestLongServerNames (BOOL fLong)
208 fLongServerNames = fLong;
212 void AfsClass_ParseRecurringTime (BOOL *pfEver, LPSYSTEMTIME pst, LPTSTR pszTime)
215 memset (pst, 0x00, sizeof(SYSTEMTIME));
217 if (lstrcmpi (pszTime, TEXT("never")))
221 if (!lstrncmpi (pszTime, TEXT("at"), lstrlen(TEXT("at"))))
222 pszTime += lstrlen(TEXT("at"));
223 while ((*pszTime == ' ') || (*pszTime == '\t'))
226 // first, does it start with a day-of-week?
228 pst->wDayOfWeek = (WORD)(-1); // daily until proven otherwise
230 for (WORD ii = 0; ii < 7; ++ii)
232 if (!lstrncmpi (apszDays[ii], pszTime, 3))
234 pst->wDayOfWeek = ii;
239 // next, find the hour
241 while (*pszTime && !isdigit(*pszTime))
244 TCHAR szComponent[ cchRESOURCE ];
245 lstrcpy (szComponent, pszTime);
247 for (pch = szComponent; isdigit(*pch); ++pch)
251 pst->wHour = atoi(szComponent);
253 // next, find the minutes
255 while (isdigit(*pszTime))
257 while (*pszTime && !isdigit(*pszTime))
260 lstrcpy (szComponent, pszTime);
261 for (pch = szComponent; isdigit(*pch); ++pch)
265 pst->wMinute = atoi(szComponent);
267 // next, check for a 'am' or 'pm' marker
269 for ( ; *pszTime; ++pszTime)
271 if (tolower(*pszTime) == TEXT('p'))
277 if (tolower(*pszTime) == TEXT('a'))
279 if (pst->wHour >= 12)
288 void AfsClass_FormatRecurringTime (LPTSTR pszTarget, SYSTEMTIME *pst)
292 wsprintf (pszTarget, TEXT("never"));
296 WORD wHour = ((pst->wHour % 12) == 0) ? 12 : (pst->wHour % 12);
298 lstrcpy (szAMPM, (pst->wHour >= 12) ? TEXT("pm") : TEXT("am"));
300 if (pst->wDayOfWeek == (WORD)(-1)) // daily at specified time?
302 wsprintf (pszTarget, TEXT("%u:%02u %s"), wHour, pst->wMinute, szAMPM);
304 else // weekly on specified date at specified time?
306 wsprintf (pszTarget, TEXT("%s %u:%02u %s"), apszDays[ pst->wDayOfWeek ], wHour, pst->wMinute, szAMPM);
312 void AfsClass_SplitFilename (LPSTR pszDirectoryA, LPSTR pszFilenameA, LPTSTR pszFullName)
314 CopyStringToAnsi (pszDirectoryA, pszFullName);
316 LPSTR pszLastSlashA = NULL;
317 for (LPSTR pszA = pszDirectoryA; *pszA; ++pszA)
319 if ((*pszA == '/') || (*pszA == '\\'))
320 pszLastSlashA = pszA;
325 strcpy (pszFilenameA, pszDirectoryA);
330 strcpy (pszFilenameA, 1+pszLastSlashA);
336 void AfsClass_SystemTimeToRestartTime (bos_RestartTime_p prt, BOOL fEnable, LPSYSTEMTIME pst)
338 memset (prt, 0x00, sizeof(bos_RestartTime_t));
340 prt->mask = BOS_RESTART_TIME_NEVER;
343 prt->mask = (bos_RestartTimeFields_t)(BOS_RESTART_TIME_HOUR | BOS_RESTART_TIME_MINUTE);
344 prt->hour = pst->wHour;
345 prt->min = pst->wMinute;
347 if (pst->wDayOfWeek != (WORD)-1)
349 prt->mask = (bos_RestartTimeFields_t)(prt->mask | BOS_RESTART_TIME_DAY);
350 prt->day = pst->wDayOfWeek;
356 void AfsClass_RestartTimeToSystemTime (BOOL *pfEnable, LPSYSTEMTIME pst, bos_RestartTime_p prt)
358 memset (pst, 0x00, sizeof(SYSTEMTIME));
360 if ((!prt->mask) || (prt->mask & BOS_RESTART_TIME_NEVER))
367 pst->wHour = (prt->mask & BOS_RESTART_TIME_HOUR) ? prt->hour : 0;
368 pst->wMinute = (prt->mask & BOS_RESTART_TIME_MINUTE) ? prt->min : 0;
369 pst->wDayOfWeek = (prt->mask & BOS_RESTART_TIME_DAY) ? prt->day : (WORD)-1;
374 void AfsClass_IntToAddress (LPSOCKADDR_IN pAddr, int IntAddr)
376 memset (pAddr, 0x00, sizeof(SOCKADDR_IN));
377 pAddr->sin_family = AF_INET;
378 pAddr->sin_addr.s_addr = htonl(IntAddr);
382 void AfsClass_AddressToInt (int *pIntAddr, LPSOCKADDR_IN pAddr)
384 *pIntAddr = ntohl(pAddr->sin_addr.s_addr);
388 void AfsClass_SpecifyRefreshDomain (DWORD dwWantUser)
394 BOOL AfsClass_Initialize (ULONG *pStatus)
396 if (!Worker_Initialize (pStatus))
403 void AfsClass_GenFullUserName (LPTSTR pszTarget, LPCTSTR pszPrincipal, LPCTSTR pszInstance)
405 lstrcpy (pszTarget, pszPrincipal);
406 if (pszInstance && *pszInstance)
407 wsprintf (&pszTarget[ lstrlen(pszTarget) ], TEXT(".%s"), pszInstance);