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

📄 httpmain.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: HTTPMAIN.CPP
Abstract: HTTP server initialization & listener thread 
--*/


#include "httpd.h"

//
//-------------------- Global data --------------
//

CGlobalVariables *g_pVars;            // Global data.  This is the "default" website.
CGlobalVariables *g_pWebsites;        // Multiple websites.
DWORD             g_cWebsites;        // Number of websites (does not count the default)
HINSTANCE g_hInst;                    // handle to DLL
LONG  g_fState;                       // Current Service State (running, stopped, starting, shutting down, unloading)
CRITICAL_SECTION g_CritSect;          // Global lock

CWebDavFileLockManager *g_pFileLockManager;  // Implements LOCK and UNLOCK support for WebDav.
SVSThreadPool *g_pTimer;                     // ISAPI extension unload and WebDAV file unlock timer thread (wakes up once a minute).

// We keep track of whether we've spun a thread in this function to deal with
// stopping+restarting, in the event that when we're unloa
HANDLE g_hAdminThread;

CHttpRequest *g_pRequestList;       // List of active http connections.

BOOL g_fUTF8;

//------------- Const data -----------------------
//

const char cszTextHtml[] = "text/html";
const char cszOctetStream[] = "application/octet-stream";
const char cszEmpty[] = "";
const char cszMaxConnectionHeader[] =  "HTTP/1.0 503 Service Unavailable\r\n\r\n";

// 
//------------- Debug data -----------------------
//
#if defined(UNDER_CE) && defined (DEBUG)
  DBGPARAM dpCurSettings = {
    TEXT("HTTPD"), {
    TEXT("Error"),TEXT("Init"),TEXT("Listen"),TEXT("Socket"),
    TEXT("Request"),TEXT("Response"),TEXT("ISAPI"),TEXT("VROOTS"),
    TEXT("ASP"),TEXT("Device"),TEXT("SSL"),TEXT("Verbose"),
    TEXT("Authentication"),TEXT("WebDAV"),TEXT("Parser"),TEXT("Tokens") },
    0x0003
  }; 
#endif


// 
//------------- Prototypes -----------------------
//
PWSTR MassageMultiString(PCWSTR wszIn, PCWSTR wszDefault=NULL);
// 
//------------- Startup functions -----------------------
//

extern "C" BOOL WINAPI DllEntry( HANDLE hInstDll, DWORD fdwReason, LPVOID lpvReserved)
{
	switch (fdwReason) {
		case DLL_PROCESS_ATTACH:
			DEBUGMSG(ZONE_INIT,(TEXT("HTTPD: DllMain attached\r\n")));
			g_hAdminThread = 0;
			g_hInst = (HINSTANCE)hInstDll;	
			svsutil_Initialize();
            DEBUGREGISTER((HINSTANCE)hInstDll);

			InitializeCriticalSection(&g_CritSect);
			DisableThreadLibraryCalls((HMODULE)hInstDll);

            g_fState = SERVICE_STATE_UNINITIALIZED;
			break;

		case DLL_PROCESS_DETACH:
			DEBUGMSG(ZONE_INIT, (TEXT("HTTPD: DllMain detach\r\n")));
			DeleteCriticalSection(&g_CritSect);
            svsutil_DeInitialize();
			DEBUGCHK(g_fState == SERVICE_STATE_UNLOADING && !g_pVars && !g_pWebsites && (g_cWebsites==0) && !g_pTimer);
			break;
	}
	return TRUE;
}

extern "C" int HttpInitialize(TCHAR *szRegPath) {
    // This was to support httpd being started in CE 3.0 - in the device.exe days
    // Leave the function intact because it's in httpd.def, but no longer
    // do anything here.  Apps need to do the right thing here and use
    // standard services.exe API's to start + stop HTTPD.
	DEBUGMSG(ZONE_ERROR,(L"HTTPD:HttpInitialize is no longer supported - use standard services.exe functions to use this\r\n"));
    DEBUGCHK(0);
	SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
	return 0;
}


// Routines that are called once after HTTPD.dll has been started, but are not safe to be called from DLLMain().
BOOL HttpInitializeOnce(void) {
	g_pTimer = new SVSThreadPool(1);
	if (!g_pTimer)
		return FALSE;

	svsutil_InitializeInterfaceMapperOnce();
	svsutil_ResetInterfaceMapper();
	DoesSystemSupportUTF8();

	g_pTimer->ScheduleEvent(PeriodicWakeupThread,0,PERIODIC_TIMER_SLEEP_TIMEOUT);
	return TRUE;
}

extern "C" int HttpInitializeFromExe()  {
    // No longer supported - HttpInitialize sets proper error code for this call
	return HttpInitialize(NULL);
}

const WCHAR wszDefaultLogDirectory[] = L"\\windows\\www";

