Process and thread id now use the server-side id instead of an
obfuscated pointer.
This commit is contained in:
parent
eb42128790
commit
8feb3bc177
|
@ -64,8 +64,8 @@ typedef struct _PDB
|
|||
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 @@ typedef struct _PDB
|
|||
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 @@ typedef struct _PDB
|
|||
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 @@ typedef struct _PDB
|
|||
#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 );
|
||||
|
|
|
@ -100,15 +100,9 @@ typedef struct _THDB
|
|||
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
|
||||
|
||||
|
|
|
@ -271,7 +271,7 @@ static void TASK_CallToStart(void)
|
|||
THDB *thdb;
|
||||
|
||||
CreateThread( NULL, size, entry, NULL, 0, &id );
|
||||
thdb = THREAD_ID_TO_THDB( id );
|
||||
thdb = THREAD_IdToTHDB( id );
|
||||
|
||||
while ( thdb->exit_code == 0x103 )
|
||||
{
|
||||
|
|
|
@ -34,8 +34,7 @@ const K32OBJ_OPS PROCESS_Ops =
|
|||
/* 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 *PROCESS_IdToPDB( DWORD id )
|
|||
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 @@ static BOOL PROCESS_InheritEnvDB( PDB *pdb, LPCSTR cmd_line, LPCSTR env,
|
|||
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 @@ PDB* PROCESS_PDBList_Getnext (PDB *pdb)
|
|||
*/
|
||||
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 @@ static PDB *PROCESS_CreatePDB( PDB *parent, BOOL inherit )
|
|||
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 @@ BOOL PROCESS_Init(void)
|
|||
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 @@ PDB *PROCESS_Create( NE_MODULE *pModule, LPCSTR cmd_line, LPCSTR env,
|
|||
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 GetCurrentProcess(void)
|
|||
*/
|
||||
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 @@ HANDLE WINAPI OpenProcess( DWORD access, BOOL inherit, DWORD id )
|
|||
*/
|
||||
DWORD WINAPI GetCurrentProcessId(void)
|
||||
{
|
||||
PDB *pdb = PROCESS_Current();
|
||||
return PDB_TO_PROCESS_ID( pdb );
|
||||
return (DWORD)PROCESS_Current()->server_pid;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ int *__errno_location()
|
|||
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 @@ int *__h_errno_location()
|
|||
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;
|
||||
|
|
|
@ -41,6 +41,8 @@ BOOL THREAD_InitDone = FALSE;
|
|||
/* 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 @@ BOOL THREAD_IsWin16( THDB *thdb )
|
|||
*/
|
||||
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 @@ THDB *THREAD_Create( PDB *pdb, DWORD stack_size, BOOL alloc_stack16,
|
|||
|
||||
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 @@ error:
|
|||
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 @@ HANDLE WINAPI CreateThread( SECURITY_ATTRIBUTES *sa, DWORD stack,
|
|||
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 @@ HANDLE WINAPI GetCurrentThread(void)
|
|||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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 @@ DWORD WINAPI GetWindowThreadProcessId( HWND hwnd, LPDWORD process )
|
|||
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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -2363,7 +2363,7 @@ BOOL16 WINAPI EnumTaskWindows16( HTASK16 hTask, WNDENUMPROC16 func,
|
|||
*/
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -1091,7 +1091,7 @@ INT WINPROC_MapMsg16To32A( UINT16 msg16, WPARAM16 wParam16, UINT *pmsg32,
|
|||
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 @@ INT WINPROC_MapMsg32ATo16( HWND hwnd, UINT msg32, WPARAM wParam32,
|
|||
|
||||
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:
|
||||
|
|
Loading…
Reference in New Issue