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 )
else WARN( "can't open /dev/urandom\n" );
}
/******************************************************************************
* NtQuerySystemInformation (NTDLL.@)
*/
NTSTATUS WINAPI NtQuerySystemInformation( SYSTEM_INFORMATION_CLASS class,
void *info, ULONG size, ULONG *ret_size )
static NTSTATUS get_system_process_info( void *info, ULONG size, ULONG *len )
{
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;
char *buffer = NULL;
unsigned int pos = 0;
char *buffer = NULL;
NTSTATUS ret;
C_ASSERT( sizeof(struct thread_info) <= sizeof(SYSTEM_THREAD_INFORMATION) );
C_ASSERT( sizeof(struct process_info) <= sizeof(SYSTEM_PROCESS_INFORMATION) );
if (size && !(buffer = malloc( size )))
{
ret = STATUS_NO_MEMORY;
break;
}
*len = 0;
if (size && !(buffer = malloc( size ))) return STATUS_NO_MEMORY;
SERVER_START_REQ( list_processes )
{
......@@ -2469,22 +2382,20 @@ C_ASSERT( sizeof(struct process_info) <= sizeof(SYSTEM_PROCESS_INFORMATION) );
}
SERVER_END_REQ;
len = 0;
if (ret)
{
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_thread_count * sizeof(SYSTEM_THREAD_INFORMATION);
free( buffer );
break;
return ret;
}
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 WCHAR *server_name, *file_part;
ULONG proc_len;
......@@ -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)
+ (name_len + 1) * sizeof(WCHAR);
len += proc_len;
*len += proc_len;
if (len <= size)
if (*len <= size)
{
memset(nt_process, 0, sizeof(*nt_process));
if (i < process_count - 1)
......@@ -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);
if (len <= size)
if (*len <= size)
{
nt_process->ti[j].CreateTime.QuadPart = server_thread->start_time;
nt_process->ti[j].ClientId.UniqueProcess = UlongToHandle(server_process->pid);
......@@ -2542,7 +2453,7 @@ C_ASSERT( sizeof(struct process_info) <= sizeof(SYSTEM_PROCESS_INFORMATION) );
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.Length = name_len * sizeof(WCHAR);
......@@ -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 );
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;
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 */
{
......
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