// stdafx.cpp : 只包括标准包含文件的源文件
// test.pch 将作为预编译头
// stdafx.obj 将包含预编译类型信息

#include "stdafx.h"

#include <time.h> //或者 #include <ctime>
#include <locale.h>

// TODO: 在 STDAFX.H 中
// 引用任何所需的附加头文件，而不是在此文件中引用

/************************************************************************/
/*  函数：[7/3/2018 Wang];
/*  描述：;
/*  参数：;
/*  	[IN] ：;
/*  	[OUT] ：;
/*  	[IN/OUT] ：;
/*  返回：void;
/*  注意：非线程安全;
/*  示例：;
/*
/*  修改：;
/*  日期：;
/*  内容：;
/************************************************************************/
void ShowSystemErrorInfo( LPCTSTR lpszTitle,const DWORD &dwError)
{
	LPVOID lpMsgBuf;
	static TCHAR szResult[MAX_PATH] = {0};
	memset(szResult, 0, sizeof(TCHAR)*MAX_PATH);
	BOOL fOk = FormatMessage(
		FORMAT_MESSAGE_ALLOCATE_BUFFER |
		FORMAT_MESSAGE_FROM_SYSTEM |
		FORMAT_MESSAGE_IGNORE_INSERTS,
		NULL,
		dwError,
		MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
		(LPTSTR)&lpMsgBuf,
		0, NULL);

	if (!fOk)
	{
		// Is it a network-related error?
		HMODULE hDll = LoadLibraryEx(TEXT("netmsg.dll"), NULL, DONT_RESOLVE_DLL_REFERENCES);

		if (hDll != NULL)
		{
			FormatMessage(
				FORMAT_MESSAGE_FROM_HMODULE |
				FORMAT_MESSAGE_FROM_SYSTEM |
				FORMAT_MESSAGE_IGNORE_INSERTS,
				hDll,
				dwError,
				MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
				(LPTSTR)&lpMsgBuf,
				0,
				NULL);

			FreeLibrary(hDll);
		}
	}

	if (lpMsgBuf != NULL)
	{
		_stprintf_s(szResult, _T("%s:%ld,%s"), lpszTitle == NULL ? _T("错误") : lpszTitle, dwError, (PCTSTR)LocalLock(lpMsgBuf));
		WriteTextLog(szResult);
		LocalFree(lpMsgBuf);
	}
	else
	{
		_stprintf_s(szResult, _T("%s:未知错误！"),lpszTitle == NULL ? _T("错误") : lpszTitle);
		WriteTextLog(szResult);
	}
}

/************************************************************************/
/*  函数：WriteTextLog[7/28/2016 IT];
/*  描述：写文本日志;
/*  参数：;
/*  	[IN] ：;
/*  返回：void;
/*  注意：;
/*  示例：;
/*
/*  修改：;
/*  日期：;
/*  内容：;
/************************************************************************/
void WriteTextLog(const TCHAR *format, ...)
{
	//static ThreadSection _critSection;
	//AutoThreadSection aSection(&_critSection);
	// 解析出日志路径;
	TCHAR szlogpath[MAX_PATH] = {0};
	static TCHAR szModulePath[MAX_PATH] = {0};
	static TCHAR szFna[_MAX_DIR] = { 0 };
	if ( szModulePath[0] == _T('\0') )
	{
		TCHAR szDrive[_MAX_DRIVE] = { 0 };
		TCHAR szDir[_MAX_DIR] = { 0 };
		TCHAR szExt[_MAX_DIR] = { 0 };
		::GetModuleFileName(NULL, szModulePath, sizeof(szModulePath) / sizeof(TCHAR));
		_tsplitpath_s(szModulePath, szDrive, szDir, szFna, szExt);
		_tcscpy_s(szModulePath, szDrive);
		_tcscat_s(szModulePath, szDir);
	}

	// 获取今年年份;
	__time64_t gmt = time(NULL);// 获取当前日历时间(1900-01-01开始的Unix时间戳);
	struct tm gmtm = {0};
	//gmtime_s(&gmtm, &gmt); // 时间戳转成UTC时间(也叫GMT时间);
	localtime_s(&gmtm, &gmt); // 时间戳转成本地时间;
	_stprintf_s(szlogpath, _T("%s%s%04d-%02d-%02d.txt"), szModulePath, szFna, gmtm.tm_year + 1900, gmtm.tm_mon+1, gmtm.tm_mday);

	// 打开或创建文件;
#if 0 // MFC
	CStdioFile fp;
	if (PathFileExists(szlogpath))
	{
		if (fp.Open(szlogpath, CFile::modeWrite) == FALSE)
		{
			return;
		}
		fp.SeekToEnd();
	}
	else
	{
		fp.Open(szlogpath, CFile::modeCreate | CFile::modeWrite);
	}

	// 格式化前设置语言区域;
	TCHAR* old_locale = _tcsdup(_tsetlocale(LC_CTYPE, NULL));
	_tsetlocale(LC_CTYPE, _T("chs"));//设定中文;

	// 格式化日志内容;
	va_list		args = NULL;
	int			len = 0;
	TCHAR		*buffer = NULL;
	va_start( args, format );
	// _vscprintf doesn't count. terminating '\0'
	len = _vsctprintf( format, args )  + 1;
	buffer = (TCHAR*)malloc( len * sizeof(TCHAR) );
	_vstprintf_s( buffer, len, format, args ); // C4996
	// Note: vsprintf is deprecated; consider using vsprintf_s instead

	// 将日志内容输入到文件中;
	fp.WriteString( CTime::GetCurrentTime().Format(_T("%Y-%m-%d %H:%M:%S ")) );
	fp.WriteString(buffer);
	fp.WriteString(_T("\n"));

	// 关闭文件，释放资源并设置回原语言区域;
	free( buffer );
	_tsetlocale(LC_CTYPE, old_locale);
	free(old_locale);//还原区域设定;
	fp.Close();
#else // 不依赖MFC;
	FILE *fp = NULL;
	fp = _tfopen(szlogpath, _T("a+"));
	if ( fp == NULL )
		return;

	fseek(fp, 0, SEEK_END);

	// 格式化前设置语言区域;
	TCHAR* old_locale = _tcsdup(_tsetlocale(LC_CTYPE, NULL));
	_tsetlocale(LC_CTYPE, _T("chs"));//设定中文;

	// 格式化日志内容;
	va_list		args = NULL;
	int			len = 0;
	TCHAR		*buffer = NULL;
	va_start( args, format );
	// _vscprintf doesn't count. terminating '\0'
	len = _vsctprintf( format, args )  + 1;
	buffer = (TCHAR*)malloc( len * sizeof(TCHAR) );
	_vstprintf_s( buffer, len, format, args ); // C4996
	// Note: vsprintf is deprecated; consider using vsprintf_s instead

	// 将日志内容输入到文件中;
	TCHAR szTime[36] = {0};
	_stprintf_s(szTime, _T("%04d-%02d-%02d %02d:%02d:%02d  "), gmtm.tm_year + 1900, gmtm.tm_mon+1, gmtm.tm_mday, gmtm.tm_hour, gmtm.tm_min, gmtm.tm_sec);
	fwrite(szTime, _tcslen(szTime)*sizeof(TCHAR), 1, fp);
	fwrite(buffer, _tcslen(buffer)*sizeof(TCHAR), 1, fp);
	fwrite(_T("\n"), sizeof(TCHAR), 1, fp);

	// 关闭文件，释放资源并设置回原语言区域;
	free( buffer );
	_tsetlocale(LC_CTYPE, old_locale);
	free(old_locale);//还原区域设定;

	fclose(fp);

#endif
}
