Full Code of basketwill/Sysmon_reverse for AI

master 94fee5819853 cached
99 files
365.0 KB
113.3k tokens
273 symbols
1 requests
Download .txt
Showing preview only (391K chars total). Download the full file or copy to clipboard to get everything.
Repository: basketwill/Sysmon_reverse
Branch: master
Commit: 94fee5819853
Files: 99
Total size: 365.0 KB

Directory structure:
gitextract_0g68xkff/

├── README.md
├── Sysmon/
│   ├── CDName.cpp
│   ├── CDName.h
│   ├── CDigitalSign.cpp
│   ├── CDigitalSign.h
│   ├── CEventLogger.cpp
│   ├── CEventLogger.h
│   ├── CMofDataParser.cpp
│   ├── CMofDataParser.h
│   ├── CSsymonEtw.cpp
│   ├── CSsymonEtw.h
│   ├── CSysmonDriverOpt.cpp
│   ├── CSysmonDriverOpt.h
│   ├── CSysmonMofData.cpp
│   ├── CSysmonMofData.h
│   ├── CSysmonUtil.cpp
│   ├── CSysmonUtil.h
│   ├── ReadMe.txt
│   ├── Resource.h
│   ├── Sysmon.cpp
│   ├── Sysmon.h
│   ├── Sysmon.rc
│   ├── Sysmon.vcxproj
│   ├── Sysmon.vcxproj.filters
│   ├── Sysmon.vcxproj.user
│   ├── stdafx.cpp
│   ├── stdafx.h
│   ├── targetver.h
│   ├── undname.cpp
│   ├── undname.h
│   └── undname.idl
├── Sysmon.sln
├── Sysmon.suo
└── Sysmon.sys/
    ├── CDeviceExtension.cpp
    ├── CDeviceExtension.h
    ├── CDriverEntry.cpp
    ├── CDriverEntry.h
    ├── CReportRecord.cpp
    ├── CReportRecord.h
    ├── CSysmonControl.cpp
    ├── CSysmonControl.h
    ├── CSysmonDispatchEngine.cpp
    ├── CSysmonDispatchEngine.h
    ├── CSysmonIoControl.h
    ├── CSysmonMiniFltFilter.cpp
    ├── CSysmonMiniFltFilter.h
    ├── ReadMe.txt
    ├── Sysmon.sys.cpp
    ├── Sysmon.sys.vcxproj
    ├── Sysmon.sys.vcxproj.filters
    ├── Sysmon.sys.vcxproj.user
    ├── cpplib/
    │   ├── CAssert.h
    │   ├── CAttachDevice.cpp
    │   ├── CAttachDevice.h
    │   ├── CDebug.cpp
    │   ├── CDebug.h
    │   ├── CDeviceObject.cpp
    │   ├── CDeviceObject.h
    │   ├── CDispatchEngine.cpp
    │   ├── CDispatchEngine.h
    │   ├── CDriverDispatch.cpp
    │   ├── CDriverDispatch.h
    │   ├── CDriverObject.cpp
    │   ├── CDriverObject.h
    │   ├── CEResource.cpp
    │   ├── CEResource.h
    │   ├── CErrorStatus.cpp
    │   ├── CErrorStatus.h
    │   ├── CFileObject.cpp
    │   ├── CFileObject.h
    │   ├── CFilterDevice.cpp
    │   ├── CFilterDevice.h
    │   ├── CIntNumber.cpp
    │   ├── CIntNumber.h
    │   ├── CIoStackLocation.cpp
    │   ├── CIoStackLocation.h
    │   ├── CIrp.cpp
    │   ├── CIrp.h
    │   ├── CListEntry.cpp
    │   ├── CListEntry.h
    │   ├── CMiniFltFilter.cpp
    │   ├── CMiniFltFilter.h
    │   ├── CNPagedLookaside.cpp
    │   ├── CNPagedLookaside.h
    │   ├── CPool.cpp
    │   ├── CPool.h
    │   ├── CString.cpp
    │   ├── CString.h
    │   ├── CSysmonBase.cpp
    │   ├── CSysmonBase.h
    │   ├── CUnicodeString.cpp
    │   ├── CUnicodeString.h
    │   ├── CVersion.cpp
    │   ├── CVersion.h
    │   ├── CppLib.cpp
    │   └── CppLib.h
    ├── stdafx.cpp
    ├── stdafx.h
    └── targetver.h

================================================
FILE CONTENTS
================================================

================================================
FILE: README.md
================================================
# Sysmon_reverse逆向微软sysmon的源代码,逆向的版本是v8
原始产品
https://docs.microsoft.com/zh-cn/sysinternals/downloads/sysmon


================================================
FILE: Sysmon/CDName.cpp
================================================
#include "StdAfx.h"
#include "CDName.h"


CDName::CDName(void)
{
}


CDName::~CDName(void)
{
}


char* CDName::_unDName()
{
	return NULL;
}

================================================
FILE: Sysmon/CDName.h
================================================
#ifndef _CDName_H
#define _CDName_H

class CDName
{
public:
	CDName(void);
	virtual ~CDName(void);

	static char* _unDName();
};

#endif



================================================
FILE: Sysmon/CDigitalSign.cpp
================================================
#include "StdAfx.h"
#include "CDigitalSign.h"


CDigitalSign::CDigitalSign(void)
	:m_bInit(false)
	,m_WinVerifyTrust(NULL)
	,m_pWTHelperGetProvSignerFromChain(NULL)
	,m_pWTHelperProvDataFromStateData(NULL)
	,m_pCryptCATAdminReleaseContext(NULL)
	,m_pCryptCATAdminReleaseCatalogContext(NULL)
	,m_pCryptCATCatalogInfoFromContext(NULL)
	,m_pCryptCATAdminEnumCatalogFromHash(NULL)
	,m_pCryptCATAdminCalcHashFromFileHandle(NULL)
	,m_pCryptCATAdminAcquireContext(NULL)
	,m_pCryptCATAdminAddCatalog(NULL)
	,m_pCryptCATAdminRemoveCatalog(NULL)
	,m_pIsCatalogFile(NULL)
	,m_pCertNameToStrW(NULL)
{
}


CDigitalSign::~CDigitalSign(void)
{
}


bool CDigitalSign::Init()
{
	if (!m_bInit)
	{
		m_bInit = true;

		HMODULE hWinTrust = LoadLibraryW(L"Wintrust.dll");

		if ( !hWinTrust )
			return false;
		
		m_WinVerifyTrust = (pWinVerifyTrust)GetProcAddress(hWinTrust, "WinVerifyTrust");
		m_pWTHelperGetProvSignerFromChain = (pWTHelperGetProvSignerFromChain)
							GetProcAddress(hWinTrust, "WTHelperGetProvSignerFromChain");

		m_pWTHelperProvDataFromStateData = (pWTHelperProvDataFromStateData)
							GetProcAddress(hWinTrust, "WTHelperProvDataFromStateData");
		
		m_pCryptCATAdminReleaseContext = (pCryptCATAdminReleaseContext)
							GetProcAddress(hWinTrust, "CryptCATAdminReleaseContext");

		m_pCryptCATAdminReleaseCatalogContext = (pCryptCATAdminReleaseCatalogContext)
							GetProcAddress(hWinTrust, "CryptCATAdminReleaseCatalogContext");

		m_pCryptCATCatalogInfoFromContext = (pCryptCATCatalogInfoFromContext)
							GetProcAddress(hWinTrust, "CryptCATCatalogInfoFromContext");

		m_pCryptCATAdminEnumCatalogFromHash = (pCryptCATAdminEnumCatalogFromHash)
							GetProcAddress(hWinTrust, "CryptCATAdminEnumCatalogFromHash");

		m_pCryptCATAdminCalcHashFromFileHandle = (pCryptCATAdminCalcHashFromFileHandle)
							GetProcAddress(hWinTrust,"CryptCATAdminCalcHashFromFileHandle");

		m_pCryptCATAdminAcquireContext = (pCryptCATAdminAcquireContext)
							GetProcAddress(hWinTrust,"CryptCATAdminAcquireContext");

		m_pCryptCATAdminAddCatalog = (pCryptCATAdminAddCatalog)
							GetProcAddress(hWinTrust, "CryptCATAdminAddCatalog");

		m_pCryptCATAdminRemoveCatalog = (pCryptCATAdminRemoveCatalog)
							GetProcAddress(hWinTrust, "CryptCATAdminRemoveCatalog");

		m_pIsCatalogFile = (pIsCatalogFile)GetProcAddress(hWinTrust, "IsCatalogFile");

		hWinTrust = LoadLibraryW(L"crypt32.dll");
		m_pCertNameToStrW = (pCertNameToStrW)GetProcAddress(hWinTrust, "CertNameToStrW");
	}
	
	return m_pCryptCATAdminAcquireContext != 0;
}

================================================
FILE: Sysmon/CDigitalSign.h
================================================
#ifndef _CDigitalSign_h
#define _CDigitalSign_h
#include <WinTrust.h>

typedef void* HCATINFO;
typedef void* HCATADMIN;

typedef struct CATALOG_INFO_ {
	DWORD cbStruct;
	WCHAR wszCatalogFile[MAX_PATH];
} CATALOG_INFO;

extern "C"
{
	typedef
	LONG
	( WINAPI *pWinVerifyTrust)(
							HWND hwnd,
							GUID *pgActionID,
							LPVOID pWVTData);

	typedef 
	CRYPT_PROVIDER_SGNR* 
	(WINAPI *pWTHelperGetProvSignerFromChain)(
							CRYPT_PROVIDER_DATA *pProvData,
							DWORD idxSigner,
							BOOL fCounterSigner,
							DWORD idxCounterSigner);

	typedef
	CRYPT_PROVIDER_DATA * (WINAPI *pWTHelperProvDataFromStateData)(
							HANDLE hStateData);

	typedef
	BOOL 
	(WINAPI *pCryptCATAdminReleaseContext)(
		IN VOID* hCatAdmin,
		IN DWORD     dwFlags
		);

	typedef
	BOOL 
	(WINAPI *pCryptCATAdminReleaseCatalogContext)(
		IN VOID* hCatAdmin,
		IN VOID*  hCatInfo,
		IN DWORD     dwFlags
		);

	typedef
	BOOL
	(WINAPI *pCryptCATCatalogInfoFromContext)(
		_In_    VOID*     hCatInfo,
		_Inout_ CATALOG_INFO *psCatInfo,
		_In_    DWORD        dwFlags
		);

	typedef
	HCATINFO 
	(WINAPI *pCryptCATAdminEnumCatalogFromHash)(
		HCATADMIN hCatAdmin,
		BYTE      *pbHash,
		DWORD     cbHash,
		DWORD     dwFlags,
		HCATINFO  *phPrevCatInfo
		);

	typedef
	BOOL
	(WINAPI *pCryptCATAdminCalcHashFromFileHandle)(
		HANDLE hFile,
		DWORD  *pcbHash,
		BYTE   *pbHash,
		DWORD  dwFlags
		);

	typedef
	BOOL
	(WINAPI *pCryptCATAdminAcquireContext)(
		HCATADMIN  *phCatAdmin,
		const GUID *pgSubsystem,
		DWORD      dwFlags
		);

	typedef
	HCATINFO
	(WINAPI *pCryptCATAdminAddCatalog)(
		HCATADMIN hCatAdmin,
		PWSTR     pwszCatalogFile,
		PWSTR     pwszSelectBaseName,
		DWORD     dwFlags
		);

	typedef
	BOOL
	(WINAPI *pCryptCATAdminRemoveCatalog)(
		IN HCATADMIN hCatAdmin,
		IN LPCWSTR   pwszCatalogFile,
		IN DWORD     dwFlags
		);

	typedef
	BOOL 
	(WINAPI *pIsCatalogFile)(
		IN HANDLE hFile,
		WCHAR     *pwszFileName
		);

	typedef
	DWORD
	(WINAPI *pCertNameToStrW)(
		DWORD           dwCertEncodingType,
		PCERT_NAME_BLOB pName,
		DWORD           dwStrType,
		LPSTR           psz,
		DWORD           csz
		);
};



class CDigitalSign
{
public:
	CDigitalSign(void);
	virtual ~CDigitalSign(void);

	bool Init();
private:
	bool m_bInit;
	pWinVerifyTrust							m_WinVerifyTrust;
	pWTHelperGetProvSignerFromChain			m_pWTHelperGetProvSignerFromChain;
	pWTHelperProvDataFromStateData			m_pWTHelperProvDataFromStateData;
	pCryptCATAdminReleaseContext			m_pCryptCATAdminReleaseContext;
	pCryptCATAdminReleaseCatalogContext		m_pCryptCATAdminReleaseCatalogContext;
	pCryptCATCatalogInfoFromContext			m_pCryptCATCatalogInfoFromContext;
	pCryptCATAdminEnumCatalogFromHash		m_pCryptCATAdminEnumCatalogFromHash;
	pCryptCATAdminCalcHashFromFileHandle	m_pCryptCATAdminCalcHashFromFileHandle;
	pCryptCATAdminAcquireContext			m_pCryptCATAdminAcquireContext;
	pCryptCATAdminAddCatalog				m_pCryptCATAdminAddCatalog;
	pCryptCATAdminRemoveCatalog				m_pCryptCATAdminRemoveCatalog;
	pIsCatalogFile							m_pIsCatalogFile;
	pCertNameToStrW							m_pCertNameToStrW;
};

#endif



================================================
FILE: Sysmon/CEventLogger.cpp
================================================
#include "StdAfx.h"
#include "CEventLogger.h"

#include <strsafe.h>
#pragma comment (lib, "strsafe.lib")


CEventLogger::CEventLogger(void):
m_hTrace(0), 
	m_hSession(0),
	m_bLoggingEnabled(FALSE),
	m_nLoggingLevel(TRACE_LEVEL_INFORMATION)
{ 
	memset(
		&m_provider_guid,
		0, 
		sizeof(m_provider_guid)); 
	memset(
		&m_session_guid,
		0,
		sizeof(m_session_guid)); 
}

CEventLogger::~CEventLogger(void) 
{ 
	DeInit();
}

/* Initialize the logger lpszLogFile: location of log file, 
must end with .etl and all folders in path must exists lpszSessionName:
unique session name, like "_trace" */

HRESULT CEventLogger::Init(
	LPCTSTR lpszLogFile, 
	LPCTSTR lpszSessionName, 
	GUID *pguid) 
{ 
	HRESULT hr = S_OK; 
	if(NULL == m_hTrace) 
	{ 
		m_strLogFile = lpszLogFile;
		m_strSessionName = lpszSessionName;
		if(m_strLogFile.GetLength() > 0 && m_strSessionName.GetLength() > 0) 
		{
			// if caller didnt supply a GUID we will create one on the fly 
			if(NULL == pguid) 
				hr = CoCreateGuid(&m_provider_guid); 
			else 
				memcpy_s(
					&m_provider_guid,
					sizeof(m_provider_guid),
					pguid, 
					sizeof(GUID));

			// register us as event provider
			hr = AtlHresultFromWin32(
				RegisterTraceGuids(
							&CEventLogger::ControlCallback, 
							this,
							&m_provider_guid,
							NULL,
							NULL,
							NULL,
							NULL,
							&m_hTrace));

			if(SUCCEEDED(hr))
			{
				m_hSession = NULL;
				m_bLoggingEnabled = FALSE;
				m_nLoggingLevel = TRACE_LEVEL_INFORMATION;

				/**
				Initialize the structure that will be used for writing events, the structure looks like this:
				struct{
				EVENT_TRACE_HEADER header;
				MOF_FIELD mof;
				}
				We will use only one MOF_FIELD after the EVENT_TRACE_HEADER and the logging text will be put here
				*/

				if(m_eventdata.GetCount() == 0)
					m_eventdata.SetCount(sizeof(EVENT_TRACE_HEADER) + sizeof(MOF_FIELD));
				if(m_eventdata.GetCount() > 0)
				{
					memset(m_eventdata.GetData(), 0, m_eventdata.GetCount());
					PEVENT_TRACE_HEADER pEventHeader = (PEVENT_TRACE_HEADER)m_eventdata.GetData();
					pEventHeader->Size = m_eventdata.GetCount();
					pEventHeader->Flags = WNODE_FLAG_USE_MOF_PTR;
					pEventHeader->Class.Type = EVENT_TRACE_TYPE_INFO;
				}

				hr = CoCreateGuid(&m_session_guid);
				m_sessiondata.SetCount(
					sizeof(EVENT_TRACE_PROPERTIES) + 
					(m_strLogFile.GetLength() + m_strSessionName.GetLength() + 2) * 2);

				if(m_sessiondata.GetCount() > 0)
				{
					memset(
						m_sessiondata.GetData(), 
						0, 
						m_sessiondata.GetCount());

					PEVENT_TRACE_PROPERTIES pTracePropperties = (PEVENT_TRACE_PROPERTIES)m_sessiondata.GetData();
					pTracePropperties->Wnode.BufferSize = m_sessiondata.GetCount();
					pTracePropperties->Wnode.Flags = WNODE_FLAG_TRACED_GUID;
					pTracePropperties->Wnode.ClientContext = 1;
					memcpy_s(
							&pTracePropperties->Wnode.Guid,
							sizeof(pTracePropperties->Wnode.Guid),
							&m_session_guid,
							sizeof(m_session_guid));

					pTracePropperties->LogFileMode = EVENT_TRACE_FILE_MODE_CIRCULAR | 
													EVENT_TRACE_USE_PAGED_MEMORY;

					pTracePropperties->MaximumFileSize = 1;
					pTracePropperties->LogFileNameOffset = sizeof(EVENT_TRACE_PROPERTIES);
					StringCchCopyW(
							(LPWSTR)((LPBYTE)pTracePropperties + pTracePropperties->LogFileNameOffset),
							m_strLogFile.GetLength() + 1,
							m_strLogFile.GetString());

					pTracePropperties->LoggerNameOffset =
											pTracePropperties->LogFileNameOffset + 
													(m_strLogFile.GetLength() + 1) * 2;

					StringCchCopyW(
						(LPWSTR)((LPBYTE)pTracePropperties + pTracePropperties->LoggerNameOffset), 
						m_strSessionName.GetLength() + 1, 
						m_strSessionName.GetString());

					// start and enable trace
					hr = AtlHresultFromWin32(
						StartTrace(
							&m_hSession, 
							m_strSessionName,
							pTracePropperties));

					if(SUCCEEDED(hr))
					{
						hr = AtlHresultFromWin32(
										EnableTrace(
												TRUE, 
												0, 
												TRACE_LEVEL_VERBOSE,
												&m_provider_guid,
												m_hSession));
					}
				}
			}
		}
		else
		{
			hr = E_INVALIDARG;
		}
	}

	return hr;
}


HRESULT CEventLogger::DeInit()
{ 
	HRESULT hr = S_OK; 
	if(NULL != m_hSession) 
	{ 
		// Disable provider 
		hr = AtlHresultFromWin32(
						EnableTrace(
									FALSE, 
									0, 
									0, 
									&m_provider_guid,
									m_hSession));

		// Stop trace
		hr = AtlHresultFromWin32(
			ControlTrace(
			m_hSession, 
			m_strSessionName,
			(PEVENT_TRACE_PROPERTIES)m_sessiondata.GetData(),
			EVENT_TRACE_CONTROL_STOP)
			);
	}

	if(NULL != m_hTrace)
	{
		// Unregister provider
		hr = AtlHresultFromWin32(
					UnregisterTraceGuids(m_hTrace));

		m_hTrace = NULL;
		m_hSession = NULL;
	}
	return hr;
}

void CEventLogger::Log(
	UCHAR nLevel, 
	LPCTSTR lpszFormat,...)
{ 
	if(NULL != m_hSession && nLevel <= m_nLoggingLevel && m_eventdata.GetCount() > 0)
	{
		va_list args;
		va_start(args, lpszFormat);
		CString strLog; 
		strLog.FormatV(lpszFormat, args);
		va_end(args);

		PEVENT_TRACE_HEADER pEventHeader = (PEVENT_TRACE_HEADER)m_eventdata.GetData();
		PMOF_FIELD pMOF = (PMOF_FIELD)((LPBYTE)pEventHeader + sizeof(EVENT_TRACE_HEADER));

		// Put the string as binary into the first the only MOF structure
		pEventHeader->Class.Level = nLevel;
		pMOF->Length = (strLog.GetLength() + 1) * sizeof(TCHAR);
		pMOF->DataPtr = (ULONG64)strLog.GetString();

		// Write event
		HRESULT hr = AtlHresultFromWin32(
								TraceEvent(
										m_hSession, 
										pEventHeader)
										);
	}
}

ULONG CEventLogger::ControlCallback(
	WMIDPREQUESTCODE nRequestCode, 
	PVOID pContext, 
	ULONG* Reserved, 
	PVOID pBuffer) 
{ 
	if(NULL != pContext) 
		return ((CEventLogger*)pContext)->_ControlCallback(
		nRequestCode,
		(PWNODE_HEADER)pBuffer
		); 

	return ERROR_SUCCESS; 
}

// Callback function which responses to logging control from ETW 
ULONG CEventLogger::_ControlCallback(
	WMIDPREQUESTCODE nRequestCode, 
	PWNODE_HEADER pHeader) 
{ 
	if(WMI_ENABLE_EVENTS == nRequestCode) 
	{
		m_bLoggingEnabled = TRUE; 
		m_hSession = GetTraceLoggerHandle(pHeader);
		if(NULL != m_hSession)
			m_nLoggingLevel = GetTraceEnableLevel(m_hSession);
	} 
	else if(WMI_DISABLE_EVENTS == nRequestCode)
	{
		m_bLoggingEnabled = FALSE;
		m_hSession = 0; 
	} 

	return ERROR_SUCCESS;
}

================================================
FILE: Sysmon/CEventLogger.h
================================================
#ifndef _CEventLogger_h
#define _CEventLogger_h
#include <CGuid.h>
#include <atlbase.h>
#include <atlstr.h> 
#include <atlcoll.h>
#include <Wmistr.h>
#include <Evntrace.h>

class CEventLogger
{
public: 
	CEventLogger(void);
	virtual ~CEventLogger(void);

	HRESULT Init(
				LPCTSTR lpszLogFile,
				LPCTSTR lpszSessionName,
				GUID *pguid = NULL);

	HRESULT DeInit();

	void Log(UCHAR nLevel, LPCTSTR lpszFormat,...);

protected: 
	static 
		ULONG
		WINAPI ControlCallback(
		WMIDPREQUESTCODE nRequestCode,
		PVOID pContext,
		ULONG* Reserved,
		PVOID pBuffer);

	ULONG _ControlCallback(
		WMIDPREQUESTCODE nRequestCode, 
		PWNODE_HEADER pHeader);

	GUID m_provider_guid;
	TRACEHANDLE m_hTrace;
	TRACEHANDLE m_hSession;
	BOOL m_bLoggingEnabled;
	UCHAR m_nLoggingLevel;
	CAtlArray<BYTE> m_eventdata;
	GUID m_session_guid;
	CStringW m_strLogFile;
	CStringW m_strSessionName;
	CAtlArray<BYTE> m_sessiondata;
};

#endif



================================================
FILE: Sysmon/CMofDataParser.cpp
================================================
#include "StdAfx.h"
#include "CMofDataParser.h"
#include "Sysmon.h"
#include <WinSock2.h>
#include <in6addr.h>

#define SeLengthSid( Sid ) (8 +(4*((SID*)Sid)->SubAuthorityCount))

#pragma comment (lib,"Ws2_32.lib")
CMofDataParser::CMofDataParser(void)
	:m_pServices(NULL)
{
	InitializeListHead(&m_ModDataList);
}

CMofDataParser::~CMofDataParser(void)
{
	
}

CMofDataParser* CMofDataParser::Instance()
{


	if ( !m_pServices)
	{
		if(FAILED(Connect(
			BSTR(_T("root\\wmi")))))
		{
			return NULL;
		}
	}

	return this;
}

HRESULT CMofDataParser::Connect(
	BSTR bstrNamespace
	)
{
	HRESULT hr = S_OK;
	IWbemLocator* pLocator = NULL;

	hr = CoInitialize(0);

	hr = CoCreateInstance(__uuidof(WbemLocator),
		0,
		CLSCTX_INPROC_SERVER,
		__uuidof(IWbemLocator),
		(LPVOID*) &pLocator);

	if (FAILED(hr))
	{
		goto cleanup;
	}

	hr = pLocator->ConnectServer(bstrNamespace,
		NULL,
		NULL,
		NULL,
		0L,
		NULL,
		NULL,
		&m_pServices);

	if (FAILED(hr))
	{
		goto cleanup;
	}

	hr = CoSetProxyBlanket(m_pServices,
		RPC_C_AUTHN_WINNT,
		RPC_C_AUTHZ_NONE,
		NULL,
		RPC_C_AUTHN_LEVEL_PKT, 
		RPC_C_IMP_LEVEL_IMPERSONATE,
		NULL, 
		EOAC_NONE);

	if (FAILED(hr))
	{
		m_pServices->Release();
		m_pServices = NULL;
	}

cleanup:

	if (pLocator)
		pLocator->Release();

	return hr;
}

BOOL CMofDataParser::Parse( 
						PEVENT_TRACE pEvent,
						CMofParseRes& Result )
{
	TCHAR ClassGuid[50] = {0};
	SYSTEMTIME st = {0};
	
	FILETIME ft = {0};
	IWbemClassObject* pEventCategoryClass = NULL;
	CMofParseRes* pEventRes = NULL;
	PROPERTY_LIST* pProperties = NULL;
	DWORD PropertyCount = 0;
	LONG pPropertyIndex[30] = {0};
	PBYTE pEventData = NULL;  
	PBYTE pEndOfEventData = NULL;

	if (!Instance())
	{
		return NULL;
	}

	StringFromGUID2(
				pEvent->Header.Guid,
				ClassGuid, 
				sizeof(ClassGuid));
	
	ft.dwHighDateTime = pEvent->Header.TimeStamp.HighPart;
	ft.dwLowDateTime = pEvent->Header.TimeStamp.LowPart;

	if (pEvent->MofLength <= 0)
	{
		return FALSE;
	}


	for ( LIST_ENTRY* pEntry = m_ModDataList.Flink;
		pEntry != &m_ModDataList;
		pEntry = pEntry->Flink)
	{
		CMofParseRes* pRes = CONTAINING_RECORD(
											pEntry,
											CMofParseRes,
											m_Entry);

		if (pRes)
		{
			if (pRes)
			{
				if (pRes->m_MofHeader.MofVsersion == pEvent->Header.Class.Version &&
					pRes->m_MofHeader.MofType == pEvent->Header.Class.Type)
				{
					if (pEvent->Header.Guid.Data1 == pRes->m_MofHeader.MofGuid.Data1 &&
						pEvent->Header.Guid.Data2 == pRes->m_MofHeader.MofGuid.Data2 &&
						pEvent->Header.Guid.Data3 == pRes->m_MofHeader.MofGuid.Data3 &&
						pEvent->Header.Guid.Data4[0] == pRes->m_MofHeader.MofGuid.Data4[0] &&
						pEvent->Header.Guid.Data4[1] == pRes->m_MofHeader.MofGuid.Data4[1] &&
						pEvent->Header.Guid.Data4[2] == pRes->m_MofHeader.MofGuid.Data4[2] &&
						pEvent->Header.Guid.Data4[3] == pRes->m_MofHeader.MofGuid.Data4[3] &&
						pEvent->Header.Guid.Data4[4] == pRes->m_MofHeader.MofGuid.Data4[4] &&
						pEvent->Header.Guid.Data4[5] == pRes->m_MofHeader.MofGuid.Data4[5] &&
						pEvent->Header.Guid.Data4[6] == pRes->m_MofHeader.MofGuid.Data4[6] &&
						pEvent->Header.Guid.Data4[7] == pRes->m_MofHeader.MofGuid.Data4[7])
					{
						Result = *pRes;
						return TRUE;
					}
				}
			}
		}
	}

	FileTimeToSystemTime(
		&ft,
		&st);
	SystemTimeToTzSpecificLocalTime(
		NULL,
		&st,
		&Result.m_MofHeader.MofLocal);


	pEventCategoryClass = GetEventCategoryClass(
									BSTR(ClassGuid),
									pEvent->Header.Class.Version);
	if (pEventCategoryClass)
	{

		pEventRes = GetEventClassPropertyList(
						pEventCategoryClass,
						pEvent->Header.Guid,
						pEvent->Header.Class.Version,
						pEvent->Header.Class.Level,
						pEvent->Header.Class.Type);

		pEventCategoryClass->Release();
		pEventCategoryClass = NULL;

		if (pEventRes)
		{
			Result = *pEventRes;
// 			if (GetPropertyList(
// 						pEventClass,
// 						&pProperties,
// 						&PropertyCount,
// 						pPropertyIndex ))
// 			{
// 				
// 				pEventData = (PBYTE)(pEvent->MofData);
// 				pEndOfEventData = ((PBYTE)(pEvent->MofData) + pEvent->MofLength);
// 
// 				if ( PropertyCount )
// 				{
// 					Result.m_MofProperty = new MOF_ITEM[PropertyCount];
// 					if (Result.m_MofProperty)
// 					{
// 						ZeroMemory(
// 							Result.m_MofProperty,
// 							sizeof(MOF_ITEM) * 
// 							PropertyCount);
// 					}
// 				}
// 
// 				if ( Result.m_MofProperty )
// 				{
// 					for (LONG i = 0; (DWORD)i < PropertyCount; i++)
// 					{
// 
// 						if ( !(0 <= pPropertyIndex[i] &&
// 							pPropertyIndex[i] <= PropertyCount ))
// 						{
// 							break;
// 						}
// 
// 						GetPropertyName( 
// 								&pProperties[pPropertyIndex[i]],
// 								Result.m_MofProperty[i].Name);
// 
// 						pEventData =  GetPropertyValue(
// 											&pProperties[pPropertyIndex[i]], 
// 											*(Result.GetItem(i)),
// 											pEventData, 
// 											(USHORT)(pEndOfEventData - pEventData));
// 
// 						if (NULL == pEventData)
// 						{
// 							break;
// 						}
// 
// 						Result.m_MofHeader.MofCount = (i + 1);
// 					}
// 				}				
// 
// 				FreePropertyList(
// 							pProperties,
// 							PropertyCount);
// 			}

			return TRUE;
		}
	}

	return FALSE;
}


IWbemClassObject* 
CMofDataParser::GetEventCategoryClass(
								BSTR bstrClassGuid,
								int Version)
{
	HRESULT hr = S_OK;
	HRESULT hrQualifier = S_OK;
	IEnumWbemClassObject* pClasses = NULL;
	IEnumWbemClassObject* pClasses_2 = NULL;
	IWbemClassObject* pClass = NULL;
	IWbemClassObject* pClass_2 = NULL;
	IWbemQualifierSet* pQualifiers = NULL;
	ULONG cnt = 0;
	ULONG cnt_2 = 0;
	VARIANT varGuid;
	VARIANT varVersion; 

	VariantInit(&varGuid);
	VariantInit(&varVersion);

	hr = m_pServices->CreateClassEnum(
						BSTR(_T("EventTrace")), 
						WBEM_FLAG_DEEP |
						WBEM_FLAG_FORWARD_ONLY |
						WBEM_FLAG_USE_AMENDED_QUALIFIERS,
						NULL,
						&pClasses);

	if (FAILED(hr))
	{
		goto cleanup;
	}

	__try
	{
		while (S_OK == hr)
		{
			if (pClass)
			{
				pClass->Release();
				pClass = NULL;
			}

			hr = pClasses->Next(WBEM_INFINITE, 1, &pClass, &cnt);

			if (FAILED(hr) || cnt != 1)
			{
				goto cleanup;
			}

			VARIANT varCLassName;
			VariantInit(&varCLassName);
			if (FAILED(pClass->Get(BSTR(_T("__CLASS")),0,&varCLassName,0,0)))
			{
				continue;
			}

			m_pServices->CreateClassEnum(
				varCLassName.bstrVal,
				WBEM_FLAG_DEEP | 
				WBEM_FLAG_UPDATE_ONLY | 
				WBEM_FLAG_USE_AMENDED_QUALIFIERS,
				0,
				&pClasses_2);

			VariantClear(&varCLassName);

			cnt_2 = 1;

			do 
			{
				
				if (pClasses_2)
				{
					if ( pClasses_2->Next(5000, 1, &pClass_2, &cnt_2) != S_OK )
						continue;

					if ( cnt_2 != 1 )
						break;			
				}
				else
				{
					pClass_2 = pClass;
					cnt_2 = 1;
				}

				HRESULT hr2 = pClass_2->Get(BSTR(_T("__CLASS")),0,&varCLassName,0,0);
				VariantClear(&varCLassName);

				if (SUCCEEDED(hr2))
				{
					if ( pQualifiers )
					{
						pQualifiers->Release();
						pQualifiers = 0;
					}

					hrQualifier = pClass_2->GetQualifierSet(&pQualifiers);

					if (pQualifiers)
					{
						hrQualifier = pQualifiers->Get(L"Guid", 0, &varGuid, NULL);

						if (SUCCEEDED(hrQualifier))
						{
							if (_wcsicmp(varGuid.bstrVal, bstrClassGuid) == 0)
							{

								hrQualifier = pQualifiers->Get(L"EventVersion", 0, &varVersion, NULL);

								if (SUCCEEDED(hrQualifier))
								{
									VariantChangeType(&varVersion, &varVersion, 0, VT_I2);
									SHORT Ver = varVersion.iVal;
									VariantClear(&varVersion);
									if (Version == Ver)
									{
										__leave; //found class
									}

									VariantClear(&varVersion);
								}
								else if (WBEM_E_NOT_FOUND == hrQualifier) 
								{
									__leave; //found class
								}
							}

							VariantClear(&varGuid);
						}

						pQualifiers->Release();
						pQualifiers = NULL;
					}
				}

				if (pClass_2)
				{
					pClass_2->Release();
					pClass_2 = NULL;
				}

			} while (cnt_2 == 1);

			if (pClasses_2)
			{
				pClasses_2->Release();
				pClasses_2 = NULL;
			}		
		} 
	}
	__except(EXCEPTION_EXECUTE_HANDLER)
	{

	}

cleanup:

	if (pClasses_2)
	{
		pClasses_2->Release();
		pClasses_2 = NULL;
	}

	if (pClasses)
	{
		pClasses->Release();
		pClasses = NULL;
	}

	if (pQualifiers)
	{
		pQualifiers->Release();
		pQualifiers = NULL;
	}

	if (pClass)
	{
		pClass->Release();
		pClass = NULL;
	}

	VariantClear(&varVersion);
	VariantClear(&varGuid);

	return pClass_2;
}

