qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 3/3] qga support process list, netstat and file stat/delete
@ 2015-03-25 12:25 itamar.tal4
  2015-03-26 19:24 ` Eric Blake
  0 siblings, 1 reply; 2+ messages in thread
From: itamar.tal4 @ 2015-03-25 12:25 UTC (permalink / raw)
  To: qemu-devel; +Cc: ori, ariel, mdroth, pavel, Itamar Tal

From: Itamar Tal <itamar@guardicore.com>

this patch add support for some more functionality in the qemu-guest-agent,
both for windows and linux. Main added features are:
- interface listing in Windows
- Process list in Windows
- network connections enumeration in Windows
- file delete for both Windows and Posix
- file stat() for both Windows and Posix
- system uptime for both Windows and Posix

Itamar,
Guardicore
itamar@guardicore.com

---
 qga/commands-posix.c    |  49 +++++
 qga/commands-win32.c    | 552 +++++++++++++++++++++++++++++++++++++++++++++++-
 qga/commands.c          |  25 +++
 qga/guest-agent-core.h  |   2 +
 qga/main.c              |   9 +
 qga/qapi-schema.json    | 172 +++++++++++++++
 qga/win32-definitions.h | 115 ++++++++++
 qga/win32-iptypes.h     | 411 +++++++++++++++++++++++++++++++++++
 8 files changed, 1332 insertions(+), 3 deletions(-)
 create mode 100644 qga/win32-definitions.h
 create mode 100644 qga/win32-iptypes.h

diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index ba8de62..15e39fc 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -23,6 +23,7 @@
 #include <string.h>
 #include <sys/stat.h>
 #include <inttypes.h>
+#include <sys/sysinfo.h>
 #include "qga/guest-agent-core.h"
 #include "qga-qmp-commands.h"
 #include "qapi/qmp/qerror.h"
@@ -2456,3 +2457,51 @@ void ga_command_state_init(GAState *s, GACommandState *cs)
 #endif
     ga_command_state_add(cs, guest_file_init, NULL);
 }
+
+uint64_t qmp_guest_uptime(Error **errp)
+{
+	struct sysinfo sys_info;
+	if (sysinfo(&sys_info))
+	{
+		error_setg(errp, "Failed reading system info");
+	}
+
+	return sys_info.uptime;
+}
+
+GuestFileStat *qmp_guest_file_stat(const char *path, Error **errp)
+{
+	GuestFileStat * file_stat = g_malloc0(sizeof(GuestFileStat));
+	struct stat file_os_stat;
+
+	if (stat(path, &file_os_stat))
+	{
+		error_setg(errp, "Failed to get file stat() for file '%s'", path);
+		return NULL;
+	}
+
+	file_stat->mode = file_os_stat.st_mode;
+	file_stat->inode = file_os_stat.st_ino;
+	file_stat->dev = file_os_stat.st_dev;
+	file_stat->nlink = file_os_stat.st_nlink;
+	file_stat->uid = file_os_stat.st_uid;
+	file_stat->gid = file_os_stat.st_gid;
+	file_stat->size = file_os_stat.st_size;
+	file_stat->atime = file_os_stat.st_atime;
+	file_stat->mtime = file_os_stat.st_mtime;
+	file_stat->ctime = file_os_stat.st_ctime;
+
+	return file_stat;
+}
+
+GuestProcessInfoList *qmp_guest_get_process_list(Error **errp)
+{
+	error_set(errp, QERR_UNSUPPORTED);
+	return NULL;
+}
+
+GuestActiveConnectionList *qmp_guest_get_active_connections(Error **errp)
+{
+	error_set(errp, QERR_UNSUPPORTED);
+	return NULL;
+}
diff --git a/qga/commands-win32.c b/qga/commands-win32.c
index 3ef0549..55d8f2e 100644
--- a/qga/commands-win32.c
+++ b/qga/commands-win32.c
@@ -19,6 +19,7 @@
 #include "qga/guest-agent-core.h"
 #include "qga/vss-win32.h"
 #include "qga-qmp-commands.h"
+#include "qga/win32-definitions.h"
 #include "qapi/qmp/qerror.h"
 #include "qemu/queue.h"
 
@@ -26,6 +27,41 @@
 #define SHTDN_REASON_FLAG_PLANNED 0x80000000
 #endif
 
+ULONG (__stdcall * GetAdaptersAddresses)(	uint32_t Family,
+											uint32_t Flags,
+											void * Reserved,
+											IP_ADAPTER_ADDRESSES * AdapterAddresses,
+											uint32_t * SizePointer) = NULL;
+
+DWORD (__stdcall * GetExtendedTcpTable)(void * pTcpTable,
+										DWORD * pdwSize,
+										BOOL bOrder,
+										ULONG ulAf,
+										TCP_TABLE_CLASS TableClass,
+										ULONG Reserved) = NULL;
+
+DWORD (__stdcall * GetExtendedUdpTable)(	void * pUdpTable,
+										DWORD * pdwSize,
+										BOOL bOrder,
+										ULONG ulAf,
+										UDP_TABLE_CLASS TableClass,
+										ULONG Reserved) = NULL;
+
+NTSTATUS (__stdcall * RtlUnicodeStringToAnsiString)(ANSI_STRING * DestinationString,
+													UNICODE_STRING * SourceString,
+													BOOLEAN AllocateDestinationString) = NULL;
+
+NTSTATUS (__stdcall * NtQueryInformationProcess)(	HANDLE ProcessHandle,
+													PROCESSINFOCLASS ProcessInformationClass,
+													void * ProcessInformation,
+													uint32_t ProcessInformationLength,
+													uint32_t * ReturnLength) = NULL;
+
+NTSTATUS (__stdcall * NtQuerySystemInformation)(SYSTEM_INFORMATION_CLASS SystemInformationClass,
+												void * SystemInformation,
+												uint32_t SystemInformationLength,
+												uint32_t * ReturnLength) = NULL;
+
 /* multiple of 100 nanoseconds elapsed between windows baseline
  *    (1/1/1601) and Unix Epoch (1/1/1970), accounting for leap years */
 #define W32_FT_OFFSET (10000000ULL * 60 * 60 * 24 * \
@@ -591,8 +627,132 @@ void qmp_guest_suspend_hybrid(Error **errp)
 
 GuestNetworkInterfaceList *qmp_guest_network_get_interfaces(Error **errp)
 {
-    error_set(errp, QERR_UNSUPPORTED);
-    return NULL;
+	GuestNetworkInterfaceList * iface_list = NULL;
+	IP_ADAPTER_ADDRESSES * ip_adapter_addresses = NULL;
+	IP_ADAPTER_ADDRESSES * current_adapter = NULL;
+	uint32_t adapter_buff_size = 15 * 1024;
+	ULONG ret = 0;
+
+	for (;;)
+	{
+		ip_adapter_addresses = g_malloc0(adapter_buff_size);
+		if (NULL == ip_adapter_addresses)
+		{
+			error_setg(errp, "Failed allocating adapters info buffer");
+			return NULL;
+		}
+
+		ret = GetAdaptersAddresses(	AF_UNSPEC,
+									GAA_FLAG_SKIP_ANYCAST |
+									GAA_FLAG_SKIP_MULTICAST |
+									GAA_FLAG_SKIP_DNS_SERVER |
+									GAA_FLAG_INCLUDE_PREFIX,
+									NULL,
+									ip_adapter_addresses,
+									&adapter_buff_size);
+		if (NO_ERROR != ret)
+		{
+			(void)g_free(ip_adapter_addresses);
+			ip_adapter_addresses = NULL;
+
+			if (ERROR_BUFFER_OVERFLOW == ret)
+			{
+				adapter_buff_size <<= 1;
+				continue;
+			}
+
+			error_setg(errp, "Error quering network adapters info");
+			return NULL;
+		}
+
+		break;
+	}
+
+	/* add all adapters to the list */
+	for (	current_adapter = ip_adapter_addresses;
+			NULL != current_adapter;
+			current_adapter = current_adapter->Next)
+	{
+		IP_ADAPTER_UNICAST_ADDRESS * ip_address = NULL;
+		UNICODE_STRING adapter_name_us;
+		ANSI_STRING adapter_name;
+		GuestNetworkInterfaceList * new_item = g_malloc0(sizeof(GuestNetworkInterfaceList));
+		new_item->value = g_malloc0(sizeof(GuestNetworkInterface));
+		new_item->next = iface_list;
+		iface_list = new_item;
+
+		adapter_name_us.Buffer = current_adapter->FriendlyName;
+		adapter_name_us.Length = wcslen(current_adapter->FriendlyName) * sizeof(wchar_t);
+		adapter_name_us.MaximumLength = adapter_name_us.Length + sizeof(wchar_t);
+		adapter_name.MaximumLength = adapter_name_us.MaximumLength;
+		adapter_name.Length = 0;
+		adapter_name.Buffer = g_malloc0(adapter_name_us.MaximumLength);
+
+		/* convert the adapter name to ansi string */
+		(void)RtlUnicodeStringToAnsiString(	&adapter_name,
+											&adapter_name_us,
+											FALSE);
+		new_item->value->name = adapter_name.Buffer;
+
+		/* copy physical address */
+		if (current_adapter->PhysicalAddressLength != 0)
+		{
+			int i = 0;
+
+			new_item->value->hardware_address = g_malloc0(current_adapter->PhysicalAddressLength * 3 + 1);
+
+			for (i = 0; i < current_adapter->PhysicalAddressLength; ++i)
+			{
+				sprintf(&new_item->value->hardware_address[i * 3],
+						"%02x:", current_adapter->PhysicalAddress[i]);
+			}
+
+			new_item->value->hardware_address[i * 3 - 1] = '\0';
+			new_item->value->has_hardware_address = true;
+		}
+
+		/* build IP list */
+		for (	ip_address = current_adapter->FirstUnicastAddress;
+				NULL != ip_address;
+				ip_address = ip_address->Next)
+		{
+			GuestIpAddressList * new_ip = NULL;
+
+			/* skip unknown addresses */
+			if ((AF_INET != ip_address->Address.lpSockaddr->sa_family) &&
+				(AF_INET6 != ip_address->Address.lpSockaddr->sa_family))
+			{
+				continue;
+			}
+
+			/* allocate new item in the list */
+			new_ip = g_malloc0(sizeof(GuestIpAddressList));
+			new_ip->value = g_malloc0(sizeof(GuestIpAddress));
+			new_item->value->has_ip_addresses = true;
+
+			/* push the new IP at the head of the list */
+			new_ip->next = new_item->value->ip_addresses;
+			new_item->value->ip_addresses = new_ip;
+
+
+			/* convert IP info by family */
+			if (AF_INET == ip_address->Address.lpSockaddr->sa_family)
+			{
+				SOCKADDR_IN * in_addr = (SOCKADDR_IN *)ip_address->Address.lpSockaddr;
+				new_ip->value->ip_address_type = GUEST_IP_ADDRESS_TYPE_IPV4;
+				new_ip->value->ip_address = g_strdup(inet_ntoa(in_addr->sin_addr));
+			}
+			else if (AF_INET6 == ip_address->Address.lpSockaddr->sa_family)
+			{
+				new_ip->value->ip_address_type = GUEST_IP_ADDRESS_TYPE_IPV6;
+				new_ip->value->ip_address = g_strdup("IPv6 not supported");
+			}
+		}
+	}
+
+	(void)g_free(ip_adapter_addresses);
+
+    return iface_list;
 }
 
 int64_t qmp_guest_get_time(Error **errp)
@@ -703,11 +863,73 @@ GuestMemoryBlockInfo *qmp_guest_get_memory_block_info(Error **errp)
     return NULL;
 }
 
+int ga_win_commands_init(void)
+{
+	HMODULE ntdll_module = GetModuleHandle("ntdll.dll");
+	HMODULE iphlpapi_module = LoadLibrary("iphlpapi.dll");
+	WSADATA wsa_data = {0};
+
+	if (WSAStartup(MAKEWORD(2,2), &wsa_data))
+	{
+		g_critical("failed to initialize WSA engine");
+		goto error;
+	}
+
+	if ((NULL == ntdll_module) ||
+		(NULL == iphlpapi_module))
+	{
+		goto error;
+	}
+
+	NtQuerySystemInformation = (void *)GetProcAddress(ntdll_module, "NtQuerySystemInformation");
+	if (NULL == NtQuerySystemInformation)
+	{
+		goto error;
+	}
+
+	RtlUnicodeStringToAnsiString = (void *)GetProcAddress(ntdll_module, "RtlUnicodeStringToAnsiString");
+	if (NULL == RtlUnicodeStringToAnsiString)
+	{
+		goto error;
+	}
+
+	NtQueryInformationProcess = (void *)GetProcAddress(ntdll_module, "NtQueryInformationProcess");
+	if (NULL == NtQueryInformationProcess)
+	{
+		goto error;
+	}
+
+	GetAdaptersAddresses = (void *)GetProcAddress(iphlpapi_module, "GetAdaptersAddresses");
+	if (NULL == GetAdaptersAddresses)
+	{
+		goto error;
+	}
+
+	GetExtendedTcpTable = (void *)GetProcAddress(iphlpapi_module, "GetExtendedTcpTable");
+	if (NULL == GetExtendedTcpTable)
+	{
+		goto error;
+	}
+
+	GetExtendedUdpTable = (void *)GetProcAddress(iphlpapi_module, "GetExtendedUdpTable");
+	if (NULL == GetExtendedUdpTable)
+	{
+		goto error;
+	}
+
+	return 1;
+
+error:
+	(void)FreeLibrary(iphlpapi_module);
+
+	return 0;
+}
+
 /* add unsupported commands to the blacklist */
 GList *ga_command_blacklist_init(GList *blacklist)
 {
     const char *list_unsupported[] = {
-        "guest-suspend-hybrid", "guest-network-get-interfaces",
+        "guest-suspend-hybrid",
         "guest-get-vcpus", "guest-set-vcpus",
         "guest-set-user-password",
         "guest-get-memory-blocks", "guest-set-memory-blocks",
@@ -742,3 +964,327 @@ void ga_command_state_init(GAState *s, GACommandState *cs)
     }
     ga_command_state_add(cs, guest_file_init, NULL);
 }
+
+uint64_t qmp_guest_uptime(Error **errp)
+{
+	uint64_t uptime_milli = GetTickCount();
+	return uptime_milli / 1000;
+}
+
+GuestFileStat *qmp_guest_file_stat(const char *path, Error **errp)
+{
+	GuestFileStat * file_stat = g_malloc0(sizeof(GuestFileStat));
+	struct _stat file_os_stat = {0};
+
+	if (_stat(path, &file_os_stat))
+	{
+		error_setg(errp, "Failed to get file stat() for file '%s': %d", path, (int)GetLastError());
+		return NULL;
+	}
+
+	file_stat->mode = file_os_stat.st_mode;
+	file_stat->inode = file_os_stat.st_ino;
+	file_stat->dev = file_os_stat.st_dev;
+	file_stat->nlink = file_os_stat.st_nlink;
+	file_stat->uid = file_os_stat.st_uid;
+	file_stat->gid = file_os_stat.st_gid;
+	file_stat->size = file_os_stat.st_size;
+	file_stat->atime = file_os_stat.st_atime;
+	file_stat->mtime = file_os_stat.st_mtime;
+	file_stat->ctime = file_os_stat.st_ctime;
+
+	return file_stat;
+}
+
+GuestProcessInfoList *qmp_guest_get_process_list(Error **errp)
+{
+	uint32_t bytes_needed = sizeof(SYSTEM_PROCESS_INFORMATION) * 20;
+	SYSTEM_PROCESS_INFORMATION * process_list = NULL;
+	SYSTEM_PROCESS_INFORMATION * process_list_iter = NULL;
+	GuestProcessInfoList * process_list_head = NULL;
+	GuestProcessInfoList * process_list_last = NULL;
+	NTSTATUS status = STATUS_SUCCESS;
+
+	/* find the minimal buffer for the process list */
+	for (;;)
+	{
+		process_list = g_malloc0(bytes_needed);
+		if (NULL == process_list)
+		{
+			error_setg(errp, "Failed allocating space for process list (%d bytes)", bytes_needed);
+			return NULL;
+		}
+
+		/* query the process list (if enough bytes are given) */
+		status = NtQuerySystemInformation(	SystemProcessInformation,
+											process_list,
+											bytes_needed,
+											&bytes_needed);
+		if (STATUS_SUCCESS != status)
+		{
+			(void)g_free(process_list);
+
+			if (STATUS_INFO_LENGTH_MISMATCH == status)
+			{
+				bytes_needed <<= 1;
+				continue;
+			}
+
+			error_setg(errp, "Failed quering process list (status %08X)", (int)status);
+			return NULL;
+		}
+
+		break;
+	}
+
+	/* iterate the process list and build the JSON reply */
+	for (process_list_iter = process_list;;)
+	{
+		GuestProcessInfoList * list_item = g_malloc0(sizeof(GuestProcessInfoList));
+		ANSI_STRING process_name;
+		HANDLE process_handle = NULL;
+		UNICODE_STRING * process_image_path = NULL;
+		PROCESS_BASIC_INFORMATION process_basic_info = {0};
+
+		if (NULL == process_list_head)
+		{
+			process_list_head = list_item;
+		}
+		if (NULL != process_list_last)
+		{
+			process_list_last->next = list_item;
+		}
+		process_list_last = list_item;
+
+		list_item->next = NULL;
+		list_item->value = g_malloc0(sizeof(GuestProcessInfo));
+		list_item->value->process_id = (int)process_list_iter->UniqueProcessId;
+		list_item->value->session_id = (int)process_list_iter->SessionId;
+
+		process_name.MaximumLength = process_list_iter->ImageName.MaximumLength;
+		process_name.Length = 0;
+		process_name.Buffer = g_malloc0(process_name.MaximumLength);
+
+		/* convert the image name to ansi string */
+		(void)RtlUnicodeStringToAnsiString(	&process_name,
+											&process_list_iter->ImageName,
+											FALSE);
+		list_item->value->process_name = process_name.Buffer;
+
+		if (!process_list_iter->NextEntryOffset)
+		{
+			break;
+		}
+
+		process_handle = OpenProcess(	PROCESS_QUERY_INFORMATION,
+										FALSE,
+										list_item->value->process_id);
+		if (NULL != process_handle)
+		{
+			status = NtQueryInformationProcess(	process_handle,
+												ProcessBasicInformation,
+												&process_basic_info,
+												sizeof(PROCESS_BASIC_INFORMATION),
+												NULL);
+			if (STATUS_SUCCESS == status)
+			{
+				list_item->value->parent_id = (int)process_basic_info.InheritedFromUniqueProcessId;
+			}
+
+			process_image_path = g_malloc0(sizeof(UNICODE_STRING) + 256 * sizeof(wchar_t));
+
+			status = NtQueryInformationProcess(	process_handle,
+												ProcessImageFileName,
+												process_image_path,
+												sizeof(UNICODE_STRING) + 256 * sizeof(wchar_t),
+												NULL);
+			if (STATUS_SUCCESS == status)
+			{
+				process_name.MaximumLength = process_image_path->MaximumLength;
+				process_name.Length = 0;
+				process_name.Buffer = g_malloc0(process_name.MaximumLength);
+
+				/* convert the image name to ansi string */
+				(void)RtlUnicodeStringToAnsiString(	&process_name,
+													process_image_path,
+													FALSE);
+				list_item->value->image_path = process_name.Buffer;
+			}
+
+			(void)g_free(process_image_path);
+
+			(void)CloseHandle(process_handle);
+		}
+
+		process_list_iter = (void *)((uint32_t)process_list_iter + process_list_iter->NextEntryOffset);
+	}
+
+	(void)g_free(process_list);
+
+	return process_list_head;
+}
+
+GuestActiveConnectionList *qmp_guest_get_active_connections(Error **errp)
+{
+	MIB_UDPTABLE_OWNER_MODULE * udp_table = NULL;
+	MIB_TCPTABLE_OWNER_MODULE * tcp_table = NULL;
+	DWORD bytes_needed = sizeof(MIB_UDPTABLE_OWNER_MODULE) * 30;
+	GuestActiveConnectionList * connections = NULL;
+	int entry_index = 0;
+	DWORD ret;
+
+	/* get the UDP table */
+	for (;;)
+	{
+		udp_table = g_malloc0(bytes_needed);
+		if (NULL == udp_table)
+		{
+			error_setg(errp, "Failed allocating active UDP connections table");
+			return NULL;
+		}
+
+		ret = GetExtendedUdpTable(	udp_table,
+									&bytes_needed,
+									TRUE,
+									AF_INET,
+									UDP_TABLE_OWNER_MODULE,
+									0);
+		if (NO_ERROR != ret)
+		{
+			(void)g_free(tcp_table);
+			udp_table = NULL;
+
+			if (ERROR_INSUFFICIENT_BUFFER == ret)
+			{
+				bytes_needed <<= 1;
+				continue;
+			}
+		}
+
+		break;
+	}
+
+	/* add the UDP connections to the list backward */
+	for (	entry_index = udp_table->dwNumEntries - 1;
+			entry_index >= 0;
+			--entry_index)
+	{
+		/* allocate new active connection item */
+		GuestActiveConnectionList * new_item = g_malloc0(sizeof(GuestActiveConnectionList));
+		new_item->value = g_malloc0(sizeof(GuestActiveConnection));
+
+		/* push the connection to the head of the list */
+		new_item->next = connections;
+		connections = new_item;
+
+		new_item->value->source_addr = g_strdup(inet_ntoa(*(struct in_addr *)&udp_table->table[entry_index].dwLocalAddr));
+		new_item->value->source_port = htons(udp_table->table[entry_index].dwLocalPort);
+		new_item->value->owner_process_id = udp_table->table[entry_index].dwOwningPid;
+		new_item->value->if_family = GUEST_IP_ADDRESS_TYPE_IPV4;
+		new_item->value->protocol = GUEST_IP_PROTOCOL_UDP;
+		new_item->value->start_time = udp_table->table[entry_index].liCreateTimestamp.QuadPart;
+	}
+
+	(void)g_free(udp_table);
+	udp_table = NULL;
+
+	bytes_needed = sizeof(MIB_TCPROW_OWNER_PID) * 30;
+
+	/* get the TCP table */
+	for (;;)
+	{
+		tcp_table = g_malloc0(bytes_needed);
+		if (NULL == tcp_table)
+		{
+			error_setg(errp, "Failed allocating active connections table");
+			return NULL;
+		}
+
+		ret = GetExtendedTcpTable(	tcp_table,
+									&bytes_needed,
+									TRUE,
+									AF_INET,
+									TCP_TABLE_OWNER_MODULE_ALL,
+									0);
+		if (NO_ERROR != ret)
+		{
+			(void)g_free(tcp_table);
+			tcp_table = NULL;
+
+			if (ERROR_INSUFFICIENT_BUFFER == ret)
+			{
+				bytes_needed <<= 1;
+				continue;
+			}
+		}
+
+		break;
+	}
+
+	/* add the TCP connections to the list backward */
+	for (	entry_index = tcp_table->dwNumEntries - 1;
+			entry_index >= 0;
+			--entry_index)
+	{
+		/* allocate new active connection item */
+		GuestActiveConnectionList * new_item = g_malloc0(sizeof(GuestActiveConnectionList));
+		new_item->value = g_malloc0(sizeof(GuestActiveConnection));
+
+		/* push the connection to the head of the list */
+		new_item->next = connections;
+		connections = new_item;
+
+		new_item->value->source_addr = g_strdup(inet_ntoa(*(struct in_addr *)&tcp_table->table[entry_index].dwLocalAddr));
+		new_item->value->source_port = htons(tcp_table->table[entry_index].dwLocalPort);
+		new_item->value->dest_addr = g_strdup(inet_ntoa(*(struct in_addr *)&tcp_table->table[entry_index].dwRemoteAddr));
+		new_item->value->dest_port = htons(tcp_table->table[entry_index].dwRemotePort);
+		new_item->value->owner_process_id = tcp_table->table[entry_index].dwOwningPid;
+		new_item->value->if_family = GUEST_IP_ADDRESS_TYPE_IPV4;
+		new_item->value->protocol = GUEST_IP_PROTOCOL_TCP;
+		new_item->value->start_time = tcp_table->table[entry_index].liCreateTimestamp.QuadPart;
+
+		switch (tcp_table->table[entry_index].dwState)
+		{
+		case MIB_TCP_STATE_CLOSED:
+			new_item->value->state = GUEST_TCP_PROTOCOL_STATE_CLOSED;
+			break;
+		case MIB_TCP_STATE_LISTEN:
+			new_item->value->state = GUEST_TCP_PROTOCOL_STATE_LISTEN;
+			break;
+		case MIB_TCP_STATE_SYN_SENT:
+			new_item->value->state = GUEST_TCP_PROTOCOL_STATE_SYN_SENT;
+			break;
+		case MIB_TCP_STATE_SYN_RCVD:
+			new_item->value->state = GUEST_TCP_PROTOCOL_STATE_SYN_RCVD;
+			break;
+		case MIB_TCP_STATE_ESTAB:
+			new_item->value->state = GUEST_TCP_PROTOCOL_STATE_ESTABLISHED;
+			break;
+		case MIB_TCP_STATE_FIN_WAIT1:
+			new_item->value->state = GUEST_TCP_PROTOCOL_STATE_FIN_WAIT1;
+			break;
+		case MIB_TCP_STATE_FIN_WAIT2:
+			new_item->value->state = GUEST_TCP_PROTOCOL_STATE_FIN_WAIT2;
+			break;
+		case MIB_TCP_STATE_CLOSE_WAIT:
+			new_item->value->state = GUEST_TCP_PROTOCOL_STATE_CLOSE_WAIT;
+			break;
+		case MIB_TCP_STATE_CLOSING:
+			new_item->value->state = GUEST_TCP_PROTOCOL_STATE_CLOSING;
+			break;
+		case MIB_TCP_STATE_LAST_ACK:
+			new_item->value->state = GUEST_TCP_PROTOCOL_STATE_LAST_ACK;
+			break;
+		case MIB_TCP_STATE_TIME_WAIT:
+			new_item->value->state = GUEST_TCP_PROTOCOL_STATE_TIME_WAIT;
+			break;
+		case MIB_TCP_STATE_DELETE_TCB:
+			new_item->value->state = GUEST_TCP_PROTOCOL_STATE_DELETE_TCB;
+			break;
+		}
+	}
+
+	(void)g_free(tcp_table);
+
+	return connections;
+}
diff --git a/qga/commands.c b/qga/commands.c
index 7834967..2fb364c 100644
--- a/qga/commands.c
+++ b/qga/commands.c
@@ -70,3 +70,28 @@ struct GuestAgentInfo *qmp_guest_info(Error **errp)
     qmp_for_each_command(qmp_command_info, info);
     return info;
 }
+
+void qmp_guest_file_delete(const char *path, Error **errp)
+{
+	if (unlink(path))
+	{
+		error_setg(errp, "Error deleting file '%s'", path);
+	}
+}
+
+char *qmp_guest_get_hostname(Error **errp)
+{
+	char hostname[64];
+
+	if (gethostname(hostname, 64))
+	{
+#ifdef _WIN32
+		error_setg(errp, "Error getting hostname (%d)", WSAGetLastError());
+#else
+		error_setg(errp, "Error getting hostname");
+#endif
+		return NULL;
+	}
+
+	return g_strdup(hostname);
+}
diff --git a/qga/guest-agent-core.h b/qga/guest-agent-core.h
index e92c6ab..89d4165 100644
--- a/qga/guest-agent-core.h
+++ b/qga/guest-agent-core.h
@@ -40,4 +40,6 @@ int64_t ga_get_fd_handle(GAState *s, Error **errp);
 
 #ifndef _WIN32
 void reopen_fd_to_null(int fd);
+#else
+int ga_win_commands_init(void);
 #endif
diff --git a/qga/main.c b/qga/main.c
index 9939a2b..3992aac 100644
--- a/qga/main.c
+++ b/qga/main.c
@@ -1163,6 +1163,15 @@ int main(int argc, char **argv)
         g_critical("failed to register signal handlers");
         goto out_bad;
     }
+#else
+    {
+
+    	if (!ga_win_commands_init())
+    	{
+    		g_critical("failed initializing commands module");
+    		goto out_bad;
+    	}
+    }
 #endif
 
     s->main_loop = g_main_loop_new(NULL, false);
diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json
index 95f49e3..1e38f98 100644
--- a/qga/qapi-schema.json
+++ b/qga/qapi-schema.json
@@ -891,3 +891,175 @@
 ##
 { 'command': 'guest-get-memory-block-info',
   'returns': 'GuestMemoryBlockInfo' }
+
+##
+# @GuestFileStat
+#
+# @st_mode: file access permissions mode
+# @st_ino: file inode id
+# @st_dev: file device node
+# @st_nlink: number of links pointing to the file
+# @st_uid: file user id
+# @st_gid: file group id
+# @st_atime: file access time
+# @st_mtime: file modification time
+# @st_ctime: file creation time
+# @st_size: file size in bytes
+#
+# Since: 2.3
+##
+{ 'type': 'GuestFileStat',
+  'data': {'mode': 'int', 'inode': 'int', 'dev': 'int',
+  			'nlink': 'int', 'uid': 'int', 'gid': 'int',
+  			'size': 'uint64', 'atime': 'int', 'mtime': 'int',
+  			'ctime': 'int'
+           }}
+
+##
+# @guest-file-stat:
+#
+# Get the stat() for a file in the guest's operating system
+#
+# Returns: hostname string.
+#
+# Since 2.3
+##
+{ 'command': 'guest-file-stat',
+  'data': { 'path': 'str' },
+  'returns': 'GuestFileStat' }
+  
+##
+# @guest-file-delete:
+#
+# Delete a file in the guest's operating system
+#
+# Returns: 
+#
+# Since 2.3
+##
+{ 'command': 'guest-file-delete',
+  'data': { 'path': 'str' }}
+
+##
+# @guest-get-hostname:
+#
+# Get the hostname of the guest's operating system
+#
+# Returns: hostname string.
+#
+# Since 2.3
+##
+{ 'command': 'guest-get-hostname',
+  'returns': 'str' }
+ 
+##
+# @guest-uptime:
+#
+# Get the time in seconds since the guest machine operating system was started
+#
+# Returns: uptime in seconds
+#
+# Since 2.3
+##
+{ 'command': 'guest-uptime',
+  'returns': 'uint64' }
+
+##
+# @GuestProcessInfo
+#
+# @process-id: the process unique id
+# @parent-id: the process parent unique id
+# @process-name: the name of the process
+# @image-path: full path of the process image
+# @session-id: the session id of the process
+#
+# Since: 2.3
+##
+{ 'type': 'GuestProcessInfo',
+  'data': {'process-id': 'int', 'parent-id': 'int', 'process-name': 'str',
+  			'image-path': 'str', 'session-id': 'int'}}
+  
+##
+# @guest-get-process-list:
+#
+# Get the list of active processes on the guest operating system
+#
+# Returns: array of active processes
+#
+# Since 2.3
+##
+{ 'command': 'guest-get-process-list',
+  'returns': ['GuestProcessInfo'] }
+
+##
+# @GuestIpProtocol:
+#
+# An enumeration of supported IP protocols
+#
+# @tcp: TCP
+#
+# @udp: UDP
+#
+# Since: 2.3
+##
+{ 'enum': 'GuestIpProtocol',
+  'data': [ 'tcp', 'udp' ] }
+  
+##
+# @GuestTcpProtocolState:
+#
+# An enumeration of TCP connection state
+#
+# @closed: CLOSED
+# @listen: LISTEN
+# @syn-sent: SYN_SENT
+# @syn-rcvd: SYN_RCVD
+# @established: ESTABLISHED
+# @fin-wait1: FIN_WAIT1
+# @fin-wait2: FIN_WAIT2
+# @close-wait: CLOSE_WAIT
+# @closing: CLOSING
+# @last-ack: LAST_ACK
+# @time-wait: TIME_WAIT
+# @delete-tcb: DELETE_TCB
+#
+# Since: 2.3
+##
+{ 'enum': 'GuestTcpProtocolState',
+  'data': [ 'closed', 'listen', 'syn-sent', 'syn-rcvd', 'established',
+  			'fin-wait1', 'fin-wait2', 'close-wait', 'closing',
+  			'last-ack', 'time-wait', 'delete-tcb' ] }
+
+##
+# @GuestActiveConnection
+#
+# @if-family: 4 / 6
+# @protocol: TCP / UDP
+# @source-addr: the source IP address of the connection
+# @source-port: the source port of the connection
+# @dest-addr: the destination IP address of the connection
+# @dest-port: the destination port of the connection
+# @owner-process_id: the process unique id for the connection owner
+# @state: connection protocol state
+# @start-time: time where bind() was called for the connection
+#
+# Since: 2.3
+##
+{ 'type': 'GuestActiveConnection',
+  'data': {	'source-addr': 'str', 'source-port': 'int', 'dest-addr': 'str',
+  			'dest-port': 'int', 'owner-process_id': 'int', 'state': 'GuestTcpProtocolState',
+  			'if-family': 'GuestIpAddressType', 'protocol': 'GuestIpProtocol',
+  			'start-time': 'uint64'}}
+ 
+ ##
+# @guest-get-active-connections:
+#
+# Get the list of active connections on the guest operating system
+#
+# Returns: array of active connections
+#
+# Since 2.3
+##
+{ 'command': 'guest-get-active-connections',
+  'returns': ['GuestActiveConnection'] }
+ 
diff --git a/qga/win32-definitions.h b/qga/win32-definitions.h
new file mode 100644
index 0000000..6bb610e
--- /dev/null
+++ b/qga/win32-definitions.h
@@ -0,0 +1,115 @@
+
+#ifndef WIN32_DEFINITIONS_H_
+#define WIN32_DEFINITIONS_H_	1
+
+#include "win32-iptypes.h"
+
+#define STATUS_INFO_LENGTH_MISMATCH		(0xC0000004)
+
+typedef
+enum _PROCESSINFOCLASS
+{
+	ProcessBasicInformation=0x0000,
+	ProcessDebugPort=0x0007,
+	ProcessWow64Information=0x001a,
+	ProcessImageFileName=0x001b,
+	ProcessBreakOnTermination=0x001d,
+} PROCESSINFOCLASS;
+
+typedef struct
+{
+    ULONG          AllocationSize;
+    ULONG          ActualSize;
+    ULONG          Flags;
+    ULONG          Unknown1;
+    UNICODE_STRING Unknown2;
+    HANDLE         InputHandle;
+    HANDLE         OutputHandle;
+    HANDLE         ErrorHandle;
+    UNICODE_STRING CurrentDirectory;
+    HANDLE         CurrentDirectoryHandle;
+    UNICODE_STRING SearchPaths;
+    UNICODE_STRING ApplicationName;
+    UNICODE_STRING CommandLine;
+    PVOID          EnvironmentBlock;
+    ULONG          Unknown[9];
+    UNICODE_STRING Unknown3;
+    UNICODE_STRING Unknown4;
+    UNICODE_STRING Unknown5;
+    UNICODE_STRING Unknown6;
+} PROCESS_PARAMETERS, *PPROCESS_PARAMETERS;
+
+typedef struct
+{
+    ULONG               AllocationSize;
+    ULONG               Unknown1;
+    HINSTANCE           ProcessHinstance;
+    PVOID               ListDlls;
+    PPROCESS_PARAMETERS ProcessParameters;
+    ULONG               Unknown2;
+    HANDLE              Heap;
+} PEB, *PPEB;
+
+typedef struct
+{
+    DWORD ExitStatus;
+    PPEB  PebBaseAddress;
+    DWORD AffinityMask;
+    DWORD BasePriority;
+    ULONG UniqueProcessId;
+    ULONG InheritedFromUniqueProcessId;
+}   PROCESS_BASIC_INFORMATION;
+
+typedef
+enum _SYSTEM_INFORMATION_CLASS
+{
+    SystemBasicInformation=0x0000,
+    SystemProcessorInformation=0x0001,
+    SystemPerformanceInformation=0x0002,
+    SystemTimeOfDayInformation=0x0003,
+    SystemPathInformation=0x0004,
+    SystemProcessInformation=0x0005,
+    SystemDeviceInformation=0x0007,
+    SystemModuleInformation=0x000B,
+} SYSTEM_INFORMATION_CLASS;
+
+typedef
+struct _SYSTEM_PROCESS_INFORMATION // Size=184
+{
+    ULONG NextEntryOffset; // Size=4 Offset=0
+    ULONG NumberOfThreads; // Size=4 Offset=4
+    LARGE_INTEGER WorkingSetPrivateSize; // Size=8 Offset=8
+    ULONG HardFaultCount; // Size=4 Offset=16
+    ULONG NumberOfThreadsHighWatermark; // Size=4 Offset=20
+    ULONGLONG CycleTime; // Size=8 Offset=24
+    LARGE_INTEGER CreateTime; // Size=8 Offset=32
+    LARGE_INTEGER UserTime; // Size=8 Offset=40
+    LARGE_INTEGER KernelTime; // Size=8 Offset=48
+    UNICODE_STRING ImageName; // Size=8 Offset=56
+    LONG BasePriority; // Size=4 Offset=64
+    PVOID UniqueProcessId; // Size=4 Offset=68
+    PVOID InheritedFromUniqueProcessId; // Size=4 Offset=72
+    ULONG HandleCount; // Size=4 Offset=76
+    ULONG SessionId; // Size=4 Offset=80
+    ULONG UniqueProcessKey; // Size=4 Offset=84
+    ULONG PeakVirtualSize; // Size=4 Offset=88
+    ULONG VirtualSize; // Size=4 Offset=92
+    ULONG PageFaultCount; // Size=4 Offset=96
+    ULONG PeakWorkingSetSize; // Size=4 Offset=100
+    ULONG WorkingSetSize; // Size=4 Offset=104
+    ULONG QuotaPeakPagedPoolUsage; // Size=4 Offset=108
+    ULONG QuotaPagedPoolUsage; // Size=4 Offset=112
+    ULONG QuotaPeakNonPagedPoolUsage; // Size=4 Offset=116
+    ULONG QuotaNonPagedPoolUsage; // Size=4 Offset=120
+    ULONG PagefileUsage; // Size=4 Offset=124
+    ULONG PeakPagefileUsage; // Size=4 Offset=128
+    ULONG PrivatePageCount; // Size=4 Offset=132
+    LARGE_INTEGER ReadOperationCount; // Size=8 Offset=136
+    LARGE_INTEGER WriteOperationCount; // Size=8 Offset=144
+    LARGE_INTEGER OtherOperationCount; // Size=8 Offset=152
+    LARGE_INTEGER ReadTransferCount; // Size=8 Offset=160
+    LARGE_INTEGER WriteTransferCount; // Size=8 Offset=168
+    LARGE_INTEGER OtherTransferCount; // Size=8 Offset=176
+} SYSTEM_PROCESS_INFORMATION;
+
+#endif /* WIN32_DEFINITIONS_H_ */
diff --git a/qga/win32-iptypes.h b/qga/win32-iptypes.h
new file mode 100644
index 0000000..baae4ea
--- /dev/null
+++ b/qga/win32-iptypes.h
@@ -0,0 +1,411 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+Module Name:
+
+    iptypes.h
+
+--*/
+
+#ifndef IP_TYPES_INCLUDED
+#define IP_TYPES_INCLUDED
+
+#include <time.h>
+
+#define INET_ADDRSTRLEN         (16)
+#define INET6_ADDRSTRLEN        (48)
+
+// Definitions and structures used by getnetworkparams and getadaptersinfo apis
+
+#define MAX_ADAPTER_DESCRIPTION_LENGTH  128 // arb.
+#define MAX_ADAPTER_NAME_LENGTH         256 // arb.
+#define MAX_ADAPTER_ADDRESS_LENGTH      8   // arb.
+#define DEFAULT_MINIMUM_ENTITIES        32  // arb.
+#define MAX_HOSTNAME_LEN                128 // arb.
+#define MAX_DOMAIN_NAME_LEN             128 // arb.
+#define MAX_SCOPE_ID_LEN                256 // arb.
+
+//
+// types
+//
+
+// Node Type
+
+#define BROADCAST_NODETYPE              1
+#define PEER_TO_PEER_NODETYPE           2
+#define MIXED_NODETYPE                  4
+#define HYBRID_NODETYPE                 8
+
+//
+// IP_ADDRESS_STRING - store an IP address as a dotted decimal string
+//
+
+typedef struct {
+    char String[4 * 4];
+} IP_ADDRESS_STRING, *PIP_ADDRESS_STRING, IP_MASK_STRING, *PIP_MASK_STRING;
+
+//
+// IP_ADDR_STRING - store an IP address with its corresponding subnet mask,
+// both as dotted decimal strings
+//
+
+typedef struct _IP_ADDR_STRING {
+    struct _IP_ADDR_STRING* Next;
+    IP_ADDRESS_STRING IpAddress;
+    IP_MASK_STRING IpMask;
+    DWORD Context;
+} IP_ADDR_STRING, *PIP_ADDR_STRING;
+
+//
+// ADAPTER_INFO - per-adapter information. All IP addresses are stored as
+// strings
+//
+
+typedef struct _IP_ADAPTER_INFO {
+    struct _IP_ADAPTER_INFO* Next;
+    DWORD ComboIndex;
+    char AdapterName[MAX_ADAPTER_NAME_LENGTH + 4];
+    char Description[MAX_ADAPTER_DESCRIPTION_LENGTH + 4];
+    UINT AddressLength;
+    BYTE Address[MAX_ADAPTER_ADDRESS_LENGTH];
+    DWORD Index;
+    UINT Type;
+    UINT DhcpEnabled;
+    PIP_ADDR_STRING CurrentIpAddress;
+    IP_ADDR_STRING IpAddressList;
+    IP_ADDR_STRING GatewayList;
+    IP_ADDR_STRING DhcpServer;
+    BOOL HaveWins;
+    IP_ADDR_STRING PrimaryWinsServer;
+    IP_ADDR_STRING SecondaryWinsServer;
+    time_t LeaseObtained;
+    time_t LeaseExpires;
+} IP_ADAPTER_INFO, *PIP_ADAPTER_INFO;
+
+//
+// The following types require Winsock2.
+//
+
+typedef enum {
+    IpPrefixOriginOther = 0,
+    IpPrefixOriginManual,
+    IpPrefixOriginWellKnown,
+    IpPrefixOriginDhcp,
+    IpPrefixOriginRouterAdvertisement,
+} IP_PREFIX_ORIGIN;
+
+typedef enum {
+    IpSuffixOriginOther = 0,
+    IpSuffixOriginManual,
+    IpSuffixOriginWellKnown,
+    IpSuffixOriginDhcp,
+    IpSuffixOriginLinkLayerAddress,
+    IpSuffixOriginRandom,
+} IP_SUFFIX_ORIGIN;
+
+typedef enum {
+    IpDadStateInvalid    = 0,
+    IpDadStateTentative,
+    IpDadStateDuplicate,
+    IpDadStateDeprecated,
+    IpDadStatePreferred,
+} IP_DAD_STATE;
+
+typedef struct _IP_ADAPTER_UNICAST_ADDRESS {
+    union {
+        ULONGLONG Alignment;
+        struct { 
+            ULONG Length;
+            DWORD Flags;
+        };
+    };
+    struct _IP_ADAPTER_UNICAST_ADDRESS *Next;
+    SOCKET_ADDRESS Address;
+
+    IP_PREFIX_ORIGIN PrefixOrigin;
+    IP_SUFFIX_ORIGIN SuffixOrigin;
+    IP_DAD_STATE DadState;
+
+    ULONG ValidLifetime;
+    ULONG PreferredLifetime;
+    ULONG LeaseLifetime;
+} IP_ADAPTER_UNICAST_ADDRESS, *PIP_ADAPTER_UNICAST_ADDRESS;
+
+typedef struct _IP_ADAPTER_ANYCAST_ADDRESS {
+    union {
+        ULONGLONG Alignment;
+        struct { 
+            ULONG Length;
+            DWORD Flags;
+        };
+    };
+    struct _IP_ADAPTER_ANYCAST_ADDRESS *Next;
+    SOCKET_ADDRESS Address;
+} IP_ADAPTER_ANYCAST_ADDRESS, *PIP_ADAPTER_ANYCAST_ADDRESS;
+
+typedef struct _IP_ADAPTER_MULTICAST_ADDRESS {
+    union {
+        ULONGLONG Alignment;
+        struct {
+            ULONG Length;
+            DWORD Flags;
+        };
+    };
+    struct _IP_ADAPTER_MULTICAST_ADDRESS *Next;
+    SOCKET_ADDRESS Address;
+} IP_ADAPTER_MULTICAST_ADDRESS, *PIP_ADAPTER_MULTICAST_ADDRESS;
+
+//
+// Per-address Flags
+//
+#define IP_ADAPTER_ADDRESS_DNS_ELIGIBLE 0x01
+#define IP_ADAPTER_ADDRESS_TRANSIENT    0x02
+
+typedef struct _IP_ADAPTER_DNS_SERVER_ADDRESS {
+    union {
+        ULONGLONG Alignment;
+        struct {
+            ULONG Length;
+            DWORD Reserved;
+        };
+    };
+    struct _IP_ADAPTER_DNS_SERVER_ADDRESS *Next;
+    SOCKET_ADDRESS Address;
+} IP_ADAPTER_DNS_SERVER_ADDRESS, *PIP_ADAPTER_DNS_SERVER_ADDRESS;
+
+typedef struct _IP_ADAPTER_PREFIX {
+    union {
+        ULONGLONG Alignment;
+        struct {
+            ULONG Length;
+            DWORD Flags;
+        };
+    };
+    struct _IP_ADAPTER_PREFIX *Next;
+    SOCKET_ADDRESS Address;
+    ULONG PrefixLength;
+} IP_ADAPTER_PREFIX, *PIP_ADAPTER_PREFIX;
+
+//
+// Per-adapter Flags
+//
+#define IP_ADAPTER_DDNS_ENABLED               0x01
+#define IP_ADAPTER_REGISTER_ADAPTER_SUFFIX    0x02
+#define IP_ADAPTER_DHCP_ENABLED               0x04
+#define IP_ADAPTER_RECEIVE_ONLY               0x08
+#define IP_ADAPTER_NO_MULTICAST               0x10
+#define IP_ADAPTER_IPV6_OTHER_STATEFUL_CONFIG 0x20
+
+//
+// OperStatus values from RFC 2863
+//
+typedef enum {
+    IfOperStatusUp = 1,
+    IfOperStatusDown,
+    IfOperStatusTesting,
+    IfOperStatusUnknown,
+    IfOperStatusDormant,
+    IfOperStatusNotPresent,
+    IfOperStatusLowerLayerDown
+} IF_OPER_STATUS;
+
+//
+// Scope levels from RFC 2373 used with ZoneIndices array.
+//
+typedef enum {
+    ScopeLevelInterface    = 1,
+    ScopeLevelLink         = 2,
+    ScopeLevelSubnet       = 3,
+    ScopeLevelAdmin        = 4,
+    ScopeLevelSite         = 5,
+    ScopeLevelOrganization = 8,
+    ScopeLevelGlobal       = 14
+} SCOPE_LEVEL;
+
+typedef struct _IP_ADAPTER_ADDRESSES {
+    union {
+        ULONGLONG Alignment;
+        struct {
+            ULONG Length;
+            DWORD IfIndex;
+        };
+    };
+    struct _IP_ADAPTER_ADDRESSES *Next;
+    PCHAR AdapterName;
+    PIP_ADAPTER_UNICAST_ADDRESS FirstUnicastAddress;
+    PIP_ADAPTER_ANYCAST_ADDRESS FirstAnycastAddress;
+    PIP_ADAPTER_MULTICAST_ADDRESS FirstMulticastAddress;
+    PIP_ADAPTER_DNS_SERVER_ADDRESS FirstDnsServerAddress;
+    PWCHAR DnsSuffix;
+    PWCHAR Description;
+    PWCHAR FriendlyName;
+    BYTE PhysicalAddress[MAX_ADAPTER_ADDRESS_LENGTH];
+    DWORD PhysicalAddressLength;
+    DWORD Flags;
+    DWORD Mtu;
+    DWORD IfType;
+    IF_OPER_STATUS OperStatus;
+    DWORD Ipv6IfIndex;
+    DWORD ZoneIndices[16];
+    PIP_ADAPTER_PREFIX FirstPrefix;
+} IP_ADAPTER_ADDRESSES, *PIP_ADAPTER_ADDRESSES;
+
+//
+// Flags used as argument to GetAdaptersAddresses().
+// "SKIP" flags are added when the default is to include the information.
+// "INCLUDE" flags are added when the default is to skip the information.
+//
+#define GAA_FLAG_SKIP_UNICAST       0x0001
+#define GAA_FLAG_SKIP_ANYCAST       0x0002
+#define GAA_FLAG_SKIP_MULTICAST     0x0004
+#define GAA_FLAG_SKIP_DNS_SERVER    0x0008
+#define GAA_FLAG_INCLUDE_PREFIX     0x0010
+#define GAA_FLAG_SKIP_FRIENDLY_NAME 0x0020
+
+//
+// IP_PER_ADAPTER_INFO - per-adapter IP information such as DNS server list.
+//
+
+typedef struct _IP_PER_ADAPTER_INFO {
+    UINT AutoconfigEnabled;
+    UINT AutoconfigActive;
+    PIP_ADDR_STRING CurrentDnsServer;
+    IP_ADDR_STRING DnsServerList;
+} IP_PER_ADAPTER_INFO, *PIP_PER_ADAPTER_INFO;
+
+//
+// FIXED_INFO - the set of IP-related information which does not depend on DHCP
+//
+
+typedef struct {
+    char HostName[MAX_HOSTNAME_LEN + 4] ;
+    char DomainName[MAX_DOMAIN_NAME_LEN + 4];
+    PIP_ADDR_STRING CurrentDnsServer;
+    IP_ADDR_STRING DnsServerList;
+    UINT NodeType;
+    char ScopeId[MAX_SCOPE_ID_LEN + 4];
+    UINT EnableRouting;
+    UINT EnableProxy;
+    UINT EnableDns;
+} FIXED_INFO, *PFIXED_INFO;
+
+typedef struct ip_interface_name_info {
+    ULONG           Index;      // Interface Index
+    ULONG           MediaType;  // Interface Types - see ipifcons.h
+    UCHAR           ConnectionType;
+    UCHAR           AccessType;
+    GUID            DeviceGuid; // Device GUID is the guid of the device
+                                // that IP exposes
+    GUID            InterfaceGuid; // Interface GUID, if not GUID_NULL is the
+                                // GUID for the interface mapped to the device.
+} IP_INTERFACE_NAME_INFO, *PIP_INTERFACE_NAME_INFO;
+
+typedef enum  {
+  TCP_TABLE_BASIC_LISTENER,
+  TCP_TABLE_BASIC_CONNECTIONS,
+  TCP_TABLE_BASIC_ALL,
+  TCP_TABLE_OWNER_PID_LISTENER,
+  TCP_TABLE_OWNER_PID_CONNECTIONS,
+  TCP_TABLE_OWNER_PID_ALL,
+  TCP_TABLE_OWNER_MODULE_LISTENER,
+  TCP_TABLE_OWNER_MODULE_CONNECTIONS,
+  TCP_TABLE_OWNER_MODULE_ALL
+} TCP_TABLE_CLASS, *PTCP_TABLE_CLASS;
+
+typedef enum  {
+  UDP_TABLE_BASIC,
+  UDP_TABLE_OWNER_PID,
+  UDP_TABLE_OWNER_MODULE
+} UDP_TABLE_CLASS, *PUDP_TABLE_CLASS;
+
+#define TCPIP_OWNING_MODULE_SIZE 	(16)
+#define ANY_SIZE					(1)
+
+typedef enum
+{
+  MIB_TCP_STATE_CLOSED = 1,
+  MIB_TCP_STATE_LISTEN = 2,
+  MIB_TCP_STATE_SYN_SENT = 3,
+  MIB_TCP_STATE_SYN_RCVD = 4,
+  MIB_TCP_STATE_ESTAB = 5,
+  MIB_TCP_STATE_FIN_WAIT1 = 6,
+  MIB_TCP_STATE_FIN_WAIT2 = 7,
+  MIB_TCP_STATE_CLOSE_WAIT = 8,
+  MIB_TCP_STATE_CLOSING = 9,
+  MIB_TCP_STATE_LAST_ACK = 10,
+  MIB_TCP_STATE_TIME_WAIT = 11,
+  MIB_TCP_STATE_DELETE_TCB = 12
+} MIB_TCP_STATE;
+
+typedef struct _MIB_UDPROW {
+  DWORD dwLocalAddr;
+  DWORD dwLocalPort;
+} MIB_UDPROW, *PMIB_UDPROW;
+
+typedef struct _MIB_UDPTABLE {
+  DWORD      dwNumEntries;
+  MIB_UDPROW table[ANY_SIZE];
+} MIB_UDPTABLE, *PMIB_UDPTABLE;
+
+typedef struct _MIB_UDPROW_OWNER_PID {
+  DWORD dwLocalAddr;
+  DWORD dwLocalPort;
+  DWORD dwOwningPid;
+} MIB_UDPROW_OWNER_PID, *PMIB_UDPROW_OWNER_PID;
+
+typedef struct _MIB_UDPTABLE_OWNER_PID {
+  DWORD                dwNumEntries;
+  MIB_UDPROW_OWNER_PID table[ANY_SIZE];
+} MIB_UDPTABLE_OWNER_PID, *PMIB_UDPTABLE_OWNER_PID;
+
+typedef struct _MIB_UDPROW_OWNER_MODULE {
+  DWORD         dwLocalAddr;
+  DWORD         dwLocalPort;
+  DWORD         dwOwningPid;
+  LARGE_INTEGER liCreateTimestamp;
+  union {
+    struct {
+      int SpecificPortBind  :1;
+    };
+    int    dwFlags;
+  };
+  ULONGLONG     OwningModuleInfo[TCPIP_OWNING_MODULE_SIZE];
+} MIB_UDPROW_OWNER_MODULE, *PMIB_UDPROW_OWNER_MODULE;
+
+typedef struct _MIB_UDPTABLE_OWNER_MODULE {
+  DWORD                   dwNumEntries;
+  MIB_UDPROW_OWNER_MODULE table[ANY_SIZE];
+} MIB_UDPTABLE_OWNER_MODULE, *PMIB_UDPTABLE_OWNER_MODULE;
+
+typedef struct _MIB_TCPROW_OWNER_MODULE {
+  DWORD 		dwState;
+  DWORD         dwLocalAddr;
+  DWORD         dwLocalPort;
+  DWORD         dwRemoteAddr;
+  DWORD         dwRemotePort;
+  DWORD         dwOwningPid;
+  LARGE_INTEGER liCreateTimestamp;
+  ULONGLONG     OwningModuleInfo[TCPIP_OWNING_MODULE_SIZE];
+} MIB_TCPROW_OWNER_MODULE, *PMIB_TCPROW_OWNER_MODULE;
+
+typedef struct {
+  DWORD                   dwNumEntries;
+  MIB_TCPROW_OWNER_MODULE table[ANY_SIZE];
+} MIB_TCPTABLE_OWNER_MODULE, *PMIB_TCPTABLE_OWNER_MODULE;
+
+typedef struct _MIB_TCPROW_OWNER_PID {
+  DWORD dwState;
+  DWORD dwLocalAddr;
+  DWORD dwLocalPort;
+  DWORD dwRemoteAddr;
+  DWORD dwRemotePort;
+  DWORD dwOwningPid;
+} MIB_TCPROW_OWNER_PID, *PMIB_TCPROW_OWNER_PID;
+
+typedef struct {
+  DWORD                dwNumEntries;
+  MIB_TCPROW_OWNER_PID table[ANY_SIZE];
+} MIB_TCPTABLE_OWNER_PID, *PMIB_TCPTABLE_OWNER_PID;
+
+#endif /* IP_TYPES_INCLUDED */ 
-- 
2.3.4

^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2015-03-26 19:24 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-03-25 12:25 [Qemu-devel] [PATCH 3/3] qga support process list, netstat and file stat/delete itamar.tal4
2015-03-26 19:24 ` Eric Blake

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).