boot/bootdata/packages/reactos.dff.in | 4 +
dll/ntdll/ldr/ldrpe.c | 91 ++--
dll/ntdll/ldr/ldrutils.c | 471 +++++++++++----------
dll/ntdll/rtl/libsupp.c | 233 +++++++++-
dll/win32/comctl32/CMakeLists.txt | 6 +-
dll/win32/comctl32/comctl32.manifest | 33 --
dll/win32/comctl32/comctl32v5.manifest | 33 --
dll/win32/comctl32/commctrl.c | 2 +-
dll/win32/comctl32/rsrc.rc | 4 -
modules/rostests/apitests/ntdll/CMakeLists.txt | 1 +
.../RtlDosApplyFileIsolationRedirection_Ustr.c | 273 +++++++++++-
sdk/cmake/CMakeMacros.cmake | 8 +
sdk/lib/rtl/actctx.c | 3 +-
13 files changed, 806 insertions(+), 356 deletions(-)
diff --git a/boot/bootdata/packages/reactos.dff.in b/boot/bootdata/packages/reactos.dff.in
index 4382637..24a5138 100644
--- a/boot/bootdata/packages/reactos.dff.in
+++ b/boot/bootdata/packages/reactos.dff.in
@@ -70,6 +70,10 @@ Signature = "$ReactOS$"
51 = system32\CatRoot
52 = system32\CatRoot2
53 = AppPatch
+54 = winsxs
+55 = winsxs\manifests
+56 = winsxs\x86_microsoft.windows.common-controls_6595b64144ccf1df_5.82.2600.2982_none_deadbeef
+57 = winsxs\x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.2600.2982_none_deadbeef
.InfEnd
diff --git a/dll/ntdll/ldr/ldrpe.c b/dll/ntdll/ldr/ldrpe.c
index 10d128f..2fceeb3 100644
--- a/dll/ntdll/ldr/ldrpe.c
+++ b/dll/ntdll/ldr/ldrpe.c
@@ -815,7 +815,6 @@ LdrpWalkImportDescriptor(IN LPWSTR DllPath OPTIONAL,
return Status;
}
-/* FIXME: This function is missing SxS support */
NTSTATUS
NTAPI
LdrpLoadImportModule(IN PWSTR DllPath OPTIONAL,
@@ -831,9 +830,14 @@ 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);
@@ -883,76 +887,57 @@ 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 */
+ goto done;
+ }
+
/* Check if it's loaded */
if (LdrpCheckForLoadedDll(DllPath,
ImpDescName,
TRUE,
- FALSE,
+ RedirectedDll,
DataTableEntry))
{
/* It's already existing in the list */
*Existing = TRUE;
- return STATUS_SUCCESS;
+ Status = STATUS_SUCCESS;
+ goto done;
}
/* 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,
- FALSE,
+ RedirectedDll,
DataTableEntry);
-
- if (!NT_SUCCESS(Status)) return Status;
+ if (!NT_SUCCESS(Status))
+ {
+ goto done;
+ }
/* Walk its import descriptor table */
Status = LdrpWalkImportDescriptor(DllPath,
@@ -964,6 +949,10 @@ done:
&(*DataTableEntry)->InInitializationOrderLinks);
}
+done:
+ /* Do we have a redirect string? */
+ RtlFreeUnicodeString(&RedirectedImpDescName);
+
return Status;
}
diff --git a/dll/ntdll/ldr/ldrutils.c b/dll/ntdll/ldr/ldrutils.c
index d960c7f..040d4c3 100644
--- a/dll/ntdll/ldr/ldrutils.c
+++ b/dll/ntdll/ldr/ldrutils.c
@@ -28,101 +28,6 @@ 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,
@@ -214,19 +119,30 @@ LdrpUpdateLoadCount3(IN PLDR_DATA_TABLE_ENTRY LdrEntry,
PIMAGE_IMPORT_DESCRIPTOR ImportEntry;
PIMAGE_THUNK_DATA FirstThunk;
PLDR_DATA_TABLE_ENTRY Entry;
- PUNICODE_STRING ImportNameUnic;
+ PUNICODE_STRING ImportNameUnic, RedirectedImportName;
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)
- return;
+ goto done;
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 */
if (LdrEntry->Flags & LDRP_UNLOAD_IN_PROGRESS)
- return;
+ goto done;
LdrEntry->Flags |= LDRP_UNLOAD_IN_PROGRESS;
}
@@ -267,54 +183,38 @@ LdrpUpdateLoadCount3(IN PLDR_DATA_TABLE_ENTRY LdrEntry,
if (NT_SUCCESS(Status))
{
- if (LdrpCheckForLoadedDll(NULL,
- ImportNameUnic,
- TRUE,
- FALSE,
- &Entry))
+ 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 (Entry->LoadCount != 0xFFFF)
+ /* Let Ldrp know */
+ if (ShowSnaps)
{
- /* 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);
- }
+ DPRINT1("LDR: %Z got redirected to %wZ\n", &ImportNameAnsi, RedirectedImportName);
}
- /* Recurse into this entry */
- LdrpUpdateLoadCount3(Entry, Flags, UpdateString);
+ RedirectedDll = TRUE;
}
- }
- /* 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 (RedirectedDll || Status == STATUS_SXS_KEY_NOT_FOUND)
{
if (LdrpCheckForLoadedDll(NULL,
- ImportNameUnic,
+ RedirectedImportName,
TRUE,
- FALSE,
+ RedirectedDll,
&Entry))
{
if (Entry->LoadCount != 0xFFFF)
@@ -336,13 +236,105 @@ LdrpUpdateLoadCount3(IN PLDR_DATA_TABLE_ENTRY LdrEntry,
/* Show snaps */
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 */
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 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 for redirected dll %wZ\n", RedirectedImportName);
+ }
+ }
+ else
+ {
+ /* Unrecoverable SxS failure */
+ DPRINT1("LDR: RtlDosApplyFileIsolationRedirection_Ustr failed for dll %wZ\n", ImportNameUnic);
+ }
+
}
NewImportForwarder++;
@@ -352,7 +344,7 @@ LdrpUpdateLoadCount3(IN PLDR_DATA_TABLE_ENTRY LdrEntry,
}
/* We're done */
- return;
+ goto done;
}
/* Check oldstyle import descriptor */
@@ -380,44 +372,87 @@ LdrpUpdateLoadCount3(IN PLDR_DATA_TABLE_ENTRY LdrEntry,
Status = RtlAnsiStringToUnicodeString(ImportNameUnic, &ImportNameAnsi, FALSE);
if (NT_SUCCESS(Status))
{
- if (LdrpCheckForLoadedDll(NULL,
- ImportNameUnic,
- TRUE,
- FALSE,
- &Entry))
+ 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 (Entry->LoadCount != 0xFFFF)
+ if (ShowSnaps)
{
- /* 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;
- }
+ DPRINT1("LDR: %Z got redirected to %wZ\n", &ImportNameAnsi, RedirectedImportName);
+ }
- /* Show snaps */
- if (ShowSnaps)
+ /* Let Ldrp know */
+ RedirectedDll = TRUE;
+ }
+
+ if (RedirectedDll || Status == STATUS_SXS_KEY_NOT_FOUND)
+ {
+ if (LdrpCheckForLoadedDll(NULL,
+ RedirectedImportName,
+ TRUE,
+ RedirectedDll,
+ &Entry))
+ {
+ if (Entry->LoadCount != 0xFFFF)
{
- DPRINT1("LDR: Flags %lu %wZ (%lx)\n", Flags, ImportNameUnic, Entry->LoadCount);
+ /* 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);
}
- /* 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
@@ -665,7 +700,6 @@ 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));
@@ -680,25 +714,14 @@ LdrpResolveDllName(PWSTR DllPath,
if (!Length || Length > BufSize)
{
- /* HACK: Try to find active context dll */
- Status = find_actctx_dll(DllName, FullDllName->Buffer);
- if(Status == STATUS_SUCCESS)
+ if (ShowSnaps)
{
- Length = wcslen(FullDllName->Buffer) * sizeof(WCHAR);
- DPRINT1("found %S for %S\n", FullDllName->Buffer, DllName);
+ DPRINT1("LDR: LdrResolveDllName - Unable to find ");
+ 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);
- return FALSE;
- }
+ RtlFreeUnicodeString(FullDllName);
+ return FALSE;
}
/* Construct full DLL name */
@@ -1038,7 +1061,7 @@ LdrpMapDll(IN PWSTR SearchPath OPTIONAL,
}
/* Check if we have a known dll directory */
- if (LdrpKnownDllObjectDirectory)
+ if (LdrpKnownDllObjectDirectory && Redirect == FALSE)
{
/* Check if the path is full */
while (*p1)
@@ -1977,8 +2000,10 @@ LdrpCheckForLoadedDll(IN PWSTR DllPath,
/* Look in the hash table if flag was set */
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 */
HashIndex = LDR_GET_HASH_ENTRY(DllName->Buffer[0]);
@@ -2006,58 +2031,54 @@ lookinhash:
return FALSE;
}
- /* Check if there is a full path in this DLL */
- wc = DllName->Buffer;
- while (*wc)
+ /* Check if this is a redirected DLL */
+ if (RedirectedDll)
{
- /* Check for a slash in the current position*/
- if ((*wc == L'\\') || (*wc == L'/'))
+ /* 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)
{
- /* 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))))
+ /* Check for a slash in the current position*/
+ if ((*wc == L'\\') || (*wc == L'/'))
{
- /* HACK: Try to find active context dll */
- Status = find_actctx_dll(DllName->Buffer, FullDllName.Buffer);
- if(Status == STATUS_SUCCESS)
+ /* 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))))
{
- 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);
+ if (ShowSnaps)
+ {
+ DPRINT1("LDR: LdrpCheckForLoadedDll - Unable To Locate %wZ: 0x%08x\n",
+ &DllName, Length);
+ }
}
- /* Return failure */
- return FALSE;
- }
+ /* Full dll name is found */
+ FullDllName.Length = Length;
+ FullDllName.MaximumLength = FullDllName.Length + sizeof(UNICODE_NULL);
+ break;
}
- /* Full dll name is found */
- FullDllName.Length = Length;
- FullDllName.MaximumLength = FullDllName.Length + sizeof(UNICODE_NULL);
- break;
+ wc++;
}
-
- wc++;
}
/* Go check the hash table */
diff --git a/dll/ntdll/rtl/libsupp.c b/dll/ntdll/rtl/libsupp.c
index 08a26cc..edc6965 100644
--- a/dll/ntdll/rtl/libsupp.c
+++ b/dll/ntdll/rtl/libsupp.c
@@ -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,111 @@ 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;
+
+ /* 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);
+ if (!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+
+ //if (!RtlDoesFileExists_U(fullname))
+ //{
+ // if (StaticString && StaticString->Buffer != fullname)
+ // {
+ // RtlFreeHeap( RtlGetProcessHeap(), 0, fullname );
+ // }
+
+ // return STATUS_SXS_KEY_NOT_FOUND;
+ //}
+
+ DPRINT1("Redirecting %wZ to %S\n", OriginalName, fullname);
+
+ if (!StaticString || StaticString->Buffer != fullname)
+ {
+ RtlInitUnicodeString(DynamicString, fullname);
+ *NewName = DynamicString;
+ }
+ else
+ {
+ *NewName = StaticString;
+ }
+
+ return Status;
}
/*
diff --git a/dll/win32/comctl32/CMakeLists.txt b/dll/win32/comctl32/CMakeLists.txt
index 1b55c5d..9285001 100644
--- a/dll/win32/comctl32/CMakeLists.txt
+++ b/dll/win32/comctl32/CMakeLists.txt
@@ -64,5 +64,7 @@ add_delay_importlibs(comctl32 winmm uxtheme)
add_importlibs(comctl32 user32 gdi32 advapi32 msvcrt kernel32 ntdll)
add_pch(comctl32 comctl32.h SOURCE)
add_cd_file(TARGET comctl32 DESTINATION reactos/system32 FOR all)
-add_cd_file(FILE ${CMAKE_CURRENT_SOURCE_DIR}/comctl32v5.manifest DESTINATION reactos/winsxs/manifests NAME_ON_CD x86_microsoft.windows.common-controls_6595b64144ccf1df_5.82.2600.2982_none_deadbeef.manifest FOR livecd)
-add_cd_file(FILE ${CMAKE_CURRENT_SOURCE_DIR}/comctl32.manifest DESTINATION reactos/winsxs/manifests NAME_ON_CD x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.2600.2982_none_deadbeef.manifest FOR livecd)
\ No newline at end of file
+add_cd_file(TARGET comctl32 DESTINATION reactos/winsxs/x86_microsoft.windows.common-controls_6595b64144ccf1df_5.82.2600.2982_none_deadbeef FOR all)
+add_cd_file(TARGET comctl32 DESTINATION reactos/winsxs/x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.2600.2982_none_deadbeef FOR all)
+add_cd_file(FILE ${CMAKE_CURRENT_SOURCE_DIR}/x86_microsoft.windows.common-controls_6595b64144ccf1df_5.82.2600.2982_none_deadbeef.manifest DESTINATION reactos/winsxs/manifests FOR all)
+add_cd_file(FILE ${CMAKE_CURRENT_SOURCE_DIR}/x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.2600.2982_none_deadbeef.manifest DESTINATION reactos/winsxs/manifests FOR all)
\ No newline at end of file
diff --git a/dll/win32/comctl32/comctl32.manifest b/dll/win32/comctl32/comctl32.manifest
deleted file mode 100644
index 1d82715..0000000
--- a/dll/win32/comctl32/comctl32.manifest
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
-
-
- Button
- ButtonListBox
- ComboBoxEx32
- ComboLBox
- Combobox
- Edit
- Listbox
- NativeFontCtl
- ReBarWindow32
- ScrollBar
- SysAnimate32
- SysDateTimePick32
- SysHeader32
- SysIPAddress32
- SysLink
- SysListView32
- SysMonthCal32
- SysPager
- SysTabControl32
- SysTreeView32
- ToolbarWindow32
- msctls_hotkey32
- msctls_progress32
- msctls_statusbar32
- msctls_trackbar32
- msctls_updown32
- tooltips_class32
-
-
diff --git a/dll/win32/comctl32/comctl32v5.manifest b/dll/win32/comctl32/comctl32v5.manifest
deleted file mode 100644
index 480451a..0000000
--- a/dll/win32/comctl32/comctl32v5.manifest
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
-
-
- Button
- ButtonListBox
- ComboBoxEx32
- ComboLBox
- Combobox
- Edit
- Listbox
- NativeFontCtl
- ReBarWindow32
- ScrollBar
- SysAnimate32
- SysDateTimePick32
- SysHeader32
- SysIPAddress32
- SysLink
- SysListView32
- SysMonthCal32
- SysPager
- SysTabControl32
- SysTreeView32
- ToolbarWindow32
- msctls_hotkey32
- msctls_progress32
- msctls_statusbar32
- msctls_trackbar32
- msctls_updown32
- tooltips_class32
-
-
diff --git a/dll/win32/comctl32/commctrl.c b/dll/win32/comctl32/commctrl.c
index e091ccc..b3235c7 100644
--- a/dll/win32/comctl32/commctrl.c
+++ b/dll/win32/comctl32/commctrl.c
@@ -1179,7 +1179,7 @@ HRESULT WINAPI DllInstall(BOOL bInstall, LPCWSTR cmdline)
{
TRACE("(%u, %s): stub\n", bInstall, debugstr_w(cmdline));
-#ifdef __REACTOS__
+#if 0
if (!create_manifest(bInstall, TRUE))
{
diff --git a/dll/win32/comctl32/rsrc.rc b/dll/win32/comctl32/rsrc.rc
index 0fb8289..e0a9376 100644
--- a/dll/win32/comctl32/rsrc.rc
+++ b/dll/win32/comctl32/rsrc.rc
@@ -36,10 +36,6 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
#include "wine/wine_common_ver.rc"
-/* @makedep: comctl32.manifest */
-WINE_MANIFEST RT_MANIFEST comctl32.manifest
-WINE_MANIFESTV5 RT_MANIFEST comctl32v5.manifest
-
/* @makedep: idt_check.bmp */
IDT_CHECK BITMAP idt_check.bmp
diff --git a/modules/rostests/apitests/ntdll/CMakeLists.txt b/modules/rostests/apitests/ntdll/CMakeLists.txt
index 7a56d74..5a09cf7 100644
--- a/modules/rostests/apitests/ntdll/CMakeLists.txt
+++ b/modules/rostests/apitests/ntdll/CMakeLists.txt
@@ -75,3 +75,4 @@ add_rostests_file(TARGET ntdll_apitest SUBDIR testdata)
add_rostests_file(FILE "${CMAKE_CURRENT_SOURCE_DIR}/ntdll_apitest.exe.local" SUBDIR testdata)
add_rostests_file(FILE "${CMAKE_CURRENT_SOURCE_DIR}/shell32.dll" SUBDIR testdata)
add_rostests_file(FILE "${CMAKE_CURRENT_SOURCE_DIR}/test.dll" SUBDIR testdata)
+add_rostests_file(FILE "${CMAKE_CURRENT_SOURCE_DIR}/ntdlltest.manifest" SUBDIR testdata)
diff --git a/modules/rostests/apitests/ntdll/RtlDosApplyFileIsolationRedirection_Ustr.c b/modules/rostests/apitests/ntdll/RtlDosApplyFileIsolationRedirection_Ustr.c
index 9a77f04..222da6a 100644
--- a/modules/rostests/apitests/ntdll/RtlDosApplyFileIsolationRedirection_Ustr.c
+++ b/modules/rostests/apitests/ntdll/RtlDosApplyFileIsolationRedirection_Ustr.c
@@ -36,6 +36,11 @@ struct test_data Tests[] =
{__LINE__, STATUS_SUCCESS, L"COMCTL32.DLL", L"\\winsxs\\x86_microsoft.windows.common-controls_6595b64144ccf1df_5.82"},
{__LINE__, STATUS_SUCCESS, L"comctl32.DLL", L"\\winsxs\\x86_microsoft.windows.common-controls_6595b64144ccf1df_5.82"},
{__LINE__, STATUS_SUCCESS, L"c:\\windows\\system32\\comctl32.DLL", L"\\winsxs\\x86_microsoft.windows.common-controls_6595b64144ccf1df_5.82"},
+ /* Files defined in the manifest, one exists, one doesn't */
+ {__LINE__, STATUS_SUCCESS, L"deptest.dll", EXPECT_IN_SAME_DIR},
+ {__LINE__, STATUS_SUCCESS, L"adllfile.dll", EXPECT_IN_SAME_DIR},
+ /* A file that exists in the same dir but isn't mentioned in the manifest */
+ {__LINE__, STATUS_SUCCESS, L"fil1.txt", EXPECT_IN_SAME_DIR},
/* This is a weird case; the source doesn't exist but does get redirected */
{__LINE__, STATUS_SUCCESS, L"c:\\windows\\system32\\gdiplus.DLL", L"\\winsxs\\x86_microsoft.windows.gdiplus_6595b64144ccf1df_1."},
/* But redirecting gdiplus from a different directory doesn't work */
@@ -51,6 +56,28 @@ struct test_data Tests[] =
{__LINE__, STATUS_SUCCESS, L"c:\\shell32.dll", EXPECT_IN_SAME_DIR}
};
+HANDLE _CreateActCtxFromFile(LPCWSTR FileName, int line)
+{
+ ACTCTXW ActCtx = {sizeof(ACTCTX)};
+ HANDLE h;
+ WCHAR buffer[MAX_PATH] , *separator;
+
+ ok (GetModuleFileNameW(NULL, buffer, MAX_PATH), "GetModuleFileName failed\n");
+ separator = wcsrchr(buffer, L'\\');
+ if (separator)
+ wcscpy(separator + 1, FileName);
+
+ ActCtx.lpSource = buffer;
+
+ SetLastError(0xdeaddead);
+ h = CreateActCtxW(&ActCtx);
+ ok_(__FILE__, line)(h != INVALID_HANDLE_VALUE, "CreateActCtx failed for %S\n", FileName);
+ // In win10 last error is unchanged and in win2k3 it is ERROR_BAD_EXE_FORMAT
+ ok_(__FILE__, line)(GetLastError() == ERROR_BAD_EXE_FORMAT || GetLastError() == 0xdeaddead, "Wrong last error %lu\n", GetLastError());
+
+ return h;
+}
+
void TestRedirection(void)
{
WCHAR SystemDir[MAX_PATH];
@@ -95,11 +122,11 @@ void TestRedirection(void)
NULL);
ok(Status == Tests[i].ExpectedStatus, "%d: Status 0x%lx, expected 0x%lx\n", Tests[i].testline, Status, Tests[i].ExpectedStatus);
- if (DynamicString.Buffer)
- {
- BOOL exists = RtlDoesFileExists_U(DynamicString.Buffer);
- ok(exists, "%d: Expected file %S to exist!\n", Tests[i].testline, DynamicString.Buffer);
- }
+ //if (DynamicString.Buffer)
+ //{
+ // BOOL exists = RtlDoesFileExists_U(DynamicString.Buffer);
+ // ok(exists, "%d: Expected file %S to exist!\n", Tests[i].testline, DynamicString.Buffer);
+ //}
if(Tests[i].ExpectedSubString && DynamicString.Buffer == NULL)
{
@@ -121,6 +148,231 @@ void TestRedirection(void)
}
}
+void TestBuffers()
+{
+ UNICODE_STRING Param, DynamicString, StaticString;
+ PUNICODE_STRING StringUsed = NULL;
+ NTSTATUS Status;
+ WCHAR buffer[MAX_PATH];
+
+ RtlInitEmptyUnicodeString(&DynamicString, NULL, 0);
+ Status = RtlDosApplyFileIsolationRedirection_Ustr(TRUE,
+ NULL,
+ NULL,
+ NULL,
+ &DynamicString,
+ &StringUsed,
+ NULL,
+ NULL,
+ NULL);
+ ok(Status ==STATUS_INVALID_PARAMETER, "0x%x\n", Status);
+
+ RtlInitEmptyUnicodeString(&Param, NULL, 0);
+ RtlInitEmptyUnicodeString(&DynamicString, NULL, 0);
+ Status = RtlDosApplyFileIsolationRedirection_Ustr(TRUE,
+ &Param,
+ NULL,
+ NULL,
+ &DynamicString,
+ &StringUsed,
+ NULL,
+ NULL,
+ NULL);
+ ok(Status ==STATUS_SXS_KEY_NOT_FOUND, "0x%x\n", Status);
+
+ /* Tests for NULL termination of OriginalName */
+ Param.MaximumLength = Param.Length = 12 * sizeof(WCHAR);
+ Param.Buffer = L"comctl32.dllcrapcrap";
+ RtlInitEmptyUnicodeString(&DynamicString, NULL, 0);
+ Status = RtlDosApplyFileIsolationRedirection_Ustr(TRUE,
+ &Param,
+ NULL,
+ NULL,
+ &DynamicString,
+ &StringUsed,
+ NULL,
+ NULL,
+ NULL);
+ ok(Status ==STATUS_SUCCESS, "\n");
+
+ /* Tests for the Extension parameter */
+ RtlInitUnicodeString(&Param, L"comctl32.dll");
+ RtlInitEmptyUnicodeString(&DynamicString, NULL, 0);
+ Status = RtlDosApplyFileIsolationRedirection_Ustr(TRUE,
+ &Param,
+ NULL,
+ NULL,
+ &DynamicString,
+ &StringUsed,
+ NULL,
+ NULL,
+ NULL);
+ ok(Status ==STATUS_SUCCESS, "\n");
+
+ RtlInitUnicodeString(&Param, L"comctl32");
+ RtlInitEmptyUnicodeString(&DynamicString, NULL, 0);
+ Status = RtlDosApplyFileIsolationRedirection_Ustr(TRUE,
+ &Param,
+ NULL,
+ NULL,
+ &DynamicString,
+ &StringUsed,
+ NULL,
+ NULL,
+ NULL);
+ ok(Status ==STATUS_SXS_KEY_NOT_FOUND, "0x%x\n", Status);
+
+ RtlInitUnicodeString(&Param, L"comctl32");
+ RtlInitEmptyUnicodeString(&DynamicString, NULL, 0);
+ Status = RtlDosApplyFileIsolationRedirection_Ustr(TRUE,
+ &Param,
+ &DotDll,
+ NULL,
+ &DynamicString,
+ &StringUsed,
+ NULL,
+ NULL,
+ NULL);
+ ok(Status ==STATUS_SUCCESS, "\n");
+
+ /* Tests for the DynamicString parameter */
+ RtlInitUnicodeString(&Param, L"comctl32.dll");
+ RtlInitEmptyUnicodeString(&DynamicString, NULL, 0);
+ Status = RtlDosApplyFileIsolationRedirection_Ustr(TRUE,
+ &Param,
+ NULL,
+ NULL,
+ &DynamicString,
+ &StringUsed,
+ NULL,
+ NULL,
+ NULL);
+ ok(Status ==STATUS_SUCCESS, "\n");
+ ok(DynamicString.Length >0 , "\n");
+ ok(DynamicString.MaximumLength == DynamicString.Length + sizeof(WCHAR) , "\n");
+ if (DynamicString.Buffer && DynamicString.Length)
+ ok(wcslen(DynamicString.Buffer) * sizeof(WCHAR) == DynamicString.Length, "got %d and %d\n", wcslen(DynamicString.Buffer) * sizeof(WCHAR) , DynamicString.Length);
+ else
+ ok(DynamicString.Buffer != NULL, "Expected non NULL buffer\n");
+ ok(StringUsed == &DynamicString, "\n");
+
+ /* Tests for the StaticString parameter */
+ wcscpy(buffer, L"comctl32.dll");
+ StaticString.Buffer = buffer;
+ StaticString.Length = sizeof(L"comctl32.dll");
+ StaticString.MaximumLength = sizeof(buffer);
+ Param = StaticString;
+ Status = RtlDosApplyFileIsolationRedirection_Ustr(TRUE,
+ &Param,
+ NULL,
+ &StaticString,
+ NULL,
+ &StringUsed,
+ NULL,
+ NULL,
+ NULL);
+ ok(Status ==STATUS_SXS_KEY_NOT_FOUND, "0x%x\n", Status);
+
+ wcscpy(buffer, L"comctl32.dll");
+ StaticString.Buffer = buffer;
+ StaticString.Length = sizeof(L"comctl32.dll");
+ StaticString.MaximumLength = sizeof(buffer);
+ Status = RtlDosApplyFileIsolationRedirection_Ustr(TRUE,
+ &StaticString,
+ NULL,
+ &StaticString,
+ NULL,
+ &StringUsed,
+ NULL,
+ NULL,
+ NULL);
+ ok(Status ==STATUS_SXS_KEY_NOT_FOUND, "0x%x\n", Status);
+
+ RtlInitUnicodeString(&Param, L"comctl32.dll");
+ RtlInitEmptyUnicodeString(&StaticString, buffer, sizeof(buffer));
+ Status = RtlDosApplyFileIsolationRedirection_Ustr(TRUE,
+ &Param,
+ NULL,
+ &StaticString,
+ NULL,
+ &StringUsed,
+ NULL,
+ NULL,
+ NULL);
+ ok(Status ==STATUS_SUCCESS, "\n");
+ ok(StaticString.Length >0 , "\n");
+ ok(StaticString.MaximumLength == sizeof(buffer) , "\n");
+ if (StaticString.Buffer && StaticString.Length)
+ ok(wcslen(StaticString.Buffer) * sizeof(WCHAR) == StaticString.Length, "got %d and %d\n", wcslen(StaticString.Buffer) * sizeof(WCHAR) , StaticString.Length);
+ else
+ ok(StaticString.Length != 0, "Expected non 0 lenght\n");
+ ok(StringUsed == &StaticString, "\n");
+
+ RtlInitEmptyUnicodeString(&StaticString, buffer, 5 * sizeof(WCHAR));
+ Status = RtlDosApplyFileIsolationRedirection_Ustr(TRUE,
+ &Param,
+ NULL,
+ &StaticString,
+ NULL,
+ &StringUsed,
+ NULL,
+ NULL,
+ NULL);
+ ok(Status == STATUS_BUFFER_TOO_SMALL, "0x%x\n", Status);
+
+ RtlInitUnicodeString(&Param, L"comctl32.dll");
+ RtlInitEmptyUnicodeString(&StaticString, buffer, sizeof(buffer));
+ RtlInitEmptyUnicodeString(&DynamicString, NULL, 0);
+ Status = RtlDosApplyFileIsolationRedirection_Ustr(TRUE,
+ &Param,
+ NULL,
+ &StaticString,
+ &DynamicString,
+ &StringUsed,
+ NULL,
+ NULL,
+ NULL);
+ ok(Status ==STATUS_SUCCESS, "\n");
+ ok(StaticString.Length >0 , "\n");
+ ok(StaticString.MaximumLength == sizeof(buffer) , "\n");
+ if (StaticString.Buffer && StaticString.Length)
+ ok(wcslen(StaticString.Buffer) * sizeof(WCHAR) == StaticString.Length, "got %d and %d\n", wcslen(StaticString.Buffer) * sizeof(WCHAR) , StaticString.Length);
+ else
+ ok(StaticString.Length != 0, "Expected non 0 lenght\n");
+ ok(DynamicString.Buffer == NULL, "\n");
+ ok(DynamicString.Length == 0, "\n");
+ ok(DynamicString.MaximumLength == 0, "\n");
+ ok(StringUsed == &StaticString, "\n");
+
+ /* Test a small buffer and a dynamic buffer */
+ RtlInitUnicodeString(&Param, L"comctl32.dll");
+ RtlInitEmptyUnicodeString(&StaticString, buffer, 5 * sizeof(WCHAR));
+ RtlInitEmptyUnicodeString(&DynamicString, NULL, 0);
+ StaticString.Buffer[0] = 1;
+ Status = RtlDosApplyFileIsolationRedirection_Ustr(TRUE,
+ &Param,
+ NULL,
+ &StaticString,
+ &DynamicString,
+ &StringUsed,
+ NULL,
+ NULL,
+ NULL);
+ ok(Status ==STATUS_SUCCESS, "\n");
+ ok(StaticString.Buffer == buffer, "\n");
+ ok(StaticString.Length == 0 , "%d\n", StaticString.Length);
+ ok(StaticString.Buffer[0] == 0, "\n");
+ ok(StaticString.MaximumLength == 5 * sizeof(WCHAR) , "%d\n", StaticString.MaximumLength);
+ ok(DynamicString.Length >0 , "\n");
+ ok(DynamicString.MaximumLength == DynamicString.Length + sizeof(WCHAR) , "\n");
+ if (DynamicString.Buffer && DynamicString.Length)
+ ok(wcslen(DynamicString.Buffer) * sizeof(WCHAR) == DynamicString.Length, "got %d and %d\n", wcslen(DynamicString.Buffer) * sizeof(WCHAR) , DynamicString.Length);
+ else
+ ok(DynamicString.Length != 0, "Expected non 0 lenght\n");
+
+ ok(StringUsed == &DynamicString, "\n");
+}
+
START_TEST(RtlDosApplyFileIsolationRedirection_Ustr)
{
int argc;
@@ -128,7 +380,18 @@ START_TEST(RtlDosApplyFileIsolationRedirection_Ustr)
argc = winetest_get_mainargs( &test_argv );
if (argc >= 3)
{
+ HANDLE h = _CreateActCtxFromFile(L"ntdlltest.manifest", __LINE__);
+ BOOL bactivated = FALSE;
+ ULONG_PTR cookie;
+
+ if (h != INVALID_HANDLE_VALUE)
+ bactivated = ActivateActCtx(h, &cookie);
+
TestRedirection();
+ TestBuffers();
+
+ if (bactivated)
+ DeactivateActCtx(0, cookie);
}
else
{
diff --git a/sdk/cmake/CMakeMacros.cmake b/sdk/cmake/CMakeMacros.cmake
index 850bb7f..a44ac5e 100644
--- a/sdk/cmake/CMakeMacros.cmake
+++ b/sdk/cmake/CMakeMacros.cmake
@@ -269,6 +269,14 @@ macro(dir_to_num dir var)
set(${var} 52)
elseif(${dir} STREQUAL reactos/AppPatch)
set(${var} 53)
+ elseif(${dir} STREQUAL reactos/winsxs)
+ set(${var} 54)
+ elseif(${dir} STREQUAL reactos/winsxs/manifests)
+ set(${var} 55)
+ elseif(${dir} STREQUAL reactos/winsxs/x86_microsoft.windows.common-controls_6595b64144ccf1df_5.82.2600.2982_none_deadbeef)
+ set(${var} 56)
+ elseif(${dir} STREQUAL reactos/winsxs/x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.2600.2982_none_deadbeef)
+ set(${var} 57)
else()
message(FATAL_ERROR "Wrong destination: ${dir}")
endif()
diff --git a/sdk/lib/rtl/actctx.c b/sdk/lib/rtl/actctx.c
index 3768f72..4cf9bba 100644
--- a/sdk/lib/rtl/actctx.c
+++ b/sdk/lib/rtl/actctx.c
@@ -3222,7 +3222,8 @@ static struct string_index *find_string_index(const struct strsection_header *se
{
const WCHAR *nameW = (WCHAR*)((BYTE*)section + iter->name_offset);
- if (!strcmpiW(nameW, name->Buffer))
+ if (!_wcsnicmp(nameW, name->Buffer, name->Length / sizeof(WCHAR)) &&
+ wcslen(nameW) == name->Length / sizeof(WCHAR))
{
index = iter;
break;