summaryrefslogtreecommitdiffhomepage
path: root/src/system/ntapi_tt_get_system_info_snapshot.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/system/ntapi_tt_get_system_info_snapshot.c')
-rw-r--r--src/system/ntapi_tt_get_system_info_snapshot.c89
1 files changed, 89 insertions, 0 deletions
diff --git a/src/system/ntapi_tt_get_system_info_snapshot.c b/src/system/ntapi_tt_get_system_info_snapshot.c
new file mode 100644
index 0000000..bfe2978
--- /dev/null
+++ b/src/system/ntapi_tt_get_system_info_snapshot.c
@@ -0,0 +1,89 @@
+/********************************************************/
+/* ntapi: Native API core library */
+/* Copyright (C) 2013,2014,2015 Z. Gilboa */
+/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */
+/********************************************************/
+
+#include <psxtypes/psxtypes.h>
+#include <pemagine/pemagine.h>
+#include <ntapi/nt_sysinfo.h>
+#include <ntapi/nt_memory.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+
+int32_t __stdcall __ntapi_tt_get_system_info_snapshot(
+ __in_out nt_system_information_snapshot * sys_info_snapshot)
+{
+ int32_t status;
+
+ /* pre-allocated buffer? */
+ if (sys_info_snapshot->buffer)
+ status = __ntapi->zw_query_system_information(
+ sys_info_snapshot->sys_info_class,
+ sys_info_snapshot->buffer,
+ sys_info_snapshot->max_len,
+ &sys_info_snapshot->info_len);
+ else {
+ /* set initial buffer size */
+ sys_info_snapshot->max_len = NT_ALLOCATION_GRANULARITY;
+
+ /* allocate initial buffer */
+ status = __ntapi->zw_allocate_virtual_memory(
+ NT_CURRENT_PROCESS_HANDLE,
+ (void **)&sys_info_snapshot->buffer,
+ 0,
+ &sys_info_snapshot->max_len,
+ NT_MEM_COMMIT,
+ NT_PAGE_READWRITE);
+
+ /* verification */
+ if (status != NT_STATUS_SUCCESS)
+ return status;
+
+ /* loop until buffer is large enough to satisfy the system */
+ while ((status = __ntapi->zw_query_system_information(
+ sys_info_snapshot->sys_info_class,
+ sys_info_snapshot->buffer,
+ sys_info_snapshot->max_len,
+ &sys_info_snapshot->info_len))
+ == NT_STATUS_INFO_LENGTH_MISMATCH) {
+
+ /* free previously allocated memory */
+ status = __ntapi->zw_free_virtual_memory(
+ NT_CURRENT_PROCESS_HANDLE,
+ (void **)&sys_info_snapshot->buffer,
+ &sys_info_snapshot->max_len,
+ NT_MEM_RELEASE);
+
+ /* verification */
+ if (status != NT_STATUS_SUCCESS)
+ return status;
+
+ /* reset buffer and increase buffer size */
+ sys_info_snapshot->buffer = (nt_system_information_buffer *)0;
+ sys_info_snapshot->max_len += NT_ALLOCATION_GRANULARITY;
+
+ /* reallocate buffer memory */
+ status = __ntapi->zw_allocate_virtual_memory(
+ NT_CURRENT_PROCESS_HANDLE,
+ (void **)&sys_info_snapshot->buffer,
+ 0,
+ &sys_info_snapshot->max_len,
+ NT_MEM_COMMIT,
+ NT_PAGE_READWRITE);
+
+ /* verification */
+ if (status != NT_STATUS_SUCCESS)
+ return status;
+ }
+ }
+
+ /* verification */
+ if (status == NT_STATUS_SUCCESS) {
+ sys_info_snapshot->pcurrent = &sys_info_snapshot->buffer->mark;
+ return NT_STATUS_SUCCESS;
+ } else {
+ sys_info_snapshot->pcurrent = (void *)0;
+ return status;
+ }
+}