actctx.c 9.31 KB
Newer Older
1 2 3 4
/*
 * Activation contexts
 *
 * Copyright 2004 Jon Griffiths
5 6
 * Copyright 2007 Eric Pouech
 * Copyright 2007 Jacek Caban for CodeWeavers
7 8 9 10 11 12 13 14 15 16 17 18 19
 *
 * 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
20
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 22 23 24 25 26 27 28 29
 */

#include "config.h"
#include "wine/port.h"

#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "winerror.h"
30
#include "winnls.h"
31
#include "winternl.h"
32 33 34 35 36 37 38 39 40
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(actctx);

/***********************************************************************
 * CreateActCtxA (KERNEL32.@)
 *
 * Create an activation context.
 */
41
HANDLE WINAPI CreateActCtxA(PCACTCTXA pActCtx)
42
{
43 44 45 46
    ACTCTXW     actw;
    SIZE_T      len;
    HANDLE      ret = INVALID_HANDLE_VALUE;
    LPWSTR      src = NULL, assdir = NULL, resname = NULL, appname = NULL;
47

48 49
    TRACE("%p %08x\n", pActCtx, pActCtx ? pActCtx->dwFlags : 0);

50
    if (!pActCtx || pActCtx->cbSize != sizeof(*pActCtx))
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
    {
        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)
    {
81
        if ((ULONG_PTR)pActCtx->lpResourceName >> 16)
82 83 84 85 86 87 88
        {
            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;
        }
89
        else actw.lpResourceName = (LPCWSTR)pActCtx->lpResourceName;
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
    }
    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;
110 111 112 113 114 115 116
}

/***********************************************************************
 * CreateActCtxW (KERNEL32.@)
 *
 * Create an activation context.
 */
117
HANDLE WINAPI CreateActCtxW(PCACTCTXW pActCtx)
118
{
119 120
    NTSTATUS    status;
    HANDLE      hActCtx;
121

122 123
    TRACE("%p %08x\n", pActCtx, pActCtx ? pActCtx->dwFlags : 0);

124
    if ((status = RtlCreateActivationContext(&hActCtx, pActCtx)))
125
    {
126
        SetLastError(RtlNtStatusToDosError(status));
127 128
        return INVALID_HANDLE_VALUE;
    }
129
    return hActCtx;
130 131 132 133 134 135 136
}

/***********************************************************************
 * ActivateActCtx (KERNEL32.@)
 *
 * Activate an activation context.
 */
137
BOOL WINAPI ActivateActCtx(HANDLE hActCtx, ULONG_PTR *ulCookie)
138
{
139 140 141 142 143 144 145 146
    NTSTATUS status;

    if ((status = RtlActivateActivationContext( 0, hActCtx, ulCookie )))
    {
        SetLastError(RtlNtStatusToDosError(status));
        return FALSE;
    }
    return TRUE;
147 148 149 150 151 152 153 154 155
}

/***********************************************************************
 * DeactivateActCtx (KERNEL32.@)
 *
 * Deactivate an activation context.
 */
BOOL WINAPI DeactivateActCtx(DWORD dwFlags, ULONG_PTR ulCookie)
{
156 157
    RtlDeactivateActivationContext( dwFlags, ulCookie );
    return TRUE;
158 159 160 161 162 163 164 165 166
}

/***********************************************************************
 * GetCurrentActCtx (KERNEL32.@)
 *
 * Get the current activation context.
 */
BOOL WINAPI GetCurrentActCtx(HANDLE* phActCtx)
{
167 168 169 170 171 172 173 174
    NTSTATUS status;

    if ((status = RtlGetActiveActivationContext(phActCtx)))
    {
        SetLastError(RtlNtStatusToDosError(status));
        return FALSE;
    }
    return TRUE;
175 176 177 178 179 180 181 182 183
}

/***********************************************************************
 * AddRefActCtx (KERNEL32.@)
 *
 * Add a reference to an activation context.
 */
void WINAPI AddRefActCtx(HANDLE hActCtx)
{
184
    RtlAddRefActivationContext(hActCtx);
185 186 187 188 189 190 191 192 193
}

/***********************************************************************
 * ReleaseActCtx (KERNEL32.@)
 *
 * Release a reference to an activation context.
 */