CMofParseRes* 
CMofDataParser::GetEventClassPropertyList(
						IWbemClassObject* pEventCategoryClass,
						GUID& Guid,
						USHORT Version,
						USHORT Level,
						USHORT EventType)
{
	HRESULT hr = S_OK;
	HRESULT hrQualifier = S_OK;
	IEnumWbemClassObject* pClasses = NULL;
	IWbemClassObject* pClass = NULL;
	IWbemQualifierSet* pQualifiers = NULL;
	BOOL FoundEventClass = FALSE;
	CMofParseRes* pMofParseRes = NULL;
	OLECHAR szClassName[100] = {0};
	ULONG cnt = 0;
	VARIANT varClassName;
	VARIANT varEventType;
	VARIANT	varDisplayName;
	
	LIST_ENTRY pList;

	InitializeListHead(&pList);
	VariantInit(&varClassName);
	VariantInit(&varEventType);
	VariantInit(&varDisplayName);

	hr = pEventCategoryClass->Get(_T("__CLASS"), 0, &varClassName, NULL, NULL);

	if (FAILED(hr))
	{
		goto cleanup;
	}

	StringCchCopy(
				szClassName,
				100,
				varClassName.bstrVal);

	if (pQualifiers)
	{
		pQualifiers->Release();
		pQualifiers = NULL;
	}

	pEventCategoryClass->GetQualifierSet(&pQualifiers);

	if (pQualifiers && !pQualifiers->Get(
		BSTR(_T("DisplayName")),
		0,
		&varDisplayName,
		0) && varDisplayName.lVal )
	{
		StringCchCopy(
				szClassName,
				MAX_PATH,
				varDisplayName.bstrVal);
	}

	hr = m_pServices->CreateClassEnum(varClassName.bstrVal, 
		WBEM_FLAG_DEEP | 
		WBEM_FLAG_UPDATE_ONLY | 
		WBEM_FLAG_USE_AMENDED_QUALIFIERS,
		NULL, 
		&pClasses);

	if (FAILED(hr))
	{		
		goto cleanup;
	}

	while (S_OK == hr)
	{
		hr = pClasses->Next(WBEM_INFINITE, 1, &pClass, &cnt);

		if (hr != S_OK)
		{
			goto cleanup;
		}

		if (cnt != 1)
		{
			break;
		}

		if (pQualifiers)
		{
			pQualifiers->Release();
			pQualifiers = NULL;
		}

		hrQualifier = pClass->GetQualifierSet(&pQualifiers);

		if (FAILED(hrQualifier))
		{			
			pClass->Release();
			pClass = NULL;
			goto cleanup;
		}

		hrQualifier = pQualifiers->Get(L"EventType", 0, &varEventType, NULL);

		if (FAILED(hrQualifier))
		{
			
			pClass->Release();
			pClass = NULL;
			goto cleanup;
		}

		// If multiple events provide the same data, the EventType qualifier
		// will contain an array of types. Loop through the array and find a match.

		if (varEventType.vt & VT_ARRAY)
		{
			HRESULT hrSafe = S_OK;
			
			SAFEARRAY* pEventTypes = varEventType.parray;
			VARIANT vargTypeName;
			VariantInit(&vargTypeName);
			if ( pQualifiers->Get(
				BSTR(_T("EventTypeName")),
				0,
				&vargTypeName, 
				0) == S_OK &&
				vargTypeName.vt & VT_ARRAY )
			{
				SAFEARRAY* pEventNames = vargTypeName.parray;
				BSTR* ppvData = NULL;
				

				if (pEventNames && pEventTypes &&
					pEventNames->rgsabound->cElements &&
					pEventTypes->rgsabound->cElements &&
					pEventTypes->rgsabound->cElements ==
					pEventNames->rgsabound->cElements)
				{
					SafeArrayAccessData(
									pEventNames,
									(void**)&ppvData);

					for (LONG i = 0; (ULONG)i < pEventTypes->rgsabound->cElements; i++)
					{
						int ClassEventType = 0;
						hrSafe = SafeArrayGetElement(pEventTypes, &i, &ClassEventType);

						CMofParseRes* pMofParseRes2 = (CMofParseRes*)malloc(sizeof(CMofParseRes));

						if (pMofParseRes2)
						{
							ZeroMemory(pMofParseRes2,sizeof(CMofParseRes));

							InitializeListHead(&pMofParseRes2->m_MofPropertyList);
							pMofParseRes2->m_MofHeader.MofClassName = SysAllocString(szClassName);
							memcpy(
								&pMofParseRes2->m_MofHeader.MofGuid,
								&Guid,			 
								sizeof(GUID));

							pMofParseRes2->m_MofHeader.MofType = ClassEventType;
							pMofParseRes2->m_MofHeader.MofLevel = Level;
							pMofParseRes2->m_MofHeader.MofVsersion = Version;
							pMofParseRes2->m_MofHeader.MofTypeName = SysAllocString(ppvData[i]);
							InsertTailList(&pList,&pMofParseRes2->m_Entry);

							if (ClassEventType == EventType)
							{
								pMofParseRes = pMofParseRes2;
							}
						}						
					}
				}

			}

			VariantClear(&vargTypeName);
		}
		else
		{
			VARIANT vargTypeName;
			VariantInit(&vargTypeName);
			if ( pQualifiers->Get(
				BSTR(_T("EventTypeName")),
				0,
				&vargTypeName, 
				0) == S_OK )
			{
				VariantChangeType(&varEventType, &varEventType, 0, VT_I2);
				USHORT vType = varEventType.iVal;

				CMofParseRes* pMofParseRes2 = (CMofParseRes*)malloc(sizeof(CMofParseRes));

				if (pMofParseRes2)
				{
					ZeroMemory(pMofParseRes2,sizeof(CMofParseRes));
					InitializeListHead(&pMofParseRes2->m_MofPropertyList);
					pMofParseRes2->m_MofHeader.MofClassName = SysAllocString(szClassName);
					memcpy(
						&pMofParseRes2->m_MofHeader.MofGuid,
						&Guid,			 
						sizeof(GUID));

					pMofParseRes2->m_MofHeader.MofType = vType;
					pMofParseRes2->m_MofHeader.MofLevel = Level;
					pMofParseRes2->m_MofHeader.MofVsersion = Version;
					pMofParseRes2->m_MofHeader.MofTypeName = SysAllocString(vargTypeName.bstrVal);

					InsertTailList(&pList,&pMofParseRes2->m_Entry);

					if (vType == EventType)
					{
						//FoundEventClass = TRUE;
						pMofParseRes = pMofParseRes2;
					}
				}
			}
			VariantClear(&vargTypeName);

			
		}
		VariantClear(&varEventType);

		SAFEARRAY* pNames = NULL;
		VARIANT QualifierVal;
		VariantInit(&QualifierVal);
		QualifierVal.vt = VT_I4;
		QualifierVal.lVal = 1;
		LONG rgIndices = 0;	

		while(TRUE)
		{
			hr = pClass->GetNames(
				(BSTR)_T("WmiDataId"),
				WBEM_FLAG_ONLY_IF_IDENTICAL,
				&QualifierVal,
				&pNames);

			if (hr != S_OK)
			{
				break;
			}

			if (!pNames->rgsabound->cElements)
			{
				break;
			}

			rgIndices = 0;
			do 
			{
				BSTR pvElement = NULL;
				CIMTYPE QualifierType = 0;
				if ( SafeArrayGetElement(pNames, &rgIndices, &pvElement) ||
					pClass->Get(pvElement, 0, 0, &QualifierType, 0))
				{
					break;
				}

				if ( pQualifiers )
				{
					pQualifiers->Release();
					pQualifiers = 0;
				}

				if(pClass->GetPropertyQualifierSet(pvElement,&pQualifiers))
				{
					break;
				}

				LONG dwLen = GetArrayValue(QualifierType,pQualifiers);
				LONG ArraySize = QualifierType & VT_ARRAY ? GetArraySize(pQualifiers) : 1;

				AddProperityList(
								&pList,
								pvElement,
								dwLen,
								ArraySize);
				rgIndices++;

			} while(rgIndices < pNames->rgsabound->cElements);

			QualifierVal.lVal++;
			SafeArrayDestroy(pNames);
			pNames = 0;
		}		
		
		pClass->Release();
		pClass = NULL;

		AddGlobalEvent(&pList);
	}

cleanup:

	if (pClass)
	{
		pClass->Release();
		pClass = NULL;
	}

	if (pClasses)
	{
		pClasses->Release();
		pClasses = NULL;
	}

	if (pQualifiers)
	{
		pQualifiers->Release();
		pQualifiers = NULL;
	}
	
	AddGlobalEvent(&pList);

	VariantClear(&varClassName);
	VariantClear(&varEventType);
	VariantClear(&varDisplayName);

	return pMofParseRes;
}


BOOL CMofDataParser::GetPropertyList(
						IWbemClassObject* pClass, 
						PROPERTY_LIST** ppProperties,
						DWORD* pPropertyCount,
						LONG* PropertyIndex)
{
	HRESULT hr = S_OK;
	SAFEARRAY* pNames = NULL;
	LONG j = 0;
	VARIANT var;

	// Retrieve the property names.

	hr = pClass->GetNames(
						NULL,
						WBEM_FLAG_LOCAL_ONLY,
						NULL,
						&pNames);
	if (pNames)
	{
		*pPropertyCount = pNames->rgsabound->cElements;

		
		*ppProperties = new PROPERTY_LIST[*pPropertyCount];	

		if ( NULL == *ppProperties)
		{
			hr = E_OUTOFMEMORY;
			goto cleanup;
		}

		ZeroMemory(
			*ppProperties,
			sizeof(PROPERTY_LIST) * (*pPropertyCount)
					);

		for (LONG i = 0; (ULONG)i < *pPropertyCount; i++)
		{
			PROPERTY_LIST* pCurProperList = &(*ppProperties)[i];
			
			__try
			{
				hr = SafeArrayGetElement(
					pNames, 
					&i,
					&(pCurProperList->Name));

				if (FAILED(hr))
				{
					goto cleanup;
				} 

				//Save the qualifiers. Used latter to help determine how to read the event data.

				hr = pClass->GetPropertyQualifierSet(
					pCurProperList->Name,
					&(pCurProperList->pQualifiers));
				if (FAILED(hr))
				{
					goto cleanup;
				} 

				hr = pCurProperList->pQualifiers->Get(
					L"WmiDataId",
					0,
					&var,
					NULL);
				if (SUCCEEDED(hr))
				{
					j = var.intVal - 1;
					VariantClear(&var);
					*(PropertyIndex + j ) = i;

				}
				else
				{
					goto cleanup;
				}

				hr = pClass->Get(
					pCurProperList->Name,
					0,
					NULL,
					&(pCurProperList->CimType),
					NULL);

				if (FAILED(hr))
				{
					goto cleanup;
				} 
			}
			__except(EXCEPTION_EXECUTE_HANDLER)
			{

			}
		}
	}

cleanup:

	if (pNames)
	{
		SafeArrayDestroy(pNames);
	}

	if (FAILED(hr))
	{
		if (*ppProperties)
		{
			FreePropertyList(
						*ppProperties,
						*pPropertyCount);
		}

		return FALSE;
	}

	return TRUE;
}


void CMofDataParser::FreePropertyList(
				PROPERTY_LIST* pProperties,
				DWORD Count)
{
	if(pProperties)
	{
		for (DWORD i=0; i < Count; i++)
		{
			SysFreeString((pProperties+i)->Name);

			if ((pProperties+i)->pQualifiers)
			{
				(pProperties+i)->pQualifiers->Release();
				(pProperties+i)->pQualifiers = NULL;
			}
		}

		delete[] pProperties;
		pProperties = NULL;
	}

}

void CMofDataParser::GetPropertyName(
						PROPERTY_LIST* pProperty,
						TCHAR* PropertyName)
{
	HRESULT hr;
	VARIANT varDisplayName;
	VariantInit(&varDisplayName);
	__try
	{
		hr = pProperty->pQualifiers->Get(
										L"DisplayName",
										0, 
										&varDisplayName,
										NULL);

	}
	__except (EXCEPTION_EXECUTE_HANDLER)
	{
		hr = -1;
	}
	

	
	if (SUCCEEDED(hr))
	{
		PropertyName = SysAllocString(varDisplayName.bstrVal);
	}
	else
	{
		PropertyName = SysAllocString(pProperty->Name);
	}
	
	VariantClear(&varDisplayName);
}


PBYTE CMofDataParser::GetPropertyValue(
								PROPERTY_LIST*	pProperty,
								MOF_ITEM&		MofItem,
								PBYTE			pEventData,
								USHORT			RemainingBytes)
{
	HRESULT hr;
	VARIANT varQualifier;
	ULONG ArraySize = 1;
	BOOL PrintAsChar = FALSE;
	BOOL PrintAsHex = FALSE;
	BOOL PrintAsIPAddress = FALSE; 
	BOOL PrintAsPort = FALSE; 
	BOOL IsWideString = FALSE;
	BOOL IsNullTerminated = FALSE;
	USHORT StringLength = 0;
	MofItem.ArraySize = 0;
	MofItem.cValues = 0;
	MofItem.liValue.QuadPart = 0;

	if (SUCCEEDED(hr = pProperty->pQualifiers->Get(
												L"Pointer",
												0, 
												NULL,
												NULL)) ||
		SUCCEEDED(hr = pProperty->pQualifiers->Get(
												L"PointerType",
												0,
												NULL,
												NULL)))
	{
		if (m_PointerSize == 4) 
		{
			ULONG temp = 0;

			CopyMemory(
					&temp,
					pEventData,
					sizeof(ULONG));

			MofItem.Types = OTHER_VALUE;
			MofItem.liValue.LowPart = temp; 
		}
		else
		{
			ULONGLONG temp = 0;

			CopyMemory(
					&temp,
					pEventData,
					sizeof(ULONGLONG));

			
			MofItem.Types = OTHER_VALUE;
			MofItem.liValue.QuadPart = temp;
		}

		pEventData += m_PointerSize;

		return pEventData;
	}
	else
	{
		
		if (pProperty->CimType & CIM_FLAG_ARRAY)
		{
			hr = pProperty->pQualifiers->Get(
											L"MAX",
											0,
											&varQualifier,
											NULL);
			if (SUCCEEDED(hr))
			{
				ArraySize = varQualifier.intVal;
				VariantClear(&varQualifier);
			}
			else
			{
				//wprintf(L"Failed to retrieve the MAX qualifier. Terminating.\n");
				return NULL;
			}
		}

		// The CimType is the data type of the property.

		switch(pProperty->CimType & (~CIM_FLAG_ARRAY))
		{
		case CIM_SINT32:
			{
				LONG temp = 0;
				MofItem.u32ArrayValue = new uint32[ArraySize];

				if ( MofItem.u32ArrayValue)
				{
					for ( ULONG i = 0 ; i < ArraySize ;  i++)
					{
						CopyMemory(
							&temp,
							pEventData,
							sizeof(LONG));

						MofItem.u32ArrayValue[i] = temp;
						
						pEventData += sizeof(LONG);
					}

					MofItem.Types = UINT32_ARRAY_VALUE;
				}
				else
				{
					return NULL;
				}

				
				return pEventData;
			}

		case CIM_UINT32:
			{
				ULONG temp = 0;

				hr = pProperty->pQualifiers->Get(
												L"Extension",
												0,
												&varQualifier,
												NULL);
				if (SUCCEEDED(hr))
				{
					
					if (_wcsicmp(L"IPAddr", varQualifier.bstrVal) == 0)
					{
						PrintAsIPAddress = TRUE;
					}

					VariantClear(&varQualifier);
				}
				else
				{
					hr = pProperty->pQualifiers->Get(
													L"Format",
													0,
													NULL,
													NULL);
					if (SUCCEEDED(hr))
					{
						PrintAsHex = TRUE;
					}
				}

				MofItem.u32ArrayValue = new uint32[ArraySize];

				if ( MofItem.u32ArrayValue)
				{
					for (ULONG i = 0; i < ArraySize; i++)
					{
						CopyMemory(&temp, pEventData, sizeof(ULONG));

						if (PrintAsIPAddress)
						{
// 							wprintf(L"%03d.%03d.%03d.%03d\n", (temp >>  0) & 0xff,
// 								(temp >>  8) & 0xff,
// 								(temp >>  16) & 0xff,
// 								(temp >>  24) & 0xff);

							MofItem.u32ArrayValue[i] = temp;
						}
						else if (PrintAsHex)
						{
							//wprintf(L"0x%x\n", temp);
							MofItem.u32ArrayValue[i] = temp;
						}
						else
						{
							//wprintf(L"%lu\n", temp);
							MofItem.u32ArrayValue[i] = temp;
						}

						pEventData += sizeof(ULONG);
					}


					MofItem.Types = UINT32_ARRAY_VALUE;
				}
				else
				{
					return NULL;
				}

				return pEventData;
			}

		case CIM_SINT64:
			{
				LONGLONG temp = 0;

				for (ULONG i=0; i < ArraySize; i++)
				{
					CopyMemory(
							&temp,
							pEventData,
							sizeof(LONGLONG));
					//wprintf(L"%I64d\n", temp);
					MofItem.liValue.QuadPart = temp;
					MofItem.Types = OTHER_VALUE;
					pEventData += sizeof(LONGLONG);
				}

				return pEventData;
			}

		case CIM_UINT64:
			{
				ULONGLONG temp = 0;

				for (ULONG i=0; i < ArraySize; i++)
				{
					CopyMemory(&temp, pEventData, sizeof(ULONGLONG));
					//wprintf(L"%I64u\n", temp);
					MofItem.liValue.QuadPart = temp;
					MofItem.Types = OTHER_VALUE;

					pEventData += sizeof(ULONGLONG);
				}

				return pEventData;
			}

		case CIM_STRING:
			{
				USHORT temp = 0;

				if( _wcsicmp(
						_T("ApplicationId"),
						MofItem.Name))
				{
					hr = pProperty->pQualifiers->Get(
						L"Format",
						0, 
						NULL,
						NULL);

					if (SUCCEEDED(hr))
					{
						IsWideString = TRUE;
					}

					hr = pProperty->pQualifiers->Get(
						L"StringTermination",
						0,
						&varQualifier, 
						NULL);

					if (FAILED(hr) || (_wcsicmp(
						varQualifier.bstrVal,
						L"NullTerminated") == 0))
					{
						IsNullTerminated = TRUE;
					}
					else if (_wcsicmp(
						varQualifier.bstrVal,
						L"Counted") == 0)
					{
						// First two bytes of the string contain its length.

						CopyMemory(
							&StringLength, 
							pEventData,
							sizeof(USHORT));

						pEventData += sizeof(USHORT);
					}
					else if (_wcsicmp(
						varQualifier.bstrVal,
						L"ReverseCounted") == 0)
					{

						CopyMemory(
							&temp,
							pEventData,
							sizeof(USHORT));

						StringLength = MAKEWORD(
							HIBYTE(temp), 
							LOBYTE(temp));

						pEventData += sizeof(USHORT);
					}
					else if (_wcsicmp(
						varQualifier.bstrVal,
						L"NotCounted") == 0)
					{

						StringLength = RemainingBytes;
					}

					if ( ArraySize)
					{
						MofItem.mofcArray = new MOF_CHAR_ARRAY[ArraySize];

						if ( MofItem.mofcArray)
						{
							MofItem.Types = CHAR_ARRAY_VALUE;
							ZeroMemory(
								MofItem.mofcArray,
								sizeof(MOF_CHAR_ARRAY)*ArraySize);

							MofItem.ArraySize = ArraySize;
						}
						else
						{
							return NULL;
						}
					}

					VariantClear(&varQualifier);

					for (ULONG i = 0; i < ArraySize; i++)
					{
						if (IsWideString)
						{
							if (IsNullTerminated)
							{
								StringLength = (USHORT)(wcslen((WCHAR*)pEventData));
								StringLength += sizeof(WCHAR);

								if ( StringLength && MofItem.mofcArray )
								{
									MofItem.mofcArray[i].Name[0] = i;
									MofItem.mofcArray[i].wValue = new WCHAR[StringLength];

									if (MofItem.mofcArray[i].wValue)
									{
										StringCchCopy(
											MofItem.mofcArray[i].wValue,
											StringLength,
											(STRSAFE_LPCWSTR)pEventData);
									}
								}				

							}
							else
							{
								LONG StringSize = (StringLength) * sizeof(WCHAR); 
								//WCHAR* pwsz = (WCHAR*)malloc(StringSize + sizeof(WCHAR)); // +2 for NULL

								if (MofItem.mofcArray)
								{
									MofItem.mofcArray[i].Name[0] = i;
									MofItem.mofcArray[i].wValue = new WCHAR[StringLength+1];

									if (MofItem.mofcArray[i].wValue)
									{
										CopyMemory(
											MofItem.mofcArray[i].wValue,
											(WCHAR*)pEventData,
											StringSize);

										*(MofItem.mofcArray[i].wValue+StringSize) = '\0';

									}
								}

							}

							StringLength *= sizeof(WCHAR);
						}
						else  // It is an ANSI string
						{
							if (IsNullTerminated)
							{
								StringLength = (USHORT)strlen((char*)pEventData) + 1;
								//printf("%s\n", (char*)pEventData);
								if ( StringLength && MofItem.mofcArray )
								{
									MofItem.mofcArray[i].Name[0] = i;
									MofItem.mofcArray[i].cValue = new char[StringLength];

									if (MofItem.mofcArray[i].cValue)
									{
										StringCchCopyA(
											MofItem.mofcArray[i].cValue,
											StringLength,
											(STRSAFE_LPCSTR)pEventData);
									}
								}
							}
							else
							{
								//char* psz = (char*)malloc(StringLength+1);  // +1 for NULL
								if (MofItem.mofcArray)
								{
									MofItem.mofcArray[i].Name[0] = i;
									MofItem.mofcArray[i].cValue = new char[StringLength+1];

									if (MofItem.mofcArray[i].cValue)
									{
										CopyMemory(
											MofItem.mofcArray[i].cValue,
											(char*)pEventData,
											StringLength);

										*(MofItem.mofcArray[i].cValue + StringLength) = '\0';

									}
								}

							}
						}

						pEventData += StringLength;
						StringLength = 0;
					}
				}
				else
				{
					MofItem.Types = OTHER_VALUE;
					MofItem.liValue.QuadPart = 0;

					CopyMemory( 
							&MofItem.liValue.LowPart,
							pEventData,
							4);
					 
					(UCHAR*)pEventData += 4;
				}

				
				return pEventData;
			} 

		case CIM_BOOLEAN:
			{
				BOOL temp = FALSE;

				for (ULONG i = 0; i < ArraySize; i++)
				{
					CopyMemory(&temp, pEventData, sizeof(BOOL));
					wprintf(L"%s\n", (temp) ? L"TRUE" : L"FALSE");
					pEventData += sizeof(BOOL);
				}

				return pEventData;
			}

		case CIM_SINT8:
		case CIM_UINT8:
			{
				hr = pProperty->pQualifiers->Get(
												L"Extension",
												0,
												&varQualifier, 
												NULL);
				if (SUCCEEDED(hr))
				{
					
					if (_wcsicmp(
							L"Guid",
							varQualifier.bstrVal) == 0)
					{
						WCHAR szGuid[50] =  {0};
						GUID Guid;

						CopyMemory(
								&Guid,
								(GUID*)pEventData,
								sizeof(GUID));

						StringFromGUID2(	
									Guid,
									szGuid,
									sizeof(szGuid)-1);
						MofItem.Types = TCHAR_VALUE;
						MofItem.cValues = new TCHAR[50];

						if (MofItem.cValues)
						{
							StringCchCopy(
										MofItem.cValues,
										50,
										szGuid
										);
						}
						
					}

					VariantClear(&varQualifier);
					pEventData += sizeof(GUID);
				}
				else 
				{
					hr = pProperty->pQualifiers->Get(
													L"Format",
													0,
													NULL,
													NULL);
					if (SUCCEEDED(hr))
					{
						PrintAsChar = TRUE;  // ANSI character
					}

					for (ULONG i = 0; i < ArraySize; i++)
					{
						if (PrintAsChar)
							wprintf(L"%c", *((char*)pEventData)); 
						else
							wprintf(L"%hd", *((BYTE*)pEventData));

						pEventData += sizeof(UINT8);
					}
				}

				wprintf(L"\n");

				return pEventData;
			}

		case CIM_CHAR16:
			{
				WCHAR temp;

				for (ULONG i = 0; i < ArraySize; i++)
				{
					CopyMemory(&temp, pEventData, sizeof(WCHAR));
					wprintf(L"%c", temp);
					pEventData += sizeof(WCHAR);
				}

				wprintf(L"\n");

				return pEventData;
			}

		case CIM_SINT16:
			{
				SHORT temp = 0;

				for (ULONG i = 0; i < ArraySize; i++)
				{
					CopyMemory(&temp, pEventData, sizeof(SHORT));
					wprintf(L"%hd\n", temp);
					pEventData += sizeof(SHORT);
				}

				return pEventData;
			}

		case CIM_UINT16:
			{
				USHORT temp = 0;

				// If the data is a port number, call the ntohs Windows Socket 2 function
				// to convert the data from TCP/IP network byte order to host byte order.
				// This is here to support legacy event classes; the Port extension 
				// should only be used on properties whose CIM type is object.

				hr = pProperty->pQualifiers->Get(
												L"Extension",
												0, 
												&varQualifier,
												NULL);
				if (SUCCEEDED(hr))
				{
					if (_wcsicmp(
								L"Port",
								varQualifier.bstrVal) == 0)
					{
						PrintAsPort = TRUE;
					}

					VariantClear(&varQualifier);
				}

				if (ArraySize)
				{
					MofItem.u32ArrayValue = new uint32[ArraySize];
					if (MofItem.u32ArrayValue)
					{
						MofItem.Types = UINT32_ARRAY_VALUE;
						ZeroMemory(
									MofItem.u32ArrayValue,
									sizeof(uint32)*ArraySize
									);
					}
				}

				for (ULONG i = 0; i < ArraySize; i++)
				{
					CopyMemory(
							&temp,
							pEventData,
							sizeof(USHORT));

					if (MofItem.u32ArrayValue)
					{
						if (PrintAsPort)
						{
							MofItem.u32ArrayValue[i] = ntohs(temp);
						}
						else
						{
							MofItem.u32ArrayValue[i] = temp;
						}
					}					

					pEventData += sizeof(USHORT);
				}

				return pEventData;
			}

		case CIM_OBJECT:
			{
				// An object data type has to include the Extension qualifier.

				hr = pProperty->pQualifiers->Get(
												L"Extension",
												0, 
												&varQualifier, 
												NULL);
				if (SUCCEEDED(hr))
				{
					if (_wcsicmp(
								L"SizeT",
								varQualifier.bstrVal) == 0)
					{
						VariantClear(&varQualifier);

						// You do not need to know the data type of the property, you just 
						// retrieve either 4 bytes or 8 bytes depending on the pointer's size.

						for (ULONG i = 0; i < ArraySize; i++)
						{
							if (m_PointerSize == 4) 
							{
								ULONG temp = 0;

								CopyMemory(
										&temp, 
										pEventData,
										sizeof(ULONG));
								wprintf(L"0x%x\n", temp);
							}
							else
							{
								ULONGLONG temp = 0;

								CopyMemory(&temp, pEventData, sizeof(ULONGLONG));
								wprintf(L"0x%x\n", temp);
							}

							pEventData += m_PointerSize;
						}

						return pEventData;
					}
					if (_wcsicmp(
								L"Port", 
								varQualifier.bstrVal) == 0)
					{
						USHORT temp = 0;

						VariantClear(&varQualifier);

						for (ULONG i = 0; i < ArraySize; i++)
						{
							CopyMemory(
									&temp,
									pEventData, 
									sizeof(USHORT));
							wprintf(L"%hu\n", ntohs(temp));
							pEventData += sizeof(USHORT);
						}

						return pEventData;
					}
					else if (_wcsicmp(L"IPAddr", varQualifier.bstrVal) == 0 ||
						_wcsicmp(L"IPAddrV4", varQualifier.bstrVal) == 0)
					{
						ULONG temp = 0;

						VariantClear(&varQualifier);

						for (ULONG i = 0; i < ArraySize; i++)
						{
							CopyMemory(&temp, pEventData, sizeof(ULONG));

							wprintf(L"%d.%d.%d.%d\n", (temp >>  0) & 0xff,
								(temp >>  8) & 0xff,
								(temp >>  16) & 0xff,
								(temp >>  24) & 0xff);

							pEventData += sizeof(ULONG);
						}

						return pEventData;
					}
					else if (_wcsicmp(
									L"IPAddrV6",
									varQualifier.bstrVal) == 0)
					{
						typedef LPTSTR (WINAPI *PIPV6ADDRTOSTRING)(
							const IN6_ADDR *Addr,
							LPTSTR S
							);

						WCHAR IPv6AddressAsString[46] = {0};
						IN6_ADDR IPv6Address;
						PIPV6ADDRTOSTRING fnRtlIpv6AddressToString;

						VariantClear(&varQualifier);

						fnRtlIpv6AddressToString = (PIPV6ADDRTOSTRING)
												GetProcAddress(
															GetModuleHandle(L"ntdll"),
															"RtlIpv6AddressToStringW");

						if (NULL == fnRtlIpv6AddressToString)
						{
							wprintf(L"GetProcAddress failed with %lu.\n", GetLastError());
							return NULL;
						}

						for (ULONG i = 0; i < ArraySize; i++)
						{
							CopyMemory(
									&IPv6Address,
									pEventData,
									sizeof(IN6_ADDR));

							fnRtlIpv6AddressToString(
												&IPv6Address,
												IPv6AddressAsString);

							wprintf(L"%s\n", IPv6AddressAsString);

							pEventData += sizeof(IN6_ADDR);
						}

						return pEventData;
					}
					else if (_wcsicmp(L"Guid", varQualifier.bstrVal) == 0)
					{
						WCHAR szGuid[50] = {0};
						GUID Guid;

						VariantClear(&varQualifier);

						for (ULONG i = 0; i < ArraySize; i++)
						{
							CopyMemory(&Guid, (GUID*)pEventData, sizeof(GUID));

							StringFromGUID2(Guid, szGuid, sizeof(szGuid)-1);
							wprintf(L"%s\n", szGuid);

							pEventData += sizeof(GUID);
						}

						return pEventData;
					}
					else if (_wcsicmp(L"Sid", varQualifier.bstrVal) == 0)
					{
						// Get the user's security identifier and print the 
						// user's name and domain.

						SID* psid;
						DWORD cchUserSize = 0;
						DWORD cchDomainSize = 0;
						WCHAR* pUser = NULL;
						WCHAR* pDomain = NULL;
						SID_NAME_USE eNameUse;
						DWORD status = 0;
						ULONG temp = 0;
						USHORT CopyLength = 0;
						BYTE buffer[SECURITY_MAX_SID_SIZE];

						VariantClear(&varQualifier);

						if ( ArraySize == 1)
						{
							MofItem.mofcArray = new MOF_CHAR_ARRAY[2];
							if (MofItem.mofcArray)
							{
								MofItem.Types = CHAR_ARRAY_VALUE;
								ZeroMemory(
										MofItem.mofcArray,
										sizeof(MOF_CHAR_ARRAY)*2);

								MofItem.ArraySize = 2;
							}
						}

						for (ULONG i = 0; i < ArraySize; i++)
						{
							CopyMemory(
									&temp,
									pEventData, 
									sizeof(ULONG));

							if (temp > 0)
							{

								USHORT BytesToSid = m_PointerSize * 2;

								pEventData += BytesToSid;

								if (RemainingBytes - BytesToSid > SECURITY_MAX_SID_SIZE)
								{
									CopyLength = SECURITY_MAX_SID_SIZE;
								}
								else
								{
									CopyLength = RemainingBytes - BytesToSid;
								}

								CopyMemory(
										&buffer,
										pEventData,
										CopyLength);

								psid = (SID*)&buffer;

								LookupAccountSid(
												NULL,
												psid,
												pUser,
												&cchUserSize,
												pDomain, 
												&cchDomainSize,
												&eNameUse);

								status = GetLastError();
								if (ERROR_INSUFFICIENT_BUFFER == status)
								{
									pUser = (WCHAR*)malloc(cchUserSize * sizeof(WCHAR));
									pDomain = (WCHAR*)malloc(cchDomainSize * sizeof(WCHAR));

									if (pUser && pDomain)
									{
										if (LookupAccountSid(
															NULL,
															psid,
															pUser,
															&cchUserSize,
															pDomain,
															&cchDomainSize,
															&eNameUse))
										{

											if ( i == 0)
											{

												if ( MofItem.mofcArray )
												{
													MofItem.mofcArray[0].wValue = new WCHAR[cchDomainSize];

													if (MofItem.mofcArray[0].wValue)
													{
														StringCchCopy(
															MofItem.mofcArray[0].Name,
															50,
															_T("Domain")
																	);

														StringCchCopy(
															MofItem.mofcArray[0].wValue,
															cchDomainSize,
															pDomain
															);		
													}

													MofItem.mofcArray[1].wValue = new WCHAR[cchUserSize];

													if (MofItem.mofcArray[1].wValue)
													{
														StringCchCopy(
															MofItem.mofcArray[1].Name,
															50,
															_T("User")
															);

														StringCchCopy(
															MofItem.mofcArray[1].wValue,
															cchUserSize,
															pUser
															);

													}
												}
											}
											
										}
										else
										{
											wprintf(L"Second LookupAccountSid failed with, %d\n", GetLastError());
										}
									}
									else
									{
										wprintf(L"Allocation error.\n");
									}

									if (pUser)
									{
										free(pUser);
										pUser = NULL;
									}

									if (pDomain)
									{
										free(pDomain);
										pDomain = NULL;
									}

									cchUserSize = 0;
									cchDomainSize = 0;
								}
								else if (ERROR_NONE_MAPPED == status)
								{
									wprintf(L"Unable to locate account for the specified SID\n");
								}
								else
								{
									wprintf(L"First LookupAccountSid failed with, %d\n", status);
								}

								pEventData += SeLengthSid(psid);
							}
							else  // There is no SID
							{
								pEventData += sizeof(ULONG);
							}
						}

						return pEventData;
					}
					else
					{
						wprintf(L"Extension, %s, not supported.\n", varQualifier.bstrVal);
						VariantClear(&varQualifier);
						return NULL;
					}
				}
				else
				{
					wprintf(L"Object data type is missing Extension qualifier.\n");
					return NULL;
				}
			}

		default: 
			{
				wprintf(L"Unknown CIM type\n");
				return NULL;
			}

		} // switch
	}
}

LONG CMofDataParser::GetArraySize(
						IWbemQualifierSet* pQualifierSet)
{
	LONG ArraySize = 1;
	VARIANT varQualifier;
	HRESULT hr;
	if ( pQualifierSet )
	{
		BSTR bstrMax = SysAllocString(L"MAX");
		VariantInit(&varQualifier);

		hr = pQualifierSet->Get(bstrMax, 0, &varQualifier, 0);
		SysFreeString(bstrMax);
		if ( !hr && varQualifier.vt == 3 )
			ArraySize = varQualifier.lVal;

		VariantClear(&varQualifier);
	}

	return ArraySize;
}

LONG CMofDataParser::GetArrayValue(
	CIMTYPE CimType,
	IWbemQualifierSet * pQualifierSet)
{
	LONG RetValue = 29;
	BSTR bstrQualifier;
	VARIANT varQualifier;
	HRESULT hr;
	BOOL bPointer;
	OLECHAR szFormat[11];
	OLECHAR szStringTermination[31];
	OLECHAR szExtension[31];
	bPointer = 0;

	szFormat[0] = 0;
	szStringTermination[0] = 0;
	szExtension[0] = 0;

	if (pQualifierSet)
	{
		bstrQualifier = SysAllocString(L"Format");
		VariantInit(&varQualifier);
		hr = pQualifierSet->Get(bstrQualifier, 0, &varQualifier, 0);
		SysFreeString(bstrQualifier);

		if ( !hr && varQualifier.lVal )
			StringCchCopy(szFormat, 10, varQualifier.bstrVal);

		bstrQualifier = SysAllocString(L"StringTermination");
		VariantClear(&varQualifier);

		hr = pQualifierSet->Get(bstrQualifier, 0, &varQualifier, 0);
		SysFreeString(bstrQualifier);

		if ( !hr && varQualifier.lVal )
			StringCchCopy(szStringTermination, 30, varQualifier.bstrVal);

		bstrQualifier = SysAllocString(L"Pointer");
		VariantClear(&varQualifier);

		hr = pQualifierSet->Get(bstrQualifier, 0, &varQualifier, 0);
		SysFreeString(bstrQualifier);

		if ( hr == S_OK)
		{
			bPointer = 1;
		}

		bstrQualifier = SysAllocString(L"Extension");
		VariantClear(&varQualifier);

		hr = pQualifierSet->Get(bstrQualifier, 0, &varQualifier, 0);
		SysFreeString(bstrQualifier);

		if ( !hr && varQualifier.lVal )
			StringCchCopy(szExtension, 30, varQualifier.bstrVal);

		VariantClear(&varQualifier);

		switch ( CimType & (~CIM_FLAG_ARRAY) )
		{
		case CIM_SINT16:
			RetValue = 4;
			break;
		case CIM_SINT32:
			RetValue = 6;
			break;
		case CIM_REAL32:
			RetValue = 11;
			break;
		case CIM_REAL64:
			RetValue = 12;
			break;
		case CIM_STRING:
			{
				if ( _wcsicmp(szStringTermination, L"NullTerminated") )
				{
					if ( _wcsicmp(szStringTermination, L"Counted") )
					{
						if ( _wcsicmp(szStringTermination, L"ReverseCounted") )
							RetValue = _wcsicmp(szStringTermination, L"NotCounted") != 0 ? 13 : 23;
						else
							RetValue = 18 - (_wcsicmp(szFormat, L"w") != 0);
					}
					else
					{
						RetValue = 16 - (_wcsicmp(szFormat, L"w") != 0);
					}
				}
				else
				{
					RetValue = 14 - (_wcsicmp(szFormat, L"w") != 0);
				}
			}
			break;
		case CIM_BOOLEAN:
			RetValue = 26;
			break;
		case CIM_OBJECT:
			if ( !_wcsicmp(szExtension, L"Port") )
			{
				RetValue = 21;

			}
			else
			{
				if ( !_wcsicmp(szExtension, L"IPAddr") )
				{
					RetValue = 20;
				}
				else if ( _wcsicmp(szExtension, L"Sid") )
				{
					if ( _wcsicmp(szExtension, L"Guid") )
					{
						if ( !_wcsicmp(szExtension, L"SizeT") )
						{
							RetValue = 6;
						}
						else
						{
							if ( _wcsicmp(szExtension, L"IPAddrV6") )
							{
								if ( _wcsicmp(szExtension, L"IPAddrV4") )
								{
									if ( !_wcsicmp(szExtension, L"WmiTime") )
										RetValue = 28;
								}
								else
								{
									RetValue = 20;
								}
							}
							else
							{
								RetValue = 27;
							}
						}

					}
					else
					{
						RetValue = 25;
					}
				}
				else
				{
					RetValue = 19;
				}
			}
			break;
		case CIM_SINT8:
			RetValue = 3;
			if ( !_wcsicmp(szFormat, L"c") )
				RetValue = 0;
			break;
		case CIM_UINT8:
			RetValue = 2;
			break;
		case CIM_UINT16:
			RetValue = 5;
			break;
		case CIM_UINT32:
			RetValue = 7;
			break;
		case CIM_SINT64:
			RetValue = 9;
			break;
		case CIM_UINT64:
			RetValue = 10;
			break;
		case CIM_CHAR16:
			RetValue = 1;
			break;
		}

		if (bPointer)
		{
			RetValue = 24;
		}

	}

	return RetValue;
}


void CMofDataParser::AddProperityList(
							LIST_ENTRY* plist,
							BSTR pvData,
							LONG ValueLen,
							LONG ArraySize)
{
	LIST_ENTRY* pEntry = plist->Flink;
	
	while(pEntry != plist)
	{		
		CMofParseRes* pRes = CONTAINING_RECORD(
											pEntry,
											CMofParseRes,
											m_Entry);

		if (pRes)
		{
			MOF_PROPERTY*  pProperty = (MOF_PROPERTY*)
									malloc(sizeof(MOF_PROPERTY));

			if (pProperty)
			{
				__try
				{
					ZeroMemory(pProperty,sizeof(MOF_PROPERTY));
					pProperty->Entry.Flink = pProperty->Entry.Blink = 0;
					int nLen = 0;
					if (pvData && (nLen = lstrlen(pvData)))
					{
						pProperty->ArraySize = ArraySize;
						pProperty->Types = ValueLen;

						pProperty->Name = (BSTR)malloc((nLen+1)* sizeof(OLECHAR));

						if (pProperty->Name)
						{
							__try
							{
								StringCchCopy(
									pProperty->Name,
									nLen + 1,
									pvData);

								InsertTailList(
									&pRes->m_MofPropertyList,
									&pProperty->Entry);
							}
							__except(EXCEPTION_EXECUTE_HANDLER)
							{
								if (pProperty->Name)
								{
									free(pProperty->Name);
									pProperty->Name = NULL;
								}
							}
							
						}
						else
						{
							free(pProperty);
							pProperty = NULL;
						}
					}					


				}
				__except(EXCEPTION_EXECUTE_HANDLER)
				{
					if (pProperty)
					{
						free(pProperty);
						pProperty = NULL;
					}
				}
			}
		}

		__try
		{
			pEntry = pEntry->Flink;
		}
		__except(EXCEPTION_EXECUTE_HANDLER)
		{
			break;
		}
		
	}
}

