[LDR] Overhaul sxs support in ldr

* Remove the hacky find_actctx_dll form ldr that was taken from wine. LdrpResolveDllName and LdrpCheckForLoadedDll should get a parameter that is already redirected.
* Use RtlDosApplyFileIsolationRedirection_Ustr in LdrpLoadImportModule and LdrpUpdateLoadCount3 to redirerect the input parameter.
This commit is contained in:
Giannis Adamopoulos 2017-10-03 22:11:47 +03:00
parent 7000fe2340
commit f318a25e10
2 changed files with 293 additions and 282 deletions

View file

@ -815,7 +815,6 @@ LdrpWalkImportDescriptor(IN LPWSTR DllPath OPTIONAL,
return Status; return Status;
} }
/* FIXME: This function is missing SxS support */
NTSTATUS NTSTATUS
NTAPI NTAPI
LdrpLoadImportModule(IN PWSTR DllPath OPTIONAL, LdrpLoadImportModule(IN PWSTR DllPath OPTIONAL,
@ -831,9 +830,14 @@ LdrpLoadImportModule(IN PWSTR DllPath OPTIONAL,
NTSTATUS Status; NTSTATUS Status;
PPEB Peb = RtlGetCurrentPeb(); PPEB Peb = RtlGetCurrentPeb();
PTEB Teb = NtCurrentTeb(); PTEB Teb = NtCurrentTeb();
UNICODE_STRING RedirectedImpDescName;
BOOLEAN RedirectedDll;
DPRINT("LdrpLoadImportModule('%S' '%s' %p %p)\n", DllPath, ImportName, DataTableEntry, Existing); DPRINT("LdrpLoadImportModule('%S' '%s' %p %p)\n", DllPath, ImportName, DataTableEntry, Existing);
RedirectedDll = FALSE;
RtlInitEmptyUnicodeString(&RedirectedImpDescName, NULL, 0);
/* Convert import descriptor name to unicode string */ /* Convert import descriptor name to unicode string */
ImpDescName = &Teb->StaticUnicodeString; ImpDescName = &Teb->StaticUnicodeString;
RtlInitAnsiString(&AnsiString, ImportName); RtlInitAnsiString(&AnsiString, ImportName);
@ -883,76 +887,59 @@ LdrpLoadImportModule(IN PWSTR DllPath OPTIONAL,
&LdrApiDefaultExtension); &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 */ /* Check if it's loaded */
if (LdrpCheckForLoadedDll(DllPath, if (LdrpCheckForLoadedDll(DllPath,
ImpDescName, ImpDescName,
TRUE, TRUE,
FALSE, RedirectedDll,
DataTableEntry)) DataTableEntry))
{ {
/* It's already existing in the list */ /* It's already existing in the list */
*Existing = TRUE; *Existing = TRUE;
return STATUS_SUCCESS; Status = STATUS_SUCCESS;
goto done;
} }
/* We're loading it for the first time */ /* We're loading it for the first time */
*Existing = FALSE; *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 */ /* Map it */
Status = LdrpMapDll(DllPath, Status = LdrpMapDll(DllPath,
NULL, NULL,
ImpDescName->Buffer, ImpDescName->Buffer,
NULL, NULL,
TRUE, TRUE,
FALSE, RedirectedDll,
DataTableEntry); DataTableEntry);
if (!NT_SUCCESS(Status))
if (!NT_SUCCESS(Status)) return Status; {
DPRINT1("LDR: LdrpMapDll failed with status %x for dll %wZ\n", Status, ImpDescName);
goto done;
}
/* Walk its import descriptor table */ /* Walk its import descriptor table */
Status = LdrpWalkImportDescriptor(DllPath, Status = LdrpWalkImportDescriptor(DllPath,
@ -964,6 +951,9 @@ done:
&(*DataTableEntry)->InInitializationOrderLinks); &(*DataTableEntry)->InInitializationOrderLinks);
} }
done:
RtlFreeUnicodeString(&RedirectedImpDescName);
return Status; return Status;
} }

View file

