https://git.reactos.org/?p=reactos.git;a=commitdiff;h=ce537f1ae945813041cad…
commit ce537f1ae945813041cad50f0853a5a16d11bc20
Author: Timo Kreuzer <timo.kreuzer(a)reactos.org>
AuthorDate: Thu May 30 19:21:45 2019 +0200
Commit: Timo Kreuzer <timo.kreuzer(a)reactos.org>
CommitDate: Fri Jun 4 09:15:55 2021 +0200
[EXPLORER] Check m_Position for -1 before using it as an index
This fixes a crash on x64.
---
base/shell/explorer/traywnd.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/base/shell/explorer/traywnd.cpp b/base/shell/explorer/traywnd.cpp
index 5473e190bfa..e14e805b8f7 100644
--- a/base/shell/explorer/traywnd.cpp
+++ b/base/shell/explorer/traywnd.cpp
@@ -1373,7 +1373,7 @@ GetPrimaryScreenRect:
m_TrayRects[m_Position] = rcTray;
}
- else
+ else if (m_Position != (DWORD)-1)
{
/* If the user isn't resizing the tray window we need to make sure the
new size or position is valid. this is to prevent changes to the window
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=e801b7dda25a1e2a70206…
commit e801b7dda25a1e2a702065fd72be01e18fdd4c00
Author: Timo Kreuzer <timo.kreuzer(a)reactos.org>
AuthorDate: Tue May 15 14:05:19 2018 +0200
Commit: Timo Kreuzer <timo.kreuzer(a)reactos.org>
CommitDate: Wed Jun 2 18:25:36 2021 +0200
[RTL/x64] Implement RtlpCaptureNonVolatileContextPointers and RtlSetUnwindContext
RtlpCaptureNonVolatileContextPointers walks the stack and captures the addresses of all non-volatile registers on the stack, when they have been saved first. This is needed to be able to fix up the non-volatile on a system call, which doesn't capture non-volatiles, but relies on them to be restored by the callees.
Instead of only checking for the TargetFrame, also check for a mode change, i.e. RIP went from kernel to user, in which case the target frame was not reached yet, because it was too large, but processing can't continue here.
RtlSetUnwindContext uses RtlpCaptureNonVolatileContextPointers to set the non-volatile registers in the the stack. They will be picked up, when returning back or unwinding, e.g. to the system call handler.
---
sdk/lib/rtl/amd64/unwind.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 71 insertions(+)
diff --git a/sdk/lib/rtl/amd64/unwind.c b/sdk/lib/rtl/amd64/unwind.c
index 989669e97f7..26a7610d250 100644
--- a/sdk/lib/rtl/amd64/unwind.c
+++ b/sdk/lib/rtl/amd64/unwind.c
@@ -687,3 +687,74 @@ RtlRaiseException(IN PEXCEPTION_RECORD ExceptionRecord)
RtlRaiseStatus(Status);
}
+static
+VOID
+RtlpCaptureNonVolatileContextPointers(
+ _Out_ PKNONVOLATILE_CONTEXT_POINTERS NonvolatileContextPointers,
+ _In_ ULONG64 TargetFrame)
+{
+ CONTEXT Context;
+ PRUNTIME_FUNCTION FunctionEntry;
+ ULONG64 ImageBase;
+ PVOID HandlerData;
+ ULONG64 EstablisherFrame;
+
+ /* Zero out the nonvolatile context pointers */
+ RtlZeroMemory(NonvolatileContextPointers, sizeof(*NonvolatileContextPointers));
+
+ /* Capture the current context */
+ RtlCaptureContext(&Context);
+
+ do
+ {
+ /* Look up the function entry */
+ FunctionEntry = RtlLookupFunctionEntry(Context.Rip, &ImageBase, NULL);
+ ASSERT(FunctionEntry != NULL);
+
+ /* Do a virtual unwind to the caller and capture saved non-volatiles */
+ RtlVirtualUnwind(UNW_FLAG_EHANDLER,
+ ImageBase,
+ Context.Rip,
+ FunctionEntry,
+ &Context,
+ &HandlerData,
+ &EstablisherFrame,
+ NonvolatileContextPointers);
+
+ /* Make sure nothing fishy is going on. Currently this is for kernel mode only. */
+ ASSERT(EstablisherFrame != 0);
+ ASSERT((LONG64)Context.Rip < 0);
+
+ /* Continue until we reached the target frame or user mode */
+ } while (EstablisherFrame < TargetFrame);
+
+ /* If the caller did the right thing, we should get exactly the target frame */
+ ASSERT(EstablisherFrame == TargetFrame);
+}
+
+VOID
+RtlSetUnwindContext(
+ _In_ PCONTEXT Context,
+ _In_ DWORD64 TargetFrame)
+{
+ KNONVOLATILE_CONTEXT_POINTERS ContextPointers;
+
+ /* Capture pointers to the non-volatiles up to the target frame */
+ RtlpCaptureNonVolatileContextPointers(&ContextPointers, TargetFrame);
+
+ /* Copy the nonvolatiles to the captured locations */
+ *ContextPointers.R12 = Context->R12;
+ *ContextPointers.R13 = Context->R13;
+ *ContextPointers.R14 = Context->R14;
+ *ContextPointers.R15 = Context->R15;
+ *ContextPointers.Xmm6 = Context->Xmm6;
+ *ContextPointers.Xmm7 = Context->Xmm7;
+ *ContextPointers.Xmm8 = Context->Xmm8;
+ *ContextPointers.Xmm9 = Context->Xmm9;
+ *ContextPointers.Xmm10 = Context->Xmm10;
+ *ContextPointers.Xmm11 = Context->Xmm11;
+ *ContextPointers.Xmm12 = Context->Xmm12;
+ *ContextPointers.Xmm13 = Context->Xmm13;
+ *ContextPointers.Xmm14 = Context->Xmm14;
+ *ContextPointers.Xmm15 = Context->Xmm15;
+}