CORE-19104
This fixes failure to create or open the `PowerProfileRegistrySemaphore`,
when it has been first created by a Process1 using powrprof from a "User1",
and while this process stays running, the semaphore is attempted to be
re-created (or opened) by another Process2 using powrprof from a different
"User2".
For example, this happens when "User1" is either the LocalSystem account
with the Process1 being Winlogon.exe (via the msgina.dll -> powrprof.dll
dependency), or, "Administrator" with the explorer.exe process when opening
the "Shutdown" dialog (via the shell32.dll -> runtime-loading of msgina.dll
-> powrprof.dll dependency),
AND,
"User2" being a non-administrator user and Process2 being explorer.exe,
again when opening the "Shutdown" dialog. In this situation, msgina.dll
fails to be loaded, because powrprof.dll fails in its `DllMain()` routine
-- see log excerpt below --, and the shell falls back to a minimal shutdown
confirmation dialog.
```
err:(dll\win32\powrprof\powrprof.c:1420) Couldn't create Semaphore: 5
(dll\ntdll\ldr\ldrinit.c:879) LDR: DLL_PROCESS_ATTACH for dll "powrprof.dll" (InitRoutine: 7ADC6DB0) failed
(dll\win32\kernel32\client\loader.c:386) LoadLibraryExW(msgina.dll) failing with status c0000142
err:(dll\win32\powrprof\powrprof.c:1420) Couldn't create Semaphore: 5
(dll\ntdll\ldr\ldrinit.c:879) LDR: DLL_PROCESS_ATTACH for dll "powrprof.dll" (InitRoutine: 7ADC6DB0) failed
(dll\win32\kernel32\client\loader.c:386) LoadLibraryExW(msgina.dll) failing with status c0000142
(dll\ntdll\ldr\ldrutils.c:2340) Image explorer.exe has no exports, but were trying to get procedure (null). BaseAddress asked 0x00400000, got entry BA 0x00400000
err:(win32ss\user\user32\windows\messagebox.c:1048) MessageBox: L"Do you want to shutdown?"
```
- Reimplement `RtlUnhandledExceptionFilter()` by just calling
`RtlUnhandledExceptionFilter2()`.
- Return an adequate exception filter value `EXCEPTION_CONTINUE_SEARCH`
from `RtlUnhandledExceptionFilter2()`, instead of some random error.
If `ExceptionCode` is `STATUS_POSSIBLE_DEADLOCK` however, return
`EXCEPTION_CONTINUE_EXECUTION` instead, as shown by a test from Whindmar Saksit.
- The second parameter of `RtlUnhandledExceptionFilter2()` is not
a flag, but a pointer to string `PCSTR` !
See https://skanthak.hier-im-netz.de/download/NTDLL.H
who is the only one online who has the correct definition,
whose usage I've double-checked on Win7 ntdll.dll.
This is used in the `<function_name>` slot in the displayed
debugger message:
```
*** An Access Violation occurred in <program_command_line>:<function_name>
The instruction at <address> tried to write to a NULL pointer
```
For example, see: https://community.osr.com/t/access-violation/33435
- Validate the opened `WinSta0_DesktopSwitch` handle;
- Don't pass the `ahEvents` array containing a NULL pointer to
`MsgWaitForMultipleObjects()`, but provide the correct number
of non-NULL handles, otherwise the function fails and the code
ends up busy-looping.
- Validate the `MsgWaitForMultipleObjects()` result: bail out if
`WAIT_FAILED` is returned.
- Validate the event index passed to `CRegWatcher::InitEvent()`
and `CRegWatcher::OnEvent()`.
- Rename `WATCHENTRY_MAX` to `WI_REGEVTS_MAX` and add it in the
`WATCH_INDEX` enumeration.
- Fix some code comments.
- Don't hardcode buffer sizes.
- `ShowWindow()` 2nd parameter is an `SW_*` flag, not `TRUE`/`FALSE`.
- The "FIXME: Add battery page" comment is outdated since commit 4bdbb3092c
- Use standard `IDC_STATIC` instead of `-1` for resource control IDs.
- `AUTOCHECKBOX` already contains `WS_TABSTOP`, no need to add it explicitly.
- Reformat file headers.
Add Wow64PrepareForException handler, which is well documented as a hook for KiUserExceptionDispatcher (see e.g. https://github.com/brew02/KiUserExceptionDispatcherHook) and used by ntdll_winetest.
This also reloads rcx and rdx for the call to RtlDispatchException from the stack instead of relying on the registers to be set up by the kernel, which again is a feature used by ntdll_winetest, which calls this function from a hook with zeroed registers.
Add useful macros, similar to the powrprof.dll `IsPwr*()` functions,
but that are suitable when one has a `SYSTEM_POWER_CAPABILITIES`
structure initialized from `NtPowerInformation(SystemPowerCapabilities)`.
- `IS_PWR_SUSPEND_ALLOWED()`, equivalent to `IsPwrSuspendAllowed()`,
indicating whether any of the S1, S2, S3 sleep states are supported.
- `IS_PWR_HIBERNATE_ALLOWED()`, equivalent to `IsPwrHibernateAllowed()`,
indicating whether the S4 sleep state is supported and the
hibernation file is present.
- `IS_PWR_POWEROFF_ALLOWED()`, equivalent to `IsPwrShutdownAllowed()`,
indicating whether the S5 "soft-off" state is supported.
CORE-20343
The 3-second timeout FIXME (instead of waiting indefinitely), made in the
COMPBATT worker thread for the `IOCTL_BATTERY_QUERY_STATUS` case, was done
because _*our*_ BATTC handler expects the batteries to always support the
BTP (Battery Trip Point) feature for signaling a change of battery status,
but in the cases where it isn't supported, any waits it tried for the
battery to notify about a status change would never happen.
Furthermore, following commit 3a6e0d4b65, the `SetStatusNotify()` call
(_which always fails if the battery doesn't support the BTP feature_)
would now always exit the `IOCTL_BATTERY_QUERY_STATUS` handling without
any waiting nor battery polling [^1], and this would cause the COMPBATT
worker thread to busy-poll again forever.
The timeout FIXME is now moved to BATTC, instead of COMPBATT, since the
actual fixes should be in BATTC. In particular, it should queue all the
query IOCTLs and then serve them, either using the StatusNotify (BTP)
functionality if the battery supports it, or if not, do a very-slow
battery polling.
I've also increased the timeout a little bit more (5 seconds and not 3).
[^1]: Per the ACPI specification, it is expected that the operating system
performs battery polling if the battery doesn't support BTP, see:
https://uefi.org/htmlspecs/ACPI_Spec_6_4_html/10_Power_Source_and_Power_Meter_Devices/Power_Source_and_Power_Meter_Devices.html#btp-battery-trip-point
Previously the function waited for the conditions *after* querying the status, and then returned the old status. Also, if querying failed, it waited and when the wait timed out it returned STATUS_SUCCESS without returning any data. If the call to SetStatusNotify failed and there was no timeout, it would wait forever.
This is all fixed now.
This is useful for numerical values that are documented as being stored
in string format as `REG_SZ` in the registry; the reason being that they
are still read or written via `GetProfileIntW()`/`WriteProfileStringW()`
by Windows' Winlogon, and these functions store `REG_SZ` values because
of the INI <-> Registry mapping mechanism.
This is more explicit than defining it for all wine tests and it directly shows us which tests need to be synced to get rid of the hack.
Addendum to 381e224 (PR #7576)
Addendum to commit 1499e7ef53.
Poor thing was crying that it was ignoring trigraph `??)`, even
though this whole thing was inside an `#if 0`-commented block...
Use something else instead.
```
msgina/shutdown.c: In function 'ShutdownDialog':
msgina/shutdown.c:1217:56: error: trigraph ??) ignored, use -trigraphs to enable [-Werror=trigraphs]
pgContext->nShutdownAction = LoadShutdownSelState(???);
msgina/shutdown.c: At top level:
cc1: error: unrecognized command line option '-Wno-unknown-warning-option' [-Werror]
```
Otherwise, you wouldn't see anything at all when opening a .NET app, and
the only hint that a .NET runtime is needed would be to see the message
in the debug log, provided a debugger is connected to ReactOS ...
NOTE: `shell32!ShellMessageBoxA()` is used instead of
`user32!MessageBoxA`, because it turns out mscoree isn't importing
from user32 but from shell32 instead (as in Wine's), and I don't want
to modify the list of imported modules.
NOTE 2: This warning function has been gradually removed with Wine commits:
c99754ef156b889fe9185cd6db034926c9bd9f15
Now, a mere `ERR("Wine Mono is not installed\n");` is emitted.
- Disable "Log Off" from the Start Menu and the C-A-D Security dialog;
- Disable the "Lock Workstation" and "Change Password" buttons in the
Security dialog.
These are only "UI"-usability features to prevent the user from
logging off when running the LiveCD. (Logging off from the SYSTEM
account, and changing its password, don't make much sense.)
CORE-11397
- Respect system policies for showing or hiding:
* Security dialog "Lock Workstation", "Log Off", "Shut Down",
"Change Password", "Task Manager" buttons;
* "Log Off" entry in the Shutdown dialog;
- Disable the "Shut Down" Security dialog button, and the "Stand by",
"Shut down" entries in the Shutdown dialog, if the logged user
doesn't have the SeShutdownPrivilege.
- Add other missing `WLX_SHUTDOWN_STATE_*` shutdown flags that are
supported by Windows.
- Improve the retrieval of shutdown options to be displayed in the
"Shut Down" dialog. In particular, don't hardcode any sort of
defaults, but let them come from what the user can do (Is logoff
allowed? Does (s)he have the rights to shutdown/reboot? etc.).
If no shutdown options are available, then simply don't display
the dialog!
- Don't hardcode the default selected shutdown option. Either it comes
from the user's registry and is valid (i.e. corresponds to an existing
shutdown option in the dialog), otherwise, fall back to the first
option in the dialog.
In particular this means:
* when opening the "Shut Down" dialog from the C-A-D Security
dialog, by default we will select the "Log Off" option, or
whatever the user last selected;
* when opening the dialog from the "Turn Off" Start Menu item, default
to the "Shut down" option, or whatever the user last selected.
* when opening the dialog from the C-A-D "Log On" dialog (no user
is logged in), the "Shut down" option will also be selected, or
whatever the system operator last selected.
- For the shell-invokable `ShellShutdownDialog()` function, implement
support for using a custom display user name, or the one in the
`"Logon User Name"` registry value saved by `WlxActivateUserShell()`.
Plus, the 3rd parameter specifies the list of shutdown options to
*exclude* from the options list.