I'm now moving a big software from OWL to MFC, most of the mission has been done, but I face alot of problems like this one when the application is closing this exception arises
When I clicked break the debuger lead me to this
that was the call stack
msdart.dll!_UMSEnterCSWraper() Unknown
msado15.dll!ATL::AtlModuleGetClassObject(struct ATL::_ATL_MODULE *,struct _GUID const &,struct _GUID const &,void * *) Unknown
msado15.dll!ATL::CComModule::GetClassObject(struct _GUID const &,struct _GUID const &,void * *) Unknown
msado15.dll!_DllGetClassObject#12() Unknown
ole32.dll!CClassCache::CDllPathEntry::DllGetClassObject(const _GUID & rclsid, const _GUID & riid, IUnknown * * ppUnk, int fMakeValid) Line 3317 C++
ole32.dll!CClassCache::CDllFnPtrMoniker::BindToObject(const _GUID & riid, void * * ppvResult) C++
ole32.dll!CClassCache::SearchForLoadedClass(const ACTIVATION_PROPERTIES & ap, CClassCache::CDllClassEntry * * ppDCE) C++
ole32.dll!ICoCreateInstanceEx(const _GUID & Clsid, IUnknown * punkOuter, unsigned long dwClsCtx, _COSERVERINFO * pServerInfo, unsigned long dwCount, unsigned long dwActvFlags, tagMULTI_QI * pResults, ActivationPropertiesIn * pActIn) Line 1163 C++
ole32.dll!CComActivator::DoCreateInstance(const _GUID & Clsid, IUnknown * punkOuter, unsigned long dwClsCtx, _COSERVERINFO * pServerInfo, unsigned long dwCount, tagMULTI_QI * pResults, ActivationPropertiesIn * pActIn) Line 332 C++
ole32.dll!CoCreateInstanceEx(const _GUID & Clsid, IUnknown * punkOuter, unsigned long dwClsCtx, _COSERVERINFO * pServerInfo, unsigned long dwCount, tagMULTI_QI * pResults) Line 157 C++
ole32.dll!CoCreateInstance(const _GUID & rclsid, IUnknown * pUnkOuter, unsigned long dwContext, const _GUID & riid, void * * ppv) Line 110 C++
> DBCore.dll!_com_ptr_t<_com_IIID<ADODB::_Command,&_GUID_b08400bd_f9d1_4d02_b856_71d5dba123e9> >::CreateInstance(const _GUID & rclsid, IUnknown * pOuter, unsigned long dwClsContext) Line 586 C++
DBCore.dll!TADOCommand::Init(TADOConnection * connection) Line 32 C++
DBCore.dll!TADOCommand::TADOCommand(TADOConnection * connection) Line 8 C++
AmnDbase.dll!TQuery::Init() Line 335 C++
AmnDbase.dll!TQuery::TQuery(const TDatabase * db, TTable * Tbl) Line 304 C++
AmnDbase.dll!TDirectQuery::TDirectQuery(const TDatabase * db) Line 932 C++
AmnDbase.dll!CommitUnsavedTransactions(TDatabase * db) Line 674 C++
AmnDbase.dll!TDatabase::Disconnect() Line 427 C++
AmnDbase.dll!TDatabase::CloseDb() Line 455 C++
AmnDbase.dll!TDatabase::Close() Line 417 C++
AmnLib2.dll!TStoreFile::Close() Line 3275 C++
AmnLib2.dll!TStoreFile::~TStoreFile() Line 1040 C++
AmnLib2.dll!`GetStoreFile'::`2'::`dynamic atexit destructor for 'StoreFile''() C++
AmnLib2.dll!_CRT_INIT(void * hDllHandle, unsigned long dwReason, void * lpreserved) Line 415 C
AmnLib2.dll!__DllMainCRTStartup(void * hDllHandle, unsigned long dwReason, void * lpreserved) Line 526 C
AmnLib2.dll!_DllMainCRTStartup(void * hDllHandle, unsigned long dwReason, void * lpreserved) Line 476 C
this is the code that called the CreateInstance
/// Init the command instance.
void TADOCommand::Init( TADOConnection* connection)
{
m_CmdText = "";
m_nRecordsAffected = 0;
m_Command = NULL;
m_ResultSet = NULL;
m_CmdConnection = NULL;
m_CmdRecordset = NULL;
if( connection->IsNull())
return;
m_Command.CreateInstance( __uuidof( Command));
SetConnection( connection);
SetCommandTimeOut( connection->GetCommandTimeout());
}
I want the code to stay working without changing any code especialy in the database layer is this due to call of couninitialize from MFC?? how can I detect that or solve this issue?
and the m_Command was defined as
_CommandPtr m_Command;
and it is com interface first it is set to null then call CreateInstance it works fine each time unless the last time it fails with this exception
The code seams to be executed when your DLL is unloaded or loaded, as far as I can see in the callstack.
When this is "loading code" the question arrises: Why is the LDL loaded again.
But using COM in DllMain is no good at all. See here
COM should never be used inside a DllMain code.
I suppose that your DLL is unloaded after the MFC already called CoUninitialize. Or your DLL is reloaded by some code, that shouldn't be executed in the shut down of your application.
Related
I've been spending way too much time on this problem.
I am developing a project that uses COM in the Visual Studio 2019 Enterprise edition. I have the following interface defined in my IDL file:
// IIOLinkBusMdlExt
[
object,
uuid(1E0C9381-E5F6-4C39-8660-C64A519FDC51),
dual,
nonextensible,
helpstring("IIOLinkBusMdlExt Interface"),
pointer_default(unique)
]
interface IIOLinkBusMdlExt : IDispatch
{
[propget, id(1), helpstring("ChannelMode getter")]
HRESULT ChannelMode(
[in] unsigned short ChannelNumber,
[out, retval] enum IOLinkChannelMode* pChannelMode
);
[propput, id(1), helpstring("ChannelMode setter")]
HRESULT ChannelMode(
[in] unsigned short ChannelNumber,
[in] enum IOLinkChannelMode ChannelMode
);
[propget, id(2), helpstring("method GetChannelModeString")]
HRESULT ChannelModeString(
[in] unsigned short ChannelNumber,
[out, retval] BSTR* pModeString
);
[id(3), helpstring("method Initialize")]
HRESULT Initialize(
[in] SAFEARRAY(IOLinkChannelMode)
);
};
Note that the I in "Initialize" is capitalized.
But the .tlh file contains this:
struct __declspec(uuid("1e0c9381-e5f6-4c39-8660-c64a519fdc51"))
IIOLinkBusMdlExt : IDispatch
{
//
// Raw methods provided by interface
//
virtual HRESULT __stdcall get_ChannelMode (
/*[in]*/ unsigned short ChannelNumber,
/*[out,retval]*/ enum IOLinkChannelMode * pChannelMode ) = 0;
virtual HRESULT __stdcall put_ChannelMode (
/*[in]*/ unsigned short ChannelNumber,
/*[in]*/ enum IOLinkChannelMode pChannelMode ) = 0;
virtual HRESULT __stdcall get_ChannelModeString (
/*[in]*/ unsigned short ChannelNumber,
/*[out,retval]*/ BSTR * pModeString ) = 0;
virtual HRESULT __stdcall initialize (
/*[in]*/ SAFEARRAY * __MIDL__IIOLinkBusMdlExt0000 ) = 0;
};
Now the i in initialize is lower case!
I verified that the .tlh file is getting rebuilt when the IDL changes by removing the declaration of Initialize() from the IDL and then looking at the .tlh file. The method was not there. Then I put the Initialize() declaration, spelled correctly, back into the IDL, rebuilt, and the method reappeared, spelled incorrectly, in the .tlh file.
What is happening?
I'm in process of updating the client to support TLS 1.3. When trying to connect to TLS 1.3 server, client is reporting "Internal error". Wireshark traces showing that server responded with Verify Certificate, Finished message. But client fails to generate the keys with following call stack -
libcrypto-1_1.dll!ASN1_get_object(const unsigned char * * pp, long * plength, int * ptag, int * pclass, long omax) Line 101
libcrypto-1_1.dll!asn1_item_embed_d2i(ASN1_VALUE_st * * pval, const unsigned char * * in, long len, const ASN1_ITEM_st * it, int tag, int aclass, char opt, ASN1_TLC_st * ctx, int depth) Line 287
[Inline Frame] libcrypto-1_1.dll!ASN1_item_ex_d2i(ASN1_VALUE_st * *) Line 124
libcrypto-1_1.dll!ASN1_item_d2i(ASN1_VALUE_st * * pval, const unsigned char * * in, long len, const ASN1_ITEM_st * it) Line 114
libcrypto-1_1.dll!d2i_X509_SIG(X509_sig_st * * a, const unsigned char * * in, long len) Line 21
MyCode.dll!PrivateKeyOperationCallback(ssl_st * pSSL, unsigned int type, unsigned int rsakeysize, const unsigned char * hash, unsigned int hashlen, unsigned char * sig, unsigned int sigmaxlen, unsigned int * siglen)
[Inline Frame] MyCode.dll!My_RSA_private_encrypt1(ssl_st *)
MyCode.dll!My_RSA_private_encrypt(int flen, const unsigned char * from, unsigned char * to, rsa_st * rsa, int padding)
libcrypto-1_1.dll!pkey_rsa_sign(evp_pkey_ctx_st * ctx, unsigned char * sig, unsigned int * siglen, const unsigned char * tbs, unsigned int tbslen) Line 185
libcrypto-1_1.dll!EVP_PKEY_sign(evp_pkey_ctx_st * ctx, unsigned char * sig, unsigned int * siglen, const unsigned char * tbs, unsigned int tbslen) Line 66
libcrypto-1_1.dll!EVP_DigestSignFinal(evp_md_ctx_st * ctx, unsigned char * sigret, unsigned int * siglen) Line 148
libcrypto-1_1.dll!EVP_DigestSign(evp_md_ctx_st * ctx, unsigned char * sigret, unsigned int * siglen, const unsigned char * tbs, unsigned int tbslen) Line 170
libssl-1_1.dll!tls_construct_cert_verify(ssl_st * s, wpacket_st * pkt) Line 307
libssl-1_1.dll!write_state_machine(ssl_st * s) Line 843
libssl-1_1.dll!state_machine(ssl_st * s, int server) Line 443
libssl-1_1.dll!ossl_statem_connect(ssl_st * s) Line 250
libssl-1_1.dll!SSL_do_handshake(ssl_st * s) Line 3661
libssl-1_1.dll!SSL_connect(ssl_st * s) Line 1662
ASN1_get_object returns "Header Too Long". Same client is able to connect to same server with TLS 1.2 and even able to connect to same server from browser with TLS 1.3.
Issue is specifically with mTLS (not with TLS).
That code path is not unique to TLS 1.3, and has been present in OpenSSL / libcrypto for quite a long time.
The error is occurring because an ASN.1 object encoded in the certificate has a definite length that exceeds the length of the data provided. Either the certificate data is corrupt, or the server is not sending the correct data.
If you're implementing the TLS 1.3 client yourself it is possible that your code is not properly handling certificate encryption, leading to garbled data being sent into the ASN.1 parsing code paths. Without further information (Wireshark dumps and the certificate itself) it is impossible to know what the specific error is.
I'm using log4cplus as a logger for both CLR and non-CLR C++/CLI code and C# code so for that reason I'm using the Unicode x64 build of log4cplus, log4cplusU.lib/dll.
If I run the following code in a non-CLR C++/CLI x64 console application, I get a memory access exception.
int _tmain(int argc, _TCHAR* argv[])
{
std::string LogFileName = "log4cplus.log";
auto db = log4cplus::helpers::towstring(LogFileName);
Exception:
Unhandled exception at 0x00007FF8E4A1CDA1 (msvcr120.dll) in ConsoleApplication1.exe: 0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF.
What's up?
I'm using Visual Studio 2013. My call stack at the exception looks like:
> log4cplusU.dll!std::vector<wchar_t,std::allocator<wchar_t> >::vector<wchar_t,std::allocator<wchar_t> >(unsigned __int64 _Count) Line 691 C++
log4cplusU.dll!log4cplus::helpers::towstring_internal(std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> > & outstr, const char * src, unsigned __int64 size, const std::locale & loc) Line 70 C++
log4cplusU.dll!log4cplus::helpers::towstring(const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & src) Line 124 C++
ConsoleApplication1.exe!wmain(int argc, wchar_t * * argv) Line 24 C++
ConsoleApplication1.exe!__tmainCRTStartup() Line 623 C
At the point where the exception fires in std::vector(size_type), _Count is a crazy number.
_Count 14757396612626683276 unsigned __int64
The reason appears to be that the string parameter gets scrambled or misinterpreted.
The same problem manifests itself on non-Unicode DEBUG MODE builds of log4cplus in unmanaged code on VS but not in release mode builds.
For example:
#include <string>
#include "stdafx.h"
#include <iostream>
#include <log4cplus/loggingmacros.h>
#include <log4cplus/configurator.h>
int _tmain(int argc, _TCHAR* argv[])
{
std::string LogConfigFileName = "WhenLoggingCppManagedCode.properties";
try
{
log4cplus::tstring cfn = LogConfigFileName;
log4cplus::PropertyConfigurator::doConfigure(cfn);
std::cout << "Good Deadpool." << std::endl;
}
catch (...)
{
std::cout << "BAD Deadpool." << std::endl;
}
std::cin.get();
return 0;
}
I haven't make any change in this demo, and it works fine firstly. But after lunch, I ran it again, the debugger crashed, and I got an error(below), the debugger reached this line in qscopedpointer.h:
inline T *data() const
{
return d;
}
error:
Unhandled exception at 0x00007FFDE604516A (Qt5Guid.dll) in Polyhedron_3.exe: 0xC000041D: Access violation reading location 0x00000004: an unhandled exception was encountered during a user callback.
stack trace like this:
Qt5Guid.dll!QScopedPointer >::data() Line 135 C++
Qt5Guid.dll!qGetPtrHelper >>(const QScopedPointer > & p) Line 983 C++
Qt5Guid.dll!QScreen::d_func() Line 59 C++
Qt5Guid.dll!QScreen::geometry() Line 302 C++
qwindowsd.dll!QWindowsWindow::isFullScreen_sys() Line 1630 C++
qwindowsd.dll!QWindowsWindow::handleResized(int wParam) Line 1394 C++
qwindowsd.dll!QWindowsContext::windowsProc(HWND__ * hwnd, unsigned int message,
QtWindows::WindowsEventType et, unsigned __int64 wParam, __int64 lParam, __int64 * result) Line 1011 C++
qwindowsd.dll!qWindowsWndProc(HWND__ * hwnd, unsigned int message, unsigned __int64
wParam, __int64 lParam) Line 1271 C++
qwindowsd.dll!qWindowsWndProc(HWND__ * hwnd, unsigned int message, unsigned __int64 wParam, __int64 lParam) Line 1280 C++
qwindowsd.dll!WindowCreationData::initialize(const QWindow * w, HWND__ * hwnd, bool frameChange, double opacityLevel) Line 707 C++
qwindowsd.dll!QWindowsWindow::setWindowFlags_sys(QFlags wt,
unsigned int flags) Line 1571 C++
qwindowsd.dll!QWindowsWindow::setParent_sys(const QPlatformWindow * parent) Line 1294 C++
qwindowsd.dll!QWindowsWindow::setParent(const QPlatformWindow * newParent) Line 1260 C++
Qt5Guid.dll!QWindow::setParent(QWindow * parent) Line 614 C++
Qt5Widgetsd.dll!q_createNativeChildrenAndSetParent(const QWidget * parentWidget) Line 1377 C++
Qt5Widgetsd.dll!q_createNativeChildrenAndSetParent(const QWidget * parentWidget) Line 1382 C++
Qt5Widgetsd.dll!QWidgetPrivate::create_sys(unsigned __int64 window, bool initializeWindow, bool destroyOldWindow) Line 1481 C++
Qt5Widgetsd.dll!QWidget::create(unsigned __int64 window, bool initializeWindow, bool destroyOldWindow) Line 1321 C++
Qt5Widgetsd.dll!QWidget::setVisible(bool visible) Line 8060 C++
Qt5Widgetsd.dll!QWidget::show() Line 7671 C++
Polyhedron_3.exe!main(int argc, char * * argv) Line 51 C++
Polyhedron_3.exe!__tmainCRTStartup() Line 626 C
Polyhedron_3.exe!mainCRTStartup() Line 466 C
===============================
I have no idea what the issue is. I appreciate if anyone could give me some advise to solve this.
Thanks.
I am trying to code an alternative to LoadLibrary function, based on the idea of calling the function LdrLoadDll from ntdll.
This function needs as a parameter the dll file to load, in a UNICODE_STRING format.
I really can't get what I am doing wrong here (string seems to be correctly initialized), but when LdrLoadDll is called, I get the following error:
Unhandled exception in "Test.exe" (NTDLL.DLL): 0xC0000005: Access Violation.
I use Visual C++ 6.0 for this test, and I am using Windows 7 64 bit.
I post full code here, thanks in advance for any help:
#include <Windows.h>
typedef LONG NTSTATUS; //To be used with VC++ 6, since NTSTATUS type is not defined
typedef struct _UNICODE_STRING { //UNICODE_STRING structure
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING;
typedef UNICODE_STRING *PUNICODE_STRING;
typedef NTSTATUS (WINAPI *fLdrLoadDll) //LdrLoadDll function prototype
(
IN PWCHAR PathToFile OPTIONAL,
IN ULONG Flags OPTIONAL,
IN PUNICODE_STRING ModuleFileName,
OUT PHANDLE ModuleHandle
);
/**************************************************************************
* RtlInitUnicodeString (NTDLL.#)
*
* Initializes a buffered unicode string.
*
* RETURNS
* Nothing.
*
* NOTES
* Assigns source to target->Buffer. The length of source is assigned to
* target->Length and target->MaximumLength. If source is NULL the length
* of source is assumed to be 0.
*/
void WINAPI RtlInitUnicodeString(
PUNICODE_STRING target, /* [I/O] Buffered unicode string to be initialized */
PCWSTR source) /* [I] '\0' terminated unicode string used to initialize target */
{
if ((target->Buffer = (PWSTR) source))
{
unsigned int length = lstrlenW(source) * sizeof(WCHAR);
if (length > 0xfffc)
length = 0xfffc;
target->Length = length;
target->MaximumLength = target->Length + sizeof(WCHAR);
}
else target->Length = target->MaximumLength = 0;
}
NTSTATUS LoadDll( LPCSTR lpFileName)
{
HMODULE hmodule = GetModuleHandleA("ntdll.dll");
fLdrLoadDll _LdrLoadDll = (fLdrLoadDll) GetProcAddress ( hmodule, "LdrLoadDll" );
int AnsiLen = lstrlenA(lpFileName);
BSTR WideStr = SysAllocStringLen(NULL, AnsiLen);
::MultiByteToWideChar(CP_ACP, 0, lpFileName, AnsiLen, WideStr, AnsiLen);
UNICODE_STRING usDllFile;
RtlInitUnicodeString(&usDllFile, WideStr); //Initialize UNICODE_STRING for LdrLoadDll function
::SysFreeString(WideStr);
NTSTATUS result = _LdrLoadDll(NULL, LOAD_WITH_ALTERED_SEARCH_PATH, &usDllFile,0); //Error on this line!
return result;
}
void main()
{
LoadDll("Kernel32.dll");
}
in
_LdrLoadDll(NULL, LOAD_WITH_ALTERED_SEARCH_PATH, &usDllFile,0);
last parameter can't be zero
you can't call SysFreeString before you call _LdrLoadDll,
since the usDllFile.buffer parameter points to this string