i have to thank one person (seriously I forgot this name... i am really bad a remembering names and numbers), he posted an article in codeproject.com regarding this functionality. Then I found more helpful code in completing the circle.. :)
WINCE600\PUBLIC\COMMON\OAK\DRIVERS\NETSAMP\NDISPWR
This is a sample program given in windows ce 6.0 showing how to query and the set the power state of network interface using deviceIocontrols (specifically, ndis ioctls for binding and unbinding the adapter after a power state change) and setDevicePower functions.
Here is the code for controlling (enabling and disabling, its the same operation as in enabling and disabling a network interface in network connection applet in control panel) an NIC.
Pay attention to the high lighted part of code.
void ControlNIC(wchar_t* InterfaceName,BOOL bEnable){HANDLE hNdisPwr;NDISPWR_SAVEPOWERSTATE SavePowerState;TCHAR szName[MAX_PATH];int nChars;TCHAR* pszAdapter;TCHAR multiSz[257];DWORD cbBuffer = sizeof(multiSz);hNdisPwr = CreateFile((PTCHAR)NDISPWR_DEVICE_NAME,0x00,0x00,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL| FILE_FLAG_OVERLAPPED,(HANDLE)INVALID_HANDLE_VALUE);if (hNdisPwr != INVALID_HANDLE_VALUE){SavePowerState.pwcAdapterName = InterfaceName;if (bEnable){SavePowerState.CePowerState = PwrDeviceUnspecified;}else{SavePowerState.CePowerState = D4;}BOOL ret = DeviceIoControl(hNdisPwr,IOCTL_NPW_SAVE_POWER_STATE,&SavePowerState,sizeof(NDISPWR_SAVEPOWERSTATE),NULL,0x00,NULL,NULL);// TODO: take care of the return value 'ret 'CloseHandle(hNdisPwr);// Just composing a Class-Qualified Device Name, to pass on to SetDevicePowerpszAdapter = new TCHAR[wcslen(InterfaceName)+1];wcscpy_s(pszAdapter,wcslen(InterfaceName)+1,InterfaceName);nChars = _sntprintf_s(szName,MAX_PATH-1,MAX_PATH-1,_T("%s\\%s"),PMCLASS_NDIS_MINIPORT,pszAdapter);szName[MAX_PATH-1]=0;DWORD res = 0;if(bEnable){res = SetDevicePower(szName,POWER_NAME,PwrDeviceUnspecified);}else{res = SetDevicePower(szName,POWER_NAME,D4);}// TODO: take care of the return value 'res'StringCchCopy(multiSz, (cbBuffer / sizeof(TCHAR))-1, pszAdapter);multiSz[::_tcslen(multiSz)+1] = _T('\0'); // Multi sz needs an extra nullBOOL bRes;if (bEnable){bRes = DoNdisIOControl(IOCTL_NDIS_BIND_ADAPTER,multiSz,(_tcslen(multiSz)+2) * sizeof(TCHAR),NULL,NULL);}else{bRes = DoNdisIOControl(IOCTL_NDIS_UNBIND_ADAPTER,multiSz,(_tcslen(multiSz)+2) * sizeof(TCHAR),NULL,NULL);}// TODO: take care of the return value 'bRes '}}
While changing the power state of a device, be sure for bind and unbind an adapter so that NDIS can take care of the protocol drivers.
4 comments:
very useful article. thanks .
I'm using Evc++ . When try to compile this method, i get an error like below ;
error C2065: DoNdisIOControl : undeclared identifier
my include class like below;
#include "Atlbase.h"
#include "Winreg.h"
#include "winioctl.h"
#include "ntddndis.h"
#include "windows.h"
#include "tchar.h"
#include "stdio.h"
#include "stdarg.h"
#include "netcon.h"
#include "iphlpapi.h"
#include "pm.h"
#include "winsock.h"
#include "ndispwr.h"
#include "string.h"
have any idea
DoNdisIOControl is just a wrapper function i provided to do the ioctl calls... i can send u the fulll source code if u want ;)
sorry for the delay in reply dude... been busy in last couple of weeks :)
here is the code for DoNdisIOControl
BOOL DoNdisIOControl(DWORD dwCommand, LPVOID pInBuffer,DWORD cbInBuffer, LPVOID pOutBuffer,DWORD * pcbOutBuffer)
{
HANDLE hNdis;
BOOL fResult = FALSE;
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)
{
fResult = ::DeviceIoControl(hNdis, dwCommand, pInBuffer, cbInBuffer,pOutBuffer, (pcbOutBuffer ? *pcbOutBuffer : 0),pcbOutBuffer, NULL);
::CloseHandle(hNdis);
}
return fResult;
}
Post a Comment