/*
 * Implementation of the StdGlobalInterfaceTable object
 *
 * The GlobalInterfaceTable (GIT) object is used to marshal interfaces between
 * threading apartments (contexts). When you want to pass an interface but not
 * as a parameter, it wouldn't get marshalled automatically, so you can use this
 * object to insert the interface into a table, and you get back a cookie.
 * Then when it's retrieved, it'll be unmarshalled into the right apartment.
 *
 * Copyright 2003 Mike Hearn <mike@theoretic.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "config.h"

#include <assert.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>

#define COBJMACROS
#define NONAMELESSUNION
#define NONAMELESSSTRUCT

#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "objbase.h"
#include "ole2.h"
#include "winerror.h"
#include "winreg.h"
#include "winternl.h"

#include "compobj_private.h" 

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(ole);

/****************************************************************************
 * StdGlobalInterfaceTable definition
 *
 * 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
{
  const IGlobalInterfaceTableVtbl *lpVtbl;

  ULONG ref;
  struct StdGITEntry* firstEntry;
  struct StdGITEntry* lastEntry;
  ULONG nextCookie;
  
} StdGlobalInterfaceTableImpl;

void* StdGlobalInterfaceTableInstance;

static CRITICAL_SECTION git_section;
static CRITICAL_SECTION_DEBUG critsect_debug =
{
    0, 0, &git_section,
    { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
      0, 0, { 0, (DWORD)(__FILE__ ": global interface table") }
};
static CRITICAL_SECTION git_section = { &critsect_debug, -1, 0, 0, 0, 0 };


/** This destroys it again. It should revoke all the held interfaces first **/
void StdGlobalInterfaceTable_Destroy(void* self) {
  TRACE("(%p)\n", self);
  FIXME("Revoke held interfaces here\n");
  
  HeapFree(GetProcessHeap(), 0, self);
  StdGlobalInterfaceTableInstance = NULL;
}

/***
 * A helper function to traverse the list and find the entry that matches the cookie.
 * Returns NULL if not found
 */
static StdGITEntry*
StdGlobalInterfaceTable_FindEntry(IGlobalInterfaceTable* iface, DWORD cookie)
{
  StdGlobalInterfaceTableImpl* const self = (StdGlobalInterfaceTableImpl*) iface;
  StdGITEntry* e;

  TRACE("iface=%p, cookie=0x%x\n", iface, (UINT)cookie);

  EnterCriticalSection(&git_section);
  e = self->firstEntry;
  while (e != NULL) {
    if (e->cookie == cookie) {
      LeaveCriticalSection(&git_section);
      return e;
    }
    e = e->next;
  }
  LeaveCriticalSection(&git_section);
  
  TRACE("Entry not found\n");
  return NULL;
}

/***
 * Here's the boring boilerplate stuff for IUnknown
 */

static HRESULT WINAPI
StdGlobalInterfaceTable_QueryInterface(IGlobalInterfaceTable* iface,
               REFIID riid, void** ppvObject)
{
  /* Make sure silly coders can't crash us */
  if (ppvObject == 0) return E_INVALIDARG;

  *ppvObject = 0; /* assume we don't have the interface */

  /* Do we implement that interface? */
  if (IsEqualIID(&IID_IUnknown, riid) ||
      IsEqualIID(&IID_IGlobalInterfaceTable, riid))
    *ppvObject = iface;
  else
    return E_NOINTERFACE;

  /* Now inc the refcount */
  IGlobalInterfaceTable_AddRef(iface);
  return S_OK;
}

static ULONG WINAPI
StdGlobalInterfaceTable_AddRef(IGlobalInterfaceTable* iface)
{
  StdGlobalInterfaceTableImpl* const self = (StdGlobalInterfaceTableImpl*) iface;

  /* InterlockedIncrement(&self->ref); */
  return self->ref;
}

static ULONG WINAPI
StdGlobalInterfaceTable_Release(IGlobalInterfaceTable* iface)
{
  StdGlobalInterfaceTableImpl* const self = (StdGlobalInterfaceTableImpl*) iface;

  /* InterlockedDecrement(&self->ref); */
  if (self->ref == 0) {
    /* Hey ho, it's time to go, so long again 'till next weeks show! */
    StdGlobalInterfaceTable_Destroy(self);
    return 0;
  }

  return self->ref;
}

/***
 * Now implement the actual IGlobalInterfaceTable interface
 */

static HRESULT WINAPI
StdGlobalInterfaceTable_RegisterInterfaceInGlobal(
               IGlobalInterfaceTable* iface, IUnknown* pUnk,
               REFIID riid, DWORD* pdwCookie)
{
  StdGlobalInterfaceTableImpl* const self = (StdGlobalInterfaceTableImpl*) iface;
  IStream* stream = NULL;
  HRESULT hres;
  StdGITEntry* entry;
  LARGE_INTEGER zero;

  TRACE("iface=%p, pUnk=%p, riid=%s, pdwCookie=0x%p\n", iface, pUnk, debugstr_guid(riid), pdwCookie);

  if (pUnk == NULL) return E_INVALIDARG;
  
  /* marshal the interface */
  TRACE("About to marshal the interface\n");

  hres = CreateStreamOnHGlobal(0, TRUE, &stream);
  if (hres) return hres;
  hres = CoMarshalInterface(stream, riid, pUnk, MSHCTX_INPROC, NULL, MSHLFLAGS_TABLESTRONG);
  if (hres)
  {
    IStream_Release(stream);
    return hres;
  }

  zero.QuadPart = 0;
  IStream_Seek(stream, zero, SEEK_SET, NULL);

  entry = HeapAlloc(GetProcessHeap(), 0, sizeof(StdGITEntry));
  if (entry == NULL) return E_OUTOFMEMORY;

  EnterCriticalSection(&git_section);
  
  entry->iid = *riid;
  entry->stream = stream;
  entry->cookie = self->nextCookie;
  self->nextCookie++; /* inc the cookie count */

  /* insert the new entry at the end of the list */
  entry->next = NULL;
  entry->prev = self->lastEntry;
  if (entry->prev) entry->prev->next = entry;
  else self->firstEntry = entry;
  self->lastEntry = entry;

  /* and return the cookie */
  *pdwCookie = entry->cookie;
  
  LeaveCriticalSection(&git_section);
  
  TRACE("Cookie is 0x%lx\n", entry->cookie);
  return S_OK;
}