void CMofDataParser::AddGlobalEvent(
							LIST_ENTRY* plist
							)
{

	while(!IsListEmpty(plist))
	{
		LIST_ENTRY* pEntry = plist->Flink;
		__try
		{
			CMofParseRes* pRes = CONTAINING_RECORD(
				pEntry,
				CMofParseRes,
				m_Entry);

			if (pRes)
			{
				RemoveEntryList(&pRes->m_Entry);
				InsertTailList(&m_ModDataList,&pRes->m_Entry);
			}
		}
		__except(EXCEPTION_EXECUTE_HANDLER)
		{
			break;
		}		
	}

	InitializeListHead(plist);
}

================================================
FILE: Sysmon/CMofDataParser.h
================================================
#ifndef _CMofDataParser_h
#define _CMofDataParser_h

#include "Sysmon.h"

#define MAX_CHAR_ARRAY_SIZE 20
#define TCHAR_VALUE 0x1
#define UINT32_ARRAY_VALUE 0x2
#define OTHER_VALUE 0x4
#define CHAR_ARRAY_VALUE 0x8
#include <WbemCli.h>
#include <Wmistr.h>
#include <Evntrace.h>
#include <strsafe.h>

typedef unsigned int uint32;
typedef unsigned long long uint64;

extern "C"
{
	typedef HRESULT (WINAPI * pSafeArrayDestroy)(SAFEARRAY *);
	typedef HRESULT (WINAPI * pSafeArrayGetElement)(SAFEARRAY * , LONG *, void *);
};


typedef struct _MOF_DATA_HEADER
{
	int			MofCount;
	SYSTEMTIME	MofLocal;
	BSTR		MofClassName;
	BSTR		MofTypeName;
	USHORT		MofType;
	USHORT		MofLevel;
	USHORT		MofVsersion;
	GUID		MofGuid;
}MOF_DATA_HEADER;

typedef struct _MOF_CHAR_ARRAY
{
	TCHAR Name[20];
	union
	{
		char*  cValue;
		WCHAR* wValue; 
	};

}MOF_CHAR_ARRAY;

typedef struct _MOF_ITEM
{
	TCHAR	Name[50];
	ULONG	Types;
	UINT32	ArraySize;
	union
	{
		TCHAR*			cValues;
		LARGE_INTEGER	liValue;
		UINT32*			u32ArrayValue;
		MOF_CHAR_ARRAY*	mofcArray;
	};
	
}MOF_ITEM,*PMOF_ITEM;

typedef struct _MOF_PROPERTY
{
	LIST_ENTRY	Entry;
	BSTR		Name;
	ULONG		Types;
	UINT32		ArraySize;

}MOF_PROPERTY;

class CMofParseRes
{
	friend class  CMofDataParser;
public:
	CMofParseRes()
	{
		ZeroMemory(
				this,
				sizeof(*this));

		InitializeListHead(
					&m_MofPropertyList
					);
	}

	~CMofParseRes()
	{
	}

	UINT32 GetCount()
	{
		return m_MofHeader.MofCount;
	}

	SYSTEMTIME GetTimeStmp()
	{
		return m_MofHeader.MofLocal;
	}
	
public:
	LIST_ENTRY			m_Entry;
private:
	MOF_DATA_HEADER		m_MofHeader;
	LIST_ENTRY			m_MofPropertyList;

};

typedef struct _propertyList
{
	BSTR Name;     
	LONG CimType;
	IWbemQualifierSet* pQualifiers;

} PROPERTY_LIST;

class CMofData
{
public:
	CMofData(void)
	{
		m_Mof = NULL;
		memset(
			&m_MofHead,
			0,
			sizeof(MOF_DATA_HEADER));
	}

	CMofData(const CMofData& Mof)
	{
		m_Mof = Mof.m_Mof;
	}

	CMofData(const PMOF_ITEM& Mof)
	{
		m_Mof = Mof;
	}

	~CMofData(void)
	{

	}

	
	void operator =(const PMOF_ITEM Mof)
	{
		m_Mof = Mof;
	}

	BOOL operator ==(const TCHAR* Name )
	{
		if ( m_Mof )
		{
			if (sizeof(TCHAR) >=  2 )
			{
				if ( !wcsicmp(Name,m_Mof->Name))
				{
					return TRUE;
				}
				
			}
			else
			{
				if (!stricmp(
							(char*)Name,
							(char*)m_Mof->Name))
				{
					return TRUE;
				}
			}
			
		}
		return FALSE;
	}

	UINT32 getDataInt32( UINT32 DataType ,int Index = 0)
	{
		if ( m_Mof )
		{
			if(m_Mof->Types == DataType
				 )
			{

				if (DataType == UINT32_ARRAY_VALUE)
				{
					if (m_Mof->u32ArrayValue)
					{
						return m_Mof->u32ArrayValue[Index];
					}		
				}
				else if ( DataType == CHAR_ARRAY_VALUE )
				{
					if ( m_Mof->mofcArray )
					{
						return (UINT32)&m_Mof->mofcArray[Index];
					}		
				}
				
						
			}
			
		}

		return 0;
	}

	UINT64 getDataInt64( UINT32 DataType ,int Index = 0 )
	{
		if ( m_Mof )
		{
			if(m_Mof->Types == DataType
				)
			{

				if (DataType == OTHER_VALUE)
				{					
					return m_Mof->liValue.QuadPart;						
				}
			}

		}

		return 0;
	}

	TCHAR* getWideString( UINT32 DataType ,int Index = 0 )
	{
		if ( m_Mof )
		{
			if(m_Mof->Types == DataType
				)
			{

				if (DataType == CHAR_ARRAY_VALUE )
				{
					if (m_Mof->mofcArray)
					{
						return m_Mof->mofcArray[Index].wValue;
					}		
				}
				else if ( DataType == TCHAR_VALUE )
				{
					if ( m_Mof->cValues )
					{
						return (TCHAR*)m_Mof->cValues;
					}		
				}
			}
		}

		return NULL;
	}

	char* getAnsiString( UINT32 DataType ,int Index = 0 )
	{
		if ( m_Mof )
		{
			if(m_Mof->Types == DataType
				)
			{

				if (DataType == CHAR_ARRAY_VALUE )
				{
					if (m_Mof->mofcArray)
					{
						return m_Mof->mofcArray[Index].cValue;
					}		
				}
				else if ( DataType == TCHAR_VALUE )
				{
					if ( m_Mof->cValues )
					{
						return (char*)m_Mof->cValues;
					}		
				}
			}
		}

		return NULL;
	}

	UINT32 GetProcessId()
	{
		return getDataInt32( UINT32_ARRAY_VALUE );
	}

	UINT64 GetUniqueProcessKey()
	{
		return getDataInt64( OTHER_VALUE );
	}

	char* GetProcessImageFileName()
	{
		char* ImageFileName = NULL;

		if (! (ImageFileName = getAnsiString( TCHAR_VALUE , 0 )) )
		{
			ImageFileName = getAnsiString(CHAR_ARRAY_VALUE,0);
		}

		return ImageFileName;
	}


	/************************************************************************/
	/* FileObject
	*/
	/************************************************************************/

	UINT64 GetFileObject()
	{
		return getDataInt64(OTHER_VALUE,0);
	}

	TCHAR* GetFileOpenPath()
	{
		TCHAR* OpenPath = NULL;

		if ( !(OpenPath = getWideString(
								TCHAR_VALUE,
								0)))
		{
			OpenPath = getWideString(
								CHAR_ARRAY_VALUE,
								0);
		}

		return OpenPath;
	}

private:
	MOF_DATA_HEADER m_MofHead;
	PMOF_ITEM		m_Mof;
	LIST_ENTRY		m_Entry;
};



class CMofDataParser
{
public:
	CMofDataParser(void);
	

	virtual ~CMofDataParser(void);
private:
	HRESULT Connect(
		BSTR bstrNamespace
		);
public:
	
	void SetPointSize(ULONG PointSize )
	{
		m_PointerSize = 8;
	}

	BOOL Parse(
			PEVENT_TRACE pEvent,
			CMofParseRes& Result );

private:
	IWbemServices*				m_pServices;
	ULONG						m_PointerSize;
	LIST_ENTRY					m_ModDataList;
protected:
	void GetPropertyName(
			PROPERTY_LIST* pProperty,
			TCHAR* PropertyName
			);

	PBYTE GetPropertyValue(
			PROPERTY_LIST*	pProperty,
			MOF_ITEM&		MofItem,
			PBYTE			pEventData,
			USHORT			RemainingBytes);

	IWbemClassObject* GetEventCategoryClass(
								BSTR bstrClassGuid,
								int Version);

	CMofParseRes* GetEventClassPropertyList(
								IWbemClassObject* pEventCategoryClass,
								GUID& Guid,
								USHORT Version,
								USHORT Level,
								USHORT EventType);

	void FreePropertyList(
					PROPERTY_LIST* pProperties,
					DWORD Count);

	BOOL GetPropertyList(
					IWbemClassObject* pClass, 
					PROPERTY_LIST** ppProperties,
					DWORD* pPropertyCount,
					LONG* PropertyIndex);

	LONG GetArraySize(
							IWbemQualifierSet* pQualifierSet);

	LONG GetArrayValue(
					CIMTYPE CimType,
					IWbemQualifierSet * pQualifierSet);

	void AddProperityList(
					LIST_ENTRY* Entry,
					BSTR pvData,
					LONG ValueLen,
					LONG ArraySize);

	void AddGlobalEvent(
					LIST_ENTRY* Entry);

public:
	CMofDataParser* Instance();
};

class FileCreateNameX86
{

public:
	FileCreateNameX86(void)
	{

	}

	~FileCreateNameX86()
	{

	}

	UINT32 FileObject;
	TCHAR FileName[1];
};

class CPropertyRes;


class CPropertyRes
{
	friend class CPropertyData;
public:
	CPropertyRes(void)
	{
		ZeroMemory(this,sizeof(*this));
	}

	CPropertyRes(const CPropertyRes& Res)
	{
		ZeroMemory(this,sizeof(*this));

		if (Res.mData_ && Res.mLen_)
		{
			mData_ = new BYTE[Res.mLen_ + 1];

			if ( mData_ )
			{
				CopyMemory(
					mData_,
					Res.mData_,
					Res.mLen_);

				mLen_ = Res.mLen_;
			}

			CopyMemory(
				mName,
				Res.mName,
				50);
		}	
		
	}

	~CPropertyRes(void)
	{
		if (mData_)
		{
			delete[] (char*)mData_;
			mData_ = NULL;
		}

		mLen_ = NULL;

		ZeroMemory(this,sizeof(*this));
	}

	void Init()
	{
		mData_ = NULL;
		mLen_ = 0;
	}

	TCHAR* GetFileName()
	{
		return (TCHAR*)mData_;
	}

	char* GetProcessName()
	{
		return (char*)mData_;
	}

	TCHAR* GetQueryDomainName()
	{
		return (TCHAR*)mData_;
	}

	TCHAR* GetQueryResult()
	{
		return (TCHAR*)mData_;
	}

	ULONGLONG GetFileObject()
	{
		if ( mData_ )
		{
			return *((ULONGLONG*)mData_);
		}

		return 0;
	}

	ULONG GetProcessId()
	{
		if ( mData_ )
		{
			return *((ULONG*)mData_);
		}

		return -1;
	}

	WORD GetPort()
	{
		if ( mData_ )
		{
			return *((WORD*)mData_);
		}

		return -1;
	}

	ULONG GetQueryStatus()
	{
		if ( mData_ )
		{
			return *((ULONG*)mData_);
		}

		return -1;
	}

	ULONG GetIpAddress()
	{
		if ( mData_ )
		{
			return *((ULONG*)mData_);
		}

		return -1;
	}

	ULONG GetIoSize()
	{
		if ( mData_ )
		{
			return *((ULONG*)mData_);
		}

		return 0;
	}

	BOOL operator == ( TCHAR* StrName)
	{
		if (!wcsicmp(StrName,mName))
		{
			return TRUE;
		}

		return FALSE;
	}

private:
	TCHAR mName[50];
	PBYTE mData_;
	int   mLen_;

};

#define PARSE_TYPE_FILE 1
#define PARSE_TYPE_OTHER 2

static CPropertyRes Res;

#endif

================================================
FILE: Sysmon/CSsymonEtw.cpp
================================================
#include "StdAfx.h"
#include "CSsymonEtw.h"
#include "CSysmonUtil.h"
#include <winsock2.h>
#include <strsafe.h>
#include <process.h>



#pragma comment(lib,"Ws2_32.lib")

#define EVENT_TRACE_SYSTEM_LOGGER_MODE 0x2000000

CSsymonEtw* CSsymonEtw::_Instace = NULL;

CSsymonEtw::CSsymonEtw(void)
{
	m_pStartTrace = NULL;
	m_pControlTrace = NULL;
	m_pOpenTrace = NULL;
	m_pProcessTrace = NULL;
	m_SessionHandle = NULL;
	m_hEtwTraceThread =0;
	m_bInit = FALSE;
	m_hGlobalEvent = CreateEvent(0, TRUE, 0, 0);
	m_bStartTrace = FALSE;
	m_bInitData = FALSE;
	m_EventClassNums = 0;

	GetSystemTimeAsFileTime(&m_SystemTime);
	QueryPerformanceCounter(&m_PerformanceCount);
	QueryPerformanceFrequency(&m_Frequency);
}


CSsymonEtw::~CSsymonEtw(void)
{
}


ULONG CSsymonEtw::InitData()
{
	FILETIME SystemTimeAsFileTime;

	if ( CSsymonEtw::m_bInitData )
	{
		//sub_4144E0(1);
	}
	else
	{
		InitializeCriticalSection(&m_csData);
		CSsymonEtw::m_bInitData = 1;
	}

	GetSystemTimeAsFileTime(&SystemTimeAsFileTime);
	m_SystemTime = SystemTimeAsFileTime;
	return SystemTimeAsFileTime.dwHighDateTime;
}

void CSsymonEtw::Enter()
{
	EnterCriticalSection(&m_csData);
}

void CSsymonEtw::Leave()
{
	LeaveCriticalSection(&m_csData);
}

HRESULT CSsymonEtw::StartTrace(BOOL bStart)
{
	WSAData Wsa = {0};
	BOOL IsThanXp = FALSE;
	DWORD dwVerison = GetVersion();
	DWORD dwMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVerison)));
	DWORD dwMinorVersion = (DWORD)(HIBYTE(LOWORD(dwVerison)));
	DWORD FileMode = 0;
	UINT ThreadId;
	HRESULT bFail;

	if (m_bInit == FALSE)
	{
		HMODULE hAdv = LoadLibraryW(L"advapi32.dll");
		m_pStartTrace = (pStartTrace)GetProcAddress(hAdv, "StartTraceW");
		m_pControlTrace = (pControlTrace)GetProcAddress(hAdv, "ControlTraceW");
		m_pOpenTrace = (pOpenTrace)GetProcAddress(hAdv, "OpenTraceW");
		m_pProcessTrace = (pProcessTrace)GetProcAddress(hAdv, "ProcessTrace");
		int ret = WSAStartup(
						MAKEWORD(2,2),
						&Wsa);
		if ( ret )
			return ret;

		m_bInit = TRUE;
	}

	if (!m_pStartTrace)
	{
		return 1;
	}

	if (m_bStartTrace == bStart)
	{
		return 0;
	}

	if (dwMajorVersion >= 6 )
	{
		if(dwMinorVersion >= 2)
		{
			IsThanXp = TRUE;
		}
	}
		
	Sysomn_Event_Properties SysmonEvent = {0};
	SysmonEvent.Properties.Wnode.BufferSize = sizeof(Sysomn_Event_Properties);
	SysmonEvent.Properties.Wnode.Flags = WNODE_FLAG_TRACED_GUID ;
	SysmonEvent.Properties.Wnode.ClientContext = 1;
	SysmonEvent.Properties.FlushTimer = 1;
	SysmonEvent.Properties.LoggerNameOffset = sizeof(EVENT_TRACE_PROPERTIES);
	SysmonEvent.Properties.LogFileNameOffset = sizeof(EVENT_TRACE_PROPERTIES) +
											MAX_PATH*sizeof(TCHAR);


	FileMode = 0;
	if (IsThanXp)
	{
		FileMode = EVENT_TRACE_SYSTEM_LOGGER_MODE;
	}

	SysmonEvent.Properties.LogFileMode = FileMode | 
								EVENT_TRACE_REAL_TIME_MODE;

	if ( dwMajorVersion < 6 || dwMinorVersion < 2)
	{
		SysmonEvent.Properties.Wnode.Guid = SystemTraceControlGuid;
	}

	LPCTSTR pLogName = _T("SYSMON TRACE");

	if (!IsThanXp)
	{
		pLogName = _T("NT Kernel Logger");
	}


	StringCchCopy(SysmonEvent.LoggerName,MAX_PATH,pLogName );

	if (CSysmonUtil::SysmonVersionIsSupport())
	{
		SysmonEvent.Properties.EnableFlags = EVENT_TRACE_FLAG_EXTENSION;
		SysmonEvent.Properties.EnableFlags |= 0x00FF0000;
		SysmonEvent.Properties.EnableFlags |=
								(EVENT_TRACE_FLAG_DISK_IO_INIT |
			                      EVENT_TRACE_FLAG_SYSTEMCALL |
								  EVENT_TRACE_FLAG_PROCESS_COUNTERS);
 		SysmonEvent.dwMax2 = 0x10009;
 		SysmonEvent.dwMax1 = 0x1000A;
 		SysmonEvent.dwMax3 = 0x10000;
	}
	else
	{
		SysmonEvent.Properties.EnableFlags |= EVENT_TRACE_FLAG_NETWORK_TCPIP; 
	}

	if (bStart)
	{
		InitData();

		ULONG bSuccess = m_pStartTrace(
											&m_SessionHandle,
											SysmonEvent.LoggerName,
											&SysmonEvent.Properties);

		if ( bSuccess && bSuccess != ERROR_ALREADY_EXISTS)
		{
			//sub_418280(&Text, L"Network trace initialization failed: Error %d", v11);
			//MessageBoxW(0, &Text, L"System Monitor", 0x10u);
			bFail = bSuccess;
		}
		else
		{
			m_hEtwTraceThread = (HANDLE)
										_beginthreadex(
													0,
													0,
													CSsymonEtw::ProcessTraceThread,
													0,
													0,
													&ThreadId);
			m_bStartTrace = bStart;
			bFail = 0;
		}
	}
	else
	{
		SetEvent(m_hGlobalEvent);
		bFail = m_pControlTrace(
									m_SessionHandle,
									SysmonEvent.LoggerName, 
									&SysmonEvent.Properties,
									EVENT_TRACE_CONTROL_STOP);

		WaitForSingleObject(m_hEtwTraceThread, INFINITE);
		CloseHandle(m_hEtwTraceThread);
		m_hEtwTraceThread = 0;
		ResetEvent(m_hGlobalEvent);

		if ( !bFail )
		{
			m_bStartTrace = 0;
			//sub_414630();
		}
	}

	return bFail;
}

void* CSsymonEtw::GetEventClassPropertyListList(PEVENT_TRACE pEventTrace)
{

	if (!m_EventClassNums)
	{
		//EventTraceGuid

		m_EventClassNums++;
	}

	if (pEventTrace)
	{

	}

	return 0;
}

UINT CSsymonEtw::ProcessTraceThread(void* lp)
{
	BOOL IsThanXp = FALSE;
	BOOL IsStop = FALSE;
	DWORD dwVerison = GetVersion();
	DWORD dwMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVerison)));
	DWORD dwMinorVersion = (DWORD)(HIBYTE(LOWORD(dwVerison)));

	if (dwMajorVersion >= 6 )
	{
		if(dwMinorVersion >= 2)
		{
			IsThanXp = TRUE;
		}
	}

	EVENT_TRACE_LOGFILE SysmonEvent = {0};
	SysmonEvent.LoggerName = NULL;
	SysmonEvent.Context = 0;
	SysmonEvent.BufferCallback = CSsymonEtw::BufferCallback;
	SysmonEvent.BuffersRead = 0;
	

	LPCTSTR pLogName = _T("SYSMON TRACE");

	if (!IsThanXp)
	{
		pLogName = _T("NT Kernel Logger");
	}

	SysmonEvent.LoggerName = (LPWSTR)pLogName;
	SysmonEvent.CurrentTime = 0;
	SysmonEvent.EventCallback = CSsymonEtw::EventCallback;
	SysmonEvent.LogFileMode = EVENT_TRACE_REAL_TIME_MODE |
							EVENT_TRACE_ADD_HEADER_MODE;

	TRACEHANDLE hOpenTrace = CSsymonEtw::Instance()->m_pOpenTrace(&SysmonEvent);

	if (!hOpenTrace)
	{
		return -1;
	}

	UINT ThreadId = 0;
	HANDLE hDataThread = (void *)_beginthreadex(
												0,
												0,
												ProcessDataThread, 
												0,
												0,
												&ThreadId);

	 ULONG bSuccess = CSsymonEtw::Instance()->m_pProcessTrace(
												&hOpenTrace,
												1,
												0,
												0);

	 if ( WaitForSingleObject(
						CSsymonEtw::Instance()->m_hGlobalEvent,
						0) == STATUS_TIMEOUT )
	 {
		 IsStop = 1;
		 SetEvent(CSsymonEtw::Instance()->m_hGlobalEvent);
	 }

	 WaitForSingleObject(hDataThread, INFINITE);
	 CloseHandle(hDataThread);

	 if ( IsStop )
	 {
		 CloseHandle(CSsymonEtw::Instance()->m_hEtwTraceThread);
		 CSsymonEtw::Instance()->m_hEtwTraceThread = 0;
		 ResetEvent(CSsymonEtw::Instance()->m_hGlobalEvent);

		 CSsymonEtw::Instance()->m_bStartTrace = 0;

		 //sub_414630();

// 		 if ( sub_407C70() & 1 )
 			 CSsymonEtw::Instance()->StartTrace(1);
	 }

	return 0;
}


ULONG 
CSsymonEtw::BufferCallback(
	PEVENT_TRACE_LOGFILE Buffer
	)
{
	return 0;
}

#include "CMofDataParser.h"
VOID
CSsymonEtw::EventCallback(
	PEVENT_TRACE pEvent
	)
{
	if (pEvent)
	{
		//CMofParseRes Result;
		//CSsymonEtw::Instance()->m_MofDataParser.Parse(pEvent,Result);
		
		return;

 		CSysmonDataEntry* pDataEntry = CSsymonEtw::Instance()->m_SysmonMofData.Phase_1(
 															&pEvent->Header.Guid,
 															pEvent->Header.Class.Version,															
 															pEvent->Header.Class.Level,
 															pEvent->Header.Class.Type);
 
 		if (pDataEntry)
 		{
 			CSsymonEtw::Instance()->Enter();
 			CSsymonEtw::Instance()->m_SysmonMofData.Phase_2(pEvent,pDataEntry);
 			CSsymonEtw::Instance()->Leave();
 		}
	}
	
}


UINT
CSsymonEtw::ProcessDataThread(void* lp)
{
	LARGE_INTEGER PerformanceCount;

	while ( WaitForSingleObject(
					CSsymonEtw::Instance()->m_hGlobalEvent, 
					250) == STATUS_TIMEOUT )
	{
		CSsymonEtw::Instance()->Enter();

		QueryPerformanceCounter(&PerformanceCount);
		ULONG LowPart = PerformanceCount.LowPart - 
			CSsymonEtw::Instance()->m_PerformanceCount.LowPart;

		ULONG HighPart = (PerformanceCount.HighPart -
				CSsymonEtw::Instance()->m_PerformanceCount.HighPart);

		ULONGLONG QuadPart = PerformanceCount.QuadPart - 
			CSsymonEtw::Instance()->m_PerformanceCount.QuadPart;

		ULONGLONG Frequency = 0;
		LARGE_INTEGER ft2 = {0};
		LARGE_INTEGER lg2 = {0};
		LARGE_INTEGER lg3 = {0};

		if ( HighPart >= 0 )
		{
			lg2.QuadPart = ((10000000 * (QuadPart % CSsymonEtw::Instance()->m_Frequency.QuadPart)) / 
				CSsymonEtw::Instance()->m_Frequency.QuadPart +
					10000000 * (QuadPart / CSsymonEtw::Instance()->m_Frequency.QuadPart));

			ft2.LowPart = lg2.LowPart;
		}
		else
		{
			

			lg2.QuadPart = CSysmonUtil::CounterTimes(
													CSsymonEtw::Instance()->m_SystemTime,
													-HighPart);

			ft2.LowPart = lg2.LowPart;
		}

		ft2.HighPart = CSsymonEtw::Instance()->m_SystemTime.dwHighDateTime;
		lg3.LowPart += CSsymonEtw::Instance()->m_SystemTime.dwLowDateTime;
		lg2.LowPart = CSsymonEtw::Instance()->m_SystemTime.dwLowDateTime;

		ft2.HighPart = (ft2.QuadPart + lg2.QuadPart) >> 32;

		CSsymonEtw::Instance()->Leave();
	}

	return 0;
}

================================================
FILE: Sysmon/CSsymonEtw.h
================================================
#ifndef _CSsymonEtw_h
#define _CSsymonEtw_h

#include "CMofDataParser.h"
#include "CSysmonMofData.h"
#include <wmistr.h>
#include <Evntrace.h>

typedef void* HEVENT;

#ifdef __cplusplus
extern "C"{
#endif

typedef
ULONG
(WINAPI
*pStartTrace)(
	 PTRACEHANDLE            SessionHandle,
	 LPCTSTR                 SessionName,
	 PEVENT_TRACE_PROPERTIES Properties
	);

typedef
ULONG
(WINAPI
*pControlTrace)
(
	TRACEHANDLE             SessionHandle,
	LPCTSTR                 SessionName,
	PEVENT_TRACE_PROPERTIES Properties,
	ULONG                   ControlCode
);

typedef
TRACEHANDLE
(WINAPI
*pOpenTrace)
(
	PEVENT_TRACE_LOGFILE Logfile
);

typedef
ULONG
(WINAPI
*pProcessTrace)(
	_In_ PTRACEHANDLE HandleArray,
	_In_ ULONG        HandleCount,
	_In_ LPFILETIME   StartTime,
	_In_ LPFILETIME   EndTime
	);

#ifdef __cplusplus
};
#endif

typedef struct _Sysomn_Event_Properties
{
	EVENT_TRACE_PROPERTIES  Properties;
	TCHAR				    LoggerName[MAX_PATH];
	TCHAR					LoggerFile[MAX_PATH];
	ULONG					dwMax1;
	ULONG					dwMax2;
	ULONG					dwMax3;
	ULONG					dwMax4;
	ULONG					dwMax5;
	ULONG					dwMax6;
	ULONG					dwMax7;
	ULONG					dwMax8;
	ULONG					dwMax9;
	ULONG					dwMax10;
}Sysomn_Event_Properties;

class CSsymonEtw
{
public:
	CSsymonEtw(void);
	virtual ~CSsymonEtw(void);

public:
	HRESULT StartTrace(BOOL bStart);
	ULONG   InitData();

	void* GetEventClassPropertyListList(PEVENT_TRACE pEventTrace);
	void Enter();
	void Leave();
public:
	pStartTrace m_pStartTrace;
	pControlTrace m_pControlTrace;
	pOpenTrace m_pOpenTrace;
	pProcessTrace m_pProcessTrace;

	BOOL				m_bInit;
	BOOL				m_bStartTrace;
	TRACEHANDLE			m_SessionHandle;
	HANDLE				m_hEtwTraceThread;
	HEVENT				m_hGlobalEvent;

	BOOL				m_bInitData;
	CRITICAL_SECTION	m_csData;
	FILETIME			m_SystemTime;

	LARGE_INTEGER		m_PerformanceCount;
	LARGE_INTEGER		m_Frequency;

	UINT64				m_EventClassNums;

	CSysmonMofData		m_SysmonMofData;
	
	CMofDataParser		m_MofDataParser;
private:
	static 
	UINT
	WINAPI
	ProcessTraceThread(void* lp);

	static
	UINT
	WINAPI
	ProcessDataThread(void* lp);

	static
	ULONG
	WINAPI 
	BufferCallback(
		PEVENT_TRACE_LOGFILE Buffer
		);

	static
	VOID
	WINAPI
	EventCallback(
		PEVENT_TRACE pEvent
		);

public:
	static CSsymonEtw* Instance()
	{
		if (!_Instace)
		{
			_Instace = new CSsymonEtw();
		}

		return _Instace;
	}

	static CSsymonEtw* _Instace;
};

#endif

================================================
FILE: Sysmon/CSysmonDriverOpt.cpp
================================================
#include "StdAfx.h"
#include "CSysmonDriverOpt.h"


CSysmonDriverOpt::CSysmonDriverOpt(void)
{
}


CSysmonDriverOpt::~CSysmonDriverOpt(void)
{
}


//======================================== ̬/жsys ======================================
// SYSļͬĿ¼
// SYSΪHelloDDK.sys,ôװInstallDriver("HelloDDK",".\\HelloDDK.sys","370030"/*Altitude*/);
//  StartDriver("HelloDDK");
// ֹͣ StopDriver("HelloDDK");
// жSYSҲƵĵụ̀ DeleteDriver("HelloDDK");
//====================================================================================================

BOOL CSysmonDriverOpt::InstallDriver(
							LPCTSTR lpszDriverName,
							LPCTSTR lpszDriverPath,
							LPCTSTR lpszAltitude)
{
	TCHAR   szTempStr[MAX_PATH];
	HKEY    hKey;
	DWORD    dwData;
	TCHAR    szDriverImagePath[MAX_PATH];    

	if( NULL == lpszDriverName || NULL == lpszDriverPath )
	{
		return FALSE;
	}

	//õ·
	GetFullPathName(
			lpszDriverPath,
			MAX_PATH,
			szDriverImagePath,
			NULL);

	SC_HANDLE hServiceMgr = NULL;
	SC_HANDLE hService = NULL;

	//򿪷ƹ
	hServiceMgr = OpenSCManager( 
							NULL,
							NULL, 
							SC_MANAGER_ALL_ACCESS );

	if( hServiceMgr == NULL ) 
	{
		CloseServiceHandle(hServiceMgr);
		return FALSE;        
	}

	//Ӧķ
	hService = CreateService( hServiceMgr,
		lpszDriverName,             // עе
		lpszDriverName,             // עDisplayName ֵ
		SERVICE_ALL_ACCESS,         // ķȨ
		SERVICE_FILE_SYSTEM_DRIVER, // ʾصķļϵͳ
		SERVICE_DEMAND_START,       // עStart ֵ
		SERVICE_ERROR_IGNORE,       // עErrorControl ֵ
		szDriverImagePath,          // עImagePath ֵ
		_T("FSFilter Activity Monitor"),// עGroup ֵ
		NULL, 
		_T("FltMgr"),                   // עDependOnService ֵ
		NULL, 
		NULL);

	if( hService == NULL ) 
	{        
		if( GetLastError() == ERROR_SERVICE_EXISTS ) 
		{
			//񴴽ʧܣڷѾ
			CloseServiceHandle(hService);       // 
			CloseServiceHandle(hServiceMgr);    // SCM
			return TRUE; 
		}
		else 
		{
			CloseServiceHandle(hService);       // 
			CloseServiceHandle(hServiceMgr);    // SCM
			return FALSE;
		}
	}
	CloseServiceHandle(hService);       // 
	CloseServiceHandle(hServiceMgr);    // SCM

	//-------------------------------------------------------------------------------------------------------
	// SYSTEM\\CurrentControlSet\\Services\\DriverName\\Instancesӽµļֵ 
	//-------------------------------------------------------------------------------------------------------
	lstrcpy(szTempStr,_T("SYSTEM\\CurrentControlSet\\Services\\"));
	lstrcat(szTempStr,lpszDriverName);
	lstrcat(szTempStr,_T("\\Instances"));
	if(RegCreateKeyEx(
				HKEY_LOCAL_MACHINE,
				szTempStr,
				0,
				_T(""),
				TRUE,
				KEY_ALL_ACCESS,
				NULL,
				&hKey,
				(LPDWORD)&dwData)!=ERROR_SUCCESS)
	{
		return FALSE;
	}

	// עDefaultInstance ֵ 
	lstrcpy(szTempStr,lpszDriverName);
	lstrcat(szTempStr,_T("Instance"));
	if(RegSetValueEx(
					hKey,
					_T("DefaultInstance"),
					0,
					REG_SZ,
					(CONST BYTE*)
					szTempStr,
					(DWORD)lstrlen(szTempStr)*sizeof(TCHAR))!=ERROR_SUCCESS)
	{
		return FALSE;
	}

	RegFlushKey(hKey);//ˢע
	RegCloseKey(hKey);
	//-------------------------------------------------------------------------------------------------------

	//-------------------------------------------------------------------------------------------------------
	// SYSTEM\\CurrentControlSet\\Services\\DriverName\\Instances\\DriverName Instanceӽµļֵ 
	//-------------------------------------------------------------------------------------------------------
	lstrcpy(szTempStr,_T("SYSTEM\\CurrentControlSet\\Services\\"));
	lstrcat(szTempStr,lpszDriverName);
	lstrcat(szTempStr,_T("\\Instances\\"));
	lstrcat(szTempStr,lpszDriverName);
	lstrcat(szTempStr,_T("Instance"));

	if(RegCreateKeyEx(
			HKEY_LOCAL_MACHINE,
			szTempStr,
			0,
			_T(""),
			TRUE,
			KEY_ALL_ACCESS,
			NULL,
			&hKey,
			(LPDWORD)&dwData)!=ERROR_SUCCESS)
	{
		return FALSE;
	}

	// עAltitude ֵ
	lstrcpy(szTempStr,lpszAltitude);
	if(RegSetValueEx(
				hKey,
				_T("Altitude"),
				0,
				REG_SZ,
				(CONST BYTE*)szTempStr,
				(DWORD)
				lstrlen(szTempStr)*sizeof(TCHAR))!=ERROR_SUCCESS)
	{
		return FALSE;
	}

	// עFlags ֵ
	dwData = 0x0;
	if(RegSetValueEx(
					hKey,
					_T("Flags"),
					0,
					REG_DWORD,
					(CONST BYTE*)&dwData,
					sizeof(DWORD))!=ERROR_SUCCESS)
	{
		return FALSE;
	}

	RegFlushKey(hKey);//ˢע
	RegCloseKey(hKey);
	//-------------------------------------------------------------------------------------------------------

	return TRUE;
}

BOOL CSysmonDriverOpt::StartDriver(LPCTSTR lpszDriverName)
{
	SC_HANDLE        schManager;
	SC_HANDLE        schService;
	SERVICE_STATUS    svcStatus;

	if( NULL == lpszDriverName)
	{
		return FALSE;
	}

	schManager = OpenSCManager(
							NULL,
							NULL,
							SC_MANAGER_ALL_ACCESS);

	if(NULL == schManager)
	{
		CloseServiceHandle(schManager);
		return FALSE;
	}

	schService = OpenService(
					schManager,
					lpszDriverName,
					SERVICE_ALL_ACCESS);

	if(NULL == schService)
	{
		CloseServiceHandle(schService);
		CloseServiceHandle(schManager);
		return FALSE;
	}

	if(!StartService(
			schService,
			0,
			NULL))
	{
		CloseServiceHandle(schService);
		CloseServiceHandle(schManager);

		DWORD dwError = GetLastError();
		if( dwError == ERROR_SERVICE_ALREADY_RUNNING ) 
		{             
			return TRUE;
		}

		TCHAR szError[50];
		wsprintf(szError,_T("%d"),dwError);
		MessageBox(NULL,szError,szError,MB_OK);

		return FALSE;
	}

	CloseServiceHandle(schService);
	CloseServiceHandle(schManager);

	return TRUE;
}

BOOL CSysmonDriverOpt::StopDriver(LPCTSTR lpszDriverName)
{
	SC_HANDLE        schManager;
	SC_HANDLE        schService;
	SERVICE_STATUS    svcStatus;
	bool            bStopped=false;

	schManager = OpenSCManager(
							NULL,
							NULL,
							SC_MANAGER_ALL_ACCESS);
	if(NULL == schManager)
	{
		return FALSE;
	}

	schService = OpenService(
						schManager,
						lpszDriverName,
						SERVICE_ALL_ACCESS);
	if(NULL == schService)
	{
		CloseServiceHandle(schManager);
		return FALSE;
	}

	if(!ControlService(
					schService,
					SERVICE_CONTROL_STOP,
					&svcStatus) &&
					(svcStatus.dwCurrentState != SERVICE_STOPPED))
	{
		CloseServiceHandle(schService);
		CloseServiceHandle(schManager);
		return FALSE;
	}

	CloseServiceHandle(schService);
	CloseServiceHandle(schManager);

	return TRUE;
}