@ -28,101 +28,6 @@ PVOID g_pfnSE_ProcessDying;
/* FUNCTIONS *****************************************************************/ /* 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 NTSTATUS
NTAPI NTAPI
LdrpAllocateUnicodeString(IN OUT PUNICODE_STRING StringOut, LdrpAllocateUnicodeString(IN OUT PUNICODE_STRING StringOut,
@ -214,19 +119,30 @@ LdrpUpdateLoadCount3(IN PLDR_DATA_TABLE_ENTRY LdrEntry,
PIMAGE_IMPORT_DESCRIPTOR ImportEntry; PIMAGE_IMPORT_DESCRIPTOR ImportEntry;
PIMAGE_THUNK_DATA FirstThunk; PIMAGE_THUNK_DATA FirstThunk;
PLDR_DATA_TABLE_ENTRY Entry; PLDR_DATA_TABLE_ENTRY Entry;
PUNICODE_STRING ImportNameUnic; PUNICODE_STRING ImportNameUnic, RedirectedImportName;
ANSI_STRING ImportNameAnsi; ANSI_STRING ImportNameAnsi;
LPSTR ImportName; LPSTR ImportName;
ULONG ImportSize; ULONG ImportSize;
NTSTATUS Status; NTSTATUS Status;
ULONG i; 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 */ /* Check the action we need to perform */
if ((Flags == LDRP_UPDATE_REFCOUNT) || (Flags == LDRP_UPDATE_PIN)) if ((Flags == LDRP_UPDATE_REFCOUNT) || (Flags == LDRP_UPDATE_PIN))
{ {
/* Make sure entry is not being loaded already */ /* Make sure entry is not being loaded already */
if (LdrEntry->Flags & LDRP_LOAD_IN_PROGRESS) if (LdrEntry->Flags & LDRP_LOAD_IN_PROGRESS)
return; goto done;
LdrEntry->Flags |= LDRP_LOAD_IN_PROGRESS; LdrEntry->Flags |= LDRP_LOAD_IN_PROGRESS;
} }
@ -234,7 +150,7 @@ LdrpUpdateLoadCount3(IN PLDR_DATA_TABLE_ENTRY LdrEntry,
{ {
/* Make sure the entry is not being unloaded already */ /* Make sure the entry is not being unloaded already */
if (LdrEntry->Flags & LDRP_UNLOAD_IN_PROGRESS) if (LdrEntry->Flags & LDRP_UNLOAD_IN_PROGRESS)
return; goto done;
LdrEntry->Flags |= LDRP_UNLOAD_IN_PROGRESS; LdrEntry->Flags |= LDRP_UNLOAD_IN_PROGRESS;
} }
@ -267,54 +183,38 @@ LdrpUpdateLoadCount3(IN PLDR_DATA_TABLE_ENTRY LdrEntry,
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
{ {
if (LdrpCheckForLoadedDll(NULL, RedirectedDll = FALSE;
ImportNameUnic, RedirectedImportName = ImportNameUnic;
TRUE,
FALSE,
&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 */ /* Check if the SxS Assemblies specify another file */
if (ShowSnaps) Status = RtlDosApplyFileIsolationRedirection_Ustr(TRUE,
{ ImportNameUnic,
DPRINT1("LDR: Flags %lu %wZ (%lx)\n", Flags, ImportNameUnic, Entry->LoadCount); &LdrApiDefaultExtension,
} UpdateString,
} NULL,
&RedirectedImportName,
NULL,
NULL,
NULL);
/* Recurse into this entry */ /* Check success */
LdrpUpdateLoadCount3(Entry, Flags, UpdateString);
}
}
/* 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 (NT_SUCCESS(Status))
{
/* Let Ldrp know */
if (ShowSnaps)
{
DPRINT1("LDR: %Z got redirected to %wZ\n", &ImportNameAnsi, RedirectedImportName);
}
RedirectedDll = TRUE;
}
if (RedirectedDll || Status == STATUS_SXS_KEY_NOT_FOUND)
{ {
if (LdrpCheckForLoadedDll(NULL, if (LdrpCheckForLoadedDll(NULL,
ImportNameUnic, RedirectedImportName,
TRUE, TRUE,
FALSE, RedirectedDll,
&Entry)) &Entry))
{ {
if (Entry->LoadCount != 0xFFFF) if (Entry->LoadCount != 0xFFFF)
@ -336,13 +236,105 @@ LdrpUpdateLoadCount3(IN PLDR_DATA_TABLE_ENTRY LdrEntry,
/* Show snaps */ /* Show snaps */
if (ShowSnaps) if (ShowSnaps)
{ {
DPRINT1("LDR: Flags %lu %wZ (%lx)\n", Flags, ImportNameUnic, Entry->LoadCount); DPRINT1("LDR: Flags %lu %wZ (%lx)\n", Flags, RedirectedImportName, Entry->LoadCount);
} }
} }
/* Recurse into this entry */ /* Recurse into this entry */
LdrpUpdateLoadCount3(Entry, Flags, UpdateString); 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++; NewImportForwarder++;
@ -352,7 +344,7 @@ LdrpUpdateLoadCount3(IN PLDR_DATA_TABLE_ENTRY LdrEntry,
} }
/* We're done */ /* We're done */
return; goto done;
} }
/* Check oldstyle import descriptor */ /* Check oldstyle import descriptor */
@ -380,44 +372,87 @@ LdrpUpdateLoadCount3(IN PLDR_DATA_TABLE_ENTRY LdrEntry,
Status = RtlAnsiStringToUnicodeString(ImportNameUnic, &ImportNameAnsi, FALSE); Status = RtlAnsiStringToUnicodeString(ImportNameUnic, &ImportNameAnsi, FALSE);
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
{ {
if (LdrpCheckForLoadedDll(NULL, RedirectedDll = FALSE;
ImportNameUnic, RedirectedImportName = ImportNameUnic;
TRUE,
FALSE,
&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 */ /* Check if the SxS Assemblies specify another file */
if (ShowSnaps) Status = RtlDosApplyFileIsolationRedirection_Ustr(TRUE,
{ ImportNameUnic,
DPRINT1("LDR: Flags %lu %wZ (%lx)\n", Flags, ImportNameUnic, Entry->LoadCount); &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);
} }
/* Recurse */ /* Let Ldrp know */
LdrpUpdateLoadCount3(Entry, Flags, UpdateString); 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 */
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 for dll %wZ\n", ImportNameUnic);
}
} }
/* Go to the next entry */ /* Go to the next entry */
ImportEntry++; ImportEntry++;
} }
} }
done:
/* Release the context */
RtlDeactivateActivationContextUnsafeFast(&ActCtx);
} }
VOID VOID
@ -665,7 +700,6 @@ LdrpResolveDllName(PWSTR DllPath,
PWCHAR NameBuffer, p1, p2 = 0; PWCHAR NameBuffer, p1, p2 = 0;
ULONG Length; ULONG Length;
ULONG BufSize = 500; ULONG BufSize = 500;
NTSTATUS Status;
/* Allocate space for full DLL name */ /* Allocate space for full DLL name */
FullDllName->Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufSize + sizeof(UNICODE_NULL)); FullDllName->Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufSize + sizeof(UNICODE_NULL));
@ -680,25 +714,14 @@ LdrpResolveDllName(PWSTR DllPath,
if (!Length || Length > BufSize) if (!Length || Length > BufSize)
{ {
/* HACK: Try to find active context dll */ if (ShowSnaps)
Status = find_actctx_dll(DllName, FullDllName->Buffer);
if(Status == STATUS_SUCCESS)
{ {
Length = wcslen(FullDllName->Buffer) * sizeof(WCHAR); DPRINT1("LDR: LdrResolveDllName - Unable to find ");
DPRINT1("found %S for %S\n", FullDllName->Buffer, DllName); DPRINT1("%ws from %ws\n", DllName, DllPath ? DllPath : LdrpDefaultPath.Buffer);
} }
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); RtlFreeUnicodeString(FullDllName);
return FALSE; return FALSE;
}
} }
/* Construct full DLL name */ /* Construct full DLL name */
@ -1038,7 +1061,7 @@ LdrpMapDll(IN PWSTR SearchPath OPTIONAL,
} }
/* Check if we have a known dll directory */ /* Check if we have a known dll directory */
if (LdrpKnownDllObjectDirectory) if (LdrpKnownDllObjectDirectory && Redirect == FALSE)
{ {
/* Check if the path is full */ /* Check if the path is full */
while (*p1) while (*p1)
@ -1977,8 +2000,10 @@ LdrpCheckForLoadedDll(IN PWSTR DllPath,
/* Look in the hash table if flag was set */ /* Look in the hash table if flag was set */
lookinhash: lookinhash:
if (Flag) if (Flag /* the second check is a hack */ && !RedirectedDll)
{ {
/* 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 */ /* Get hash index */
HashIndex = LDR_GET_HASH_ENTRY(DllName->Buffer[0]); HashIndex = LDR_GET_HASH_ENTRY(DllName->Buffer[0]);
@ -2006,58 +2031,54 @@ lookinhash:
return FALSE; return FALSE;
} }
/* Check if there is a full path in this DLL */ /* Check if this is a redirected DLL */
wc = DllName->Buffer; if (RedirectedDll)
while (*wc)
{ {
/* Check for a slash in the current position*/ /* Redirected dlls already have a full path */
if ((*wc == L'\\') || (*wc == L'/')) FullPath = TRUE;
FullDllName = *DllName;
}
else
{
/* Check if there is a full path in this DLL */
wc = DllName->Buffer;
while (*wc)
{ {
/* Found the slash, so dll name contains path */ /* Check for a slash in the current position*/
FullPath = TRUE; if ((*wc == L'\\') || (*wc == L'/'))
/* 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 */ /* Found the slash, so dll name contains path */
Status = find_actctx_dll(DllName->Buffer, FullDllName.Buffer); FullPath = TRUE;
if(Status == STATUS_SUCCESS)
{
Length = wcslen(FullDllName.Buffer) * sizeof(WCHAR);
DPRINT1("found %S for %S\n", FullDllName.Buffer, DllName->Buffer);
}
else
{
if (ShowSnaps) /* 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))))
{ {
DPRINT1("LDR: LdrpCheckForLoadedDll - Unable To Locate %wZ: 0x%08x\n", if (ShowSnaps)
&DllName, Length); {
DPRINT1("LDR: LdrpCheckForLoadedDll - Unable To Locate %wZ: 0x%08x\n",
&DllName, Length);
}
} }
/* Return failure */ /* Full dll name is found */
return FALSE; FullDllName.Length = Length;
} FullDllName.MaximumLength = FullDllName.Length + sizeof(UNICODE_NULL);
break;
} }
/* Full dll name is found */ wc++;
FullDllName.Length = Length;
FullDllName.MaximumLength = FullDllName.Length + sizeof(UNICODE_NULL);
break;
} }
wc++;
} }
/* Go check the hash table */ /* Go check the hash table */