Andrew Nguyen : ipconfig: Partially implement basic adapter information output.
Alexandre Julliard
julliard at winehq.org
Tue Aug 17 11:31:18 CDT 2010
Module: wine
Branch: master
Commit: 6ffd8d49be532d62b8e7d0ab2564e78939661fd4
URL: http://source.winehq.org/git/wine.git/?a=commit;h=6ffd8d49be532d62b8e7d0ab2564e78939661fd4
Author: Andrew Nguyen <anguyen at codeweavers.com>
Date: Mon Aug 16 21:27:32 2010 -0500
ipconfig: Partially implement basic adapter information output.
---
programs/ipconfig/En.rc | 5 ++
programs/ipconfig/Makefile.in | 2 +-
programs/ipconfig/ipconfig.c | 130 +++++++++++++++++++++++++++++++++++++++--
programs/ipconfig/ipconfig.h | 5 ++
4 files changed, 136 insertions(+), 6 deletions(-)
diff --git a/programs/ipconfig/En.rc b/programs/ipconfig/En.rc
index 4635ff6..7eeffdf 100644
--- a/programs/ipconfig/En.rc
+++ b/programs/ipconfig/En.rc
@@ -27,4 +27,9 @@ STRINGTABLE
{
STRING_USAGE, "Usage: ipconfig [ /? | /all ]\n"
STRING_INVALID_CMDLINE, "Error: Unknown or invalid command line parameters specified\n"
+ STRING_ADAPTER_FRIENDLY, "%s adapter %s\n"
+ STRING_ETHERNET, "Ethernet"
+ STRING_UNKNOWN, "Unknown"
+ STRING_CONN_DNS_SUFFIX, "Connection-specific DNS suffix"
+ STRING_IP_ADDRESS, "IP address"
}
diff --git a/programs/ipconfig/Makefile.in b/programs/ipconfig/Makefile.in
index 18a7714..cd0c2dc 100644
--- a/programs/ipconfig/Makefile.in
+++ b/programs/ipconfig/Makefile.in
@@ -5,7 +5,7 @@ SRCDIR = @srcdir@
VPATH = @srcdir@
MODULE = ipconfig.exe
APPMODE = -mconsole -municode
-IMPORTS = user32
+IMPORTS = iphlpapi ws2_32 user32
C_SRCS = ipconfig.c
diff --git a/programs/ipconfig/ipconfig.c b/programs/ipconfig/ipconfig.c
index 7c988bb..89ea8a4 100644
--- a/programs/ipconfig/ipconfig.c
+++ b/programs/ipconfig/ipconfig.c
@@ -20,6 +20,7 @@
*/
#include <windows.h>
+#include <iphlpapi.h>
#include <wine/debug.h>
#include <wine/unicode.h>
@@ -27,16 +28,13 @@
WINE_DEFAULT_DEBUG_CHANNEL(ipconfig);
-static int ipconfig_printfW(const WCHAR *msg, ...)
+static int ipconfig_vprintfW(const WCHAR *msg, va_list va_args)
{
- va_list va_args;
int wlen;
DWORD count, ret;
WCHAR msg_buffer[8192];
- va_start(va_args, msg);
wlen = vsprintfW(msg_buffer, msg, va_args);
- va_end(va_args);
ret = WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), msg_buffer, wlen, &count, NULL);
if (!ret)
@@ -59,6 +57,34 @@ static int ipconfig_printfW(const WCHAR *msg, ...)
return count;
}
+static int ipconfig_printfW(const WCHAR *msg, ...)
+{
+ va_list va_args;
+ int len;
+
+ va_start(va_args, msg);
+ len = ipconfig_vprintfW(msg, va_args);
+ va_end(va_args);
+
+ return len;
+}
+
+static int ipconfig_message_printfW(int msg, ...)
+{
+ va_list va_args;
+ WCHAR msg_buffer[8192];
+ int len;
+
+ LoadStringW(GetModuleHandleW(NULL), msg, msg_buffer,
+ sizeof(msg_buffer)/sizeof(WCHAR));
+
+ va_start(va_args, msg);
+ len = ipconfig_vprintfW(msg_buffer, va_args);
+ va_end(va_args);
+
+ return len;
+}
+
static int ipconfig_message(int msg)
{
static const WCHAR formatW[] = {'%','s',0};
@@ -66,19 +92,109 @@ static int ipconfig_message(int msg)
LoadStringW(GetModuleHandleW(NULL), msg, msg_buffer,
sizeof(msg_buffer)/sizeof(WCHAR));
+
return ipconfig_printfW(formatW, msg_buffer);
}
+static const WCHAR *iftype_to_string(DWORD type)
+{
+ static WCHAR msg_buffer[50];
+
+ int msg;
+
+ switch (type)
+ {
+ case IF_TYPE_ETHERNET_CSMACD:
+ /* The loopback adapter appears as an Ethernet device. */
+ case IF_TYPE_SOFTWARE_LOOPBACK:
+ msg = STRING_ETHERNET;
+ break;
+ default:
+ msg = STRING_UNKNOWN;
+ }
+
+ LoadStringW(GetModuleHandleW(NULL), msg, msg_buffer,
+ sizeof(msg_buffer)/sizeof(WCHAR));
+
+ return msg_buffer;
+}
+
+static void print_field(int msg, const WCHAR *value)
+{
+ static const WCHAR formatW[] = {' ',' ',' ',' ','%','s',':',' ','%','s','\n',0};
+
+ WCHAR field[] = {'.',' ','.',' ','.',' ','.',' ','.',' ','.',' ','.',' ','.',' ','.',
+ ' ','.',' ','.',' ','.',' ','.',' ','.',' ','.',' ','.',' ','.',' ',0};
+ WCHAR name_buffer[sizeof(field)/sizeof(WCHAR)];
+
+ LoadStringW(GetModuleHandleW(NULL), msg, name_buffer, sizeof(name_buffer)/sizeof(WCHAR));
+ memcpy(field, name_buffer, sizeof(WCHAR) * min(strlenW(name_buffer), sizeof(field)/sizeof(WCHAR) - 1));
+
+ ipconfig_printfW(formatW, field, value);
+}
+
+static void print_basic_information(void)
+{
+ IP_ADAPTER_ADDRESSES *adapters;
+ ULONG out = 0;
+
+ if (GetAdaptersAddresses(AF_UNSPEC, 0, NULL, NULL, &out) == ERROR_BUFFER_OVERFLOW)
+ {
+ adapters = HeapAlloc(GetProcessHeap(), 0, out);
+ if (!adapters)
+ exit(1);
+
+ if (GetAdaptersAddresses(AF_UNSPEC, 0, NULL, adapters, &out) == ERROR_SUCCESS)
+ {
+ IP_ADAPTER_ADDRESSES *p;
+
+ for (p = adapters; p; p = p->Next)
+ {
+ static const WCHAR newlineW[] = {'\n',0};
+
+ IP_ADAPTER_UNICAST_ADDRESS *addr;
+
+ ipconfig_message_printfW(STRING_ADAPTER_FRIENDLY, iftype_to_string(p->IfType), p->FriendlyName);
+ ipconfig_printfW(newlineW);
+ print_field(STRING_CONN_DNS_SUFFIX, p->DnsSuffix);
+
+ for (addr = p->FirstUnicastAddress; addr; addr = addr->Next)
+ {
+ WCHAR addr_buf[54];
+ DWORD len = sizeof(addr_buf)/sizeof(WCHAR);
+
+ if (WSAAddressToStringW(addr->Address.lpSockaddr,
+ addr->Address.iSockaddrLength, NULL,
+ addr_buf, &len) == 0)
+ print_field(STRING_IP_ADDRESS, addr_buf);
+ /* FIXME: Output corresponding subnet mask. */
+ }
+
+ /* FIXME: Output default gateway address. */
+ ipconfig_printfW(newlineW);
+ }
+ }
+
+ HeapFree(GetProcessHeap(), 0, adapters);
+ }
+}
+
int wmain(int argc, WCHAR *argv[])
{
static const WCHAR slashHelp[] = {'/','?',0};
static const WCHAR slashAll[] = {'/','a','l','l',0};
+ WSADATA data;
+
+ if (WSAStartup(MAKEWORD(2, 2), &data))
+ return 1;
+
if (argc > 1)
{
if (!strcmpW(slashHelp, argv[1]))
{
ipconfig_message(STRING_USAGE);
+ WSACleanup();
return 1;
}
else if (!strcmpiW(slashAll, argv[1]))
@@ -87,6 +203,7 @@ int wmain(int argc, WCHAR *argv[])
{
ipconfig_message(STRING_INVALID_CMDLINE);
ipconfig_message(STRING_USAGE);
+ WSACleanup();
return 1;
}
@@ -96,10 +213,13 @@ int wmain(int argc, WCHAR *argv[])
{
ipconfig_message(STRING_INVALID_CMDLINE);
ipconfig_message(STRING_USAGE);
+ WSACleanup();
return 1;
}
}
+ else
+ print_basic_information();
- WINE_FIXME("Network interface output is not currently implemented\n");
+ WSACleanup();
return 0;
}
diff --git a/programs/ipconfig/ipconfig.h b/programs/ipconfig/ipconfig.h
index f02792d..e555b87 100644
--- a/programs/ipconfig/ipconfig.h
+++ b/programs/ipconfig/ipconfig.h
@@ -23,3 +23,8 @@
/* Translation IDs. */
#define STRING_USAGE 101
#define STRING_INVALID_CMDLINE 102
+#define STRING_ADAPTER_FRIENDLY 103
+#define STRING_ETHERNET 104
+#define STRING_UNKNOWN 105
+#define STRING_CONN_DNS_SUFFIX 106
+#define STRING_IP_ADDRESS 107
More information about the wine-cvs
mailing list