Commit bb6aa6c7 authored by Paul Gofman's avatar Paul Gofman Committed by Alexandre Julliard

ntdll: Factor out get_system_process_info() function.

parent b5f3ddd1
...@@ -2359,105 +2359,18 @@ static void read_dev_urandom( void *buf, ULONG len ) ...@@ -2359,105 +2359,18 @@ static void read_dev_urandom( void *buf, ULONG len )
else WARN( "can't open /dev/urandom\n" ); else WARN( "can't open /dev/urandom\n" );
} }
/****************************************************************************** static NTSTATUS get_system_process_info( void *info, ULONG size, ULONG *len )
* NtQuerySystemInformation (NTDLL.@)
*/
NTSTATUS WINAPI NtQuerySystemInformation( SYSTEM_INFORMATION_CLASS class,
void *info, ULONG size, ULONG *ret_size )
{ {
NTSTATUS ret = STATUS_SUCCESS;
ULONG len = 0;
TRACE( "(0x%08x,%p,0x%08x,%p)\n", class, info, size, ret_size );
switch (class)
{
case SystemNativeBasicInformation: /* 114 */
if (!is_win64) return STATUS_INVALID_INFO_CLASS;
/* fall through */
case SystemBasicInformation: /* 0 */
{
SYSTEM_BASIC_INFORMATION sbi;
virtual_get_system_info( &sbi, FALSE );
len = sizeof(sbi);
if (size == len)
{
if (!info) ret = STATUS_ACCESS_VIOLATION;
else memcpy( info, &sbi, len);
}
else ret = STATUS_INFO_LENGTH_MISMATCH;
break;
}
case SystemCpuInformation: /* 1 */
if (size >= (len = sizeof(cpu_info)))
{
if (!info) ret = STATUS_ACCESS_VIOLATION;
else memcpy(info, &cpu_info, len);
}
else ret = STATUS_INFO_LENGTH_MISMATCH;
break;
case SystemPerformanceInformation: /* 2 */
{
SYSTEM_PERFORMANCE_INFORMATION spi;
static BOOL fixme_written = FALSE;
get_performance_info( &spi );
len = sizeof(spi);
if (size >= len)
{
if (!info) ret = STATUS_ACCESS_VIOLATION;
else memcpy( info, &spi, len);
}
else ret = STATUS_INFO_LENGTH_MISMATCH;
if(!fixme_written) {
FIXME("info_class SYSTEM_PERFORMANCE_INFORMATION\n");
fixme_written = TRUE;
}
break;
}
case SystemTimeOfDayInformation: /* 3 */
{
struct tm *tm;
time_t now;
SYSTEM_TIMEOFDAY_INFORMATION sti = {{{ 0 }}};
sti.BootTime.QuadPart = server_start_time;
now = time( NULL );
tm = gmtime( &now );
sti.TimeZoneBias.QuadPart = mktime( tm ) - now;
tm = localtime( &now );
if (tm->tm_isdst) sti.TimeZoneBias.QuadPart -= 3600;
sti.TimeZoneBias.QuadPart *= TICKSPERSEC;
NtQuerySystemTime( &sti.SystemTime );
if (size <= sizeof(sti))
{
len = size;
if (!info) ret = STATUS_ACCESS_VIOLATION;
else memcpy( info, &sti, size);
}
else ret = STATUS_INFO_LENGTH_MISMATCH;
break;
}
case SystemProcessInformation: /* 5 */
{
unsigned int process_count, total_thread_count, total_name_len, i, j; unsigned int process_count, total_thread_count, total_name_len, i, j;
char *buffer = NULL;
unsigned int pos = 0; unsigned int pos = 0;
char *buffer = NULL;
NTSTATUS ret;
C_ASSERT( sizeof(struct thread_info) <= sizeof(SYSTEM_THREAD_INFORMATION) ); C_ASSERT( sizeof(struct thread_info) <= sizeof(SYSTEM_THREAD_INFORMATION) );
C_ASSERT( sizeof(struct process_info) <= sizeof(SYSTEM_PROCESS_INFORMATION) ); C_ASSERT( sizeof(struct process_info) <= sizeof(SYSTEM_PROCESS_INFORMATION) );
if (size && !(buffer = malloc( size ))) *len = 0;
{ if (size && !(buffer = malloc( size ))) return STATUS_NO_MEMORY;
ret = STATUS_NO_MEMORY;
break;
}
SERVER_START_REQ( list_processes ) SERVER_START_REQ( list_processes )
{ {
...@@ -2469,22 +2382,20 @@ C_ASSERT( sizeof(struct process_info) <= sizeof(SYSTEM_PROCESS_INFORMATION) ); ...@@ -2469,22 +2382,20 @@ C_ASSERT( sizeof(struct process_info) <= sizeof(SYSTEM_PROCESS_INFORMATION) );
} }
SERVER_END_REQ; SERVER_END_REQ;
len = 0;
if (ret) if (ret)
{ {
if (ret == STATUS_INFO_LENGTH_MISMATCH) if (ret == STATUS_INFO_LENGTH_MISMATCH)
len = sizeof(SYSTEM_PROCESS_INFORMATION) * process_count *len = sizeof(SYSTEM_PROCESS_INFORMATION) * process_count
+ (total_name_len + process_count) * sizeof(WCHAR) + (total_name_len + process_count) * sizeof(WCHAR)
+ total_thread_count * sizeof(SYSTEM_THREAD_INFORMATION); + total_thread_count * sizeof(SYSTEM_THREAD_INFORMATION);
free( buffer ); free( buffer );
break; return ret;
} }
for (i = 0; i < process_count; i++) for (i = 0; i < process_count; i++)
{ {
SYSTEM_PROCESS_INFORMATION *nt_process = (SYSTEM_PROCESS_INFORMATION *)((char *)info + len); SYSTEM_PROCESS_INFORMATION *nt_process = (SYSTEM_PROCESS_INFORMATION *)((char *)info + *len);
const struct process_info *server_process; const struct process_info *server_process;
const WCHAR *server_name, *file_part; const WCHAR *server_name, *file_part;
ULONG proc_len; ULONG proc_len;
...@@ -2505,9 +2416,9 @@ C_ASSERT( sizeof(struct process_info) <= sizeof(SYSTEM_PROCESS_INFORMATION) ); ...@@ -2505,9 +2416,9 @@ C_ASSERT( sizeof(struct process_info) <= sizeof(SYSTEM_PROCESS_INFORMATION) );
proc_len = sizeof(*nt_process) + server_process->thread_count * sizeof(SYSTEM_THREAD_INFORMATION) proc_len = sizeof(*nt_process) + server_process->thread_count * sizeof(SYSTEM_THREAD_INFORMATION)
+ (name_len + 1) * sizeof(WCHAR); + (name_len + 1) * sizeof(WCHAR);
len += proc_len; *len += proc_len;
if (len <= size) if (*len <= size)
{ {
memset(nt_process, 0, sizeof(*nt_process)); memset(nt_process, 0, sizeof(*nt_process));
if (i < process_count - 1) if (i < process_count - 1)
...@@ -2528,7 +2439,7 @@ C_ASSERT( sizeof(struct process_info) <= sizeof(SYSTEM_PROCESS_INFORMATION) ); ...@@ -2528,7 +2439,7 @@ C_ASSERT( sizeof(struct process_info) <= sizeof(SYSTEM_PROCESS_INFORMATION) );
{ {
const struct thread_info *server_thread = (const struct thread_info *)(buffer + pos); const struct thread_info *server_thread = (const struct thread_info *)(buffer + pos);
if (len <= size) if (*len <= size)
{ {
nt_process->ti[j].CreateTime.QuadPart = server_thread->start_time; nt_process->ti[j].CreateTime.QuadPart = server_thread->start_time;
nt_process->ti[j].ClientId.UniqueProcess = UlongToHandle(server_process->pid); nt_process->ti[j].ClientId.UniqueProcess = UlongToHandle(server_process->pid);
...@@ -2542,7 +2453,7 @@ C_ASSERT( sizeof(struct process_info) <= sizeof(SYSTEM_PROCESS_INFORMATION) ); ...@@ -2542,7 +2453,7 @@ C_ASSERT( sizeof(struct process_info) <= sizeof(SYSTEM_PROCESS_INFORMATION) );
pos += sizeof(*server_thread); pos += sizeof(*server_thread);
} }
if (len <= size) if (*len <= size)
{ {
nt_process->ProcessName.Buffer = (WCHAR *)&nt_process->ti[server_process->thread_count]; nt_process->ProcessName.Buffer = (WCHAR *)&nt_process->ti[server_process->thread_count];
nt_process->ProcessName.Length = name_len * sizeof(WCHAR); nt_process->ProcessName.Length = name_len * sizeof(WCHAR);
...@@ -2552,10 +2463,99 @@ C_ASSERT( sizeof(struct process_info) <= sizeof(SYSTEM_PROCESS_INFORMATION) ); ...@@ -2552,10 +2463,99 @@ C_ASSERT( sizeof(struct process_info) <= sizeof(SYSTEM_PROCESS_INFORMATION) );
} }
} }
if (len > size) ret = STATUS_INFO_LENGTH_MISMATCH; if (*len > size) ret = STATUS_INFO_LENGTH_MISMATCH;
free( buffer ); free( buffer );
return ret;
}
/******************************************************************************
* NtQuerySystemInformation (NTDLL.@)
*/
NTSTATUS WINAPI NtQuerySystemInformation( SYSTEM_INFORMATION_CLASS class,
void *info, ULONG size, ULONG *ret_size )
{
NTSTATUS ret = STATUS_SUCCESS;
ULONG len = 0;
TRACE( "(0x%08x,%p,0x%08x,%p)\n", class, info, size, ret_size );
switch (class)
{
case SystemNativeBasicInformation: /* 114 */
if (!is_win64) return STATUS_INVALID_INFO_CLASS;
/* fall through */
case SystemBasicInformation: /* 0 */
{
SYSTEM_BASIC_INFORMATION sbi;
virtual_get_system_info( &sbi, FALSE );
len = sizeof(sbi);
if (size == len)
{
if (!info) ret = STATUS_ACCESS_VIOLATION;
else memcpy( info, &sbi, len);
}
else ret = STATUS_INFO_LENGTH_MISMATCH;
break;
}
case SystemCpuInformation: /* 1 */
if (size >= (len = sizeof(cpu_info)))
{
if (!info) ret = STATUS_ACCESS_VIOLATION;
else memcpy(info, &cpu_info, len);
}
else ret = STATUS_INFO_LENGTH_MISMATCH;
break; break;
case SystemPerformanceInformation: /* 2 */
{
SYSTEM_PERFORMANCE_INFORMATION spi;
static BOOL fixme_written = FALSE;
get_performance_info( &spi );
len = sizeof(spi);
if (size >= len)
{
if (!info) ret = STATUS_ACCESS_VIOLATION;
else memcpy( info, &spi, len);
} }
else ret = STATUS_INFO_LENGTH_MISMATCH;
if(!fixme_written) {
FIXME("info_class SYSTEM_PERFORMANCE_INFORMATION\n");
fixme_written = TRUE;
}
break;
}
case SystemTimeOfDayInformation: /* 3 */
{
struct tm *tm;
time_t now;
SYSTEM_TIMEOFDAY_INFORMATION sti = {{{ 0 }}};
sti.BootTime.QuadPart = server_start_time;
now = time( NULL );
tm = gmtime( &now );
sti.TimeZoneBias.QuadPart = mktime( tm ) - now;
tm = localtime( &now );
if (tm->tm_isdst) sti.TimeZoneBias.QuadPart -= 3600;
sti.TimeZoneBias.QuadPart *= TICKSPERSEC;
NtQuerySystemTime( &sti.SystemTime );
if (size <= sizeof(sti))
{
len = size;
if (!info) ret = STATUS_ACCESS_VIOLATION;
else memcpy( info, &sti, size);
}
else ret = STATUS_INFO_LENGTH_MISMATCH;
break;
}
case SystemProcessInformation: /* 5 */
ret = get_system_process_info( info, size, &len );
break;
case SystemProcessorPerformanceInformation: /* 8 */ case SystemProcessorPerformanceInformation: /* 8 */
{ {
......
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