BOOL IsHttpdEnabled(void) {
	CReg reg(HKEY_LOCAL_MACHINE, RK_HTTPD);
	if (reg.ValueDW(RV_ISENABLED,1))
		return TRUE;

	SetLastError(ERROR_SERVICE_DISABLED);

	DEBUGMSG(ZONE_INIT,(L"HTTPD: IsEnabled=0, will not start web server\r\n"));
	DWORD dwMaxLogSize;
	WCHAR wszLogDir[MAX_PATH + 1];

	if (0 == (dwMaxLogSize = reg.ValueDW(RV_MAXLOGSIZE)))
		return FALSE;

	if ( ! reg.ValueSZ(RV_LOGDIR,wszLogDir,MAX_PATH+1))
		wcscpy(wszLogDir,wszDefaultLogDirectory);

	CLog cLog(dwMaxLogSize,wszLogDir);
	cLog.WriteEvent(IDS_HTTPD_DISABLED);

	return FALSE;
}

void CGlobalVariables::InitGlobals(CReg *pWebsite)  {
	DWORD dwMaxLogSize;
	WCHAR wszLogDir[MAX_PATH + 1];

	ZEROMEM(this);

	CReg reg;
	m_fRootSite = !pWebsite;

	// if pWebsite==NULL, then this is initialization of default website.
	if (m_fRootSite) {
		DEBUGCHK(g_pVars == NULL);

		// certain functions, including listen thread management and ISAPI Filters
		// are managed globally by the main site.

		reg.Open(HKEY_LOCAL_MACHINE, RK_HTTPD);
		if (!reg.IsOK())   {
			CLog cLog(DEFAULTLOGSIZE,L"\\windows\\www");
			cLog.WriteEvent(IDS_HTTPD_NO_REGKEY);
			DEBUGMSG(ZONE_ERROR,(L"HTTPD:  No registry key setup, will not handle requests\r\n"));
			return;
		}
		pWebsite = ®

		if (! IsHttpdEnabled())
			return;

		// thread pool is global
		m_nMaxConnections = pWebsite->ValueDW(RV_MAXCONNECTIONS,10);
		m_pThreadPool = new SVSThreadPool(m_nMaxConnections + 1);  // +1 for ISAPI Cache removal thread
		if (!m_pThreadPool)
			return;

		// initial string setup only needs to be done once.
		if (NULL == (m_pszStatusBodyBuf = MyRgAllocNZ(CHAR,BODYSTRINGSIZE)))
			return;

		InitializeResponseCodes(m_pszStatusBodyBuf);

		strcpy(m_szMaxConnectionMsg,cszMaxConnectionHeader);
		WCHAR wszMaxConnectionMsg[256];

		LoadString(g_hInst,IDS_SERVER_BUSY,wszMaxConnectionMsg,ARRAYSIZEOF(wszMaxConnectionMsg));
		MyW2A(wszMaxConnectionMsg,m_szMaxConnectionMsg + sizeof(cszMaxConnectionHeader) - 1,
				  sizeof(m_szMaxConnectionMsg) - sizeof(cszMaxConnectionHeader));

		m_fUseDefaultSite = pWebsite->ValueDW(RV_ALLOW_DEFAULTSITE,TRUE);

		// setup logging
		dwMaxLogSize = pWebsite->ValueDW(RV_MAXLOGSIZE);
		if ( ! pWebsite->ValueSZ(RV_LOGDIR,wszLogDir,MAX_PATH+1)) {
			wcscpy(wszLogDir,wszDefaultLogDirectory);
		}

		WCHAR *wszBasicRealm;
		if (NULL != (wszBasicRealm = (WCHAR*)pWebsite->ValueSZ(RV_BASIC_REALM))) {
			if (NULL == (m_szBasicRealm = MySzDupWtoA(wszBasicRealm)))
				return;
		}
		else {
			static const CHAR cszBasicRealmDefault[] = "Microsoft-WinCE";
			if (NULL == (m_szBasicRealm = MySzDupA(cszBasicRealmDefault)))
				return;
		}

		m_pLog = new CLog(dwMaxLogSize,wszLogDir);
		if (!m_pLog)
			return;

		// max POST/Header sizes, 
		m_dwPostReadSize       = pWebsite->ValueDW(RV_POSTREADSIZE,  48*1024); // 48 K default
		if (m_dwPostReadSize < MIN_POST_READ_SIZE) {
			DEBUGMSG(ZONE_ERROR,(L"HTTPD: PostReadSize set in registry = %d, however minimum must be %d.  Resetting value to minimum acceptable\r\n",m_dwPostReadSize,MIN_POST_READ_SIZE));
			m_dwPostReadSize = MIN_POST_READ_SIZE;
		}
		
		m_dwMaxHeaderReadSize  = pWebsite->ValueDW(RV_MAXHEADERSIZE, 48*1024); // 48 K default
		m_dwSystemChangeNumber = pWebsite->ValueDW(RV_CHANGENUMBER,  1);
		m_dwConnectionTimeout  = pWebsite->ValueDW(RV_CONN_TIMEOUT,30*1000); // 30 second default

		m_fExtensions = InitExtensions(pWebsite);
	}
#if defined (DEBUG) || defined (_DEBUG)
	else	
		DEBUGCHK(g_pVars);
#endif

	m_dwListenPort = pWebsite->ValueDW(RV_PORT, IPPORT_HTTP);
	DEBUGCHK(m_dwListenPort);

	m_fASP            = InitASP(pWebsite);
	m_fWebDav         = InitWebDav(pWebsite);
	m_fDirBrowse      = pWebsite->ValueDW(RV_DIRBROWSE, HTTPD_ALLOW_DIR_BROWSE);
	
	m_wszDefaultPages = MassageMultiString(pWebsite->ValueSZ(RV_DEFAULTPAGE),HTTPD_DEFAULT_PAGES);

	const WCHAR *sz = pWebsite->ValueSZ(RV_ADMINUSERS);
	if (sz)
		m_wszAdminUsers =  svsutil_wcsdup((WCHAR*)sz);
	else
		m_wszAdminUsers = NULL;

	InitAuthentication(pWebsite);
	if (m_fRootSite)
		InitSSL(pWebsite);

	WCHAR *wszServerID;
	if (NULL != (wszServerID = (WCHAR*)pWebsite->ValueSZ(RV_SERVER_ID))) {
		// User specified an over-ride server ID, convert to ANSI and use it.
		if (NULL == (m_szServerID = MySzDupWtoA(wszServerID)))
			return;
	}
	else {
		// Use default server ID if not overridden
		static const char szDefaultServerIdFmt[]    = "Microsoft-WinCE/%d.%02d";

		if (NULL == (m_szServerID =  MyRgAllocNZ(CHAR,CCHSIZEOF(szDefaultServerIdFmt)+20)))
			return;

		sprintf(m_szServerID,szDefaultServerIdFmt,CE_MAJOR_VER,CE_MINOR_VER);
	}

	InitMapping(*pWebsite,RV_HOSTEDSITES); // SVSInterfaceMapper does hard work here.

	m_pVroots = new CVRoots(pWebsite,m_fDirBrowse,m_fBasicAuth, m_fNTLMAuth, m_fNegotiateAuth);
	if (!m_pVroots)
		return;

	// vroot table must be initialized or web server can't return files.  Warn
	// user if this is not the case
	if ((m_pVroots->Count() == 0) && m_fRootSite) 
		m_pLog->WriteEvent(IDS_HTTPD_NO_VROOTS);

	m_fAcceptConnections = TRUE;
}


