📄 sntp.cxx
字号:
iErr = ERROR_SERVICE_NOT_ACTIVE;
if (iErr == ERROR_SUCCESS)
iErr = gpTS->UpdateNowOrLater (Now);
gpTS->Unlock ();
}
DEBUGMSG(ZONE_TRACE, (L"[TIMESVC] Time update request : %d\r\n", iErr));
return iErr;
}
static DWORD WINAPI ForceSyncTime (LPVOID dwUnused) {
DEBUGMSG(ZONE_TRACE, (L"[TIMESVC] Forced time update request from OS\r\n"));
int iErr = ERROR_SERVICE_DOES_NOT_EXIST;
if (gpTS) {
gpTS->Lock ();
iErr = ERROR_SUCCESS;
if (! gpTS->IsStarted())
iErr = ERROR_SERVICE_NOT_ACTIVE;
if (iErr == ERROR_SUCCESS) {
iErr = gpTS->ForcedUpdate ();
}
gpTS->Unlock ();
}
DEBUGMSG(ZONE_TRACE, (L"[TIMESVC] Forced time update request : %d\r\n", iErr));
return iErr;
}
static DWORD WINAPI GetTimeOffsetOnServer (LPVOID lpArg) {
DEBUGMSG(ZONE_TRACE, (L"[TIMESVC] Time offset request from OS\r\n"));
GetTimeOffset *pArg = (GetTimeOffset *)lpArg;
int fTimeChanged = FALSE;
int iSrv = 0;
for ( ; ; ) {
if (! gpTS) {
DEBUGMSG(ZONE_ERROR, (L"[TIMESVC] GetServerOffset: service not initialized!\r\n"));
return ERROR_SERVICE_DOES_NOT_EXIST;
}
char hostname[DNS_MAX_NAME_BUFFER_LENGTH];
if (pArg->cchServer[0] == '\0') {
int iErr = ERROR_SUCCESS;
gpTS->Lock ();
if (gpTS->IsStarted ()) {
if (iSrv < gpTS->cServers) {
memcpy (hostname, gpTS->sntp_servers[iSrv++], sizeof(hostname));
} else {
DEBUGMSG(ZONE_WARNING, (L"[TIMESVC] GetServerOffset: all servers queried, but no connection.\r\n"));
iErr = ERROR_HOST_UNREACHABLE;
}
} else {
DEBUGMSG(ZONE_ERROR, (L"[TIMESVC] GetServerOffset: service not active!\r\n"));
iErr = ERROR_SERVICE_NOT_ACTIVE;
}
gpTS->Unlock ();
if (iErr != ERROR_SUCCESS)
return iErr;
} else
memcpy (hostname, pArg->cchServer, sizeof(hostname));
if (GetOffsetFromServer (hostname, &pArg->llOffset))
return ERROR_SUCCESS;
if (pArg->cchServer[0] != '\0')
break;
}
DEBUGMSG(ZONE_TRACE, (L"[TIMESVC] GetServerOffset : could not connect (ERROR_HOST_UNREACHABLE)\r\n"));
return ERROR_HOST_UNREACHABLE;
}
static DWORD WINAPI SetTime (LPVOID dwUnused) {
DEBUGMSG(ZONE_TRACE, (L"[TIMESVC] Force time update request from OS\r\n"));
int iErr = ERROR_SERVICE_DOES_NOT_EXIST;
if (gpTS) {
gpTS->Lock ();
iErr = ERROR_SUCCESS;
if (! gpTS->IsStarted())
iErr = ERROR_SERVICE_NOT_ACTIVE;
if (iErr == ERROR_SUCCESS)
iErr = gpTS->UpdateNowOrLater (Now, TRUE);
gpTS->Unlock ();
}
DEBUGMSG(ZONE_TRACE, (L"[TIMESVC] Force time update request : %d\r\n", iErr));
return iErr;
}
static DWORD WINAPI NetworkChange (LPVOID dwUnused) {
DEBUGMSG(ZONE_TRACE, (L"[TIMESVC] Network up/down event from OS\r\n"));
int iErr = ERROR_SERVICE_DOES_NOT_EXIST;
if (gpTS) {
gpTS->Lock ();
iErr = ERROR_SUCCESS;
if (! gpTS->IsStarted())
iErr = ERROR_SERVICE_NOT_ACTIVE;
if ((iErr == ERROR_SUCCESS) && (gpTS->LastUpdateFailed ()))
iErr = gpTS->UpdateNowOrLater (Now);
gpTS->Unlock ();
}
DEBUGMSG(ZONE_TRACE, (L"[TIMESVC] Time update request : %d\r\n", iErr));
return iErr;
}
static DWORD WINAPI StartServer (LPVOID lpUnused) {
DEBUGMSG(ZONE_TRACE, (L"[TIMESVC] Start Server request from OS\r\n"));
int iErr = ERROR_SERVICE_DOES_NOT_EXIST;
if (gpTS) {
gpTS->Lock ();
iErr = ERROR_SUCCESS;
if (gpTS->IsStarted())
iErr = ERROR_ALREADY_INITIALIZED;
WSADATA wsd;
WSAStartup (MAKEWORD(1,1), &wsd);
if (iErr == ERROR_SUCCESS)
iErr = gpTS->RefreshConfig ();
if (iErr == ERROR_SUCCESS)
iErr = gpTS->Start ();
gpTS->Unlock ();
}
DEBUGMSG(ZONE_TRACE, (L"[TIMESVC] Start Server request : %d\r\n", iErr));
return iErr;
}
static DWORD WINAPI StopServer (LPVOID lpUnused) {
DEBUGMSG(ZONE_TRACE, (L"[TIMESVC] Stop Server request from OS\r\n"));
int iErr = ERROR_SERVICE_DOES_NOT_EXIST;
if (gpTS) {
gpTS->Lock ();
iErr = ERROR_SUCCESS;
if (! gpTS->IsStarted())
iErr = ERROR_SERVICE_NOT_ACTIVE;
SVSThreadPool *pp = (iErr == ERROR_SUCCESS) ? gpTS->Stop () : NULL;
gpTS->Unlock ();
if (pp) {
delete pp;
WSACleanup ();
}
}
DEBUGMSG(ZONE_TRACE, (L"[TIMESVC] Stop Server request : %d\r\n", iErr));
return iErr;
}
static DWORD WINAPI ExternalTimeUpdate (LPVOID lpUnused) {
DEBUGMSG(ZONE_TRACE, (L"[TIMESVC] External time update indicator from OS\r\n"));
int iErr = ERROR_SERVICE_DOES_NOT_EXIST;
if (gpTS) {
gpTS->Lock ();
iErr = ERROR_SUCCESS;
if (! gpTS->IsStarted()) {
iErr = ERROR_SERVICE_NOT_ACTIVE;
} else {
iErr = gpTS->TimeChanged ();
}
gpTS->Unlock ();
}
DEBUGMSG(ZONE_TRACE, (L"[TIMESVC] External time update indicator : %d\r\n", iErr));
return iErr;
}
///////////////////////////////////////////////////////////////////////
//
// OS interface
//
//
static DWORD WINAPI NotifyThread (LPVOID lpUnused) {
DEBUGMSG(ZONE_INIT, (L"[TIMESVC] NotifyThread started\r\n"));
HMODULE hCoreDll = LoadLibrary (L"coredll.dll");
tCeRunAppAtEvent pCeRunAppAtEvent = (tCeRunAppAtEvent)GetProcAddress (hCoreDll, L"CeRunAppAtEvent");
HANDLE hWakeup = CreateEvent (NULL, FALSE, FALSE, L"timesvc\\wakeup");
HANDLE hTimeSet = CreateEvent (NULL, FALSE, FALSE, L"timesvc\\timeset");
HANDLE hNotifyInitialized = OpenEvent (EVENT_ALL_ACCESS, FALSE, NOTIFICATION_EVENTNAME_API_SET_READY);
if (! (pCeRunAppAtEvent && hWakeup && hTimeSet && hNotifyInitialized)) {
DEBUGMSG(ZONE_ERROR, (L"[TIMESVC] NotifyThread: could not initialize, aborting\r\n"));
FreeLibrary (hCoreDll);
if (hWakeup)
CloseHandle (hWakeup);
if (hTimeSet)
CloseHandle (hTimeSet);
if (hNotifyInitialized)
CloseHandle (hNotifyInitialized);
return 0;
}
// Clean up...
int fNotificationsPresent = (WAIT_OBJECT_0 == WaitForSingleObject (hNotifyInitialized, NOTIFICATION_WAIT_SEC*1000));
CloseHandle (hNotifyInitialized);
if (! fNotificationsPresent) {
CloseHandle (hWakeup);
CloseHandle (hTimeSet);
return 0;
}
pCeRunAppAtEvent (NAMED_EVENT_PREFIX_TEXT L"timesvc\\wakeup", 0);
pCeRunAppAtEvent (NAMED_EVENT_PREFIX_TEXT L"timesvc\\timeset", 0);
pCeRunAppAtEvent (NAMED_EVENT_PREFIX_TEXT L"timesvc\\wakeup", NOTIFICATION_EVENT_WAKEUP);
pCeRunAppAtEvent (NAMED_EVENT_PREFIX_TEXT L"timesvc\\timeset", NOTIFICATION_EVENT_TIME_CHANGE);
HMODULE hiphlp = LoadLibrary (L"iphlpapi.dll");
tNotifyAddrChange pNotifyAddrChange = hiphlp ? (tNotifyAddrChange)GetProcAddress (hiphlp, L"NotifyAddrChange") : NULL;
HANDLE hNetwork = NULL;
if (pNotifyAddrChange)
pNotifyAddrChange(&hNetwork, NULL);
for ( ; ; ) {
HANDLE ah[4];
ah[0] = hExitEvent;
ah[1] = hWakeup;
ah[2] = hTimeSet;
ah[3] = hNetwork;
DWORD cEvents = hNetwork ? 4 : 3;
DWORD dwRes = WaitForMultipleObjects (cEvents, ah, FALSE, INFINITE);
if (dwRes == (WAIT_OBJECT_0+1)) // Wakeup
Exec (SyncTime);
else if (dwRes == (WAIT_OBJECT_0+2)) // Time reset
Exec (ExternalTimeUpdate);
else if (dwRes == (WAIT_OBJECT_0+3)) // Network address changed
Exec (NetworkChange);
else
break;
}
pCeRunAppAtEvent (NAMED_EVENT_PREFIX_TEXT L"timesvc\\wakeup", 0);
pCeRunAppAtEvent (NAMED_EVENT_PREFIX_TEXT L"timesvc\\timeset", 0);
CloseHandle (hWakeup);
CloseHandle (hTimeSet);
if (hiphlp)
FreeLibrary (hiphlp);
FreeLibrary (hCoreDll);
DEBUGMSG(ZONE_INIT, (L"Notify Thread exited\r\n"));
return 0;
}
static int StartOsNotifications (void) {
if (hExitEvent)
return FALSE;
hExitEvent = CreateEvent (NULL, TRUE, FALSE, NULL);
hNotifyThread = NULL;
if (hExitEvent) {
hNotifyThread = CreateThread (NULL, 0, NotifyThread, NULL, 0, NULL);
if (! hNotifyThread) {
CloseHandle (hExitEvent);
hExitEvent = NULL;
}
}
return hNotifyThread != NULL;
}
static int StopOsNotifications (void) {
if (hNotifyThread) {
SetEvent (hExitEvent);
CloseHandle (hExitEvent);
hExitEvent = NULL;
WaitForSingleObject (hNotifyThread, INFINITE);
CloseHandle (hNotifyThread);
hNotifyThread = NULL;
}
return TRUE;
}
//
// Public interface
//
int InitializeSNTP (HINSTANCE hMod) {
svsutil_Initialize ();
DEBUGREGISTER(hMod);
DEBUGMSG(ZONE_INIT, (L"[TIMESVC] Module loaded\r\n"));
gpTS = new TimeState;
return (gpTS != NULL) ? ERROR_SUCCESS : ERROR_OUTOFMEMORY;
}
void DestroySNTP (void) {
delete gpTS;
gpTS = NULL;
DEBUGMSG(ZONE_INIT, (L"[TIMESVC] Module unloaded\r\n"));
svsutil_DeInitialize ();
}
int StartSNTP (void) {
int iErr = Exec (StartServer);
if (iErr == ERROR_SUCCESS)
StartOsNotifications ();
return iErr;
}
int StopSNTP (void) {
int iErr = Exec (StopServer);
if (iErr == ERROR_SUCCESS)
StopOsNotifications ();
return iErr;
}
int RefreshSNTP (void) {
int iErr = Exec (StopServer);
if (iErr == ERROR_SUCCESS)
iErr = Exec (StartServer);
return iErr;
}
DWORD GetStateSNTP (void) {
DWORD dwState = SERVICE_STATE_UNINITIALIZED;
if (gpTS) {
gpTS->Lock ();
dwState = gpTS->IsStarted () ? SERVICE_STATE_ON : SERVICE_STATE_OFF;
gpTS->Unlock ();
}
return dwState;
}
int ServiceControlSNTP (PBYTE pBufIn, DWORD dwLenIn, PBYTE pBufOut, DWORD dwLenOut, PDWORD pdwActualOut, int *pfProcessed) {
int iErr = ERROR_INVALID_PARAMETER;
*pfProcessed = FALSE;
if ((dwLenIn == sizeof(L"sync")) && (wcsicmp ((WCHAR *)pBufIn, L"sync") == 0)) {
*pfProcessed = TRUE;
return Exec (ForceSyncTime);
} else if ((dwLenIn == sizeof(L"set")) && (wcsicmp ((WCHAR *)pBufIn, L"set") == 0)) {
*pfProcessed = TRUE;
return Exec (SetTime);
} else if ((dwLenIn == sizeof(L"update")) && (wcsicmp ((WCHAR *)pBufIn, L"update") == 0)) {
*pfProcessed = TRUE;
return Exec (ExternalTimeUpdate);
} else if ((dwLenIn >= sizeof(L"gettimeoffset")) && (wcsnicmp ((WCHAR *)pBufIn, L"gettimeoffset", (sizeof(L"gettimeoffset") - sizeof(L""))/ sizeof(WCHAR)) == 0)) {
*pfProcessed = TRUE;
// Check for '\0' sentinel
if (((WCHAR *)pBufIn)[(dwLenIn-1)/sizeof(WCHAR)] != '\0')
return ERROR_INVALID_PARAMETER;
if ((dwLenOut != sizeof (__int64)) || (! pdwActualOut))
return ERROR_INVALID_PARAMETER;
GetTimeOffset *pArg = (GetTimeOffset *)LocalAlloc (LMEM_FIXED, sizeof(GetTimeOffset));
if (! pArg)
return GetLastError ();
pArg->llOffset = 0;
pArg->cchServer[0] = '\0';
dwLenIn -= (sizeof(L"gettimeoffset") - sizeof(L""));
pBufIn += (sizeof(L"gettimeoffset") - sizeof(L""));
if (dwLenIn > sizeof(WCHAR)) {
if (*(WCHAR *)pBufIn != ' ') {
LocalFree (pArg);
return ERROR_INVALID_PARAMETER;
}
dwLenIn += sizeof(WCHAR);
pBufIn += sizeof(WCHAR);
if ((dwLenIn < 2*sizeof(WCHAR)) || (*(WCHAR *)pBufIn == '\0')) {
LocalFree (pArg);
return ERROR_INVALID_PARAMETER;
}
if (0 == WideCharToMultiByte (CP_ACP, 0, (WCHAR *)pBufIn, -1, (LPSTR)pArg->cchServer, sizeof(pArg->cchServer), NULL, NULL)) {
LocalFree (pArg);
return GetLastError ();
}
} else {
SVSUTIL_ASSERT (*(WCHAR *)pBufIn == '\0');
}
iErr = Exec (GetTimeOffsetOnServer, pArg);
if (iErr == ERROR_SUCCESS) {
memcpy (pBufOut, &pArg->llOffset, sizeof(pArg->llOffset));
*pdwActualOut = sizeof(pArg->llOffset);
}
LocalFree (pArg);
}
return iErr;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -