예제 #1
0
static void
WriteEvents(TextWriter &writer, const Result &result)
{
  JSON::ObjectWriter object(writer);

  WriteEvent(object, "takeoff", result.takeoff_time, result.takeoff_location);
  WriteEvent(object, "release", result.release_time, result.release_location);
  WriteEvent(object, "landing", result.landing_time, result.landing_location);
}
예제 #2
0
void GOrgueMidiRecorder::SendEvent(GOrgueMidiEvent& e)
{
	e.SetDevice(m_OutputDevice);
	if (m_OutputDevice)
		m_organfile->SendMidiMessage(e);
	if (IsRecording())
		WriteEvent(e);
}
//
// Write an EBP configuration element to the XML output stream.
//
void CDCConfig::WriteEBP(QTextStream& xmlStream)
{
	xmlStream << "  <ebp" ;
	WriteStringAttr(xmlStream, "name", m_configName) ;
	WriteDecimalAttr(xmlStream, "mux_period", m_multiplexPeriod) ;
	// num_groups is not read. It is written as a debugging aid
	xmlStream << ">\n" ;

	PerfEventList::iterator it     = m_eventContainer.getPerfEventList()->begin();
	PerfEventList::iterator it_end = m_eventContainer.getPerfEventList()->end();
	for (; it != it_end; it++) {
		WriteEvent(xmlStream, &(*it)) ;
	}

	WriteTooltip(xmlStream, m_toolTip) ;
	WriteDescription(xmlStream, m_description) ;
	xmlStream << "  </ebp>\n" ;
}
예제 #4
0
static DWORD WINAPI _xfilter(LPVOID dummy=nullptr)
{
	ProcessException=TRUE;
	DWORD Result = EXCEPTION_EXECUTE_HANDLER;
	BOOL Res=FALSE;
//   if(From == EXCEPT_KERNEL)
//     CriticalInternalError=TRUE;

	if (!Is_STACK_OVERFLOW && Opt.ExceptUsed)
	{
		if (!Opt.strExceptEventSvc.IsEmpty())
		{
			HMODULE m = LoadLibrary(Opt.strExceptEventSvc);

			if (m)
			{
				typedef BOOL (WINAPI *ExceptionProc_t)(EXCEPTION_POINTERS *xp,
				                                       const PLUGINRECORD *Module,
				                                       const PluginStartupInfo *LocalStartupInfo,
				                                       LPDWORD Result);
				ExceptionProc_t p = (ExceptionProc_t)GetProcAddress(m,"ExceptionProc");

				if (p)
				{
					static PluginStartupInfo LocalStartupInfo;
					ClearStruct(LocalStartupInfo);
					static FarStandardFunctions LocalStandardFunctions;
					ClearStruct(LocalStandardFunctions);
					CreatePluginStartupInfo(nullptr, &LocalStartupInfo, &LocalStandardFunctions);
					LocalStartupInfo.ModuleName = Opt.strExceptEventSvc;
					static PLUGINRECORD PlugRec;

					if (Module)
					{
						ClearStruct(PlugRec);
						PlugRec.TypeRec=RTYPE_PLUGIN;
						PlugRec.SizeRec=sizeof(PLUGINRECORD);
						PlugRec.ModuleName=Module->GetModuleName();
						PlugRec.WorkFlags=Module->GetWorkFlags();
						PlugRec.CallFlags=Module->GetFuncFlags();
						PlugRec.FuncFlags=0;
						PlugRec.FuncFlags|=Module->HasGetGlobalInfo()?PICFF_GETGLOBALINFO:0;
						PlugRec.FuncFlags|=Module->HasSetStartupInfo()?PICFF_SETSTARTUPINFO:0;
						PlugRec.FuncFlags|=Module->HasOpenPanel()?PICFF_OPENPANEL:0;
						PlugRec.FuncFlags|=Module->HasAnalyse()?PICFF_ANALYSE:0;
						PlugRec.FuncFlags|=Module->HasClosePanel()?PICFF_CLOSEPANEL:0;
						PlugRec.FuncFlags|=Module->HasGetPluginInfo()?PICFF_GETPLUGININFO:0;
						PlugRec.FuncFlags|=Module->HasGetOpenPanelInfo()?PICFF_GETOPENPANELINFO:0;
						PlugRec.FuncFlags|=Module->HasGetFindData()?PICFF_GETFINDDATA:0;
						PlugRec.FuncFlags|=Module->HasFreeFindData()?PICFF_FREEFINDDATA:0;
						PlugRec.FuncFlags|=Module->HasGetVirtualFindData()?PICFF_GETVIRTUALFINDDATA:0;
						PlugRec.FuncFlags|=Module->HasFreeVirtualFindData()?PICFF_FREEVIRTUALFINDDATA:0;
						PlugRec.FuncFlags|=Module->HasSetDirectory()?PICFF_SETDIRECTORY:0;
						PlugRec.FuncFlags|=Module->HasGetFiles()?PICFF_GETFILES:0;
						PlugRec.FuncFlags|=Module->HasPutFiles()?PICFF_PUTFILES:0;
						PlugRec.FuncFlags|=Module->HasDeleteFiles()?PICFF_DELETEFILES:0;
						PlugRec.FuncFlags|=Module->HasMakeDirectory()?PICFF_MAKEDIRECTORY:0;
						PlugRec.FuncFlags|=Module->HasProcessHostFile()?PICFF_PROCESSHOSTFILE:0;
						PlugRec.FuncFlags|=Module->HasSetFindList()?PICFF_SETFINDLIST:0;
						PlugRec.FuncFlags|=Module->HasConfigure()?PICFF_CONFIGURE:0;
						PlugRec.FuncFlags|=Module->HasExitFAR()?PICFF_EXITFAR:0;
						PlugRec.FuncFlags|=Module->HasProcessPanelInput()?PICFF_PROCESSPANELINPUT:0;
						PlugRec.FuncFlags|=Module->HasProcessPanelEvent()?PICFF_PROCESSPANELEVENT:0;
						PlugRec.FuncFlags|=Module->HasProcessEditorEvent()?PICFF_PROCESSEDITOREVENT:0;
						PlugRec.FuncFlags|=Module->HasCompare()?PICFF_COMPARE:0;
						PlugRec.FuncFlags|=Module->HasProcessEditorInput()?PICFF_PROCESSEDITORINPUT:0;
						PlugRec.FuncFlags|=Module->HasMinFarVersion()?PICFF_MINFARVERSION:0;
						PlugRec.FuncFlags|=Module->HasProcessViewerEvent()?PICFF_PROCESSVIEWEREVENT:0;
						PlugRec.FuncFlags|=Module->HasProcessDialogEvent()?PICFF_PROCESSDIALOGEVENT:0;
						PlugRec.FuncFlags|=Module->HasProcessSynchroEvent()?PICFF_PROCESSSYNCHROEVENT:0;
#if defined(MANTIS_0000466)
						PlugRec.FuncFlags|=Module->HasProcessMacro()?PICFF_PROCESSMACRO:0;
#endif
#if defined(MANTIS_0001687)
						PlugRec.FuncFlags|=Module->HasProcessConsoleInput()?PICFF_PROCESSCONSOLEINPUT:0;
#endif
					}

					Res=p(xp,(Module?&PlugRec:nullptr),&LocalStartupInfo,&Result);
				}

				FreeLibrary(m);
			}
		}
	}

	if (Res)
	{
		if (From == EXCEPT_KERNEL)
		{
			CriticalInternalError=TRUE;
		}

		return Result;
	}

	struct __ECODE
	{
		NTSTATUS Code;     // код исключения
		LNGID IdMsg;    // ID сообщения из LNG-файла
		DWORD RetCode;  // Что вернем?
	} ECode[]=

	{
		{EXCEPTION_ACCESS_VIOLATION, MExcRAccess, EXCEPTION_EXECUTE_HANDLER},
		{EXCEPTION_ARRAY_BOUNDS_EXCEEDED, MExcOutOfBounds, EXCEPTION_EXECUTE_HANDLER},
		{EXCEPTION_INT_DIVIDE_BY_ZERO,MExcDivideByZero, EXCEPTION_EXECUTE_HANDLER},
		{EXCEPTION_STACK_OVERFLOW,MExcStackOverflow, EXCEPTION_EXECUTE_HANDLER},
		{EXCEPTION_BREAKPOINT,MExcBreakPoint, EXCEPTION_EXECUTE_HANDLER},
		{EXCEPTION_FLT_DIVIDE_BY_ZERO,MExcFloatDivideByZero,EXCEPTION_EXECUTE_HANDLER}, // BUGBUG: Floating-point exceptions (VC) are disabled by default. See http://msdn2.microsoft.com/en-us/library/aa289157(vs.71).aspx#floapoint_topic8
		{EXCEPTION_FLT_OVERFLOW,MExcFloatOverflow,EXCEPTION_EXECUTE_HANDLER},           // BUGBUG:  ^^^
		{EXCEPTION_FLT_STACK_CHECK,MExcFloatStackOverflow,EXCEPTION_EXECUTE_HANDLER},   // BUGBUG:  ^^^
		{EXCEPTION_FLT_UNDERFLOW,MExcFloatUnderflow,EXCEPTION_EXECUTE_HANDLER},         // BUGBUG:  ^^^
		{EXCEPTION_ILLEGAL_INSTRUCTION,MExcBadInstruction,EXCEPTION_EXECUTE_HANDLER},
		{EXCEPTION_PRIV_INSTRUCTION,MExcBadInstruction,EXCEPTION_EXECUTE_HANDLER},
		{EXCEPTION_DATATYPE_MISALIGNMENT, MExcDatatypeMisalignment, EXCEPTION_EXECUTE_HANDLER},
		// сюды добавляем.
	};
	// EXCEPTION_CONTINUE_EXECUTION  ??????
	DWORD rc;
	string strBuf1, strBuf2, strBuf3;
	LangString strBuf;
	string strFileName;
	BOOL ShowMessages=FALSE;
	// получим запись исключения
	EXCEPTION_RECORD *xr = xp->ExceptionRecord;

	// выведим дамп перед выдачей сообщений
	WriteEvent(FLOG_ALL,xp,Module,nullptr,0);

	// CONTEXT можно использовать для отображения или записи в лог
	//         содержимого регистров...
	// CONTEXT *xc = xp->ContextRecord;
	rc = Result;// EXCEPTION_EXECUTE_HANDLER;
	/*$ 23.01.2001 skv
	  Неизвестное исключение не стоит игнорировать.
	*/

	if (From == EXCEPT_KERNEL || !Module)
		strFileName=g_strFarModuleName;
	else
		strFileName = Module->GetModuleName();

	LPCWSTR Exception=nullptr;
	// просмотрим "знакомые" FAR`у исключения и обработаем...
	for (size_t I=0; I < ARRAYSIZE(ECode); ++I)
	{
		if (ECode[I].Code == static_cast<NTSTATUS>(xr->ExceptionCode))
		{
			Exception=MSG(ECode[I].IdMsg);
			rc=ECode[I].RetCode;

			if (xr->ExceptionCode == static_cast<DWORD>(EXCEPTION_ACCESS_VIOLATION))
			{
				int Offset = 0;
				// вот только не надо здесь неочевидных оптимизаций вида
				// if ( xr->ExceptionInformation[0] == 8 ) Offset = 2 else Offset = xr->ExceptionInformation[0],
				// а то M$ порадует нас как-нибудь xr->ExceptionInformation[0] == 4 и все будет в полной жопе.

				switch (xr->ExceptionInformation[0])
				{
					case 0:
						Offset = 0;
						break;
					case 1:
						Offset = 1;
						break;
					case 8:
						Offset = 2;
						break;
				}

				strBuf2.Format(L"0x%p", xr->ExceptionInformation[1]+10);
				strBuf = MExcRAccess+Offset;
				strBuf << strBuf2;
				Exception=strBuf;
			}

			break;
		}
	}

	if (!Exception)
	{
		strBuf2.Format(L"%s (0x%X)", MSG(MExcUnknown), xr->ExceptionCode);
		Exception = strBuf2;
	}

	int MsgCode=0;
	if (FrameManager && !FrameManager->ManagerIsDown())
	{
		MsgCode=ExcDialog(strFileName,Exception,xr->ExceptionAddress);
		ShowMessages=TRUE;
	}

	if (ShowMessages && (Is_STACK_OVERFLOW || From == EXCEPT_KERNEL))
	{
		CriticalInternalError=TRUE;
	}

	if(MsgCode==1)
	{
		SetErrorMode(ErrorMode&~SEM_NOGPFAULTERRORBOX);
		rc=EXCEPTION_CONTINUE_SEARCH;
		UseExternalHandler=true;
	}
	else
	{
		rc = EXCEPTION_EXECUTE_HANDLER;
	}
	//return UnhandledExceptionFilter(xp);
	return rc;
}
예제 #5
0
int CDb3Mmap::WorkEventChain(DWORD ofsContact, DBContact *dbc, int firstTime)
{
	int isUnread = 0;

	if (firstTime) {
		dbePrevEvent = NULL;
		ofsPrevEvent = 0;
		ofsDestPrevEvent = 0;
		ofsThisEvent = dbc->ofsFirstEvent;
		eventCount = 0;
		backLookup = 0;
		lastTimestamp = 0;
		ofsFirstUnread = tsFirstUnread = 0;
		if (cb->bEraseHistory) {
			dbc->eventCount = 0;
			dbc->ofsFirstEvent = 0;
			dbc->ofsLastEvent = 0;
			dbc->ofsFirstUnread = 0;
			dbc->tsFirstUnread = 0;
			return ERROR_NO_MORE_ITEMS;
		}
	}

	if (ofsThisEvent == 0) {
		FinishUp(ofsDestPrevEvent, dbc);
		return ERROR_NO_MORE_ITEMS;
	}

	DBEvent dbeOld;
	if (!SignatureValid(ofsThisEvent, DBEVENT_SIGNATURE)) {
		DWORD ofsNew = 0;
		DWORD ofsTmp = dbc->ofsLastEvent;

		if (!backLookup && ofsTmp) {
			backLookup = 1;
			while (SignatureValid(ofsTmp, DBEVENT_SIGNATURE)) {
				if (PeekEvent(ofsTmp, dbc->dwContactID, dbeOld) != ERROR_SUCCESS)
					break;
				ofsNew = ofsTmp;
				ofsTmp = dbeOld.ofsPrev;
			}
		}
		if (ofsNew) {
			cb->pfnAddLogMessage(STATUS_WARNING, TranslateT("Event chain corrupted, trying to recover..."));
			ofsThisEvent = ofsNew;
		}
		else {
			cb->pfnAddLogMessage(STATUS_ERROR, TranslateT("Event chain corrupted, further entries ignored"));
			FinishUp(ofsDestPrevEvent, dbc);
			return ERROR_NO_MORE_ITEMS;
		}
	}

	if (PeekEvent(ofsThisEvent, dbc->dwContactID, dbeOld) != ERROR_SUCCESS) {
		FinishUp(ofsDestPrevEvent, dbc);
		return ERROR_NO_MORE_ITEMS;
	}

	if (firstTime) {
		if (dbeOld.ofsPrev != 0)
			cb->pfnAddLogMessage(STATUS_WARNING, TranslateT("First event not marked as such: correcting"));

		dbeOld.ofsPrev = 0;
		lastTimestamp = dbeOld.timestamp;
	}

	if (dbeOld.flags & 1)
		dbeOld.flags &= ~1;

	if (dbeOld.flags & ~DBEF_ALL) {
		cb->pfnAddLogMessage(STATUS_WARNING, TranslateT("Extra flags found in event: removing"));
		dbeOld.flags &= DBEF_ALL;
	}

	if (!(dbeOld.flags & (DBEF_READ | DBEF_SENT))) {
		if (cb->bMarkRead) dbeOld.flags |= DBEF_READ;
		else if (ofsFirstUnread == 0) {
			if (dbc->ofsFirstUnread != ofsThisEvent || dbc->tsFirstUnread != dbeOld.timestamp)
				cb->pfnAddLogMessage(STATUS_WARNING, TranslateT("First unread event marked wrong: fixing"));
			isUnread = 1;
		}
	}

	if (dbeOld.cbBlob > 1024 * 1024 || dbeOld.cbBlob == 0) {
		cb->pfnAddLogMessage(STATUS_ERROR, TranslateT("Infeasibly large event blob: skipping"));
		ofsThisEvent = dbeOld.ofsNext;
		return ERROR_SUCCESS;
	}

	DBEvent *dbePrev = NULL;
	if (dbePrevEvent && dbeOld.timestamp == lastTimestamp) {
		int len = offsetof(DBEvent, blob) + dbePrevEvent->cbBlob;
		dbePrev = (DBEvent*)malloc(len);
		memcpy(dbePrev, dbePrevEvent, len);
	}

	if (offsetof(DBEvent, blob) + dbeOld.cbBlob > memsize) {
		memsize = offsetof(DBEvent, blob) + dbeOld.cbBlob;
		memblock = (DBEvent*)realloc(memblock, memsize);
	}
	DBEvent *dbeNew = memblock;

	DWORD ret;
	if (m_dbHeader.version < DB_095_1_VERSION) {
		DBEvent_094 oldEvent;
		ret = ReadSegment(ofsThisEvent, &oldEvent, offsetof(DBEvent_094, blob));
		if (ret == ERROR_SUCCESS) {
			dbeNew->signature = oldEvent.signature;
			dbeNew->contactID = dbc->dwContactID;
			memcpy(&dbeNew->ofsPrev, &oldEvent.ofsPrev, offsetof(DBEvent_094, blob) - sizeof(DWORD));
			ret = ReadSegment(ofsThisEvent + offsetof(DBEvent_094, blob), &dbeNew->blob, dbeOld.cbBlob);
		}
	}
	else ret = ReadSegment(ofsThisEvent, dbeNew, offsetof(DBEvent, blob) + dbeOld.cbBlob);

	if (ret != ERROR_SUCCESS) {
		FinishUp(ofsDestPrevEvent, dbc);
		return ERROR_NO_MORE_ITEMS;
	}

	if ((dbeNew->ofsModuleName = ConvertModuleNameOfs(dbeOld.ofsModuleName)) == 0) {
		ofsThisEvent = dbeOld.ofsNext;
		return ERROR_SUCCESS;
	}

	if (!firstTime && dbeOld.ofsPrev != ofsPrevEvent)
		cb->pfnAddLogMessage(STATUS_WARNING, TranslateT("Event not backlinked correctly: fixing"));

	dbeNew->flags = dbeOld.flags;
	dbeNew->ofsPrev = ofsDestPrevEvent;
	dbeNew->ofsNext = 0;
	if (dbeNew->contactID == 0)
		dbeNew->contactID = dbc->dwContactID;

	if (dbeOld.wEventType == EVENTTYPE_MESSAGE && cb->bConvertUtf && !(dbeOld.flags & DBEF_ENCRYPTED))
		ConvertOldEvent(dbeNew);

	if (dbePrev) {
		if (dbePrev->cbBlob == dbeNew->cbBlob &&
			dbePrev->ofsModuleName == dbeNew->ofsModuleName &&
			dbePrev->wEventType == dbeNew->wEventType &&
			(dbePrev->flags & DBEF_SENT) == (dbeNew->flags & DBEF_SENT) && !memcmp(dbePrev->blob, dbeNew->blob, dbeNew->cbBlob))
		{
			cb->pfnAddLogMessage(STATUS_WARNING, TranslateT("Duplicate event was found: skipping"));
			if (dbc->eventCount)
				dbc->eventCount--;
			free(dbePrev);
			// ofsDestPrevEvent is still the same!
			ofsPrevEvent = ofsThisEvent;
			ofsThisEvent = dbeOld.ofsNext;
			return ERROR_SUCCESS;
		}
		free(dbePrev);
	}
	else if (!firstTime && dbeNew->timestamp < lastTimestamp) {
		DWORD found = 0;
		DBEvent dbeTmp = { 0 };
		DWORD ofsTmp = 0;

		if (cb->bCheckOnly) {
			if (!cb->bAggressive) {
				ofsTmp = dbeOld.ofsPrev;
				while (PeekEvent(ofsTmp, dbc->dwContactID, dbeTmp) == ERROR_SUCCESS) {
					if (dbeTmp.ofsPrev == ofsContact) {
						found = 1;
						break;
					}
					if (dbeTmp.timestamp < dbeNew->timestamp) {
						found = 2;
						break;
					}
					ofsTmp = dbeTmp.ofsPrev;
				}
			}
			cb->pfnAddLogMessage(STATUS_WARNING, TranslateT("Event position in chain is not correct"));
		}
		else {
			ofsTmp = ofsDestPrevEvent;
			while (ReadWrittenSegment(ofsTmp, &dbeTmp, sizeof(dbeTmp)) == ERROR_SUCCESS) {
				if (dbeTmp.ofsPrev == ofsContact) {
					found = 1;
					break;
				}
				if (dbeTmp.timestamp < dbeNew->timestamp) {
					found = 2;
					break;
				}
				ofsTmp = dbeTmp.ofsPrev;
			}
			if (found)
				cb->pfnAddLogMessage(STATUS_WARNING, TranslateT("Event position in chain is not correct: fixing"));
			else
				cb->pfnAddLogMessage(STATUS_WARNING, TranslateT("Event position in chain is not correct: unable to fix"));
		}

		// insert before FIRST
		if (found == 1 && !cb->bCheckOnly) {
			dbeNew->ofsPrev = 0;
			dbeNew->ofsNext = dbc->ofsFirstEvent;

			DWORD ofsDestThis = WriteEvent(dbeNew);
			if (!ofsDestThis)
				return ERROR_HANDLE_DISK_FULL;

			if (isUnread && tsFirstUnread >= dbeNew->timestamp) {
				ofsFirstUnread = ofsDestThis;
				tsFirstUnread = dbeNew->timestamp;
			}
			// fix first event
			WriteOfsNextToPrevious(0, dbc, ofsDestThis);
			// fix next event
			WriteSegment(dbeNew->ofsNext + offsetof(DBEvent, ofsPrev), &ofsDestThis, sizeof(DWORD));
		}
		else if (found == 2 && !cb->bCheckOnly) {
			dbeNew->ofsPrev = ofsTmp;
			dbeNew->ofsNext = dbeTmp.ofsNext;

			DWORD ofsDestThis = WriteEvent(dbeNew);
			if (!ofsDestThis)
				return ERROR_HANDLE_DISK_FULL;

			if (isUnread && tsFirstUnread >= dbeNew->timestamp) {
				ofsFirstUnread = ofsDestThis;
				tsFirstUnread = dbeNew->timestamp;
			}
			// fix previous event
			WriteOfsNextToPrevious(dbeNew->ofsPrev, dbc, ofsDestThis);
			// fix next event
			WriteSegment(dbeNew->ofsNext + offsetof(DBEvent, ofsPrev), &ofsDestThis, sizeof(DWORD));
		}

		if (found) {
			eventCount++;
			// ofsDestPrevEvent is still the same!
			ofsPrevEvent = ofsThisEvent;
			ofsThisEvent = dbeOld.ofsNext;
			return ERROR_SUCCESS;
		}
	}

	lastTimestamp = dbeNew->timestamp;
	dbePrevEvent = dbeNew;

	DWORD ofsDestThis = WriteEvent(dbeNew);
	if (!ofsDestThis)
		return ERROR_HANDLE_DISK_FULL;

	if (isUnread) {
		ofsFirstUnread = ofsDestThis;
		tsFirstUnread = dbeOld.timestamp;
	}

	eventCount++;
	WriteOfsNextToPrevious(ofsDestPrevEvent, dbc, ofsDestThis);

	ofsDestPrevEvent = ofsDestThis;
	ofsPrevEvent = ofsThisEvent;
	ofsThisEvent = dbeOld.ofsNext;
	return ERROR_SUCCESS;
}
예제 #6
0
파일: Analysis.cpp 프로젝트: edwig/Marlin
// PRIMARY FUNCTION TO WRITE A LINE TO THE LOGFILE
bool
LogAnalysis::AnalysisLog(const char* p_function,LogType p_type,bool p_doFormat,const char* p_format,...)
{
  // Multi threaded protection
  AutoCritSec lock(&m_lock);
  CString logBuffer;
  bool result = false;

  // Make sure the system is initialized
  Initialisation();

  // Make sure we ARE logging
  if(m_logLevel == HLL_NOLOG)
  {
    return result;
  }

  // Check on the loglevel
  if(m_logLevel == HLL_ERRORS && (p_type == LogType::LOG_INFO || p_type == LogType::LOG_TRACE))
  {
    return result;
  }

  // Timing position in the buffer
  int position = 0;

  // Set the type
  char type = ' ';
  switch(p_type)
  {
    case LogType::LOG_TRACE:type = 'T'; break;
    case LogType::LOG_INFO: type = '-'; break;
    case LogType::LOG_ERROR:type = 'E'; break;
    case LogType::LOG_WARN: type = 'W'; break;
  }

  // Get/print the time
  if(m_doTiming)
  {
    __timeb64 now;
    struct tm today;

    position = 26;  // Prefix string length
    _ftime64_s(&now);
    _localtime64_s(&today,&now.time);
    logBuffer.Format("%4.4d-%2.2d-%2.2d %2.2d:%2.2d:%2.2d.%03d %c "
                    ,today.tm_year + 1900
                    ,today.tm_mon  + 1
                    ,today.tm_mday
                    ,today.tm_hour
                    ,today.tm_min
                    ,today.tm_sec
                    ,now.millitm
                    ,type);
  }

  // Print the calling function
  logBuffer += p_function;
  if(logBuffer.GetLength() < position + ANALYSIS_FUNCTION_SIZE)
  {
    logBuffer.Append("                                            "
                    ,position + ANALYSIS_FUNCTION_SIZE - logBuffer.GetLength());
  }

  // Print the arguments
  if(p_doFormat)
  {
    va_list  varargs;
    va_start(varargs,p_format);
    logBuffer.AppendFormatV(p_format,varargs);
    va_end(varargs);
  }
  else
  {
    logBuffer += p_format;
  }

  // Add end-of line
  logBuffer += "\r\n";

  if(m_file)
  {
    // Locked m_list gets a buffer
    m_list.push_back(logBuffer);
    result = true;
  }
  else if(m_doEvents)
  {
    WriteEvent(m_eventLog,p_type,logBuffer);
    result = true;
  }
  // In case of an error, flush immediately!
  if(m_file && p_type == LogType::LOG_ERROR)
  {
    SetEvent(m_event);
  }
  return result;
}