Process and thread id now use the server-side id instead of an
obfuscated pointer.

diff --git a/include/process.h b/include/process.h
index bf3def8..3cacf39 100644
--- a/include/process.h
+++ b/include/process.h
@@ -64,8 +64,8 @@
     K32OBJ          *event;            /* 0c Pointer to an event object (unused) */
     DWORD            exit_code;        /* 10 Process exit code */
     DWORD            unknown2;         /* 14 Unknown */
-    HANDLE         heap;             /* 18 Default process heap */
-    HANDLE         mem_context;      /* 1c Process memory context */
+    HANDLE           heap;             /* 18 Default process heap */
+    HANDLE           mem_context;      /* 1c Process memory context */
     DWORD            flags;            /* 20 Flags */
     void            *pdb16;            /* 24 DOS PSP */
     WORD             PSP_sel;          /* 28 Selector to DOS PSP */
@@ -74,12 +74,12 @@
     WORD             running_threads;  /* 2e Number of running threads */
     WORD             unknown3;         /* 30 Unknown */
     WORD             ring0_threads;    /* 32 Number of ring 0 threads */
-    HANDLE         system_heap;      /* 34 System heap to allocate handles */
-    HTASK          task;             /* 38 Win16 task */
+    HANDLE           system_heap;      /* 34 System heap to allocate handles */
+    HTASK            task;             /* 38 Win16 task */
     void            *mem_map_files;    /* 3c Pointer to mem-mapped files */
     ENVDB           *env_db;           /* 40 Environment database */
     HANDLE_TABLE    *handle_table;     /* 44 Handle table */
-    struct _PDB   *parent;           /* 48 Parent process */
+    struct _PDB     *parent;           /* 48 Parent process */
     WINE_MODREF     *modref_list;      /* 4c MODREF list */
     void            *thread_list;      /* 50 List of threads */
     void            *debuggee_CB;      /* 54 Debuggee context block */
@@ -90,25 +90,24 @@
     K32OBJ          *console;          /* 84 Console */
     DWORD            tls_bits[2];      /* 88 TLS in-use bits */
     DWORD            process_dword;    /* 90 Unknown */
-    struct _PDB   *group;            /* 94 Process group */
+    struct _PDB     *group;            /* 94 Process group */
     WINE_MODREF     *exe_modref;       /* 98 MODREF for the process EXE */
     LPTOP_LEVEL_EXCEPTION_FILTER top_filter; /* 9c Top exception filter */
     DWORD            priority;         /* a0 Priority level */
-    HANDLE         heap_list;        /* a4 Head of process heap list */
+    HANDLE           heap_list;        /* a4 Head of process heap list */
     void            *heap_handles;     /* a8 Head of heap handles list */
     DWORD            unknown6;         /* ac Unknown */
     K32OBJ          *console_provider; /* b0 Console provider (??) */
     WORD             env_selector;     /* b4 Selector to process environment */
     WORD             error_mode;       /* b6 Error mode */
-    HANDLE         load_done_evt;    /* b8 Event for process loading done */
+    HANDLE           load_done_evt;    /* b8 Event for process loading done */
     DWORD            unknown7;         /* bc Unknown */
     DWORD            unknown8;         /* c0 Unknown (NT) */
     LCID             locale;           /* c4 Locale to be queried by GetThreadLocale (NT) */
     /* The following are Wine-specific fields */
     void            *server_pid;       /*    Server id for this process */
-    HANDLE        *dos_handles;      /*    Handles mapping DOS -> Win32 */
-    struct _PDB   *list_next;        /*    List reference - list of PDB's */
-    struct _PDB   *list_prev;        /*    List reference - list of PDB's */
+    HANDLE          *dos_handles;      /*    Handles mapping DOS -> Win32 */
+    struct _PDB     *next;             /*    List reference - list of PDB's */
 } PDB;
 
 /* Process flags */
@@ -118,11 +117,6 @@
 #define PDB32_FILE_APIS_OEM 0x0040  /* File APIs are OEM */
 #define PDB32_WIN32S_PROC   0x8000  /* Win32s process */
 
