Blame src/system/ntapi_tt_get_system_info_snapshot.c

dd89bb
/********************************************************/
dd89bb
/*  ntapi: Native API core library                      */
dd89bb
/*  Copyright (C) 2013,2014,2015  Z. Gilboa             */
dd89bb
/*  Released under GPLv2 and GPLv3; see COPYING.NTAPI.  */
dd89bb
/********************************************************/
dd89bb
dd89bb
#include <psxtypes/psxtypes.h>
dd89bb
#include <pemagine/pemagine.h>
dd89bb
#include <ntapi/nt_sysinfo.h>
dd89bb
#include <ntapi/nt_memory.h>
dd89bb
#include <ntapi/ntapi.h>
dd89bb
#include "ntapi_impl.h"
dd89bb
dd89bb
int32_t __stdcall __ntapi_tt_get_system_info_snapshot(
dd89bb
	__in_out nt_system_information_snapshot * sys_info_snapshot)
dd89bb
{
dd89bb
	int32_t		status;
dd89bb
dd89bb
	/* pre-allocated buffer? */
dd89bb
	if (sys_info_snapshot->buffer)
dd89bb
		status = __ntapi->zw_query_system_information(
dd89bb
			sys_info_snapshot->sys_info_class,
dd89bb
			sys_info_snapshot->buffer,
dd89bb
			sys_info_snapshot->max_len,
dd89bb
			&sys_info_snapshot->info_len);
dd89bb
	else {
dd89bb
		/* set initial buffer size */
dd89bb
		sys_info_snapshot->max_len = NT_ALLOCATION_GRANULARITY;
dd89bb
dd89bb
		/* allocate initial buffer */
dd89bb
		status = __ntapi->zw_allocate_virtual_memory(
dd89bb
			NT_CURRENT_PROCESS_HANDLE,
dd89bb
			(void **)&sys_info_snapshot->buffer,
dd89bb
			0,
dd89bb
			&sys_info_snapshot->max_len,
dd89bb
			NT_MEM_COMMIT,
dd89bb
			NT_PAGE_READWRITE);
dd89bb
dd89bb
		/* verification */
dd89bb
		if (status != NT_STATUS_SUCCESS)
dd89bb
			return status;
dd89bb
dd89bb
		/* loop until buffer is large enough to satisfy the system */
dd89bb
		while ((status = __ntapi->zw_query_system_information(
dd89bb
					sys_info_snapshot->sys_info_class,
dd89bb
					sys_info_snapshot->buffer,
dd89bb
					sys_info_snapshot->max_len,
dd89bb
					&sys_info_snapshot->info_len))
dd89bb
				== NT_STATUS_INFO_LENGTH_MISMATCH) {
dd89bb
dd89bb
			/* free previously allocated memory */
dd89bb
			status = __ntapi->zw_free_virtual_memory(
dd89bb
					NT_CURRENT_PROCESS_HANDLE,
dd89bb
					(void **)&sys_info_snapshot->buffer,
dd89bb
					&sys_info_snapshot->max_len,
dd89bb
					NT_MEM_RELEASE);
dd89bb
dd89bb
			/* verification */
dd89bb
			if (status != NT_STATUS_SUCCESS)
dd89bb
				return status;
dd89bb
dd89bb
			/* reset buffer and increase buffer size */
dd89bb
			sys_info_snapshot->buffer = (nt_system_information_buffer *)0;
dd89bb
			sys_info_snapshot->max_len += NT_ALLOCATION_GRANULARITY;
dd89bb
dd89bb
			/* reallocate buffer memory */
dd89bb
			status = __ntapi->zw_allocate_virtual_memory(
dd89bb
					NT_CURRENT_PROCESS_HANDLE,
dd89bb
					(void **)&sys_info_snapshot->buffer,
dd89bb
					0,
dd89bb
					&sys_info_snapshot->max_len,
dd89bb
					NT_MEM_COMMIT,
dd89bb
					NT_PAGE_READWRITE);
dd89bb
dd89bb
			/* verification */
dd89bb
			if (status != NT_STATUS_SUCCESS)
dd89bb
				return status;
dd89bb
		}
dd89bb
	}
dd89bb
dd89bb
	/* verification */
dd89bb
	if (status == NT_STATUS_SUCCESS) {
dd89bb
		sys_info_snapshot->pcurrent = &sys_info_snapshot->buffer->mark;
dd89bb
		return NT_STATUS_SUCCESS;
dd89bb
	} else {
dd89bb
		sys_info_snapshot->pcurrent = (void *)0;
dd89bb
		return status;
dd89bb
	}
dd89bb
}