void CAddCopyrightInfoDlg::OnBnClickedSubmit() { if(m_Path.Trim()=="") { MessageBox(_T("请输入路径!")); return; } if(m_Copyright.Trim().GetLength()!=0) { m_Copyright.Append(L"\r\n");//添加换行 } TCHAR pathItem[MAX_PATH]; TCHAR pathProject[MAX_PATH]; wcsncpy_s(pathItem, m_Path.GetBuffer(m_Path.GetLength()), m_Path.GetLength()); wcsncpy_s(pathProject, pathItem, wcslen(pathItem)); wcsncat_s(pathItem,L"\\Common7\\IDE\\ItemTemplatesCache", 31); wcsncat_s(pathProject, L"\\Common7\\IDE\\ProjectTemplatesCache", 34); char* copyright = NULL; copyright = CStringToCharArray(m_Copyright); if(MyFindFile(pathItem, copyright) && MyFindFile(pathProject, copyright)) { MessageBox(L"添加成功"); } if(copyright!=NULL) { delete copyright; copyright = NULL; } UpdateData(); }
static void GetFilePath(PWCHAR filePath, ULONG numberOfElements, LPCWSTR FileName) { wcsncpy_s(filePath, numberOfElements, RootDirectory, wcslen(RootDirectory)); size_t unclen = wcslen(UNCName); if (unclen > 0 && _wcsnicmp(FileName, UNCName, unclen) == 0) { if (_wcsnicmp(FileName + unclen, L".", 1) != 0) { wcsncat_s(filePath, numberOfElements, FileName + unclen, wcslen(FileName) - unclen); } } else { wcsncat_s(filePath, numberOfElements, FileName, wcslen(FileName)); } }
void getJSONInput(HINSTANCE hInstance, wchar_t* json) { // TODO throw exception HRSRC hResInfo = FindResource(hInstance, MAKEINTRESOURCE(IDT_GAME_JSON), L"TEXT"); HGLOBAL hResource = LoadResource(hInstance, hResInfo); char* buff = (char*)LockResource(hResource); int resSize = SizeofResource(hInstance, hResInfo); char tmpFileName[L_tmpnam]; tmpnam(tmpFileName); FILE* tmp = fopen(tmpFileName, "wb"); fwrite(buff, sizeof(char), resSize / sizeof(char), tmp); fclose(tmp); FreeResource(hResource); FILE *fr = fopen(tmpFileName, "rt,ccs=UTF-8"); wchar_t buffer[20000]; json[0] = '\0'; int jsonLength = 0; while (!feof(fr)) { fgetws(buffer, 20000, fr); wcsncat_s(json, 19999, buffer, 20000 - jsonLength); jsonLength += wcslen(buffer); } }
void CreateIpcName() { ZeroMemory(krnlobjsddl, sizeof(krnlobjsddl)); ZeroMemory(mgrpipename, sizeof(mgrpipename)); ZeroMemory(mgrmutexname, sizeof(mgrmutexname)); LPWSTR pszUserSid = nullptr; if(GetUserSid(&pszUserSid)) { // SDDL_ALL_APP_PACKAGES / SDDL_RESTRICTED_CODE / SDDL_LOCAL_SYSTEM / SDDL_BUILTIN_ADMINISTRATORS / User SID _snwprintf_s(krnlobjsddl, _TRUNCATE, L"D:%s(A;;GA;;;RC)(A;;GA;;;SY)(A;;GA;;;BA)(A;;GA;;;%s)", (IsWindowsVersion62OrLater() ? L"(A;;GA;;;AC)" : L""), pszUserSid); // (SDDL_MANDATORY_LABEL, SDDL_NO_WRITE_UP, SDDL_ML_LOW) wcsncat_s(krnlobjsddl, L"S:(ML;;NW;;;LW)", _TRUNCATE); LocalFree(pszUserSid); } LPWSTR pszUserUUID = nullptr; if(GetUserUUID(&pszUserUUID)) { _snwprintf_s(mgrpipename, _TRUNCATE, L"%s%s", IMCRVMGRPIPE, pszUserUUID); _snwprintf_s(mgrmutexname, _TRUNCATE, L"%s%s", IMCRVMGRMUTEX, pszUserUUID); LocalFree(pszUserUUID); } }
void InitLua() { CHAR version[64]; lua = luaL_newstate(); if(lua == nullptr) { return; } luaL_openlibs(lua); luaL_newlib(lua, luaFuncs); lua_setglobal(lua, u8"crvmgr"); //skk-version _snprintf_s(version, _TRUNCATE, "%s", WCTOU8(TEXTSERVICE_NAME L" " TEXTSERVICE_VER)); lua_pushstring(lua, version); lua_setglobal(lua, u8"SKK_VERSION"); //%AppData%\\CorvusSKK\\init.lua if(luaL_dofile(lua, WCTOU8(pathinitlua)) == LUA_OK) { return; } ZeroMemory(pathinitlua, sizeof(pathinitlua)); #ifdef _DEBUG //<module directory>\\init.lua if(GetModuleFileNameW(nullptr, pathinitlua, _countof(pathinitlua)) != 0) { WCHAR *pdir = wcsrchr(pathinitlua, L'\\'); if(pdir != nullptr) { *(pdir + 1) = L'\0'; wcsncat_s(pathinitlua, fninitlua, _TRUNCATE); } } #else PWSTR knownfolderpath = nullptr; //%SystemRoot%\\IME\\IMCRVSKK\\init.lua if(SUCCEEDED(SHGetKnownFolderPath(FOLDERID_Windows, KF_FLAG_DONT_VERIFY, nullptr, &knownfolderpath))) { _snwprintf_s(pathinitlua, _TRUNCATE, L"%s\\%s\\%s\\%s", knownfolderpath, L"IME", TEXTSERVICE_DIR, fninitlua); CoTaskMemFree(knownfolderpath); } #endif if(luaL_dofile(lua, WCTOU8(pathinitlua)) == LUA_OK) { return; } UninitLua(); }
static void GetFilePath( PWCHAR filePath, ULONG numberOfElements, LPCWSTR FileName) { wcsncpy_s(filePath, numberOfElements, RootDirectory, wcslen(RootDirectory)); wcsncat_s(filePath, numberOfElements, FileName, wcslen(FileName)); }
void CreateConfigPath() { WCHAR appdata[MAX_PATH]; pathconfigxml[0] = L'\0'; if(SHGetFolderPathW(NULL, CSIDL_APPDATA | CSIDL_FLAG_DONT_VERIFY, NULL, SHGFP_TYPE_CURRENT, appdata) != S_OK) { appdata[0] = L'\0'; return; } wcsncat_s(appdata, L"\\", _TRUNCATE); wcsncat_s(appdata, TextServiceDesc, _TRUNCATE); wcsncat_s(appdata, L"\\", _TRUNCATE); _wmkdir(appdata); SetCurrentDirectoryW(appdata); _snwprintf_s(pathconfigxml, _TRUNCATE, L"%s%s", appdata, fnconfigxml); LPWSTR pszUserSid; WCHAR szDigest[32+1]; MD5_DIGEST digest; int i; ZeroMemory(cnfmutexname, sizeof(cnfmutexname)); ZeroMemory(szDigest, sizeof(szDigest)); if(GetUserSid(&pszUserSid)) { if(GetMD5(&digest, (CONST BYTE *)pszUserSid, (DWORD)wcslen(pszUserSid)*sizeof(WCHAR))) { for(i=0; i<_countof(digest.digest); i++) { _snwprintf_s(&szDigest[i*2], _countof(szDigest)-i*2, _TRUNCATE, L"%02x", digest.digest[i]); } } LocalFree(pszUserSid); } _snwprintf_s(cnfmutexname, _TRUNCATE, L"%s%s", VIMCNFMUTEX, szDigest); }
void CMeasure::GetScaledValue(AUTOSCALE autoScale, int decimals, double theValue, WCHAR* buffer, size_t sizeInWords) { WCHAR format[32]; double value = 0; if (decimals == 0) { wcsncpy_s(format, L"%.0f", _TRUNCATE); } else { _snwprintf_s(format, _TRUNCATE, L"%%.%if", decimals); } const double* tblScale = g_TblScale[(autoScale == AUTOSCALE_1000 || autoScale == AUTOSCALE_1000K) ? AUTOSCALE_INDEX_1000 : AUTOSCALE_INDEX_1024]; if (theValue >= tblScale[0]) { value = theValue / tblScale[0]; wcsncat_s(format, L" T", _TRUNCATE); } else if (theValue >= tblScale[1]) { value = theValue / tblScale[1]; wcsncat_s(format, L" G", _TRUNCATE); } else if (theValue >= tblScale[2]) { value = theValue / tblScale[2]; wcsncat_s(format, L" M", _TRUNCATE); } else if (autoScale == AUTOSCALE_1024K || autoScale == AUTOSCALE_1000K || theValue >= tblScale[3]) { value = theValue / tblScale[3]; wcsncat_s(format, L" k", _TRUNCATE); } else { value = theValue; wcsncat_s(format, L" ", _TRUNCATE); } _snwprintf_s(buffer, sizeInWords, _TRUNCATE, format, value); }
static void GetFilePath( PWCHAR filePath, ULONG numberOfElements, LPCWSTR FileName) { filePath[0] = 0; wcsncpy_s(filePath, numberOfElements, RootDirectory, wcslen(RootDirectory)); wcsncat_s(filePath, numberOfElements, FileName, wcslen(FileName)); RtlZeroMemory(filePath+ wcslen(filePath), (numberOfElements-wcslen(filePath)) * sizeof(WCHAR)); }
MIR_CORE_DLL(wchar_t*) mir_wstrncat(wchar_t *dest, const wchar_t *src, size_t len) { if (dest == NULL) return NULL; if (src == NULL) *dest = 0; else wcsncat_s(dest, len, src, _TRUNCATE); return dest; }
// strapp - Appends the specified source string to the specified destination // string. Allocates additional space so that the destination string "grows" // as new strings are appended to it. This function is fairly infrequently // used so efficiency is not a major concern. // // - dest (IN/OUT): Address of the destination string. Receives the resulting // combined string after the append operation. // // - source (IN): Source string to be appended to the destination string. // // Return Value: // // None. // VOID strapp (LPWSTR *dest, LPCWSTR source) { SIZE_T length; LPWSTR temp; temp = *dest; length = wcslen(*dest) + wcslen(source); *dest = new WCHAR [length + 1]; wcsncpy_s(*dest, length + 1, temp, _TRUNCATE); wcsncat_s(*dest, length + 1, source, _TRUNCATE); delete [] temp; }
// // Install our DLL in Lightroom's address space // bool CLightroom::LoadDll() { bool isSuccess = false; // Bail out right away if the DLL is already loaded if( getRemoteDllBase() && pRemoteDllBase != 0 ) return calculateRemoteEntryPoint(); // Build an absolute path to LrMouseWheel.dll size_t cchPath = wcslen( wszPath ); WCHAR wszFullPath[ MAX_PATH * 2 ]; wcsncpy_s( wszFullPath, wszPath, cchPath + 1 ); if( cchPath > 0 ) wcsncat_s( wszFullPath, L"\\", 1 ); wcsncat_s( wszFullPath, wszLrMouseWheelDll, _TRUNCATE ); // Copy the filename into the remote process DWORD cbDllFilename = ( wcslen( wszFullPath ) + 1 ) * sizeof( WCHAR ); LPVOID pRemoteDllFilename = VirtualAllocEx( hProcess, NULL, cbDllFilename, MEM_COMMIT, PAGE_READWRITE ); if( WriteProcessMemory( hProcess, pRemoteDllFilename, wszFullPath, cbDllFilename, NULL ) ) { // Cause the DLL to be loaded into the remote process PTHREAD_START_ROUTINE pEntryPoint = ( PTHREAD_START_ROUTINE )GetProcAddress( GetModuleHandleW( L"kernel32.dll" ), "LoadLibraryW" ); HANDLE hRemoteThread = CreateRemoteThread( hProcess, NULL, 0, pEntryPoint, pRemoteDllFilename, 0, NULL ); if( hRemoteThread ) { WaitForSingleObject( hRemoteThread, INFINITE ); // Find out where the DLL was loaded isSuccess = ( GetExitCodeThread( hRemoteThread, &pRemoteDllBase ) != 0 ) && pRemoteDllBase != 0; // Clean up CloseHandle( hRemoteThread ); } } VirtualFreeEx( hProcess, pRemoteDllFilename, 0, MEM_RELEASE ); return isSuccess && calculateRemoteEntryPoint(); }
void CreateConfigPath() { WCHAR appdata[MAX_PATH]; pathconfigxml[0] = L'\0'; pathskkdic[0] = L'\0'; pathskkidx[0] = L'\0'; if(SHGetFolderPathW(NULL, CSIDL_APPDATA | CSIDL_FLAG_DONT_VERIFY, NULL, SHGFP_TYPE_CURRENT, appdata) != S_OK) { appdata[0] = L'\0'; return; } wcsncat_s(appdata, L"\\", _TRUNCATE); wcsncat_s(appdata, TextServiceDesc, _TRUNCATE); wcsncat_s(appdata, L"\\", _TRUNCATE); _wmkdir(appdata); SetCurrentDirectoryW(appdata); _snwprintf_s(pathconfigxml, _TRUNCATE, L"%s%s", appdata, fnconfigxml); _snwprintf_s(pathskkdic, _TRUNCATE, L"%s%s", appdata, fnskkdic); _snwprintf_s(pathskkidx, _TRUNCATE, L"%s%s", appdata, fnskkidx); ZeroMemory(cnfmutexname, sizeof(cnfmutexname)); LPWSTR pszDigest = NULL; if(GetSidMD5Digest(&pszDigest)) { _snwprintf_s(cnfmutexname, _TRUNCATE, L"%s%s", CORVUSCNFMUTEX, pszDigest); LocalFree(pszDigest); } }
HRESULT XmlFileParser::ElementContent( const WCHAR* strData, UINT DataLen, BOOL More ) { // Accumulate this element content into the current desc body content. wcsncat_s( m_CurrentElementDesc.strElementBody, strData, DataLen ); if(m_nType == 1 && localFind && _wcsicmp(m_CurrentElementDesc.strElementName,L"Description") == 0) { memset(pArcadeInfo->strDescription,0,1024); wcsncpy_s( pArcadeInfo->strDescription,m_CurrentElementDesc.strElementBody,wcslen(m_CurrentElementDesc.strElementBody) ); localFind = false; } return S_OK; }
BOOL CAddCopyrightInfoDlg::MyFindFile(TCHAR* path, char* copyright) { WIN32_FIND_DATA findFileData; TCHAR szFind[MAX_PATH] = {0}; TCHAR szFindTemp[MAX_PATH] = {0}; wcsncpy_s(szFind,path,wcslen(path)); wcsncat_s(szFind,L"\\*.*",4); HANDLE h = FindFirstFile(szFind, &findFileData); if(INVALID_HANDLE_VALUE==h) { MessageBox(_T("请检查路径是否正确")); return FALSE; } while(true) { if(findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { if(findFileData.cFileName[0]!='.') { wcsncpy_s(szFindTemp,path,wcslen(path)); wcsncat_s(szFindTemp,L"\\",1); wcsncat_s(szFindTemp,findFileData.cFileName,sizeof(findFileData.cFileName)); MyFindFile(szFindTemp, copyright); } } else { TCHAR exName[_MAX_EXT]; _wsplitpath(findFileData.cFileName, NULL, NULL, NULL, exName); if(wcscmp(exName,_T(".cs"))==0)//只有是.cs文件的才写 { TCHAR filePath[MAX_PATH]; wcsncpy_s(filePath,path,wcslen(path)); wcsncat_s(filePath,L"\\",1); wcsncat_s(filePath,findFileData.cFileName,sizeof(findFileData.cFileName)); TCHAR fileName[MAX_PATH]; wcsncpy_s(fileName, filePath, wcslen(filePath)-3);//去除.cs wcsncat_s(fileName,L".bak",4); CopyFile(filePath,fileName,TRUE);//备份文件 WriteCopyright(filePath, fileName, copyright);//写版权信息 } } if(!FindNextFile(h,&findFileData)) break; } FindClose(h); return TRUE; }
void formatStringTags(const char* fmt, TCHAR* pOut, int outLen, stringTagCallback pCallback, StringTagContext* pContext) { static TCHAR widebuf[256]; int numTagsFound = 0; swprintf_s(widebuf, L"%S", fmt); TCHAR* iter = widebuf; for (;;) { TCHAR* tagStart = wcschr(iter, '{'); if (!tagStart) { tagStart = wcschr(iter, '['); if (!tagStart) break;//didn't find a tag } pContext->bracketChar = *tagStart; numTagsFound++; wcsncat_s(pOut, outLen, iter, tagStart-iter); TCHAR* tagEnd = wcschr(tagStart, '}'); if (!tagEnd) tagEnd = wcschr(tagStart, ']'); TCHAR buf[16] = {0}; TCHAR temp = *tagEnd; *tagEnd = '\0'; if (!commonTagCallback(tagStart+1, buf, pContext) && pCallback) pCallback(tagStart+1, buf, pContext); wcscat_s(pOut, outLen, buf); *tagEnd = temp; iter = tagEnd+1; } if (numTagsFound) { wcscat_s(pOut, outLen, iter); } else { wcscpy_s(pOut, outLen, widebuf); } }
int _tmain(int argc, _TCHAR* argv[]) { // Bind to the runtime. ICLRRuntimeHost *pClrHost = NULL; HRESULT hrCorBind = CorBindToRuntimeEx( NULL, // Load the latest CLR version available L"wks", // Workstation GC ("wks" or "svr" overrides) 0, // No flags needed CLSID_CLRRuntimeHost, IID_ICLRRuntimeHost, (PVOID*)&pClrHost); CheckFail(hrCorBind, "Bind to runtime failed (0x%x)"); // Construct our host control object. DHHostControl *pHostControl = new DHHostControl(pClrHost); if (!pHostControl) Fail("Host control allocation failed"); pClrHost->SetHostControl(pHostControl); // Now, begin the CLR. HRESULT hrStart = pClrHost->Start(); if (hrStart == S_FALSE) _ASSERTE(!L"Runtime already started; probably OK to proceed"); else CheckFail(hrStart, "Runtime startup failed (0x%x)"); // Construct the shim path (i.e. shim.exe). WCHAR wcShimPath[MAX_PATH]; if (!GetCurrentDirectoryW(MAX_PATH, wcShimPath)) CheckFail(HRESULT_FROM_WIN32(GetLastError()), "GetCurrentDirectory failed (0x%x)"); wcsncat_s(wcShimPath, sizeof(wcShimPath) / sizeof(WCHAR), L"\\shim.exe", MAX_PATH - wcslen(wcShimPath) - 1); // Gather the arguments to pass to the shim. LPWSTR wcShimArgs = NULL; if (argc > 1) { SIZE_T totalLength = 1; // 1 is the NULL terminator for(int i = 1; i < argc; i++) { // TODO: add characters for quotes around args w/ spaces inside them if (i != 1) totalLength++; // add a space between args totalLength += _tcslen(argv[i]) + 1; } wcShimArgs = new WCHAR[totalLength]; wcShimArgs[0] = '\0'; for(int i = 1; i < argc; i++) { if (i != 1) wcscat_s(wcShimArgs, totalLength, L" "); wcsncat_s(wcShimArgs, totalLength, argv[i], wcslen(argv[i])); } } if (wcShimArgs == NULL) Fail("Missing program path (host.exe <exePath>)\r\n"); // And execute the program... DWORD retVal; HRESULT hrExecute = pClrHost->ExecuteInDefaultAppDomain( wcShimPath, L"Shim", L"Start", wcShimArgs, &retVal); CheckFail(hrExecute, "Execution of shim failed (0x%x)\r\n"); if (wcShimArgs) delete wcShimArgs; // Stop the CLR and cleanup. pHostControl->ShuttingDown(); pClrHost->Stop(); pClrHost->Release(); return retVal; }
void TestMove_s( void ) { wchar_t buf[128]; wchar_t s2[] = L"VALUE"; wchar_t str[] = L"VALUE"; wchar_t src1[100] = L"hello"; wchar_t src2[7] = L"goodbye"; wchar_t dst1[6], dst2[5], dst3[5]; wchar_t sc1[100] = L"good"; wchar_t sc2[6] = L"hello"; wchar_t sc3[6] = L"hello"; wchar_t sc4[7] = L"abc"; wchar_t sc5[1000] = L"bye"; int violations = NumViolations; /* wcstok_s */ static wchar_t str1[] = L"?a???b,,,#c"; static wchar_t str2[] = L"\t \t"; static wchar_t str3[] = L"?a???b,,,#c"; wchar_t *t, *ptr1, *ptr2, *ptr3; rsize_t max1 = ARRAYCOUNT( str1 ); rsize_t max2 = ARRAYCOUNT( str2 ); rsize_t max3 = ARRAYCOUNT( str3 ); /***********************************************************************/ /* set constraint-handler */ /***********************************************************************/ set_constraint_handler_s( my_constraint_handler ); /***********************************************************************/ /* memcpy_s */ /***********************************************************************/ // printf( "Test memcpys (%s).\n", ProgramName ); /* Test the "good" case */ VERIFY( wmemcpy_s( buf, ARRAYCOUNT( buf ), s2, 0 ) == 0 ); VERIFY( wmemcpy_s( buf, ARRAYCOUNT( buf ), s2, 1 + wcslen( s2 ) ) == 0 ); VERIFY( wmemcpy_s( buf, wcslen( s2 ) + 2, s2, 1 + wcslen( s2 ) ) == 0 ); VERIFY( wcslen( buf ) == wcslen( L"VALUE" ) ); VERIFY( wcscmp( buf, L"VALUE" ) == 0 ); VERIFY( NumViolations == violations ); /* Test various failing cases */ /* Test runtime-constraint violations */ VERIFY( wmemcpy_s( buf, 3, s2, wcslen( s2 ) ) != 0 ); VERIFY( buf[0] == L'\0' ); VERIFY( NumViolations == ++violations ); VERIFY( wmemcpy_s( NULL, ARRAYCOUNT( buf ), s2, wcslen( s2 ) ) != 0 ); VERIFY( NumViolations == ++violations ); VERIFY( wmemcpy_s( buf, ARRAYCOUNT( buf ), NULL, wcslen( s2 ) ) != 0 ); VERIFY( NumViolations == ++violations ); VERIFY( wmemcpy_s( buf, ARRAYCOUNT( buf ), s2, sizeof( buf ) / sizeof( buf[0] )+ 1 ) != 0 ); VERIFY( NumViolations == ++violations ); VERIFY( wmemcpy_s( buf, ARRAYCOUNT( buf ), buf + 1, wcslen( s2 ) ) != 0 ); VERIFY( NumViolations == ++violations ); #if RSIZE_MAX != SIZE_MAX VERIFY( wmemcpy_s( buf, ARRAYCOUNT( buf ), s2, ~0 ) != 0 ); VERIFY( NumViolations == ++violations ); #endif /***********************************************************************/ /* memmove_s */ /***********************************************************************/ // printf( "Test memmove (%s).\n", ProgramName ); /* Test the "good" cases */ VERIFY( wmemmove_s( buf, ARRAYCOUNT( buf ), s2, 0 ) == 0 ); VERIFY( wmemmove_s( buf, ARRAYCOUNT( buf ), s2, 1 + wcslen( s2 ) ) == 0 ); VERIFY( wmemmove_s( buf, ARRAYCOUNT( buf ), buf + 1, 1 + wcslen( s2 ) ) == 0 ); VERIFY( wmemmove_s( buf, 1 + wcslen( s2 ), s2, 1 + wcslen( s2 ) ) == 0 ); VERIFY( wcslen( buf ) == wcslen( L"VALUE" ) ); VERIFY( wcscmp( buf, L"VALUE" ) == 0 ); VERIFY( NumViolations == violations ); /* Test various failing cases */ /* Test runtime-constraint violations */ VERIFY( wmemmove_s( buf, 3, s2, wcslen( s2 ) ) != 0 ); VERIFY( buf[0] == L'\0' ); VERIFY( NumViolations == ++violations ); VERIFY( wmemmove_s( NULL, ARRAYCOUNT( buf ), s2, wcslen( s2 ) ) != 0 ); VERIFY( NumViolations == ++violations ); VERIFY( wmemmove_s( buf, ARRAYCOUNT( buf ), NULL, wcslen( s2 ) ) != 0 ); VERIFY( NumViolations == ++violations ); VERIFY( wmemmove_s( buf, ARRAYCOUNT( buf ), s2, ARRAYCOUNT( buf ) + 1 ) != 0 ); VERIFY( NumViolations == ++violations ); #if RSIZE_MAX != SIZE_MAX VERIFY( wmemmove_s( buf, ~0, s2, wcslen( s2 ) ) != 0 ); VERIFY( NumViolations == ++violations ); VERIFY( wmemmove_s( buf, ARRAYCOUNT( buf ), s2, ~0 ) != 0 ); VERIFY( NumViolations == ++violations ); #endif /***********************************************************************/ /* wcscpy_s */ /***********************************************************************/ // printf( "Test memcpy (%s).\n", ProgramName ); /* Test the "good" cases */ VERIFY( wcscpy_s( buf, ARRAYCOUNT( buf ), s2 ) == 0 ); VERIFY( wcscpy_s( buf, ARRAYCOUNT( buf ), s2 ) == 0 ); VERIFY( wcscpy_s( buf, wcslen( s2 ) + 1, s2 ) == 0 ); VERIFY( wcslen( buf ) == wcslen( L"VALUE" ) ); VERIFY( wcscmp( buf, L"VALUE" ) == 0 ); VERIFY( NumViolations == violations ); /* Test various failing cases */ /* Test runtime-constraint violations */ VERIFY( wcscpy_s( buf, 3, s2 ) != 0 ); VERIFY( NumViolations == ++violations ); VERIFY( buf[0] == L'\0' ); VERIFY( wcscpy_s( NULL, ARRAYCOUNT( buf ), s2 ) != 0 ); VERIFY( NumViolations == ++violations ); VERIFY( wcscpy_s( buf, ARRAYCOUNT( buf ), NULL ) != 0 ); VERIFY( NumViolations == ++violations ); VERIFY( wcscpy_s( buf, 5, s2 ) != 0 ); VERIFY( NumViolations == ++violations ); VERIFY( wcscpy_s( buf, ARRAYCOUNT( buf ), buf + 1 ) != 0 ); VERIFY( NumViolations == ++violations ); #if RSIZE_MAX != SIZE_MAX VERIFY( wcscpy_s( buf, ~0, s2 ) != 0 ); VERIFY( NumViolations == ++violations ); #endif /***********************************************************************/ /* wcscat_s */ /***********************************************************************/ // printf( "Test wcscat (%s).\n", ProgramName ); wcscpy( sc1,src1 ); VERIFY( wcscmp( sc1,src1 ) == 0 ); VERIFY( wcscat_s( sc1, 100, sc5 ) == 0 ); VERIFY( wcscmp( sc1, L"hellobye") == 0 ); VERIFY( wcscat_s( sc2, 6, L"" ) == 0 ); VERIFY( wcscat_s( sc3, 6, L"X" ) != 0 ); VERIFY( NumViolations == ++violations ); VERIFY( sc3[0] == L'\0'); VERIFY( wcscat_s(sc4, 7, L"defghijklmn") != 0); VERIFY( NumViolations == ++violations ); VERIFY( wcscmp(sc4, L"" ) == 0); /***********************************************************************/ /* wcsnlen_s */ /***********************************************************************/ // printf( "Test wcsnlen (%s).\n", ProgramName ); /* Test the "good" case */ VERIFY( wcsnlen_s( str, ARRAYCOUNT( str ) ) == wcslen( str ) ); VERIFY( wcsnlen_s( str, 4 ) == 4 ); VERIFY( wcsnlen_s( str, 0 ) == 0 ); VERIFY( wcsnlen_s( NULL, 1000 ) == 0 ); /* Test various failing cases */ /* No runtime-constraint violations to test */ VERIFY( NumViolations == violations ); /***********************************************************************/ /* wcsncpy_s */ /***********************************************************************/ // printf( "Test wcsncpy (%s).\n", ProgramName ); /* Test the "good" case */ VERIFY( wcsncpy_s( buf, ARRAYCOUNT( buf ), s2, 0 ) == 0 ); VERIFY( wcsncpy_s( buf, ARRAYCOUNT( buf ), s2, wcslen( s2 ) ) == 0 ); VERIFY( wcsncpy_s( buf, wcslen( s2 ) + 1, s2, wcslen( s2 ) ) == 0 ); VERIFY( wcslen( buf ) == wcslen( L"VALUE" ) ); VERIFY( wcscmp( buf, L"VALUE" ) == 0 ); VERIFY( NumViolations == violations ); VERIFY( wcsncpy_s( dst1, 6, src1, 100 ) == 0 ); VERIFY( wcscmp( dst1, src1 ) == 0 ); VERIFY( wcsncpy_s( dst3, 5, src2, 4 ) == 0 ); /* Test various failing cases */ /* Test runtime-constraint violations */ VERIFY( wcsncpy_s( buf, 3, s2, wcslen( s2 ) ) != 0 ); VERIFY( NumViolations == ++violations ); VERIFY( buf[0] == '\0' ); VERIFY( wcsncpy_s( NULL, ARRAYCOUNT( buf ), s2, wcslen( s2 ) ) != 0 ); VERIFY( NumViolations == ++violations ); VERIFY( wcsncpy_s( buf, ARRAYCOUNT( buf ), NULL, wcslen( s2 ) ) != 0 ); VERIFY( NumViolations == ++violations ); VERIFY( wcsncpy_s( buf, ARRAYCOUNT( buf ), buf + 1, wcslen( s2 ) ) != 0 ); VERIFY( NumViolations == ++violations ); VERIFY( wcsncpy_s( dst2, 5, src2, 7 ) != 0 ); VERIFY( NumViolations == ++violations ); #if RSIZE_MAX != SIZE_MAX VERIFY( wcsncpy_s( buf, ~0, s2, wcslen( s2 ) ) != 0 ); VERIFY( NumViolations == ++violations ); VERIFY( wcsncpy_s( buf, ARRAYCOUNT( buf ), s2, ~0 ) != 0 ); VERIFY( NumViolations == ++violations ); #endif /***********************************************************************/ /* wcsncat_s */ /***********************************************************************/ // printf( "Test wcsncat (%s).\n", ProgramName ); wcscpy( sc1, L"good" ); wcscpy( sc2, L"hello" ); wcscpy( sc3, L"hello" ); wcscpy( sc4, L"abc" ); VERIFY( wcsncat_s( sc1, 100, sc5, 1000 ) == 0); VERIFY( wcscmp( sc1, L"goodbye" ) == 0 ); VERIFY( wcsncat_s( sc2, 6, L"", 1 ) == 0 ); VERIFY( wcsncat_s( sc4, 7, L"defghijklmn", 3 ) == 0 ); VERIFY( wcscmp( sc4, L"abcdef" ) == 0 ); /* Test runtime-constraint violations */ VERIFY( wcsncat_s( sc3, 6, L"XXX", 3 ) != 0 ); VERIFY( NumViolations == ++violations ); VERIFY( sc3[0] == L'\0'); /***********************************************************************/ /* wcstok_s */ /***********************************************************************/ // printf( "Test wcstok (%s).\n", ProgramName ); VERIFY( (t = wcstok_s( str1, &max1, L"?", &ptr1 )) != NULL ); /* points to the token "a" */ VERIFY( wcscmp( t, L"a" ) == 0 ); VERIFY( (t = wcstok_s( NULL, &max1, L",", &ptr1 )) != NULL ); /* points to the token "??b" */ VERIFY( wcscmp( t, L"??b" ) == 0 ); VERIFY( NULL == wcstok_s( str2, &max2, L" \t", &ptr2 ) ); /* null pointer */ VERIFY( NumViolations == violations ); VERIFY( (t = wcstok_s( NULL, &max1, L"#,", &ptr1 )) != NULL ); /* points to the token "c" */ VERIFY( wcscmp( t, L"c" ) == 0 ); VERIFY( ptr1 != NULL ); VERIFY( NumViolations == violations ); VERIFY( NULL == wcstok_s( NULL, &max1, L"#,", &ptr1 ) ); /* at the end */ wcscpy( str1, str3 ); max1 = ARRAYCOUNT( str1 ); VERIFY( NULL == wcstok_s( str1, &max1, str3, &ptr3 ) ); /* only delimiter chars */ // printf( "Test wcstok rtc (%s).\n", ProgramName ); /* Test runtime-constraint violations */ ptr1 = NULL; VERIFY( NULL == wcstok_s( NULL, &max1, L"?", &ptr1 ) ); /* null pointer */ VERIFY( NumViolations == ++violations ); VERIFY( NULL == wcstok_s( str3, NULL, L"?", &ptr1 ) ); VERIFY( NumViolations == ++violations ); VERIFY( NULL == wcstok_s( str3, &max3, NULL, &ptr1 ) ); VERIFY( NumViolations == ++violations ); VERIFY( NULL == wcstok_s( str3, &max3, L"?", NULL ) ); VERIFY( NumViolations == ++violations ); ptr3 = NULL; VERIFY( NULL == wcstok_s( NULL, &max3, L"?", &ptr3 ) ); VERIFY( NumViolations == ++violations ); #if RSIZE_MAX != SIZE_MAX max1 = ~0; VERIFY( NULL == wcstok_s( str3, &max1, L"?", &ptr1 ) ); VERIFY( NumViolations == ++violations ); #endif }
int _tmain(int argc, _TCHAR* argv[]) { char bufOut[CMD_SIZE] = {0}; TCHAR bufCmd[CMD_SIZE] = {0}; TCHAR *intext = NULL; if(argc == 1) wcsncat_s(bufCmd, L"qrcode.exe -h", CMD_SIZE); else wcsncat_s(bufCmd, L"qrcode.exe", CMD_SIZE); int i; for(i = 1; i < argc; i++) { if(!IsOption(argv[i])) break; wcsncat_s(bufCmd, L" ", CMD_SIZE); wcsncat_s(bufCmd, argv[i], CMD_SIZE); if(IsOptionWithParameter(argv[i]) && (i + 1 < argc)) { i++; wcsncat_s(bufCmd, L" ", CMD_SIZE); wcsncat_s(bufCmd, argv[i], CMD_SIZE); } } if(i < argc) { wcsncat_s(bufCmd, L" \"", CMD_SIZE); wcsncat_s(bufCmd, argv[i], CMD_SIZE); wcsncat_s(bufCmd, L"\"", CMD_SIZE); } else { intext = readStdin(); wcsncat_s(bufCmd, L" \"", CMD_SIZE); wcsncat_s(bufCmd, intext, CMD_SIZE); wcsncat_s(bufCmd, L"\"", CMD_SIZE); } DWORD len = ::WideCharToMultiByte(CP_UTF8, 0, bufCmd, wcslen(bufCmd), bufOut, CMD_SIZE, NULL, NULL); STARTUPINFOA si; PROCESS_INFORMATION pi; ZeroMemory( &si, sizeof(si) ); si.cb = sizeof(si); ZeroMemory( &pi, sizeof(pi) ); // Start the child process. if( !CreateProcessA( NULL, // No module name (use command line) bufOut, // Command line NULL, // Process handle not inheritable NULL, // Thread handle not inheritable TRUE, // Set handle inheritance to FALSE 0, NULL, // Use parent's environment block NULL, // Use parent's starting directory &si, // Pointer to STARTUPINFO structure &pi ) // Pointer to PROCESS_INFORMATION structure ) { return FALSE; } // Wait until child process exits. WaitForSingleObject( pi.hProcess, INFINITE ); // Close process and thread handles. CloseHandle( pi.hProcess ); CloseHandle( pi.hThread ); return 0; }
void SetLogPathName() { // NOTE: under PAL, we don't get the comand line, so we depend on the random number generator to give us a unique // filename. WCHAR* OriginalExecutableName = GetCommandLineW(); // TODO-Cleanup: not cool to write to the process view of commandline.... size_t len = wcslen(OriginalExecutableName); WCHAR* ExecutableName = new WCHAR[len + 1]; wcscpy_s(ExecutableName, len + 1, OriginalExecutableName); ExecutableName[len] = W('\0'); WCHAR* quote1 = NULL; // if there are any quotes in filename convert them to spaces. while ((quote1 = wcsstr(ExecutableName, W("\""))) != NULL) *quote1 = W(' '); // remove any illegal or annoying characters from file name by converting them to underscores while ((quote1 = wcspbrk(ExecutableName, W("=<>:\"/\\|?! *.,"))) != NULL) *quote1 = W('_'); const WCHAR* DataFileExtension = W(".mc"); size_t ExecutableNameLength = wcslen(ExecutableName); size_t DataFileExtensionLength = wcslen(DataFileExtension); size_t logPathLength = wcslen(g_logPath); size_t dataFileNameLength = logPathLength + 1 + ExecutableNameLength + 1 + DataFileExtensionLength + 1; const size_t MaxAcceptablePathLength = MAX_PATH - 20; // subtract 20 to leave buffer, for possible random number addition if (dataFileNameLength >= MaxAcceptablePathLength) { // The path name is too long; creating the file will fail. This can happen because we use the command line, // which for ngen includes lots of environment variables, for example. // Assume (!) the extra space is all in the ExecutableName, so shorten that. ExecutableNameLength -= dataFileNameLength - MaxAcceptablePathLength; dataFileNameLength = MaxAcceptablePathLength; } // Always add a random number, just in case the above doesn't give us a unique filename. #ifdef FEATURE_PAL unsigned __int64 randNumber = 0; const size_t RandNumberLength = sizeof(randNumber) * 2 + 1; // 16 hex digits + null WCHAR RandNumberString[RandNumberLength]; PAL_Random(&randNumber, sizeof(randNumber)); swprintf_s(RandNumberString, RandNumberLength, W("%016llX"), randNumber); #else // !FEATURE_PAL unsigned int randNumber = 0; const size_t RandNumberLength = sizeof(randNumber) * 2 + 1; // 8 hex digits + null WCHAR RandNumberString[RandNumberLength]; rand_s(&randNumber); swprintf_s(RandNumberString, RandNumberLength, W("%08X"), randNumber); #endif // !FEATURE_PAL dataFileNameLength += RandNumberLength - 1; // Construct the full pathname we're going to use. g_dataFileName = new WCHAR[dataFileNameLength]; g_dataFileName[0] = 0; wcsncat_s(g_dataFileName, dataFileNameLength, g_logPath, logPathLength); wcsncat_s(g_dataFileName, dataFileNameLength, DIRECTORY_SEPARATOR_STR_W, 1); wcsncat_s(g_dataFileName, dataFileNameLength, ExecutableName, ExecutableNameLength); if (RandNumberLength > 0) { wcsncat_s(g_dataFileName, dataFileNameLength, RandNumberString, RandNumberLength); } wcsncat_s(g_dataFileName, dataFileNameLength, DataFileExtension, DataFileExtensionLength); }
// Resolve - Creates a nicely formatted rendition of the CallStack, including // symbolic information (function names and line numbers) if available. and // saves it for later retrieval. This is almost identical to Callstack::dump above. // // Note: The symbol handler must be initialized prior to calling this // function. // // - showInternalFrames (IN): If true, then all frames in the CallStack will be // dumped. Otherwise, frames internal to the heap will not be dumped. // // Return Value: // // None. // void CallStack::resolve(BOOL showInternalFrames) { if (m_resolved) { // already resolved, no need to do it again // resolving twice may report an incorrect module for the stack frames // if the memory was leaked in a dynamic library that was already unloaded. return; } if (m_status & CALLSTACK_STATUS_INCOMPLETE) { // This call stack appears to be incomplete. Using StackWalk64 may be // more reliable. Report(L" HINT: The following call stack may be incomplete. Setting \"StackWalkMethod\"\n" L" in the vld.ini file to \"safe\" instead of \"fast\" may result in a more\n" L" complete stack trace.\n"); } IMAGEHLP_LINE64 sourceInfo = { 0 }; sourceInfo.SizeOfStruct = sizeof(IMAGEHLP_LINE64); BYTE symbolBuffer [sizeof(SYMBOL_INFO) + MAX_SYMBOL_NAME_SIZE] = { 0 }; WCHAR callingModuleName [MAX_PATH] = L""; WCHAR lowerCaseName [MAX_PATH]; const size_t max_line_length = MAXREPORTLENGTH + 1; m_resolvedCapacity = m_size * max_line_length; m_resolved = new WCHAR[m_resolvedCapacity]; const size_t allocedBytes = m_resolvedCapacity * sizeof(WCHAR); ZeroMemory(m_resolved, allocedBytes); // Iterate through each frame in the call stack. for (UINT32 frame = 0; frame < m_size; frame++) { // Try to get the source file and line number associated with // this program counter address. SIZE_T programCounter = (*this)[frame]; g_symbolLock.Enter(); BOOL foundline = FALSE; DWORD displacement = 0; // It turns out that calls to SymGetLineFromAddrW64 may free the very memory we are scrutinizing here // in this method. If this is the case, m_Resolved will be null after SymGetLineFromAddrW64 returns. // When that happens there is nothing we can do except crash. DbgTrace(L"dbghelp32.dll %i: SymGetLineFromAddrW64\n", GetCurrentThreadId()); foundline = SymGetLineFromAddrW64(g_currentProcess, programCounter, &displacement, &sourceInfo); assert(m_resolved != NULL); if (foundline && !showInternalFrames) { wcscpy_s(lowerCaseName, sourceInfo.FileName); _wcslwr_s(lowerCaseName, wcslen(lowerCaseName) + 1); if (isInternalModule(lowerCaseName)) { // Don't show frames in files internal to the heap. g_symbolLock.Leave(); continue; } } // Initialize structures passed to the symbol handler. SYMBOL_INFO* functionInfo = (SYMBOL_INFO*)&symbolBuffer; functionInfo->SizeOfStruct = sizeof(SYMBOL_INFO); functionInfo->MaxNameLen = MAX_SYMBOL_NAME_LENGTH; // Try to get the name of the function containing this program // counter address. DWORD64 displacement64 = 0; LPWSTR functionName; DbgTrace(L"dbghelp32.dll %i: SymFromAddrW\n", GetCurrentThreadId()); if (SymFromAddrW(g_currentProcess, programCounter, &displacement64, functionInfo)) { functionName = functionInfo->Name; } else { // GetFormattedMessage( GetLastError() ); functionName = L"(Function name unavailable)"; displacement64 = 0; } g_symbolLock.Leave(); HMODULE hCallingModule = GetCallingModule(programCounter); LPWSTR moduleName = L"(Module name unavailable)"; if (hCallingModule && GetModuleFileName(hCallingModule, callingModuleName, _countof(callingModuleName)) > 0) { moduleName = wcsrchr(callingModuleName, L'\\'); if (moduleName == NULL) moduleName = wcsrchr(callingModuleName, L'/'); if (moduleName != NULL) moduleName++; else moduleName = callingModuleName; } // Use static here to increase performance, and avoid heap allocs. Hopefully this won't // prove to be an issue in thread safety. If it does, it will have to be simply non-static. static WCHAR stack_line[max_line_length] = L""; int NumChars = -1; // Display the current stack frame's information. if (foundline) { // Just truncate anything that is too long. if (displacement == 0) NumChars = _snwprintf_s(stack_line, max_line_length, _TRUNCATE, L" %s (%d): %s!%s\n", sourceInfo.FileName, sourceInfo.LineNumber, moduleName, functionName); else NumChars = _snwprintf_s(stack_line, max_line_length, _TRUNCATE, L" %s (%d): %s!%s + 0x%X bytes\n", sourceInfo.FileName, sourceInfo.LineNumber, moduleName, functionName, displacement); } else { if (displacement64 == 0) NumChars = _snwprintf_s(stack_line, max_line_length, _TRUNCATE, L" " ADDRESSFORMAT L" (File and line number not available): %s!%s\n", programCounter, moduleName, functionName); else NumChars = _snwprintf_s(stack_line, max_line_length, _TRUNCATE, L" " ADDRESSFORMAT L" (File and line number not available): %s!%s + 0x%X bytes\n", programCounter, moduleName, functionName, (DWORD)displacement64); } if (NumChars >= 0) { assert(m_resolved != NULL); m_resolvedLength += NumChars; wcsncat_s(m_resolved, m_resolvedCapacity, stack_line, NumChars); } } // end for loop }
int _tmain(int argc, _TCHAR* argv[]) { TCHAR szPath[MAX_PATH] = { 0, }; DWORD dwSize = GetModuleFileName(NULL, szPath, MAX_PATH); TCHAR * pdest = _tcsrchr(szPath, '\\'); _tcsncpy_s(gServicePath, sizeof(gServicePath) / sizeof(TCHAR), szPath, (size_t)(pdest - szPath)); if (argc < 2) { ExecuteSubProcess(); return 0; } if (_tcsicmp(L"/i", argv[1]) == 0) return Install(szPath, ServiceName); else if (_tcsicmp(L"/k", argv[1]) == 0) return KillService(ServiceName); else if (_tcsicmp(L"/u", argv[1]) == 0) return UnInstall(ServiceName); else if (_tcsicmp(L"/s", argv[1]) == 0) return RunService(ServiceName); else if (_tcsicmp(L"/t", argv[1]) == 0) { DWORD dwPID; WCHAR *szServicePath; WCHAR *cmd = L"drbdadm.exe initial-split-brain minor-6"; WCHAR fullName[MAX_PATH] = {0}; size_t len; errno_t err = _wdupenv_s(&szServicePath, &len, L"DRBD_PATH"); if (err) { // default szServicePath = L"C:\\Program Files\\drbd\\bin"; } if ((wcslen(szServicePath) + wcslen(cmd) + 4) > MAX_PATH) { printf("szServicePath: too big!!\n"); } wcsncpy_s(fullName, szServicePath, wcslen(szServicePath)); wcscat_s(fullName, L"\\"); wcsncat_s(fullName, cmd, wcslen(cmd)); //wnsprintf printf("fullName: %ws\n", fullName); // test! DWORD ret = RunProcess(EXEC_MODE_WIN, SW_NORMAL, NULL, cmd, szServicePath, dwPID, 0, NULL, NULL); free(szServicePath); return ERROR_SUCCESS; } #if 1 // _WIN32_HANDLER_TIMEOUT: test by a separate application, not daemon. remove later else if (_tcsicmp(L"/n", argv[1]) == 0) { // internal test only: no-daemon test unsigned short servPort = DRBD_DAEMON_TCP_PORT; DWORD threadID; if (CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) SockListener, &servPort, 0, (LPDWORD) &threadID) == NULL) { WriteLog(L"pthread_create() failed\n"); return 0; } int i = 0; while (1) { printf("test main loop(%d)...\n", i++); Sleep(10000); } } #endif else { TCHAR msg[256]; _stprintf_s(msg, _T("Usage: drbdService.exe [/i|/k|/u|/s]\n")); WriteLog(msg); return ERROR_INVALID_PARAMETER; } return ERROR_SUCCESS; }
// Resolve - Creates a nicely formatted rendition of the CallStack, including // symbolic information (function names and line numbers) if available. and // saves it for later retrieval. This is almost identical to Callstack::dump above. // // Note: The symbol handler must be initialized prior to calling this // function. // // - showInternalFrames (IN): If true, then all frames in the CallStack will be // dumped. Otherwise, frames internal to the heap will not be dumped. // // Return Value: // // None. // int CallStack::resolve(BOOL showInternalFrames) { if (m_resolved) { // already resolved, no need to do it again // resolving twice may report an incorrect module for the stack frames // if the memory was leaked in a dynamic library that was already unloaded. return 0; } if (m_status & CALLSTACK_STATUS_STARTUPCRT) { // there is no need to resolve a leak that will not be reported return 0; } if (m_status & CALLSTACK_STATUS_INCOMPLETE) { // This call stack appears to be incomplete. Using StackWalk64 may be // more reliable. Report(L" HINT: The following call stack may be incomplete. Setting \"StackWalkMethod\"\n" L" in the vld.ini file to \"safe\" instead of \"fast\" may result in a more\n" L" complete stack trace.\n"); } int unresolvedFunctionsCount = 0; IMAGEHLP_LINE64 sourceInfo = { 0 }; sourceInfo.SizeOfStruct = sizeof(IMAGEHLP_LINE64); bool skipStartupLeaks = !!(g_vld.GetOptions() & VLD_OPT_SKIP_CRTSTARTUP_LEAKS); // Use static here to increase performance, and avoid heap allocs. // It's thread safe because of g_heapMapLock lock. static WCHAR stack_line[MAXREPORTLENGTH + 1] = L""; bool isPrevFrameInternal = false; bool isDynamicInitializer = false; DWORD NumChars = 0; CriticalSectionLocker<DbgHelp> locker(g_DbgHelp); const size_t max_line_length = MAXREPORTLENGTH + 1; m_resolvedCapacity = m_size * max_line_length; const size_t allocedBytes = m_resolvedCapacity * sizeof(WCHAR); m_resolved = new WCHAR[m_resolvedCapacity]; if (m_resolved) { ZeroMemory(m_resolved, allocedBytes); } // Iterate through each frame in the call stack. for (UINT32 frame = 0; frame < m_size; frame++) { // Try to get the source file and line number associated with // this program counter address. SIZE_T programCounter = (*this)[frame]; DWORD displacement = 0; // It turns out that calls to SymGetLineFromAddrW64 may free the very memory we are scrutinizing here // in this method. If this is the case, m_Resolved will be null after SymGetLineFromAddrW64 returns. // When that happens there is nothing we can do except crash. DbgTrace(L"dbghelp32.dll %i: SymGetLineFromAddrW64\n", GetCurrentThreadId()); BOOL foundline = g_DbgHelp.SymGetLineFromAddrW64(g_currentProcess, programCounter, &displacement, &sourceInfo, locker); if (skipStartupLeaks && foundline && !isDynamicInitializer && !(m_status & CALLSTACK_STATUS_NOTSTARTUPCRT) && isCrtStartupModule(sourceInfo.FileName)) { m_status |= CALLSTACK_STATUS_STARTUPCRT; delete[] m_resolved; m_resolved = NULL; m_resolvedCapacity = 0; m_resolvedLength = 0; return 0; } bool isFrameInternal = false; if (foundline && !showInternalFrames) { if (isInternalModule(sourceInfo.FileName)) { // Don't show frames in files internal to the heap. isFrameInternal = true; } } // show one allocation function for context if (NumChars > 0 && !isFrameInternal && isPrevFrameInternal) { m_resolvedLength += NumChars; if (m_resolved) { wcsncat_s(m_resolved, m_resolvedCapacity, stack_line, NumChars); } } isPrevFrameInternal = isFrameInternal; DWORD64 displacement64; BYTE symbolBuffer[sizeof(SYMBOL_INFO) + MAX_SYMBOL_NAME_SIZE]; LPCWSTR functionName = getFunctionName(programCounter, displacement64, (SYMBOL_INFO*)&symbolBuffer, locker); if (skipStartupLeaks && foundline && beginWith(functionName, wcslen(functionName), L"`dynamic initializer for '")) { isDynamicInitializer = true; } if (!foundline) displacement = (DWORD)displacement64; NumChars = resolveFunction( programCounter, foundline ? &sourceInfo : NULL, displacement, functionName, stack_line, _countof( stack_line )); if (NumChars > 0 && !isFrameInternal) { m_resolvedLength += NumChars; if (m_resolved) { wcsncat_s(m_resolved, m_resolvedCapacity, stack_line, NumChars); } } } // end for loop m_status |= CALLSTACK_STATUS_NOTSTARTUPCRT; return unresolvedFunctionsCount; }
/* Process a given event */ DWORD ProcessEvent(EVT_HANDLE hEvent) { EVT_HANDLE hProviderMetadata = NULL; PEVT_VARIANT eventInfo = NULL; LPWSTR pwsMessage = NULL; LPWSTR pwszPublisherName = NULL; ULONGLONG eventTime; ULONGLONG keyword; DWORD status = ERROR_SUCCESS; int event_id = 0; int winlevel = 0; int level = 0; WCHAR source[SOURCE_SZ]; WCHAR hostname[HOSTNAME_SZ]; WCHAR * formatted_string = NULL; WCHAR * tstamp = NULL; WCHAR * index = NULL; WCHAR defmsg[ERRMSG_SZ]; WCHAR tstamped_message[SYSLOG_DEF_SZ]; /* Get and store the publishers new Windows Events name */ eventInfo = GetEventInfo(hEvent); if (eventInfo) { pwszPublisherName = (LPWSTR)eventInfo[0].StringVal; } else { return ERR_CONTINUE; } eventTime = eventInfo[1].FileTimeVal; event_id = eventInfo[2].UInt16Val; /* Check for the "Microsoft-Windows-" prefix in the publisher name */ /* and remove it if found. Saves 18 characters in the message */ if(wcsncmp(pwszPublisherName, L"Microsoft-Windows-", 18) == 0) wcsncpy_s(source, COUNT_OF(source), pwszPublisherName+18, _TRUNCATE); else wcsncpy_s(source, COUNT_OF(source), pwszPublisherName, _TRUNCATE); /* Format Event Timestamp */ if ((tstamp = WinEventTimeToString(eventTime)) == NULL) tstamp = L"TIME_ERROR"; /* Add hostname for RFC compliance (RFC 3164) */ if (ProgramUseIPAddress == TRUE) { _snwprintf_s(hostname, HOSTNAME_SZ, _TRUNCATE, L"%S", ProgramHostName); } else { if (ExpandEnvironmentStringsW(L"%COMPUTERNAME%", hostname, COUNT_OF(hostname)) == 0) { wcscpy_s(hostname, COUNT_OF(hostname), L"HOSTNAME_ERR"); Log(LOG_ERROR|LOG_SYS, "Cannot expand %COMPUTERNAME%"); } } /* replace every space in source by underscores */ index = source; while( *index ) { if( *index == L' ' ) { *index = L'_'; } index++; } /* Add Timestamp and hostname then format source & event ID for consistency with Event Viewer */ if(SyslogIncludeTag) { _snwprintf_s(tstamped_message, COUNT_OF(tstamped_message), _TRUNCATE, L"%s %s %S: %s: %i: ", tstamp, hostname, SyslogTag, source, event_id ); } else { _snwprintf_s(tstamped_message, COUNT_OF(tstamped_message), _TRUNCATE, L"%s %s %s: %i: ", tstamp, hostname, source, event_id ); } /* Get the handle to the provider's metadata that contains the message strings. */ hProviderMetadata = EvtOpenPublisherMetadata(NULL, pwszPublisherName, NULL, 0, 0); if (NULL == hProviderMetadata) { if (LogInteractive) Log(LOG_ERROR|LOG_SYS, "OpenPublisherMetadata failed for Publisher: \"%S\"", source); return ERR_CONTINUE; } /* Get the message string from the event */ pwsMessage = GetMessageString(hProviderMetadata, hEvent); if (pwsMessage == NULL) { Log(LOG_ERROR|LOG_SYS, "Error getting message string for event DETAILS: Publisher: %S EventID: %i", source, event_id); return ERR_CONTINUE; } /* Get string and strip whitespace */ formatted_string = CollapseExpandMessageW(pwsMessage); /* Create a default message if resources or formatting didn't work */ if (formatted_string == NULL) { if(SyslogIncludeTag) { _snwprintf_s(defmsg, COUNT_OF(defmsg), _TRUNCATE, L"%S: (Facility: %u, Status: %s)", SyslogTag, HRESULT_FACILITY(event_id), FAILED(event_id) ? L"Failure" : L"Success" ); } else { _snwprintf_s(defmsg, COUNT_OF(defmsg), _TRUNCATE, L"(Facility: %u, Status: %s)", HRESULT_FACILITY(event_id), FAILED(event_id) ? L"Failure" : L"Success" ); } formatted_string = defmsg; } /* Get Event Error Level. In the case of Security Events, * set Failures to Error instead of notice using the * keyword attribute */ keyword = (EvtVarTypeNull == eventInfo[4].Type) ? 0 : eventInfo[4].UInt64Val; if ((keyword & WINEVENT_KEYWORD_AUDIT_FAILURE) != 0) { // Add AUDIT_FAILURE message for better parsing wcsncat_s(tstamped_message, COUNT_OF(tstamped_message), L"AUDIT_FAILURE ", _TRUNCATE); winlevel = WINEVENT_ERROR_LEVEL; } else winlevel = (int)eventInfo[3].ByteVal; /* Select syslog level */ switch (winlevel) { case WINEVENT_CRITICAL_LEVEL: level = SYSLOG_BUILD(SyslogFacility, SYSLOG_CRIT); break; case WINEVENT_ERROR_LEVEL: level = SYSLOG_BUILD(SyslogFacility, SYSLOG_ERR); break; case WINEVENT_WARNING_LEVEL: level = SYSLOG_BUILD(SyslogFacility, SYSLOG_WARNING); break; case WINEVENT_INFORMATION_LEVEL: level = SYSLOG_BUILD(SyslogFacility, SYSLOG_NOTICE); break; case WINEVENT_AUDIT_LEVEL: wcsncat_s(tstamped_message, COUNT_OF(tstamped_message), L"AUDIT_SUCCESS ", _TRUNCATE); level = SYSLOG_BUILD(SyslogFacility, SYSLOG_NOTICE); break; case WINEVENT_VERBOSE_LEVEL: level = SYSLOG_BUILD(SyslogFacility, SYSLOG_DEBUG); break; /* Everything else */ default: level = SYSLOG_BUILD(SyslogFacility, SYSLOG_NOTICE); break; } /* Combine the message strings */ wcsncat_s(tstamped_message, COUNT_OF(tstamped_message), formatted_string, _TRUNCATE); /* Send the event to the Syslog Server */ /* Making sure it is severe enough to be logged */ if (SyslogLogLevel == 0 || (SyslogLogLevel >= (DWORD)winlevel && winlevel > 0)) if (SyslogSendW(tstamped_message, level)) status = ERR_FAIL; /* Cleanup memory and open handles */ if(pwsMessage) free(pwsMessage); if(eventInfo) free(eventInfo); if (hProviderMetadata) EvtClose(hProviderMetadata); if (hEvent) EvtClose(hEvent); return status; }
void UpdateConfigPath() { PWSTR knownfolderpath = nullptr; //%AppData%\\CorvusSKK\\config.xml //%AppData%\\CorvusSKK\\skkdict.txt if(SUCCEEDED(SHGetKnownFolderPath(FOLDERID_RoamingAppData, KF_FLAG_DONT_VERIFY, nullptr, &knownfolderpath))) { _snwprintf_s(pathconfigxml, _TRUNCATE, L"%s\\%s\\%s", knownfolderpath, TextServiceDesc, fnconfigxml); _snwprintf_s(pathskkdic, _TRUNCATE, L"%s\\%s\\%s", knownfolderpath, TextServiceDesc, fnskkdic); CoTaskMemFree(knownfolderpath); } if(GetFileAttributesW(pathconfigxml) == INVALID_FILE_ATTRIBUTES) { #ifdef _DEBUG //<module directory>\\config.xml if(GetModuleFileNameW(hInst, pathconfigxml, _countof(pathconfigxml)) != 0) { WCHAR *pdir = wcsrchr(pathconfigxml, L'\\'); if(pdir != nullptr) { *(pdir + 1) = L'\0'; wcsncat_s(pathconfigxml, fnconfigxml, _TRUNCATE); } } #else //%SystemRoot%\\IME\\IMCRVSKK\\config.xml if(SUCCEEDED(SHGetKnownFolderPath(FOLDERID_Windows, KF_FLAG_DONT_VERIFY, nullptr, &knownfolderpath))) { _snwprintf_s(pathconfigxml, _TRUNCATE, L"%s\\%s\\%s\\%s", knownfolderpath, L"IME", TEXTSERVICE_DIR, fnconfigxml); CoTaskMemFree(knownfolderpath); } #endif } if(GetFileAttributesW(pathskkdic) == INVALID_FILE_ATTRIBUTES) { #ifdef _DEBUG //<module directory>\\skkdict.txt if(GetModuleFileNameW(hInst, pathskkdic, _countof(pathskkdic)) != 0) { WCHAR *pdir = wcsrchr(pathskkdic, L'\\'); if(pdir != nullptr) { *(pdir + 1) = L'\0'; wcsncat_s(pathskkdic, fnskkdic, _TRUNCATE); } } #else //%SystemRoot%\\IME\\IMCRVSKK\\skkdict.txt if(SUCCEEDED(SHGetKnownFolderPath(FOLDERID_Windows, KF_FLAG_DONT_VERIFY, nullptr, &knownfolderpath))) { _snwprintf_s(pathskkdic, _TRUNCATE, L"%s\\%s\\%s\\%s", knownfolderpath, L"IME", TEXTSERVICE_DIR, fnskkdic); CoTaskMemFree(knownfolderpath); } #endif } }
HRESULT PasswordUtil_Check(LPCWSTR password, LPCWSTR salt, LPCWSTR passwordHash, BOOL* pResult) { if(IsBadStringPtrW(password,512)) return E_INVALIDARG; if(IsBadStringPtrW(salt,512)) return E_INVALIDARG; if(IsBadStringPtrW(passwordHash,512)) return E_INVALIDARG; if(IsBadWritePtr(pResult,sizeof(BOOL*))) return E_INVALIDARG; *pResult = FALSE; HRESULT hr = S_OK; HCRYPTPROV hProv = NULL; HCRYPTHASH hHash = NULL; WCHAR saltAndPwd[1024] = L""; wcsncat_s(saltAndPwd, 1024, password, 512); wcsncat_s(saltAndPwd, 1024, L"$",1); wcsncat_s(saltAndPwd, 1024, salt, 511); DWORD dwFlags = CRYPT_SILENT|CRYPT_MACHINE_KEYSET; TCHAR szContainer[50] = _T("{BDECD56B-6D48-4add-9AEE-265D537408DF}"); CString auditMessage; BOOL bCreated = FALSE; if(!CryptAcquireContext(&hProv, szContainer, MS_ENHANCED_PROV, PROV_RSA_FULL, dwFlags)) { hr = HRESULT_FROM_WIN32(GetLastError()); if(hr==0x80090016L) // Key Not Found { bCreated = TRUE; if(!CryptAcquireContext(&hProv, szContainer, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET|dwFlags)) { hr = HRESULT_FROM_WIN32(GetLastError()); if(hr == 0x8009000FL) // Key Exists { if(CryptAcquireContext(&hProv, szContainer, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_DELETEKEYSET|dwFlags)) { hr = S_OK; if(!CryptAcquireContext(&hProv, szContainer, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET|dwFlags)) { hr = HRESULT_FROM_WIN32(GetLastError()); } else { hr = S_OK; } } else { hr = HRESULT_FROM_WIN32(GetLastError()); } } else { hr = S_OK; } } else { hr = S_OK; } } } if(SUCCEEDED(hr)) { if(bCreated) { // Set DACL for this container to allow full control for everyone and for local system. PSECURITY_DESCRIPTOR pSd = NULL; LPBYTE pbDacl = NULL; HRESULT hr2 = CreateSecurityDescriptor(&pSd, &pbDacl); if(SUCCEEDED(hr2)) { CryptSetProvParam(hProv, PP_KEYSET_SEC_DESCR, reinterpret_cast<LPBYTE>(pSd), DACL_SECURITY_INFORMATION); delete pSd; delete[] pbDacl; } } if(CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash)) { //auditMessage.Format(_T("Step 2-2. Error Code: 0x%X."), hr); //CEventLog::AddAppLog(auditMessage, FAILED_LOGIN, EVENTLOG_WARNING_TYPE); if(CryptHashData(hHash, (BYTE*)saltAndPwd, (DWORD)(wcslen(saltAndPwd))*2, 0)) { //auditMessage.Format(_T("Step 2-3. Error Code: 0x%X."), hr); //CEventLog::AddAppLog(auditMessage, FAILED_LOGIN, EVENTLOG_WARNING_TYPE); BYTE szData[50] = {0}; DWORD dwDataLen = 50; if(CryptGetHashParam(hHash, HP_HASHVAL, szData, &dwDataLen, 0)) { /*auditMessage.Format(_T("Step 2-4. Error Code: 0x%X."), hr); CEventLog::AddAppLog(auditMessage, FAILED_LOGIN, EVENTLOG_WARNING_TYPE);*/ CW2A ansiPasswordHash(passwordHash); int passwordHashLen = static_cast<int>(strlen(ansiPasswordHash)); int nDestLen = Base64DecodeGetRequiredLength(passwordHashLen); CHeapPtr<BYTE> dataBuffer; if(dataBuffer.AllocateBytes(nDestLen)) { //auditMessage.Format(_T("Step 2-5. Error Code: 0x%X."), hr); //CEventLog::AddAppLog(auditMessage, FAILED_LOGIN, EVENTLOG_WARNING_TYPE); if(Base64Decode(ansiPasswordHash, passwordHashLen, dataBuffer, &nDestLen)) { size_t testHashLength = static_cast<size_t>(dwDataLen); size_t validHashLength = static_cast<size_t>(nDestLen); *pResult = (testHashLength == validHashLength && (memcmp(szData, dataBuffer, testHashLength) == 0)); } } else hr = E_OUTOFMEMORY; } else hr = HRESULT_FROM_WIN32(GetLastError()); } else hr = HRESULT_FROM_WIN32(GetLastError()); CryptDestroyHash(hHash); } else hr = HRESULT_FROM_WIN32(GetLastError()); CryptReleaseContext(hProv, 0); } //else // hr = HRESULT_FROM_WIN32(GetLastError()); //auditMessage.Format(_T("Step Final. Error Code: 0x%X."), hr); //CEventLog::AddAppLog(auditMessage, FAILED_LOGIN, EVENTLOG_WARNING_TYPE); return hr; }
void CDirectoryWatcher::WorkerThread() { DWORD numBytes; CDirWatchInfo * pdi = NULL; LPOVERLAPPED lpOverlapped; WCHAR buf[READ_DIR_CHANGE_BUFFER_SIZE] = {0}; WCHAR * pFound = NULL; while (m_bRunning) { CleanupWatchInfo(); if (watchedPaths.GetCount()) { // Any incoming notifications? pdi = NULL; numBytes = 0; InterlockedExchange(&m_bCleaned, FALSE); if ( (!m_hCompPort) || !GetQueuedCompletionStatus(m_hCompPort, &numBytes, (PULONG_PTR) &pdi, &lpOverlapped, 600000 /*10 minutes*/)) { // No. Still trying? if (!m_bRunning) return; CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) L": restarting watcher\n"); m_hCompPort.CloseHandle(); // We must sync the whole section because other threads may // receive "AddPath" calls that will delete the completion // port *while* we are adding references to it . AutoLocker lock(m_critSec); // Clear the list of watched objects and recreate that list. // This will also delete the old completion port ClearInfoMap(); CleanupWatchInfo(); for (int i=0; i<watchedPaths.GetCount(); ++i) { CTSVNPath watchedPath = watchedPaths[i]; CAutoFile hDir = CreateFile(watchedPath.GetWinPath(), FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, //security attributes OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | //required privileges: SE_BACKUP_NAME and SE_RESTORE_NAME. FILE_FLAG_OVERLAPPED, NULL); if (!hDir) { // this could happen if a watched folder has been removed/renamed CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) L": CreateFile failed. Can't watch directory %s\n", watchedPaths[i].GetWinPath()); watchedPaths.RemovePath(watchedPath); break; } DEV_BROADCAST_HANDLE NotificationFilter; SecureZeroMemory(&NotificationFilter, sizeof(NotificationFilter)); NotificationFilter.dbch_size = sizeof(DEV_BROADCAST_HANDLE); NotificationFilter.dbch_devicetype = DBT_DEVTYP_HANDLE; NotificationFilter.dbch_handle = hDir; // RegisterDeviceNotification sends a message to the UI thread: // make sure we *can* send it and that the UI thread isn't waiting on a lock int numPaths = watchedPaths.GetCount(); size_t numWatch = watchInfoMap.size(); lock.Unlock(); NotificationFilter.dbch_hdevnotify = RegisterDeviceNotification(hWnd, &NotificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE); lock.Lock(); // since we released the lock to prevent a deadlock with the UI thread, // it could happen that new paths were added to watch, or another thread // could have cleared our info map. // if that happened, we have to restart watching all paths again. if ((numPaths != watchedPaths.GetCount()) || (numWatch != watchInfoMap.size())) { ClearInfoMap(); CleanupWatchInfo(); Sleep(200); break; } CDirWatchInfo * pDirInfo = new CDirWatchInfo(hDir, watchedPath); hDir.Detach(); // the new CDirWatchInfo object owns the handle now pDirInfo->m_hDevNotify = NotificationFilter.dbch_hdevnotify; HANDLE port = CreateIoCompletionPort(pDirInfo->m_hDir, m_hCompPort, (ULONG_PTR)pDirInfo, 0); if (port == NULL) { CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) L": CreateIoCompletionPort failed. Can't watch directory %s\n", watchedPath.GetWinPath()); // we must close the directory handle to allow ClearInfoMap() // to close the completion port properly pDirInfo->CloseDirectoryHandle(); ClearInfoMap(); CleanupWatchInfo(); delete pDirInfo; pDirInfo = NULL; watchedPaths.RemovePath(watchedPath); break; } m_hCompPort = port; if (!ReadDirectoryChangesW(pDirInfo->m_hDir, pDirInfo->m_Buffer, READ_DIR_CHANGE_BUFFER_SIZE, TRUE, FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME | FILE_NOTIFY_CHANGE_LAST_WRITE, &numBytes,// not used &pDirInfo->m_Overlapped, NULL)) //no completion routine! { CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) L": ReadDirectoryChangesW failed. Can't watch directory %s\n", watchedPath.GetWinPath()); // we must close the directory handle to allow ClearInfoMap() // to close the completion port properly pDirInfo->CloseDirectoryHandle(); ClearInfoMap(); CleanupWatchInfo(); delete pDirInfo; pDirInfo = NULL; watchedPaths.RemovePath(watchedPath); break; } CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) L": watching path %s\n", pDirInfo->m_DirName.GetWinPath()); watchInfoMap[pDirInfo->m_hDir] = pDirInfo; } } else { if (!m_bRunning) return; if (watchInfoMap.empty()) continue; // NOTE: the longer this code takes to execute until ReadDirectoryChangesW // is called again, the higher the chance that we miss some // changes in the file system! if (pdi) { BOOL bRet = false; std::list<CTSVNPath> notifyPaths; { AutoLocker lock(m_critSec); // in case the CDirectoryWatcher objects have been cleaned, // the m_bCleaned variable will be set to true here. If the // objects haven't been cleared, we can access them here. if (InterlockedExchange(&m_bCleaned, FALSE)) continue; if ( (!pdi->m_hDir) || watchInfoMap.empty() || (watchInfoMap.find(pdi->m_hDir) == watchInfoMap.end())) { continue; } PFILE_NOTIFY_INFORMATION pnotify = (PFILE_NOTIFY_INFORMATION)pdi->m_Buffer; DWORD nOffset = 0; do { pnotify = (PFILE_NOTIFY_INFORMATION)((LPBYTE)pnotify + nOffset); if ((ULONG_PTR)pnotify - (ULONG_PTR)pdi->m_Buffer > READ_DIR_CHANGE_BUFFER_SIZE) break; nOffset = pnotify->NextEntryOffset; if (pnotify->FileNameLength >= (READ_DIR_CHANGE_BUFFER_SIZE*sizeof(TCHAR))) continue; SecureZeroMemory(buf, READ_DIR_CHANGE_BUFFER_SIZE*sizeof(TCHAR)); wcsncpy_s(buf, pdi->m_DirPath, _countof(buf)-1); errno_t err = wcsncat_s(buf+pdi->m_DirPath.GetLength(), READ_DIR_CHANGE_BUFFER_SIZE-pdi->m_DirPath.GetLength(), pnotify->FileName, min(READ_DIR_CHANGE_BUFFER_SIZE-pdi->m_DirPath.GetLength(), int(pnotify->FileNameLength/sizeof(TCHAR)))); if (err == STRUNCATE) { continue; } buf[(pnotify->FileNameLength/sizeof(TCHAR))+pdi->m_DirPath.GetLength()] = 0; if (m_FolderCrawler) { if ((pFound = StrStrI(buf, L"\\tmp"))!=NULL) { pFound += 4; if (((*pFound)=='\\')||((*pFound)=='\0')) { continue; } } if ((pFound = StrStrI(buf, L":\\RECYCLER"))!=NULL) { if ((*(pFound + 10) == '\0') || (*(pFound + 10) == '\\')) continue; } if ((pFound = StrStrI(buf, L":\\$Recycle.Bin"))!=NULL) { if ((*(pFound + 14) == '\0') || (*(pFound + 14) == '\\')) continue; } if (StrStrI(buf, L".tmp")!=NULL) { // assume files with a .tmp extension are not versioned and interesting, // so ignore them. continue; } CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) L": change notification for %s\n", buf); notifyPaths.push_back(CTSVNPath(buf)); } } while ((nOffset > 0)&&(nOffset < READ_DIR_CHANGE_BUFFER_SIZE)); // setup next notification cycle SecureZeroMemory (pdi->m_Buffer, sizeof(pdi->m_Buffer)); SecureZeroMemory (&pdi->m_Overlapped, sizeof(OVERLAPPED)); bRet = ReadDirectoryChangesW (pdi->m_hDir, pdi->m_Buffer, READ_DIR_CHANGE_BUFFER_SIZE, TRUE, FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME | FILE_NOTIFY_CHANGE_LAST_WRITE, &numBytes,// not used &pdi->m_Overlapped, NULL); //no completion routine! } if (!notifyPaths.empty()) { for (auto nit = notifyPaths.cbegin(); nit != notifyPaths.cend(); ++nit) { m_FolderCrawler->AddPathForUpdate(*nit); } } // any clean-up to do? CleanupWatchInfo(); if (!bRet) { // Since the call to ReadDirectoryChangesW failed, just // wait a while. We don't want to have this thread // running using 100% CPU if something goes completely // wrong. Sleep(200); } } } }// if (watchedPaths.GetCount()) else Sleep(200); }// while (m_bRunning) }