static HRESULT WINAPI
StdGlobalInterfaceTable_RevokeInterfaceFromGlobal(
               IGlobalInterfaceTable* iface, DWORD dwCookie)
{
  StdGlobalInterfaceTableImpl* const self = (StdGlobalInterfaceTableImpl*) iface;
  StdGITEntry* entry;
  HRESULT hr;

  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 */
  }
  
  /* Free the stream */
  hr = CoReleaseMarshalData(entry->stream);
  if (hr != S_OK)
  {
    WARN("Failed to release marshal data, hr = 0x%08lx\n", hr);
    return hr;
  }
  IStream_Release(entry->stream);
		    
  /* chop entry out of the list, and free the memory */
  EnterCriticalSection(&git_section);
  if (entry->prev) entry->prev->next = entry->next;
  else self->firstEntry = entry->next;
  if (entry->next) entry->next->prev = entry->prev;
  else self->lastEntry = entry->prev;
  LeaveCriticalSection(&git_section);

  HeapFree(GetProcessHeap(), 0, entry);
  return S_OK;
}

static HRESULT WINAPI
StdGlobalInterfaceTable_GetInterfaceFromGlobal(
               IGlobalInterfaceTable* iface, DWORD dwCookie,
               REFIID riid, void **ppv)
{
  StdGITEntry* entry;
  HRESULT hres;
  LARGE_INTEGER move;
  LPUNKNOWN lpUnk;
  
  TRACE("dwCookie=0x%lx, riid=%s, ppv=%p\n", dwCookie, debugstr_guid(riid), ppv);
  
  entry = StdGlobalInterfaceTable_FindEntry(iface, dwCookie);
  if (entry == NULL) return E_INVALIDARG;

  if (!IsEqualIID(&entry->iid, riid)) {
    WARN("entry->iid (%s) != riid\n", debugstr_guid(&entry->iid));
    return E_INVALIDARG;
  }
  TRACE("entry=%p\n", entry);
  
  /* unmarshal the interface */
  hres = CoUnmarshalInterface(entry->stream, riid, ppv);
  if (hres) {
    WARN("Failed to unmarshal stream\n");
    return hres;
  }
  
  /* rewind stream, in case it's used again */
  move.u.LowPart = 0;
  move.u.HighPart = 0;
  IStream_Seek(entry->stream, move, STREAM_SEEK_SET, NULL);

  /* addref it */
  lpUnk = *ppv;
  IUnknown_AddRef(lpUnk);
  TRACE("ppv=%p\n", *ppv);
  return S_OK;
}

/* Classfactory definition - despite what MSDN says, some programs need this */

static HRESULT WINAPI
GITCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid, LPVOID *ppv)
{
  *ppv = NULL;
  if (IsEqualIID(riid,&IID_IUnknown) ||
      IsEqualIID(riid,&IID_IGlobalInterfaceTable))
  {
    *ppv = (LPVOID)iface;
    return S_OK;
  }
  return E_NOINTERFACE;
}

static ULONG WINAPI GITCF_AddRef(LPCLASSFACTORY iface)
{
  return 2;
}

static ULONG WINAPI GITCF_Release(LPCLASSFACTORY iface)
{
  return 1;
}

static HRESULT WINAPI
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);
  }

  FIXME("(%s), not supported.\n",debugstr_guid(riid));
  return E_NOINTERFACE;
}

static HRESULT WINAPI GITCF_LockServer(LPCLASSFACTORY iface, BOOL fLock)
{
    FIXME("(%d), stub!\n",fLock);
    return S_OK;
}

static const IClassFactoryVtbl GITClassFactoryVtbl = {
    GITCF_QueryInterface,
    GITCF_AddRef,
    GITCF_Release,
    GITCF_CreateInstance,
    GITCF_LockServer
};

static const IClassFactoryVtbl *PGITClassFactoryVtbl = &GITClassFactoryVtbl;

HRESULT StdGlobalInterfaceTable_GetFactory(LPVOID *ppv)
{
  *ppv = &PGITClassFactoryVtbl;
  TRACE("Returning GIT classfactory\n");
  return S_OK;
}

/* Virtual function table */
static const IGlobalInterfaceTableVtbl StdGlobalInterfaceTableImpl_Vtbl =
{
  StdGlobalInterfaceTable_QueryInterface,
  StdGlobalInterfaceTable_AddRef,
  StdGlobalInterfaceTable_Release,
  StdGlobalInterfaceTable_RegisterInterfaceInGlobal,
  StdGlobalInterfaceTable_RevokeInterfaceFromGlobal,
  StdGlobalInterfaceTable_GetInterfaceFromGlobal
};

/** This function constructs the GIT. It should only be called once **/
void* StdGlobalInterfaceTable_Construct()
{
  StdGlobalInterfaceTableImpl* newGIT;

  newGIT = HeapAlloc(GetProcessHeap(), 0, sizeof(StdGlobalInterfaceTableImpl));
  if (newGIT == 0) return newGIT;

  newGIT->lpVtbl = &StdGlobalInterfaceTableImpl_Vtbl;
  newGIT->ref = 1;      /* 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;
}
