Index: dll/ntdll/ldr/actctx.c =================================================================== --- dll/ntdll/ldr/actctx.c (revision 0) +++ dll/ntdll/ldr/actctx.c (revision 0) @@ -0,0 +1,146 @@ + +#include +#define NDEBUG +#include + +#include "wine/unicode.h" + +UNICODE_STRING windows_dir = { 0, 0, NULL }; /* windows directory */ + +/*********************************************************************** + * create_module_activation_context + */ +NTSTATUS create_module_activation_context( LDR_DATA_TABLE_ENTRY *module ) +{ + NTSTATUS status; + LDR_RESOURCE_INFO info; + IMAGE_RESOURCE_DATA_ENTRY *entry; + WCHAR *manifestFile; + UNICODE_STRING manifestFile_U; + static const WCHAR dotManifestW[] = {'.','m','a','n','i','f','e','s','t',0}; + OBJECT_ATTRIBUTES attr; + IO_STATUS_BLOCK io; + HANDLE mfHandle; + + /* Check if this module has a manifest file */ + manifestFile = RtlAllocateHeap( RtlGetProcessHeap(), 0, (module->FullDllName.Length + 2 + sizeof(dotManifestW)) * sizeof(WCHAR)); + wcsncpy(manifestFile, module->FullDllName.Buffer, module->FullDllName.Length); + wcscat(manifestFile, dotManifestW); + + status = RtlDosPathNameToNtPathName_U(manifestFile, &manifestFile_U, NULL, NULL); + + attr.Length = sizeof(attr); + attr.RootDirectory = 0; + attr.Attributes = OBJ_CASE_INSENSITIVE; + attr.ObjectName = &manifestFile_U; + attr.SecurityDescriptor = NULL; + attr.SecurityQualityOfService = NULL; + + status = NtOpenFile(&mfHandle, GENERIC_READ, &attr, &io, FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_ALERT); + + RtlFreeUnicodeString(&manifestFile_U); + NtClose(mfHandle); + + if (NT_SUCCESS(status)) + { + ACTCTXW ctx; + DPRINT1("Manifest file found %S\n", manifestFile); + + ctx.cbSize = sizeof(ctx); + ctx.lpSource = NULL; + ctx.dwFlags = ACTCTX_FLAG_APPLICATION_NAME_VALID | ACTCTX_FLAG_HMODULE_VALID; + ctx.hModule = module->DllBase; + ctx.lpResourceName = NULL;//(ULONG_PTR)CREATEPROCESS_MANIFEST_RESOURCE_ID; + ctx.lpApplicationName = module->BaseDllName.Buffer; + status = RtlCreateActivationContext( &module->EntryPointActivationContext, &ctx ); +DPRINT1("Status %x\n", status); + if (NT_SUCCESS(status)) DPRINT1("%wZ seems to contain side by side libs!!!!!!!!!!!\n", module->BaseDllName); + RtlFreeHeap(RtlGetProcessHeap(), 0, manifestFile); + return status; + } + + info.Type = (ULONG_PTR)RT_MANIFEST; + info.Name = (ULONG_PTR)CREATEPROCESS_MANIFEST_RESOURCE_ID; + info.Language = 0; + status = LdrFindResource_U(module->DllBase, &info, 3, &entry); + + /* Try the resource for dll files */ + if (!NT_SUCCESS(status)) + { + info.Name = (ULONG_PTR)ISOLATIONAWARE_MANIFEST_RESOURCE_ID; + status = LdrFindResource_U(module->DllBase, &info, 3, &entry); + } + + if (NT_SUCCESS(status)) + { + ACTCTXW ctx; + ctx.cbSize = sizeof(ctx); + ctx.lpSource = NULL; + ctx.dwFlags = ACTCTX_FLAG_RESOURCE_NAME_VALID | ACTCTX_FLAG_HMODULE_VALID; + ctx.hModule = module->DllBase; + ctx.lpResourceName = (LPCWSTR)info.Name; //(LPCWSTR)CREATEPROCESS_MANIFEST_RESOURCE_ID;//ISOLATIONAWARE_MANIFEST_RESOURCE_ID; + status = RtlCreateActivationContext( &module->EntryPointActivationContext, &ctx ); +DPRINT1("Status %x\n", status); + if (NT_SUCCESS(status)) DPRINT1("%wZ seems to contain side by side libs!!!!!!!!!!!\n", module->BaseDllName); + } + + return status; +} + +NTSTATUS find_actctx_dll( LPCWSTR libname, WCHAR *fullname ) +{ + static const WCHAR winsxsW[] = {'\\','w','i','n','s','x','s','\\',0}; + static const WCHAR dotManifestW[] = {'.','m','a','n','i','f','e','s','t',0}; + + ACTIVATION_CONTEXT_ASSEMBLY_DETAILED_INFORMATION *info; + ACTCTX_SECTION_KEYED_DATA data; + UNICODE_STRING nameW; + NTSTATUS status; + SIZE_T needed, size = 1024; + + RtlInitUnicodeString( &nameW, libname ); + data.cbSize = sizeof(data); + status = RtlFindActivationContextSectionString( FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX, NULL, + ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION, + &nameW, &data ); + if (status != STATUS_SUCCESS) return status; + + for (;;) + { + if (!(info = RtlAllocateHeap( RtlGetProcessHeap(), 0, size ))) + { + status = STATUS_NO_MEMORY; + goto done; + } + status = RtlQueryInformationActivationContext( 0, data.hActCtx, &data.ulAssemblyRosterIndex, + AssemblyDetailedInformationInActivationContext, + info, size, &needed ); + if (status == STATUS_SUCCESS) break; + if (status != STATUS_BUFFER_TOO_SMALL) goto done; + RtlFreeHeap( RtlGetProcessHeap(), 0, info ); + size = needed; + /* restart with larger buffer */ + } +DPRINT1("manafestpath %S\n", info->lpAssemblyManifestPath); +DPRINT1("DirectoryName %S\n", info->lpAssemblyDirectoryName); + if (!info->lpAssemblyManifestPath || !info->lpAssemblyDirectoryName) + { + status = STATUS_SXS_KEY_NOT_FOUND; + goto done; + } + + DPRINT1("%S. %S\n", info->lpAssemblyManifestPath, info->lpAssemblyDirectoryName); + wcscpy(fullname , SharedUserData->NtSystemRoot); + wcscat(fullname, winsxsW); + wcscat(fullname, info->lpAssemblyDirectoryName); + wcscat(fullname, L"\\"); + wcscat(fullname, libname); + DPRINT1("Successfully found a side by side lib!!!!!!!!!! %S\n", fullname); + status = STATUS_SUCCESS; + +done: + RtlFreeHeap( RtlGetProcessHeap(), 0, info ); + RtlReleaseActivationContext( data.hActCtx ); +DPRINT1("%S\n", fullname); + return status; +}