ReactOS  0.4.14-dev-297-g23e575c
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 
24 VOID
25 NTAPI
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 
44 NTAPI
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 
128 Quickie:
129  /* Failure or success path, return to caller and free on failure */
130  if (ContextInfo.hActCtx) RtlReleaseActivationContext(ContextInfo.hActCtx);
131  return Status;
132 }
133 
134 NTSTATUS
135 NTAPI
138  OUT PVOID *ActCtx)
139 {
143  ACTCTXW Context;
144  HANDLE Result;
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 */
172  if (NT_SUCCESS(Status)) *ActCtx = Result;
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  */
195 VOID
196 WINAPI
198 {
199  /* Call the native API */
201 }
202 
203 /*
204  * @implemented
205  */
206 VOID
207 WINAPI
209 {
210  /* Call the native API */
212 }
213 
214 /*
215  * @implemented
216  */
217 BOOL
218 WINAPI
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  */
235 BOOL
236 WINAPI
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  */
266 BOOL
267 WINAPI
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  */
296 BOOL
297 WINAPI
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  */
326 BOOL
327 WINAPI
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",
364  __FUNCTION__,
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",
391  __FUNCTION__,
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",
402  __FUNCTION__,
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",
416  __FUNCTION__,
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",
427  __FUNCTION__);
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",
453  __FUNCTION__,
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",
468  __FUNCTION__,
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 */
NTSTATUS NTAPI BasepAllocateActivationContextActivationBlock(IN DWORD Flags, IN PVOID CompletionRoutine, IN PVOID CompletionContext, OUT PBASEP_ACTCTX_BLOCK *ActivationBlock)
Definition: actctx.c:45
BOOL WINAPI ActivateActCtx(IN HANDLE hActCtx, OUT PULONG_PTR ulCookie)
Definition: actctx.c:237
NTSTATUS NTAPI RtlActivateActivationContext(ULONG flags, HANDLE handle, PULONG_PTR cookie)
Definition: actctx.c:5322
VOID WINAPI AddRefActCtx(IN HANDLE hActCtx)
Definition: actctx.c:197
NTSTATUS NTAPI RtlCreateActivationContext(IN ULONG Flags, IN PACTIVATION_CONTEXT_DATA ActivationContextData, IN ULONG ExtraBytes, IN PVOID NotificationRoutine, IN PVOID NotificationContext, OUT PACTIVATION_CONTEXT *ActCtx)
Definition: actctx.c:5061
const uint16_t * PCWSTR
Definition: typedefs.h:55
#define IN
Definition: typedefs.h:38
#define TRUE
Definition: types.h:120
struct _Entry Entry
Definition: kefuncs.h:640
NTSTATUS NTAPI RtlZombifyActivationContext(PVOID Context)
Definition: actctx.c:5285
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
BOOL WINAPI GetCurrentActCtx(OUT PHANDLE phActCtx)
Definition: actctx.c:298
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
#define INVALID_HANDLE_VALUE
Definition: compat.h:391
#define QUERY_ACTCTX_FLAG_VALID
Definition: actctx.c:17
NTSTATUS NTAPI RtlQueryInformationActivationContext(ULONG flags, HANDLE handle, PVOID subinst, ULONG class, PVOID buffer, SIZE_T bufsize, SIZE_T *retlen)
Definition: actctx.c:5443
struct TraceInfo Info
#define RTL_QUERY_ACTIVATION_CONTEXT_FLAG_IS_HMODULE
Definition: rtltypes.h:117
uint32_t ULONG_PTR
Definition: typedefs.h:63
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
BOOL WINAPI DeactivateActCtx(IN DWORD dwFlags, IN ULONG_PTR ulCookie)
Definition: actctx.c:268
BOOL WINAPI ZombifyActCtx(HANDLE hActCtx)
Definition: actctx.c:219
#define STATUS_INVALID_PARAMETER_3
Definition: ntstatus.h:463
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
unsigned int BOOL
Definition: ntddk_ex.h:94
#define ISOLATIONAWARE_MANIFEST_RESOURCE_ID
Definition: winuser.h:622
_Unreferenced_parameter_ PVOID * CompletionContext
Definition: cdprocs.h:1130
VOID NTAPI RtlAddRefActivationContext(HANDLE handle)
Definition: actctx.c:5261
smooth NULL
Definition: ftsmooth.c:416
#define STATUS_INVALID_PARAMETER_2
Definition: ntstatus.h:462
_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:426
void DPRINT(...)
Definition: polytest.cpp:61
Definition: pedump.c:457
DWORD BaseSetLastNTError(IN NTSTATUS Status)
Definition: reactos.cpp:166
NTSTATUS NTAPI LdrFindResource_U(_In_ PVOID BaseAddress, _In_ PLDR_RESOURCE_INFO ResourceInfo, _In_ ULONG Level, _Out_ PIMAGE_RESOURCE_DATA_ENTRY *ResourceDataEntry)
_In_ PCWSTR FullDllName
Definition: ldrtypes.h:247
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
#define STATUS_INVALID_PARAMETER_5
Definition: ntstatus.h:465
#define STATUS_SXS_INVALID_ACTCTXDATA_FORMAT
Definition: ntstatus.h:1165
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
VOID WINAPI ReleaseActCtx(IN HANDLE hActCtx)
Definition: actctx.c:208
#define WINAPI
Definition: msvc.h:8
unsigned long DWORD
Definition: ntddk_ex.h:95
#define RTL_QUERY_ACTIVATION_CONTEXT_FLAG_IS_ADDRESS
Definition: rtltypes.h:118
_In_ PCWSTR _Out_ PVOID * ActCtx
Definition: ldrtypes.h:247
static ULONG_PTR
Definition: actctx.c:35
#define RTL_DEACTIVATE_ACTIVATION_CONTEXT_FLAG_FORCE_EARLY_DEACTIVATION
Definition: rtltypes.h:111
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
VOID NTAPI RtlReleaseActivationContext(HANDLE handle)
Definition: actctx.c:5272
#define STATUS_RESOURCE_DATA_NOT_FOUND
Definition: ntstatus.h:359
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:414
#define STATUS_INVALID_PARAMETER_1
Definition: ntstatus.h:461
VOID NTAPI BasepFreeActivationContextActivationBlock(IN PBASEP_ACTCTX_BLOCK ActivationBlock)
Definition: actctx.c:26
Status
Definition: gdiplustypes.h:24
ULONG_PTR SIZE_T
Definition: typedefs.h:78
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
NTSTATUS NTAPI RtlGetActiveActivationContext(HANDLE *handle)
Definition: actctx.c:5410
#define RTL_QUERY_ACTIVATION_CONTEXT_FLAG_USE_ACTIVE_ACTIVATION_CONTEXT
Definition: rtltypes.h:116
#define DPRINT1
Definition: precomp.h:8
#define OUT
Definition: typedefs.h:39
static const GUID LPCWSTR
Definition: actctx.c:37
#define RT_MANIFEST
Definition: winuser.h:620
struct tagContext Context
Definition: acpixf.h:1024
_In_ PIRP _In_opt_ PVOID _In_opt_ POPLOCK_WAIT_COMPLETE_ROUTINE CompletionRoutine
Definition: fsrtlfuncs.h:673
unsigned int ULONG
Definition: retypes.h:1
uint32_t * PULONG_PTR
Definition: typedefs.h:63
NTSTATUS NTAPI BasepProbeForDllManifest(IN PVOID DllHandle, IN PCWSTR FullDllName, OUT PVOID *ActCtx)
Definition: actctx.c:136
#define STATUS_INVALID_PARAMETER_4
Definition: ntstatus.h:464
return STATUS_SUCCESS
Definition: btrfs.c:2966
#define __FUNCTION__
Definition: types.h:112
base of all file and directory entries
Definition: entries.h:82
NTSTATUS NTAPI RtlDeactivateActivationContext(ULONG flags, ULONG_PTR cookie)
Definition: actctx.c:5330
#define RTL_QUERY_ACTIVATION_CONTEXT_FLAG_NO_ADDREF
Definition: rtltypes.h:119
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68