Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

658 lines
15 KiB

// StartTrace.cpp : Defines the entry point for the DLL application.
//
//***************************************************************************
//
// judyp May 1999
//
//***************************************************************************
#include "stdafx.h"
#pragma warning (disable : 4786)
#pragma warning (disable : 4275)
#include <iostream>
#include <strstream>
#include <fstream>
#include <fcntl.h>
#include <io.h>
#include <string>
#include <sstream>
#include <map>
#include <list>
using namespace std;
#include <malloc.h>
#include <tchar.h>
#include <windows.h>
#ifdef NONNT5
typedef unsigned long ULONG_PTR;
#endif
#include <wmistr.h>
#include <guiddef.h>
#include <initguid.h>
#include <evntrace.h>
#include <WTYPES.H>
#include "t_string.h"
#include "Persistor.h"
#include "Logger.h"
#include "TCOData.h"
#include "Utilities.h"
#include "StructureWrappers.h"
#include "StructureWapperHelpers.h"
#include "ConstantMap.h"
#include "CollectionControl.h"
extern CConstantMap g_ConstantMap;
#define MAX_LINE 2048
int ParseGuids
(
TCHAR *ptcBuffer,
TCOData *pstructTCOData,
LPTSTR *plptstrErrorDesc
);
int ParseExeData
(
t_string &tsData,
int &nExes,
LPTSTR *&lptstrArray,
LPTSTR *plptstrErrorDesc
);
// If an error occurs you users of this function must delete
// plptstrErrorDesc. It will contain a string describing
// the error.
int GetAllTCOData
(
IN LPCTSTR lpctstrFile,
OUT TCOData **pstructTCOData,
OUT TCOFunctionalData **pstructTCOFunctionalData,
OUT LPTSTR *plptstrErrorDesc, // Any error we had.
IN bool bGetFunctionalData
)
{
*pstructTCOData = (TCOData *) malloc (sizeof(TCOData));
RtlZeroMemory(*pstructTCOData , sizeof(TCOData));
if (bGetFunctionalData)
{
*pstructTCOFunctionalData = (TCOFunctionalData *) malloc(sizeof(TCOFunctionalData));
RtlZeroMemory(*pstructTCOFunctionalData , sizeof(TCOFunctionalData));
}
LPSTR lpstrFile;
#ifdef UNICODE
lpstrFile = NewLPSTR(lpctstrFile);
#else
lpstrFile = NewTCHAR(lpctstrFile);
#endif
CPersistor PersistorIn
(lpstrFile,
ios::in | 0x20, // ios::nocreate = 0x20 - cannot get to compile!!!
true );
HRESULT hr = PersistorIn.Open();
if (FAILED(hr))
{
t_string tsTemp;
tsTemp = _T("TCOData error: Could not open file or file was not in correct character set (Unicode or ANSI) for file ");
t_string tsFile;
#ifdef _UNICODE
LPWSTR lpwstrTemp = NewLPWSTR(lpstrFile);
tsFile = lpwstrTemp;
free(lpwstrTemp);
#else
tsFile = lpstrFile;
#endif
tsTemp += tsFile;
free (lpstrFile);
lpstrFile = NULL;
tsTemp += _T(".");
*plptstrErrorDesc = NewTCHAR(tsTemp.c_str());
return -1;
}
free (lpstrFile);
lpstrFile = NULL;
int nReturn =
GetTCOData
(
PersistorIn,
*pstructTCOData,
plptstrErrorDesc // Any error we had.
);
if (nReturn != ERROR_SUCCESS)
{
PersistorIn.Close();
return nReturn;
}
if (bGetFunctionalData)
{
nReturn =
TCOFunctionalObjects
(
PersistorIn,
*pstructTCOFunctionalData,
plptstrErrorDesc // Describes error this function had.
);
}
PersistorIn.Close();
return nReturn;
}
// If an error occurs you users of this function must delete
// plptstrErrorDesc. It will contain a string describing
// the error.
int GetTCOData
(
IN CPersistor &PersistorIn,
OUT TCOData *pstructTCOData,
OUT LPTSTR *plptstrErrorDesc // Any error we had.
)
{
RtlZeroMemory(pstructTCOData , sizeof(TCOData));
// We are doing line oriented serailization and assume that
// a line in the stream is 1024 or less TCHARS.
TCHAR *ptcBuffer = (TCHAR *) malloc(MAX_LINE * sizeof(TCHAR));
*plptstrErrorDesc = NULL;
// Short description
GetALine(PersistorIn.Stream(),ptcBuffer, MAX_LINE);
pstructTCOData->m_lptstrShortDesc = NewTCHAR(ptcBuffer);
// Long description.
GetALine(PersistorIn.Stream(),ptcBuffer, MAX_LINE);
pstructTCOData->m_lptstrLongDesc = NewTCHAR(ptcBuffer);
// Expected result had better be in the Constant map.
// Constant map is used to map a string to an undsigned int.
GetALine(PersistorIn.Stream(),ptcBuffer, MAX_LINE);
t_string tsTemp;
tsTemp = ptcBuffer;
CONSTMAP::iterator Iterator;
Iterator = g_ConstantMap.m_Map.find(tsTemp);
// If you do not find your value in the map look in
// ConstantMap.cpp. You probably forgot to add it;->
if (Iterator == g_ConstantMap.m_Map.end())
{
*plptstrErrorDesc = NewTCHAR(_T("TCOData error: Expected error is not in map"));
free(ptcBuffer);
return -1;
}
else
{
pstructTCOData->m_lptstrExpectedResult = NewTCHAR(ptcBuffer);
pstructTCOData->m_ulExpectedResult = (*Iterator).second;
}
// TraceHandle values are VALUE_VALID or VALUE_NULL
GetALine(PersistorIn.Stream(),ptcBuffer, MAX_LINE);
tsTemp = ptcBuffer;
if (case_insensitive_compare(tsTemp,_T("VALUE_VALID")) == 0)
{
pstructTCOData->m_pTraceHandle =
(TRACEHANDLE *) malloc (sizeof(TRACEHANDLE));
*pstructTCOData->m_pTraceHandle = NULL;
}
else if (case_insensitive_compare(tsTemp,_T("VALUE_NULL")) == 0)
{
pstructTCOData->m_pTraceHandle = (TRACEHANDLE *) NULL;
}
else
{
*plptstrErrorDesc =
NewTCHAR
(_T("TCOData error: Error in value of TraceHandle. Valid values are \"VALUE_VALID\" or \"VALUE_NULL\"."));
free(ptcBuffer);
return -1;
}
GetALine(PersistorIn.Stream(),ptcBuffer, MAX_LINE);
tsTemp = ptcBuffer;
InitializeTCHARVar(tsTemp , (void *) &pstructTCOData->m_lptstrInstanceName);
// API test - valid values 0 - 6
// OtherTest = 0,
// StartTraceTest = 1,
// StopTraceTest = 2,
// EnableTraceTest = 3,
// QueryTraceTest = 4,
// UpdateTrace = 5,
// QueryAllTraces = 6
GetALine(PersistorIn.Stream(),ptcBuffer, MAX_LINE);
tsTemp = ptcBuffer;
InitializeULONGVar(tsTemp , (void *) &pstructTCOData->m_ulAPITest);
if (pstructTCOData->m_ulAPITest < 0 || pstructTCOData->m_ulAPITest > 6)
{
*plptstrErrorDesc =
NewTCHAR
(_T("TCOData error: Error in value of m_ulAPITest. Valid values are 0 - 6. See enum in TCOData.h"));
free(ptcBuffer);
return -1;
}
// Valid values are KERNEL_LOGGER or PRIVATE_LOGGER
GetALine(PersistorIn.Stream(),ptcBuffer, MAX_LINE);
pstructTCOData->m_lptstrLoggerMode = NewTCHAR(ptcBuffer);
// Enable is used for EnableTrace.
GetALine(PersistorIn.Stream(),ptcBuffer, MAX_LINE);
tsTemp = ptcBuffer;
if (case_insensitive_compare(tsTemp.substr(0,7),_T("ENABLE:")) != 0)
{
*plptstrErrorDesc =
NewTCHAR
(_T("TCOData error: Enable: expected."));
free(ptcBuffer);
return -1;
}
else
{
InitializeULONGVar(tsTemp.substr(7) , &pstructTCOData->m_ulEnable);
}
// EnableFlag is used for EnableTrace and is passed to the provider.
GetALine(PersistorIn.Stream(),ptcBuffer, MAX_LINE);
tsTemp = ptcBuffer;
if (case_insensitive_compare(tsTemp.substr(0,11),_T("ENABLEFLAG:")) != 0)
{
*plptstrErrorDesc =
NewTCHAR
(_T("TCOData error: EnableFlag: expected."));
free(ptcBuffer);
return -1;
}
else
{
InitializeHandleVar(tsTemp.substr(11) , &pstructTCOData->m_ulEnableFlag);
}
// EnableLevel is used for EnableTrace and is passed to the provider.
GetALine(PersistorIn.Stream(),ptcBuffer, MAX_LINE);
tsTemp = ptcBuffer;
if (case_insensitive_compare(tsTemp.substr(0,12),_T("ENABLELEVEL:")) != 0)
{
*plptstrErrorDesc =
NewTCHAR
(_T("TCOData error: EnableLevel: expected."));
free(ptcBuffer);
return -1;
}
else
{
InitializeHandleVar(tsTemp.substr(12) , &pstructTCOData->m_ulEnableLevel);
}
CEventTraceProperties cPropsIn;
// This has to be mofified to allow a NULL strucutre.
cPropsIn.Persist( PersistorIn);
pstructTCOData->m_pProps = cPropsIn.GetEventTracePropertiesInstance();
if (pstructTCOData->m_pProps &&
case_insensitive_compare(tsTemp,_T("PRIVATE_LOGGER")) == 0)
{
pstructTCOData->m_pProps->LogFileMode =
pstructTCOData->m_pProps->LogFileMode | EVENT_TRACE_PRIVATE_LOGGER_MODE;
}
GetALine(PersistorIn.Stream(),ptcBuffer, MAX_LINE);
int nReturn = ParseGuids(ptcBuffer, pstructTCOData, plptstrErrorDesc);
if(nReturn != ERROR_SUCCESS)
{
return nReturn;
}
// Validator
if (PersistorIn.Stream().eof() == false)
{
GetALine(PersistorIn.Stream(),ptcBuffer, MAX_LINE);
pstructTCOData->m_lptstrValidator = NewTCHAR(ptcBuffer);
}
free(ptcBuffer);
return 0;
}
// If an error occurs you users of this function must delete
// plptstrErrorDesc. It will contain a string describing
// the error.
int TCOFunctionalObjects
( IN CPersistor &PersistorIn,
IN OUT TCOFunctionalData *pstructTCOFunctionalData,
OUT LPTSTR *plptstrErrorDesc // Describes error this function had.
)
{
// We are doing line oriented serailization and assume that
// a line in the stream is 1024 or less TCHARS.
TCHAR *ptcBuffer = (TCHAR *) malloc(MAX_LINE * sizeof(TCHAR));
*plptstrErrorDesc = NULL;
t_string tsTemp;
t_string tsError;
t_string tsSubstr;
if (PersistorIn.Stream().eof() == false)
{
GetALine(PersistorIn.Stream(),ptcBuffer, MAX_LINE);
tsTemp = ptcBuffer;
tsSubstr = tsTemp.substr(0,9);
if (case_insensitive_compare(tsSubstr,_T("provider:")) == 0)
{
tsSubstr = tsTemp.substr(9);
int nReturn =
ParseExeData
(
tsSubstr,
pstructTCOFunctionalData->m_nProviders,
pstructTCOFunctionalData->m_lptstrProviderArray,
plptstrErrorDesc
);
if (nReturn != ERROR_SUCCESS)
{
tsError = _T("Invalid providers argument: ");
tsError += tsTemp;
tsError += _T(".");
*plptstrErrorDesc = NewTCHAR(tsError.c_str());
free(ptcBuffer);
return -1;
}
}
else
{
tsError = _T("Invalid providers argument: ");
tsError += tsTemp;
tsError += _T(".");
*plptstrErrorDesc = NewTCHAR(tsError.c_str());
free(ptcBuffer);
return -1;
}
}
// We may have a DataProvider. If not we us our default.
if (PersistorIn.Stream().eof() == false)
{
GetALine(PersistorIn.Stream(),ptcBuffer, MAX_LINE);
tsTemp = ptcBuffer;
tsSubstr = tsTemp.substr(0,9);
if (case_insensitive_compare(tsSubstr,_T("consumer:")) == 0)
{
tsSubstr = tsTemp.substr(9);
int nReturn =
ParseExeData
(
tsSubstr,
pstructTCOFunctionalData->m_nConsumers,
pstructTCOFunctionalData->m_lptstrConsumerArray,
plptstrErrorDesc
);
if (nReturn != ERROR_SUCCESS)
{
tsError = _T("Invalid consumers argument: ");
tsError += tsTemp;
tsError += _T(".");
*plptstrErrorDesc = NewTCHAR(tsError.c_str());
free(ptcBuffer);
return -1;
}
}
else
{
tsError = _T("Invalid consumers argument: ");
tsError += tsTemp;
tsError += _T(".");
*plptstrErrorDesc = NewTCHAR(tsError.c_str());
free(ptcBuffer);
return -1;
}
}
free(ptcBuffer);
return 0;
}
void FreeTCOData (TCOData *pstructTCOData)
{
if (!pstructTCOData)
{
return;
}
free(pstructTCOData->m_lptstrShortDesc);
free(pstructTCOData->m_lptstrLongDesc);
free(pstructTCOData->m_lptstrExpectedResult);
free(pstructTCOData->m_pTraceHandle);
free(pstructTCOData->m_lptstrInstanceName);
free(pstructTCOData->m_lptstrLoggerMode);
free(pstructTCOData->m_lpguidArray);
if (pstructTCOData->m_pProps)
{
free(pstructTCOData->m_pProps->LoggerName);
free(pstructTCOData->m_pProps->LogFileName);
}
free(pstructTCOData->m_pProps);
free(pstructTCOData->m_lptstrValidator);
free(pstructTCOData);
}
void FreeTCOFunctionalData (TCOFunctionalData *pstructTCOFunctionalData)
{
if (!pstructTCOFunctionalData)
{
return;
}
int i;
TCHAR *pTemp;
for (i = 0; i < pstructTCOFunctionalData->m_nProviders; i++)
{
pTemp = pstructTCOFunctionalData->m_lptstrProviderArray[i];
free (pTemp);
}
free (pstructTCOFunctionalData->m_lptstrProviderArray);
for (i = 0; i < pstructTCOFunctionalData->m_nConsumers; i++)
{
pTemp = pstructTCOFunctionalData->m_lptstrConsumerArray[i];
free (pTemp);
}
free (pstructTCOFunctionalData->m_lptstrConsumerArray);
free(pstructTCOFunctionalData);
}
int ParseExeData
(
t_string &tsData,
int &nExes,
LPTSTR *&lptstrArray,
LPTSTR *plptstrErrorDesc
)
{
// Embedded " are not allowed in the command line. Had to draw
// the line somewhere.
// Tokenize on "," and " at end of line.
list <t_string> listExes;
bool bDone = false;
int nBeg = 0;
int nFind = tsData.find(_T(","), nBeg);
t_string tsExe;
while (!bDone)
{
if (nFind != t_string::npos)
{
tsExe = tsData.substr(nBeg,nFind - nBeg);
listExes.push_back(tsExe);
tsExe.erase();
}
else
{
tsExe = tsData.substr(nBeg,t_string::npos);
listExes.push_back(tsExe);
bDone = true;
tsExe.erase();
}
nBeg = nFind + 1;
nFind = tsData.find(_T(","), nBeg);
}
// Allocate the Exe array
nExes = listExes.size();
lptstrArray =
(TCHAR **) malloc (sizeof(TCHAR *) * nExes);
RtlZeroMemory
(lptstrArray,
sizeof(sizeof(TCHAR *) * nExes));
list<t_string>::iterator pListExes;
int i = 0;
for (pListExes = listExes.begin(); pListExes != listExes.end() ; ++pListExes)
{
tsExe = (*pListExes);
lptstrArray[i++] = NewTCHAR(tsExe.c_str());
}
return ERROR_SUCCESS;
}
int ParseGuids
(
TCHAR *ptcBuffer,
TCOData *pstructTCOData,
LPTSTR *plptstrErrorDesc
)
{
// Is Wnode does not have a GUID put the first one from list in it.
t_string tsTemp;
tsTemp = ptcBuffer;
if (case_insensitive_compare(tsTemp.substr(0,6),_T("guids:")) != 0)
{
tsTemp.erase();
tsTemp = _T("Invalid Guids entry: ");
tsTemp += ptcBuffer;
tsTemp += _T(".");
*plptstrErrorDesc = NewTCHAR(tsTemp.c_str());
return -1;
}
// Count the commas
int nFind = tsTemp.find(_T(','));
t_string tsGuid;
int nBeg = 6;
if(nBeg == tsTemp.length())
{
pstructTCOData->m_nGuids = 0;
pstructTCOData->m_lpguidArray = NULL;
return 0;
}
// We only have one GUID.
if (nFind == t_string::npos)
{
tsGuid = tsTemp.substr(nBeg,nFind - nBeg);
// Allocate the GUID array
pstructTCOData->m_nGuids = 1;
pstructTCOData->m_lpguidArray =
(GUID *) malloc (sizeof(GUID) * pstructTCOData->m_nGuids);
RtlZeroMemory
(pstructTCOData->m_lpguidArray ,
sizeof(sizeof(GUID) * pstructTCOData->m_nGuids));
// Just one GUID, thank you.
wGUIDFromString(tsGuid.c_str(), &pstructTCOData->m_lpguidArray[0]);
return 0;
}
// We have more than one GUID.
bool bDone = false;
list <t_string> listGuids;
while (!bDone)
{
if (nFind != t_string::npos)
{
tsGuid = tsTemp.substr(nBeg,nFind - nBeg);
listGuids.push_back(tsGuid);
tsGuid.erase();
}
else
{
tsGuid = tsTemp.substr(nBeg,t_string::npos);
listGuids.push_back(tsGuid);
bDone = true;
tsGuid.erase();
}
nBeg = nFind + 1;
nFind = tsTemp.find(',', nBeg);
}
// Allocate the GUID array
pstructTCOData->m_nGuids = listGuids.size();
pstructTCOData->m_lpguidArray =
(GUID *) malloc (sizeof(GUID) * pstructTCOData->m_nGuids);
RtlZeroMemory
(pstructTCOData->m_lpguidArray ,
sizeof(sizeof(GUID) * pstructTCOData->m_nGuids));
list<t_string>::iterator pListGuids;
int i = 0;
for (pListGuids = listGuids.begin(); pListGuids != listGuids.end() ; ++pListGuids)
{
tsGuid = (*pListGuids);
wGUIDFromString(tsGuid.c_str(), &pstructTCOData->m_lpguidArray[i++]);
}
return 0;
}