- Naming style migrated to camel-case - P7lib logger sources added - Vcpkg manifest, CMake presets and build moved to root - SDL2, Vulkan and RmlUi dependencies added - Logger LOG macro added - Logger configuration - SDL2 window configuration - Vulkan configuration - RmlUi configuration - SDL event loop
700 lines
22 KiB
C++
700 lines
22 KiB
C++
////////////////////////////////////////////////////////////////////////////////
|
|
// /
|
|
// 2012-2020 (c) Baical /
|
|
// /
|
|
// This library is free software; you can redistribute it and/or /
|
|
// modify it under the terms of the GNU Lesser General Public /
|
|
// License as published by the Free Software Foundation; either /
|
|
// version 3.0 of the License, or (at your option) any later version. /
|
|
// /
|
|
// This library is distributed in the hope that it will be useful, /
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU /
|
|
// Lesser General Public License for more details. /
|
|
// /
|
|
// You should have received a copy of the GNU Lesser General Public /
|
|
// License along with this library. /
|
|
// /
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
#pragma once
|
|
|
|
#define FJOURNAL_FILE_BUFFER_LENGTH (0x20000)
|
|
#define FJOURNAL_FILE_BUFFER_MINIMUM_REMAINDER (0x2000)
|
|
#define FJOURNAL_THREAD_WAKEUP_INTERVAL (2500)
|
|
#define FJOURNAL_FILE_EXTENSION L"log"
|
|
#define FJOURNAL_DESCRIPTION_MAX_LENGTH (64)
|
|
#define FJOURNAL_MAX_FILES (7)
|
|
|
|
|
|
void __cdecl FJournal_Routine(void *i_pContext);
|
|
|
|
// 1. Dump to the file
|
|
// 2. must have parameters and possibility to export them
|
|
// 3. should have own thread to notify about writing, every 1-5 seconds.
|
|
|
|
class CJournal
|
|
: virtual public IJournal
|
|
{
|
|
private:
|
|
//put volatile variables at the top, to obtain 32 bit alignment.
|
|
//Project has 8 bytes alignment by default
|
|
volatile LONG m_lReference_Counter;
|
|
|
|
HANDLE m_hLog_File;
|
|
wchar_t *m_pJournal_Buffer;
|
|
wchar_t *m_pWrite_Buffer;
|
|
DWORD m_dwBuffer_Used;
|
|
|
|
HANDLE m_hThread;
|
|
HANDLE m_hEvent_Exit;
|
|
HANDLE m_hEvent_Write;
|
|
|
|
CRITICAL_SECTION m_tCS;
|
|
|
|
SYSTEMTIME m_tTime;
|
|
wchar_t m_pTypes_Description[IJournal::eLEVEL_COUNT][FJOURNAL_DESCRIPTION_MAX_LENGTH];
|
|
CWString m_cFile_Name;
|
|
UINT64 m_pCount[IJournal::eLEVEL_COUNT];
|
|
|
|
IJournal::eLevel m_eVerbosity;
|
|
|
|
IJournal::eTime m_eTime; //ignored for a while
|
|
tBOOL m_bFunction;
|
|
tBOOL m_bType;
|
|
|
|
BOOL m_bInitialized;
|
|
BOOL m_bError;
|
|
|
|
DWORD m_dwMax_Files;
|
|
public:
|
|
////////////////////////////////////////////////////////////////////////////
|
|
CJournal()
|
|
: m_lReference_Counter(1)
|
|
, m_hLog_File(INVALID_HANDLE_VALUE)
|
|
, m_pJournal_Buffer(NULL)
|
|
, m_pWrite_Buffer(NULL)
|
|
, m_dwBuffer_Used(0)
|
|
, m_hThread(NULL)
|
|
, m_hEvent_Exit(NULL)
|
|
, m_hEvent_Write(NULL)
|
|
, m_eVerbosity(IJournal::eLEVEL_TRACE)
|
|
, m_eTime(IJournal::eTIME_YYYYMMDDHHMMSSMS)
|
|
, m_bFunction(TRUE)
|
|
, m_bType(TRUE)
|
|
, m_bInitialized(FALSE)
|
|
, m_bError(FALSE)
|
|
, m_dwMax_Files(FJOURNAL_MAX_FILES)
|
|
{
|
|
memset(&m_tCS, 0, sizeof(CRITICAL_SECTION));
|
|
memset(&m_pCount, 0, sizeof(m_pCount));
|
|
|
|
InitializeCriticalSection(&m_tCS);
|
|
|
|
wcscpy_s(m_pTypes_Description[IJournal::eLEVEL_TRACE], FJOURNAL_DESCRIPTION_MAX_LENGTH, L"INFO : ");
|
|
wcscpy_s(m_pTypes_Description[IJournal::eLEVEL_DEBUG], FJOURNAL_DESCRIPTION_MAX_LENGTH, L"DEBUG: ");
|
|
wcscpy_s(m_pTypes_Description[IJournal::eLEVEL_INFO], FJOURNAL_DESCRIPTION_MAX_LENGTH, L"INFO : ");
|
|
wcscpy_s(m_pTypes_Description[IJournal::eLEVEL_WARNING], FJOURNAL_DESCRIPTION_MAX_LENGTH, L"WARN.: ");
|
|
wcscpy_s(m_pTypes_Description[IJournal::eLEVEL_ERROR], FJOURNAL_DESCRIPTION_MAX_LENGTH, L"ERROR: ");
|
|
wcscpy_s(m_pTypes_Description[IJournal::eLEVEL_CRITICAL], FJOURNAL_DESCRIPTION_MAX_LENGTH, L"CRIT.: ");
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
void Set_Files_Max_Count(DWORD i_dwVal)
|
|
{
|
|
m_dwMax_Files = i_dwVal;
|
|
}//Set_Files_Max_Count
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
tBOOL Initialize(const tXCHAR *i_pName)
|
|
{
|
|
if (TRUE == m_bInitialized)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
if ( (NULL == i_pName)
|
|
|| (TRUE == m_bError)
|
|
)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
CWString l_sDirectory;
|
|
|
|
if (FALSE == m_bError)
|
|
{
|
|
m_pJournal_Buffer = new wchar_t[FJOURNAL_FILE_BUFFER_LENGTH];
|
|
m_pWrite_Buffer = new wchar_t[FJOURNAL_FILE_BUFFER_LENGTH];
|
|
if ( (NULL == m_pJournal_Buffer) || (NULL == m_pWrite_Buffer) )
|
|
{
|
|
m_bError = TRUE;
|
|
}
|
|
}
|
|
|
|
if (FALSE == m_bError)
|
|
{
|
|
CFSYS::Get_Process_Directory(&l_sDirectory);
|
|
l_sDirectory.Append(2, L"\\", i_pName);
|
|
|
|
if (FALSE == CFSYS::Directory_Exists(l_sDirectory.Get()))
|
|
{
|
|
m_bError = (! CFSYS::Directory_Create(l_sDirectory.Get()));
|
|
}
|
|
}
|
|
|
|
|
|
if (FALSE == m_bError)
|
|
{
|
|
Remove_Old_Journals(l_sDirectory.Get(),
|
|
m_dwMax_Files,
|
|
FJOURNAL_FILE_EXTENSION
|
|
);
|
|
|
|
DWORD l_dwIterator = 0;
|
|
SYSTEMTIME l_tTime;
|
|
GetLocalTime(&l_tTime);
|
|
do
|
|
{
|
|
swprintf_s(m_pJournal_Buffer,
|
|
FJOURNAL_FILE_BUFFER_LENGTH,
|
|
L"%s\\%04d_%02d_%02d-%02d_%02d_%02d-%d.%s",
|
|
l_sDirectory.Get(),
|
|
(int)l_tTime.wYear,
|
|
(int)l_tTime.wMonth,
|
|
(int)l_tTime.wDay,
|
|
(int)l_tTime.wHour,
|
|
(int)l_tTime.wMinute,
|
|
(int)l_tTime.wSecond,
|
|
(int)l_dwIterator++,
|
|
FJOURNAL_FILE_EXTENSION
|
|
);
|
|
} while (CFSYS::File_Exists(m_pJournal_Buffer));
|
|
|
|
m_cFile_Name.Set((wchar_t*)m_pJournal_Buffer);
|
|
|
|
m_hLog_File = CreateFileW(m_pJournal_Buffer,
|
|
GENERIC_WRITE | GENERIC_READ,
|
|
FILE_SHARE_READ,
|
|
NULL,
|
|
OPEN_ALWAYS,
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
NULL
|
|
);
|
|
|
|
if ( (NULL == m_hLog_File)
|
|
|| (INVALID_HANDLE_VALUE == m_hLog_File)
|
|
)
|
|
{
|
|
m_hLog_File = INVALID_HANDLE_VALUE;
|
|
m_bError = TRUE;
|
|
}
|
|
}
|
|
|
|
if (FALSE == m_bError)
|
|
{
|
|
m_hEvent_Exit = CreateEventW(NULL, FALSE, FALSE, NULL);
|
|
m_hEvent_Write = CreateEventW(NULL, TRUE, FALSE, NULL);
|
|
if ( (NULL == m_hEvent_Exit) || (NULL == m_hEvent_Write) )
|
|
{
|
|
m_bError = TRUE;
|
|
}
|
|
}
|
|
|
|
if (FALSE == m_bError)
|
|
{
|
|
m_pJournal_Buffer[0] = 0xFEFF;
|
|
m_dwBuffer_Used = 1;
|
|
|
|
m_hThread = (void*)_beginthread(&Routine_Entry_Point, 0, this);
|
|
if (NULL == m_hThread)
|
|
{
|
|
m_bError = TRUE;
|
|
}
|
|
}
|
|
|
|
if (FALSE == m_bError)
|
|
{
|
|
m_bInitialized = TRUE;
|
|
}
|
|
|
|
return (! m_bError);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
void Set_Verbosity(IJournal::eLevel i_eVerbosity)
|
|
{
|
|
EnterCriticalSection(&m_tCS);
|
|
m_eVerbosity = i_eVerbosity;
|
|
LeaveCriticalSection(&m_tCS);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
void Set_Format(IJournal::eTime i_eTime, tBOOL i_bFunction, tBOOL i_bType)
|
|
{
|
|
EnterCriticalSection(&m_tCS);
|
|
m_eTime = i_eTime;
|
|
m_bFunction = i_bFunction;
|
|
m_bType = i_bType;
|
|
LeaveCriticalSection(&m_tCS);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
IJournal::eLevel Get_Verbosity()
|
|
{
|
|
IJournal::eLevel l_eResult;
|
|
EnterCriticalSection(&m_tCS);
|
|
l_eResult = m_eVerbosity;
|
|
LeaveCriticalSection(&m_tCS);
|
|
|
|
return l_eResult;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
tBOOL Log(IJournal::eLevel i_eType,
|
|
IJournal::hModule i_hModule,
|
|
const char *i_pFile,
|
|
const char *i_pFunction,
|
|
tUINT32 i_dwLine,
|
|
const tXCHAR *i_pFormat,
|
|
...
|
|
)
|
|
{
|
|
tBOOL l_bResult = TRUE;
|
|
int l_iCount = 0;
|
|
wchar_t *l_pBuffer = NULL;
|
|
|
|
if ( (FALSE == m_bInitialized)
|
|
|| (NULL == i_pFormat)
|
|
|| (i_eType >= IJournal::eLEVEL_COUNT)
|
|
)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
EnterCriticalSection(&m_tCS);
|
|
|
|
m_pCount[i_eType]++;
|
|
|
|
if (i_eType < m_eVerbosity)
|
|
{
|
|
l_bResult = FALSE;
|
|
goto l_lExit;
|
|
}
|
|
|
|
if ( (m_dwBuffer_Used >= FJOURNAL_FILE_BUFFER_LENGTH)
|
|
|| (FJOURNAL_FILE_BUFFER_MINIMUM_REMAINDER >= (FJOURNAL_FILE_BUFFER_LENGTH - m_dwBuffer_Used) )
|
|
)
|
|
{
|
|
SetEvent(m_hEvent_Write);
|
|
|
|
while (WAIT_OBJECT_0 == WaitForSingleObject(m_hEvent_Write, 0))
|
|
{
|
|
Sleep(5);
|
|
}
|
|
}
|
|
|
|
|
|
if ( (l_bResult)
|
|
&& (i_pFunction)
|
|
&& (m_bFunction)
|
|
)
|
|
{
|
|
l_pBuffer = m_pJournal_Buffer + m_dwBuffer_Used;
|
|
|
|
while (*i_pFunction)
|
|
{
|
|
(*l_pBuffer++) = (*i_pFunction++);
|
|
m_dwBuffer_Used ++;
|
|
}
|
|
|
|
l_iCount = swprintf_s(m_pJournal_Buffer + m_dwBuffer_Used,
|
|
FJOURNAL_FILE_BUFFER_LENGTH - m_dwBuffer_Used,
|
|
L"() Ln %04d : ", (int)i_dwLine
|
|
);
|
|
if (0 > l_iCount)
|
|
{
|
|
l_bResult = FALSE;
|
|
}
|
|
else
|
|
{
|
|
m_dwBuffer_Used += l_iCount;
|
|
}
|
|
|
|
l_pBuffer = m_pJournal_Buffer + m_dwBuffer_Used;
|
|
(*l_pBuffer++) = 13;
|
|
(*l_pBuffer++) = 10;
|
|
m_dwBuffer_Used += 2;
|
|
}
|
|
|
|
if (l_bResult)
|
|
{
|
|
GetLocalTime(&m_tTime);
|
|
l_iCount = swprintf_s(m_pJournal_Buffer + m_dwBuffer_Used,
|
|
FJOURNAL_FILE_BUFFER_LENGTH - m_dwBuffer_Used,
|
|
L"[%04d.%02d.%02d %02d:%02d:%02d.%03d] %s ",
|
|
(int)m_tTime.wYear, (int)m_tTime.wMonth, (int)m_tTime.wDay,
|
|
(int)m_tTime.wHour, (int)m_tTime.wMinute, (int)m_tTime.wSecond, (int)m_tTime.wMilliseconds,
|
|
m_bType ? m_pTypes_Description[i_eType] : L""
|
|
);
|
|
if (0 > l_iCount)
|
|
{
|
|
l_bResult = FALSE;
|
|
}
|
|
else
|
|
{
|
|
m_dwBuffer_Used += l_iCount;
|
|
}
|
|
}
|
|
|
|
if (l_bResult)
|
|
{
|
|
va_list l_pArgList;
|
|
va_start(l_pArgList, i_pFormat);
|
|
size_t l_stRemaining = 0;
|
|
|
|
if (S_OK == StringCbVPrintfExW(m_pJournal_Buffer + m_dwBuffer_Used,
|
|
(FJOURNAL_FILE_BUFFER_LENGTH - m_dwBuffer_Used) * sizeof(wchar_t),
|
|
NULL,
|
|
&l_stRemaining,
|
|
STRSAFE_IGNORE_NULLS,
|
|
i_pFormat,
|
|
l_pArgList
|
|
)
|
|
)
|
|
{
|
|
m_dwBuffer_Used = FJOURNAL_FILE_BUFFER_LENGTH - (DWORD)(l_stRemaining / sizeof(wchar_t));
|
|
}
|
|
else
|
|
{
|
|
l_bResult = FALSE;
|
|
}
|
|
|
|
va_end(l_pArgList);
|
|
}
|
|
|
|
if (l_bResult)
|
|
{
|
|
l_pBuffer = m_pJournal_Buffer + m_dwBuffer_Used;
|
|
(*l_pBuffer++) = 13;
|
|
(*l_pBuffer++) = 10;
|
|
m_dwBuffer_Used += 2;
|
|
}
|
|
|
|
l_lExit:
|
|
|
|
LeaveCriticalSection(&m_tCS);
|
|
|
|
return l_bResult;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
wchar_t *Get_File_Name()
|
|
{
|
|
if (FALSE == m_bInitialized)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
return m_cFile_Name.Get();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
tUINT64 Get_Count(IJournal::eLevel i_eType)
|
|
{
|
|
UINT64 l_qwReturn = 0ULL;
|
|
if (i_eType >= IJournal::eLEVEL_COUNT)
|
|
{
|
|
return 0ULL;
|
|
}
|
|
|
|
EnterCriticalSection(&m_tCS);
|
|
l_qwReturn = m_pCount[i_eType];
|
|
LeaveCriticalSection(&m_tCS);
|
|
|
|
return l_qwReturn;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
tINT32 Add_Ref()
|
|
{
|
|
return InterlockedIncrement(&m_lReference_Counter);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
tINT32 Release()
|
|
{
|
|
volatile tINT32 l_iRCnt = InterlockedDecrement(&m_lReference_Counter);
|
|
|
|
if ( 0 >= l_iRCnt)
|
|
{
|
|
delete this;
|
|
}
|
|
|
|
return l_iRCnt;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
BOOL Get_Initialized()
|
|
{
|
|
return m_bInitialized;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
tBOOL Register_Thread(const tXCHAR *i_pName, tUINT32 i_dwThreadId)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
tBOOL Unregister_Thread(tUINT32 i_dwThreadId)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
tBOOL Register_Module(const tXCHAR *i_pName, IJournal::hModule *o_hModule)
|
|
{
|
|
if (o_hModule)
|
|
{
|
|
*o_hModule = NULL;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
protected:
|
|
////////////////////////////////////////////////////////////////////////////
|
|
static void __cdecl Routine_Entry_Point(void *i_pContext)
|
|
{
|
|
CJournal * l_pFJournal = (CJournal *)i_pContext;
|
|
if (l_pFJournal)
|
|
{
|
|
l_pFJournal->Routine();
|
|
}
|
|
_endthread();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
void Routine()
|
|
{
|
|
BOOL l_bExit = FALSE;
|
|
HANDLE l_pEvents[] = {m_hEvent_Exit, m_hEvent_Write};
|
|
DWORD l_dwWFMO_result = 0;
|
|
DWORD l_dwSize = 0;
|
|
|
|
while (FALSE == l_bExit)
|
|
{
|
|
l_dwWFMO_result = WaitForMultipleObjects(sizeof(l_pEvents)/sizeof(l_pEvents[0]),
|
|
l_pEvents,
|
|
FALSE,
|
|
FJOURNAL_THREAD_WAKEUP_INTERVAL
|
|
); //Process events
|
|
|
|
|
|
// Exit signal
|
|
if (WAIT_OBJECT_0 == l_dwWFMO_result)
|
|
{
|
|
l_dwSize = Copy_Bufer(TRUE);
|
|
if (l_dwSize)
|
|
{
|
|
Write((BYTE*)m_pWrite_Buffer, l_dwSize);
|
|
}
|
|
|
|
l_bExit = TRUE;
|
|
}
|
|
else if ( (WAIT_OBJECT_0 + 1) == l_dwWFMO_result)// we have received signal for write
|
|
{
|
|
l_dwSize = Copy_Bufer(FALSE);
|
|
ResetEvent(m_hEvent_Write);
|
|
|
|
if ( (l_dwSize) && (FALSE == Write((BYTE*)m_pWrite_Buffer, l_dwSize)) )
|
|
{
|
|
l_bExit = TRUE;
|
|
}
|
|
}
|
|
else if (WAIT_TIMEOUT == l_dwWFMO_result)
|
|
{
|
|
l_dwSize = Copy_Bufer(TRUE);
|
|
|
|
if ( (l_dwSize) && (FALSE == Write((BYTE*)m_pWrite_Buffer, l_dwSize)) )
|
|
{
|
|
l_bExit = TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
m_hThread = NULL;
|
|
}
|
|
|
|
private:
|
|
////////////////////////////////////////////////////////////////////////////
|
|
DWORD Copy_Bufer(BOOL i_bLock)
|
|
{
|
|
DWORD l_dwResult = 0;
|
|
|
|
if (i_bLock)
|
|
{
|
|
EnterCriticalSection(&m_tCS);
|
|
}
|
|
|
|
if (m_dwBuffer_Used)
|
|
{
|
|
l_dwResult = m_dwBuffer_Used * sizeof(wchar_t);
|
|
memcpy_s(m_pWrite_Buffer, FJOURNAL_FILE_BUFFER_LENGTH * sizeof(wchar_t), m_pJournal_Buffer, l_dwResult);
|
|
m_dwBuffer_Used = 0;
|
|
}
|
|
|
|
if (i_bLock)
|
|
{
|
|
LeaveCriticalSection(&m_tCS);
|
|
}
|
|
|
|
return l_dwResult;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
BOOL Write(BYTE *i_pBuffer, DWORD i_dwSize)
|
|
{
|
|
BOOL l_bResult = TRUE;
|
|
DWORD l_dwReturned = 0;
|
|
DWORD l_dwWriten = 0;
|
|
|
|
if ( (0 >= i_dwSize) || (NULL == i_pBuffer) )
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
while ( l_dwWriten != i_dwSize )
|
|
{
|
|
l_dwReturned = 0;
|
|
if ( 0 == WriteFile(m_hLog_File,
|
|
i_pBuffer + l_dwWriten,
|
|
i_dwSize - l_dwWriten,
|
|
&l_dwReturned,
|
|
NULL)
|
|
)
|
|
{
|
|
i_dwSize = 0;
|
|
l_dwWriten = 0;
|
|
l_bResult = FALSE;
|
|
}
|
|
else
|
|
{
|
|
l_dwWriten += l_dwReturned;
|
|
}
|
|
} //while
|
|
|
|
return l_bResult;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
BOOL Remove_Old_Journals(wchar_t *i_pFolder, DWORD i_dwMax_Files, const wchar_t *i_pExtension)
|
|
{
|
|
wchar_t l_pFileName[ MAX_PATH ] = L"9999";
|
|
DWORD l_dwPrev_Error_Mode = 0;
|
|
WIN32_FIND_DATAW l_tFind_Info;
|
|
HANDLE l_hFind = INVALID_HANDLE_VALUE;
|
|
DWORD l_dwCount = 0;
|
|
BOOL l_bResult = TRUE;
|
|
|
|
if ( (NULL == i_pFolder) || (NULL == i_pExtension) )
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
l_dwPrev_Error_Mode = SetErrorMode(SEM_FAILCRITICALERRORS);
|
|
|
|
l_dwCount = i_dwMax_Files + 1;
|
|
|
|
while ( (l_dwCount > i_dwMax_Files) && (l_bResult) )
|
|
{
|
|
l_dwCount = 0;
|
|
|
|
swprintf_s(m_pJournal_Buffer, FJOURNAL_FILE_BUFFER_LENGTH, L"%s\\*.%s", i_pFolder, i_pExtension);
|
|
|
|
l_hFind = FindFirstFileW(m_pJournal_Buffer, &l_tFind_Info);
|
|
|
|
while(INVALID_HANDLE_VALUE != l_hFind)
|
|
{
|
|
if (0 == (l_tFind_Info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
|
|
{
|
|
l_dwCount ++;
|
|
if (0 <= _wcsicmp(l_pFileName, l_tFind_Info.cFileName))
|
|
{
|
|
wcscpy_s(l_pFileName, MAX_PATH, l_tFind_Info.cFileName);
|
|
}
|
|
|
|
if ( ! FindNextFileW(l_hFind, &l_tFind_Info))
|
|
{
|
|
FindClose(l_hFind);
|
|
l_hFind = INVALID_HANDLE_VALUE;
|
|
}
|
|
}
|
|
} //while(INVALID_HANDLE_VALUE != hFind)
|
|
|
|
SetErrorMode(l_dwPrev_Error_Mode);
|
|
|
|
if (l_dwCount > i_dwMax_Files)
|
|
{
|
|
swprintf_s(m_pJournal_Buffer, FJOURNAL_FILE_BUFFER_LENGTH, L"%s\\%s", i_pFolder, l_pFileName);
|
|
|
|
DWORD l_dwFAttr = GetFileAttributesW(m_pJournal_Buffer);
|
|
l_dwFAttr = l_dwFAttr & (~FILE_ATTRIBUTE_ARCHIVE);
|
|
l_dwFAttr = l_dwFAttr & (~FILE_ATTRIBUTE_READONLY);
|
|
l_dwFAttr = l_dwFAttr & (~FILE_ATTRIBUTE_SYSTEM);
|
|
SetFileAttributesW(m_pJournal_Buffer, l_dwFAttr);
|
|
l_bResult = DeleteFileW(m_pJournal_Buffer);
|
|
l_dwCount --;
|
|
wcscpy_s(l_pFileName, MAX_PATH, L"9999");
|
|
}
|
|
}
|
|
|
|
return l_bResult;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
virtual ~CJournal() //use Release() instead
|
|
{
|
|
if (m_hThread)
|
|
{
|
|
if (m_hEvent_Exit)
|
|
{
|
|
SetEvent(m_hEvent_Exit);
|
|
if (WAIT_TIMEOUT == WaitForSingleObject(m_hThread, 150000))
|
|
{
|
|
OutputDebugStringW(L"~CFJournal::Thread exit failed !\n");
|
|
}
|
|
CloseHandle(m_hEvent_Exit);
|
|
m_hEvent_Exit = NULL;
|
|
}
|
|
}
|
|
|
|
if (m_hEvent_Write)
|
|
{
|
|
CloseHandle(m_hEvent_Write);
|
|
m_hEvent_Write = NULL;
|
|
}
|
|
|
|
if (INVALID_HANDLE_VALUE != m_hLog_File)
|
|
{
|
|
CloseHandle(m_hLog_File);
|
|
m_hLog_File = INVALID_HANDLE_VALUE;
|
|
}
|
|
|
|
if (m_pJournal_Buffer)
|
|
{
|
|
delete [] m_pJournal_Buffer;
|
|
m_pJournal_Buffer = NULL;
|
|
}
|
|
|
|
if (m_pWrite_Buffer)
|
|
{
|
|
delete [] m_pWrite_Buffer;
|
|
m_pWrite_Buffer = NULL;
|
|
}
|
|
|
|
DeleteCriticalSection(&m_tCS);
|
|
}
|
|
|
|
};
|