diff --git a/dll/ntdll/ldr/ldrpe.c b/dll/ntdll/ldr/ldrpe.c index fb217ed686f..10d128f2c96 100644 --- a/dll/ntdll/ldr/ldrpe.c +++ b/dll/ntdll/ldr/ldrpe.c @@ -815,6 +815,7 @@ LdrpWalkImportDescriptor(IN LPWSTR DllPath OPTIONAL, return Status; } +/* FIXME: This function is missing SxS support */ NTSTATUS NTAPI LdrpLoadImportModule(IN PWSTR DllPath OPTIONAL, @@ -830,14 +831,9 @@ LdrpLoadImportModule(IN PWSTR DllPath OPTIONAL, NTSTATUS Status; PPEB Peb = RtlGetCurrentPeb(); PTEB Teb = NtCurrentTeb(); - UNICODE_STRING RedirectedImpDescName; - BOOLEAN RedirectedDll; DPRINT("LdrpLoadImportModule('%S' '%s' %p %p)\n", DllPath, ImportName, DataTableEntry, Existing); - RedirectedDll = FALSE; - RtlInitEmptyUnicodeString(&RedirectedImpDescName, NULL, 0); - /* Convert import descriptor name to unicode string */ ImpDescName = &Teb->StaticUnicodeString; RtlInitAnsiString(&AnsiString, ImportName); @@ -887,59 +883,76 @@ LdrpLoadImportModule(IN PWSTR DllPath OPTIONAL, &LdrApiDefaultExtension); } - /* Check if the SxS Assemblies specify another file */ - Status = RtlDosApplyFileIsolationRedirection_Ustr(TRUE, - ImpDescName, - &LdrApiDefaultExtension, - NULL, - &RedirectedImpDescName, - &ImpDescName, - NULL, - NULL, - NULL); - - /* Check success */ - if (NT_SUCCESS(Status)) - { - /* Let Ldrp know */ - RedirectedDll = TRUE; - } - else if (Status != STATUS_SXS_KEY_NOT_FOUND) - { - /* Unrecoverable SxS failure */ - DPRINT1("LDR: RtlDosApplyFileIsolationRedirection_Ustr failed with status %x for dll %wZ\n", Status, ImpDescName); - goto done; - } - /* Check if it's loaded */ if (LdrpCheckForLoadedDll(DllPath, ImpDescName, TRUE, - RedirectedDll, + FALSE, DataTableEntry)) { /* It's already existing in the list */ *Existing = TRUE; - Status = STATUS_SUCCESS; - goto done; + return STATUS_SUCCESS; } /* We're loading it for the first time */ *Existing = FALSE; +#if 0 + /* Load manifest */ + { + ACTCTX_SECTION_KEYED_DATA data; + NTSTATUS status; + + //DPRINT1("find_actctx_dll for %S\n", fullname); + //RtlInitUnicodeString(&nameW, libname); + data.cbSize = sizeof(data); + status = RtlFindActivationContextSectionString( + FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX, NULL, + ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION, + ImpDescName, + &data); + //if (status != STATUS_SUCCESS) return status; + DPRINT1("Status: 0x%08X\n", status); + + if (NT_SUCCESS(status)) + { + ACTIVATION_CONTEXT_ASSEMBLY_DETAILED_INFORMATION *info; + SIZE_T needed, size = 1024; + + 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; + } + + DPRINT("manifestpath === %S\n", info->lpAssemblyManifestPath); + DPRINT("DirectoryName === %S\n", info->lpAssemblyDirectoryName); + } + } +done: +#endif + /* Map it */ Status = LdrpMapDll(DllPath, NULL, ImpDescName->Buffer, NULL, TRUE, - RedirectedDll, + FALSE, DataTableEntry); - if (!NT_SUCCESS(Status)) - { - DPRINT1("LDR: LdrpMapDll failed with status %x for dll %wZ\n", Status, ImpDescName); - goto done; - } + + if (!NT_SUCCESS(Status)) return Status; /* Walk its import descriptor table */ Status = LdrpWalkImportDescriptor(DllPath, @@ -951,9 +964,6 @@ LdrpLoadImportModule(IN PWSTR DllPath OPTIONAL, &(*DataTableEntry)->InInitializationOrderLinks); } -done: - RtlFreeUnicodeString(&RedirectedImpDescName); - return Status; } diff --git a/dll/ntdll/ldr/ldrutils.c b/dll/ntdll/ldr/ldrutils.c index 2542a9a3243..d960c7fcee1 100644 --- a/dll/ntdll/ldr/ldrutils.c +++ b/dll/ntdll/ldr/ldrutils.c @@ -28,6 +28,101 @@ PVOID g_pfnSE_ProcessDying; /* FUNCTIONS *****************************************************************/ +/* NOTE: Remove this one once our actctx support becomes better */ +NTSTATUS find_actctx_dll( LPCWSTR libname, WCHAR *fullname ) +{ + static const WCHAR winsxsW[] = {'\\','w','i','n','s','x','s','\\'}; + 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; + WCHAR *p; + + 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; + } + + DPRINT("manifestpath === %S\n", info->lpAssemblyManifestPath); + DPRINT("DirectoryName === %S\n", info->lpAssemblyDirectoryName); + if (!info->lpAssemblyManifestPath || !info->lpAssemblyDirectoryName) + { + status = STATUS_SXS_KEY_NOT_FOUND; + goto done; + } + + if ((p = wcsrchr( info->lpAssemblyManifestPath, '\\' ))) + { + DWORD dirlen = info->ulAssemblyDirectoryNameLength / sizeof(WCHAR); + + p++; + if (_wcsnicmp( p, info->lpAssemblyDirectoryName, dirlen ) || wcsicmp( p + dirlen, dotManifestW )) + { + /* manifest name does not match directory name, so it's not a global + * windows/winsxs manifest; use the manifest directory name instead */ + dirlen = p - info->lpAssemblyManifestPath; + needed = (dirlen + 1) * sizeof(WCHAR) + nameW.Length; + + p = fullname; + /*if (!(*fullname = p = RtlAllocateHeap( GetProcessHeap(), 0, needed ))) + { + status = STATUS_NO_MEMORY; + goto done; + }*/ + memcpy( p, info->lpAssemblyManifestPath, dirlen * sizeof(WCHAR) ); + p += dirlen; + wcscpy( p, libname ); + goto done; + } + } + + needed = (wcslen(SharedUserData->NtSystemRoot) * sizeof(WCHAR) + + sizeof(winsxsW) + info->ulAssemblyDirectoryNameLength + nameW.Length + 2*sizeof(WCHAR)); + + p = fullname; + //if (!(*fullname = p = RtlAllocateHeap( GetProcessHeap(), 0, needed ))) + //{ + //status = STATUS_NO_MEMORY; + //goto done; + //} + wcscpy( p, SharedUserData->NtSystemRoot ); + p += wcslen(p); + memcpy( p, winsxsW, sizeof(winsxsW) ); + p += sizeof(winsxsW) / sizeof(WCHAR); + memcpy( p, info->lpAssemblyDirectoryName, info->ulAssemblyDirectoryNameLength ); + p += info->ulAssemblyDirectoryNameLength / sizeof(WCHAR); + *p++ = '\\'; + wcscpy( p, libname ); + +done: + RtlFreeHeap( RtlGetProcessHeap(), 0, info ); + RtlReleaseActivationContext( data.hActCtx ); + DPRINT("%S\n", fullname); + return status; +} + + NTSTATUS NTAPI LdrpAllocateUnicodeString(IN OUT PUNICODE_STRING StringOut, @@ -119,30 +214,19 @@ LdrpUpdateLoadCount3(IN PLDR_DATA_TABLE_ENTRY LdrEntry, PIMAGE_IMPORT_DESCRIPTOR ImportEntry; PIMAGE_THUNK_DATA FirstThunk; PLDR_DATA_TABLE_ENTRY Entry; - PUNICODE_STRING ImportNameUnic, RedirectedImportName; + PUNICODE_STRING ImportNameUnic; ANSI_STRING ImportNameAnsi; LPSTR ImportName; ULONG ImportSize; NTSTATUS Status; ULONG i; - BOOLEAN RedirectedDll; - RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED ActCtx; - - /* Set up the Act Ctx */ - ActCtx.Size = sizeof(ActCtx); - ActCtx.Format = RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_FORMAT_WHISTLER; - RtlZeroMemory(&ActCtx.Frame, sizeof(RTL_ACTIVATION_CONTEXT_STACK_FRAME)); - - /* Activate the ActCtx */ - RtlActivateActivationContextUnsafeFast(&ActCtx, - LdrEntry->EntryPointActivationContext); /* Check the action we need to perform */ if ((Flags == LDRP_UPDATE_REFCOUNT) || (Flags == LDRP_UPDATE_PIN)) { /* Make sure entry is not being loaded already */ if (LdrEntry->Flags & LDRP_LOAD_IN_PROGRESS) - goto done; + return; LdrEntry->Flags |= LDRP_LOAD_IN_PROGRESS; } @@ -150,7 +234,7 @@ LdrpUpdateLoadCount3(IN PLDR_DATA_TABLE_ENTRY LdrEntry, { /* Make sure the entry is not being unloaded already */ if (LdrEntry->Flags & LDRP_UNLOAD_IN_PROGRESS) - goto done; + return; LdrEntry->Flags |= LDRP_UNLOAD_IN_PROGRESS; } @@ -183,38 +267,54 @@ LdrpUpdateLoadCount3(IN PLDR_DATA_TABLE_ENTRY LdrEntry, if (NT_SUCCESS(Status)) { - RedirectedDll = FALSE; - RedirectedImportName = ImportNameUnic; - - /* Check if the SxS Assemblies specify another file */ - Status = RtlDosApplyFileIsolationRedirection_Ustr(TRUE, - ImportNameUnic, - &LdrApiDefaultExtension, - UpdateString, - NULL, - &RedirectedImportName, - NULL, - NULL, - NULL); - - /* Check success */ - if (NT_SUCCESS(Status)) + if (LdrpCheckForLoadedDll(NULL, + ImportNameUnic, + TRUE, + FALSE, + &Entry)) { - /* Let Ldrp know */ - if (ShowSnaps) + if (Entry->LoadCount != 0xFFFF) { - DPRINT1("LDR: %Z got redirected to %wZ\n", &ImportNameAnsi, RedirectedImportName); + /* Perform the required action */ + switch (Flags) + { + case LDRP_UPDATE_REFCOUNT: + Entry->LoadCount++; + break; + case LDRP_UPDATE_DEREFCOUNT: + Entry->LoadCount--; + break; + case LDRP_UPDATE_PIN: + Entry->LoadCount = 0xFFFF; + break; + } + + /* Show snaps */ + if (ShowSnaps) + { + DPRINT1("LDR: Flags %lu %wZ (%lx)\n", Flags, ImportNameUnic, Entry->LoadCount); + } } - RedirectedDll = TRUE; + /* Recurse into this entry */ + LdrpUpdateLoadCount3(Entry, Flags, UpdateString); } + } - if (RedirectedDll || Status == STATUS_SXS_KEY_NOT_FOUND) + /* Go through forwarders */ + NewImportForwarder = (PIMAGE_BOUND_FORWARDER_REF)(BoundEntry + 1); + for (i = 0; i < BoundEntry->NumberOfModuleForwarderRefs; i++) + { + ImportName = (LPSTR)FirstEntry + NewImportForwarder->OffsetModuleName; + + RtlInitAnsiString(&ImportNameAnsi, ImportName); + Status = RtlAnsiStringToUnicodeString(ImportNameUnic, &ImportNameAnsi, FALSE); + if (NT_SUCCESS(Status)) { if (LdrpCheckForLoadedDll(NULL, - RedirectedImportName, + ImportNameUnic, TRUE, - RedirectedDll, + FALSE, &Entry)) { if (Entry->LoadCount != 0xFFFF) @@ -236,105 +336,13 @@ LdrpUpdateLoadCount3(IN PLDR_DATA_TABLE_ENTRY LdrEntry, /* Show snaps */ if (ShowSnaps) { - DPRINT1("LDR: Flags %lu %wZ (%lx)\n", Flags, RedirectedImportName, Entry->LoadCount); + DPRINT1("LDR: Flags %lu %wZ (%lx)\n", Flags, ImportNameUnic, Entry->LoadCount); } } /* Recurse into this entry */ LdrpUpdateLoadCount3(Entry, Flags, UpdateString); } - else if (RedirectedDll) - { - DPRINT1("LDR: LdrpCheckForLoadedDll failed for redirected dll %wZ\n", RedirectedImportName); - } - } - else - { - /* Unrecoverable SxS failure */ - DPRINT1("LDR: RtlDosApplyFileIsolationRedirection_Ustr failed with status %x for dll %wZ\n", Status, ImportNameUnic); - } - - } - - /* Go through forwarders */ - NewImportForwarder = (PIMAGE_BOUND_FORWARDER_REF)(BoundEntry + 1); - for (i = 0; i < BoundEntry->NumberOfModuleForwarderRefs; i++) - { - ImportName = (LPSTR)FirstEntry + NewImportForwarder->OffsetModuleName; - - RtlInitAnsiString(&ImportNameAnsi, ImportName); - Status = RtlAnsiStringToUnicodeString(ImportNameUnic, &ImportNameAnsi, FALSE); - if (NT_SUCCESS(Status)) - { - RedirectedDll = FALSE; - RedirectedImportName = ImportNameUnic; - - /* Check if the SxS Assemblies specify another file */ - Status = RtlDosApplyFileIsolationRedirection_Ustr(TRUE, - ImportNameUnic, - &LdrApiDefaultExtension, - UpdateString, - NULL, - &RedirectedImportName, - NULL, - NULL, - NULL); - /* Check success */ - if (NT_SUCCESS(Status)) - { - if (ShowSnaps) - { - DPRINT1("LDR: %Z got redirected to %wZ\n", &ImportNameAnsi, RedirectedImportName); - } - /* Let Ldrp know */ - RedirectedDll = TRUE; - } - - if (RedirectedDll || Status == STATUS_SXS_KEY_NOT_FOUND) - { - if (LdrpCheckForLoadedDll(NULL, - RedirectedImportName, - TRUE, - RedirectedDll, - &Entry)) - { - if (Entry->LoadCount != 0xFFFF) - { - /* Perform the required action */ - switch (Flags) - { - case LDRP_UPDATE_REFCOUNT: - Entry->LoadCount++; - break; - case LDRP_UPDATE_DEREFCOUNT: - Entry->LoadCount--; - break; - case LDRP_UPDATE_PIN: - Entry->LoadCount = 0xFFFF; - break; - } - - /* Show snaps */ - if (ShowSnaps) - { - DPRINT1("LDR: Flags %lu %wZ (%lx)\n", Flags, RedirectedImportName, Entry->LoadCount); - } - } - - /* Recurse into this entry */ - LdrpUpdateLoadCount3(Entry, Flags, UpdateString); - } - else if (RedirectedDll) - { - DPRINT1("LDR: LdrpCheckForLoadedDll failed with status %x for redirected dll %wZ\n", Status, RedirectedImportName); - } - } - else - { - /* Unrecoverable SxS failure */ - DPRINT1("LDR: RtlDosApplyFileIsolationRedirection_Ustr failed with status %x for dll %wZ\n", Status, ImportNameUnic); - } - } NewImportForwarder++; @@ -344,7 +352,7 @@ LdrpUpdateLoadCount3(IN PLDR_DATA_TABLE_ENTRY LdrEntry, } /* We're done */ - goto done; + return; } /* Check oldstyle import descriptor */ @@ -372,87 +380,44 @@ LdrpUpdateLoadCount3(IN PLDR_DATA_TABLE_ENTRY LdrEntry, Status = RtlAnsiStringToUnicodeString(ImportNameUnic, &ImportNameAnsi, FALSE); if (NT_SUCCESS(Status)) { - RedirectedDll = FALSE; - RedirectedImportName = ImportNameUnic; - - /* Check if the SxS Assemblies specify another file */ - Status = RtlDosApplyFileIsolationRedirection_Ustr(TRUE, - ImportNameUnic, - &LdrApiDefaultExtension, - UpdateString, - NULL, - &RedirectedImportName, - NULL, - NULL, - NULL); - /* Check success */ - if (NT_SUCCESS(Status)) + if (LdrpCheckForLoadedDll(NULL, + ImportNameUnic, + TRUE, + FALSE, + &Entry)) { - if (ShowSnaps) + if (Entry->LoadCount != 0xFFFF) { - DPRINT1("LDR: %Z got redirected to %wZ\n", &ImportNameAnsi, RedirectedImportName); - } - - /* Let Ldrp know */ - RedirectedDll = TRUE; - } - - if (RedirectedDll || Status == STATUS_SXS_KEY_NOT_FOUND) - { - if (LdrpCheckForLoadedDll(NULL, - RedirectedImportName, - TRUE, - RedirectedDll, - &Entry)) - { - if (Entry->LoadCount != 0xFFFF) + /* Perform the required action */ + switch (Flags) { - /* Perform the required action */ - switch (Flags) - { - case LDRP_UPDATE_REFCOUNT: - Entry->LoadCount++; - break; - case LDRP_UPDATE_DEREFCOUNT: - Entry->LoadCount--; - break; - case LDRP_UPDATE_PIN: - Entry->LoadCount = 0xFFFF; - break; - } - - /* Show snaps */ - if (ShowSnaps) - { - DPRINT1("LDR: Flags %lu %wZ (%lx)\n", Flags, RedirectedImportName, Entry->LoadCount); - } + case LDRP_UPDATE_REFCOUNT: + Entry->LoadCount++; + break; + case LDRP_UPDATE_DEREFCOUNT: + Entry->LoadCount--; + break; + case LDRP_UPDATE_PIN: + Entry->LoadCount = 0xFFFF; + break; } - /* Recurse */ - LdrpUpdateLoadCount3(Entry, Flags, UpdateString); - } - else if (RedirectedDll) - { - DPRINT1("LDR: LdrpCheckForLoadedDll failed for redirected dll %wZ\n", RedirectedImportName); + /* Show snaps */ + if (ShowSnaps) + { + DPRINT1("LDR: Flags %lu %wZ (%lx)\n", Flags, ImportNameUnic, Entry->LoadCount); + } } + /* Recurse */ + LdrpUpdateLoadCount3(Entry, Flags, UpdateString); } - else - { - /* Unrecoverable SxS failure */ - DPRINT1("LDR: RtlDosApplyFileIsolationRedirection_Ustr failed for dll %wZ\n", ImportNameUnic); - } - } /* Go to the next entry */ ImportEntry++; } } - -done: - /* Release the context */ - RtlDeactivateActivationContextUnsafeFast(&ActCtx); } VOID @@ -700,6 +665,7 @@ LdrpResolveDllName(PWSTR DllPath, PWCHAR NameBuffer, p1, p2 = 0; ULONG Length; ULONG BufSize = 500; + NTSTATUS Status; /* Allocate space for full DLL name */ FullDllName->Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufSize + sizeof(UNICODE_NULL)); @@ -714,14 +680,25 @@ LdrpResolveDllName(PWSTR DllPath, if (!Length || Length > BufSize) { - if (ShowSnaps) + /* HACK: Try to find active context dll */ + Status = find_actctx_dll(DllName, FullDllName->Buffer); + if(Status == STATUS_SUCCESS) { - DPRINT1("LDR: LdrResolveDllName - Unable to find "); - DPRINT1("%ws from %ws\n", DllName, DllPath ? DllPath : LdrpDefaultPath.Buffer); + Length = wcslen(FullDllName->Buffer) * sizeof(WCHAR); + DPRINT1("found %S for %S\n", FullDllName->Buffer, DllName); } + else + { + /* NOTE: This code should remain after removing the hack */ + if (ShowSnaps) + { + DPRINT1("LDR: LdrResolveDllName - Unable to find "); + DPRINT1("%ws from %ws\n", DllName, DllPath ? DllPath : LdrpDefaultPath.Buffer); + } - RtlFreeUnicodeString(FullDllName); - return FALSE; + RtlFreeUnicodeString(FullDllName); + return FALSE; + } } /* Construct full DLL name */ @@ -1061,7 +1038,7 @@ LdrpMapDll(IN PWSTR SearchPath OPTIONAL, } /* Check if we have a known dll directory */ - if (LdrpKnownDllObjectDirectory && Redirect == FALSE) + if (LdrpKnownDllObjectDirectory) { /* Check if the path is full */ while (*p1) @@ -2000,10 +1977,8 @@ LdrpCheckForLoadedDll(IN PWSTR DllPath, /* Look in the hash table if flag was set */ lookinhash: - if (Flag /* the second check is a hack */ && !RedirectedDll) + if (Flag) { - /* FIXME: if we get redirected dll it means that we also get a full path so we need to find its filename for the hash lookup */ - /* Get hash index */ HashIndex = LDR_GET_HASH_ENTRY(DllName->Buffer[0]); @@ -2031,54 +2006,58 @@ lookinhash: return FALSE; } - /* Check if this is a redirected DLL */ - if (RedirectedDll) + /* Check if there is a full path in this DLL */ + wc = DllName->Buffer; + while (*wc) { - /* Redirected dlls already have a full path */ - FullPath = TRUE; - FullDllName = *DllName; - } - else - { - /* Check if there is a full path in this DLL */ - wc = DllName->Buffer; - while (*wc) + /* Check for a slash in the current position*/ + if ((*wc == L'\\') || (*wc == L'/')) { - /* Check for a slash in the current position*/ - if ((*wc == L'\\') || (*wc == L'/')) + /* Found the slash, so dll name contains path */ + FullPath = TRUE; + + /* Setup full dll name string */ + FullDllName.Buffer = NameBuf; + + /* FIXME: This is from the Windows 2000 loader, not XP/2003, we should call LdrpSearchPath */ + Length = RtlDosSearchPath_U(DllPath ? DllPath : LdrpDefaultPath.Buffer, + DllName->Buffer, + NULL, + sizeof(NameBuf) - sizeof(UNICODE_NULL), + FullDllName.Buffer, + NULL); + + /* Check if that was successful */ + if (!(Length) || (Length > (sizeof(NameBuf) - sizeof(UNICODE_NULL)))) { - /* Found the slash, so dll name contains path */ - FullPath = TRUE; - - /* Setup full dll name string */ - FullDllName.Buffer = NameBuf; - - /* FIXME: This is from the Windows 2000 loader, not XP/2003, we should call LdrpSearchPath */ - Length = RtlDosSearchPath_U(DllPath ? DllPath : LdrpDefaultPath.Buffer, - DllName->Buffer, - NULL, - sizeof(NameBuf) - sizeof(UNICODE_NULL), - FullDllName.Buffer, - NULL); - - /* Check if that was successful */ - if (!(Length) || (Length > (sizeof(NameBuf) - sizeof(UNICODE_NULL)))) + /* HACK: Try to find active context dll */ + Status = find_actctx_dll(DllName->Buffer, FullDllName.Buffer); + if(Status == STATUS_SUCCESS) { - if (ShowSnaps) - { - DPRINT1("LDR: LdrpCheckForLoadedDll - Unable To Locate %wZ: 0x%08x\n", - &DllName, Length); - } + Length = wcslen(FullDllName.Buffer) * sizeof(WCHAR); + DPRINT1("found %S for %S\n", FullDllName.Buffer, DllName->Buffer); + } + else + { + + if (ShowSnaps) + { + DPRINT1("LDR: LdrpCheckForLoadedDll - Unable To Locate %wZ: 0x%08x\n", + &DllName, Length); } - /* Full dll name is found */ - FullDllName.Length = Length; - FullDllName.MaximumLength = FullDllName.Length + sizeof(UNICODE_NULL); - break; + /* Return failure */ + return FALSE; + } } - wc++; + /* Full dll name is found */ + FullDllName.Length = Length; + FullDllName.MaximumLength = FullDllName.Length + sizeof(UNICODE_NULL); + break; } + + wc++; } /* Go check the hash table */ diff --git a/dll/ntdll/rtl/libsupp.c b/dll/ntdll/rtl/libsupp.c index d29ccaf82de..08a26ccc996 100644 --- a/dll/ntdll/rtl/libsupp.c +++ b/dll/ntdll/rtl/libsupp.c @@ -642,133 +642,6 @@ RtlPcToFileHeader(IN PVOID PcValue, return ImageBase; } -NTSTATUS get_buffer(LPWSTR *buffer, SIZE_T needed, PUNICODE_STRING CallerBuffer, BOOLEAN bAllocateBuffer) -{ - WCHAR *p; - - if (CallerBuffer && CallerBuffer->MaximumLength > needed) - { - p = CallerBuffer->Buffer; - CallerBuffer->Length = needed - sizeof(WCHAR); - } - else - { - if (!bAllocateBuffer) - return STATUS_BUFFER_TOO_SMALL; - - if (CallerBuffer) - CallerBuffer->Buffer[0] = 0; - - p = RtlAllocateHeap(RtlGetProcessHeap(), 0, needed ); - if (!p) - return STATUS_NO_MEMORY; - } - *buffer = p; - - return STATUS_SUCCESS; -} - -/* NOTE: Remove this one once our actctx support becomes better */ -NTSTATUS find_actctx_dll( PUNICODE_STRING pnameW, LPWSTR *fullname, PUNICODE_STRING CallerBuffer, BOOLEAN bAllocateBuffer) -{ - static const WCHAR winsxsW[] = {'\\','w','i','n','s','x','s','\\'}; - static const WCHAR dotManifestW[] = {'.','m','a','n','i','f','e','s','t',0}; - - ACTIVATION_CONTEXT_ASSEMBLY_DETAILED_INFORMATION *info; - ACTCTX_SECTION_KEYED_DATA data; - NTSTATUS status; - SIZE_T needed, size = 1024; - WCHAR *p; - - data.cbSize = sizeof(data); - status = RtlFindActivationContextSectionString( FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX, NULL, - ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION, - pnameW, &data ); - if (status != STATUS_SUCCESS) - { - //DPRINT1("RtlFindActivationContextSectionString returned 0x%x for %wZ\n", status, pnameW); - 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; - } - - DPRINT("manifestpath === %S\n", info->lpAssemblyManifestPath); - DPRINT("DirectoryName === %S\n", info->lpAssemblyDirectoryName); - if (!info->lpAssemblyManifestPath /*|| !info->lpAssemblyDirectoryName*/) - { - status = STATUS_SXS_KEY_NOT_FOUND; - goto done; - } - - if ((p = wcsrchr( info->lpAssemblyManifestPath, '\\' ))) - { - DWORD dirlen = info->ulAssemblyDirectoryNameLength / sizeof(WCHAR); - - p++; - if (!info->lpAssemblyDirectoryName || _wcsnicmp( p, info->lpAssemblyDirectoryName, dirlen ) || wcsicmp( p + dirlen, dotManifestW )) - { - /* manifest name does not match directory name, so it's not a global - * windows/winsxs manifest; use the manifest directory name instead */ - dirlen = p - info->lpAssemblyManifestPath; - needed = (dirlen + 1) * sizeof(WCHAR) + pnameW->Length; - - status = get_buffer(fullname, needed, CallerBuffer, bAllocateBuffer); - if (!NT_SUCCESS(status)) - goto done; - - p = *fullname; - - memcpy( p, info->lpAssemblyManifestPath, dirlen * sizeof(WCHAR) ); - p += dirlen; - memcpy( p, pnameW->Buffer, pnameW->Length); - p += (pnameW->Length / sizeof(WCHAR)); - *p = L'\0'; - - goto done; - } - } - - needed = (wcslen(SharedUserData->NtSystemRoot) * sizeof(WCHAR) + - sizeof(winsxsW) + info->ulAssemblyDirectoryNameLength + pnameW->Length + 2*sizeof(WCHAR)); - - status = get_buffer(fullname, needed, CallerBuffer, bAllocateBuffer); - if (!NT_SUCCESS(status)) - goto done; - - p = *fullname; - - wcscpy( p, SharedUserData->NtSystemRoot ); - p += wcslen(p); - memcpy( p, winsxsW, sizeof(winsxsW) ); - p += sizeof(winsxsW) / sizeof(WCHAR); - memcpy( p, info->lpAssemblyDirectoryName, info->ulAssemblyDirectoryNameLength ); - p += info->ulAssemblyDirectoryNameLength / sizeof(WCHAR); - *p++ = L'\\'; - memcpy( p, pnameW->Buffer, pnameW->Length); - p += (pnameW->Length / sizeof(WCHAR)); - *p = L'\0'; - -done: - RtlFreeHeap( RtlGetProcessHeap(), 0, info ); - RtlReleaseActivationContext( data.hActCtx ); - DPRINT("%S\n", fullname); - return status; -} - /* * @unimplemented */ @@ -785,101 +658,7 @@ RtlDosApplyFileIsolationRedirection_Ustr(IN ULONG Flags, IN PSIZE_T FileNameSize, IN PSIZE_T RequiredLength) { - NTSTATUS Status; - LPWSTR fullname; - WCHAR buffer [MAX_PATH]; - UNICODE_STRING localStr, localStr2, *pstrParam; - WCHAR *p; - BOOLEAN GotExtension; - WCHAR c; - - /* Check for invalid parameters */ - if (!OriginalName) - { - return STATUS_INVALID_PARAMETER; - } - - if (!DynamicString && !StaticString) - { - return STATUS_INVALID_PARAMETER; - } - - if ((DynamicString) && (StaticString) && !(NewName)) - { - return STATUS_INVALID_PARAMETER; - } - - if (!OriginalName->Buffer || OriginalName->Length == 0) - { - return STATUS_SXS_KEY_NOT_FOUND; - } - - if (StaticString && (OriginalName == StaticString || OriginalName->Buffer == StaticString->Buffer)) - { - return STATUS_SXS_KEY_NOT_FOUND; - } - - pstrParam = OriginalName; - - /* Get the file name with an extension */ - p = OriginalName->Buffer + OriginalName->Length / sizeof(WCHAR) - 1; - GotExtension = FALSE; - while (p >= OriginalName->Buffer) - { - c = *p--; - if (c == L'.') - { - GotExtension = TRUE; - } - else if (c == L'\\') - { - localStr.Buffer = p + 2; - localStr.Length = OriginalName->Length - ((ULONG_PTR)localStr.Buffer - (ULONG_PTR)OriginalName->Buffer); - localStr.MaximumLength = OriginalName->MaximumLength - ((ULONG_PTR)localStr.Buffer - (ULONG_PTR)OriginalName->Buffer); - pstrParam = &localStr; - break; - } - } - - if (!GotExtension) - { - if (!Extension) - { - return STATUS_SXS_KEY_NOT_FOUND; - } - - if (pstrParam->Length + Extension->Length > sizeof(buffer)) - { - //FIXME! - return STATUS_NO_MEMORY; - } - - RtlInitEmptyUnicodeString(&localStr2, buffer, sizeof(buffer)); - RtlAppendUnicodeStringToString(&localStr2, pstrParam); - RtlAppendUnicodeStringToString(&localStr2, Extension); - pstrParam = &localStr2; - } - - /* Use wine's function as long as we use wine's sxs implementation in ntdll */ - Status = find_actctx_dll(pstrParam, &fullname, StaticString, DynamicString != NULL); - if (!NT_SUCCESS(Status)) - { - return Status; - } - - DPRINT("Redirecting %wZ to %S\n", OriginalName, fullname); - - if (!StaticString || StaticString->Buffer != fullname) - { - RtlInitUnicodeString(DynamicString, fullname); - *NewName = DynamicString; - } - else - { - *NewName = StaticString; - } - - return Status; + return STATUS_SXS_KEY_NOT_FOUND; } /*