// 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 #include #include #include #include #include #include #include #include using namespace std; #include #include #include #ifdef NONNT5 typedef unsigned long ULONG_PTR; #endif #include #include #include #include #include #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 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::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 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::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; }