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

📄 soapisap.cpp

📁 Windows CE 6.0 Server 源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
            }
        fRetVal = DllProcessAttach(g_hInstance);
        CoUninitialize();
#endif 

   

    pVer->dwExtensionVersion = HSE_VERSION;

#ifndef UNDER_CE
    lstrcpynA( pVer->lpszExtensionDesc, "MSSOAP Isapi Listener ", HSE_MAX_EXT_DLL_NAME_LEN );
#else
    strncpy( pVer->lpszExtensionDesc, "MSSOAP Isapi Listener ", HSE_MAX_EXT_DLL_NAME_LEN );
#endif 

    EnterCriticalSection(&g_cs);

#ifdef UNDER_CE
    if(NULL == g_hTerminateThread)
    {
       g_hTerminateThread = CreateThread(NULL, 0, TerminateISAPIThread, 0, 0, 0);
       ASSERT(NULL != g_hTerminateThread);

       g_hTerminateEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
       ASSERT(NULL != g_hTerminateEvent);       
    }
#endif 


    if (!g_fThreadPoolInitialized)
    {
        if (InitializeThreadPool(g_cThreads, g_cObjCachePerThread) != 0)
        {
            fRetVal = FALSE;
            goto Cleanup;
        }
    }

Cleanup:
    ++g_cExtensions;
    LeaveCriticalSection(&g_cs);

    if (!fRetVal)
    {
        TerminateExtension(0);
    }

    return fRetVal;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
//  function: TerminateExtension ( DWORD dwFlags )
//
//  parameters:
//          Arguments:
//              dwFlags - specifies whether the DLL can refuse to unload or not
//          Returns:
//              TRUE, if the DLL can be unloaded
//
//  description:
//          This is optional ISAPI extension DLL entry point.
//          If present, it will be called before unloading the DLL,
//          giving it a chance to perform any shutdown procedures.
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////

BOOL WINAPI TerminateExtension ( DWORD dwFlags )
{
#ifdef UNDER_CE
    DEBUGMSG(SOAP_ISAPI_DBG,(L"[SOAPISAPI] TerminateExtension--setting terminate event\n"));               
    SetEvent(g_hTerminateEvent);
    #ifdef DEBUG
    DWORD dwRet = 
    #endif
    WaitForSingleObject(g_hTerminateEvent, INFINITE);
    DEBUGMSG(SOAP_ISAPI_DBG,(L"[SOAPISAPI] --TerminateExtension--I'm awake, exiting\n"));               
    
    ASSERT(dwRet == WAIT_OBJECT_0);  
#else
    EnterCriticalSection(&g_cs);

    if (--g_cExtensions == 0)
    {

        TerminateThreadPool();
    }

    LeaveCriticalSection(&g_cs);
#endif 
    return TRUE;
}


