Thanks for the patch! Reading and following the instructions at https://wiki.winehq.org/Submitting_Patches will improve the chances of it being accepted.
Please use your real name in the Git commit, for example:
```
git config --global user.name "Your Name"
git commit --amend --reset-author
git push --force
```
Also, drop "See Bug 53960" and "This patch fixes that" from the commit message, wrap the paragraph of explanation to 72 characters per line, and add a new line `Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53960` at the end of the commit message.
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/5752#note_71951
This MR adds support for creating file mapping objects backed by large pages on Linux, by making the following changes:
## wineserver
* On Linux, `create_temp_file` will first attempt to use memfds as the backing fd. If it fails, it'll return to the current codepath, creating a temporary file in either the server or config directory.
* The created memfd will be sealed against writes, if the caller requesting the appropriate page protection flags.
* This removes the requirement that FDs be only created on filesystems/directories that aren't `noexec`.
* In the server method `create_mapping` , if large pages have been requested by the caller, hold that the calling thread's token holds `SeLockMemoryPrivilege` .
* Additionally, add `SeLockMemoryPrivilege` to the list of privileges enabled for the Administrator.
## `ntdll`
* Add `virtual_get_min_large_page_size` and its exported wrapper `wine_unix_get_min_large_page_size`.
* On Linux, the minimum page size is determined by going through `/sys/kernel/mm/hugepages`. If hugepage support was not detected, `STATUS_NOT_SUPPORTED` is returned instead. On other platforms, the older hard-coded value of 2\*1024\*1024 is returned instead.
* `NtCreateSection` will validate certain parameters if large pages are requested. Specifically, it will return STATUS_INVALID_PARAMETER if the requested mapping is not anonymous/unnamed, or the size is not a multiple of the minimum supported page size.
## `kernelbase`
* `GetLargePageMinimum` will use `wine_unix_get_min_large_page_size`.
## `kernel32/tests`
* Add new test test_large_page_file_mapping, which validates privilege enforcements and parameter validation while creating large pages backed file mapping obejcts. The tests are skipped if `GetLargePageMinimum` returns 0.
--
v4: virtual_get_min_large_page_size: initialize min_size to 0
https://gitlab.winehq.org/wine/wine/-/merge_requests/5769
This MR adds support for creating file mapping objects backed by large pages on Linux, by making the following changes:
## wineserver
* On Linux, `create_temp_file` will first attempt to use memfds as the backing fd. If it fails, it'll return to the current codepath, creating a temporary file in either the server or config directory.
* The created memfd will be sealed against writes, if the caller requesting the appropriate page protection flags.
* This removes the requirement that FDs be only created on filesystems/directories that aren't `noexec`.
* In the server method `create_mapping` , if large pages have been requested by the caller, hold that the calling thread's token holds `SeLockMemoryPrivilege` .
* Additionally, add `SeLockMemoryPrivilege` to the list of privileges enabled for the Administrator.
## `ntdll`
* Add `virtual_get_min_large_page_size` and its exported wrapper `wine_unix_get_min_large_page_size`.
* On Linux, the minimum page size is determined by going through `/sys/kernel/mm/hugepages`. If hugepage support was not detected, `STATUS_NOT_SUPPORTED` is returned instead. On other platforms, the older hard-coded value of 2\*1024\*1024 is returned instead.
* `NtCreateSection` will validate certain parameters if large pages are requested. Specifically, it will return STATUS_INVALID_PARAMETER if the requested mapping is not anonymous/unnamed, or the size is not a multiple of the minimum supported page size.
## `kernelbase`
* `GetLargePageMinimum` will use `wine_unix_get_min_large_page_size`.
## `kernel32/tests`
* Add new test test_large_page_file_mapping, which validates privilege enforcements and parameter validation while creating large pages backed file mapping obejcts. The tests are skipped if `GetLargePageMinimum` returns 0.
--
v3: create_memfd: Remove call to file_set_error, create with MFD_EXEC.
Add test_large_page_file_mapping to validate large page support.
NtCreateSection: Validate parameters if large pages are requested.
Check for LockMemoryPrivilege when creating large page mappings.
GetLargePageMinimum: use wine_unix_get_min_large_page_size.
Add functions for determining the minimum supported large page size.
Add SeLockMemoryPrivilege to the list of admin privileges.
create_temp_file: If available, use memfd for backing unnamed files.
https://gitlab.winehq.org/wine/wine/-/merge_requests/5769
This MR adds support for creating file mapping objects backed by large pages on Linux, by making the following changes:
## wineserver
* On Linux, `create_temp_file` will first attempt to use memfds as the backing fd. If it fails, it'll return to the current codepath, creating a temporary file in either the server or config directory.
* The created memfd will be sealed against writes, if the caller requesting the appropriate page protection flags.
* This removes the requirement that FDs be only created on filesystems/directories that aren't `noexec`.
* In the server method `create_mapping` , if large pages have been requested by the caller, hold that the calling thread's token holds `SeLockMemoryPrivilege` .
* Additionally, add `SeLockMemoryPrivilege` to the list of privileges enabled for the Administrator.
## `ntdll`
* Add `virtual_get_min_large_page_size` and its exported wrapper `wine_unix_get_min_large_page_size`.
* On Linux, the minimum page size is determined by going through `/sys/kernel/mm/hugepages`. If hugepage support was not detected, `STATUS_NOT_SUPPORTED` is returned instead. On other platforms, the older hard-coded value of 2\*1024\*1024 is returned instead.
* `NtCreateSection` will validate certain parameters if large pages are requested. Specifically, it will return STATUS_INVALID_PARAMETER if the requested mapping is not anonymous/unnamed, or the size is not a multiple of the minimum supported page size.
## `kernelbase`
* `GetLargePageMinimum` will use `wine_unix_get_min_large_page_size`.
## `kernel32/tests`
* Add new test test_large_page_file_mapping, which validates privilege enforcements and parameter validation while creating large pages backed file mapping obejcts. The tests are skipped if `GetLargePageMinimum` returns 0.
--
v2: create_memfd: Remove call to file_set_error, create with MFD_EXEC.
https://gitlab.winehq.org/wine/wine/-/merge_requests/5769
On Thu May 30 19:34:47 2024 +0000, Gabriel Ivăncescu wrote:
> > There is a difference between C/C++ and JS that we need to cover one
> way or another. C implementation is bound to a specific object type,
> which makes using `impl_from_*` possible. To keep that possibility in
> hooks, they need to be bound to a specific object type as well. More
> idiomatically: hooks are a part of C implementation of JS functions and
> C implementations are specific to object instance type.
> Well yes, of course they check for the object type compatibility, but in
> the end they should still preserve their "function identity" instead of
> being looked up from the object everytime, even if it's completely
> detached from it.
> > Do you have a branch where I could see it in action?
> I need to fix a couple things but I will update the branch tomorrow with
> the prototype chains most likely. (it's probably not 100% perfectly
> designed but I mean the general idea)
I've updated the branch with prototype chains; there's a lot of commits
in-between so please ignore them for now (some are split, some aren't
ready for upstream review), since order (same as from Proton) is like:
basic proxy impl->cycle collection integration->proper global host
window->basic prototypes (only one, no chains)->constructors->prototype
chains
Probably first commit of interest would be
`d672d8b44ef084106c59b30fa01952fe4daf9189` aka `mshtml: Copy the builtin
data to the proxy prototype on init.`
Or you can just run the tests and change the BuiltinFuncCall to use the
DISPID (no need to check IID for testing), proxy_prop_info should
already get the dispid anyway (for proxy props) and see why it fails.
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/5444#note_71942
This MR adds support for creating file mapping objects backed by large pages on Linux, by making the following changes:
## wineserver
* On Linux, `create_temp_file` will first attempt to use memfds as the backing fd. If it fails, it'll return to the current codepath, creating a temporary file in either the server or config directory.
* The created memfd will be sealed against writes, if the caller requesting the appropriate page protection flags.
* This removes the requirement that FDs be only created on filesystems/directories that aren't `noexec`.
* In the server method `create_mapping` , if large pages have been requested by the caller, hold that the calling thread's token holds `SeLockMemoryPrivilege` .
* Additionally, add `SeLockMemoryPrivilege` to the list of privileges enabled for the Administrator.
## ntdll
* Add `virtual_get_min_large_page_size` and its exported wrapper wine_unix_get_min_large_page_size
### `kernelbase.dll`
*
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/5769
--
v2: mshtml: Move IDispatchEx forwarding implementation to outer window object.
mshtml: Use macro for window object IDispatch functions implementation.
mshtml: Use DispatchEx vtbl for all window properties.
https://gitlab.winehq.org/wine/wine/-/merge_requests/5766
Observable issue before this change is that text extent does not match size
of ExtTextOutW() output. The fix is to shape text in similar way before measuring.
Individual extents returned in this case are arguably useless, they do not
match visual output order, and only give an idea on how much each input character
contributed to overall width. To match input character order all intra-line and
intra-item reordering is disabled.
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/5757
The first commits add some test infrastructure to be able check raw input keyboard events, along with a few tests relevant to the code paths in this MR. This MR also introduces support for checking async key state in tests.
For some fixes it was difficult to express the current Wine behavior with TODOs in the expected sequence, so tests for these were added along with the fix.
--
v3: server: Set VK_PACKET async state in raw input legacy mode.
https://gitlab.winehq.org/wine/wine/-/merge_requests/5754
The first commit adds some test infrastructure to be able check raw input keyboard events, along with a few tests relevant to the code paths in this MR.
The second commit fixes raw input behavior with unicode inputs, and adds regression tests. Note that it was difficult to express the current Wine behavior with TODOs in the expected sequence, that's why I didn't introduce these regression tests independently.
--
v2: server: Set VK_PACKET async state in raw input legacy mode.
user32: Check async key state in raw nolegacy tests.
server: Don't send raw input events for unicode inputs.
server: Apply modifier vkey transformations regardless of unicode flag.
server: Use right-left modifier vkeys for hooks.
user32: Add tests for raw keyboard messages.
user32: Add more test for unicode input with vkey.
https://gitlab.winehq.org/wine/wine/-/merge_requests/5754
This should help unifying the interface and get rid of the get_info callback.
Later, I think we could create bitmaps over sections shared with some DWM process and/or host compositor.
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/5764
On macOS, getxattr() is surprisingly slow, several times slower than running listxattr on the same file.
(It seems like getxattr() is doing security checks before determining whether the xattr exists or not).
On macOS 14.5, timing for 30000 calls to the following functions (the target file contains no xattrs):
```
lstat: 29729459 ns
getxattr: 110323334 ns
listxattr: 14672500 ns
```
And a Wine test that calls FindFirstFile 2500 times with a path of "C:\\windows\\system32\\*.nonexistent":
```
currently: 12119 ms
with this patch: 5580 ms
```
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/5758
> There is a difference between C/C++ and JS that we need to cover one way or another. C implementation is bound to a specific object type, which makes using `impl_from_*` possible. To keep that possibility in hooks, they need to be bound to a specific object type as well. More idiomatically: hooks are a part of C implementation of JS functions and C implementations are specific to object instance type.
Well yes, of course they check for the object type compatibility, but in the end they should still preserve their "function identity" instead of being looked up from the object everytime, even if it's completely detached from it.
> Do you have a branch where I could see it in action?
I need to fix a couple things but I will update the branch tomorrow with the prototype chains most likely. (it's probably not 100% perfectly designed but I mean the general idea)
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/5444#note_71825
> But this `func_info_t` (rather than IID) is used for storing/creating the function object itself (like create_builtin_function but for proxies), not tied to any object, and such function object contains all the "code" of the function not just the signature, so isn't that actually more correct, idiomatically at least?
There is a difference between C/C++ and JS that we need to cover one way or another. C implementation is bound to a specific object type, which makes using `impl_from_*` possible. To keep that possibility in hooks, they need to be bound to a specific object type as well. More idiomatically: hooks are a part of C implementation of JS functions and C implementations are specific to object instance type.
> There are no interfaces added to deal with prototype chains, unless you mean the new method I added for `func_info_t`?
Do you have a branch where I could see it in action?
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/5444#note_71824
Presently the wine file explorer has a create shortcut entry that does nothing. This implements the FCIDM_SHVIEW_CREATELINK command.
This is a patch that was first submitted in 2017 and I unfortunately let the revision request fall unimplemented.
--
v7: shell32: Implement FCIDM_SHVIEW_CREATELINK
https://gitlab.winehq.org/wine/wine/-/merge_requests/5373
Presently the wine file explorer has a create shortcut entry that does nothing. This implements the FCIDM_SHVIEW_CREATELINK command.
This is a patch that was first submitted in 2017 and I unfortunately let the revision request fall unimplemented.
--
v6: shell32: Implement FCIDM_SHVIEW_CREATELINK
https://gitlab.winehq.org/wine/wine/-/merge_requests/5373
This series of patches introduces a new set of structures and functions that will enable code to be re-used across various functions in d3dx9, and eventually d3dx10-d3dx11. It might be possible to split this further, but I feel like this initial set gives better context as to where things are heading.
I have a [branch](https://gitlab.winehq.org/cmcadams/wine/-/commits/WIP/d3dx-shared-s… that uses these structures and functions in d3dx10 if further context would be useful. There are a lot of changes here, but after playing around with different approaches this was the best/cleanest way I could come up with for code sharing. I'm sure there will be things I missed or potentially ways to improve this, I'm open to suggestions of course. :)
--
v3: d3dx9: Use d3dx_load_pixels_from_pixels() in D3DXLoadVolumeFromMemory().
d3dx9: Use d3dx_pixels structure in decompression helper function.
d3dx9: Introduce d3dx_load_pixels_from_pixels() helper function.
d3dx9: Use d3dx_image structure in D3DXLoadSurfaceFromFileInMemory().
d3dx9: Introduce d3dx_image structure for use in D3DXGetImageInfoFromFileInMemory().
d3dx9: Refactor WIC image info retrieval code in D3DXGetImageInfoFromFileInMemory().
d3dx9: Refactor WIC GUID to D3DXIMAGE_FILEFORMAT conversion code.
https://gitlab.winehq.org/wine/wine/-/merge_requests/5666
> Meantime, I noticed that we could prepare MSHTML for the change better by completing dispex refactoring (and document objects split), see https://gitlab.winehq.org/jacek/wine/-/commits/mshtml-dispex/ for a draft. Unfortunately, it needs a few more vtbl entries, but the unification seems worth to me. On top of that, you wouldn't need to have a dedicated new interface implementation for document node and the window variant should be easier as it could be just a forwarder. What do you think?
Looks fine to me. I'm not a fan of all the new vtbl methods, but it's better than what we have currently, so it's fine. This will definitely simplify it, but at the same time, I still want to know if is there something wrong with this MR I should change?
I'd like to get it moving, considering it doesn't have much to do with this, these changes would come later ofc.
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/5444#note_71791
> The problem with `func_info_t` is that it carries information specific to the instance (like hooks), not only abstract things like the signature, so you can't just apply "current style" function info to "style" object without some additional refactoring. It's hard to comment in more details without the code.
But this `func_info_t` (rather than IID) is used for storing/creating the function object itself (like create_builtin_function but for proxies), not tied to any object, and such function object contains all the "code" of the function not just the signature, so isn't that actually more correct, idiomatically at least?
If this builtin mshtml function were to be implemented in pure jscript somehow, it would contain all its code there, including hooks and everything else. It doesn't feel that right to me to "look up" the function on a specific object when calling it in such case, which may end up with the wrong function if we're not careful.
> I'm still hoping to see how the interface capable of handling prototype chains looks like.
There are no interfaces added to deal with prototype chains, unless you mean the new method I added for `func_info_t`?
It's basically like this:
```idl
HRESULT BuiltinFuncCall([in] void *func_ctx, [in] BOOL setter, [in] DISPPARAMS *dp, [out, optional] VARIANT *ret,
[out] EXCEPINFO *ei, [in] IServiceProvider *caller);
```
and then it's called here:
```c
static HRESULT ProxyFunction_call(script_ctx_t *ctx, FunctionInstance *func, jsval_t vthis, unsigned flags,
unsigned argc, jsval_t *argv, jsval_t *r, IServiceProvider *caller)
{
ProxyFunction *function = (ProxyFunction*)func;
DISPPARAMS dp = { NULL, NULL, argc, 0 };
IWineJSDispatchHost *proxy_target;
VARIANT buf[6], retv;
EXCEPINFO ei = { 0 };
IDispatch *this_obj;
jsdisp_t *jsdisp;
HRESULT hres;
unsigned i;
if(flags & DISPATCH_CONSTRUCT)
return E_UNEXPECTED;
if(argc > function->function.length)
argc = function->function.length;
if(is_undefined(vthis) || is_null(vthis))
this_obj = lookup_global_host(ctx);
else if(!is_object_instance(vthis))
return E_UNEXPECTED;
else
this_obj = get_object(vthis);
jsdisp = to_jsdisp(this_obj);
if(jsdisp) {
if(!(proxy_target = get_proxy_target(jsdisp)))
return E_UNEXPECTED;
IWineJSDispatchHost_AddRef(proxy_target);
}else if(FAILED(IDispatch_QueryInterface(this_obj, &IID_IWineJSDispatchHost, (void**)&proxy_target)) || !proxy_target)
return E_UNEXPECTED;
if(dp.cArgs <= ARRAY_SIZE(buf))
dp.rgvarg = buf;
else if(!(dp.rgvarg = malloc(dp.cArgs * sizeof(*dp.rgvarg)))) {
hres = E_OUTOFMEMORY;
goto fail;
}
for(i = 0; i < dp.cArgs; i++) {
hres = jsval_to_variant(argv[i], &dp.rgvarg[dp.cArgs - i - 1]);
if(FAILED(hres))
goto cleanup;
}
V_VT(&retv) = VT_EMPTY;
hres = IWineJSDispatchHost_BuiltinFuncCall(proxy_target, function->func_ctx, function->setter, &dp, r ? &retv : NULL, &ei, caller);
if(hres == DISP_E_EXCEPTION)
disp_fill_exception(ctx, &ei);
else if(hres == E_NOINTERFACE)
hres = E_UNEXPECTED;
else if(SUCCEEDED(hres) && r) {
hres = variant_to_jsval(ctx, &retv, r);
VariantClear(&retv);
if(SUCCEEDED(hres))
hres = convert_to_proxy(ctx, r);
}
cleanup:
while(i--)
VariantClear(&dp.rgvarg[i]);
if(dp.rgvarg != buf)
free(dp.rgvarg);
fail:
IWineJSDispatchHost_Release(proxy_target);
return hres;
}
```
nothing special or complicated, and of course the `func_ctx` is stored by PropGetInfo rather than the IID (and we check it for NULL to see whether it's a func/accessor or a proxy prop).
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/5444#note_71782
--
v2: win32u: Use a helper to set the window surface clipping, within the lock.
wineandroid: Remove now unnecessary set_surface_region calls.
server: Update window surface regions when the window is shaped.
win32u: Intersect the clipping region with the window shape region.
server: Merge get_surface_region / get_window_region requests together.
server: Split update_surface_region into get_window_region helper.
win32u: Initialize window surfaces with a hwnd.
https://gitlab.winehq.org/wine/wine/-/merge_requests/5753
I was going to reimplement path resolution in ShellExecute, but half way through I realized that's very unnecessary.
Since what I wanted is a version of `PathResolve` that behaves differently _only_ for filespec paths, I ended up duplicating a lot of code, then I realized I can still pass filespec paths onto `PathResolve` and only deal with non-filespec paths.
--
v4: shell32: Fix ShellExecute for non-filespec paths.
https://gitlab.winehq.org/wine/wine/-/merge_requests/5692
I was going to reimplement path resolution in ShellExecute, but half way through I realized that's very unnecessary.
Since what I wanted is a version of `PathResolve` that behaves differently _only_ for filespec paths, I ended up duplicating a lot of code, then I realized I can still pass filespec paths onto `PathResolve` and only deal with non-filespec paths.
--
v5: debug CI failure
https://gitlab.winehq.org/wine/wine/-/merge_requests/5692
> The IID would have the IHTMLStyle3 interface (which is correct), but when looking the "zoom" prop up on HTMLCurrentStyle via DISPID, it would get the one from CSSStyleDeclaration, which has different behavior. Yes, it's weird as hell, and my explanation isn't that great either.
It seems to me that we could just use `IHTMLCSSStyleDeclaration` to expose `zoom` for applicable compat modes. It's implemented by both style and current style. What are other examples? Note that for some cases we may use some private interface, like we already need to in other a few cases.
> Instead I'm now using a mixed approach where I have a new method (but a normal method in the vtbl like PropInvoke rather than a function pointer callback) that uses a "func_ctx" which is basically the `func_info_t` (it's opaque to jscript, it doesn't care).
The problem with `func_info_t` is that it carries information specific to the instance (like hooks), not only abstract things like the signature, so you can't just apply "current style" function info to "style" object without some additional refactoring. It's hard to comment in more details without the code.
> Anyway, this is not very related to this MR, is there something I can do to get this moving?
I'm still hoping to see how the interface capable of handling prototype chains looks like.
Meantime, I noticed that we could prepare MSHTML for the change better by completing dispex refactoring (and document objects split), see https://gitlab.winehq.org/jacek/wine/-/commits/mshtml-dispex/ for a draft. Unfortunately, it needs a few more vtbl entries, but the unification seems worth to me. On top of that, you wouldn't need to have a dedicated new interface implementation for document node and the window variant should be easier as it could be just a forwarder. What do you think?
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/5444#note_71748