BOOL CSysmonDriverOpt::DeleteDriver(LPCTSTR lpszDriverName)
{
	SC_HANDLE        schManager;
	SC_HANDLE        schService;
	SERVICE_STATUS    svcStatus;

	schManager = OpenSCManager(
							NULL,
							NULL,
							SC_MANAGER_ALL_ACCESS);
	if(NULL == schManager)
	{
		return FALSE;
	}

	schService = OpenService(
						schManager,
						lpszDriverName,
						SERVICE_ALL_ACCESS);

	if(NULL == schService)
	{
		CloseServiceHandle(schManager);
		return FALSE;
	}

	ControlService(
				schService,
				SERVICE_CONTROL_STOP,
				&svcStatus);

	if(!DeleteService(schService))
	{
		CloseServiceHandle(schService);
		CloseServiceHandle(schManager);
		return FALSE;
	}

	CloseServiceHandle(schService);
	CloseServiceHandle(schManager);

	return TRUE;
}


================================================
FILE: Sysmon/CSysmonDriverOpt.h
================================================
#ifndef _CSysmonDriverOpt_h
#define _CSysmonDriverOpt_h

class CSysmonDriverOpt
{
public:
	CSysmonDriverOpt(void);
	virtual ~CSysmonDriverOpt(void);
public:
	BOOL InstallDriver(
					LPCTSTR lpszDriverName,
					LPCTSTR lpszDriverPath,
					LPCTSTR lpszAltitude); 

	BOOL StartDriver(LPCTSTR lpszDriverName);

	BOOL StopDriver(LPCTSTR lpszDriverName);

	BOOL DeleteDriver(LPCTSTR lpszDriverName);
};

#endif

================================================
FILE: Sysmon/CSysmonMofData.cpp
================================================
#include "StdAfx.h"
#include "CSysmonMofData.h"
#include "CSsymonEtw.h"
#include "CSysmonUtil.h"
#include "Sysmon.h"

#define MAX_MOF_DATA_LIST 357913940

CTcpIpInfo CSysmonMofData::m_TcpIpEventTypeName[25]  = {
	{_T("Send"),2},
	{_T("SendIPV4"),2},
	{_T("SendIPV6"),2},
	{_T("Recv"),3},
	{_T("RecvIPV4"),3},
	{_T("RecvIPV6"),3},
	{_T("Accept"),4},
	{_T("AcceptIPV4"),4},
	{_T("AcceptIPV6"),4},
	{_T("Connect"),5},
	{_T("ConnectIPV4"),5},
	{_T("ConnectIPV6"),5},
	{_T("Disconnect"),6},
	{_T("DisconnectIPV4"),6},
	{_T("DisconnectIPV6"),6},
	{_T("Reconnect"),7},
	{_T("ReconnectIPV4"),7},
	{_T("ReconnectIPV6"),7},
	{_T("Retransmit"),8},
	{_T("RetransmitIPV4"),8},
	{_T("RetransmitIPV6"),8},
	{_T("TCPCopy"),9},
	{_T("TCPCopyIPV4"),9},
	{_T("TCPCopyIPV6"),9}
};

CSysmonMofData::CSysmonMofData(void)
	:m_pIWbemService(NULL)
	,m_EventListNums(0)
{
	m_SysmonEventList = new CSysmonEventList(0,0);
}


CSysmonMofData::~CSysmonMofData(void)
{
	if (m_SysmonEventList)
	{
		delete m_SysmonEventList;
		m_SysmonEventList = NULL;
	}
}

HRESULT CSysmonMofData::CoCreateInstance()
{
	OLECHAR *pwWdmi;
	HRESULT hr;
	IWbemLocator *pLocator;
	
	pLocator = 0;
	pwWdmi = SysAllocString(L"root\\wmi");
	CoInitializeEx(0, 0);
	hr = ::CoCreateInstance(
							__uuidof(WbemLocator),
							0,
							CLSCTX_INPROC_SERVER,
							__uuidof(IWbemLocator),
							(LPVOID *)&pLocator);
	if ( SUCCEEDED(hr) )
	{
		hr = pLocator->ConnectServer(
								pwWdmi,
								NULL,
								NULL, 
								NULL,
								0L,
								NULL,
								NULL,
								&m_pIWbemService);

		if ( SUCCEEDED(hr) )
			hr = CoSetProxyBlanket(
								m_pIWbemService, 
								RPC_C_AUTHN_WINNT,
								RPC_C_AUTHZ_NONE,
								0,
								RPC_C_AUTHN_LEVEL_PKT,
								RPC_C_IMP_LEVEL_IMPERSONATE,
								0,
								EOAC_NONE);
	}

	SysFreeString(pwWdmi);
	if ( pLocator )
		pLocator->Release();

	return hr;
}

CSysmonDataEntry* CSysmonMofData::Phase_1(
	GUID* ClassGuid,
	USHORT Version,
	USHORT Level,
	USHORT Type)
{
	CSysmonDataEntry* pDataEntry = NULL;
	LONG nIndex = 0;
	do 
	{

		if ( !m_EventListNums )
		{
			CSysmonDataEntry* pDataEntry_1 = new CSysmonDataEntry(
				(GUID*)&EventTraceGuid,
				-1,
				0,
				0);

			if ( pDataEntry_1 )
			{
				pDataEntry_1->InitData(&pDataEntry_1->m_EventClassName, L"EventTrace");
				pDataEntry_1->InitData(&pDataEntry_1->m_EventTypeName, L"Header");

				CSysmonEventList* pEventList = m_SysmonEventList->InsertBack(
					m_SysmonEventList->m_Entry.Blink,
					pDataEntry_1);

				if ( (unsigned int)(MAX_MOF_DATA_LIST - m_EventListNums) < 1 )
				{
					//std::_Xlength_error("list<T> too long");
				}

				++m_EventListNums;

				m_SysmonEventList->m_Entry.Blink = &pEventList->m_Entry;
				pEventList->m_Entry.Blink->Flink = &pEventList->m_Entry;
			}
		}

		if ( !IsListEmpty(&m_SysmonEventList->m_Entry) )
		{
			LIST_ENTRY* pEntry = m_SysmonEventList->m_Entry.Flink;
			CSysmonDataEntry* pTem_2 = NULL;
			CSysmonDataEntry* pTem_3 = NULL;
			while(TRUE)
			{
				CSysmonEventList* pList = CONTAINING_RECORD(pEntry,CSysmonEventList,m_Entry);
				CSysmonDataEntry* pTemp = (CSysmonDataEntry*)pList->m_pEvent;
				
				int TotleSize = 12;

				if (pTemp)
				{
					LONG* p1 = (LONG*)&(pTemp->m_EventGuid);
					LONG* p2 = (LONG*)ClassGuid;

					while( *p1 == *p2)
					{
						p1++;
						p2++;

						BOOL bExit = TotleSize < 4;						
						TotleSize -= 4;

						if (bExit)
						{
							if ( pTemp->m_EventType == Type &&
								pTemp->m_EventVersion == Version)
							{

								pDataEntry = pTemp;
								return pDataEntry;
							}

							if (pTemp->m_EventType == 0x0FFFF )
							{
								if (!pTem_2)
								{
									pTem_2 = pTemp;
								}
							}

							break;
						}						
					}
				}

				pEntry = pEntry->Flink;

				if (pEntry != &m_SysmonEventList->m_Entry)
				{
					continue;
				}

				break;
			}
		}

		if (!pDataEntry)
		{
			pDataEntry = GetEventCategoryClass(ClassGuid,Version,Level,Type);

			if (!pDataEntry)
			{
				pDataEntry = new CSysmonDataEntry(
											ClassGuid,
											Type,
											Version,
											Level);

				if ( pDataEntry )
				{
					pDataEntry->m_EventClassName = NULL;
					pDataEntry->m_EventTypeName = NULL;

					pDataEntry->m_ProperityList = 0;
					pDataEntry->m_ProperitySize = 0;
						
				}
			}
		}
		
	} while (FALSE);
	

	return pDataEntry;
}

void 
CSysmonMofData::Phase_2(
	PEVENT_TRACE pEvent,
	CSysmonDataEntry* pDataEntry
	)
{
	LARGE_INTEGER SystemTime;
	LARGE_INTEGER SystemTime_2;

	__try
	{
		if (pEvent && pDataEntry)
		{
			if (pEvent->MofData && 
				pEvent->MofLength)
			{
				CSysmonData* pEventClass = pDataEntry->m_EventClassName;
				ULONG dwClassType = 0;

				if (pEventClass && pEventClass->Compare(_T("TcpIp")))
				{
					dwClassType = 1;
				}
				else if (pEventClass && pEventClass->Compare(_T("UdpIp")))
				{
					dwClassType = 2;
				}
				else if (pEventClass && pEventClass->Compare(_T("MSNT_TcpIpInformation")))
				{
					dwClassType = 3;
				}

				if ( dwClassType == 1 ||
					dwClassType == 2 ||
					dwClassType == 3 )
				{
					BOOL v15 = (pEvent->Header.TimeStamp.HighPart == 0x1000000);
					BOOL v16 = (pEvent->Header.TimeStamp.HighPart > 0x1000000);

					if (pEvent->Header.TimeStamp.HighPart < 0x1000000 ||
						pEvent->Header.TimeStamp.LowPart < 0 )
					{
						SystemTime.QuadPart = CSysmonUtil::CounterTimes(
							CSsymonEtw::Instance()->m_SystemTime,
							pEvent->Header.TimeStamp.QuadPart - 
							CSsymonEtw::Instance()->m_PerformanceCount.QuadPart
							);

						SystemTime_2.LowPart = CSsymonEtw::Instance()->m_SystemTime.dwLowDateTime;
						SystemTime_2.HighPart = CSsymonEtw::Instance()->m_SystemTime.dwHighDateTime;
						SystemTime_2.QuadPart += SystemTime.QuadPart;

						SystemTime.LowPart = CSsymonEtw::Instance()->m_SystemTime.dwLowDateTime;
						SystemTime.HighPart = CSsymonEtw::Instance()->m_SystemTime.dwHighDateTime;
					}
					else
					{
						SystemTime_2.HighPart = pEvent->Header.TimeStamp.HighPart;
						SystemTime_2.LowPart = pEvent->Header.TimeStamp.LowPart;

						SystemTime.LowPart = CSsymonEtw::Instance()->m_SystemTime.dwLowDateTime;
						SystemTime.HighPart = CSsymonEtw::Instance()->m_SystemTime.dwHighDateTime;
					}


					if (SystemTime_2.QuadPart >= SystemTime.QuadPart)
					{
						CSysmonData* pEventType = pDataEntry->m_EventTypeName;
						LONG EventType = 0;
						BOOL IsUdp = FALSE;

						__try
						{
							IsUdp = pEventClass->CompareN(_T("Udp"),3);
						}
						__except(EXCEPTION_EXECUTE_HANDLER)
						{
							IsUdp = FALSE;
						}
						
						if (pEventType && pEventType->Len())
						{						
							LONG nI = 0;
							BOOL NotEque = TRUE;
							__try
							{
								while(TRUE && nI < 24)
								{
									BSTR pEventTypeName_1 = CSysmonMofData::m_TcpIpEventTypeName[nI].NetName;
									BSTR pEventTypeName_2 = pEventType->m_pData;
									while(TRUE && pEventTypeName_1 && pEventTypeName_2)
									{
										if (pEventTypeName_1[0] != pEventTypeName_2[0])
										{
											break;
										}

										if (pEventTypeName_1[0] == 0)
										{
											NotEque = FALSE;
											break;
										}

										pEventTypeName_1++;
										pEventTypeName_2++;
									}

									if (NotEque == FALSE)
									{
										break;
									}

									nI++;

									if (nI > 24)
									{
										EventType = 0;
										__leave;
									}
								}

								EventType = CSysmonMofData::m_TcpIpEventTypeName[nI].NetType;
							}
							__except(EXCEPTION_EXECUTE_HANDLER)
							{

							}							
							
						}
						else
						{
							EventType = (pEvent->Header.Class.Type==11)?3:(pEvent->Header.Class.Type==10)+1;
						}

						if (IsUdp == TRUE || EventType == 4 || EventType == 5)
						{
							if ( pDataEntry->m_ProperityList &&
								!pDataEntry->m_ProperityList->IsListEmpty())
							{
								__try
								{
									Sysmon_Net_Report* NetReport = (Sysmon_Net_Report*)
										malloc(sizeof(Sysmon_Net_Report));

									if (NetReport)
									{
										NetReport->NrEventType = 1;
										NetReport->NrProcessId = pEvent->Header.ProcessId;
										if (pEvent->Header.ThreadId == -1)
										{
											NetReport->NrThreadId = 0;
										}
										else
										{
											NetReport->NrThreadId = pEvent->Header.ThreadId;
										}

										__m128i m128Zero = {0};
										_mm_storeu_si128((__m128i *)&NetReport->NrGuid, m128Zero);
									}
								}
								__except(EXCEPTION_EXECUTE_HANDLER)
								{

								}
								
							}
						}
					}
				}				
			}
		}
	}
	__except(EXCEPTION_EXECUTE_HANDLER)
	{

	}
}

CSysmonDataEntry* 
CSysmonMofData::GetEventCategoryClass(
	GUID* ClassGuid,
	USHORT Version,
	USHORT Level,
	USHORT Type)
{
	HRESULT hr = S_OK;
	OLECHAR* oleTrace = NULL;
	OLECHAR* oleClassName = NULL;
	OLECHAR* oleGuid = NULL;
	OLECHAR* oleVersion = NULL;
	VARIANT varGuid;
	VARIANT varVersion;
	VARIANT varClassName;
	CSysmonDataEntry* pDataEntry;
	OLECHAR* oleClassName_2 = NULL;
	pDataEntry = NULL;
	IEnumWbemClassObject* pClasses = NULL;
	IEnumWbemClassObject* pClasses_2 = NULL;
	IWbemClassObject* pClass = NULL;
	IWbemClassObject* pClass_2 = NULL;
	IWbemQualifierSet* pQualifiers = NULL;
	ULONG CntTrace = 1;
	ULONG CntClass = 1;
	TCHAR EventGuid[5*sizeof(GUID)] = {0};
	TCHAR GuidString[5*sizeof(GUID)] = {0};

	VariantInit(&varClassName);
	VariantInit(&varGuid);
	VariantInit(&varVersion);

	do
	{
		if (!m_pIWbemService && CoCreateInstance())
		{
			break;
		}

		StringCchPrintf(
			EventGuid,
			5*sizeof(GUID),
			_T("{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}"),
			ClassGuid->Data1,
			ClassGuid->Data2,
			ClassGuid->Data3,
			ClassGuid->Data4[0],
			ClassGuid->Data4[1],
			ClassGuid->Data4[2],
			ClassGuid->Data4[3],
			ClassGuid->Data4[4],
			ClassGuid->Data4[5],
			ClassGuid->Data4[6],
			ClassGuid->Data4[7]);

		oleTrace		= SysAllocString(_T("EventTrace"));
		oleClassName	= SysAllocString(_T("__CLASS"));
		oleGuid			= SysAllocString(_T("Guid"));
		oleVersion	= SysAllocString(_T("EventVersion"));

		hr = m_pIWbemService->CreateClassEnum(
									oleTrace,
									WBEM_FLAG_DEEP | 
									WBEM_FLAG_UPDATE_ONLY | 
									WBEM_FLAG_USE_AMENDED_QUALIFIERS,
									0,
									&pClasses);
		SysFreeString(oleTrace);

		if (hr != S_OK)
		{
			break;
		}

		__try
		{		

			do 
			{
				if (pClass)
				{
					pClass->Release();
					pClass = NULL;
				}
				
				if( pClasses->Next(5000,1, &pClass, &CntTrace) != S_OK)
				{
					continue;
				}

				if (CntTrace != 1)
				{
					break;
				}

				if ( pClass->Get(oleClassName, 0, &varClassName, 0, 0) != S_OK )
					continue;

				oleClassName_2 = SysAllocString(varClassName.bstrVal);
				m_pIWbemService->CreateClassEnum(
					oleClassName_2,
					WBEM_FLAG_DEEP | 
					WBEM_FLAG_UPDATE_ONLY | 
					WBEM_FLAG_USE_AMENDED_QUALIFIERS,
					0,
					&pClasses_2);

				SysFreeString(oleClassName_2);
				VariantClear(&varClassName);

				CntClass = 1;

				do 
				{
					pClass_2 = NULL;
					if (pClasses_2)
					{
						if ( pClasses_2->Next(5000, 1, &pClass_2, &CntClass) != S_OK )
							continue;

						if ( CntClass != 1 )
							break;					
					}
					else
					{
						CntClass = 1;
						pClass_2 = pClass;
					}

					HRESULT hr2 = pClass_2->Get(oleClassName, 0, &varClassName, 0, 0);
					VariantClear(&varClassName);

					if (hr2 == S_OK)
					{
						if ( pQualifiers )
						{
							pQualifiers->Release();
							pQualifiers = 0;
						}

						HRESULT hrQualifier = pClass_2->GetQualifierSet(&pQualifiers);

						if ( FAILED(hrQualifier))
						{
							break;
						}

						if(pQualifiers->Get(
							oleGuid,
							0,
							&varGuid,
							0) == S_OK)
						{
							wcscpy_s(GuidString, 5*sizeof(GUID), varGuid.bstrVal);
							VariantClear(&varGuid);

 							if ( !wcsstr(GuidString, L"{") )
 								StringCchPrintf(GuidString, 5*sizeof(GUID),_T("{%s}"),GuidString);

							if ( !_wcsicmp(GuidString, EventGuid) )
							{
								if(pQualifiers->Get(
									oleVersion,
									0,
									&varVersion,
									0) == S_OK)
								{
									VariantChangeType(&varVersion, &varVersion, 0, VT_I2);
									WORD VersionTmp = varVersion.iVal;
									VariantClear(&varVersion);
									if ( Version != VersionTmp )
										continue;

									pDataEntry = GetPropertyList(
															pClass_2,
															ClassGuid,
															Version,
															Level,
															Type);
								}
								else
								{
									pDataEntry = GetPropertyList(
																pClass_2,
																ClassGuid,
																Version,
																Level,
																Type);
								}

								__leave;
							}							
						}					
					}

				} while (CntClass == 1);

				if (pClasses_2)
				{
					pClasses_2->Release();
					pClasses_2 = NULL;
				}

			} while (CntTrace == 1);

		}
		__except(EXCEPTION_EXECUTE_HANDLER)
		{

		}
		
		if (pClasses)
		{
			pClasses->Release();
			pClasses = NULL;
		}

	} while (FALSE);
		
	VariantClear(&varGuid);
	VariantClear(&varVersion);

	SysFreeString(oleGuid);
	SysFreeString(oleClassName);
	SysFreeString(oleVersion);

	if (pClasses)
	{
		pClasses->Release();
		pClasses = NULL;
	}

	if (pClasses_2)
	{
		pClasses_2->Release();
		pClasses_2 = NULL;
	}

	if (pQualifiers)
	{
		pQualifiers->Release();
		pQualifiers = NULL;
	}

	return pDataEntry;
}

void CSysmonMofData::InsertBack(
			CSysmonEventList* pEventList,
			LONG* Reference,
			void* pElm)
{
	CSysmonEventList* pNewList = pEventList->InsertBack(pEventList->m_Entry.Blink,pElm);
	(*Reference)++;
	 if ( 0x15555554 - *Reference < 1 )
	 {
		 //std::_Xlength_error("list<T> too long");
	 }

	 (*Reference)++;
	 pEventList->m_Entry.Blink = &pNewList->m_Entry;
	 pNewList->m_Entry.Blink->Flink = &pNewList->m_Entry;
}

void CSysmonDataEntry::operator =(CSysmonDataEntry* pDataEntry)
{
	if (this != pDataEntry)
	{
		m_EventClassName = pDataEntry->m_EventClassName;
		if ( pDataEntry->m_EventClassName )
			InterlockedIncrement((volatile LONG *)&m_EventClassName->m_Reference);
	}
}

void CSysmonMofData::SysmonAddProperityList(
				CSysmonEventList* pList, 
				BSTR ProperityName,
				LONG Len,
				LONG ArraySize)
{
	if ( pList)
	{
		LONG Reference = 0;
		LIST_ENTRY* pEntry = pList->m_Entry.Flink;
		while( pEntry != &pList->m_Entry)
		{
			CSysmonEventList* pEventList = CONTAINING_RECORD(pEntry,CSysmonEventList,m_Entry);

			if (pEventList)
			{
				CSysmonDataEntry* pDataEntry = (CSysmonDataEntry*)pEventList->m_pEvent;

				if (pDataEntry)
				{
					CSysmonProperty* pProperity = new CSysmonProperty(ProperityName,Len,ArraySize);
					pDataEntry->m_ProperitySize++;

					CSysmonEventList* pNewList = pDataEntry->m_ProperityList->InsertBack(
						pDataEntry->m_ProperityList->m_Entry.Blink,
						pProperity);

					pDataEntry->m_ProperityList->m_Entry.Blink = &pNewList->m_Entry;
					pNewList->m_Entry.Blink = &pNewList->m_Entry;

				}
				
			}		
			

			pEntry = pEntry->Flink;
		}

	}
}

CSysmonDataEntry* CSysmonMofData::GetPropertyList(
							IWbemClassObject* pClass,
							GUID* ClassGuid,
							USHORT Version,
							USHORT Level,
							USHORT Type)
{
	CSysmonDataEntry* pDataEntry;
	CSysmonEventList* pEventList;
	CSysmonEventList* pEventList_2;
	CSysmonDataEntry* pRetEventv63;
	CSysmonDataEntry* pOldDataEntry;
	LONG Reference;
	BSTR bstrDisplayName;
	BSTR bstrClassName;
	BSTR bstrEventType;
	BSTR bstrEventTypeName;
	BSTR bstrWmiDataId;
	BSTR bstrVarClassName;
	VARIANT varClassName;
	VARIANT varDisplayName;
	VARIANTARG vargType;
	VARIANTARG vargTypeName;
	IWbemQualifierSet * pQualifierSet = NULL;
	IEnumWbemClassObject* pClasses = NULL;
	IWbemClassObject*	  pClass_1 = NULL;
	ULONG Cnt;
	HRESULT hr;
	ULONG*		ppvData;
	BSTR*		ppvData_2;
	OLECHAR szClassName[MAX_PATH] = {0};
	OLECHAR szEventName[MAX_PATH] = {0};
	pSafeArrayDestroy ApiSafeArrayDestroy = NULL;
	pSafeArrayGetElement ApiSafeArrayGetElement = NULL;
	pEventList = new CSysmonEventList(0,0);
	pDataEntry = NULL;
	VariantInit(&varClassName);
	VariantInit(&varDisplayName);
	VariantInit(&vargType);
	VariantInit(&vargTypeName);

	//VariantInit(&v40);
	//VariantInit(&v36);
	Reference = 1;
	pRetEventv63 = NULL;
	bstrClassName = SysAllocString(L"__CLASS");
	bstrWmiDataId = SysAllocString(L"WmiDataId");
	bstrEventType = SysAllocString(L"EventType");
	bstrEventTypeName = SysAllocString(L"EventTypeName");
	bstrDisplayName = SysAllocString(L"DisplayName");

	if ( pClass->Get(
					bstrClassName,
					0,
					&varClassName, 
					0,
					0) == S_OK )
	{
		StringCchCopy(
				szClassName,
				MAX_PATH,
				varClassName.bstrVal);

		if (pQualifierSet)
		{
			pQualifierSet->Release();
			pQualifierSet = NULL;
		}

		pClass->GetQualifierSet(&pQualifierSet);
		if ( !pQualifierSet->Get(
								bstrDisplayName,
								0,
								&varDisplayName,
								0) && varDisplayName.lVal )
				StringCchCopy(szClassName, MAX_PATH, varDisplayName.bstrVal);

		pDataEntry = new CSysmonDataEntry(ClassGuid,-1,-1,-1);
		pRetEventv63 = pDataEntry;
		pOldDataEntry = pDataEntry;

		if (pDataEntry)
		{
			pDataEntry->InitData(&pDataEntry->m_EventClassName,szClassName);
			pEventList_2 = pEventList->InsertBack(
											pEventList->m_Entry.Blink,
											pDataEntry);

			pEventList->m_Entry.Blink = &pEventList_2->m_Entry;
			pEventList_2->m_Entry.Blink->Flink = &pEventList_2->m_Entry;

			bstrVarClassName = SysAllocString(varClassName.bstrVal);
			hr = m_pIWbemService->CreateClassEnum(
											bstrVarClassName,
											WBEM_FLAG_DEEP | 
											WBEM_FLAG_UPDATE_ONLY | 
											WBEM_FLAG_USE_AMENDED_QUALIFIERS,
											0,
											&pClasses);
			SysFreeString(bstrVarClassName);

			if ( hr == S_OK)
			{
				ApiSafeArrayDestroy = SafeArrayDestroy;
				ApiSafeArrayGetElement = SafeArrayGetElement;

				Cnt = 1;
				while ( TRUE )
				{
					pClass_1 = 0;
					if ( pClasses->Next(5000, 1, &pClass_1, &Cnt) != S_OK )
					{

						pClass_1 = pClass;
						pClass_1->AddRef();

					}

					if ( pQualifierSet )
					{
						pQualifierSet->Release();
						pQualifierSet = 0;
					}

					pClass_1->GetQualifierSet(&pQualifierSet);
					 VariantClear(&vargType);

					 if ( pQualifierSet->Get(
											bstrEventType,
											0,
											&vargType,
											0) == S_OK )
					 {

						 if (vargType.vt & VT_ARRAY)
						 {
							 SAFEARRAY* pl1 = vargType.parray;
							 SAFEARRAY* pl2 = NULL;
							 LONG plLbound_1 = 0;
							 LONG plUbound_1 = 0;
							 LONG plLbound_2 = 0;
							 LONG plUbound_2 = 0;
							 VariantClear(&vargTypeName);
							 if ( pQualifierSet->Get(
													bstrEventTypeName,
													0,
													&vargTypeName, 
													0) == S_OK && (vargTypeName.vt & VT_ARRAY) )
							 {
								 pl2 = vargTypeName.parray;
							 }

							 if ( !pl1
								 || SafeArrayGetLBound(pl1, 1, &plLbound_1)
								 || SafeArrayGetUBound(pl1, 1, &plUbound_1)
								 || plUbound_1 < 0 )
							 {
								 pDataEntry = pRetEventv63;
								 break;
							 }

							  SafeArrayAccessData(pl1, (void**)&ppvData);

							  if ( pl2 )
							  {
								  if ( SafeArrayGetLBound(pl2, 1, &plLbound_2) ||
									  SafeArrayGetUBound(pl2, 1, &plUbound_2) ||
									  plUbound_2 < 0 )
								  {
									  pDataEntry = pRetEventv63;
									  break;
								  }

								  SafeArrayAccessData(pl2, (void**)&ppvData_2);
							  }

							  if ( plLbound_1 <= plUbound_1)
							  {
								  LONG rgIndices = plLbound_1;

								  while(TRUE)
								  {
									  do 
									  {
										  USHORT uType = (*(USHORT*)&ppvData[rgIndices]);

										  try
										  {
											  CSysmonDataEntry* pDataEntry__3 = new CSysmonDataEntry(ClassGuid,uType,Version,Level);

											  if (pDataEntry__3)
											  {
												  InsertBack(pEventList,&Reference,pDataEntry__3);

												  if (pOldDataEntry->GetCLassNameLen())
												  {
													  *pDataEntry__3 = pOldDataEntry;
												  }

												  if (Type == uType)
												  {
													  pRetEventv63 = pDataEntry__3;
												  }

												  if ( pl2 )
												  {
													  if ( rgIndices < plLbound_2 || rgIndices > plUbound_2 )
													  {
														  break;
													  }

													  pDataEntry__3->InitData(
														  &pDataEntry__3->m_EventTypeName,
														  ppvData_2[rgIndices]);
												  }
											  }

										  }
										  catch(...)
										  {

										  }

									  } while (FALSE);
									  
									  rgIndices++;

									  if ( rgIndices > plUbound_1 )
									  {
										  pl1 = vargType.parray;
										  break;
									  }
								  }
							  }

							   SafeArrayUnaccessData(pl1);
							   ApiSafeArrayDestroy(pl1);
							   VariantInit(&vargType);

							   if ( pl2 )
							   {
								   SafeArrayUnaccessData(pl2);
								   SafeArrayDestroy(pl2);
								   VariantInit(&vargTypeName);
							   }

						 }
						 else
						 {

							 VariantChangeType(&vargType, &vargType, 0, VT_I2);
							 USHORT vType = vargType.iVal;
							 VariantClear(&vargTypeName);

							 if ( pQualifierSet->Get(
													bstrEventTypeName,
													0,
													&vargTypeName, 
													0) )
							 {
								 szEventName[0] = 0;
							 }
							 else
							 {
								 wcscpy_s(
										szEventName,
										MAX_PATH,
										vargTypeName.bstrVal
										);
							 }

							 CSysmonDataEntry* pDataEntry__3 = new CSysmonDataEntry(ClassGuid,vType,Version,Level);
							 if (pDataEntry__3)
							 {
								 InsertBack(pEventList,&Reference,pDataEntry__3);

								 if (pOldDataEntry->GetCLassNameLen())
								 {
									 *pDataEntry__3 = pOldDataEntry;
								 }

								 if ( Type == vType)
								 {
									 pRetEventv63 = pDataEntry__3;
								 }

								 pDataEntry__3->InitData(
									 &pDataEntry__3->m_EventTypeName,
									 szEventName);
							 }

						 }

					 }

					 SAFEARRAY* pNames = NULL;
					 LONG plLbound_1 = 0;
					 LONG plUbound_1 = 0;
					 LONG plLbound_2 = 0;
					 LONG plUbound_2 = 0;
					 BSTR pv_1 = NULL;
					 CIMTYPE QualifierType = 0;
					 VariantClear(&varClassName);
					 varClassName.vt = VT_I4;
					 varClassName.lVal = 1;

					 //LONG Index = 1;
					 //hr = pClass->GetNames(NULL, WBEM_FLAG_LOCAL_ONLY, NULL, &pNames);
					 hr = pClass_1->GetNames(
						 bstrWmiDataId,
						 WBEM_FLAG_ONLY_IF_IDENTICAL, 
						 &varClassName,
						 &pNames);

					 while( hr == S_OK)
					 {

						 if ( SafeArrayGetLBound(pNames, 1, &plLbound_1) ||
							 SafeArrayGetUBound(pNames, 1, &plUbound_1) || plUbound_1 < 0 )
							 break;

						 //plUbound_1 = pNames->rgsabound->cElements;

						 if ( plLbound_1 <= plUbound_1 )
						 {
							 LONG nIndex = plLbound_1;
							 do
							 {
								 if ( ApiSafeArrayGetElement(pNames, &nIndex, &pv_1) || pClass_1->Get(pv_1, 0, 0, &QualifierType, 0) )
									 break;

								 if ( pQualifierSet )
								 {
									 pQualifierSet->Release();
									 pQualifierSet = 0;
								 }

								 if ( pClass_1->GetPropertyQualifierSet(pv_1, &pQualifierSet) )
									 break;

								 LONG v30 = GetArrayValue(QualifierType, pQualifierSet);
								 LONG ArraySize = QualifierType & 0x2000 ? GetArraySize(pQualifierSet) : 1;

								 SysmonAddProperityList(
													pEventList,
													pv_1,
													v30, 
													ArraySize);
								 ++nIndex;
								
							 }
							 while ( nIndex <= plUbound_1 );
						 }

						 ApiSafeArrayDestroy(pNames);
						 pNames = 0;
						  varClassName.lVal++;// = (Index++);
					 }

					 AddEvent(pEventList);

					 if ( Cnt != 1 )
					 {
						 pDataEntry = pRetEventv63;
						 break;
					 }
				}//1
			}//0.
		}
	}

	VariantClear(&varClassName);
	VariantClear(&varDisplayName);
	VariantClear(&vargTypeName);
	SysFreeString(bstrClassName);
	SysFreeString(bstrDisplayName);
	SysFreeString(bstrEventType);
	SysFreeString(bstrEventTypeName);
	SysFreeString(bstrWmiDataId);

	AddEvent(pEventList);

	LIST_ENTRY* pEntry = pEventList->m_Entry.Flink;

	InitializeListHead(&pEventList->m_Entry);

	while (pEntry != &pEventList->m_Entry)
	{
		CSysmonEventList* pList = CONTAINING_RECORD(
			pEntry,
			CSysmonEventList,m_Entry);

		pEntry = pEntry->Flink;

		if (pList)
		{
			delete pList;
			pList = NULL;
		}			
	}

	return pDataEntry;
}

CSysmonEventList* CSysmonMofData::AddEvent(
										CSysmonEventList* pEventList)
{
	CSysmonEventList* pRetList = pEventList;
	if (pEventList)
	{
		LIST_ENTRY* pEntry = pEventList->m_Entry.Flink;

		while(pEntry != &pEventList->m_Entry )
		{	
			CSysmonEventList* pList = CONTAINING_RECORD(pEntry,CSysmonEventList,m_Entry);
			if (pList)
			{
				CSysmonDataEntry* pDataEntry = (CSysmonDataEntry*)pList->m_pEvent;
				CSysmonEventList* pEvent = 
									m_SysmonEventList->InsertBack(
												m_SysmonEventList->m_Entry.Blink,
												pDataEntry);

				m_SysmonEventList->m_Entry.Blink = &pEvent->m_Entry;
				pEvent->m_Entry.Blink->Flink = &pEvent->m_Entry;

				m_EventListNums++;
			}

			pEntry = pEntry->Flink;
		}

		pEntry = pEventList->m_Entry.Flink;

		InitializeListHead(&pEventList->m_Entry);
		
		while (pEntry != &pEventList->m_Entry)
		{
			CSysmonEventList* pList = CONTAINING_RECORD(
												pEntry,
												CSysmonEventList,m_Entry);

			pRetList = pList;
			pEntry = pEntry->Flink;

			if (pList)
			{
				delete pList;
				pList = NULL;
			}			
		}

		return pRetList;
	}

	return NULL;
}

LONG CSysmonMofData::GetArrayValue(
							CIMTYPE CimType,
							IWbemQualifierSet * pQualifierSet)
{
	LONG RetValue = 29;
	BSTR bstrQualifier;
	VARIANT varQualifier;
	HRESULT hr;
	BOOL bPointer;
	OLECHAR szFormat[11];
	OLECHAR szStringTermination[31];
	OLECHAR szExtension[31];
	bPointer = 0;

	szFormat[0] = 0;
	szStringTermination[0] = 0;
	szExtension[0] = 0;

	if (pQualifierSet)
	{
		bstrQualifier = SysAllocString(L"Format");
		VariantInit(&varQualifier);
		hr = pQualifierSet->Get(bstrQualifier, 0, &varQualifier, 0);
		SysFreeString(bstrQualifier);

		if ( !hr && varQualifier.lVal )
			StringCchCopy(szFormat, 10, varQualifier.bstrVal);

		bstrQualifier = SysAllocString(L"StringTermination");
		VariantClear(&varQualifier);

		hr = pQualifierSet->Get(bstrQualifier, 0, &varQualifier, 0);
		SysFreeString(bstrQualifier);

		if ( !hr && varQualifier.lVal )
			StringCchCopy(szStringTermination, 30, varQualifier.bstrVal);

		bstrQualifier = SysAllocString(L"Pointer");
		VariantClear(&varQualifier);

		hr = pQualifierSet->Get(bstrQualifier, 0, &varQualifier, 0);
		SysFreeString(bstrQualifier);

		if ( hr == S_OK)
		{
			bPointer = 1;
		}

		bstrQualifier = SysAllocString(L"Extension");
		VariantClear(&varQualifier);

		hr = pQualifierSet->Get(bstrQualifier, 0, &varQualifier, 0);
		SysFreeString(bstrQualifier);

		if ( !hr && varQualifier.lVal )
			StringCchCopy(szExtension, 30, varQualifier.bstrVal);

		VariantClear(&varQualifier);

		 switch ( CimType & (~CIM_FLAG_ARRAY) )
		 {
		 case CIM_SINT16:
			 RetValue = 4;
			 break;
		 case CIM_SINT32:
			 RetValue = 6;
			 break;
		 case CIM_REAL32:
			 RetValue = 11;
			 break;
		 case CIM_REAL64:
			 RetValue = 12;
			 break;
		 case CIM_STRING:
			 {
				 if ( _wcsicmp(szStringTermination, L"NullTerminated") )
				 {
					 if ( _wcsicmp(szStringTermination, L"Counted") )
					 {
						 if ( _wcsicmp(szStringTermination, L"ReverseCounted") )
							 RetValue = _wcsicmp(szStringTermination, L"NotCounted") != 0 ? 13 : 23;
						 else
							 RetValue = 18 - (_wcsicmp(szFormat, L"w") != 0);
					 }
					 else
					 {
						 RetValue = 16 - (_wcsicmp(szFormat, L"w") != 0);
					 }
				 }
				 else
				 {
					 RetValue = 14 - (_wcsicmp(szFormat, L"w") != 0);
				 }
			 }
			 break;
		 case CIM_BOOLEAN:
			 RetValue = 26;
			 break;
		 case CIM_OBJECT:
			 if ( !_wcsicmp(szExtension, L"Port") )
			 {
				 RetValue = 21;
				
			 }
			 else
			 {
				 if ( !_wcsicmp(szExtension, L"IPAddr") )
				 {
					 RetValue = 20;
				 }
				 else if ( _wcsicmp(szExtension, L"Sid") )
				 {
					 if ( _wcsicmp(szExtension, L"Guid") )
					 {
						 if ( !_wcsicmp(szExtension, L"SizeT") )
						 {
							 RetValue = 6;
						 }
						 else
						 {
							 if ( _wcsicmp(szExtension, L"IPAddrV6") )
							 {
								 if ( _wcsicmp(szExtension, L"IPAddrV4") )
								 {
									 if ( !_wcsicmp(szExtension, L"WmiTime") )
										 RetValue = 28;
								 }
								 else
								 {
									 RetValue = 20;
								 }
							 }
							 else
							 {
								 RetValue = 27;
							 }
						 }
						
					 }
					 else
					 {
						 RetValue = 25;
					 }
				 }
				 else
				 {
					 RetValue = 19;
				 }
			 }
			 break;
		 case CIM_SINT8:
			 RetValue = 3;
			 if ( !_wcsicmp(szFormat, L"c") )
				 RetValue = 0;
			 break;
		 case CIM_UINT8:
			 RetValue = 2;
			 break;
		 case CIM_UINT16:
			 RetValue = 5;
			 break;
		 case CIM_UINT32:
			 RetValue = 7;
			 break;
		 case CIM_SINT64:
			 RetValue = 9;
			 break;
		 case CIM_UINT64:
			 RetValue = 10;
			 break;
		 case CIM_CHAR16:
			 RetValue = 1;
			 break;
		 }

		 if (bPointer)
		 {
			 RetValue = 24;
		 }
		 
	}

	return RetValue;
}

