ReactOS 0.4.16-dev-257-g6aa11ac
actctx.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: dll/win32/kernel32/client/actctx.c
5 * PURPOSE: Activation contexts - NT-compatible helpers
6 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
7 *
8 * NOTE: See also kernel32/wine/actctx.c
9 */
10
11/* INCLUDES ******************************************************************/
12
13#include <k32.h>
14#define NDEBUG
15#include <debug.h>
16
17#define QUERY_ACTCTX_FLAG_VALID (QUERY_ACTCTX_FLAG_USE_ACTIVE_ACTCTX | \
18 QUERY_ACTCTX_FLAG_ACTCTX_IS_HMODULE | \
19 QUERY_ACTCTX_FLAG_ACTCTX_IS_ADDRESS | \
20 QUERY_ACTCTX_FLAG_NO_ADDREF)
21
22/* PRIVATE FUNCTIONS *********************************************************/
23
24VOID
27{
28 /* Exit if there was nothing passed in */
29 if (!ActivationBlock) return;
30
31 /* Do we have a context? */
32 if (ActivationBlock->ActivationContext)
33 {
34 /* Release and clear it */
35 RtlReleaseActivationContext(ActivationBlock->ActivationContext);
36 ActivationBlock->ActivationContext = NULL;
37 }
38
39 /* Free the block */
40 RtlFreeHeap(RtlGetProcessHeap(), 0, ActivationBlock);
41}
42
48 OUT PBASEP_ACTCTX_BLOCK *ActivationBlock)
49{
51 ACTIVATION_CONTEXT_BASIC_INFORMATION ContextInfo;
52
53 /* Clear the info structure */
54 ContextInfo.dwFlags = 0;
55 ContextInfo.hActCtx = NULL;
56
57 /* Assume failure */
58 if (ActivationBlock) *ActivationBlock = NULL;
59
60 /* Only support valid flags */
61 if (Flags & ~(1 | 2)) // FIXME: What are they? 2 looks like BASEP_ACTCTX_FORCE_BLOCK
62 {
63 /* Fail if unknown flags are passed in */
65 goto Quickie;
66 }
67
68 /* Caller should have passed in an activation block */
69 if (!ActivationBlock)
70 {
71 /* Fail otherwise */
73 goto Quickie;
74 }
75
76 /* Query RTL for information on the current activation context */
78 NULL,
79 NULL,
80 ActivationContextBasicInformation,
81 &ContextInfo,
82 sizeof(ContextInfo),
83 NULL);
84 if (!NT_SUCCESS(Status))
85 {
86 /* Failed -- bail out */
87 DPRINT1("SXS: %s - Failure getting active activation context; ntstatus %08lx\n",
89 goto Quickie;
90 }
91
92 /* Check if the current one should be freed */
93 if (ContextInfo.dwFlags & 1)
94 {
95 /* Release and clear it */
96 RtlReleaseActivationContext(ContextInfo.hActCtx);
97 ContextInfo.hActCtx = NULL;
98 }
99
100 /* Check if there's an active context, or if the caller is forcing one */
101 if (!(Flags & 2) || (ContextInfo.hActCtx))
102 {
103 /* Allocate the block */
104 *ActivationBlock = RtlAllocateHeap(RtlGetProcessHeap(),
105 0,
106 sizeof(BASEP_ACTCTX_BLOCK));
107 if (!(*ActivationBlock))
108 {
109 /* Ran out of memory, fail */
111 goto Quickie;
112 }
113
114 /* Fill it out */
115 (*ActivationBlock)->ActivationContext = ContextInfo.hActCtx;
116 (*ActivationBlock)->Flags = 0;
117 if (Flags & 1) (*ActivationBlock)->Flags |= 1; // Not sure about this flag
118 (*ActivationBlock)->CompletionRoutine = CompletionRoutine;
119 (*ActivationBlock)->CompletionContext = CompletionContext;
120
121 /* Tell Quickie below not to free anything, since this is success */
122 ContextInfo.hActCtx = NULL;
123 }
124
125 /* Set success status */
127
128Quickie:
129 /* Failure or success path, return to caller and free on failure */
130 if (ContextInfo.hActCtx) RtlReleaseActivationContext(ContextInfo.hActCtx);
131 return Status;
132}
133
135NTAPI
139{
143 ACTCTXW Context;
145
146 /* Check if activation context parameter is provided */
147 if (!ActCtx)
148 {
149 ASSERT(FALSE);
151 }
152
153 /* Zero it out */
154 *ActCtx = NULL;
155
156 /* Check whether the image has manifest resource associated with it */
157 Info.Type = (ULONG_PTR)RT_MANIFEST;
159 Info.Language = 0;
160 if (!(Status = LdrFindResource_U(DllHandle, &Info, 3, &Entry)))
161 {
162 /* Create the activation context */
163 Context.cbSize = sizeof(Context);
164 Context.lpSource = FullDllName;
165 Context.dwFlags = ACTCTX_FLAG_RESOURCE_NAME_VALID | ACTCTX_FLAG_HMODULE_VALID;
166 Context.hModule = DllHandle;
168
170
171 /* Store activation context pointer if it was created successfully */
173
174 /* CORE-10843: Windows always returns this since we pass the wrong struct */
176 {
177 /* Fake "Manifest not found" so the load doesn't fail */
178 static int Once;
179 if (Once++)
180 {
181 DPRINT1("HACK: Passed invalid ACTIVATION_CONTEXT_DATA!\n");
182 }
184 }
185 }
186
187 return Status;
188}
189
190/* PUBLIC FUNCTIONS **********************************************************/
191
192/*
193 * @implemented
194 */
195VOID
196WINAPI
198{
199 /* Call the native API */
201}
202
203/*
204 * @implemented
205 */
206VOID
207WINAPI
209{
210 /* Call the native API */
212}
213
214/*
215 * @implemented
216 */
217BOOL
218WINAPI
220{
222
223 /* Call the native API */
225 if (NT_SUCCESS(Status)) return TRUE;
226
227 /* Set last error if we failed */
229 return FALSE;
230}
231
232/*
233 * @implemented
234 */
235BOOL
236WINAPI
238 OUT PULONG_PTR ulCookie)
239{
241
242 /* Check if the handle was invalid */
243 if (hActCtx == INVALID_HANDLE_VALUE)
244 {
245 /* Set error and bail out */
247 return FALSE;
248 }
249
250 /* Call the native API */
251 Status = RtlActivateActivationContext(0, hActCtx, ulCookie);
252 if (!NT_SUCCESS(Status))
253 {
254 /* Set error and bail out */
256 return FALSE;
257 }
258
259 /* It worked */
260 return TRUE;
261}
262
263/*
264 * @implemented
265 */
266BOOL
267WINAPI
269 IN ULONG_PTR ulCookie)
270{
271 ULONG NativeFlags;
272
273 /* Check if the flags are invalid */
274 if ((dwFlags & ~DEACTIVATE_ACTCTX_FLAG_FORCE_EARLY_DEACTIVATION) != 0)
275 {
276 /* Set error and bail out */
278 return FALSE;
279 }
280
281 /* Convert flags */
282 NativeFlags = 0;
283 if (dwFlags & DEACTIVATE_ACTCTX_FLAG_FORCE_EARLY_DEACTIVATION)
284 {
286 }
287
288 /* Call the native API -- it can never fail */
289 RtlDeactivateActivationContext(NativeFlags, ulCookie);
290 return TRUE;
291}
292
293/*
294 * @implemented
295 */
296BOOL
297WINAPI
299{
301
302 /* Check if the output handle pointer was invalid */
303 if (phActCtx == NULL)
304 {
305 /* Set error and bail out */
307 return FALSE;
308 }
309
310 /* Call the native API */
312 if (!NT_SUCCESS(Status))
313 {
314 /* Set error and bail out */
316 return FALSE;
317 }
318
319 /* It worked */
320 return TRUE;
321}
322
323/*
324 * @implemented
325 */
326BOOL
327WINAPI
329 IN HANDLE hActCtx,
330 IN PVOID pvSubInstance,
331 IN ULONG ulInfoClass,
332 IN PVOID pvBuffer,
333 IN SIZE_T cbBuffer,
334 IN OUT SIZE_T *pcbWrittenOrRequired OPTIONAL)
335{
336 ULONG NativeFlags = 0;
338
339 /* Assume failure */
340 if (pcbWrittenOrRequired) *pcbWrittenOrRequired = 0;
341
342 /* Check if native flags were passed in to the Win32 function */
343 switch (dwFlags & 3)
344 {
346 dwFlags |= QUERY_ACTCTX_FLAG_USE_ACTIVE_ACTCTX;
347 break;
349 dwFlags |= QUERY_ACTCTX_FLAG_ACTCTX_IS_HMODULE;
350 break;
351 case (RTL_QUERY_ACTIVATION_CONTEXT_FLAG_IS_ADDRESS - 1): // Yep, not sure why
352 dwFlags |= QUERY_ACTCTX_FLAG_ACTCTX_IS_ADDRESS;
353 break;
354 }
355
356 /* Now mask out the native flags */
357 dwFlags &= ~3;
358
359 /* Check if any invalid flags are left */
361 {
362 /* Yep, bail out */
363 DPRINT1("SXS: %s() bad flags(passed: 0x%lx, allowed: 0x%lx, bad: 0x%lx)\n",
365 dwFlags,
369 return FALSE;
370 }
371
372 /* See if additional parameters are required */
373 switch (ulInfoClass)
374 {
375 case ActivationContextBasicInformation:
376 case ActivationContextDetailedInformation:
377 case CompatibilityInformationInActivationContext:
378 case RunlevelInformationInActivationContext:
379
380 /* Nothing to check */
381 break;
382
383 case AssemblyDetailedInformationInActivationContext:
384 case FileInformationInAssemblyOfAssemblyInActivationContext:
385
386 /* We need a subinstance for these queries*/
387 if (!pvSubInstance)
388 {
389 /* None present, bail out */
390 DPRINT1("SXS: %s() InfoClass 0x%lx requires SubInstance != NULL\n",
392 ulInfoClass);
394 return FALSE;
395 }
396 break;
397
398 default:
399
400 /* Invalid class, bail out */
401 DPRINT1("SXS: %s() bad InfoClass(0x%lx)\n",
403 ulInfoClass);
405 return FALSE;
406 }
407
408 /* Check if no buffer was passed in*/
409 if (!pvBuffer)
410 {
411 /* But a non-zero length was? */
412 if (cbBuffer)
413 {
414 /* This is bogus... */
415 DPRINT1("SXS: %s() (pvBuffer == NULL) && ((cbBuffer=0x%lu) != 0)\n",
417 cbBuffer);
419 return FALSE;
420 }
421
422 /* But the caller doesn't want to know how big to make it? */
423 if (!pcbWrittenOrRequired)
424 {
425 /* That's bogus */
426 DPRINT1("SXS: %s() (pvBuffer == NULL) && (pcbWrittenOrRequired == NULL)\n",
429 return FALSE;
430 }
431 }
432
433 /* These 3 flags are mutually exclusive -- only one should be present */
434 switch (dwFlags & (QUERY_ACTCTX_FLAG_VALID & ~QUERY_ACTCTX_FLAG_NO_ADDREF))
435 {
436 /* Convert into native format */
437 case QUERY_ACTCTX_FLAG_USE_ACTIVE_ACTCTX:
439 break;
440 case QUERY_ACTCTX_FLAG_ACTCTX_IS_HMODULE:
442 break;
443 case QUERY_ACTCTX_FLAG_ACTCTX_IS_ADDRESS:
445 break;
446 case 0:
447 break;
448
449 /* More than one flag is set... */
450 default:
451 /* Bail out */
452 DPRINT1("SXS: %s(dwFlags=0x%lx) more than one flag in 0x%lx was passed\n",
454 dwFlags,
455 0x1C);
457 return FALSE;
458 }
459
460 /* Convert this last flag */
461 if (dwFlags & QUERY_ACTCTX_FLAG_NO_ADDREF)
462 {
464 }
465
466 /* Now call the native API */
467 DPRINT("SXS: %s() Calling Native API with Native Flags %lx for Win32 Flags %lx\n",
469 NativeFlags,
470 dwFlags);
472 hActCtx,
473 pvSubInstance,
474 ulInfoClass,
475 pvBuffer,
476 cbBuffer,
477 pcbWrittenOrRequired);
478 if (NT_SUCCESS(Status)) return TRUE;
479
480 /* Failed, set error and return */
482 return FALSE;
483}
484
485/* EOF */
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:590
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:608
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
BOOL WINAPI ZombifyActCtx(HANDLE hActCtx)
Definition: actctx.c:219
VOID WINAPI ReleaseActCtx(IN HANDLE hActCtx)
Definition: actctx.c:208
BOOL WINAPI DeactivateActCtx(IN DWORD dwFlags, IN ULONG_PTR ulCookie)
Definition: actctx.c:268
VOID WINAPI AddRefActCtx(IN HANDLE hActCtx)
Definition: actctx.c:197
BOOL WINAPI QueryActCtxW(IN DWORD dwFlags, IN HANDLE hActCtx, IN PVOID pvSubInstance, IN ULONG ulInfoClass, IN PVOID pvBuffer, IN SIZE_T cbBuffer, IN OUT SIZE_T *pcbWrittenOrRequired OPTIONAL)
Definition: actctx.c:328
BOOL WINAPI GetCurrentActCtx(OUT PHANDLE phActCtx)
Definition: actctx.c:298
NTSTATUS NTAPI BasepAllocateActivationContextActivationBlock(IN DWORD Flags, IN PVOID CompletionRoutine, IN PVOID CompletionContext, OUT PBASEP_ACTCTX_BLOCK *ActivationBlock)
Definition: actctx.c:45
NTSTATUS NTAPI BasepProbeForDllManifest(IN PVOID DllHandle, IN PCWSTR FullDllName, OUT PVOID *ActCtx)
Definition: actctx.c:136
BOOL WINAPI ActivateActCtx(IN HANDLE hActCtx, OUT PULONG_PTR ulCookie)
Definition: actctx.c:237
#define QUERY_ACTCTX_FLAG_VALID
Definition: actctx.c:17
VOID NTAPI BasepFreeActivationContextActivationBlock(IN PBASEP_ACTCTX_BLOCK ActivationBlock)
Definition: actctx.c:26
#define __FUNCTION__
Definition: types.h:116
#define ULONG_PTR
Definition: config.h:101
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
Status
Definition: gdiplustypes.h:25
NTSYSAPI NTSTATUS WINAPI RtlActivateActivationContext(DWORD, HANDLE, ULONG_PTR *)
NTSYSAPI NTSTATUS WINAPI RtlZombifyActivationContext(HANDLE)
Definition: actctx.c:5396
NTSYSAPI void WINAPI RtlAddRefActivationContext(HANDLE)
Definition: actctx.c:5373
NTSYSAPI void WINAPI RtlDeactivateActivationContext(DWORD, ULONG_PTR)
NTSYSAPI void WINAPI RtlReleaseActivationContext(HANDLE)
Definition: actctx.c:5384
NTSYSAPI NTSTATUS WINAPI RtlCreateActivationContext(HANDLE *, const void *)
NTSYSAPI NTSTATUS WINAPI RtlGetActiveActivationContext(HANDLE *)
Definition: actctx.c:5539
NTSYSAPI NTSTATUS WINAPI RtlQueryInformationActivationContext(ULONG, HANDLE, PVOID, ULONG, PVOID, SIZE_T, SIZE_T *)
Definition: actctx.c:5572
NTSTATUS NTAPI LdrFindResource_U(_In_ PVOID BaseAddress, _In_ PLDR_RESOURCE_INFO ResourceInfo, _In_ ULONG Level, _Out_ PIMAGE_RESOURCE_DATA_ENTRY *ResourceDataEntry)
_In_ PCWSTR _Out_ PVOID * ActCtx
Definition: ldrtypes.h:247
_In_ PCWSTR FullDllName
Definition: ldrtypes.h:247
#define ASSERT(a)
Definition: mode.c:44
#define RTL_QUERY_ACTIVATION_CONTEXT_FLAG_IS_ADDRESS
Definition: rtltypes.h:118
#define RTL_QUERY_ACTIVATION_CONTEXT_FLAG_IS_HMODULE
Definition: rtltypes.h:117
#define RTL_DEACTIVATE_ACTIVATION_CONTEXT_FLAG_FORCE_EARLY_DEACTIVATION
Definition: rtltypes.h:111
#define RTL_QUERY_ACTIVATION_CONTEXT_FLAG_NO_ADDREF
Definition: rtltypes.h:119
#define RTL_QUERY_ACTIVATION_CONTEXT_FLAG_USE_ACTIVE_ACTIVATION_CONTEXT
Definition: rtltypes.h:116
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
#define STATUS_INVALID_PARAMETER_4
Definition: ntstatus.h:478
#define STATUS_INVALID_PARAMETER_2
Definition: ntstatus.h:476
#define STATUS_SXS_INVALID_ACTCTXDATA_FORMAT
Definition: ntstatus.h:1384
#define STATUS_RESOURCE_DATA_NOT_FOUND
Definition: ntstatus.h:373
#define STATUS_INVALID_PARAMETER_1
Definition: ntstatus.h:475
#define STATUS_INVALID_PARAMETER_3
Definition: ntstatus.h:477
#define STATUS_INVALID_PARAMETER_5
Definition: ntstatus.h:479
DWORD BaseSetLastNTError(IN NTSTATUS Status)
Definition: reactos.cpp:167
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:73
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
base of all file and directory entries
Definition: entries.h:83
Definition: pedump.c:458
uint32_t * PULONG_PTR
Definition: typedefs.h:65
const uint16_t * PCWSTR
Definition: typedefs.h:57
#define NTAPI
Definition: typedefs.h:36
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:690
_In_ WDFREQUEST _In_opt_ PFN_WDF_REQUEST_COMPLETION_ROUTINE _In_opt_ __drv_aliasesMem WDFCONTEXT CompletionContext
Definition: wdfrequest.h:898
_In_ WDFREQUEST _In_opt_ PFN_WDF_REQUEST_COMPLETION_ROUTINE CompletionRoutine
Definition: wdfrequest.h:895
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1176
#define WINAPI
Definition: msvc.h:6
#define RT_MANIFEST
Definition: winuser.h:621
#define ISOLATIONAWARE_MANIFEST_RESOURCE_ID
Definition: winuser.h:623
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185