4 * Copyright 2004 Jon Griffiths
5 * Copyright 2007 Eric Pouech
6 * Copyright 2007 Jacek Caban for CodeWeavers
7 * Copyright 2007 Alexandre Julliard
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25 #include "wine/port.h"
30 #define NONAMELESSUNION
31 #define NONAMELESSSTRUCT
33 #define WIN32_NO_STATUS
35 #include "ntdll_misc.h"
36 #include "wine/debug.h"
37 #include "wine/unicode.h"
39 WINE_DEFAULT_DEBUG_CHANNEL(actctx);
41 #define ACTCTX_FLAGS_ALL (\
42 ACTCTX_FLAG_PROCESSOR_ARCHITECTURE_VALID |\
43 ACTCTX_FLAG_LANGID_VALID |\
44 ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID |\
45 ACTCTX_FLAG_RESOURCE_NAME_VALID |\
46 ACTCTX_FLAG_SET_PROCESS_DEFAULT |\
47 ACTCTX_FLAG_APPLICATION_NAME_VALID |\
48 ACTCTX_FLAG_SOURCE_IS_ASSEMBLYREF |\
49 ACTCTX_FLAG_HMODULE_VALID )
51 #define ACTCTX_MAGIC 0xC07E3E11
53 typedef struct _ACTIVATION_CONTEXT
60 static ACTIVATION_CONTEXT *check_actctx( HANDLE h )
62 ACTIVATION_CONTEXT *actctx = h;
64 if (!h || h == INVALID_HANDLE_VALUE) return NULL;
65 switch (actctx->magic)
74 static inline void actctx_addref( ACTIVATION_CONTEXT *actctx )
76 interlocked_xchg_add( &actctx->ref_count, 1 );
79 static void actctx_release( ACTIVATION_CONTEXT *actctx )
81 if (interlocked_xchg_add( &actctx->ref_count, -1 ) == 1)
84 RtlFreeHeap( GetProcessHeap(), 0, actctx );
89 /***********************************************************************
90 * RtlCreateActivationContext (NTDLL.@)
92 * Create an activation context.
94 * FIXME: function signature/prototype is wrong
96 NTSTATUS WINAPI RtlCreateActivationContext( HANDLE *handle, const void *ptr )
98 const ACTCTXW *pActCtx = ptr; /* FIXME: not the right structure */
99 ACTIVATION_CONTEXT *actctx;
101 TRACE("%p %08x\n", pActCtx, pActCtx ? pActCtx->dwFlags : 0);
103 if (!pActCtx || pActCtx->cbSize != sizeof(*pActCtx) ||
104 (pActCtx->dwFlags & ~ACTCTX_FLAGS_ALL))
105 return STATUS_INVALID_PARAMETER;
107 if (!(actctx = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(*actctx) )))
108 return STATUS_NO_MEMORY;
110 actctx->magic = ACTCTX_MAGIC;
111 actctx->ref_count = 1;
114 return STATUS_SUCCESS;
118 /***********************************************************************
119 * RtlAddRefActivationContext (NTDLL.@)
121 void WINAPI RtlAddRefActivationContext( HANDLE handle )
123 ACTIVATION_CONTEXT *actctx;
125 if ((actctx = check_actctx( handle ))) actctx_addref( actctx );
129 /******************************************************************
130 * RtlReleaseActivationContext (NTDLL.@)
132 void WINAPI RtlReleaseActivationContext( HANDLE handle )
134 ACTIVATION_CONTEXT *actctx;
136 if ((actctx = check_actctx( handle ))) actctx_release( actctx );
140 /******************************************************************
141 * RtlActivateActivationContext (NTDLL.@)
143 NTSTATUS WINAPI RtlActivateActivationContext( ULONG unknown, HANDLE handle, ULONG_PTR *cookie )
145 RTL_ACTIVATION_CONTEXT_STACK_FRAME *frame;
147 TRACE( "%p %p\n", handle, cookie );
149 if (!(frame = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(*frame) )))
150 return STATUS_NO_MEMORY;
152 frame->Previous = NtCurrentTeb()->ActivationContextStack.ActiveFrame;
153 frame->ActivationContext = handle;
155 NtCurrentTeb()->ActivationContextStack.ActiveFrame = frame;
156 RtlAddRefActivationContext( handle );
158 *cookie = (ULONG_PTR)frame;
159 return STATUS_SUCCESS;
163 /***********************************************************************
164 * RtlDeactivateActivationContext (NTDLL.@)
166 void WINAPI RtlDeactivateActivationContext( ULONG flags, ULONG_PTR cookie )
168 RTL_ACTIVATION_CONTEXT_STACK_FRAME *frame, *top;
170 TRACE( "%x %lx\n", flags, cookie );
172 /* find the right frame */
173 top = NtCurrentTeb()->ActivationContextStack.ActiveFrame;
174 for (frame = top; frame; frame = frame->Previous)
175 if ((ULONG_PTR)frame == cookie) break;
178 RtlRaiseStatus( STATUS_SXS_INVALID_DEACTIVATION );
180 if (frame != top && !(flags & DEACTIVATE_ACTCTX_FLAG_FORCE_EARLY_DEACTIVATION))
181 RtlRaiseStatus( STATUS_SXS_EARLY_DEACTIVATION );
183 /* pop everything up to and including frame */
184 NtCurrentTeb()->ActivationContextStack.ActiveFrame = frame->Previous;
186 while (top != NtCurrentTeb()->ActivationContextStack.ActiveFrame)
188 frame = top->Previous;
189 RtlReleaseActivationContext( top->ActivationContext );
190 RtlFreeHeap( GetProcessHeap(), 0, top );
196 /******************************************************************
197 * RtlFreeThreadActivationContextStack (NTDLL.@)
199 void WINAPI RtlFreeThreadActivationContextStack(void)
201 RTL_ACTIVATION_CONTEXT_STACK_FRAME *frame;
203 frame = NtCurrentTeb()->ActivationContextStack.ActiveFrame;
206 RTL_ACTIVATION_CONTEXT_STACK_FRAME *prev = frame->Previous;
207 RtlReleaseActivationContext( frame->ActivationContext );
208 RtlFreeHeap( GetProcessHeap(), 0, frame );
211 NtCurrentTeb()->ActivationContextStack.ActiveFrame = NULL;
215 /******************************************************************
216 * RtlGetActiveActivationContext (NTDLL.@)
218 NTSTATUS WINAPI RtlGetActiveActivationContext( HANDLE *handle )
220 if (NtCurrentTeb()->ActivationContextStack.ActiveFrame)
222 *handle = NtCurrentTeb()->ActivationContextStack.ActiveFrame->ActivationContext;
223 RtlAddRefActivationContext( *handle );
228 return STATUS_SUCCESS;
232 /******************************************************************
233 * RtlIsActivationContextActive (NTDLL.@)
235 BOOLEAN WINAPI RtlIsActivationContextActive( HANDLE handle )
237 RTL_ACTIVATION_CONTEXT_STACK_FRAME *frame;
239 for (frame = NtCurrentTeb()->ActivationContextStack.ActiveFrame; frame; frame = frame->Previous)
240 if (frame->ActivationContext == handle) return TRUE;