LONG CSysmonMofData::GetArraySize(
							IWbemQualifierSet* pQualifierSet)
{
	LONG ArraySize = 1;
	VARIANT varQualifier;
	HRESULT hr;
	if ( pQualifierSet )
	{
		BSTR bstrMax = SysAllocString(L"MAX");
		VariantInit(&varQualifier);

		hr = pQualifierSet->Get(bstrMax, 0, &varQualifier, 0);
		SysFreeString(bstrMax);
		if ( !hr && varQualifier.vt == 3 )
			ArraySize = varQualifier.lVal;

		VariantClear(&varQualifier);
	}

	return ArraySize;
}

CSysmonData::CSysmonData()
	:m_pData(NULL)
	,m_pAlloc(NULL)
	,m_Reference(0) 
{

}

CSysmonData::~CSysmonData()
{

}

BOOL CSysmonData::Compare(BSTR pString)
{
	if (pString && m_pData)
	{
		return _wcsicmp(m_pData,pString) == 0;
	}
	return FALSE;
}

BOOL CSysmonData::CompareN(BSTR pString,ULONG Size)
{
	if (pString && m_pData)
	{
		return _wcsnicmp(m_pData,pString,Size) == 0;
	}
	return FALSE;
}

CSysmonDataEntry::CSysmonDataEntry()
	:m_EventClassName(NULL)
	,m_EventTypeName(NULL)
	,m_ProperitySize(0)
{

}

CSysmonDataEntry::CSysmonDataEntry(
								GUID* Guid,
								USHORT Type,
								USHORT Version,
								USHORT Level)
{
	m_EventClassName = NULL;
	m_EventTypeName = NULL;

	m_EventType = Type;
	m_EventVersion = Version;
	m_EventLevel = Level;
	m_ProperitySize = 0;
	m_ProperityList = new CSysmonEventList(0,0);
	
	_mm_storeu_si128(
				(__m128i *)&m_EventGuid,
				_mm_loadu_si128((const __m128i *)Guid));
}

CSysmonDataEntry::~CSysmonDataEntry()
{

}

LONG CSysmonDataEntry::GetCLassNameLen()
{
	if ( m_EventClassName && m_EventClassName->m_pData)
	{
		return SysStringLen(m_EventClassName->m_pData);
	}

	return 0;
}

CSysmonDataEntry* CSysmonDataEntry::InitData(CSysmonData** pData,BSTR pString)
{
	BSTR pOldData = 0;
	if (pData && *pData)
	{
		pOldData = (*pData)->m_pData;
	}

	if (!pString || pOldData != pString)
	{
		if (*pData)
		{
			if ( !InterlockedDecrement((volatile LONG *)&(*pData)->m_Reference))
			{
				if ((*pData)->m_pData)
				{
					SysFreeString((*pData)->m_pData);
					(*pData)->m_pData = 0;
				}

				if ( m_EventClassName->m_pAlloc )
				{
					delete (*pData)->m_pAlloc;
					(*pData)->m_pAlloc = 0;
				}

				delete (*pData);
			}

			(*pData) = NULL;
		}
	}

	CSysmonData* pNew = new CSysmonData();

	if (pNew)
	{
		pNew->m_pAlloc = 0;
		pNew->m_Reference = 1;
		pNew->m_pData = SysAllocString(pString);
		
		if ( !pNew->m_pData && pString )
		{
		//	LogError(0x8007000E);
		}
	}
	else
	{
		//LogError(0x8007000E);
	}

	*pData = pNew;

	return this;
}


CSysmonEventList::CSysmonEventList()
	:m_pEvent(0)
{
	InitializeListHead(&m_Entry);
}

CSysmonEventList::CSysmonEventList(
							LIST_ENTRY* Fink,
							LIST_ENTRY* Blink)
							:m_pEvent(0)
{
	LIST_ENTRY* pl1;
	LIST_ENTRY* pl2;

	pl1 = Fink;
	m_pEvent = 0;
	if (Fink)
	{
		pl2 = Blink;
	}
	else
	{
		pl1 = &m_Entry;
		pl2 = &m_Entry;
	}

	m_Entry.Flink = pl1;
	m_Entry.Blink = pl2;
}

CSysmonEventList::~CSysmonEventList()
{

}

CSysmonEventList* CSysmonEventList::InsertBack(LIST_ENTRY* Blink,void* pElm)
{
	CSysmonEventList* pList = new CSysmonEventList(
												&m_Entry,
												Blink);
	if (pList)
	{
		pList->m_pEvent = pElm;
	}

	return pList;
}

================================================
FILE: Sysmon/CSysmonMofData.h
================================================
#ifndef _CSysmonMofData_h
#define _CSysmonMofData_h

#include "Sysmon.h"
#include <wbemidl.h>
#include <comutil.h>
#include <wbemidl.h>
#include <wmistr.h>
#include <WbemCli.h>
#include <strsafe.h>
#include <intrin.h>
#include <Evntrace.h>

extern "C"
{
	typedef HRESULT (WINAPI * pSafeArrayDestroy)(SAFEARRAY *);
	typedef HRESULT (WINAPI * pSafeArrayGetElement)(SAFEARRAY * , LONG *, void *);
};


typedef struct _CTcpIpInfo
{
	BSTR NetName;
	ULONG NetType;
}CTcpIpInfo;

typedef struct _Sysmon_Net_Report
{
	ULONG			NrSize;
	ULONG			NrProcessId;
	ULONG			NrThreadId;
	GUID			NrGuid;
	LARGE_INTEGER	NrSystemTime;
	ULONG			NrEventType;
	ULONG			NrUdpOrTcp;
}Sysmon_Net_Report;

class CSysmonData
{
	friend class CSysmonDataEntry;
	friend class CSysmonProperty;
	friend class CSysmonMofData;
public:
	CSysmonData();
	~CSysmonData();

	BOOL Compare(BSTR pString);
	BOOL CompareN(BSTR pString,ULONG Size);

	LONG Len()
	{
		if (m_pData)
		{
			__try
			{
				return lstrlen(m_pData);
			}
			__except(EXCEPTION_EXECUTE_HANDLER)
			{

			}
			
		}
		return 0;
	}
private:
	BSTR m_pData;
	void* m_pAlloc;
	LONG  m_Reference; 
};

class CSysmonEventList
{
	friend class CSysmonMofData;
public:
	CSysmonEventList();
	~CSysmonEventList();
	BOOL IsListEmpty()
	{
		return ::IsListEmpty(&m_Entry);
	}

	CSysmonEventList(LIST_ENTRY* Fink,LIST_ENTRY* Blink);
	CSysmonEventList* InsertBack(LIST_ENTRY* Blink,void* pElm);
private:
	void*		m_pEvent;
public:
	LIST_ENTRY	m_Entry;
};

class CSysmonDataEntry
{
	friend class CSysmonMofData;
public:
	CSysmonDataEntry();
	CSysmonDataEntry(GUID* Guid,USHORT Type,USHORT Version,USHORT Level);
	~CSysmonDataEntry();
	void operator =(CSysmonDataEntry* pDataEntry);
	CSysmonDataEntry* InitData(CSysmonData** pData,BSTR pString);
	LONG GetCLassNameLen();
	
private:
	CSysmonData*		m_EventClassName;
	CSysmonData*		m_EventTypeName;
	GUID				m_EventGuid;
	USHORT				m_EventType;
	USHORT				m_EventVersion;
	USHORT				m_EventLevel;

	ULONG				m_ProperitySize;
	CSysmonEventList*	m_ProperityList;
};

class CSysmonProperty
{
	friend class CSysmonMofData;
public:
	CSysmonProperty()
		:m_Data(NULL)
		,m_Len(0),
		m_ArraySize(0)
	{

	}

	CSysmonProperty(BSTR pName,LONG Len,LONG ArraySize)
		:m_Data(NULL)
		,m_Len(0),
		m_ArraySize(0)
	{
		
		if (pName)
		{
			InitData(&m_Data,pName);
		}
		m_Len = Len;
		m_ArraySize = ArraySize;

	}

	~CSysmonProperty()
	{

	}

	void InitData(CSysmonData** pData,BSTR pString)
	{
		BSTR pOldData = 0;
		if (pData && *pData)
		{
			pOldData = (*pData)->m_pData;
		}

		if (!pString || pOldData != pString)
		{
			if (*pData)
			{
				if ( !InterlockedDecrement((volatile LONG *)&(*pData)->m_Reference))
				{
					if ((*pData)->m_pData)
					{
						SysFreeString((*pData)->m_pData);
						(*pData)->m_pData = 0;
					}

					if ( (*pData)->m_pAlloc )
					{
						delete (*pData)->m_pAlloc;
						(*pData)->m_pAlloc = 0;
					}

					delete (*pData);
				}

				(*pData) = NULL;
			}
		}

		CSysmonData* pNew = new CSysmonData();

		if (pNew)
		{
			pNew->m_pAlloc = 0;
			pNew->m_Reference = 1;
			pNew->m_pData = SysAllocString(pString);

			if ( !pNew->m_pData && pString )
			{
				//	LogError(0x8007000E);
			}
		}
		else
		{
			//LogError(0x8007000E);
		}

		*pData = pNew;
	}

private:
	CSysmonData*	m_Data;
	LONG			m_Len;
	LONG			m_ArraySize;
};

class CSysmonMofData
{
public:
	CSysmonMofData(void);
	virtual ~CSysmonMofData(void);

public:
	CSysmonDataEntry* GetEventCategoryClass(
										GUID* ClassGuid,
										USHORT Version,
										USHORT Level,
										USHORT Type);

	CSysmonDataEntry* GetPropertyList(
							IWbemClassObject* pClass,
							GUID* ClassGuid,
							USHORT Version,
							USHORT Level,
							USHORT Type);

	void SysmonAddProperityList(
						CSysmonEventList* pList, 
						BSTR ProperityName,
						LONG Len,
						LONG ArraySize);

	CSysmonDataEntry* Phase_1(
						GUID* ClassGuid,
						USHORT Version,
						USHORT Level,
						USHORT Type);

	void Phase_2(
				PEVENT_TRACE pEvent,
				CSysmonDataEntry* pDataEntry
						);

	HRESULT CoCreateInstance();

	LONG GetArraySize(IWbemQualifierSet* pQualifierSet);
	LONG GetArrayValue(
				CIMTYPE CimType,
				IWbemQualifierSet * pQualifierSet);

	void InsertBack(
				CSysmonEventList* pEventList,
				LONG* Reference,
				void* pElm);


	CSysmonEventList* AddEvent(CSysmonEventList* pEventList);

private:
	IWbemServices*		m_pIWbemService;
	CSysmonEventList*	m_SysmonEventList;
	LONG				m_EventListNums;
public:
	static CTcpIpInfo	m_TcpIpEventTypeName[25];
};

#endif

================================================
FILE: Sysmon/CSysmonUtil.cpp
================================================
#include "StdAfx.h"
#include "CSysmonUtil.h"


CSysmonUtil::CSysmonUtil(void)
{
}


CSysmonUtil::~CSysmonUtil(void)
{
}

BOOL CSysmonUtil::SysmonVersionIsSupport()
{
	BOOL result;
	OSVERSIONINFOEX VersionInformation;

	VersionInformation.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
	VersionInformation.dwMajorVersion = 0;
	memset(
		&VersionInformation.dwMinorVersion,
		0,
		sizeof(OSVERSIONINFOW));

	GetVersionEx((POSVERSIONINFO)&VersionInformation);

	if ( VersionInformation.dwMajorVersion >= 6 )
		return 1;

	if ( VersionInformation.dwMajorVersion != 5 || 
		!VersionInformation.dwMinorVersion )
	{
		result = 0;
	}

	if ( VersionInformation.dwMinorVersion == 1 )
	{
		//= XP2
		return VersionInformation.wServicePackMajor >= 2;
	}
	if ( VersionInformation.dwMinorVersion == 2 )
	{
		result = (VersionInformation.wProductType == VER_NT_WORKSTATION);
	}
	else
	{
		result = 0;
	}

	return result;
}

unsigned __int64 CSysmonUtil::CounterTimes(FILETIME t1,__int64 t2)
{
	unsigned __int64 Result = 0;

	if ( t2 >= 0 )
	{
		return (unsigned __int64)(10000000 * (t2 % (QWORD)(t1.dwLowDateTime + 16))) / (QWORD)(t1.dwLowDateTime + 16)
		+ 10000000 * (t2 / (QWORD)(t1.dwLowDateTime + 16));
	}
	else
	{
		Result = CounterTimes(t1,-t2);
	}

	return Result;
}

================================================
FILE: Sysmon/CSysmonUtil.h
================================================
#ifndef _CSysmonUtil_h
#define _CSysmonUtil_h

typedef unsigned __int64 QWORD;

class CSysmonUtil
{
public:
	CSysmonUtil(void);
	~CSysmonUtil(void);

public:
	static
	BOOL 
	SysmonVersionIsSupport();

	static
	unsigned __int64 CounterTimes(FILETIME t1,__int64 t2);
};

#endif

================================================
FILE: Sysmon/ReadMe.txt
================================================
========================================================================
    WIN32 APPLICATION : Sysmon Project Overview
========================================================================

AppWizard has created this Sysmon application for you.

This file contains a summary of what you will find in each of the files that
make up your Sysmon application.


Sysmon.vcxproj
    This is the main project file for VC++ projects generated using an Application Wizard.
    It contains information about the version of Visual C++ that generated the file, and
    information about the platforms, configurations, and project features selected with the
    Application Wizard.

Sysmon.vcxproj.filters
    This is the filters file for VC++ projects generated using an Application Wizard. 
    It contains information about the association between the files in your project 
    and the filters. This association is used in the IDE to show grouping of files with
    similar extensions under a specific node (for e.g. ".cpp" files are associated with the
    "Source Files" filter).

Sysmon.cpp
    This is the main application source file.

/////////////////////////////////////////////////////////////////////////////
AppWizard has created the following resources:

Sysmon.rc
    This is a listing of all of the Microsoft Windows resources that the
    program uses.  It includes the icons, bitmaps, and cursors that are stored
    in the RES subdirectory.  This file can be directly edited in Microsoft
    Visual C++.

Resource.h
    This is the standard header file, which defines new resource IDs.
    Microsoft Visual C++ reads and updates this file.

Sysmon.ico
    This is an icon file, which is used as the application's icon (32x32).
    This icon is included by the main resource file Sysmon.rc.

small.ico
    This is an icon file, which contains a smaller version (16x16)
    of the application's icon. This icon is included by the main resource
    file Sysmon.rc.

/////////////////////////////////////////////////////////////////////////////
Other standard files:

StdAfx.h, StdAfx.cpp
    These files are used to build a precompiled header (PCH) file
    named Sysmon.pch and a precompiled types file named StdAfx.obj.

/////////////////////////////////////////////////////////////////////////////
Other notes:

AppWizard uses "TODO:" comments to indicate parts of the source code you
should add to or customize.

/////////////////////////////////////////////////////////////////////////////


================================================
FILE: Sysmon/Resource.h
================================================
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by Sysmon.rc
//

#define IDS_APP_TITLE			103

#define IDR_MAINFRAME			128
#define IDD_SYSMON_DIALOG	102
#define IDD_ABOUTBOX			103
#define IDM_ABOUT				104
#define IDM_EXIT				105
#define IDI_SYSMON			107
#define IDI_SMALL				108
#define IDC_SYSMON			109
#define IDC_MYICON				2
#ifndef IDC_STATIC
#define IDC_STATIC				-1
#endif
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS

#define _APS_NO_MFC					130
#define _APS_NEXT_RESOURCE_VALUE	129
#define _APS_NEXT_COMMAND_VALUE		32771
#define _APS_NEXT_CONTROL_VALUE		1000
#define _APS_NEXT_SYMED_VALUE		110
#endif
#endif


================================================
FILE: Sysmon/Sysmon.cpp
================================================
// Sysmon.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#include "Sysmon.h"
#include <ShellAPI.h>
#include "CSysmonDriverOpt.h"
#include "CSsymonEtw.h"
#include <wchar.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LOADSTRING 100


extern "C" typedef BOOL (WINAPI *pIsWow64Process)(
	HANDLE hProcess,
	PBOOL  Wow64Process
	);

int APIENTRY _tWinMain(
					HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine,
                     int       nCmdShow)
{
	UNREFERENCED_PARAMETER(hPrevInstance);
	UNREFERENCED_PARAMETER(lpCmdLine);

	int argc = 0;
	char** argv = NULL;
	WCHAR** argvW = (WCHAR**)NULL;
	
	argvW = ::CommandLineToArgvW(::GetCommandLine(), &argc);
// 	argv = (char**)malloc(argc * sizeof(char*));
// 	int cb = 0;
// 	for (int i = 0; i < argc; i++)   
// 	{
// 		cb = WideCharToMultiByte (CP_ACP, 0, argvW[i],  -1, NULL, 0, NULL, NULL);
// 		argv[i] = (char*)malloc(cb * sizeof(WCHAR) + 1);
// 		WideCharToMultiByte (CP_ACP, 0, argvW[i], -1, argv[i], cb, NULL, NULL);
// 	}

	BOOL bIsWow64Process = FALSE;
	HMODULE v4 = GetModuleHandleW(L"kernel32.dll");
	pIsWow64Process v5 = (pIsWow64Process)GetProcAddress(v4, "IsWow64Process");
	if ( v5 )
	{
		v5(GetCurrentProcess(), &bIsWow64Process);
	}

	if (bIsWow64Process)
	{
		return RunSysmonX64();
	}


	if (argc > 1)
	{
		if (lstrcmpi(argvW[1],_T("-i")) == 0 )
		{
			
			CSysmonDriverOpt Opt;

			Opt.InstallDriver(
							_T("Sysmon"),
							_T("Sysmon.sys"),
							_T("370030"));

			
			if(Opt.StartDriver(_T("Sysmon")))
			{
				MessageBox(NULL,_T("Success"),_T("Success"),MB_OK);
			}
		}

		if (lstrcmpi(argvW[1],_T("-n")) == 0 )
		{

			CSsymonEtw::Instance()->StartTrace(1);
		}
	}


	MSG msg;
	while (GetMessage(&msg, NULL, 0, 0))
	{

		TranslateMessage(&msg);

		DispatchMessage(&msg);

	}

	return msg.wParam;


 	return TRUE;
}


extern "C" typedef void (WINAPI *pGetNativeSystemInfo)(LPSYSTEM_INFO lpSystemInfo);

BOOLEAN __fastcall SysmonTempFileName(wchar_t * FileName, wchar_t* TempName)
{
	wchar_t *v2;
	int i;
	unsigned int v5;
	wchar_t Dsta[MAX_PATH] = {0};
	WCHAR Buffer[MAX_PATH] = {0};
	WCHAR RandName[20] = {0};
	v2 = TempName;
	wcscpy_s(Dsta, MAX_PATH, FileName);

	if ( !GetTempPathW(MAX_PATH, Buffer) )
		return 0;

	i = 0;

	while ( TRUE )
	{
		do 
		{
			wcscpy_s(v2, 520, Buffer);
			if ( RandName[0] )
			{
				wcscat_s(v2, 520, RandName);
				wcscat_s(v2, 520, L"\\");
				if ( GetFileAttributesW(v2) != -1 || !CreateDirectoryW(v2, 0) )
					break;
			}

			wcscat_s(v2, 520, Dsta);
			if ( GetFileAttributesW(v2) == -1 )
				return 1;
			if ( RandName[0] )
			{
				wcsrchr(v2, '\\')[1] = 0;
				RemoveDirectoryW(v2);
			}

		} while (FALSE);
		
		rand_s(&v5);
		swprintf_s(RandName, 20, L"SYS%u", v5);
		if ( (unsigned int)++i >= 10 )
			return 0;
	}

	return 1;
}

wchar_t *__fastcall SysmonFormatMessageW(wchar_t *Dest, int len)
{
	int v2;
	wchar_t *v3;
	DWORD v5;
	WCHAR* Buffer;

	Buffer = 0;

	v3 = Dest;

	v5 = FormatMessageW(12544, 0, GetLastError(), 0, (LPWSTR)&Buffer, 0, 0);
	if ( v5 && len >= (signed int)(v5 + 14) )
	{
		Buffer[lstrlenW(Buffer) - 2] = 0;
		_swprintf(v3, L"%s", Buffer, GetLastError());
	}
	else
	{
		*v3 = 0;
	}
	if ( Buffer )
		LocalFree(*(HLOCAL *)Buffer);
	return v3;
}

BOOLEAN __fastcall SysmonExtractResource(LPCWSTR lpName, wchar_t *Filename)
{
	HRSRC hrFile;
	HGLOBAL hgFile;
	DWORD nFileLength;
	const void *ptr;
	FILE *hFile;

	hrFile = FindResourceW(0, lpName, L"BINRES");

	if ( !hrFile )
		return 0;
	hgFile = LoadResource(0, hrFile);
	nFileLength = SizeofResource(0, hrFile);
	ptr = LockResource(hgFile);
	hFile = _wfopen(Filename, L"wb");

	if ( !hFile )
		return 0;

	fwrite(ptr, 1, nFileLength, hFile);
	fclose(hFile);

	return 1;
}

DWORD RunSysmonX64()
{
	HMODULE v0;
	pGetNativeSystemInfo v1;
	DWORD result;
	wchar_t *v4;

	STARTUPINFOW StartupInfo = {0};
	SYSTEM_INFO SystemInfo = {0};
	PROCESS_INFORMATION ProcessInformation = {0};
	DWORD ExitCode;
	wchar_t Dest[256] = {0};
	WCHAR Filename[520] = {0};

	ExitCode = 0;
	StartupInfo.cb = 68;
	StartupInfo.lpReserved = 0;
	memset(&StartupInfo.lpDesktop, 0, 0x3Cu);

	__m128i Xmm0 = {0};
	_mm_storeu_si128((__m128i *)&ProcessInformation, Xmm0);

	v0 = LoadLibraryW(L"kernel32.dll");
	v1 = (pGetNativeSystemInfo)GetProcAddress(v0, "GetNativeSystemInfo");

	if ( v1 )
		v1(&SystemInfo);
	else
		GetSystemInfo(&SystemInfo);

	if ( SystemInfo.wProcessorArchitecture != PROCESSOR_ARCHITECTURE_AMD64 )
	{
		wprintf(L"Unsupported processor type: %d\n", SystemInfo.wProcessorArchitecture);
		return 1630;
	}

	memset(Filename, 0, sizeof(WCHAR)*520);
	if ( !GetModuleFileNameW(0, Filename, 520) )
	{
		ExitCode = GetLastError();
		wprintf(L"Failed to get the module filename:\n%s\n\n", SysmonFormatMessageW(Dest, 256));
		return ExitCode;
	}

	v4 = wcsrchr(Filename, '\\');

	if ( !SysmonTempFileName(v4 + 1,Filename) )
	{
		ExitCode = GetLastError();

		wprintf(L"Failed to create temporaryfile:\n%s\n\n", SysmonFormatMessageW(Dest, 256));
		return ExitCode;
	}

	if ( !SysmonExtractResource((LPCWSTR)1001,Filename) && GetFileAttributesW(Filename) == -1 )
	{
		ExitCode = GetLastError();
		wprintf(L"Failed to extract the 64-bit version:\n%s\n\n", SysmonFormatMessageW(Dest, 256));
		return ExitCode;
	}

	if ( CreateProcessW(
					Filename,
					GetCommandLineW(),
					0,
					0,
					0,
					0,
					0,
					0,
					&StartupInfo,
					&ProcessInformation) )
	{
		WaitForSingleObject(ProcessInformation.hProcess, 0xFFFFFFFF);
		GetExitCodeProcess(ProcessInformation.hProcess, &ExitCode);
		CloseHandle(ProcessInformation.hProcess);
		CloseHandle(ProcessInformation.hThread);
		result = ExitCode;
		if ( ExitCode == 999 )
			return result;
	}
	else
	{
		ExitCode = GetLastError();
		wprintf(L"Error launching 64-bit version:\n%s\n\n", SysmonFormatMessageW(Dest, 256));
	}

	DeleteFileW(Filename);

	return ExitCode;
}

================================================
FILE: Sysmon/Sysmon.h
================================================
#pragma once

#include "resource.h"

BOOLEAN
	FORCEINLINE
	IsListEmpty(
	__in const LIST_ENTRY * ListHead
	)
{
	return (BOOLEAN)(ListHead->Flink == ListHead);
}

FORCEINLINE
	VOID
	InitializeListHead(
	__out PLIST_ENTRY ListHead
	)
{
	ListHead->Flink = ListHead->Blink = ListHead;
}

FORCEINLINE
	VOID
	InsertTailList(
	__inout PLIST_ENTRY ListHead,
	__inout __drv_aliasesMem PLIST_ENTRY Entry
	)
{
	PLIST_ENTRY Blink;

	Blink = ListHead->Blink;
	Entry->Flink = ListHead;
	Entry->Blink = Blink;
	Blink->Flink = Entry;
	ListHead->Blink = Entry;
}

FORCEINLINE
	BOOLEAN
	RemoveEntryList(
	__in PLIST_ENTRY Entry
	)
{
	PLIST_ENTRY Blink;
	PLIST_ENTRY Flink;

	Flink = Entry->Flink;
	Blink = Entry->Blink;
	Blink->Flink = Flink;
	Flink->Blink = Blink;
	return (BOOLEAN)(Flink == Blink);
}

FORCEINLINE
	PLIST_ENTRY
	RemoveHeadList(
	__inout PLIST_ENTRY ListHead
	)
{
	PLIST_ENTRY Flink;
	PLIST_ENTRY Entry;

	Entry = ListHead->Flink;
	Flink = Entry->Flink;
	ListHead->Flink = Flink;
	Flink->Blink = ListHead;
	return Entry;
}

DWORD RunSysmonX64();


================================================
FILE: Sysmon/Sysmon.vcxproj
================================================
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ItemGroup Label="ProjectConfigurations">
    <ProjectConfiguration Include="Debug|Win32">
      <Configuration>Debug</Configuration>
      <Platform>Win32</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Debug|x64">
      <Configuration>Debug</Configuration>
      <Platform>x64</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Release|Win32">
      <Configuration>Release</Configuration>
      <Platform>Win32</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Release|x64">
      <Configuration>Release</Configuration>
      <Platform>x64</Platform>
    </ProjectConfiguration>
  </ItemGroup>
  <PropertyGroup Label="Globals">
    <ProjectGuid>{E64CC626-B5DB-47C9-93DD-D14F2F60B6C6}</ProjectGuid>
    <Keyword>Win32Proj</Keyword>
    <RootNamespace>Sysmon</RootNamespace>
  </PropertyGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
    <ConfigurationType>Application</ConfigurationType>
    <UseDebugLibraries>true</UseDebugLibraries>
    <CharacterSet>Unicode</CharacterSet>
    <UseOfAtl>Static</UseOfAtl>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
    <ConfigurationType>Application</ConfigurationType>
    <UseDebugLibraries>true</UseDebugLibraries>
    <CharacterSet>Unicode</CharacterSet>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
    <ConfigurationType>Application</ConfigurationType>
    <UseDebugLibraries>false</UseDebugLibraries>
    <WholeProgramOptimization>true</WholeProgramOptimization>
    <CharacterSet>Unicode</CharacterSet>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
    <ConfigurationType>Application</ConfigurationType>
    <UseDebugLibraries>false</UseDebugLibraries>
    <WholeProgramOptimization>true</WholeProgramOptimization>
    <CharacterSet>Unicode</CharacterSet>
  </PropertyGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
  <ImportGroup Label="ExtensionSettings">
  </ImportGroup>
  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  </ImportGroup>
  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  </ImportGroup>
  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  </ImportGroup>
  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  </ImportGroup>
  <PropertyGroup Label="UserMacros" />
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
    <LinkIncremental>true</LinkIncremental>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
    <LinkIncremental>true</LinkIncremental>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
    <LinkIncremental>false</LinkIncremental>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
    <LinkIncremental>false</LinkIncremental>
    <TargetName>$(ProjectName)64</TargetName>
  </PropertyGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
    <ClCompile>
      <PrecompiledHeader>Use</PrecompiledHeader>
      <WarningLevel>Level3</WarningLevel>
      <Optimization>Disabled</Optimization>
      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;INITGUID;%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
      <ExceptionHandling>Async</ExceptionHandling>
    </ClCompile>
    <Link>
      <SubSystem>Windows</SubSystem>
      <GenerateDebugInformation>true</GenerateDebugInformation>
    </Link>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
    <ClCompile>
      <PrecompiledHeader>Use</PrecompiledHeader>
      <WarningLevel>Level3</WarningLevel>
      <Optimization>Disabled</Optimization>
      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
    </ClCompile>
    <Link>
      <SubSystem>Windows</SubSystem>
      <GenerateDebugInformation>true</GenerateDebugInformation>
    </Link>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
    <ClCompile>
      <WarningLevel>Level3</WarningLevel>
      <PrecompiledHeader>Use</PrecompiledHeader>
      <Optimization>MaxSpeed</Optimization>
      <FunctionLevelLinking>true</FunctionLevelLinking>
      <IntrinsicFunctions>true</IntrinsicFunctions>
      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;INITGUID;%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
    </ClCompile>
    <Link>
      <SubSystem>Windows</SubSystem>
      <GenerateDebugInformation>true</GenerateDebugInformation>
      <EnableCOMDATFolding>true</EnableCOMDATFolding>
      <OptimizeReferences>true</OptimizeReferences>
    </Link>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
    <ClCompile>
      <WarningLevel>Level3</WarningLevel>
      <PrecompiledHeader>Use</PrecompiledHeader>
      <Optimization>MaxSpeed</Optimization>
      <FunctionLevelLinking>true</FunctionLevelLinking>
      <IntrinsicFunctions>true</IntrinsicFunctions>
      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
    </ClCompile>
    <Link>
      <SubSystem>Windows</SubSystem>
      <GenerateDebugInformation>true</GenerateDebugInformation>
      <EnableCOMDATFolding>true</EnableCOMDATFolding>
      <OptimizeReferences>true</OptimizeReferences>
    </Link>
  </ItemDefinitionGroup>
  <ItemGroup>
    <None Include="ReadMe.txt" />
    <None Include="small.ico" />
    <None Include="Sysmon.ico" />
  </ItemGroup>
  <ItemGroup>
    <ClInclude Include="CDigitalSign.h" />
    <ClInclude Include="CDName.h" />
    <ClInclude Include="CEventLogger.h" />
    <ClInclude Include="CMofDataParser.h" />
    <ClInclude Include="CSsymonEtw.h" />
    <ClInclude Include="CSysmonDriverOpt.h" />
    <ClInclude Include="CSysmonMofData.h" />
    <ClInclude Include="CSysmonUtil.h" />
    <ClInclude Include="Resource.h" />
    <ClInclude Include="stdafx.h" />
    <ClInclude Include="Sysmon.h" />
    <ClInclude Include="targetver.h" />
    <ClInclude Include="undname.h" />
  </ItemGroup>
  <ItemGroup>
    <ClCompile Include="CDigitalSign.cpp" />
    <ClCompile Include="CDName.cpp" />
    <ClCompile Include="CEventLogger.cpp" />
    <ClCompile Include="CMofDataParser.cpp" />
    <ClCompile Include="CSsymonEtw.cpp" />
    <ClCompile Include="CSysmonDriverOpt.cpp" />
    <ClCompile Include="CSysmonMofData.cpp" />
    <ClCompile Include="CSysmonUtil.cpp" />
    <ClCompile Include="stdafx.cpp">
      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
    </ClCompile>
    <ClCompile Include="Sysmon.cpp" />
    <ClCompile Include="undname.cpp" />
  </ItemGroup>
  <ItemGroup>
    <ResourceCompile Include="Sysmon.rc" />
  </ItemGroup>
  <ItemGroup>
    <Midl Include="undname.idl" />
  </ItemGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
  <ImportGroup Label="ExtensionTargets">
  </ImportGroup>
</Project>

================================================
FILE: Sysmon/Sysmon.vcxproj.filters
================================================
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ItemGroup>
    <Filter Include="Source Files">
      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
    </Filter>
    <Filter Include="Header Files">
      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
    </Filter>
    <Filter Include="Resource Files">
      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
    </Filter>
  </ItemGroup>
  <ItemGroup>
    <None Include="ReadMe.txt" />
    <None Include="small.ico">
      <Filter>Resource Files</Filter>
    </None>
    <None Include="Sysmon.ico">
      <Filter>Resource Files</Filter>
    </None>
  </ItemGroup>
  <ItemGroup>
    <ClInclude Include="stdafx.h">
      <Filter>Header Files</Filter>
    </ClInclude>
    <ClInclude Include="targetver.h">
      <Filter>Header Files</Filter>
    </ClInclude>
    <ClInclude Include="Resource.h">
      <Filter>Header Files</Filter>
    </ClInclude>
    <ClInclude Include="Sysmon.h">
      <Filter>Header Files</Filter>
    </ClInclude>
    <ClInclude Include="CSysmonDriverOpt.h">
      <Filter>Header Files</Filter>
    </ClInclude>
    <ClInclude Include="CSsymonEtw.h">
      <Filter>Header Files</Filter>
    </ClInclude>
    <ClInclude Include="CSysmonUtil.h">
      <Filter>Header Files</Filter>
    </ClInclude>
    <ClInclude Include="CSysmonMofData.h">
      <Filter>Header Files</Filter>
    </ClInclude>
    <ClInclude Include="CMofDataParser.h">
      <Filter>Header Files</Filter>
    </ClInclude>
    <ClInclude Include="CDigitalSign.h">
      <Filter>Header Files</Filter>
    </ClInclude>
    <ClInclude Include="CEventLogger.h">
      <Filter>Header Files</Filter>
    </ClInclude>
    <ClInclude Include="CDName.h">
      <Filter>Header Files</Filter>
    </ClInclude>
    <ClInclude Include="undname.h">
      <Filter>Header Files</Filter>
    </ClInclude>
  </ItemGroup>
  <ItemGroup>
    <ClCompile Include="stdafx.cpp">
      <Filter>Source Files</Filter>
    </ClCompile>
    <ClCompile Include="Sysmon.cpp">
      <Filter>Source Files</Filter>
    </ClCompile>
    <ClCompile Include="CSysmonDriverOpt.cpp">
      <Filter>Source Files</Filter>
    </ClCompile>
    <ClCompile Include="CSsymonEtw.cpp">
      <Filter>Source Files</Filter>
    </ClCompile>
    <ClCompile Include="CSysmonUtil.cpp">
      <Filter>Source Files</Filter>
    </ClCompile>
    <ClCompile Include="CSysmonMofData.cpp">
      <Filter>Source Files</Filter>
    </ClCompile>
    <ClCompile Include="CMofDataParser.cpp">
      <Filter>Source Files</Filter>
    </ClCompile>
    <ClCompile Include="CDigitalSign.cpp">
      <Filter>Source Files</Filter>
    </ClCompile>
    <ClCompile Include="CEventLogger.cpp">
      <Filter>Source Files</Filter>
    </ClCompile>
    <ClCompile Include="CDName.cpp">
      <Filter>Source Files</Filter>
    </ClCompile>
    <ClCompile Include="undname.cpp">
      <Filter>Source Files</Filter>
    </ClCompile>
  </ItemGroup>
  <ItemGroup>
    <ResourceCompile Include="Sysmon.rc">
      <Filter>Resource Files</Filter>
    </ResourceCompile>
  </ItemGroup>
  <ItemGroup>
    <Midl Include="undname.idl">
      <Filter>Source Files</Filter>
    </Midl>
  </ItemGroup>
</Project>

================================================
FILE: Sysmon/Sysmon.vcxproj.user
================================================
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
    <LocalDebuggerCommandArguments>-n</LocalDebuggerCommandArguments>
    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
    <LocalDebuggerCommandArguments>sysmon.exe -i</LocalDebuggerCommandArguments>
    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
  </PropertyGroup>
</Project>

================================================
FILE: Sysmon/stdafx.cpp
================================================
// stdafx.cpp : source file that includes just the standard includes
// Sysmon.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information

#include "stdafx.h"

// TODO: reference any additional headers you need in STDAFX.H
// and not in this file


================================================
FILE: Sysmon/stdafx.h
================================================
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//

#pragma once

#include "targetver.h"

#define WIN32_LEAN_AND_MEAN             // Exclude rarely-used stuff from Windows headers
// Windows Header Files:
#include <windows.h>

// C RunTime Header Files
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>


// TODO: reference additional headers your program requires here


================================================
FILE: Sysmon/targetver.h
================================================
#pragma once

// Including SDKDDKVer.h defines the highest available Windows platform.

// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
#define _CRT_RAND_S  
#include <SDKDDKVer.h>


