GIT implementation

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



With this patch, RhymBox makes it to the login screen now! :)

ChangeLog:
- Implement the global interface table object using a simple linked list
- Connect it via CoCreateInstance

It relies upon my previous patch which stubbed this object out.

thanks -mike
diff -u dlls/ole32/compobj.c dlls/ole32-mike/compobj.c
--- dlls/ole32/compobj.c	Sat Jan 11 20:58:10 2003
+++ dlls/ole32-mike/compobj.c	Sun Mar  9 19:49:42 2003
@@ -1317,6 +1318,20 @@
   *ppv = 0;
 
   /*
+   * 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);
+    if (hres) return hres;
+    
+    TRACE("Retrieved GIT (%p)\n", *ppv);
+    return S_OK;
+  }
+  
+  /*
    * Get a class factory to construct the object we want.
    */
   hres = CoGetClassObject(rclsid,
diff -u dlls/ole32/git.c dlls/ole32-mike/git.c
--- dlls/ole32/git.c	Sun Mar  9 20:11:24 2003
+++ dlls/ole32-mike/git.c	Sun Mar  9 20:05:57 2003
@@ -50,15 +50,31 @@
  * This class implements IGlobalInterfaceTable and is a process-wide singleton
  * used for marshalling interfaces between threading apartments using cookies.
  */
+
+/* Each entry in the linked list of GIT entries */
+typedef struct StdGITEntry
+{
+  DWORD cookie;
+  IID iid;      /* IID of the interface */
+  IStream* stream; /* Holds the marshalled interface */
+
+  struct StdGITEntry* next;
+  struct StdGITEntry* prev;  
+} StdGITEntry;
+
+/* Class data */
 typedef struct StdGlobalInterfaceTableImpl
 {
   ICOM_VFIELD(IGlobalInterfaceTable);
 
   ULONG ref;
+  struct StdGITEntry* firstEntry;
+  struct StdGITEntry* lastEntry;
+  ULONG nextCookie;
   
-  /* FIXME: put the table here */
 } StdGlobalInterfaceTableImpl;
 
+
 /* IUnknown */
 static HRESULT WINAPI StdGlobalInterfaceTable_QueryInterface(IGlobalInterfaceTable* iface, REFIID riid, void** ppvObject);
 static ULONG   WINAPI StdGlobalInterfaceTable_AddRef(IGlobalInterfaceTable* iface);
@@ -94,7 +110,10 @@
 
   ICOM_VTBL(newGIT) = &StdGlobalInterfaceTableImpl_Vtbl;
   
-  newGIT->ref = 0; /* Initialise the reference count */
+  newGIT->ref = 0;      /* Initialise the reference count */
+  newGIT->firstEntry = NULL; /* we start with an empty table   */
+  newGIT->lastEntry  = NULL;
+  newGIT->nextCookie = 0xf100; /* that's where windows starts, so that's where we start */
   TRACE("Created the GIT at %p\n", newGIT);
 
   return (void*)newGIT;
@@ -104,15 +123,35 @@
 void StdGlobalInterfaceTable_Destroy(void* self) {
   TRACE("(%p)\n", self);
   FIXME("Revoke held interfaces here\n");
+  
   HeapFree(GetProcessHeap(), 0, self);
 }
 
 /***
+ * A helper function to traverse the list and find the entry that matches the cookie.
+ * Returns NULL if not found
+ */
+StdGITEntry* StdGlobalInterfaceTable_FindEntry(IGlobalInterfaceTable* iface, DWORD cookie) {
+  StdGlobalInterfaceTableImpl* const self = (StdGlobalInterfaceTableImpl*) iface;
+  StdGITEntry* e;
+
+  TRACE("iface=%p, cookie=0x%x\n", iface, (UINT)cookie);
+  
+  e = self->firstEntry;
+  while (e != NULL) {
+    if (e->cookie == cookie) return e;
+    e = e->next;
+  }
+  return NULL;
+}
+
+/***
  * Here's the boring boilerplate stuff for IUnknown
  */
 
 HRESULT WINAPI StdGlobalInterfaceTable_QueryInterface(IGlobalInterfaceTable* iface, REFIID riid, void** ppvObject) {
   StdGlobalInterfaceTableImpl* const self = (StdGlobalInterfaceTableImpl*) iface;
+
   /* Make sure silly coders can't crash us */
   if (ppvObject == 0) return E_INVALIDARG;
 
@@ -126,7 +165,7 @@
   } else return E_NOINTERFACE;
 
   /* Now inc the refcount */
-  StdGlobalInterfaceTable_AddRef(iface);
+  /* we don't use refcounts for now: StdGlobalInterfaceTable_AddRef(iface); */
   return S_OK;
 }
 
