For React Native.
-- v3: kernel32/tests: Add tests for RtlActivateActivationContextUnsafe() and RtlDeactivateActivationContextUnsafeFast(). ntdll: Implement RtlDeactivateActivationContextUnsafeFast(). ntdll: Implement RtlActivateActivationContextUnsafeFast(). ntdll: Set and check 0x8 flag for activation context stack frames. kernel32/tests: Add tests for normal activation context stack frame flags. ntdll: Use explicit ACTIVATION_CONTEXT type instead of HANDLE.
From: Zhiyi Zhang zzhang@codeweavers.com
--- dlls/kernelbase/loader.c | 10 +++- dlls/ntdll/actctx.c | 98 +++++++++++++++++++--------------------- dlls/ntdll/thread.c | 3 +- include/winternl.h | 22 ++++----- 4 files changed, 67 insertions(+), 66 deletions(-)
diff --git a/dlls/kernelbase/loader.c b/dlls/kernelbase/loader.c index 6d651b0cc9f..eb9c6b8921a 100644 --- a/dlls/kernelbase/loader.c +++ b/dlls/kernelbase/loader.c @@ -1173,7 +1173,7 @@ void WINAPI DECLSPEC_HOTPATCH AddRefActCtx( HANDLE context ) */ HANDLE WINAPI DECLSPEC_HOTPATCH CreateActCtxW( PCACTCTXW ctx ) { - HANDLE context; + struct _ACTIVATION_CONTEXT *context;
TRACE( "%p %08lx\n", ctx, ctx ? ctx->dwFlags : 0 );
@@ -1225,7 +1225,13 @@ BOOL WINAPI DECLSPEC_HOTPATCH FindActCtxSectionStringW( DWORD flags, const GUID */ BOOL WINAPI DECLSPEC_HOTPATCH GetCurrentActCtx( HANDLE *pcontext ) { - return set_ntstatus( RtlGetActiveActivationContext( pcontext )); + struct _ACTIVATION_CONTEXT *actctx; + NTSTATUS status; + + status = RtlGetActiveActivationContext( &actctx ); + if (status == STATUS_SUCCESS) + *pcontext = actctx; + return set_ntstatus( status ); }
diff --git a/dlls/ntdll/actctx.c b/dlls/ntdll/actctx.c index 9828d90d11d..7c8a4e0e1a9 100644 --- a/dlls/ntdll/actctx.c +++ b/dlls/ntdll/actctx.c @@ -1074,11 +1074,11 @@ static WCHAR *build_assembly_id( const struct assembly_identity *ai ) return ret; }
-static ACTIVATION_CONTEXT *check_actctx( HANDLE h ) +static ACTIVATION_CONTEXT *check_actctx( ACTIVATION_CONTEXT *actctx ) { - ACTIVATION_CONTEXT *ret = NULL, *actctx = h; + ACTIVATION_CONTEXT *ret = NULL;
- if (!h || h == INVALID_HANDLE_VALUE) return NULL; + if (!actctx || actctx == INVALID_HANDLE_VALUE) return NULL; __TRY { if (actctx->magic == ACTCTX_MAGIC) ret = actctx; @@ -3414,7 +3414,7 @@ static NTSTATUS parse_depend_manifests(struct actctx_loader* acl) return status; }
-static HANDLE get_current_actctx_no_addref(void) +static ACTIVATION_CONTEXT * get_current_actctx_no_addref(void) { ACTIVATION_CONTEXT_STACK *actctx_stack = NtCurrentTeb()->ActivationContextStackPointer;
@@ -3425,36 +3425,36 @@ static HANDLE get_current_actctx_no_addref(void) }
/* find the appropriate activation context for RtlQueryInformationActivationContext */ -static NTSTATUS find_query_actctx( HANDLE *handle, DWORD flags, ULONG class ) +static NTSTATUS find_query_actctx( ACTIVATION_CONTEXT **actctx, DWORD flags, ULONG class ) { NTSTATUS status = STATUS_SUCCESS;
if (flags & QUERY_ACTCTX_FLAG_USE_ACTIVE_ACTCTX) { - if (*handle) return STATUS_INVALID_PARAMETER; + if (*actctx) return STATUS_INVALID_PARAMETER;
- *handle = get_current_actctx_no_addref(); + *actctx = get_current_actctx_no_addref(); } else if (flags & (QUERY_ACTCTX_FLAG_ACTCTX_IS_ADDRESS|QUERY_ACTCTX_FLAG_ACTCTX_IS_HMODULE)) { ULONG_PTR magic; LDR_DATA_TABLE_ENTRY *pldr;
- if (!*handle) return STATUS_INVALID_PARAMETER; + if (!*actctx) return STATUS_INVALID_PARAMETER;
LdrLockLoaderLock( 0, NULL, &magic ); - if (!LdrFindEntryForAddress( *handle, &pldr )) + if (!LdrFindEntryForAddress( *actctx, &pldr )) { - if ((flags & QUERY_ACTCTX_FLAG_ACTCTX_IS_HMODULE) && *handle != pldr->DllBase) + if ((flags & QUERY_ACTCTX_FLAG_ACTCTX_IS_HMODULE) && *actctx != pldr->DllBase) status = STATUS_DLL_NOT_FOUND; else - *handle = pldr->ActivationContext; + *actctx = pldr->ActivationContext; } else status = STATUS_DLL_NOT_FOUND; LdrUnlockLoaderLock( 0, magic ); } - else if (!*handle && (class != ActivationContextBasicInformation)) - *handle = process_actctx; + else if (!*actctx && (class != ActivationContextBasicInformation)) + *actctx = process_actctx;
return status; } @@ -5227,7 +5227,7 @@ static const WCHAR *find_app_settings( ACTIVATION_CONTEXT *actctx, const WCHAR * void actctx_init(void) { ACTCTXW ctx; - HANDLE handle; + ACTIVATION_CONTEXT *actctx;
ctx.cbSize = sizeof(ctx); ctx.lpSource = NULL; @@ -5235,7 +5235,7 @@ void actctx_init(void) ctx.hModule = NtCurrentTeb()->Peb->ImageBaseAddress; ctx.lpResourceName = (LPCWSTR)CREATEPROCESS_MANIFEST_RESOURCE_ID;
- if (!RtlCreateActivationContext( &handle, &ctx )) process_actctx = check_actctx(handle); + if (!RtlCreateActivationContext( &actctx, &ctx )) process_actctx = check_actctx( actctx );
NtCurrentTeb()->Peb->ActivationContextData = process_actctx; } @@ -5248,7 +5248,7 @@ void actctx_init(void) * * FIXME: function signature/prototype is wrong */ -NTSTATUS WINAPI RtlCreateActivationContext( HANDLE *handle, const void *ptr ) +NTSTATUS WINAPI RtlCreateActivationContext( ACTIVATION_CONTEXT **new_actctx, const void *ptr ) { const ACTCTXW *pActCtx = ptr; /* FIXME: not the right structure */ const WCHAR *directory = NULL; @@ -5384,7 +5384,7 @@ NTSTATUS WINAPI RtlCreateActivationContext( HANDLE *handle, const void *ptr ) if (status == STATUS_SUCCESS) status = parse_depend_manifests(&acl); free_depend_manifests( &acl );
- if (status == STATUS_SUCCESS) *handle = actctx; + if (status == STATUS_SUCCESS) *new_actctx = actctx; else actctx_release( actctx ); return status;
@@ -5398,22 +5398,18 @@ error: /*********************************************************************** * RtlAddRefActivationContext (NTDLL.@) */ -void WINAPI RtlAddRefActivationContext( HANDLE handle ) +void WINAPI RtlAddRefActivationContext( ACTIVATION_CONTEXT *actctx ) { - ACTIVATION_CONTEXT *actctx; - - if ((actctx = check_actctx( handle ))) actctx_addref( actctx ); + if (check_actctx( actctx )) actctx_addref( actctx ); }
/****************************************************************** * RtlReleaseActivationContext (NTDLL.@) */ -void WINAPI RtlReleaseActivationContext( HANDLE handle ) +void WINAPI RtlReleaseActivationContext( ACTIVATION_CONTEXT *actctx ) { - ACTIVATION_CONTEXT *actctx; - - if ((actctx = check_actctx( handle ))) actctx_release( actctx ); + if (check_actctx( actctx )) actctx_release( actctx ); }
/****************************************************************** @@ -5421,38 +5417,38 @@ void WINAPI RtlReleaseActivationContext( HANDLE handle ) * * FIXME: function prototype might be wrong */ -NTSTATUS WINAPI RtlZombifyActivationContext( HANDLE handle ) +NTSTATUS WINAPI RtlZombifyActivationContext( ACTIVATION_CONTEXT *actctx ) { - FIXME("%p: stub\n", handle); + FIXME("%p: stub\n", actctx); return STATUS_NOT_IMPLEMENTED; }
/****************************************************************** * RtlActivateActivationContext (NTDLL.@) */ -NTSTATUS WINAPI RtlActivateActivationContext( ULONG unknown, HANDLE handle, PULONG_PTR cookie ) +NTSTATUS WINAPI RtlActivateActivationContext( ULONG unknown, ACTIVATION_CONTEXT *actctx, PULONG_PTR cookie ) { - return RtlActivateActivationContextEx( 0, NtCurrentTeb(), handle, cookie ); + return RtlActivateActivationContextEx( 0, NtCurrentTeb(), actctx, cookie ); }
/****************************************************************** * RtlActivateActivationContextEx (NTDLL.@) */ -NTSTATUS WINAPI RtlActivateActivationContextEx( ULONG flags, TEB *teb, HANDLE handle, ULONG_PTR *cookie ) +NTSTATUS WINAPI RtlActivateActivationContextEx( ULONG flags, TEB *teb, ACTIVATION_CONTEXT *actctx, ULONG_PTR *cookie ) { ACTIVATION_CONTEXT_STACK *actctx_stack = teb->ActivationContextStackPointer; RTL_ACTIVATION_CONTEXT_STACK_FRAME *frame;
frame = RtlAllocateHeap( GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, sizeof(*frame) ); frame->Previous = actctx_stack->ActiveFrame; - frame->ActivationContext = handle; + frame->ActivationContext = actctx; frame->Flags = 0; actctx_stack->ActiveFrame = frame; - RtlAddRefActivationContext( handle ); + RtlAddRefActivationContext( actctx );
*cookie = (ULONG_PTR)frame; - TRACE( "%p cookie=%Ix\n", handle, *cookie ); + TRACE( "%p cookie=%Ix\n", actctx, *cookie ); return STATUS_SUCCESS; }
@@ -5522,9 +5518,9 @@ void WINAPI RtlFreeActivationContextStack( ACTIVATION_CONTEXT_STACK *actctx_stac /****************************************************************** * RtlGetActiveActivationContext (NTDLL.@) */ -NTSTATUS WINAPI RtlGetActiveActivationContext( HANDLE *handle ) +NTSTATUS WINAPI RtlGetActiveActivationContext( ACTIVATION_CONTEXT **actctx ) { - RtlAddRefActivationContext( *handle = get_current_actctx_no_addref() ); + RtlAddRefActivationContext( *actctx = get_current_actctx_no_addref() ); return STATUS_SUCCESS; }
@@ -5532,13 +5528,13 @@ NTSTATUS WINAPI RtlGetActiveActivationContext( HANDLE *handle ) /****************************************************************** * RtlIsActivationContextActive (NTDLL.@) */ -BOOLEAN WINAPI RtlIsActivationContextActive( HANDLE handle ) +BOOLEAN WINAPI RtlIsActivationContextActive( ACTIVATION_CONTEXT *actctx ) { ACTIVATION_CONTEXT_STACK *actctx_stack = NtCurrentTeb()->ActivationContextStackPointer; RTL_ACTIVATION_CONTEXT_STACK_FRAME *frame;
for (frame = actctx_stack->ActiveFrame; frame; frame = frame->Previous) - if (frame->ActivationContext == handle) return TRUE; + if (frame->ActivationContext == actctx) return TRUE; return FALSE; }
@@ -5549,18 +5545,17 @@ BOOLEAN WINAPI RtlIsActivationContextActive( HANDLE handle ) * Get information about an activation context. * FIXME: function signature/prototype may be wrong */ -NTSTATUS WINAPI RtlQueryInformationActivationContext( ULONG flags, HANDLE handle, PVOID subinst, +NTSTATUS WINAPI RtlQueryInformationActivationContext( ULONG flags, ACTIVATION_CONTEXT *actctx, PVOID subinst, ULONG class, PVOID buffer, SIZE_T bufsize, SIZE_T *retlen ) { - ACTIVATION_CONTEXT *actctx; NTSTATUS status;
- TRACE("%08lx %p %p %lu %p %Id %p\n", flags, handle, + TRACE("%08lx %p %p %lu %p %Id %p\n", flags, actctx, subinst, class, buffer, bufsize, retlen);
if (retlen) *retlen = 0; - if ((status = find_query_actctx( &handle, flags, class ))) return status; + if ((status = find_query_actctx( &actctx, flags, class ))) return status;
switch (class) { @@ -5571,9 +5566,9 @@ NTSTATUS WINAPI RtlQueryInformationActivationContext( ULONG flags, HANDLE handle if (retlen) *retlen = sizeof(*info); if (!info || bufsize < sizeof(*info)) return STATUS_BUFFER_TOO_SMALL;
- info->hActCtx = handle; + info->hActCtx = actctx; info->dwFlags = 0; /* FIXME */ - if (!(flags & QUERY_ACTCTX_FLAG_NO_ADDREF)) RtlAddRefActivationContext( handle ); + if (!(flags & QUERY_ACTCTX_FLAG_NO_ADDREF)) RtlAddRefActivationContext( actctx ); } break;
@@ -5584,7 +5579,7 @@ NTSTATUS WINAPI RtlQueryInformationActivationContext( ULONG flags, HANDLE handle SIZE_T len, manifest_len = 0, config_len = 0, appdir_len = 0; LPWSTR ptr;
- if (!(actctx = check_actctx(handle))) return STATUS_INVALID_PARAMETER; + if (!check_actctx(actctx)) return STATUS_INVALID_PARAMETER;
if (actctx->num_assemblies) assembly = actctx->assemblies;
@@ -5639,7 +5634,7 @@ NTSTATUS WINAPI RtlQueryInformationActivationContext( ULONG flags, HANDLE handle SIZE_T len, id_len = 0, ad_len = 0, path_len = 0; LPWSTR ptr;
- if (!(actctx = check_actctx(handle))) return STATUS_INVALID_PARAMETER; + if (!check_actctx(actctx)) return STATUS_INVALID_PARAMETER; if (!subinst) return STATUS_INVALID_PARAMETER;
index = *(DWORD*)subinst; @@ -5708,7 +5703,7 @@ NTSTATUS WINAPI RtlQueryInformationActivationContext( ULONG flags, HANDLE handle SIZE_T len, dll_len = 0; LPWSTR ptr;
- if (!(actctx = check_actctx(handle))) return STATUS_INVALID_PARAMETER; + if (!check_actctx(actctx)) return STATUS_INVALID_PARAMETER; if (!acqi) return STATUS_INVALID_PARAMETER;
if (acqi->ulAssemblyIndex >= actctx->num_assemblies) @@ -5752,7 +5747,7 @@ NTSTATUS WINAPI RtlQueryInformationActivationContext( ULONG flags, HANDLE handle ULONG num_compat_contexts = 0, n; SIZE_T len;
- if (!(actctx = check_actctx(handle))) return STATUS_INVALID_PARAMETER; + if (!check_actctx(actctx)) return STATUS_INVALID_PARAMETER;
if (actctx->num_assemblies) assembly = actctx->assemblies;
@@ -5777,7 +5772,7 @@ NTSTATUS WINAPI RtlQueryInformationActivationContext( ULONG flags, HANDLE handle struct assembly *assembly; SIZE_T len;
- if (!(actctx = check_actctx(handle))) return STATUS_INVALID_PARAMETER; + if (!check_actctx(actctx)) return STATUS_INVALID_PARAMETER;
len = sizeof(*acrli); if (retlen) *retlen = len; @@ -5894,11 +5889,10 @@ NTSTATUS WINAPI RtlFindActivationContextSectionGuid( ULONG flags, const GUID *ex /*********************************************************************** * RtlQueryActivationContextApplicationSettings (NTDLL.@) */ -NTSTATUS WINAPI RtlQueryActivationContextApplicationSettings( DWORD flags, HANDLE handle, const WCHAR *ns, +NTSTATUS WINAPI RtlQueryActivationContextApplicationSettings( DWORD flags, ACTIVATION_CONTEXT *actctx, const WCHAR *ns, const WCHAR *settings, WCHAR *buffer, SIZE_T size, SIZE_T *written ) { - ACTIVATION_CONTEXT *actctx; const WCHAR *res;
if (flags) @@ -5919,8 +5913,8 @@ NTSTATUS WINAPI RtlQueryActivationContextApplicationSettings( DWORD flags, HANDL } else ns = windowsSettings2005NSW;
- if (!handle) handle = process_actctx; - if (!(actctx = check_actctx( handle ))) return STATUS_INVALID_PARAMETER; + if (!actctx) actctx = process_actctx; + if (!check_actctx( actctx )) return STATUS_INVALID_PARAMETER;
if (!(res = find_app_settings( actctx, settings, ns ))) return STATUS_SXS_KEY_NOT_FOUND;
diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c index ee784fb2db2..3d1e6e0f752 100644 --- a/dlls/ntdll/thread.c +++ b/dlls/ntdll/thread.c @@ -257,7 +257,8 @@ NTSTATUS WINAPI RtlCreateUserThread( HANDLE process, SECURITY_DESCRIPTOR *descr, ULONG flags = suspended ? THREAD_CREATE_FLAGS_CREATE_SUSPENDED : 0; ULONG_PTR buffer[offsetof( PS_ATTRIBUTE_LIST, Attributes[2] ) / sizeof(ULONG_PTR)]; PS_ATTRIBUTE_LIST *attr_list = (PS_ATTRIBUTE_LIST *)buffer; - HANDLE handle, actctx; + struct _ACTIVATION_CONTEXT *actctx; + HANDLE handle; TEB *teb; ULONG ret; NTSTATUS status; diff --git a/include/winternl.h b/include/winternl.h index 86f5f4e5480..e8a0b6ef5c6 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -3812,7 +3812,7 @@ typedef struct _LDR_DATA_TABLE_ENTRY SHORT TlsIndex; LIST_ENTRY HashLinks; ULONG TimeDateStamp; - HANDLE ActivationContext; + struct _ACTIVATION_CONTEXT *ActivationContext; void* Lock; LDR_DDAG_NODE* DdagNode; LIST_ENTRY NodeModuleLink; @@ -4700,8 +4700,8 @@ NTSYSAPI BYTE WINAPI RtlAcquireResourceExclusive(LPRTL_RWLOCK,BYTE); NTSYSAPI BYTE WINAPI RtlAcquireResourceShared(LPRTL_RWLOCK,BYTE); NTSYSAPI void WINAPI RtlAcquireSRWLockExclusive(RTL_SRWLOCK*); NTSYSAPI void WINAPI RtlAcquireSRWLockShared(RTL_SRWLOCK*); -NTSYSAPI NTSTATUS WINAPI RtlActivateActivationContext(DWORD,HANDLE,ULONG_PTR*); -NTSYSAPI NTSTATUS WINAPI RtlActivateActivationContextEx(ULONG,TEB*,HANDLE,ULONG_PTR*); +NTSYSAPI NTSTATUS WINAPI RtlActivateActivationContext(DWORD,struct _ACTIVATION_CONTEXT *,ULONG_PTR*); +NTSYSAPI NTSTATUS WINAPI RtlActivateActivationContextEx(ULONG,TEB*,struct _ACTIVATION_CONTEXT *,ULONG_PTR*); NTSYSAPI NTSTATUS WINAPI RtlAddAccessAllowedAce(PACL,DWORD,DWORD,PSID); NTSYSAPI NTSTATUS WINAPI RtlAddAccessAllowedAceEx(PACL,DWORD,DWORD,DWORD,PSID); NTSYSAPI NTSTATUS WINAPI RtlAddAccessAllowedObjectAce(PACL,DWORD,DWORD,DWORD,GUID*,GUID*,PSID); @@ -4715,7 +4715,7 @@ NTSYSAPI NTSTATUS WINAPI RtlAddAuditAccessAceEx(PACL,DWORD,DWORD,DWORD,PSID,BOO NTSYSAPI NTSTATUS WINAPI RtlAddAuditAccessObjectAce(PACL,DWORD,DWORD,DWORD,GUID*,GUID*,PSID,BOOL,BOOL); NTSYSAPI NTSTATUS WINAPI RtlAddMandatoryAce(PACL,DWORD,DWORD,DWORD,DWORD,PSID); NTSYSAPI NTSTATUS WINAPI RtlAddProcessTrustLabelAce(PACL,DWORD,DWORD,PSID,DWORD,DWORD); -NTSYSAPI void WINAPI RtlAddRefActivationContext(HANDLE); +NTSYSAPI void WINAPI RtlAddRefActivationContext(struct _ACTIVATION_CONTEXT *); NTSYSAPI PVOID WINAPI RtlAddVectoredContinueHandler(ULONG,PVECTORED_EXCEPTION_HANDLER); NTSYSAPI PVOID WINAPI RtlAddVectoredExceptionHandler(ULONG,PVECTORED_EXCEPTION_HANDLER); NTSYSAPI PVOID WINAPI RtlAddressInSectionTable(const IMAGE_NT_HEADERS*,HMODULE,DWORD); @@ -4754,7 +4754,7 @@ NTSYSAPI NTSTATUS WINAPI RtlCopySecurityDescriptor(PSECURITY_DESCRIPTOR,PSECURI NTSYSAPI BOOLEAN WINAPI RtlCopySid(DWORD,PSID,PSID); NTSYSAPI void WINAPI RtlCopyUnicodeString(UNICODE_STRING*,const UNICODE_STRING*); NTSYSAPI NTSTATUS WINAPI RtlCreateAcl(PACL,DWORD,DWORD); -NTSYSAPI NTSTATUS WINAPI RtlCreateActivationContext(HANDLE*,const void*); +NTSYSAPI NTSTATUS WINAPI RtlCreateActivationContext(struct _ACTIVATION_CONTEXT **,const void*); NTSYSAPI NTSTATUS WINAPI RtlCreateAtomTable(ULONG,RTL_ATOM_TABLE*); NTSYSAPI NTSTATUS WINAPI RtlCreateEnvironment(BOOLEAN, PWSTR*); NTSYSAPI HANDLE WINAPI RtlCreateHeap(ULONG,PVOID,SIZE_T,SIZE_T,PVOID,PRTL_HEAP_PARAMETERS); @@ -4862,7 +4862,7 @@ NTSYSAPI void WINAPI RtlFreeUnicodeString(PUNICODE_STRING); NTSYSAPI void WINAPI RtlFreeUserStack(void*); NTSYSAPI NTSTATUS WINAPI RtlGUIDFromString(PUNICODE_STRING,GUID*); NTSYSAPI NTSTATUS WINAPI RtlGetAce(PACL,DWORD,LPVOID *); -NTSYSAPI NTSTATUS WINAPI RtlGetActiveActivationContext(HANDLE*); +NTSYSAPI NTSTATUS WINAPI RtlGetActiveActivationContext(struct _ACTIVATION_CONTEXT **); NTSYSAPI NTSTATUS WINAPI RtlGetCompressionWorkSpaceSize(USHORT,PULONG,PULONG); NTSYSAPI NTSTATUS WINAPI RtlGetControlSecurityDescriptor(PSECURITY_DESCRIPTOR, PSECURITY_DESCRIPTOR_CONTROL,LPDWORD); NTSYSAPI ULONG WINAPI RtlGetCurrentDirectory_U(ULONG, LPWSTR); @@ -4932,7 +4932,7 @@ NTSYSAPI NTSTATUS WINAPI RtlInitializeSid(PSID,PSID_IDENTIFIER_AUTHORITY,BYTE); NTSYSAPI NTSTATUS WINAPI RtlInt64ToUnicodeString(ULONGLONG,ULONG,UNICODE_STRING *); NTSYSAPI NTSTATUS WINAPI RtlIntegerToChar(ULONG,ULONG,ULONG,PCHAR); NTSYSAPI NTSTATUS WINAPI RtlIntegerToUnicodeString(ULONG,ULONG,UNICODE_STRING *); -NTSYSAPI BOOLEAN WINAPI RtlIsActivationContextActive(HANDLE); +NTSYSAPI BOOLEAN WINAPI RtlIsActivationContextActive(struct _ACTIVATION_CONTEXT *); NTSYSAPI BOOL WINAPI RtlIsCriticalSectionLocked(RTL_CRITICAL_SECTION *); NTSYSAPI BOOL WINAPI RtlIsCriticalSectionLockedByThread(RTL_CRITICAL_SECTION *); NTSYSAPI BOOLEAN WINAPI RtlIsCurrentProcess(HANDLE); @@ -4979,14 +4979,14 @@ NTSYSAPI void WINAPI RtlPopFrame(TEB_ACTIVE_FRAME*); NTSYSAPI BOOLEAN WINAPI RtlPrefixString(const STRING*,const STRING*,BOOLEAN); NTSYSAPI void WINAPI RtlProcessFlsData(void*,ULONG); NTSYSAPI void WINAPI RtlPushFrame(TEB_ACTIVE_FRAME*); -NTSYSAPI NTSTATUS WINAPI RtlQueryActivationContextApplicationSettings(DWORD,HANDLE,const WCHAR*,const WCHAR*,WCHAR*,SIZE_T,SIZE_T*); +NTSYSAPI NTSTATUS WINAPI RtlQueryActivationContextApplicationSettings(DWORD,struct _ACTIVATION_CONTEXT *,const WCHAR*,const WCHAR*,WCHAR*,SIZE_T,SIZE_T*); NTSYSAPI NTSTATUS WINAPI RtlQueryAtomInAtomTable(RTL_ATOM_TABLE,RTL_ATOM,ULONG*,ULONG*,WCHAR*,ULONG*); NTSYSAPI NTSTATUS WINAPI RtlQueryDynamicTimeZoneInformation(RTL_DYNAMIC_TIME_ZONE_INFORMATION*); NTSYSAPI NTSTATUS WINAPI RtlQueryEnvironmentVariable(WCHAR*,const WCHAR*,SIZE_T,WCHAR*,SIZE_T,SIZE_T*); NTSYSAPI NTSTATUS WINAPI RtlQueryEnvironmentVariable_U(PWSTR,PUNICODE_STRING,PUNICODE_STRING); NTSYSAPI NTSTATUS WINAPI RtlQueryHeapInformation(HANDLE,HEAP_INFORMATION_CLASS,PVOID,SIZE_T,PSIZE_T); NTSYSAPI NTSTATUS WINAPI RtlQueryInformationAcl(PACL,LPVOID,DWORD,ACL_INFORMATION_CLASS); -NTSYSAPI NTSTATUS WINAPI RtlQueryInformationActivationContext(ULONG,HANDLE,PVOID,ULONG,PVOID,SIZE_T,SIZE_T*); +NTSYSAPI NTSTATUS WINAPI RtlQueryInformationActivationContext(ULONG,struct _ACTIVATION_CONTEXT *,PVOID,ULONG,PVOID,SIZE_T,SIZE_T*); NTSYSAPI NTSTATUS WINAPI RtlQueryInformationActiveActivationContext(ULONG,PVOID,SIZE_T,SIZE_T *); NTSYSAPI NTSTATUS WINAPI RtlQueryPackageIdentity(HANDLE,WCHAR*,SIZE_T*,WCHAR*,SIZE_T*,BOOLEAN*); NTSYSAPI BOOL WINAPI RtlQueryPerformanceCounter(LARGE_INTEGER*); @@ -5003,7 +5003,7 @@ NTSYSAPI void WINAPI RtlRbInsertNodeEx(RTL_RB_TREE*,RTL_BALANCED_NODE*,BOOL NTSYSAPI void WINAPI RtlRbRemoveNode(RTL_RB_TREE*,RTL_BALANCED_NODE*); NTSYSAPI PVOID WINAPI RtlReAllocateHeap(HANDLE,ULONG,PVOID,SIZE_T) __WINE_ALLOC_SIZE(4) __WINE_DEALLOC(RtlFreeHeap,3); NTSYSAPI NTSTATUS WINAPI RtlRegisterWait(PHANDLE,HANDLE,RTL_WAITORTIMERCALLBACKFUNC,PVOID,ULONG,ULONG); -NTSYSAPI void WINAPI RtlReleaseActivationContext(HANDLE); +NTSYSAPI void WINAPI RtlReleaseActivationContext(struct _ACTIVATION_CONTEXT *); NTSYSAPI void WINAPI RtlReleasePath(PWSTR); NTSYSAPI void WINAPI RtlReleasePebLock(void); NTSYSAPI void WINAPI RtlReleaseRelativeName(RTL_RELATIVE_NAME*); @@ -5100,7 +5100,7 @@ NTSYSAPI NTSTATUS WINAPI RtlWow64GetProcessMachines(HANDLE,USHORT*,USHORT*); NTSYSAPI NTSTATUS WINAPI RtlWow64GetSharedInfoProcess(HANDLE,BOOLEAN*,WOW64INFO*); NTSYSAPI NTSTATUS WINAPI RtlWow64IsWowGuestMachineSupported(USHORT,BOOLEAN*); NTSYSAPI NTSTATUS WINAPI RtlWriteRegistryValue(ULONG,PCWSTR,PCWSTR,ULONG,PVOID,ULONG); -NTSYSAPI NTSTATUS WINAPI RtlZombifyActivationContext(HANDLE); +NTSYSAPI NTSTATUS WINAPI RtlZombifyActivationContext(struct _ACTIVATION_CONTEXT *); NTSYSAPI NTSTATUS WINAPI RtlpNtCreateKey(PHANDLE,ACCESS_MASK,const OBJECT_ATTRIBUTES*,ULONG,const UNICODE_STRING*,ULONG,PULONG); NTSYSAPI NTSTATUS WINAPI RtlpNtEnumerateSubKey(HANDLE,UNICODE_STRING *, ULONG); NTSYSAPI NTSTATUS WINAPI RtlpNtMakeTemporaryKey(HANDLE);
From: Zhiyi Zhang zzhang@codeweavers.com
Test that the flags for normal activation context stack frames has 0x8, which is probably to note that a frame is allocated from the heap according to later tests. --- dlls/kernel32/tests/actctx.c | 67 ++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+)
diff --git a/dlls/kernel32/tests/actctx.c b/dlls/kernel32/tests/actctx.c index ca24ed10549..71b1b5721fb 100644 --- a/dlls/kernel32/tests/actctx.c +++ b/dlls/kernel32/tests/actctx.c @@ -31,11 +31,15 @@
static BOOL (WINAPI *pQueryActCtxSettingsW)(DWORD,HANDLE,LPCWSTR,LPCWSTR,LPWSTR,SIZE_T,SIZE_T*);
+static NTSTATUS (NTAPI *pRtlActivateActivationContext)(ULONG,struct _ACTIVATION_CONTEXT *,ULONG_PTR *); +static NTSTATUS (NTAPI *pRtlActivateActivationContextEx)(ULONG,TEB *,struct _ACTIVATION_CONTEXT *,ULONG_PTR *); static NTSTATUS(NTAPI *pRtlFindActivationContextSectionString)(DWORD,const GUID *,ULONG,PUNICODE_STRING,PACTCTX_SECTION_KEYED_DATA); static BOOLEAN (NTAPI *pRtlCreateUnicodeStringFromAsciiz)(PUNICODE_STRING, PCSZ); static VOID (NTAPI *pRtlFreeUnicodeString)(PUNICODE_STRING); static NTSTATUS(NTAPI *pRtlQueryInformationActiveActivationContext)(ULONG,PVOID,SIZE_T,SIZE_T *);
+#define NTDLL_ACTCTX_STACK_FRAME_HEAP_ALLOCATED 0x8 /* RTL_ACTIVATION_CONTEXT_STACK_FRAME.Flags */ + #ifdef __i386__ #define ARCH "x86" #elif defined __aarch64__ || defined__arm64ec__ @@ -2197,7 +2201,9 @@ static void test_allowDelayedBinding(void)
static void test_actctx(void) { + RTL_ACTIVATION_CONTEXT_STACK_FRAME *frame; ULONG_PTR cookie; + NTSTATUS status; HANDLE handle; BOOL b;
@@ -2213,6 +2219,65 @@ static void test_actctx(void) ReleaseActCtx(handle); }
+ /* Test flags for normal frames */ + if (!create_manifest_file("test1.manifest", manifest1, -1, NULL, NULL)) + { + skip("Could not create manifest file\n"); + return; + } + handle = test_create("test1.manifest"); + ok(handle != INVALID_HANDLE_VALUE, "handle == INVALID_HANDLE_VALUE, error %lu\n", GetLastError()); + DeleteFileA("test1.manifest"); + if (handle != INVALID_HANDLE_VALUE) + { + b = ActivateActCtx(handle, &cookie); + ok(b, "ActivateActCtx failed: %lu\n", GetLastError()); + + frame = NtCurrentTeb()->ActivationContextStackPointer->ActiveFrame; + ok(!frame->Previous, "Got unexpected Previous.\n"); + ok(frame->ActivationContext == handle, "Got unexpected ActivationContext.\n"); + todo_wine + ok(frame->Flags & NTDLL_ACTCTX_STACK_FRAME_HEAP_ALLOCATED, "Got unexpected Flags %#lx.\n", frame->Flags); + + b = DeactivateActCtx(0, cookie); + ok(b, "DeactivateActCtx failed: %lu\n", GetLastError()); + b = GetCurrentActCtx(&handle); + ok(handle == NULL, "handle = %p, expected NULL\n", handle); + ok(b, "GetCurrentActCtx failed: %lu\n", GetLastError()); + + status = pRtlActivateActivationContext(0, handle, &cookie); + ok(status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status); + + frame = NtCurrentTeb()->ActivationContextStackPointer->ActiveFrame; + ok(!frame->Previous, "Got unexpected Previous.\n"); + ok(frame->ActivationContext == handle, "Got unexpected ActivationContext.\n"); + todo_wine + ok(frame->Flags & NTDLL_ACTCTX_STACK_FRAME_HEAP_ALLOCATED, "Got unexpected Flags %#lx.\n", frame->Flags); + + b = DeactivateActCtx(0, cookie); + ok(b, "DeactivateActCtx failed: %lu\n", GetLastError()); + b = GetCurrentActCtx(&handle); + ok(handle == NULL, "handle = %p, expected NULL\n", handle); + ok(b, "GetCurrentActCtx failed: %lu\n", GetLastError()); + + status = pRtlActivateActivationContextEx(0, NtCurrentTeb(), handle, &cookie); + ok(status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status); + + frame = NtCurrentTeb()->ActivationContextStackPointer->ActiveFrame; + ok(!frame->Previous, "Got unexpected Previous.\n"); + ok(frame->ActivationContext == handle, "Got unexpected ActivationContext.\n"); + todo_wine + ok(frame->Flags & NTDLL_ACTCTX_STACK_FRAME_HEAP_ALLOCATED, "Got unexpected Flags %#lx.\n", frame->Flags); + + b = DeactivateActCtx(0, cookie); + ok(b, "DeactivateActCtx failed: %lu\n", GetLastError()); + b = GetCurrentActCtx(&handle); + ok(handle == NULL, "handle = %p, expected NULL\n", handle); + ok(b, "GetCurrentActCtx failed: %lu\n", GetLastError()); + + ReleaseActCtx(handle); + } + /* test for whitespace handling in Eq ::= S? '=' S? */ create_manifest_file("test1_1.manifest", manifest1_1, -1, NULL, NULL); handle = test_create("test1_1.manifest"); @@ -3096,6 +3161,8 @@ static BOOL init_funcs(void) pQueryActCtxSettingsW = (void *)GetProcAddress( hLibrary, "QueryActCtxSettingsW" );
hLibrary = GetModuleHandleA("ntdll.dll"); + X(RtlActivateActivationContext); + X(RtlActivateActivationContextEx); X(RtlFindActivationContextSectionString); X(RtlCreateUnicodeStringFromAsciiz); X(RtlFreeUnicodeString);
From: Zhiyi Zhang zzhang@codeweavers.com
Prepare for RtlActivateActivationContextUnsafeFast(), which adds frames with flags 0x20. Normal frame flags are 0x28. So 0x8 is most likely to note that it's callee-allocated and needs to be freed in RtlFreeActivationContextStack(). Whereas missing 0x8 probably means a frame is caller-allocated. --- dlls/kernel32/tests/actctx.c | 3 --- dlls/ntdll/actctx.c | 5 +++-- dlls/ntdll/ntdll_misc.h | 3 +++ 3 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/dlls/kernel32/tests/actctx.c b/dlls/kernel32/tests/actctx.c index 71b1b5721fb..050b39516d9 100644 --- a/dlls/kernel32/tests/actctx.c +++ b/dlls/kernel32/tests/actctx.c @@ -2236,7 +2236,6 @@ static void test_actctx(void) frame = NtCurrentTeb()->ActivationContextStackPointer->ActiveFrame; ok(!frame->Previous, "Got unexpected Previous.\n"); ok(frame->ActivationContext == handle, "Got unexpected ActivationContext.\n"); - todo_wine ok(frame->Flags & NTDLL_ACTCTX_STACK_FRAME_HEAP_ALLOCATED, "Got unexpected Flags %#lx.\n", frame->Flags);
b = DeactivateActCtx(0, cookie); @@ -2251,7 +2250,6 @@ static void test_actctx(void) frame = NtCurrentTeb()->ActivationContextStackPointer->ActiveFrame; ok(!frame->Previous, "Got unexpected Previous.\n"); ok(frame->ActivationContext == handle, "Got unexpected ActivationContext.\n"); - todo_wine ok(frame->Flags & NTDLL_ACTCTX_STACK_FRAME_HEAP_ALLOCATED, "Got unexpected Flags %#lx.\n", frame->Flags);
b = DeactivateActCtx(0, cookie); @@ -2266,7 +2264,6 @@ static void test_actctx(void) frame = NtCurrentTeb()->ActivationContextStackPointer->ActiveFrame; ok(!frame->Previous, "Got unexpected Previous.\n"); ok(frame->ActivationContext == handle, "Got unexpected ActivationContext.\n"); - todo_wine ok(frame->Flags & NTDLL_ACTCTX_STACK_FRAME_HEAP_ALLOCATED, "Got unexpected Flags %#lx.\n", frame->Flags);
b = DeactivateActCtx(0, cookie); diff --git a/dlls/ntdll/actctx.c b/dlls/ntdll/actctx.c index 7c8a4e0e1a9..d4dba2369e3 100644 --- a/dlls/ntdll/actctx.c +++ b/dlls/ntdll/actctx.c @@ -5443,7 +5443,7 @@ NTSTATUS WINAPI RtlActivateActivationContextEx( ULONG flags, TEB *teb, ACTIVATIO frame = RtlAllocateHeap( GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, sizeof(*frame) ); frame->Previous = actctx_stack->ActiveFrame; frame->ActivationContext = actctx; - frame->Flags = 0; + frame->Flags = NTDLL_ACTCTX_STACK_FRAME_HEAP_ALLOCATED; actctx_stack->ActiveFrame = frame; RtlAddRefActivationContext( actctx );
@@ -5508,7 +5508,8 @@ void WINAPI RtlFreeActivationContextStack( ACTIVATION_CONTEXT_STACK *actctx_stac { RTL_ACTIVATION_CONTEXT_STACK_FRAME *prev = frame->Previous; RtlReleaseActivationContext( frame->ActivationContext ); - RtlFreeHeap( GetProcessHeap(), 0, frame ); + if (frame->Flags & NTDLL_ACTCTX_STACK_FRAME_HEAP_ALLOCATED) + RtlFreeHeap( GetProcessHeap(), 0, frame ); frame = prev; } actctx_stack->ActiveFrame = NULL; diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h index f82edef6b65..e0760afdc2a 100644 --- a/dlls/ntdll/ntdll_misc.h +++ b/dlls/ntdll/ntdll_misc.h @@ -35,6 +35,9 @@
#define NTDLL_TLS_ERRNO 16 /* TLS slot for _errno() */
+/* undocumented */ +#define NTDLL_ACTCTX_STACK_FRAME_HEAP_ALLOCATED 0x8 /* RTL_ACTIVATION_CONTEXT_STACK_FRAME.Flags */ + #ifdef __i386__ static const USHORT current_machine = IMAGE_FILE_MACHINE_I386; #elif defined(__x86_64__)
From: Zhiyi Zhang zzhang@codeweavers.com
--- dlls/ntdll/actctx.c | 19 +++++++++++++++++++ dlls/ntdll/ntdll.spec | 2 +- include/winternl.h | 11 +++++++++++ 3 files changed, 31 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/actctx.c b/dlls/ntdll/actctx.c index d4dba2369e3..5b9befc6bb7 100644 --- a/dlls/ntdll/actctx.c +++ b/dlls/ntdll/actctx.c @@ -5431,6 +5431,25 @@ NTSTATUS WINAPI RtlActivateActivationContext( ULONG unknown, ACTIVATION_CONTEXT return RtlActivateActivationContextEx( 0, NtCurrentTeb(), actctx, cookie ); }
+/****************************************************************** + * RtlActivateActivationContextUnsafeFast (NTDLL.@) + * + * FIXME: function prototype might be wrong + */ +RTL_ACTIVATION_CONTEXT_STACK_FRAME * FASTCALL RtlActivateActivationContextUnsafeFast( RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED *frame_extended, + ACTIVATION_CONTEXT *actctx ) +{ + ACTIVATION_CONTEXT_STACK *actctx_stack = NtCurrentTeb()->ActivationContextStackPointer; + + TRACE( "%p %p\n", frame_extended, actctx ); + + frame_extended->Frame.Previous = actctx_stack->ActiveFrame; + frame_extended->Frame.ActivationContext = actctx; + frame_extended->Frame.Flags = 0; + actctx_stack->ActiveFrame = &frame_extended->Frame; + RtlAddRefActivationContext( actctx ); + return &frame_extended->Frame; +}
/****************************************************************** * RtlActivateActivationContextEx (NTDLL.@) diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index 4e36bfe2662..f79dfd50da5 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -484,7 +484,7 @@ @ stdcall RtlAcquireSRWLockShared(ptr) @ stdcall RtlActivateActivationContext(long ptr ptr) @ stdcall RtlActivateActivationContextEx(long ptr ptr ptr) -@ stub RtlActivateActivationContextUnsafeFast +@ stdcall -fastcall RtlActivateActivationContextUnsafeFast(ptr ptr) @ stdcall RtlAddAccessAllowedAce(ptr long long ptr) @ stdcall RtlAddAccessAllowedAceEx(ptr long long long ptr) @ stdcall RtlAddAccessAllowedObjectAce(ptr long long long ptr ptr ptr) diff --git a/include/winternl.h b/include/winternl.h index e8a0b6ef5c6..fe102fb47ff 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -231,6 +231,17 @@ typedef struct _RTL_ACTIVATION_CONTEXT_STACK_FRAME ULONG Flags; } RTL_ACTIVATION_CONTEXT_STACK_FRAME, *PRTL_ACTIVATION_CONTEXT_STACK_FRAME;
+typedef struct _RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED +{ + SIZE_T Size; + ULONG Format; + RTL_ACTIVATION_CONTEXT_STACK_FRAME Frame; + PVOID Extra1; + PVOID Extra2; + PVOID Extra3; + PVOID Extra4; +} RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED, *PRTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED; + typedef struct _ACTIVATION_CONTEXT_STACK { RTL_ACTIVATION_CONTEXT_STACK_FRAME *ActiveFrame;
From: Zhiyi Zhang zzhang@codeweavers.com
--- dlls/ntdll/actctx.c | 17 +++++++++++++++++ dlls/ntdll/ntdll.spec | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/actctx.c b/dlls/ntdll/actctx.c index 5b9befc6bb7..bc23bcc79ef 100644 --- a/dlls/ntdll/actctx.c +++ b/dlls/ntdll/actctx.c @@ -5451,6 +5451,23 @@ RTL_ACTIVATION_CONTEXT_STACK_FRAME * FASTCALL RtlActivateActivationContextUnsafe return &frame_extended->Frame; }
+/****************************************************************** + * RtlDeactivateActivationContextUnsafeFast (NTDLL.@) + * + * FIXME: function prototype might be wrong + */ +VOID FASTCALL RtlDeactivateActivationContextUnsafeFast( RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED *frame_extended ) +{ + ACTIVATION_CONTEXT_STACK *actctx_stack = NtCurrentTeb()->ActivationContextStackPointer; + ACTIVATION_CONTEXT *actctx; + + TRACE( "%p\n", frame_extended ); + + actctx = actctx_stack->ActiveFrame->ActivationContext; + actctx_stack->ActiveFrame = frame_extended->Frame.Previous; + RtlReleaseActivationContext( actctx ); +} + /****************************************************************** * RtlActivateActivationContextEx (NTDLL.@) */ diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index f79dfd50da5..78da963b969 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -606,7 +606,7 @@ @ stub RtlCutoverTimeToSystemTime @ stdcall RtlDeNormalizeProcessParams(ptr) @ stdcall RtlDeactivateActivationContext(long long) -@ stub RtlDeactivateActivationContextUnsafeFast +@ stdcall -fastcall RtlDeactivateActivationContextUnsafeFast(ptr) @ stub RtlDebugPrintTimes @ stdcall RtlDecodePointer(ptr) @ stdcall RtlDecodeSystemPointer(ptr) RtlDecodePointer
From: Zhiyi Zhang zzhang@codeweavers.com
--- dlls/kernel32/tests/actctx.c | 121 +++++++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+)
diff --git a/dlls/kernel32/tests/actctx.c b/dlls/kernel32/tests/actctx.c index 050b39516d9..947804a02d8 100644 --- a/dlls/kernel32/tests/actctx.c +++ b/dlls/kernel32/tests/actctx.c @@ -33,7 +33,11 @@ static BOOL (WINAPI *pQueryActCtxSettingsW)(DWORD,HANDLE,LPCWSTR,LPCWSTR,LPWST
static NTSTATUS (NTAPI *pRtlActivateActivationContext)(ULONG,struct _ACTIVATION_CONTEXT *,ULONG_PTR *); static NTSTATUS (NTAPI *pRtlActivateActivationContextEx)(ULONG,TEB *,struct _ACTIVATION_CONTEXT *,ULONG_PTR *); +static PRTL_ACTIVATION_CONTEXT_STACK_FRAME (FASTCALL *pRtlActivateActivationContextUnsafeFast)(PRTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED, + struct _ACTIVATION_CONTEXT *); +static VOID (FASTCALL *pRtlDeactivateActivationContextUnsafeFast)(PRTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED); static NTSTATUS(NTAPI *pRtlFindActivationContextSectionString)(DWORD,const GUID *,ULONG,PUNICODE_STRING,PACTCTX_SECTION_KEYED_DATA); +static VOID (NTAPI *pRtlFreeThreadActivationContextStack)(VOID); static BOOLEAN (NTAPI *pRtlCreateUnicodeStringFromAsciiz)(PUNICODE_STRING, PCSZ); static VOID (NTAPI *pRtlFreeUnicodeString)(PUNICODE_STRING); static NTSTATUS(NTAPI *pRtlQueryInformationActiveActivationContext)(ULONG,PVOID,SIZE_T,SIZE_T *); @@ -3160,7 +3164,10 @@ static BOOL init_funcs(void) hLibrary = GetModuleHandleA("ntdll.dll"); X(RtlActivateActivationContext); X(RtlActivateActivationContextEx); + X(RtlActivateActivationContextUnsafeFast); + X(RtlDeactivateActivationContextUnsafeFast); X(RtlFindActivationContextSectionString); + X(RtlFreeThreadActivationContextStack); X(RtlCreateUnicodeStringFromAsciiz); X(RtlFreeUnicodeString); X(RtlQueryInformationActiveActivationContext); @@ -4590,6 +4597,119 @@ static void test_RtlQueryInformationActiveActivationContext(void) ReleaseActCtx( context ); }
+static void test_RtlActivateActivationContextUnsafeFast(void) +{ + RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED frame_extended1 = {0}, frame_extended2 = {0}; + HANDLE context1, context2, current_context; + RTL_ACTIVATION_CONTEXT_STACK_FRAME *frame; + BOOL ret; + + ret = GetCurrentActCtx(¤t_context); + ok(ret, "GetCurrentActCtx failed.\n"); + ok(!current_context, "Got unexpected handle.\n"); + + if (!create_manifest_file("test1.manifest", manifest1, -1, NULL, NULL)) + { + skip("Could not create manifest file 1.\n"); + return; + } + if (!create_manifest_file("test2.manifest", manifest1_1, -1, NULL, NULL)) + { + skip("Could not create manifest file 2.\n"); + DeleteFileA("test1.manifest"); + return; + } + context1 = test_create("test1.manifest"); + ok(context1 != INVALID_HANDLE_VALUE, "Failed to create context, error %lu.\n", GetLastError()); + DeleteFileA("test1.manifest"); + context2 = test_create("test2.manifest"); + ok(context2 != INVALID_HANDLE_VALUE, "Failed to create context, error %lu.\n", GetLastError()); + DeleteFileA("test2.manifest"); + + /* Size and Format don't seem to be checked */ + frame_extended1.Size = 0; + frame_extended1.Format = 0xdeadbeef; + frame = pRtlActivateActivationContextUnsafeFast(&frame_extended1, context1); + /* RtlActivateActivationContextUnsafeFast() has a different prototype on <= Win7 */ + ok(frame == &frame_extended1.Frame || broken(frame != &frame_extended1.Frame), "Got unexpected frame.\n"); + ok(frame_extended1.Size == 0, "Got unexpected Size %#Ix.\n", frame_extended1.Size); + ok(frame_extended1.Format == 0xdeadbeef, "Got unexpected Format %#lx.\n", frame_extended1.Format); + ok(!frame_extended1.Frame.Previous, "Got unexpected Previous.\n"); + ok(frame_extended1.Frame.ActivationContext == context1, "Got unexpected ActivationContext.\n"); + ok(!(frame_extended1.Frame.Flags & NTDLL_ACTCTX_STACK_FRAME_HEAP_ALLOCATED), + "Got unexpected Flags %#lx.\n", frame_extended1.Frame.Flags); + + ret = GetCurrentActCtx(¤t_context); + ok(current_context == context1, "Got unexpected handle.\n"); + ReleaseActCtx(current_context); + + pRtlDeactivateActivationContextUnsafeFast(&frame_extended1); + ret = GetCurrentActCtx(¤t_context); + ok(ret, "GetCurrentActCtx failed.\n"); + ok(!current_context, "Got unexpected handle.\n"); + + /* Normal call */ + frame_extended1.Size = sizeof(frame_extended1); + frame_extended1.Format = 0; + frame = pRtlActivateActivationContextUnsafeFast(&frame_extended1, context1); + /* RtlActivateActivationContextUnsafeFast() has a different prototype on <= Win7 */ + ok(frame == &frame_extended1.Frame || broken(frame != &frame_extended1.Frame), "Got unexpected frame.\n"); + ok(frame_extended1.Size == sizeof(frame_extended1), "Got unexpected Size %#Ix.\n", frame_extended1.Size); + ok(frame_extended1.Format == 0, "Got unexpected Format %#lx.\n", frame_extended1.Format); + ok(!frame_extended1.Frame.Previous, "Got unexpected Previous.\n"); + ok(frame_extended1.Frame.ActivationContext == context1, "Got unexpected ActivationContext.\n"); + ok(!(frame_extended1.Frame.Flags & NTDLL_ACTCTX_STACK_FRAME_HEAP_ALLOCATED), + "Got unexpected Flags %#lx.\n", frame_extended1.Frame.Flags); + + ret = GetCurrentActCtx(¤t_context); + ok(current_context == context1, "Got unexpected handle.\n"); + ReleaseActCtx(current_context); + + /* Activate another activation context */ + frame_extended2.Size = sizeof(frame_extended2); + frame_extended2.Format = 0; + frame = pRtlActivateActivationContextUnsafeFast(&frame_extended2, context2); + ok(frame == &frame_extended2.Frame || broken(frame != &frame_extended2.Frame), "Got unexpected frame %p.\n", frame); + ok(frame_extended2.Size == sizeof(frame_extended2), "Got unexpected Size %#Ix.\n", frame_extended2.Size); + ok(frame_extended2.Format == 0, "Got unexpected Format %#lx.\n", frame_extended2.Format); + ok(frame_extended2.Frame.Previous == &frame_extended1.Frame, "Got unexpected Previous.\n"); + ok(frame_extended2.Frame.ActivationContext == context2, "Got unexpected ActivationContext.\n"); + ok(!(frame_extended2.Frame.Flags & NTDLL_ACTCTX_STACK_FRAME_HEAP_ALLOCATED), + "Got unexpected Flags %#lx.\n", frame_extended2.Frame.Flags); + + ret = GetCurrentActCtx(¤t_context); + ok(current_context == context2, "Got unexpected handle.\n"); + ReleaseActCtx(current_context); + + pRtlDeactivateActivationContextUnsafeFast(&frame_extended2); + ret = GetCurrentActCtx(¤t_context); + ok(current_context == context1, "Got unexpected handle.\n"); + ReleaseActCtx(current_context); + + pRtlDeactivateActivationContextUnsafeFast(&frame_extended1); + ret = GetCurrentActCtx(¤t_context); + ok(ret, "GetCurrentActCtx failed.\n"); + ok(!current_context, "Got unexpected handle.\n"); + + /* Test freeing an unsafe frame. Not crashing means RtlFreeThreadActivationContextStack() must + * be able to handle it, most likely by checking the frame flags */ + frame_extended1.Size = sizeof(frame_extended1); + frame = pRtlActivateActivationContextUnsafeFast(&frame_extended1, context1); + ok(frame == &frame_extended1.Frame || broken(frame != &frame_extended1.Frame), "Got unexpected frame.\n"); + + ret = GetCurrentActCtx(¤t_context); + ok(current_context == context1, "Got unexpected handle.\n"); + ReleaseActCtx(current_context); + + pRtlFreeThreadActivationContextStack(); + ret = GetCurrentActCtx(¤t_context); + ok(ret, "GetCurrentActCtx failed.\n"); + ok(!current_context, "Got unexpected handle.\n"); + + ReleaseActCtx(context2); + ReleaseActCtx(context1); +} + START_TEST(actctx) { int argc; @@ -4630,5 +4750,6 @@ START_TEST(actctx) test_compatibility(); test_settings(); test_RtlQueryInformationActiveActivationContext(); + test_RtlActivateActivationContextUnsafeFast(); for (int i = 1; i <= 6; i++) run_child_process_two_dll(i); }
On Wed Jun 18 07:42:55 2025 +0000, Nikolay Sivov wrote:
Do we need to check size field?
It doesn't check the size field. I added tests to show this.