- Tweak the dimensions of the read-only editboxes.
- Tweak the Confirmation checkbox: adjust its dimensions, remove some
artificatial newlines, and adjust the wording in some translations.
- Support double-clicking on the Installation type page radio buttons.
The Installation type page offers two self-excluding options:
"Install ReactOS", and "Upgrade an existing ReactOS installation",
and no other controls are available (except for the wizard navigation
buttons). Thus, we can implement the UI feature of supporting double-
clicked radio buttons as an abbreviation for "select + Next".
For this, add the `BS_NOTIFY` style to both radio buttons, so as to
receive the `BN_DBLCLK` notification via the `WM_COMMAND` message.
Based on a suggestion by Raymond Chen,
https://devblogs.microsoft.com/oldnewthing/20050804-10/?p=34713
- Ensure the correct radio button is selected when activating the
Installation type page:
ensure the "Install ReactOS" radio button is checked if we don't have
a selected installation (default case), which can also happen if the
user clicked on the "Do not upgrade" button on the Upgrade/Repair
selection page, then went back.
- In the Upgrade/Repair selection page, go to the next page if the user
double-clicked on a listed installation.
- In the Drives/Partitions page:
* support pressing DELETE key to delete an existing partition;
* support pressing ENTER key to install ReactOS on a eligible
partition;
* enable the "Create" partition button only if the selected disk region
is not partitioned, and can be partitioned according to the disk's
partitioning scheme (e.g. for MBR disks, no more than 4 primary
partitions).
- Explicitly check for `BN_CLICKED` notification when handling
single-click on standard push-buttons.
- Return TRUE explicitly from `WM_COMMAND` in the _dialog_ procedures
when the message is handled and no extra default processing is needed.
- Reduce some extra indentation when possible.
- Move `ExpandInstallerPath()` from userinit.c to livecd.c, and update
its SAL2 annotations and Doxygen comment.
- Make `StartInstaller()` directly use the cached ReactOS installer path.
- This avoids invoking yet again `ExpandInstallerPath()` when trying to
locate the installer also for the aim of determining whether to disable
the "Install" button.
Use the standard way of checking for the existence of
the `HKLM\SYSTEM\CurrentControlSet\Control\MiniNT` key.
Addendum to commits 8fabb29ed9 and 9fa8028ae4.
Updating keyboard layout settings with user-overridden values, was
restricted to non-unattended setups, in an apparent attempt to fix
in commit 829b0c63d9 (r38146) the problem reported at CORE-3634.
This special-casing is now unnecessary.
For example, when installing ReactOS in French, this selects the French
keyboard layout as default, while keeping English installed but not
activated.
This is partly a "hack", and adapts the existing solution chosen in USETUP.
A better fix will be done in the future.
- Improve install abort on errors;
- Wait for the install thread to finish within the page that created it;
- Display the hourglass cursor while waiting for the thread.
- Ensure the wizard gets shown, centered on the screen, and focused,
when the Finish page is reached.
- Trigger the change of the "Cancel" wizard dialog button text, not
from the `WM_INITDIALOG` page handler, but from `PSN_SETACTIVE`.
- Add a `PSN_KILLACTIVE` handler to kill the timer initialized in
the `PSN_SETACTIVE` handler.
- Add a `PSN_WIZBACK` handler to disable going back in the wizard.
- Store the wizard page descriptors in a separate static array.
Then loop over these descriptors to create each page.
- Set the window small icon.
- Add a property sheet callback to set the window large icon (and not
a rescaled small icon!) from the `PSCB_INITIALIZED` notification.
Also, handle the `PSCB_PRECREATE` notification, and subclass the
property sheet window procedure, so as to be able to initially center
the wizard window while keeping it hidden before showing it,
independently of which wizard page is going to be initially shown.
A small hack for handling the `DM_REPOSITION` message is added,
because Wine's comctl32 propsheet.c doesn't send the message after
creating, initializing and resizing the property sheet dialog...
- drivepage.c:
* Move some local loop variables inside their loop block.
* Move the core of the Drives/Partitions dialog `PSN_WIZNEXT` handler
into a separate function.
- reactos.c:
* Move some `break;` into their corresponding `case` blocks.
* Replace remaining `EnableWindow(GetDlgItem(...), ...)` instances
with `EnableDlgItem(...)`.
* Introduce `hWndParent` variables in some routines, so as not to
invoke `GetParent(hwndDlg)` repeatedly.
* Use NULL for default "Error" message-box title.
* Remove an empty `case WM_DESTROY` in `FinishDlgProc()`.
- Use explicit Unicode property-sheet structures.
- Update the copyright notice dates. Fix the file header in drivepage.c.
Add the missing file header into reactos.rc.
- Fix TAB order in the Installation type page.
- Don't systematically set focus to the "Install ReactOS" radio-button.
Always resetting the focus to the "Install" choice is unwanted,
because, if the user instead selects "Upgrade", goes to the next
"Upgrade/Repair" page, then goes back to the installation type page,
the selection focus wouldn't be on what the user previously chose,
but would instead be on the "Install" choice, while the "Upgrade"
choice would stay checked, thus leading to an inconsistency.
We want instead the selection to stay as the user previously chose,
without changing it.
- Correctly handle item selection change in the Installations list,
so that only the "selected" state change is detected and UI buttons
are updated accordingly.
When the `PSN_QUERYINITIALFOCUS` notification is received (whenever
the page is made active), reselect the currently-selected item so as
to properly update the UI buttons.
- Add missing keyboard accelerators in the Devices selection page.
- Group all the push-buttons together in the Drives/Partitions page,
so that when the focus is on the first one and the user presses the
Left-arrow key, the focus stays on the buttons and doesn't go to the
partitions list.
- Remove the `PSN_QUERYINITIALFOCUS` hack in the Drives/Partition page
dialog procedure (see commit 6cb1394bb1, PR #9272).
- Correctly handle item selection change in the Drives/Partition list,
so that only the "selected" state change is detected and UI buttons
are updated accordingly.
When the `PSN_QUERYINITIALFOCUS` notification is received (whenever
the page is made active), reselect the currently-selected item so as
to properly update the UI buttons.
- Remove redundant `WS_VISIBLE` style for all the Edit-text fields of
the Summary page.
- In the Start/Welcome and the Finish/Abort pages: when disabling the
wizard "Back"/"Next" navigation buttons with `PropSheet_SetWizButtons()`,
for the purpose of hiding them next, do *NOT* use that macro, because
it posts the `PSM_SETWIZBUTTONS` message instead of sending it, and so,
it would be handled after hiding the buttons. The message would then
interfere with the hidden buttons (when both "Back" and "Next" are
hidden, "Next" gets forcefully shown).
- Set the default button to "No" for some confirmation dialogs
(setup abort; partition deletion; ...).
Import patch from wine-9.15: wine-mirror/wine@320547b
```
comctl32/tests: Add test for PSN_QUERYINITIALFOCUS for the propsheet.
wine commit id 320547b6757a7236929a0d47847cab0802607cde by Jacob Czekalla <[email protected]>
```
- Move around the status items static controls.
- Bolden the main status label.
- Whereas the repair/upgrade procedure may move, rename, or delete files,
the regular installation only copies files. Therefore, display only the
file name instead of the full "Copying..." message in this case.
(Based upon a suggestion by Carl Bialorucki.)
CORE-20681
Send `WM_ACTIVATE` and `WM_ACTIVATEAPP` to the property sheet active page.
And do the same with `WM_ENABLE`, `WM_QUERYENDSESSION`, `WM_ENDSESSION`,
and `WM_DEVICECHANGE`, after sending them to the tab control first.
Similar in spirit to commit d09c3d0af8.
This test allows viewing the window keyboard messages (`WM_KEYDOWN/UP`,
`WM_CHAR`, ...) that are sent by Win32k whenever the user presses keys,
including what happens when Alt+Numpad combinations are typed in.
The application shows the list of received messages in a format similar
to that of Microsoft Spy++.
As soon as `ObCreateObject()` is successfully invoked, zero-out the winsta
and desktop object buffers and assign them the current process session ID
(into their first `dwSessionId` member). Only then, continue with regular
initialization.
It's done in this systematic way in order to ensure that, in case the
regular initialization of these objects fails and `ObDereferenceObject()`
is invoked, the `nt!ExpWin32SessionCallout()` routine (in `ntoskrnl/ex/win32k.c`)
that is executed as part of the Win32 "delete" object callback registered
by win32k.sys with the Object Manager, correctly finds a valid initialized
`SessionId` value in the "common header" of either the window station
or the desktop object being deleted.
As a side-result, other parts of win32k can directly refer to
`pdesk->dwSessionId` instead of `pdesk->rpwinstaParent->dwSessionId`
for a given desktop.
- Don't use `NtCurrentPeb()` to retrieve the current process session ID,
but `PsGetCurrentProcessSessionId()` instead that doesn't require a PEB.
- Turn the purposely-leaking local `hWinstaDir` variable into a global
`ghWinStaDir` variable, so that when win32k.sys unloading support will
be implemented, one could close `ghWinStaDir` so as to delete the per-
session window-station object directory.
(It isn't created as an `OBJ_PERMANENT` object for this reason.
See comment https://github.com/reactos/reactos/pull/621#discussion_r196303521
in PR #621.)
This hack was introduced in commit 89d0892531 (r6908) to automatically
assign, on kernel-side, the created window as the "current" desktop window,
when it was the first one to be created for the given desktop.
This was necessary back when Win32 desktop windows were managed on
CSRSS side (via the ReactOS-specific `win32csr/desktopbg.c` module).
Since the introduction of the `winsrv` module, and the move of desktop
windows management into Win32k in commit 765f09416d (r57632), see also
CORE-6723, this hack isn't needed anymore because the same sequence
of actions is done by `IntCreateDesktop()`, just after creating the
desktop window.
The call to `IntDefWindowProc()` in the desktop window procedure
`default` case, was disabled in commit ff31610bfb (r68908), because
of a supposed "painting message regression", probably related at
that time to a previous commit 6dfa71c487 (r68904) and CORE-7797.
This isn't relevant anymore.
- Use SAL2 annotations; write Doxygen documentation (based on GPT-5.4 feedback).
- Simplify some of the code.
- Add the `ObSetHandleAttributes()` prototype to `ndk/obfuncs.h`,
since it is exported by ntoskrnl.exe
- Simplify the `ObjectHandleFlagInformation` class implementation,
by directly invoking the `ObSetHandleAttributes()` routine.
Addendum to commit 02d0bb9dbd (r22228) that implemented the class,
and to commit 91105c7915 (r61037) that implemented `ObSetHandleAttributes()`.
- Use SAL2 annotations; write Doxygen documentation (based on GPT-5.4
feedback and https://ntdoc.m417z.com/ntsetinformationobject).
- The `HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\HideDesktopIcons`
entries were redundant between hivedef.inf and hivesft.inf.
In addition, adding them were useless, because the "Network Places"
(network location folder) icon they were specifying is already shown
by default (like the others) on the desktop.
This basically reverts commit 054c755d91 (r31545) -- originally added
for the next commit 562c812846 (r31547).
The "reason" given by this commit was also wrong: the registration
of the network folder is done instead in its `HKCR\CLSID\<the_clsid>`
registry key.
- Similarly, the `HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Bitbucket`
registry key doesn't need to be pre-created; the shell will create it
on-demand at runtime.
This reverts commit bab735cf05 (r35203).
In `SHELL32_IsShellFolderNamespaceItemHidden()`, use `SHRegGetBoolUSValue()`
to look at both `HKEY_CURRENT_USER` with fallback to `HKEY_LOCAL_MACHINE`,
when searching for the registry value that determines whether a shell-folder
namespace item is to be hidden or shown.
Behaviour confirmed on Windows 2003.
Addendum to commit 6ae11ba09d (PR #7189).
The shortcut spawns CMD.EXE in the background and runs a specific
command-line that determines where the reactos.exe installer is:
cmd.exe /D /E:ON /C "start %SystemDrive%\%PROCESSOR_ARCHITECTURE:x86=I386%\reactos.exe"
An alternative could be:
cmd.exe /D /C "for /F %f in ('"if %PROCESSOR_ARCHITECTURE%==x86 (echo I386) else (echo %PROCESSOR_ARCHITECTURE%)"') do start %SystemDrive%\%f\reactos.exe"
(In this second case an exact value comparison is made, contrary
to the first case where all instances of "x86" would be replaced.)
The reason for using CMD.EXE, is that the `PROCESSOR_ARCHITECTURE`
environment variable contains the "almost" correct value for the
architecture directory name where reactos.exe can be found, except
for the x86 case where `PROCESSOR_ARCHITECTURE` is set to "x86"
(as on Windows) but the directory is named "I386" (as on Windows again).
The environment variables used by some shell links for the Live-environment,
are passed as data by CMake on the MKSHELLLINK build tool command-line.
When building on Windows, they are transmitted to the tool via CMD.EXE,
and we have somehow to force CMD.EXE to keep these variables unexpanded.
Depending on the precise context where these variables are being used,
either use an "escaped" format with `^%`, as in: `^%SystemRoot^%` ,
or, surround the variable name with `^` instead: `%^SystemRoot^%` .
This second form appears to work when the variable is specified within
a quoted sub-string given to the CMD.EXE command-line.
Addendum to commit a46e1e96ec.
Only handle `DESTINATION`, and transfer all the other parameters verbatim to `add_link()`.
Addendum to commits 3a3b16af0d, 8cb3980766, and a46e1e96ec (PR #8936).
Using `userenv!CreateEnvironmentBlock()` when starting the shell ensures
that, even if it's started as LocalSystem, its environment inherits the
"dynamical" environment variables created by SMSS at runtime (stored in
`HKLM\SYSTEM\CurrentControlSet\Session Manager\Environment`).
In ReactOS/Windows PE "MiniNT" mode, the Winlogon environment doesn't
contain these values, and doesn't start the Setup with this augmented
environment. (This is compatible with what Windows does, on WinPE or
during a clean installation.)
Winlogon creates an augmented environment only when a user logs in and
starts its shell (standard boot), which isn't the case in "MiniNT" mode.
It is thus the responsibility of the module that starts the shell instead
to do it: in ReactOS' case, userinit.exe in LiveCD mode.
As a result, we get access to the `COMPUTERNAME`, `NUMBER_OF_PROCESSORS`,
`OS`, and `PROCESSOR_*` environment variables, amongst others.
CORE-19691
Removing the `livecd_start.cmd` entry also caused the "Profiles/Default User/My Documents"
directory to not be created in the LiveImage. When booting it, this
caused explorer.exe to hang while loading the desktop, for **some**
(but not all) non-english environments.
(Technically it should instead ignore the non-existing directory if it
cannot create or open it, or drop an error then continue execution...
But that's another bug for another time!)
Adding back the creation of this directory fixes the hang.
CORE-15156, CORE-19691, CORE-19692
Finally get rid of the livecd_start.cmd hack introduced waaaay back
in commit ff6d7b0236 (r54514)!
See also commits ea682b6909 (r54512) and 71867403fd (r54513).
For target paths, use the shell "special shell folder" syntax:
`shell:windows\...` or `shell:system\...`, introduced in commit
7b081be46d (PR #7158) by Whindmar Saksit.
Specify an explicit icon path and index for the "Read Me.lnk" shortcut.
Includes ideas from PR #7154 by Katayama Hirofumi MZ.
The generated shell links are confirmed to work on ReactOS, but also on
Windows 2003 and Windows 7.
- Change the MKSHELLLINK icon parameter syntax to be: `-i [icon_path[,nr]]`
where, either both `icon_path` and icon index are given, separated by
a comma ',' , or, either the `icon_path` is given but the index is
optional (default: 0), or, only the icon index is given, in which case
the icon path is set to the target instead.
- Use a `VERBATIM` command-line for `add_custom_command()`, so that *nix
builds can cope with parameters containing backslashes.
- The shortcut target path, working directory, command-line arguments,
and icon path all may specify explicit Win32 environment variables
(like `%SystemRoot%`, `%HOMEDRIVE%`, etc.). Because these environment
variables are specified as data given to the build tool via CMake,
**AND** we have to workaround keeping these variables unexpanded when
they are transmitted to the tool via CMD.EXE (on builds made on Windows),
specify these variables in an "escaped" format, using `^%` instead:
`^%SystemRoot^%`, etc.
Additionally these paths may be explicitly quoted and passed that way
to the MKSHELLLINK tool.
In order to deal with both unquoting the strings and unescaping the
environment variables, introduce a helper function and invoke them on
the aforementioned strings.
CORE-15156, CORE-19691, CORE-19692
- When specifying a "special shell folder" in the shortcut target,
e.g.: `shell:windows\system32\cmd.exe` , or: `shell:system\cmd.exe`,
resolve it using a ReactOS-specific path, but also use a version
using unexpanded environment variables: for both examples,
`%SystemRoot%\system32\cmd.exe`
- Whenever the shortcut target or the icon path contains unexpanded
environment variables, add associated `EXP_SZ_LINK` data blocks.
- Use the previously-introduced ANSI-to-UTF16 `my_mbstowcs()` routine
to convert the ANSI strings to Unicode for the `EXP_SZ_LINK` data blocks.
Support the creation of shortcuts that can use Unicode versions of
their name (description), relative path, working directory, command-
line arguments, and icon location.
This option can be selected at runtime with a switch.
Additionally:
- Ensure that `wchar_t` is 16-bit wide.
- Introduce and use a "poor-man" ANSI-to-UTF16LE `my_mbstowcs()` routine
to convert the ANSI strings, for the Unicode scenario mentioned above.
We cannot use the host mbstowcs() routine, since on *nix systems the
iconv library being used may have been compiled with a 32-bit `wchar_t`
(even if the tool is compiled with: `-fshort-wchar -fwide-exec-charset=UTF-16LE`),
as this is the case with the GitHub actions build bots.
Addendum to commit 7b081be46d (PR #7158).
CORE-15156, CORE-19691, CORE-19692
Since commit 7b081be46d (PR #7158), one can create shell links that
point to a file in a subdirectory of SystemRoot (e.g. X:\reactos) or
SystemRoot\system32 using a shell "special shell folder" syntax, for
example:
`shell:windows\Readme.txt` (--> X:\reactos\Readme.txt) ,
`shell:windows\system32\cmd.exe` , or:
`shell:system\cmd.exe` (--> X:\reactos\system32\cmd.exe) .
An `EXP_SPECIAL_FOLDER` data block allows parts of a shortcuts pidl
to be overridden by such a special folder.
- In these cases, try to build the shortcut pidl such that it faithfully
mirrors the intended path. For example, when using `shell:system\cmd.exe`,
resolve the `shell:system` part to `X:\reactos\system32` instead of
just `X:\reactos` ; this helps understanding what happens when
spelunking into such a shell link. This also helps when converting
such a path to one containing unexpanded environment variables, for
the purposes of making the Windows explorer shell show the correct
shortcut target path, or resolve it independently of the SystemRoot
being used; and, to be able to use the path for the shortcut icon.
- Get rid of the `index`/`specialindex` variables.
These were used for making the `EXP_SPECIAL_FOLDER` data block point
to the correct path suffix part that follows the special path prefix
in the ID list.
Hardcoding its value caused problems when the special path prefix is
made to contain more path elements than just "X:\reactos". For example,
"X:\reactos\system32" in the case of the `shell:system` prefix.
Instead, retrieve the length of the special path prefix, then, compare
it with the length of the path elements being parsed in the loop.
----
This problem was made explicit when the the following code path is run:
```
shell32!CShellLink.cpp:CShellLink::Load(IStream *stm)
--> ILCombine(folder, m_pPidl + pSpecial->cbOffset)
```
- Use the `bool` type from `stdbool.h`
- Update "Specification" URL, using instead the
"[MS-SHLLINK]: Shell Link (.LNK) Binary File Format"
- Document which structures in `undocshell.h` correspond to those
in MKSHELLLINK.
- Add `SLDF_*` constants from PSDK `shlobj.h` for consumption, and
alias the tool-specific `LINK_*` ones to these.
- The first member of the `LNK_HEADER`/`SHELL_LINK_HEADER` structure
is not a signature, but its size.
Fix the `FILETIME` fields ordering. The `IconIndex` member is signed.
The `HotKey` member is a 16-bits value.
- The third member of the `ID_LIST_GUID`/`tagGUIDStruct` structure is
not "dummy", but is a sort-order. Add also some known corresponding
values, and unhardcode the value used in the code.
- Make the `is_path_separator()` return a `bool`, and use the helper
more thoroughly in the code.
- Improve the help/usage text shown by the tool.
- In case an invalid/unknown argument is encountered, set the `bHelp`
flag just after showing the error, so as to display the tool usage
and bail out early.
- Improve/clarify some code comments.
- Update the file header notice.
- Use variables to define and hold the on-disk shortcuts destination
directories (the "Profiles/All Users/..."), and use these variables
in the `add_livecd_shortcut()` calls; this allows shortening the
corresponding lines.
- There are currently two shortcuts: "Command Prompt" and "ReactOS
Explorer", that are added to more than one destination.
Previously, we had to invoke `add_livecd_shortcut()` for each
destination. However, each invocation recreated the _**same**_
shortcut file (with the same .lnk file name) in the build directory.
To solve this, the `dest` parameter of the `add_livecd_shortcut()`
function, is replaced by a `DESTINATION` keyword, whose value is
a list of one or more destination directories, where the shortcut
should be added.
CMakeLists.txt: `add_livecd_shortcut()`:
Turn the macro into a function. Instead of keeping a `LIVECD_SHORTCUTS`
global-scope list variable, just define a `livecd_links` custom target
as initially empty, then, using `set_property()`, directly append to it
its "SOURCES" i.e. generated .lnk files.
(This is equivalent to using `target_sources(livecd_links PRIVATE ...)`
only in CMake 3.20+ for the custom target.)
CMakeMacros.cmake: `add_link()`:
- Since both `name` and `path` parameters are mandatory, make them
explicit in the function declaration instead of defining them as
"optional" parameters.
- Remove the `set_source_files_properties(... PROPERTIES GENERATED TRUE)`
invocation that followed the `add_custom_command(...)` call, since,
per the documentation[^1],
"Each output file will be marked with the `GENERATED` source file
property automatically." (Since CMake 3.2 at least.)
[^1]: https://cmake.org/cmake/help/v3.17/command/add_custom_command.html
- Remove hardcoded FONT resource attributes (fallback to defaults).
- Unify per-language CAPTIONs of wizard pages.
- Unify the Welcome page title control sizes with those of
the Finish page and what's used in the 1st-stage GUI setup.
Unify these also across translations.
Add also an Abort page that is displayed when the user cancels the
1st-stage setup, or when an error occurs and installation is aborted.
- Rewrite the text, change the layout;
- When the installer is started without any Win32 shell, or the
installation is running in unattended mode, the Finish/Abort
pages only offer to restart the computer with a 15-second timeout
countdown.
If the user has opened programs with interactive windows in the
meantime, the timeout countdown just pauses whenever the installer
window is de-activated/unfocused; it restarts when the window is
re-activated. (This currently doesn't work in ReactOS due to a bug
in the `WM_ACTIVATE` message delivery.)
If, on the contrary, the installer is started by the user when a
Win32 shell is running, the Finish/Abort page offers to either restart
the computer "now", or postpone the restart to later (when the user
manually restarts the computer); no reboot countdown is present there.
- Disable/hide the "Back" button for the Install processing page.
- In `SetWindowResTextW()` and `SetWindowResPrintfVW()`, don't assume a
fixed size of 256 characters max for the retrieved resource strings,
but allocate a suitably-sized buffer IF the resource string is longer
than the fixed buffer. (Use the fixed buffer only if the string is shorter.)
- Introduce two helpers `LoadAllocStringW()` and `FormatAllocStringWV()`,
based on existing code from `DisplayMessageV()`, and use these for
`DisplayMessageV()`, `SetWindowResTextW()`, and `SetWindowResPrintfVW()`.
- Add missing translations in the Hindi file for:
`IDD_UPDATEREPAIRPAGE` and `IDD_SUMMARYPAGE` dialogs,
and `IDS_INSTALLATION_*` and `IDS_PARTITION_*` strings.
Addendum to commit f5960cea70 (PR #951).
- Update some sentences in the `IDD_UPDATEREPAIRPAGE` dialog.
- Harmonize the length of the `IDD_DEVICEPAGE` dialog comboboxes
amongst all the translations.
Addendum to commit ef268d1301 (r73577).
Magnify, OSK, and UtilMan shortcuts don't require a working directory
`%HOMEDRIVE%%HOMEPATH%`, since they don't access or save files into the
current user's directory. (And most of the time they run under the SYSTEM
account, for which neither the `%HOMEDRIVE%` nor `%HOMEPATH%` environment
variables exist.)
While it's true these shortcuts on Windows XP/2003 have their working
directory set to these values, on Windows 7+ at least this isn't the
case anymore.
- Make the menu contents more dynamic; inspired by PR #8871 by Ahmed Arif.
- advopts.c: Double-relicense ntldropts.c/h to GPL-2.0-or-later or MIT,
as most of the code in this file has been rewritten for years now.
- options.c (FreeLoader setup options menu):
Double-relicense options.c/h to GPL-2.0-or-later or MIT, as most
of the code in this file has been rewritten since commit 9ff4e4b9ef.
CORE-9069, CORE-13525, RELEASE-11
This new BootCD contains the functionality of both the original bootcd
(text-mode 1st-stage installer) and the livecd (that will include the
1st-stage GUI installer later).
Our separate livecd ISOs become obsolete, and this completely removes
the need for the so-called "hybridcd" ISO.
Some details:
- The "hybridcd" build target is completely removed, since now the new
BootCD *is* basically what we used to call "hybridcd".
- The "livecd" build target is kept so far (to minimize the code changes),
but internally I start to refer to it as "LiveImage", and is reduced
to a minimum.
A minimal non-bootable "liveimg.iso" is built (but currently not
included within the BootCD). Its purpose will be to implement the
"ReactOS Live" functionality as a RAMDISK.
(We currently don't support other file formats apart from ISO and
flat disk for a RAMDISK).
The "ReactOS Live" (non-RAMDISK) is implemented by adding to the
BootCD file tree the files from the LiveImage.
These files add two root directories, "Profiles" and "reactos"
(which is the SystemRoot for the non-ramdisk LiveImage).
- The minimal text-mode ReactOS installation used for the 1st-stage
installer, including USETUP itself, and the executable for the
1st-stage GUI installer and the reactos.cab (installation source),
are moved to the root directory called "i386" (ideally, one directory
per architecture).
- The "bootcdregtest" target, i.e. the ISOs we feed our testbots with,
are left untouched, i.e. they are only constituted of the 1st-stage
text-mode installation only, but placed in a per-architecture root
directory ("i386", etc. as for the bootcd).
- Remove the ACPI APIC/SMP entries from bootcd.ini. They will be made
available via the Advanced Boot Options F8 menu in Debug builds, for
testing purposes only, in a subsequent commit.
This commit is based upon an older SVN one:
svn path=/branches/setup_improvements/; revision=75273
And slightly improve the search loop.
- Unconditionally look into the root directory as well, in order to cover
all possible boot disk layouts in case someone customizes the ReactOS
boot media layout.
- Improve the `InfOpenFile()` call error handling, in order to show the
erroneous line _iff_ the call failed because of a wrong syntax in
TXTSETUP.SIF . Distinguish it from a failure because the file doesn't
exist in the source path being tested (in which case, no error is shown).
The legide.sys driver, introduced in commit ae2827f481, is compiled *ONLY*
for the x86 platform (not x64 nor the others) as specified in commit 7d33f7503b.
Fix the file installation copy by moving its entry into the x86-specific section.
Addendum to commit 7174935d73 (PR #8888). CORE-17256
These two registry values, stored in `HKEY_LOCAL_MACHINE\SYSTEM\Setup`,
are generated at runtime by the kernel; they are based on the current
values of: `LoaderBlock->NtHalPathName` and `LoaderBlock->ArcBootDeviceName`
respectively.
In particular, hardcoding `SystemPartition` to a default value
"\Device\Harddisk0\Partition1" , would be as random as hardcoding it
to anything else, since nothing justifies that there exists a partition
on the first harddisk, and if there is one, nothing guarantees that it
is one that was used to boot the operating system... Especially when
booting a LiveCD!
Addendum to commit c498d0930a.
`SmpTranslateSystemPartitionInformation()`: Reset the `DirInfo->Name.Buffer`
to use the `DirInfoBuffer` scratch area, before doing the OS boot drive letter
fallback. Otherwise, writing directly to `DirInfo->Name.Buffer` would
use its old value, that is going to be `NULL` when the calls to
`NtQueryDirectoryObject()` failed, and this would induce a memory access
crash.
Take also the opportunity to use structures embedding the
`KEY_VALUE_PARTIAL_INFORMATION` and `OBJECT_DIRECTORY_INFORMATION`
data headers, instead of straight `CHAR` arrays. This allows the
structures to use the correct memory alignments required by these
data headers.
instead of the MBR-specific PARTITION_TABLE_ENTRY structure.
Simplify also some aspects of the code:
- for MBR code, avoid copying around partition entries, but use
pointers instead;
- more generally, use the actual disk sector size instead of guessing,
and pass it to the partition interface routines.
This is the same fix for the same condition check, as the one already
applied to `IopCreateArcNamesDisk()` in commit 3fe12f1a7c.
This bug was introduced in commit 538b9e4fbf (r49212) and is identical
to the one introduced in commit 6d0861e9ed (r49131).
The idea behind the condition check, is that we consider the enumerated
disk to be a match with the currently-considered one from the ARC disk
signatures, *IF*:
- there is only one single disk listed in the ARC disk signatures,
*AND* only one single disk detected at runtime by the kernel,
*AND* this disk is MBR-partitioned;
- *OR*, there is one or more disks present and the enumerated disk's
signature match the currently-considered ARC disk signature. (This
is the more general case for when there are one or multiple disks
on the system, and/or one disk at least is GPT).
Addendum to commit 5ab1cfc553.
- Fix the drive letters assignment ordering for hard disks.
* Fix the loop that assigns letters to MBR boot and primary partitions;
* Fix the condition that finds the boot partition (or defaults to the
first primary partition) to be skipped when assigning letters to all
remaining hard-disk partitions -- after letters have been assigned
to the specific boot, primary, logical, etc. partitions.
NOTE: The drive-letter assignment algorithm is as follows:
1. For each hard disk, assign a letter to the first encountered boot
(MBR "active") partition; or if GPT disk, to all data partitions.
If no boot partition has been found on this disk, assign a letter
to all of its primary partitions.
2. Assign a letter to all (MBR) logical partitions for each hard disk.
3. Assign a letter to all remaining partitions with recognized IDs on
all disks.
****
We observe that the algorithm 1-3 is tailored for MBR-partitioned disks,
as it is inherited from the way MS-DOS did it. In addition, partitions
on GPT disks acquire their drive letters early one, during step 1.
****
4. Assign letters to floppy disks (see below), then to CD-ROMs.
5. Finally, verify that the OS boot volume has got a drive letter; if
not, get a free one (or delete the 'Z' drive letter and reassign it
to the boot volume).
(See also "Inside Storage Management, Part 1", Mark Russinovich,
https://www.digiater.nl/openvms/decus/vmslt00b/nt/storage-mgt-nt_2.htm
about the `IoAssignDriveLetters` function.)
- When assigning drive letters to floppy drives, first assign letters to
legacy (non-MountMgr-aware) devices, and then to MountMgr-aware devices.
Addendum to commit 5ab1cfc553.
- Static const-ify the `FloppyString` and `CdString` constants, that are
common to both `HalpNextDriveLetter()` and `xHalIoAssignDriveLetters()`.
- Improve code comments and variable names.
- In `xHalIoAssignDriveLetters()`:
* One of the two "generic string buffers" can be thrown away, since
we can already use the on-stack `Buffer`.
* No need to `sprintf` + `RtlInitAnsiString` + `RtlAnsiStringToUnicodeString`
with the risk of failing the conversion (that also allocates memory).
Instead, just invoke `swprintf` + `RtlInitUnicodeString` as already
done elsewhere in this function.
* Replace some '0' to 'FALSE' where applicable.
* Reduce indentation level of two for-loops.
- Compile their contents only when NDEBUG is _NOT_ defined.
- Only keep the first DPRINT in these functions in order to keep the
file path and line number, but replace the others with DbgPrint in
order to have a clearer printout.
- Fix a bug in FstubDbgPrintSetPartitionEx(), where PartitionNumber has
to be used as an indicator parameter but MUST NOT be used to index the
PartitionEntry pointer. (PartitionEntry already points to the data for
setting the partition specified by PartitionNumber.)
The bug certainly came from a copy-pasting error from FstubDbgPrintPartitionEx().
In `SmpTranslateSystemPartitionInformation()`, fall back to using the
OS boot drive letter if none was found to be assigned to the SystemPartition.
Otherwise, just fail if any other error was encountered.
(This behaviour has been introduced in a post-SP1 Windows 7 update.)
Additionally, simplify very slightly the code.
- `ArcBootDeviceName`: Given a theoretically valid ARC boot path
of the form:
`multi(0)disk(0)rdisk(0)partition(2)ReactOS\\weird)name`
correctly determine `ArcBootDeviceName` to be:
`multi(0)disk(0)rdisk(0)partition(2)`
and `SystemRoot` to be what follows it:
`ReactOS\\weird)name`
Usual paths like: `multi(0)disk(0)rdisk(0)partition(2)\\ReactOS`
are still correctly handled, of course.
- The `ArcHalDeviceName` path is the ARC path to the system partition,
where the firmware started the bootloader from. For historical reasons
it's called Arc **HAL**, because on older (and non-x86) Windows versions
the HAL was to be placed next to the OS loader in the system partition,
while the rest of the OS (kernel, etc.) was placed elsewhere.
So, in order to correctly set `ArcHalDeviceName`, pass the determined
SystemPartition all the way down to `WinLdrInitializePhase1()`.
This has been forgotten since the split of `IopCreateArcNames()`
in commit 6d0861e9ed (r49131).
Also, improve comments regarding `ArcHalDeviceName` vs. `ArcBootDeviceName`.
In the `HKLM\SYSTEM\CurrentControlSet\Control` registry key,
the `FirmwareBootDevice` value specifies the firmware boot
(i.e. system partition) device in ARC format, obtained from
`LoaderBlock->ArcHalDeviceName`.
For some reason it is exposed only on Windows Vista and later.
This value is similar to the `SystemBootDevice` one, which specifies
instead the OS boot device in ARC format, obtained from
`LoaderBlock->ArcBootDeviceName`.
In addition: check the value returned by `RtlCreateUnicodeStringFromAsciiz()`
and fail if so.
Instead of mixing the paths order (ArcBoot, NtHal, ArcHal, NtBoot),
show them in a meaningful order: ArcHal, NtHal, ArcBoot, NtBoot.
- The `ArcHalDeviceName` + `NtHalPathName` is the path to the system
loader started by the firmware (and the HAL in old non-x86 Windows
versions).
- The `ArcBootDeviceName` + `NtBootPathName` is the operating system
boot partition and directory ("system root").
For fixed-disks (i.e. not floppy nor CD-ROM), check in `disk.c!DiskInitialize()`
whether the disk being enumerated is GPT. If so, retrieve its disk GUID.
Pass this information to `AddReactOSArcDiskInfo()` when filling the ARC
disk information block, which sets the `IsGpt` and `GptSignature` members
of the `ARC_DISK_SIGNATURE` structure accordingly.
Debugging output example, where the first disk (0x80) is MBR, while the
second (0x81) is GPT:
```
(freeldr\disk\disk.c:100) err: DiskInitialize(0x80, 'multi(0)disk(0)rdisk(0)', Type: 25)
(freeldr\disk\disk.c:125) err: Signature: 163fbb9d
(freeldr\disk\disk.c:134) err: Checksum: 47699104
(freeldr\disk\disk.c:137) err: IsPartitionValid: TRUE
(freeldr\disk\disk.c:100) err: DiskInitialize(0x81, 'multi(0)disk(0)rdisk(1)', Type: 25)
(freeldr\disk\disk.c:125) err: Signature: 0
(freeldr\disk\disk.c:134) err: Checksum: 9cb5ff90
(freeldr\disk\disk.c:137) err: IsPartitionValid: TRUE
(freeldr\disk\disk.c:157) err: Disk 0x81 is GPT, DiskGuid: {1e4e8972-e026-4d5f-b213-7be3f2fad3f8}
```
----
This fixes the BSOD 0x7B `INACCESSIBLE_BOOT_DEVICE` that happens when
trying to boot a ReactOS installation present in a partition on a GPT
partitioned disk.
In the kernel IO manager:
`IopCreateArcNamesDisk()`, invoked by `IopCreateArcNames()`, tries to
map the list of disks dynamically detected by the boot disk drivers
with those detected by the bootloader, by matching their disk signatures.
- The signatures of the disks detected by the boot disk drivers are
obtained when querying their drive layout and partition table (which
also tells whether the disk is MBR or GPT partitioned);
- while the signatures of the disks detected by the bootloader are
enumerated in the `LoaderBlock->ArcDiskInformation->DiskSignatureListHead`
linked-list (inside `ARC_DISK_SIGNATURE` structures).
The routine compares the disk signatures by invoking `IopVerifyDiskSignature()`,
which, depending on whether the disk is MBR or GPT (as reported in the
drive layout), compares the signature with that of `ARC_DISK_SIGNATURE`
`Signature` (for MBR) or `GptSignature` (for GPT) structure members.
In case the boot disk turns out to not be mapped -- which was the case
until now if it was GPT-partitioned -- then the `IopMarkBootPartition()`
routine invoked later, wouldn't be able to find and open the boot disk,
and would trigger the BSOD 0x7B, as the result.
so that it can be used for other platforms.
Based upon suggestions by Daniel Victor (@iLauncherDev).
partition.c: Double-license GPL-2.0-or-later and MIT
As implicitly implied by the MSDN description for `IoGetAttachedDevice()`:
https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/nf-ntifs-iogetattacheddevice
> IoGetAttachedDevice differs from IoGetAttachedDeviceReference in the
> following respects:
>
> [...]
>
> - Callers of IoGetAttachedDevice must ensure that no device objects are
> added to or removed from the stack while IoGetAttachedDevice is executing.
> Callers that cannot do this must use IoGetAttachedDeviceReference instead.
the `IoGetAttachedDeviceReference()` has to acquire the device list lock
to ensure that no device objects get added to or removed from the device
stack during its invocation.
Similarly, `IoGetDeviceAttachmentBaseRef()` has to do the same.
This function is the internal helper for the `IoAttachDevice*()` functions,
in particular for `IoAttachDeviceToDeviceStackSafe()`.
Because the function modifies the chained list of stacked devices, it must
hold the device list lock (the I/O system database lock) while doing the
devices attachment.
In particular, modifying the `SourceDevice`'s extension `AttachedTo` field,
but also modifying its other fields and the `AttachedDevice` ones as well.
This fix is similar to the one already committed in f8cbc3e48c (r70496).
----
In MSDN [^1] it is indicated (although not as clearly as it could be) that
`IoAttachDeviceToDeviceStackSafe()` sets the returned `AttachedToDeviceObject`
pointer under the device list lock. The reason is best spelled in [^2][^3].
Indeed, when a filter attaches to a lower PDO (`PhysicalDevice`) by doing:
```c
myDeviceExtension->LowerDevice =
IoAttachDeviceToDeviceStack(myFilterDevice, PhysicalDevice);
```
there exists a time window where the function finished attaching the filter
device to the PDO, but hasn't yet returned the device at the top of the
stack to be stored in `myDeviceExtension->LowerDevice` (which gets used
later internally by the filter to pass IRPs down the device stack).
During this time, the filter device may receive some IRPs and its
dispatch routine would use a not-yet initialized `LowerDevice` member.
The IoAttachDeviceToDeviceStackSafe() allows doing:
```c
Status = IoAttachDeviceToDeviceStackSafe(
myFilterDevice, PhysicalDevice, &myDeviceExtension->LowerDevice);
```
and forbidding the IRPs to be delivered to the filter device, while the
`LowerDevice` member is being initialized with the device list lock held.
----
[^1]: "IoAttachDeviceToDeviceStackSafe function (ntddk.h)"
https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntddk/nf-ntddk-ioattachdevicetodevicestacksafe#remarks
[^2]: "IoAttachDeviceToDeviceStack gotcha" (Satya Das, Winprogger)
https://winprogger.com/ioattachdevicetodevicestack-gotcha/
[^3]: Community OSR answer (by Tony Mason)
https://community.osr.com/t/attach-filter-driver/9450/3
CORE-9023
In case FREELDR.INI is missing, or there are no operating systems listed
and available (either the corresponding section is missing, or is empty),
fall back to the FreeLoader Setup and Configuration F2 menu, that allows
performing a minimal number of operations (enabling FreeLoader debugging;
doing a custom boot... and more to come!)
Fix also a bug in `InitOperatingSystemList()`, that would allow
allocating an empty list with zero items. Now it returns NULL if
no operating systems are found.
Default to the Minimal text UI instead of the fullfledged one, if no
"MinimalUI" option can be found in FREELDR.INI (or if the INI is missing).
CORE-9023
Make also the advanced boot menu depend on the operating system type.
It can be opened by pressing F8, or F5, as in the Windows' bootloader.
The FreeLoader-specific options are moved to a separate menu,
accessible via the F2 key from the main menu.
Work-in-progress: display the boot options that correspond to the
currently-selected boot entry.