How to avoid RaceOnRCW when calling the ComboBox Clear function using Invoke - multithreading

I am working on a UART terminal program like TeraTerm. I am making my own terminal program since I need some features that I can't find in other terminal programs.
My terminal program can open several terminal windows that each display the output from a chosen COM port. Each terminal window runs in its own thread.
I have overridden the terminal window form's WndProc function to catch device changed events since I want to update a ComboBox's items with the current PC's available COM ports. This is done to keep the list of COM ports up to date if the user is plugging in a USB COM port device.
My WndProc looks as follows:
protected override void WndProc(ref Message m)
{
switch(m.Msg)
{
case WM_DEVICECHANGE:
GetAvailableCOMPorts();
COMPortsComboBox.Invoke(UpdateCOMPortsComboBoxDelegate);
break;
}
base.WndProc(ref m);
}
The UpdateCOMPortsComboBoxDelegate is the function updating the items in the ComboBox when a device change occurs. It does not matter if the device wa not a COM device. I do not check to keep it simple.
The UpdateCOMPortsComboBox function pointed to by the delegate looks as follows:
private void UpdateCOMPortsComboBox()
{
bool State = COMPortsComboBox.Enabled;
COMPortsComboBox.Enabled = false;
COMPortsComboBox.Items.Clear();
COMPortsComboBox.Enabled = State;
// Then add the new list of COM ports
for(int i = 0; i < AvailableSerialPorts.Length; i++)
{
COMPortsComboBox.Items.Add(AvailableSerialPorts[i]);
}
}
My problems is that I sometimes get a RaceOnRCW at the Clear() method call even though I have used Invoke to make sure it is called on the thread running the controls message loop.
What is going on?
How do I prevent this from happening?
Or maybe how can I figure out if a control is in use on another thread? And then perhaps wait for the other thread to finish.
Is there perhaps a better way to update the ComboBox items with a new list when the device change event occurs?
The call stack looks as follows when it happens:
mscorlib.dll!System.__ComObject.ReleaseSelf() + 0x5 bytes
mscorlib.dll!System.Runtime.InteropServices.Marshal.ReleaseComObject(object o) + 0x9a bytes
System.Windows.Forms.dll!System.Windows.Forms.StringSource.ReleaseAutoComplete() + 0x11 bytes
System.Windows.Forms.dll!System.Windows.Forms.ComboBox.OnHandleDestroyed(System.EventArgs e) + 0x85 bytes
System.Windows.Forms.dll!System.Windows.Forms.Control.WmDestroy(ref System.Windows.Forms.Message m) + 0x46 bytes
System.Windows.Forms.dll!System.Windows.Forms.Control.WndProc(ref System.Windows.Forms.Message m) + 0x44d bytes
System.Windows.Forms.dll!System.Windows.Forms.ComboBox.WndProc(ref System.Windows.Forms.Message m) + 0x882 bytes
System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.OnMessage(ref System.Windows.Forms.Message m) + 0x13 bytes
System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.WndProc(ref System.Windows.Forms.Message m) + 0x31 bytes
System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.DebuggableCallback(System.IntPtr hWnd, int msg, System.IntPtr wparam, System.IntPtr lparam) + 0x64 bytes
[Native to Managed Transition]
[Managed to Native Transition]
System.Windows.Forms.dll!System.Windows.Forms.UnsafeNativeMethods.DestroyWindow(System.Runtime.InteropServices.HandleRef hWnd) + 0x10 bytes
System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.DestroyHandle() + 0x89 bytes
System.Windows.Forms.dll!System.Windows.Forms.Control.DestroyHandle() + 0x157 bytes
System.Windows.Forms.dll!System.Windows.Forms.Control.RecreateHandleCore() + 0x16a bytes
System.Windows.Forms.dll!System.Windows.Forms.ComboBox.RecreateHandleCore() + 0x1a bytes
System.Windows.Forms.dll!System.Windows.Forms.ComboBox.SetAutoComplete(bool reset, bool recreate) + 0x105 bytes
System.Windows.Forms.dll!System.Windows.Forms.ComboBox.ObjectCollection.ClearInternal() + 0xa1 bytes
System.Windows.Forms.dll!System.Windows.Forms.ComboBox.ObjectCollection.Clear() + 0x17 bytes
> Echo.exe!Echo.Echo.UpdateCOMPortsComboBox() Line 231 + 0x1d bytes C#
[Native to Managed Transition]
mscorlib.dll!System.Delegate.DynamicInvokeImpl(object[] args) + 0x77 bytes
System.Windows.Forms.dll!System.Windows.Forms.Control.InvokeMarshaledCallbackDo(System.Windows.Forms.Control.ThreadMethodEntry tme) + 0xa7 bytes
System.Windows.Forms.dll!System.Windows.Forms.Control.InvokeMarshaledCallbackHelper(object obj) + 0x90 bytes
System.Windows.Forms.dll!System.Windows.Forms.Control.InvokeMarshaledCallback(System.Windows.Forms.Control.ThreadMethodEntry tme) + 0xa2 bytes
System.Windows.Forms.dll!System.Windows.Forms.Control.InvokeMarshaledCallbacks() + 0xda bytes
System.Windows.Forms.dll!System.Windows.Forms.Control.MarshaledInvoke(System.Windows.Forms.Control caller, System.Delegate method, object[] args, bool synchronous) + 0x365 bytes
System.Windows.Forms.dll!System.Windows.Forms.Control.Invoke(System.Delegate method, object[] args) + 0x50 bytes
System.Windows.Forms.dll!System.Windows.Forms.Control.Invoke(System.Delegate method) + 0x7 bytes
Echo.exe!Echo.Echo.WndProc(ref System.Windows.Forms.Message m) Line 247 + 0x19 bytes C#
System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.OnMessage(ref System.Windows.Forms.Message m) + 0x13 bytes
System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.WndProc(ref System.Windows.Forms.Message m) + 0x31 bytes
System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.DebuggableCallback(System.IntPtr hWnd, int msg, System.IntPtr wparam, System.IntPtr lparam) + 0x64 bytes
[Native to Managed Transition]
[Managed to Native Transition]
System.Windows.Forms.dll!System.Windows.Forms.StringSource.Bind(System.Runtime.InteropServices.HandleRef edit, int options) + 0x46 bytes
System.Windows.Forms.dll!System.Windows.Forms.ComboBox.SetAutoComplete(bool reset, bool recreate) + 0x2f4 bytes
System.Windows.Forms.dll!System.Windows.Forms.ComboBox.ObjectCollection.Add(object item) + 0x55 bytes
Echo.exe!Echo.Echo.UpdateCOMPortsComboBox() Line 237 + 0x34 bytes C#
[Native to Managed Transition]
mscorlib.dll!System.Delegate.DynamicInvokeImpl(object[] args) + 0x77 bytes
System.Windows.Forms.dll!System.Windows.Forms.Control.InvokeMarshaledCallbackDo(System.Windows.Forms.Control.ThreadMethodEntry tme) + 0xa7 bytes
System.Windows.Forms.dll!System.Windows.Forms.Control.InvokeMarshaledCallbackHelper(object obj) + 0x90 bytes
System.Windows.Forms.dll!System.Windows.Forms.Control.InvokeMarshaledCallback(System.Windows.Forms.Control.ThreadMethodEntry tme) + 0xa2 bytes
System.Windows.Forms.dll!System.Windows.Forms.Control.InvokeMarshaledCallbacks() + 0xda bytes
System.Windows.Forms.dll!System.Windows.Forms.Control.MarshaledInvoke(System.Windows.Forms.Control caller, System.Delegate method, object[] args, bool synchronous) + 0x365 bytes
System.Windows.Forms.dll!System.Windows.Forms.Control.Invoke(System.Delegate method, object[] args) + 0x50 bytes
System.Windows.Forms.dll!System.Windows.Forms.Control.Invoke(System.Delegate method) + 0x7 bytes
Echo.exe!Echo.Echo.WndProc(ref System.Windows.Forms.Message m) Line 247 + 0x19 bytes C#
System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.OnMessage(ref System.Windows.Forms.Message m) + 0x13 bytes
System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.WndProc(ref System.Windows.Forms.Message m) + 0x31 bytes
System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.DebuggableCallback(System.IntPtr hWnd, int msg, System.IntPtr wparam, System.IntPtr lparam) + 0x64 bytes
[Native to Managed Transition]
[Managed to Native Transition]
System.Windows.Forms.dll!System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(System.IntPtr dwComponentID, int reason, int pvLoopData) + 0x1b8 bytes
System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(int reason, System.Windows.Forms.ApplicationContext context) + 0x16c bytes
System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoop(int reason, System.Windows.Forms.ApplicationContext context) + 0x61 bytes
System.Windows.Forms.dll!System.Windows.Forms.Application.RunDialog(System.Windows.Forms.Form form) + 0x33 bytes
System.Windows.Forms.dll!System.Windows.Forms.Form.ShowDialog(System.Windows.Forms.IWin32Window owner) + 0x38f bytes
System.Windows.Forms.dll!System.Windows.Forms.Form.ShowDialog() + 0x7 bytes
Echo.exe!Echo.Program.NewEcho() Line 48 + 0xa bytes C#
mscorlib.dll!System.Threading.ThreadHelper.ThreadStart_Context(object state) + 0x63 bytes
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool ignoreSyncCtx) + 0xb0 bytes
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) + 0x2c bytes
mscorlib.dll!System.Threading.ThreadHelper.ThreadStart() + 0x44 bytes
[Native to Managed Transition]
I use the following code to create new terminal windows in a separate thread:
public static void CreateNewEchoThread()
{
//// Create a new thread
Thread EchoThread = new Thread(new ThreadStart(Program.NewEcho));
// Set thread parameters
EchoThread.IsBackground = true;
EchoThread.SetApartmentState(ApartmentState.STA);
//// Start the thread
EchoThread.Start();
// Increment the number of open Echo forms
Echo.NumberOfOpenWindows++;
}
[STAThread]
static void NewEcho()
{
// Create a new Echo form window and show it as a Dialog to prevent the thread from exiting immediately.
Echo NewEchoForm = new Echo();
NewEchoForm.ShowDialog();
}

