// Issue 1125: Hook undocumented function used for running commands typed in Windows 7 Win-menu search string. HRESULT WINAPI OnShellExecCmdLine(HWND hwnd, LPCWSTR pwszCommand, LPCWSTR pwszStartDir, int nShow, LPVOID pUnused, DWORD dwSeclFlags) { //typedef HRESULT (WINAPI* OnShellExecCmdLine_t)(HWND hwnd, LPCWSTR pwszCommand, LPCWSTR pwszStartDir, int nShow, LPVOID pUnused, DWORD dwSeclFlags); ORIGINAL_EX(ShellExecCmdLine); HRESULT hr = S_OK; // This is used from "Run" dialog too. We need to process command internally, because // otherwise Win can pass CREATE_SUSPENDED into CreateProcessW, so console will flickers. // From Win7 start menu: "cmd" and Ctrl+Shift+Enter - dwSeclFlags==0x79 if (nShow && pwszCommand && pwszStartDir) { if (!IsBadStringPtrW(pwszCommand, MAX_PATH) && !IsBadStringPtrW(pwszStartDir, MAX_PATH)) { hr = OurShellExecCmdLine(hwnd, pwszCommand, pwszStartDir, (dwSeclFlags & 0x40)==0x40, false); if (hr == (HRESULT)-1) goto ApiCall; else goto wrap; } } ApiCall: if (!F(ShellExecCmdLine)) { hr = HRESULT_FROM_WIN32(ERROR_INVALID_FUNCTION); } else { hr = F(ShellExecCmdLine)(hwnd, pwszCommand, pwszStartDir, nShow, pUnused, dwSeclFlags); } wrap: return hr; }
bool is_file_existsW(_In_ const wchar_t* file_path) { _ASSERTE(NULL != file_path); _ASSERTE(TRUE != IsBadStringPtrW(file_path, MAX_PATH)); if ((NULL == file_path) || (TRUE == IsBadStringPtrW(file_path, MAX_PATH))) return false; WIN32_FILE_ATTRIBUTE_DATA info = { 0 }; if (GetFileAttributesExW(file_path, GetFileExInfoStandard, &info) == 0) return false; else return true; }
TEST_F(GetSystemParametersInfoTest, should_get_some_oem_info) { const int SPI_GETOEMINFO = 258; rapi::SystemParametersInfoInput input(SPI_GETOEMINFO, expectedSize, true); ASSERT_PRED_FORMAT3(assertInvoke, sizeof(input), (LPBYTE)&input, S_OK); ASSERT_FALSE(IsBadStringPtrW((LPCWSTR)output, expectedSize)); // Just so we can inspect the output value while debugging. LPCWSTR oemText = (LPCWSTR)output; }
/** * @brief * @param * @see * @remarks * @code * @endcode * @return **/ bool is_file_existsW(_In_ const wchar_t* file_path) { _ASSERTE(NULL != file_path); _ASSERTE(TRUE != IsBadStringPtrW(file_path, MAX_PATH)); if ((NULL == file_path) || (TRUE == IsBadStringPtrW(file_path, MAX_PATH))) return false; WIN32_FILE_ATTRIBUTE_DATA info = { 0 }; // // CreateFile()이 아닌 GetFileAttributesEx()를 이용하면 파일이 다른 process에 의해 lock되어 있어도 // 파일 존재여부를 정확히 체크할 수 있다. // if (GetFileAttributesExW(file_path, GetFileExInfoStandard, &info) == 0) return false; else return true; }
DBG_INTERFACE void AssertValidStringPtr( const tchar* ptr, int maxchar/* = 0xFFFFFF */ ) { #if defined( _WIN32 ) && !defined( _X360 ) #ifdef TCHAR_IS_CHAR Assert( !IsBadStringPtr( ptr, maxchar ) ); #else Assert( !IsBadStringPtrW( ptr, maxchar ) ); #endif #else Assert( ptr ); #endif }
/************************************************************************** * AddMRUStringW [COMCTL32.401] * * Add an item to an MRU string list. * * PARAMS * hList [I] Handle to list. * lpszString [I] The string to add. * * RETURNS * Success: The number corresponding to the registry name where the string * has been stored (0 maps to 'a', 1 to 'b' and so on). * Failure: -1, if hList is NULL or memory allocation fails. If lpszString * is invalid, the function returns 0, and GetLastError() returns * ERROR_INVALID_PARAMETER. The last error value is set only in * this case. * * NOTES * -If lpszString exists in the list already, it is moved to the top of the * MRU list (it is not duplicated). * -If the list is full the least recently used list entry is replaced with * lpszString. * -If this function returns 0 you should check the last error value to * ensure the call really succeeded. */ INT WINAPI AddMRUStringW(HANDLE hList, LPCWSTR lpszString) { TRACE("(%p,%s)\n", hList, debugstr_w(lpszString)); if (!hList) return -1; if (!lpszString || IsBadStringPtrW(lpszString, -1)) { SetLastError(ERROR_INVALID_PARAMETER); return 0; } return AddMRUData(hList, lpszString, (strlenW(lpszString) + 1) * sizeof(WCHAR)); }
/************************************************************************** * CreateMRUListLazyW [COMCTL32.404] * * See CreateMRUListLazyA. */ HANDLE WINAPI CreateMRUListLazyW (const MRUINFOW *infoW, DWORD dwParam2, DWORD dwParam3, DWORD dwParam4) { LPWINEMRULIST mp; /* Native does not check for a NULL lpcml */ if (!infoW->hKey || IsBadStringPtrW(infoW->lpszSubKey, -1)) return NULL; mp = Alloc(sizeof(WINEMRULIST)); memcpy(&mp->extview, infoW, sizeof(MRUINFOW)); mp->extview.lpszSubKey = Alloc((strlenW(infoW->lpszSubKey) + 1) * sizeof(WCHAR)); strcpyW(mp->extview.lpszSubKey, infoW->lpszSubKey); mp->isUnicode = TRUE; return create_mru_list(mp); }
WriteMiniDumpResult __stdcall WriteMiniDumpW(MINIDUMP_TYPE eType, wchar_t* szFileName, DWORD dwThread, EXCEPTION_POINTERS* pExceptInfo) { // Check the string parameter because I am paranoid. I can't check // the eType as that might change in the future. if (IsBadStringPtrW(szFileName, MAX_PATH) == TRUE) { return WriteMiniDumpResult::BadParameter; } // If an exception pointer blob was passed in. if (pExceptInfo != NULL) { if (IsBadReadPtr(pExceptInfo, sizeof(EXCEPTION_POINTERS)) == TRUE) { return WriteMiniDumpResult::BadParameter; } } // Package up the data for the dump writer thread. DUMPTHREADPARAMS stParams; stParams.eReturnValue = WriteMiniDumpResult::InvalidError; stParams.eType = eType; stParams.pExceptInfo = pExceptInfo; stParams.dwThreadID = dwThread; stParams.szFileName = szFileName; stParams.dwMiniDumpWriteDumpLastError = ERROR_SUCCESS; // Crank the writer thread. unsigned dwTID; HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, DumpThread, &stParams, 0, &dwTID); if ((HANDLE)-1 != hThread) { // The thread is running. Block until the thread ends. WaitForSingleObject(hThread, INFINITE); CloseHandle(hThread); } else { stParams.dwMiniDumpWriteDumpLastError = GetLastError(); stParams.eReturnValue = WriteMiniDumpResult::eDEATH_ERROR; } // Set the last error code based so it looks like this thread made // the call to MiniDumpWriteDump. SetLastError(stParams.dwMiniDumpWriteDumpLastError); return stParams.eReturnValue; }
/************************************************************************** * CreateMRUListLazyW [COMCTL32.404] * * See CreateMRUListLazyA. */ HANDLE WINAPI CreateMRUListLazyW (LPCREATEMRULISTW lpcml, DWORD dwParam2, DWORD dwParam3, DWORD dwParam4) { LPWINEMRULIST mp; /* Native does not check for a NULL lpcml */ if (lpcml->cbSize != sizeof(CREATEMRULISTW) || !lpcml->hKey || IsBadStringPtrW(lpcml->lpszSubKey, -1)) return NULL; mp = Alloc(sizeof(WINEMRULIST)); memcpy(&mp->extview, lpcml, sizeof(CREATEMRULISTW)); mp->extview.lpszSubKey = Alloc((strlenW(lpcml->lpszSubKey) + 1) * sizeof(WCHAR)); strcpyW((LPWSTR)mp->extview.lpszSubKey, lpcml->lpszSubKey); mp->isUnicode = TRUE; return CreateMRUListLazy_common(mp); }
static PyObject * Z_get(void *ptr, Py_ssize_t size) { wchar_t *p; p = *(wchar_t **)ptr; if (p) { #if defined(MS_WIN32) && !defined(_WIN32_WCE) if (IsBadStringPtrW(*(wchar_t **)ptr, -1)) { PyErr_Format(PyExc_ValueError, "invalid string pointer %p", *(wchar_t **)ptr); return NULL; } #endif return PyUnicode_FromWideChar(p, wcslen(p)); } else { Py_INCREF(Py_None); return Py_None; } }
BSUMDRET __stdcall CreateCurrentProcessMiniDumpW ( MINIDUMP_TYPE eType , wchar_t * szFileName , DWORD dwThread , EXCEPTION_POINTERS * pExceptInfo ) { // Check the string parameter because I am paranoid. I can't check // the eType as that might change in the future. ASSERT ( FALSE == IsBadStringPtrW ( szFileName , MAX_PATH ) ) ; if ( TRUE == IsBadStringPtrW ( szFileName , MAX_PATH ) ) { return ( eBAD_PARAM ) ; } // If an exception pointer blob was passed in. if ( NULL != pExceptInfo ) { ASSERT ( FALSE == IsBadReadPtr ( pExceptInfo , sizeof ( EXCEPTION_POINTERS))); if ( TRUE == IsBadReadPtr ( pExceptInfo , sizeof ( EXCEPTION_POINTERS))) { return ( eBAD_PARAM ) ; } } // Have I even tried to get the exported MiniDumpWriteDump function // yet? if ( ( NULL == g_pfnMDWD ) && ( eINVALID_ERROR == g_eIMDALastError)) { if ( FALSE == IsMiniDumpFunctionAvailable ( ) ) { return ( g_eIMDALastError ) ; } } // If the MiniDumpWriteDump function pointer is NULL, return // whatever was in g_eIMDALastError. if ( NULL == g_pfnMDWD ) { return ( g_eIMDALastError ) ; } // Package up the data for the dump writer thread. DUMPTHREADPARAMS stParams ; stParams.eReturnValue = eINVALID_ERROR ; stParams.eType = eType ; stParams.pExceptInfo = pExceptInfo ; stParams.dwThreadID = dwThread ; stParams.szFileName = szFileName ; stParams.dwMiniDumpWriteDumpLastError = ERROR_SUCCESS ; // Crank the writer thread. DWORD dwTID ; HANDLE hThread = (HANDLE)CreateThread ( NULL , 0 , DumpThread , &stParams , 0 , &dwTID ) ; ASSERT ( (HANDLE)-1 != hThread ) ; if ( (HANDLE)-1 != hThread ) { // The thread is running. Block until the thread ends. WaitForSingleObject ( hThread , INFINITE ) ; // Close the handle. VERIFY ( CloseHandle ( hThread ) ) ; } else { stParams.dwMiniDumpWriteDumpLastError = GetLastError ( ) ; stParams.eReturnValue = eDEATH_ERROR ; } // Set the last error code based so it looks like this thread made // the call to MiniDumpWriteDump. SetLastError ( stParams.dwMiniDumpWriteDumpLastError ) ; return ( stParams.eReturnValue ) ; }
NDASVOL_LINKAGE HRESULT NDASVOL_CALL NdasIsNdasPathW( __in LPCWSTR FilePath) { HRESULT hr; if (IsBadStringPtrW(FilePath, UINT_PTR(-1))) { return E_INVALIDARG; } XTLTRACE2(NdasVolTrace, 4, "NdasIsNdasPathW(%ls)\n", FilePath); LPWSTR mountPoint; hr = pGetVolumeMountPointForPathW(FilePath, &mountPoint); if (FAILED(hr)) { XTLTRACE2(NdasVolTrace, TRACE_LEVEL_ERROR, "pGetVolumeMountPointForPath(%ls) failed, hr=0x%X\n", FilePath, hr); return hr; } XTL::AutoProcessHeapPtr<WCHAR> mountPointPtr = mountPoint; LPWSTR deviceName; hr = pGetVolumeDeviceNameForMountPointW(mountPoint, &deviceName); if (FAILED(hr)) { XTLTRACE2(NdasVolTrace, TRACE_LEVEL_ERROR, "pGetVolumeDeviceNameForMountPoint(%ls) failed, hr=0x%X\n", mountPoint, hr); return hr; } XTL::AutoProcessHeapPtr<TCHAR> deviceNamePtr = deviceName; // Volume is a \\.\C: XTL::AutoFileHandle volumeHandle = CreateFileW( deviceName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (INVALID_HANDLE_VALUE == static_cast<HANDLE>(volumeHandle)) { hr = HRESULT_FROM_WIN32(GetLastError()); XTLTRACE2(NdasVolTrace, TRACE_LEVEL_ERROR, "CreateFile failed, path=%ls, hr=0x%X\n", deviceName, hr); return hr; } return NdasIsNdasVolume(volumeHandle); }
BSUMDRET BUGSUTIL_DLLINTERFACE __stdcall CreateCurrentProcessCrashDumpW ( MINIDUMP_TYPE eType , wchar_t * szFileName , DWORD dwThread , EXCEPTION_POINTERS * pExceptInfo ) { // Holds the return value. BSUMDRET eReturnVal = eOPEN_DUMP_FAILED ; // Check the string parameter because I am paranoid. I can't check // the eType as that might change in the future. ASSERT ( FALSE == IsBadStringPtrW ( szFileName , MAX_PATH ) ) ; if ( TRUE == IsBadStringPtrW ( szFileName , MAX_PATH ) ) { return ( eBAD_PARAM ) ; } ASSERT ( FALSE == IsBadReadPtr ( pExceptInfo , sizeof ( EXCEPTION_POINTERS*))); if ( TRUE == IsBadReadPtr ( pExceptInfo , sizeof ( EXCEPTION_POINTERS*))) { return ( eBAD_PARAM ) ; } ASSERT ( 0 != dwThread ) ; if ( 0 == dwThread ) { return ( eBAD_PARAM ) ; } // Have I even tried to get the exported MiniDumpWriteDump function // yet? if ( ( NULL == g_pfnMDWD ) && ( eINVALID_ERROR == g_eIMDALastError)) { if ( FALSE == IsMiniDumpFunctionAvailable ( ) ) { return ( g_eIMDALastError ) ; } } // If the MiniDumpWriteDump function pointer is NULL, return // whatever was in g_eIMDALastError. if ( NULL == g_pfnMDWD ) { return ( g_eIMDALastError ) ; } // Create the file first. HANDLE hFile = CreateFileW ( szFileName , GENERIC_READ | GENERIC_WRITE , 0 , NULL , CREATE_ALWAYS , FILE_ATTRIBUTE_NORMAL , NULL ) ; ASSERT ( INVALID_HANDLE_VALUE != hFile ) ; if ( INVALID_HANDLE_VALUE != hFile ) { MINIDUMP_EXCEPTION_INFORMATION stMDEI ; stMDEI.ThreadId = dwThread ; stMDEI.ExceptionPointers = pExceptInfo ; stMDEI.ClientPointers = TRUE ; // Got the file open. Write it. BOOL bRet = g_pfnMDWD ( GetCurrentProcess ( ) , GetCurrentProcessId ( ) , hFile , eType , &stMDEI , NULL , NULL ) ; ASSERT ( TRUE == bRet ) ; if ( TRUE == bRet ) { eReturnVal = eDUMP_SUCCEEDED ; } else { // Oops. eReturnVal = eMINIDUMPWRITEDUMP_FAILED ; } // Close the open file. VERIFY ( CloseHandle ( hFile ) ) ; } else { // Could not open the file! eReturnVal = eOPEN_DUMP_FAILED ; } // Always save the last error value so I can set it in the original // thread. g_eIMDALastError = eReturnVal ; return ( eReturnVal ) ; }
BOOL AnalyseWin32k(PDWORD poffset_UserInitialize, PDWORD poffset_bInitializeEUDC_patch) { DWORD offset_UserInitialize = 0; DWORD offset_bInitializeEUDC_patch = 0; char szPath[MAX_PATH]; GetSystemDirectory(szPath, MAX_PATH); strcat_s(szPath, MAX_PATH, "\\win32k.sys"); HMODULE hMod = LoadLibraryEx(szPath, NULL, DONT_RESOLVE_DLL_REFERENCES); if (hMod) { PIMAGE_NT_HEADERS32 pHeaders32 = (PIMAGE_NT_HEADERS32) ((PUCHAR)hMod + ((PIMAGE_DOS_HEADER)hMod)->e_lfanew); PIMAGE_SECTION_HEADER pSection = NULL, pCodeSection = NULL; PIMAGE_BASE_RELOCATION pRelocation = NULL; ULONG RelocationSize = 0, NumberOfSections = 0; ULONGLONG OldBase = 0; if (pHeaders32->FileHeader.Machine == IMAGE_FILE_MACHINE_I386) { // 32-bit image if (pHeaders32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress) { pRelocation = (PIMAGE_BASE_RELOCATION)RVATOVA( hMod, pHeaders32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress ); RelocationSize = pHeaders32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size; } OldBase = (ULONGLONG)pHeaders32->OptionalHeader.ImageBase; NumberOfSections = pHeaders32->FileHeader.NumberOfSections; pSection = (PIMAGE_SECTION_HEADER) (pHeaders32->FileHeader.SizeOfOptionalHeader + (PUCHAR)&pHeaders32->OptionalHeader); } else if (pHeaders32->FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64) { // 64-bit image PIMAGE_NT_HEADERS64 pHeaders64 = (PIMAGE_NT_HEADERS64) ((PUCHAR)hMod + ((PIMAGE_DOS_HEADER)hMod)->e_lfanew); if (pHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress) { pRelocation = (PIMAGE_BASE_RELOCATION)RVATOVA( hMod, pHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress ); RelocationSize = pHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size; } OldBase = pHeaders64->OptionalHeader.ImageBase; NumberOfSections = pHeaders64->FileHeader.NumberOfSections; pSection = (PIMAGE_SECTION_HEADER) (pHeaders64->FileHeader.SizeOfOptionalHeader + (PUCHAR)&pHeaders64->OptionalHeader); } else { DbgMsg(__FILE__, __LINE__, __FUNCTION__"() ERROR: Unkown machine type\n"); FreeLibrary(hMod); return FALSE; } // enumerate image sections for (ULONG i = 0; i < NumberOfSections; i++) { // find section, that contains global variable if (!strncmp((char *)&pSection->Name, ".text", 5)) { pCodeSection = pSection; break; } pSection += 1; } if (pRelocation && pCodeSection) { // parse image relocation table ULONG Size = 0; while (RelocationSize > Size && pRelocation->SizeOfBlock) { ULONG Number = (pRelocation->SizeOfBlock - 8) / 2; PUSHORT Rel = (PUSHORT)((PUCHAR)pRelocation + 8); for (ULONG i = 0; i < Number; i++) { if (Rel[i] > 0) { USHORT Type = (Rel[i] & 0xF000) >> 12; ULONG Rva = 0; PVOID *Va = NULL; // get address of global variable that used by our instruction if (Type == IMAGE_REL_BASED_HIGHLOW || Type == IMAGE_REL_BASED_DIR64) { Rva = pRelocation->VirtualAddress + (Rel[i] & 0x0FFF); Va = (PVOID *)RVATOVA(hMod, Rva); } else { DbgMsg(__FILE__, __LINE__, __FUNCTION__ "() ERROR: Unknown relocation type (%d)\n", Type); } if (Va && Rva > 0 && Rva > pCodeSection->VirtualAddress && Rva < pCodeSection->VirtualAddress + pCodeSection->Misc.VirtualSize) { // get address of global variable, that requre fixup PVOID VarAddr = *Va; VarAddr = (PVOID)((ULONGLONG)VarAddr - OldBase + (PUCHAR)hMod); if (!IsBadStringPtrW((LPWSTR)VarAddr, MAX_PATH)) { if (!wcscmp((LPWSTR)VarAddr, WIN32K_STR_1)) { DbgMsg( __FILE__, __LINE__, __FUNCTION__"(): \"%ws\" referenced at offset 0x%.8x\n", WIN32K_STR_1, Rva ); // lookup for stdcall prolog of win32k!UserInitialize() for (DWORD i = 0; i < 50; i++) { if (!memcmp( (PUCHAR)Va - i, WIN32K_STDCALL_PROLOG, WIN32K_STDCALL_PROLOG_LEN)) { if (offset_UserInitialize > 0) { DbgMsg( __FILE__, __LINE__, __FUNCTION__"() ERROR: multipile heuristic matches for win32k!UserInitialize()\n" ); FreeLibrary(hMod); return FALSE; } offset_UserInitialize = Rva - i; DbgMsg( __FILE__, __LINE__, __FUNCTION__"(): win32k!UserInitialize() found at offset 0x%.8x\n", offset_UserInitialize ); break; } } } else if (!wcscmp((LPWSTR)VarAddr, WIN32K_STR_2)) { DbgMsg( __FILE__, __LINE__, __FUNCTION__"(): \"%ws\" referenced at offset 0x%.8x\n", WIN32K_STR_2, Rva ); /* Check for the following code in win32k!bInitializeEUDC(): mov ?SharedQueryTable@@A.Name, offset aFontlinkdefaul ; "FontLinkDefaultChar" mov ?SharedQueryTable@@A.EntryContext, eax call edi ; RtlQueryRegistryValues(x,x,x,x,x) test eax, eax jge short loc_BF80525F */ LONG InstPtr = -6; PUCHAR pInst = (PUCHAR)Va; if (*(PUSHORT)(pInst + InstPtr) == 0x05c7) { // disassemble next 5 instructions for (DWORD i = 0; i < 5; i++) { LONG InstLen = (LONG)c_Catchy(pInst + InstPtr); if (InstLen == (LONG)CATCHY_ERROR) { DbgMsg(__FILE__, __LINE__, __FUNCTION__"() ERROR: c_Catchy() fails\n"); FreeLibrary(hMod); return FALSE; } InstPtr += InstLen; // check for call edi / test eax, eax if (*(PUSHORT)(pInst + InstPtr + 0) == 0xd7ff && *(PUSHORT)(pInst + InstPtr + 2) == 0xc085) { if (offset_bInitializeEUDC_patch > 0) { DbgMsg( __FILE__, __LINE__, __FUNCTION__"() ERROR: multipile heuristic matches for win32k!bInitializeEUDC()\n" ); FreeLibrary(hMod); return FALSE; } offset_bInitializeEUDC_patch = Rva + InstPtr; DbgMsg( __FILE__, __LINE__, __FUNCTION__"(): win32k!bInitializeEUDC() CALL EDI found at offset 0x%.8x\n", offset_bInitializeEUDC_patch ); break; } } } } } } } } pRelocation = (PIMAGE_BASE_RELOCATION)((PUCHAR)pRelocation + pRelocation->SizeOfBlock); Size += pRelocation->SizeOfBlock; } }
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; }