void CGlobalVariables::DeInitGlobals(void)  {
	// note that certain variables (like ISAPIs and logging) are only
	// initialized on the default web site.
	DEBUGCHK(g_pVars->m_nConnections == 0);
	DEBUGCHK(g_fState != SERVICE_STATE_ON);

	MyFree(m_wszDefaultPages);
	MyFree(m_wszAdminUsers);
	MyFree(m_pszStatusBodyBuf);
	MyFree(m_pszSSLIssuer);
	MyFree(m_pszSSLSubject);
	MyFree(m_szServerID);
	MyFree(m_szBasicRealm);

	if (m_pVroots)
		delete m_pVroots;

	if (m_fRootSite) {
		DEBUGCHK(this == g_pVars);

		if (m_fWebDav && (g_fState == SERVICE_STATE_UNLOADING))
			DeInitWebDav(); // only on unload because lock manager persists across refreshes
	
		if (m_fFilters)
			CleanupFilters();

		if (m_fExtensions)
			DeInitExtensions();

		if (m_pISAPICache) {
			// Flush all ISAPIs.  This will block until everyone's unloaded.
			m_pISAPICache->RemoveUnusedISAPIs(TRUE);
			delete m_pISAPICache;
		}

		if (m_pThreadPool)
			delete m_pThreadPool;

		if (m_fSSL)
			FreeSSLResources();

		MyFreeLib(m_hSecurityLib);

		// Log must be the last thing we destroy, because theoretically
		// a cleanup function could make a call into it to report an error condition.
		if (m_pLog)
			delete m_pLog;

		m_dwSystemChangeNumber++;
		CReg reg(HKEY_LOCAL_MACHINE,RK_HTTPD);
		reg.SetDW(RV_CHANGENUMBER,m_dwSystemChangeNumber);
	}
#if defined (DEBUG)
	else {
		// non-root website should never have got any of this set, always use default for these settings.
		DEBUGCHK(m_pISAPICache == NULL);
		DEBUGCHK(m_pLog == NULL);
		DEBUGCHK(m_pThreadPool == NULL);
		DEBUGCHK(m_hSSLCertStore == 0);
		DEBUGCHK(m_fHasSSLCreds == FALSE);
		DEBUGCHK(m_hSecurityLib == NULL);
	}
#endif

	DeInitMapping(); // SVSInterfaceMapper call
}


⌨️ 快捷键说明

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