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

📄 httpddev.cpp

📁 Windows CE 6.0 Server 源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft shared
// source or premium shared source license agreement under which you licensed
// this source code. If you did not accept the terms of the license agreement,
// you are not authorized to use this source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the SOURCE.RTF on your install media or the root of your tools installation.
// THE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
/*--
Module Name: httpddev.cpp
Abstract: HTTP device driver exports, and routines that are
                  exposed to facilitate their manipulation.
--*/


#include "httpd.h"


BOOL HttpStopAndRestart(void);

//
//   Functions exported from HTTPD.
//
extern "C" void HttpdStart() {
    HANDLE hFile;
    DWORD dwBytesReturned;

    hFile = CreateFile(HTTPD_DEV_NAME,GENERIC_READ|GENERIC_WRITE,0,
        NULL,OPEN_EXISTING,0,NULL);

    if (INVALID_HANDLE_VALUE == hFile)
        return;

    DeviceIoControl(hFile,IOCTL_SERVICE_START,0,0,0,0,&dwBytesReturned,0);
    CloseHandle(hFile);
}

extern "C" void HttpdStop() {
    HANDLE hFile;
    DWORD dwBytesReturned;

    hFile = CreateFile(HTTPD_DEV_NAME,GENERIC_READ|GENERIC_WRITE,0,
        NULL,OPEN_EXISTING,0,NULL);

    if (INVALID_HANDLE_VALUE == hFile)
        return;

    DeviceIoControl(hFile,IOCTL_SERVICE_STOP,0,0,0,0,&dwBytesReturned,0);
    CloseHandle(hFile);
}

//  This call must NOT block!  It's possible for an ISAPI extension to
//  call this function, in which case we want the ISAPI extension to continue
//  executing so that request (along with any others) can terminate.
//  Only after the request has terminated can we start up again.

extern "C" void HttpdStopAndRestart() {
    HANDLE hFile;
    DWORD dwBytesReturned;

    hFile = CreateFile(HTTPD_DEV_NAME,GENERIC_READ|GENERIC_WRITE,0,
        NULL,OPEN_EXISTING,0,NULL);

    if (INVALID_HANDLE_VALUE == hFile)
        return;

    DeviceIoControl(hFile,IOCTL_SERVICE_REFRESH,0,0,0,0,&dwBytesReturned,0);
    CloseHandle(hFile);
}

//
// Internal helper functions to handle state changes.
//
void WaitForHttpToShutDown(void) {
    CloseAllConnections();
    g_pVars->m_fAcceptConnections = FALSE;
    WaitForConnectionThreadsToEnd();
    CleanupGlobalMemory(g_cWebsites);
}

// lpv = NULL when we don't want to start up again, lpv=1 when we'll restart immediatly.
DWORD WINAPI HttpdStopThread(LPVOID lpv) {
    MyWaitForAdminThreadReadyState();

    DEBUGCHK(g_fState == SERVICE_STATE_SHUTTING_DOWN && g_hAdminThread);

    WaitForHttpToShutDown();

    DEBUGCHK(g_fState == SERVICE_STATE_SHUTTING_DOWN);
    DEBUGCHK(!g_pVars && !g_pWebsites && (g_cWebsites==0));

    if (!lpv) {
        g_fState = SERVICE_STATE_OFF;
        CloseHandle(g_hAdminThread);
        g_hAdminThread = 0;
    }
    return 0;
}

//  This thread stops the server and restarts it.
DWORD WINAPI HttpdStopAndRestartThread(LPVOID lpv)  {
    MyWaitForAdminThreadReadyState();
    HttpdStopThread((void*)1);

    g_fState = SERVICE_STATE_STARTING_UP;
    InitializeGlobals();

    CloseHandle(g_hAdminThread);
    g_hAdminThread = 0;
    return 0;
}

BOOL HttpStopAndRestart(void)  {
    if (InterlockedCompareExchange(&g_fState,(INTERLOCKED_COMP) SERVICE_STATE_SHUTTING_DOWN, (INTERLOCKED_COMP) SERVICE_STATE_ON) != (INTERLOCKED_RESULT)SERVICE_STATE_ON) {
        SetLastError(ERROR_SERVICE_NOT_ACTIVE);
        return FALSE;
    }

    DEBUGCHK(!g_hAdminThread);

    g_hAdminThread = MyCreateThread(HttpdStopAndRestartThread,0);
    return g_hAdminThread ? TRUE : FALSE;
}

// Called to shutdown all HTTPD threads.
BOOL HttpShutDown(void) {
    // persist our shutdown state to registry.
    CReg reg(HKEY_LOCAL_MACHINE, RK_HTTPD);
    reg.SetDW(RV_ISENABLED,0);

    if (InterlockedCompareExchange(&g_fState,SERVICE_STATE_SHUTTING_DOWN,
                                          SERVICE_STATE_ON) != (INTERLOCKED_RESULT)SERVICE_STATE_ON) {
        SetLastError(ERROR_SERVICE_NOT_ACTIVE);
        return FALSE;
    }

    DEBUGCHK(!g_hAdminThread);
    g_hAdminThread = MyCreateThread(HttpdStopThread,0);
    return g_hAdminThread ? TRUE : FALSE;
}