-/* PDB <-> Process id conversion macros */
-#define PROCESS_OBFUSCATOR     ((DWORD)0xdeadbeef)
-#define PROCESS_ID_TO_PDB(id)  ((PDB *)((id) ^ PROCESS_OBFUSCATOR))
-#define PDB_TO_PROCESS_ID(pdb) ((DWORD)(pdb) ^ PROCESS_OBFUSCATOR)
-
 /* scheduler/environ.c */
 extern BOOL ENV_BuildEnvironment( PDB *pdb );
 extern BOOL ENV_InheritEnvironment( PDB *pdb, LPCSTR env );
diff --git a/include/thread.h b/include/thread.h
index 4eac025..8c49ff4 100644
--- a/include/thread.h
+++ b/include/thread.h
@@ -100,15 +100,9 @@
     int            socket;         /* 200 Socket for server communication */
     unsigned int   seq;            /*     Server sequence number */
     void          *server_tid;     /*     Server id for this thread */
+    struct _THDB  *next;           /*     Global thread list */
 } THDB;
 
-
-
-/* THDB <-> Thread id conversion macros */
-#define THREAD_OBFUSCATOR       ((DWORD)0xdeadbeef)
-#define THREAD_ID_TO_THDB(id)   ((THDB *)((id) ^ THREAD_OBFUSCATOR))
-#define THDB_TO_THREAD_ID(thdb) ((DWORD)(thdb) ^ THREAD_OBFUSCATOR)
-
 /* The pseudo handle value returned by GetCurrentThread */
 #define CURRENT_THREAD_PSEUDOHANDLE 0xfffffffe
 
diff --git a/loader/task.c b/loader/task.c
index c17d513..32dfc0f 100644
--- a/loader/task.c
+++ b/loader/task.c
@@ -271,7 +271,7 @@
         THDB *thdb;
 
         CreateThread( NULL, size, entry, NULL, 0, &id );
-        thdb = THREAD_ID_TO_THDB( id );
+        thdb = THREAD_IdToTHDB( id );
 
         while ( thdb->exit_code == 0x103 )
         {
diff --git a/scheduler/process.c b/scheduler/process.c
index 3260923..7859587 100644
--- a/scheduler/process.c
+++ b/scheduler/process.c
@@ -34,8 +34,7 @@
 /* The initial process PDB */
 static PDB initial_pdb;
 
-static PDB *PROCESS_PDBList = NULL;
-static DWORD PROCESS_PDBList_Size = 0;
+static PDB *PROCESS_First = &initial_pdb;
 
 /***********************************************************************
  *           PROCESS_Current
@@ -96,13 +95,14 @@
     PDB *pdb;
 
     if (!id) return PROCESS_Current();
-    pdb = PROCESS_ID_TO_PDB( id );
-    if (!K32OBJ_IsValid( &pdb->header, K32OBJ_PROCESS ))
+    pdb = PROCESS_First;
+    while (pdb)
     {
-        SetLastError( ERROR_INVALID_PARAMETER );
-        return NULL;
+        if ((DWORD)pdb->server_pid == id) return pdb;
+        pdb = pdb->next;
     }
-    return pdb;
+    SetLastError( ERROR_INVALID_PARAMETER );
+    return NULL;
 }
 
 
@@ -184,105 +184,6 @@
     return TRUE;
 }
 
-/***********************************************************************
- *	     PROCESS_PDBList_Insert
- * Insert this PDB into the global PDB list
- */
-
-static void PROCESS_PDBList_Insert (PDB *pdb)
-{
-  TRACE (process, "Inserting PDB 0x%0lx, #%ld current\n", 
-	 PDB_TO_PROCESS_ID (pdb), PROCESS_PDBList_Size);
-
-  SYSTEM_LOCK (); 	/* FIXME: Do I need to worry about this ?
-			 * I.e., could more than one process be
-			 * created at once ?
-			 */
-  if (PROCESS_PDBList == NULL)
-    {
-      PROCESS_PDBList = pdb;
-      pdb->list_next = NULL;
-      pdb->list_prev = NULL;
-    }
-  else
-    {
-      PDB *first = PROCESS_PDBList, *last = PROCESS_PDBList;
-      if (first->list_prev) last = first->list_prev;
-
-      PROCESS_PDBList = pdb;
-      pdb->list_next = first;
-      pdb->list_prev = last;
-      last->list_next = pdb;
-      first->list_prev = pdb;
-    }
-  PROCESS_PDBList_Size ++;
-  SYSTEM_UNLOCK ();
-}
-
-/***********************************************************************
- *	     PROCESS_PDBList_Remove
- * Remove this PDB from the global PDB list
- */
-
-static void PROCESS_PDBList_Remove (PDB *pdb)
-{
-  PDB *next = pdb->list_next, *prev = pdb->list_prev;
-  
-  TRACE (process, "Removing PDB 0x%0lx, #%ld current\n", 
-	 PDB_TO_PROCESS_ID (pdb), PROCESS_PDBList_Size);
-
-  SYSTEM_LOCK ();
-
-  if (prev == next)
-    {
-      next->list_prev = NULL;
-      next->list_next = NULL;
-    }
-  else
-    {
-      if (next) next->list_prev = prev;
-      if (prev) prev->list_next = next;
-    }
-  
-  if (pdb == PROCESS_PDBList)
-    {
-      PROCESS_PDBList = next ? next : prev;
-    }
-  PROCESS_PDBList_Size --;
-
-  SYSTEM_UNLOCK ();
-}
-
-/***********************************************************************
- *	     PROCESS_PDBList_Getsize
- * Return the number of items in the global PDB list
- */
-
-int	PROCESS_PDBList_Getsize ()
-{
-  return PROCESS_PDBList_Size;
-}
-
-/***********************************************************************
- * 	     PROCESS_PDBList_Getfirst
- * Return the head of the PDB list
- */
-
-PDB*	PROCESS_PDBList_Getfirst ()
-{
-  return PROCESS_PDBList;
-}
-
-/***********************************************************************
- * 	     PROCESS_PDBList_Getnext
- * Return the "next" pdb as referenced from the argument.
- * If at the end of the list, return NULL.
- */
-
-PDB*	PROCESS_PDBList_Getnext (PDB *pdb)
-{
-  return (pdb->list_next != PROCESS_PDBList) ? pdb->list_next : NULL;
-}
 
 /***********************************************************************
  *           PROCESS_FreePDB
@@ -291,16 +192,13 @@
  */
 static void PROCESS_FreePDB( PDB *pdb )
 {
-    /*
-     * FIXME: 
-     * If this routine is called because PROCESS_CreatePDB fails, the
-     * following call to PROCESS_PDBList_Remove will probably screw
-     * up.  
-     */
-    PROCESS_PDBList_Remove (pdb);
+    PDB **pptr = &PROCESS_First;
+
     pdb->header.type = K32OBJ_UNKNOWN;
     if (pdb->handle_table) HANDLE_CloseAll( pdb, NULL );
     ENV_FreeEnvironment( pdb );
+    while (*pptr && (*pptr != pdb)) pptr = &(*pptr)->next;
+    if (*pptr) *pptr = pdb->next;
     if (pdb->heap && (pdb->heap != pdb->system_heap)) HeapDestroy( pdb->heap );
     DeleteCriticalSection( &pdb->crit_section );
     HeapFree( SystemHeap, 0, pdb );
@@ -329,12 +227,12 @@
     pdb->group           = pdb;
     pdb->priority        = 8;  /* Normal */
     pdb->heap            = pdb->system_heap;  /* will be changed later on */
+    pdb->next            = PROCESS_First;
+    PROCESS_First = pdb;
 
     /* Create the handle table */
 
     if (!HANDLE_CreateTable( pdb, inherit )) goto error;
-
-    PROCESS_PDBList_Insert (pdb);
     return pdb;
 
 error:
@@ -390,7 +288,6 @@
     SYSLEVEL_EmergencyTeb = thdb->teb_sel;
 
     /* Create the environment DB of the first process */
-    PROCESS_PDBList_Insert( &initial_pdb );
     if (!PROCESS_BuildEnvDB( &initial_pdb )) return FALSE;
 
     /* Initialize the first thread */
@@ -460,8 +357,8 @@
     if ((info->hProcess = HANDLE_Alloc( parent, &pdb->header, PROCESS_ALL_ACCESS,
                                         FALSE, server_phandle )) == INVALID_HANDLE_VALUE)
         goto error;
-    info->dwProcessId = PDB_TO_PROCESS_ID(pdb);
-    info->dwThreadId  = THDB_TO_THREAD_ID(thdb);
+    info->dwProcessId = (DWORD)pdb->server_pid;
+    info->dwThreadId  = (DWORD)thdb->server_tid;
 
     /* Duplicate the standard handles */
 
@@ -566,20 +463,18 @@
  */
 HANDLE WINAPI OpenProcess( DWORD access, BOOL inherit, DWORD id )
 {
-    int server_handle;
-    PDB *pdb = PROCESS_ID_TO_PDB(id);
-    if (!K32OBJ_IsValid( &pdb->header, K32OBJ_PROCESS ))
-    {
-        SetLastError( ERROR_INVALID_HANDLE );
-        return 0;
-    }
-    if ((server_handle = CLIENT_OpenProcess( pdb->server_pid, access, inherit )) == -1)
-    {
-        SetLastError( ERROR_INVALID_HANDLE );
-        return 0;
-    }
+    PDB *pdb;
+    struct open_process_request req;
+    struct open_process_reply reply;
+
+    if (!(pdb = PROCESS_IdToPDB( id ))) return 0;
+    req.pid     = (void *)id;
+    req.access  = access;
+    req.inherit = inherit;
+    CLIENT_SendRequest( REQ_OPEN_PROCESS, -1, 1, &req, sizeof(req) );
+    if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) return 0;
     return HANDLE_Alloc( PROCESS_Current(), &pdb->header, access,
-                         inherit, server_handle );
+                         inherit, reply.handle );
 }			      
 
 