I found a way to avoid the RaceOnRCW.
I replace the Clear call by a loop that removes each item one by one. Not the solution I like, but it seems to work.
I would still like to hear other ideas about how to do it, since it bothers me that I can't use the Clear function.
int NItems = COMPortsComboBox.Items.Count;
for(int i = 0; i < NItems; i++)
{
COMPortsComboBox.Items.RemoveAt(0);
}

Related

Java Card OwnerPin - APDU Command

I'm starting to learn java card and I'm reading a sample code of a wallet and there an OwnerPin in it.
Here's the part of the code, related to the pin and its verification:
OwnerPIN pin;
private myApplet(byte[] bArray, short bOffset, byte bLength) {
// It is good programming practice to allocate
// all the memory that an applet needs during
// its lifetime inside the constructor
pin = new OwnerPIN(PIN_TRY_LIMIT, MAX_PIN_SIZE);
byte iLen = bArray[bOffset]; // aid length
bOffset = (short) (bOffset + iLen + 1);
byte cLen = bArray[bOffset]; // info length
bOffset = (short) (bOffset + cLen + 1);
byte aLen = bArray[bOffset]; // applet data length
// The installation parameters contain the PIN
// initialization value
pin.update(bArray, (short) (bOffset + 1), aLen);
register();
}
I'm having a little trouble understanding this code. I know that this is the part when the pin is set according to the installation script:
0x80 0xB8 0x00 0x00 0xd 0xb 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x00 0x00 0x00 0x7F;
I can't understand what is the value of pin will be after installing the applet.
The shown code is not enough to actually say anything about the given APDU.
This code sample though:
byte iLen = bArray[bOffset]; // aid length
bOffset = (short) (bOffset + iLen + 1);
byte cLen = bArray[bOffset]; // info length
bOffset = (short) (bOffset + cLen + 1);
byte aLen = bArray[bOffset]; // applet data length
is the default code for the Applet's installation method, therefore could be triggered by a Global Platform INSTALL command. However, the given APDU is not a valid Global Platform at all.
From your code we cannot see the entrypoint of the APDU in the process method, but probably it works like this: the given data is a LV-encoded list (Length/Value), therefore you parse the length byte for aid first, save the length iLen and increment bOffset to the next LV-pair. in the end the value and length of the applet data is taken and feeded into the pin.update.
In the given APDU, the PIN is acutally missing, try to parse the contents and length for aid and info and you will see that the applet data bytes are missing.

