[PATCH 04/27] [Kernel32]: ActCtx: Added infrastructure for loading a manifest (app,

Eric Pouech eric.pouech at wanadoo.fr
Sat Apr 28 07:21:26 CDT 2007


assembly)

A+
---

 dlls/kernel32/actctx.c |  148 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 148 insertions(+), 0 deletions(-)

diff --git a/dlls/kernel32/actctx.c b/dlls/kernel32/actctx.c
index 7d95d4d..ff15fb9 100644
--- a/dlls/kernel32/actctx.c
+++ b/dlls/kernel32/actctx.c
@@ -28,10 +28,14 @@ #include "windef.h"
 #include "winbase.h"
 #include "winerror.h"
 #include "winnls.h"
+#include "winuser.h"
+#include "winternl.h"
 #include "wine/debug.h"
+#include "wine/unicode.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(actctx);
 
+static const WCHAR dotManifestW[] = {'.','m','a','n','i','f','e','s','t','\0'};
 
 #define ACTCTX_FLAGS_ALL (\
  ACTCTX_FLAG_PROCESSOR_ARCHITECTURE_VALID |\
@@ -48,6 +52,12 @@ #define ACTCTX_FAKE_COOKIE ((ULONG_PTR) 
 
 #define ACTCTX_MAGIC       0xC07E3E11
 
+typedef struct
+{
+    const char*         ptr;
+    const char*         end;
+} xmlbuf_t;
+
 struct file_info
 {
     ULONG               type;
@@ -89,6 +99,13 @@ struct actctx
     ULONG               num_assemblies;
 };
 
+struct actctx_loader
+{
+    struct actctx*      actctx;
+    struct assembly_identity*   dependencies;
+    unsigned            num_dependencies;
+};
+
 static struct assembly* add_assembly(struct actctx* actctx, enum assembly_type at)
 {
     struct assembly*    assembly;
@@ -190,6 +207,111 @@ done:
     return ret;
 }
 
+static DWORD parse_manifest(struct actctx_loader* acl, struct assembly_identity* ai,
+                            struct file_info* fi, xmlbuf_t* xmlbuf)
+{
+    return ERROR_SUCCESS;
+}
+
+static BOOL CALLBACK get_first_manifest(HMODULE hModule, LPCWSTR lpszType,
+                                        LPWSTR lpszName, LONG_PTR lParam)
+{
+    HRSRC*      prsc = (HRSRC*)lParam;
+
+    *prsc = FindResourceW(hModule, lpszName, lpszType);
+    return FALSE;
+}
+
+static DWORD get_manifest_in_module(struct actctx_loader* acl,
+                                    struct assembly_identity* ai,
+                                    HANDLE hModule, LPCWSTR resname)
+{
+    HRSRC               rsc = NULL;
+    HGLOBAL             hgbl = NULL;
+    struct file_info    fi;
+    xmlbuf_t            buf;
+
+    if (!resname)
+    {
+        /* lookup first resource as manifest */
+        EnumResourceNamesW(hModule, (LPWSTR)RT_MANIFEST, get_first_manifest,
+                           (LONG_PTR)&rsc);
+        if (!rsc) return ERROR_FILE_NOT_FOUND;
+    }
+    else rsc = FindResourceW(hModule, resname, (LPWSTR)RT_MANIFEST);
+    if (!(hgbl = LoadResource(hModule, rsc))) return ERROR_FILE_NOT_FOUND;
+    fi.type = ACTIVATION_CONTEXT_PATH_TYPE_NONE;
+    fi.info = NULL; /* FIXME */
+    buf.ptr = LockResource(hgbl);
+    buf.end = buf.ptr + SizeofResource(hModule, rsc);
+    return parse_manifest(acl, ai, &fi, &buf);
+}
+
+static DWORD get_manifest_in_file(struct actctx_loader* acl,
+                                  struct assembly_identity* ai,
+                                  LPCWSTR name, LPCWSTR resname, BOOL first)
+{
+    HANDLE      hFile, hMap;
+    PVOID       base;
+    DWORD       ret = ERROR_FILE_NOT_FOUND;
+
+    hFile = CreateFileW(name, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0);
+    if (hFile != INVALID_HANDLE_VALUE)
+    {
+        hMap = CreateFileMappingW(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
+        if (hMap != INVALID_HANDLE_VALUE)
+        {
+            base = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0);
+            if (base)
+            {
+                HANDLE      hModule = (HMODULE)(ULONG_PTR)base;
+
+                if (RtlImageNtHeader(hModule)) /* we got a PE file */
+                {
+                    if (first)
+                    {
+                        LPWSTR  manifestfile;
+
+                        manifestfile = HeapAlloc(GetProcessHeap(), 0,
+                                                 lstrlenW(name) * sizeof(WCHAR) + sizeof(dotManifestW));
+                        if (manifestfile)
+                        {
+                            strcpyW(manifestfile, name);
+                            strcatW(manifestfile, dotManifestW);
+                            ret = get_manifest_in_file(acl, ai, manifestfile,
+                                                       resname, FALSE);
+                            HeapFree(GetProcessHeap(), 0, manifestfile);
+                        }
+                    }
+                    if (ret) ret = get_manifest_in_module(acl, ai, hModule, resname);
+                }
+                else
+                {
+                    ULONG               len;
+                    struct file_info    fi;
+                    xmlbuf_t            buf;
+
+                    fi.type = ACTIVATION_CONTEXT_PATH_TYPE_WIN32_FILE;
+                    if ((len = GetFullPathNameW(name, 0, NULL, NULL)))
+                    {
+                        LPWSTR  tmp;
+                        fi.info = tmp = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+                        if (tmp) GetFullPathNameW(name, len, tmp, NULL);
+                    }
+                    buf.ptr = base;
+                    buf.end = buf.ptr + GetFileSize(hFile, NULL);
+                    ret = parse_manifest(acl, ai, &fi, &buf);
+                }
+                UnmapViewOfFile(base);
+            }
+            CloseHandle(hMap);
+        }
+        CloseHandle(hFile);
+    } else TRACE("file not found: %u\n", GetLastError());
+
+    return ret;
+}
+
 /***********************************************************************
  * CreateActCtxW (KERNEL32.@)
  *
@@ -197,8 +319,10 @@ done:
  */
 HANDLE WINAPI CreateActCtxW(PCACTCTXW pActCtx)
 {
+    struct actctx_loader acl;
     struct actctx*      actctx;
     struct assembly*    assembly;
+    LPCWSTR             resname = NULL;
     DWORD               ret = ERROR_SUCCESS;
 
     TRACE("%p %08x\n", pActCtx, pActCtx ? pActCtx->dwFlags : 0);
@@ -225,6 +349,30 @@ HANDLE WINAPI CreateActCtxW(PCACTCTXW pA
     assembly->manifest.info = NULL;
     assembly->manifest.type = ACTIVATION_CONTEXT_PATH_TYPE_WIN32_FILE;
 
+    acl.actctx = actctx;
+    acl.dependencies = NULL;
+    acl.num_dependencies = 0;
+
+    if (pActCtx->dwFlags & ACTCTX_FLAG_RESOURCE_NAME_VALID)
+        resname = pActCtx->lpResourceName;
+
+    if (pActCtx->dwFlags & ACTCTX_FLAG_HMODULE_VALID)
+    {
+        ret = get_manifest_in_module(&acl, NULL, pActCtx->hModule, resname);
+    }
+    else if (pActCtx->lpSource)
+    {
+        ret = get_manifest_in_file(&acl, NULL, pActCtx->lpSource, resname, TRUE);
+    }
+    else
+    {
+        /* this includes the host application settings
+         * (lpApplicationName and lpAssemblyDirectory)
+         */
+        FIXME("Unsupported yet flags %x\n", pActCtx->dwFlags);
+        ret = ERROR_INVALID_PARAMETER;
+    }
+
     if (ret == ERROR_SUCCESS)
     {
         return (HANDLE)actctx;




More information about the wine-patches mailing list