branch update for HEAD-2003050101
[reactos.git] / include / napi / teb.h
index 694ecf3..e3c5927 100644 (file)
@@ -187,9 +187,9 @@ typedef struct _TEB
    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
@@ -220,7 +220,7 @@ typedef struct _TEB
    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
@@ -228,22 +228,85 @@ typedef struct _TEB
    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 */