testtoolsconn/stat/desktop/source/lib/src/statmember.cpp
changeset 0 3da2a79470a7
equal deleted inserted replaced
-1:000000000000 0:3da2a79470a7
       
     1 /*
       
     2 * Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 
       
    21 #include "stdafx.h"
       
    22 #include "statmember.h"
       
    23 #include <stdio.h>
       
    24 
       
    25 ////////////////////////////////////////////////////////////////////////////////////////
       
    26 // Construct and initialise a STAT object and check it hasn't passed it's expiry date.
       
    27 //
       
    28 STATDLLMember::STATDLLMember(const STATCONNECTTYPE iConnectType, const char *pszPlatformType, Reporter *theRep)
       
    29 : pRep(theRep), 
       
    30   iConnectionType(iConnectType), 
       
    31   iErrorCode(GENERAL_FAILURE), 
       
    32   lNextConnection((STATDLLMember*)0), 
       
    33   lPrevConnection((STATDLLMember*)0),
       
    34   pEngine(NULL)
       
    35 {
       
    36 	CString lPrefix="";
       
    37 
       
    38 	pszAddress = NULL;
       
    39 	iErrorCode = GENERAL_FAILURE;
       
    40 	strcpy(szErrorText, "An unknown error has occured");
       
    41 
       
    42 	// set logging identifier
       
    43 	lPrefix.Format(LPCTSTR("[%d:%s] "), iConnectType, pszPlatformType);
       
    44  	const char *lPrefixPtr=(const char *)lPrefix.GetBuffer(lPrefix.GetLength());
       
    45 	strncpy(szPrefix, lPrefixPtr, MAX_ID_PREFIX);
       
    46 
       
    47 	pEngine = new CSTATEngine;
       
    48 	if (pEngine)
       
    49 	{
       
    50 		if ((iErrorCode = pEngine->Initialise(iConnectType, pszPlatformType)) != ITS_OK)
       
    51 		{
       
    52 			ErrorMessage("Could not initialise new connection object");
       
    53 			delete pEngine;
       
    54 			pEngine = NULL;
       
    55 		}
       
    56 		else
       
    57 		{
       
    58 			pszAddress = new char[strlen(pszPlatformType) + 1];
       
    59 			if (pszAddress)
       
    60 				strcpy(pszAddress, pszPlatformType);
       
    61 		}
       
    62 	}
       
    63 	else
       
    64 		ErrorMessage("Could not create new connection object");
       
    65 
       
    66 	// did we make it?
       
    67 	if (iErrorCode == ITS_OK)
       
    68 		Message("Connection initialised successfully");
       
    69 }
       
    70 
       
    71 
       
    72 ////////////////////////////////////////////////////////////////////////////////////////
       
    73 // Release any STAT resources.
       
    74 //
       
    75 STATDLLMember::~STATDLLMember()
       
    76 {
       
    77 	if (pEngine)
       
    78 	{
       
    79 		Message("Releasing member resources");
       
    80 		pEngine->Release();
       
    81 		delete pEngine;
       
    82 	}
       
    83 
       
    84 	if (pszAddress)
       
    85 		delete [] pszAddress;
       
    86 }
       
    87 
       
    88 
       
    89 ////////////////////////////////////////////////////////////////////////////////////////
       
    90 // Do all the preparations in one go
       
    91 //
       
    92 bool
       
    93 STATDLLMember::Prepare(int iMillisecondDelay, LPTSTR pszLogPath, bool bAppend, MessageReporter *const aMessageReporter, LPTSTR pszRefDir, const bool bRemoveOldImages, const int iFactor, bool bState)
       
    94 {
       
    95 	if (pEngine)
       
    96 	{
       
    97 		pEngine->SetMultithreaded(bState);
       
    98 	}
       
    99 
       
   100 	if (!SetCommandDelay(iMillisecondDelay))
       
   101 		return false;
       
   102 
       
   103 	if (pszLogPath && (*pszLogPath) && !SetLogging(pszLogPath, bAppend, aMessageReporter))
       
   104 		return false;
       
   105 
       
   106 	if (pszRefDir && (*pszRefDir) && !SetImageVerification(pszRefDir, bRemoveOldImages, iFactor))
       
   107 		return false;
       
   108 
       
   109 	return true;
       
   110 }
       
   111 
       
   112 
       
   113 ////////////////////////////////////////////////////////////////////////////////////////
       
   114 // Set the delay time between commands
       
   115 //
       
   116 int
       
   117 STATDLLMember::SetCommandDelay(int iMillisecondDelay)
       
   118 {
       
   119 	if (pEngine)
       
   120 	{
       
   121 		pEngine->SetCommandDelay(iMillisecondDelay);
       
   122 		Message("Command delay set");
       
   123 		iErrorCode = ITS_OK;
       
   124 		return true;
       
   125 	}
       
   126 
       
   127 	iErrorCode = GENERAL_FAILURE;
       
   128 	ErrorMessage("Command delay could not be set");
       
   129 	return false;
       
   130 }
       
   131 
       
   132 
       
   133 ////////////////////////////////////////////////////////////////////////////////////////
       
   134 // Set logging of STAT commands.
       
   135 //
       
   136 int
       
   137 STATDLLMember::SetLogging(LPTSTR pszLogPath, bool bAppend, MessageReporter *const aMessageReporter)
       
   138 {
       
   139 	iErrorCode = GENERAL_FAILURE;
       
   140 	CString logpath = pszLogPath;
       
   141 
       
   142 	if (pEngine)
       
   143 	{
       
   144 		if (LOG_FILE_OK == (iErrorCode = pEngine->SetLogging(logpath, szPrefix, bAppend, 
       
   145 				(aMessageReporter != NULL), true, aMessageReporter)))
       
   146 		{
       
   147 			Message("Logging set");
       
   148 			return LOG_FILE_OK;
       
   149 		}
       
   150 	}
       
   151 
       
   152 	ErrorMessage("Logging could not be set");
       
   153 	return GENERAL_FAILURE;
       
   154 }
       
   155 
       
   156 
       
   157 ////////////////////////////////////////////////////////////////////////////////////////
       
   158 // Send a string of STAT commands through to the STAT object.
       
   159 //
       
   160 int
       
   161 STATDLLMember::SendRawCommand(LPCTSTR pszText, ScriptProgressMonitor *const monitor)
       
   162 {
       
   163 	iErrorCode = GENERAL_FAILURE;
       
   164 	CString file = pszText;
       
   165 
       
   166 	if (pEngine)
       
   167 	{
       
   168 		{
       
   169 		CString msg;
       
   170 		msg.Format( "Sending raw command...%s", pszText );
       
   171 		Message(msg.operator LPCTSTR());
       
   172 		}
       
   173 		if ((iErrorCode = pEngine->OpenScriptFile(file, false)) == ITS_OK)
       
   174 			if ((iErrorCode = pEngine->RunScript(monitor)) == END_SCRIPT)
       
   175 				return ITS_OK;
       
   176 	}
       
   177 
       
   178 	ErrorMessage("Command text could not be processed successfully");
       
   179 	return iErrorCode;
       
   180 }
       
   181 
       
   182 
       
   183 ////////////////////////////////////////////////////////////////////////////////////////
       
   184 // Open a script file or text block in the engine.
       
   185 //
       
   186 int
       
   187 STATDLLMember::OpenScriptFile(LPCTSTR pszText, bool bIsFile)
       
   188 {
       
   189 	iErrorCode = GENERAL_FAILURE;
       
   190 	CString file = pszText;
       
   191 
       
   192 	if (pEngine)
       
   193 	{
       
   194 		{
       
   195 		CString msg;
       
   196 		msg.Format( "Opening script file...%s", pszText );
       
   197 		Message(msg.operator LPCTSTR());
       
   198 		}
       
   199 		if ((iErrorCode = pEngine->OpenScriptFile(pszText, bIsFile)) == ITS_OK)
       
   200 				return iErrorCode;
       
   201 	}
       
   202 
       
   203 	ErrorMessage("Open script file could not be processed successfully");
       
   204 	return iErrorCode;
       
   205 }
       
   206 
       
   207 
       
   208 ////////////////////////////////////////////////////////////////////////////////////////
       
   209 // Runs the script in the engine.
       
   210 //
       
   211 int
       
   212 STATDLLMember::RunScript(ScriptProgressMonitor *const monitor)
       
   213 {
       
   214 	iErrorCode = GENERAL_FAILURE;
       
   215 
       
   216 	if (pEngine)
       
   217 	{
       
   218 		{
       
   219 		CString msg;
       
   220 		msg.Format( "Running script..." );
       
   221 		Message(msg.operator LPCTSTR());
       
   222 		}
       
   223 
       
   224 		iErrorCode = pEngine->RunScript(monitor);
       
   225 	}
       
   226 
       
   227 	if( iErrorCode != END_SCRIPT )
       
   228 	{
       
   229 		ErrorMessage("Run script could not be processed successfully");
       
   230 	}
       
   231 
       
   232 	if(monitor)
       
   233 	{
       
   234 		monitor->OnCompleteScript( iErrorCode );
       
   235 	}
       
   236 
       
   237 	return iErrorCode;
       
   238 }
       
   239 
       
   240 
       
   241 ////////////////////////////////////////////////////////////////////////////////////////
       
   242 // Send a command file containing a string of STAT commands through to the STAT object.
       
   243 // Checks that it is actually an accessible file before accepting it.
       
   244 //
       
   245 int
       
   246 STATDLLMember::SendCommandFile(LPCTSTR pszFile, ScriptProgressMonitor *const monitor)
       
   247 {
       
   248 	iErrorCode = GENERAL_FAILURE;
       
   249 	CString file = pszFile;
       
   250 
       
   251 	if (pEngine)
       
   252 	{
       
   253 		Message("Sending command file...");
       
   254 		if ((iErrorCode = pEngine->OpenScriptFile(file, true)) == ITS_OK)
       
   255 			if ((iErrorCode = pEngine->RunScript(monitor)) == END_SCRIPT)
       
   256 				return true;
       
   257 	}
       
   258 
       
   259 	ErrorMessage("Script file could not be processed successfully");
       
   260 	return false;
       
   261 }
       
   262 
       
   263 
       
   264 ////////////////////////////////////////////////////////////////////////////////////////
       
   265 // Stops processing the current command.
       
   266 //
       
   267 int
       
   268 STATDLLMember::StopProcessing(void)
       
   269 {
       
   270 	iErrorCode = GENERAL_FAILURE;
       
   271 
       
   272 	if (pEngine)
       
   273 	{
       
   274 		Message("Stopping processing...");
       
   275 		pEngine->eStopProcessing = STAT_PAUSE;
       
   276 		return true;
       
   277 	}
       
   278 
       
   279 	ErrorMessage("Stopping the process could not be processed successfully");
       
   280 	return false;
       
   281 }
       
   282 
       
   283 
       
   284 ////////////////////////////////////////////////////////////////////////////////////////
       
   285 // Returns the number of commands in the current script.
       
   286 //
       
   287 int
       
   288 STATDLLMember::GetCommandCount(LPCTSTR pszFile, int* commandCount)
       
   289 {
       
   290 	iErrorCode = GENERAL_FAILURE;
       
   291 
       
   292 	if (pEngine)
       
   293 	{
       
   294 		Message("Sending command file...");
       
   295 		if ((iErrorCode = pEngine->GetCommandCount(pszFile, commandCount)) == ITS_OK)
       
   296 				return ITS_OK;
       
   297 	}
       
   298 
       
   299 	ErrorMessage("Getting the command count could not be processed successfully");
       
   300 	return GENERAL_FAILURE;
       
   301 }
       
   302 
       
   303 
       
   304 ////////////////////////////////////////////////////////////////////////////////////////
       
   305 // Returns the number of the current command.
       
   306 //
       
   307 int
       
   308 STATDLLMember::GetCurrentCommandNumber( int* commandNumber )
       
   309 {
       
   310 	iErrorCode = GENERAL_FAILURE;
       
   311 
       
   312 	if (pEngine)
       
   313 	{
       
   314 		Message("Getting current command number...");
       
   315 		*commandNumber =	pEngine->iCurrentCommand;
       
   316 		iErrorCode = ITS_OK;
       
   317 			return iErrorCode;
       
   318 	}
       
   319 
       
   320 	ErrorMessage("Getting the current command number could not be processed successfully");
       
   321 	return iErrorCode;
       
   322 }
       
   323 
       
   324 ////////////////////////////////////////////////////////////////////////////////////////
       
   325 // Returns the text recevied by the commands.
       
   326 //
       
   327 const char *
       
   328 STATDLLMember::GetReceivedData(void)
       
   329 {
       
   330 	if (pEngine)
       
   331 	{
       
   332 		Message("Getting data received by commands...");
       
   333 		return ( pEngine->GetReceivedData() );
       
   334 	}
       
   335 
       
   336 	return ( "Getting the error text could not be processed successfully" );
       
   337 }
       
   338 
       
   339 ////////////////////////////////////////////////////////////////////////////////////////
       
   340 // Returns the text associated with an error value.
       
   341 //
       
   342 const char *
       
   343 STATDLLMember::GetErrorText( int errorCode )
       
   344 {
       
   345 	if (pEngine)
       
   346 	{
       
   347 		Message("Getting current command number...");
       
   348 		return ( pEngine->GetErrorText(errorCode) );
       
   349 	}
       
   350 
       
   351 	return ( "Getting the error text could not be processed successfully" );
       
   352 }
       
   353 
       
   354 ////////////////////////////////////////////////////////////////////////////////////////
       
   355 // Sets image verification with supplied reference directory, and will remove existing
       
   356 // images if specified.  Also sets the 'fudge' factor for the verification itself.
       
   357 //
       
   358 int
       
   359 STATDLLMember::SetImageVerification(LPTSTR pszRefDir, const bool bRemoveOldImages, const int iFactor)
       
   360 {
       
   361 	iErrorCode = GENERAL_FAILURE;
       
   362 	Message("Setting image verification Dir [%s] Remove Old %d Factor %d...", ToAnsi(pszRefDir), bRemoveOldImages, iFactor);
       
   363 
       
   364 	if (pEngine && pEngine->pImageVerify)
       
   365 	{
       
   366 		//set default logging path
       
   367 		CString defaultDirectory=STAT_LOGFILEPATH_VALUE;
       
   368 		//read from inifile if entry exists
       
   369 		if(statIniFile.SectionExists(ST_TEST_KEY) )
       
   370 		{
       
   371 			CString setting;
       
   372 			setting.Empty();
       
   373 			setting=statIniFile.GetKeyValue(ST_LOGFILEPATH,ST_TEST_KEY);
       
   374 			if(!setting.IsEmpty())
       
   375 				defaultDirectory = setting;
       
   376 		}
       
   377 		iErrorCode = pEngine->pImageVerify->Initialise(defaultDirectory);
       
   378 		if(iErrorCode == ERROR_REGISTRY)
       
   379 		{
       
   380 			ErrorMessage("Config file failure");
       
   381 		}
       
   382 		else if(iErrorCode == REFDIR_FOUND)
       
   383 		{
       
   384 			if (bRemoveOldImages)
       
   385 			{
       
   386 				Message("Removing old images...");
       
   387 				iErrorCode = pEngine->pImageVerify->DeleteReferenceImages();
       
   388 			}
       
   389 			else
       
   390 				Message("Old reference images exist");
       
   391 		}
       
   392 
       
   393 		// if preparations went OK...
       
   394 		if(iErrorCode == ITS_OK)
       
   395 		{
       
   396 			Message("Copying new images from [%s]...", ToAnsi(pszRefDir));
       
   397 			iErrorCode = pEngine->pImageVerify->CopyReferenceImages(pszRefDir);
       
   398 			if(iErrorCode != ITS_OK)
       
   399 				ErrorMessage("Images could not be copied");
       
   400 		}
       
   401 
       
   402 		// success?
       
   403 		if(iErrorCode == ITS_OK || iErrorCode == REFDIR_FOUND)
       
   404 		{
       
   405 			if (pEngine->pImageVerify->EnableVerification(iFactor) > 0)
       
   406 			{
       
   407 				Message("Image verification set");
       
   408 				return true;
       
   409 			}
       
   410 			else
       
   411 			{
       
   412 				iErrorCode = GENERAL_FAILURE;
       
   413 				ErrorMessage("No images available for verification");
       
   414 			}
       
   415 		}
       
   416 
       
   417 		// disable on error
       
   418 		pEngine->pImageVerify->DisableVerification();
       
   419 	}
       
   420 
       
   421 	ErrorMessage("Image verification could not be set");
       
   422 	return false;
       
   423 }
       
   424 
       
   425 
       
   426 ////////////////////////////////////////////////////////////////////////////////////////
       
   427 // Gets a 'snapshot' of the screen of the remote target and returns the information
       
   428 // and data in the supplied parameters. Only stores the most recent snapshot.
       
   429 //
       
   430 STATDLLMember::GetSnapshot(TBitmapFileHeader **ppFile, TBitmapInfoHeader **ppBitmap, char **ppData, unsigned long *pSize)
       
   431 {
       
   432 	// basic screenshot command
       
   433 	CString file = "<B><S><E>";
       
   434 
       
   435 	iErrorCode = GENERAL_FAILURE;
       
   436 	*ppFile = NULL;
       
   437 	*ppBitmap = NULL;
       
   438 	*ppData = NULL;
       
   439 	*pSize = NULL;
       
   440 
       
   441 	if (pEngine)
       
   442 	{
       
   443 		Message("Sending snapshot command...");
       
   444 		if ((iErrorCode = pEngine->OpenScriptFile(file, false)) == ITS_OK)
       
   445 		{
       
   446 			pEngine->pConverter->bWriteToFile = false;
       
   447 			if ((iErrorCode = pEngine->RunScript(NULL)) == END_SCRIPT)
       
   448 			{
       
   449 				Message("Accessing bitmap data...");
       
   450 				pEngine->pConverter->GetScreenshotData(ppFile, ppBitmap, ppData, pSize);
       
   451 			}
       
   452 			pEngine->pConverter->bWriteToFile = true;
       
   453 		}
       
   454 	}
       
   455 
       
   456 	// success
       
   457 	if (ppFile && (*ppFile) && ppBitmap && (*ppBitmap) && ppData && (*ppData) && pSize && (*pSize))
       
   458 	{
       
   459 		Message("Bitmap data retrieved successfully");
       
   460 		return true;
       
   461 	}
       
   462 
       
   463 	ErrorMessage("Snapshot could not be taken");
       
   464 	return false;
       
   465 }
       
   466 
       
   467 
       
   468 //////////////////////////////////////////////////////////////////////////////////////////
       
   469 // Converts a char * to it's Unicode equivalent
       
   470 //
       
   471 LPTSTR
       
   472 STATDLLMember::ToUnicode(const char *string)
       
   473 {
       
   474 #ifdef UNICODE
       
   475 	static TCHAR szBuffer[MAX_UNICODE_LEN + 1] = {0};
       
   476 	szBuffer[0] = (TCHAR)0;
       
   477 
       
   478     // Convert to UNICODE.
       
   479     if (!MultiByteToWideChar(CP_ACP,					// conversion type
       
   480 							 0,							// flags
       
   481 							 string,					// source
       
   482 							 -1,						// length
       
   483 							 szBuffer,					// dest
       
   484 							 MAX_UNICODE_LEN))			// length
       
   485     {
       
   486         return _T("Could not convert");
       
   487     }
       
   488 
       
   489     return szBuffer;
       
   490 #else
       
   491 	return (LPTSTR)string;
       
   492 #endif
       
   493 }
       
   494 
       
   495 
       
   496 //////////////////////////////////////////////////////////////////////////////////////////
       
   497 // Converts a Unicode to it's char * equivalent
       
   498 //
       
   499 const char *
       
   500 STATDLLMember::ToAnsi(LPCTSTR string)
       
   501 {
       
   502 #ifdef UNICODE
       
   503 	static char szBuffer[MAX_UNICODE_LEN + 1] = {0};
       
   504 	szBuffer[0] = (char)0;
       
   505 
       
   506     // Convert to ANSI.
       
   507     if (!WideCharToMultiByte(CP_ACP,					// conversion type
       
   508 							 0,							// flags
       
   509 							 string,					// source
       
   510 							 -1,						// length
       
   511 							 szBuffer,					// dest
       
   512 							 MAX_UNICODE_LEN,			// length
       
   513 							 NULL,
       
   514 							 NULL ))
       
   515     {
       
   516         return "Could not convert";
       
   517     }
       
   518 
       
   519     return szBuffer;
       
   520 #else
       
   521 	return (char *)string;
       
   522 #endif
       
   523 }
       
   524 
       
   525 
       
   526 //////////////////////////////////////////////////////////////////////////////////////
       
   527 // Split a connection registry entry into its respective parts
       
   528 void
       
   529 STATDLLMember::ParseConnection(char *pConnection, STATCONNECTTYPE *pType, char **ppAddress)
       
   530 {
       
   531 	(*pType) = SymbianInvalid;
       
   532 	(*ppAddress) = NULL;
       
   533 
       
   534 	static char szConnection[256];
       
   535 	memset(szConnection, 0, sizeof(szConnection));
       
   536 	strcpy(szConnection, pConnection);
       
   537 
       
   538 	char *p = strchr(szConnection, ':');
       
   539 	if (p)
       
   540 	{
       
   541 		(*p) = (char)0;
       
   542 		(*ppAddress) = p + 1;
       
   543 
       
   544 		if (stricmp(szConnection, "SymbianSocket") == 0)
       
   545 		{
       
   546 			(*pType) = SymbianSocket;
       
   547 		}
       
   548 		else if (stricmp(szConnection, "SymbianSerial") == 0)
       
   549 		{
       
   550 			(*pType) = SymbianSerial;
       
   551 		}
       
   552 		else if (stricmp(szConnection, "SymbianInfrared") == 0)
       
   553 		{
       
   554 			(*pType) = SymbianInfrared;
       
   555 		}
       
   556 		else if (stricmp(szConnection, "SymbianBluetooth") == 0)
       
   557 		{
       
   558 			(*pType) = SymbianBluetooth;
       
   559 		}
       
   560 
       
   561 		(*p) = ':';
       
   562 	}
       
   563 }
       
   564 
       
   565 
       
   566 //////////////////////////////////////////////////////////////////////////////////////////
       
   567 // PRIVATE METHODS
       
   568 //////////////////////////////////////////////////////////////////////////////////////////
       
   569 
       
   570 //////////////////////////////////////////////////////////////////////////////////////////
       
   571 // Writes a message to file
       
   572 //
       
   573 void
       
   574 STATDLLMember::Message(const char * message, ...)
       
   575 {
       
   576 	if (pRep)
       
   577 	{
       
   578 		char szText[MAX_ERROR_MSG_LEN * 2] = {0};
       
   579 		va_list pMsg;
       
   580 
       
   581 		strcpy(szText, szPrefix);
       
   582 
       
   583 		va_start (pMsg, message);
       
   584 		vsprintf (szText + strlen(szText), message, pMsg);
       
   585 		va_end (pMsg);
       
   586 
       
   587 		pRep->info(szText);
       
   588 	}
       
   589 }
       
   590 
       
   591 
       
   592 //////////////////////////////////////////////////////////////////////////////////////////
       
   593 // Writes an error message to file
       
   594 //
       
   595 void
       
   596 STATDLLMember::ErrorMessage(const char * message, ...)
       
   597 {
       
   598 	if (pRep)
       
   599 	{
       
   600 		va_list pMsg;
       
   601 		char szErrorMsg[MAX_ERROR_MSG_LEN + 1] = {0};
       
   602 
       
   603 		// get the API error
       
   604 		va_start (pMsg, message);
       
   605 		vsprintf (szErrorMsg, message, pMsg);
       
   606 		va_end (pMsg);
       
   607 
       
   608 		// save the complete error
       
   609 		if (pEngine)
       
   610 		{
       
   611 			if (pEngine->GetDeviceReturnCode() != 0)
       
   612 			{
       
   613 				sprintf(szErrorText, "%s (%d : %s - Device return code %d)", 
       
   614 										szErrorMsg, 
       
   615 										iErrorCode, 
       
   616 										ToAnsi(pEngine->GetErrorText(iErrorCode)),
       
   617 										pEngine->GetDeviceReturnCode());
       
   618 			}
       
   619 			else
       
   620 			{
       
   621 				sprintf(szErrorText, "%s (%d : %s)", 
       
   622 										szErrorMsg, 
       
   623 										iErrorCode, 
       
   624 										ToAnsi(pEngine->GetErrorText(iErrorCode)));
       
   625 			}
       
   626 		}
       
   627 		else
       
   628 			strcpy(szErrorText, "(STAT Engine not initialised)");
       
   629 
       
   630 		// construct a full log message
       
   631 		char szLogError[MAX_ERROR_MSG_LEN * 2] = {0};
       
   632 		sprintf(szLogError, "%sERROR: %s", szPrefix, szErrorText);
       
   633 		pRep->error(szLogError);
       
   634 	}
       
   635 }