/*
 * SHLWAPI thread and MT synchronisation functions
 *
 * Copyright 2002 Juergen Schmied
 * Copyright 2002 Jon Griffiths
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */
#include <stdarg.h>
#include <string.h>

#define COBJMACROS

#include "windef.h"
#include "winbase.h"
#include "winnls.h"
#include "wine/debug.h"
#define NO_SHLWAPI_REG
#define NO_SHLWAPI_PATH
#define NO_SHLWAPI_GDI
#define NO_SHLWAPI_STREAM
#define NO_SHLWAPI_USER
#include "shlwapi.h"

WINE_DEFAULT_DEBUG_CHANNEL(shell);

/* Get a function pointer from a DLL handle */
#define GET_FUNC(func, module, name, fail) \
  do { \
    if (!func) { \
      if (!SHLWAPI_h##module && !(SHLWAPI_h##module = LoadLibraryA(#module ".dll"))) return fail; \
      if (!(func = (void*)GetProcAddress(SHLWAPI_h##module, name))) return fail; \
    } \
  } while (0)

/* DLL handles for late bound calls */
extern HMODULE SHLWAPI_hshell32;

/* Function pointers for GET_FUNC macro; these need to be global because of gcc bug */
static HRESULT (WINAPI *pSHGetInstanceExplorer)(IUnknown**);

extern DWORD SHLWAPI_ThreadRef_index;  /* Initialised in shlwapi_main.c */

DWORD WINAPI SHStringFromGUIDA(REFGUID,LPSTR,INT);

/**************************************************************************
 *      _CreateAllAccessSecurityAttributes       [SHLWAPI.356]
 *
 * Initialise security attributes from a security descriptor.
 *
 * PARAMS
 *  lpAttr [O] Security attributes
 *  lpSec  [I] Security descriptor
 *
 * RETURNS
 *  Success: lpAttr, initialised using lpSec.
 *  Failure: NULL, if any parameters are invalid.
 *
 * NOTES
 *  This function always returns NULL if the underlying OS version
 *  Wine is impersonating does not use security descriptors (i.e. anything
 *  before Windows NT).
 */
LPSECURITY_ATTRIBUTES WINAPI _CreateAllAccessSecurityAttributes(
	LPSECURITY_ATTRIBUTES lpAttr,
	PSECURITY_DESCRIPTOR lpSec,
        DWORD p3)
{
  /* This function is used within SHLWAPI only to create security attributes
   * for shell semaphores. */

  TRACE("(%p,%p,%08x)\n", lpAttr, lpSec, p3);

  if (!(GetVersion() & 0x80000000))  /* NT */
  {
    if (!lpSec || !lpAttr)
      return NULL;

    if (InitializeSecurityDescriptor(lpSec, 1))
    {
      if (SetSecurityDescriptorDacl(lpSec, TRUE, NULL, FALSE))
      {
         lpAttr->nLength = sizeof(SECURITY_ATTRIBUTES);
         lpAttr->lpSecurityDescriptor = lpSec;
         lpAttr->bInheritHandle = FALSE;
         return lpAttr;
      }
    }
  }
  return NULL;
}

/*************************************************************************
 *      _SHGetInstanceExplorer	[SHLWAPI.@]
 *
 * Get an interface to the shell explorer.
 *
 * PARAMS
 *  lppUnknown [O] Destination for explorers IUnknown interface.
 *
 * RETURNS
 *  Success: S_OK. lppUnknown contains the explorer interface.
 *  Failure: An HRESULT error code.
 */
HRESULT WINAPI _SHGetInstanceExplorer(IUnknown **lppUnknown)
{
  /* This function is used within SHLWAPI only to hold the IE reference
   * for threads created with the CTF_PROCESS_REF flag set. */

  GET_FUNC(pSHGetInstanceExplorer, shell32, "SHGetInstanceExplorer", E_FAIL);
  return pSHGetInstanceExplorer(lppUnknown);
}

/* Internal thread information structure */
typedef struct tagSHLWAPI_THREAD_INFO
{
  LPTHREAD_START_ROUTINE pfnThreadProc; /* Thread start */
  LPTHREAD_START_ROUTINE pfnCallback;   /* Thread initialisation */
  PVOID     pData;                      /* Application specific data */
  BOOL      bInitCom;                   /* Initialise COM for the thread? */
  HANDLE    hEvent;                     /* Signal for creator to continue */
  IUnknown *refThread;                  /* Reference to thread creator */
  IUnknown *refIE;                      /* Reference to the IE process */
} SHLWAPI_THREAD_INFO, *LPSHLWAPI_THREAD_INFO;


/*************************************************************************
 * SHGetThreadRef	[SHLWAPI.@]
 *
 * Get a per-thread object reference set by SHSetThreadRef().
 *
 * PARAMS
 *   lppUnknown [O] Destination to receive object reference
 *
 * RETURNS
 *   Success: S_OK. lppUnknown is set to the object reference.
 *   Failure: E_NOINTERFACE, if an error occurs or lppUnknown is NULL.
 */
HRESULT WINAPI SHGetThreadRef(IUnknown **lppUnknown)
{
  TRACE("(%p)\n", lppUnknown);

  if (!lppUnknown || SHLWAPI_ThreadRef_index == TLS_OUT_OF_INDEXES)
    return E_NOINTERFACE;

  *lppUnknown = (IUnknown*)TlsGetValue(SHLWAPI_ThreadRef_index);
  if (!*lppUnknown)
    return E_NOINTERFACE;

  /* Add a reference. Caller will Release() us when finished */
  IUnknown_AddRef(*lppUnknown);
  return S_OK;
}

/*************************************************************************
 * SHSetThreadRef	[SHLWAPI.@]
 *
 * Store a per-thread object reference.
 *
 * PARAMS
 *   lpUnknown [I] Object reference to store
 *
 * RETURNS
 *   Success: S_OK. lpUnknown is stored and can be retrieved by SHGetThreadRef()
 *   Failure: E_NOINTERFACE, if an error occurs or lpUnknown is NULL.
 */
HRESULT WINAPI SHSetThreadRef(IUnknown *lpUnknown)
{
  TRACE("(%p)\n", lpUnknown);

  if (!lpUnknown || SHLWAPI_ThreadRef_index  == TLS_OUT_OF_INDEXES)
    return E_NOINTERFACE;

  TlsSetValue(SHLWAPI_ThreadRef_index, lpUnknown);
  return S_OK;
}

/*************************************************************************
 * SHReleaseThreadRef	[SHLWAPI.@]
 *
 * Release a per-thread object reference.
 *
 * PARAMS
 *  None.
 *
 * RETURNS
 *   Success: S_OK. The threads object reference is released.
 *   Failure: An HRESULT error code.
 */
HRESULT WINAPI SHReleaseThreadRef()
{
  FIXME("() - stub!\n");
  return S_OK;
}

/*************************************************************************
 * SHLWAPI_ThreadWrapper
 *
 * Internal wrapper for executing user thread functions from SHCreateThread.
 */
static DWORD WINAPI SHLWAPI_ThreadWrapper(PVOID pTi)
{
  SHLWAPI_THREAD_INFO ti;
  HRESULT hCom = E_FAIL;
  DWORD dwRet;

  TRACE("(%p)\n", pTi);

  /* We are now executing in the context of the newly created thread.
   * So we copy the data passed to us (it is on the stack of the function
   * that called us, which is waiting for us to signal an event before
   * returning). */
  memcpy(&ti, pTi, sizeof(SHLWAPI_THREAD_INFO));

  /* Initialise COM for the thread, if desired */
  if (ti.bInitCom)
  {
    hCom = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED|COINIT_DISABLE_OLE1DDE);

    if (FAILED(hCom))
      hCom = CoInitializeEx(NULL, COINIT_DISABLE_OLE1DDE);
  }

  /* Execute the callback function before returning */
  if (ti.pfnCallback)
    ti.pfnCallback(ti.pData);

  /* Signal the thread that created us; it can return now */
  SetEvent(ti.hEvent);

  /* Execute the callers start code */
  dwRet = ti.pfnThreadProc(ti.pData);

  /* Release references to the caller and IE process, if held */
  if (ti.refThread)
    IUnknown_Release(ti.refThread);

  if (ti.refIE)
    IUnknown_Release(ti.refIE);

  if (SUCCEEDED(hCom))
    CoUninitialize();

  /* Return the users thread return value */
  return dwRet;
}

/*************************************************************************
 *      SHCreateThread	[SHLWAPI.16]
 *
 * Create a new thread.
 *
 * PARAMS
 *   pfnThreadProc [I] Function to execute in new thread
 *   pData         [I] Application specific data passed to pfnThreadProc
 *   dwFlags       [I] CTF_ flags from "shlwapi.h"
 *   pfnCallback   [I] Function to execute before pfnThreadProc
 *
 * RETURNS
 *   Success: TRUE. pfnThreadProc was executed.
 *   Failure: FALSE. pfnThreadProc was not executed.
 *
 * NOTES
 *   If the thread cannot be created, pfnCallback is NULL, and dwFlags
 *   has bit CTF_INSIST set, pfnThreadProc will be executed synchronously.
 */
BOOL WINAPI SHCreateThread(LPTHREAD_START_ROUTINE pfnThreadProc, VOID *pData,
                           DWORD dwFlags, LPTHREAD_START_ROUTINE pfnCallback)
{
  SHLWAPI_THREAD_INFO ti;
  BOOL bCalled = FALSE;

  TRACE("(%p,%p,0x%X,%p)\n", pfnThreadProc, pData, dwFlags, pfnCallback);

  /* Set up data to pass to the new thread (On our stack) */
  ti.pfnThreadProc = pfnThreadProc;
  ti.pfnCallback = pfnCallback;
  ti.pData = pData;
  ti.bInitCom = dwFlags & CTF_COINIT ? TRUE : FALSE;
  ti.hEvent = CreateEventW(NULL,FALSE,FALSE,NULL);

  /* Hold references to the current thread and IE process, if desired */
  if(dwFlags & CTF_THREAD_REF)
    SHGetThreadRef(&ti.refThread);
  else
    ti.refThread = NULL;

  if(dwFlags & CTF_PROCESS_REF)
    _SHGetInstanceExplorer(&ti.refIE);
  else
    ti.refIE = NULL;

  /* Create the thread */
  if(ti.hEvent)
  {
    DWORD dwRetVal;
    HANDLE hThread;

    hThread = CreateThread(NULL, 0, SHLWAPI_ThreadWrapper, &ti, 0, &dwRetVal);

    if(hThread)
    {
      /* Wait for the thread to signal us to continue */
      WaitForSingleObject(ti.hEvent, INFINITE);
      CloseHandle(hThread);
      bCalled = TRUE;
    }
    CloseHandle(ti.hEvent);
  }

  if (!bCalled)
  {
    if (!ti.pfnCallback && dwFlags & CTF_INSIST)
    {
      /* Couldn't call, call synchronously */
      pfnThreadProc(pData);
      bCalled = TRUE;
    }
    else
    {
      /* Free references, since thread hasn't run to do so */
      if(ti.refThread)
        IUnknown_Release(ti.refThread);

      if(ti.refIE)
        IUnknown_Release(ti.refIE);
    }
  }
  return bCalled;
}

/*************************************************************************
 *      _SHGlobalCounterGetValue	[SHLWAPI.223]
 *
 * Get the current count of a semaphore.
 *
 * PARAMS
 *  hSem [I] Semaphore handle
 *
 * RETURNS
 *  The current count of the semaphore.
 */
LONG WINAPI _SHGlobalCounterGetValue(HANDLE hSem)
{
  LONG dwOldCount = 0;

  TRACE("(%p)\n", hSem);
  ReleaseSemaphore(hSem, 1, &dwOldCount); /* +1 */
  WaitForSingleObject(hSem, 0);           /* -1 */
  return dwOldCount;
}

/*************************************************************************
 *      _SHGlobalCounterIncrement	[SHLWAPI.224]
 *
 * Claim a semaphore.
 *
 * PARAMS
 *  hSem [I] Semaphore handle
 *
 * RETURNS
 *  The new count of the semaphore.
 */
LONG WINAPI _SHGlobalCounterIncrement(HANDLE hSem)
{
  LONG dwOldCount = 0;

  TRACE("(%p)\n", hSem);
  ReleaseSemaphore(hSem, 1, &dwOldCount);
  return dwOldCount + 1;
}

/*************************************************************************
 *      _SHGlobalCounterDecrement	[SHLWAPI.424]
 *
 * Release a semaphore.
 *
 * PARAMS
 *  hSem [I] Semaphore handle
 *
 * RETURNS
 *  The new count of the semaphore.
 */
DWORD WINAPI _SHGlobalCounterDecrement(HANDLE hSem)
{
  DWORD dwOldCount = 0;

  TRACE("(%p)\n", hSem);

  dwOldCount = _SHGlobalCounterGetValue(hSem);
  WaitForSingleObject(hSem, 0);
  return dwOldCount - 1;
}

/*************************************************************************
 *      _SHGlobalCounterCreateNamedW	[SHLWAPI.423]
 *
 * Unicode version of _SHGlobalCounterCreateNamedA.
 */
HANDLE WINAPI _SHGlobalCounterCreateNamedW(LPCWSTR lpszName, DWORD iInitial)
{
  static const WCHAR szPrefix[] = { 's', 'h', 'e', 'l', 'l', '.', '\0' };
  const int iPrefixLen = 6;
  WCHAR szBuff[MAX_PATH];
  const int iBuffLen = sizeof(szBuff)/sizeof(WCHAR);
  SECURITY_DESCRIPTOR sd;
  SECURITY_ATTRIBUTES sAttr, *pSecAttr;
  HANDLE hRet;

  TRACE("(%s,%d)\n", debugstr_w(lpszName), iInitial);

  /* Create Semaphore name */
  memcpy(szBuff, szPrefix, (iPrefixLen + 1) * sizeof(WCHAR));
  if (lpszName)
    StrCpyNW(szBuff + iPrefixLen, lpszName, iBuffLen - iPrefixLen);

  /* Initialise security attributes */
  pSecAttr = _CreateAllAccessSecurityAttributes(&sAttr, &sd, 0);

  if (!(hRet = CreateSemaphoreW(pSecAttr , iInitial, MAXLONG, szBuff)))
    hRet = OpenSemaphoreW(SYNCHRONIZE|SEMAPHORE_MODIFY_STATE, 0, szBuff);
  return hRet;
}

/*************************************************************************
 *      _SHGlobalCounterCreateNamedA	[SHLWAPI.422]
 *
 * Create a semaphore.
 *
 * PARAMS
 *  lpszName [I] Name of semaphore
 *  iInitial [I] Initial count for semaphore
 *
 * RETURNS
 *  A new semaphore handle.
 */
HANDLE WINAPI _SHGlobalCounterCreateNamedA(LPCSTR lpszName, DWORD iInitial)
{
  WCHAR szBuff[MAX_PATH];

  TRACE("(%s,%d)\n", debugstr_a(lpszName), iInitial);

  if (lpszName)
    MultiByteToWideChar(0, 0, lpszName, -1, szBuff, MAX_PATH);
  return _SHGlobalCounterCreateNamedW(lpszName ? szBuff : NULL, iInitial);
}

/*************************************************************************
 *      _SHGlobalCounterCreate	[SHLWAPI.222]
 *
 * Create a semaphore using the name of a GUID.
 *
 * PARAMS
 *  guid [I] GUID to use as semaphore name
 *
 * RETURNS
 *  A handle to the semaphore.
 *
 * NOTES
 *  The initial count of the semaphore is set to 0.
 */
HANDLE WINAPI _SHGlobalCounterCreate (REFGUID guid)
{
  char szName[40];

  TRACE("(%s)\n", debugstr_guid(guid));

  /* Create a named semaphore using the GUID string */
  SHStringFromGUIDA(guid, szName, sizeof(szName) - 1);
  return _SHGlobalCounterCreateNamedA(szName, 0);
}
