ole32: GIT can be released on process detach only.
This commit is contained in:
parent
05528ea01b
commit
98f3ecc32a
|
@ -4590,6 +4590,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID reserved)
|
|||
|
||||
case DLL_PROCESS_DETACH:
|
||||
if (reserved) break;
|
||||
release_std_git();
|
||||
COMPOBJ_UninitProcess();
|
||||
RPC_UnregisterAllChannelHooks();
|
||||
COMPOBJ_DllList_Free();
|
||||
|
|
|
@ -174,6 +174,7 @@ struct oletls
|
|||
|
||||
/* Global Interface Table Functions */
|
||||
extern IGlobalInterfaceTable *get_std_git(void) DECLSPEC_HIDDEN;
|
||||
extern void release_std_git(void) DECLSPEC_HIDDEN;
|
||||
extern HRESULT StdGlobalInterfaceTable_GetFactory(LPVOID *ppv) DECLSPEC_HIDDEN;
|
||||
|
||||
HRESULT COM_OpenKeyForCLSID(REFCLSID clsid, LPCWSTR keyname, REGSAM access, HKEY *key) DECLSPEC_HIDDEN;
|
||||
|
|
|
@ -66,7 +66,6 @@ typedef struct StdGlobalInterfaceTableImpl
|
|||
{
|
||||
IGlobalInterfaceTable IGlobalInterfaceTable_iface;
|
||||
|
||||
ULONG ref;
|
||||
struct list list;
|
||||
ULONG nextCookie;
|
||||
|
||||
|
@ -89,16 +88,6 @@ static inline StdGlobalInterfaceTableImpl *impl_from_IGlobalInterfaceTable(IGlob
|
|||
return CONTAINING_RECORD(iface, StdGlobalInterfaceTableImpl, IGlobalInterfaceTable_iface);
|
||||
}
|
||||
|
||||
/** This destroys it again. It should revoke all the held interfaces first **/
|
||||
static void StdGlobalInterfaceTable_Destroy(void* This)
|
||||
{
|
||||
TRACE("(%p)\n", This);
|
||||
FIXME("Revoke held interfaces here\n");
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
std_git = NULL;
|
||||
}
|
||||
|
||||
/***
|
||||
* A helper function to traverse the list and find the entry that matches the cookie.
|
||||
* Returns NULL if not found. Must be called inside git_section critical section.
|
||||
|
@ -147,25 +136,13 @@ StdGlobalInterfaceTable_QueryInterface(IGlobalInterfaceTable* iface,
|
|||
static ULONG WINAPI
|
||||
StdGlobalInterfaceTable_AddRef(IGlobalInterfaceTable* iface)
|
||||
{
|
||||
StdGlobalInterfaceTableImpl* const This = impl_from_IGlobalInterfaceTable(iface);
|
||||
|
||||
/* InterlockedIncrement(&This->ref); */
|
||||
return This->ref;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static ULONG WINAPI
|
||||
StdGlobalInterfaceTable_Release(IGlobalInterfaceTable* iface)
|
||||
{
|
||||
StdGlobalInterfaceTableImpl* const This = impl_from_IGlobalInterfaceTable(iface);
|
||||
|
||||
/* InterlockedDecrement(&This->ref); */
|
||||
if (This->ref == 0) {
|
||||
/* Hey ho, it's time to go, so long again 'till next weeks show! */
|
||||
StdGlobalInterfaceTable_Destroy(This);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return This->ref;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/***
|
||||
|
@ -387,13 +364,12 @@ IGlobalInterfaceTable* get_std_git(void)
|
|||
if (!newGIT) return NULL;
|
||||
|
||||
newGIT->IGlobalInterfaceTable_iface.lpVtbl = &StdGlobalInterfaceTableImpl_Vtbl;
|
||||
newGIT->ref = 1;
|
||||
list_init(&newGIT->list);
|
||||
newGIT->nextCookie = 0xf100; /* that's where windows starts, so that's where we start */
|
||||
|
||||
if (InterlockedCompareExchangePointer((void**)&std_git, &newGIT->IGlobalInterfaceTable_iface, NULL))
|
||||
{
|
||||
StdGlobalInterfaceTable_Destroy(newGIT);
|
||||
HeapFree(GetProcessHeap(), 0, newGIT);
|
||||
}
|
||||
else
|
||||
TRACE("Created the GIT at %p\n", newGIT);
|
||||
|
@ -401,3 +377,23 @@ IGlobalInterfaceTable* get_std_git(void)
|
|||
|
||||
return std_git;
|
||||
}
|
||||
|
||||
void release_std_git(void)
|
||||
{
|
||||
StdGlobalInterfaceTableImpl *git;
|
||||
StdGITEntry *entry, *entry2;
|
||||
|
||||
if (!std_git) return;
|
||||
|
||||
git = impl_from_IGlobalInterfaceTable(std_git);
|
||||
LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &git->list, StdGITEntry, entry)
|
||||
{
|
||||
list_remove(&entry->entry);
|
||||
|
||||
CoReleaseMarshalData(entry->stream);
|
||||
IStream_Release(entry->stream);
|
||||
HeapFree(GetProcessHeap(), 0, entry);
|
||||
}
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, git);
|
||||
}
|
||||
|
|
|
@ -2806,6 +2806,7 @@ static void test_globalinterfacetable(void)
|
|||
DWORD ret;
|
||||
IUnknown *object;
|
||||
IClassFactory *cf;
|
||||
ULONG ref;
|
||||
|
||||
trace("test_globalinterfacetable\n");
|
||||
cLocks = 0;
|
||||
|
@ -2821,6 +2822,16 @@ static void test_globalinterfacetable(void)
|
|||
hr = CoCreateInstance(&CLSID_StdGlobalInterfaceTable, NULL, CLSCTX_INPROC_SERVER, &IID_IGlobalInterfaceTable, (void **)&git);
|
||||
ok_ole_success(hr, CoCreateInstance);
|
||||
|
||||
ref = IGlobalInterfaceTable_AddRef(git);
|
||||
ok(ref == 1, "ref=%d\n", ref);
|
||||
ref = IGlobalInterfaceTable_AddRef(git);
|
||||
ok(ref == 1, "ref=%d\n", ref);
|
||||
|
||||
ref = IGlobalInterfaceTable_Release(git);
|
||||
ok(ref == 1, "ref=%d\n", ref);
|
||||
ref = IGlobalInterfaceTable_Release(git);
|
||||
ok(ref == 1, "ref=%d\n", ref);
|
||||
|
||||
hr = IGlobalInterfaceTable_RegisterInterfaceInGlobal(git, (IUnknown *)&Test_ClassFactory, &IID_IClassFactory, &cookie);
|
||||
ok_ole_success(hr, IGlobalInterfaceTable_RegisterInterfaceInGlobal);
|
||||
|
||||
|
|
Loading…
Reference in New Issue