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?rev=60086&r1=60085&r2=60086&view=diff
==============================================================================
--- 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?rev=60086&r1=60085&r2=60086&view=diff
==============================================================================
--- 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/actctx.c?rev=60086&r1=60085&r2=60086&view=diff
==============================================================================
--- 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/actctx.c?rev=60086&r1=60085&r2=60086&view=diff
==============================================================================
--- 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=60086&r1=60085&r2=60086&view=diff
==============================================================================
--- 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=60086&r1=60085&r2=60086&view=diff
==============================================================================
--- 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&r1=60085&r2=60086&view=diff
==============================================================================
--- 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 )


Reply via email to