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

📄 pgpnetkernelworker.cpp

📁 vc环境下的pgp源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/*____________________________________________________________________________
	Copyright (c) 1998 Network Associates, Inc. and its Affiliated Companies
	All rights reserved.

	$Id: pgpNetKernelWorker.cpp,v 1.61.4.1 1999/06/14 03:22:38 elowe Exp $
____________________________________________________________________________*/

#include <windows.h>
#include <assert.h>
#include <winioctl.h>
#include <ntddndis.h>
#include <queue>

// PGP includes
#include "pgpRMWOLock.h"
#include "pgpErrors.h"
#include "pgpMem.h"

// PGPnet includes
#include "pgpNetAppLog.h"
#include "pgpNetDebugLog.h"
#include "pgpIKE.h"
#include "pgpRWLockSignal.h"
#include "pgpNetCConfig.h"
#include "pgpEndianConversion.h"
#include "pgpNetQueueElement.h"
#include "pgpNetDSAarray.h"
#include "pgpNetIPC.h"
#include "pgpNetKernelXChng.h"

#include "pgpNetKernelWorker.h"

#define DBGOUT(s) CPGPnetDebugLog::DbgOutFL(__FILE__, __LINE__); \
			CPGPnetDebugLog::DbgOut((s));

// external globals
extern PGPCond_t							g_ShutdownRequest;
extern PGPCond_t							g_localIPEvent;
extern PGPCond_t							g_SuspendEvent;
extern PGPUInt32							g_localIP;
extern PGPContextRef						g_Context;
extern CPGPrwLockSignal< CPGPnetCConfig > *	g_pConfig;
extern DWORD								g_platformID;
extern PGPBoolean							g_isWAN;

extern CPGPrwLockSignal< std::queue<CPGPnetQueueElement> >	g_IKEQueue;
extern CPGPrwLockSignal< std::queue<CPGPnetQueueElement> >	g_GUIQueue;
extern CPGPrwLockSignal< std::queue<CPGPnetQueueElement> >	g_KernelQueue;
extern CPGPrwLockSignal<CPGPnetDSAarray>					g_SAarray;


CPGPnetKernelWorker::CPGPnetKernelWorker()
: m_hMac(INVALID_HANDLE_VALUE), m_MacName("")
{
}

void CPGPnetKernelWorker::debugMsg(int lineno, const char *fmt, ...)
{
	if (CPGPnetDebugLog::isDebug()) {
		char temp[256];
		sprintf(temp, "KernelWorker(%d)\t:\t", lineno);
		va_list args;
		va_start(args, fmt);
		CPGPnetDebugLog::instance()->vdbgOut(fmt, args, temp);
		va_end(args);
	}
}

