903 lines
22 KiB
C
903 lines
22 KiB
C
|
/*++
|
||
|
|
||
|
Copyright (c) 1996 Microsoft Corporation
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
nteapi.c
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
Routines for manipulating dynamic IP Network Table Entries (NTEs)
|
||
|
and NBT devices (interfaces).
|
||
|
|
||
|
Author:
|
||
|
|
||
|
Mike Massa (mikemas) 18-Mar-1996
|
||
|
|
||
|
Environment:
|
||
|
|
||
|
User Mode - Win32
|
||
|
|
||
|
Revision History:
|
||
|
|
||
|
--*/
|
||
|
|
||
|
|
||
|
#include "clusres.h"
|
||
|
#include <winsock2.h>
|
||
|
#include <ipexport.h>
|
||
|
#include <ntddip.h>
|
||
|
#include <nteapi.h>
|
||
|
#include <nbtioctl.h>
|
||
|
#include <clusdef.h>
|
||
|
#include <ntddcnet.h>
|
||
|
#include <clusrtl.h>
|
||
|
|
||
|
//
|
||
|
// Public Routines
|
||
|
//
|
||
|
DWORD
|
||
|
TcpipAddNTE(
|
||
|
IN LPWSTR AdapterId,
|
||
|
IN IPAddr Address,
|
||
|
IN IPMask SubnetMask,
|
||
|
OUT PULONG NTEContext,
|
||
|
OUT PULONG NTEInstance
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Adds a new NTE to a specified IP interface. The target IP interface is
|
||
|
identified by the name of the adapter associated with it.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
AdapterId - A unicode string identifying the adapter/interface to which
|
||
|
to add the new NTE.
|
||
|
|
||
|
Address - The IP address to assign to the new NTE.
|
||
|
|
||
|
SubnetMask - The IP subnet mask to assign to the new NTE.
|
||
|
|
||
|
NTEContext - On output, contains the context value identifying the new NTE.
|
||
|
|
||
|
NTEInstance - On output, contains the instance ID of the new NTE.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
ERROR_SUCCESS if the operation was successful.
|
||
|
A Windows error code otherwise.
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
NTSTATUS status;
|
||
|
PCLRTL_NET_ADAPTER_INFO adapterInfo;
|
||
|
PCLRTL_NET_ADAPTER_ENUM adapterEnum;
|
||
|
HANDLE handle;
|
||
|
IP_ADD_NTE_REQUEST requestBuffer;
|
||
|
PIP_ADD_NTE_RESPONSE responseBuffer =
|
||
|
(PIP_ADD_NTE_RESPONSE) &requestBuffer;
|
||
|
DWORD requestBufferSize = sizeof(requestBuffer);
|
||
|
DWORD responseBufferSize = sizeof(*responseBuffer);
|
||
|
|
||
|
|
||
|
adapterEnum = ClRtlEnumNetAdapters();
|
||
|
|
||
|
if (adapterEnum != NULL) {
|
||
|
adapterInfo = ClRtlFindNetAdapterById(adapterEnum, AdapterId);
|
||
|
|
||
|
if (adapterInfo != NULL) {
|
||
|
status = ClusResOpenDriver(&handle, DD_CLUSNET_DEVICE_NAME);
|
||
|
|
||
|
if ( status == ERROR_SUCCESS ) {
|
||
|
requestBuffer.InterfaceContext = adapterInfo->Index;
|
||
|
requestBuffer.Address = Address;
|
||
|
requestBuffer.SubnetMask = SubnetMask;
|
||
|
|
||
|
requestBuffer.InterfaceName.Length = 0;
|
||
|
requestBuffer.InterfaceName.MaximumLength = 0;
|
||
|
requestBuffer.InterfaceName.Buffer = NULL;
|
||
|
|
||
|
status = ClusResDoIoctl(
|
||
|
handle,
|
||
|
IOCTL_CLUSNET_ADD_NTE,
|
||
|
&requestBuffer,
|
||
|
requestBufferSize,
|
||
|
responseBuffer,
|
||
|
&responseBufferSize
|
||
|
);
|
||
|
|
||
|
if (NT_SUCCESS(status)) {
|
||
|
*NTEContext = (ULONG) responseBuffer->Context;
|
||
|
*NTEInstance = responseBuffer->Instance;
|
||
|
status = ERROR_SUCCESS;
|
||
|
}
|
||
|
|
||
|
CloseHandle(handle);
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
status = ERROR_INVALID_PARAMETER;
|
||
|
}
|
||
|
|
||
|
ClRtlFreeNetAdapterEnum(adapterEnum);
|
||
|
}
|
||
|
else {
|
||
|
status = GetLastError();
|
||
|
}
|
||
|
|
||
|
return(status);
|
||
|
}
|
||
|
|
||
|
|
||
|
DWORD
|
||
|
TcpipDeleteNTE(
|
||
|
IN ULONG NTEContext
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Deletes a specified NTE. The target NTE must have been added using
|
||
|
TcpipAddNTE.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
NTEContext - The context value identifying the NTE to delete.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
ERROR_SUCCESS if the operation was successful.
|
||
|
A Windows error code otherwise.
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
NTSTATUS status;
|
||
|
HANDLE handle;
|
||
|
IP_DELETE_NTE_REQUEST requestBuffer;
|
||
|
DWORD requestBufferSize = sizeof(requestBuffer);
|
||
|
DWORD responseBufferSize = 0;
|
||
|
|
||
|
|
||
|
status = ClusResOpenDriver(&handle, DD_CLUSNET_DEVICE_NAME);
|
||
|
|
||
|
if ( status != ERROR_SUCCESS ) {
|
||
|
return status;
|
||
|
}
|
||
|
|
||
|
requestBuffer.Context = (unsigned short) NTEContext;
|
||
|
|
||
|
status = ClusResDoIoctl(
|
||
|
handle,
|
||
|
IOCTL_CLUSNET_DELETE_NTE,
|
||
|
&requestBuffer,
|
||
|
requestBufferSize,
|
||
|
NULL,
|
||
|
&responseBufferSize
|
||
|
);
|
||
|
|
||
|
CloseHandle(handle);
|
||
|
|
||
|
if (NT_SUCCESS(status)) {
|
||
|
return(ERROR_SUCCESS);
|
||
|
}
|
||
|
|
||
|
return(RtlNtStatusToDosError(status));
|
||
|
}
|
||
|
|
||
|
|
||
|
DWORD
|
||
|
TcpipSetNTEAddress(
|
||
|
DWORD NTEContext,
|
||
|
IPAddr Address,
|
||
|
IPMask SubnetMask
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Sets the address of a specified NTE.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
NTEContext - The context value identifying the target NTE.
|
||
|
|
||
|
Address - The IP address to assign to the NTE. Assigning 0.0.0.0
|
||
|
invalidates the NTE.
|
||
|
|
||
|
SubnetMask - The IP subnet mask to assign to the NTE.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
ERROR_SUCCESS if the operation was successful.
|
||
|
A Windows error code otherwise.
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
NTSTATUS status;
|
||
|
HANDLE handle;
|
||
|
IP_SET_ADDRESS_REQUEST requestBuffer;
|
||
|
DWORD requestBufferSize = sizeof(requestBuffer);
|
||
|
DWORD responseBufferSize = 0;
|
||
|
|
||
|
|
||
|
status = ClusResOpenDriver(&handle, DD_CLUSNET_DEVICE_NAME);
|
||
|
|
||
|
if ( status != ERROR_SUCCESS ) {
|
||
|
return status;
|
||
|
}
|
||
|
|
||
|
requestBuffer.Context = (unsigned short) NTEContext;
|
||
|
requestBuffer.Address = Address;
|
||
|
requestBuffer.SubnetMask = SubnetMask;
|
||
|
|
||
|
status = ClusResDoIoctl(
|
||
|
handle,
|
||
|
IOCTL_CLUSNET_SET_NTE_ADDRESS,
|
||
|
&requestBuffer,
|
||
|
requestBufferSize,
|
||
|
NULL,
|
||
|
&responseBufferSize
|
||
|
);
|
||
|
|
||
|
CloseHandle(handle);
|
||
|
|
||
|
if (NT_SUCCESS(status)) {
|
||
|
return(ERROR_SUCCESS);
|
||
|
}
|
||
|
|
||
|
return(RtlNtStatusToDosError(status));
|
||
|
}
|
||
|
|
||
|
|
||
|
DWORD
|
||
|
TcpipGetNTEInfo(
|
||
|
IN ULONG NTEContext,
|
||
|
OUT PTCPIP_NTE_INFO NTEInfo
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Gathers information about a specified NTE.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
NTEContext - The context value identifying the NTE to query.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
ERROR_SUCCESS if the operation was successful.
|
||
|
A Windows error code otherwise.
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
NTSTATUS status;
|
||
|
HANDLE handle;
|
||
|
IP_GET_NTE_INFO_REQUEST requestBuffer;
|
||
|
DWORD requestBufferSize = sizeof(requestBuffer);
|
||
|
IP_GET_NTE_INFO_RESPONSE responseBuffer;
|
||
|
DWORD responseBufferSize = sizeof(responseBuffer);
|
||
|
|
||
|
|
||
|
status = ClusResOpenDriver(&handle, L"\\Device\\Ip");
|
||
|
|
||
|
if ( status != ERROR_SUCCESS ) {
|
||
|
return status;
|
||
|
}
|
||
|
|
||
|
requestBuffer.Context = (unsigned short) NTEContext;
|
||
|
|
||
|
status = ClusResDoIoctl(
|
||
|
handle,
|
||
|
IOCTL_IP_GET_NTE_INFO,
|
||
|
&requestBuffer,
|
||
|
requestBufferSize,
|
||
|
&responseBuffer,
|
||
|
&responseBufferSize
|
||
|
);
|
||
|
|
||
|
CloseHandle(handle);
|
||
|
|
||
|
if (NT_SUCCESS(status)) {
|
||
|
NTEInfo->Instance = responseBuffer.Instance;
|
||
|
NTEInfo->Address = responseBuffer.Address;
|
||
|
NTEInfo->SubnetMask = responseBuffer.SubnetMask;
|
||
|
NTEInfo->Flags = responseBuffer.Flags;
|
||
|
|
||
|
return(ERROR_SUCCESS);
|
||
|
}
|
||
|
|
||
|
return(RtlNtStatusToDosError(status));
|
||
|
}
|
||
|
|
||
|
|
||
|
DWORD
|
||
|
NbtAddInterface(
|
||
|
OUT LPWSTR DeviceName,
|
||
|
IN OUT LPDWORD DeviceNameSize,
|
||
|
OUT PULONG DeviceInstance
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Adds a new NBT interface.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
DeviceName - A unicode string identifying the new NBT interface.
|
||
|
|
||
|
DeviceNameSize - On input, the size of theh device name buffer.
|
||
|
On output, the size of the device name string, or
|
||
|
the size needed to accomodate the string.
|
||
|
|
||
|
DeviceInstance - A pointer to a variable into which to place the
|
||
|
instance ID associated with the new interface.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
ERROR_SUCCESS if the operation was successful.
|
||
|
A Windows error code otherwise.
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
NTSTATUS status;
|
||
|
HANDLE nbthandle = (HANDLE) NULL;
|
||
|
HANDLE cnhandle = (HANDLE) NULL;
|
||
|
PNETBT_ADD_DEL_IF requestBuffer = NULL;
|
||
|
DWORD requestBufferSize = 0;
|
||
|
PNETBT_ADD_DEL_IF responseBuffer = NULL;
|
||
|
DWORD responseBufferSize = 0;
|
||
|
HKEY key = NULL;
|
||
|
LPWSTR NBTDeviceName;
|
||
|
LPWSTR exportString = NULL;
|
||
|
DWORD exportStringSize = 0;
|
||
|
LONG valueType;
|
||
|
|
||
|
|
||
|
//
|
||
|
// get a handle to NetBT's Linkage key, query the size of the
|
||
|
// export value, allocate a buffer large enough to hold it and
|
||
|
// read it in
|
||
|
//
|
||
|
|
||
|
status = RegOpenKeyExW(
|
||
|
HKEY_LOCAL_MACHINE,
|
||
|
L"SYSTEM\\CurrentControlSet\\Services\\NetBT\\Linkage",
|
||
|
0,
|
||
|
KEY_READ,
|
||
|
&key);
|
||
|
|
||
|
if (status != ERROR_SUCCESS) {
|
||
|
goto error_exit;
|
||
|
}
|
||
|
|
||
|
status = RegQueryValueExW(
|
||
|
key,
|
||
|
L"Export",
|
||
|
NULL,
|
||
|
&valueType,
|
||
|
NULL,
|
||
|
&exportStringSize
|
||
|
);
|
||
|
|
||
|
if (status != ERROR_SUCCESS) {
|
||
|
goto error_exit;
|
||
|
}
|
||
|
|
||
|
exportString = LocalAlloc( LMEM_FIXED, exportStringSize );
|
||
|
if ( exportString == NULL ) {
|
||
|
status = ERROR_NOT_ENOUGH_MEMORY;
|
||
|
goto error_exit;
|
||
|
}
|
||
|
|
||
|
status = RegQueryValueExW(
|
||
|
key,
|
||
|
L"Export",
|
||
|
NULL,
|
||
|
&valueType,
|
||
|
(LPBYTE)exportString,
|
||
|
&exportStringSize
|
||
|
);
|
||
|
|
||
|
if (status != ERROR_SUCCESS) {
|
||
|
goto error_exit;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Export is a multi-sz; loop through all the interfaces
|
||
|
// until we find one that we can open successfully.
|
||
|
//
|
||
|
// Hold the handle until we are done with the ioctl so
|
||
|
// that the NBT device doesn't go away.
|
||
|
//
|
||
|
|
||
|
NBTDeviceName = exportString;
|
||
|
do {
|
||
|
|
||
|
status = ClusResOpenDriver(&nbthandle, NBTDeviceName);
|
||
|
|
||
|
if ( status == ERROR_FILE_NOT_FOUND ) {
|
||
|
|
||
|
//
|
||
|
// get the next device name from the export string
|
||
|
//
|
||
|
|
||
|
NBTDeviceName += ( lstrlenW( NBTDeviceName ) + 1 );
|
||
|
if ( *NBTDeviceName == 0 ) {
|
||
|
status = ERROR_FILE_NOT_FOUND;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
} while ( status == ERROR_FILE_NOT_FOUND );
|
||
|
|
||
|
if ( status != ERROR_SUCCESS ) {
|
||
|
goto error_exit;
|
||
|
}
|
||
|
|
||
|
requestBufferSize = FIELD_OFFSET(NETBT_ADD_DEL_IF, IfName[0])
|
||
|
+ lstrlenW( NBTDeviceName ) * sizeof(WCHAR)
|
||
|
+ sizeof(UNICODE_NULL);
|
||
|
|
||
|
if (requestBufferSize < sizeof(NETBT_ADD_DEL_IF)) {
|
||
|
requestBufferSize = sizeof(NETBT_ADD_DEL_IF);
|
||
|
}
|
||
|
|
||
|
requestBuffer = LocalAlloc(LMEM_FIXED, requestBufferSize);
|
||
|
|
||
|
if (requestBuffer == NULL) {
|
||
|
status = ERROR_NOT_ENOUGH_MEMORY;
|
||
|
goto error_exit;
|
||
|
}
|
||
|
|
||
|
RtlZeroMemory( requestBuffer, requestBufferSize );
|
||
|
|
||
|
requestBuffer->Length = lstrlenW( NBTDeviceName ) * sizeof(WCHAR)
|
||
|
+ sizeof(UNICODE_NULL);
|
||
|
|
||
|
RtlCopyMemory(
|
||
|
&requestBuffer->IfName[0],
|
||
|
NBTDeviceName,
|
||
|
requestBuffer->Length
|
||
|
);
|
||
|
|
||
|
responseBufferSize = FIELD_OFFSET(NETBT_ADD_DEL_IF, IfName[0]) +
|
||
|
*DeviceNameSize;
|
||
|
|
||
|
if (responseBufferSize < sizeof(NETBT_ADD_DEL_IF)) {
|
||
|
responseBufferSize = sizeof(NETBT_ADD_DEL_IF);
|
||
|
}
|
||
|
|
||
|
responseBuffer = LocalAlloc(LMEM_FIXED, responseBufferSize);
|
||
|
|
||
|
if (responseBuffer == NULL) {
|
||
|
status = ERROR_NOT_ENOUGH_MEMORY;
|
||
|
goto error_exit;
|
||
|
}
|
||
|
|
||
|
status = ClusResOpenDriver(&cnhandle, DD_CLUSNET_DEVICE_NAME);
|
||
|
|
||
|
if ( status == ERROR_SUCCESS ) {
|
||
|
|
||
|
status = ClusResDoIoctl(
|
||
|
cnhandle,
|
||
|
IOCTL_CLUSNET_ADD_NBT_INTERFACE,
|
||
|
requestBuffer,
|
||
|
requestBufferSize,
|
||
|
responseBuffer,
|
||
|
&responseBufferSize
|
||
|
);
|
||
|
|
||
|
if (NT_SUCCESS(status)) {
|
||
|
*DeviceNameSize = responseBuffer->Length;
|
||
|
|
||
|
if (NT_SUCCESS(responseBuffer->Status)) {
|
||
|
wcscpy(DeviceName, &(responseBuffer->IfName[0]));
|
||
|
*DeviceInstance = responseBuffer->InstanceNumber;
|
||
|
status = ERROR_SUCCESS;
|
||
|
}
|
||
|
else {
|
||
|
status = responseBuffer->Status;
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
status = RtlNtStatusToDosError(status);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
error_exit:
|
||
|
if ( key ) {
|
||
|
RegCloseKey( key );
|
||
|
}
|
||
|
|
||
|
if ( requestBuffer ) {
|
||
|
LocalFree( requestBuffer );
|
||
|
}
|
||
|
|
||
|
if ( responseBuffer ) {
|
||
|
LocalFree( responseBuffer );
|
||
|
}
|
||
|
|
||
|
if ( nbthandle ) {
|
||
|
CloseHandle( nbthandle );
|
||
|
}
|
||
|
|
||
|
if ( cnhandle ) {
|
||
|
CloseHandle( cnhandle );
|
||
|
}
|
||
|
|
||
|
return(status);
|
||
|
}
|
||
|
|
||
|
|
||
|
DWORD
|
||
|
NbtDeleteInterface(
|
||
|
IN LPWSTR DeviceName
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Deletes an NBT interface.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
DeviceName - A unicode string identifying the target NBT interface.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
ERROR_SUCCESS if the operation was successful.
|
||
|
A Windows error code otherwise.
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
NTSTATUS status;
|
||
|
HANDLE handle = (HANDLE) NULL;
|
||
|
DWORD responseBufferSize = 0;
|
||
|
PNETBT_ADD_DEL_IF requestBuffer = NULL;
|
||
|
DWORD requestBufferSize = 0;
|
||
|
|
||
|
|
||
|
requestBufferSize = FIELD_OFFSET(NETBT_ADD_DEL_IF, IfName[0])
|
||
|
+ lstrlenW( DeviceName ) * sizeof(WCHAR)
|
||
|
+ sizeof(UNICODE_NULL);
|
||
|
|
||
|
if (requestBufferSize < sizeof(NETBT_ADD_DEL_IF)) {
|
||
|
requestBufferSize = sizeof(NETBT_ADD_DEL_IF);
|
||
|
}
|
||
|
|
||
|
requestBuffer = LocalAlloc(LMEM_FIXED, requestBufferSize);
|
||
|
|
||
|
if (requestBuffer == NULL) {
|
||
|
status = ERROR_NOT_ENOUGH_MEMORY;
|
||
|
goto error_exit;
|
||
|
}
|
||
|
|
||
|
RtlZeroMemory( requestBuffer, requestBufferSize );
|
||
|
|
||
|
requestBuffer->Length = lstrlenW( DeviceName ) * sizeof(WCHAR)
|
||
|
+ sizeof(UNICODE_NULL);
|
||
|
|
||
|
RtlCopyMemory(
|
||
|
&requestBuffer->IfName[0],
|
||
|
DeviceName,
|
||
|
requestBuffer->Length
|
||
|
);
|
||
|
|
||
|
status = ClusResOpenDriver(&handle, DD_CLUSNET_DEVICE_NAME);
|
||
|
|
||
|
if ( status != ERROR_SUCCESS ) {
|
||
|
goto error_exit;
|
||
|
}
|
||
|
|
||
|
status = ClusResDoIoctl(
|
||
|
handle,
|
||
|
IOCTL_CLUSNET_DEL_NBT_INTERFACE,
|
||
|
requestBuffer,
|
||
|
requestBufferSize,
|
||
|
NULL,
|
||
|
&responseBufferSize
|
||
|
);
|
||
|
|
||
|
if (NT_SUCCESS(status)) {
|
||
|
status = ERROR_SUCCESS;
|
||
|
}
|
||
|
else {
|
||
|
status = RtlNtStatusToDosError(status);
|
||
|
}
|
||
|
|
||
|
error_exit:
|
||
|
|
||
|
if (requestBuffer) {
|
||
|
LocalFree(requestBuffer);
|
||
|
}
|
||
|
|
||
|
if (handle) {
|
||
|
CloseHandle(handle);
|
||
|
}
|
||
|
|
||
|
return(status);
|
||
|
}
|
||
|
|
||
|
|
||
|
DWORD
|
||
|
NbtBindInterface(
|
||
|
IN LPWSTR DeviceName,
|
||
|
IN IPAddr Address,
|
||
|
IN IPMask SubnetMask
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Binds a specified NBT interface to a specified IP address.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
DeviceName - A unicode string identifying the target NBT interface.
|
||
|
|
||
|
Address - The IP address to which bind the interface. Assigning 0.0.0.0
|
||
|
invalidates the interface.
|
||
|
|
||
|
SubnetMask - The subnet mask of the IP interface.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
ERROR_SUCCESS if the operation was successful.
|
||
|
A Windows error code otherwise.
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
NTSTATUS status;
|
||
|
HANDLE handle;
|
||
|
tNEW_IP_ADDRESS requestBuffer;
|
||
|
DWORD requestBufferSize = sizeof(requestBuffer);
|
||
|
DWORD responseBufferSize = 0;
|
||
|
|
||
|
|
||
|
status = ClusResOpenDriver(&handle, DeviceName);
|
||
|
|
||
|
if ( status != ERROR_SUCCESS ) {
|
||
|
return status;
|
||
|
}
|
||
|
|
||
|
requestBuffer.IpAddress = Address;
|
||
|
requestBuffer.SubnetMask = SubnetMask;
|
||
|
|
||
|
status = ClusResDoIoctl(
|
||
|
handle,
|
||
|
IOCTL_NETBT_NEW_IPADDRESS,
|
||
|
&requestBuffer,
|
||
|
requestBufferSize,
|
||
|
NULL,
|
||
|
&responseBufferSize
|
||
|
);
|
||
|
|
||
|
CloseHandle(handle);
|
||
|
|
||
|
if (NT_SUCCESS(status)) {
|
||
|
return(ERROR_SUCCESS);
|
||
|
}
|
||
|
|
||
|
return(RtlNtStatusToDosError(status));
|
||
|
}
|
||
|
|
||
|
DWORD
|
||
|
NbtSetWinsAddrInterface(
|
||
|
IN LPWSTR DeviceName,
|
||
|
IN IPAddr PrWinsAddress,
|
||
|
IN IPAddr SecWinsAddress
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Sets the WINS addrs for a given Nbt Interface.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
DeviceName - A unicode string identifying the target NBT interface.
|
||
|
|
||
|
PrWinsAddress - Primary WINS addr
|
||
|
|
||
|
SecWinsAddress - Secondary WINS addr
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
ERROR_SUCCESS if the operation was successful.
|
||
|
A Windows error code otherwise.
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
NTSTATUS status;
|
||
|
HANDLE handle;
|
||
|
NETBT_SET_WINS_ADDR requestBuffer;
|
||
|
DWORD requestBufferSize = sizeof(requestBuffer);
|
||
|
DWORD responseBufferSize = 0;
|
||
|
|
||
|
|
||
|
status = ClusResOpenDriver(&handle, DeviceName);
|
||
|
|
||
|
if ( status != ERROR_SUCCESS ) {
|
||
|
return status;
|
||
|
}
|
||
|
|
||
|
requestBuffer.PrimaryWinsAddr = ntohl(PrWinsAddress);
|
||
|
requestBuffer.SecondaryWinsAddr = ntohl(SecWinsAddress);
|
||
|
|
||
|
status = ClusResDoIoctl(
|
||
|
handle,
|
||
|
IOCTL_NETBT_SET_WINS_ADDRESS,
|
||
|
&requestBuffer,
|
||
|
requestBufferSize,
|
||
|
NULL,
|
||
|
&responseBufferSize
|
||
|
);
|
||
|
|
||
|
CloseHandle(handle);
|
||
|
|
||
|
if (NT_SUCCESS(status)) {
|
||
|
return(ERROR_SUCCESS);
|
||
|
}
|
||
|
|
||
|
return(RtlNtStatusToDosError(status));
|
||
|
}
|
||
|
|
||
|
|
||
|
DWORD
|
||
|
NbtGetWinsAddresses(
|
||
|
IN LPWSTR DeviceName,
|
||
|
OUT IPAddr * PrimaryWinsServer,
|
||
|
OUT IPAddr * SecondaryWinsServer
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Returns the addresses of the WINS servers for which the specified device
|
||
|
is configured.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
DeviceName - A unicode string identifying the target NBT interface.
|
||
|
|
||
|
PrimaryWinsServer - A pointer to a variable into which to place the address
|
||
|
of the primary WINS server.
|
||
|
|
||
|
SecondaryWinsServer - A pointer to a variable into which to place the address
|
||
|
of the primary WINS server.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
ERROR_SUCCESS if the operation was successful.
|
||
|
A Windows error code otherwise.
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
NTSTATUS status;
|
||
|
HANDLE handle;
|
||
|
tWINS_ADDRESSES responseBuffer;
|
||
|
DWORD responseBufferSize = sizeof(responseBuffer);
|
||
|
|
||
|
|
||
|
status = ClusResOpenDriver(&handle, DeviceName);
|
||
|
|
||
|
if ( status != ERROR_SUCCESS ) {
|
||
|
return status;
|
||
|
}
|
||
|
|
||
|
status = ClusResDoIoctl(
|
||
|
handle,
|
||
|
IOCTL_NETBT_GET_WINS_ADDR,
|
||
|
NULL,
|
||
|
0,
|
||
|
&responseBuffer,
|
||
|
&responseBufferSize
|
||
|
);
|
||
|
|
||
|
CloseHandle(handle);
|
||
|
|
||
|
if (NT_SUCCESS(status)) {
|
||
|
*PrimaryWinsServer = htonl(responseBuffer.PrimaryWinsServer);
|
||
|
*SecondaryWinsServer = htonl(responseBuffer.BackupWinsServer);
|
||
|
return(ERROR_SUCCESS);
|
||
|
}
|
||
|
|
||
|
return(RtlNtStatusToDosError(status));
|
||
|
}
|
||
|
|
||
|
|
||
|
DWORD
|
||
|
NbtGetInterfaceInfo(
|
||
|
IN LPWSTR DeviceName,
|
||
|
OUT IPAddr * Address,
|
||
|
OUT PULONG DeviceInstance
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Returns the IP address to which an NBT interface is bound and the interface
|
||
|
instance ID.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
DeviceName - A unicode string identifying the target NBT interface.
|
||
|
|
||
|
Address - A pointer to the location in which to store the address of the
|
||
|
interface.
|
||
|
|
||
|
DeviceInstance - A pointer to the location in which to store the instance ID
|
||
|
associated with the interface.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
ERROR_SUCCESS if the operation was successful.
|
||
|
A Windows error code otherwise.
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
NTSTATUS status;
|
||
|
HANDLE handle;
|
||
|
IPAddr address;
|
||
|
NETBT_ADD_DEL_IF responseBuffer;
|
||
|
DWORD responseBufferSize;
|
||
|
|
||
|
|
||
|
status = ClusResOpenDriver(&handle, DeviceName);
|
||
|
|
||
|
if ( status != ERROR_SUCCESS ) {
|
||
|
return status;
|
||
|
}
|
||
|
|
||
|
responseBufferSize = sizeof(address);
|
||
|
|
||
|
status = ClusResDoIoctl(
|
||
|
handle,
|
||
|
IOCTL_NETBT_GET_IP_ADDRS,
|
||
|
NULL,
|
||
|
0,
|
||
|
&address,
|
||
|
&responseBufferSize
|
||
|
);
|
||
|
|
||
|
if (!((status == STATUS_SUCCESS) || (status == STATUS_BUFFER_OVERFLOW))) {
|
||
|
CloseHandle(handle);
|
||
|
return(RtlNtStatusToDosError(status));
|
||
|
}
|
||
|
|
||
|
*Address = htonl(address);
|
||
|
|
||
|
responseBufferSize = sizeof(responseBuffer);
|
||
|
|
||
|
status = ClusResDoIoctl(
|
||
|
handle,
|
||
|
IOCTL_NETBT_QUERY_INTERFACE_INSTANCE,
|
||
|
NULL,
|
||
|
0,
|
||
|
&responseBuffer,
|
||
|
&responseBufferSize
|
||
|
);
|
||
|
|
||
|
CloseHandle(handle);
|
||
|
|
||
|
if (status == STATUS_SUCCESS) {
|
||
|
if (responseBuffer.Status == STATUS_SUCCESS) {
|
||
|
*DeviceInstance = responseBuffer.InstanceNumber;
|
||
|
}
|
||
|
else {
|
||
|
status = RtlNtStatusToDosError(responseBuffer.Status);
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
status = RtlNtStatusToDosError(status);
|
||
|
}
|
||
|
|
||
|
return(status);
|
||
|
}
|
||
|
|
||
|
|