Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Re: Programmatically setting static IPv6 address in Winodws CE

754 views
Skip to first unread message

Michel Verhagen (eMVP)

unread,
Feb 10, 2008, 5:45:55 PM2/10/08
to
I've got no experience with IPv6, but I don't think there's a difference
between programmatically setting IPv4 or IPv6 addresses.

The short answer: Set the registry settings and rebind the network adapter.

The long answer:

#include "stdafx.h"
#include <Iphlpapi.h>
#include <winioctl.h>
#include <ntddndis.h>

#ifdef DEBUG_IMAGE
#define ADAPTERNAME L"VMINI1"
#else
#define ADAPTERNAME L"AU1MAC1"
#endif

#define SUBKEY L"Comm\\" ADAPTERNAME L"\\Parms\\TCPIP"
#define IPADDRESS L"192.168.1.144"
#define SUBNETMASK L"255.255.255.0"
#define GATEWAY L"192.168.1.4"


///////////////////////////////////////////////////////
// Description:
// Sends an IOCTRL to the NDIS driver
//
// Input:
// Command - I/O control code, which should support the NDIS
I/O controls.
// pInBuffer - Pointer to a buffer that contains the data
required to perform the operation.
// InBufferSize - Size, in bytes, of the buffer pointed to by
pInBuffer.
// pOutBuffer - Pointer to a buffer that receives the output data
for the operation.
// OutBufSize - Size, in bytes, of the buffer pointed to by
pOutBuffer.
//
static BOOL NdisIOControl(DWORD Command, void* const pInBuffer, DWORD
InBufferSize, void* const pOutBuffer, DWORD* OutBufferSize)
{
BOOL ReturnVal = FALSE;

HANDLE hNdis = CreateFile(DD_NDIS_DEVICE_NAME, GENERIC_READ |
GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
OPEN_ALWAYS,
0, NULL);

if (INVALID_HANDLE_VALUE != hNdis)
{
ReturnVal = DeviceIoControl(hNdis, Command, pInBuffer, InBufferSize,
pOutBuffer, (OutBufferSize ?
*OutBufferSize:0),
OutBufferSize, NULL);
CloseHandle(hNdis);
}

return ReturnVal;
}

///////////////////////////////////////////////////////
// Description:
// Rebind all protocols of specified adapter
//
// Input:
// Adapter - The name of the adapter to rebind all protocols to
//
static BOOL RebindNdisAdapter(LPCWSTR Adapter)
{
WCHAR szAdapter[MAX_PATH]={0};
wcscpy(szAdapter, Adapter);
return NdisIOControl(IOCTL_NDIS_REBIND_ADAPTER, (void*
const)szAdapter, (wcslen(szAdapter)+2) * sizeof(WCHAR), NULL, 0);
}

int WINAPI WinMain( HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
HANDLE hIPCEvent = NULL;
DWORD dwStatus = NotifyAddrChange(&hIPCEvent, NULL);
if( NO_ERROR != dwStatus )
{
wprintf(L"ERROR! Unable to register for IP Address changes!\r\n");
return 0;
}

wprintf(L"Changing network settings in registry to use static
address...");
// Change registry settings for the adapter to use a static address
HKEY hKey;
if( ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, SUBKEY, 0, 0,
&hKey) )
{
RegSetValueEx(hKey, L"IpAddress", 0, REG_SZ, (CONST
BYTE*)IPADDRESS, sizeof(IPADDRESS) * sizeof(WCHAR));
RegSetValueEx(hKey, L"Subnetmask", 0, REG_SZ, (CONST
BYTE*)SUBNETMASK, sizeof(SUBNETMASK) * sizeof(WCHAR));
RegSetValueEx(hKey, L"DefaultGateway", 0, REG_SZ, (CONST
BYTE*)GATEWAY, sizeof(GATEWAY) * sizeof(WCHAR));
DWORD dwValue = 0;
RegSetValueEx(hKey, L"EnableDHCP", 0, REG_DWORD, (CONST
BYTE*)&dwValue, sizeof(dwValue));
RegCloseKey(hKey);
}
wprintf(L"\r\nReloading network settings...");
// Reload the settings from the registry
if( !RebindNdisAdapter(ADAPTERNAME) )
{
wprintf(L" ERROR! (%d)\r\n", GetLastError());
return 0;
}

wprintf(L"\r\nWaiting for network adapter refresh...");
// Wait until they are applied
if( WAIT_OBJECT_0 == WaitForSingleObject(hIPCEvent, INFINITE) )
wprintf(L"\r\nNetwork settings changed!");
else
wprintf(L" ERROR!\r\n");

wprintf(L"\r\nChanging network settings in registry to use DHCP...");
// Now change back to use DHCP
if( ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, SUBKEY, 0, 0,
&hKey) )
{
DWORD dwValue = 1;
RegSetValueEx(hKey, L"EnableDHCP", 0, REG_DWORD, (CONST
BYTE*)&dwValue, sizeof(dwValue));
RegCloseKey(hKey);
}

wprintf(L"\r\nReloading network settings...");
// Reload the settings from the registry
if( !RebindNdisAdapter(ADAPTERNAME) )
{
wprintf(L" ERROR! (%d)\r\n", GetLastError());
return 0;
}

wprintf(L"\r\nWaiting for network adapter refresh...");
// Wait until they are applied
if( WAIT_OBJECT_0 == WaitForSingleObject(hIPCEvent, INFINITE) )
wprintf(L"\r\nNetwork settings changed!");
else
wprintf(L" ERROR!\r\n");

// Close the IP address change event handle
CloseHandle(hIPCEvent);

wprintf(L"\r\n");

return 1;
}

Good luck,

Michel Verhagen, eMVP
Check out my blog: http://GuruCE.com/blog

GuruCE
http://GuruCE.com
Consultancy, training and development services.


Sandeep R wrote:
> Hi,
>
> Does anyone know how to set a static IPv6 address for an adapter in Windows
> CE(CE 5.0 or WM 5.0 or WM 6.0). I know it can be done using the ipv6 utility
> available in CE (using the command "ipv6 -p <interface index / static ipv6
> address"), but I don't want to use "ipv6" utility, rather I want to do that
> through my program.
>
>
> Best regards,
> Sandeep

Sandeep R

unread,
Feb 11, 2008, 4:09:00 AM2/11/08
to
Hi Michel,

Thanks for the reply. Windows CE uses dual-stack architecture, so the device
will have both IPv4 and IPv6 addresses assigned for an IP connection. So the
given code will set only a static IPv4 address. The registry keys for IPv6
are different [as created by the ipv6.exe utility]. They are listed under
[HKEY_LOCAL_MACHINE\Comm\Tcpip6\Parms\Interfaces\{<GUID>}\Addresses. However,
the GUID doesn't seem to a constant value. So I can't add an IPv6 address
under the above mentioned key without knowing the GUID for the adapter.

Any idea on how to get the GUID here?

Best regards,
Sandeep

Sandeep R

unread,
Feb 12, 2008, 9:48:12 AM2/12/08
to
It turns out that, it is not a GUID. but some other value which is constant
for an adapter. Any idea?

Best regards,
Sandeep

0 new messages