server: Make sure pids/tids are multiples of four.

Street Fighter V unpacker relies on it when validating other processes
for its anti-debug checks, it uses (PID&0xfffffffc)>>2 as an array index
and then checks back indexes against PIDs, and terminates early if some
PIDs do not match.

Signed-off-by: Rémi Bernon <rbernon@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
feature/deterministic
Rémi Bernon 2020-04-25 10:05:10 +02:00 committed by Alexandre Julliard
parent 8bb684c63e
commit daa120309e
2 changed files with 18 additions and 17 deletions

View File

@ -409,7 +409,6 @@ static void test_query_process(void)
DWORD_PTR tid;
DWORD j;
todo_wine_if(last_pid & 3)
ok(!(last_pid & 3), "Unexpected PID low bits: %p\n", spi->UniqueProcessId);
for ( j = 0; j < spi->dwThreadCount; j++)
{
@ -419,7 +418,6 @@ static void test_query_process(void)
spi->ti[j].ClientId.UniqueProcess, spi->UniqueProcessId);
tid = (DWORD_PTR)spi->ti[j].ClientId.UniqueThread;
todo_wine_if(tid & 3)
ok(!(tid & 3), "Unexpected TID low bits: %p\n", spi->ti[j].ClientId.UniqueThread);
}
}
@ -450,7 +448,6 @@ static void test_query_process(void)
cid.UniqueThread = 0;
status = NtOpenProcess( &handle, PROCESS_QUERY_LIMITED_INFORMATION, &attr, &cid );
todo_wine_if( status != STATUS_SUCCESS )
ok( status == STATUS_SUCCESS || broken( status == STATUS_ACCESS_DENIED ) /* wxppro */,
"NtOpenProcess returned:%x\n", status );
if (status != STATUS_SUCCESS) continue;
@ -470,7 +467,6 @@ static void test_query_process(void)
cid.UniqueThread = ULongToHandle(GetCurrentThreadId() + i);
status = NtOpenThread( &handle, THREAD_QUERY_LIMITED_INFORMATION, &attr, &cid );
todo_wine_if( status != STATUS_SUCCESS )
ok( status == STATUS_SUCCESS || broken( status == STATUS_ACCESS_DENIED ) /* wxppro */,
"NtOpenThread returned:%x\n", status );
if (status != STATUS_SUCCESS) continue;

View File

@ -339,21 +339,24 @@ static void kill_all_processes(void);
#define PTID_OFFSET 8 /* offset for first ptid value */
static unsigned int index_from_ptid(unsigned int id) { return id / 4; }
static unsigned int ptid_from_index(unsigned int index) { return index * 4; }
/* allocate a new process or thread id */
unsigned int alloc_ptid( void *ptr )
{
struct ptid_entry *entry;
unsigned int id;
unsigned int index;
if (used_ptid_entries < alloc_ptid_entries)
{
id = used_ptid_entries + PTID_OFFSET;
index = used_ptid_entries + PTID_OFFSET;
entry = &ptid_entries[used_ptid_entries++];
}
else if (next_free_ptid && num_free_ptids >= 256)
{
id = next_free_ptid;
entry = &ptid_entries[id - PTID_OFFSET];
index = next_free_ptid;
entry = &ptid_entries[index - PTID_OFFSET];
if (!(next_free_ptid = entry->next)) last_free_ptid = 0;
num_free_ptids--;
}
@ -368,35 +371,37 @@ unsigned int alloc_ptid( void *ptr )
}
ptid_entries = entry;
alloc_ptid_entries = count;
id = used_ptid_entries + PTID_OFFSET;
index = used_ptid_entries + PTID_OFFSET;
entry = &ptid_entries[used_ptid_entries++];
}
entry->ptr = ptr;
return id;
return ptid_from_index( index );
}
/* free a process or thread id */
void free_ptid( unsigned int id )
{
struct ptid_entry *entry = &ptid_entries[id - PTID_OFFSET];
unsigned int index = index_from_ptid( id );
struct ptid_entry *entry = &ptid_entries[index - PTID_OFFSET];
entry->ptr = NULL;
entry->next = 0;
/* append to end of free list so that we don't reuse it too early */
if (last_free_ptid) ptid_entries[last_free_ptid - PTID_OFFSET].next = id;
else next_free_ptid = id;
last_free_ptid = id;
if (last_free_ptid) ptid_entries[last_free_ptid - PTID_OFFSET].next = index;
else next_free_ptid = index;
last_free_ptid = index;
num_free_ptids++;
}
/* retrieve the pointer corresponding to a process or thread id */
void *get_ptid_entry( unsigned int id )
{
if (id < PTID_OFFSET) return NULL;
if (id - PTID_OFFSET >= used_ptid_entries) return NULL;
return ptid_entries[id - PTID_OFFSET].ptr;
unsigned int index = index_from_ptid( id );
if (index < PTID_OFFSET) return NULL;
if (index - PTID_OFFSET >= used_ptid_entries) return NULL;
return ptid_entries[index - PTID_OFFSET].ptr;
}
/* return the main thread of the process */