Major refactoring of the exception handling code + misc fixes:
- Fix/add prototypes for RtlCaptureContext, RtlDispatchException and RtlUnwind
- Fix EXCEPTION_REGISTRATION_RECORD structure and PEXCEPTION_ROUTINE
- Add w32api excpt.h (based on mingw) with PSDK compatibility fixes
- Fix seriously broken User-Mode Ldr thunk and APC Callback prototypes
- Fix KiUserExceptionDispatcher
- Remove useless NTDLL entrypoint
- Implement NTDLL Ki* callbacks in ASM
- Implement RtlCaptureContext
- Fix RtlRaiseException to handle cases when a user-mode debugger is present
- Fix RtlRaiseStatus as above, plus set the exception address and capture context
- Little cleanup of RTL headers
- Implement RtlpGetStackLimits, RtlpGetExceptionList, RtlpSetExceptionList, RtlpGetExceptionAddress in ASM
- Fix RtlDispatchException, add cases for exceptions in the DPC stack and validate the validity of the
exception frames. Add support for exception logging by the global flag. Use TRAP_FRAME/EXCPETION_FRAME instead of
Context.
- Fix RtlUnwind logic, support cases where it's called with custom arguments instead of NULL.
- Reimplement RtlpCaptureContext to work properly, convert exception handler calling functions to INTEL syntax
and fix some bugs (like checking for the right unwind flag, clearing volatile register values, etc. Also use some
optimizations to increase speed.
- Modify some kernel functions (like KeContextToTrapFrame, KiDispatchException, KiInitializeUserApc, etc.) to
support a PKEXCEPTION_FRAME for future PPC compatibility.
- Reimplement RtlCaptureUnicodeString/FreeUnicodeString as inlined probe macros and optimize them.
- Export ExRaiseStatus/Exception as Rtl*
- Reimplement NtContinue to have more platform-independent code, and to protect and validate user-mode context
and parameters with SEH.
- Implement KiRaiseException, add SEH to all user-mode parameters and when copying data to the user-mode stack.
- Fix KiInitializeUserApc to use KeTrapFrameToContext, to save the debug registers, not to deliver APCs during
v86 mode, and to protect user-mode stack operations in SEH and probing. Also make it generate the proper stack for the
user-mode callback.
- Implement KiUnexpectedInterrupt and KiCoprocessorError
- Reimplement NtRaiseException in ASM to take advantage of optimizations due to the trap frame being in the
stack when called through System call interface.
- Fix Ntcontinue to respect AlertThread paramter
- Fix some functiosn to return with KiServiceExit2 instead of KiServiceExit when required/needed
- Fix KiDispatchException's logic, fix hacks when calling KeUserExceptionDispatcher, use correct context
flags,...
- Make NTDLL Ki* callbacks have SEH to protect them and return to kernel-mode with notification of any
exceptions (the kernel-mode code to handle this isn't written yet though)
svn path=/trunk/; revision=17811
2005-09-11 22:32:20 +00:00
|
|
|
/*
|
2004-05-31 19:45:16 +00:00
|
|
|
* COPYRIGHT: See COPYING in the top level directory
|
2005-01-26 13:58:37 +00:00
|
|
|
* PROJECT: ReactOS kernel
|
|
|
|
* FILE: ntoskrnl/rtl/libsupp.c
|
Major refactoring of the exception handling code + misc fixes:
- Fix/add prototypes for RtlCaptureContext, RtlDispatchException and RtlUnwind
- Fix EXCEPTION_REGISTRATION_RECORD structure and PEXCEPTION_ROUTINE
- Add w32api excpt.h (based on mingw) with PSDK compatibility fixes
- Fix seriously broken User-Mode Ldr thunk and APC Callback prototypes
- Fix KiUserExceptionDispatcher
- Remove useless NTDLL entrypoint
- Implement NTDLL Ki* callbacks in ASM
- Implement RtlCaptureContext
- Fix RtlRaiseException to handle cases when a user-mode debugger is present
- Fix RtlRaiseStatus as above, plus set the exception address and capture context
- Little cleanup of RTL headers
- Implement RtlpGetStackLimits, RtlpGetExceptionList, RtlpSetExceptionList, RtlpGetExceptionAddress in ASM
- Fix RtlDispatchException, add cases for exceptions in the DPC stack and validate the validity of the
exception frames. Add support for exception logging by the global flag. Use TRAP_FRAME/EXCPETION_FRAME instead of
Context.
- Fix RtlUnwind logic, support cases where it's called with custom arguments instead of NULL.
- Reimplement RtlpCaptureContext to work properly, convert exception handler calling functions to INTEL syntax
and fix some bugs (like checking for the right unwind flag, clearing volatile register values, etc. Also use some
optimizations to increase speed.
- Modify some kernel functions (like KeContextToTrapFrame, KiDispatchException, KiInitializeUserApc, etc.) to
support a PKEXCEPTION_FRAME for future PPC compatibility.
- Reimplement RtlCaptureUnicodeString/FreeUnicodeString as inlined probe macros and optimize them.
- Export ExRaiseStatus/Exception as Rtl*
- Reimplement NtContinue to have more platform-independent code, and to protect and validate user-mode context
and parameters with SEH.
- Implement KiRaiseException, add SEH to all user-mode parameters and when copying data to the user-mode stack.
- Fix KiInitializeUserApc to use KeTrapFrameToContext, to save the debug registers, not to deliver APCs during
v86 mode, and to protect user-mode stack operations in SEH and probing. Also make it generate the proper stack for the
user-mode callback.
- Implement KiUnexpectedInterrupt and KiCoprocessorError
- Reimplement NtRaiseException in ASM to take advantage of optimizations due to the trap frame being in the
stack when called through System call interface.
- Fix Ntcontinue to respect AlertThread paramter
- Fix some functiosn to return with KiServiceExit2 instead of KiServiceExit when required/needed
- Fix KiDispatchException's logic, fix hacks when calling KeUserExceptionDispatcher, use correct context
flags,...
- Make NTDLL Ki* callbacks have SEH to protect them and return to kernel-mode with notification of any
exceptions (the kernel-mode code to handle this isn't written yet though)
svn path=/trunk/; revision=17811
2005-09-11 22:32:20 +00:00
|
|
|
* PURPOSE: RTL Support Routines
|
|
|
|
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
|
|
|
|
* Gunnar Dalsnes
|
2004-05-31 19:45:16 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
/* INCLUDES ******************************************************************/
|
|
|
|
|
2004-08-15 16:39:12 +00:00
|
|
|
#include <ntoskrnl.h>
|
2004-05-31 19:45:16 +00:00
|
|
|
#define NDEBUG
|
2008-08-30 16:31:06 +00:00
|
|
|
#include <debug.h>
|
2004-05-31 19:45:16 +00:00
|
|
|
|
Major refactoring of the exception handling code + misc fixes:
- Fix/add prototypes for RtlCaptureContext, RtlDispatchException and RtlUnwind
- Fix EXCEPTION_REGISTRATION_RECORD structure and PEXCEPTION_ROUTINE
- Add w32api excpt.h (based on mingw) with PSDK compatibility fixes
- Fix seriously broken User-Mode Ldr thunk and APC Callback prototypes
- Fix KiUserExceptionDispatcher
- Remove useless NTDLL entrypoint
- Implement NTDLL Ki* callbacks in ASM
- Implement RtlCaptureContext
- Fix RtlRaiseException to handle cases when a user-mode debugger is present
- Fix RtlRaiseStatus as above, plus set the exception address and capture context
- Little cleanup of RTL headers
- Implement RtlpGetStackLimits, RtlpGetExceptionList, RtlpSetExceptionList, RtlpGetExceptionAddress in ASM
- Fix RtlDispatchException, add cases for exceptions in the DPC stack and validate the validity of the
exception frames. Add support for exception logging by the global flag. Use TRAP_FRAME/EXCPETION_FRAME instead of
Context.
- Fix RtlUnwind logic, support cases where it's called with custom arguments instead of NULL.
- Reimplement RtlpCaptureContext to work properly, convert exception handler calling functions to INTEL syntax
and fix some bugs (like checking for the right unwind flag, clearing volatile register values, etc. Also use some
optimizations to increase speed.
- Modify some kernel functions (like KeContextToTrapFrame, KiDispatchException, KiInitializeUserApc, etc.) to
support a PKEXCEPTION_FRAME for future PPC compatibility.
- Reimplement RtlCaptureUnicodeString/FreeUnicodeString as inlined probe macros and optimize them.
- Export ExRaiseStatus/Exception as Rtl*
- Reimplement NtContinue to have more platform-independent code, and to protect and validate user-mode context
and parameters with SEH.
- Implement KiRaiseException, add SEH to all user-mode parameters and when copying data to the user-mode stack.
- Fix KiInitializeUserApc to use KeTrapFrameToContext, to save the debug registers, not to deliver APCs during
v86 mode, and to protect user-mode stack operations in SEH and probing. Also make it generate the proper stack for the
user-mode callback.
- Implement KiUnexpectedInterrupt and KiCoprocessorError
- Reimplement NtRaiseException in ASM to take advantage of optimizations due to the trap frame being in the
stack when called through System call interface.
- Fix Ntcontinue to respect AlertThread paramter
- Fix some functiosn to return with KiServiceExit2 instead of KiServiceExit when required/needed
- Fix KiDispatchException's logic, fix hacks when calling KeUserExceptionDispatcher, use correct context
flags,...
- Make NTDLL Ki* callbacks have SEH to protect them and return to kernel-mode with notification of any
exceptions (the kernel-mode code to handle this isn't written yet though)
svn path=/trunk/; revision=17811
2005-09-11 22:32:20 +00:00
|
|
|
extern ULONG NtGlobalFlag;
|
|
|
|
|
2007-05-09 00:44:45 +00:00
|
|
|
typedef struct _RTL_RANGE_ENTRY
|
|
|
|
{
|
|
|
|
LIST_ENTRY Entry;
|
|
|
|
RTL_RANGE Range;
|
|
|
|
} RTL_RANGE_ENTRY, *PRTL_RANGE_ENTRY;
|
|
|
|
|
|
|
|
PAGED_LOOKASIDE_LIST RtlpRangeListEntryLookasideList;
|
2007-12-11 21:52:12 +00:00
|
|
|
SIZE_T RtlpAllocDeallocQueryBufferSize = 128;
|
2007-05-09 00:44:45 +00:00
|
|
|
|
2004-05-31 19:45:16 +00:00
|
|
|
/* FUNCTIONS *****************************************************************/
|
|
|
|
|
2010-07-23 23:30:00 +00:00
|
|
|
PVOID
|
|
|
|
NTAPI
|
|
|
|
RtlPcToFileHeader(
|
|
|
|
IN PVOID PcValue,
|
|
|
|
OUT PVOID *BaseOfImage)
|
|
|
|
{
|
|
|
|
PLDR_DATA_TABLE_ENTRY LdrEntry;
|
|
|
|
BOOLEAN InSystem;
|
2018-05-10 19:37:30 +00:00
|
|
|
KIRQL OldIrql;
|
2010-07-23 23:30:00 +00:00
|
|
|
|
|
|
|
/* Get the base for this file */
|
|
|
|
if ((ULONG_PTR)PcValue > (ULONG_PTR)MmHighestUserAddress)
|
|
|
|
{
|
2018-05-10 19:37:30 +00:00
|
|
|
/* Acquire the loaded module spinlock */
|
|
|
|
KeAcquireSpinLock(&PsLoadedModuleSpinLock, &OldIrql);
|
|
|
|
|
2010-07-23 23:30:00 +00:00
|
|
|
/* We are in kernel */
|
|
|
|
*BaseOfImage = KiPcToFileHeader(PcValue, &LdrEntry, FALSE, &InSystem);
|
2018-05-10 19:37:30 +00:00
|
|
|
|
|
|
|
/* Release lock */
|
|
|
|
KeReleaseSpinLock(&PsLoadedModuleSpinLock, OldIrql);
|
2010-07-23 23:30:00 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-05-10 19:37:30 +00:00
|
|
|
/* User mode is not handled here! */
|
|
|
|
*BaseOfImage = NULL;
|
2010-07-23 23:30:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return *BaseOfImage;
|
|
|
|
}
|
|
|
|
|
2007-05-09 00:44:45 +00:00
|
|
|
VOID
|
|
|
|
NTAPI
|
|
|
|
RtlInitializeRangeListPackage(VOID)
|
|
|
|
{
|
|
|
|
/* Setup the lookaside list for allocations (not used yet) */
|
|
|
|
ExInitializePagedLookasideList(&RtlpRangeListEntryLookasideList,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
POOL_COLD_ALLOCATION,
|
|
|
|
sizeof(RTL_RANGE_ENTRY),
|
2009-08-24 18:19:53 +00:00
|
|
|
'elRR',
|
2007-05-09 00:44:45 +00:00
|
|
|
16);
|
|
|
|
}
|
|
|
|
|
Major refactoring of the exception handling code + misc fixes:
- Fix/add prototypes for RtlCaptureContext, RtlDispatchException and RtlUnwind
- Fix EXCEPTION_REGISTRATION_RECORD structure and PEXCEPTION_ROUTINE
- Add w32api excpt.h (based on mingw) with PSDK compatibility fixes
- Fix seriously broken User-Mode Ldr thunk and APC Callback prototypes
- Fix KiUserExceptionDispatcher
- Remove useless NTDLL entrypoint
- Implement NTDLL Ki* callbacks in ASM
- Implement RtlCaptureContext
- Fix RtlRaiseException to handle cases when a user-mode debugger is present
- Fix RtlRaiseStatus as above, plus set the exception address and capture context
- Little cleanup of RTL headers
- Implement RtlpGetStackLimits, RtlpGetExceptionList, RtlpSetExceptionList, RtlpGetExceptionAddress in ASM
- Fix RtlDispatchException, add cases for exceptions in the DPC stack and validate the validity of the
exception frames. Add support for exception logging by the global flag. Use TRAP_FRAME/EXCPETION_FRAME instead of
Context.
- Fix RtlUnwind logic, support cases where it's called with custom arguments instead of NULL.
- Reimplement RtlpCaptureContext to work properly, convert exception handler calling functions to INTEL syntax
and fix some bugs (like checking for the right unwind flag, clearing volatile register values, etc. Also use some
optimizations to increase speed.
- Modify some kernel functions (like KeContextToTrapFrame, KiDispatchException, KiInitializeUserApc, etc.) to
support a PKEXCEPTION_FRAME for future PPC compatibility.
- Reimplement RtlCaptureUnicodeString/FreeUnicodeString as inlined probe macros and optimize them.
- Export ExRaiseStatus/Exception as Rtl*
- Reimplement NtContinue to have more platform-independent code, and to protect and validate user-mode context
and parameters with SEH.
- Implement KiRaiseException, add SEH to all user-mode parameters and when copying data to the user-mode stack.
- Fix KiInitializeUserApc to use KeTrapFrameToContext, to save the debug registers, not to deliver APCs during
v86 mode, and to protect user-mode stack operations in SEH and probing. Also make it generate the proper stack for the
user-mode callback.
- Implement KiUnexpectedInterrupt and KiCoprocessorError
- Reimplement NtRaiseException in ASM to take advantage of optimizations due to the trap frame being in the
stack when called through System call interface.
- Fix Ntcontinue to respect AlertThread paramter
- Fix some functiosn to return with KiServiceExit2 instead of KiServiceExit when required/needed
- Fix KiDispatchException's logic, fix hacks when calling KeUserExceptionDispatcher, use correct context
flags,...
- Make NTDLL Ki* callbacks have SEH to protect them and return to kernel-mode with notification of any
exceptions (the kernel-mode code to handle this isn't written yet though)
svn path=/trunk/; revision=17811
2005-09-11 22:32:20 +00:00
|
|
|
BOOLEAN
|
|
|
|
NTAPI
|
2009-10-23 22:51:39 +00:00
|
|
|
RtlpCheckForActiveDebugger(VOID)
|
Major refactoring of the exception handling code + misc fixes:
- Fix/add prototypes for RtlCaptureContext, RtlDispatchException and RtlUnwind
- Fix EXCEPTION_REGISTRATION_RECORD structure and PEXCEPTION_ROUTINE
- Add w32api excpt.h (based on mingw) with PSDK compatibility fixes
- Fix seriously broken User-Mode Ldr thunk and APC Callback prototypes
- Fix KiUserExceptionDispatcher
- Remove useless NTDLL entrypoint
- Implement NTDLL Ki* callbacks in ASM
- Implement RtlCaptureContext
- Fix RtlRaiseException to handle cases when a user-mode debugger is present
- Fix RtlRaiseStatus as above, plus set the exception address and capture context
- Little cleanup of RTL headers
- Implement RtlpGetStackLimits, RtlpGetExceptionList, RtlpSetExceptionList, RtlpGetExceptionAddress in ASM
- Fix RtlDispatchException, add cases for exceptions in the DPC stack and validate the validity of the
exception frames. Add support for exception logging by the global flag. Use TRAP_FRAME/EXCPETION_FRAME instead of
Context.
- Fix RtlUnwind logic, support cases where it's called with custom arguments instead of NULL.
- Reimplement RtlpCaptureContext to work properly, convert exception handler calling functions to INTEL syntax
and fix some bugs (like checking for the right unwind flag, clearing volatile register values, etc. Also use some
optimizations to increase speed.
- Modify some kernel functions (like KeContextToTrapFrame, KiDispatchException, KiInitializeUserApc, etc.) to
support a PKEXCEPTION_FRAME for future PPC compatibility.
- Reimplement RtlCaptureUnicodeString/FreeUnicodeString as inlined probe macros and optimize them.
- Export ExRaiseStatus/Exception as Rtl*
- Reimplement NtContinue to have more platform-independent code, and to protect and validate user-mode context
and parameters with SEH.
- Implement KiRaiseException, add SEH to all user-mode parameters and when copying data to the user-mode stack.
- Fix KiInitializeUserApc to use KeTrapFrameToContext, to save the debug registers, not to deliver APCs during
v86 mode, and to protect user-mode stack operations in SEH and probing. Also make it generate the proper stack for the
user-mode callback.
- Implement KiUnexpectedInterrupt and KiCoprocessorError
- Reimplement NtRaiseException in ASM to take advantage of optimizations due to the trap frame being in the
stack when called through System call interface.
- Fix Ntcontinue to respect AlertThread paramter
- Fix some functiosn to return with KiServiceExit2 instead of KiServiceExit when required/needed
- Fix KiDispatchException's logic, fix hacks when calling KeUserExceptionDispatcher, use correct context
flags,...
- Make NTDLL Ki* callbacks have SEH to protect them and return to kernel-mode with notification of any
exceptions (the kernel-mode code to handle this isn't written yet though)
svn path=/trunk/; revision=17811
2005-09-11 22:32:20 +00:00
|
|
|
{
|
|
|
|
/* This check is meaningless in kernel-mode */
|
2009-10-23 22:51:39 +00:00
|
|
|
return FALSE;
|
- More sharing between ntdll/ntoskrnl: shared Dbg code.
- Added NtCreateDebugObject, NtDebugContinue, NtQueryDebugFilterState, NtSetDebugFilterState, NtWaitForDebugEvent to system call list.
- Added some debug constants to headers
- Updated RtlpCheckForActiveDebugger in ntoskrnl to return whatever we're expecting as the "normal" case.
- Added RtlpSetInDbgPrint to rtl support library for special DbgPrint implementation difference in user-mode
- Removed all the deprecated debug APIs in ntdll.
- Implemented NtQueryDebugFilterState and NtSetDebugFilterState based on royce's implementation.
- Started modifications on KeDebugService, and implemented DebugService in rtl
- Implemented all the Dbg* APIs in RTL.
- Implemented DbgUiConnectToDbg, DbgUiContinue, DbgUiWaitStateChange, DbgUiRemoteBreakin, DbgUiIssueRemoteBreakin
- Changed KD Print callbacks to also receive the length of the string.
Right now, one call that should be shared still isn't (the final DebugPrint call) because calling KeDebugService from kernel-mode seems to cause a hang. Also, DebugService does not currently cause an exception like it should (instead it still calls the Kdp handler), because those changes would've made the patch even bigger and are still untested.
svn path=/trunk/; revision=18078
2005-09-26 04:59:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
BOOLEAN
|
|
|
|
NTAPI
|
2009-11-02 17:45:51 +00:00
|
|
|
RtlpSetInDbgPrint(VOID)
|
- More sharing between ntdll/ntoskrnl: shared Dbg code.
- Added NtCreateDebugObject, NtDebugContinue, NtQueryDebugFilterState, NtSetDebugFilterState, NtWaitForDebugEvent to system call list.
- Added some debug constants to headers
- Updated RtlpCheckForActiveDebugger in ntoskrnl to return whatever we're expecting as the "normal" case.
- Added RtlpSetInDbgPrint to rtl support library for special DbgPrint implementation difference in user-mode
- Removed all the deprecated debug APIs in ntdll.
- Implemented NtQueryDebugFilterState and NtSetDebugFilterState based on royce's implementation.
- Started modifications on KeDebugService, and implemented DebugService in rtl
- Implemented all the Dbg* APIs in RTL.
- Implemented DbgUiConnectToDbg, DbgUiContinue, DbgUiWaitStateChange, DbgUiRemoteBreakin, DbgUiIssueRemoteBreakin
- Changed KD Print callbacks to also receive the length of the string.
Right now, one call that should be shared still isn't (the final DebugPrint call) because calling KeDebugService from kernel-mode seems to cause a hang. Also, DebugService does not currently cause an exception like it should (instead it still calls the Kdp handler), because those changes would've made the patch even bigger and are still untested.
svn path=/trunk/; revision=18078
2005-09-26 04:59:48 +00:00
|
|
|
{
|
2009-11-02 17:45:51 +00:00
|
|
|
/* Nothing to set in kernel mode */
|
- More sharing between ntdll/ntoskrnl: shared Dbg code.
- Added NtCreateDebugObject, NtDebugContinue, NtQueryDebugFilterState, NtSetDebugFilterState, NtWaitForDebugEvent to system call list.
- Added some debug constants to headers
- Updated RtlpCheckForActiveDebugger in ntoskrnl to return whatever we're expecting as the "normal" case.
- Added RtlpSetInDbgPrint to rtl support library for special DbgPrint implementation difference in user-mode
- Removed all the deprecated debug APIs in ntdll.
- Implemented NtQueryDebugFilterState and NtSetDebugFilterState based on royce's implementation.
- Started modifications on KeDebugService, and implemented DebugService in rtl
- Implemented all the Dbg* APIs in RTL.
- Implemented DbgUiConnectToDbg, DbgUiContinue, DbgUiWaitStateChange, DbgUiRemoteBreakin, DbgUiIssueRemoteBreakin
- Changed KD Print callbacks to also receive the length of the string.
Right now, one call that should be shared still isn't (the final DebugPrint call) because calling KeDebugService from kernel-mode seems to cause a hang. Also, DebugService does not currently cause an exception like it should (instead it still calls the Kdp handler), because those changes would've made the patch even bigger and are still untested.
svn path=/trunk/; revision=18078
2005-09-26 04:59:48 +00:00
|
|
|
return FALSE;
|
Major refactoring of the exception handling code + misc fixes:
- Fix/add prototypes for RtlCaptureContext, RtlDispatchException and RtlUnwind
- Fix EXCEPTION_REGISTRATION_RECORD structure and PEXCEPTION_ROUTINE
- Add w32api excpt.h (based on mingw) with PSDK compatibility fixes
- Fix seriously broken User-Mode Ldr thunk and APC Callback prototypes
- Fix KiUserExceptionDispatcher
- Remove useless NTDLL entrypoint
- Implement NTDLL Ki* callbacks in ASM
- Implement RtlCaptureContext
- Fix RtlRaiseException to handle cases when a user-mode debugger is present
- Fix RtlRaiseStatus as above, plus set the exception address and capture context
- Little cleanup of RTL headers
- Implement RtlpGetStackLimits, RtlpGetExceptionList, RtlpSetExceptionList, RtlpGetExceptionAddress in ASM
- Fix RtlDispatchException, add cases for exceptions in the DPC stack and validate the validity of the
exception frames. Add support for exception logging by the global flag. Use TRAP_FRAME/EXCPETION_FRAME instead of
Context.
- Fix RtlUnwind logic, support cases where it's called with custom arguments instead of NULL.
- Reimplement RtlpCaptureContext to work properly, convert exception handler calling functions to INTEL syntax
and fix some bugs (like checking for the right unwind flag, clearing volatile register values, etc. Also use some
optimizations to increase speed.
- Modify some kernel functions (like KeContextToTrapFrame, KiDispatchException, KiInitializeUserApc, etc.) to
support a PKEXCEPTION_FRAME for future PPC compatibility.
- Reimplement RtlCaptureUnicodeString/FreeUnicodeString as inlined probe macros and optimize them.
- Export ExRaiseStatus/Exception as Rtl*
- Reimplement NtContinue to have more platform-independent code, and to protect and validate user-mode context
and parameters with SEH.
- Implement KiRaiseException, add SEH to all user-mode parameters and when copying data to the user-mode stack.
- Fix KiInitializeUserApc to use KeTrapFrameToContext, to save the debug registers, not to deliver APCs during
v86 mode, and to protect user-mode stack operations in SEH and probing. Also make it generate the proper stack for the
user-mode callback.
- Implement KiUnexpectedInterrupt and KiCoprocessorError
- Reimplement NtRaiseException in ASM to take advantage of optimizations due to the trap frame being in the
stack when called through System call interface.
- Fix Ntcontinue to respect AlertThread paramter
- Fix some functiosn to return with KiServiceExit2 instead of KiServiceExit when required/needed
- Fix KiDispatchException's logic, fix hacks when calling KeUserExceptionDispatcher, use correct context
flags,...
- Make NTDLL Ki* callbacks have SEH to protect them and return to kernel-mode with notification of any
exceptions (the kernel-mode code to handle this isn't written yet though)
svn path=/trunk/; revision=17811
2005-09-11 22:32:20 +00:00
|
|
|
}
|
2005-04-01 00:39:52 +00:00
|
|
|
|
2009-11-02 17:45:51 +00:00
|
|
|
VOID
|
|
|
|
NTAPI
|
|
|
|
RtlpClearInDbgPrint(VOID)
|
|
|
|
{
|
|
|
|
/* Nothing to clear in kernel mode */
|
|
|
|
}
|
|
|
|
|
2005-04-01 00:39:52 +00:00
|
|
|
KPROCESSOR_MODE
|
2008-11-29 20:47:48 +00:00
|
|
|
NTAPI
|
2015-09-03 23:57:39 +00:00
|
|
|
RtlpGetMode(VOID)
|
2005-05-09 01:38:29 +00:00
|
|
|
{
|
|
|
|
return KernelMode;
|
2005-04-01 00:39:52 +00:00
|
|
|
}
|
|
|
|
|
2005-07-20 23:35:59 +00:00
|
|
|
PVOID
|
2008-11-29 20:47:48 +00:00
|
|
|
NTAPI
|
2006-09-07 05:07:34 +00:00
|
|
|
RtlpAllocateMemory(ULONG Bytes,
|
2005-07-20 23:35:59 +00:00
|
|
|
ULONG Tag)
|
|
|
|
{
|
|
|
|
return ExAllocatePoolWithTag(PagedPool,
|
|
|
|
(SIZE_T)Bytes,
|
|
|
|
Tag);
|
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
2008-11-29 20:47:48 +00:00
|
|
|
NTAPI
|
2005-07-20 23:35:59 +00:00
|
|
|
RtlpFreeMemory(PVOID Mem,
|
|
|
|
ULONG Tag)
|
|
|
|
{
|
2008-08-29 21:19:41 +00:00
|
|
|
if (Tag == TAG_ASTR || Tag == TAG_OSTR || Tag == TAG_USTR)
|
|
|
|
ExFreePool(Mem);
|
|
|
|
else
|
|
|
|
ExFreePoolWithTag(Mem, Tag);
|
2005-07-20 23:35:59 +00:00
|
|
|
}
|
|
|
|
|
2005-01-19 01:11:43 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2008-11-29 20:47:48 +00:00
|
|
|
VOID NTAPI
|
2005-01-19 01:11:43 +00:00
|
|
|
RtlAcquirePebLock(VOID)
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2008-11-29 20:47:48 +00:00
|
|
|
VOID NTAPI
|
2005-01-19 01:11:43 +00:00
|
|
|
RtlReleasePebLock(VOID)
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2005-09-08 00:09:32 +00:00
|
|
|
NTSTATUS
|
2008-11-29 20:47:48 +00:00
|
|
|
NTAPI
|
2005-09-08 00:09:32 +00:00
|
|
|
LdrShutdownThread(VOID)
|
|
|
|
{
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2005-04-01 00:39:52 +00:00
|
|
|
|
2005-01-19 01:11:43 +00:00
|
|
|
PPEB
|
2008-11-29 20:47:48 +00:00
|
|
|
NTAPI
|
2008-09-12 15:09:17 +00:00
|
|
|
RtlGetCurrentPeb(VOID)
|
2005-01-19 01:11:43 +00:00
|
|
|
{
|
2005-04-01 00:39:52 +00:00
|
|
|
return ((PEPROCESS)(KeGetCurrentThread()->ApcState.Process))->Peb;
|
2005-01-19 01:11:43 +00:00
|
|
|
}
|
|
|
|
|
2005-05-09 01:38:29 +00:00
|
|
|
NTSTATUS
|
2008-11-29 20:47:48 +00:00
|
|
|
NTAPI
|
2011-09-19 16:52:37 +00:00
|
|
|
RtlDeleteHeapLock(IN OUT PHEAP_LOCK Lock)
|
2004-05-31 19:45:16 +00:00
|
|
|
{
|
2011-09-19 16:52:37 +00:00
|
|
|
ExDeleteResourceLite(&Lock->Resource);
|
2015-03-29 06:04:19 +00:00
|
|
|
ExFreePoolWithTag(Lock, TAG_RTHL);
|
2011-09-19 16:52:37 +00:00
|
|
|
|
2005-01-03 23:35:02 +00:00
|
|
|
return STATUS_SUCCESS;
|
2004-05-31 19:45:16 +00:00
|
|
|
}
|
|
|
|
|
2005-01-03 23:35:02 +00:00
|
|
|
NTSTATUS
|
2008-11-29 20:47:48 +00:00
|
|
|
NTAPI
|
2011-09-19 16:52:37 +00:00
|
|
|
RtlEnterHeapLock(IN OUT PHEAP_LOCK Lock, IN BOOLEAN Exclusive)
|
2004-05-31 19:45:16 +00:00
|
|
|
{
|
2011-09-17 20:26:31 +00:00
|
|
|
KeEnterCriticalRegion();
|
2011-09-19 16:52:37 +00:00
|
|
|
|
|
|
|
if (Exclusive)
|
|
|
|
ExAcquireResourceExclusiveLite(&Lock->Resource, TRUE);
|
|
|
|
else
|
|
|
|
ExAcquireResourceSharedLite(&Lock->Resource, TRUE);
|
|
|
|
|
2011-09-17 20:26:31 +00:00
|
|
|
return STATUS_SUCCESS;
|
2004-05-31 19:45:16 +00:00
|
|
|
}
|
|
|
|
|
2014-10-24 19:05:54 +00:00
|
|
|
BOOLEAN
|
|
|
|
NTAPI
|
|
|
|
RtlTryEnterHeapLock(IN OUT PHEAP_LOCK Lock, IN BOOLEAN Exclusive)
|
|
|
|
{
|
|
|
|
BOOLEAN Success;
|
|
|
|
KeEnterCriticalRegion();
|
|
|
|
|
|
|
|
if (Exclusive)
|
|
|
|
Success = ExAcquireResourceExclusiveLite(&Lock->Resource, FALSE);
|
|
|
|
else
|
|
|
|
Success = ExAcquireResourceSharedLite(&Lock->Resource, FALSE);
|
|
|
|
|
|
|
|
if (!Success)
|
|
|
|
KeLeaveCriticalRegion();
|
|
|
|
|
|
|
|
return Success;
|
|
|
|
}
|
|
|
|
|
2005-01-03 23:35:02 +00:00
|
|
|
NTSTATUS
|
2008-11-29 20:47:48 +00:00
|
|
|
NTAPI
|
2011-09-19 16:52:37 +00:00
|
|
|
RtlInitializeHeapLock(IN OUT PHEAP_LOCK *Lock)
|
2004-05-31 19:45:16 +00:00
|
|
|
{
|
2015-03-29 06:04:19 +00:00
|
|
|
PHEAP_LOCK HeapLock = ExAllocatePoolWithTag(NonPagedPool,
|
|
|
|
sizeof(HEAP_LOCK),
|
|
|
|
TAG_RTHL);
|
2011-09-19 16:52:37 +00:00
|
|
|
if (HeapLock == NULL)
|
|
|
|
return STATUS_NO_MEMORY;
|
|
|
|
|
|
|
|
ExInitializeResourceLite(&HeapLock->Resource);
|
|
|
|
*Lock = HeapLock;
|
|
|
|
|
2010-10-05 12:42:55 +00:00
|
|
|
return STATUS_SUCCESS;
|
2004-05-31 19:45:16 +00:00
|
|
|
}
|
|
|
|
|
2005-01-03 23:35:02 +00:00
|
|
|
NTSTATUS
|
2008-11-29 20:47:48 +00:00
|
|
|
NTAPI
|
2011-09-19 16:52:37 +00:00
|
|
|
RtlLeaveHeapLock(IN OUT PHEAP_LOCK Lock)
|
2004-05-31 19:45:16 +00:00
|
|
|
{
|
2011-09-19 16:52:37 +00:00
|
|
|
ExReleaseResourceLite(&Lock->Resource);
|
2011-09-17 20:26:31 +00:00
|
|
|
KeLeaveCriticalRegion();
|
2011-09-19 16:52:37 +00:00
|
|
|
|
2005-01-03 23:35:02 +00:00
|
|
|
return STATUS_SUCCESS;
|
2004-05-31 19:45:16 +00:00
|
|
|
}
|
|
|
|
|
2013-01-14 09:35:50 +00:00
|
|
|
struct _HEAP;
|
|
|
|
|
|
|
|
VOID
|
|
|
|
NTAPI
|
|
|
|
RtlpAddHeapToProcessList(struct _HEAP *Heap)
|
|
|
|
{
|
|
|
|
UNREFERENCED_PARAMETER(Heap);
|
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
|
|
NTAPI
|
|
|
|
RtlpRemoveHeapFromProcessList(struct _HEAP *Heap)
|
|
|
|
{
|
|
|
|
UNREFERENCED_PARAMETER(Heap);
|
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
|
|
RtlInitializeHeapManager(VOID)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2009-06-17 12:44:05 +00:00
|
|
|
#if DBG
|
2005-02-22 17:58:19 +00:00
|
|
|
VOID FASTCALL
|
|
|
|
CHECK_PAGED_CODE_RTL(char *file, int line)
|
|
|
|
{
|
|
|
|
if(KeGetCurrentIrql() > APC_LEVEL)
|
|
|
|
{
|
2013-08-31 16:02:13 +00:00
|
|
|
DbgPrint("%s:%i: Pagable code called at IRQL > APC_LEVEL (%u)\n", file, line, KeGetCurrentIrql());
|
2008-08-24 15:48:05 +00:00
|
|
|
ASSERT(FALSE);
|
2005-02-22 17:58:19 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2013-08-28 18:57:29 +00:00
|
|
|
VOID
|
|
|
|
NTAPI
|
|
|
|
RtlpSetHeapParameters(IN PRTL_HEAP_PARAMETERS Parameters)
|
|
|
|
{
|
|
|
|
/* Apply defaults for non-set parameters */
|
|
|
|
if (!Parameters->SegmentCommit) Parameters->SegmentCommit = MmHeapSegmentCommit;
|
|
|
|
if (!Parameters->SegmentReserve) Parameters->SegmentReserve = MmHeapSegmentReserve;
|
|
|
|
if (!Parameters->DeCommitFreeBlockThreshold) Parameters->DeCommitFreeBlockThreshold = MmHeapDeCommitFreeBlockThreshold;
|
|
|
|
if (!Parameters->DeCommitTotalFreeThreshold) Parameters->DeCommitTotalFreeThreshold = MmHeapDeCommitTotalFreeThreshold;
|
|
|
|
}
|
|
|
|
|
Major refactoring of the exception handling code + misc fixes:
- Fix/add prototypes for RtlCaptureContext, RtlDispatchException and RtlUnwind
- Fix EXCEPTION_REGISTRATION_RECORD structure and PEXCEPTION_ROUTINE
- Add w32api excpt.h (based on mingw) with PSDK compatibility fixes
- Fix seriously broken User-Mode Ldr thunk and APC Callback prototypes
- Fix KiUserExceptionDispatcher
- Remove useless NTDLL entrypoint
- Implement NTDLL Ki* callbacks in ASM
- Implement RtlCaptureContext
- Fix RtlRaiseException to handle cases when a user-mode debugger is present
- Fix RtlRaiseStatus as above, plus set the exception address and capture context
- Little cleanup of RTL headers
- Implement RtlpGetStackLimits, RtlpGetExceptionList, RtlpSetExceptionList, RtlpGetExceptionAddress in ASM
- Fix RtlDispatchException, add cases for exceptions in the DPC stack and validate the validity of the
exception frames. Add support for exception logging by the global flag. Use TRAP_FRAME/EXCPETION_FRAME instead of
Context.
- Fix RtlUnwind logic, support cases where it's called with custom arguments instead of NULL.
- Reimplement RtlpCaptureContext to work properly, convert exception handler calling functions to INTEL syntax
and fix some bugs (like checking for the right unwind flag, clearing volatile register values, etc. Also use some
optimizations to increase speed.
- Modify some kernel functions (like KeContextToTrapFrame, KiDispatchException, KiInitializeUserApc, etc.) to
support a PKEXCEPTION_FRAME for future PPC compatibility.
- Reimplement RtlCaptureUnicodeString/FreeUnicodeString as inlined probe macros and optimize them.
- Export ExRaiseStatus/Exception as Rtl*
- Reimplement NtContinue to have more platform-independent code, and to protect and validate user-mode context
and parameters with SEH.
- Implement KiRaiseException, add SEH to all user-mode parameters and when copying data to the user-mode stack.
- Fix KiInitializeUserApc to use KeTrapFrameToContext, to save the debug registers, not to deliver APCs during
v86 mode, and to protect user-mode stack operations in SEH and probing. Also make it generate the proper stack for the
user-mode callback.
- Implement KiUnexpectedInterrupt and KiCoprocessorError
- Reimplement NtRaiseException in ASM to take advantage of optimizations due to the trap frame being in the
stack when called through System call interface.
- Fix Ntcontinue to respect AlertThread paramter
- Fix some functiosn to return with KiServiceExit2 instead of KiServiceExit when required/needed
- Fix KiDispatchException's logic, fix hacks when calling KeUserExceptionDispatcher, use correct context
flags,...
- Make NTDLL Ki* callbacks have SEH to protect them and return to kernel-mode with notification of any
exceptions (the kernel-mode code to handle this isn't written yet though)
svn path=/trunk/; revision=17811
2005-09-11 22:32:20 +00:00
|
|
|
VOID
|
|
|
|
NTAPI
|
|
|
|
RtlpCheckLogException(IN PEXCEPTION_RECORD ExceptionRecord,
|
|
|
|
IN PCONTEXT ContextRecord,
|
|
|
|
IN PVOID ContextData,
|
|
|
|
IN ULONG Size)
|
|
|
|
{
|
|
|
|
/* Check the global flag */
|
|
|
|
if (NtGlobalFlag & FLG_ENABLE_EXCEPTION_LOGGING)
|
|
|
|
{
|
|
|
|
/* FIXME: Log this exception */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOLEAN
|
|
|
|
NTAPI
|
|
|
|
RtlpHandleDpcStackException(IN PEXCEPTION_REGISTRATION_RECORD RegistrationFrame,
|
|
|
|
IN ULONG_PTR RegistrationFrameEnd,
|
|
|
|
IN OUT PULONG_PTR StackLow,
|
|
|
|
IN OUT PULONG_PTR StackHigh)
|
|
|
|
{
|
|
|
|
PKPRCB Prcb;
|
|
|
|
ULONG_PTR DpcStack;
|
|
|
|
|
|
|
|
/* Check if we are at DISPATCH or higher */
|
|
|
|
if (KeGetCurrentIrql() >= DISPATCH_LEVEL)
|
|
|
|
{
|
|
|
|
/* Get the PRCB and DPC Stack */
|
|
|
|
Prcb = KeGetCurrentPrcb();
|
|
|
|
DpcStack = (ULONG_PTR)Prcb->DpcStack;
|
|
|
|
|
|
|
|
/* Check if we are in a DPC and the stack matches */
|
|
|
|
if ((Prcb->DpcRoutineActive) &&
|
|
|
|
(RegistrationFrameEnd <= DpcStack) &&
|
2007-09-27 13:07:43 +00:00
|
|
|
((ULONG_PTR)RegistrationFrame >= DpcStack - KERNEL_STACK_SIZE))
|
Major refactoring of the exception handling code + misc fixes:
- Fix/add prototypes for RtlCaptureContext, RtlDispatchException and RtlUnwind
- Fix EXCEPTION_REGISTRATION_RECORD structure and PEXCEPTION_ROUTINE
- Add w32api excpt.h (based on mingw) with PSDK compatibility fixes
- Fix seriously broken User-Mode Ldr thunk and APC Callback prototypes
- Fix KiUserExceptionDispatcher
- Remove useless NTDLL entrypoint
- Implement NTDLL Ki* callbacks in ASM
- Implement RtlCaptureContext
- Fix RtlRaiseException to handle cases when a user-mode debugger is present
- Fix RtlRaiseStatus as above, plus set the exception address and capture context
- Little cleanup of RTL headers
- Implement RtlpGetStackLimits, RtlpGetExceptionList, RtlpSetExceptionList, RtlpGetExceptionAddress in ASM
- Fix RtlDispatchException, add cases for exceptions in the DPC stack and validate the validity of the
exception frames. Add support for exception logging by the global flag. Use TRAP_FRAME/EXCPETION_FRAME instead of
Context.
- Fix RtlUnwind logic, support cases where it's called with custom arguments instead of NULL.
- Reimplement RtlpCaptureContext to work properly, convert exception handler calling functions to INTEL syntax
and fix some bugs (like checking for the right unwind flag, clearing volatile register values, etc. Also use some
optimizations to increase speed.
- Modify some kernel functions (like KeContextToTrapFrame, KiDispatchException, KiInitializeUserApc, etc.) to
support a PKEXCEPTION_FRAME for future PPC compatibility.
- Reimplement RtlCaptureUnicodeString/FreeUnicodeString as inlined probe macros and optimize them.
- Export ExRaiseStatus/Exception as Rtl*
- Reimplement NtContinue to have more platform-independent code, and to protect and validate user-mode context
and parameters with SEH.
- Implement KiRaiseException, add SEH to all user-mode parameters and when copying data to the user-mode stack.
- Fix KiInitializeUserApc to use KeTrapFrameToContext, to save the debug registers, not to deliver APCs during
v86 mode, and to protect user-mode stack operations in SEH and probing. Also make it generate the proper stack for the
user-mode callback.
- Implement KiUnexpectedInterrupt and KiCoprocessorError
- Reimplement NtRaiseException in ASM to take advantage of optimizations due to the trap frame being in the
stack when called through System call interface.
- Fix Ntcontinue to respect AlertThread paramter
- Fix some functiosn to return with KiServiceExit2 instead of KiServiceExit when required/needed
- Fix KiDispatchException's logic, fix hacks when calling KeUserExceptionDispatcher, use correct context
flags,...
- Make NTDLL Ki* callbacks have SEH to protect them and return to kernel-mode with notification of any
exceptions (the kernel-mode code to handle this isn't written yet though)
svn path=/trunk/; revision=17811
2005-09-11 22:32:20 +00:00
|
|
|
{
|
|
|
|
/* Update the limits to the DPC Stack's */
|
|
|
|
*StackHigh = DpcStack;
|
2007-09-27 13:07:43 +00:00
|
|
|
*StackLow = DpcStack - KERNEL_STACK_SIZE;
|
Major refactoring of the exception handling code + misc fixes:
- Fix/add prototypes for RtlCaptureContext, RtlDispatchException and RtlUnwind
- Fix EXCEPTION_REGISTRATION_RECORD structure and PEXCEPTION_ROUTINE
- Add w32api excpt.h (based on mingw) with PSDK compatibility fixes
- Fix seriously broken User-Mode Ldr thunk and APC Callback prototypes
- Fix KiUserExceptionDispatcher
- Remove useless NTDLL entrypoint
- Implement NTDLL Ki* callbacks in ASM
- Implement RtlCaptureContext
- Fix RtlRaiseException to handle cases when a user-mode debugger is present
- Fix RtlRaiseStatus as above, plus set the exception address and capture context
- Little cleanup of RTL headers
- Implement RtlpGetStackLimits, RtlpGetExceptionList, RtlpSetExceptionList, RtlpGetExceptionAddress in ASM
- Fix RtlDispatchException, add cases for exceptions in the DPC stack and validate the validity of the
exception frames. Add support for exception logging by the global flag. Use TRAP_FRAME/EXCPETION_FRAME instead of
Context.
- Fix RtlUnwind logic, support cases where it's called with custom arguments instead of NULL.
- Reimplement RtlpCaptureContext to work properly, convert exception handler calling functions to INTEL syntax
and fix some bugs (like checking for the right unwind flag, clearing volatile register values, etc. Also use some
optimizations to increase speed.
- Modify some kernel functions (like KeContextToTrapFrame, KiDispatchException, KiInitializeUserApc, etc.) to
support a PKEXCEPTION_FRAME for future PPC compatibility.
- Reimplement RtlCaptureUnicodeString/FreeUnicodeString as inlined probe macros and optimize them.
- Export ExRaiseStatus/Exception as Rtl*
- Reimplement NtContinue to have more platform-independent code, and to protect and validate user-mode context
and parameters with SEH.
- Implement KiRaiseException, add SEH to all user-mode parameters and when copying data to the user-mode stack.
- Fix KiInitializeUserApc to use KeTrapFrameToContext, to save the debug registers, not to deliver APCs during
v86 mode, and to protect user-mode stack operations in SEH and probing. Also make it generate the proper stack for the
user-mode callback.
- Implement KiUnexpectedInterrupt and KiCoprocessorError
- Reimplement NtRaiseException in ASM to take advantage of optimizations due to the trap frame being in the
stack when called through System call interface.
- Fix Ntcontinue to respect AlertThread paramter
- Fix some functiosn to return with KiServiceExit2 instead of KiServiceExit when required/needed
- Fix KiDispatchException's logic, fix hacks when calling KeUserExceptionDispatcher, use correct context
flags,...
- Make NTDLL Ki* callbacks have SEH to protect them and return to kernel-mode with notification of any
exceptions (the kernel-mode code to handle this isn't written yet though)
svn path=/trunk/; revision=17811
2005-09-11 22:32:20 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Not in DPC stack */
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2010-07-16 17:53:00 +00:00
|
|
|
#if !defined(_ARM_) && !defined(_AMD64_)
|
2008-03-11 02:45:13 +00:00
|
|
|
|
2006-08-30 06:52:10 +00:00
|
|
|
BOOLEAN
|
|
|
|
NTAPI
|
|
|
|
RtlpCaptureStackLimits(IN ULONG_PTR Ebp,
|
|
|
|
IN ULONG_PTR *StackBegin,
|
|
|
|
IN ULONG_PTR *StackEnd)
|
|
|
|
{
|
|
|
|
PKTHREAD Thread = KeGetCurrentThread();
|
|
|
|
|
2007-09-27 13:07:43 +00:00
|
|
|
/* Don't even try at ISR level or later */
|
|
|
|
if (KeGetCurrentIrql() > DISPATCH_LEVEL) return FALSE;
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2006-08-30 06:52:10 +00:00
|
|
|
/* Start with defaults */
|
|
|
|
*StackBegin = Thread->StackLimit;
|
|
|
|
*StackEnd = (ULONG_PTR)Thread->StackBase;
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2007-09-27 13:07:43 +00:00
|
|
|
/* Check if EBP is inside the stack */
|
|
|
|
if ((*StackBegin <= Ebp) && (Ebp <= *StackEnd))
|
|
|
|
{
|
|
|
|
/* Then make the stack start at EBP */
|
|
|
|
*StackBegin = Ebp;
|
|
|
|
}
|
|
|
|
else
|
2006-08-30 06:52:10 +00:00
|
|
|
{
|
2007-09-27 13:07:43 +00:00
|
|
|
/* Now we're going to assume we're on the DPC stack */
|
|
|
|
*StackEnd = (ULONG_PTR)(KeGetPcr()->Prcb->DpcStack);
|
|
|
|
*StackBegin = *StackEnd - KERNEL_STACK_SIZE;
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2007-09-27 13:07:43 +00:00
|
|
|
/* Check if we seem to be on the DPC stack */
|
|
|
|
if ((*StackEnd) && (*StackBegin < Ebp) && (Ebp <= *StackEnd))
|
|
|
|
{
|
|
|
|
/* We're on the DPC stack */
|
|
|
|
*StackBegin = Ebp;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* We're somewhere else entirely... use EBP for safety */
|
|
|
|
*StackBegin = Ebp;
|
|
|
|
*StackEnd = (ULONG_PTR)PAGE_ALIGN(*StackBegin);
|
|
|
|
}
|
2006-08-30 06:52:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Return success */
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2007-10-01 17:58:49 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
ULONG
|
|
|
|
NTAPI
|
|
|
|
RtlWalkFrameChain(OUT PVOID *Callers,
|
|
|
|
IN ULONG Count,
|
|
|
|
IN ULONG Flags)
|
|
|
|
{
|
2007-10-30 22:38:43 +00:00
|
|
|
ULONG_PTR Stack, NewStack, StackBegin, StackEnd = 0;
|
2007-10-01 17:58:49 +00:00
|
|
|
ULONG Eip;
|
|
|
|
BOOLEAN Result, StopSearch = FALSE;
|
|
|
|
ULONG i = 0;
|
2009-12-17 20:58:58 +00:00
|
|
|
PETHREAD Thread = PsGetCurrentThread();
|
2007-10-01 17:58:49 +00:00
|
|
|
PTEB Teb;
|
|
|
|
PKTRAP_FRAME TrapFrame;
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2007-10-01 17:58:49 +00:00
|
|
|
/* Get current EBP */
|
|
|
|
#if defined(_M_IX86)
|
|
|
|
#if defined __GNUC__
|
|
|
|
__asm__("mov %%ebp, %0" : "=r" (Stack) : );
|
|
|
|
#elif defined(_MSC_VER)
|
|
|
|
__asm mov Stack, ebp
|
|
|
|
#endif
|
|
|
|
#elif defined(_M_MIPS)
|
|
|
|
__asm__("move $sp, %0" : "=r" (Stack) : );
|
|
|
|
#elif defined(_M_PPC)
|
|
|
|
__asm__("mr %0,1" : "=r" (Stack) : );
|
2008-02-07 20:04:31 +00:00
|
|
|
#elif defined(_M_ARM)
|
|
|
|
__asm__("mov sp, %0" : "=r"(Stack) : );
|
2007-10-01 17:58:49 +00:00
|
|
|
#else
|
|
|
|
#error Unknown architecture
|
|
|
|
#endif
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2007-10-01 17:58:49 +00:00
|
|
|
/* Set it as the stack begin limit as well */
|
|
|
|
StackBegin = (ULONG_PTR)Stack;
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2007-10-01 17:58:49 +00:00
|
|
|
/* Check if we're called for non-logging mode */
|
|
|
|
if (!Flags)
|
|
|
|
{
|
|
|
|
/* Get the actual safe limits */
|
|
|
|
Result = RtlpCaptureStackLimits((ULONG_PTR)Stack,
|
|
|
|
&StackBegin,
|
|
|
|
&StackEnd);
|
|
|
|
if (!Result) return 0;
|
2017-05-06 17:51:26 +00:00
|
|
|
}
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2007-10-01 17:58:49 +00:00
|
|
|
/* Use a SEH block for maximum protection */
|
2008-11-24 13:40:26 +00:00
|
|
|
_SEH2_TRY
|
2007-10-01 17:58:49 +00:00
|
|
|
{
|
|
|
|
/* Check if we want the user-mode stack frame */
|
|
|
|
if (Flags == 1)
|
|
|
|
{
|
2007-10-19 23:21:45 +00:00
|
|
|
/* Get the trap frame and TEB */
|
2009-12-17 20:58:58 +00:00
|
|
|
TrapFrame = KeGetTrapFrame(&Thread->Tcb);
|
|
|
|
Teb = Thread->Tcb.Teb;
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2007-10-01 17:58:49 +00:00
|
|
|
/* Make sure we can trust the TEB and trap frame */
|
2007-10-19 23:21:45 +00:00
|
|
|
if (!(Teb) ||
|
|
|
|
(KeIsAttachedProcess()) ||
|
2007-10-01 17:58:49 +00:00
|
|
|
(KeGetCurrentIrql() >= DISPATCH_LEVEL))
|
|
|
|
{
|
|
|
|
/* Invalid or unsafe attempt to get the stack */
|
2010-04-30 22:47:44 +00:00
|
|
|
_SEH2_YIELD(return 0;)
|
2007-10-01 17:58:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Get the stack limits */
|
2009-12-10 00:35:12 +00:00
|
|
|
StackBegin = (ULONG_PTR)Teb->NtTib.StackLimit;
|
|
|
|
StackEnd = (ULONG_PTR)Teb->NtTib.StackBase;
|
2007-10-06 07:53:20 +00:00
|
|
|
#ifdef _M_IX86
|
2007-10-01 17:58:49 +00:00
|
|
|
Stack = TrapFrame->Ebp;
|
2007-10-06 07:53:20 +00:00
|
|
|
#elif defined(_M_PPC)
|
|
|
|
Stack = TrapFrame->Gpr1;
|
2009-10-04 16:53:15 +00:00
|
|
|
#else
|
|
|
|
#error Unknown architecture
|
2007-10-06 07:53:20 +00:00
|
|
|
#endif
|
2007-10-01 17:58:49 +00:00
|
|
|
|
|
|
|
/* Validate them */
|
2013-09-12 10:06:34 +00:00
|
|
|
if (StackEnd <= StackBegin) _SEH2_YIELD(return 0);
|
2007-10-01 17:58:49 +00:00
|
|
|
ProbeForRead((PVOID)StackBegin,
|
|
|
|
StackEnd - StackBegin,
|
|
|
|
sizeof(CHAR));
|
|
|
|
}
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2007-10-01 17:58:49 +00:00
|
|
|
/* Loop the frames */
|
|
|
|
for (i = 0; i < Count; i++)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Leave if we're past the stack,
|
|
|
|
* if we're before the stack,
|
|
|
|
* or if we've reached ourselves.
|
|
|
|
*/
|
|
|
|
if ((Stack >= StackEnd) ||
|
|
|
|
(!i ? (Stack < StackBegin) : (Stack <= StackBegin)) ||
|
|
|
|
((StackEnd - Stack) < (2 * sizeof(ULONG_PTR))))
|
|
|
|
{
|
|
|
|
/* We're done or hit a bad address */
|
|
|
|
break;
|
|
|
|
}
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2007-10-01 17:58:49 +00:00
|
|
|
/* Get new stack and EIP */
|
|
|
|
NewStack = *(PULONG_PTR)Stack;
|
|
|
|
Eip = *(PULONG_PTR)(Stack + sizeof(ULONG_PTR));
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2007-10-01 17:58:49 +00:00
|
|
|
/* Check if the new pointer is above the oldone and past the end */
|
|
|
|
if (!((Stack < NewStack) && (NewStack < StackEnd)))
|
|
|
|
{
|
|
|
|
/* Stop searching after this entry */
|
|
|
|
StopSearch = TRUE;
|
|
|
|
}
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2007-10-01 17:58:49 +00:00
|
|
|
/* Also make sure that the EIP isn't a stack address */
|
|
|
|
if ((StackBegin < Eip) && (Eip < StackEnd)) break;
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2007-10-01 17:58:49 +00:00
|
|
|
/* Check if we reached a user-mode address */
|
2009-12-17 20:58:58 +00:00
|
|
|
if (!(Flags) && !(Eip & 0x80000000)) break; // FIXME: 3GB breakage
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2007-10-01 17:58:49 +00:00
|
|
|
/* Save this frame */
|
|
|
|
Callers[i] = (PVOID)Eip;
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2007-10-01 17:58:49 +00:00
|
|
|
/* Check if we should continue */
|
|
|
|
if (StopSearch)
|
|
|
|
{
|
|
|
|
/* Return the next index */
|
|
|
|
i++;
|
|
|
|
break;
|
|
|
|
}
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2007-10-01 17:58:49 +00:00
|
|
|
/* Move to the next stack */
|
|
|
|
Stack = NewStack;
|
|
|
|
}
|
|
|
|
}
|
2008-11-24 13:40:26 +00:00
|
|
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
2007-10-01 17:58:49 +00:00
|
|
|
{
|
|
|
|
/* No index */
|
|
|
|
i = 0;
|
|
|
|
}
|
2008-11-24 13:40:26 +00:00
|
|
|
_SEH2_END;
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2007-10-01 17:58:49 +00:00
|
|
|
/* Return frames parsed */
|
2007-10-19 23:21:45 +00:00
|
|
|
return i;
|
2007-10-01 17:58:49 +00:00
|
|
|
}
|
|
|
|
|
2008-03-11 02:45:13 +00:00
|
|
|
#endif
|
|
|
|
|
2010-07-23 23:30:00 +00:00
|
|
|
VOID
|
|
|
|
NTAPI
|
|
|
|
RtlpGetStackLimits(
|
|
|
|
OUT PULONG_PTR LowLimit,
|
|
|
|
OUT PULONG_PTR HighLimit)
|
|
|
|
{
|
|
|
|
PKTHREAD CurrentThread = KeGetCurrentThread();
|
2023-11-15 20:12:05 +00:00
|
|
|
*LowLimit = (ULONG_PTR)CurrentThread->StackLimit;
|
2023-05-20 08:59:09 +00:00
|
|
|
#ifdef _M_IX86
|
2023-11-15 20:12:05 +00:00
|
|
|
*HighLimit = (ULONG_PTR)CurrentThread->InitialStack -
|
2023-05-20 08:59:09 +00:00
|
|
|
sizeof(FX_SAVE_AREA);
|
|
|
|
#else
|
2010-07-23 23:30:00 +00:00
|
|
|
*HighLimit = (ULONG_PTR)CurrentThread->InitialStack;
|
2023-05-20 08:59:09 +00:00
|
|
|
#endif
|
2010-07-23 23:30:00 +00:00
|
|
|
}
|
|
|
|
|
2005-06-24 18:11:16 +00:00
|
|
|
/* RTL Atom Tables ************************************************************/
|
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
RtlpInitAtomTableLock(PRTL_ATOM_TABLE AtomTable)
|
|
|
|
{
|
|
|
|
ExInitializeFastMutex(&AtomTable->FastMutex);
|
|
|
|
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
VOID
|
|
|
|
RtlpDestroyAtomTableLock(PRTL_ATOM_TABLE AtomTable)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
BOOLEAN
|
|
|
|
RtlpLockAtomTable(PRTL_ATOM_TABLE AtomTable)
|
|
|
|
{
|
|
|
|
ExAcquireFastMutex(&AtomTable->FastMutex);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
|
|
RtlpUnlockAtomTable(PRTL_ATOM_TABLE AtomTable)
|
|
|
|
{
|
|
|
|
ExReleaseFastMutex(&AtomTable->FastMutex);
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOLEAN
|
|
|
|
RtlpCreateAtomHandleTable(PRTL_ATOM_TABLE AtomTable)
|
|
|
|
{
|
|
|
|
AtomTable->ExHandleTable = ExCreateHandleTable(NULL);
|
|
|
|
return (AtomTable->ExHandleTable != NULL);
|
|
|
|
}
|
|
|
|
|
2013-11-18 15:21:53 +00:00
|
|
|
BOOLEAN
|
|
|
|
NTAPI
|
|
|
|
RtlpCloseHandleCallback(
|
|
|
|
IN PHANDLE_TABLE_ENTRY HandleTableEntry,
|
|
|
|
IN HANDLE Handle,
|
|
|
|
IN PVOID HandleTable)
|
|
|
|
{
|
|
|
|
/* Destroy and unlock the handle entry */
|
|
|
|
return ExDestroyHandle(HandleTable, Handle, HandleTableEntry);
|
|
|
|
}
|
|
|
|
|
2005-06-24 18:11:16 +00:00
|
|
|
VOID
|
|
|
|
RtlpDestroyAtomHandleTable(PRTL_ATOM_TABLE AtomTable)
|
|
|
|
{
|
|
|
|
if (AtomTable->ExHandleTable)
|
|
|
|
{
|
2005-12-07 17:06:48 +00:00
|
|
|
ExSweepHandleTable(AtomTable->ExHandleTable,
|
2013-11-18 15:21:53 +00:00
|
|
|
RtlpCloseHandleCallback,
|
|
|
|
AtomTable->ExHandleTable);
|
2007-01-22 08:15:17 +00:00
|
|
|
ExDestroyHandleTable(AtomTable->ExHandleTable, NULL);
|
2005-06-24 18:11:16 +00:00
|
|
|
AtomTable->ExHandleTable = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
PRTL_ATOM_TABLE
|
|
|
|
RtlpAllocAtomTable(ULONG Size)
|
|
|
|
{
|
2015-03-29 06:04:19 +00:00
|
|
|
PRTL_ATOM_TABLE Table = ExAllocatePoolWithTag(NonPagedPool,
|
|
|
|
Size,
|
|
|
|
TAG_ATMT);
|
2005-06-24 18:11:16 +00:00
|
|
|
if (Table != NULL)
|
|
|
|
{
|
|
|
|
RtlZeroMemory(Table,
|
|
|
|
Size);
|
|
|
|
}
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2005-06-24 18:11:16 +00:00
|
|
|
return Table;
|
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
|
|
RtlpFreeAtomTable(PRTL_ATOM_TABLE AtomTable)
|
|
|
|
{
|
2015-03-29 06:04:19 +00:00
|
|
|
ExFreePoolWithTag(AtomTable, TAG_ATMT);
|
2005-06-24 18:11:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
PRTL_ATOM_TABLE_ENTRY
|
|
|
|
RtlpAllocAtomTableEntry(ULONG Size)
|
|
|
|
{
|
2008-08-31 15:29:21 +00:00
|
|
|
PRTL_ATOM_TABLE_ENTRY Entry;
|
|
|
|
|
|
|
|
Entry = ExAllocatePoolWithTag(NonPagedPool, Size, TAG_ATMT);
|
|
|
|
if (Entry != NULL)
|
|
|
|
{
|
|
|
|
RtlZeroMemory(Entry, Size);
|
|
|
|
}
|
2005-06-24 18:11:16 +00:00
|
|
|
|
2008-08-31 15:29:21 +00:00
|
|
|
return Entry;
|
2005-06-24 18:11:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
|
|
RtlpFreeAtomTableEntry(PRTL_ATOM_TABLE_ENTRY Entry)
|
|
|
|
{
|
2008-08-31 15:29:21 +00:00
|
|
|
ExFreePoolWithTag(Entry, TAG_ATMT);
|
2005-06-24 18:11:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
|
|
RtlpFreeAtomHandle(PRTL_ATOM_TABLE AtomTable, PRTL_ATOM_TABLE_ENTRY Entry)
|
|
|
|
{
|
|
|
|
ExDestroyHandle(AtomTable->ExHandleTable,
|
2007-01-22 08:15:17 +00:00
|
|
|
(HANDLE)((ULONG_PTR)Entry->HandleIndex << 2),
|
|
|
|
NULL);
|
2005-06-24 18:11:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
BOOLEAN
|
|
|
|
RtlpCreateAtomHandle(PRTL_ATOM_TABLE AtomTable, PRTL_ATOM_TABLE_ENTRY Entry)
|
|
|
|
{
|
|
|
|
HANDLE_TABLE_ENTRY ExEntry;
|
2005-08-07 23:43:58 +00:00
|
|
|
HANDLE Handle;
|
|
|
|
USHORT HandleIndex;
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2009-08-12 11:42:34 +00:00
|
|
|
/* Initialize ex handle table entry */
|
2006-05-19 00:32:50 +00:00
|
|
|
ExEntry.Object = Entry;
|
|
|
|
ExEntry.GrantedAccess = 0x1; /* FIXME - valid handle */
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2009-08-12 11:42:34 +00:00
|
|
|
/* Create ex handle */
|
2005-08-07 23:43:58 +00:00
|
|
|
Handle = ExCreateHandle(AtomTable->ExHandleTable,
|
2009-08-12 11:42:34 +00:00
|
|
|
&ExEntry);
|
|
|
|
if (!Handle) return FALSE;
|
|
|
|
|
|
|
|
/* Calculate HandleIndex (by getting rid of the first two bits) */
|
|
|
|
HandleIndex = (USHORT)((ULONG_PTR)Handle >> 2);
|
|
|
|
|
|
|
|
/* Index must be less than 0xC000 */
|
|
|
|
if (HandleIndex >= 0xC000)
|
2005-06-24 18:11:16 +00:00
|
|
|
{
|
2009-08-12 11:42:34 +00:00
|
|
|
/* Destroy ex handle */
|
|
|
|
ExDestroyHandle(AtomTable->ExHandleTable,
|
|
|
|
Handle,
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
/* Return failure */
|
|
|
|
return FALSE;
|
2005-06-24 18:11:16 +00:00
|
|
|
}
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2009-08-12 11:42:34 +00:00
|
|
|
/* Initialize atom table entry */
|
|
|
|
Entry->HandleIndex = HandleIndex;
|
|
|
|
Entry->Atom = 0xC000 + HandleIndex;
|
|
|
|
|
|
|
|
/* Return success */
|
|
|
|
return TRUE;
|
2005-06-24 18:11:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
PRTL_ATOM_TABLE_ENTRY
|
|
|
|
RtlpGetAtomEntry(PRTL_ATOM_TABLE AtomTable, ULONG Index)
|
|
|
|
{
|
|
|
|
PHANDLE_TABLE_ENTRY ExEntry;
|
2005-08-08 10:54:32 +00:00
|
|
|
PRTL_ATOM_TABLE_ENTRY Entry = NULL;
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2005-08-08 10:54:32 +00:00
|
|
|
/* NOTE: There's no need to explicitly enter a critical region because it's
|
|
|
|
guaranteed that we're in a critical region right now (as we hold
|
|
|
|
the atom table lock) */
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2005-06-24 18:11:16 +00:00
|
|
|
ExEntry = ExMapHandleToPointer(AtomTable->ExHandleTable,
|
2005-08-07 23:43:58 +00:00
|
|
|
(HANDLE)((ULONG_PTR)Index << 2));
|
2005-06-24 18:11:16 +00:00
|
|
|
if (ExEntry != NULL)
|
|
|
|
{
|
2006-05-19 00:32:50 +00:00
|
|
|
Entry = ExEntry->Object;
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2005-06-24 18:11:16 +00:00
|
|
|
ExUnlockHandleTableEntry(AtomTable->ExHandleTable,
|
|
|
|
ExEntry);
|
|
|
|
}
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2005-08-08 10:54:32 +00:00
|
|
|
return Entry;
|
2005-06-24 18:11:16 +00:00
|
|
|
}
|
|
|
|
|
2020-03-28 13:28:49 +00:00
|
|
|
/* Ldr SEH-Protected access to IMAGE_NT_HEADERS */
|
|
|
|
|
|
|
|
/* Rtl SEH-Free version of this */
|
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
RtlpImageNtHeaderEx(
|
|
|
|
_In_ ULONG Flags,
|
|
|
|
_In_ PVOID Base,
|
|
|
|
_In_ ULONG64 Size,
|
|
|
|
_Out_ PIMAGE_NT_HEADERS *OutHeaders);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
* @note: This is here, so that we do not drag SEH into rosload, freeldr and bootmgfw
|
|
|
|
*/
|
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
RtlImageNtHeaderEx(
|
|
|
|
_In_ ULONG Flags,
|
|
|
|
_In_ PVOID Base,
|
|
|
|
_In_ ULONG64 Size,
|
|
|
|
_Out_ PIMAGE_NT_HEADERS *OutHeaders)
|
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
/* Assume failure. This is also done in RtlpImageNtHeaderEx, but this is guarded by SEH. */
|
|
|
|
if (OutHeaders != NULL)
|
|
|
|
*OutHeaders = NULL;
|
|
|
|
|
|
|
|
_SEH2_TRY
|
|
|
|
{
|
|
|
|
Status = RtlpImageNtHeaderEx(Flags, Base, Size, OutHeaders);
|
|
|
|
}
|
|
|
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
|
|
|
{
|
|
|
|
/* Fail with the SEH error */
|
|
|
|
Status = _SEH2_GetExceptionCode();
|
|
|
|
}
|
|
|
|
_SEH2_END;
|
|
|
|
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
2005-12-08 23:55:34 +00:00
|
|
|
/*
|
|
|
|
* Ldr Resource support code
|
|
|
|
*/
|
|
|
|
|
|
|
|
IMAGE_RESOURCE_DIRECTORY *find_entry_by_name( IMAGE_RESOURCE_DIRECTORY *dir,
|
|
|
|
LPCWSTR name, void *root,
|
|
|
|
int want_dir );
|
|
|
|
IMAGE_RESOURCE_DIRECTORY *find_entry_by_id( IMAGE_RESOURCE_DIRECTORY *dir,
|
2006-09-07 05:07:34 +00:00
|
|
|
USHORT id, void *root, int want_dir );
|
2005-12-08 23:55:34 +00:00
|
|
|
IMAGE_RESOURCE_DIRECTORY *find_first_entry( IMAGE_RESOURCE_DIRECTORY *dir,
|
|
|
|
void *root, int want_dir );
|
|
|
|
|
|
|
|
/**********************************************************************
|
|
|
|
* find_entry
|
|
|
|
*
|
|
|
|
* Find a resource entry
|
|
|
|
*/
|
|
|
|
NTSTATUS find_entry( PVOID BaseAddress, LDR_RESOURCE_INFO *info,
|
|
|
|
ULONG level, void **ret, int want_dir )
|
|
|
|
{
|
|
|
|
ULONG size;
|
|
|
|
void *root;
|
|
|
|
IMAGE_RESOURCE_DIRECTORY *resdirptr;
|
|
|
|
|
|
|
|
root = RtlImageDirectoryEntryToData( BaseAddress, TRUE, IMAGE_DIRECTORY_ENTRY_RESOURCE, &size );
|
|
|
|
if (!root) return STATUS_RESOURCE_DATA_NOT_FOUND;
|
2014-06-22 18:44:21 +00:00
|
|
|
if (size < sizeof(*resdirptr)) return STATUS_RESOURCE_DATA_NOT_FOUND;
|
2005-12-08 23:55:34 +00:00
|
|
|
resdirptr = root;
|
|
|
|
|
|
|
|
if (!level--) goto done;
|
|
|
|
if (!(*ret = find_entry_by_name( resdirptr, (LPCWSTR)info->Type, root, want_dir || level )))
|
|
|
|
return STATUS_RESOURCE_TYPE_NOT_FOUND;
|
|
|
|
if (!level--) return STATUS_SUCCESS;
|
|
|
|
|
|
|
|
resdirptr = *ret;
|
|
|
|
if (!(*ret = find_entry_by_name( resdirptr, (LPCWSTR)info->Name, root, want_dir || level )))
|
|
|
|
return STATUS_RESOURCE_NAME_NOT_FOUND;
|
|
|
|
if (!level--) return STATUS_SUCCESS;
|
|
|
|
if (level) return STATUS_INVALID_PARAMETER; /* level > 3 */
|
|
|
|
|
|
|
|
resdirptr = *ret;
|
|
|
|
|
|
|
|
if ((*ret = find_first_entry( resdirptr, root, want_dir ))) return STATUS_SUCCESS;
|
|
|
|
|
|
|
|
return STATUS_RESOURCE_DATA_NOT_FOUND;
|
|
|
|
|
|
|
|
done:
|
|
|
|
*ret = resdirptr;
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2012-09-14 09:56:23 +00:00
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
RtlpSafeCopyMemory(
|
|
|
|
_Out_writes_bytes_all_(Length) VOID UNALIGNED *Destination,
|
|
|
|
_In_reads_bytes_(Length) CONST VOID UNALIGNED *Source,
|
|
|
|
_In_ SIZE_T Length)
|
|
|
|
{
|
|
|
|
_SEH2_TRY
|
|
|
|
{
|
|
|
|
RtlCopyMemory(Destination, Source, Length);
|
|
|
|
}
|
|
|
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
|
|
|
{
|
|
|
|
_SEH2_YIELD(return _SEH2_GetExceptionCode());
|
|
|
|
}
|
|
|
|
_SEH2_END;
|
|
|
|
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2013-01-14 09:35:50 +00:00
|
|
|
BOOLEAN
|
|
|
|
NTAPI
|
2015-09-17 13:36:55 +00:00
|
|
|
RtlCallVectoredExceptionHandlers(_In_ PEXCEPTION_RECORD ExceptionRecord,
|
|
|
|
_In_ PCONTEXT Context)
|
2013-01-14 09:35:50 +00:00
|
|
|
{
|
|
|
|
/* In the kernel we don't have vectored exception handlers */
|
|
|
|
return FALSE;
|
|
|
|
}
|
2005-12-08 23:55:34 +00:00
|
|
|
|
2015-09-17 13:36:55 +00:00
|
|
|
VOID
|
|
|
|
NTAPI
|
|
|
|
RtlCallVectoredContinueHandlers(_In_ PEXCEPTION_RECORD ExceptionRecord,
|
|
|
|
_In_ PCONTEXT Context)
|
|
|
|
{
|
|
|
|
/* No vectored continue handlers either in kernel mode */
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-06-10 16:44:51 +00:00
|
|
|
#ifdef _M_AMD64
|
|
|
|
|
|
|
|
PRUNTIME_FUNCTION
|
|
|
|
NTAPI
|
|
|
|
RtlpLookupDynamicFunctionEntry(
|
|
|
|
_In_ DWORD64 ControlPc,
|
|
|
|
_Out_ PDWORD64 ImageBase,
|
|
|
|
_In_ PUNWIND_HISTORY_TABLE HistoryTable)
|
|
|
|
{
|
|
|
|
/* No support for dynamic function tables in the kernel */
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2004-05-31 19:45:16 +00:00
|
|
|
/* EOF */
|