windows-nt/Source/XPSP1/NT/net/rras/ras/ddm/adminapi.c

1084 lines
27 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/********************************************************************/
/** Copyright(c) 1995 Microsoft Corporation. **/
/********************************************************************/
//***
//
// Filename: adminapi.c
//
// Description: Contains code to respond to DDM admin. requests.
//
// History: May 11,1995 NarenG Created original version.
//
#include "ddm.h"
#include <lmmsg.h>
#include "objects.h"
#include "handlers.h"
#include "rasapiif.h"
#include "routerif.h"
#include "util.h"
#include <dimsvc.h> // Generated by MIDL
#include <string.h>
#include <stdlib.h>
#include <mprapip.h>
//**
//
// Call: DDMAdminInterfaceConnect
//
// Returns: NO_ERROR - Success
//
// Description:
//
DWORD
DDMAdminInterfaceConnect(
IN HANDLE hDimInterface,
IN HANDLE hEvent,
IN BOOL fBlocking,
IN DWORD dwCallersProcessId
)
{
HANDLE hClientProcess = NULL;
DWORD dwRetCode = NO_ERROR;
ROUTER_INTERFACE_OBJECT* pIfObject = NULL;
HANDLE hEventToBeDuplicated = NULL;
DWORD fReturn = FALSE;
EnterCriticalSection( &(gblpInterfaceTable->CriticalSection) );
do
{
if ( ( pIfObject = IfObjectGetPointer((HANDLE)hDimInterface) ) == NULL )
{
dwRetCode = ERROR_INVALID_HANDLE;
break;
}
if ( pIfObject->State == RISTATE_CONNECTED )
{
dwRetCode = NO_ERROR;
fReturn = TRUE;
break;
}
if ( pIfObject->State == RISTATE_CONNECTING )
{
dwRetCode = ERROR_ALREADY_CONNECTING;
fReturn = TRUE;
break;
}
if ( ( hEvent == NULL ) && ( fBlocking ) )
{
//
// This call is to be synchrnonous, create an event and block on
// it.
//
hEventToBeDuplicated = CreateEvent( NULL, FALSE, FALSE, NULL );
if ( hEventToBeDuplicated == NULL )
{
dwRetCode = GetLastError();
break;
}
dwCallersProcessId = GetCurrentProcessId();
}
else
{
hEventToBeDuplicated = hEvent;
}
if ( hEventToBeDuplicated != NULL )
{
//
//
// Get process handle of the caller of this API
//
hClientProcess = OpenProcess(
STANDARD_RIGHTS_REQUIRED | SPECIFIC_RIGHTS_ALL,
FALSE,
dwCallersProcessId);
if ( hClientProcess == NULL )
{
dwRetCode = GetLastError();
break;
}
//
// Duplicate the handle to the event
//
if ( !DuplicateHandle(
hClientProcess,
hEventToBeDuplicated,
GetCurrentProcess(),
&(pIfObject->hEventNotifyCaller),
0,
FALSE,
DUPLICATE_SAME_ACCESS ) )
{
CloseHandle( hClientProcess );
dwRetCode = GetLastError();
break;
}
CloseHandle( hClientProcess );
}
else
{
pIfObject->hEventNotifyCaller = INVALID_HANDLE_VALUE;
}
//
// Initiate a connection
//
dwRetCode = RasConnectionInitiate( pIfObject, FALSE );
if ( dwRetCode != NO_ERROR )
{
CloseHandle( pIfObject->hEventNotifyCaller );
pIfObject->hEventNotifyCaller = INVALID_HANDLE_VALUE;
}
else
{
dwRetCode = PENDING;
}
DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
"RasConnectionInitiate: To %ws dwRetCode=%d",
pIfObject->lpwsInterfaceName, dwRetCode );
}
while( FALSE );
LeaveCriticalSection( &(gblpInterfaceTable->CriticalSection) );
//
// If we are or already connecting or connected then simply return
//
if ( fReturn )
{
return( dwRetCode );
}
//
// This is a synchronous call, we need to wait till compeletion
//
if ( ( hEvent == NULL ) && ( fBlocking ) )
{
if ( dwRetCode == PENDING )
{
if ( WaitForSingleObject( hEventToBeDuplicated, INFINITE )
== WAIT_FAILED )
{
CloseHandle( hEventToBeDuplicated );
return( GetLastError() );
}
EnterCriticalSection( &(gblpInterfaceTable->CriticalSection) );
if ( ( pIfObject = IfObjectGetPointer((HANDLE)hDimInterface) )
== NULL )
{
dwRetCode = ERROR_INVALID_HANDLE;
}
else
{
dwRetCode = pIfObject->dwLastError;
}
LeaveCriticalSection( &(gblpInterfaceTable->CriticalSection) );
}
if ( hEventToBeDuplicated != NULL )
{
CloseHandle( hEventToBeDuplicated );
}
}
return( dwRetCode );
}
//**
//
// Call: DDMAdminInterfaceDisconnect
//
// Returns: NO_ERROR - Success
//
// Description:
//
DWORD
DDMAdminInterfaceDisconnect(
IN HANDLE hDimInterface
)
{
DWORD dwRetCode = NO_ERROR;
DWORD dwTransportIndex = -1;
if ( gblDDMConfigInfo.dwNumRouterManagers > 0 )
{
for ( dwTransportIndex = 0;
dwTransportIndex < gblDDMConfigInfo.dwNumRouterManagers;
dwTransportIndex++ )
{
dwRetCode =
DDMDisconnectInterface(
hDimInterface,
gblRouterManagers[dwTransportIndex].DdmRouterIf.dwProtocolId );
if ( dwRetCode != NO_ERROR )
{
return( dwRetCode );
}
}
}
else
{
//
// [old comment] If no router managers are installed then we are a AMB
// or NBF only client connection, simply call disconnect interface
//
// [new comment]
//
// AMB and NBF have been removed from the project but this path is
// being kept since logically, you should be able to disconnect an
// interface regardless of whether any router managers exist.
//
// This philosphy is in spirit with the work we'll do
// to merge rasman, dim, and ddm. Then it will be possible for
// code paths like this to execute without any router managers being
// loaded.
//
dwRetCode = DDMDisconnectInterface( hDimInterface, -1 );
}
return( dwRetCode );
}
//**
//
// Call: DDMAdminServerGetInfo
//
// Returns: NO_ERROR - Success
//
// Description:
//
DWORD
DDMAdminServerGetInfo(
IN OUT PVOID pServerInfo,
IN DWORD dwLevel
)
{
MPR_SERVER_0* pServerInfo0;
if ( dwLevel == 0 )
{
pServerInfo0 = (MPR_SERVER_0*)pServerInfo;
pServerInfo0->fLanOnlyMode = FALSE;
}
else
{
return( ERROR_NOT_SUPPORTED );
}
EnterCriticalSection( &(gblDeviceTable.CriticalSection) );
//
// Copy server info
//
pServerInfo0->dwTotalPorts = gblDeviceTable.NumDeviceNodes;
pServerInfo0->dwPortsInUse = gblDeviceTable.NumDevicesInUse;
LeaveCriticalSection( &(gblDeviceTable.CriticalSection) );
return( NO_ERROR );
}
//**
//
// Call: DDMAdminConnectionEnum
//
// Returns: NO_ERROR - Success
//
// Description:
//
DWORD
DDMAdminConnectionEnum(
IN OUT PDIM_INFORMATION_CONTAINER pInfoStruct,
IN DWORD dwLevel,
IN DWORD dwPreferedMaximumLength,
IN LPDWORD lpdwEntriesRead,
IN LPDWORD lpdwTotalEntries,
IN OUT LPDWORD lpdwResumeHandle OPTIONAL
)
{
PRASI_CONNECTION_0 pRasConnection0 = NULL;
PRASI_CONNECTION_1 pRasConnection1 = NULL;
PRASI_CONNECTION_2 pRasConnection2 = NULL;
PCONNECTION_OBJECT pConnObj = NULL;
DWORD dwBucketIndex = 0;
DWORD dwConnObjIndex = 0;
DWORD dwConnInfoSize = 0;
DWORD dwStartIndex = ( lpdwResumeHandle == NULL )
? 0
: *lpdwResumeHandle;
// Calculate the connection info size
switch (dwLevel) {
case 0:
dwConnInfoSize = sizeof( RASI_CONNECTION_0 );
break;
case 1:
dwConnInfoSize = sizeof( RASI_CONNECTION_1 );
break;
case 2:
dwConnInfoSize = sizeof( RASI_CONNECTION_2 );
break;
default:
return ERROR_NOT_SUPPORTED;
}
EnterCriticalSection( &(gblDeviceTable.CriticalSection) );
if ( gblDeviceTable.NumConnectionNodes < dwStartIndex )
{
LeaveCriticalSection( &(gblDeviceTable.CriticalSection) );
return( ERROR_NO_MORE_ITEMS );
}
*lpdwTotalEntries = gblDeviceTable.NumConnectionNodes - dwStartIndex;
if ( dwPreferedMaximumLength != -1 )
{
*lpdwEntriesRead = dwPreferedMaximumLength / dwConnInfoSize;
if ( *lpdwEntriesRead > *lpdwTotalEntries )
{
*lpdwEntriesRead = *lpdwTotalEntries;
}
}
else
{
*lpdwEntriesRead = *lpdwTotalEntries;
}
pInfoStruct->dwBufferSize = *lpdwEntriesRead * dwConnInfoSize;
pInfoStruct->pBuffer = MIDL_user_allocate( pInfoStruct->dwBufferSize );
if ( pInfoStruct->pBuffer == NULL )
{
LeaveCriticalSection( &(gblDeviceTable.CriticalSection) );
pInfoStruct->dwBufferSize = 0;
return( ERROR_NOT_ENOUGH_MEMORY );
}
if (dwLevel == 0)
pRasConnection0 = (PRASI_CONNECTION_0)pInfoStruct->pBuffer;
else if (dwLevel == 1)
pRasConnection1 = (PRASI_CONNECTION_1)pInfoStruct->pBuffer;
else
pRasConnection2 = (PRASI_CONNECTION_2)pInfoStruct->pBuffer;
for ( dwBucketIndex = 0;
dwBucketIndex < gblDeviceTable.NumDeviceBuckets;
dwBucketIndex++ )
{
for( pConnObj = gblDeviceTable.ConnectionBucket[dwBucketIndex];
pConnObj != (CONNECTION_OBJECT *)NULL;
pConnObj = pConnObj->pNext )
{
//
// Check if this connection object is within the range we need to
// copy from.
//
if ( ( dwConnObjIndex >= dwStartIndex ) &&
( dwConnObjIndex < (dwStartIndex+*lpdwEntriesRead)))
{
//
// Copy the info
//
if (dwLevel == 0) {
GetRasiConnection0Data( pConnObj, pRasConnection0 );
pRasConnection0++;
}
else if (dwLevel == 1) {
GetRasiConnection1Data( pConnObj, pRasConnection1 );
pRasConnection1++;
}
else {
GetRasiConnection2Data( pConnObj, pRasConnection2 );
pRasConnection2++;
}
}
else if (dwConnObjIndex>=(dwStartIndex+*lpdwEntriesRead))
{
//
// Beyond the range so exit
//
if ( lpdwResumeHandle != NULL )
{
*lpdwResumeHandle = dwConnObjIndex;
}
LeaveCriticalSection( &(gblDeviceTable.CriticalSection) );
return( ERROR_MORE_DATA );
}
dwConnObjIndex++;
}
}
LeaveCriticalSection( &(gblDeviceTable.CriticalSection) );
return( NO_ERROR );
}
//**
//
// Call: DDMAdminConnectionGetInfo
//
// Returns: NO_ERROR - Success
//
// Description:
//
DWORD
DDMAdminConnectionGetInfo(
IN HANDLE hConnection,
IN OUT PDIM_INFORMATION_CONTAINER pInfoStruct,
IN DWORD dwLevel
)
{
DWORD dwRetCode = NO_ERROR;
ROUTER_INTERFACE_OBJECT * pIfObject;
CONNECTION_OBJECT * pConnObj;
if ( dwLevel > 2 )
{
return( ERROR_NOT_SUPPORTED );
}
EnterCriticalSection( &(gblDeviceTable.CriticalSection) );
switch( dwLevel )
{
case 0:
pInfoStruct->dwBufferSize = sizeof( RASI_CONNECTION_0 );
break;
case 1:
pInfoStruct->dwBufferSize = sizeof( RASI_CONNECTION_1 );
break;
case 2:
pInfoStruct->dwBufferSize = sizeof( RASI_CONNECTION_2 );
break;
}
pInfoStruct->pBuffer = MIDL_user_allocate( pInfoStruct->dwBufferSize );
if ( pInfoStruct->pBuffer == NULL )
{
LeaveCriticalSection( &(gblDeviceTable.CriticalSection) );
return( ERROR_NOT_ENOUGH_MEMORY );
}
//
// Copy Connection info
//
do
{
pConnObj = ConnObjGetPointer( (HCONN)hConnection );
if ( pConnObj == (CONNECTION_OBJECT *)NULL )
{
dwRetCode = ERROR_INTERFACE_NOT_CONNECTED;
break;
}
switch( dwLevel )
{
case 0:
dwRetCode = GetRasiConnection0Data(
pConnObj,
(PRASI_CONNECTION_0)pInfoStruct->pBuffer );
break;
case 1:
dwRetCode = GetRasiConnection1Data(
pConnObj,
(PRASI_CONNECTION_1)pInfoStruct->pBuffer );
break;
case 2:
dwRetCode = GetRasiConnection2Data(
pConnObj,
(PRASI_CONNECTION_2)pInfoStruct->pBuffer );
break;
}
}while( FALSE );
if ( dwRetCode != NO_ERROR )
{
MIDL_user_free( pInfoStruct->pBuffer );
pInfoStruct->pBuffer = NULL;
pInfoStruct->dwBufferSize = 0;
}
LeaveCriticalSection( &(gblDeviceTable.CriticalSection) );
return( dwRetCode );
}
//**
//
// Call: DDMAdminConnectionClearStats
//
// Returns: NO_ERROR - Success
//
// Description:
//
DWORD
DDMAdminConnectionClearStats(
IN HANDLE hConnection
)
{
return( RasBundleClearStatisticsEx(NULL, (HCONN)hConnection ) );
}
//**
//
// Call: DDMAdminPortEnum
//
// Returns: NO_ERROR - Success
//
// Description:
//
DWORD
DDMAdminPortEnum(
IN OUT PDIM_INFORMATION_CONTAINER pInfoStruct,
IN HANDLE hConnection,
IN DWORD dwLevel,
IN DWORD dwPreferedMaximumLength,
IN LPDWORD lpdwEntriesRead,
IN LPDWORD lpdwTotalEntries,
IN OUT LPDWORD lpdwResumeHandle OPTIONAL
)
{
PRASI_PORT_0 pRasPort0 = NULL;
PDEVICE_OBJECT pDevObj = NULL;
PCONNECTION_OBJECT pConnObj = NULL;
DWORD dwIndex = 0;
DWORD dwBucketIndex = 0;
DWORD dwDevObjIndex = 0;
DWORD dwStartIndex = ( lpdwResumeHandle == NULL )
? 0
: *lpdwResumeHandle;
if ( dwLevel != 0 )
{
return( ERROR_NOT_SUPPORTED );
}
EnterCriticalSection( &(gblDeviceTable.CriticalSection) );
if ( hConnection != INVALID_HANDLE_VALUE )
{
if ( ( pConnObj = ConnObjGetPointer( (HCONN)hConnection ) ) == NULL )
{
LeaveCriticalSection( &(gblDeviceTable.CriticalSection) );
return( ERROR_INVALID_HANDLE );
}
if ( pConnObj->cActiveDevices < dwStartIndex )
{
LeaveCriticalSection( &(gblDeviceTable.CriticalSection) );
return( ERROR_NO_MORE_ITEMS );
}
*lpdwTotalEntries = pConnObj->cActiveDevices - dwStartIndex;
}
else
{
if ( gblDeviceTable.NumDeviceNodes < dwStartIndex )
{
LeaveCriticalSection( &(gblDeviceTable.CriticalSection) );
return( ERROR_NO_MORE_ITEMS );
}
*lpdwTotalEntries = gblDeviceTable.NumDeviceNodes - dwStartIndex;
}
if ( dwPreferedMaximumLength != -1 )
{
*lpdwEntriesRead = dwPreferedMaximumLength / sizeof( RAS_PORT_0 );
if ( *lpdwEntriesRead > *lpdwTotalEntries )
{
*lpdwEntriesRead = *lpdwTotalEntries;
}
}
else
{
*lpdwEntriesRead = *lpdwTotalEntries;
}
pInfoStruct->dwBufferSize = *lpdwEntriesRead * sizeof( RASI_PORT_0 );
pInfoStruct->pBuffer = MIDL_user_allocate( pInfoStruct->dwBufferSize );
if ( pInfoStruct->pBuffer == NULL )
{
LeaveCriticalSection( &(gblDeviceTable.CriticalSection) );
pInfoStruct->dwBufferSize = 0;
return( ERROR_NOT_ENOUGH_MEMORY );
}
pRasPort0 = (PRASI_PORT_0)pInfoStruct->pBuffer;
if ( hConnection == INVALID_HANDLE_VALUE )
{
for ( dwBucketIndex = 0;
dwBucketIndex < gblDeviceTable.NumDeviceBuckets;
dwBucketIndex++ )
{
for( pDevObj = gblDeviceTable.DeviceBucket[dwBucketIndex];
pDevObj != (DEVICE_OBJECT *)NULL;
pDevObj = pDevObj->pNext )
{
//
// Check if this port is within the range we need to copy
// from.
//
if ( ( dwDevObjIndex >= dwStartIndex ) &&
( dwDevObjIndex < (dwStartIndex+*lpdwEntriesRead)))
{
//
// Copy the info
//
GetRasiPort0Data( pDevObj, pRasPort0 );
pRasPort0++;
}
else if (dwDevObjIndex>=(dwStartIndex+*lpdwEntriesRead))
{
//
// Beyond the range so exit
//
if ( lpdwResumeHandle != NULL )
{
*lpdwResumeHandle = dwDevObjIndex;
}
LeaveCriticalSection( &(gblDeviceTable.CriticalSection) );
return( ERROR_MORE_DATA );
}
dwDevObjIndex++;
}
}
}
else
{
for ( dwIndex = 0; dwIndex < pConnObj->cDeviceListSize; dwIndex++ )
{
if ( pConnObj->pDeviceList[dwIndex] != NULL )
{
//
// Check if this port is within the range we need to copy
// from.
//
if ( ( dwDevObjIndex >= dwStartIndex ) &&
( dwDevObjIndex < (dwStartIndex+*lpdwEntriesRead)))
{
//
// Copy the info
//
GetRasiPort0Data(pConnObj->pDeviceList[dwIndex], pRasPort0);
pRasPort0++;
}
else if (dwDevObjIndex>=(dwStartIndex+*lpdwEntriesRead))
{
//
// Beyond the range so exit
//
if ( lpdwResumeHandle != NULL )
{
*lpdwResumeHandle = dwDevObjIndex;
}
LeaveCriticalSection( &(gblDeviceTable.CriticalSection) );
return( NO_ERROR );
}
dwDevObjIndex++;
}
}
}
LeaveCriticalSection( &(gblDeviceTable.CriticalSection) );
return( NO_ERROR );
}
//**
//
// Call: DDMAdminPortGetInfo
//
// Returns: NO_ERROR - Success
//
// Description:
//
DWORD
DDMAdminPortGetInfo(
IN HANDLE hPort,
IN OUT PDIM_INFORMATION_CONTAINER pInfoStruct,
IN DWORD dwLevel
)
{
DEVICE_OBJECT * pDevObj;
DWORD dwRetCode;
if ( dwLevel > 1 )
{
return( ERROR_NOT_SUPPORTED );
}
EnterCriticalSection( &(gblDeviceTable.CriticalSection) );
pInfoStruct->dwBufferSize = ( dwLevel == 0 )
? sizeof( RAS_PORT_0 )
: sizeof( RAS_PORT_1 );
pInfoStruct->pBuffer = MIDL_user_allocate( pInfoStruct->dwBufferSize );
if ( pInfoStruct->pBuffer == NULL )
{
LeaveCriticalSection( &(gblDeviceTable.CriticalSection) );
return( ERROR_NOT_ENOUGH_MEMORY );
}
//
// Copy port info
//
do
{
pDevObj = DeviceObjGetPointer( (HPORT)hPort );
if ( pDevObj == (HPORT)NULL )
{
dwRetCode = ERROR_INVALID_PORT_HANDLE;
break;
}
if ( dwLevel == 0 )
{
dwRetCode = GetRasiPort0Data( pDevObj,
(PRASI_PORT_0)pInfoStruct->pBuffer );
}
else
{
dwRetCode = GetRasiPort1Data( pDevObj,
(PRASI_PORT_1)pInfoStruct->pBuffer );
}
}
while( FALSE );
if ( dwRetCode != NO_ERROR )
{
MIDL_user_free( pInfoStruct->pBuffer );
pInfoStruct->pBuffer = NULL;
pInfoStruct->dwBufferSize = 0;
}
LeaveCriticalSection( &(gblDeviceTable.CriticalSection) );
return( dwRetCode );
}
//**
//
// Call: DDMAdminPortClearStats
//
// Returns: NO_ERROR - Success
//
// Description:
//
DWORD
DDMAdminPortClearStats(
IN HANDLE hPort
)
{
PDEVICE_OBJECT pDevObj = NULL;
EnterCriticalSection( &(gblDeviceTable.CriticalSection) );
if ( ( pDevObj = DeviceObjGetPointer( (HPORT)hPort ) ) == NULL )
{
LeaveCriticalSection( &(gblDeviceTable.CriticalSection) );
return( ERROR_INVALID_HANDLE );
}
LeaveCriticalSection( &(gblDeviceTable.CriticalSection) );
return( RasPortClearStatistics(NULL, (HPORT)hPort ) );
}
//**
//
// Call: DDMAdminPortReset
//
// Returns: NO_ERROR - Success
//
// Description:
//
DWORD
DDMAdminPortReset(
IN HANDLE hPort
)
{
return( NO_ERROR );
}
//**
//
// Call: DDMAdminPortDisconnect
//
// Returns: NO_ERROR - Success
//
// Description: Disconnect the client port.
//
DWORD
DDMAdminPortDisconnect(
IN HANDLE hPort
)
{
DEVICE_OBJECT * pDevObj;
DWORD dwRetCode = NO_ERROR;
EnterCriticalSection( &(gblDeviceTable.CriticalSection) );
do
{
if ( ( pDevObj = DeviceObjGetPointer( (HPORT)hPort ) ) == NULL )
{
dwRetCode = ERROR_INVALID_HANDLE;
break;
}
if ( pDevObj->fFlags & DEV_OBJ_OPENED_FOR_DIALOUT )
{
RasApiCleanUpPort( pDevObj );
}
else
{
if ( pDevObj->fFlags & DEV_OBJ_PPP_IS_ACTIVE )
{
PppDdmStop( (HPORT)pDevObj->hPort, NO_ERROR );
}
else
{
DevStartClosing( pDevObj );
}
}
}
while( FALSE );
LeaveCriticalSection( &(gblDeviceTable.CriticalSection) );
return( dwRetCode );
}
//**
//
// Call: DDMRegisterConnectionNotification
//
// Returns: NO_ERROR - Success
// Non-zero returns - Failure
//
// Description: Will insert or remove and event from the notification list
//
DWORD
DDMRegisterConnectionNotification(
IN BOOL fRegister,
IN HANDLE hEventClient,
IN HANDLE hEventRouter
)
{
DWORD dwRetCode = NO_ERROR;
NOTIFICATION_EVENT * pNotificationEvent = NULL;
EnterCriticalSection( &(gblpInterfaceTable->CriticalSection) );
if ( fRegister )
{
//
// Insert event in notification list
//
pNotificationEvent = (NOTIFICATION_EVENT *)
LOCAL_ALLOC(
LPTR,
sizeof(NOTIFICATION_EVENT) );
if ( pNotificationEvent == NULL )
{
dwRetCode = GetLastError();
}
else
{
pNotificationEvent->hEventClient = hEventClient;
pNotificationEvent->hEventRouter = hEventRouter;
InsertHeadList(
(LIST_ENTRY *)&(gblDDMConfigInfo.NotificationEventListHead),
(LIST_ENTRY*)pNotificationEvent );
}
}
else
{
//
// Remove event from notification list
//
for( pNotificationEvent = (NOTIFICATION_EVENT *)
(gblDDMConfigInfo.NotificationEventListHead.Flink);
pNotificationEvent != (NOTIFICATION_EVENT *)
&(gblDDMConfigInfo.NotificationEventListHead);
pNotificationEvent = (NOTIFICATION_EVENT *)
(pNotificationEvent->ListEntry.Flink) )
{
if ( pNotificationEvent->hEventClient == hEventClient )
{
RemoveEntryList( (LIST_ENTRY *)pNotificationEvent );
CloseHandle( pNotificationEvent->hEventClient );
CloseHandle( pNotificationEvent->hEventRouter );
LOCAL_FREE( pNotificationEvent );
break;
}
}
}
LeaveCriticalSection( &(gblpInterfaceTable->CriticalSection) );
return( dwRetCode );
}
//**
//
// Call: DDMSendUserMessage
//
// Returns: NO_ERROR - Success
//
// Description:
//
DWORD
DDMSendUserMessage(
IN HANDLE hConnection,
IN LPWSTR lpwszMessage
)
{
PCONNECTION_OBJECT pConnObj = NULL;
DWORD dwRetCode = NO_ERROR;
EnterCriticalSection( &(gblDeviceTable.CriticalSection) );
do
{
pConnObj = ConnObjGetPointer( (HCONN)hConnection );
if ( pConnObj == (CONNECTION_OBJECT *)NULL )
{
dwRetCode = ERROR_INTERFACE_NOT_CONNECTED;
break;
}
if ( pConnObj->fFlags & CONN_OBJ_MESSENGER_PRESENT )
{
WCHAR wszRemoteComputer[CNLEN+1];
MultiByteToWideChar( CP_ACP,
0,
pConnObj->bComputerName,
-1,
wszRemoteComputer,
CNLEN+1 );
dwRetCode = NetMessageBufferSend(
NULL,
wszRemoteComputer,
NULL,
(BYTE*)lpwszMessage,
(wcslen(lpwszMessage)+1) * sizeof(WCHAR));
}
} while( FALSE );
LeaveCriticalSection( &(gblDeviceTable.CriticalSection) );
return(dwRetCode);
}