PageRenderTime 93ms CodeModel.GetById 13ms app.highlight 74ms RepoModel.GetById 2ms app.codeStats 0ms

/reporting/crashrpt/Utility.cpp

http://crashrpt.googlecode.com/
C++ | 607 lines | 478 code | 99 blank | 30 comment | 52 complexity | d04c35f91afcb92ad1f6f5911454ecd0 MD5 | raw file
  1/************************************************************************************* 
  2This file is a part of CrashRpt library.
  3Copyright (c) 2003-2013 The CrashRpt project authors. All Rights Reserved.
  4
  5Use of this source code is governed by a BSD-style license
  6that can be found in the License.txt file in the root of the source
  7tree. All contributing project authors may
  8be found in the Authors.txt file in the root of the source tree.
  9***************************************************************************************/
 10
 11// File: Utility.cpp
 12// Description: Miscellaneous helper functions
 13// Authors: mikecarruth, zexspectrum
 14// Date: 
 15
 16#include "stdafx.h"
 17#include "Utility.h"
 18#include "resource.h"
 19#include "strconv.h"
 20
 21CString Utility::getAppName()
 22{
 23    TCHAR szFileName[_MAX_PATH];
 24    GetModuleFileName(NULL, szFileName, _MAX_FNAME);
 25
 26    CString sAppName; // Extract from last '\' to '.'
 27    sAppName = szFileName;
 28    sAppName = sAppName.Mid(sAppName.ReverseFind(_T('\\')) + 1)
 29        .SpanExcluding(_T("."));
 30
 31    return sAppName;
 32}
 33
 34CString Utility::GetModuleName(HMODULE hModule)
 35{
 36    CString string;
 37    LPTSTR buf = string.GetBuffer(_MAX_PATH);
 38    GetModuleFileName(hModule, buf, _MAX_PATH);
 39    string.ReleaseBuffer();
 40    return string;
 41}
 42
 43CString Utility::GetModulePath(HMODULE hModule)
 44{
 45    CString string;
 46    LPTSTR buf = string.GetBuffer(_MAX_PATH);
 47    GetModuleFileName(hModule, buf, _MAX_PATH);
 48    TCHAR* ptr = _tcsrchr(buf,'\\');
 49    if(ptr!=NULL)
 50        *(ptr)=0; // remove executable name
 51    string.ReleaseBuffer();
 52    return string;
 53}
 54
 55int Utility::getTempDirectory(CString& strTemp)
 56{
 57    TCHAR* pszTempVar = NULL;
 58
 59#if _MSC_VER<1400
 60    pszTempVar = _tgetenv(_T("TEMP"));
 61    strTemp = CString(pszTempVar);
 62#else
 63    size_t len = 0;
 64    errno_t err = _tdupenv_s(&pszTempVar, &len, _T("TEMP"));
 65    if(err!=0)
 66    {
 67        // Couldn't get environment variable TEMP    
 68        return 1;
 69    }
 70    strTemp = CString(pszTempVar);
 71    free(pszTempVar);
 72#endif    
 73
 74    return 0;
 75}
 76
 77CString Utility::getTempFileName()
 78{
 79    TCHAR szTempDir[MAX_PATH - 14]   = _T("");
 80    TCHAR szTempFile[MAX_PATH]       = _T("");
 81
 82    if (GetTempPath(MAX_PATH - 14, szTempDir))
 83        GetTempFileName(szTempDir, getAppName(), 0, szTempFile);
 84
 85    return szTempFile;
 86}
 87
 88int Utility::GetSystemTimeUTC(CString& sTime)
 89{
 90    sTime.Empty();
 91
 92    // Get system time in UTC format
 93
 94    time_t cur_time;
 95    time(&cur_time);
 96    char szDateTime[64];
 97
 98#if _MSC_VER<1400
 99    struct tm* timeinfo = gmtime(&cur_time);
100    strftime(szDateTime, 64,  "%Y-%m-%dT%H:%M:%SZ", timeinfo);
101#else
102    struct tm timeinfo;
103    gmtime_s(&timeinfo, &cur_time);
104    strftime(szDateTime, 64,  "%Y-%m-%dT%H:%M:%SZ", &timeinfo);
105#endif
106
107    sTime = szDateTime;
108
109    return 0;
110}
111
112void Utility::UTC2SystemTime(CString sUTC, SYSTEMTIME& st)
113{
114    CString sYear = sUTC.Mid(0, 4);
115    CString sMonth = sUTC.Mid(5, 2);
116    CString sDay = sUTC.Mid(8, 2);
117    CString sHour = sUTC.Mid(11, 2);
118    CString sMin = sUTC.Mid(14, 2);
119    CString sSec = sUTC.Mid(17, 2);
120
121    SYSTEMTIME UtcTime;
122    memset(&UtcTime, 0, sizeof(SYSTEMTIME));
123    UtcTime.wYear = (WORD)_ttoi(sYear);
124    UtcTime.wMonth = (WORD)_ttoi(sMonth);
125    UtcTime.wDay = (WORD)_ttoi(sDay);
126    UtcTime.wHour = (WORD)_ttoi(sHour);
127    UtcTime.wMinute = (WORD)_ttoi(sMin);
128    UtcTime.wSecond = (WORD)_ttoi(sSec);
129
130    // Convert to local time
131    SystemTimeToTzSpecificLocalTime(NULL, &UtcTime, &st);
132}
133
134int Utility::GenerateGUID(CString& sGUID)
135{
136    int status = 1;
137    sGUID.Empty();
138
139    strconv_t strconv;
140
141    // Create GUID
142
143    UCHAR *pszUuid = 0; 
144    GUID *pguid = NULL;
145    pguid = new GUID;
146    if(pguid!=NULL)
147    {
148        HRESULT hr = CoCreateGuid(pguid);
149        if(SUCCEEDED(hr))
150        {
151            // Convert the GUID to a string
152            hr = UuidToStringA(pguid, &pszUuid);
153            if(SUCCEEDED(hr) && pszUuid!=NULL)
154            { 
155                status = 0;
156                sGUID = strconv.a2t((char*)pszUuid);
157                RpcStringFreeA(&pszUuid);
158            }
159        }
160        delete pguid; 
161    }
162
163    return status;
164}
165
166int Utility::GetOSFriendlyName(CString& sOSName)
167{
168    sOSName.Empty();
169    CRegKey regKey;
170    LONG lResult = regKey.Open(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"), KEY_READ);
171    if(lResult==ERROR_SUCCESS)
172    {    
173        TCHAR buf[1024];
174        ULONG buf_size = 0;
175
176        TCHAR* PRODUCT_NAME = _T("ProductName");
177        TCHAR* CURRENT_BUILD_NUMBER = _T("CurrentBuildNumber");
178        TCHAR* CSD_VERSION = _T("CSDVersion");
179
180#pragma warning(disable:4996)
181
182        buf_size = 1023;
183        if(ERROR_SUCCESS == regKey.QueryValue(buf, PRODUCT_NAME, &buf_size))
184        {
185            sOSName += buf;
186        }
187
188        buf_size = 1023;
189        if(ERROR_SUCCESS == regKey.QueryValue(buf, CURRENT_BUILD_NUMBER, &buf_size))
190        {
191            sOSName += _T(" Build ");
192            sOSName += buf;
193        }
194
195        buf_size = 1023;
196        if(ERROR_SUCCESS == regKey.QueryValue(buf, CSD_VERSION, &buf_size))
197        {
198            sOSName += _T(" ");
199            sOSName += buf;
200        }
201
202#pragma warning(default:4996)
203
204        regKey.Close();    
205        return 0;
206    }
207
208    return 1;
209}
210
211BOOL Utility::IsOS64Bit()
212{
213    BOOL b64Bit = FALSE;
214
215#ifdef _WIN64
216    // 64-bit applications always run under 64-bit Windows
217    return TRUE;
218#endif
219
220    // Check for 32-bit applications
221
222    typedef BOOL (WINAPI *PFNISWOW64PROCESS)(HANDLE, PBOOL);
223
224    HMODULE hKernel32 = LoadLibrary(_T("kernel32.dll"));
225    if(hKernel32!=NULL)
226    {
227        PFNISWOW64PROCESS pfnIsWow64Process = 
228            (PFNISWOW64PROCESS)GetProcAddress(hKernel32, "IsWow64Process");
229        if(pfnIsWow64Process==NULL)
230        {
231            // If there is no IsWow64Process() API, than Windows is 32-bit for sure
232            FreeLibrary(hKernel32);
233            return FALSE;
234        }
235
236        pfnIsWow64Process(GetCurrentProcess(), &b64Bit);
237        FreeLibrary(hKernel32);
238    }
239
240    return b64Bit;
241}
242
243int Utility::GetGeoLocation(CString& sGeoLocation)
244{
245    sGeoLocation = _T("");
246
247    typedef GEOID (WINAPI *PFNGETUSERGEOID)(GEOCLASS);
248    typedef int (WINAPI *PFNGETGEOINFOW)(GEOID, GEOTYPE, LPWSTR, int, LANGID);
249
250    HMODULE hKernel32 = LoadLibrary(_T("kernel32.dll"));
251    if(hKernel32!=NULL)
252    {
253        PFNGETUSERGEOID pfnGetUserGeoID = 
254            (PFNGETUSERGEOID)GetProcAddress(hKernel32, "GetUserGeoID");
255        PFNGETGEOINFOW pfnGetGeoInfoW = 
256            (PFNGETGEOINFOW)GetProcAddress(hKernel32, "GetGeoInfoW");
257        if(pfnGetUserGeoID==NULL || 
258            pfnGetGeoInfoW==NULL)
259            return -1;
260
261        GEOID GeoLocation = pfnGetUserGeoID(GEOCLASS_NATION);
262        if(GeoLocation!=GEOID_NOT_AVAILABLE)
263        { 
264            WCHAR szGeoInfo[1024] = _T("");    
265            int n = pfnGetGeoInfoW(GeoLocation, GEO_RFC1766, szGeoInfo, 1024, 0);
266            if(n!=0)
267            {
268                sGeoLocation = szGeoInfo;
269                FreeLibrary(hKernel32);
270                return 0;
271            }
272        }
273
274        FreeLibrary(hKernel32);    
275    }
276
277    return -1;
278}
279
280int Utility::GetSpecialFolder(int csidl, CString& sFolderPath)
281{
282    sFolderPath.Empty();
283
284    TCHAR szPath[_MAX_PATH];
285    BOOL bResult = SHGetSpecialFolderPath(NULL, szPath, csidl, TRUE);
286    if(!bResult)
287        return 1;
288
289    sFolderPath = CString(szPath);
290
291    return 0;
292}
293
294CString Utility::ReplaceInvalidCharsInFileName(CString sFileName)
295{
296    sFileName.Replace(_T("*"),_T("_"));
297    sFileName.Replace(_T("|"),_T("_"));
298    sFileName.Replace(_T("/"),_T("_"));
299    sFileName.Replace(_T("?"),_T("_"));
300    sFileName.Replace(_T("<"),_T("_"));
301    sFileName.Replace(_T(">"),_T("_"));
302    return sFileName;
303}
304
305int Utility::RecycleFile(CString sFilePath, bool bPermanentDelete)
306{
307    SHFILEOPSTRUCT fop;
308    memset(&fop, 0, sizeof(SHFILEOPSTRUCT));
309
310    TCHAR szFrom[_MAX_PATH];  
311    memset(szFrom, 0, sizeof(TCHAR)*(_MAX_PATH));
312    _TCSCPY_S(szFrom, _MAX_PATH, sFilePath.GetBuffer(0));
313    szFrom[sFilePath.GetLength()+1] = 0;
314
315    fop.fFlags |= FOF_SILENT;                // don't report progress
316    fop.fFlags |= FOF_NOERRORUI;           // don't report errors
317    fop.fFlags |= FOF_NOCONFIRMATION;        // don't confirm delete
318    fop.wFunc = FO_DELETE;                   // REQUIRED: delete operation
319    fop.pFrom = szFrom;                      // REQUIRED: which file(s)
320    fop.pTo = NULL;                          // MUST be NULL
321    if (bPermanentDelete) 
322    { 
323        // if delete requested..
324        fop.fFlags &= ~FOF_ALLOWUNDO;   // ..don't use Recycle Bin
325    } 
326    else 
327    {                                 // otherwise..
328        fop.fFlags |= FOF_ALLOWUNDO;    // ..send to Recycle Bin
329    }
330
331    return SHFileOperation(&fop); // do it!  
332}
333
334CString Utility::GetINIString(LPCTSTR pszFile, LPCTSTR pszSection, LPCTSTR pszName)
335{  
336    TCHAR szBuffer[1024] = _T("");  
337    GetPrivateProfileString(pszSection, pszName, _T(""), szBuffer, 1024, pszFile);
338
339    CString sResult = szBuffer;
340    sResult.Replace(_T("\\n"), _T("\n"));
341
342    return sResult;
343}
344
345void Utility::SetINIString(LPCTSTR pszFile, LPCTSTR pszSection, LPCTSTR pszName, LPCTSTR pszValue)
346{   
347    WritePrivateProfileString(pszSection, pszName, pszValue, pszFile);
348}
349
350
351void Utility::SetLayoutRTL(HWND hWnd)
352{
353    DWORD dwExStyle = GetWindowLong(hWnd, GWL_EXSTYLE);
354    dwExStyle |= WS_EX_LAYOUTRTL;
355    SetWindowLong(hWnd, GWL_EXSTYLE, dwExStyle);
356
357    SetLayout(GetDC(hWnd), LAYOUT_RTL);
358
359    CRect rcWnd;
360    ::GetClientRect(hWnd, &rcWnd);
361
362    HWND hWndChild = GetWindow(hWnd, GW_CHILD);
363    while(hWndChild!=NULL)
364    {    
365        SetLayoutRTL(hWndChild);
366
367        CRect rc;
368        ::GetWindowRect(hWndChild, &rc);    
369        ::MapWindowPoints(0, hWnd, (LPPOINT)&rc, 2);
370        ::MoveWindow(hWndChild, rcWnd.Width()-rc.right, rc.top, rc.Width(), rc.Height(), TRUE);
371
372        SetLayout(GetDC(hWndChild), LAYOUT_RTL);
373
374        hWndChild = GetWindow(hWndChild, GW_HWNDNEXT);
375    }  
376}
377
378CString Utility::FormatErrorMsg(DWORD dwErrorCode)
379{
380    LPTSTR msg = 0;
381    FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_ALLOCATE_BUFFER,
382        NULL, dwErrorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
383        (LPTSTR)&msg, 0, NULL);
384    CString str = msg;
385    str.Replace(_T("\r\n"), _T(""));
386    GlobalFree(msg);
387    return str;
388}
389
390// GetBaseFileName
391// This helper function returns file name without extension
392CString Utility::GetFileName(CString sPath)
393{
394    CString sBase = sPath;
395    int pos1 = sPath.ReverseFind('\\');
396    if(pos1>=0)
397        sBase = sBase.Mid(pos1+1);
398
399    return sBase;
400}
401
402// GetBaseFileName
403// This helper function returns file name without extension
404CString Utility::GetBaseFileName(CString sFileName)
405{
406    CString sBase = sFileName;
407    int pos1 = sFileName.ReverseFind('\\');
408    if(pos1>=0)
409        sBase = sBase.Mid(pos1+1);
410
411    int pos2 = sBase.ReverseFind('.');
412    if(pos2>=0)
413    {
414        sBase = sFileName.Mid(0, pos2);
415    }
416    return sBase;
417}
418
419// GetFileExtension
420// This helper function returns file extension by file name
421CString Utility::GetFileExtension(CString sFileName)
422{
423    CString sExt;
424    int pos = sFileName.ReverseFind('.');
425    if(pos>=0)
426    {
427        sExt = sFileName.Mid(pos+1);
428    }
429    return sExt;
430}
431
432CString Utility::GetProductVersion(CString sModuleName)
433{
434    CString sProductVer; 
435
436    DWORD dwBuffSize = GetFileVersionInfoSize(sModuleName, 0);
437    LPBYTE pBuff = (LPBYTE)GlobalAlloc(GPTR, dwBuffSize);  
438
439    if(NULL!=pBuff && 0!=GetFileVersionInfo(sModuleName, 0, dwBuffSize, pBuff))
440    {
441        VS_FIXEDFILEINFO* fi = NULL;
442        UINT uLen = 0;
443        VerQueryValue(pBuff, _T("\\"), (LPVOID*)&fi, &uLen);
444
445        WORD dwVerMajor = HIWORD(fi->dwProductVersionMS);
446        WORD dwVerMinor = LOWORD(fi->dwProductVersionMS);
447        WORD dwPatchLevel = HIWORD(fi->dwProductVersionLS);
448        WORD dwVerBuild = LOWORD(fi->dwProductVersionLS);
449
450        sProductVer.Format(_T("%u.%u.%u.%u"), 
451            dwVerMajor, dwVerMinor, dwPatchLevel, dwVerBuild);    
452    } 
453
454    GlobalFree((HGLOBAL)pBuff);
455
456    return sProductVer;
457}
458
459// Creates a folder. If some intermediate folders in the path do not exist,
460// it creates them.
461BOOL Utility::CreateFolder(CString sFolderName)
462{  
463    CString sIntermediateFolder;
464
465    // Skip disc drive name "X:\" if presents
466    int start = sFolderName.Find(':', 0);
467    if(start>=0)
468        start+=2; 
469
470    int pos = start;  
471    for(;;)
472    {
473        pos = sFolderName.Find('\\', pos);
474        if(pos<0)
475        {
476            sIntermediateFolder = sFolderName;
477        }
478        else
479        {
480            sIntermediateFolder = sFolderName.Left(pos);
481        }
482
483        BOOL bCreate = CreateDirectory(sIntermediateFolder, NULL);
484        if(!bCreate && GetLastError()!=ERROR_ALREADY_EXISTS)
485            return FALSE;
486
487        DWORD dwAttrs = GetFileAttributes(sIntermediateFolder);
488        if((dwAttrs&FILE_ATTRIBUTE_DIRECTORY)==0)
489            return FALSE;
490
491        if(pos==-1)
492            break;
493
494        pos++;
495    }
496
497    return TRUE;
498}
499
500ULONG64 Utility::SystemTimeToULONG64( const SYSTEMTIME& st )
501{
502    FILETIME ft ;
503    SystemTimeToFileTime( &st, &ft ) ;
504    ULARGE_INTEGER integer ;
505    integer.LowPart = ft.dwLowDateTime ;
506    integer.HighPart = ft.dwHighDateTime ;
507    return integer.QuadPart ;
508}
509
510CString Utility::FileSizeToStr(ULONG64 uFileSize)
511{
512    CString sFileSize;
513
514    if(uFileSize==0)
515    {
516        sFileSize = _T("0 KB");
517    }
518    else if(uFileSize<1024)
519    {
520        float fSizeKbytes = (float)uFileSize/(float)1024;
521        TCHAR szStr[64];
522#if _MSC_VER<1400
523        _stprintf(szStr, _T("%0.1f KB"), fSizeKbytes);    
524#else
525        _stprintf_s(szStr, 64, _T("%0.1f KB"), fSizeKbytes);    
526#endif
527        sFileSize = szStr;
528    }
529    else if(uFileSize<1024*1024)
530    {
531        sFileSize.Format(_T("%I64u KB"), uFileSize/1024);
532    }
533    else
534    {
535        float fSizeMbytes = (float)uFileSize/(float)(1024*1024);
536        TCHAR szStr[64];
537#if _MSC_VER<1400
538        _stprintf(szStr, _T("%0.1f MB"), fSizeMbytes);    
539#else
540        _stprintf_s(szStr, 64, _T("%0.1f MB"), fSizeMbytes);    
541#endif
542        sFileSize = szStr;
543    }
544
545    return sFileSize;
546}
547
548CString Utility::AddEllipsis(LPCTSTR szString, int nMaxLength)
549{
550	if(szString==NULL)
551		return CString("");
552
553	CString sResult = szString;
554	if(sResult.GetLength()>nMaxLength)
555	{
556		if(nMaxLength>=3)
557			sResult = sResult.Mid(0, nMaxLength-3)+_T("...");		
558	}
559
560	return sResult;
561}
562
563std::vector<CString> Utility::ExplodeStr(LPCTSTR szString, LPCTSTR szSeparators)
564{
565	std::vector<CString> aTokens;
566
567	CString copy = szString;	
568	TCHAR  *context = 0;
569	TCHAR  *token = _tcstok_s(const_cast<LPTSTR>((LPCTSTR)copy), szSeparators, &context);	
570	while (token != 0) 
571	{
572		aTokens.push_back(token);
573		token=_tcstok_s(NULL, szSeparators, &context);		
574	};
575
576	return aTokens;
577}
578
579long Utility::GetFileSize(const TCHAR *fileName)
580{
581    BOOL                        fOk;
582    WIN32_FILE_ATTRIBUTE_DATA   fileInfo;
583
584    if (NULL == fileName)
585        return -1;
586
587    fOk = GetFileAttributesEx(fileName, GetFileExInfoStandard, (void*)&fileInfo);
588    if (!fOk)
589        return -1;
590    //assert(0 == fileInfo.nFileSizeHigh);
591    return (long)fileInfo.nFileSizeLow;
592}
593
594BOOL Utility::IsFileSearchPattern(CString sFileName)
595{
596	// Remove the "\\?\" prefix in case of a long path name
597	if(sFileName.Left(4).Compare(_T("\\\\?\\"))==0)
598		sFileName = sFileName.Mid(4);
599
600	// Check if the file name is a search template.		
601	BOOL bSearchPattern = FALSE;	
602	int nPos = sFileName.FindOneOf(_T("*?"));
603	if(nPos>=0)
604		bSearchPattern = true;
605	return bSearchPattern;
606}
607