Problem with safearray marshalling on 64bit windows

endasil
endasil used Ask the Experts™
on
Is there anything i need to do differently on win 64 to get safearray working?

I have the following code and it works fine on windows vista / 7 32 bit, but running on 64bit i get a  heap corruption error when leaving the scope of the function upon safeArrayDestroy. This is the first time i am trying to correct errors on a 64 bit system so i'm a bit fresh in the area and don't have many ideas on what can go wrong yet.

FAILURE_BUCKET_ID:  FILL_PATTERN_ffffffff_c0000374_OLEAUT32.dll!_SafeArrayDestroy
BUCKET_ID:  X64_APPLICATION_FAULT_FILL_PATTERN_ffffffff_OLEAUT32!_SafeArrayDestroy+.

callstack:


Calling application
-------------------
HRESULT CRegWriter::SetValue(LPCTSTR path, LPCTSTR var, DWORD dwType, const BYTE *lpData,DWORD cbData)
{
	if(m_object){

		CComSafeArrayBound bound[1];
		bound[0].SetCount(cbData);
		bound[0].SetLowerBound(0);
		CComSafeArray<BYTE> sar(bound);	
		for(unsigned int i = 0; i < cbData; i++)
		{
			sar.SetAt(i, lpData[i]);
		}
		HRESULT hr = m_object->RgWriteValue(_bstr_t(path), _bstr_t(var), dwType, sar);
		return hr;
	}

Target application
------------------
STDMETHODIMP MyRegClass::RgWriteValue(BSTR path, BSTR var, DWORD dwType, SAFEARRAY *indata)
{
	if(!SafePath(path)){					
		return E_FAIL;			
	}

	CComSafeArray<BYTE> sar;
	sar.Attach(indata);

	int size = sar.GetUpperBound() +1;
	BYTE* lpData = new BYTE[size];

	for(int i = 0; i < size; i++) 
	{
		lpData[i] = sar.GetAt(i);
	}

	HKEY hk = NULL;	
	DWORD err = RegCreateKeyEx(HKEY_LOCAL_MACHINE, path, 0,NULL,REG_OPTION_NON_VOLATILE,  KEY_READ | KEY_WRITE, NULL, &hk, NULL);
	
	if(err != ERROR_SUCCESS ){
		return err;
	}

	err = RegSetValueEx(hk, var , 0, dwType, lpData, size);		
	delete lpData;
	return err;
}

Open in new window

Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®

Commented:
Shouldn't be a
sar = new CComSafeArray<BYTE>(bound);  
somewhere in there?

Author

Commented:
Sorry, but i do not follow you here.

I pack the stuff into a CComSafeArray with the following code
 
 CComSafeArray<BYTE> sar(bound);
for(unsigned int i = 0; i < cbData; i++)
{
       sar.SetAt(i, lpData[i]);
}


Then in the other application i create a sar and attach it to the indata with

   CComSafeArray<BYTE> sar;
        sar.Attach(indata);

and then process the data in the sar. Where am i going wrong with that?

Commented:
oops, you're right...   ignore my comment.
Commented:
Solved the problem by adding sar.Detach() before leaving the function.

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial