static ULONG WINAPI ID3DXFileDataImpl_Release(ID3DXFileData *iface) { ID3DXFileDataImpl *This = impl_from_ID3DXFileData(iface); ULONG ref = InterlockedDecrement(&This->ref); TRACE("(%p)->(): new ref = %u\n", iface, ref); if (!ref) { ULONG i; for (i = 0; i < This->nb_children; i++) (This->children[i])->lpVtbl->Release(This->children[i]); HeapFree(GetProcessHeap(), 0, This->children); IDirectXFileData_Release(This->dxfile_data); HeapFree(GetProcessHeap(), 0, This); } return ref; }
static ULONG WINAPI IDirectXFileEnumObjectImpl_Release(IDirectXFileEnumObject* iface) { IDirectXFileEnumObjectImpl *This = impl_from_IDirectXFileEnumObject(iface); ULONG ref = InterlockedDecrement(&This->ref); TRACE("(%p/%p)->(): new ref %d\n", iface, This, ref); if (!ref) { ULONG i; for (i = 0; i < This->nb_xobjects; i++) IDirectXFileData_Release(This->pRefObjects[i]); if (This->mapped_memory) UnmapViewOfFile(This->mapped_memory); HeapFree(GetProcessHeap(), 0, This->decomp_buffer); HeapFree(GetProcessHeap(), 0, This); } return ref; }
ref = IDirectXFile_Release(lpDirectXFile); ok(ref == 0, "Got refcount %d, expected 0\n", ref); /* Nothing changes for all other objects */ ref = getRefcount( (IUnknown *) lpdxfeo); ok(ref == 1, "Got refcount %d, expected 1\n", ref); ref = getRefcount( (IUnknown *) lpdxfd); ok(ref == 2, "Got refcount %d, expected 2\n", ref); ref = IDirectXFileEnumObject_Release(lpdxfeo); ok(ref == 0, "Got refcount %d, expected 0\n", ref); /* Enum object releases references to all top level objects */ ref = getRefcount( (IUnknown *) lpdxfd); ok(ref == 1, "Got refcount %d, expected 1\n", ref); ref = IDirectXFileData_Release(lpdxfd); ok(ref == 0, "Got refcount %d, expected 0\n", ref); } static void test_CreateEnumObject(void) { HRESULT hr; ULONG ref; LPDIRECTXFILE lpDirectXFile = NULL; LPDIRECTXFILEENUMOBJECT lpdxfeo; LPDIRECTXFILEDATA lpdxfd; DXFILELOADMEMORY dxflm; BYTE* pdata; DWORD size; if (!pDirectXFileCreate)
/*** IDirectXFileEnumObject methods ***/ static HRESULT WINAPI IDirectXFileEnumObjectImpl_GetNextDataObject(IDirectXFileEnumObject* iface, LPDIRECTXFILEDATA* ppDataObj) { IDirectXFileEnumObjectImpl *This = impl_from_IDirectXFileEnumObject(iface); IDirectXFileDataImpl* object; HRESULT hr; if (!ppDataObj) return E_POINTER; *ppDataObj = NULL; TRACE("(%p/%p)->(%p)\n", This, iface, ppDataObj); if (This->nb_xobjects >= MAX_OBJECTS) { ERR("Too many objects\n"); return DXFILEERR_NOMOREOBJECTS; } /* Check if there are templates defined before the object */ if (!parse_templates(&This->buf, TRUE)) return DXFILEERR_PARSEERROR; if (!This->buf.rem_bytes) return DXFILEERR_NOMOREOBJECTS; hr = IDirectXFileDataImpl_Create(&object); if (FAILED(hr)) return hr; object->pobj = HeapAlloc(GetProcessHeap(), 0, sizeof(xobject)*MAX_SUBOBJECTS); if (!object->pobj) { ERR("Out of memory\n"); hr = DXFILEERR_BADALLOC; goto error; } object->pstrings = HeapAlloc(GetProcessHeap(), 0, MAX_STRINGS_BUFFER); if (!object->pstrings) { ERR("Out of memory\n"); hr = DXFILEERR_BADALLOC; goto error; } object->cur_enum_object = 0; object->level = 0; object->from_ref = FALSE; This->buf.pxo_globals = This->xobjects; This->buf.nb_pxo_globals = This->nb_xobjects; This->buf.level = 0; This->buf.pdata = NULL; This->buf.capacity = 0; This->buf.cur_pos_data = 0; This->buf.cur_pstrings = This->buf.pstrings = object->pstrings; This->buf.pxo = This->xobjects[This->nb_xobjects] = This->buf.pxo_tab = object->pobj; This->buf.pxo->pdata = NULL; This->buf.pxo->nb_subobjects = 1; if (!parse_object(&This->buf)) { WARN("Object is not correct\n"); hr = DXFILEERR_PARSEERROR; goto error; } *ppDataObj = (LPDIRECTXFILEDATA)object; /* Get a reference to created object */ This->pRefObjects[This->nb_xobjects] = (LPDIRECTXFILEDATA)object; IDirectXFileData_AddRef(This->pRefObjects[This->nb_xobjects]); This->nb_xobjects++; return DXFILE_OK; error: IDirectXFileData_Release(&object->IDirectXFileData_iface); return hr; }