Implement MmAllocateMappingAddress and MmFreeMappingAddress routines.
Based on mm-implement-mappingaddress.patch by Thomas Faber with some changes from me.
Required by Microsoft NTFS driver (from Windows Server 2003 SP2 only, the one from Windows XP SP3 does not need them) and by NDIS & TDI drivers (both from Windows XP SP3 and Windows Server 2003 SP2). Also they are called when using Dr. Web Security Space 8 filter drivers together with MS FltMgr & TDI.
Fortunately, this part (these two routines) are enough to get the drivers working in both cases, and others (partially incomplete) routines are not badly required, so they can be finished and committed later.
CORE-10147, CORE-14635, CORE-17409, CORE-19318
Fix warnings:
E:\3rdRepo\ReactOS_Fork4\ntoskrnl\ex\keyedevt.c(458): warning C6387: 'Timeout' could be '0': this does not adhere to the specification for the function 'ExpWaitForKeyedEvent'.
E:\3rdRepo\ReactOS_Fork4\ntoskrnl\ex\keyedevt.c(527): warning C6387: 'Timeout' could be '0': this does not adhere to the specification for the function 'ExpReleaseKeyedEvent'.
JIRA issue: None.
Proposed changes
Timeout parameter of those two functions should be optional.
KeFlushQueuedDpcs is used by some drivers, when unloading or removing a device, to be sure no DPC is still running their code. On a UP system this can be done "inline", on an SMP system, it requires to send an IPI to each processor that has DPCs queued and also synchronize it with the calling thread, which is what KeSetSystemAffinityThread does implicitly: When a queued DPC was detected on a remote processor (implying that processor is currently running at DISPATCH_LEVEL or above), KeSetSystemAffinityThread will schedule the current thread on that processor and send a DPC interrupt. The remote processor will handle that DPC interrupt once it is back below DISPATCH_LEVEL. It will only run the current thread, after all queued DPCs (including threaded DPCs) have finished running.
Addendum to commit baa47fa5e.
Similarly to what was originally done, have KdbpCliInterpretInitFile()
parse the KDBinit file by breaking back into the debugger.
But contrary to before, replace the deprecated call to KdbEnter() by
a standard DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C) . This allows
KdbEnterDebuggerException() to do the KdbpCliInterpretInitFile() call.
Additional fixes and improvements:
- Run KdbpCliInterpretInitFile() in full KDBG environment (interrupts
disabled, modified IRQL, own stack), like the usual interactive loop.
- The KDBinit data buffer must be in non-paged pool.
- Demote the "Could not open KDBinit" error to a DPRINT, so that it
doesn't pollute the debug log when the KDBG init function is called
early (before the storage stack is initialized), or if the file
doesn't exist -- since this is an optional feature.
- Move the printing pager state reset code (setting the number of
printed rows and columns to zero, and the output aborted flag)
to KdbpDoCommand(). This allows to keep the original behaviour,
while also inheriting it whenever KdbpDoCommand() is invoked
elsewhere (for example, from KdbpCliInterpretInitFile()).
- Use KdbPuts/Printf() instead of KdbpPrint() for the entry banners,
so that they aren't subject to the current printing pager state.
Do the same for the "command unknown" error in KdbpDoCommand().
- Add a "Type 'help' for a list of commands" banner, for the users.
- Replace the do-while-loop with a simple while-loop.
Previously FsRtlNotifyVolumeEvent would pass a pointer to a TARGET_DEVICE_CUSTOM_NOTIFICATION structure on the stack to IoReportTargetDeviceChangeAsynchronous, which would store a pointer to it in a work-item and process that after the stack object was already out of scope. This broke x64 boot. Started happening after recent fixes to IoReportTargetDeviceChangeAsynchronous.
Looks like public symbols contain this structure starting with Win7,
so we can deduce what it looked like in Win2003.
Note that our previous definition was missing a second ULONG at the
end, which can be seen in the SeQueryInfoToken kmtest -- if you
allocated only sizeof(AUX_ACCESS_DATA), the test would crash with
a 4 byte buffer overflow.
Pass a proper write/execute flag in the ExceptionInformation[0] field of the exception record instead of the raw fault code. This fixes comdlg:filedlg wine test, which writes to a write protected resource section, which needs to be handled by kernel32 UnhandledExceptionFilter, which relies on this parameter to be correct.
According to our declaration/definition, IoChangeFileObjectFilerContext returns NTSTATUS, not BOOLEAN. Zero return (which was actually checked before) for BOOLEAN means failure, but for NTSTATUS it's success. So it should (and now actually does) free and fail appropriately only in failure case, but not in success, when it shouldn't.
This fixes most of problems with fltmgr.sys driver from Windows XP/Server 2003 and a lot of 3rd party filter drivers which use it from many apps (Avast Free Antivirus all versions, Avira AntiVir Personal 8.2, Dr. Web Security Space 8.0, Kaspersky Antivirus 2012 etc. etc.).
CORE-14157, CORE-14635, CORE-19318
Implement undocumented MmProbeAndLockProcessPages routine. Based on mm-implement-mappingaddress.patch by Thomas Faber from CORE-10147, with some improvements from me.
It's badly required by FltMgr.sys driver from Windows XP/Server 2003 and closely used by a lot of apps those are depending on this driver (e. g., Avast Free Antivirus several versions, Avira Antivir Personal 8.2 etc. etc.).
Fixes several asserts from MDL support routines when the 3rd-party minifilter drivers are loading FltMgr.
CORE-14157
The PR #6649 which fixed an issue with orphaned KCBs leaking in memory which also pointed to unloaded registry hives, it also brought a problem.
In CmpEnumerateOpenSubKeys there is a risk of getting hit by a deadlock as we enumerate the cache table to remove empty cache entries.
Fundamentally CmpEnumerateOpenSubKeys locks down a KCB from cache for exclusive use in order to tear down its contents from memory but it doesn't address the fact a KCB might have already been locked in the same calling thread, leading to a recursion.
This leads to random hangs when unloading a hive during system startup (tipically on a clean install).
The solution here is to simply lock the whole registry when we unload a hive so that we don't have to worry the KCBs are getting tampered by anybody else. This also simplifies the code.
Although locking the entire registry while other apps are doing registry related operations to other hives can cause overhead. If this turns out to be bad then we have to rethink the locking mechanism here.
CORE-19539
* [NTOS:MM] section.c: Remove unused functions
MiSetControlAreaSymbolsLoaded(),
MiLoadUserSymbols():
Added on 436edb2 (r60802). Never used.
MiSubsectionConsistent():
Added on cda03c0 (r57209). Never used.
MiGetFileObjectForSectionAddress():
Added on 635d9ca (r67810). Calls removed on 0dfd233 (r68123).
MiSetProtectionOnSection():
Added on 9f28638 (r56317). Never used.
Plus,
MmCreateArm3Section():
Add an UNIMPLEMENTED on a specific case.
* [NTOS:MM] section.c: Use static instead of NTAPI for local functions
* [NTOS:EX] Various fixes for Daylight Saving Time transitions
* Fix automatic time changes when DST starts and ends.
* Currently it takes two cycles of the update provided by w32time to make the actual change.
* Convert Eric Kohl's TimeZoneID code contained in ExRefreshTimeZoneInformation to a new function.
* Use this new function in ExpSetTimeZoneInformation and ExRefreshTimeZoneInformation functions.
CORE-19290
Follow-up to commit 24a14abf2 (r57412).
HBelusca's comment:
> If this ExFreePoolWithTag() call was left commented, it's probably
> because, back in the day where I introduced it, there was a pool
> corruption that was detected, the source of which was unknown at
> that time. In retrospect, it is most probably the interrupt disconnect
> bug in IoDisconnectInterrupt() that was causing it. Now that this
> bug has been fixed just previously, it should be safe to re-enable
> pool freeing with tag.
- Fix annotations
- Don't use KiServiceExit to return to the caller with an error code, instead just return from the function, that is the same thing.
- Refactor failure path
- Add DPRINTs on failure
- Implement KiExceptionExit, which works like KiServiceExit2, but takes an exception frame as 2nd parameter
- Add a local exception frame to NtRaiseException and NtContinue, which is needed to exit with a full context on x64 and arm
- Use KeContextToTrapFrame again instead of KiSetTrapContext, since we have a proper exception frame now.
* [NTOS:CC] Restore unlock and reacquire locks around MmPageOutPhysicalAddress which was mistakenly lost in commit 2b14056
* Add bypass for problematic code path for now
ExAllocatePoolWithTag doesn't raise an exception on failure, only ExAllocatePoolWithQuotaTag does. Use that when quotas are relevant instead of silently continuing with a NULL pointer.