unsigned int
CPGPnetKernelWorker::Run()
{
	PGPUInt32		ret = 0;
	const PGPInt16	numHandles = 4;
	HANDLE			lpHandles[numHandles];
	std::string		szMacNTName = "\\\\.\\";
	PGPBoolean		running = TRUE;
	PGPEVENT_CONTEXT pgpEvent;

	lpHandles[0] = g_ShutdownRequest;
	lpHandles[1] = g_KernelQueue.event();
	lpHandles[3] = g_SuspendEvent;

	debugMsg(__LINE__, ">> Run");
	// look for name of driver in registry
	ret = getMacName();
	szMacNTName += m_MacName;

	debugMsg(__LINE__, "MacName: %s", szMacNTName.c_str());

	m_hMac = CreateFile(szMacNTName.c_str(),
                  GENERIC_READ,
                  0, // FILE_SHARE_READ | FILE_SHARE_WRITE,
                  NULL,
                  OPEN_EXISTING,
                  FILE_ATTRIBUTE_NORMAL,
                  NULL
                  );

    if (m_hMac == INVALID_HANDLE_VALUE) {
		debugMsg(__LINE__, "Damn, unable to open driver");

		CPGPnetAppLog::instance()->logSysEvent(GetLastError(), 
			0,
			__FILE__, 
			__LINE__);
		CPGPnetAppLog::instance()->logServiceEvent(kPGPnetSrvcError_NoDriver,
			0,
			0,
			__FILE__,
			__LINE__);
		g_pConfig->startWriting();
		g_pConfig->data().isDriverUp(FALSE);
		g_pConfig->stopWriting();
		goto end;
    }

	if (!createSharedMemory()) {
		debugMsg(__LINE__, "Unable to create shared mem");
		CPGPnetAppLog::instance()->logServiceEvent(kPGPnetSrvcError_DrvSharedMemory,
			0,
			0,
			__FILE__,
			__LINE__);
		g_pConfig->startWriting();
		g_pConfig->data().isDriverUp(FALSE);
		g_pConfig->stopWriting();
		goto end;
	}

	// create SA event thingy
	if (!createKernelEvent(&pgpEvent)) {
		debugMsg(__LINE__, "Unable to create kernel event");
		CPGPnetAppLog::instance()->logServiceEvent(kPGPnetSrvcError_DrvEvent,
			0,
			0,
			__FILE__,
			__LINE__);
		g_pConfig->startWriting();
		g_pConfig->data().isDriverUp(FALSE);
		g_pConfig->stopWriting();
		goto end;
	} else {
		lpHandles[2] = pgpEvent.Win32EventHandle;
	}

	if (!createMsgQueue()) {
		debugMsg(__LINE__, "Unable to create message queue");
		CPGPnetAppLog::instance()->logServiceEvent(kPGPnetSrvcError_DrvSharedMemory,
			0,
			0,
			__FILE__,
			__LINE__);
		g_pConfig->startWriting();
		g_pConfig->data().isDriverUp(FALSE);
		g_pConfig->stopWriting();
		goto end;
	}
	
	debugMsg(__LINE__, "Driver looks good");
	g_pConfig->startWriting();
	g_pConfig->data().isDriverUp(TRUE);
	g_pConfig->stopWriting();

	debugMsg(__LINE__, "Starting wait loop");
	while (running) {
		ret = WaitForMultipleObjects(numHandles,
									 lpHandles, 
									 FALSE, 
									 5000);
		if (ret == WAIT_TIMEOUT) {
			// XXX collect some statistics and send to app
			// if app is around
			// also send to tray app if present
		} else if (ret >= WAIT_ABANDONED_0) {
			debugMsg(__LINE__, "something abandoned");
			running = FALSE;
			goto end;
		} else if (ret >= WAIT_OBJECT_0) {
			switch (ret - WAIT_OBJECT_0) {
			case 0:
				debugMsg(__LINE__, "ShutdownRequest signaled");
				running = FALSE;
				goto end;
				break;
			case 1:
				debugMsg(__LINE__, "Queue signaled");
				processQueue();
				break;
			case 2:
				debugMsg(__LINE__, "Event from kernel");
				processKernelEvent();
				break;
			case 3:
			{
				debugMsg(__LINE__, "Got Suspend Event");

				if (g_SAarray.data().numSAs() > 0)
					break;

				if (m_hMac != INVALID_HANDLE_VALUE) {
					if (m_pSharedMem) {
						deleteMsgQueue();
						deleteSharedMemory();
						deleteKernelEvent(&pgpEvent);
					}
					CloseHandle(m_hMac);
				}

				return kPGPError_NoErr;
			}
			break;
			default:
				debugMsg(__LINE__, "Something signaled");
				break;
			}
		}
	}

end:
	debugMsg(__LINE__, "Shutting down");
	if (m_hMac != INVALID_HANDLE_VALUE) {
		if (m_pSharedMem) {
			DWORD dwRet;
			(void) sendKernelRequest(OID_PGP_SHUTDOWN, 0, 0, &dwRet);
			deleteMsgQueue();
			deleteSharedMemory();
			deleteKernelEvent(&pgpEvent);
		}
		CloseHandle(m_hMac);
	}

	debugMsg(__LINE__, "<< Run");
	return kPGPError_NoErr;
}

