Aug 13, 2005

VS 2003 ATL weirdness

Given some ATL com object, excerpt from the idl:

HRESULT Hash(
[in] BSTR PlainText,
[out, retval] BSTR* HashResult);

Nothing esoteric:

STDMETHODIMP CCrypto::Hash(BSTR PlainText, BSTR* HashResult)
{
if (PlainText==NULL)
return E_INVALIDARG;

if (HashResult==NULL)
return E_INVALIDARG;

int plainutf8len = WideCharToMultiByte(CP_UTF8,NULL,
PlainText,SysStringLen(PlainText),NULL,NULL,NULL,NULL);
...

Mizerably fails in the following ASP snippet:

set crypto = CreateObject("someproj.Crypto")
hash = crypto.Hash(Request("pass"))
set crypto = Nothing

debugger shows that it dies after processing the whole asp script here:

70955C1B je CRequestHit::~CRequestHit+25h (70955C23h)
70955C1D mov ecx,dword ptr [eax]
70955C1F push eax
70955C20 call dword ptr [ecx+8] <-- ecx=0, ecx+8 is goodbye
70955C23 mov eax,dword ptr [esi+20h]
70955C26 test eax,eax
70955C28 je CRequestHit::~CRequestHit+32h (70955C30h)

Works ok in the following:

set crypto = CreateObject("someproj.Crypto")
hash = crypto.Hash(Cstr(Request("pass")))
set crypto = Nothing

Scary...


Now, I found how to make it work without Cstr, actually by checking something else. It appears to be some problem with injected implementation of IDispatch, changing

class ATL_NO_VTABLE CCrypto :
public ICrypto

to

class ATL_NO_VTABLE CCrypto :
public IDispatchImpl<ICrypto>

Fixes this.

No comments: