mirror of
https://github.com/reactos/wine.git
synced 2024-11-28 14:10:32 +00:00
- 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,
|
ProcessInformation,ProcessInformationLength,
|
||||||
ReturnLength
|
ReturnLength
|
||||||
);
|
);
|
||||||
|
ret = STATUS_NOT_IMPLEMENTED;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -316,7 +317,7 @@ NTSTATUS WINAPI NtQueryInformationToken(
|
|||||||
*retlen = len;
|
*retlen = len;
|
||||||
|
|
||||||
if (tokeninfolength < len)
|
if (tokeninfolength < len)
|
||||||
return STATUS_BUFFER_TOO_SMALL;
|
return STATUS_INFO_LENGTH_MISMATCH;
|
||||||
|
|
||||||
switch (tokeninfoclass)
|
switch (tokeninfoclass)
|
||||||
{
|
{
|
||||||
@ -542,28 +543,226 @@ NTSTATUS WINAPI NtQuerySystemInformation(
|
|||||||
IN ULONG Length,
|
IN ULONG Length,
|
||||||
OUT PULONG ResultLength)
|
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 *
|
/* Something to do with the size of the registry *
|
||||||
* Since we don't have a size limitation, fake it *
|
* Since we don't have a size limitation, fake it *
|
||||||
* This is almost certainly wrong. *
|
* This is almost certainly wrong. *
|
||||||
* This sets each of the three words in the struct to 32 MB, *
|
* This sets each of the three words in the struct to 32 MB, *
|
||||||
* which is enough to make the IE 5 installer happy. */
|
* 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);
|
SYSTEM_REGISTRY_QUOTA_INFORMATION* srqi = (SYSTEM_REGISTRY_QUOTA_INFORMATION*)SystemInformation;
|
||||||
*(DWORD *)SystemInformation = 0x2000000;
|
if (Length >= sizeof(*srqi))
|
||||||
*(((DWORD *)SystemInformation)+1) = 0x200000;
|
{
|
||||||
*(((DWORD *)SystemInformation)+2) = 0x200000;
|
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;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
FIXME("(0x%08x,%p,0x%08lx,%p) stub\n",
|
FIXME("(0x%08x,%p,0x%08lx,%p) stub\n",
|
||||||
SystemInformationClass,SystemInformation,Length,ResultLength);
|
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;
|
void* module;
|
||||||
int threads;
|
int threads;
|
||||||
int priority;
|
int priority;
|
||||||
|
int handles;
|
||||||
/* VARARG(filename,string); */
|
/* VARARG(filename,string); */
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -3664,6 +3665,6 @@ union generic_reply
|
|||||||
struct open_token_reply open_token_reply;
|
struct open_token_reply open_token_reply;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SERVER_PROTOCOL_VERSION 120
|
#define SERVER_PROTOCOL_VERSION 121
|
||||||
|
|
||||||
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
||||||
|
@ -482,17 +482,18 @@ typedef struct _UNWIND_HISTORY_TABLE {
|
|||||||
/* This is used by NtQuerySystemInformation */
|
/* This is used by NtQuerySystemInformation */
|
||||||
/* FIXME: Isn't THREAD_INFO and THREADINFO the same structure? */
|
/* FIXME: Isn't THREAD_INFO and THREADINFO the same structure? */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
FILETIME ftCreationTime;
|
FILETIME ftKernelTime;
|
||||||
DWORD dwUnknown1;
|
FILETIME ftUserTime;
|
||||||
DWORD dwStartAddress;
|
FILETIME ftCreateTime;
|
||||||
DWORD dwOwningPID;
|
DWORD dwTickCount;
|
||||||
DWORD dwThreadID;
|
DWORD dwStartAddress;
|
||||||
DWORD dwCurrentPriority;
|
DWORD dwOwningPID;
|
||||||
DWORD dwBasePriority;
|
DWORD dwThreadID;
|
||||||
DWORD dwContextSwitches;
|
DWORD dwCurrentPriority;
|
||||||
DWORD dwThreadState;
|
DWORD dwBasePriority;
|
||||||
DWORD dwWaitReason;
|
DWORD dwContextSwitches;
|
||||||
DWORD dwUnknown2[5];
|
DWORD dwThreadState;
|
||||||
|
DWORD dwWaitReason;
|
||||||
} THREADINFO, *PTHREADINFO;
|
} THREADINFO, *PTHREADINFO;
|
||||||
|
|
||||||
/* FIXME: Isn't THREAD_INFO and THREADINFO the same structure? */
|
/* 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 {
|
typedef struct _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION {
|
||||||
#ifdef __WINESRC__
|
#ifdef __WINESRC__
|
||||||
LARGE_INTEGER liIdleTime;
|
LARGE_INTEGER liIdleTime;
|
||||||
DWORD dwSpare[76];
|
DWORD dwSpare[10];
|
||||||
#else
|
#else
|
||||||
LARGE_INTEGER IdleTime;
|
LARGE_INTEGER IdleTime;
|
||||||
LARGE_INTEGER KernelTime;
|
LARGE_INTEGER KernelTime;
|
||||||
|
@ -503,6 +503,12 @@ obj_handle_t open_object( const struct namespace *namespace, const WCHAR *name,
|
|||||||
return handle;
|
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 */
|
/* close a handle */
|
||||||
DECL_HANDLER(close_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 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 *alloc_handle_table( struct process *process, int count );
|
||||||
extern struct handle_table *copy_handle_table( struct process *process, struct process *parent );
|
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);
|
extern void close_global_handles(void);
|
||||||
|
|
||||||
#endif /* __WINE_SERVER_HANDLE_H */
|
#endif /* __WINE_SERVER_HANDLE_H */
|
||||||
|
@ -845,6 +845,7 @@ struct process_snapshot *process_snap( int *count )
|
|||||||
ptr->threads = process->running_threads;
|
ptr->threads = process->running_threads;
|
||||||
ptr->count = process->obj.refcount;
|
ptr->count = process->obj.refcount;
|
||||||
ptr->priority = process->priority;
|
ptr->priority = process->priority;
|
||||||
|
ptr->handles = get_handle_table_count(process);
|
||||||
grab_object( process );
|
grab_object( process );
|
||||||
ptr++;
|
ptr++;
|
||||||
}
|
}
|
||||||
|
@ -86,6 +86,7 @@ struct process_snapshot
|
|||||||
int count; /* process refcount */
|
int count; /* process refcount */
|
||||||
int threads; /* number of threads */
|
int threads; /* number of threads */
|
||||||
int priority; /* priority class */
|
int priority; /* priority class */
|
||||||
|
int handles; /* number of handles */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct module_snapshot
|
struct module_snapshot
|
||||||
|
@ -1175,6 +1175,7 @@ enum char_info_mode
|
|||||||
void* module; /* main module */
|
void* module; /* main module */
|
||||||
int threads; /* number of threads */
|
int threads; /* number of threads */
|
||||||
int priority; /* process priority */
|
int priority; /* process priority */
|
||||||
|
int handles; /* number of handles */
|
||||||
VARARG(filename,string); /* file name of main exe */
|
VARARG(filename,string); /* file name of main exe */
|
||||||
@END
|
@END
|
||||||
|
|
||||||
|
@ -128,6 +128,7 @@ static int snapshot_next_process( struct snapshot *snapshot, struct next_process
|
|||||||
reply->module = 0; /* FIXME */
|
reply->module = 0; /* FIXME */
|
||||||
reply->threads = ptr->threads;
|
reply->threads = ptr->threads;
|
||||||
reply->priority = ptr->priority;
|
reply->priority = ptr->priority;
|
||||||
|
reply->handles = ptr->handles;
|
||||||
if (ptr->process->exe.filename)
|
if (ptr->process->exe.filename)
|
||||||
{
|
{
|
||||||
size_t len = min( ptr->process->exe.namelen, get_reply_max_size() );
|
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, " module=%p,", req->module );
|
||||||
fprintf( stderr, " threads=%d,", req->threads );
|
fprintf( stderr, " threads=%d,", req->threads );
|
||||||
fprintf( stderr, " priority=%d,", req->priority );
|
fprintf( stderr, " priority=%d,", req->priority );
|
||||||
|
fprintf( stderr, " handles=%d,", req->handles );
|
||||||
fprintf( stderr, " filename=" );
|
fprintf( stderr, " filename=" );
|
||||||
dump_varargs_string( cur_size );
|
dump_varargs_string( cur_size );
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user