659 lines
15 KiB
C++
659 lines
15 KiB
C++
// 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;
|
|
|
|
}
|