⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sntp.cxx

📁 Windows CE 6.0 Server 源码
💻 CXX
📖 第 1 页 / 共 4 页
字号:
            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 + -