- Implemented a few information classes in NtQuerySystemInformation.
- Added handle information to (wineserver) process snapshot.
This commit is contained in:
parent
66824e5fb6
commit
9fd54b2838
219
dlls/ntdll/nt.c
219
dlls/ntdll/nt.c
|
@ -139,6 +139,7 @@ NTSTATUS WINAPI NtQueryInformationProcess(
|
|||
ProcessInformation,ProcessInformationLength,
|
||||
ReturnLength
|
||||
);
|
||||
ret = STATUS_NOT_IMPLEMENTED;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -316,7 +317,7 @@ NTSTATUS WINAPI NtQueryInformationToken(
|
|||
*retlen = len;
|
||||
|
||||
if (tokeninfolength < len)
|
||||
return STATUS_BUFFER_TOO_SMALL;
|
||||
return STATUS_INFO_LENGTH_MISMATCH;
|
||||
|
||||
switch (tokeninfoclass)
|
||||
{
|
||||
|
@ -542,28 +543,226 @@ NTSTATUS WINAPI NtQuerySystemInformation(
|
|||
IN ULONG Length,
|
||||
OUT PULONG ResultLength)
|
||||
{
|
||||
switch(SystemInformationClass)
|
||||
NTSTATUS ret = STATUS_SUCCESS;
|
||||
ULONG len = 0;
|
||||
|
||||
TRACE("(0x%08x,%p,0x%08lx,%p)\n",
|
||||
SystemInformationClass,SystemInformation,Length,ResultLength);
|
||||
|
||||
switch (SystemInformationClass)
|
||||
{
|
||||
case 0x25:
|
||||
case SystemBasicInformation:
|
||||
{
|
||||
SYSTEM_BASIC_INFORMATION* sbi = (SYSTEM_BASIC_INFORMATION*)SystemInformation;
|
||||
if (Length >= sizeof(*sbi))
|
||||
{
|
||||
sbi->dwUnknown1 = 0;
|
||||
sbi->uKeMaximumIncrement = 0;
|
||||
sbi->uPageSize = 1024; /* FIXME */
|
||||
sbi->uMmNumberOfPhysicalPages = 12345; /* FIXME */
|
||||
sbi->uMmLowestPhysicalPage = 0; /* FIXME */
|
||||
sbi->uMmHighestPhysicalPage = 12345; /* FIXME */
|
||||
sbi->uAllocationGranularity = 65536; /* FIXME */
|
||||
sbi->pLowestUserAddress = 0; /* FIXME */
|
||||
sbi->pMmHighestUserAddress = (void*)~0; /* FIXME */
|
||||
sbi->uKeActiveProcessors = 1; /* FIXME */
|
||||
sbi->bKeNumberProcessors = 1; /* FIXME */
|
||||
len = sizeof(*sbi);
|
||||
}
|
||||
else ret = STATUS_INFO_LENGTH_MISMATCH;
|
||||
}
|
||||
break;
|
||||
case SystemPerformanceInformation:
|
||||
{
|
||||
SYSTEM_PERFORMANCE_INFORMATION* spi = (SYSTEM_PERFORMANCE_INFORMATION*)SystemInformation;
|
||||
if (Length >= sizeof(*spi))
|
||||
{
|
||||
memset(spi, 0, sizeof(*spi)); /* FIXME */
|
||||
len = sizeof(*spi);
|
||||
}
|
||||
else ret = STATUS_INFO_LENGTH_MISMATCH;
|
||||
}
|
||||
break;
|
||||
case SystemTimeOfDayInformation:
|
||||
{
|
||||
SYSTEM_TIMEOFDAY_INFORMATION* sti = (SYSTEM_TIMEOFDAY_INFORMATION*)SystemInformation;
|
||||
if (Length >= sizeof(*sti))
|
||||
{
|
||||
sti->liKeBootTime.QuadPart = 0; /* FIXME */
|
||||
sti->liKeSystemTime.QuadPart = 0; /* FIXME */
|
||||
sti->liExpTimeZoneBias.QuadPart = 0; /* FIXME */
|
||||
sti->uCurrentTimeZoneId = 0; /* FIXME */
|
||||
sti->dwReserved = 0;
|
||||
len = sizeof(*sti);
|
||||
}
|
||||
else ret = STATUS_INFO_LENGTH_MISMATCH;
|
||||
}
|
||||
break;
|
||||
case SystemProcessInformation:
|
||||
{
|
||||
SYSTEM_PROCESS_INFORMATION* spi = (SYSTEM_PROCESS_INFORMATION*)SystemInformation;
|
||||
SYSTEM_PROCESS_INFORMATION* last = NULL;
|
||||
HANDLE hSnap = 0;
|
||||
char procname[1024];
|
||||
DWORD wlen;
|
||||
|
||||
SERVER_START_REQ( create_snapshot )
|
||||
{
|
||||
req->flags = SNAP_PROCESS | SNAP_THREAD;
|
||||
req->inherit = FALSE;
|
||||
req->pid = 0;
|
||||
if (!(ret = wine_server_call( req ))) hSnap = reply->handle;
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
len = 0;
|
||||
while (ret == STATUS_SUCCESS)
|
||||
{
|
||||
SERVER_START_REQ( next_process )
|
||||
{
|
||||
req->handle = hSnap;
|
||||
req->reset = (len == 0);
|
||||
wine_server_set_reply( req, procname, sizeof(procname)-1 );
|
||||
if (!(ret = wine_server_call( req )))
|
||||
{
|
||||
procname[wine_server_reply_size(reply)] = 0;
|
||||
if (Length >= len + sizeof(*spi))
|
||||
{
|
||||
memset(spi, 0, sizeof(*spi));
|
||||
spi->dwOffset = sizeof(*spi);
|
||||
spi->dwThreadCount = reply->threads;
|
||||
memset(&spi->ftCreationTime, 0, sizeof(spi->ftCreationTime));
|
||||
/* spi->pszProcessName will be set later on */
|
||||
spi->dwBasePriority = reply->priority;
|
||||
spi->dwProcessID = (DWORD)reply->pid;
|
||||
spi->dwParentProcessID = (DWORD)reply->ppid;
|
||||
spi->dwHandleCount = reply->handles;
|
||||
spi->dwVirtualBytesPeak = 0; /* FIXME */
|
||||
spi->dwVirtualBytes = 0; /* FIXME */
|
||||
spi->dwPageFaults = 0; /* FIXME */
|
||||
spi->dwWorkingSetPeak = 0; /* FIXME */
|
||||
spi->dwWorkingSet = 0; /* FIXME */
|
||||
spi->dwUnknown5 = 0; /* FIXME */
|
||||
spi->dwPagedPool = 0; /* FIXME */
|
||||
spi->dwUnknown6 = 0; /* FIXME */
|
||||
spi->dwNonPagedPool = 0; /* FIXME */
|
||||
spi->dwPageFileBytesPeak = 0; /* FIXME */
|
||||
spi->dwPrivateBytes = 0; /* FIXME */
|
||||
spi->dwPageFileBytes = 0; /* FIXME */
|
||||
/* spi->ti will be set later on */
|
||||
len += sizeof(*spi) - sizeof(spi->ti);
|
||||
}
|
||||
else ret = STATUS_INFO_LENGTH_MISMATCH;
|
||||
}
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
if (ret != STATUS_SUCCESS)
|
||||
{
|
||||
if (ret == STATUS_NO_MORE_FILES) ret = STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
RtlMultiByteToUnicodeN(NULL, 0, &wlen, procname, strlen(procname) + 1);
|
||||
if (Length >= len + wlen + spi->dwThreadCount * sizeof(THREAD_INFO))
|
||||
{
|
||||
int i, j;
|
||||
|
||||
/* set thread info */
|
||||
spi->dwOffset += spi->dwThreadCount * sizeof(THREAD_INFO);
|
||||
len += spi->dwThreadCount * sizeof(THREAD_INFO);
|
||||
i = j = 0;
|
||||
while (ret == STATUS_SUCCESS)
|
||||
{
|
||||
SERVER_START_REQ( next_thread )
|
||||
{
|
||||
req->handle = hSnap;
|
||||
req->reset = (j == 0);
|
||||
if (!(ret = wine_server_call( req )))
|
||||
{
|
||||
j++;
|
||||
if (reply->pid == spi->dwProcessID)
|
||||
{
|
||||
/* ftKernelTime, ftUserTime, ftCreateTime;
|
||||
* dwTickCount, dwStartAddress
|
||||
*/
|
||||
spi->ti[i].dwOwningPID = reply->pid;
|
||||
spi->ti[i].dwThreadID = reply->tid;
|
||||
spi->ti[i].dwCurrentPriority = reply->base_pri + reply->delta_pri;
|
||||
spi->ti[i].dwBasePriority = reply->base_pri;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
}
|
||||
if (ret == STATUS_NO_MORE_FILES) ret = STATUS_SUCCESS;
|
||||
|
||||
/* now append process name */
|
||||
spi->pszProcessName = (WCHAR*)((char*)spi + spi->dwOffset);
|
||||
RtlMultiByteToUnicodeN( spi->pszProcessName, wlen, NULL, procname, strlen(procname) + 1);
|
||||
len += wlen;
|
||||
spi->dwOffset += wlen;
|
||||
|
||||
last = spi;
|
||||
spi = (SYSTEM_PROCESS_INFORMATION*)((char*)spi + spi->dwOffset);
|
||||
}
|
||||
else ret = STATUS_INFO_LENGTH_MISMATCH;
|
||||
}
|
||||
if (ret == STATUS_SUCCESS && last) last->dwOffset = 0;
|
||||
if (hSnap) NtClose(hSnap);
|
||||
}
|
||||
break;
|
||||
case SystemProcessorPerformanceInformation:
|
||||
{
|
||||
SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION* sppi = (SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION*)SystemInformation;
|
||||
if (Length >= sizeof(*sppi))
|
||||
{
|
||||
memset(sppi, 0, sizeof(*sppi)); /* FIXME */
|
||||
len = sizeof(*sppi);
|
||||
}
|
||||
else ret = STATUS_INFO_LENGTH_MISMATCH;
|
||||
}
|
||||
break;
|
||||
|
||||
case SystemCacheInformation:
|
||||
{
|
||||
SYSTEM_CACHE_INFORMATION* sci = (SYSTEM_CACHE_INFORMATION*)SystemInformation;
|
||||
if (Length >= sizeof(*sci))
|
||||
{
|
||||
memset(sci, 0, sizeof(*sci)); /* FIXME */
|
||||
len = sizeof(*sci);
|
||||
}
|
||||
else ret = STATUS_INFO_LENGTH_MISMATCH;
|
||||
}
|
||||
break;
|
||||
case SystemRegistryQuotaInformation:
|
||||
/* Something to do with the size of the registry *
|
||||
* Since we don't have a size limitation, fake it *
|
||||
* This is almost certainly wrong. *
|
||||
* This sets each of the three words in the struct to 32 MB, *
|
||||
* which is enough to make the IE 5 installer happy. */
|
||||
FIXME("(0x%08x,%p,0x%08lx,%p) faking max registry size of 32 MB\n",
|
||||
SystemInformationClass,SystemInformation,Length,ResultLength);
|
||||
*(DWORD *)SystemInformation = 0x2000000;
|
||||
*(((DWORD *)SystemInformation)+1) = 0x200000;
|
||||
*(((DWORD *)SystemInformation)+2) = 0x200000;
|
||||
{
|
||||
SYSTEM_REGISTRY_QUOTA_INFORMATION* srqi = (SYSTEM_REGISTRY_QUOTA_INFORMATION*)SystemInformation;
|
||||
if (Length >= sizeof(*srqi))
|
||||
{
|
||||
FIXME("(0x%08x,%p,0x%08lx,%p) faking max registry size of 32 MB\n",
|
||||
SystemInformationClass,SystemInformation,Length,ResultLength);
|
||||
srqi->RegistryQuotaAllowed = 0x2000000;
|
||||
srqi->RegistryQuotaUsed = 0x200000;
|
||||
srqi->Reserved1 = (void*)0x200000;
|
||||
if (ResultLength) *ResultLength = sizeof(*srqi);
|
||||
}
|
||||
else ret = STATUS_INFO_LENGTH_MISMATCH;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
FIXME("(0x%08x,%p,0x%08lx,%p) stub\n",
|
||||
SystemInformationClass,SystemInformation,Length,ResultLength);
|
||||
ZeroMemory (SystemInformation, Length);
|
||||
memset(SystemInformation, 0, Length);
|
||||
ret = STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
if (ResultLength) *ResultLength = len;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1592,6 +1592,7 @@ struct next_process_reply
|
|||
void* module;
|
||||
int threads;
|
||||
int priority;
|
||||
int handles;
|
||||
/* VARARG(filename,string); */
|
||||
};
|
||||
|
||||
|
@ -3664,6 +3665,6 @@ union generic_reply
|
|||
struct open_token_reply open_token_reply;
|
||||
};
|
||||
|
||||
#define SERVER_PROTOCOL_VERSION 120
|
||||
#define SERVER_PROTOCOL_VERSION 121
|
||||
|
||||
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
||||
|
|
|
@ -482,17 +482,18 @@ typedef struct _UNWIND_HISTORY_TABLE {
|
|||
/* This is used by NtQuerySystemInformation */
|
||||
/* FIXME: Isn't THREAD_INFO and THREADINFO the same structure? */
|
||||
typedef struct {
|
||||
FILETIME ftCreationTime;
|
||||
DWORD dwUnknown1;
|
||||
DWORD dwStartAddress;
|
||||
DWORD dwOwningPID;
|
||||
DWORD dwThreadID;
|
||||
DWORD dwCurrentPriority;
|
||||
DWORD dwBasePriority;
|
||||
DWORD dwContextSwitches;
|
||||
DWORD dwThreadState;
|
||||
DWORD dwWaitReason;
|
||||
DWORD dwUnknown2[5];
|
||||
FILETIME ftKernelTime;
|
||||
FILETIME ftUserTime;
|
||||
FILETIME ftCreateTime;
|
||||
DWORD dwTickCount;
|
||||
DWORD dwStartAddress;
|
||||
DWORD dwOwningPID;
|
||||
DWORD dwThreadID;
|
||||
DWORD dwCurrentPriority;
|
||||
DWORD dwBasePriority;
|
||||
DWORD dwContextSwitches;
|
||||
DWORD dwThreadState;
|
||||
DWORD dwWaitReason;
|
||||
} THREADINFO, *PTHREADINFO;
|
||||
|
||||
/* FIXME: Isn't THREAD_INFO and THREADINFO the same structure? */
|
||||
|
@ -771,7 +772,7 @@ typedef struct _SYSTEM_PERFORMANCE_INFORMATION {
|
|||
typedef struct _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION {
|
||||
#ifdef __WINESRC__
|
||||
LARGE_INTEGER liIdleTime;
|
||||
DWORD dwSpare[76];
|
||||
DWORD dwSpare[10];
|
||||
#else
|
||||
LARGE_INTEGER IdleTime;
|
||||
LARGE_INTEGER KernelTime;
|
||||
|
|
|
@ -503,6 +503,12 @@ obj_handle_t open_object( const struct namespace *namespace, const WCHAR *name,
|
|||
return handle;
|
||||
}
|
||||
|
||||
/* return the size of the handle table of a given process */
|
||||
unsigned int get_handle_table_count( struct process *process )
|
||||
{
|
||||
return process->handles->count;
|
||||
}
|
||||
|
||||
/* close a handle */
|
||||
DECL_HANDLER(close_handle)
|
||||
{
|
||||
|
|
|
@ -47,6 +47,8 @@ extern obj_handle_t open_object( const struct namespace *namespace, const WCHAR
|
|||
extern obj_handle_t find_inherited_handle( struct process *process, const struct object_ops *ops );
|
||||
extern struct handle_table *alloc_handle_table( struct process *process, int count );
|
||||
extern struct handle_table *copy_handle_table( struct process *process, struct process *parent );
|
||||
extern unsigned int get_handle_table_count( struct process *process);
|
||||
|
||||
extern void close_global_handles(void);
|
||||
|
||||
#endif /* __WINE_SERVER_HANDLE_H */
|
||||
|
|
|
@ -845,6 +845,7 @@ struct process_snapshot *process_snap( int *count )
|
|||
ptr->threads = process->running_threads;
|
||||
ptr->count = process->obj.refcount;
|
||||
ptr->priority = process->priority;
|
||||
ptr->handles = get_handle_table_count(process);
|
||||
grab_object( process );
|
||||
ptr++;
|
||||
}
|
||||
|
|
|
@ -86,6 +86,7 @@ struct process_snapshot
|
|||
int count; /* process refcount */
|
||||
int threads; /* number of threads */
|
||||
int priority; /* priority class */
|
||||
int handles; /* number of handles */
|
||||
};
|
||||
|
||||
struct module_snapshot
|
||||
|
|
|
@ -1175,6 +1175,7 @@ enum char_info_mode
|
|||
void* module; /* main module */
|
||||
int threads; /* number of threads */
|
||||
int priority; /* process priority */
|
||||
int handles; /* number of handles */
|
||||
VARARG(filename,string); /* file name of main exe */
|
||||
@END
|
||||
|
||||
|
|
|
@ -128,6 +128,7 @@ static int snapshot_next_process( struct snapshot *snapshot, struct next_process
|
|||
reply->module = 0; /* FIXME */
|
||||
reply->threads = ptr->threads;
|
||||
reply->priority = ptr->priority;
|
||||
reply->handles = ptr->handles;
|
||||
if (ptr->process->exe.filename)
|
||||
{
|
||||
size_t len = min( ptr->process->exe.namelen, get_reply_max_size() );
|
||||
|
|
|
@ -1372,6 +1372,7 @@ static void dump_next_process_reply( const struct next_process_reply *req )
|
|||
fprintf( stderr, " module=%p,", req->module );
|
||||
fprintf( stderr, " threads=%d,", req->threads );
|
||||
fprintf( stderr, " priority=%d,", req->priority );
|
||||
fprintf( stderr, " handles=%d,", req->handles );
|
||||
fprintf( stderr, " filename=" );
|
||||
dump_varargs_string( cur_size );
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue