Link to home
Start Free TrialLog in
Avatar of endasil
endasil

asked on

Problem with safearray marshalling on 64bit windows

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

Avatar of graye
graye
Flag of United States of America image

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

ASKER

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?
oops, you're right...   ignore my comment.
ASKER CERTIFIED SOLUTION
Avatar of endasil
endasil

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial