- In RtlInitializeContext only set the registers required, don't offset RSP
- In KiInitializeContextThread force control segments, which are not set by RtlInitializeContext
- Allocate the stack home space in KiInitializeContextThread
- Fix BaseInitializeContext to work with the changed stack adjustments
Validate ACCESS_SYSTEM_SECURITY access requests when creating a new
handle in ObpIncrementHandleCount.
- Check for SeSecurityPrivilege (with SeSinglePrivilegeCheck) when a
caller requests ACCESS_SYSTEM_SECURITY on handle creation.
- Take away ACCESS_SYSTEM_SECURITY from RemainingDesiredAccess /
PreviouslyGrantedAccess if the privilege isn't held.
FsRtlCheckLockForReadAccess() accepts access through an exclusive
byte-range lock when the IRP key matches, even if another process
owns the lock. FsRtlFastUnlockAll() likewise removes exclusive locks
without checking the Process argument.
Require both the key and requestor process for exclusive-read access,
and skip exclusive locks owned by other processes in FsRtlFastUnlockAll().
This matches the ownership checks already used by
FsRtlFastCheckLockForRead() and FsRtlFastUnlockAllByKey().
Reference:
- https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/nf-ntifs-_fsrtl_advanced_fcb_header-fsrtlfastchecklockforread
MmFreeContiguousMemory() is callable at up to DISPATCH_LEVEL,
but MiFreeContiguousMemory() used PAGED_CODE(), which incorrectly asserted
above APC_LEVEL in checked builds.
Replace it with an assertion that enforces the exported IRQL contract.
IopDereferenceVpbAndFree frees a zero-reference VPB only while it is still
installed in RealDevice->Vpb. This can leave the device with a dangling
VPB pointer while detached VPBs are retained.
Reverse the identity test so only a detached, nonpersistent VPB is released
after its reference count reaches zero.
Reference:
- https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/ns-wdm-_vpb
MmUnloadSystemImage() had an explicit leak placeholder for driver images.
Implement the MmUnloadSystemImage() that performs matching teardown
for the image mappings, releasing the reserved system PTE range.
Also fix similar leak in MiLoadImageSection() by releasing image mappings
after load failures.
CORE-8294
Note that the driver images loaded at boot, which were not reloaded by
MiReloadBootLoadedDrivers(), remain at their loader-assigned addresses
and do not own system PTEs.
Root cause: CcRosDeleteFileCache's first loop ran under the spinlock and removed VACBs from the LRU and dirty lists, but left them in CacheMapVacbListHead. It also set Vacb->Dirty = TRUE as a flush hint (after CcRosUnmarkDirtyVacb cleared it), creating an inconsistent VACB state: Dirty=TRUE but not in the dirty list, with only the cache-map-list refcount (1). After releasing the lock, the second loop removed VACBs from CacheMapVacbListHead without holding any lock.
This created a race with CcFlushCache: a caller that already held a SharedCacheMap pointer could call CcRosLookupVacb between the two loops, find the VACB (refcount → 2), see Dirty=TRUE (the hack), and call CcRosFlushVacb. Meanwhile the second loop could set Dirty=FALSE, drop the cmap ref (→1, print "Leaking VACB"), and then the early-return in CcRosUnmarkDirtyVacb would skip the decrement. CcRosReleaseVacb then drops 1→0 → ASSERT(Refs > 0) fires.
Before the previous fix, the same race caused ASSERT(Vacb->Dirty) in the old CcRosUnmarkDirtyVacb — the previous fix just changed which assert fired.
The fix:
- CcRosDeleteFileCache: VACBs are now removed from CacheMapVacbListHead in the first loop, under the spinlock, and moved to a private LocalVacbList. After the lock is released, CcRosLookupVacb can no longer find these VACBs, preventing new lookup references from being created.
- CcRosReleaseVacb: Removed the overly strict ASSERT(Refs > 0). When CcRosDeleteFileCache drops the cmap ref while a lookup is outstanding, CcRosReleaseVacb legitimately releases the last reference and CcRosVacbDecRefCount correctly frees the VACB. Callers (e.g., CcFlushCache) don't access the VACB pointer afterward.
Signed-off-by: Timo Kreuzer <[email protected]>
- CcRosUnmarkDirtyVacb: return BOOLEAN, guard against double-unmark
- CcRosMarkDirtyVacb: guard against double-insertion
- CcRosFlushVacb: only re-mark dirty on failure if we were the one who unmarked
- Add comments to lockless Dirty reads in CcFlushCache and CcRosReleaseVacb
Signed-off-by: Timo Kreuzer <[email protected]>
The stub returns STATUS_INVALID_INFO_CLASS rather than STATUS_NOT_IMPLEMENTED.
This is a temporary measure to indicate to ntdll_winetest that this system information class is not implemented and prevent the test from crashing.
- 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).
This is needed for PCI debugging devices whose KD modules depend
on the functions registered in HalpRegisterKdSupportFunctions().
Also it's consistent with what x86 does, and also what Win7 x64 does
(the KdInitSystem is invoked after the HalInitializeProcessor call).
Necessary for PR #9156 on AMD64. CORE-20385
FstubCreateDiskRaw is supposed to wipe the MBR when it makes a RAW disk.
Before this fix, that function only cleared the first of the 4 partition entries, so one entry (16 bytes) instead of the whole table (64).
As a consequence, the wiped MBR written back to disk still had entries 2, 3 and 4 sitting there with old data, and those came back as ghost/garbage partitions.
- Use a global structure instead of pointer
- Allocate only the GUID buffer
- Keep track of allocated size and number of GUIDs
- Grow in steps of 8 GUIDs
- Use ExAllocatePoolWithTag instead of ExAllocatePool
- Use IsEqualGUID
See CORE-12791
- Don't compile the non-conformng swprintf (it is identical to _swprinf)
- Rename swprintf to _swprintf
- Forward non-conforming exports to the underscored versions in CRT dlls
Fix KiWriteSystemTime and move it to NDK. The previous implementation of KiWriteSystemTime was broken and updated the fields in the wrong order. Before that it was right for SystemTime and wrong for InterruptTime. ExpSetTimeZoneInformation had it wrong for the TimeZoneBias.
Add KiReadSystemTime to read KSYSTEM_TIME values correctly, instead of doing it manually (and partly wrongly) all over the place.
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.