#include "ke.h"
#include "i386/mm.h"
#include "i386/fpu.h"
-#include "module.h"
#include "ob.h"
#include "mm.h"
#include "ps.h"
#include "ldr.h"
#include "kd.h"
#include "ex.h"
-#include "xhal.h"
-#include "v86m.h"
-#include "fs.h"
-#include "port.h"
-#include "nls.h"
+#include "fsrtl.h"
+#include "lpc.h"
+#include "rtl.h"
#ifdef KDBG
#include "../kdbg/kdb.h"
#endif
BOOLEAN CmImportHardwareHive(PCHAR ChunkBase, ULONG ChunkSize);
VOID KdInitSystem(ULONG Reserved, PLOADER_PARAMETER_BLOCK LoaderBlock);
-BOOLEAN
-FASTCALL
+/* FIXME - RtlpCreateUnicodeString is obsolete and should be removed ASAP! */
+BOOLEAN FASTCALL
RtlpCreateUnicodeString(
IN OUT PUNICODE_STRING UniDest,
IN PCWSTR Source,
IN POOL_TYPE PoolType);
-
-NTSTATUS
-RtlCaptureUnicodeString(
- OUT PUNICODE_STRING Dest,
- IN KPROCESSOR_MODE CurrentMode,
- IN POOL_TYPE PoolType,
- IN BOOLEAN CaptureIfKernel,
- IN PUNICODE_STRING UnsafeSrc
-);
VOID
-RtlReleaseCapturedUnicodeString(
- IN PUNICODE_STRING CapturedString,
- IN KPROCESSOR_MODE CurrentMode,
- IN BOOLEAN CaptureIfKernel
-);
+NTAPI
+RtlpLogException(IN PEXCEPTION_RECORD ExceptionRecord,
+ IN PCONTEXT ContextRecord,
+ IN PVOID ContextData,
+ IN ULONG Size);
-#endif
+/* FIXME: Interlocked functions that need to be made into a public header */
+FORCEINLINE
+LONG
+InterlockedAnd(IN OUT LONG volatile *Target,
+ IN LONG Set)
+{
+ LONG i;
+ LONG j;
+
+ j = *Target;
+ do {
+ i = j;
+ j = InterlockedCompareExchange((PLONG)Target,
+ i & Set,
+ i);
+
+ } while (i != j);
+
+ return j;
+}
/*
- *
+ * generic information class probing code
*/
-#define MM_STACK_SIZE (3*4096)
+
+#define ICIF_QUERY 0x1
+#define ICIF_SET 0x2
+#define ICIF_QUERY_SIZE_VARIABLE 0x4
+#define ICIF_SET_SIZE_VARIABLE 0x8
+#define ICIF_SIZE_VARIABLE (ICIF_QUERY_SIZE_VARIABLE | ICIF_SET_SIZE_VARIABLE)
+
+typedef struct _INFORMATION_CLASS_INFO
+{
+ ULONG RequiredSizeQUERY;
+ ULONG RequiredSizeSET;
+ ULONG AlignmentSET;
+ ULONG AlignmentQUERY;
+ ULONG Flags;
+} INFORMATION_CLASS_INFO, *PINFORMATION_CLASS_INFO;
+
+#define ICI_SQ_SAME(Size, Alignment, Flags) \
+ { Size, Size, Alignment, Alignment, Flags }
+
+#define ICI_SQ(SizeQuery, SizeSet, AlignmentQuery, AlignmentSet, Flags) \
+ { SizeQuery, SizeSet, AlignmentQuery, AlignmentSet, Flags }
+
+static __inline NTSTATUS
+DefaultSetInfoBufferCheck(UINT Class,
+ const INFORMATION_CLASS_INFO *ClassList,
+ UINT ClassListEntries,
+ PVOID Buffer,
+ ULONG BufferLength,
+ KPROCESSOR_MODE PreviousMode)
+{
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ if (Class >= 0 && Class < ClassListEntries)
+ {
+ if (!(ClassList[Class].Flags & ICIF_SET))
+ {
+ Status = STATUS_INVALID_INFO_CLASS;
+ }
+ else if (ClassList[Class].RequiredSizeSET > 0 &&
+ BufferLength != ClassList[Class].RequiredSizeSET)
+ {
+ if (!(ClassList[Class].Flags & ICIF_SET_SIZE_VARIABLE))
+ {
+ Status = STATUS_INFO_LENGTH_MISMATCH;
+ }
+ }
+
+ if (NT_SUCCESS(Status))
+ {
+ if (PreviousMode != KernelMode)
+ {
+ _SEH_TRY
+ {
+ ProbeForRead(Buffer,
+ BufferLength,
+ ClassList[Class].AlignmentSET);
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+ }
+ }
+ }
+ else
+ Status = STATUS_INVALID_INFO_CLASS;
+
+ return Status;
+}
+
+static __inline NTSTATUS
+DefaultQueryInfoBufferCheck(UINT Class,
+ const INFORMATION_CLASS_INFO *ClassList,
+ UINT ClassListEntries,
+ PVOID Buffer,
+ ULONG BufferLength,
+ PULONG ReturnLength,
+ KPROCESSOR_MODE PreviousMode)
+{
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ if (Class >= 0 && Class < ClassListEntries)
+ {
+ if (!(ClassList[Class].Flags & ICIF_QUERY))
+ {
+ Status = STATUS_INVALID_INFO_CLASS;
+ }
+ else if (ClassList[Class].RequiredSizeQUERY > 0 &&
+ BufferLength != ClassList[Class].RequiredSizeQUERY)
+ {
+ if (!(ClassList[Class].Flags & ICIF_QUERY_SIZE_VARIABLE))
+ {
+ Status = STATUS_INFO_LENGTH_MISMATCH;
+ }
+ }
+
+ if (NT_SUCCESS(Status))
+ {
+ if (PreviousMode != KernelMode)
+ {
+ _SEH_TRY
+ {
+ if (Buffer != NULL)
+ {
+ ProbeForWrite(Buffer,
+ BufferLength,
+ ClassList[Class].AlignmentQUERY);
+ }
+
+ if (ReturnLength != NULL)
+ {
+ ProbeForWriteUlong(ReturnLength);
+ }
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+ }
+ }
+ }
+ else
+ Status = STATUS_INVALID_INFO_CLASS;
+
+ return Status;
+}
+
+/*
+ * Use IsPointerOffset to test whether a pointer should be interpreted as an offset
+ * or as a pointer
+ */
+#if defined(_X86_) || defined(_M_AMD64)
+
+/* for x86 and x86-64 the MSB is 1 so we can simply test on that */
+#define IsPointerOffset(Ptr) ((LONG_PTR)(Ptr) >= 0)
+
+#elif defined(_IA64_)
+
+/* on Itanium if the 24 most significant bits are set, we're not dealing with
+ offsets anymore. */
+#define IsPointerOffset(Ptr) (((ULONG_PTR)(Ptr) & 0xFFFFFF0000000000ULL) == 0)
+
+#else
+#error IsPointerOffset() needs to be defined for this architecture
+#endif
+
+#endif
#endif /* INCLUDE_INTERNAL_NTOSKRNL_H */