[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.

svn path=/trunk/; revision=60086
This commit is contained in:
Alex Ionescu
2013-09-13 22:44:57 +00:00
parent 6e8c79e64d
commit 1a0744c854
7 changed files with 196 additions and 33 deletions
+1 -1
View File
@@ -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()
+1 -1
View File
@@ -38,7 +38,7 @@ NTSTATUS create_module_activation_context( LDR_DATA_TABLE_ENTRY *module )
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;
}
@@ -21,7 +21,6 @@
/* PRIVATE FUNCTIONS *********************************************************/
VOID
NTAPI
BasepFreeActivationContextActivationBlock(IN PBASEP_ACTCTX_BLOCK ActivationBlock)
+1 -1
View File
@@ -107,7 +107,7 @@ HANDLE WINAPI CreateActCtxW(PCACTCTXW pActCtx)
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;
+6 -2
View File
@@ -3511,8 +3511,12 @@ NTSYSAPI
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
+12
View File
@@ -903,6 +903,18 @@ typedef struct _ACTIVATION_CONTEXT_STACK
} 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 */
//
+175 -27
View File
@@ -34,7 +34,7 @@ BOOLEAN RtlpNotAllowingMultipleActivation;
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 assembly
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
{
@@ -167,6 +191,60 @@ struct actctx_loader
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};
static const WCHAR bindingRedirectW[] = {'b','i','n','d','i','n','g','R','e','d','i','r','e','c','t',0};
@@ -210,8 +288,8 @@ static const WCHAR manifestv3W[] = {'u','r','n',':','s','c','h','e','m','a','s',
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 @@ static WCHAR *build_assembly_id( const struct assembly_identity *ai )
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 ACTIVATION_CONTEXT *check_actctx( HANDLE h )
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 @@ static void actctx_release( ACTIVATION_CONTEXT *actctx )
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 @@ void actctx_init(void)
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 )
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 = ptr;
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 @@ NTSTATUS WINAPI RtlCreateActivationContext( HANDLE *handle, void *ptr )
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 @@ NTSTATUS WINAPI RtlCreateActivationContext( HANDLE *handle, void *ptr )
free_depend_manifests( &acl );
if (NT_SUCCESS(status))
*handle = actctx;
*ActCtx = actctx;
else actctx_release( actctx );
return status;
@@ -2356,13 +2454,62 @@ error:
return status;
}
#if 0
#define ACT_CTX_VALID(p) ((((ULONG_PTR)p - 1) | 7) != -1)
VOID
NTAPI
RtlAddRefActivationContext(HANDLE handle)
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_addref( actctx );
if ((actctx = check_actctx(handle))) actctx_addref(actctx);
}
VOID
@@ -2371,8 +2518,9 @@ RtlReleaseActivationContext( HANDLE handle )
{
ACTIVATION_CONTEXT *actctx;
if ((actctx = check_actctx( handle ))) actctx_release( actctx );
if ((actctx = check_actctx(handle))) actctx_release(actctx);
}
#endif
NTSTATUS
NTAPI RtlActivateActivationContextEx( ULONG flags, PTEB tebAddress, HANDLE handle, PULONG_PTR cookie )