BOOL HttpUnload(void)  {
    LONG fOldState;

    DEBUGMSG(ZONE_INIT,(L"HTTPD: Starting to unload service\r\n"));

    // If a stop/start/restart thread is running already, then wait for it before continuing.
    if (g_hAdminThread)
        WaitForSingleObject(g_hAdminThread,INFINITE);

    Sleep(100);

    // If the service is either shutting down or starting up then we can't unload.
    // Succeeding on unload but not really unloading is NOT an option, lib will get freed by services.exe or device.exe
    // when this function returns and running threads in httpd's context will crash, so keep polling as long as it takes.
    while (1) {
        if ((fOldState = (long)InterlockedCompareExchange(&g_fState,SERVICE_STATE_UNLOADING,SERVICE_STATE_ON)) == SERVICE_STATE_ON ||
            (fOldState = (long)InterlockedCompareExchange(&g_fState,SERVICE_STATE_UNLOADING,SERVICE_STATE_OFF)) == SERVICE_STATE_OFF)
        {
            break;
        }
        DEBUGMSG(ZONE_INIT,(L"HTTPD: HttpUnload can't unload service, HTTPD state must be on or off, current state = %d, sleep for 2 seconds\r\n",g_fState));
        Sleep(2000);
    }
    DEBUGCHK(!g_hAdminThread);

    if (fOldState == SERVICE_STATE_ON) {
        WaitForHttpToShutDown();
    }

    if (g_pTimer) {
        g_pTimer->Shutdown();
        delete g_pTimer;
        g_pTimer = NULL;
    }

    svsutil_DeInitializeInterfaceMapperOnce(); // not DLLMain safe.

    DEBUGCHK(g_fState == SERVICE_STATE_UNLOADING);
    DEBUGCHK(!g_pVars && !g_hAdminThread && !g_pWebsites && (g_cWebsites==0));
    DEBUGMSG(ZONE_INIT,(L"HTTPD: Done unloading service\r\n"));
    return TRUE;
}


// Certain operations may only be performed by trusted caller (mostly services.exe itself)
BOOL CheckCallerTrusted(void) {
    // Currently not tied into ACLs.
    return TRUE;
}


//      @func BOOL | HTP_IOControl | Device IO control routine
//  @parm DWORD | dwOpenData | value returned from HTP_Open call
//  @parm DWORD | dwCode | io control code to be performed
//  @parm PBYTE | pBufIn | input data to the device
//  @parm DWORD | dwLenIn | number of bytes being passed in
//  @parm PBYTE | pBufOut | output data from the device
//  @parm DWORD | dwLenOut |maximum number of bytes to receive from device
//  @parm PDWORD | pdwActualOut | actual number of bytes received from device
//  @rdesc      Returns TRUE for success, FALSE for failure
//      @remark Routine exported by a device driver.  "PRF" is the string passed
//          in as lpszType in RegisterDevice

extern "C" BOOL HTP_IOControl(DWORD dwData, DWORD dwCode, PBYTE pBufIn,
              DWORD dwLenIn, PBYTE pBufOut, DWORD dwLenOut,
              PDWORD pdwActualOut)  {
    DEBUGMSG (ZONE_DEVICE, (TEXT("HTP_IOControl(dwCode = 0x%X)\r\n"), dwCode));

    DWORD dwOut;

    switch (dwCode)
    {
        case IOCTL_SERVICE_START:
        {
            CReg reg;
            reg.Open(HKEY_LOCAL_MACHINE,RK_HTTPD);
            reg.SetDW(RV_ISENABLED,1);

            if (InterlockedCompareExchange(&g_fState,  SERVICE_STATE_STARTING_UP,
                       SERVICE_STATE_OFF) == SERVICE_STATE_OFF) {

                DEBUGCHK(!g_hAdminThread);
                g_hAdminThread = MyCreateThread(InitializeGlobalsThread,0);
                if (g_hAdminThread) {
                    return TRUE;
                }
                g_fState = SERVICE_STATE_OFF;
                return FALSE;
            }
            SetLastError(ERROR_SERVICE_ALREADY_RUNNING);
            DEBUGMSG(ZONE_INIT,(L"HTTPD: HTP_IOControl cannot process, IOCTL_SERVICE_START, state != starting up, serviceState=%d\r\n",g_fState));
            return FALSE;
        }
        break;

        case IOCTL_SERVICE_STOP:
            return HttpShutDown();
        break;

        case IOCTL_SERVICE_REFRESH:
            return HttpStopAndRestart();
        break;

        case IOCTL_SERVICE_STATUS:
            __try {
                if (!pBufOut || dwLenOut < sizeof(DWORD)) {
                    SetLastError(ERROR_INVALID_PARAMETER);
                    return FALSE;
                }
                *(DWORD *)pBufOut = g_fState;
                if (pdwActualOut)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -