[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