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?r…
==============================================================================
--- 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?r…
==============================================================================
--- 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/…
==============================================================================
--- 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/ac…
==============================================================================
--- 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 )