================================================
FILE: Sysmon/undname.cpp
================================================
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// This source code is licensed under Microsoft Shared Source License
// Version 1.0 for Windows CE.
// For a copy of the license visit http://go.microsoft.com/fwlink/?LinkId=3223.
//
//	Make sure all dependent defines exist and have a valid value
#include "stdafx.h"
// #ifndef	NO_COMPILER_NAMES
// #define	NO_COMPILER_NAMES	0
// #endif
// #ifndef VERS_32BIT
// #define VERS_32BIT	1
// #endif
// #ifndef PACK_SIZE
// #if !VERS_32BIT
// #define PACK_SIZE	2
// #elif defined(_X86_)
// #define PACK_SIZE	4
// #else
// #define PACK_SIZE	8
// #endif
// #endif
// //	Check for version inconsistancies, and setup version flags
// #ifdef	VERS_BSC
// #undef	NO_COMPILER_NAMES
// #define	NO_COMPILER_NAMES	1
// #pragma	inline_depth ( 3 )
// #pragma	check_stack ( off )
// #else
// #pragma	inline_depth ( 3 )
// #pragma	check_stack ( off )
// #endif
// #define	PURE	=0
// // #include	<stddef.h>
// #include	<stdlib.h>
// #include	"undname.h"
// #pragma warning(disable:4291)	// No matching operator delete
// class	DName;
// class	DNameNode;
// class	Replicator;
// class	HeapManager;
// class	UnDecorator;
// const	unsigned int	memBlockSize	= 508;	// A '512' byte block including the header
// class	HeapManager
// {
// private:
// 	Alloc_t	pOpNew;
// 	Free_t	pOpDelete;
// 	struct	Block
// 	{
// 		Block *	next;
// 		char	memBlock[ memBlockSize ];
// 		__near	Block ()	{	next	= 0;	}
// 	};
// 	Block *	head;
// 	Block *	tail;
// 	unsigned int	blockLeft;
// public:
// 	void	__near	Constructor ( Alloc_t pAlloc, Free_t pFree )
// 	{	pOpNew	= pAlloc;
// 	pOpDelete	= pFree;
// 	blockLeft	= 0;
// 	head	= 0;
// 	tail	= 0;
// 	}
// 	void __far *	__near	getMemory ( unsigned int, int );
// 	void	__near	Destructor ( void )
// 	{	if	( pOpDelete != 0 )
// 	while	( tail = head )
// 	{
// 		head	= tail->next;
// 		( *pOpDelete )( tail );
// 	}
// 	}
// #define	gnew	new(heap,0)
// #define	rnew	new(heap,1)
// };
// void   *	__near __pascal	operator new ( unsigned int, HeapManager &, int = 0 );
// static	HeapManager	heap;
// //	The MS Token table
// enum	Tokens
// {
// #if !VERS_32BIT
// 	TOK_near,
// 	TOK_nearSp,
// 	TOK_nearP,
// 	TOK_far,
// 	TOK_farSp,
// 	TOK_farP,
// 	TOK_huge,
// 	TOK_hugeSp,
// 	TOK_hugeP,
// #endif
// 	TOK_basedLp,
// 	TOK_cdecl,
// 	TOK_pascal,
// 	TOK_stdcall,
// 	TOK_thiscall,
// 	TOK_fastcall,
// 	TOK_cocall,
// 	TOK_ptr64,
// 	TOK_restrict,
// #if !VERS_32BIT
// 	TOK_interrupt,
// 	TOK_saveregs,
// 	TOK_self,
// 	TOK_segment,
// 	TOK_segnameLpQ,
// #endif
// 	TOK__last
// };
// static	const pcchar_t	__near	tokenTable[]	=
// {
// #if !VERS_32BIT
// 	"__near",	// TOK_near
// 	"__near ",	// TOK_nearSp
// 	"__near*",	// TOK_nearP
// 	"__far",	// TOK_far
// 	"__far ",	// TOK_farSp
// 	"__far*",	// TOK_farP
// 	"__huge",	// TOK_huge
// 	"__huge ",	// TOK_hugeSp
// 	"__huge*",	// TOK_hugeP
// #endif
// 	"__based(",	// TOK_basedLp
// 	"__cdecl",	// TOK_cdecl
// 	"__pascal",	// TOK_pascal
// 	"__stdcall",	// TOK_stdcall
// 	"__thiscall",	// TOK_thiscall
// 	"__fastcall",	// TOK_fastcall
// 	"__cocall",	// TOK_cocall
// 	"__ptr64",	// TOK_ptr64
// 	"__restrict",	// TOK_restrict
// #if !VERS_32BIT
// 	"__interrupt",	// TOK_interrupt
// 	"__saveregs",	// TOK_saveregs
// 	"__self",	// TOK_self
// 	"__segment",	// TOK_segment
// 	"__segname("",	// TOK_segnameLpQ
// #endif
// 	""
// };
// //	The operator mapping table
// static	const pcchar_t	__near	nameTable[]	=
// {
// 	" new",
// 	" delete",
// 	"=",
// 	">>",
// 	"<<",
// 	"!",
// 	"==",
// 	"!=",
// 	"[]",
// 	"operator",
// 	"->",
// 	"*",
// 	"++",
// 	"--",
// 	"-",
// 	"+",
// 	"&",
// 	"->*",
// 	"/",
// 	"%",
// 	"<",
// 	"<=",
// 	">",
// 	">=",
// 	",",
// 	"()",
// 	"~",
// 	"^",
// 	"|",
// 	"&&",
// 	"||",
// 	"*=",
// 	"+=",
// 	"-=",
// 	"/=",
// 	"%=",
// 	">>=",
// 	"<<=",
// 	"&=",
// 	"|=",
// 	"^=",
// #if	( !NO_COMPILER_NAMES )
// 	"`vftable'",
// 	"`vbtable'",
// 	"`vcall'",
// 	"`typeof'",
// 	"`local static guard'",
// 	"`string'",
// 	"`vbase destructor'",
// 	"`vector deleting destructor'",
// 	"`default constructor closure'",
// 	"`scalar deleting destructor'",
// 	"`vector constructor iterator'",
// 	"`vector destructor iterator'",
// 	"`vector vbase constructor iterator'",
// 	"`virtual displacement map",
// 	"`eh vector constructor iterator'",
// 	"`eh vector destructor iterator'",
// 	"`eh vector vbase constructor iterator'",
// 	"`copy constructor closure'",
// 	"`udt returning'",
// 	"`EH", //eh initialized struct
// 	"`RTTI", //rtti initialized struct
// 	"`local vftable'",
// 	"`local vftable constructor closure'",
// #endif	// !NO_COMPILER_NAMES
// 	" new[]",
// 	" delete[]",
// #if ( !NO_COMPILER_NAMES )
// 	"`omni callsig'",
// 	"`placement delete closure'",
// 	"`placement delete[] closure'",
// #endif
// 	""
// };
// static const pcchar_t __near ehTable[] =
// {
// 	" Ptr to Member Data'",
// 	" Catchable Type'",
// 	" Catchable Type Array'",
// 	" ThrowInfo'",
// };
// static const pcchar_t __near rttiTable[] =
// {
// 	" Type Descriptor'",
// 	" Base Class Descriptor at (",
// 	" Base Class Array'",
// 	" Class Hierarchy Descriptor'",
// 	" Complete Object Locator'",
// };
// //	The following 'enum' should really be nested inside 'class DName', but to
// //	make the code compile better with Glockenspiel, I have extracted it
// enum	DNameStatus
// {
// 	DN_valid,
// 	DN_invalid,
// 	DN_truncated,
// 	DN_error
// };
// class	DName
// {
// public:
// 	__near	DName ();
// 	__near	DName ( char );
// #if	1
// 	__near	DName ( const DName & );	// Shallow copy
// #endif
// 	__near	DName ( DNameNode * );
// 	__near	DName ( pcchar_t );
// 	__near	DName ( pcchar_t&, char );
// 	__near	DName ( DNameStatus );
// 	__near	DName ( DName * );
// 	__near	DName ( unsigned long );
// 	int	__near	isValid () const;
// 	int	__near	isEmpty () const;
// 	DNameStatus	__near	status () const;
// 	DName &	__near	setPtrRef ();
// 	int	__near	isPtrRef () const;
// 	int	__near	isUDC () const;
// 	void	__near	setIsUDC ();
// 	int	__near	isUDTThunk () const;
// 	void	__near	setIsUDTThunk ();
// 	int	isNoTE () const;
// 	void	setIsNoTE ();
// 	int	__near	length () const;
// 	char	__near	getLastChar () const;
// 	pchar_t	__near	getString ( pchar_t, int ) const;
// 	DName	__near	operator + ( pcchar_t ) const;
// 	DName	__near	operator + ( const DName & ) const;
// 	DName	__near	operator + ( char ) const;
// 	DName	__near	operator + ( DName * ) const;
// 	DName	__near	operator + ( DNameStatus ) const;
// 	DName &	__near	operator += ( char );
// 	DName &	__near	operator += ( pcchar_t );
// 	DName &	__near	operator += ( DName * );
// 	DName &	__near	operator += ( DNameStatus );
// 	DName &	__near	operator += ( const DName & );
// 	DName &	__near	operator |= ( const DName & );
// 	DName &	__near	operator = ( pcchar_t );
// 	DName &	__near	operator = ( const DName & );
// 	DName &	__near	operator = ( char );
// 	DName &	__near	operator = ( DName * );
// 	DName &	__near	operator = ( DNameStatus );
// 	//	Friends :
// 	friend	DName	__near __pascal	operator + ( char, const DName & );
// 	friend	DName	__near __pascal	operator + ( pcchar_t, const DName & );
// 	friend	DName	__near __pascal	operator + ( DNameStatus, const DName & );
// private:
// 	DNameNode *	node;
// 	DNameStatus	stat	: 4;
// 	unsigned int	isIndir	: 1;
// 	unsigned int	isAUDC	: 1;
// 	unsigned int	isAUDTThunk	: 1;
// 	unsigned int	NoTE	: 1;
// 	void	__near	doPchar ( pcchar_t, int );
// };
// class	Replicator
// {
// private:
// 	//	Declare, in order to suppress automatic generation
// 	void	operator = ( const Replicator& );
// 	int	index;
// 	DName *	dNameBuffer[ 10 ];
// 	const DName	ErrorDName;
// 	const DName	InvalidDName;
// public:
// 	__near	Replicator ();
// 	int	__near	isFull () const;
// 	Replicator &	__near	operator += ( const DName & );
// 	const DName &	__near	operator [] ( int ) const;
// };
// class	UnDecorator
// {
// private:
// 	//	Declare, in order to suppress automatic generation
// 	void	operator = ( const UnDecorator& );
// 	Replicator	ArgList;
// 	static	Replicator *	pArgList;
// 	Replicator	ZNameList;
// 	static	Replicator *	pZNameList;
// 	static	Replicator *	pTemplateArgList;
// 	static	pcchar_t	gName;
// 	static	pcchar_t	name;
// 	static	pchar_t	outputString;
// 	static	int	maxStringLength;
// 	static	unsigned long	disableFlags;
// 	static	DName	__near	getDecoratedName ( void );
// 	static	DName	__near	getSymbolName ( void );
// 	static	DName	__near	getZName ( void );
// 	static	DName	__near	getOperatorName ( void );
// 	static	DName	__near	getScope ( void );
// 	static	DName	getScopedName ( void );
// 	static	DName	__near	getSignedDimension ( void );
// 	static	DName	__near	getDimension ( void );
// 	static	int	__near	getNumberOfDimensions ( void );
// 	static	DName	__near	getTemplateName ( void );
// 	static	DName	__near	getTemplateArgumentList( void );
// 	static	DName	__near	getTemplateConstant( void );
// 	static	DName	__near	composeDeclaration ( const DName & );
// 	static	int	__near	getTypeEncoding ( void );
// 	static	DName	__near	getBasedType ( void );
// 	static	DName	__near	getECSUName ( void );
// 	static	DName	__near	getEnumType ( void );
// 	static	DName	__near	getCallingConvention ( void );
// 	static	DName	__near	getReturnType ( DName * = 0 );
// 	static	DName	__near	getDataType ( DName * );
// 	static	DName	__near	getPrimaryDataType ( const DName & );
// 	static	DName	__near	getDataIndirectType ( const DName &, char, const DName &, int = FALSE );
// 	static	DName	__near	getDataIndirectType ();
// 	static	DName	__near	getBasicDataType ( const DName & );
// 	static	DName	__near	getECSUDataType ( void );
// 	static	DName	__near	getPtrRefType ( const DName &, const DName &, int );
// 	static	DName	__near	getPtrRefDataType ( const DName &, int );
// 	static	DName	__near	getArrayType ( const DName& );
// 	static	DName	getFunctionIndirectType( const DName & superType );
// 	static	DName	__near	getArgumentTypes ( void );
// 	static	DName	__near	getArgumentList ( void );
// 	static	DName	__near	getThrowTypes ( void );
// 	static	DName	__near	getLexicalFrame ( void );
// 	static	DName	__near	getStorageConvention ( void );
// 	static	DName	__near	getThisType ( void );
// 	static	DName	__near	getPointerType ( const DName &, const DName & );
// 	static	DName	__near	getReferenceType ( const DName &, const DName & );
// 	static	DName	__near	getExternalDataType ( const DName & );
// 	static	DName	__near	getSegmentName ( void );
// #if	( !NO_COMPILER_NAMES )
// 	static	DName	__near	getDisplacement ( void );
// 	static	DName	__near	getCallIndex ( void );
// 	static	DName	__near	getGuardNumber ( void );
// 	static	DName	__near	getVfTableType ( const DName & );
// 	static	DName	__near	getVbTableType ( const DName & );
// 	static	DName	__near	getVCallThunkType ( void );
// #endif	// !NO_COMPILER_NAMES
// 	static	DName	getStringEncoding ( char *prefix, int wantBody );
// 	static GetParameter_t m_pGetParameter;
// public:
// 	__near	UnDecorator ( pchar_t, pcchar_t, int, GetParameter_t, unsigned long );
// 	static	int	__near	doUnderScore ();
// 	static	int	__near	doMSKeywords ();
// 	static	int	__near	doFunctionReturns ();
// 	static	int	__near	doAllocationModel ();
// 	static	int	__near	doAllocationLanguage ();
// #if	0
// 	static	int	__near	doMSThisType ();
// 	static	int	__near	doCVThisType ();
// #endif
// 	static	int	__near	doThisTypes ();
// 	static	int	__near	doAccessSpecifiers ();
// 	static	int	__near	doThrowTypes ();
// 	static	int	__near	doMemberTypes ();
// 	static	int	__near	doReturnUDTModel ();
// 	static	int	__near	do32BitNear ();
// 	static	int	__near	doNameOnly ();
// 	static	int	__near	doTypeOnly ();
// 	static	int	__near	haveTemplateParameters ();
// 	static	int	__near	doEcsu ();
// 	static	int	__near	doNoIdentCharCheck ();
// 	static	pcchar_t	__near	UScore ( Tokens );
// 	__near	operator pchar_t ();
// };
// Replicator *	UnDecorator::pArgList;
// Replicator *	UnDecorator::pZNameList	= 0;
// Replicator *	UnDecorator::pTemplateArgList	= 0;
// pcchar_t	UnDecorator::gName	= 0;
// pcchar_t	UnDecorator::name	= 0;
// pchar_t	UnDecorator::outputString	= 0;
// int	UnDecorator::maxStringLength	= 0;
// unsigned long	UnDecorator::disableFlags	= 0;
// GetParameter_t	UnDecorator::m_pGetParameter	= 0;
// // #ifdef _CRTBLD
// pchar_t	__far _CRTIMP __loadds	__unDName (	pchar_t outputString,
// 	// #else
// 	// pchar_t	__far __cdecl __loadds	unDName (	pchar_t outputString,
// 	// #endif
// 	pcchar_t name,
// 	int maxStringLength,	// Note, COMMA is leading following optional arguments
// 	Alloc_t pAlloc,
// 	Free_t pFree,
// 	unsigned short disableFlags
// 	)
// 	/*
// 	*	This function will undecorate a name, returning the string corresponding to
// 	*	the C++ declaration needed to produce the name.  Its has a similar interface
// 	*	to 'strncpy'.
// 	*
// 	*	If the target string 'outputString' is specified to be NULL, a string of
// 	*	suitable length will be allocated and its address returned.  If the returned
// 	*	string is allocated by 'unDName', then it is the programmers responsibility
// 	*	to deallocate it.  It will have been allocated on the far heap.
// 	*
// 	*	If the target string is not NULL, then the parameter 'maxStringLength' will
// 	*	specify the maximum number of characters which may be placed in the string.
// 	*	In this case, the returned value is the same as 'outputString'.
// 	*
// 	*	Both the input parameter 'name' and the returned string are NULL terminated
// 	*	strings of characters.
// 	*
// 	*	If the returned value is NULL, it indicates that the undecorator ran out of
// 	*	memory, or an internal error occurred, and was unable to complete its task.
// 	*/
// {
// 	//	Must have an allocator and a deallocator (and we MUST trust them)
// 	if	( !( pAlloc ))
// 		return	0;
// 	else
// 		heap.Constructor ( pAlloc, pFree );
// 	//	Create the undecorator object, and get the result
// 	UnDecorator	unDecorate (	outputString,
// 		name,
// 		maxStringLength,
// 		0,
// 		disableFlags
// 		);
// 	pchar_t	unDecoratedName	= unDecorate;
// 	// Destruct the heap (would use a destructor, but that causes DLL problems)
// 	heap.Destructor ();
// 	//	And return the composed name
// 	return	unDecoratedName;
// }	// End of FUNCTION "unDName"
// // #ifdef _CRTBLD
// pchar_t	__far _CRTIMP __loadds	__unDNameEx (	pchar_t outputString,
// 	// #else
// 	// pchar_t	__far __cdecl __loadds	unDNameEx (	pchar_t outputString,
// 	// #endif
// 	pcchar_t name,
// 	int maxStringLength,	// Note, COMMA is leading following optional arguments
// 	Alloc_t pAlloc,
// 	Free_t pFree,
// 	GetParameter_t pGetParameter,
// 	unsigned long disableFlags
// 	)
// 	/*
// 	*	This function will undecorate a name, returning the string corresponding to
// 	*	the C++ declaration needed to produce the name.  Its has a similar interface
// 	*	to 'strncpy'.
// 	*
// 	*	If the target string 'outputString' is specified to be NULL, a string of
// 	*	suitable length will be allocated and its address returned.  If the returned
// 	*	string is allocated by 'unDName', then it is the programmers responsibility
// 	*	to deallocate it.  It will have been allocated on the far heap.
// 	*
// 	*	If the target string is not NULL, then the parameter 'maxStringLength' will
// 	*	specify the maximum number of characters which may be placed in the string.
// 	*	In this case, the returned value is the same as 'outputString'.
// 	*
// 	*	Both the input parameter 'name' and the returned string are NULL terminated
// 	*	strings of characters.
// 	*
// 	*	If the returned value is NULL, it indicates that the undecorator ran out of
// 	*	memory, or an internal error occurred, and was unable to complete its task.
// 	*/
// {
// 	//	Must have an allocator and a deallocator (and we MUST trust them)
// 	if	( !( pAlloc ))
// 		return	0;
// 	else
// 		heap.Constructor ( pAlloc, pFree );
// 	//	Create the undecorator object, and get the result
// 	UnDecorator	unDecorate (	outputString,
// 		name,
// 		maxStringLength,
// 		pGetParameter,
// 		disableFlags
// 		);
// 	pchar_t	unDecoratedName	= unDecorate;
// 	// Destruct the heap (would use a destructor, but that causes DLL problems)
// 	heap.Destructor ();
// 	//	And return the composed name
// 	return	unDecoratedName;
// }	// End of FUNCTION "unDName"
// //	The 'UnDecorator' member functions
// inline	__near	UnDecorator::UnDecorator	(	pchar_t output,
// 	pcchar_t dName,
// 	int maxLen,
// 	GetParameter_t pGetParameter,
// 	unsigned long disable
// 	)
// {
// 	name	= dName;
// 	gName	= name;
// 	if	( output ) {
// 		maxStringLength	= maxLen - 1;	// The algorithm in getString doesn't leave room
// 		// for terminating NULL; be paranoid and leave one
// 		// extra char.
// 		// It's a lot easier to fix this here....
// 		outputString	= output;
// 	}
// 	else {
// 		outputString	= 0;
// 		maxStringLength	= 0;
// 	}
// 	pZNameList	= &ZNameList;
// 	pArgList	= &ArgList;
// 	disableFlags	= disable;
// 	m_pGetParameter	= pGetParameter;
// }	// End of "UnDecorator" CONSTRUCTOR '()'
// inline	__near	UnDecorator::operator pchar_t ()
// {
// 	DName	result;
// 	DName	unDName;
// 	//	Find out if the name is a decorated name or not.  Could be a reserved
// 	//	CodeView variant of a decorated name
// 	if	( name )
// 	{
// 		if	(( *name == '?' ) && ( name[ 1 ] == '@' ))
// 		{
// #if	( !NO_COMPILER_NAMES )
// 			gName	+= 2;
// 			result	= "CV: " + getDecoratedName ();
// #else	// } elif NO_COMPILER_NAMES
// 			result	= DN_invalid;
// #endif	// NO_COMPILER_NAMES
// 		}	// End of IF then
// 		elif	(( *name == '?' ) && ( name[1] == '$' ))
// 			result	= getTemplateName ();
// 		else
// 			result	= getDecoratedName ();
// 	}	// End of IF then
// 	//	If the name was not a valid name, then make the name the same as the original
// 	//	It is also invalid if there are any remaining characters in the name (except when
// 	//	we're giving the name only)
// 	if	( result.status () == DN_error )
// 		return	0;
// 	elif	( (*gName && !doNameOnly ()) || ( result.status () == DN_invalid ))
// 		unDName	= name;	// Return the original name
// 	else
// 		unDName	= result;
// 	//	Construct the return string
// 	if	( !outputString )
// 	{
// 		maxStringLength	= unDName.length () + 1;
// 		outputString 	= rnew char[ maxStringLength ];
// 	}	// End of IF
// 	if	( outputString )
// 		unDName.getString ( outputString, maxStringLength );
// 	//	Return the result
// 	return	outputString;
// }	// End of "UnDecorator" OPERATOR 'pchar_t'
// DName	__near	UnDecorator::getDecoratedName ( void )
// {
// 	//	Ensure that it is intended to be a decorated name
// 	if	( doTypeOnly() )
// 	{
// 		// Disable the type-only flag, so that if we get here recursively, eg.
// 		// in a template tag, we do full name undecoration.
// 		disableFlags &= ~UNDNAME_TYPE_ONLY;
// 		// If we're decoding just a type, process it as the type for an abstract
// 		// declarator, by giving an empty symbol name.
// 		DName	result = getDataType ( NULL );
// 		disableFlags |= UNDNAME_TYPE_ONLY;
// 		return result;
// 	}
// 	elif	( *gName == '?' )
// 	{
// 		//	Extract the basic symbol name
// 		gName++;	// Advance the original name pointer
// 		DName	symbolName	= getSymbolName ();
// 		int	udcSeen	= symbolName.isUDC ();
// 		//	Abort if the symbol name is invalid
// 		if	( !symbolName.isValid ())
// 			return	symbolName;
// 		//	Extract, and prefix the scope qualifiers
// 		if	( *gName && ( *gName != '@' )) {
// 			DName	scope = getScope ();
// 			if	( !scope.isEmpty() )
// 				symbolName	= scope + "::" + symbolName;
// 		}
// 		if	( udcSeen )
// 			symbolName.setIsUDC ();
// 		//	Now compose declaration
// 		if	( symbolName.isEmpty () || symbolName.isNoTE() )
// 		{
// 			return	symbolName;
// 		}
// 		elif	( !*gName || ( *gName == '@' ) )
// 		{
// 			if	( *gName )
// 				gName++;
// 			if	(doNameOnly () && !udcSeen) {
// 				// Eat the rest of the dname, in case this is a recursive invocation,
// 				// such as for a template argument.
// 				(void)composeDeclaration( DName() );
// 				return symbolName;
// 			}
// 			else {
// 				return	composeDeclaration ( symbolName );
// 			}
// 		}	// End of ELIF then
// 		else
// 			return	DN_invalid;
// 	}	// End of IF then
// 	elif	( *gName )
// 		return	DN_invalid;
// 	else
// 		return	DN_truncated;
// }	// End of "UnDecorator" FUNCTION "getDecoratedName"
// inline	DName	__near	UnDecorator::getSymbolName ( void )
// {
// 	if	( *gName == '?' )
// 	{
// 		gName++;
// 		return	getOperatorName ();
// 	}	// End of IF then
// 	else
// 		return	getZName ();
// }	// End of "UnDecorator" FUNCTION "getSymbolName"
// DName	__near	UnDecorator::getZName ( void )
// {
// 	int	zNameIndex	= *gName - '0';
// 	//	Handle 'zname-replicators', otherwise an actual name
// 	if	(( zNameIndex >= 0 ) && ( zNameIndex <= 9 ))
// 	{
// 		gName++;	// Skip past the replicator
// 		//	And return the indexed name
// 		return	( *pZNameList )[ zNameIndex ];
// 	}	// End of IF then
// 	else
// 	{
// 		DName	zName;
// 		if	( *gName == '?' )
// 		{
// 			zName	= getTemplateName ();
// 			if	( *gName++ != '@' )
// 				zName	= *--gName ? DN_invalid : DN_truncated;
// 		}
// 		else
// 			//	Extract the 'zname' to the terminator
// 			zName	= DName( gName, '@' );	// This constructor updates 'name'
// 		//	Add it to the current list of 'zname's
// 		if	( !pZNameList->isFull ())
// 			*pZNameList	+= zName;
// 		//	And return the symbol name
// 		return	zName;
// 	}	// End of IF else
// }	// End of "UnDecorator" FUNCTION "getZName"
// inline	DName	__near	UnDecorator::getOperatorName ( void )
// {
// 	DName	operatorName;
// 	DName	tmpName;
// 	int	udcSeen	= FALSE;
// 	//	So what type of operator is it ?
// 	switch	( *gName++ )
// 	{
// 	case 0:
// 		gName--;	// End of string, better back-track
// 		return	DN_truncated;
// 	case OC_ctor:
// 	case OC_dtor:
// 		//
// 		// The constructor and destructor are special:
// 		// Their operator name is the name of their first enclosing scope, which
// 		// will always be a tag, which may be a template specialization!
// 		//
// 		{
// 			//	Use a temporary.  Don't want to advance the name pointer
// 			pcchar_t	pName	= gName;
// 			operatorName	= getZName ();
// 			gName = pName;	// Undo our lookahead
// 			if	( !operatorName.isEmpty () && ( gName[ -1 ] == OC_dtor ))
// 				operatorName	= '~' + operatorName;
// 			return	operatorName;
// 		}	// End of CASE 'OC_ctor,OC_dtor'
// 		break;
// 	case OC_new:
// 	case OC_delete:
// 	case OC_assign:
// 	case OC_rshift:
// 	case OC_lshift:
// 	case OC_not:
// 	case OC_equal:
// 	case OC_unequal:
// 		operatorName	= nameTable[ gName[ -1 ] - OC_new ];
// 		break;
// 	case OC_udc:
// 		udcSeen	= TRUE;
// 		//	No break
// 	case OC_index:
// 	case OC_pointer:
// 	case OC_star:
// 	case OC_incr:
// 	case OC_decr:
// 	case OC_minus:
// 	case OC_plus:
// 	case OC_amper:
// 	case OC_ptrmem:
// 	case OC_divide:
// 	case OC_modulo:
// 	case OC_less:
// 	case OC_leq:
// 	case OC_greater:
// 	case OC_geq:
// 	case OC_comma:
// 	case OC_call:
// 	case OC_compl:
// 	case OC_xor:
// 	case OC_or:
// 	case OC_land:
// 	case OC_lor:
// 	case OC_asmul:
// 	case OC_asadd:
// 	case OC_assub:	// Regular operators from the first group
// 		operatorName	= nameTable[ gName[ -1 ] - OC_index + ( OC_unequal - OC_new + 1 )];
// 		break;
// 	case '_':
// 		switch	( *gName++ )
// 		{
// 		case 0:
// 			gName--;	// End of string, better back-track
// 			return	DN_truncated;
// 		case OC_asdiv:
// 		case OC_asmod:
// 		case OC_asrshift:
// 		case OC_aslshift:
// 		case OC_asand:
// 		case OC_asor:
// 		case OC_asxor:	// Regular operators from the extended group
// 			operatorName	= nameTable[ gName[ -1 ] - OC_asdiv + ( OC_assub - OC_index + 1 ) + ( OC_unequal - OC_new + 1 )];
// 			break;
// #if	( !NO_COMPILER_NAMES )
// 		case OC_vftable:
// 		case OC_vbtable:
// 		case OC_vcall:
// 			return	nameTable[ gName[ -1 ] - OC_asdiv + ( OC_assub - OC_index + 1 ) + ( OC_unequal - OC_new + 1 )];
// 		case OC_string:
// 			{
// 				DName result = getStringEncoding( "`string'", TRUE );
// 				result.setIsNoTE();
// 				return result;
// 			}
// 		case OC_metatype:
// 		case OC_guard:
// 		case OC_vbdtor:
// 		case OC_vdeldtor:
// 		case OC_defctor:
// 		case OC_sdeldtor:
// 		case OC_vctor:
// 		case OC_vdtor:
// 		case OC_vallctor:
// 		case OC_ehvctor:
// 		case OC_ehvdtor:
// 		case OC_ehvctorvb:
// 		case OC_copyctorclosure:
// 		case OC_locvfctorclosure:
// 		case OC_locvftable:	// Special purpose names
// 		case OC_placementDeleteClosure:
// 		case OC_placementArrayDeleteClosure:
// 			return nameTable[ gName[ -1 ] - OC_metatype + ( OC_vcall - OC_asdiv + 1 ) + ( OC_assub - OC_index + 1 ) + ( OC_unequal - OC_new + 1 )];
// 		case OC_udtthunk:
// 			operatorName = nameTable[ gName[ -1 ] - OC_metatype + ( OC_vcall - OC_asdiv + 1 ) + ( OC_assub - OC_index + 1 ) + ( OC_unequal - OC_new + 1 )];
// 			tmpName 	= getOperatorName();
// 			if ( !tmpName.isEmpty() && tmpName.isUDTThunk() )
// 				return	DN_invalid;
// 			return operatorName + tmpName;
// 			break;
// 		case OC_eh_init:
// 			break;
// 		case OC_rtti_init:
// 			operatorName = nameTable[ gName[ -1 ] - OC_metatype + ( OC_vcall - OC_asdiv + 1 ) + ( OC_assub - OC_index + 1 ) + ( OC_unequal - OC_new + 1 )];
// 			tmpName = rttiTable[ gName[0] - OC_rtti_TD ];
// 			switch	( *gName++ )
// 			{
// 			case OC_rtti_TD:
// 				{
// 					DName	result = getDataType ( NULL );
// 					return result + ' ' + operatorName + tmpName;
// 				}
// 				break;
// 			case OC_rtti_BCD:
// 				{
// 					DName	result = operatorName + tmpName;
// 					result += getSignedDimension() + ',';
// 					result += getSignedDimension() + ',';
// 					result += getSignedDimension() + ',';
// 					result += getDimension() + ')';
// 					return result + ''';
// 				}
// 				break;
// 			case OC_rtti_BCA:
// 			case OC_rtti_CHD:
// 			case OC_rtti_COL:
// 				return operatorName + tmpName;
// 				break;
// 			default:
// 				gName--;
// 				return DN_truncated;
// 				break;
// 			}
// 			break;
// #endif	// !NO_COMPILER_NAMES
// 		case OC_arrayNew:
// 		case OC_arrayDelete:
// 			operatorName = nameTable[ gName[ -1 ] - OC_metatype + ( OC_vcall - OC_asdiv + 1 ) + ( OC_assub - OC_index + 1 ) + ( OC_unequal - OC_new + 1 )
// #if NO_COMPILER_NAMES
// 				- ( OC_locvfctorclosure - OC_vftable + 1 )	// discount names not in table
// #endif
// 			];
// 			break;
// 			// Yet another level of nested encodings....
// 		case '?':
// 			switch( *gName++ ) {
// 			case 0:
// 				gName--;	// End of string, better back-track
// 				return	DN_truncated;
// 			case OC_anonymousNamespace:
// 				//
// 				// Anonymous namespace (new-style) is a string encoding of the
// 				// machine name and the translation unit name.  Since the remainder
// 				// of the name doesn't really fit the dname grammar, skip it.
// 				// There are two '@' markers in the name....
// 				//
// 				{
// 					DName result = getStringEncoding( "`anonymous namespace'", FALSE );
// 					result.setIsNoTE();
// 					return result;
// 				}
// 			default:
// 				return	DN_invalid;
// 			}
// 			break;
// 		default:
// 			return	DN_invalid;
// 		}	// End of SWITCH
// 		break;
// 	default:
// 		return	DN_invalid;
// 	}	// End of SWITCH
// 	//	This really is an operator name, so prefix it with 'operator'
// 	if	( udcSeen )
// 		operatorName.setIsUDC ();
// 	elif	( !operatorName.isEmpty ())
// 		operatorName	= "operator" + operatorName;
// 	return	operatorName;
// }	// End of "UnDecorator" FUNCTION "getOperatorName"
// DName	UnDecorator::getStringEncoding ( char *prefix, int wantBody )
// {
// 	DName result = prefix;
// 	// First @ comes right after operator code
// 	if	( *gName++ != '@' || *gName++ != '_' ) {
// 		return DN_invalid;
// 	}
// 	// Skip the string kind
// 	*gName++;
// 	// Get (& discard) the length
// 	getDimension();
// 	// Get (& discart) the checksum
// 	getDimension();
// 	while ( *gName && *gName != '@' ) {
// 		// For now, we'll just skip it
// 		gName++;
// 	}
// 	if	( !*gName ) {
// 		gName--;
// 		return DN_truncated;
// 	}
// 	// Eat the terminating '@'
// 	gName++;
// 	return result;
// }
// DName	__near	UnDecorator::getScope ( void )
// {
// 	DName	scope;
// 	bool	fNeedBracket = false;
// 	//	Get the list of scopes
// 	while	(( scope.status () == DN_valid ) && *gName && ( *gName != '@' ))
// 	{	//	Insert the scope operator if not the first scope
// 		if	( !scope.isEmpty() ) {
// 			scope	= "::" + scope;
// 			if (fNeedBracket) {
// 				scope = '[' + scope;
// 				fNeedBracket = false;
// 			}
// 		}
// 		//	Determine what kind of scope it is
// 		if	( *gName == '?' )
// 			switch	( *++gName )
// 		{
// 			case '?':
// 				if	( gName[1] == '_' && gName[2] == '?' ) {
// 					//
// 					// Anonymous namespace name (new style)
// 					//
// 					gName++;
// 					scope = getOperatorName () + scope;
// 					// There should be a zname termination @...
// 					if	( *gName == '@' ) {
// 						gName++;
// 					}
// 				}
// 				else if	( !doNameOnly() )
// 					scope	= '`' + getDecoratedName () + ''' + scope;
// 				else
// 				getDecoratedName();	// Skip lexical scope info
// 				break;
// 			case '$':
// 				// It's a template name, which is a kind of zname; back up
// 				// and handle like a zname.
// 				gName--;
// 				scope	= getZName () + scope;
// 				break;
// 			case '%':
// 				//
// 				// It an anonymous namespace (old-style);
// 				// skip the (unreadable) name and instead insert
// 				// an appropriate string
// 				//
// 				while ( *gName != '@' ) {
// 					gName++;
// 				}
// 				gName++;
// 				scope = "`anonymous namespace'" + scope;
// 				break;
// 			case 'I':
// 				//
// 				// This is the interface whose method the class is
// 				// implementing
// 				//
// 				gName++;
// 				scope = getZName () + ']' + scope;
// 				fNeedBracket = true;
// 				break;
// 			default:
// 				if	( !doNameOnly() )
// 					scope	= getLexicalFrame () + scope;
// 				else
// 					getLexicalFrame();	// Skip lexical scope info
// 				break;
// 		}	// End of SWITCH
// 		else
// 			scope	= getZName () + scope;
// 	}	// End of WHILE
// 	//	Catch error conditions
// 	switch	( *gName )
// 	{
// 	case 0:
// 		if	( scope.isEmpty() )
// 			scope	= DN_truncated;
// 		else
// 			scope	= DName ( DN_truncated ) + "::" + scope;
// 		break;
// 	case '@':	// '@' expected to end the scope list
// 		break;
// 	default:
// 		scope	= DN_invalid;
// 		break;
// 	}	// End of SWITCH
// 	//	Return the composed scope
// 	return	scope;
// }	// End of "UnDecorator" FUNCTION "getScope"
// DName	__near	UnDecorator::getSignedDimension ( void )
// {
// 	if	( !*gName )
// 		return	DN_truncated;
// 	elif	( *gName == '?' ) {
// 		gName++;	// skip the '?'
// 		return	'-' + getDimension();
// 	}
// 	else
// 		return	getDimension();
// }	// End of "Undecorator" FUNCTION "getSignedDimension"
// DName	__near	UnDecorator::getDimension ( void )
// {
// 	if	( !*gName )
// 		return	DN_truncated;
// 	elif	(( *gName >= '0' ) && ( *gName <= '9' ))
// 		return	DName ((unsigned long)( *gName++ - '0' + 1 ));
// 	else
// 	{
// 		unsigned long	dim	= 0L;
// 		//	Don't bother detecting overflow, it's not worth it
// 		while	( *gName != '@' )
// 		{
// 			if	( !*gName )
// 				return	DN_truncated;
// 			elif	(( *gName >= 'A' ) && ( *gName <= 'P' ))
// 				dim	= ( dim << 4 ) + ( *gName - 'A' );
// 			else
// 				return	DN_invalid;
// 			gName++;
// 		}	// End of WHILE
// 		//	Ensure integrity, and return
// 		if	( *gName++ != '@' )
// 			return	DN_invalid;	// Should never get here
// 		return	dim;
// 	}	// End of ELIF else
// }	// End of "UnDecorator" FUNCTION "getDimension"
// int	__near	UnDecorator::getNumberOfDimensions ( void )
// {
// 	if	( !*gName )
// 		return	0;
// 	elif	(( *gName >= '0' ) && ( *gName <= '9' ))
// 		return	(( *gName++ - '0' ) + 1 );
// 	else
// 	{
// 		int	dim	= 0;
// 		//	Don't bother detecting overflow, it's not worth it
// 		while	( *gName != '@' )
// 		{
// 			if	( !*gName )
// 				return	0;
// 			elif	(( *gName >= 'A' ) && ( *gName <= 'P' ))
// 				dim	= ( dim << 4 ) + ( *gName - 'A' );
// 			else
// 				return	-1;
// 			gName++;
// 		}	// End of WHILE
// 		//	Ensure integrity, and return
// 		if	( *gName++ != '@' )
// 			return	-1;	// Should never get here
// 		return	dim;
// 	}	// End of ELIF else
// }	// End of "UnDecorator" FUNCTION "getNumberOfDimensions"
// DName	__near	UnDecorator::getTemplateName ( void )
// {
// 	//
// 	// First make sure we're really looking at a template name
// 	//
// 	if	( gName[0] != '?' || gName[1] != '$' )
// 		return DN_invalid;
// 	gName += 2;	// Skip the marker characters
// 	//
// 	// Stack the replicators, since template names are their own replicator scope:
// 	//
// 	Replicator * pSaveArgList 	= pArgList;
// 	Replicator * pSaveZNameList 	= pZNameList;
// 	Replicator * pSaveTemplateArgList 	= pTemplateArgList;
// 	Replicator localArgList, localZNameList, localTemplateArgList;
// 	pArgList 	= &localArgList;
// 	pZNameList 	= &localZNameList;
// 	pTemplateArgList 	= &localTemplateArgList;
// 	//
// 	// Crack the template name:
// 	//
// 	DName	templateName	= getZName ();
// 	if	( !templateName.isEmpty ())
// 	{
// 		templateName	+= '<' + getTemplateArgumentList ();
// 		if	( templateName.getLastChar () == '>' )
// 			templateName += ' ';
// 		templateName	+= '>';
// 	}
// 	//
// 	// Restore the previous replicators:
// 	//
// 	pArgList	= pSaveArgList;
// 	pZNameList	= pSaveZNameList;
// 	pTemplateArgList	= pSaveTemplateArgList;
// 	//	Return the completed 'template-name'
// 	return	templateName;
// }	// End of "UnDecorator" FUNCTION "getTemplateName"
// DName	__near	UnDecorator::getTemplateArgumentList ( void )
// {
// 	int	first	= TRUE;
// 	DName	aList;
// 	while	(( aList.status () == DN_valid ) && *gName && ( *gName != AT_endoflist ))
// 	{
// 		//	Insert the argument list separator if not the first argument
// 		if	( first )
// 			first	= FALSE;
// 		else
// 			aList	+= ',';
// 		//	Get the individual argument type
// 		int	argIndex	= *gName - '0';
// 		//	Handle 'template-argument-replicators', otherwise a new argument type
// 		if	(( argIndex >= 0 ) && ( argIndex <= 9 ))
// 		{
// 			gName++;	// Skip past the replicator
// 			//	Append to the argument list
// 			aList	+= ( *pTemplateArgList )[ argIndex ];
// 		}	// End of IF then
// 		else
// 		{
// 			pcchar_t	oldGName	= gName;
// 			DName	arg;
// 			//
// 			//	Extract the 'argument' type
// 			//
// 			if	( *gName == DT_void ) {
// 				gName++;
// 				arg = "void";
// 			} 
// 			elif ( (*gName == '$') && (gName[1] != '$')) {
// 				gName++;
// 				arg = getTemplateConstant();
// 			}
// 			elif ( *gName == '?' ) {
// 				//
// 				// This is a template-parameter, i.e. we have a "specialization" of
// 				// X<T>. so get the template-parameter-index and use a "generic" name
// 				// for this parameter
// 				//
// 				DName dimension = getSignedDimension();
// 				if ( haveTemplateParameters()) {
// 					char buffer[16];
// 					dimension.getString( buffer, 16 );
// 					char *str = (*m_pGetParameter)(atol(buffer));
// 					if ( str != NULL ) {
// 						arg = str;
// 					}
// 					else {
// 						arg = "`template-parameter" + dimension + "'";
// 					}
// 				}
// 				else {
// 					arg = "`template-parameter" + dimension + "'";
// 				}
// 			}
// 			else {
// 				arg = getPrimaryDataType ( DName() );
// 			}
// 			//	Add it to the current list of 'template-argument's, if it is bigger than a one byte encoding
// 			if	((( gName - oldGName ) > 1 ) && !pTemplateArgList->isFull ())
// 				*pTemplateArgList	+= arg;
// 			//	Append to the argument list
// 			aList	+= arg;
// 		}	// End of IF else
// 	}	// End of WHILE
// 	//	Return the completed template argument list
// 	return	aList;
// }	// End of "UnDecorator" FUNCTION "getTemplateArgumentList"
// DName	__near	UnDecorator::getTemplateConstant(void)
// {
// 	//
// 	// template-constant ::=
// 	//	'0'	<template-integral-constant>
// 	//	'1' <template-address-constant>
// 	//	'2' <template-floating-point-constant>
// 	//
// 	switch ( *gName++ )
// 	{
// 		//
// 		// template-integral-constant ::=
// 		//	<signed-dimension>
// 		//
// 	case TC_integral:
// 		return 	getSignedDimension ();
// 		//
// 		// template-address-constant ::=
// 		//	'@'	// Null pointer
// 		//	<decorated-name>
// 		//
// 	case TC_address:
// 		if 	( *gName == TC_nullptr )
// 		{
// 			gName++;
// 			return	"NULL";
// 		}
// 		else
// 			return	DName("&") + getDecoratedName ();
// 	case TC_name:
// 		return getDecoratedName ();
// 		//
// 		// template-floating-point-constant ::=
// 		//	<normalized-mantissa><exponent>
// 		//
// 	case TC_fp:
// 		{
// 			DName	mantissa ( getSignedDimension () );
// 			DName	exponent ( getSignedDimension () );
// 			if	( mantissa.isValid() && exponent.isValid() )
// 			{
// 				//
// 				// Get string representation of mantissa
// 				//
// 				char	buf[100];	// Way overkill for a compiler generated fp constant
// 				if	( !mantissa.getString( &(buf[1]), 100 ) )
// 					return	DN_invalid;
// 				//
// 				// Insert decimal point
// 				//
// 				buf[0] = buf[1];
// 				if	( buf[0] == '-' )
// 				{
// 					buf[1] = buf[2];
// 					buf[2] = '.';
// 				}
// 				else
// 					buf[1] = '.';
// 				//
// 				// String it all together
// 				//
// 				return DName( buf ) + 'e' + exponent;
// 			} // End of IF then
// 			else
// 				return DN_truncated;
// 		}	// End of BLOCK case TC_fp
// 	case TC_dummy:
// 		{
// 			//
// 			// This is a template-parameter, i.e. we have a "specialization" of
// 			// X<n>. so get the template-parameter-index and use a "generic" name
// 			// for this parameter
// 			//
// 			DName dimension = getSignedDimension();
// 			if ( haveTemplateParameters()) {
// 				char buffer[16];
// 				dimension.getString( buffer, 16 );
// 				char *str = (*m_pGetParameter)(atol(buffer));
// 				if ( str != NULL ) {
// 					return str;
// 				}
// 			}
// 			return "`template-parameter" + dimension + "'";
// 		}
// 		break;
// 	case '':
// 		--gName;
// 		return	DN_truncated;
// 	default:
// 		return	DN_invalid;
// 	}	// End of SWITCH
// }	// End of "UnDecorator" FUNCTION "getTemplateConstant"
// inline	DName	__near	UnDecorator::composeDeclaration ( const DName & symbol )
// {
// 	DName	declaration;
// 	unsigned int	typeCode	= getTypeEncoding ();
// 	int	symIsUDC	= symbol.isUDC ();
// 	//	Handle bad typeCode's, or truncation
// 	if	( TE_isbadtype ( typeCode ))
// 		return	DN_invalid;
// 	elif	( TE_istruncated ( typeCode ))
// 		return	( DN_truncated + symbol );
// 	//	This is a very complex part.  The type of the declaration must be
// 	//	determined, and the exact composition must be dictated by this type.
// 	//	Is it any type of a function ?
// 	//	However, for ease of decoding, treat the 'localdtor' thunk as data, since
// 	//	its decoration is a function of the variable to which it belongs and not
// 	//	a usual function type of decoration.
// #if	( NO_COMPILER_NAMES )
// 	if	( TE_isthunk ( typeCode ))
// 		return	DN_invalid;
// 	if	( TE_isfunction ( typeCode ))
// #else	// } elif !NO_COMPILER_NAMES {
// 	if	( TE_isfunction ( typeCode ) && !(( TE_isthunk ( typeCode ) && TE_islocaldtor ( typeCode )) ||
// 		( TE_isthunk ( typeCode ) && ( TE_istemplatector ( typeCode ) || TE_istemplatedtor ( typeCode )))))
// #endif	// !NO_COMPILER_NAMES
// 	{
// 		//	If it is based, then compose the 'based' prefix for the name
// 		if	( TE_isbased ( typeCode ))
// 			if	( doMSKeywords () && doAllocationModel ())
// 				declaration	= ' ' + getBasedType ();
// 			else
// 				declaration	|= getBasedType ();	// Just lose the 'based-type'
// #if	( !NO_COMPILER_NAMES )
// 		//	Check for some of the specially composed 'thunk's
// 		if	( TE_isthunk ( typeCode ) && TE_isvcall ( typeCode ))
// 		{
// 			declaration	+= symbol + '{' + getCallIndex () + ',';
// 			declaration	+= getVCallThunkType () + "}' ";
// 			if ( doMSKeywords () && doAllocationLanguage ())
// 				declaration	= ' ' + getCallingConvention () + ' ' + declaration;	// What calling convention ?
// 			else
// 				declaration |= getCallingConvention ();	// Just lose the 'calling-convention'
// 		}	// End of IF then
// 		else
// #endif	// !NO_COMPILER_NAMES
// 		{
// 			DName	vtorDisp;
// 			DName	adjustment;
// 			DName	thisType;
// #if	( !NO_COMPILER_NAMES )
// 			if	( TE_isthunk ( typeCode ))
// 			{
// 				if	( TE_isvtoradj ( typeCode ))
// 					vtorDisp	= getDisplacement ();
// 				adjustment	= getDisplacement ();
// 			}	// End of IF else
// #endif	// !NO_COMPILER_NAMES
// 			//	Get the 'this-type' for non-static function members
// 			if	( TE_ismember ( typeCode ) && !TE_isstatic ( typeCode ))
// 				if	( doThisTypes ())
// 					thisType	= getThisType ();
// 				else
// 					thisType	|= getThisType ();
// 			if	( doMSKeywords ())
// 			{
// 				//	Attach the calling convention
// 				if	( doAllocationLanguage ())
// 					declaration	= getCallingConvention () + declaration;	// What calling convention ?
// 				else
// 					declaration	|= getCallingConvention ();	// Just lose the 'calling-convention'
// 				//	Any model specifiers ?
// #if !VERS_32BIT
// 				if	( doAllocationModel ())
// 					if	( TE_isnear ( typeCode ))
// 						declaration	= UScore ( TOK_nearSp ) + declaration;
// 				elif	( TE_isfar ( typeCode ))
// 					declaration	= UScore ( TOK_farSp ) + declaration;
// #endif
// 			}	// End of IF
// 			else
// 				declaration	|= getCallingConvention ();	// Just lose the 'calling-convention'
// 			//	Now put them all together
// 			if	( !symbol.isEmpty ())
// 				if	( !declaration.isEmpty () && !doNameOnly() )	// And the symbol name
// 					declaration	+= ' ' + symbol;
// 				else
// 					declaration	= symbol;
// 			//	Compose the return type, catching the UDC case
// 			DName *	pDeclarator	= 0;
// 			DName	returnType;
// 			if	( symIsUDC )	// Is the symbol a UDC operator ?
// 			{
// 				declaration	+= " " + getReturnType ();
// 				if	( doNameOnly() )
// 					return	declaration;
// 			}
// 			else
// 			{
// 				pDeclarator	= gnew DName;
// 				returnType	= getReturnType ( pDeclarator );
// 			}	// End of IF else
// #if	( !NO_COMPILER_NAMES )
// 			//	Add the displacements for virtual function thunks
// 			if	( TE_isthunk ( typeCode ))
// 			{
// 				if	( TE_isvtoradj ( typeCode ))
// 					declaration	+= "`vtordisp{" + vtorDisp + ',';
// 				else
// 					declaration	+= "`adjustor{";
// 				declaration	+= adjustment + "}' ";
// 			}	// End of IF
// #endif	// !NO_COMPILER_NAMES
// 			//	Add the function argument prototype
// 			declaration	+= '(' + getArgumentTypes () + ')';
// 			//	If this is a non-static member function, append the 'this' modifiers
// 			if	( TE_ismember ( typeCode ) && !TE_isstatic ( typeCode ))
// 				declaration	+= thisType;
// 			//	Add the 'throw' signature
// 			if	( doThrowTypes ())
// 				declaration	+= getThrowTypes ();
// 			else
// 				declaration	|= getThrowTypes ();	// Just lose the 'throw-types'
// 			//	If it has a declarator, then insert it into the declaration,
// 			//	sensitive to the return type composition
// 			if	( doFunctionReturns () && pDeclarator )
// 			{
// 				*pDeclarator	= declaration;
// 				declaration	= returnType;
// 			}	// End of IF
// 		}	// End of IF else
// 	}	// End of IF then
// 	else
// 	{
// 		declaration	+= symbol;
// 		//	Catch the special handling cases
// #if	( !NO_COMPILER_NAMES )
// 		if	( TE_isvftable ( typeCode ))
// 			return	getVfTableType ( declaration );
// 		elif	( TE_isvbtable ( typeCode ))
// 			return	getVbTableType ( declaration );
// 		elif	( TE_isguard ( typeCode ))
// 			return	( declaration + '{' + getGuardNumber () + "}'" );
// 		elif	( TE_isthunk ( typeCode ) && TE_islocaldtor ( typeCode ))
// 			declaration	+= "`local static destructor helper'";
// 		elif	( TE_isthunk ( typeCode ) && TE_istemplatector ( typeCode ))
// 			declaration	+= "`template static data member constructor helper'";
// 		elif	( TE_isthunk ( typeCode ) && TE_istemplatedtor ( typeCode ))
// 			declaration	+= "`template static data member destructor helper'";
// 		elif	( TE_ismetaclass ( typeCode ))
// 			//
// 			// Meta-class information has its information in its operator id
// 			//
// 			return declaration;
// #else	// } elif NO_COMPILER_NAMES {
// 		if	( TE_isvftable ( typeCode )
// 			|| TE_isvbtable ( typeCode )
// 			|| TE_isguard ( typeCode )
// 			|| TE_ismetaclass ( typeCode ))
// 			return	DN_invalid;
// #endif	// NO_COMPILER_NAMES
// 		if ( TE_isthunk( typeCode ) && ( TE_istemplatector( typeCode ) || TE_istemplatedtor( typeCode ))) {
// 			//
// 			// Insert a space before the declaration
// 			//
// 			declaration = " " + declaration;
// 		}
// 		else {
// 			//	All others are decorated as data symbols
// 			declaration	= getExternalDataType ( declaration );
// 		}
// 	}	// End of IF else
// 	//	Prepend the 'virtual' and 'static' attributes for members
// 	if	( TE_ismember ( typeCode ))
// 	{
// 		if	( doMemberTypes ())
// 		{
// 			if	( TE_isstatic ( typeCode ))
// 				declaration	= "static " + declaration;
// 			if	( TE_isvirtual ( typeCode ) || ( TE_isthunk ( typeCode ) && ( TE_isvtoradj ( typeCode ) || TE_isadjustor ( typeCode ))))
// 				declaration	= "virtual " + declaration;
// 		}	// End of IF
// 		//	Prepend the access specifiers
// 		if	( doAccessSpecifiers ())
// 			if	( TE_isprivate ( typeCode ))
// 				declaration	= "private: " + declaration;
// 		elif	( TE_isprotected ( typeCode ))
// 			declaration	= "protected: " + declaration;
// 		elif	( TE_ispublic ( typeCode ))
// 			declaration	= "public: " + declaration;
// 	}	// End of IF
// #if	( !NO_COMPILER_NAMES )
// 	//	If it is a thunk, mark it appropriately
// 	if	( TE_isthunk ( typeCode ))
// 		declaration	= "[thunk]:" + declaration;
// #endif	// !NO_COMPILER_NAMES
// 	//	Return the composed declaration
// 	return	declaration;
// }	// End of "UnDecorator" FUNCTION "composeDeclaration"
// inline	int	__near	UnDecorator::getTypeEncoding ( void )
// {
// 	unsigned int	typeCode	= 0u;
// 	//	Strip any leading '_' which indicates that it is based
// 	if	( *gName == '_' )
// 	{
// 		TE_setisbased ( typeCode );
// 		gName++;
// 	}	// End of IF
// 	//	Now handle the code proper :-
// 	if	(( *gName >= 'A' ) && ( *gName <= 'Z' ))	// Is it some sort of function ?
// 	{
// 		int	code	= *gName++ - 'A';
// 		//	Now determine the function type
// 		TE_setisfunction ( typeCode );	// All of them are functions ?
// 		//	Determine the calling model
// 		if	( code & TE_far )
// 			TE_setisfar ( typeCode );
// 		else
// 			TE_setisnear ( typeCode );
// 		//	Is it a member function or not ?
// 		if	( code < TE_external )
// 		{
// 			//	Record the fact that it is a member
// 			TE_setismember ( typeCode );
// 			//	What access permissions does it have
// 			switch	( code & TE_access )
// 			{
// 			case TE_private:
// 				TE_setisprivate ( typeCode );
// 				break;
// 			case TE_protect:
// 				TE_setisprotected ( typeCode );
// 				break;
// 			case TE_public:
// 				TE_setispublic ( typeCode );
// 				break;
// 			default:
// 				TE_setisbadtype ( typeCode );
// 				return	typeCode;
// 			}	// End of SWITCH
// 			//	What type of a member function is it ?
// 			switch	( code & TE_adjustor )
// 			{
// 			case TE_adjustor:
// 				TE_setisadjustor ( typeCode );
// 				break;
// 			case TE_virtual:
// 				TE_setisvirtual ( typeCode );
// 				break;
// 			case TE_static:
// 				TE_setisstatic ( typeCode );
// 				break;
// 			case TE_member:
// 				break;
// 			default:
// 				TE_setisbadtype ( typeCode );
// 				return	typeCode;
// 			}	// End of SWITCH
// 		}	// End of IF
// 	}	// End of IF then
// 	elif	( *gName == '$' )	// Extended set ?  Special handling
// 	{
// 		//	What type of symbol is it ?
// 		switch	( *( ++gName ))
// 		{
// 		case SHF_localdtor:	// A destructor helper for a local static ?
// 			TE_setislocaldtor ( typeCode );
// 			break;
// 		case SHF_vcall:	// A VCall-thunk ?
// 			TE_setisvcall ( typeCode );
// 			break;
// 		case SHF_templateStaticDataMemberCtor:	// A constructor helper for template static data members
// 			TE_setistemplatector ( typeCode );
// 			break; 
// 		case SHF_templateStaticDataMemberDtor:	// A destructor helper for template static data members
// 			TE_setistemplatedtor ( typeCode );
// 			break; 
// 		case 0:
// 			TE_setistruncated ( typeCode );
// 			break;
// 		case '0':
// 		case '1':
// 		case '2':
// 		case '3':
// 		case '4':
// 		case '5':	// Construction displacement adjustor thunks
// 			{
// 				int	code	= *gName - '0';
// 				//	Set up the principal type information
// 				TE_setisfunction ( typeCode );
// 				TE_setismember ( typeCode );
// 				TE_setisvtoradj ( typeCode );
// 				//	Is it 'near' or 'far' ?
// 				if	( code & TE_far )
// 					TE_setisfar ( typeCode );
// 				else
// 					TE_setisnear ( typeCode );
// 				//	What type of access protection ?
// 				switch	( code & TE_access_vadj )
// 				{
// 				case TE_private_vadj:
// 					TE_setisprivate ( typeCode );
// 					break;
// 				case TE_protect_vadj:
// 					TE_setisprotected ( typeCode );
// 					break;
// 				case TE_public_vadj:
// 					TE_setispublic ( typeCode );
// 					break;
// 				default:
// 					TE_setisbadtype ( typeCode );
// 					return	typeCode;
// 				}	// End of SWITCH
// 			}	// End of CASE '0,1,2,3,4,5'
// 			break;
// 		default:
// 			TE_setisbadtype ( typeCode );
// 			return	typeCode;
// 		}	// End of SWITCH
// 		//	Advance past the code character
// 		gName++;
// 	}	// End of ELIF then
// 	elif	(( *gName >= TE_static_d ) && ( *gName <= TE_metatype ))	// Non function decorations ?
// 	{
// 		int	code	= *gName++;
// 		TE_setisdata ( typeCode );
// 		//	What type of symbol is it ?
// 		switch	( code )
// 		{
// 		case ( TE_static_d | TE_private_d ):
// 			TE_setisstatic ( typeCode );
// 			TE_setisprivate ( typeCode );
// 			break;
// 		case ( TE_static_d | TE_protect_d ):
// 			TE_setisstatic ( typeCode );
// 			TE_setisprotected ( typeCode );
// 			break;
// 		case ( TE_static_d | TE_public_d ):
// 			TE_setisstatic ( typeCode );
// 			TE_setispublic ( typeCode );
// 			break;
// 		case TE_global:
// 			TE_setisglobal ( typeCode );
// 			break;
// 		case TE_guard:
// 			TE_setisguard ( typeCode );
// 			break;
// 		case TE_local:
// 			TE_setislocal ( typeCode );
// 			break;
// 		case TE_vftable:
// 			TE_setisvftable ( typeCode );
// 			break;
// 		case TE_vbtable:
// 			TE_setisvbtable ( typeCode );
// 			break;
// 		case TE_metatype:
// 			TE_setismetaclass ( typeCode );
// 			break;
// 		defau
Download .txt
gitextract_0g68xkff/

