📄 pgpnetkernelworker.cpp
字号:
/*____________________________________________________________________________
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 + -