mirror of
https://github.com/reactos/reactos.git
synced 2024-06-21 05:21:31 +00:00
[0.4.12] [NTDLL/LDR] Revert the 0.4.12-workaround for comctl32 imagelist
This reverts 0.4.12-RC-2-g
f57e9ed926
and therefore brings the SxS state back to master. It allows many SxS-dependent apps to run again that broke by the new 0.4.12-workaround.
e.g: Miranda 0.10.48
Unfortunately this will expose many issues for the first time in the 0.4.12release (same way like in master),
that I could properly hide in all past releases by a different workaround (that we can not longer use due to heavy 0.4.12-dev SxS works)
This commit reintroduces:
- CORE-14433 MSVCPP 6 installer open-dlg, MS Word Viewer 2003 open-dlg lacks icons
- CORE-15118 OCR CuneiForm 12 lacks icons in the menubar
- CORE-15892 DosBOX 0.74.2 NSIS-installer lacks checkboxes
We think that all those issues are caused by incompatible comctl32 v5/v6 imagelists actually.
If time will allow it, I might experiment with some macros later to hide the comctl32-issue leaving SxS intact.
This commit is contained in:
parent
5ac548544f
commit
fbe1fbe32b
|
@ -642,6 +642,133 @@ 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
|
||||
*/
|
||||
|
@ -658,7 +785,169 @@ RtlDosApplyFileIsolationRedirection_Ustr(IN ULONG Flags,
|
|||
IN PSIZE_T FileNameSize,
|
||||
IN PSIZE_T RequiredLength)
|
||||
{
|
||||
return STATUS_SXS_KEY_NOT_FOUND;
|
||||
NTSTATUS Status;
|
||||
LPWSTR fullname;
|
||||
WCHAR buffer [MAX_PATH];
|
||||
UNICODE_STRING localStr, localStr2, *pstrParam;
|
||||
WCHAR *p;
|
||||
BOOLEAN GotExtension;
|
||||
WCHAR c;
|
||||
C_ASSERT(sizeof(UNICODE_NULL) == sizeof(WCHAR));
|
||||
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
if (NtCurrentPeb()->ProcessParameters &&
|
||||
(NtCurrentPeb()->ProcessParameters->Flags & RTL_USER_PROCESS_PARAMETERS_PRIVATE_DLL_PATH))
|
||||
{
|
||||
UNICODE_STRING RealName, LocalName;
|
||||
WCHAR RealNameBuf[MAX_PATH], LocalNameBuf[MAX_PATH];
|
||||
|
||||
RtlInitEmptyUnicodeString(&RealName, RealNameBuf, sizeof(RealNameBuf));
|
||||
RtlInitEmptyUnicodeString(&LocalName, LocalNameBuf, sizeof(LocalNameBuf));
|
||||
|
||||
Status = RtlComputePrivatizedDllName_U(OriginalName, &RealName, &LocalName);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("RtlComputePrivatizedDllName_U failed for %wZ: 0x%lx\n", OriginalName, Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (RtlDoesFileExists_UStr(&LocalName))
|
||||
{
|
||||
Status = get_buffer(&fullname, LocalName.Length + sizeof(UNICODE_NULL), StaticString, DynamicString != NULL);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
RtlCopyMemory(fullname, LocalName.Buffer, LocalName.Length + sizeof(UNICODE_NULL));
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT1("Error while retrieving buffer for %wZ: 0x%lx\n", OriginalName, Status);
|
||||
}
|
||||
}
|
||||
else if (RtlDoesFileExists_UStr(&RealName))
|
||||
{
|
||||
Status = get_buffer(&fullname, RealName.Length + sizeof(UNICODE_NULL), StaticString, DynamicString != NULL);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
RtlCopyMemory(fullname, RealName.Buffer, RealName.Length + sizeof(UNICODE_NULL));
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT1("Error while retrieving buffer for %wZ: 0x%lx\n", OriginalName, Status);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Status = STATUS_NOT_FOUND;
|
||||
}
|
||||
|
||||
if (RealName.Buffer != RealNameBuf)
|
||||
RtlFreeUnicodeString(&RealName);
|
||||
if (LocalName.Buffer != LocalNameBuf)
|
||||
RtlFreeUnicodeString(&LocalName);
|
||||
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("Redirecting %wZ to %S\n", OriginalName, fullname);
|
||||
if (!StaticString || StaticString->Buffer != fullname)
|
||||
{
|
||||
RtlInitUnicodeString(DynamicString, fullname);
|
||||
*NewName = DynamicString;
|
||||
}
|
||||
else
|
||||
{
|
||||
*NewName = StaticString;
|
||||
}
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
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