/////////////////////////////////////////////////////////////////////////////////////////////////////////
//  function: HttpExtensionProc(EXTENSION_CONTROL_BLOCK *pECB)
//
//  parameters:
//          Arguments:   pECB - pointer to the extenstion control block
//
//          Returns:     HSE_STATUS_PENDING on successful transmission completion
//                       HSE_STATUS_ERROR on failure
//
//  description:
//          Http extension proc called by the web server on request.
//          Queue's up a request to the worker queue for async
//          execution of the query.
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////
DWORD WINAPI HttpExtensionProc (EXTENSION_CONTROL_BLOCK *pECB )
{
    if (g_pThreadPool->pWorkerQueue->dwSize < MAX_REQUEST_QUEUE_SIZE)
    {
        PWORKERITEM pItem = CreateWorkerItem(ProcessRequest, (void *)pECB);

        if (pItem)
        {
#ifdef UNDER_CE
            //NOTE: we have to cache this because as soon as we put the
            //  WORKERITEM on the queue we lose ownership
            HANDLE hProcessingHandle = pItem->hFinishedProcessing;
            WorkerEnqueue(g_pThreadPool->pWorkerQueue, pItem);
           
            DWORD dwRet = WaitForSingleObject(hProcessingHandle, INFINITE);
            ASSERT(dwRet == WAIT_OBJECT_0);
    
             if(NULL != hProcessingHandle)
                CloseHandle(hProcessingHandle);

 
            if(dwRet == WAIT_OBJECT_0)
            {
                BOOL fCanKeepAlive = FALSE;
                //do a check to see if we CAN do a keepalive
                pECB->ServerSupportFunction(pECB->ConnID,
                    HSE_REQ_IS_KEEP_CONN,
                    &fCanKeepAlive, NULL, NULL );                
                
                if(fCanKeepAlive)
                    return HSE_STATUS_SUCCESS_AND_KEEP_CONN;
                else
                    return HSE_STATUS_SUCCESS;
            }
            else
                return HSE_STATUS_ERROR;

#else
            WorkerEnqueue(g_pThreadPool->pWorkerQueue, pItem);
            return HSE_STATUS_PENDING;
#endif             
        }
    }

    return HSE_STATUS_ERROR;
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
//  function: ProcessRequest(void * pContext)
//
//  parameters:
//          Arguments:   pContext - pointer to the extenstion control block
//
//  description:
//          Process a query request, a callback called by a thread from
//          the thread pool when a query is queued up by iis.
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////

DWORD ProcessRequest(void * pContext)
{

    PREQUESTINFO pRequestInfo = (PREQUESTINFO)pContext;
    PTHREADINFO  pThreadInfo  = (PTHREADINFO)pRequestInfo->m_pvThreadInfo;
    EXTENSION_CONTROL_BLOCK *pECB = (EXTENSION_CONTROL_BLOCK*)pRequestInfo->m_pvContext;
    HRESULT     hr = S_OK;
    CRequest	cReq(pECB, pThreadInfo);
    CRequest*   pRequest = &cReq;
#ifndef UNDER_CE
    HANDLE      hRequestToken = NULL;
    BOOL        fImpersonate = FALSE;
#endif 
    CAutoBSTR bstrSoapAction;

    TRACEL((2, (const LPCSTR) _T("Processing request: %S\r\n"), pECB->lpszQueryString));

#ifndef CE_NO_EXCEPTIONS
    try
    {
#endif 
        CHK (pRequest->Validate());
        //
        // Get the request token from IIS and set the token for this thread
        //

#ifndef UNDER_CE
        if(pECB->ServerSupportFunction(
                    pECB->ConnID,
                    HSE_REQ_GET_IMPERSONATION_TOKEN,
                    &hRequestToken,
                    NULL,
                    NULL
                    ))
        {
            //
            //Impersonate the logged on user
            //
            if (ImpersonateLoggedOnUser(hRequestToken))
                fImpersonate = TRUE;
            else
            {
                pRequest->SetErrorCode(Error_AccessDenied);
                CHK(E_FAIL);
            }
        }
#endif 

        // We only process GET, POST or HEAD requests here
        if(stricmp(pECB->lpszMethod, "POST"))
        {
            DEBUGMSG(SOAP_PROCESS_REQUEST,(L"[SOAPISAPI] got a POST\n"));

            if (!stricmp(pECB->lpszMethod, "GET"))
            {
                hr = pRequest->ProcessGet(FALSE);
            }
            else if (!stricmp(pECB->lpszMethod, "HEAD"))
            {

                hr = pRequest->ProcessGet(TRUE);
            }
            else
            {
                pRequest->SetErrorCode(Error_MethodNotAllowed);
            }
            goto Cleanup;
        }

        // We only process POST from here on
        if (FAILED(hr = pRequest->ProcessPathInfo()))
        {
            CHK (bstrSoapAction.Assign(pRequest->GetHeaderParam("SOAPAction"), FALSE));
            pRequest->WriteFaultMessage(hr, bstrSoapAction);
            goto Cleanup;
        }

        if (FAILED(hr = pRequest->ProcessParams()))
        {
            CHK (bstrSoapAction.Assign(pRequest->GetHeaderParam("SOAPAction"), FALSE));
            pRequest->WriteFaultMessage(hr, bstrSoapAction);
            goto Cleanup;
        }

        if (FAILED(hr = pRequest->ExecuteRequest()))
        {
            CHK (bstrSoapAction.Assign(pRequest->GetHeaderParam("SOAPAction"), FALSE));
            pRequest->WriteFaultMessage(hr, bstrSoapAction);
            goto Cleanup;
        }

#ifndef UNDER_CE
    }
    catch (...)
    {
        ASSERT(0);
        // We come here if we get an Access Violation. At this point we cannot trust any
        // memory or cache in the thread. Just clear the thread's buffer and its
        // cache.
        // Don't try to release memory since it may be corrupted and cause further AVs.
        if (pThreadInfo && pThreadInfo->pObjCache)
            pThreadInfo->pObjCache->ClearCache();
        pRequest->SetErrorCode(Error_InternalError);
    }
#endif 

Cleanup:

    if(pRequest)
        pRequest->FlushContents();

#ifndef UNDER_CE
    if(fImpersonate)
    {
        //
        // ReverToSelf() will set the security context to the IIS security Context
        //
        RevertToSelf();
    }
    pECB->ServerSupportFunction(
            pECB->ConnID,
           HSE_REQ_DONE_WITH_SESSION,
            NULL,
            NULL,
            NULL
            );
#endif 
    TRACEL((2, (const LPCSTR) _T("End Processing request")));
    
#ifdef UNDER_CE
     ASSERT(NULL != pRequestInfo->hFinishedProcessing); 
     SetEvent(pRequestInfo->hFinishedProcessing);
#endif 

    //note: this return isnt used in CE
    return HSE_STATUS_SUCCESS_AND_KEEP_CONN;
}


WCHAR g_wszThreadsRegKey[] = L"Software\\Microsoft\\MSSOAP\\SOAPISAP";
WCHAR g_wszThreadsParentRegKey[] = L"Software\\Microsoft\\MSSOAP";

/////////////////////////////////////////////////////////////////////////////////////////////////////////
//  function: InitRegInfo()
//
//  parameters:
//
//  description:
//          Read the registry Software\\Microsoft\\MSSOAP\\SOAPISAP
//          and get the number of threads.
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////
void InitRegInfo()
{
    HKEY    hKey = (HKEY) INVALID_HANDLE_VALUE;
    DWORD   dwVal, dwLen = sizeof(DWORD);

    if( (ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE, g_wszThreadsRegKey, 0,
                            KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS,
                            &hKey)) || hKey == INVALID_HANDLE_VALUE )
    {
        GetLastError();
        return;
    }


    // Read num threads value.
    if(ERROR_SUCCESS == RegQueryValueEx(hKey, L"NumThreads", NULL, NULL, (LPBYTE) &dwVal, &dwLen))
    {
        g_cThreads = dwVal;
    }

    // Read num objs cahced per thread
    dwLen = sizeof(DWORD);
    if(ERROR_SUCCESS == RegQueryValueEx(hKey, L"ObjCachedPerThread", NULL, NULL, (LPBYTE) &dwVal, &dwLen))
    {
        g_cObjCachePerThread = dwVal;
    }

    // Read max post size allowed
    dwLen = sizeof(DWORD);
    if(ERROR_SUCCESS == RegQueryValueEx(hKey, L"MaxPostSize", NULL, NULL, (LPBYTE) &dwVal, &dwLen))
    {
        g_cbMaxPost = dwVal;
    }

#ifndef UNDER_CE
    dwLen = sizeof(DWORD); //NOTE: setting dwLen was put in by chgray and was not in the
                           // orig STK2.2
    if (RegQueryValueEx(hKey, L"NoNagling", NULL, NULL, (LPBYTE) &dwVal, &dwLen) == ERROR_SUCCESS)
    {
        g_dwNaglingFlags = dwVal ? HSE_IO_SYNC | HSE_IO_NODELAY : 0;
    }
#endif 

    RegCloseKey(hKey);
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
//  function: SetRegInfo()
//
//  parameters:
//
//  description:
//          Initialize the registry Software\\Microsoft\\MSSOAP\\SOAPISAP
//          and the number of threads.
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////
void SetRegInfo()
{
    HRESULT     hr;
    HKEY    hKey = (HKEY) INVALID_HANDLE_VALUE;
    DWORD   dwVal, dwLen = 0;

    if( (ERROR_SUCCESS != RegCreateKeyEx(HKEY_LOCAL_MACHINE, g_wszThreadsRegKey,
                            0, NULL, REG_OPTION_NON_VOLATILE,
                            KEY_SET_VALUE | KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS,
                            NULL, &hKey, &dwVal)) || hKey == INVALID_HANDLE_VALUE )
    {
        GetLastError();
        return;
    }

    //Read/set num threads value.
    dwLen = sizeof(DWORD);
    hr = RegQueryValueEx(hKey, L"NumThreads", NULL, NULL, (LPBYTE) &dwVal, &dwLen);
    if (hr != ERROR_SUCCESS)
    {
        dwVal = (2 * g_si.dwNumberOfProcessors)+ 1;
        dwLen = sizeof(DWORD);
        hr = RegSetValueEx( hKey, L"NumThreads", NULL, REG_DWORD, (LPBYTE)&dwVal, dwLen);
    }

    dwLen = sizeof(DWORD);
    hr = RegQueryValueEx(hKey, L"ObjCachedPerThread", NULL, NULL, (LPBYTE) &dwVal, &dwLen);
    if(ERROR_SUCCESS != hr)
    {
        dwVal = 5;      // default = 5 objects cached per thread
        dwLen = sizeof(DWORD);
        hr = RegSetValueEx( hKey, L"ObjCachedPerThread", NULL, REG_DWORD, (LPBYTE)&dwVal, dwLen);
    }

    dwLen = sizeof(DWORD);
    hr = RegQueryValueEx(hKey, L"MaxPostSize", NULL, NULL, (LPBYTE) &dwVal, &dwLen);
    if(ERROR_SUCCESS != hr)
    {
        dwVal = 100 * 1024;      // default = 100 Kb.
        dwLen = sizeof(DWORD);
        hr = RegSetValueEx( hKey, L"MaxPostSize", NULL, REG_DWORD, (LPBYTE)&dwVal, dwLen);
    }

    dwLen = sizeof(DWORD);
    if (RegQueryValueEx(hKey, L"NoNagling", NULL, NULL, (LPBYTE) &dwVal, &dwLen) != ERROR_SUCCESS)
    {
        dwVal = 0;
        dwLen = sizeof(DWORD);
        RegSetValueEx(hKey, L"NoNagling", NULL, REG_DWORD, (LPBYTE) &dwVal, dwLen);
    }

    RegCloseKey(hKey);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
//  function: RemoveRegInfo()
//
//  parameters:
//
//  description:
//          Removes the registry Software\\Microsoft\\MSSOAP\\SOAPISAP

⌨️ 快捷键说明

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