├── README.md
├── Sysmon/
│   ├── CDName.cpp
│   ├── CDName.h
│   ├── CDigitalSign.cpp
│   ├── CDigitalSign.h
│   ├── CEventLogger.cpp
│   ├── CEventLogger.h
│   ├── CMofDataParser.cpp
│   ├── CMofDataParser.h
│   ├── CSsymonEtw.cpp
│   ├── CSsymonEtw.h
│   ├── CSysmonDriverOpt.cpp
│   ├── CSysmonDriverOpt.h
│   ├── CSysmonMofData.cpp
│   ├── CSysmonMofData.h
│   ├── CSysmonUtil.cpp
│   ├── CSysmonUtil.h
│   ├── ReadMe.txt
│   ├── Resource.h
│   ├── Sysmon.cpp
│   ├── Sysmon.h
│   ├── Sysmon.rc
│   ├── Sysmon.vcxproj
│   ├── Sysmon.vcxproj.filters
│   ├── Sysmon.vcxproj.user
│   ├── stdafx.cpp
│   ├── stdafx.h
│   ├── targetver.h
│   ├── undname.cpp
│   ├── undname.h
│   └── undname.idl
├── Sysmon.sln
├── Sysmon.suo
└── Sysmon.sys/
    ├── CDeviceExtension.cpp
    ├── CDeviceExtension.h
    ├── CDriverEntry.cpp
    ├── CDriverEntry.h
    ├── CReportRecord.cpp
    ├── CReportRecord.h
    ├── CSysmonControl.cpp
    ├── CSysmonControl.h
    ├── CSysmonDispatchEngine.cpp
    ├── CSysmonDispatchEngine.h
    ├── CSysmonIoControl.h
    ├── CSysmonMiniFltFilter.cpp
    ├── CSysmonMiniFltFilter.h
    ├── ReadMe.txt
    ├── Sysmon.sys.cpp
    ├── Sysmon.sys.vcxproj
    ├── Sysmon.sys.vcxproj.filters
    ├── Sysmon.sys.vcxproj.user
    ├── cpplib/
    │   ├── CAssert.h
    │   ├── CAttachDevice.cpp
    │   ├── CAttachDevice.h
    │   ├── CDebug.cpp
    │   ├── CDebug.h
    │   ├── CDeviceObject.cpp
    │   ├── CDeviceObject.h
    │   ├── CDispatchEngine.cpp
    │   ├── CDispatchEngine.h
    │   ├── CDriverDispatch.cpp
    │   ├── CDriverDispatch.h
    │   ├── CDriverObject.cpp
    │   ├── CDriverObject.h
    │   ├── CEResource.cpp
    │   ├── CEResource.h
    │   ├── CErrorStatus.cpp
    │   ├── CErrorStatus.h
    │   ├── CFileObject.cpp
    │   ├── CFileObject.h
    │   ├── CFilterDevice.cpp
    │   ├── CFilterDevice.h
    │   ├── CIntNumber.cpp
    │   ├── CIntNumber.h
    │   ├── CIoStackLocation.cpp
    │   ├── CIoStackLocation.h
    │   ├── CIrp.cpp
    │   ├── CIrp.h
    │   ├── CListEntry.cpp
    │   ├── CListEntry.h
    │   ├── CMiniFltFilter.cpp
    │   ├── CMiniFltFilter.h
    │   ├── CNPagedLookaside.cpp
    │   ├── CNPagedLookaside.h
    │   ├── CPool.cpp
    │   ├── CPool.h
    │   ├── CString.cpp
    │   ├── CString.h
    │   ├── CSysmonBase.cpp
    │   ├── CSysmonBase.h
    │   ├── CUnicodeString.cpp
    │   ├── CUnicodeString.h
    │   ├── CVersion.cpp
    │   ├── CVersion.h
    │   ├── CppLib.cpp
    │   └── CppLib.h
    ├── stdafx.cpp
    ├── stdafx.h
    └── targetver.h
Download .txt
SYMBOL INDEX (273 symbols across 61 files)

FILE: Sysmon.sys/CDeviceExtension.h
  function class (line 5) | class CDeviceExtension

FILE: Sysmon.sys/CDriverEntry.cpp
  function CDriverEntry (line 32) | CDriverEntry& CDriverEntry::Instance()
  function BOOL (line 48) | BOOL CDriverEntry::IsSupportFlt()
  function NTSTATUS (line 62) | NTSTATUS
  function CErrorStatus (line 229) | CErrorStatus
  function CErrorStatus (line 254) | CErrorStatus

FILE: Sysmon.sys/CDriverEntry.h
  function class (line 13) | class CDriverEntry

FILE: Sysmon.sys/CReportRecord.h
  function class (line 8) | class CSysmonRecord
  function class (line 18) | class CReportSysmonRecord

FILE: Sysmon.sys/CSysmonControl.h
  function class (line 4) | class CSysmonControl

FILE: Sysmon.sys/CSysmonDispatchEngine.cpp
  function NTSTATUS (line 28) | NTSTATUS
  function NTSTATUS (line 112) | NTSTATUS
  function NTSTATUS (line 244) | NTSTATUS
  function PIRP (line 290) | PIRP

FILE: Sysmon.sys/CSysmonDispatchEngine.h
  function class (line 7) | class CSysmonDispatchEngine

FILE: Sysmon.sys/CSysmonIoControl.h
  type Base_Sysmon_FileObj_Type (line 4) | typedef enum _Base_Sysmon_FileObj_Type
  type Sysmon_Flt_CompletionContext (line 11) | typedef struct _Sysmon_Flt_CompletionContext
  type Sysmon_Flt_Stream_Context (line 20) | typedef struct _Sysmon_Flt_Stream_Context

FILE: Sysmon.sys/CSysmonMiniFltFilter.cpp
  function CErrorStatus (line 22) | CErrorStatus CSysmonMiniFltFilter::Init(PDRIVER_OBJECT DriverObj)
  function NTSTATUS (line 97) | NTSTATUS
  function NTSTATUS (line 109) | NTSTATUS
  function NTSTATUS (line 132) | NTSTATUS

FILE: Sysmon.sys/CSysmonMiniFltFilter.h
  function class (line 9) | class CSysmonMiniFltFilter :

FILE: Sysmon.sys/Sysmon.sys.cpp
  function NTSTATUS (line 13) | NTSTATUS

FILE: Sysmon.sys/cpplib/CAttachDevice.cpp
  function CErrorStatus (line 28) | CErrorStatus
  function CErrorStatus (line 45) | CErrorStatus

FILE: Sysmon.sys/cpplib/CAttachDevice.h
  function class (line 9) | class CAttachDevice
  function PDEVICE_OBJECT (line 21) | PDEVICE_OBJECT Device()
  function PDEVICE_OBJECT (line 26) | PDEVICE_OBJECT LowDevice()

FILE: Sysmon.sys/cpplib/CDebug.h
  function class (line 5) | class CDebug

FILE: Sysmon.sys/cpplib/CDeviceObject.cpp
  function PDEVICE_OBJECT (line 37) | PDEVICE_OBJECT* CDeviceObject::operator &()
  function ULONG (line 57) | ULONG& CDeviceObject::Flags()
  function PVOID (line 62) | PVOID& CDeviceObject::DeviceExtension()
  function PDRIVER_OBJECT (line 67) | PDRIVER_OBJECT& CDeviceObject::DriverObject()
  function ULONG (line 72) | ULONG& CDeviceObject::DeviceType()
  function PDEVICE_OBJECT (line 77) | PDEVICE_OBJECT& CDeviceObject::AttachedDevice()
  function PDEVICE_OBJECT (line 82) | PDEVICE_OBJECT& CDeviceObject::NextDevice()
  function ULONG (line 87) | ULONG& CDeviceObject::Characteristics()
  function CErrorStatus (line 96) | CErrorStatus
  function CErrorStatus (line 138) | CErrorStatus
  function CErrorStatus (line 175) | CErrorStatus

FILE: Sysmon.sys/cpplib/CDeviceObject.h
  function class (line 8) | class CDeviceObject

FILE: Sysmon.sys/cpplib/CDispatchEngine.h
  function class (line 4) | class CDispatchEngine

FILE: Sysmon.sys/cpplib/CDriverDispatch.cpp
  function BOOL (line 23) | BOOL CDriverDispatch::operator !() const
  function PDRIVER_DISPATCH (line 28) | PDRIVER_DISPATCH& CDriverDispatch::operator [](int n)

FILE: Sysmon.sys/cpplib/CDriverDispatch.h
  function class (line 5) | class CDriverDispatch

FILE: Sysmon.sys/cpplib/CDriverObject.h
  function class (line 5) | class CDriverObject

FILE: Sysmon.sys/cpplib/CEResource.h
  function class (line 6) | class CEResource

FILE: Sysmon.sys/cpplib/CErrorStatus.cpp
  function BOOL (line 30) | BOOL

FILE: Sysmon.sys/cpplib/CErrorStatus.h
  function class (line 6) | class CErrorStatus

FILE: Sysmon.sys/cpplib/CFileObject.cpp
  function PVOID (line 30) | PVOID CFileObject::operator !()
  function PUNICODE_STRING (line 35) | PUNICODE_STRING CFileObject::FileName()
  function PFILE_OBJECT (line 40) | PFILE_OBJECT&    CFileObject::RelatedFileObject()

FILE: Sysmon.sys/cpplib/CFileObject.h
  function class (line 4) | class CFileObject

FILE: Sysmon.sys/cpplib/CFilterDevice.cpp
  function CErrorStatus (line 28) | CErrorStatus
  function CErrorStatus (line 90) | CErrorStatus
  function CErrorStatus (line 151) | CErrorStatus
  function CErrorStatus (line 178) | CErrorStatus
  function CErrorStatus (line 199) | CErrorStatus
  function PDEVICE_OBJECT (line 237) | PDEVICE_OBJECT
  function CAttachDevice (line 243) | CAttachDevice&

FILE: Sysmon.sys/cpplib/CFilterDevice.h
  function class (line 17) | class CFilterDevice

FILE: Sysmon.sys/cpplib/CIoStackLocation.cpp
  function BOOLEAN (line 37) | BOOLEAN
  function BOOLEAN (line 43) | BOOLEAN CIoStackLocation::operator !=(const PIO_STACK_LOCATION Stack)
  function PVOID (line 48) | PVOID CIoStackLocation::operator !()
  function CFileObject (line 53) | CFileObject CIoStackLocation::FileObject()
  function UCHAR (line 58) | UCHAR&	CIoStackLocation::Flags()

FILE: Sysmon.sys/cpplib/CIoStackLocation.h
  function class (line 6) | class CIoStackLocation