Assertion in appcore.cpp while loading regular DLL dynamically linked to MFC

I have inherited an application which consists of a regular DLL which is dynamically linked to MFC and which is loaded from a Windows service executable which also links dynamically to MFC. The code is being compiled using Microsoft Visual Studio 2008 Professional (old, I know...). This application has been 'working' for several years but I have found that I cannot run it as Debug build due to the following assertion in appcore.cpp:
Debug Assertion Failed!
Program: C:\Projects\CMM\Debug\CMM.exe
File: f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\appcore.cpp
Line: 380
For more information on how your program can cause an assertion
failure, see the Visual C++ documentation on asserts.
(Press Retry to debug the application)
which corresponds to the following code in the CWinApp constructor:
ASSERT(AfxGetThread() == NULL);
pThreadState->m_pCurrentWinThread = this;
ASSERT(AfxGetThread() == this);
This occurs when loading the DLL via LoadLibrary and leads me to suspect that the application has worked more by luck than judgement over the years (due to ASSERT not being included as part of the Release build).
My (admittedly limited) understanding of MFC is that although there should generally only be a single instance of CWinApp, it is permissible to have an additional one in regular DLLs which link dynamically to MFC, as in this case. The code has one instance in the service executable and one in the DLL. The CWinApp constructor gets called three (?) times, once for some internal instance within the MFC framework, once for the instance in the service executable and once for the instance in the DLL. The first two work fine, it is the third which blows up.
All of the exported functions start with AFX_MANAGE_STATE (although execution never gets that far) and the pre-processor flags are, I believe, correct w.r.t. Microsoft's documentation (_AFXDLL for the EXE, _AFXDLL, _USRDLL and _WINDLL for the DLL).
I have tried using AfxLoadLibrary instead of LoadLibrary to no effect. However, if I include
AFX_MANAGE_STATE( AfxGetStaticModuleState() )
at the start of the function which calls LoadLibrary/AfxLoadLibrary, the CWinApp object is actually constructed but execution then blows up in dllmodul.cpp instead.
Can anybody shed any light on why this might be happening or what I need to do to fix it?
EDIT
This is the call stack when the assertion occurs:
mfc90d.dll!CWinApp::CWinApp(const char * lpszAppName=0x00000000) Line 380 + 0x1c bytes C++
cimdll.dll!CCimDllApp::CCimDllApp() Line 146 + 0x19 bytes C++
cimdll.dll!`dynamic initializer for 'theApp''() Line 129 + 0xd bytes C++
msvcr90d.dll!_initterm(void (void)* * pfbegin=0x1b887c88, void (void)* * pfend=0x1b887d6c) Line 903 C
cimdll.dll!_CRT_INIT(void * hDllHandle=0x1b770000, unsigned long dwReason=1, void * lpreserved=0x00000000) Line 318 + 0xf bytes C
cimdll.dll!__DllMainCRTStartup(void * hDllHandle=0x1b770000, unsigned long dwReason=1, void * lpreserved=0x00000000) Line 540 + 0x11 bytes C
cimdll.dll!_DllMainCRTStartup(void * hDllHandle=0x1b770000, unsigned long dwReason=1, void * lpreserved=0x00000000) Line 510 + 0x11 bytes C
ntdll.dll!_LdrxCallInitRoutine#16() + 0x16 bytes
ntdll.dll!LdrpCallInitRoutine() + 0x43 bytes
ntdll.dll!LdrpInitializeNode() + 0x101 bytes
ntdll.dll!LdrpInitializeGraphRecurse() + 0x71 bytes
ntdll.dll!LdrpPrepareModuleForExecution() + 0x8b bytes
ntdll.dll!LdrpLoadDllInternal() + 0x121 bytes
ntdll.dll!LdrpLoadDll() + 0x92 bytes
ntdll.dll!_LdrLoadDll#16() + 0xd9 bytes
KernelBase.dll!_LoadLibraryExW#12() + 0x138 bytes
KernelBase.dll!_LoadLibraryExA#12() + 0x26 bytes
KernelBase.dll!_LoadLibraryA#4() + 0x32 bytes
mfc90d.dll!AfxCtxLoadLibraryA(const char * lpLibFileName=0x02a70ce0) Line 487 + 0x74 bytes C++
mfc90d.dll!AfxLoadLibrary(const char * lpszModuleName=0x02a70ce0) Line 193 + 0x9 bytes C++
CMM.exe!CMonDevDll::LoadDLL() Line 207 + 0x1b bytes C++
CMM.exe!CMonDevDll::LoadDllEntryPoints() Line 268 + 0x8 bytes C++
CMM.exe!CMonDevDll::Initialize(CMonDevRun * pMonDevRun=0x0019fe60) Line 186 + 0x8 bytes C++
CMM.exe!CCtcLinkMonDev::Initialize(CMonDevRun * pMonDevRun=0x0019fe60, CCtcRegistry & reg={...}, int nLinkId=1) Line 546 + 0x18 bytes C++
CMM.exe!CCtcLinkSwitchMgr::Initialize(CMonDevRun * pMonDevRun=0x0019fe60, CCtcRegistry & reg={...}) Line 188 + 0x14 bytes C++
CMM.exe!CMonDevRun::Initialize(ATL::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char> > > szServiceName="CimService") Line 257 + 0x16 bytes C++
CMM.exe!CMonDevService::Run() Line 202 + 0x2d bytes C++
CommonFilesD.dll!CCtcServiceBase::ParseStandardArgs(int argc=-1, char * * argv=0x02a51b44) Line 278 + 0xf bytes C++
CMM.exe!main(int argc=4, char * * argv=0x02a51b38) Line 126 + 0x16 bytes C++
CMM.exe!__tmainCRTStartup() Line 586 + 0x19 bytes C
CMM.exe!mainCRTStartup() Line 403 C
kernel32.dll!#BaseThreadInitThunk#12() + 0x24 bytes
ntdll.dll!__RtlUserThreadStart() + 0x2f bytes
ntdll.dll!__RtlUserThreadStart#8() + 0x1b bytes
I finally managed to track down the cause of my crash. A library used by my DLL was linking statically to Boost.Thread and causing this issue, presumably due to a runtime mismatch. Changing the library to link dynamically to Boost instead seems to have fixed the problem.

ASSERT(::IsWindow(m_hWnd)) fails in Afxwin2.inl

I am creating a view in my project which is a child class of CView.
class CBaseGLView : public CView
In oncreate function I am checking it null or not as below:
int CBaseGLView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
m_hWnd = GetSafeHwnd();
if( ::IsWindow(m_hWnd)== NULL)
{
return 1;
}
m_pCDC= new CClientDC(this);
m_hDC = m_pCDC->GetSafeHdc();
if (SetWindowPixelFormat()==FALSE)
return 0;
return 0;
}
When I am debugging with ApplicationVerifier I am getting a debug assertion in below lines in afxwin2.inl:
_AFXWIN_INLINE LRESULT CWnd::_AFX_FUNCNAME(SendMessage)(UINT message, WPARAM wParam, LPARAM lParam) const
{ ASSERT(::IsWindow(m_hWnd)); return ::SendMessage(m_hWnd, message, wParam, lParam); }
And also m_hwnd is shown as unused 0 with the memory address of 0x00170fd6.
Given below is the output from Application verifier.
VERIFIER STOP 00000013: pid 0xDF4: First chance access violation for current stack trace.
339F9020 : Invalid address causing the exception.
0109D75E : Code address executing the invalid access.
0018E034 : Exception record.
0018E084 : Context record.
Following is the call stack of the debug build. It is too long, sorry for that.
ntdll.dll!7729000c()
[Frames below may be incorrect and/or missing, no symbols loaded for ntdll.dll]
vrfcore.dll!VfCoreRedirectedStopMessage(unsigned long Code=19, char * Message=0x73341b5c, unsigned long Param1=444756000, char * Description1=0x73341b94, unsigned long Param2=17422174, char * Description2=0x73341bb4, unsigned long Param3=1630260, char * Description3=0x73341bd4, unsigned long Param4=1630340, char * Description4=0x73341c00) Line 103 + 0x19 bytes C++
vfbasics.dll!VerifierStopMessage(unsigned long Code=19, char * Message=0x73341b5c, unsigned long Param1=444756000, char * Description1=0x73341b94, unsigned long Param2=17422174, char * Description2=0x73341bb4, unsigned long Param3=1630260, char * Description3=0x73341bd4, unsigned long Param4=1630340, char * Description4=0x73341c00) Line 1214 C
vfbasics.dll!AVrfpCheckFirstChanceException(_EXCEPTION_POINTERS * ExceptionPointers=0x0018df7c) Line 1108 + 0x2b bytes C
vfbasics.dll!AVrfpVectoredExceptionHandler(_EXCEPTION_POINTERS * ExceptionPointers=0x0018df7c) Line 323 C
ntdll.dll!772f62de()
ntdll.dll!772db652()
ntdll.dll!772db314()
ntdll.dll!77290133()
user32.dll!753a617a()
Axial.exe!CWnd::SendMessageA(unsigned int message=2125, unsigned int wParam=0, long lParam=0) Line 42 + 0x44 bytes C++
Axial.exe!SECWorkbookClientWnd::OnMDISetMenu(unsigned int wParam=261688291, long lParam=21302363) Line 390 C++
Axial.exe!CWnd::OnWndMsg(unsigned int message=560, unsigned int wParam=261688291, long lParam=21302363, long * pResult=0x0018e980) Line 2018 + 0x11 bytes C++
Axial.exe!CWnd::WindowProc(unsigned int message=560, unsigned int wParam=261688291, long lParam=21302363) Line 1755 + 0x20 bytes C++
Axial.exe!AfxCallWndProc(CWnd * pWnd=0x1a54bf98, HWND__ * hWnd=0x00120ff0, unsigned int nMsg=560, unsigned int wParam=261688291, long lParam=21302363) Line 240 + 0x1c bytes C++
Axial.exe!AfxWndProc(HWND__ * hWnd=0x00120ff0, unsigned int nMsg=560, unsigned int wParam=261688291, long lParam=21302363) Line 403 C++
user32.dll!753962fa()
user32.dll!75397316()
user32.dll!75396ce9()
user32.dll!75396de8()
user32.dll!75396e44()
ntdll.dll!7729010a()
user32.dll!753972b9()
user32.dll!753a2161()
user32.dll!753a0f91()
user32.dll!753a9deb()
user32.dll!753a9dfd()
user32.dll!753a8124()
Axial.exe!CMDIChildWnd::DefWindowProcA(unsigned int nMsg=34, unsigned int wParam=0, long lParam=0) Line 429 C++
Axial.exe!CWnd::WindowProc(unsigned int message=34, unsigned int wParam=0, long lParam=0) Line 1756 + 0x1c bytes C++
Axial.exe!AfxCallWndProc(CWnd * pWnd=0x1a826f08, HWND__ * hWnd=0x00210bbe, unsigned int nMsg=34, unsigned int wParam=0, long lParam=0) Line 240 + 0x1c bytes C++
Axial.exe!AfxWndProc(HWND__ * hWnd=0x00210bbe, unsigned int nMsg=34, unsigned int wParam=0, long lParam=0) Line 403 C++
user32.dll!753962fa()
user32.dll!75396d3a()
user32.dll!75396ce9()
user32.dll!75396de8()
user32.dll!75396e44()
ntdll.dll!7729010a()
user32.dll!75398e63()
user32.dll!753a7b51()
Axial.exe!CFrameWnd::BringToTop(int nCmdShow=1) Line 2362 C++
Axial.exe!CFrameWnd::ActivateFrame(int nCmdShow=1) Line 2341 C++
Axial.exe!CMDIChildWnd::ActivateFrame(int nCmdShow=-1) Line 762 C++
Axial.exe!CFrameWnd::InitialUpdateFrame(CDocument * pDoc=0x1a6a2de8, int bMakeVisible=1) Line 814 C++
Axial.exe!CDocTemplate::InitialUpdateFrame(CFrameWnd * pFrame=0x1a826f08, CDocument * pDoc=0x1a6a2de8, int bMakeVisible=1) Line 330 C++
Axial.exe!CMultiDocTemplate::OpenDocumentFile(const char * lpszPathName=0x0018f6fc, int bMakeVisible=1) Line 166 C++
Axial.exe!CDocManager::OpenDocumentFile(const char * lpszFileName=0x19418fa0) Line 986 C++
Axial.exe!CWinApp::OpenDocumentFile(const char * lpszFileName=0x19418fa0) Line 84 C++
Axial.exe!CAxialApp::OpenDocumentFile(const char * lpszFileName=0x19418fa0) Line 983 + 0xc bytes C++
Axial.exe!CWinApp::OnOpenRecentFile(unsigned int nID=57616) Line 132 + 0x2a bytes C++
Axial.exe!_AfxDispatchCmdMsg(CCmdTarget * pTarget=0x018e6e88, unsigned int nID=57616, int nCode=0, void (void)* pfn=0x009f8140, void * pExtra=0x00000000, unsigned int nSig=60, AFX_CMDHANDLERINFO * pHandlerInfo=0x00000000) Line 101 + 0xa bytes C++
Axial.exe!CCmdTarget::OnCmdMsg(unsigned int nID=57616, int nCode=0, void * pExtra=0x00000000, AFX_CMDHANDLERINFO * pHandlerInfo=0x00000000) Line 381 + 0x27 bytes C++
Axial.exe!CAxialApp::OnCmdMsg(unsigned int id=57616, int code=0, void * extra=0x00000000, AFX_CMDHANDLERINFO * handler=0x00000000) Line 1135 + 0x40 bytes C++
Axial.exe!CFrameWnd::OnCmdMsg(unsigned int nID=57616, int nCode=0, void * pExtra=0x00000000, AFX_CMDHANDLERINFO * pHandlerInfo=0x00000000) Line 951 + 0x23 bytes C++
Axial.exe!SECMDIFrameWnd::OnCmdMsg(unsigned int nID=57616, int nCode=0, void * pExtra=0x00000000, AFX_CMDHANDLERINFO * pHandlerInfo=0x00000000) Line 2270 C++
Axial.exe!CWnd::OnCommand(unsigned int wParam=57616, long lParam=0) Line 2364 C++
Axial.exe!CFrameWnd::OnCommand(unsigned int wParam=57616, long lParam=0) Line 366 C++
Axial.exe!SECMDIFrameWnd::OnCommand(unsigned int wParam=57616, long lParam=0) Line 2214 + 0x10 bytes C++
Axial.exe!CWnd::OnWndMsg(unsigned int message=273, unsigned int wParam=57616, long lParam=0, long * pResult=0x0018fc68) Line 1769 + 0x1e bytes C++
Axial.exe!CWnd::WindowProc(unsigned int message=273, unsigned int wParam=57616, long lParam=0) Line 1755 + 0x20 bytes C++
Axial.exe!SECMDIFrameWnd::WindowProc(unsigned int message=273, unsigned int wParam=57616, long lParam=0) Line 2685 + 0x14 bytes C++
Axial.exe!AfxCallWndProc(CWnd * pWnd=0x1a4acf78, HWND__ * hWnd=0x0005102a, unsigned int nMsg=273, unsigned int wParam=57616, long lParam=0) Line 240 + 0x1c bytes C++
Axial.exe!AfxWndProc(HWND__ * hWnd=0x0005102a, unsigned int nMsg=273, unsigned int wParam=57616, long lParam=0) Line 403 C++
user32.dll!753962fa()
user32.dll!75396d3a()
user32.dll!75396ce9()
user32.dll!753977c4()
user32.dll!75397bca()
Axial.exe!AfxInternalPumpMessage() Line 183 C++
Axial.exe!CWinThread::PumpMessage() Line 900 C++
Axial.exe!CWinThread::Run() Line 629 + 0xd bytes C++
Axial.exe!CWinApp::Run() Line 896 C++
Axial.exe!AfxWinMain(HINSTANCE__ * hInstance=0x00400000, HINSTANCE__ * hPrevInstance=0x00000000, char * lpCmdLine=0x07e78ffd, int nCmdShow=1) Line 47 + 0xd bytes C++
Axial.exe!WinMain(HINSTANCE__ * hInstance=0x00400000, HINSTANCE__ * hPrevInstance=0x00000000, char * lpCmdLine=0x07e78ffd, int nCmdShow=1) Line 34 C++
Axial.exe!__tmainCRTStartup() Line 263 + 0x2c bytes C
Axial.exe!WinMainCRTStartup() Line 182 C
kernel32.dll!768033aa()
ntdll.dll!772b9ef2()
ntdll.dll!772b9ec5()
Your help is greately appreciated.
Thanks.
It looks like the problem is SECWorkbookClientWnd::OnMDISetMenu. You're probably calling a function that is trying to send a message to a CWnd that is not yet created/attached.

How do I get a max number of bytes from a string?

In .NET 2.0, I need to send some strings across the wire, but when building my packets I need to limit them to only 255 bytes.
I was going to use
UnicodeEncoding.GetBytes(char* chars,int charCount, byte* bytes, int byteCount)
MSDN: http://msdn.microsoft.com/en-US/library/z2s6sc1d(v=vs.80)
but I can't compile my app with /unsafe, so this is out.
Here's the basic method I need to fill out:
private void GenerateSNMPObjectPacket(String value, int maxByteCount)
{
int byteCount = Encoding.UTF8.GetByteCount(value);
if (byteCount > maxByteCount)
byteCount = maxByteCount;
byte[] valueBytes = new byte[byteCount];
//somehow get UTF8 bytes into valueBytes
//do what I do with my byte array
}

Buffer Overflow When Declaring Char Array

I've never done any C++/COM work before, so I'm trying to hijack an existing solution and just alter it to my needs. The project was written and successfully compiled with VC 6 and I'm attempting to work with it now in 2010. I had to change a few references to get it to compile, but for some reason, the dll I generate is causing an exception on my system (the original works fine). Doing some research on the error, it looks like I'm getting a buffer overflow when I try to declare a char array.
bool CFile::simpleWrite(char* cData)
{
try{
// temp result variable
BOOL bResult = 0;
// file handle
HANDLE hFile = INVALID_HANDLE_VALUE;
// get the CMain singleton
CMain* m_pMain = CMain::GetInstance();
// this point gets synchronization to ensure we get unique file name...
char cDirFilename[MAX_PATH + 1];
GetLogFileName(cDirFilename, MAX_PATH);
// sanity check
if(strcmp(cDirFilename, "c:\\") == 0) assert(0);
// try and create a file
hFile = CreateFile( cDirFilename, GENERIC_WRITE, FILE_SHARE_READ,NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
// if have a good file handle
if(hFile != INVALID_HANDLE_VALUE){
size_t lenFileData = strlen(cData) + 72;
char* cFileData = new char[lenFileData];
_snprintf(cFileData, lenFileData, "<?xml version=\"1.0\"?>\r\n<RootElement>\r\n%s</RootElement>\r\n\0", cData);
...
Here is the declaration/assignment for cData (cXML in the calling method).
char cXML[EVENT_LOG_MAX_MESSAGE];
// get the CMain singleton
CMain* pMain = CMain::GetInstance();
long lThreadID = GetCurrentThreadId();
// put the parameters into XML format
pMain->BuildXML(cXML, EVENT_LOG_MAX_MESSAGE,errLogLevel,userActivityID,methodName,lineNumber,className,AppID,errorDescription,errorID,lThreadID);
// write the data to file
if(!simpleWrite(cXML))
...
BuildXML is doing a _snprintf into cXML and returning it.
Here is the stacktrace going from my call into some of the VC files.
Test.dll!_heap_alloc_base(unsigned int size) Line 55 C
Test.dll!_heap_alloc_dbg_impl(unsigned int nSize, int nBlockUse, const char * szFileName, int nLine, int * errno_tmp) Line 431 + 0x9 bytes C++
Test.dll!_nh_malloc_dbg_impl(unsigned int nSize, int nhFlag, int nBlockUse, const char * szFileName, int nLine, int * errno_tmp) Line 239 + 0x19 bytes C++
Test.dll!_nh_malloc_dbg(unsigned int nSize, int nhFlag, int nBlockUse, const char * szFileName, int nLine) Line 302 + 0x1d bytes C++
Test.dll!malloc(unsigned int nSize) Line 56 + 0x15 bytes C++
Test.dll!operator new(unsigned int size) Line 59 + 0x9 bytes C++
Test.dll!operator new[](unsigned int count) Line 6 + 0x9 bytes C++
Test.dll!CFile::simpleWrite(char * cData) Line 87 + 0xc bytes C++
I'm sure there is some stupid basic mistake, but I can't seem to get it figured out.
Your error is most likely somewhere else where you end up corrupting the heap. I notice you use strlen here without adding one for the terminating zero. Have a look in your code to see if you use strlen for allocating memory and copying somewhere, because I think you're corrupting the heap by allocating one byte too little and then strcpy'ing to it.
As I suspected, this was all my own stupidity. This COM application had a dependency that I wasn't aware of. Never saw anything trying to look for it in the process monitor and the project had a local copy of the file for compile purposes apparently. Thanks for the input though.

Resources