PVOID SystemReserved1[0x36]; // CCh
PVOID Spare1; // 1A4h
LONG ExceptionCode; // 1A8h
- ULONG SpareBytes1[0x28]; // 1ACh
+ UCHAR SpareBytes1[0x28]; // 1ACh
PVOID SystemReserved2[0xA]; // 1D4h
-// GDI_TEB_BATCH GdiTebBatch; // 1FCh
+ GDI_TEB_BATCH GdiTebBatch; // 1FCh
ULONG gdiRgn; // 6DCh
ULONG gdiPen; // 6E0h
ULONG gdiBrush; // 6E4h
PVOID Instrumentation[0x10]; // F2Ch
PVOID WinSockData; // F6Ch
ULONG GdiBatchCount; // F70h
- ULONG Spare2; // F74h
+ ULONG Spare2; // F74h // NOTE: RtlExitUserThread writes something here
ULONG Spare3; // F78h
ULONG Spare4; // F7Ch
PVOID ReservedForOle; // F80h
PVOID WineDebugInfo; // Needed for WINE DLL's
} TEB, *PTEB;
+#ifndef LIBCAPTIVE
-#define NtCurrentPeb() (NtCurrentTeb()->Peb)
+/* FIXME: at least NtCurrentTeb should be defined in winnt.h */
+
+#ifndef NtCurrentTeb
+
+#if defined(_M_IX86)
+/* on the x86, the TEB is contained in the FS segment */
+/*
+ FIXME: GCC should allow defining a variable that directly maps to a register.
+ It could make for even faster code
+*/
+static inline struct _TEB * NtCurrentTeb(void)
+{
+ struct _TEB * pTeb;
+
+ /* FIXME: instead of hardcoded offsets, use offsetof() - if possible */
+ __asm__ __volatile__
+ (
+ "movl %%fs:0x18, %0\n" /* fs:18h == Teb->Tib.Self */
+ : "=r" (pTeb) /* can't have two memory operands */
+ : /* no inputs */
+ );
+
+ return pTeb;
+}
+#define NtCurrentTeb NtCurrentTeb
+
+#elif defined(_M_ALPHA)
+
+void * __rdteb(void);
+#pragma intrinsic(__rdteb)
+
+/* on the Alpha AXP, we call the rdteb PAL to retrieve the address of the TEB */
+#define NtCurrentTeb() ((struct _TEB *)__rdteb())
+
+#elif defined(_M_MIPS)
+
+/* on the MIPS R4000, the TEB is loaded at a fixed address */
+#define NtCurrentTeb() ((struct _TEB *)0x7FFFF4A8)
+
+#elif defined(_M_PPC)
+
+unsigned __gregister_get(unsigned const regnum);
+#pragma intrinsic(__gregister_get)
+
+/* on the PowerPC, the TEB is pointed to by GPR 13 */
+#define NtCurrentTeb() ((struct _TEB *)__gregister_get(13))
+
+#else
+#error Unsupported architecture or no architecture specified.
+#endif
+
+#endif
+
+#endif /* LIBCAPTIVE */
+
+#ifdef _M_IX86
#ifdef G_GNUC_UNUSED
-static inline PTEB NtCurrentTeb(VOID) G_GNUC_UNUSED;
+static inline struct _PEB * NtCurrentPeb(void) G_GNUC_UNUSED;
#endif /* G_GNUC_UNUSED */
-static inline PTEB NtCurrentTeb(VOID)
+static inline struct _PEB * NtCurrentPeb(void)
{
- int x;
-
- __asm__ __volatile__("movl %%fs:0x18, %0\n\t"
- : "=r" (x) /* can't have two memory operands */
- : /* no inputs */
- );
-
- return((PTEB)x);
+ struct _PEB * pPeb;
+
+ __asm__ __volatile__
+ (
+ "movl %%fs:0x30, %0\n" /* fs:30h == Teb->Peb */
+ : "=r" (pPeb) /* can't have two memory operands */
+ : /* no inputs */
+ );
+
+ return pPeb;
}
+#else
+/* generic NtCurrentPeb() */
+#define NtCurrentPeb() (NtCurrentTeb()->Peb)
+#endif
+
#endif /* __INCLUDE_INTERNAL_TEB */