PGPBoolean 
CPGPnetKernelWorker::sendKernelRequest(PGPUInt32 blockID, 
									   void *pBuffer, 
									   PGPUInt32 BufferSize, 
									   ULONG *pReturnedCount)
{
	ULONG		dwReturnedCount;
	PGPUInt32	dwBuffer;
	ULONG *		pMyReturnedCount;
	void *		pMyBuffer;
	PGPBoolean	result = FALSE;

	debugMsg(__LINE__, ">> sendKernelRequest(%x)", blockID);
	if (pReturnedCount) {
		pMyReturnedCount = pReturnedCount;
	} else {
		pMyReturnedCount = &dwReturnedCount;
	}

	*pMyReturnedCount = 0;
    
	if (pBuffer && BufferSize) {
		pMyBuffer = pBuffer;
	} else {
		pMyBuffer = &dwBuffer;
		BufferSize = sizeof(dwBuffer);
	}
    
	debugMsg(__LINE__, "Buffer size: %d", BufferSize);

	if (m_hMac != INVALID_HANDLE_VALUE) {

		debugMsg(__LINE__, "Sending DeviceIoControl()");

		result = DeviceIoControl(m_hMac,
			IOCTL_NDIS_QUERY_GLOBAL_STATS,
			&blockID,
			sizeof(blockID),
			pMyBuffer,
			BufferSize,
			pMyReturnedCount,
			NULL);
	
		debugMsg(__LINE__, "DeviceIoControl returned, result: %d, ReturnedCount: %d",
			result,
			*pMyReturnedCount);

		if (result) {
			if (pReturnedCount == NULL && dwReturnedCount > 0) {
				CPGPnetAppLog::instance()->logServiceEvent(
					kPGPnetSrvcError_DrvCommunication,
					0,
					0,
					__FILE__,
					__LINE__);
				debugMsg(__LINE__, "Unexpected data size=%d != 0\n",
					dwReturnedCount);
				result = FALSE;
			}
		} else {
			debugMsg(__LINE__, "Something wrong\n");
			CPGPnetAppLog::instance()->logSysEvent(GetLastError(),
				0,
				__FILE__,
				__LINE__);
			CPGPnetAppLog::instance()->logServiceEvent(
				kPGPnetSrvcError_DrvCommunication,
				0,
				0,
				__FILE__,
				__LINE__);
		}
	}
	debugMsg(__LINE__, "<< sendKernelRequest(%d)", result);
	return (result);
}

void
CPGPnetKernelWorker::processQueue()
{
	debugMsg(__LINE__, ">> processQueue");

	while (!g_KernelQueue.data().empty()) {
		g_KernelQueue.startReading();
		// pull one thing off;
		CPGPnetQueueElement queueElem = g_KernelQueue.data().front();
		g_KernelQueue.stopReading();

		g_KernelQueue.startWriting();
		g_KernelQueue.data().pop();
		g_KernelQueue.stopWriting();

		ULONG dwRet;
		switch (queueElem.type()) {
		case OID_PGP_NEWSA:
		{
			debugMsg(__LINE__, "Got OID_PGP_NEWSA");

			PGPikeSA *pSA = 0;
			pgpCopyMemory(queueElem.data(), &pSA, sizeof(PGPikeSA*));

			(void) sendKernelRequest(OID_PGP_NEWSA, 
				const_cast<void*>(pSA),
				sizeof(PGPikeSA),
				&dwRet);
			break;
		}
		case OID_PGP_SADIED:
			debugMsg(__LINE__, "Got OID_PGP_SADIED");

			if (queueElem.size() != sizeof(PGPipsecSPI)) {
				debugMsg(__LINE__, "SADIED wrong size data");
				pgpAssert(FALSE);
				return;
			}
			(void) sendKernelRequest(queueElem.type(), 
				const_cast<void*>(queueElem.data()),
				queueElem.size(),
				&dwRet);
			break;
		case OID_PGP_SAFAILED:
			debugMsg(__LINE__, "Got OID_PGP_SAFAILED");

			if (queueElem.size() != sizeof(PGPikeMTSAFailed)) {
				debugMsg(__LINE__, "SAFAILED wrong size data");
				pgpAssert(FALSE);
				return;
			}

			(void) sendKernelRequest(queueElem.type(), 
				const_cast<void*>(queueElem.data()),
				queueElem.size(),
				&dwRet);
			break;
		case OID_PGP_SAUPDATE:
			debugMsg(__LINE__, "Got OID_PGP_SAUPDATE");

			if (queueElem.size() != sizeof(PGPipsecSPI)) {
				debugMsg(__LINE__, "SAUPDATE wrong size data");
				pgpAssert(FALSE);
				return;
			}
			// fall-through
		case OID_PGP_ALLHOSTS:
		case OID_PGP_NEWHOST:
		case OID_PGP_NEWCONFIG:
			debugMsg(__LINE__, "Got One of OID_PGP_ALLHOSTS, OID_PGP_NEWHOST, OID_PGP_NEWCONFIG");

			(void) sendKernelRequest(queueElem.type(), 
				const_cast<void*>(queueElem.data()),
				queueElem.size(),
				&dwRet);
			break;
		case OID_PGP_LOCALIP:
			debugMsg(__LINE__, "Got OID_PGP_LOCALIP");

			(void) getLocalIP();
			PGPCondSignal(&g_localIPEvent);
			break;
		case PGPNET_ATTEMPTIKE:
		{
			debugMsg(__LINE__, "Got PGPNET_ATTEMPTIKE");

			// queueElem.ipAddress isn't the ipAddress of the host
			// but rather the index of the host in the host list
			// The ipAddress field was just a convienant place to put

⌨️ 快捷键说明

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