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).
- Set the ip address, subnet mask and default gateway when an alternate configuration has been configured.
- Set registry values for the alternate configuration and APIPA.
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.
Follow-up of #8846. Now <jpnvkeys.h>
is useless. Minor refactoring and
standardation.
JIRA issue: CORE-19268
- Replace <jpnvkeys.h> usage with
<wine/ime.h> and fix
VK_DBE_ENTERIMECONFIGMODE
naming.
- Remove duplicated
WM_IME_REPORT/IR_* and
UNDETERMINESTRUCT definitions
now provided by wine/ime.h.
- Introduce win3send.c half-
implementing
ImmSendIMEMessageExA/W.
- Add CMake option
IMM_WIN3_SUPPORT (default: ON).
Prepare for CTF IME support.
JIRA issue: CORE-19268
- Add GCS_PRIVATE (0x8000) constant,
COMPSTR_PRIVATE structure, and
CtfImmIsGuidMapEnable prototype
to <imm32_undoc.h>.
- Implement GCS_PRIVATE index in
ImmGetCompositionStringA/W.
- `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
This fixes boot regression on Xbox, introduced in 3964c936cb.
A new `call writestr` on early boot leads to `writechr` helper call,
which uses INT 10h BIOS service. This ends up in early boot crash,
as the original Xbox doesn't have VGA BIOS, nor the BIOS Data Area.
Fix the problem by adding Xbox-specific assembly helpers.
CORE-16216, CORE-19882
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
A bug fix of FontLink'ed glyph size.
JIRA issue: CORE-20470
- Add FONTLINK_ENTRY structure
and g_FontLinkEntries variable.
- Delete font-link cache mechanism.
- Don't access the registry while
rendering is in progress.
- Request sub-font sizes while
drawing FontLink text.
CORE-20539
Before calling "fs_write" test if we are in a read-write mode by checking "rw".
I intend to re-evaluate this to try and reduce the difference to dosfschk in the future.
Co-authored-by: Hermès BÉLUSCA - MAÏTO <hermes.belusca-maito@reactos.org>
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).