mirror of
https://github.com/reactos/reactos.git
synced 2025-02-22 16:36:33 +00:00
[0.4.8] revert [NTDLL/LDR] Overhaul sxs work
This reverts commit 0.4.8-dev-502-g7000fe2340
. This reverts commit 0.4.8-dev-503-gf318a25e10
. The two changes were done once to work towards better shim-supporting APIs of newer Windows versions on demand in the future. Luckily we do not depend on them yet. Giannis already fixed most regressions of the 2 commits before branching 0.4.8RC (e.g. 2nd stage theme-selector). Unfortunately we still have issues atm with the existing mixture of Wine comctl32 v5 vs v6. The image-lists of both are not compatible as Giannis told us. We revert both commits for this release to fix CORE-14433 (missing icons due to incompatible image-lists). We can not simply add a manifest here, because 3rd party apps are affected. I double-checked, all of those (formerly affected) apps are working fine and show the icons after the revert: 2nd-stage-theme-selection, MS Excel Viewer 2007 open-dlg, MSVCPP 6 installer open-dlg, FaxViewer save-dlg, MS Word Viewer 2003 open-dlg This revert also obsoletes works/fixes like2f11904000
.
This commit is contained in:
parent
795c7f70cc
commit
11bf8fa047
3 changed files with 277 additions and 509 deletions
|
@ -815,6 +815,7 @@ 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,
|
||||||
|
@ -830,14 +831,9 @@ 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);
|
||||||
|
@ -887,59 +883,76 @@ 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,
|
||||||
RedirectedDll,
|
FALSE,
|
||||||
DataTableEntry))
|
DataTableEntry))
|
||||||
{
|
{
|
||||||
/* It's already existing in the list */
|
/* It's already existing in the list */
|
||||||
*Existing = TRUE;
|
*Existing = TRUE;
|
||||||
Status = STATUS_SUCCESS;
|
return 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,
|
||||||
RedirectedDll,
|
FALSE,
|
||||||
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,
|
||||||
|
@ -951,9 +964,6 @@ LdrpLoadImportModule(IN PWSTR DllPath OPTIONAL,
|
||||||
&(*DataTableEntry)->InInitializationOrderLinks);
|
&(*DataTableEntry)->InInitializationOrderLinks);
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
|
||||||
RtlFreeUnicodeString(&RedirectedImpDescName);
|
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,101 @@ 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,
|
||||||
|
@ -119,30 +214,19 @@ 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, RedirectedImportName;
|
PUNICODE_STRING ImportNameUnic;
|
||||||
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)
|
||||||
goto done;
|
return;
|
||||||
|
|
||||||
LdrEntry->Flags |= LDRP_LOAD_IN_PROGRESS;
|
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 */
|
/* Make sure the entry is not being unloaded already */
|
||||||
if (LdrEntry->Flags & LDRP_UNLOAD_IN_PROGRESS)
|
if (LdrEntry->Flags & LDRP_UNLOAD_IN_PROGRESS)
|
||||||
goto done;
|
return;
|
||||||
|
|
||||||
LdrEntry->Flags |= LDRP_UNLOAD_IN_PROGRESS;
|
LdrEntry->Flags |= LDRP_UNLOAD_IN_PROGRESS;
|
||||||
}
|
}
|
||||||
|
@ -183,38 +267,54 @@ LdrpUpdateLoadCount3(IN PLDR_DATA_TABLE_ENTRY LdrEntry,
|
||||||
|
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
RedirectedDll = FALSE;
|
if (LdrpCheckForLoadedDll(NULL,
|
||||||
RedirectedImportName = ImportNameUnic;
|
ImportNameUnic,
|
||||||
|
TRUE,
|
||||||
/* Check if the SxS Assemblies specify another file */
|
FALSE,
|
||||||
Status = RtlDosApplyFileIsolationRedirection_Ustr(TRUE,
|
&Entry))
|
||||||
ImportNameUnic,
|
|
||||||
&LdrApiDefaultExtension,
|
|
||||||
UpdateString,
|
|
||||||
NULL,
|
|
||||||
&RedirectedImportName,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
/* Check success */
|
|
||||||
if (NT_SUCCESS(Status))
|
|
||||||
{
|
{
|
||||||
/* Let Ldrp know */
|
if (Entry->LoadCount != 0xFFFF)
|
||||||
if (ShowSnaps)
|
|
||||||
{
|
{
|
||||||
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,
|
if (LdrpCheckForLoadedDll(NULL,
|
||||||
RedirectedImportName,
|
ImportNameUnic,
|
||||||
TRUE,
|
TRUE,
|
||||||
RedirectedDll,
|
FALSE,
|
||||||
&Entry))
|
&Entry))
|
||||||
{
|
{
|
||||||
if (Entry->LoadCount != 0xFFFF)
|
if (Entry->LoadCount != 0xFFFF)
|
||||||
|
@ -236,105 +336,13 @@ LdrpUpdateLoadCount3(IN PLDR_DATA_TABLE_ENTRY LdrEntry,
|
||||||
/* Show snaps */
|
/* Show snaps */
|
||||||
if (ShowSnaps)
|
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 */
|
/* 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++;
|
||||||
|
@ -344,7 +352,7 @@ LdrpUpdateLoadCount3(IN PLDR_DATA_TABLE_ENTRY LdrEntry,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We're done */
|
/* We're done */
|
||||||
goto done;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check oldstyle import descriptor */
|
/* Check oldstyle import descriptor */
|
||||||
|
@ -372,87 +380,44 @@ 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))
|
||||||
{
|
{
|
||||||
RedirectedDll = FALSE;
|
if (LdrpCheckForLoadedDll(NULL,
|
||||||
RedirectedImportName = ImportNameUnic;
|
ImportNameUnic,
|
||||||
|
TRUE,
|
||||||
/* Check if the SxS Assemblies specify another file */
|
FALSE,
|
||||||
Status = RtlDosApplyFileIsolationRedirection_Ustr(TRUE,
|
&Entry))
|
||||||
ImportNameUnic,
|
|
||||||
&LdrApiDefaultExtension,
|
|
||||||
UpdateString,
|
|
||||||
NULL,
|
|
||||||
&RedirectedImportName,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL);
|
|
||||||
/* Check success */
|
|
||||||
if (NT_SUCCESS(Status))
|
|
||||||
{
|
{
|
||||||
if (ShowSnaps)
|
if (Entry->LoadCount != 0xFFFF)
|
||||||
{
|
{
|
||||||
DPRINT1("LDR: %Z got redirected to %wZ\n", &ImportNameAnsi, RedirectedImportName);
|
/* Perform the required action */
|
||||||
}
|
switch (Flags)
|
||||||
|
|
||||||
/* 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 */
|
case LDRP_UPDATE_REFCOUNT:
|
||||||
switch (Flags)
|
Entry->LoadCount++;
|
||||||
{
|
break;
|
||||||
case LDRP_UPDATE_REFCOUNT:
|
case LDRP_UPDATE_DEREFCOUNT:
|
||||||
Entry->LoadCount++;
|
Entry->LoadCount--;
|
||||||
break;
|
break;
|
||||||
case LDRP_UPDATE_DEREFCOUNT:
|
case LDRP_UPDATE_PIN:
|
||||||
Entry->LoadCount--;
|
Entry->LoadCount = 0xFFFF;
|
||||||
break;
|
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 */
|
/* Show snaps */
|
||||||
LdrpUpdateLoadCount3(Entry, Flags, UpdateString);
|
if (ShowSnaps)
|
||||||
}
|
{
|
||||||
else if (RedirectedDll)
|
DPRINT1("LDR: Flags %lu %wZ (%lx)\n", Flags, ImportNameUnic, Entry->LoadCount);
|
||||||
{
|
}
|
||||||
DPRINT1("LDR: LdrpCheckForLoadedDll failed for redirected dll %wZ\n", RedirectedImportName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Recurse */
|
||||||
|
LdrpUpdateLoadCount3(Entry, Flags, UpdateString);
|
||||||
}
|
}
|
||||||
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
|
||||||
|
@ -700,6 +665,7 @@ 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));
|
||||||
|
@ -714,14 +680,25 @@ LdrpResolveDllName(PWSTR DllPath,
|
||||||
|
|
||||||
if (!Length || Length > BufSize)
|
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 ");
|
Length = wcslen(FullDllName->Buffer) * sizeof(WCHAR);
|
||||||
DPRINT1("%ws from %ws\n", DllName, DllPath ? DllPath : LdrpDefaultPath.Buffer);
|
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);
|
RtlFreeUnicodeString(FullDllName);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Construct full DLL name */
|
/* Construct full DLL name */
|
||||||
|
@ -1061,7 +1038,7 @@ LdrpMapDll(IN PWSTR SearchPath OPTIONAL,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if we have a known dll directory */
|
/* Check if we have a known dll directory */
|
||||||
if (LdrpKnownDllObjectDirectory && Redirect == FALSE)
|
if (LdrpKnownDllObjectDirectory)
|
||||||
{
|
{
|
||||||
/* Check if the path is full */
|
/* Check if the path is full */
|
||||||
while (*p1)
|
while (*p1)
|
||||||
|
@ -2000,10 +1977,8 @@ 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 /* 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 */
|
/* Get hash index */
|
||||||
HashIndex = LDR_GET_HASH_ENTRY(DllName->Buffer[0]);
|
HashIndex = LDR_GET_HASH_ENTRY(DllName->Buffer[0]);
|
||||||
|
|
||||||
|
@ -2031,54 +2006,58 @@ lookinhash:
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if this is a redirected DLL */
|
/* Check if there is a full path in this DLL */
|
||||||
if (RedirectedDll)
|
wc = DllName->Buffer;
|
||||||
|
while (*wc)
|
||||||
{
|
{
|
||||||
/* Redirected dlls already have a full path */
|
/* Check for a slash in the current position*/
|
||||||
FullPath = TRUE;
|
if ((*wc == L'\\') || (*wc == L'/'))
|
||||||
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*/
|
/* Found the slash, so dll name contains path */
|
||||||
if ((*wc == L'\\') || (*wc == L'/'))
|
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 */
|
/* HACK: Try to find active context dll */
|
||||||
FullPath = TRUE;
|
Status = find_actctx_dll(DllName->Buffer, FullDllName.Buffer);
|
||||||
|
if(Status == STATUS_SUCCESS)
|
||||||
/* 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))))
|
|
||||||
{
|
{
|
||||||
if (ShowSnaps)
|
Length = wcslen(FullDllName.Buffer) * sizeof(WCHAR);
|
||||||
{
|
DPRINT1("found %S for %S\n", FullDllName.Buffer, DllName->Buffer);
|
||||||
DPRINT1("LDR: LdrpCheckForLoadedDll - Unable To Locate %wZ: 0x%08x\n",
|
}
|
||||||
&DllName, Length);
|
else
|
||||||
}
|
{
|
||||||
|
|
||||||
|
if (ShowSnaps)
|
||||||
|
{
|
||||||
|
DPRINT1("LDR: LdrpCheckForLoadedDll - Unable To Locate %wZ: 0x%08x\n",
|
||||||
|
&DllName, Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Full dll name is found */
|
/* Return failure */
|
||||||
FullDllName.Length = Length;
|
return FALSE;
|
||||||
FullDllName.MaximumLength = FullDllName.Length + sizeof(UNICODE_NULL);
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wc++;
|
/* Full dll name is found */
|
||||||
|
FullDllName.Length = Length;
|
||||||
|
FullDllName.MaximumLength = FullDllName.Length + sizeof(UNICODE_NULL);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wc++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Go check the hash table */
|
/* Go check the hash table */
|
||||||
|
|
|
@ -642,133 +642,6 @@ RtlPcToFileHeader(IN PVOID PcValue,
|
||||||
return ImageBase;
|
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
|
* @unimplemented
|
||||||
*/
|
*/
|
||||||
|
@ -785,101 +658,7 @@ RtlDosApplyFileIsolationRedirection_Ustr(IN ULONG Flags,
|
||||||
IN PSIZE_T FileNameSize,
|
IN PSIZE_T FileNameSize,
|
||||||
IN PSIZE_T RequiredLength)
|
IN PSIZE_T RequiredLength)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
return STATUS_SXS_KEY_NOT_FOUND;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in a new issue