is there a bug in mfc71d.dll?

G

Guest

this is the function that the problem lies in. it is in MFC file ctlpset.cpp

BOOL COleControl::GetPropsetData(LPFORMATETC lpFormatEtc,
LPSTGMEDIUM lpStgMedium, REFCLSID fmtid)
{
ASSERT_VALID(this);
ASSERT(AfxIsValidAddress(lpFormatEtc, sizeof(FORMATETC), FALSE));
ASSERT(AfxIsValidAddress(lpStgMedium, sizeof(STGMEDIUM)));

BOOL bGetDataHere = (lpStgMedium->tymed != TYMED_NULL);

// Allow IStream or IStorage as the storage medium.

if (!(lpFormatEtc->tymed & (TYMED_ISTREAM|TYMED_ISTORAGE)))
{
TRACE(traceAppMsg, 0, "Propset only supported for stream or storage.\n");
return FALSE;
}

LPSTORAGE lpStorage = NULL; // here they initialize the lpStorage,
lpStream to NULL
LPSTREAM lpStream = NULL;
//then they test whether the output file is a stream or storage.

if (lpFormatEtc->tymed & TYMED_ISTORAGE)
{

//if it is storage,then the lpStorage is assigned a new value
//but lpStream keep the NULL value.

// Caller wants propset data in a storage object.

if (bGetDataHere)
{
// Use the caller-supplied storage object.
lpStorage = lpStgMedium->pstg;
}
else
{
// Create a storage object on a memory ILockBytes implementation.
LPLOCKBYTES lpLockBytes = NULL;

if (FAILED(CreateILockBytesOnHGlobal(NULL, TRUE, &lpLockBytes)))
{
TRACE(traceAppMsg, 0, "CreateILockBytesOnHGlobal failed.\n");
return FALSE;
}

ASSERT_POINTER(lpLockBytes, ILockBytes);

if (FAILED(StgCreateDocfileOnILockBytes(lpLockBytes,
STGM_SHARE_EXCLUSIVE|STGM_CREATE|STGM_READWRITE, 0,
&lpStorage)))
{
TRACE(traceAppMsg, 0, "StgCreateDocfileOnILockBytes failed.\n");
lpLockBytes->Release();
return FALSE;
}

// Docfile now has reference to ILockBytes, so release ours.
lpLockBytes->Release();
}

ASSERT_POINTER(lpStorage, IStorage);

// Create a stream within the storage.
if (FAILED(lpStorage->CreateStream(OLESTR("Contents"),
STGM_SHARE_EXCLUSIVE|STGM_CREATE|STGM_READWRITE, 0, 0,
&lpStream)))
{
TRACE(traceAppMsg, 0, "IStorage::CreateStream failed.\n");
if (!bGetDataHere)
lpStorage->Release();
return FALSE;
}
}
else
{
//if it is stream ,then the lpStream is assigned a new value
//but lpStorage keep the NULL value.
// Caller wants propset data in a stream object.

if (bGetDataHere)
{
// Use the caller-supplied stream object
lpStream = lpStgMedium->pstm;
}
else
{
lpStream = _AfxCreateMemoryStream();
if (lpStream == NULL)
return FALSE;
}
}

//but in later program, we can find that, if there is a fail in the
process, they always release lpStream,lpStorage togetgher. so we can tell,
if our ocx control adhere to MS's rule, it runs fluently, if not, it may have
problem.
ASSERT_POINTER(lpStream, IStream);

// Create the property set.

CLSID clsid;
GetClassID(&clsid);
CPropertySet pset(clsid);
pset.SetOSVersion(MAKELONG(LOWORD(GetVersion()), OSTYPE));
CPropertySection* ppsec = pset.AddSection(fmtid);
if (ppsec == NULL)
{
TRACE(traceAppMsg, 0, "CPropertySet::AddSection failed.\n");
lpStream->Release();
lpStorage->Release();
return FALSE;
}

// Set the name, based on the ambient display name (from the container).
ppsec->SetSectionName(AmbientDisplayName());

CPropsetPropExchange propx(*ppsec, lpStorage, FALSE);

BOOL bPropExchange = FALSE;
TRY
{
DoPropExchange(&propx);
bPropExchange = TRUE;
}
END_TRY

if (!bPropExchange)
{
TRACE(traceAppMsg, 0, "DoPropExchange failed.\n");
lpStream->Release();
lpStorage->Release();
return FALSE;
}

// Store the property set in the stream.

if (!pset.WriteToStream(lpStream))
{
TRACE(traceAppMsg, 0, "CPropertySet::WriteToStream failed.\n");
lpStream->Release();
lpStorage->Release();
return FALSE;
}

// Return the property set in the requested medium.

if (lpFormatEtc->tymed & TYMED_ISTORAGE)
{
// Return as a storage object.

ASSERT_POINTER(lpStorage, IStorage);
lpStream->Release();
lpStgMedium->pstg = lpStorage;
lpStgMedium->tymed = TYMED_ISTORAGE;
lpStgMedium->pUnkForRelease = NULL;
}
else
{
// Return as a stream.

ASSERT_POINTER(lpStream, IStream);
lpStgMedium->pstm = lpStream;
lpStgMedium->tymed = TYMED_ISTREAM;
lpStgMedium->pUnkForRelease = NULL;
}

return TRUE;
}
 
G

Guest

I have also met this problem.

I use wizard to create a ocx, and without add anyting in it. when I plug it
in my form, and use it's Idataobject->getdatahere to save it's properties to
a stream.
it exposes a crash. I have found MS has done some modification in the MFC
class.
but I don't know why?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top