1084 lines
27 KiB
C
1084 lines
27 KiB
C
|
/********************************************************************/
|
|||
|
/** 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);
|
|||
|
}
|
|||
|
|
|||
|
|