[RTL]
[reactos.git] / reactos / lib / rtl / actctx.c
index eb07758..0d55e03 100644 (file)
@@ -3,7 +3,7 @@
  * PROJECT:         ReactOS Runtime Library
  * PURPOSE:         Activation Context Support
  * FILE:            lib/rtl/actctx.c
- * PROGRAMERS:      
+ * PROGRAMERS:
  *                  Jon Griffiths
  *                  Eric Pouech
  *                  Jacek Caban for CodeWeavers
@@ -22,7 +22,7 @@
 
 #include <wine/unicode.h>
 
-#define QUERY_ACTCTX_FLAG_ACTIVE (0x00000001)
+BOOLEAN RtlpNotAllowingMultipleActivation;
 
 #define ACTCTX_FLAGS_ALL (\
     ACTCTX_FLAG_PROCESSOR_ARCHITECTURE_VALID |\
@@ -192,7 +192,7 @@ static const WCHAR helpdirW[] = {'h','e','l','p','d','i','r',0};
 static const WCHAR iidW[] = {'i','i','d',0};
 static const WCHAR languageW[] = {'l','a','n','g','u','a','g','e',0};
 static const WCHAR manifestVersionW[] = {'m','a','n','i','f','e','s','t','V','e','r','s','i','o','n',0};
-static const WCHAR nameW[] = {'n','a','m','e',0};
+static const WCHAR g_nameW[] = {'n','a','m','e',0};
 static const WCHAR newVersionW[] = {'n','e','w','V','e','r','s','i','o','n',0};
 static const WCHAR oldVersionW[] = {'o','l','d','V','e','r','s','i','o','n',0};
 static const WCHAR optionalW[] = {'o','p','t','i','o','n','a','l',0};
@@ -203,7 +203,7 @@ static const WCHAR typeW[] = {'t','y','p','e',0};
 static const WCHAR versionW[] = {'v','e','r','s','i','o','n',0};
 static const WCHAR xmlnsW[] = {'x','m','l','n','s',0};
 
-static const WCHAR xmlW[] = {'?','x','m','l',0};
+static const WCHAR g_xmlW[] = {'?','x','m','l',0};
 static const WCHAR manifestv1W[] = {'u','r','n',':','s','c','h','e','m','a','s','-','m','i','c','r','o','s','o','f','t','-','c','o','m',':','a','s','m','.','v','1',0};
 static const WCHAR manifestv3W[] = {'u','r','n',':','s','c','h','e','m','a','s','-','m','i','c','r','o','s','o','f','t','-','c','o','m',':','a','s','m','.','v','3',0};
 
@@ -239,7 +239,7 @@ static UNICODE_STRING xmlstr2unicode(const xmlstr_t *xmlstr)
     UNICODE_STRING res;
 
     res.Buffer = (PWSTR)xmlstr->ptr;
-    res.Length = res.MaximumLength = xmlstr->len * sizeof(WCHAR);
+    res.Length = res.MaximumLength = (USHORT)xmlstr->len * sizeof(WCHAR);
 
     return res;
 }
@@ -528,21 +528,17 @@ static WCHAR *build_assembly_id( const struct assembly_identity *ai )
         {',','p','r','o','c','e','s','s','o','r','A','r','c','h','i','t','e','c','t','u','r','e','=',0};
     static const WCHAR public_keyW[] =
         {',','p','u','b','l','i','c','K','e','y','T','o','k','e','n','=',0};
-    static const WCHAR typeW[] =
-        {',','t','y','p','e','=',0};
-    static const WCHAR versionW[] =
-        {',','v','e','r','s','i','o','n','=',0};
 
     WCHAR version[64], *ret;
     SIZE_T size = 0;
 
     sprintfW( version, version_formatW,
               ai->version.major, ai->version.minor, ai->version.build, ai->version.revision );
-    if (ai->name) size += strlenW(ai->name) * sizeof(WCHAR);
+    if (ai->name) size += strlenW(ai->name);
     if (ai->arch) size += strlenW(archW) + strlenW(ai->arch) + 2;
     if (ai->public_key) size += strlenW(public_keyW) + strlenW(ai->public_key) + 2;
-    if (ai->type) size += strlenW(typeW) + strlenW(ai->type) + 2;
-    size += strlenW(versionW) + strlenW(version) + 2;
+    if (ai->type) size += 1 + strlenW(typeW) + 1 + strlenW(ai->type) + 2;
+    size += 1+ strlenW(versionW) + 1 + strlenW(version) + 2;
 
     if (!(ret = RtlAllocateHeap( RtlGetProcessHeap(), 0, (size + 1) * sizeof(WCHAR) )))
         return NULL;
@@ -575,12 +571,12 @@ static ACTIVATION_CONTEXT *check_actctx( HANDLE h )
 
 static inline void actctx_addref( ACTIVATION_CONTEXT *actctx )
 {
-    _InterlockedExchangeAdd( &actctx->ref_count, 1 );
+    InterlockedExchangeAdd( &actctx->ref_count, 1 );
 }
 
 static void actctx_release( ACTIVATION_CONTEXT *actctx )
 {
-    if (_InterlockedExchangeAdd( &actctx->ref_count, -1 ) == 1)
+    if (InterlockedExchangeAdd( &actctx->ref_count, -1 ) == 1)
     {
         unsigned int i, j;
 
@@ -645,7 +641,7 @@ static BOOL next_xml_attr(xmlbuf_t* xmlbuf, xmlstr_t* name, xmlstr_t* value,
     if (ptr == xmlbuf->end || *ptr != '=') return FALSE;
 
     name->ptr = xmlbuf->ptr;
-    name->len = ptr-xmlbuf->ptr;
+    name->len = (ULONG)(ptr - xmlbuf->ptr);
     xmlbuf->ptr = ptr;
 
     ptr++;
@@ -661,7 +657,7 @@ static BOOL next_xml_attr(xmlbuf_t* xmlbuf, xmlstr_t* name, xmlstr_t* value,
         return FALSE;
     }
 
-    value->len = ptr - value->ptr;
+    value->len = (ULONG)(ptr - value->ptr);
     xmlbuf->ptr = ptr + 1;
 
     if (xmlbuf->ptr == xmlbuf->end) return FALSE;
@@ -703,7 +699,7 @@ static BOOL next_xml_elem(xmlbuf_t* xmlbuf, xmlstr_t* elem)
         ptr++;
 
     elem->ptr = xmlbuf->ptr;
-    elem->len = ptr - xmlbuf->ptr;
+    elem->len = (ULONG)(ptr - xmlbuf->ptr);
     xmlbuf->ptr = ptr;
     return xmlbuf->ptr != xmlbuf->end;
 }
@@ -731,7 +727,7 @@ static BOOL parse_text_content(xmlbuf_t* xmlbuf, xmlstr_t* content)
     if (!ptr) return FALSE;
 
     content->ptr = xmlbuf->ptr;
-    content->len = ptr - xmlbuf->ptr;
+    content->len = (ULONG)(ptr - xmlbuf->ptr);
     xmlbuf->ptr = ptr;
 
     return TRUE;
@@ -847,7 +843,7 @@ static BOOL parse_assembly_identity_elem(xmlbuf_t* xmlbuf, ACTIVATION_CONTEXT* a
 
     while (next_xml_attr(xmlbuf, &attr_name, &attr_value, &error, &end))
     {
-        if (xmlstr_cmp(&attr_name, nameW))
+        if (xmlstr_cmp(&attr_name, g_nameW))
         {
             if (!(ai->name = xmlstrdupW(&attr_value))) return FALSE;
         }
@@ -944,7 +940,7 @@ static BOOL parse_cominterface_proxy_stub_elem(xmlbuf_t* xmlbuf, struct dll_redi
         {
             if (!(entity->u.proxy.iid = xmlstrdupW(&attr_value))) return FALSE;
         }
-        if (xmlstr_cmp(&attr_name, nameW))
+        if (xmlstr_cmp(&attr_name, g_nameW))
         {
             if (!(entity->u.proxy.name = xmlstrdupW(&attr_value))) return FALSE;
         }
@@ -1107,7 +1103,7 @@ static BOOL parse_com_interface_external_proxy_stub_elem(xmlbuf_t* xmlbuf,
         {
             if (!(entity->u.proxy.iid = xmlstrdupW(&attr_value))) return FALSE;
         }
-        if (xmlstr_cmp(&attr_name, nameW))
+        if (xmlstr_cmp(&attr_name, g_nameW))
         {
             if (!(entity->u.proxy.name = xmlstrdupW(&attr_value))) return FALSE;
         }
@@ -1133,7 +1129,7 @@ static BOOL parse_clr_class_elem(xmlbuf_t* xmlbuf, struct assembly* assembly)
 
     while (next_xml_attr(xmlbuf, &attr_name, &attr_value, &error, &end))
     {
-        if (xmlstr_cmp(&attr_name, nameW))
+        if (xmlstr_cmp(&attr_name, g_nameW))
         {
             if (!(entity->u.clrclass.name = xmlstrdupW(&attr_value))) return FALSE;
         }
@@ -1165,7 +1161,7 @@ static BOOL parse_clr_surrogate_elem(xmlbuf_t* xmlbuf, struct assembly* assembly
 
     while (next_xml_attr(xmlbuf, &attr_name, &attr_value, &error, &end))
     {
-        if (xmlstr_cmp(&attr_name, nameW))
+        if (xmlstr_cmp(&attr_name, g_nameW))
         {
             if (!(entity->u.clrsurrogate.name = xmlstrdupW(&attr_value))) return FALSE;
         }
@@ -1299,7 +1295,7 @@ static BOOL parse_file_elem(xmlbuf_t* xmlbuf, struct assembly* assembly)
         attr_nameU = xmlstr2unicode(&attr_name);
         attr_valueU = xmlstr2unicode(&attr_value);
 
-        if (xmlstr_cmp(&attr_name, nameW))
+        if (xmlstr_cmp(&attr_name, g_nameW))
         {
             if (!(dll->name = xmlstrdupW(&attr_value))) return FALSE;
             DPRINT("name=%wZ\n", &attr_valueU);
@@ -1499,7 +1495,7 @@ static NTSTATUS parse_manifest_buffer( struct actctx_loader* acl, struct assembl
 
     if (!next_xml_elem(xmlbuf, &elem)) return STATUS_SXS_CANT_GEN_ACTCTX;
 
-    if (xmlstr_cmp(&elem, xmlW) &&
+    if (xmlstr_cmp(&elem, g_xmlW) &&
         (!parse_xml_header(xmlbuf) || !next_xml_elem(xmlbuf, &elem)))
         return STATUS_SXS_CANT_GEN_ACTCTX;
 
@@ -1553,7 +1549,7 @@ static NTSTATUS parse_manifest( struct actctx_loader* acl, struct assembly_ident
                                                       : ACTIVATION_CONTEXT_PATH_TYPE_NONE;
 
     unicode_tests = IS_TEXT_UNICODE_SIGNATURE | IS_TEXT_UNICODE_REVERSE_SIGNATURE;
-    if (RtlIsTextUnicode( (PVOID) buffer, size, &unicode_tests ))
+    if (RtlIsTextUnicode((PVOID)buffer, (ULONG)size, &unicode_tests ))
     {
         xmlbuf.ptr = buffer;
         xmlbuf.end = xmlbuf.ptr + size / sizeof(WCHAR);
@@ -1576,13 +1572,17 @@ static NTSTATUS parse_manifest( struct actctx_loader* acl, struct assembly_ident
     }
     else
     {
-        /* let's assume utf-8 for now */
-        int len;
-        WCHAR *new_buff;
+        /* TODO: this doesn't handle arbitrary encodings */
+        ANSI_STRING xmlA;
+        UNICODE_STRING xmlW;
+
+        ASSERT(size < MAXUSHORT);
+        xmlA.Buffer = (PCHAR)buffer;
+        xmlA.Length = xmlA.MaximumLength = (USHORT)size;
 
         _SEH2_TRY
         {
-            len = mbstowcs( NULL, buffer, size);
+            status = RtlAnsiStringToUnicodeString(&xmlW, &xmlA, TRUE);
         }
         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
         {
@@ -1591,23 +1591,18 @@ static NTSTATUS parse_manifest( struct actctx_loader* acl, struct assembly_ident
         }
         _SEH2_END;
 
-        DPRINT("len = %x\n", len);
-
-        if (len == -1)
+        if (!NT_SUCCESS(status))
         {
-            DPRINT1( "utf-8 conversion failed\n" );
+            DPRINT1("RtlAnsiStringToUnicodeString failed with %lx\n", status);
             return STATUS_SXS_CANT_GEN_ACTCTX;
         }
-        if (!(new_buff = RtlAllocateHeap( RtlGetProcessHeap(), HEAP_ZERO_MEMORY, len)))
-            return STATUS_NO_MEMORY;
+        ASSERT(xmlW.Buffer != NULL);
 
-        mbstowcs( new_buff, buffer, size);
-        xmlbuf.ptr = new_buff;
-
-        xmlbuf.end = xmlbuf.ptr + len / sizeof(WCHAR);
+        xmlbuf.ptr = xmlW.Buffer;
+        xmlbuf.end = xmlbuf.ptr + xmlW.Length / sizeof(WCHAR);
         status = parse_manifest_buffer( acl, assembly, ai, &xmlbuf );
 
-        RtlFreeHeap( RtlGetProcessHeap(), 0, new_buff );
+        RtlFreeUnicodeString(&xmlW);
     }
     return status;
 }
@@ -1626,7 +1621,7 @@ static NTSTATUS open_nt_file( HANDLE *handle, UNICODE_STRING *name )
     return NtOpenFile( handle, GENERIC_READ, &attr, &io, FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_ALERT );
 }
 
-static NTSTATUS get_module_filename( HMODULE module, UNICODE_STRING *str, unsigned int extra_len )
+static NTSTATUS get_module_filename( HMODULE module, UNICODE_STRING *str, USHORT extra_len )
 {
     NTSTATUS status;
     ULONG magic;
@@ -1659,6 +1654,9 @@ static NTSTATUS get_manifest_in_module( struct actctx_loader* acl, struct assemb
     IMAGE_RESOURCE_DATA_ENTRY* entry = NULL;
     void *ptr;
 
+    //DPRINT( "looking for res %s in module %p %s\n", resname,
+    //                hModule, filename );
+
 #if 0
     if (TRACE_ON(actctx))
     {
@@ -1792,7 +1790,7 @@ static NTSTATUS get_manifest_in_manifest_file( struct actctx_loader* acl, struct
     status = NtQueryInformationFile( file, &io, &info, sizeof(info), FileStandardInformation);
 
     if (status == STATUS_SUCCESS)
-        status = parse_manifest(acl, ai, filename, directory, shared, base, info.EndOfFile.QuadPart);
+        status = parse_manifest(acl, ai, filename, directory, shared, base, (SIZE_T)info.EndOfFile.QuadPart);
 
     NtUnmapViewOfSection( NtCurrentProcess(), base );
     NtClose( mapping );
@@ -1879,7 +1877,7 @@ static WCHAR *lookup_manifest_file( HANDLE dir, struct assembly_identity *ai )
         WCHAR *tmp;
         ULONG build, revision;
 
-        data_len = io.Information;
+        data_len = (ULONG)io.Information;
 
         for (;;)
         {
@@ -1888,7 +1886,7 @@ static WCHAR *lookup_manifest_file( HANDLE dir, struct assembly_identity *ai )
                 NtQueryDirectoryFile( dir, 0, NULL, NULL, &io, buffer, sizeof(buffer),
                                       FileBothDirectoryInformation, FALSE, &lookup_us, FALSE );
                 if (io.Status != STATUS_SUCCESS) break;
-                data_len = io.Information;
+                data_len = (ULONG)io.Information;
                 data_pos = 0;
             }
             dir_info = (FILE_BOTH_DIR_INFORMATION*)(buffer + data_pos);
@@ -1903,8 +1901,8 @@ static WCHAR *lookup_manifest_file( HANDLE dir, struct assembly_identity *ai )
             revision = atoiW(tmp);
             if (build == ai->version.build && revision < ai->version.revision)
                 continue;
-            ai->version.build = build;
-            ai->version.revision = revision;
+            ai->version.build = (USHORT)build;
+            ai->version.revision = (USHORT)revision;
 
             if ((ret = RtlAllocateHeap( RtlGetProcessHeap(), 0, dir_info->FileNameLength * sizeof(WCHAR) )))
             {
@@ -1933,7 +1931,7 @@ static NTSTATUS lookup_winsxs(struct actctx_loader* acl, struct assembly_identit
 
     if (!ai->arch || !ai->name || !ai->public_key) return STATUS_NO_SUCH_FILE;
 
-    if (!(path = RtlAllocateHeap( RtlGetProcessHeap(), 0, 
+    if (!(path = RtlAllocateHeap( RtlGetProcessHeap(), 0,
                                   ((strlenW(SharedUserData->NtSystemRoot) + 1) *sizeof(WCHAR)) + sizeof(manifest_dirW) )))
         return STATUS_NO_MEMORY;
 
@@ -2003,7 +2001,7 @@ static NTSTATUS lookup_assembly(struct actctx_loader* acl,
     UNICODE_STRING nameW;
     HANDLE file;
 
-    DPRINT1( "looking for name=%S version=%u.%u.%u.%u arch=%S\n",
+    DPRINT( "looking for name=%S version=%u.%u.%u.%u arch=%S\n",
            ai->name, ai->version.major, ai->version.minor, ai->version.build, ai->version.revision, ai->arch );
 
     if ((status = lookup_winsxs(acl, ai)) != STATUS_NO_SUCH_FILE) return status;
@@ -2368,18 +2366,18 @@ RtlReleaseActivationContext( HANDLE handle )
 }
 
 NTSTATUS
-NTAPI RtlActivateActivationContext( ULONG unknown, HANDLE handle, PULONG_PTR cookie )
+NTAPI RtlActivateActivationContextEx( ULONG flags, PTEB tebAddress, HANDLE handle, PULONG_PTR cookie )
 {
     RTL_ACTIVATION_CONTEXT_STACK_FRAME *frame;
 
     if (!(frame = RtlAllocateHeap( RtlGetProcessHeap(), 0, sizeof(*frame) )))
         return STATUS_NO_MEMORY;
 
-    frame->Previous = NtCurrentTeb()->ActivationContextStackPointer->ActiveFrame;
+    frame->Previous = tebAddress->ActivationContextStackPointer->ActiveFrame;
     frame->ActivationContext = handle;
     frame->Flags = 0;
 
-    NtCurrentTeb()->ActivationContextStackPointer->ActiveFrame = frame;
+    tebAddress->ActivationContextStackPointer->ActiveFrame = frame;
     RtlAddRefActivationContext( handle );
 
     *cookie = (ULONG_PTR)frame;
@@ -2388,6 +2386,12 @@ NTAPI RtlActivateActivationContext( ULONG unknown, HANDLE handle, PULONG_PTR coo
 }
 
 
+NTSTATUS
+NTAPI RtlActivateActivationContext( ULONG flags, HANDLE handle, PULONG_PTR cookie )
+{
+    return RtlActivateActivationContextEx(flags, NtCurrentTeb(), handle, cookie);
+}
+
 NTSTATUS
 NTAPI
 RtlDeactivateActivationContext( ULONG flags, ULONG_PTR cookie )
@@ -2422,19 +2426,41 @@ RtlDeactivateActivationContext( ULONG flags, ULONG_PTR cookie )
 }
 
 VOID
-NTAPI RtlFreeThreadActivationContextStack(void)
+NTAPI
+RtlFreeActivationContextStack(PACTIVATION_CONTEXT_STACK Stack)
 {
-    RTL_ACTIVATION_CONTEXT_STACK_FRAME *frame;
+    PRTL_ACTIVATION_CONTEXT_STACK_FRAME ActiveFrame, PrevFrame;
 
-    frame = NtCurrentTeb()->ActivationContextStackPointer->ActiveFrame;
-    while (frame)
+    /* Nothing to do if there is no stack */
+    if (!Stack) return;
+
+    /* Get the current active frame */
+    ActiveFrame = Stack->ActiveFrame;
+
+    /* Go through them in backwards order and release */
+    while (ActiveFrame)
     {
-        RTL_ACTIVATION_CONTEXT_STACK_FRAME *prev = frame->Previous;
-        RtlReleaseActivationContext( frame->ActivationContext );
-        RtlFreeHeap( RtlGetProcessHeap(), 0, frame );
-        frame = prev;
+        PrevFrame = ActiveFrame->Previous;
+        RtlReleaseActivationContext(ActiveFrame->ActivationContext);
+        RtlFreeHeap(RtlGetProcessHeap(), 0, ActiveFrame);
+        ActiveFrame = PrevFrame;
     }
-    NtCurrentTeb()->ActivationContextStackPointer->ActiveFrame = NULL;
+
+    /* Zero out the active frame */
+    Stack->ActiveFrame = NULL;
+
+    /* TODO: Empty the Frame List Cache */
+    ASSERT(IsListEmpty(&Stack->FrameListCache));
+
+    /* Free activation stack memory */
+    RtlFreeHeap(RtlGetProcessHeap(), 0, Stack);
+}
+
+VOID
+NTAPI RtlFreeThreadActivationContextStack(void)
+{
+    RtlFreeActivationContextStack(NtCurrentTeb()->ActivationContextStackPointer);
+    NtCurrentTeb()->ActivationContextStackPointer = NULL;
 }
 
 
@@ -2517,11 +2543,11 @@ RtlQueryInformationActivationContext( ULONG flags, HANDLE handle, PVOID subinst,
             acdi->ulFormatVersion = assembly ? 1 : 0; /* FIXME */
             acdi->ulAssemblyCount = actctx->num_assemblies;
             acdi->ulRootManifestPathType = assembly ? assembly->manifest.type : 0 /* FIXME */;
-            acdi->ulRootManifestPathChars = assembly && assembly->manifest.info ? manifest_len - 1 : 0;
+            acdi->ulRootManifestPathChars = assembly && assembly->manifest.info ? (DWORD)manifest_len - 1 : 0;
             acdi->ulRootConfigurationPathType = actctx->config.type;
-            acdi->ulRootConfigurationPathChars = actctx->config.info ? config_len - 1 : 0;
+            acdi->ulRootConfigurationPathChars = actctx->config.info ? (DWORD)config_len - 1 : 0;
             acdi->ulAppDirPathType = actctx->appdir.type;
-            acdi->ulAppDirPathChars = actctx->appdir.info ? appdir_len - 1 : 0;
+            acdi->ulAppDirPathChars = actctx->appdir.info ? (DWORD)appdir_len - 1 : 0;
             ptr = (LPWSTR)(acdi + 1);
             if (manifest_len)
             {
@@ -2581,9 +2607,9 @@ RtlQueryInformationActivationContext( ULONG flags, HANDLE handle, PVOID subinst,
             }
 
             afdi->ulFlags = 0;  /* FIXME */
-            afdi->ulEncodedAssemblyIdentityLength = (id_len - 1) * sizeof(WCHAR);
+            afdi->ulEncodedAssemblyIdentityLength = (DWORD)(id_len - 1) * sizeof(WCHAR);
             afdi->ulManifestPathType = assembly->manifest.type;
-            afdi->ulManifestPathLength = assembly->manifest.info ? (path_len - 1) * sizeof(WCHAR) : 0;
+            afdi->ulManifestPathLength = assembly->manifest.info ? (DWORD)(path_len - 1) * sizeof(WCHAR) : 0;
             /* FIXME afdi->liManifestLastWriteTime = 0; */
             afdi->ulPolicyPathType = ACTIVATION_CONTEXT_PATH_TYPE_NONE; /* FIXME */
             afdi->ulPolicyPathLength = 0;
@@ -2593,7 +2619,7 @@ RtlQueryInformationActivationContext( ULONG flags, HANDLE handle, PVOID subinst,
             afdi->ulManifestVersionMinor = 0;
             afdi->ulPolicyVersionMajor = 0; /* FIXME */
             afdi->ulPolicyVersionMinor = 0; /* FIXME */
-            afdi->ulAssemblyDirectoryNameLength = ad_len ? (ad_len - 1) * sizeof(WCHAR) : 0;
+            afdi->ulAssemblyDirectoryNameLength = ad_len ? (DWORD)(ad_len - 1) * sizeof(WCHAR) : 0;
             ptr = (LPWSTR)(afdi + 1);
             afdi->lpAssemblyEncodedAssemblyIdentity = ptr;
             memcpy( ptr, assembly_id, id_len * sizeof(WCHAR) );
@@ -2646,7 +2672,7 @@ RtlQueryInformationActivationContext( ULONG flags, HANDLE handle, PVOID subinst,
             }
             if (retlen) *retlen = 0; /* yes that's what native does !! */
             afdi->ulFlags = ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION;
-            afdi->ulFilenameLength = dll_len ? (dll_len - 1) * sizeof(WCHAR) : 0;
+            afdi->ulFilenameLength = dll_len ? (DWORD)(dll_len - 1) * sizeof(WCHAR) : 0;
             afdi->ulPathLength = 0; /* FIXME */
             ptr = (LPWSTR)(afdi + 1);
             if (dll_len)
@@ -2667,28 +2693,66 @@ RtlQueryInformationActivationContext( ULONG flags, HANDLE handle, PVOID subinst,
 
 NTSTATUS
 NTAPI
-RtlFindActivationContextSectionString( ULONG flags, const GUID *guid, ULONG section_kind,
-                                       UNICODE_STRING *section_name, PVOID ptr )
+RtlQueryInformationActiveActivationContext(ULONG ulInfoClass,
+                                           PVOID pvBuffer,
+                                           SIZE_T cbBuffer OPTIONAL,
+                                           SIZE_T *pcbWrittenOrRequired OPTIONAL)
 {
-    PACTCTX_SECTION_KEYED_DATA data = ptr;
-    NTSTATUS status = STATUS_SXS_KEY_NOT_FOUND;
+    return RtlQueryInformationActivationContext(QUERY_ACTCTX_FLAG_USE_ACTIVE_ACTCTX,
+                                                NULL,
+                                                NULL,
+                                                ulInfoClass,
+                                                pvBuffer,
+                                                cbBuffer,
+                                                pcbWrittenOrRequired);
+}
+
+#define FIND_ACTCTX_RETURN_FLAGS 0x00000002
+#define FIND_ACTCTX_RETURN_ASSEMBLY_METADATA 0x00000004
+#define FIND_ACTCTX_VALID_MASK (FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX | FIND_ACTCTX_RETURN_FLAGS | FIND_ACTCTX_RETURN_ASSEMBLY_METADATA)
 
-    if (guid)
+NTSTATUS
+NTAPI
+RtlpFindActivationContextSection_CheckParameters( ULONG flags, const GUID *guid, ULONG section_kind,
+                                                  UNICODE_STRING *section_name, PACTCTX_SECTION_KEYED_DATA data )
+{
+    /* Check general parameter combinations */
+    if (!section_name ||
+        (flags & ~FIND_ACTCTX_VALID_MASK) ||
+        ((flags & FIND_ACTCTX_VALID_MASK) && !data) ||
+        (data && data->cbSize < offsetof(ACTCTX_SECTION_KEYED_DATA, ulAssemblyRosterIndex)))
     {
-        DPRINT1("expected guid == NULL\n");
+        DPRINT1("invalid parameter\n");
         return STATUS_INVALID_PARAMETER;
     }
-    if (flags & ~FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX)
+
+    /* TODO */
+    if (flags & FIND_ACTCTX_RETURN_FLAGS ||
+        flags & FIND_ACTCTX_RETURN_ASSEMBLY_METADATA)
     {
         DPRINT1("unknown flags %08x\n", flags);
         return STATUS_INVALID_PARAMETER;
     }
-    if (!data || data->cbSize < offsetof(ACTCTX_SECTION_KEYED_DATA, ulAssemblyRosterIndex) ||
-        !section_name || !section_name->Buffer)
-    {
-        DPRINT1("invalid parameter\n");
-        return STATUS_INVALID_PARAMETER;
-    }
+
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+RtlFindActivationContextSectionString( ULONG flags, const GUID *guid, ULONG section_kind,
+                                       UNICODE_STRING *section_name, PVOID ptr )
+{
+    PACTCTX_SECTION_KEYED_DATA data = ptr;
+    NTSTATUS status;
+
+    status = RtlpFindActivationContextSection_CheckParameters(flags, guid, section_kind, section_name, data);
+    if (!NT_SUCCESS(status)) return status;
+
+    status = STATUS_SXS_KEY_NOT_FOUND;
+
+    /* if there is no data, but params are valid,
+       we return that sxs key is not found to be at least somehow compatible */
+    if (!data) return status;
 
     ASSERT(NtCurrentTeb());
     ASSERT(NtCurrentTeb()->ActivationContextStackPointer);
@@ -2712,39 +2776,107 @@ NTAPI
 RtlAllocateActivationContextStack(IN PVOID *Context)
 {
     PACTIVATION_CONTEXT_STACK ContextStack;
+
+    /* Check if it's already allocated */
+    if (*Context) return STATUS_SUCCESS;
+
+    /* Allocate space for the context stack */
     ContextStack = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof (ACTIVATION_CONTEXT_STACK) );
     if (!ContextStack)
     {
         return STATUS_NO_MEMORY;
     }
 
-    ContextStack->ActiveFrame = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(RTL_ACTIVATION_CONTEXT_STACK_FRAME));
-    if (!ContextStack->ActiveFrame) return STATUS_NO_MEMORY;
+    /* Initialize the context stack */
+    ContextStack->Flags = 0;
+    ContextStack->ActiveFrame = NULL;
+    InitializeListHead(&ContextStack->FrameListCache);
+    ContextStack->NextCookieSequenceNumber = 1;
+    ContextStack->StackId = 1; //TODO: Timer-based
 
     *Context = ContextStack;
 
-    /* FIXME: Documentation on MSDN reads that activation contexts are only created
-              for modules that have a valid manifest file or resource */
-    actctx_init();
-
     return STATUS_SUCCESS;
 }
 
-NTSTATUS
-NTAPI
+PRTL_ACTIVATION_CONTEXT_STACK_FRAME
+FASTCALL
 RtlActivateActivationContextUnsafeFast(IN PRTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED Frame,
                                        IN PVOID Context)
 {
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
+#if NEW_NTDLL_LOADER
+    RTL_ACTIVATION_CONTEXT_STACK_FRAME *ActiveFrame;
+
+    /* Get the curren active frame */
+    ActiveFrame = NtCurrentTeb()->ActivationContextStackPointer->ActiveFrame;
+
+    DPRINT1("ActiveFrame %p, &Frame->Frame %p, Context %p\n", ActiveFrame, &Frame->Frame, Context);
+
+    /* Actually activate it */
+    Frame->Frame.Previous = ActiveFrame;
+    Frame->Frame.ActivationContext = Context;
+    Frame->Frame.Flags = 0;
+
+    /* Check if we can activate this context */
+    if ((ActiveFrame && (ActiveFrame->ActivationContext != Context)) ||
+        Context)
+    {
+        /* Set new active frame */
+        NtCurrentTeb()->ActivationContextStackPointer->ActiveFrame = &Frame->Frame;
+        return &Frame->Frame;
+    }
+
+    /* We can get here only one way: it was already activated */
+    DPRINT1("Trying to activate improper activation context\n");
+
+    /* Activate only if we are allowing multiple activation */
+    if (!RtlpNotAllowingMultipleActivation)
+    {
+        NtCurrentTeb()->ActivationContextStackPointer->ActiveFrame = &Frame->Frame;
+    }
+    else
+    {
+        /* Set flag */
+        Frame->Frame.Flags = 0x30;
+    }
+
+    /* Return pointer to the activation frame */
+    return &Frame->Frame;
+#else
+
+    RTL_ACTIVATION_CONTEXT_STACK_FRAME *frame = &Frame->Frame;
+
+    frame->Previous = NtCurrentTeb()->ActivationContextStackPointer->ActiveFrame;
+    frame->ActivationContext = Context;
+    frame->Flags = 0;
+
+    NtCurrentTeb()->ActivationContextStackPointer->ActiveFrame = frame;
+
+    return STATUS_SUCCESS;
+#endif
 }
 
-NTSTATUS
-NTAPI
+PRTL_ACTIVATION_CONTEXT_STACK_FRAME
+FASTCALL
 RtlDeactivateActivationContextUnsafeFast(IN PRTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED Frame)
 {
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
+    RTL_ACTIVATION_CONTEXT_STACK_FRAME *frame;
+    //RTL_ACTIVATION_CONTEXT_STACK_FRAME *top;
+
+    /* find the right frame */
+    //top = NtCurrentTeb()->ActivationContextStackPointer->ActiveFrame;
+    frame = &Frame->Frame;
+
+    if (!frame)
+    {
+        DPRINT1("No top frame!\n");
+        RtlRaiseStatus( STATUS_SXS_INVALID_DEACTIVATION );
+    }
+
+    /* pop everything up to and including frame */
+    NtCurrentTeb()->ActivationContextStackPointer->ActiveFrame = frame->Previous;
+
+    return frame;
 }