On Sat Apr 8 12:22:23 2023 +0000, Nikolay Sivov wrote:
> As I recall, for original fix to accept a range of resource IDs the
> question was how are those different from each other, meaning if there
> are multiple resources, when one should be used but not another.
From Micrsoft documentation, [Using Side-by-Side Assemblies as a Resource][sxs-rsrc] outlines the significance of each reserved manifest resource ID.
Further investigation shows the following:
1. `CREATEPROCESS_MANIFEST_RESOURCE_ID` (value: `1`): This is used for process-wide initial (`NULL`) activation context.
- **Usage documentation**: [Enabling an Assembly in an Application Without Extensions](https://learn.microsoft.com/en-us/windows/win32/sbscs/enabling-…
- **Intended container module type**: EXE only.
- **Lifetime**: Alive until the process is terminated. Owned by system (NTDLL).
- **Isolation-aware**: No.
2. `ISOLATIONAWARE_MANIFEST_RESOURCE_ID` (value: `2`): This is used to specify the assembly manifest that the loader (Ldr) uses to resolve static imports. Also, this is used by isolation-aware wrappers defined in `*.inl` files included in the Windows SDK (`include\um`) when the `ISOLATION_AWARE_ENABLED` macro is defined as a nonzero value.
- **Usage documentation**: [Enabling an Assembly in an Application Hosting a DLL, Extension, or Control Panel](https://learn.microsoft.com/en-us/windows/win32/sbscs/enabling-an-as…
- **Intended container module type**: EXE and DLL.
- **Lifetime**: Alive until the module is unloaded (e.g., via `FreeLibrary`). Owned by system (NTDLL).
- **Isolation-aware**: Yes.
3. `ISOLATIONAWARE_NOSTATICIMPORT_MANIFEST_RESOURCE_ID` (value: `3`): Ignored by the loader when resolving static imports. This is used by isolation-aware API wrappers defined in `*.inl` files included in the Windows SDK (`include\um`) when the `ISOLATION_AWARE_ENABLED` macro is defined as a nonzero value.
- **Usage documentation**: [IsolationAwareCleanup function][IsolationAwareCleanup]
- **Intended container module type**: EXE and DLL.
- **Lifetime**: Alive until the application calls [`IsolationAwareCleanup`][IsolationAwareCleanup][^ia-cleanup-note]. Owned by the isolation-aware API wrapper library.
- **Isolation-aware**: Yes.
The `ISOLATION_AWARE_ENABLED` macro is documented in [Isolating Components][sxs-ic] as well as [Specifying a Default Activation Context][sxs-def-actctx]. When `ISOLATION_AWARE_ENABLED` macro is defined as a nonzero value, then the isolation-aware API wrapper library is enabled. The isolation-aware API wrapper library is responsible for:
- Creating (lazily) and destroying activation context (in `IsolationAwareCleanup`), if the manifest resource ID is `ISOLATIONAWARE_NOSTATICIMPORT_MANIFEST_RESOURCE_ID`.[^actctx-lifetime-remark]
- Note: the loader does not manage the activation context's lifetime and delegates the responsibility to the system loader if the manifest resource ID is `ISOLATIONAWARE_MANIFEST_RESOURCE_ID`.
- Intercepting Win32 API calls for automatic activation context activation. Each API wrapper activates the "isolation-aware" activation context (obtaining one if it did not exist) before calling the original procedure, and deactivates it before returning.
The isolation-aware wrappers may be either be defined inline, or compiled into static libraries that are linked to the final application executable.
From the information above, we can infer the following:
1. Although side-by-side awareness is a cross-cutting concern, the *activation* of activation contexts itself is *not* usually performed automatically by the system (with the sole exception of process-wide activation context associated with `CREATEPROCESS_MANIFEST_RESOURCE_ID`).
2. `ISOLATIONAWARE_NOSTATICIMPORT_MANIFEST_RESOURCE_ID` is treated like any other resource ID as far as the loader is concerned.
3. The resource ID of the manifest only concerns how the module containing the manifest intends to use the manifest. In fact, for DLLs that do not *statically* import symbols from side-by-side assemblies, the three resource IDs above are basically equivalent. A DLL can elect not to use manifest resources at all, and manage activation context and library loading by itself.
This is why I believe that this merge request is sufficient in completing the isolation-aware component support in Wine; the heavy lifting is done by the application side, not the system.
---
[^ia-cleanup-note]: According to the documentation, the application is presumably responsible for calling `IsolationAwareCleanup` from `DllMain` on `fdwReason = DLL_PROCESS_DETACH`.
[^actctx-lifetime-remark]: [IsolationAwareCleanup § Remarks](https://learn.microsoft.com/en-us/previous-versions/windows/deskto…, from Microsoft documentation.
[sxs-rsrc]: https://learn.microsoft.com/en-us/windows/win32/sbscs/using-side-by-side-as…
[IsolationAwareCleanup]: https://learn.microsoft.com/en-us/previous-versions/windows/desktop/legacy/…
[sxs-ic]: https://learn.microsoft.com/en-us/windows/win32/sbscs/isolating-components
[sxs-def-actctx]: https://learn.microsoft.com/en-us/windows/win32/sbscs/specifying-a-default-…
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/2555#note_29410
Today, the test scenario "ACTCTX_FLAG_HMODULE_VALID but hModule if not
set" is broken and unreliable. This problem is not evident in WineHQ
batch test runs; rather, the test failure seems to only be triggered
when the kernel32:actctx test is run in isolation.
When the flag ACTCTX_FLAG_HMODULE_VALID is specified in ACTCTX but
hModule is set to NULL, CreateActCtxW() may encounter different failure
modes depending on the environment and/or the test executable file.
Error codes observed so far include ERROR_SXS_CANT_GEN_ACTCTX and
ERROR_SXS_MANIFEST_TOO_BIG.
It appears that the inconsistent failure was caused by Windows trying to
interpret the main executable file of the current process as an XML
manifest file. This fails for the following reasons:
- A valid PE executable that starts with the "MZ" signature is not a
valid XML file.
- The test executable's size exceeds the limit imposed by the manifest
parser. This is much more likely for binaries with debugging symbols.
Meanwhile, winetest bundles a stripped version of the test executable
(kernel32_test-stripped.exe), which may end up masking the problem.
Fix this by changing the FullDllName of the main executable module's
LDR_DATA_TABLE_ENTRY to the pathname of a temporary manifest file (valid
or invalid) before testing. The testing is performed in a child
process, since it deliberately "corrupts" the process state.
--
v3: kernel32/tests: Fix test for ACTCTX_FLAG_HMODULE_VALID with hModule = NULL case.
https://gitlab.winehq.org/wine/wine/-/merge_requests/2617
Today, the test scenario "ACTCTX_FLAG_HMODULE_VALID but hModule if not
set" is broken and unreliable. This problem is not evident in WineHQ
batch test runs; rather, the test failure seems to only be triggered
when the kernel32:actctx test is run in isolation.
When the flag ACTCTX_FLAG_HMODULE_VALID is specified in ACTCTX but
hModule is set to NULL, CreateActCtxW() may encounter different failure
modes depending on the environment and/or the test executable file.
Error codes observed so far include ERROR_SXS_CANT_GEN_ACTCTX and
ERROR_SXS_MANIFEST_TOO_BIG.
It appears that the inconsistent failure was caused by Windows trying to
interpret the main executable file of the current process as an XML
manifest file. Note that a valid PE executable that starts with the
"MZ" signature is not a valid XML file; furthermore, the test executable
may simply be too large for a single manifest file.
Fix this by changing the FullDllName of the main executable module's
LDR_DATA_TABLE_ENTRY to the pathname of a temporary manifest file (valid
or invalid) before testing. The testing is performed in a child
process, since it deliberately "corrupts" the process state.
--
Notes:
- Deleting the temporary file should be done by the `create_temp_manifest_file`
--
v2: kernel32/tests: Fix test for ACTCTX_FLAG_HMODULE_VALID with hModule = NULL case.
https://gitlab.winehq.org/wine/wine/-/merge_requests/2617
Today, the test scenario "ACTCTX_FLAG_HMODULE_VALID but hModule if not
set" is broken and unreliable. This problem is not evident in WineHQ
batch test runs; rather, the test failure seems to only be triggered
when the kernel32:actctx test is run in isolation.
When the flag ACTCTX_FLAG_HMODULE_VALID is specified in ACTCTX but
hModule is set to NULL, CreateActCtxW() may encounter different failure
modes depending on the environment and/or the test executable file.
Error codes observed so far include ERROR_SXS_CANT_GEN_ACTCTX and
ERROR_SXS_MANIFEST_TOO_BIG.
It appears that the inconsistent failure was caused by Windows trying to
interpret the main executable file of the current process as an XML
manifest file. Note that a valid PE executable that starts with the
"MZ" signature is not a valid XML file; furthermore, the test executable
may simply be too large for a single manifest file.
Fix this by changing the FullDllName of the main executable module's
LDR_DATA_TABLE_ENTRY to the pathname of a temporary manifest file (valid
or invalid) before testing. The testing is performed in a child
process, since it deliberately "corrupts" the process state.
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/2617
The last patch is a huge optimization to what is done in patch 2. Without that the sample is first copied from GPU to CPU each time wg_transform_read_mf() locks the buffer (allocating extra linear buffer on the way) and then copies the data back to GPU. That happens even if there is no sample available from wg_transform. With the last patch there is just one memory copy to the (write-only) locked DXGI surface buffer. And CPU to GPU texture transfer (which would be there anyway in most cases on software path as most of the apps are going to get the image to GPU anyway). In principle we could also skip the explicit staging texture and use _UpdateSubresource instead directly from h264 decoder, but this is currently not supported in wined3d for chroma formats and the overall difference between _UpdateSubresource and explicit mapped staging texture is not that great probably.
--
v6: winegstreamer: Pass temporary sample to wg_transform_read_mf() in h264 decoder.
winegstreamer: Provide samples if DXGI device manager is set in h264 decoder.
winegstreamer: Process MFT_MESSAGE_SET_D3D_MANAGER in h264 decoder.
mf/tests: Test h264 decoder with dxgi device manager.
https://gitlab.winehq.org/wine/wine/-/merge_requests/2587
The last patch is a huge optimization to what is done in patch 2. Without that the sample is first copied from GPU to CPU each time wg_transform_read_mf() locks the buffer (allocating extra linear buffer on the way) and then copies the data back to GPU. That happens even if there is no sample available from wg_transform. With the last patch there is just one memory copy to the (write-only) locked DXGI surface buffer. And CPU to GPU texture transfer (which would be there anyway in most cases on software path as most of the apps are going to get the image to GPU anyway). In principle we could also skip the explicit staging texture and use _UpdateSubresource instead directly from h264 decoder, but this is currently not supported in wined3d for chroma formats and the overall difference between _UpdateSubresource and explicit mapped staging texture is not that great probably.
--
v5: winegstreamer: Pass temporary sample to wg_transform_read_mf() in h264 decoder.
winegstreamer: Provide samples if DXGI device manager is set in h264 decoder.
winegstreamer: Process MFT_MESSAGE_SET_D3D_MANAGER in h264 decoder.
mf/tests: Test h264 decoder with dxgi device manager.
mf/tests: Increase h264data.bin video length.
https://gitlab.winehq.org/wine/wine/-/merge_requests/2587