Alexandre Julliard : ntdll:
Add infrastructure for loading manifest dependencies (
based on a patch by Eric Pouech).
Alexandre Julliard
julliard at wine.codeweavers.com
Fri Jul 20 06:02:06 CDT 2007
Module: wine
Branch: master
Commit: c5bf0947f605cefd9ddfc205e3418d083ce8e8d7
URL: http://source.winehq.org/git/wine.git/?a=commit;h=c5bf0947f605cefd9ddfc205e3418d083ce8e8d7
Author: Alexandre Julliard <julliard at winehq.org>
Date: Thu Jul 19 17:50:11 2007 +0200
ntdll: Add infrastructure for loading manifest dependencies (based on a patch by Eric Pouech).
---
dlls/ntdll/actctx.c | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 119 insertions(+), 0 deletions(-)
diff --git a/dlls/ntdll/actctx.c b/dlls/ntdll/actctx.c
index 1d06356..d46f77c 100644
--- a/dlls/ntdll/actctx.c
+++ b/dlls/ntdll/actctx.c
@@ -217,6 +217,42 @@ static void free_assembly_identity(struct assembly_identity *ai)
RtlFreeHeap( GetProcessHeap(), 0, ai->arch );
}
+static BOOL add_dependent_assembly_id(struct actctx_loader* acl,
+ struct assembly_identity* ai)
+{
+ /* FIXME: should check that the passed ai isn't already in the list */
+ if (acl->num_dependencies == acl->allocated_dependencies)
+ {
+ void *ptr;
+ unsigned int new_count;
+ if (acl->dependencies)
+ {
+ new_count = acl->allocated_dependencies * 2;
+ ptr = RtlReAllocateHeap(GetProcessHeap(), 0, acl->dependencies,
+ new_count * sizeof(acl->dependencies[0]));
+ }
+ else
+ {
+ new_count = 4;
+ ptr = RtlAllocateHeap(GetProcessHeap(), 0, new_count * sizeof(acl->dependencies[0]));
+ }
+ if (!ptr) return FALSE;
+ acl->dependencies = ptr;
+ acl->allocated_dependencies = new_count;
+ }
+ acl->dependencies[acl->num_dependencies++] = *ai;
+
+ return TRUE;
+}
+
+static void free_depend_manifests(struct actctx_loader* acl)
+{
+ unsigned int i;
+ for (i = 0; i < acl->num_dependencies; i++)
+ free_assembly_identity(&acl->dependencies[i]);
+ RtlFreeHeap(GetProcessHeap(), 0, acl->dependencies);
+}
+
static ACTIVATION_CONTEXT *check_actctx( HANDLE h )
{
ACTIVATION_CONTEXT *actctx = h;
@@ -802,6 +838,85 @@ static NTSTATUS get_manifest_in_associated_manifest( struct actctx_loader* acl,
return status;
}
+static NTSTATUS lookup_assembly(struct actctx_loader* acl,
+ struct assembly_identity* ai)
+{
+ static const WCHAR dotDllW[] = {'.','d','l','l',0};
+ unsigned int i;
+ WCHAR *buffer, *p;
+ NTSTATUS status;
+ UNICODE_STRING nameW;
+ HANDLE file;
+
+ /* FIXME: add support for language specific lookup */
+
+ nameW.Buffer = NULL;
+ if (!(buffer = RtlAllocateHeap( GetProcessHeap(), 0,
+ (strlenW(acl->actctx->appdir.info) + 2 * strlenW(ai->name) + 2) * sizeof(WCHAR) + sizeof(dotManifestW) )))
+ return STATUS_NO_MEMORY;
+
+ /* lookup in appdir\name.dll
+ * appdir\name.manifest
+ * appdir\name\name.dll
+ * appdir\name\name.manifest
+ */
+ strcpyW( buffer, acl->actctx->appdir.info );
+ p = buffer + strlenW(buffer);
+ for (i = 0; i < 2; i++)
+ {
+ *p++ = '\\';
+ strcpyW( p, ai->name );
+ p += strlenW(p);
+
+ strcpyW( p, dotDllW );
+ if (RtlDosPathNameToNtPathName_U( buffer, &nameW, NULL, NULL ))
+ {
+ status = open_nt_file( &file, &nameW );
+ if (!status)
+ {
+ status = get_manifest_in_pe_file( acl, ai, nameW.Buffer, file,
+ (LPCWSTR)CREATEPROCESS_MANIFEST_RESOURCE_ID, 0 );
+ NtClose( file );
+ break;
+ }
+ RtlFreeUnicodeString( &nameW );
+ }
+
+ strcpyW( p, dotManifestW );
+ if (RtlDosPathNameToNtPathName_U( buffer, &nameW, NULL, NULL ))
+ {
+ status = open_nt_file( &file, &nameW );
+ if (!status)
+ {
+ status = get_manifest_in_manifest_file( acl, ai, nameW.Buffer, file );
+ NtClose( file );
+ break;
+ }
+ RtlFreeUnicodeString( &nameW );
+ }
+ }
+ RtlFreeUnicodeString( &nameW );
+ return STATUS_SXS_ASSEMBLY_NOT_FOUND;
+}
+
+static NTSTATUS parse_depend_manifests(struct actctx_loader* acl)
+{
+ NTSTATUS status = STATUS_SUCCESS;
+ unsigned int i;
+
+ for (i = 0; i < acl->num_dependencies; i++)
+ {
+ if (lookup_assembly(acl, &acl->dependencies[i]) != STATUS_SUCCESS)
+ {
+ FIXME( "Could not find assembly %s\n", debugstr_w(acl->dependencies[i].name) );
+ status = STATUS_SXS_CANT_GEN_ACTCTX;
+ break;
+ }
+ }
+ /* FIXME should now iterate through all refs */
+ return status;
+}
+
/***********************************************************************
* RtlCreateActivationContext (NTDLL.@)
@@ -913,6 +1028,10 @@ NTSTATUS WINAPI RtlCreateActivationContext( HANDLE *handle, const void *ptr )
if (file) NtClose( file );
RtlFreeUnicodeString( &nameW );
+
+ if (status == STATUS_SUCCESS) status = parse_depend_manifests(&acl);
+ free_depend_manifests( &acl );
+
if (status == STATUS_SUCCESS) *handle = actctx;
else actctx_release( actctx );
return status;
More information about the wine-cvs
mailing list