windows-nt/Source/XPSP1/NT/termsrv/drivers/td/tdnetb/tdnetb.c
2020-09-26 16:20:57 +08:00

1047 lines
30 KiB
C

/*************************************************************************
*
* tdnetb.c
*
* NETBIOS transport specific routines for TDI interface.
*
* Copyright 1998, Microsoft
*
*************************************************************************/
#include <ntddk.h>
#include <tdi.h>
#include <winstaw.h>
#define _DEFCHARINFO_
#include <icadd.h>
#include <ctxdd.h>
#include <sdapi.h>
#include <td.h>
#include "tdtdi.h"
#include "tdnetb.h"
#ifdef _HYDRA_
// This becomes the device name
PWCHAR ModuleName = L"tdnetb";
#endif
/*=============================================================================
== External Functions Defined
=============================================================================*/
NTSTATUS TdiDeviceOpen( PTD, PSD_OPEN );
NTSTATUS TdiDeviceClose( PTD, PSD_CLOSE );
NTSTATUS TdiDeviceOpenEndpoint( PTD, PVOID, ULONG );
NTSTATUS TdiDeviceBuildTransportNameAndAddress( PTD, PICA_STACK_ADDRESS,
PUNICODE_STRING,
PTRANSPORT_ADDRESS *, PULONG );
NTSTATUS TdiDeviceBuildWildcardAddress( PTD, PTRANSPORT_ADDRESS *, PULONG );
NTSTATUS TdiDeviceWaitForDatagramConnection( PTD, PFILE_OBJECT, PDEVICE_OBJECT,
PTRANSPORT_ADDRESS *, PULONG );
NTSTATUS TdiDeviceCompleteDatagramConnection( PTD, PFILE_OBJECT, PDEVICE_OBJECT, PTRANSPORT_ADDRESS, ULONG );
NTSTATUS TdiDeviceConnectionSend( PTD );
NTSTATUS TdiDeviceReadComplete( PTD, PUCHAR, PULONG );
/*=============================================================================
== External Functions Referenced
=============================================================================*/
NTSTATUS MemoryAllocate( ULONG, PVOID * );
VOID MemoryFree( PVOID );
/*=============================================================================
== Internal Functions Defined
=============================================================================*/
NTSTATUS _NetBiosGetTransportName( PTD, LONG, PUNICODE_STRING );
NTSTATUS _GetComputerName( PTD, PUNICODE_STRING );
VOID GetGUID( PUNICODE_STRING ,int);
NTSTATUS
_OpenRegKey(
PHANDLE HandlePtr,
PWCHAR KeyName
);
NTSTATUS
_GetRegDWORDValue(
HANDLE KeyHandle,
PWCHAR ValueName,
PULONG ValueData
);
NTSTATUS
_GetRegStringValue(
HANDLE KeyHandle,
PWCHAR ValueName,
PKEY_VALUE_PARTIAL_INFORMATION *ValueData,
PUSHORT ValueSize
);
NTSTATUS
_GetRegMultiSZValue(
HANDLE KeyHandle,
PWCHAR ValueName,
PUNICODE_STRING ValueData
);
NTSTATUS
_GetRegSZValue(
HANDLE KeyHandle,
PWCHAR ValueName,
PUNICODE_STRING ValueData,
PULONG ValueType
);
PWCHAR
_EnumRegMultiSz(
PWCHAR MszString,
ULONG MszStringLength,
ULONG StringIndex
);
/*=============================================================================
== Global variables
=============================================================================*/
/*
* Define variables used by tdicommon code
*/
USHORT TdiDeviceEndpointType = TdiConnectionStream;
USHORT TdiDeviceAddressType = TDI_ADDRESS_TYPE_NETBIOS;
USHORT TdiDeviceInBufHeader = 0;
// ULONG TdiDeviceMaxTransportAddressLength = sizeof(TA_NETBIOS_ADDRESS);
/*******************************************************************************
*
* TdiDeviceOpen
*
* Allocate and initialize private data structures
*
* ENTRY:
* pTd (input)
* Pointer to TD data structure
* pSdOpen (input/output)
* Points to the parameter structure SD_OPEN.
*
* EXIT:
* STATUS_SUCCESS - no error
*
******************************************************************************/
NTSTATUS
TdiDeviceOpen( PTD pTd, PSD_OPEN pSdOpen )
{
return( STATUS_SUCCESS );
}
/*******************************************************************************
*
* TdiDeviceClose
*
* Close transport driver
*
* NOTE: this must not close the current connection endpoint
*
* ENTRY:
* pTd (input)
* Pointer to TD data structure
* pSdClose (input/output)
* Points to the parameter structure SD_CLOSE.
*
* EXIT:
* STATUS_SUCCESS - no error
*
******************************************************************************/
NTSTATUS
TdiDeviceClose( PTD pTd, PSD_CLOSE pSdClose )
{
return( STATUS_SUCCESS );
}
/*******************************************************************************
*
* TdiDeviceOpenEndpoint
*
* Open an existing endpoint
*
* ENTRY:
* pTd (input)
* Pointer to TD data structure
* pIcaEndpoint (input)
* Pointer to ICA endpoint structure
* IcaEndpointLength (input)
* length of endpoint data
*
* EXIT:
* STATUS_SUCCESS - no error
*
******************************************************************************/
NTSTATUS
TdiDeviceOpenEndpoint(
PTD pTd,
PVOID pIcaEndpoint,
ULONG IcaEndpointLength
)
{
return( STATUS_SUCCESS );
}
/*****************************************************************************
*
* TdiDeviceBuildTransportNameAndAddress
*
* Build the Transport Name and Address given an optional ICA_STACK_ADDRESS,
* or the Lana value from the pTd->Params structure.
*
* ENTRY:
*
* pTd (input)
* pointer to TD data structure
* pLocalAddress (input)
* pointer to local address to use (OPTIONAL)
* pTransportName (output)
* pointer to UNICODE_STRING to return transport name
* NOTE: the buffer pointed to be pTransportName->Buffer must
* be free'd by the caller
* ppTransportAddress (output)
* pointer to location to return TRANSPORT_ADDRESS structure
* NOTE: the transport address buffer must be free'd by the caller
* pTransportAddressLength (output)
* pointer to location to return TransportAddress length
*
* EXIT:
* STATUS_SUCCESS - Success
*
****************************************************************************/
NTSTATUS
TdiDeviceBuildTransportNameAndAddress(
PTD pTd,
PICA_STACK_ADDRESS pLocalAddress,
PUNICODE_STRING pTransportName,
PTRANSPORT_ADDRESS *ppTransportAddress,
PULONG pTransportAddressLength
)
{
PTDI_ADDRESS_NETBIOS pNetbiosAddress;
PWCHAR pComputerName;
NTSTATUS Status;
/*
* For NetBios, the transport device name is determined from
* the specified LanAdapter (Lana) number.
*/
Status = _NetBiosGetTransportName( pTd, pTd->Params.Network.LanAdapter,
pTransportName );
if ( !NT_SUCCESS( Status ) )
goto badtransportname;
/*
* Allocate a transport address structure
*/
*pTransportAddressLength = sizeof(TRANSPORT_ADDRESS) +
sizeof(TDI_ADDRESS_NETBIOS);
Status = MemoryAllocate( *pTransportAddressLength, ppTransportAddress );
if ( !NT_SUCCESS( Status ) )
goto badmalloc;
/*
* Initialize the static part of the transport address
*/
(*ppTransportAddress)->TAAddressCount = 1;
(*ppTransportAddress)->Address[0].AddressLength = sizeof(TDI_ADDRESS_NETBIOS);
(*ppTransportAddress)->Address[0].AddressType = TDI_ADDRESS_TYPE_NETBIOS;
pNetbiosAddress = (PTDI_ADDRESS_NETBIOS)(*ppTransportAddress)->Address[0].Address;
/*
* If a local address is specified, then use it.
*/
if ( pLocalAddress ) {
/*
* Skip over the address family(type) data (bytes 0&1) of the
* local address struct, and copy the remainder of the address
* directly to the Address field of the TransportAddress struct.
*/
ASSERT( *(PUSHORT)pLocalAddress == TDI_ADDRESS_TYPE_NETBIOS );
RtlCopyMemory( pNetbiosAddress, &((PCHAR)pLocalAddress)[2], sizeof(TDI_ADDRESS_NETBIOS) );
/*
* There was no local address specified.
* Use the local ComputerName to build the NetBios name.
*/
} else {
ANSI_STRING ansiString;
UNICODE_STRING unicodeString;
Status = _GetComputerName( pTd, &unicodeString );
if ( !NT_SUCCESS( Status ) )
goto badcomputername;
pNetbiosAddress->NetbiosNameType = TDI_ADDRESS_NETBIOS_TYPE_UNIQUE;
/*
* Now convert ComputerName from unicode to ansi and
* store it in the NetBios name field of the transport address.
*/
ansiString.Length = 0;
ansiString.MaximumLength = sizeof(pNetbiosAddress->NetbiosName);
ansiString.Buffer = pNetbiosAddress->NetbiosName;
RtlUnicodeStringToAnsiString( &ansiString, &unicodeString, FALSE );
RtlFillMemory( &pNetbiosAddress->NetbiosName[ansiString.Length],
sizeof(pNetbiosAddress->NetbiosName) - ansiString.Length,
'.' );
pNetbiosAddress->NetbiosName[15] = '\0';
}
return( STATUS_SUCCESS );
/*=============================================================================
== Error returns
=============================================================================*/
badcomputername:
MemoryFree( *ppTransportAddress );
badmalloc:
MemoryFree( pTransportName->Buffer );
badtransportname:
return( Status );
}
/*****************************************************************************
*
* TdiDeviceBuildWildcardAddress
*
* Build a wildcard Address for this protocol.
*
* ENTRY:
*
* pTd (input)
* pointer to TD data structure
* ppWildcardAddress (output)
* pointer to location to return TRANSPORT_ADDRESS structure
* NOTE: the transport address buffer must be free'd by the caller
* pWildcardAddressLength (output)
* pointer to location to return TransportAddress length
*
* EXIT:
* STATUS_SUCCESS - Success
*
****************************************************************************/
NTSTATUS
TdiDeviceBuildWildcardAddress(
PTD pTd,
PTRANSPORT_ADDRESS *ppWildcardAddress,
PULONG pWildcardAddressLength
)
{
PTDI_ADDRESS_NETBIOS pNetbiosAddress;
UNICODE_STRING unicodeString;
ANSI_STRING ansiString;
PWCHAR pComputerName;
NTSTATUS Status;
/*
* Allocate a transport address structure
*/
*pWildcardAddressLength = sizeof(TRANSPORT_ADDRESS) +
sizeof(TDI_ADDRESS_NETBIOS);
Status = MemoryAllocate( *pWildcardAddressLength, ppWildcardAddress );
if ( !NT_SUCCESS( Status ) )
return( Status );
/*
* Initialize the static part of the transport address
*/
(*ppWildcardAddress)->TAAddressCount = 1;
(*ppWildcardAddress)->Address[0].AddressLength = sizeof(TDI_ADDRESS_NETBIOS);
(*ppWildcardAddress)->Address[0].AddressType = TDI_ADDRESS_TYPE_NETBIOS;
pNetbiosAddress = (PTDI_ADDRESS_NETBIOS)(*ppWildcardAddress)->Address[0].Address;
pNetbiosAddress->NetbiosNameType = TDI_ADDRESS_NETBIOS_TYPE_GROUP;
RtlZeroMemory( pNetbiosAddress->NetbiosName,
sizeof(pNetbiosAddress->NetbiosName) );
Status = _GetComputerName( pTd, &unicodeString );
if ( !NT_SUCCESS( Status ) ) {
MemoryFree( *ppWildcardAddress );
return( Status );
}
/*
* Now convert ComputerName from unicode to ansi and
* store it in the NetBios name field of the transport address.
*/
ansiString.Length = 0;
ansiString.MaximumLength = sizeof(pNetbiosAddress->NetbiosName);
ansiString.Buffer = pNetbiosAddress->NetbiosName;
RtlUnicodeStringToAnsiString( &ansiString, &unicodeString, FALSE );
#ifdef notdef
RtlFillMemory( &pNetbiosAddress->NetbiosName[ansiString.Length],
sizeof(pNetbiosAddress->NetbiosName) - ansiString.Length,
'.' );
pNetbiosAddress->NetbiosName[15] = '\0';
#endif
return( STATUS_SUCCESS );
}
/*****************************************************************************
*
* TdiDeviceWaitForDatagramConnection
*
* Wait for a datagram connection request, validate it,
* and return the remote transport address of the connection.
*
* ENTRY:
*
* pTd (input)
* pointer to TD data structure
* pFileObject (input)
* pointer to file object to wait for a connection on
* ppRemoteAddress (output)
* pointer to location to return TRANSPORT_ADDRESS structure
* NOTE: the transport address buffer must be free'd by the caller
* pRemoteAddressLength (output)
* pointer to location to return RemoteAddress length
*
* EXIT:
* STATUS_SUCCESS - Success
*
****************************************************************************/
NTSTATUS
TdiDeviceWaitForDatagramConnection(
PTD pTd,
PFILE_OBJECT pFileObject,
PDEVICE_OBJECT pDeviceObject,
PTRANSPORT_ADDRESS *ppRemoteAddress,
PULONG pRemoteAddressLength
)
{
return( STATUS_NOT_SUPPORTED );
}
/*****************************************************************************
*
* TdiDeviceCompleteDatagramConnection
*
* Do any final work to complete a datagram connection.
*
* ENTRY:
*
* pTd (input)
* pointer to TD data structure
* pFileObject (input)
* pointer to file object for this connection
*
* EXIT:
* STATUS_SUCCESS - Success
*
****************************************************************************/
NTSTATUS
TdiDeviceCompleteDatagramConnection(
PTD pTd,
PFILE_OBJECT pFileObject,
PDEVICE_OBJECT pDeviceObject,
PTRANSPORT_ADDRESS pTransportAddress,
ULONG TransportAddressLength
)
{
return( STATUS_NOT_SUPPORTED );
}
/*******************************************************************************
*
* TdiDeviceConnectionSend
*
* Initialize host module data structure
* -- this structure gets sent to the client
*
*
* ENTRY:
* pTd (input)
* Pointer to td data structure
*
* EXIT:
* STATUS_SUCCESS - no error
*
******************************************************************************/
NTSTATUS
TdiDeviceConnectionSend( PTD pTd )
{
PCLIENTMODULES pClient;
/*
* Get pointer to client structure
*/
pClient = pTd->pClient;
/*
* Initialize Td host module structure
*/
pClient->TdVersionL = VERSION_HOSTL_TDNETB;
pClient->TdVersionH = VERSION_HOSTH_TDNETB;
pClient->TdVersion = VERSION_HOSTH_TDNETB;
return( STATUS_SUCCESS );
}
/*******************************************************************************
*
* TdiDeviceReadComplete
*
* Do any read complete processing
*
*
* ENTRY:
* pTd (input)
* Pointer to td data structure
* pBuffer (input)
* Pointer to input buffer
* pByteCount (input/output)
* Pointer to location containing byte count read
*
* EXIT:
* STATUS_SUCCESS - no error
*
******************************************************************************/
NTSTATUS
TdiDeviceReadComplete( PTD pTd, PUCHAR pBuffer, PULONG pByteCount )
{
return( STATUS_SUCCESS );
}
/*******************************************************************************
*
* _NetBiosGetTransportName
*
* Read netbios registry entries to find the transport device name
* for the specified LanAdapter number.
*
* ENTRY:
* pTd (input)
* Pointer to td data structure
* Lana (input)
* Lan Adapter number
* pTransportName (output)
* pointer to UNICODE_STRING to return transport name
* NOTE: the buffer pointed to be pTransportName->Buffer must
* be free'd by the caller
*
* EXIT:
* STATUS_SUCCESS - no error
*
******************************************************************************/
#if 0
NTSTATUS
_NetBiosGetTransportName(
PTD pTd,
LONG Lana,
PUNICODE_STRING pTransportName
)
{
UNICODE_STRING nameString;
OBJECT_ATTRIBUTES objectAttributes;
HANDLE netbiosKey = NULL;
ULONG providerListLength;
PKEY_VALUE_PARTIAL_INFORMATION pProviderNameInfo = NULL;
ULONG lanaMapLength;
PKEY_VALUE_PARTIAL_INFORMATION pLanaMapInfo = NULL;
PLANA_MAP pLanaMap;
int ProviderCount;
int i;
PWSTR currentProviderName;
NTSTATUS Status;
//
// Read the registry for information on all Netbios providers,
// including Lana numbers, protocol numbers, and provider device
// names. First, open the Netbios key in the registry.
//
RtlInitUnicodeString( &nameString, NETBIOS_KEY );
InitializeObjectAttributes(
&objectAttributes,
&nameString,
OBJ_CASE_INSENSITIVE,
(HANDLE) NULL,
(PSECURITY_DESCRIPTOR) NULL
);
Status = ZwOpenKey( &netbiosKey, KEY_READ, &objectAttributes );
if ( !NT_SUCCESS( Status ) )
return( Status );
//
// Determine the size of the provider names. We need this so
// that we can allocate enough memory to hold it.
//
providerListLength = 0;
RtlInitUnicodeString( &nameString, L"Bind" );
Status = ZwQueryValueKey( netbiosKey,
&nameString,
KeyValuePartialInformation,
NULL,
0,
&providerListLength
);
if ( Status != STATUS_BUFFER_TOO_SMALL )
return( Status );
//
// Allocate enough memory to hold the mapping.
//
Status = MemoryAllocate( providerListLength, &pProviderNameInfo );
if ( !NT_SUCCESS( Status ) )
goto error_exit;
//
// Get the list of transports from the registry.
//
Status = ZwQueryValueKey( netbiosKey,
&nameString,
KeyValuePartialInformation,
pProviderNameInfo,
providerListLength,
&providerListLength
);
if ( !NT_SUCCESS( Status ) ) {
MemoryFree( pProviderNameInfo );
return( Status );
}
//
// Determine the size of the Lana map. We need this so that we
// can allocate enough memory to hold it.
//
lanaMapLength = 0;
RtlInitUnicodeString( &nameString, L"LanaMap" );
Status = ZwQueryValueKey( netbiosKey,
&nameString,
KeyValuePartialInformation,
NULL,
0,
&lanaMapLength
);
if ( Status != STATUS_BUFFER_TOO_SMALL ) {
MemoryFree( pProviderNameInfo );
return( Status );
}
//
// Allocate enough memory to hold the Lana map.
//
Status = MemoryAllocate( lanaMapLength, &pLanaMapInfo );
if ( !NT_SUCCESS( Status ) )
goto error_exit;
//
// Get the list of transports from the registry.
//
Status = ZwQueryValueKey( netbiosKey,
&nameString,
KeyValuePartialInformation,
pLanaMapInfo,
lanaMapLength,
&lanaMapLength
);
if ( !NT_SUCCESS( Status ) ) {
MemoryFree( pLanaMapInfo );
MemoryFree( pProviderNameInfo );
return( Status );
}
//
// Determine the number of Netbios providers loaded on the system.
//
ProviderCount = (int) (lanaMapLength / sizeof(LANA_MAP));
//
// Fill in the array of provider information.
//
Status = STATUS_DEVICE_DOES_NOT_EXIST;
pLanaMap = (PLANA_MAP)pLanaMapInfo->Data;
for ( currentProviderName = (PWSTR)pProviderNameInfo->Data, i = 0;
*currentProviderName != UNICODE_NULL && i < ProviderCount;
currentProviderName += wcslen( currentProviderName ) + 1, i++ ) {
if ( pLanaMap[i].Lana == Lana && pLanaMap[i].Enum ) {
pTransportName->Length = wcslen( currentProviderName ) *
sizeof(UNICODE_NULL);
pTransportName->MaximumLength = pTransportName->Length +
sizeof(UNICODE_NULL);
Status = MemoryAllocate( pTransportName->MaximumLength,
&pTransportName->Buffer );
if ( !NT_SUCCESS( Status ) )
break;
wcscpy( pTransportName->Buffer, currentProviderName );
Status = STATUS_SUCCESS;
break;
}
}
MemoryFree( pLanaMapInfo );
MemoryFree( pProviderNameInfo );
ZwClose( netbiosKey );
return( Status );
/*=============================================================================
== Error returns
=============================================================================*/
error_exit:
if ( netbiosKey != NULL ) {
ZwClose( netbiosKey );
}
if ( pProviderNameInfo != NULL ) {
MemoryFree( pProviderNameInfo );
}
if ( pLanaMapInfo != NULL ) {
MemoryFree( pLanaMapInfo );
}
return( Status );
}
#endif
NTSTATUS
_NetBiosGetTransportName(
PTD pTd,
LONG Lana,
PUNICODE_STRING pTransportName
)
{
UNICODE_STRING nameString;
OBJECT_ATTRIBUTES objectAttributes;
HANDLE netbiosKey = NULL;
ULONG providerListLength;
PKEY_VALUE_PARTIAL_INFORMATION pProviderNameInfo = NULL;
int ProviderCount;
ULONG lanaMapLength;
PKEY_VALUE_PARTIAL_INFORMATION pLanaMapInfo = NULL;
PLANA_MAP pLanaMap;
int i;
USHORT Len;
PWSTR currentProviderName;
NTSTATUS Status;
UNICODE_STRING RouteString;
PWCHAR GUIDStr;
RtlInitUnicodeString( &RouteString , NULL );
GetGUID( &RouteString , Lana );
Len = RouteString.Length;
GUIDStr = RouteString.Buffer;
if (Len < (2 * sizeof(UNICODE_NULL)))
{
// The GUID not present - That means the device no longer exists
Status = STATUS_DEVICE_DOES_NOT_EXIST;
goto error_exit;
}
//
// Read the registry for information on all Netbios providers,
// including Lana numbers, protocol numbers, and provider device
// names. First, open the Netbios key in the registry.
//
RtlInitUnicodeString( &nameString, NETBIOS_KEY );
InitializeObjectAttributes(
&objectAttributes,
&nameString,
OBJ_CASE_INSENSITIVE,
(HANDLE) NULL,
(PSECURITY_DESCRIPTOR) NULL
);
Status = ZwOpenKey( &netbiosKey, KEY_READ, &objectAttributes );
if ( !NT_SUCCESS( Status ) )
return( Status );
//
// Determine the size of the provider names. We need this so
// that we can allocate enough memory to hold it.
//
providerListLength = 0;
RtlInitUnicodeString( &nameString, L"Bind" );
Status = ZwQueryValueKey( netbiosKey,
&nameString,
KeyValuePartialInformation,
NULL,
0,
&providerListLength
);
if ( Status != STATUS_BUFFER_TOO_SMALL )
return( Status );
//
// Allocate enough memory to hold the mapping.
//
Status = MemoryAllocate( providerListLength, &pProviderNameInfo );
if ( !NT_SUCCESS( Status ) )
goto error_exit;
//
// Get the list of transports from the registry.
//
Status = ZwQueryValueKey( netbiosKey,
&nameString,
KeyValuePartialInformation,
pProviderNameInfo,
providerListLength,
&providerListLength
);
if ( !NT_SUCCESS( Status ) ) {
MemoryFree( pProviderNameInfo );
return( Status );
}
//
// Determine the size of the Lana map. We need this so that we
// can allocate enough memory to hold it.
//
lanaMapLength = 0;
RtlInitUnicodeString( &nameString, L"LanaMap" );
Status = ZwQueryValueKey( netbiosKey,
&nameString,
KeyValuePartialInformation,
NULL,
0,
&lanaMapLength
);
if ( Status != STATUS_BUFFER_TOO_SMALL ) {
MemoryFree( pProviderNameInfo );
return( Status );
}
//
// Allocate enough memory to hold the Lana map.
//
Status = MemoryAllocate( lanaMapLength, &pLanaMapInfo );
if ( !NT_SUCCESS( Status ) )
goto error_exit;
//
// Get the list of transports from the registry.
//
Status = ZwQueryValueKey( netbiosKey,
&nameString,
KeyValuePartialInformation,
pLanaMapInfo,
lanaMapLength,
&lanaMapLength
);
if ( !NT_SUCCESS( Status ) ) {
MemoryFree( pLanaMapInfo );
MemoryFree( pProviderNameInfo );
return( Status );
}
//
// Determine the number of Netbios providers loaded on the system.
//
ProviderCount = (int) (lanaMapLength / sizeof(LANA_MAP));
//
// Fill in the array of provider information.
//
Status = STATUS_DEVICE_DOES_NOT_EXIST;
pLanaMap = (PLANA_MAP)pLanaMapInfo->Data;
Len = Len/sizeof(WCHAR); // convert length from bytes to WCHARs
#if 0
DbgPrint("GUIDStr=%ws, Len=%d\n",GUIDStr, Len);
#endif
for ( currentProviderName = (PWSTR)pProviderNameInfo->Data, i = 0;
*currentProviderName != UNICODE_NULL && i < ProviderCount;
currentProviderName += wcslen( currentProviderName ) + 1, i++ ) {
#if 0
DbgPrint("currentProviderName: %ws\n",currentProviderName);
DbgPrint("i=%d, pLanaMap.Enum=%d\n", i, pLanaMap[i].Enum);
DbgPrint("wcscmp str=%ws\n",currentProviderName+wcslen(currentProviderName)-Len);
#endif
if ((pLanaMap[i].Enum) &&
(Len <=wcslen(currentProviderName)) &&
(!wcsncmp((currentProviderName+wcslen(currentProviderName)-Len), GUIDStr, Len)))
{
pTransportName->Length = wcslen( currentProviderName ) *
sizeof(UNICODE_NULL);
pTransportName->MaximumLength = pTransportName->Length +
sizeof(UNICODE_NULL);
Status = MemoryAllocate( pTransportName->MaximumLength,
&pTransportName->Buffer );
if ( !NT_SUCCESS( Status ) )
break;
wcscpy( pTransportName->Buffer, currentProviderName );
Status = STATUS_SUCCESS;
break;
}
}
MemoryFree( pLanaMapInfo );
MemoryFree( pProviderNameInfo );
ZwClose( netbiosKey );
return( Status );
/*=============================================================================
== Error returns
=============================================================================*/
error_exit:
if ( netbiosKey != NULL ) {
ZwClose( netbiosKey );
}
if ( pProviderNameInfo != NULL ) {
MemoryFree( pProviderNameInfo );
}
if ( pLanaMapInfo != NULL ) {
MemoryFree( pLanaMapInfo );
}
return( Status );
}
/*******************************************************************************
*
* _GetComputerName
*
* Read computer name from the registry
*
* ENTRY:
* pTd (input)
* Pointer to td data structure
* pComputerName (output)
* pointer to UNICODE_STRING to return computer name
* NOTE: the buffer pointed to be pComputerName->Buffer must
* be free'd by the caller
*
* EXIT:
* STATUS_SUCCESS - no error
*
******************************************************************************/
NTSTATUS
_GetComputerName(
PTD pTd,
PUNICODE_STRING pComputerName
)
{
UNICODE_STRING nameString;
OBJECT_ATTRIBUTES objectAttributes;
HANDLE hKey;
WCHAR ComputerNameBuffer[256];
PKEY_VALUE_PARTIAL_INFORMATION pComputerNameInfo;
ULONG returnLength;
NTSTATUS Status;
/*
* Try to open the ActiveComputerName key.
* If this fails, attempt to open the static key.
*/
RtlInitUnicodeString( &nameString, VOLATILE_COMPUTERNAME );
InitializeObjectAttributes( &objectAttributes,
&nameString,
OBJ_CASE_INSENSITIVE,
NULL,
NULL
);
Status = ZwOpenKey( &hKey, KEY_READ, &objectAttributes );
if ( !NT_SUCCESS( Status ) ) {
RtlInitUnicodeString( &nameString, NON_VOLATILE_COMPUTERNAME );
InitializeObjectAttributes( &objectAttributes,
&nameString,
OBJ_CASE_INSENSITIVE,
NULL,
NULL
);
Status = ZwOpenKey( &hKey, KEY_READ, &objectAttributes );
}
if ( !NT_SUCCESS( Status ) )
return( Status );
/*
* Now get the ComputerName value
*/
RtlInitUnicodeString( &nameString, COMPUTERNAME_VALUE );
Status = ZwQueryValueKey( hKey,
&nameString,
KeyValuePartialInformation,
ComputerNameBuffer,
sizeof(ComputerNameBuffer),
&returnLength
);
ZwClose( hKey );
if ( !NT_SUCCESS( Status ) )
return( Status );
/*
* Allocate a buffer to return the ComputerName string,
* initialize the return unicode string, and copy the computer name.
*/
pComputerNameInfo = (PKEY_VALUE_PARTIAL_INFORMATION)ComputerNameBuffer;
Status = MemoryAllocate( pComputerNameInfo->DataLength,
&pComputerName->Buffer );
if ( !NT_SUCCESS( Status ) )
return( Status );
RtlCopyMemory( pComputerName->Buffer, pComputerNameInfo->Data,
pComputerNameInfo->DataLength );
pComputerName->Length =
pComputerName->MaximumLength =
(USHORT)(pComputerNameInfo->DataLength - sizeof(UNICODE_NULL));
return( STATUS_SUCCESS );
}