@@ -588,8 +483,7 @@
  */
 DWORD WINAPI GetCurrentProcessId(void)
 {
-    PDB *pdb = PROCESS_Current();
-    return PDB_TO_PROCESS_ID( pdb );
+    return (DWORD)PROCESS_Current()->server_pid;
 }
 
 
diff --git a/scheduler/sysdeps.c b/scheduler/sysdeps.c
index 5183166..06e2b58 100644
--- a/scheduler/sysdeps.c
+++ b/scheduler/sysdeps.c
@@ -50,7 +50,7 @@
     if (!thdb) return perrno;
 #ifdef NO_REENTRANT_X11
     /* Use static libc errno while running in Xlib. */
-    if (X11DRV_CritSection.OwningThread == THDB_TO_THREAD_ID(thdb))
+    if (X11DRV_CritSection.OwningThread == thdb->server_tid)
         return perrno;
 #endif
     return &thdb->thread_errno;
@@ -67,7 +67,7 @@
     if (!thdb) return ph_errno;
 #ifdef NO_REENTRANT_X11
     /* Use static libc h_errno while running in Xlib. */
-    if (X11DRV_CritSection.OwningThread == THDB_TO_THREAD_ID(thdb))
+    if (X11DRV_CritSection.OwningThread == thdb->server_tid)
         return ph_errno;
 #endif
     return &thdb->thread_h_errno;
diff --git a/scheduler/thread.c b/scheduler/thread.c
index 0f0a0b1..8df1351 100644
--- a/scheduler/thread.c
+++ b/scheduler/thread.c
@@ -41,6 +41,8 @@
 /* THDB of the initial thread */
 static THDB initial_thdb;
 
+/* Global thread list (FIXME: not thread-safe) */
+THDB *THREAD_First = &initial_thdb;
 
 /***********************************************************************
  *           THREAD_Current
@@ -74,23 +76,22 @@
  */
 THDB *THREAD_IdToTHDB( DWORD id )
 {
-    THDB *thdb;
+    THDB *thdb = THREAD_First;
 
     if (!id) return THREAD_Current();
-    thdb = THREAD_ID_TO_THDB( id );
-    if (!K32OBJ_IsValid( &thdb->header, K32OBJ_THREAD ))
+    while (thdb)
     {
-        /* Allow task handles to be used; convert to main thread */
-        if ( IsTask16( id ) )
-        {
-            TDB *pTask = (TDB *)GlobalLock16( id );
-            if (pTask) return pTask->thdb;
-        }
-        
-        SetLastError( ERROR_INVALID_PARAMETER );
-        return NULL;
+        if ((DWORD)thdb->server_tid == id) return thdb;
+        thdb = thdb->next;
     }
-    return thdb;
+    /* Allow task handles to be used; convert to main thread */
+    if ( IsTask16( id ) )
+    {
+        TDB *pTask = (TDB *)GlobalLock16( id );
+        if (pTask) return pTask->thdb;
+    }
+    SetLastError( ERROR_INVALID_PARAMETER );
+    return NULL;
 }
 
 
