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
11 #include <afs/param.h>
15 #include <WINNT/afsclass.h>
18 #define LOCAL_CRITSEC_COUNT
22 * VARIABLES __________________________________________________________________
26 #ifdef LOCAL_CRITSEC_COUNT
27 size_t cs_EnterCount = 0;
28 DWORD cs_ThreadID = 0;
31 size_t cRefreshAllReq = 0;
33 CRITICAL_SECTION *pcs = NULL;
34 BOOL fLongServerNames = FALSE;
38 static LPTSTR apszDays[] = {
39 TEXT("sun"), TEXT("mon"), TEXT("tue"),
40 TEXT("wed"), TEXT("thu"), TEXT("fri"), TEXT("sat")
45 * PROTOTYPES _________________________________________________________________
51 * ROUTINES ___________________________________________________________________
55 void AfsClass_InitCriticalSection (void)
59 pcs = New (CRITICAL_SECTION);
60 InitializeCriticalSection (pcs);
62 #ifdef LOCAL_CRITSEC_COUNT
69 LPCRITICAL_SECTION AfsClass_GetCriticalSection (void)
71 AfsClass_InitCriticalSection();
75 void AfsClass_Enter (void)
77 AfsClass_InitCriticalSection();
78 EnterCriticalSection (pcs);
80 #ifdef LOCAL_CRITSEC_COUNT
82 cs_ThreadID = GetCurrentThreadId();
86 void AfsClass_Leave (void)
88 #ifdef LOCAL_CRITSEC_COUNT
89 if (!ASSERT( cs_EnterCount > 0 ))
91 if (!ASSERT( cs_ThreadID == GetCurrentThreadId() ))
95 if (!ASSERT( pcs->RecursionCount > 0 ))
97 if (!ASSERT( pcs->OwningThread == (PVOID)GetCurrentThreadId() ))
100 LeaveCriticalSection (pcs);
103 int AfsClass_GetEnterCount (void)
105 #ifdef LOCAL_CRITSEC_COUNT
106 return (int)cs_EnterCount;
108 return pcs->RecursionCount;
112 void AfsClass_UnixTimeToSystemTime (LPSYSTEMTIME pst, ULONG ut, BOOL fElapsed)
116 memset (pst, 0x00, sizeof(SYSTEMTIME));
120 // A Unix time is the number of seconds since 1/1/1970.
121 // The first step in this conversion is to change that count-of-seconds
122 // into a count-of-100ns-intervals...
125 ldw.QuadPart = (LONGLONG)10000000 * (LONGLONG)ut;
127 // Then adjust the count to be a count-of-100ns-intervals since
128 // 1/1/1601, instead of 1/1/1970. That means adding a *big* number...
130 ldw.QuadPart += (LONGLONG)0x019DB1DED53E8000;
132 // Now the count is effectively a FILETIME, which we can convert
133 // to a SYSTEMTIME with a Win32 API.
136 ft.dwHighDateTime = (DWORD)ldw.HighPart;
137 ft.dwLowDateTime = (DWORD)ldw.LowPart;
138 FileTimeToSystemTime (&ft, pst);
144 pst->wDayOfWeek -= 1;
150 ULONG AfsClass_SystemTimeToUnixTime (LPSYSTEMTIME pst)
158 if (st.wYear == 1970)
162 if (!SystemTimeToFileTime (&st, &ft))
166 now.HighPart = (LONG)ft.dwHighDateTime;
167 now.LowPart = (ULONG)ft.dwLowDateTime;
169 LARGE_INTEGER offset;
170 offset.HighPart = 0x019db1de;
171 offset.LowPart = 0xd53e8000;
173 LARGE_INTEGER result;
174 result.QuadPart = (now.QuadPart - offset.QuadPart) / 10000000;
175 return (ULONG)result.LowPart;
179 void AfsClass_ElapsedTimeToSeconds (ULONG *pcSeconds, LPSYSTEMTIME pet)
184 *pcSeconds += pet->wSecond;
185 *pcSeconds += pet->wMinute * 60L;
186 *pcSeconds += pet->wHour * 60L * 60L;
187 *pcSeconds += pet->wDay * 60L * 60L * 24L;
192 double AfsClass_FileTimeToDouble (FILETIME *pft)
195 rc = (double)pft->dwHighDateTime * (double)0x100000000;
196 rc += (double)pft->dwLowDateTime;
201 void AfsClass_RequestLongServerNames (BOOL fLong)
203 fLongServerNames = fLong;
207 void AfsClass_ParseRecurringTime (BOOL *pfEver, LPSYSTEMTIME pst, LPTSTR pszTime)
210 memset (pst, 0x00, sizeof(SYSTEMTIME));
212 if (lstrcmpi (pszTime, TEXT("never")))
216 if (!lstrncmpi (pszTime, TEXT("at"), lstrlen(TEXT("at"))))
217 pszTime += lstrlen(TEXT("at"));
218 while ((*pszTime == ' ') || (*pszTime == '\t'))
221 // first, does it start with a day-of-week?
223 pst->wDayOfWeek = (WORD)(-1); // daily until proven otherwise
225 for (size_t ii = 0; ii < 7; ++ii)
227 if (!lstrncmpi (apszDays[ii], pszTime, 3))
229 pst->wDayOfWeek = ii;
234 // next, find the hour
236 while (*pszTime && !isdigit(*pszTime))
239 TCHAR szComponent[ cchRESOURCE ];
240 lstrcpy (szComponent, pszTime);
242 for (pch = szComponent; isdigit(*pch); ++pch)
246 pst->wHour = atoi(szComponent);
248 // next, find the minutes
250 while (isdigit(*pszTime))
252 while (*pszTime && !isdigit(*pszTime))
255 lstrcpy (szComponent, pszTime);
256 for (pch = szComponent; isdigit(*pch); ++pch)
260 pst->wMinute = atoi(szComponent);
262 // next, check for a 'am' or 'pm' marker
264 for ( ; *pszTime; ++pszTime)
266 if (tolower(*pszTime) == TEXT('p'))
272 if (tolower(*pszTime) == TEXT('a'))
274 if (pst->wHour >= 12)
283 void AfsClass_FormatRecurringTime (LPTSTR pszTarget, SYSTEMTIME *pst)
287 wsprintf (pszTarget, TEXT("never"));
291 WORD wHour = ((pst->wHour % 12) == 0) ? 12 : (pst->wHour % 12);
293 lstrcpy (szAMPM, (pst->wHour >= 12) ? TEXT("pm") : TEXT("am"));
295 if (pst->wDayOfWeek == (WORD)(-1)) // daily at specified time?
297 wsprintf (pszTarget, TEXT("%u:%02u %s"), wHour, pst->wMinute, szAMPM);
299 else // weekly on specified date at specified time?
301 wsprintf (pszTarget, TEXT("%s %u:%02u %s"), apszDays[ pst->wDayOfWeek ], wHour, pst->wMinute, szAMPM);
307 void AfsClass_SplitFilename (LPSTR pszDirectoryA, LPSTR pszFilenameA, LPTSTR pszFullName)
309 CopyStringToAnsi (pszDirectoryA, pszFullName);
311 LPSTR pszLastSlashA = NULL;
312 for (LPSTR pszA = pszDirectoryA; *pszA; ++pszA)
314 if ((*pszA == '/') || (*pszA == '\\'))
315 pszLastSlashA = pszA;
320 strcpy (pszFilenameA, pszDirectoryA);
325 strcpy (pszFilenameA, 1+pszLastSlashA);
331 void AfsClass_SystemTimeToRestartTime (bos_RestartTime_p prt, BOOL fEnable, LPSYSTEMTIME pst)
333 memset (prt, 0x00, sizeof(bos_RestartTime_t));
335 prt->mask = BOS_RESTART_TIME_NEVER;
338 prt->mask = (bos_RestartTimeFields_t)(BOS_RESTART_TIME_HOUR | BOS_RESTART_TIME_MINUTE);
339 prt->hour = pst->wHour;
340 prt->min = pst->wMinute;
342 if (pst->wDayOfWeek != (WORD)-1)
344 prt->mask = (bos_RestartTimeFields_t)(prt->mask | BOS_RESTART_TIME_DAY);
345 prt->day = pst->wDayOfWeek;
351 void AfsClass_RestartTimeToSystemTime (BOOL *pfEnable, LPSYSTEMTIME pst, bos_RestartTime_p prt)
353 memset (pst, 0x00, sizeof(SYSTEMTIME));
355 if ((!prt->mask) || (prt->mask & BOS_RESTART_TIME_NEVER))
362 pst->wHour = (prt->mask & BOS_RESTART_TIME_HOUR) ? prt->hour : 0;
363 pst->wMinute = (prt->mask & BOS_RESTART_TIME_MINUTE) ? prt->min : 0;
364 pst->wDayOfWeek = (prt->mask & BOS_RESTART_TIME_DAY) ? prt->day : (WORD)-1;
369 void AfsClass_IntToAddress (LPSOCKADDR_IN pAddr, int IntAddr)
371 memset (pAddr, 0x00, sizeof(SOCKADDR_IN));
372 pAddr->sin_family = AF_INET;
373 pAddr->sin_addr.s_addr = htonl(IntAddr);
377 void AfsClass_AddressToInt (int *pIntAddr, LPSOCKADDR_IN pAddr)
379 *pIntAddr = ntohl(pAddr->sin_addr.s_addr);
383 void AfsClass_SpecifyRefreshDomain (DWORD dwWantUser)
389 BOOL AfsClass_Initialize (ULONG *pStatus)
391 if (!Worker_Initialize (pStatus))
398 void AfsClass_GenFullUserName (LPTSTR pszTarget, LPCTSTR pszPrincipal, LPCTSTR pszInstance)
400 lstrcpy (pszTarget, pszPrincipal);
401 if (pszInstance && *pszInstance)
402 wsprintf (&pszTarget[ lstrlen(pszTarget) ], TEXT(".%s"), pszInstance);