void WINAPI ReleaseActCtx(HANDLE hActCtx)
{
194
    RtlReleaseActivationContext(hActCtx);
195 196 197 198 199
}

/***********************************************************************
 * ZombifyActCtx (KERNEL32.@)
 *
200
 * Deactivate context without releasing it.
201 202 203
 */
BOOL WINAPI ZombifyActCtx(HANDLE hActCtx)
{
204 205 206 207 208 209 210 211
    NTSTATUS status;

    if ((status = RtlZombifyActivationContext(hActCtx)))
    {
        SetLastError(RtlNtStatusToDosError(status));
        return FALSE;
    }
    return TRUE;
212 213 214 215 216
}

/***********************************************************************
 * FindActCtxSectionStringA (KERNEL32.@)
 *
217
 * Find information about a string in an activation context.
218 219 220
 */
BOOL WINAPI FindActCtxSectionStringA(DWORD dwFlags, const GUID* lpExtGuid,
                                    ULONG ulId, LPCSTR lpSearchStr,
221
                                    PACTCTX_SECTION_KEYED_DATA pInfo)
222
{
223 224 225 226 227 228 229
    LPWSTR  search_str;
    DWORD   len;
    BOOL    ret;

    TRACE("%08x %s %u %s %p\n", dwFlags, debugstr_guid(lpExtGuid),
          ulId, debugstr_a(lpSearchStr), pInfo);

230
    if (!lpSearchStr || !pInfo)
231 232 233 234 235 236 237 238 239 240 241 242 243
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

    len = MultiByteToWideChar(CP_ACP, 0, lpSearchStr, -1, NULL, 0);
    search_str = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
    MultiByteToWideChar(CP_ACP, 0, lpSearchStr, -1, search_str, len);

    ret = FindActCtxSectionStringW(dwFlags, lpExtGuid, ulId, search_str, pInfo);

    HeapFree(GetProcessHeap(), 0, search_str);
    return ret;
244 245 246 247 248
}

/***********************************************************************
 * FindActCtxSectionStringW (KERNEL32.@)
 *
249
 * Find information about a string in an activation context.
250 251 252
 */
BOOL WINAPI FindActCtxSectionStringW(DWORD dwFlags, const GUID* lpExtGuid,
                                    ULONG ulId, LPCWSTR lpSearchStr,
253
                                    PACTCTX_SECTION_KEYED_DATA pInfo)
254
{
255 256
    UNICODE_STRING us;
    NTSTATUS status;
257

258 259 260 261 262 263
    if (!pInfo)
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

264 265 266 267 268 269 270
    RtlInitUnicodeString(&us, lpSearchStr);
    if ((status = RtlFindActivationContextSectionString(dwFlags, lpExtGuid, ulId, &us, pInfo)))
    {
        SetLastError(RtlNtStatusToDosError(status));
        return FALSE;
    }
    return TRUE;
271 272 273 274 275 276 277 278 279
}

/***********************************************************************
 * FindActCtxSectionGuid (KERNEL32.@)
 *
 * Find information about a GUID in an activation context.
 */
BOOL WINAPI FindActCtxSectionGuid(DWORD dwFlags, const GUID* lpExtGuid,
                                  ULONG ulId, const GUID* lpSearchGuid,
280
                                  PACTCTX_SECTION_KEYED_DATA pInfo)
281
{
282 283 284 285 286 287 288 289 290
    NTSTATUS status;

    if ((status = RtlFindActivationContextSectionGuid(dwFlags, lpExtGuid, ulId, lpSearchGuid, pInfo)))
    {
        SetLastError(RtlNtStatusToDosError(status));
        return FALSE;
    }

    return TRUE;
291 292 293 294 295 296 297 298 299 300 301
}

/***********************************************************************
 * 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)
{
302 303 304 305 306 307 308 309 310
    NTSTATUS status;

    if ((status = RtlQueryInformationActivationContext( dwFlags, hActCtx, pvSubInst, ulClass,
                                                        pvBuff, cbBuff, pcbLen )))
    {
        SetLastError(RtlNtStatusToDosError(status));
        return FALSE;
    }
    return TRUE;
311
}