294 lines
6.9 KiB
C
294 lines
6.9 KiB
C
|
/*
|
|||
|
File pnp.c
|
|||
|
|
|||
|
Handles pnp notifications such as lan interfaces coming up and down.
|
|||
|
*/
|
|||
|
|
|||
|
#define UNICODE
|
|||
|
#define _UNICODE
|
|||
|
|
|||
|
#include <nt.h>
|
|||
|
#include <ntrtl.h>
|
|||
|
#include <nturtl.h>
|
|||
|
|
|||
|
#include <stdlib.h>
|
|||
|
#include <windows.h>
|
|||
|
#include <stdio.h>
|
|||
|
#include <wchar.h>
|
|||
|
#include <winsock.h>
|
|||
|
#include <npapi.h>
|
|||
|
#include <ipexport.h>
|
|||
|
#include <ras.h>
|
|||
|
#include <rasman.h>
|
|||
|
#include <acd.h>
|
|||
|
#include <tapi.h>
|
|||
|
|
|||
|
#include <ndisguid.h>
|
|||
|
#include <wmium.h>
|
|||
|
|
|||
|
#include "radebug.h"
|
|||
|
|
|||
|
extern HANDLE hPnpEventG;
|
|||
|
|
|||
|
//**
|
|||
|
//
|
|||
|
// Call: PnpMediaSenseCb
|
|||
|
//
|
|||
|
// Returns: None
|
|||
|
//
|
|||
|
// Description:
|
|||
|
//
|
|||
|
VOID
|
|||
|
WINAPI
|
|||
|
PnpMediaSenseCb(
|
|||
|
PWNODE_HEADER pWnodeHeader,
|
|||
|
UINT_PTR NotificationContext
|
|||
|
)
|
|||
|
{
|
|||
|
PWNODE_SINGLE_INSTANCE pWnode = (PWNODE_SINGLE_INSTANCE)pWnodeHeader;
|
|||
|
LPWSTR lpwsName = (LPWSTR)RtlOffsetToPointer(
|
|||
|
pWnode,
|
|||
|
pWnode->OffsetInstanceName );
|
|||
|
|
|||
|
//
|
|||
|
// Get the information for the media disconnect.
|
|||
|
//
|
|||
|
|
|||
|
if ( memcmp( &(pWnodeHeader->Guid),
|
|||
|
&GUID_NDIS_STATUS_MEDIA_DISCONNECT,
|
|||
|
sizeof( GUID ) ) == 0 )
|
|||
|
{
|
|||
|
RASAUTO_TRACE1(
|
|||
|
"PnpMediaSenseCb [disconnect] called for %ws",
|
|||
|
lpwsName );
|
|||
|
|
|||
|
if (hPnpEventG)
|
|||
|
{
|
|||
|
SetEvent(hPnpEventG);
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
//
|
|||
|
// Get the information for the media connect.
|
|||
|
//
|
|||
|
|
|||
|
if ( memcmp( &(pWnodeHeader->Guid),
|
|||
|
&GUID_NDIS_STATUS_MEDIA_CONNECT,
|
|||
|
sizeof( GUID ) ) == 0 )
|
|||
|
{
|
|||
|
RASAUTO_TRACE1(
|
|||
|
"PnpMediaSenseCb [connect] called for %ws",
|
|||
|
lpwsName );
|
|||
|
|
|||
|
if (hPnpEventG)
|
|||
|
{
|
|||
|
SetEvent(hPnpEventG);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//**
|
|||
|
//
|
|||
|
// Call: PnpMediaSenseRegister
|
|||
|
//
|
|||
|
// Returns: NO_ERROR - Success
|
|||
|
// Non-zero returns - Failure
|
|||
|
//
|
|||
|
// Description:
|
|||
|
//
|
|||
|
DWORD
|
|||
|
PnpMediaSenseRegister(
|
|||
|
IN BOOL fRegister
|
|||
|
)
|
|||
|
{
|
|||
|
DWORD dwRetCode = NO_ERROR;
|
|||
|
PVOID pvDeliveryInfo = PnpMediaSenseCb;
|
|||
|
|
|||
|
dwRetCode = WmiNotificationRegistration(
|
|||
|
(LPGUID)(&GUID_NDIS_STATUS_MEDIA_CONNECT),
|
|||
|
(BOOLEAN)fRegister,
|
|||
|
pvDeliveryInfo,
|
|||
|
(ULONG_PTR)NULL,
|
|||
|
NOTIFICATION_CALLBACK_DIRECT );
|
|||
|
|
|||
|
if ( dwRetCode != NO_ERROR )
|
|||
|
{
|
|||
|
return( dwRetCode );
|
|||
|
}
|
|||
|
|
|||
|
dwRetCode = WmiNotificationRegistration(
|
|||
|
(LPGUID)(&GUID_NDIS_STATUS_MEDIA_DISCONNECT),
|
|||
|
(BOOLEAN)fRegister,
|
|||
|
pvDeliveryInfo,
|
|||
|
(ULONG_PTR)NULL,
|
|||
|
NOTIFICATION_CALLBACK_DIRECT );
|
|||
|
|
|||
|
if ( dwRetCode != NO_ERROR )
|
|||
|
{
|
|||
|
return( dwRetCode );
|
|||
|
}
|
|||
|
|
|||
|
return( NO_ERROR );
|
|||
|
}
|
|||
|
|
|||
|
//**
|
|||
|
//
|
|||
|
// Call: PnpBindingsNotificationsCb
|
|||
|
//
|
|||
|
// Returns: None
|
|||
|
//
|
|||
|
// Description:
|
|||
|
//
|
|||
|
VOID
|
|||
|
WINAPI
|
|||
|
PnpBindingsNotificationsCb(
|
|||
|
PWNODE_HEADER pWnodeHeader,
|
|||
|
UINT_PTR NotificationContext
|
|||
|
)
|
|||
|
{
|
|||
|
LPWSTR lpwszGUIDStart;
|
|||
|
LPWSTR lpwszGUIDEnd;
|
|||
|
LPWSTR lpwszGUID;
|
|||
|
WCHAR wchGUIDSaveLast;
|
|||
|
PWNODE_SINGLE_INSTANCE pWnode = (PWNODE_SINGLE_INSTANCE)pWnodeHeader;
|
|||
|
LPWSTR lpwsName = (LPWSTR)RtlOffsetToPointer(
|
|||
|
pWnode,
|
|||
|
pWnode->OffsetInstanceName );
|
|||
|
LPWSTR lpwsTransportName = (LPWSTR)RtlOffsetToPointer(
|
|||
|
pWnode,
|
|||
|
pWnode->DataBlockOffset );
|
|||
|
|
|||
|
//
|
|||
|
// Extract GUID from the \device\GUID name
|
|||
|
//
|
|||
|
lpwszGUID = lpwsTransportName + wcslen( lpwsTransportName ) + 1;
|
|||
|
lpwszGUIDStart = wcsrchr( lpwszGUID, L'{' );
|
|||
|
lpwszGUIDEnd = wcsrchr( lpwszGUID, L'}' );
|
|||
|
|
|||
|
if ( (lpwszGUIDStart != NULL )
|
|||
|
&& (lpwszGUIDEnd != NULL ))
|
|||
|
{
|
|||
|
BOOL fBind, fUnbind;
|
|||
|
|
|||
|
// Only signal when something happens with IP. This will prevent
|
|||
|
// us from handling too many notifications
|
|||
|
//
|
|||
|
if ( _wcsicmp( L"TCPIP", lpwsTransportName ) == 0 )
|
|||
|
{
|
|||
|
fBind = ( memcmp(
|
|||
|
&(pWnodeHeader->Guid),
|
|||
|
&GUID_NDIS_NOTIFY_BIND,
|
|||
|
sizeof( GUID ) ) == 0);
|
|||
|
fUnbind = (memcmp(
|
|||
|
&(pWnodeHeader->Guid),
|
|||
|
&GUID_NDIS_NOTIFY_UNBIND,
|
|||
|
sizeof(GUID))==0);
|
|||
|
|
|||
|
if (fBind || fUnbind)
|
|||
|
{
|
|||
|
RASAUTO_TRACE4(
|
|||
|
"PnpBindingsNotificationsCb %d %d if=%ws, trans=%ws",
|
|||
|
fBind,
|
|||
|
fUnbind,
|
|||
|
lpwsName,
|
|||
|
lpwsTransportName );
|
|||
|
|
|||
|
if (hPnpEventG)
|
|||
|
{
|
|||
|
SetEvent(hPnpEventG);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
RASAUTO_TRACE2(
|
|||
|
"PnpBindingsNotificationsCb non-tcp: if=%ws, trans=%ws",
|
|||
|
lpwsName,
|
|||
|
lpwsTransportName );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
//**
|
|||
|
//
|
|||
|
// Call: PnpBindingsNotificationsRegister
|
|||
|
//
|
|||
|
// Returns: NO_ERROR - Success
|
|||
|
// Non-zero returns - Failure
|
|||
|
//
|
|||
|
// Description:
|
|||
|
//
|
|||
|
DWORD
|
|||
|
PnpBindingsNotificationsRegister(
|
|||
|
IN BOOL fRegister
|
|||
|
)
|
|||
|
{
|
|||
|
DWORD dwRetCode = NO_ERROR;
|
|||
|
PVOID pvDeliveryInfo = PnpBindingsNotificationsCb;
|
|||
|
|
|||
|
dwRetCode = WmiNotificationRegistration(
|
|||
|
(LPGUID)(&GUID_NDIS_NOTIFY_BIND),
|
|||
|
(BOOLEAN)fRegister,
|
|||
|
pvDeliveryInfo,
|
|||
|
(ULONG_PTR)NULL,
|
|||
|
NOTIFICATION_CALLBACK_DIRECT );
|
|||
|
|
|||
|
if ( dwRetCode != NO_ERROR )
|
|||
|
{
|
|||
|
return( dwRetCode );
|
|||
|
}
|
|||
|
|
|||
|
dwRetCode = WmiNotificationRegistration(
|
|||
|
(LPGUID)(&GUID_NDIS_NOTIFY_UNBIND),
|
|||
|
(BOOLEAN)fRegister,
|
|||
|
pvDeliveryInfo,
|
|||
|
(ULONG_PTR)NULL,
|
|||
|
NOTIFICATION_CALLBACK_DIRECT );
|
|||
|
|
|||
|
if ( dwRetCode != NO_ERROR )
|
|||
|
{
|
|||
|
return( dwRetCode );
|
|||
|
}
|
|||
|
|
|||
|
return( NO_ERROR );
|
|||
|
}
|
|||
|
|
|||
|
DWORD
|
|||
|
PnpRegister(
|
|||
|
IN BOOL fRegister)
|
|||
|
{
|
|||
|
DWORD dwErr = NO_ERROR;
|
|||
|
|
|||
|
RASAUTO_TRACE1("PnpRegister: %d", !!fRegister);
|
|||
|
|
|||
|
dwErr = PnpBindingsNotificationsRegister(fRegister);
|
|||
|
if (dwErr == NO_ERROR)
|
|||
|
{
|
|||
|
dwErr = PnpMediaSenseRegister(fRegister);
|
|||
|
if (dwErr == NO_ERROR)
|
|||
|
{
|
|||
|
RASAUTO_TRACE("PnpRegister: success.");
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (fRegister)
|
|||
|
{
|
|||
|
PnpBindingsNotificationsRegister(FALSE);
|
|||
|
}
|
|||
|
RASAUTO_TRACE1("PnpRegister: MSense reg failure 0x%x", dwErr);
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
RASAUTO_TRACE1("PnpRegister: Bingings reg failure 0x%x", dwErr);
|
|||
|
}
|
|||
|
|
|||
|
return dwErr;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|