Author: ion Date: Fri Sep 13 22:44:57 2013 New Revision: 60086
URL: http://svn.reactos.org/svn/reactos?rev=60086&view=rev Log: [KERNEL32/NTDLL]: Fix definition of RtlCreateActivationContext (although the code is still 100% incompatible with Windows, at least it won't destroy the stack anymore when Windows' kernel32.dll tries to call it). Take the Windows definition of ACTIVATION_CONTEXT and use it instead. Also do the Windows behavior of allocating an ACTIVATION_CONTEXT_WRAPPED structure (which has a magic header), and returning the internal ACTIVATION_CONTEXT (and then looking up the "WRAPPED" whenever we need to check the magic). Ran kernel32:actctx and no regressions seen. My hope is to get the Rtl* interfaces at least compatible enough to Kernel32 from Windows so that when using it in ROS, it doesn't immediately crash and burn, we'll see how far that goes. I don't want to rewrite 2500 lines of XML parsing.
Modified: trunk/reactos/dll/ntdll/def/ntdll.spec trunk/reactos/dll/ntdll/ldr/ldrutils.c trunk/reactos/dll/win32/kernel32/client/actctx.c trunk/reactos/dll/win32/kernel32/wine/actctx.c trunk/reactos/include/ndk/rtlfuncs.h trunk/reactos/include/ndk/rtltypes.h trunk/reactos/lib/rtl/actctx.c
Modified: trunk/reactos/dll/ntdll/def/ntdll.spec URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/ntdll/def/ntdll.spec?re... ============================================================================== --- trunk/reactos/dll/ntdll/def/ntdll.spec [iso-8859-1] (original) +++ trunk/reactos/dll/ntdll/def/ntdll.spec [iso-8859-1] Fri Sep 13 22:44:57 2013 @@ -473,7 +473,7 @@ @ stdcall RtlCopyString(ptr ptr) @ stdcall RtlCopyUnicodeString(ptr ptr) @ stdcall RtlCreateAcl(ptr long long) -@ stdcall RtlCreateActivationContext(ptr ptr) +@ stdcall RtlCreateActivationContext(long ptr long ptr ptr ptr) @ stdcall RtlCreateAndSetSD(ptr long ptr ptr ptr) @ stdcall RtlCreateAtomTable(long ptr) @ stdcall RtlCreateBootStatusDataFile()
Modified: trunk/reactos/dll/ntdll/ldr/ldrutils.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/ntdll/ldr/ldrutils.c?re... ============================================================================== --- trunk/reactos/dll/ntdll/ldr/ldrutils.c [iso-8859-1] (original) +++ trunk/reactos/dll/ntdll/ldr/ldrutils.c [iso-8859-1] Fri Sep 13 22:44:57 2013 @@ -38,7 +38,7 @@ ctx.dwFlags = ACTCTX_FLAG_RESOURCE_NAME_VALID | ACTCTX_FLAG_HMODULE_VALID; ctx.hModule = module->DllBase; ctx.lpResourceName = (LPCWSTR)ISOLATIONAWARE_MANIFEST_RESOURCE_ID; - status = RtlCreateActivationContext( &module->EntryPointActivationContext, &ctx ); + status = RtlCreateActivationContext(0, (PVOID)&ctx, 0, NULL, NULL, &module->EntryPointActivationContext); } return status; }
Modified: trunk/reactos/dll/win32/kernel32/client/actctx.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/client/a... ============================================================================== --- trunk/reactos/dll/win32/kernel32/client/actctx.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/kernel32/client/actctx.c [iso-8859-1] Fri Sep 13 22:44:57 2013 @@ -20,7 +20,6 @@ QUERY_ACTCTX_FLAG_NO_ADDREF)
/* PRIVATE FUNCTIONS *********************************************************/ -
VOID NTAPI
Modified: trunk/reactos/dll/win32/kernel32/wine/actctx.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/wine/act... ============================================================================== --- trunk/reactos/dll/win32/kernel32/wine/actctx.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/kernel32/wine/actctx.c [iso-8859-1] Fri Sep 13 22:44:57 2013 @@ -107,7 +107,7 @@
TRACE("%p %08x\n", pActCtx, pActCtx ? pActCtx->dwFlags : 0);
- if ((status = RtlCreateActivationContext(&hActCtx, (PVOID*)pActCtx))) + if ((status = RtlCreateActivationContext(0, (PVOID)pActCtx, 0, NULL, NULL, &hActCtx))) { SetLastError(RtlNtStatusToDosError(status)); return INVALID_HANDLE_VALUE;
Modified: trunk/reactos/include/ndk/rtlfuncs.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/ndk/rtlfuncs.h?rev=... ============================================================================== --- trunk/reactos/include/ndk/rtlfuncs.h [iso-8859-1] (original) +++ trunk/reactos/include/ndk/rtlfuncs.h [iso-8859-1] Fri Sep 13 22:44:57 2013 @@ -3511,8 +3511,12 @@ NTSTATUS NTAPI RtlCreateActivationContext( - _Out_ PHANDLE Handle, - _Inout_ PVOID ReturnedData + _In_ ULONG Flags, + _In_ PACTIVATION_CONTEXT_DATA ActivationContextData, + _In_ ULONG ExtraBytes, + _In_ PVOID NotificationRoutine, + _In_ PVOID NotificationContext, + _Out_ PACTIVATION_CONTEXT *ActCtx );
NTSYSAPI
Modified: trunk/reactos/include/ndk/rtltypes.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/ndk/rtltypes.h?rev=... ============================================================================== --- trunk/reactos/include/ndk/rtltypes.h [iso-8859-1] (original) +++ trunk/reactos/include/ndk/rtltypes.h [iso-8859-1] Fri Sep 13 22:44:57 2013 @@ -902,6 +902,18 @@ LIST_ENTRY FrameListCache; } ACTIVATION_CONTEXT_STACK, *PACTIVATION_CONTEXT_STACK; #endif + +typedef struct _ACTIVATION_CONTEXT_DATA +{ + ULONG Magic; + ULONG HeaderSize; + ULONG FormatVersion; + ULONG TotalSize; + ULONG DefaultTocOffset; + ULONG ExtendedTocOffset; + ULONG AssemblyRosterOffset; + ULONG Flags; +} ACTIVATION_CONTEXT_DATA, *PACTIVATION_CONTEXT_DATA;
#endif /* NTOS_MODE_USER */
Modified: trunk/reactos/lib/rtl/actctx.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/actctx.c?rev=60086&... ============================================================================== --- trunk/reactos/lib/rtl/actctx.c [iso-8859-1] (original) +++ trunk/reactos/lib/rtl/actctx.c [iso-8859-1] Fri Sep 13 22:44:57 2013 @@ -34,7 +34,7 @@ ACTCTX_FLAG_SOURCE_IS_ASSEMBLYREF |\ ACTCTX_FLAG_HMODULE_VALID )
-#define ACTCTX_MAGIC 0xC07E3E11 +#define ACTCTX_MAGIC_MARKER (PVOID)'gMcA'
#define ACTCTX_FAKE_HANDLE ((HANDLE) 0xf00baa) #define ACTCTX_FAKE_COOKIE ((ULONG_PTR) 0xf00bad) @@ -148,16 +148,40 @@ struct entity_array entities; };
+typedef struct _ASSEMBLY_STORAGE_MAP_ENTRY +{ + ULONG Flags; + UNICODE_STRING DosPath; + HANDLE Handle; +} ASSEMBLY_STORAGE_MAP_ENTRY, *PASSEMBLY_STORAGE_MAP_ENTRY; + +typedef struct _ASSEMBLY_STORAGE_MAP +{ + ULONG Flags; + ULONG AssemblyCount; + PASSEMBLY_STORAGE_MAP_ENTRY *AssemblyArray; +} ASSEMBLY_STORAGE_MAP, *PASSEMBLY_STORAGE_MAP; + typedef struct _ACTIVATION_CONTEXT { - ULONG magic; - long ref_count; - struct file_info config; - struct file_info appdir; - struct assembly *assemblies; - unsigned int num_assemblies; - unsigned int allocated_assemblies; -} ACTIVATION_CONTEXT; + LONG RefCount; + ULONG Flags; + LIST_ENTRY Links; + PACTIVATION_CONTEXT_DATA ActivationContextData; + PVOID NotificationRoutine; + PVOID NotificationContext; + ULONG SentNotifications[8]; + ULONG DisabledNotifications[8]; + ASSEMBLY_STORAGE_MAP StorageMap; + PASSEMBLY_STORAGE_MAP_ENTRY InlineStorageMapEntries; + ULONG StackTraceIndex; + PVOID StackTraces[4][4]; + struct file_info config; + struct file_info appdir; + struct assembly *assemblies; + unsigned int num_assemblies; + unsigned int allocated_assemblies; +} ACTIVATION_CONTEXT, *PIACTIVATION_CONTEXT;
struct actctx_loader { @@ -166,6 +190,60 @@ unsigned int num_dependencies; unsigned int allocated_dependencies; }; + +typedef struct _ACTIVATION_CONTEXT_WRAPPED +{ + PVOID MagicMarker; + ACTIVATION_CONTEXT ActivationContext; +} ACTIVATION_CONTEXT_WRAPPED, *PACTIVATION_CONTEXT_WRAPPED; + +VOID +NTAPI +RtlpSxsBreakOnInvalidMarker(IN PACTIVATION_CONTEXT ActCtx, + IN ULONG FailureCode) +{ + EXCEPTION_RECORD ExceptionRecord; + + /* Fatal SxS exception header */ + ExceptionRecord.ExceptionRecord = NULL; + ExceptionRecord.ExceptionCode = STATUS_SXS_CORRUPTION; + ExceptionRecord.ExceptionFlags = EXCEPTION_NONCONTINUABLE; + + /* With SxS-specific information plus the context itself */ + ExceptionRecord.ExceptionInformation[0] = 1; + ExceptionRecord.ExceptionInformation[1] = FailureCode; + ExceptionRecord.ExceptionInformation[2] = (ULONG_PTR)ActCtx; + ExceptionRecord.NumberParameters = 3; + + /* Raise it */ + RtlRaiseException(&ExceptionRecord); +} + +FORCEINLINE +VOID +RtlpValidateActCtx(IN PACTIVATION_CONTEXT ActCtx) +{ + PACTIVATION_CONTEXT_WRAPPED pActual; + + /* Get the caller-opaque header */ + pActual = CONTAINING_RECORD(ActCtx, + ACTIVATION_CONTEXT_WRAPPED, + ActivationContext); + + /* Check if the header matches as expected */ + if (pActual->MagicMarker != ACTCTX_MAGIC_MARKER) + { + /* Nope, print out a warning, assert, and then throw an exception */ + DbgPrint("%s : Invalid activation context marker %p found in activation context %p\n" + " This means someone stepped on the allocation, or someone is using a\n" + " deallocated activation context\n", + __FUNCTION__, + pActual->MagicMarker, + ActCtx); + ASSERT(pActual->MagicMarker == ACTCTX_MAGIC_MARKER); + RtlpSxsBreakOnInvalidMarker(ActCtx, 1); + } +}
static const WCHAR assemblyW[] = {'a','s','s','e','m','b','l','y',0}; static const WCHAR assemblyIdentityW[] = {'a','s','s','e','m','b','l','y','I','d','e','n','t','i','t','y',0}; @@ -210,8 +288,8 @@ static const WCHAR dotManifestW[] = {'.','m','a','n','i','f','e','s','t',0}; static const WCHAR version_formatW[] = {'%','u','.','%','u','.','%','u','.','%','u',0};
-static ACTIVATION_CONTEXT system_actctx = { ACTCTX_MAGIC, 1 }; -static ACTIVATION_CONTEXT *process_actctx = &system_actctx; +static ACTIVATION_CONTEXT_WRAPPED system_actctx = { ACTCTX_MAGIC_MARKER, { 1 } }; +static ACTIVATION_CONTEXT *process_actctx = &system_actctx.ActivationContext;
static WCHAR *strdupW(const WCHAR* str) { @@ -551,15 +629,19 @@ append_string( ret, versionW, version ); return ret; } - static ACTIVATION_CONTEXT *check_actctx( HANDLE h ) { ACTIVATION_CONTEXT *ret = NULL, *actctx = h; + PACTIVATION_CONTEXT_WRAPPED pActual;
if (!h || h == INVALID_HANDLE_VALUE) return NULL; _SEH2_TRY { - if (actctx && actctx->magic == ACTCTX_MAGIC) ret = actctx; + if (actctx) + { + pActual = CONTAINING_RECORD(actctx, ACTIVATION_CONTEXT_WRAPPED, ActivationContext); + if (pActual->MagicMarker == ACTCTX_MAGIC_MARKER) ret = &pActual->ActivationContext; + } } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { @@ -571,12 +653,14 @@
static inline void actctx_addref( ACTIVATION_CONTEXT *actctx ) { - InterlockedExchangeAdd( &actctx->ref_count, 1 ); + InterlockedExchangeAdd( &actctx->RefCount, 1 ); }
static void actctx_release( ACTIVATION_CONTEXT *actctx ) { - if (InterlockedExchangeAdd( &actctx->ref_count, -1 ) == 1) + PACTIVATION_CONTEXT_WRAPPED pActual; + + if (InterlockedExchangeAdd(&actctx->RefCount, -1) == 1) { unsigned int i, j;
@@ -599,8 +683,9 @@ RtlFreeHeap( RtlGetProcessHeap(), 0, actctx->config.info ); RtlFreeHeap( RtlGetProcessHeap(), 0, actctx->appdir.info ); RtlFreeHeap( RtlGetProcessHeap(), 0, actctx->assemblies ); - actctx->magic = 0; - RtlFreeHeap( RtlGetProcessHeap(), 0, actctx ); + pActual = CONTAINING_RECORD(actctx, ACTIVATION_CONTEXT_WRAPPED, ActivationContext); + pActual->MagicMarker = 0; + RtlFreeHeap(RtlGetProcessHeap(), 0, pActual); } }
@@ -2238,15 +2323,26 @@ ctx.hModule = NtCurrentTeb()->ProcessEnvironmentBlock->ImageBaseAddress; ctx.lpResourceName = (LPCWSTR)CREATEPROCESS_MANIFEST_RESOURCE_ID;
- if (!RtlCreateActivationContext( &handle, &ctx )) process_actctx = check_actctx(handle); + if (NT_SUCCESS(RtlCreateActivationContext(0, (PVOID)&ctx, 0, NULL, NULL, &handle))) + { + process_actctx = check_actctx(handle); + } }
/* FUNCTIONS ***************************************************************/
-NTSTATUS WINAPI RtlCreateActivationContext( HANDLE *handle, void *ptr ) -{ - const ACTCTXW *pActCtx = ptr; +NTSTATUS +NTAPI +RtlCreateActivationContext(IN ULONG Flags, + IN PACTIVATION_CONTEXT_DATA ActivationContextData, + IN ULONG ExtraBytes, + IN PVOID NotificationRoutine, + IN PVOID NotificationContext, + OUT PACTIVATION_CONTEXT *ActCtx) +{ + const ACTCTXW *pActCtx = (PVOID)ActivationContextData; const WCHAR *directory = NULL; + PACTIVATION_CONTEXT_WRAPPED ActualActCtx; ACTIVATION_CONTEXT *actctx; UNICODE_STRING nameW; ULONG lang = 0; @@ -2261,11 +2357,13 @@ return STATUS_INVALID_PARAMETER;
- if (!(actctx = RtlAllocateHeap( RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*actctx) ))) + if (!(ActualActCtx = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ActualActCtx)))) return STATUS_NO_MEMORY;
- actctx->magic = ACTCTX_MAGIC; - actctx->ref_count = 1; + ActualActCtx->MagicMarker = ACTCTX_MAGIC_MARKER; + + actctx = &ActualActCtx->ActivationContext; + actctx->RefCount = 1; actctx->config.type = ACTIVATION_CONTEXT_PATH_TYPE_NONE; actctx->config.info = NULL; actctx->appdir.type = ACTIVATION_CONTEXT_PATH_TYPE_WIN32_FILE; @@ -2346,7 +2444,7 @@ free_depend_manifests( &acl );
if (NT_SUCCESS(status)) - *handle = actctx; + *ActCtx = actctx; else actctx_release( actctx ); return status;
@@ -2356,23 +2454,73 @@ return status; }
+#if 0 +#define ACT_CTX_VALID(p) ((((ULONG_PTR)p - 1) | 7) != -1) + VOID NTAPI -RtlAddRefActivationContext(HANDLE handle) -{ - ACTIVATION_CONTEXT *actctx; - - if ((actctx = check_actctx( handle ))) actctx_addref( actctx ); +RtlAddRefActivationContext(IN PACTIVATION_CONTEXT Handle) +{ + PIACTIVATION_CONTEXT ActCtx = (PIACTIVATION_CONTEXT)Handle; + LONG OldRefCount, NewRefCount; + + if ((ActCtx) && (ACT_CTX_VALID(ActCtx)) && (ActCtx->RefCount != LONG_MAX)) + { + RtlpValidateActCtx(ActCtx); + + while (TRUE) + { + OldRefCount = ActCtx->RefCount; + ASSERT(OldRefCount > 0); + + if (OldRefCount == LONG_MAX) break; + + NewRefCount = OldRefCount + 1; + if (InterlockedCompareExchange(&ActCtx->RefCount, + NewRefCount, + OldRefCount) == OldRefCount) + { + break; + } + } + + NewRefCount = LONG_MAX; + ASSERT(NewRefCount > 0); + } }
VOID NTAPI RtlReleaseActivationContext( HANDLE handle ) { + PIACTIVATION_CONTEXT ActCtx = (PIACTIVATION_CONTEXT) Handle; + + if ((ActCtx) && (ACT_CTX_VALID(ActCtx)) && (ActCtx->RefCount != LONG_MAX)) + { + RtlpValidateActCtx(ActCtx); + + actctx_release(ActCtx); + } +} +#else +VOID +NTAPI +RtlAddRefActivationContext( HANDLE handle ) +{ ACTIVATION_CONTEXT *actctx;
- if ((actctx = check_actctx( handle ))) actctx_release( actctx ); -} + if ((actctx = check_actctx(handle))) actctx_addref(actctx); +} + +VOID +NTAPI +RtlReleaseActivationContext( HANDLE handle ) +{ + ACTIVATION_CONTEXT *actctx; + + if ((actctx = check_actctx(handle))) actctx_release(actctx); +} +#endif
NTSTATUS NTAPI RtlActivateActivationContextEx( ULONG flags, PTEB tebAddress, HANDLE handle, PULONG_PTR cookie )