@@ -155,16 +194,92 @@
  */
 
 HRESULT WINAPI StdGlobalInterfaceTable_RegisterInterfaceInGlobal(IGlobalInterfaceTable* iface, IUnknown* pUnk, REFIID riid, DWORD* pdwCookie) {
-  FIXME("stub\n");
-  return E_NOTIMPL;
+  StdGlobalInterfaceTableImpl* const self = (StdGlobalInterfaceTableImpl*) iface;
+  IStream* stream = NULL;
+  HRESULT hres;
+  StdGITEntry* entry;
+
+  TRACE("iface=%p, pUnk=%p, riid=%s, pdwCookie=%p\n", iface, pUnk, debugstr_guid(riid), pdwCookie);
+
+  if (pUnk == NULL) return E_INVALIDARG;
+  
+  /* marshal the interface */
+  hres = CoMarshalInterThreadInterfaceInStream(riid, pUnk, &stream);
+  if (hres) return hres;
+  entry = HeapAlloc(GetProcessHeap(), 0, sizeof(StdGITEntry));
+  if (entry == NULL) return E_OUTOFMEMORY;
+  
+  entry->iid = *riid;
+  entry->stream = stream;
+  entry->cookie = self->nextCookie;
+  self->nextCookie++; /* inc the cookie count */
+  
+  if (self->firstEntry == NULL) {
+    /* create the first entry */
+    entry->next = NULL;
+    entry->prev = NULL;
+    self->firstEntry = entry;
+    self->lastEntry = entry;
+  } else {
+    /* insert the new entry onto the end of the list */
+    entry->prev = self->lastEntry;
+    entry->prev->next = entry;
+    /* and move the last entry pointer along one */
+    self->lastEntry = self->lastEntry->next;
+  }
+
+  /* and return the cookie */
+  *pdwCookie = entry->cookie;
+  return S_OK;
 }
 
 HRESULT WINAPI StdGlobalInterfaceTable_RevokeInterfaceFromGlobal(IGlobalInterfaceTable* iface, DWORD dwCookie) {
-  FIXME("stub\n");
-  return E_NOTIMPL;
+  StdGlobalInterfaceTableImpl* const self = (StdGlobalInterfaceTableImpl*) iface;
+  StdGITEntry* entry;
+
+  TRACE("iface=%p, dwCookie=0x%x\n", iface, (UINT)dwCookie);
+  
+  entry = StdGlobalInterfaceTable_FindEntry(iface, dwCookie);
+  if (entry == NULL) {
+    TRACE("Entry not found\n");
+    return E_INVALIDARG; /* not found */
+  }
+
+  /* chop entry out of the list, and free the memory */
+  if (self->firstEntry == self->lastEntry) {
+    /* we only have one entry */
+    self->firstEntry = NULL;
+    self->lastEntry = NULL;
+  } else if (entry == self->firstEntry) {
+    /* we have more than one entry, this is the first */
+    self->firstEntry = entry->next;
+    self->firstEntry->prev = NULL;
+  } else if (entry == self->lastEntry) {
+    /* we have more than one entry, this is the last */
+    self->lastEntry = entry->prev;
+    self->lastEntry->next = NULL;
+  } else {
+    /* we have more than one entry, and this is in the middle */
+    entry->prev->next = entry->next;
+    entry->next->prev = entry->prev;
+  }
+
+    
+  HeapFree(GetProcessHeap(), 0, entry);
+  return S_OK;
 }
 
 HRESULT WINAPI StdGlobalInterfaceTable_GetInterfaceFromGlobal(IGlobalInterfaceTable* iface, DWORD dwCookie, REFIID riid, void **ppv) {
-  FIXME("stub\n");
-  return E_NOTIMPL;
+  StdGITEntry* entry;
+  HRESULT hres;
+  
+  entry = StdGlobalInterfaceTable_FindEntry(iface, dwCookie);
+  if (entry == NULL) return E_INVALIDARG;
+  if (!IsEqualIID(&entry->iid, &riid)) return E_INVALIDARG;
+
+  /* unmarshal the interface */
+  hres = CoGetInterfaceAndReleaseStream(entry->stream, riid, *ppv);
+  if (hres) return hres;
+  
+  return S_OK;
 }
diff -u dlls/ole32/marshal.c dlls/ole32-mike/marshal.c
--- dlls/ole32/marshal.c	Thu Dec 19 22:16:35 2002
+++ dlls/ole32-mike/marshal.c	Sun Mar  9 15:41:21 2003
@@ -555,7 +555,7 @@
   LARGE_INTEGER		seekto;
   HRESULT		hres;
 
-  TRACE("(,%s,)\n",debugstr_guid(riid));
+  TRACE("(%s, %p, %p)\n",debugstr_guid(riid), pUnk, ppStm);
   hres = CreateStreamOnHGlobal(0, TRUE, ppStm);
   if (hres) return hres;
   /* CoMarshalInterface(...); */
diff -u dlls/ole32/oleproxy.c dlls/ole32-mike/oleproxy.c
--- dlls/ole32/oleproxy.c	Sun Mar  9 20:11:24 2003
+++ dlls/ole32-mike/oleproxy.c	Sun Mar  9 17:48:02 2003
@@ -516,16 +516,7 @@
 	)
     )
 	return MARSHAL_GetStandardMarshalCF(ppv);
-
-    if (IsEqualIID(rclsid, &CLSID_StdGlobalInterfaceTable)) {
-      if (StdGlobalInterfaceTableInstance == NULL) { 
-	StdGlobalInterfaceTableInstance = StdGlobalInterfaceTable_Construct();
-	FIXME("Created (%p)\n", StdGlobalInterfaceTableInstance);
-      }
-      *ppv = StdGlobalInterfaceTableInstance;
-      return S_OK;
-    }
-    
+   
     FIXME("\n\tCLSID:\t%s,\n\tIID:\t%s\n",debugstr_guid(rclsid),debugstr_guid(iid));
     return CLASS_E_CLASSNOTAVAILABLE;
 }

[Index of Archives]     [Gimp for Windows]     [Red Hat]     [Samba]     [Yosemite Camping]     [Graphics Cards]     [Wine Home]

  Powered by Linux