@@ -264,6 +265,8 @@
 
     if (!THREAD_InitTHDB( thdb, stack_size, alloc_stack16, server_thandle, server_phandle ))
         goto error;
+    thdb->next = THREAD_First;
+    THREAD_First = thdb;
     PE_InitTls( thdb );
     return thdb;
 
@@ -280,10 +283,14 @@
 static void THREAD_Destroy( K32OBJ *ptr )
 {
     THDB *thdb = (THDB *)ptr;
+    THDB **pptr = &THREAD_First;
 
     assert( ptr->type == K32OBJ_THREAD );
     ptr->type = K32OBJ_UNKNOWN;
 
+    while (*pptr && (*pptr != thdb)) pptr = &(*pptr)->next;
+    if (*pptr) *pptr = thdb->next;
+
     /* Free the associated memory */
 
 #ifdef __i386__
@@ -340,7 +347,7 @@
                            THREAD_ALL_ACCESS, inherit, server_handle );
     if (handle == INVALID_HANDLE_VALUE) goto error;
     if (SYSDEPS_SpawnThread( thread ) == -1) goto error;
-    if (id) *id = THDB_TO_THREAD_ID( thread );
+    if (id) *id = (DWORD)thread->server_tid;
     return handle;
 
 error:
@@ -404,7 +411,9 @@
  */
 DWORD WINAPI GetCurrentThreadId(void)
 {
-    return THDB_TO_THREAD_ID( THREAD_Current() );
+    THDB *thdb = THREAD_Current();
+    /* FIXME: should not get here without a thread */
+    return thdb ? (DWORD)thdb->server_tid : 0x12345678;
 }
 
 
diff --git a/windows/queue.c b/windows/queue.c
index d801e5c..7da4e2f 100644
--- a/windows/queue.c
+++ b/windows/queue.c
@@ -3,7 +3,7 @@
  * Copyright 1993, 1994 Alexandre Julliard
  */
 
-#include <stdlib.h>
+#include <string.h>
 #include <signal.h>
 #include "wine/winbase16.h"
 #include "wine/winuser16.h"
@@ -1363,8 +1363,8 @@
     htask=QUEUE_GetQueueTask( wndPtr->hmemTaskQ );
     tdb = (TDB*)GlobalLock16(htask);
     if (!tdb || !tdb->thdb) return 0;
-    if (process) *process = PDB_TO_PROCESS_ID( tdb->thdb->process );
-    return THDB_TO_THREAD_ID( tdb->thdb );
+    if (process) *process = (DWORD)tdb->thdb->process->server_pid;
+    return tdb->thdb->server_tid;
 }
 
 
diff --git a/windows/win.c b/windows/win.c
index c5ebfd6..475b5e1 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -2363,7 +2363,7 @@
  */
 BOOL WINAPI EnumThreadWindows( DWORD id, WNDENUMPROC func, LPARAM lParam )
 {
-    THDB	*tdb = THREAD_ID_TO_THDB(id);
+    THDB *tdb = THREAD_IdToTHDB(id);
 
     return (BOOL16)EnumTaskWindows16(tdb->teb.htask16, (WNDENUMPROC16)func, lParam);
 }
diff --git a/windows/winproc.c b/windows/winproc.c
index e994b44..3f04ceb 100644
--- a/windows/winproc.c
+++ b/windows/winproc.c
@@ -1091,7 +1091,7 @@
 	     message queues.
 	  */
 	  HTASK16 htask = (HTASK16) *plparam;
-	  DWORD idThread = THDB_TO_THREAD_ID(((TDB*)GlobalLock16(htask))->thdb);
+	  DWORD idThread = ((TDB*)GlobalLock16(htask))->thdb->server_tid;
 	  *plparam = (LPARAM) idThread;
 	}
 	return 1;
@@ -1780,7 +1780,7 @@
 
     case WM_ACTIVATEAPP:
 	if (*plparam) {
-	*plparam = (LPARAM) THREAD_ID_TO_THDB((DWORD) *plparam)->teb.htask16;
+	*plparam = (LPARAM)THREAD_IdToTHDB((DWORD) *plparam)->teb.htask16;
 	}
 	return 1;
     case WM_ASKCBFORMATNAME: