mirror of
git://source.winehq.org/git/wine.git
synced 2024-11-01 21:04:06 +00:00
374 lines
11 KiB
C
374 lines
11 KiB
C
/*
|
|
* Activation contexts
|
|
*
|
|
* Copyright 2004 Jon Griffiths
|
|
* Copyright 2007 Eric Pouech
|
|
* Copyright 2007 Jacek Caban for CodeWeavers
|
|
*
|
|
* 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 "config.h"
|
|
#include "wine/port.h"
|
|
|
|
#include <stdarg.h>
|
|
#include "windef.h"
|
|
#include "winbase.h"
|
|
#include "winerror.h"
|
|
#include "winnls.h"
|
|
#include "wine/debug.h"
|
|
|
|
WINE_DEFAULT_DEBUG_CHANNEL(actctx);
|
|
|
|
|
|
#define ACTCTX_FLAGS_ALL (\
|
|
ACTCTX_FLAG_PROCESSOR_ARCHITECTURE_VALID |\
|
|
ACTCTX_FLAG_LANGID_VALID |\
|
|
ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID |\
|
|
ACTCTX_FLAG_RESOURCE_NAME_VALID |\
|
|
ACTCTX_FLAG_SET_PROCESS_DEFAULT |\
|
|
ACTCTX_FLAG_APPLICATION_NAME_VALID |\
|
|
ACTCTX_FLAG_SOURCE_IS_ASSEMBLYREF |\
|
|
ACTCTX_FLAG_HMODULE_VALID )
|
|
|
|
#define ACTCTX_FAKE_HANDLE ((HANDLE) 0xf00baa)
|
|
#define ACTCTX_FAKE_COOKIE ((ULONG_PTR) 0xf00bad)
|
|
|
|
#define ACTCTX_MAGIC 0xC07E3E11
|
|
|
|
struct actctx
|
|
{
|
|
ULONG magic;
|
|
LONG ref_count;
|
|
};
|
|
|
|
/***********************************************************************
|
|
* CreateActCtxA (KERNEL32.@)
|
|
*
|
|
* Create an activation context.
|
|
*/
|
|
HANDLE WINAPI CreateActCtxA(PCACTCTXA pActCtx)
|
|
{
|
|
ACTCTXW actw;
|
|
SIZE_T len;
|
|
HANDLE ret = INVALID_HANDLE_VALUE;
|
|
LPWSTR src = NULL, assdir = NULL, resname = NULL, appname = NULL;
|
|
|
|
TRACE("%p %08x\n", pActCtx, pActCtx ? pActCtx->dwFlags : 0);
|
|
|
|
if (!pActCtx || pActCtx->cbSize != sizeof(*pActCtx) ||
|
|
(pActCtx->dwFlags & ~ACTCTX_FLAGS_ALL))
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return INVALID_HANDLE_VALUE;
|
|
}
|
|
|
|
actw.cbSize = sizeof(actw);
|
|
actw.dwFlags = pActCtx->dwFlags;
|
|
if (pActCtx->lpSource)
|
|
{
|
|
len = MultiByteToWideChar(CP_ACP, 0, pActCtx->lpSource, -1, NULL, 0);
|
|
src = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
|
|
if (!src) return INVALID_HANDLE_VALUE;
|
|
MultiByteToWideChar(CP_ACP, 0, pActCtx->lpSource, -1, src, len);
|
|
}
|
|
actw.lpSource = src;
|
|
|
|
if (actw.dwFlags & ACTCTX_FLAG_PROCESSOR_ARCHITECTURE_VALID)
|
|
actw.wProcessorArchitecture = pActCtx->wProcessorArchitecture;
|
|
if (actw.dwFlags & ACTCTX_FLAG_LANGID_VALID)
|
|
actw.wLangId = pActCtx->wLangId;
|
|
if (actw.dwFlags & ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID)
|
|
{
|
|
len = MultiByteToWideChar(CP_ACP, 0, pActCtx->lpAssemblyDirectory, -1, NULL, 0);
|
|
assdir = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
|
|
if (!assdir) goto done;
|
|
MultiByteToWideChar(CP_ACP, 0, pActCtx->lpAssemblyDirectory, -1, assdir, len);
|
|
actw.lpAssemblyDirectory = assdir;
|
|
}
|
|
if (actw.dwFlags & ACTCTX_FLAG_RESOURCE_NAME_VALID)
|
|
{
|
|
if ((ULONG_PTR)pActCtx->lpResourceName >> 16)
|
|
{
|
|
len = MultiByteToWideChar(CP_ACP, 0, pActCtx->lpResourceName, -1, NULL, 0);
|
|
resname = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
|
|
if (!resname) goto done;
|
|
MultiByteToWideChar(CP_ACP, 0, pActCtx->lpResourceName, -1, resname, len);
|
|
actw.lpResourceName = resname;
|
|
}
|
|
else actw.lpResourceName = (LPWSTR)pActCtx->lpResourceName;
|
|
}
|
|
if (actw.dwFlags & ACTCTX_FLAG_APPLICATION_NAME_VALID)
|
|
{
|
|
len = MultiByteToWideChar(CP_ACP, 0, pActCtx->lpApplicationName, -1, NULL, 0);
|
|
appname = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
|
|
if (!appname) goto done;
|
|
MultiByteToWideChar(CP_ACP, 0, pActCtx->lpApplicationName, -1, appname, len);
|
|
actw.lpApplicationName = appname;
|
|
}
|
|
if (actw.dwFlags & ACTCTX_FLAG_HMODULE_VALID)
|
|
actw.hModule = pActCtx->hModule;
|
|
|
|
ret = CreateActCtxW(&actw);
|
|
|
|
done:
|
|
HeapFree(GetProcessHeap(), 0, src);
|
|
HeapFree(GetProcessHeap(), 0, assdir);
|
|
HeapFree(GetProcessHeap(), 0, resname);
|
|
HeapFree(GetProcessHeap(), 0, appname);
|
|
return ret;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* CreateActCtxW (KERNEL32.@)
|
|
*
|
|
* Create an activation context.
|
|
*/
|
|
HANDLE WINAPI CreateActCtxW(PCACTCTXW pActCtx)
|
|
{
|
|
struct actctx* actctx;
|
|
DWORD ret = ERROR_SUCCESS;
|
|
|
|
TRACE("%p %08x\n", pActCtx, pActCtx ? pActCtx->dwFlags : 0);
|
|
|
|
if (!pActCtx || pActCtx->cbSize != sizeof(*pActCtx) ||
|
|
(pActCtx->dwFlags & ~ACTCTX_FLAGS_ALL))
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return INVALID_HANDLE_VALUE;
|
|
}
|
|
actctx = HeapAlloc(GetProcessHeap(), 0, sizeof(*actctx));
|
|
if (!actctx) return INVALID_HANDLE_VALUE;
|
|
|
|
actctx->magic = ACTCTX_MAGIC;
|
|
actctx->ref_count = 1;
|
|
|
|
if (ret == ERROR_SUCCESS)
|
|
{
|
|
return (HANDLE)actctx;
|
|
}
|
|
|
|
ReleaseActCtx((HANDLE)actctx);
|
|
SetLastError(ret);
|
|
return INVALID_HANDLE_VALUE;
|
|
}
|
|
|
|
static struct actctx* check_actctx(HANDLE h)
|
|
{
|
|
struct actctx* actctx = (struct actctx*)h;
|
|
|
|
switch (actctx->magic)
|
|
{
|
|
case ACTCTX_MAGIC: return actctx;
|
|
default:
|
|
SetLastError(ERROR_INVALID_HANDLE);
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
/***********************************************************************
|
|
* ActivateActCtx (KERNEL32.@)
|
|
*
|
|
* Activate an activation context.
|
|
*/
|
|
BOOL WINAPI ActivateActCtx(HANDLE hActCtx, ULONG_PTR *ulCookie)
|
|
{
|
|
static BOOL reported = FALSE;
|
|
|
|
if (reported)
|
|
TRACE("%p %p\n", hActCtx, ulCookie);
|
|
else
|
|
{
|
|
FIXME("%p %p\n", hActCtx, ulCookie);
|
|
reported = TRUE;
|
|
}
|
|
|
|
if (ulCookie)
|
|
*ulCookie = ACTCTX_FAKE_COOKIE;
|
|
return TRUE;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* DeactivateActCtx (KERNEL32.@)
|
|
*
|
|
* Deactivate an activation context.
|
|
*/
|
|
BOOL WINAPI DeactivateActCtx(DWORD dwFlags, ULONG_PTR ulCookie)
|
|
{
|
|
static BOOL reported = FALSE;
|
|
|
|
if (reported)
|
|
TRACE("%08x %08lx\n", dwFlags, ulCookie);
|
|
else
|
|
{
|
|
FIXME("%08x %08lx\n", dwFlags, ulCookie);
|
|
reported = TRUE;
|
|
}
|
|
|
|
if (ulCookie != ACTCTX_FAKE_COOKIE)
|
|
return FALSE;
|
|
return TRUE;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* GetCurrentActCtx (KERNEL32.@)
|
|
*
|
|
* Get the current activation context.
|
|
*/
|
|
BOOL WINAPI GetCurrentActCtx(HANDLE* phActCtx)
|
|
{
|
|
FIXME("%p\n", phActCtx);
|
|
*phActCtx = ACTCTX_FAKE_HANDLE;
|
|
return TRUE;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* AddRefActCtx (KERNEL32.@)
|
|
*
|
|
* Add a reference to an activation context.
|
|
*/
|
|
void WINAPI AddRefActCtx(HANDLE hActCtx)
|
|
{
|
|
struct actctx* actctx;
|
|
|
|
TRACE("%p\n", hActCtx);
|
|
|
|
if ((actctx = check_actctx(hActCtx)))
|
|
InterlockedIncrement( &actctx->ref_count );
|
|
}
|
|
|
|
/***********************************************************************
|
|
* ReleaseActCtx (KERNEL32.@)
|
|
*
|
|
* Release a reference to an activation context.
|
|
*/
|
|
void WINAPI ReleaseActCtx(HANDLE hActCtx)
|
|
{
|
|
struct actctx* actctx;
|
|
|
|
TRACE("%p\n", hActCtx);
|
|
|
|
if ((actctx = check_actctx(hActCtx)))
|
|
{
|
|
if (!InterlockedDecrement( &actctx->ref_count ))
|
|
{
|
|
actctx->magic = 0;
|
|
HeapFree(GetProcessHeap(), 0, actctx);
|
|
}
|
|
}
|
|
}
|
|
|
|
/***********************************************************************
|
|
* ZombifyActCtx (KERNEL32.@)
|
|
*
|
|
* Release a reference to an activation context.
|
|
*/
|
|
BOOL WINAPI ZombifyActCtx(HANDLE hActCtx)
|
|
{
|
|
FIXME("%p\n", hActCtx);
|
|
if (hActCtx != ACTCTX_FAKE_HANDLE)
|
|
return FALSE;
|
|
return TRUE;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* FindActCtxSectionStringA (KERNEL32.@)
|
|
*
|
|
* Find information about a GUID in an activation context.
|
|
*/
|
|
BOOL WINAPI FindActCtxSectionStringA(DWORD dwFlags, const GUID* lpExtGuid,
|
|
ULONG ulId, LPCSTR lpSearchStr,
|
|
PACTCTX_SECTION_KEYED_DATA pInfo)
|
|
{
|
|
FIXME("%08x %s %u %s %p\n", dwFlags, debugstr_guid(lpExtGuid),
|
|
ulId, debugstr_a(lpSearchStr), pInfo);
|
|
SetLastError( ERROR_CALL_NOT_IMPLEMENTED);
|
|
return FALSE;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* FindActCtxSectionStringW (KERNEL32.@)
|
|
*
|
|
* Find information about a GUID in an activation context.
|
|
*/
|
|
BOOL WINAPI FindActCtxSectionStringW(DWORD dwFlags, const GUID* lpExtGuid,
|
|
ULONG ulId, LPCWSTR lpSearchStr,
|
|
PACTCTX_SECTION_KEYED_DATA pInfo)
|
|
{
|
|
FIXME("%08x %s %u %s %p\n", dwFlags, debugstr_guid(lpExtGuid),
|
|
ulId, debugstr_w(lpSearchStr), pInfo);
|
|
|
|
if (lpExtGuid)
|
|
{
|
|
FIXME("expected lpExtGuid == NULL\n");
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return FALSE;
|
|
}
|
|
|
|
if (dwFlags & ~FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX)
|
|
{
|
|
FIXME("unknown dwFlags %08x\n", dwFlags);
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return FALSE;
|
|
}
|
|
|
|
if (!pInfo || pInfo->cbSize < sizeof (ACTCTX_SECTION_KEYED_DATA))
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return FALSE;
|
|
}
|
|
|
|
pInfo->ulDataFormatVersion = 1;
|
|
pInfo->lpData = NULL;
|
|
pInfo->lpSectionGlobalData = NULL;
|
|
pInfo->ulSectionGlobalDataLength = 0;
|
|
pInfo->lpSectionBase = NULL;
|
|
pInfo->ulSectionTotalLength = 0;
|
|
pInfo->hActCtx = ACTCTX_FAKE_HANDLE;
|
|
pInfo->ulAssemblyRosterIndex = 0;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* FindActCtxSectionGuid (KERNEL32.@)
|
|
*
|
|
* Find information about a GUID in an activation context.
|
|
*/
|
|
BOOL WINAPI FindActCtxSectionGuid(DWORD dwFlags, const GUID* lpExtGuid,
|
|
ULONG ulId, const GUID* lpSearchGuid,
|
|
PACTCTX_SECTION_KEYED_DATA pInfo)
|
|
{
|
|
FIXME("%08x %s %u %s %p\n", dwFlags, debugstr_guid(lpExtGuid),
|
|
ulId, debugstr_guid(lpSearchGuid), pInfo);
|
|
SetLastError( ERROR_CALL_NOT_IMPLEMENTED);
|
|
return FALSE;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* QueryActCtxW (KERNEL32.@)
|
|
*
|
|
* Get information about an activation context.
|
|
*/
|
|
BOOL WINAPI QueryActCtxW(DWORD dwFlags, HANDLE hActCtx, PVOID pvSubInst,
|
|
ULONG ulClass, PVOID pvBuff, SIZE_T cbBuff,
|
|
SIZE_T *pcbLen)
|
|
{
|
|
FIXME("%08x %p %p %u %p %ld %p\n", dwFlags, hActCtx,
|
|
pvSubInst, ulClass, pvBuff, cbBuff, pcbLen);
|
|
/* this makes Adobe Photoshop 7.0 happy */
|
|
SetLastError( ERROR_CALL_NOT_IMPLEMENTED);
|
|
return FALSE;
|
|
}
|