Module: wine Branch: master Commit: 2f21130f2e922614382425b702b90bc581d526e4 URL: http://source.winehq.org/git/wine.git/?a=commit;h=2f21130f2e922614382425b702...
Author: Nikolay Sivov nsivov@codeweavers.com Date: Sun Aug 18 09:10:18 2013 +0400
ole32: Fix standard GIT initialization.
---
dlls/ole32/compobj.c | 8 +----- dlls/ole32/compobj_private.h | 4 +-- dlls/ole32/git.c | 43 ++++++++++++++++++++++++----------------- 3 files changed, 28 insertions(+), 27 deletions(-)
diff --git a/dlls/ole32/compobj.c b/dlls/ole32/compobj.c index 92ace8a..710f21e 100644 --- a/dlls/ole32/compobj.c +++ b/dlls/ole32/compobj.c @@ -2905,15 +2905,11 @@ HRESULT WINAPI CoCreateInstance(
/* * The Standard Global Interface Table (GIT) object is a process-wide singleton. - * Rather than create a class factory, we can just check for it here */ if (IsEqualIID(rclsid, &CLSID_StdGlobalInterfaceTable)) { - if (StdGlobalInterfaceTableInstance == NULL) - StdGlobalInterfaceTableInstance = StdGlobalInterfaceTable_Construct(); - hres = IGlobalInterfaceTable_QueryInterface((IGlobalInterfaceTable*)StdGlobalInterfaceTableInstance, - iid, - ppv); + IGlobalInterfaceTable *git = get_std_git(); + hres = IGlobalInterfaceTable_QueryInterface(git, iid, ppv); if (hres) return hres;
TRACE("Retrieved GIT (%p)\n", *ppv); diff --git a/dlls/ole32/compobj_private.h b/dlls/ole32/compobj_private.h index c4379cb..6352553 100644 --- a/dlls/ole32/compobj_private.h +++ b/dlls/ole32/compobj_private.h @@ -173,10 +173,8 @@ struct oletls
/* Global Interface Table Functions */ - -extern void* StdGlobalInterfaceTable_Construct(void) DECLSPEC_HIDDEN; +extern IGlobalInterfaceTable *get_std_git(void) DECLSPEC_HIDDEN; extern HRESULT StdGlobalInterfaceTable_GetFactory(LPVOID *ppv) DECLSPEC_HIDDEN; -extern void* StdGlobalInterfaceTableInstance DECLSPEC_HIDDEN;
HRESULT COM_OpenKeyForCLSID(REFCLSID clsid, LPCWSTR keyname, REGSAM access, HKEY *key) DECLSPEC_HIDDEN; HRESULT COM_OpenKeyForAppIdFromCLSID(REFCLSID clsid, REGSAM access, HKEY *subkey) DECLSPEC_HIDDEN; diff --git a/dlls/ole32/git.c b/dlls/ole32/git.c index dd65c2e..ad921ed 100644 --- a/dlls/ole32/git.c +++ b/dlls/ole32/git.c @@ -72,7 +72,7 @@ typedef struct StdGlobalInterfaceTableImpl
} StdGlobalInterfaceTableImpl;
-void* StdGlobalInterfaceTableInstance; +static IGlobalInterfaceTable *std_git;
static CRITICAL_SECTION git_section; static CRITICAL_SECTION_DEBUG critsect_debug = @@ -96,7 +96,7 @@ static void StdGlobalInterfaceTable_Destroy(void* This) FIXME("Revoke held interfaces here\n");
HeapFree(GetProcessHeap(), 0, This); - StdGlobalInterfaceTableInstance = NULL; + std_git = NULL; }
/*** @@ -335,9 +335,8 @@ GITCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pUnk, REFIID riid, LPVOID *ppv) { if (IsEqualIID(riid,&IID_IGlobalInterfaceTable)) { - if (StdGlobalInterfaceTableInstance == NULL) - StdGlobalInterfaceTableInstance = StdGlobalInterfaceTable_Construct(); - return IGlobalInterfaceTable_QueryInterface( (IGlobalInterfaceTable*) StdGlobalInterfaceTableInstance, riid, ppv); + IGlobalInterfaceTable *git = get_std_git(); + return IGlobalInterfaceTable_QueryInterface(git, riid, ppv); }
FIXME("(%s), not supported.\n",debugstr_guid(riid)); @@ -378,19 +377,27 @@ static const IGlobalInterfaceTableVtbl StdGlobalInterfaceTableImpl_Vtbl = StdGlobalInterfaceTable_GetInterfaceFromGlobal };
-/** This function constructs the GIT. It should only be called once **/ -void* StdGlobalInterfaceTable_Construct(void) +IGlobalInterfaceTable* get_std_git(void) { - StdGlobalInterfaceTableImpl* newGIT; - - newGIT = HeapAlloc(GetProcessHeap(), 0, sizeof(StdGlobalInterfaceTableImpl)); - if (newGIT == 0) return newGIT; - - newGIT->IGlobalInterfaceTable_iface.lpVtbl = &StdGlobalInterfaceTableImpl_Vtbl; - newGIT->ref = 1; /* Initialise the reference count */ - list_init(&newGIT->list); - newGIT->nextCookie = 0xf100; /* that's where windows starts, so that's where we start */ - TRACE("Created the GIT at %p\n", newGIT); + if (!std_git) + { + StdGlobalInterfaceTableImpl* newGIT; + + newGIT = HeapAlloc(GetProcessHeap(), 0, sizeof(StdGlobalInterfaceTableImpl)); + 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); + } + else + TRACE("Created the GIT at %p\n", newGIT); + }
- return (void*)newGIT; + return std_git; }