FILE: Sysmon.sys/cpplib/CIrp.cpp
  function PIRP (line 23) | PIRP
  function NTSTATUS (line 29) | NTSTATUS&
  function KPROCESSOR_MODE (line 35) | KPROCESSOR_MODE&
  function ULONG_PTR (line 41) | ULONG_PTR&
  function PMDL (line 47) | PMDL&
  function PVOID (line 53) | PVOID&
  function PVOID (line 60) | PVOID&
  function PVOID (line 66) | PVOID&
  function PVOID (line 72) | PVOID&
  function PVOID (line 78) | PVOID&
  function UINT8 (line 84) | UINT8&
  function UINT8 (line 90) | UINT8&
  function UINT8 (line 96) | UINT8&
  function UINT8 (line 102) | UINT8&
  function ULONG (line 108) | ULONG&
  function INT64 (line 114) | INT64&
  function ULONG (line 120) | ULONG&
  function INT64 (line 126) | INT64&
  function ULONG (line 132) | ULONG&
  function ULONG (line 144) | ULONG&
  function ULONG (line 157) | ULONG&
  function PDEVICE_OBJECT (line 169) | PDEVICE_OBJECT&	CIrp::Device() const
  function PFILE_OBJECT (line 174) | PFILE_OBJECT&	CIrp::FileObject() const
  function PIO_STACK_LOCATION (line 179) | PIO_STACK_LOCATION
  function NTSTATUS (line 211) | NTSTATUS
  function NTSTATUS (line 220) | NTSTATUS SimpleCompletion(
  function NTSTATUS (line 238) | NTSTATUS
  function CErrorStatus (line 286) | CErrorStatus
  function CErrorStatus (line 320) | CErrorStatus

FILE: Sysmon.sys/cpplib/CIrp.h
  function class (line 7) | class CIrp

FILE: Sysmon.sys/cpplib/CListEntry.h
  type C_LIST_NODE (line 9) | typedef struct _C_LIST_NODE
  function class (line 49) | class Iterator
  function BOOLEAN (line 213) | BOOLEAN Insert( T* _X )
  function BOOLEAN (line 259) | BOOLEAN Remove( T* _X )
  function LIST_ENTRY (line 324) | LIST_ENTRY* End()
  function UnLock (line 336) | void UnLock()

FILE: Sysmon.sys/cpplib/CMiniFltFilter.cpp
  function CErrorStatus (line 178) | CErrorStatus
  function NTSTATUS (line 196) | NTSTATUS
  function NTSTATUS (line 208) | NTSTATUS
  function NTSTATUS (line 233) | NTSTATUS

FILE: Sysmon.sys/cpplib/CMiniFltFilter.h
  type Flt_Fn_Callback (line 10) | typedef enum _Flt_Fn_Callback
  function class (line 25) | class CMiniFltFilter

FILE: Sysmon.sys/cpplib/CNPagedLookaside.h
  function T (line 27) | T* Allocate()
  function Free (line 32) | void Free( T* pT )

FILE: Sysmon.sys/cpplib/CPool.h
  function operator (line 37) | operator T*() const
  function BOOL (line 42) | BOOL
  function BOOL (line 48) | BOOL
  function T (line 54) | const
  function T (line 92) | T* Allocate( SIZE_T _S )
  function T (line 111) | T* Allocate()
  function Free (line 129) | void Free()
  function INT3264 (line 139) | INT3264 Size()

FILE: Sysmon.sys/cpplib/CString.h
  function virtual (line 14) | virtual ~CStringT(void)
  function operator (line 19) | operator T*()
  function operator (line 65) | operator WCHAR*()

FILE: Sysmon.sys/cpplib/CSysmonBase.cpp
  function USHORT (line 18) | USHORT
  function BOOL (line 116) | BOOL

FILE: Sysmon.sys/cpplib/CSysmonBase.h
  function class (line 7) | class CSysmonBase

FILE: Sysmon.sys/cpplib/CUnicodeString.cpp
  function PUNICODE_STRING (line 56) | PUNICODE_STRING CUnicodeString::operator &()

FILE: Sysmon.sys/cpplib/CUnicodeString.h
  function class (line 8) | class CUnicodeString

FILE: Sysmon.sys/cpplib/CVersion.cpp
  function ULONG (line 41) | ULONG CVersion::GetMajorVersion()
  function ULONG (line 50) | ULONG CVersion::GetMinorVersion()
  function ULONG (line 59) | ULONG CVersion::GetBuilderNumber()

FILE: Sysmon.sys/cpplib/CVersion.h
  function class (line 5) | class CVersion

FILE: Sysmon.sys/cpplib/CppLib.cpp
  function EXTERN_C (line 42) | EXTERN_C
  function atexit (line 57) | int
  function EXTERN_C (line 81) | EXTERN_C
  function DeleteHelper (line 124) | void
  function CallGlobalConstructors (line 131) | void
  function CallGlobalDestructors (line 148) | void
  function EXCEPTION_DISPOSITION (line 167) | EXCEPTION_DISPOSITION
  function _CxxThrowException (line 182) | void
  function _CxxThrowException (line 193) | void

FILE: Sysmon.sys/cpplib/CppLib.h
  type CHAR (line 6) | typedef char CHAR;
  type UCHAR (line 7) | typedef unsigned char UCHAR;
  type BOOLEAN (line 8) | typedef unsigned char BOOLEAN;
  type wchar_t (line 9) | typedef wchar_t WCHAR;
  type boolean (line 10) | typedef unsigned char boolean;
  type UINT32 (line 11) | typedef unsigned __int32 UINT32;
  type ULONG32 (line 12) | typedef unsigned int ULONG32, *PULONG32;
  type DWORD32 (line 13) | typedef unsigned int DWORD32, *PDWORD32;
  type BOOL (line 14) | typedef int BOOL;
  type INT8 (line 15) | typedef signed char         INT8, *PINT8;
  type INT16 (line 16) | typedef signed short        INT16, *PINT16;
  type INT32 (line 17) | typedef signed int          INT32, *PINT32;
  type INT64 (line 18) | typedef signed __int64      INT64, *PINT64;
  type UINT8 (line 19) | typedef unsigned char       UINT8, *PUINT8;
  type UINT16 (line 20) | typedef unsigned short      UINT16, *PUINT16;
  type UINT32 (line 21) | typedef unsigned int        UINT32, *PUINT32;
  type UINT64 (line 22) | typedef unsigned __int64    UINT64, *PUINT64;
  type __int64 (line 24) | typedef __int64  INT64;
  type __int3264 (line 25) | typedef __int3264 ADDRPOINT;
  type __int3264 (line 26) | typedef __int3264 INT3264;
  type UINT (line 27) | typedef unsigned int UINT;
  type BYTE (line 28) | typedef unsigned char BYTE;
  type ULONG (line 29) | typedef unsigned long ULONG;
  type SHORT (line 30) | typedef short SHORT;
  type USHORT (line 31) | typedef unsigned short USHORT;
  type AtExitEntry (line 49) | struct AtExitEntry
  type MemoryType (line 65) | enum MemoryType
  function operator (line 81) | operator new(size_t size)
  function operator (line 89) | operator new[](size_t size)
  function operator (line 97) | operator new(size_t size, MemoryType memType)
  function operator (line 105) | operator new[](size_t size, MemoryType memType)
  function operator (line 115) | operator new(size_t size, void *pMem)
  function operator (line 124) | operator new[](size_t size, void *pMem)
  function operator (line 136) | operator delete(void *p)
  function operator (line 144) | operator delete[](void *p)
  function operator (line 152) | operator delete(void *p, MemoryType memType)
  function operator (line 161) | operator delete[](void *p, MemoryType memType)
  function operator (line 173) | operator delete(void *pMem1, void *pMem2)
  function operator (line 184) | operator delete[](void *pMem1, void *pMem2)
  function class (line 206) | class type_info {

FILE: Sysmon/CDName.h
  function class (line 4) | class CDName

FILE: Sysmon/CDigitalSign.h
  type CATALOG_INFO (line 8) | typedef struct CATALOG_INFO_ {
  type CRYPT_PROVIDER_SGNR (line 22) | typedef
  type CRYPT_PROVIDER_DATA (line 30) | typedef
  type const (line 76) | typedef
  function class (line 121) | class CDigitalSign

FILE: Sysmon/CEventLogger.cpp
  function HRESULT (line 33) | HRESULT CEventLogger::Init(
  function HRESULT (line 164) | HRESULT CEventLogger::DeInit()
  function ULONG (line 229) | ULONG CEventLogger::ControlCallback(
  function ULONG (line 245) | ULONG CEventLogger::_ControlCallback(

FILE: Sysmon/CEventLogger.h
  function class (line 10) | class CEventLogger

FILE: Sysmon/CMofDataParser.cpp
  function CMofDataParser (line 21) | CMofDataParser* CMofDataParser::Instance()
  function HRESULT (line 37) | HRESULT CMofDataParser::Connect(
  function BOOL (line 94) | BOOL CMofDataParser::Parse(
  function IWbemClassObject (line 258) | IWbemClassObject*
  function CMofParseRes (line 446) | CMofParseRes*
  function BOOL (line 769) | BOOL CMofDataParser::GetPropertyList(
  function PBYTE (line 949) | PBYTE CMofDataParser::GetPropertyValue(
  function LONG (line 1908) | LONG CMofDataParser::GetArraySize(
  function LONG (line 1930) | LONG CMofDataParser::GetArrayValue(

FILE: Sysmon/CMofDataParser.h
  type uint32 (line 16) | typedef unsigned int uint32;
  type uint64 (line 17) | typedef unsigned long long uint64;
  type MOF_DATA_HEADER (line 26) | typedef struct _MOF_DATA_HEADER
  type MOF_CHAR_ARRAY (line 38) | typedef struct _MOF_CHAR_ARRAY
  type MOF_ITEM (line 49) | typedef struct _MOF_ITEM
  type MOF_PROPERTY (line 64) | typedef struct _MOF_PROPERTY
  function class (line 73) | class CMofParseRes
  type PROPERTY_LIST (line 110) | typedef struct _propertyList
  function class (line 118) | class CMofData
  function UINT32 (line 283) | UINT32 GetProcessId()
  function UINT64 (line 288) | UINT64 GetUniqueProcessKey()
  function UINT64 (line 311) | UINT64 GetFileObject()
  function TCHAR (line 316) | TCHAR* GetFileOpenPath()
  function class (line 340) | class CMofDataParser
  function class (line 419) | class FileCreateNameX86
  function class (line 440) | class CPropertyRes
  function Init (line 488) | void Init()
  function TCHAR (line 494) | TCHAR* GetFileName()
  function TCHAR (line 504) | TCHAR* GetQueryDomainName()
  function TCHAR (line 509) | TCHAR* GetQueryResult()
  function ULONGLONG (line 514) | ULONGLONG GetFileObject()
  function ULONG (line 524) | ULONG GetProcessId()
  function WORD (line 534) | WORD GetPort()
  function ULONG (line 544) | ULONG GetQueryStatus()
  function ULONG (line 554) | ULONG GetIpAddress()
  function ULONG (line 564) | ULONG GetIoSize()
  function BOOL (line 574) | BOOL operator == ( TCHAR* StrName)

FILE: Sysmon/CSsymonEtw.cpp
  function ULONG (line 41) | ULONG CSsymonEtw::InitData()
  function HRESULT (line 70) | HRESULT CSsymonEtw::StartTrace(BOOL bStart)
  function UINT (line 237) | UINT CSsymonEtw::ProcessTraceThread(void* lp)
  function ULONG (line 324) | ULONG
  function VOID (line 333) | VOID
  function UINT (line 362) | UINT

FILE: Sysmon/CSsymonEtw.h
  type Sysomn_Event_Properties (line 57) | typedef struct _Sysomn_Event_Properties
  function class (line 74) | class CSsymonEtw

FILE: Sysmon/CSysmonDriverOpt.cpp
  function BOOL (line 23) | BOOL CSysmonDriverOpt::InstallDriver(
  function BOOL (line 190) | BOOL CSysmonDriverOpt::StartDriver(LPCTSTR lpszDriverName)
  function BOOL (line 251) | BOOL CSysmonDriverOpt::StopDriver(LPCTSTR lpszDriverName)
  function BOOL (line 294) | BOOL CSysmonDriverOpt::DeleteDriver(LPCTSTR lpszDriverName)

FILE: Sysmon/CSysmonDriverOpt.h
  function class (line 4) | class CSysmonDriverOpt

FILE: Sysmon/CSysmonMofData.cpp
  function HRESULT (line 53) | HRESULT CSysmonMofData::CoCreateInstance()
  function CSysmonDataEntry (line 99) | CSysmonDataEntry* CSysmonMofData::Phase_1(
  function CSysmonDataEntry (line 407) | CSysmonDataEntry*
  function CSysmonDataEntry (line 722) | CSysmonDataEntry* CSysmonMofData::GetPropertyList(
  function CSysmonEventList (line 1126) | CSysmonEventList* CSysmonMofData::AddEvent(
  function LONG (line 1180) | LONG CSysmonMofData::GetArrayValue(
  function LONG (line 1365) | LONG CSysmonMofData::GetArraySize(
  function BOOL (line 1400) | BOOL CSysmonData::Compare(BSTR pString)
  function BOOL (line 1409) | BOOL CSysmonData::CompareN(BSTR pString,ULONG Size)
  function LONG (line 1451) | LONG CSysmonDataEntry::GetCLassNameLen()
  function CSysmonDataEntry (line 1461) | CSysmonDataEntry* CSysmonDataEntry::InitData(CSysmonData** pData,BSTR pS...
  function CSysmonEventList (line 1553) | CSysmonEventList* CSysmonEventList::InsertBack(LIST_ENTRY* Blink,void* p...

FILE: Sysmon/CSysmonMofData.h
  type CTcpIpInfo (line 21) | typedef struct _CTcpIpInfo
  type Sysmon_Net_Report (line 27) | typedef struct _Sysmon_Net_Report
  function class (line 38) | class CSysmonData
  function class (line 72) | class CSysmonEventList
  function class (line 91) | class CSysmonDataEntry
  function class (line 114) | class CSysmonProperty
  function InitData (line 146) | void InitData(CSysmonData** pData,BSTR pString)
  function class (line 206) | class CSysmonMofData

FILE: Sysmon/CSysmonUtil.cpp
  function BOOL (line 14) | BOOL CSysmonUtil::SysmonVersionIsSupport()

FILE: Sysmon/CSysmonUtil.h
  type QWORD (line 4) | typedef unsigned __int64 QWORD;
  function class (line 6) | class CSysmonUtil

FILE: Sysmon/Sysmon.cpp
  function _tWinMain (line 20) | int APIENTRY _tWinMain(
  function BOOLEAN (line 103) | BOOLEAN __fastcall SysmonTempFileName(wchar_t * FileName, wchar_t* TempN...
  function BOOLEAN (line 178) | BOOLEAN __fastcall SysmonExtractResource(LPCWSTR lpName, wchar_t *Filename)
  function DWORD (line 204) | DWORD RunSysmonX64()

FILE: Sysmon/Sysmon.h
  function BOOLEAN (line 5) | BOOLEAN
  function FORCEINLINE (line 14) | FORCEINLINE
  function FORCEINLINE (line 23) | FORCEINLINE
  function FORCEINLINE (line 39) | FORCEINLINE
  function FORCEINLINE (line 55) | FORCEINLINE
Condensed preview — 99 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (432K chars).
[
  {
    "path": "README.md",
    "chars": 108,
    "preview": "# Sysmon_reverse逆向微软sysmon的源代码,逆向的版本是v8\n原始产品\nhttps://docs.microsoft.com/zh-cn/sysinternals/downloads/sysmon\n"
  },
  {
    "path": "Sysmon/CDName.cpp",
    "chars": 139,
    "preview": "#include \"StdAfx.h\"\n#include \"CDName.h\"\n\n\nCDName::CDName(void)\n{\n}\n\n\nCDName::~CDName(void)\n{\n}\n\n\nchar* CDName::_unDName("
  },
  {
    "path": "Sysmon/CDName.h",
    "chars": 138,
    "preview": "#ifndef _CDName_H\n#define _CDName_H\n\nclass CDName\n{\npublic:\n\tCDName(void);\n\tvirtual ~CDName(void);\n\n\tstatic char* _unDNa"
  },
  {
    "path": "Sysmon/CDigitalSign.cpp",
    "chars": 2525,
    "preview": "#include \"StdAfx.h\"\n#include \"CDigitalSign.h\"\n\n\nCDigitalSign::CDigitalSign(void)\n\t:m_bInit(false)\n\t,m_WinVerifyTrust(NUL"
  },
  {
    "path": "Sysmon/CDigitalSign.h",
    "chars": 3046,
    "preview": "#ifndef _CDigitalSign_h\n#define _CDigitalSign_h\n#include <WinTrust.h>\n\ntypedef void* HCATINFO;\ntypedef void* HCATADMIN;\n"
  },
  {
    "path": "Sysmon/CEventLogger.cpp",
    "chars": 6343,
    "preview": "#include \"StdAfx.h\"\n#include \"CEventLogger.h\"\n\n#include <strsafe.h>\n#pragma comment (lib, \"strsafe.lib\")\n\n\nCEventLogger:"
  },
  {
    "path": "Sysmon/CEventLogger.h",
    "chars": 918,
    "preview": "#ifndef _CEventLogger_h\n#define _CEventLogger_h\n#include <CGuid.h>\n#include <atlbase.h>\n#include <atlstr.h> \n#include <a"
  },
  {
    "path": "Sysmon/CMofDataParser.cpp",
    "chars": 43275,
    "preview": "#include \"StdAfx.h\"\n#include \"CMofDataParser.h\"\n#include \"Sysmon.h\"\n#include <WinSock2.h>\n#include <in6addr.h>\n\n#define "
  },
  {
    "path": "Sysmon/CMofDataParser.h",
    "chars": 8139,
    "preview": "#ifndef _CMofDataParser_h\n#define _CMofDataParser_h\n\n#include \"Sysmon.h\"\n\n#define MAX_CHAR_ARRAY_SIZE 20\n#define TCHAR_V"
  },
  {
    "path": "Sysmon/CSsymonEtw.cpp",
    "chars": 8936,
    "preview": "#include \"StdAfx.h\"\n#include \"CSsymonEtw.h\"\n#include \"CSysmonUtil.h\"\n#include <winsock2.h>\n#include <strsafe.h>\n#include"
  },
  {
    "path": "Sysmon/CSsymonEtw.h",
    "chars": 2357,
    "preview": "#ifndef _CSsymonEtw_h\n#define _CSsymonEtw_h\n\n#include \"CMofDataParser.h\"\n#include \"CSysmonMofData.h\"\n#include <wmistr.h>"
  },
  {
    "path": "Sysmon/CSysmonDriverOpt.cpp",
    "chars": 7013,
    "preview": "#include \"StdAfx.h\"\n#include \"CSysmonDriverOpt.h\"\n\n\nCSysmonDriverOpt::CSysmonDriverOpt(void)\n{\n}\n\n\nCSysmonDriverOpt::~CS"
  },
  {
    "path": "Sysmon/CSysmonDriverOpt.h",
    "chars": 407,
    "preview": "#ifndef _CSysmonDriverOpt_h\n#define _CSysmonDriverOpt_h\n\nclass CSysmonDriverOpt\n{\npublic:\n\tCSysmonDriverOpt(void);\n\tvirt"
  },
  {
    "path": "Sysmon/CSysmonMofData.cpp",
    "chars": 32287,
    "preview": "#include \"StdAfx.h\"\n#include \"CSysmonMofData.h\"\n#include \"CSsymonEtw.h\"\n#include \"CSysmonUtil.h\"\n#include \"Sysmon.h\"\n\n#d"
  },
  {
    "path": "Sysmon/CSysmonMofData.h",
    "chars": 4526,
    "preview": "#ifndef _CSysmonMofData_h\n#define _CSysmonMofData_h\n\n#include \"Sysmon.h\"\n#include <wbemidl.h>\n#include <comutil.h>\n#incl"
  },
  {
    "path": "Sysmon/CSysmonUtil.cpp",
    "chars": 1259,
    "preview": "#include \"StdAfx.h\"\n#include \"CSysmonUtil.h\"\n\n\nCSysmonUtil::CSysmonUtil(void)\n{\n}\n\n\nCSysmonUtil::~CSysmonUtil(void)\n{\n}\n"
  },
  {
    "path": "Sysmon/CSysmonUtil.h",
    "chars": 275,
    "preview": "#ifndef _CSysmonUtil_h\n#define _CSysmonUtil_h\n\ntypedef unsigned __int64 QWORD;\n\nclass CSysmonUtil\n{\npublic:\n\tCSysmonUtil"
  },
  {
    "path": "Sysmon/ReadMe.txt",
    "chars": 2505,
    "preview": "========================================================================\n    WIN32 APPLICATION : Sysmon Project Overview"
  },
  {
    "path": "Sysmon/Resource.h",
    "chars": 700,
    "preview": "//{{NO_DEPENDENCIES}}\n// Microsoft Visual C++ generated include file.\n// Used by Sysmon.rc\n//\n\n#define IDS_APP_TITLE\t\t\t1"
  },
  {
    "path": "Sysmon/Sysmon.cpp",
    "chars": 5893,
    "preview": "// Sysmon.cpp : Defines the entry point for the application.\n//\n\n#include \"stdafx.h\"\n#include \"Sysmon.h\"\n#include <Shell"
  },
  {
    "path": "Sysmon/Sysmon.h",
    "chars": 1045,
    "preview": "#pragma once\n\n#include \"resource.h\"\n\nBOOLEAN\n\tFORCEINLINE\n\tIsListEmpty(\n\t__in const LIST_ENTRY * ListHead\n\t)\n{\n\treturn ("
  },
  {
    "path": "Sysmon/Sysmon.vcxproj",
    "chars": 8778,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microso"
  },
  {
    "path": "Sysmon/Sysmon.vcxproj.filters",
    "chars": 3574,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuil"
  },
  {
    "path": "Sysmon/Sysmon.vcxproj.user",
    "chars": 598,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuil"
  },
  {
    "path": "Sysmon/stdafx.cpp",
    "chars": 285,
    "preview": "// stdafx.cpp : source file that includes just the standard includes\n// Sysmon.pch will be the pre-compiled header\n// st"
  },
  {
    "path": "Sysmon/stdafx.h",
    "chars": 508,
    "preview": "// stdafx.h : include file for standard system include files,\n// or project specific include files that are used frequen"
  },
  {
    "path": "Sysmon/targetver.h",
    "chars": 327,
    "preview": "#pragma once\n\n// Including SDKDDKVer.h defines the highest available Windows platform.\n\n// If you wish to build your app"
  },
  {
    "path": "Sysmon/undname.cpp",
    "chars": 84831,
    "preview": "//\n// Copyright (c) Microsoft Corporation.  All rights reserved.\n//\n//\n// This source code is licensed under Microsoft S"
  },
  {
    "path": "Sysmon/undname.h",
    "chars": 5634,
    "preview": "//\n// Copyright (c) Microsoft Corporation.  All rights reserved.\n//\n//\n// This source code is licensed under Microsoft S"
  },
  {
    "path": "Sysmon/undname.idl",
    "chars": 22856,
    "preview": "import \"oaidl.idl\";\nimport \"ocidl.idl\";\n\n//\n// Copyright (c) Microsoft Corporation.  All rights reserved.\n//\n//\n// Use o"
  },
  {
    "path": "Sysmon.sln",
    "chars": 1970,
    "preview": "\nMicrosoft Visual Studio Solution File, Format Version 11.00\n# Visual Studio 2010\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A"
  },
  {
    "path": "Sysmon.sys/CDeviceExtension.cpp",
    "chars": 869,
    "preview": "#include \"CDeviceExtension.h\"\n\n/**********************************************************************************/\n#pra"
  },
  {
    "path": "Sysmon.sys/CDeviceExtension.h",
    "chars": 280,
    "preview": "#ifndef _CDeviceExtension_h\n#define _CDeviceExtension_h\n#include <CppLib.h>\n\nclass CDeviceExtension\n{\npublic:\n\tCDeviceEx"
  },
  {
    "path": "Sysmon.sys/CDriverEntry.cpp",
    "chars": 7266,
    "preview": "#include \"CDriverEntry.h\"\n#include <CppLib.h>\n#include \"CErrorStatus.h\"\n#include \"CUnicodeString.h\"\n#include \"CString.h\""
  },
  {
    "path": "Sysmon.sys/CDriverEntry.h",
    "chars": 1095,
    "preview": "#ifndef _CDriverEntry_h\n#define _CDriverEntry_h\n#include \"CVersion.h\"\n#include <CppLib.h>\n#include \"CReportRecord.h\"\n#in"
  },
  {
    "path": "Sysmon.sys/CReportRecord.cpp",
    "chars": 627,
    "preview": "#include \"CReportRecord.h\"\n\n/**********************************************************************************/\n#pragma"
  },
  {
    "path": "Sysmon.sys/CReportRecord.h",
    "chars": 349,
    "preview": "#ifndef _CReportRecord_h\n#define _CReportRecord_h\n\n#include <cpplib.h>\n#include <CListEntry.h>\n\n\nclass CSysmonRecord\n{\np"
  },
  {
    "path": "Sysmon.sys/CSysmonControl.cpp",
    "chars": 323,
    "preview": "#include \"CSysmonControl.h\"\n\n/**********************************************************************************/\n#pragm"
  },
  {
    "path": "Sysmon.sys/CSysmonControl.h",
    "chars": 149,
    "preview": "#ifndef _CSysmonControl_h\n#define _CSysmonControl_h\n\nclass CSysmonControl\n{\npublic:\n\tCSysmonControl(void);\n\tvirtual ~CSy"
  },
  {
    "path": "Sysmon.sys/CSysmonDispatchEngine.cpp",
    "chars": 8678,
    "preview": "#include \"CSysmonDispatchEngine.h\"\n#include <CErrorStatus.h>\n#include <CIoStackLocation.h>\n#include <CIrp.h>\n#include <C"
  },
  {
    "path": "Sysmon.sys/CSysmonDispatchEngine.h",
    "chars": 1244,
    "preview": "#ifndef _CSysmonDispatchEngine_h\n#define _CSysmonDispatchEngine_h\n#include <CppLib.h>\n#include \"CDeviceExtension.h\"\n#inc"
  },
  {
    "path": "Sysmon.sys/CSysmonIoControl.h",
    "chars": 461,
    "preview": "#ifndef _CSysmonControl_h\n#define _CSysmonControl_h\n\ntypedef enum _Base_Sysmon_FileObj_Type\n{\n\tkFileObjErrorType = 0,\n\tk"
  },
  {
    "path": "Sysmon.sys/CSysmonMiniFltFilter.cpp",
    "chars": 2699,
    "preview": "#include \"CSysmonMiniFltFilter.h\"\n#include \"CSysmonDispatchEngine.h\"\n#include \"CSysmonIoControl.h\"\n\n\n#define FLTPOST(Fn)"
  },
  {
    "path": "Sysmon.sys/CSysmonMiniFltFilter.h",
    "chars": 822,
    "preview": "#ifndef _CSysmonMiniFltFilter_h\n#define _CSysmonMiniFltFilter_h\n\n#include <cminifltfilter.h>\n#include <CListEntry.h>\n#in"
  },
  {
    "path": "Sysmon.sys/ReadMe.txt",
    "chars": 2141,
    "preview": "========================================================================\n    DYNAMIC LINK LIBRARY : Sysmon.sys Project O"
  },
  {
    "path": "Sysmon.sys/Sysmon.sys.cpp",
    "chars": 374,
    "preview": "// Sysmon.sys.cpp : Defines the exported functions for the DLL application.\n//\n\n#include \"stdafx.h\"\n#include <CppLib.h>\n"
  },
  {
    "path": "Sysmon.sys/Sysmon.sys.vcxproj",
    "chars": 15913,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microso"
  },
  {
    "path": "Sysmon.sys/Sysmon.sys.vcxproj.filters",
    "chars": 6979,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuil"
  },
  {
    "path": "Sysmon.sys/Sysmon.sys.vcxproj.user",
    "chars": 139,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuil"
  },
  {
    "path": "Sysmon.sys/cpplib/CAssert.h",
    "chars": 99,
    "preview": "#ifndef _CAssert_h\n#define _CAssert_h\n\n#define CAssert( a )\n#define CAssertAddrValid( a , b)\n#endif"
  },
  {
    "path": "Sysmon.sys/cpplib/CAttachDevice.cpp",
    "chars": 1829,
    "preview": "#include \"CAttachDevice.h\"\n#include \"CDebug.h\"\n\n\n/**********************************************************************"
  },
  {
    "path": "Sysmon.sys/cpplib/CAttachDevice.h",
    "chars": 700,
    "preview": "#ifndef _CAfdAttachDevice_H\n#define _CAfdAttachDevice_H\n\n#include \"cpplib.h\"\n#include \"CListEntry.h\"\n#include \"CErrorSta"
  },
  {
    "path": "Sysmon.sys/cpplib/CDebug.cpp",
    "chars": 493,
    "preview": "#include \"cpplib.h\"\n#include \"CDebug.h\"\n#include <stdarg.h>\n#include <stdio.h>\n\n\nCDebug::CDebug(void)\n{\n}\n\n\nCDebug::~CDe"
  },
  {
    "path": "Sysmon.sys/cpplib/CDebug.h",
    "chars": 314,
    "preview": "#ifndef _CDebug_h\n#define _CDebug_h\n#include \"cpplib.h\"\n\nclass CDebug\n{\npublic:\n\ttypedef enum {kMaxLengthString = 256};\n"
  },
  {
    "path": "Sysmon.sys/cpplib/CDeviceObject.cpp",
    "chars": 3900,
    "preview": "\n#include \"CDeviceObject.h\"\n#include \"CAssert.h\"\n#include \"CDebug.h\"\n\nCDeviceObject::CDeviceObject(void)\n\t:mDeviceObject"
  },
  {
    "path": "Sysmon.sys/cpplib/CDeviceObject.h",
    "chars": 1368,
    "preview": "#ifndef _CDeviceObject_h\n#define _CDeviceObject_h\n#include \"cpplib.h\"\n#include \"CErrorStatus.h\"\n#include \"CString.h\"\n#in"
  },
  {
    "path": "Sysmon.sys/cpplib/CDispatchEngine.cpp",
    "chars": 120,
    "preview": "#include \"CDispatchEngine.h\"\n\n\nCDispatchEngine::CDispatchEngine(void)\n{\n}\n\n\nCDispatchEngine::~CDispatchEngine(void)\n{\n}\n"
  },
  {
    "path": "Sysmon.sys/cpplib/CDispatchEngine.h",
    "chars": 154,
    "preview": "#ifndef _CDispatchEngine_h\n#define _CDispatchEngine_h\n\nclass CDispatchEngine\n{\npublic:\n\tCDispatchEngine(void);\n\tvirtual "
  },
  {
    "path": "Sysmon.sys/cpplib/CDriverDispatch.cpp",
    "chars": 572,
    "preview": "#include \"CDriverDispatch.h\"\n\n\nCDriverDispatch::CDriverDispatch(void)\n\t:mDriverDisptach(NULL)\n{\n}\n\nCDriverDispatch::CDri"
  },
  {
    "path": "Sysmon.sys/cpplib/CDriverDispatch.h",
    "chars": 402,
    "preview": "#ifndef _CDriverDispatch_h\n#define _CDriverDispatch_h\n#include <cpplib.h>\n\nclass CDriverDispatch\n{\npublic:\n\tCDriverDispa"
  },
  {
    "path": "Sysmon.sys/cpplib/CDriverObject.cpp",
    "chars": 399,
    "preview": "\n#include \"CDriverObject.h\"\n\n\nCDriverObject::CDriverObject(void)\n{\n}\n\nCDriverObject::CDriverObject(PDRIVER_OBJECT Driver"
  },
  {
    "path": "Sysmon.sys/cpplib/CDriverObject.h",
    "chars": 341,
    "preview": "#ifndef _CDriverObject_h\n#define _CDriverObject_h\n#include \"cpplib.h\"\n\nclass CDriverObject\n{\npublic:\n\tCDriverObject(void"
  },
  {
    "path": "Sysmon.sys/cpplib/CEResource.cpp",
    "chars": 327,
    "preview": "#include \"CEResource.h\"\n\n\nCEResource::CEResource(void)\n{\n\t//mReference = 0;\n\tExInitializeResource(&mEResoure);\n}\n\nCEReso"
  },
  {
    "path": "Sysmon.sys/cpplib/CEResource.h",
    "chars": 236,
    "preview": "#ifndef _CEResource_h\n#define _CEResource_h\n\n#include \"cpplib.h\"\n\nclass CEResource\n{\npublic:\n\tCEResource(void);\n\t~CEReso"
  },
  {
    "path": "Sysmon.sys/cpplib/CErrorStatus.cpp",
    "chars": 481,
    "preview": "#include \"CErrorStatus.h\"\n\n\nCErrorStatus::CErrorStatus(void)\n{\n\tmNtStatus = STATUS_UNSUCCESSFUL;\n}\n\nCErrorStatus::~CErro"
  },
  {
    "path": "Sysmon.sys/cpplib/CErrorStatus.h",
    "chars": 393,
    "preview": "#ifndef _CErrorStatus_H\n#define _CErrorStatus_H\n\n#include \"cpplib.h\"\n\nclass CErrorStatus\n{\npublic:\n\tCErrorStatus(void);\n"
  },
  {
    "path": "Sysmon.sys/cpplib/CFileObject.cpp",
    "chars": 576,
    "preview": "#include \"cpplib.h\"\n#include \"CFileObject.h\"\n\n\nCFileObject::CFileObject(void)\n\t:mFileObj(NULL)\n{\n}\n\nCFileObject::CFileOb"
  },
  {
    "path": "Sysmon.sys/cpplib/CFileObject.h",
    "chars": 358,
    "preview": "#ifndef _CFileObject_h\n#define _CFileObject_h\n\nclass CFileObject\n{\npublic:\n\tCFileObject(void);\n\tCFileObject(const CFileO"
  },
  {
    "path": "Sysmon.sys/cpplib/CFilterDevice.cpp",
    "chars": 4180,
    "preview": "#include \"CFilterDevice.h\"\n#include \"CIrp.h\"\n#include \"CppLib.h\"\n#include \"CAssert.h\"\n\nWCHAR* CFilterDevice::sDeviceName"
  },
  {
    "path": "Sysmon.sys/cpplib/CFilterDevice.h",
    "chars": 2110,
    "preview": "#ifndef _CFilterDevice_H\n#define _CFilterDevice_H\n\n#include \"cpplib.h\"\n#include \"CErrorStatus.h\"\n#include \"CAttachDevice"
  },
  {
    "path": "Sysmon.sys/cpplib/CIntNumber.cpp",
    "chars": 26,
    "preview": "#include \"CIntNumber.h\"\n\n\n"
  },
  {
    "path": "Sysmon.sys/cpplib/CIntNumber.h",
    "chars": 885,
    "preview": "#ifndef _CIntNumber_h\n#define _CIntNumber_h\n\n#include \"cpplib.h\"\n\ntemplate<typename T>\nclass CIntNumber\n{\npublic:\n\tCIntN"
  },
  {
    "path": "Sysmon.sys/cpplib/CIoStackLocation.cpp",
    "chars": 939,
    "preview": "#include \"cpplib.h\"\n#include \"CIoStackLocation.h\"\n\n\nCIoStackLocation::CIoStackLocation(void)\n\t:mStack(NULL)\n{\n}\n\nCIoStac"
  },
  {
    "path": "Sysmon.sys/cpplib/CIoStackLocation.h",
    "chars": 576,
    "preview": "#ifndef _CIoStackLocation_h\n#define _CIoStackLocation_h\n\n#include \"CFileObject.h\"\n\nclass CIoStackLocation\n{\npublic:\n\tCIo"
  },
  {
    "path": "Sysmon.sys/cpplib/CIrp.cpp",
    "chars": 5092,
    "preview": "#include \"cpplib.h\"\n#include \"CIrp.h\"\n#include \"CAssert.h\"\n\nCIrp::CIrp(void)\n:mIrp(NULL)\n{\n\n}\n\nCIrp::CIrp(PIRP pIrp)\n:mI"
  },
  {
    "path": "Sysmon.sys/cpplib/CIrp.h",
    "chars": 2426,
    "preview": "#ifndef _CIrp_h\n#define _CIrp_h\n\n#include \"cpplib.h\"\n#include \"CErrorStatus.h\"\n\nclass CIrp\n{\npublic:\n\tenum IrpStackLocat"
  },
  {
    "path": "Sysmon.sys/cpplib/CListEntry.cpp",
    "chars": 271,
    "preview": "#include \"CListEntry.h\"\n\n// template< typename T>\n// CAfdList<T>::CAfdList()\n// {\n// \tInitializeListHead( &mAfdList);\n//"
  },
  {
    "path": "Sysmon.sys/cpplib/CListEntry.h",
    "chars": 4139,
    "preview": "#ifndef _CListEntry_H\n#define _CListEntry_H\n\n#include \"cpplib.h\"\n#include \"CEResource.h\"\n\n#define LIST_COMMON_TAG 'Aflt'"
  },
  {
    "path": "Sysmon.sys/cpplib/CMiniFltFilter.cpp",
    "chars": 6413,
    "preview": "#include \"CMiniFltFilter.h\"\n\n\n#pragma comment(lib,\"FltMgr.lib\")\n\n/******************************************************"
  },
  {
    "path": "Sysmon.sys/cpplib/CMiniFltFilter.h",
    "chars": 2687,
    "preview": "#ifndef _CMiniFltFilter_h\n#define _CMiniFltFilter_h\n\n#include <fltKernel.h>\n#include \"CErrorStatus.h\"\n\n#define MAX_FLT_C"
  },
  {
    "path": "Sysmon.sys/cpplib/CNPagedLookaside.cpp",
    "chars": 30,
    "preview": "#include \"CNPagedLookaside.h\"\n"
  },
  {
    "path": "Sysmon.sys/cpplib/CNPagedLookaside.h",
    "chars": 641,
    "preview": "#ifndef _CNPagedLookaside_h\n#define _CNPagedLookaside_h\n\n#include \"cpplib.h\"\n\ntemplate< typename T, USHORT PoolTag = NPA"
  },
  {
    "path": "Sysmon.sys/cpplib/CPool.cpp",
    "chars": 21,
    "preview": "#include \"CPool.h\"\n\n\n"
  },
  {
    "path": "Sysmon.sys/cpplib/CPool.h",
    "chars": 1983,
    "preview": "#ifndef _CPool_h\n#define _CPool_h\n\n#include \"cpplib.h\"\n#include \"CIntNumber.h\"\n\ntemplate<typename T,\n\t\tPOOL_TYPE PoolTyp"
  },
  {
    "path": "Sysmon.sys/cpplib/CString.cpp",
    "chars": 21,
    "preview": "#include \"CString.h\"\n"
  },
  {
    "path": "Sysmon.sys/cpplib/CString.h",
    "chars": 696,
    "preview": "#ifndef _CStringT_h\n#define _CStringT_h\n#include <CppLib.h>\n\ntemplate<typename T, int COUNT>\nclass CStringT\n{\npublic:\n\tC"
  },
  {
    "path": "Sysmon.sys/cpplib/CSysmonBase.cpp",
    "chars": 3622,
    "preview": "#include \"CSysmonBase.h\"\n#include <CErrorStatus.h>\n#include <cpplib.h>\n\nCSysmonBase::CSysmonBase(void)\n{\n}\n\n\nCSysmonBase"
  },
  {
    "path": "Sysmon.sys/cpplib/CSysmonBase.h",
    "chars": 439,
    "preview": "#ifndef _CSysmonBase_h\n#define _CSysmonBase_h\n\n#include <cpplib.h>\n#include <fltKernel.h>\n\nclass CSysmonBase\n{\npublic:\n\t"
  },
  {
    "path": "Sysmon.sys/cpplib/CUnicodeString.cpp",
    "chars": 1880,
    "preview": "#include \"CUnicodeString.h\"\n\n/**********************************************************************************/\n#pragm"
  },
  {
    "path": "Sysmon.sys/cpplib/CUnicodeString.h",
    "chars": 439,
    "preview": "#ifndef _CUnicodeString_h\n#define _CUnicodeString_h\n\n\n#include <CppLib.h>\n\n\nclass CUnicodeString\n{\npublic:\n\tCUnicodeStri"
  },
  {
    "path": "Sysmon.sys/cpplib/CVersion.cpp",
    "chars": 1258,
    "preview": "#include \"CVersion.h\"\n\nCVersion::CVersion(void)\n\t:mMajorVersion(0)\n\t,mMinorVersion(0)\n\t,mBuildNumber(0)\n{\n}\n\n\nCVersion::"
  },
  {
    "path": "Sysmon.sys/cpplib/CVersion.h",
    "chars": 352,
    "preview": "#ifndef _CVersion_h\n#define _CVersion_h\n#include <cpplib.h>\n\nclass CVersion\n{\npublic:\n\tCVersion(void);\n\t~CVersion(void);"
  },
  {
    "path": "Sysmon.sys/cpplib/CppLib.cpp",
    "chars": 3609,
    "preview": "#include \"CppLib.h\"\n#include <excpt.h>\n#include \"CAssert.h\"\nAtExitEntry *AtExitEntryList = NULL;\n\n\n// Exported variables"
  },
  {
    "path": "Sysmon.sys/cpplib/CppLib.h",
    "chars": 3399,
    "preview": "#ifndef _CPP_LIB_h\n#define _CPP_LIB_h\n#include <ntifs.h>\n#include <strsafe.h>\n\ntypedef char CHAR;\ntypedef unsigned char "
  },
  {
    "path": "Sysmon.sys/stdafx.cpp",
    "chars": 289,
    "preview": "// stdafx.cpp : source file that includes just the standard includes\n// Sysmon.sys.pch will be the pre-compiled header\n/"
  },
  {
    "path": "Sysmon.sys/stdafx.h",
    "chars": 402,
    "preview": "// stdafx.h : include file for standard system include files,\n// or project specific include files that are used frequen"
  },
  {
    "path": "Sysmon.sys/targetver.h",
    "chars": 284,
    "preview": "#pragma once\n\n// Including SDKDDKVer.h defines the highest available Windows platform.\n\n// If you wish to build your app"
  }
]

// ... and 2 more files (download for full content)

About this extraction

This page contains the full source code of the basketwill/Sysmon_reverse GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 99 files (365.0 KB), approximately 113.3k tokens, and a symbol index with 273 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!