Commit 9fd54b28 authored by Eric Pouech's avatar Eric Pouech Committed by Alexandre Julliard

- Implemented a few information classes in NtQuerySystemInformation.

- Added handle information to (wineserver) process snapshot.
parent 66824e5f
......@@ -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 );
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment