pWnd read access violation on Windows version 20H2 - c++

I am running into a very strange issue with my mfc c++ program on newer Windows 10 builds. Specifically 20H2 (Build 19042).
When launching a specific dialog from my main menu PCs running this OS build crash silently, without warning.
I have gained access to dump files and determined the issue to be
"Unhandled exception thrown: read access violation. pWnd -> was 0x33312E" with exception code 0xC0000005
This was thrown inside of wincore.cpp on line 265
IResult = pWnd->WindowProc(nMsg, wParam, lParam);
Looking at the disassembly for this line it fails here...
0053A92C mov eax,dword ptr [pWnd] (pWnd is 0x0019f4a4)
0053A92F mov ecx,dword ptr [eax] (eax is 0x0019f4a4)
(ecx is 0x0033312E)
0053A931 mov edx,dword ptr [ecx+11Ch] (Unhandled exception here)
Call stack looks like this.
Program.exe!AfxCallWndProc(CWnd* pWnd, HWND__* hand, unsigned int nMsg, unsigned int wParam, long iParam) line 265
Program.exe!AfxWndProc(HWND__* hWnd, unsigned int nMsg, unsigned int wParam,long iParam) line 418
user32.dll!__InternalCallWinProc#20()
user32.dll!UserCallWinProcCheckWow()
user32.dll!DispatchClientMessage()
user32.dll!___fnDWORD#4()
ntdll.dll!_KiUserCallbackDispatcher#12()
Program.exe!CWND::UpdateWindow() line 106
Program.exe!CWND::RunModalLoop(unsigned long dwFlags) line 4632
Program.exe!CWND::CreateRunDlgIndirect(const DLGTEMPLATE * lpDialogTemplate, CWnd* pParentWnd, HINSTANCE__ * hInst) line 470
Program.exe!CDialog::DoModal() line 633
Program.exe!CMainDlg::OnDeviceButton() line 1271
Here is the code in OnDeviceButton()
Void CMainDlg::OnDeviceButton()
{
CDevice device;
device.deviceType = 7;
device.DoModal();
}
Here is code from CDevice
BOOL CDevice::OnInitDialog()
{
CDialog::OnInitDialog();
CloseCPC();
deviceList.SetExtendedStyle(LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT);
deviceList.InsertVolumn(0, _T("Device"), LVCFMT_LEFT, 150);
deviceList.InsertColumn(1, _T("Software Version"), LVCFMT_CENTER. 100);
deviceList.InsertItem(0, _T("BRTB"));
SetupVersionTree();
SetTimer(1,1,NULL);
Sleep(20);
return TRUE;
}
Void CDevice::OnTimer(UINT_PTR nIDEvent)
{
If(nODEvent == 1)
{
KillTimer(1);
If(CPC_handle == -1)
{
InitCPC(7,this);
}
If(firstPass)
{
GetVersion();
}
SetTimer(1,10000,NULL);
}
}
Any ideas? I've run through about everything I can think of for debugging besides submitting a help ticket directly to Microsoft asking for assistance.
If there is any other information I can provide please let me know.
Edit
I forgot to mention "solutions" that I have found.
Initialization if the class object as a pointer
CDevice* device = new CDevice();
A random development version which only difference is a new dialog item. (No longer crashes with this version)
Setting the timer up in InitDialog method after 20ms sleep.
Initializing two CPC msg structures in constructor.
These all individually "resolve" the issue but I cannot seem to find any patterns between these "solutions" and I can't sell them as a solution with the reason of "because it seems to fix it".

Related

Thread is terminated for no apparent reason

So I am currently making a system to list all visible windows and then choose a random one. The code exists and is working.. in 32-bit. The problem is that it won't work when compiling for 64-bit. It does not even hit my breaking point before terminating the thread. I have also tried using a try block with the same result. The thread exit code is 0. NOTE: The code is messy due to it being filled with debugging and testing stuff.
Here is my code:
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
{
wchar_t wnd_title[2048]; // Will be replaced
SendMessage(hwnd, WM_GETTEXT, sizeof(wnd_title), (LPARAM)wnd_title);
if (!hwnd || !IsWindowVisible(hwnd) || !SendMessage(hwnd, WM_GETTEXT, sizeof(wnd_title), (LPARAM)wnd_title)) {
return TRUE;
}
std::vector<HWND>& Windows = *reinterpret_cast<std::vector<HWND>*>(lParam);
Windows.push_back(hwnd);
OutputDebugString(wnd_title);
OutputDebugString(L"\n");
return TRUE;
}
std::vector<HWND> GetOpenWindows() {
std::vector<HWND> Windows;
EnumWindows(EnumWindowsProc, reinterpret_cast<LPARAM>(&Windows));
return Windows;
}
void GetRandomWindow() {
stringstream ss; // For Debug
std::ostringstream stream; //For Debug
std::vector<HWND> Windows = GetOpenWindows();
int ChosenWindow = Utils::RandIntRange(0, Windows.size());
if (ChosenWindow < Windows.size()) { // Breaking point here (HIT)
TCHAR wnd_title[MAX_PATH];
SendMessage(Windows[ChosenWindow], WM_GETTEXT, MAX_PATH, (LPARAM)wnd_title); //Breaking point here (NOT HIT)
OutputDebugString(L"\n");
OutputDebugString(wnd_title);
MessageBox(NULL, L"Hi", L"Test", MB_OK);
}
}
The thread was terminated because the wrong size was passed to the message. The thread hang issue was fixed by using SendMessageTimeout(...); instead of SendMessage(..);. This works because a window was not responding to any messages.
(Answer is for people who have the same issue)
Thanks to Igor Tandetnik and Peter for the help!

MFC Ribbon quick access toolbar crash when state is changed

I have an old MFC application I am updating and I just added a ribbon (using the CMFCRibbonBar class).
However any commands in the quick access toolbar on the ribbon that cause a change in state (eg closing the file and exiting to the main menu) cause a crash when the command is used from the quick access toolbar but not the normal ribbon button.
The crash happens in the MFC file afxribbonbar.cpp in OnMouseMove()
if (pHit != m_pHighlighted)
{
PopTooltip();
if (m_pHighlighted != NULL)
{
ASSERT_VALID(m_pHighlighted);
m_pHighlighted->m_bIsHighlighted = FALSE;
m_pHighlighted->OnHighlight(FALSE);
InvalidateRect(m_pHighlighted->GetRect());
m_pHighlighted = NULL;
}
It crashes on the InvalidateRect line, because m_pHighlighted seems to exist but have no data, so either the stack is corrupted or m_pHighlighted doesn't exist anymore.
I have some lines to reload where all the frames were last time the user was in the new state and I found if I comment out the lines when I change state the crash doesn't happen:
theApp.SaveState(this, ToolbarKey(i_oldAppState));
and
theApp.LoadState( this, ToolbarKey(i_newAppState) );
But ideally I want these lines as otherwise all the windows and frames revert to their default state and users have to resize everything again.
It feels like the entries in the quick access toolbar are being destroyed and recreated when I change state, but I can't find where MFC does this, or a way to set the highlighted entry to null.
EDIT: The crash is an unhandled exception due to an access reading violation in mfc140u.dll. The crash happens deep in the MFC code, well away from anything I have written.
The call stack when this unhandled exception occurs is:
mfc140u.dll!CBasePane::get_accValue(tagVARIANT varChild, wchar_t * * pszValue) Line 1494 C++
mfc140u.dll!CMFCRibbonBar::OnMouseMove(unsigned int nFlags, CPoint point) Line 2348 C++
mfc140u.dll!CMFCRibbonBar::OnLButtonUp(unsigned int nFlags, CPoint point) Line 2276 C++
mfc140u.dll!CWnd::OnWndMsg(unsigned int message, unsigned __int64 wParam, __int64 lParam, __int64 * pResult) Line 2698 C++
mfc140u.dll!CWnd::WindowProc(unsigned int message, unsigned __int64 wParam, __int64 lParam) Line 2099 C++
mfc140u.dll!CBasePane::WindowProc(unsigned int message, unsigned __int64 wParam, __int64 lParam) Line 1020 C++
mfc140u.dll!CMFCRibbonBar::WindowProc(unsigned int message, unsigned __int64 wParam, __int64 lParam) Line 4884 C++
mfc140u.dll!AfxCallWndProc(CWnd * pWnd, HWND__ * hWnd, unsigned int nMsg, unsigned __int64 wParam, __int64 lParam) Line 265 C++
mfc140u.dll!AfxWndProc(HWND__ * hWnd, unsigned int nMsg, unsigned __int64 wParam, __int64 lParam) Line 417 C++
mfc140u.dll!AfxWndProcBase(HWND__ * hWnd, unsigned int nMsg, unsigned __int64 wParam, __int64 lParam) Line 299 C++
user32.dll!UserCallWinProcCheckWow() Unknown
user32.dll!DispatchMessageWorker() Unknown
user32.dll!IsDialogMessageW() Unknown
mfc140u.dll!CWnd::IsDialogMessageW(tagMSG * lpMsg) Line 194 C++
[Inline Frame] mfc140u.dll!CWnd::PreTranslateInput(tagMSG *) Line 4606 C++
mfc140u.dll!CBasePane::PreTranslateMessage(tagMSG * pMsg) Line 1057 C++
mfc140u.dll!CMFCRibbonBar::PreTranslateMessage(tagMSG * pMsg) Line 3734 C++
mfc140u.dll!CWnd::WalkPreTranslateTree(HWND__ * hWndStop, tagMSG * pMsg) Line 3379 C++
mfc140u.dll!AfxInternalPreTranslateMessage(tagMSG * pMsg) Line 233 C++
mfc140u.dll!AfxInternalPumpMessage() Line 178 C++
mfc140u.dll!CWinThread::Run() Line 629 C++
I had the same bug in the BCG Library. I Made my private fix there for the variables m_pHighlighted and m_pPressed.
BOOL CBCGPRibbonBar::LoadState (LPCTSTR lpszProfileName, int nIndex, UINT uiID)
{
// 2014-04-23 mri: we need to clear pointer to may be active elements that
// may get deleted, when LoadState is executed.
// We cannot set m_pActiveCategory to NULL!!!! This get us into problems when the
// program starts and the minimize/maximize button is used, when this pointer is
// NULL.
m_pHighlighted = NULL;
m_pPressed = NULL;
You should set them to nullptr before you call LoadState
As I remember the problem ist that a click in the ribbon is handled in the Mouse-Down message. So the Mouse-Up message is never executed that clears this member...

Accessing dbch_devicetype fails

I have a piece of MS C++ (unmanaged) code that runs whenever a USB device is inserted or removed into my computer. On Windows 7, this code runs fine. On Windows 10, it throws an error. What happens is that when a USB drive, or any other USB device for that matter, is inserted into my computer, the OnMyDeviceChange routine gets called 3 times; it is only called two (correct) times on Windows 7. Anyways, on Windows 10, the first two times, the routine runs fine. The third time it fails on this line: type.Format("%d",pHdr->dbch_devicetype);. Does anyone know why?
Note: we now know that for the code that fails, pHdr is null.
Here is my code:
ON_MESSAGE(WM_DEVICECHANGE, OnMyDeviceChange)//in BEGIN_MESSAGE_MAP(CMainFrame, CBCGPMDIFrameWnd)
LRESULT CMainFrame::OnMyDeviceChange(WPARAM wParam, LPARAM lParam)
{
//return 0;//essentially comment out everything else
PDEV_BROADCAST_HDR pHdr = (PDEV_BROADCAST_HDR)lParam;
AddLogLine("1");
// AfxMessageBox(pHdr->dbch_devicetype);
PDEV_BROADCAST_DEVICEINTERFACE pDevInf = (PDEV_BROADCAST_DEVICEINTERFACE)pHdr;
AddLogLine("2");
CString type;
type.Format("%d",pHdr->dbch_devicetype);
AddLogLine("type = " + type);
if(pHdr->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE)
{
UpdateDevice(pDevInf, wParam);
}
return 0;
}
//More relevant code:
struct _DEV_BROADCAST_HDR { /* */
DWORD dbch_size;
DWORD dbch_devicetype;
DWORD dbch_reserved;
};
typedef struct _DEV_BROADCAST_HDR DEV_BROADCAST_HDR;
typedef DEV_BROADCAST_HDR DBTFAR* PDEV_BROADCAST_HDR;

MFC program crashes when window resized with error "A required resource was not found."

I'm developing an SDI MFC application where there are some custom buttons which are drawn in a custom way or have images loaded on top of them. When the running application is re-sized continuously for about 5 to 10 minutes, it crashes with the error "A required resource was not found."
I have checked the code thoroughly and all the GetDC() calls are followed by ReleaseDC() calls. Furthermore, I always save the old GDI object (for example, an oldBrush), whenever I do a DC.SelectObject(&newBrush) call and then restore the old pen with DC.SelectObject(&oldBrush).
Any hints for what else might be causing this error?
Edit: I used the program Deleaker to find the GDI leaks in the program and deleted those GDI objects which were causing the leak.
Edit: Here's the call stack for AfxThrowResourceException:
mfc110ud.dll!AfxThrowResourceException() Line 1353 C++
mfc110ud.dll!CWindowDC::CWindowDC(CWnd * pWnd) Line 1022 C++
mfc110ud.dll!CMFCToolBarImages::PrepareDrawImage(tagAFXDrawState & ds, CSize sizeImageDest, int bFadeInactive) Line 1219 C++
mfc110ud.dll!CMFCToolBarImages::DrawEx(CDC * pDC, CRect rect, int iImageIndex, CMFCToolBarImages::ImageAlignHorz horzAlign, CMFCToolBarImages::ImageAlignVert vertAlign, CRect rectSrc, unsigned char alphaSrc) Line 1729 C++
mfc110ud.dll!CMFCControlRenderer::FillInterior(CDC * pDC, CRect rect, CMFCToolBarImages::ImageAlignHorz horz, CMFCToolBarImages::ImageAlignVert vert, unsigned int index, unsigned char alphaSrc) Line 470 C++
mfc110ud.dll!CMFCControlRenderer::FillInterior(CDC * pDC, CRect rect, unsigned int index, unsigned char alphaSrc) Line 474 C++
mfc110ud.dll!CMFCControlRenderer::Draw(CDC * pDC, CRect rect, unsigned int index, unsigned char alphaSrc) Line 253 C++
mfc110ud.dll!CMFCVisualManagerOffice2007::DrawNcCaption(CDC * pDC, CRect rectCaption, unsigned long dwStyle, unsigned long dwStyleEx, const ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t> > > & strTitle, const ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t> > > & strDocument, HICON__ * hIcon, int bPrefix, int bActive, int bTextCenter, const CObList & lstSysButtons) Line 2097 C++
mfc110ud.dll!CMFCVisualManagerOffice2007::OnNcPaint(CWnd * pWnd, const CObList & lstSysButtons, CRect rectRedraw) Line 2343 C++
mfc110ud.dll!CFrameImpl::OnNcPaint() Line 1564 C++
mfc110ud.dll!CFrameWndEx::OnNcPaint() Line 1030 C++
mfc110ud.dll!CWnd::OnWndMsg(unsigned int message, unsigned int wParam, long lParam, long * pResult) Line 2459 C++
mfc110ud.dll!CWnd::WindowProc(unsigned int message, unsigned int wParam, long lParam) Line 2137 C++
mfc110ud.dll!AfxCallWndProc(CWnd * pWnd, HWND__ * hWnd, unsigned int nMsg, unsigned int wParam, long lParam) Line 290 C++
mfc110ud.dll!AfxWndProc(HWND__ * hWnd, unsigned int nMsg, unsigned int wParam, long lParam) Line 453 C++
mfc110ud.dll!AfxWndProcBase(HWND__ * hWnd, unsigned int nMsg, unsigned int wParam, long lParam) Line 304 C++
I am sure you have a GDI or other Windows resource leak. The message text Comes from an internal exception in the MFC.
What you see is the result of a call to AfxThrowResourceException. Set a break Point on this function in the Debugger and you can see what Operation Fails.
As a result of this acion you know if you have a Memory or GDI leak, or may be other handle leak...

mouse hook broke all windows input

I'm new to c++ programming and am trying to make a small reporting tool that will detect when the mouse and keyboard haven't been touched over a period of time.
I have been searching for some example mouse hook code and found this
#define _WIN32_WINNT 0x0400
#pragma comment( lib, "user32.lib" )
#include <windows.h>
#include <stdio.h>
HHOOK hMouseHook;
__declspec(dllexport) LRESULT CALLBACK KeyboardEvent (int nCode, WPARAM wParam, LPARAM lParam)
{
MOUSEHOOKSTRUCT * pMouseStruct = (MOUSEHOOKSTRUCT *)lParam;
if (pMouseStruct != NULL)
printf("Mouse position X = %d Mouse Position Y = %d\n", pMouseStruct->pt.x,pMouseStruct->pt.y);
return CallNextHookEx(hMouseHook,
nCode,wParam,lParam);
}
void MessageLoop()
{
MSG message;
while (GetMessage(&message,NULL,0,0)) {
TranslateMessage( &message );
DispatchMessage( &message );
}
}
DWORD WINAPI MyMouseLogger(LPVOID lpParm)
{
HINSTANCE hInstance = GetModuleHandle(NULL);
if (!hInstance) hInstance = LoadLibrary((LPCSTR) lpParm);
if (!hInstance) return 1;
hMouseHook = SetWindowsHookEx (
WH_MOUSE_LL,
(HOOKPROC) KeyboardEvent,
hInstance,
NULL
);
MessageLoop();
UnhookWindowsHookEx(hMouseHook);
return 0;
}
int main(int argc, char** argv)
{
HANDLE hThread;
DWORD dwThread;
hThread = CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE)
MyMouseLogger, (LPVOID) argv[0], NULL, &dwThread);
if (hThread)
return WaitForSingleObject(hThread,INFINITE);
else return 1;
}
I compiled and ran this as a test which seems to do what I wanted. After that I started testing a couple of things. compiled on c++ and g++ for the hell of it. removed the pMouseStruct and tested "if(lParam)" instead. Everything seemed to be behaving and it was getting late so I decided to return to this the next day.
When I booted in to windows today, I was unable to move the mouse or input anything with the keyboard. It seems input inside windows (normal and safe mode) is not working anymore. Any ideas how to fix this?
Using Windows 7 64bit.
So far I have tried the following:
- reversed a recent overclocking tweak.
- returned the code to the way it was before i played with it, recompiled, and ran.
- Googling.
- chkdsk /f on the system drive.
- system restore (doesn't like raid)
- copied user32.dll off a friend.
Plz forgive my ignorance :-)
I ended up reinstalling windows 7 and soon ran into more strange problems. I have since discovered that standby was corrupting various things and have stopped using it. Now I'm running a fresh install of windows 7 that has never been put to sleep. Still don't have any bizarre problems to this day :-)