/*** * This implements the IUnknown method Release for this * class */ static ULONG WINAPI StgStreamImpl_Release( IStream* iface) { StgStreamImpl* This = impl_from_IStream(iface); ULONG ref = InterlockedDecrement(&This->ref); if (!ref) { TRACE("(%p)\n", This); /* * Release the reference we are holding on the parent storage. * IStorage_Release(&This->parentStorage->IStorage_iface); * * No, don't do this. Some apps call IStorage_Release without * calling IStream_Release first. If we grab a reference the * file is not closed, and the app fails when it tries to * reopen the file (Easy-PC, for example). Just inform the * storage that we have closed the stream */ if (This->parentStorage) StorageBaseImpl_RemoveStream(This->parentStorage, This); This->parentStorage = 0; HeapFree(GetProcessHeap(), 0, This); } return ref; }
/*** * This is the destructor of the StgStreamImpl class. * * This method will clean-up all the resources used-up by the given StgStreamImpl * class. The pointer passed-in to this function will be freed and will not * be valid anymore. */ static void StgStreamImpl_Destroy(StgStreamImpl* This) { TRACE("(%p)\n", This); /* * Release the reference we are holding on the parent storage. * IStorage_Release((IStorage*)This->parentStorage); * * No, don't do this. Some apps call IStorage_Release without * calling IStream_Release first. If we grab a reference the * file is not closed, and the app fails when it tries to * reopen the file (Easy-PC, for example). Just inform the * storage that we have closed the stream */ if(This->parentStorage) { StorageBaseImpl_RemoveStream(This->parentStorage, This); } This->parentStorage = 0; /* * Finally, free the memory used-up by the class. */ HeapFree(GetProcessHeap(), 0, This); }