/**----------------------------------------------------------------------------
\brief
\param
\return
\code
\endcode
-----------------------------------------------------------------------------*/
void
DebugMessage(
const char* Function,
int Line,
const char* LogPrefix,
const char* fmt,
...
)
{
	_ASSERTE(NULL != LogPrefix); if (NULL == LogPrefix) return;
	_ASSERTE(NULL != fmt); if (NULL == fmt) return;

	char log_buffer[4096] = { 0 };
	size_t remain = sizeof(log_buffer);
	char* pos = log_buffer;
	va_list args;

	// 프로세스 정보
	// 
	char    name_buffer[MAX_PATH + 1] = { 0 };
	char    *name = name_buffer;
	name_buffer[0] = '\0';
	DWORD len = GetModuleFileNameA(NULL, name_buffer, sizeof(name_buffer));
	if (len>0) name = get_filename_part(name_buffer, len);

	// format string 파라미터를 Multibyte / WideChar 가 잘 못 들어온 경우등
	// 에러가 발생할 수 있어서 해당 함수를 찾기위한 디버그 코드 
	// e.g. %s => L"debug string...."    or %S => "debug string"
	// 
	size_t remain_b = remain;
	char* pos_b = pos;

	HRESULT hRes = StringCbPrintfExA(
		pos,
		remain,
		&pos,
		&remain,
		0,
		"%-18s(%04u:%04u), %s %s() ",
		name,
		GetCurrentProcessId(),
		GetCurrentThreadId(),
		LogPrefix,
		Function
		);
	if (S_OK != hRes)
	{
		OutputDebugStringA("StringCbPrintfExA() failed, more log buffer needed...?");
		return;
	}
	remain_b = remain;
	pos_b = pos;


	va_start(args, fmt);
	hRes = StringCbVPrintfExA(
		pos,
		remain,
		&pos,
		&remain,
		0,
		fmt,
		args
		);

	if (S_OK != hRes)
	{
		// 한글 같은 unicode 문자열이 있는 경우 발생할 수 있음
		// 
		StringCbPrintfExA(
			pos_b,
			remain_b,
			&pos_b,
			&remain_b,
			0,
			"invalid function call parameters, line=%d",
			Line
			);
		remain = remain_b;
		pos = pos_b;
	}
	va_end(args);

	hRes = StringCbPrintfExA(
		pos,
		remain,
		&pos,
		&remain,
		0,
		"%s",
		"\r\n"
		);
	if (!SUCCEEDED(hRes))
	{

		OutputDebugStringA("StringCbPrintfExA() failed, more log buffer needed...?");
		return;
	}

	OutputDebugStringA(log_buffer);
}
Beispiel #2
0
/**
 * @brief	
 * @param	
 * @see		
 * @remarks	
 * @code		
 * @endcode	
 * @return	
**/
void
log_write_fmt(
    _In_ uint32_t log_level, 
	_In_z_ const char* function,
    _In_z_ const char* fmt, 
    _In_ ...
    )
{
    if (NULL == fmt) return;

	char log_buffer[2048];
    size_t remain = sizeof(log_buffer);
    char* pos = log_buffer;
    va_list args;

    // log level
    switch (log_level)
    {
    case log_level_debug: StringCbPrintfExA(pos, remain, &pos, &remain, 0, "%s", "[DEBG] "); break;
    case log_level_info:  StringCbPrintfExA(pos, remain, &pos, &remain, 0, "%s", "[INFO] "); break;
    case log_level_warn:  StringCbPrintfExA(pos, remain, &pos, &remain, 0, "%s", "[WARN] "); break;
    case log_level_error: StringCbPrintfExA(pos, remain, &pos, &remain, 0, "%s", "[EROR] "); break;
    default:
        _ASSERTE(!"never reach here!");
        return;
    }

    //> show process name
    if (true == _show_process_name)
    {
        StringCbPrintfExA(
            pos, 
            remain, 
            &pos, 
            &remain, 
            0, 
            "%ws",
            get_current_module_fileEx().c_str()
            );
    }

    //> show pid, tid
    if (true == _show_pid_tid)
    {
        StringCbPrintfExA(
            pos,
            remain,
            &pos,
            &remain,
            0,
            "(%+5u:%+5u) : ",
            GetCurrentProcessId(),
            GetCurrentThreadId()
            );
    }

    //> show function name
    if (true == _show_function_name)
    {
        StringCbPrintfExA(pos, remain, &pos, &remain, 0, "%s : ", function);
    }

    va_start(args,fmt);
    HRESULT hRes = StringCbVPrintfExA(
                        pos, 
                        remain, 
                        &pos,
                        &remain,
                        0, 
                        fmt, 
                        args
                        );

    if (S_OK != hRes)
    {
		// invalid character 가 끼어있는 경우 발생 할 수 있음
        StringCbPrintfExA(
            pos, 
            remain, 
            &pos, 
            &remain,
            0, 
            "invalid function call parameters"
            );
    }    
    va_end(args);

    // line feed
    StringCbPrintfExA(pos, remain, &pos, &remain, 0, "\n");

    // Let's write logs.
    switch (log_level)
    {
    case log_level_error: // same as log_level_critical
        write_to_console(wtc_red, log_buffer);
        break;
    case log_level_info:
    case log_level_warn:
        write_to_console(wtc_green, log_buffer);
        break;
    default:
        write_to_console(wtc_none, log_buffer);
    }
           

    OutputDebugStringA(log_buffer);
}
Beispiel #3
0
VOID __fastcall HashSaveWorkerMain( PHASHSAVECONTEXT phsctx )
{
	// Note that ALL message communication to and from the main window MUST
	// be asynchronous, or else there may be a deadlock.

	// Prep: expand directories, max path, etc. (prefix was set by earlier call)
	PostMessage(phsctx->hWnd, HM_WORKERTHREAD_TOGGLEPREP, (WPARAM)phsctx, TRUE);
	if (! HashCalcPrepare(phsctx))
        return;
    HashCalcSetSaveFormat(phsctx);
	PostMessage(phsctx->hWnd, HM_WORKERTHREAD_TOGGLEPREP, (WPARAM)phsctx, FALSE);

    // Extract the slist into a vector for parallel_for_each
    std::vector<PHASHSAVEITEM> vecpItems;
    vecpItems.resize(phsctx->cTotal + 1);
    SLBuildIndex(phsctx->hList, (PVOID*)vecpItems.data());
    assert(vecpItems.back() == nullptr);
    vecpItems.pop_back();
    assert(vecpItems.back() != nullptr);

#ifdef USE_PPL
    const bool bMultithreaded = vecpItems.size() > 1 && IsSSD(vecpItems[0]->szPath);
    concurrency::concurrent_vector<void*> vecBuffers;  // a vector of all allocated read buffers (one per thread)
    DWORD dwBufferTlsIndex = TlsAlloc();               // TLS index of the current thread's read buffer
    if (dwBufferTlsIndex == TLS_OUT_OF_INDEXES)
        return;
#else
    constexpr bool bMultithreaded = false;
#endif

    PBYTE pbTheBuffer;  // file read buffer, used iff not multithreaded
    if (! bMultithreaded)
    {
        pbTheBuffer = (PBYTE)VirtualAlloc(NULL, READ_BUFFER_SIZE, MEM_COMMIT, PAGE_READWRITE);
        if (pbTheBuffer == NULL)
            return;
    }

    // Initialize the progress bar update synchronization vars
    CRITICAL_SECTION updateCritSec;
    volatile ULONGLONG cbCurrentMaxSize = 0;
    if (bMultithreaded)
        InitializeCriticalSection(&updateCritSec);

#ifdef _TIMED
    DWORD dwStarted;
    dwStarted = GetTickCount();
#endif

    class CanceledException {};

    // concurrency::parallel_for_each(vecpItems.cbegin(), vecpItems.cend(), ...
    auto per_file_worker = [&](PHASHSAVEITEM pItem)
	{
        WHCTXEX whctx;

        // Indicate which hash type we are after, see WHEX... values in WinHash.h
        whctx.dwFlags = 1 << (phsctx->ofn.nFilterIndex - 1);

        PBYTE pbBuffer;
#ifdef USE_PPL
        if (bMultithreaded)
        {
            // Allocate or retrieve the already-allocated read buffer for the current thread
            pbBuffer = (PBYTE)TlsGetValue(dwBufferTlsIndex);
            if (pbBuffer == NULL)
            {
                pbBuffer = (PBYTE)VirtualAlloc(NULL, READ_BUFFER_SIZE, MEM_COMMIT, PAGE_READWRITE);
                if (pbBuffer == NULL)
                    throw CanceledException();
                // Cache the read buffer for the current thread
                vecBuffers.push_back(pbBuffer);
                TlsSetValue(dwBufferTlsIndex, pbBuffer);
            }
        }
#endif

#pragma warning(push)
#pragma warning(disable: 4700 4703)  // potentially uninitialized local pointer variable 'pbBuffer' used
		// Get the hash
		WorkerThreadHashFile(
			(PCOMMONCONTEXT)phsctx,
			pItem->szPath,
			&whctx,
			&pItem->results,
            bMultithreaded ? pbBuffer : pbTheBuffer,
			NULL, 0,
            bMultithreaded ? &updateCritSec : NULL, &cbCurrentMaxSize
#ifdef _TIMED
          , &pItem->dwElapsed
#endif
        );

        if (phsctx->status == PAUSED)
            WaitForSingleObject(phsctx->hUnpauseEvent, INFINITE);
		if (phsctx->status == CANCEL_REQUESTED)
            throw CanceledException();

		// Write the data
		HashCalcWriteResult(phsctx, pItem);

		// Update the UI
		InterlockedIncrement(&phsctx->cSentMsgs);
		PostMessage(phsctx->hWnd, HM_WORKERTHREAD_UPDATE, (WPARAM)phsctx, (LPARAM)pItem);
    };
#pragma warning(pop)

    try
    {
#ifdef USE_PPL
        if (bMultithreaded)
            concurrency::parallel_for_each(vecpItems.cbegin(), vecpItems.cend(), per_file_worker);
        else
#endif
            std::for_each(vecpItems.cbegin(), vecpItems.cend(), per_file_worker);
    }
    catch (CanceledException) {}  // ignore cancellation requests

#ifdef _TIMED
    if (phsctx->cTotal > 1 && phsctx->status != CANCEL_REQUESTED)
    {
        union {
            CHAR  szA[MAX_STRINGMSG];
            WCHAR szW[MAX_STRINGMSG];
        } buffer;
        size_t cbBufferLeft;
        if (phsctx->opt.dwSaveEncoding == 1)  // UTF-16
        {
            StringCbPrintfExW(buffer.szW, sizeof(buffer), NULL, &cbBufferLeft, 0, L"; Total elapsed: %d ms\r\n", GetTickCount() - dwStarted);
        }
        else                                  // UTF-8 or ANSI
        {
            StringCbPrintfExA(buffer.szA, sizeof(buffer), NULL, &cbBufferLeft, 0,  "; Total elapsed: %d ms\r\n", GetTickCount() - dwStarted);
        }
        DWORD dwUnused;
        WriteFile(phsctx->hFileOut, buffer.szA, (DWORD) (sizeof(buffer) - cbBufferLeft), &dwUnused, NULL);
    }
#endif

#ifdef USE_PPL
    if (bMultithreaded)
    {
        for (void* pBuffer : vecBuffers)
            VirtualFree(pBuffer, 0, MEM_RELEASE);
        DeleteCriticalSection(&updateCritSec);
    }
    else
#endif
        VirtualFree(pbTheBuffer, 0, MEM_RELEASE);
}
int vsprintfex( char *buffer, int buffersize,const char *format, va_list argList )
{
	int ptr=0;
	const char* in=format;
	LPSTR end;

	int nNextArg=0,index,length;

    while (*in!='\0')
	{
		if (*in=='%')
		{
			in++;
			
			// Finding first non number
			for(index=0;in[index]>='0' && in[index]<='9';index++);

			// Now index points to nonnumberic character
			if (in[index]==':')
			{
				// ok number was argument place
				if (index==0)
					return 0;
				nNextArg=atoi(in);
                
				// finding next '%'
				in+=index+1;
				for (length=0;in[length]!='\0' && in[length]!='%';length++);

				char* pTemp=new char[length+2];
				pTemp[0]='%';
				CopyMemory(pTemp+1,in,length);
				pTemp[length+1]='\0';
				HRESULT hRes=StringCbPrintfExA(buffer+ptr,buffersize-ptr,&end,NULL,STRSAFE_IGNORE_NULLS,pTemp,va_getarg(argList,nNextArg));
				if (FAILED(hRes))
					return 0;
                ptr=int(end-buffer);
				delete[] pTemp;

				if (in[length]=='\0')
					break;
				
				in+=length;
			}
			else
			{
				nNextArg++;
				for (;in[index]!='\0' && in[index]!='%';index++);
			

				char* pTemp=new char[index+2];
				pTemp[0]='%';
				CopyMemory(pTemp+1,in,index);
				pTemp[index+1]='\0';
				HRESULT hRes=StringCbPrintfExA(buffer+ptr,buffersize-ptr,&end,NULL,STRSAFE_IGNORE_NULLS,pTemp,va_getarg(argList,nNextArg));
				if (FAILED(hRes))
					return 0;
                ptr=int(end-buffer);
				delete[] pTemp;
				
				if (in[index]=='\0')
					break;
				
				in+=index;                
			}
		}
		else
			buffer[ptr++]=*(in++);
	}
	buffer[ptr]='\0';
	return ptr;
}
Beispiel #5
0
BOOL WINAPI LSLog(int nLevel, LPCSTR pszModule, LPCSTR pszMessage)
{
#if defined(LS_COMPAT_LOGGING)
    wchar_t wzLogFile[MAX_PATH] = { 0 };

    int nLogLevel = GetRCIntW(L"LSLogLevel", 2);

    // Should this message be logged?
    if (!pszModule || !pszMessage ||
        (nLevel > nLogLevel) || (nLevel < 1) || (nLevel > 4))
    {
        return FALSE;
    }

    // Has a log file been assigned?
    if (!GetRCStringW(L"LSLogFile", wzLogFile, NULL, MAX_PATH))
    {
        return FALSE;
    }

    // If so, open it
    HANDLE hLogFile = CreateFile(wzLogFile,
        GENERIC_WRITE,
        FILE_SHARE_READ | FILE_SHARE_WRITE,
        NULL,
        OPEN_ALWAYS,
        FILE_ATTRIBUTE_NORMAL,
        NULL);

    // Did open succeed?
    if (hLogFile == INVALID_HANDLE_VALUE)
    {
        return FALSE;
    }

    // Move to the end of the file
    SetFilePointer(hLogFile, 0, NULL, FILE_END);

    // Get timestamp
    SYSTEMTIME st = { 0 };
    GetLocalTime(&st);

    // Add timestamp and module name to message
    LPCSTR rszLevel[4] = { "Error", "Warning", "Notice", "Debug" };

    CHAR szLine[MAX_LINE_LENGTH] = { 0 };
    size_t cbLine = sizeof(szLine);
    size_t cbRemaining = 0;

    if (SUCCEEDED(StringCbPrintfExA(szLine, cbLine, NULL, &cbRemaining,
        STRSAFE_IGNORE_NULLS, "%02d-%02d-%04d %02d:%02d:%02d - %s - %s: %s\r\n",
        st.wMonth, st.wDay, st.wYear, st.wHour, st.wMinute, st.wSecond,
        rszLevel[nLevel-1], pszModule, pszMessage)))
    {
        size_t cbToWrite = cbLine - cbRemaining;
        ASSERT(cbToWrite <= MAXDWORD);

        // Write it to the log file
        DWORD dwCount = 0;
        WriteFile(hLogFile, szLine, (DWORD)cbToWrite, &dwCount, NULL);
    }

    // Close the log
    CloseHandle(hLogFile);
#endif // LS_COMPAT_LOGGING

    return TRUE;
}