1099 lines
25 KiB
C
1099 lines
25 KiB
C
/*++
|
||
|
||
Copyright (c) 1991 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
Registry.c
|
||
|
||
Abstract:
|
||
|
||
This contains all routines necessary to load the lana number to device pathname
|
||
mapping and the Lana Enum record.
|
||
|
||
Author:
|
||
|
||
Colin Watson (colinw) 14-Mar-1992
|
||
|
||
Revision History:
|
||
|
||
|
||
Notes:
|
||
The fcb holds an area for registry workspace. this is where the strings
|
||
used to hold the DriverNames will be held in a single allocation.
|
||
|
||
build with -DUTILITY to run as a test application.
|
||
--*/
|
||
|
||
#include "Nb.h"
|
||
//#include <zwapi.h>
|
||
//#include <stdlib.h>
|
||
#include <crt\stdlib.h>
|
||
|
||
|
||
#define DEFAULT_VALUE_SIZE 4096
|
||
|
||
#define ROUNDUP_TO_LONG(x) (((x) + sizeof(PVOID) - 1) & ~(sizeof(PVOID) - 1))
|
||
|
||
#ifdef UTILITY
|
||
#define ZwClose NtClose
|
||
#define ZwCreateKey NtCreateKey
|
||
#define ZwOpenKey NtOpenKey
|
||
#define ZwQueryValueKey NtQueryValueKey
|
||
#define ExFreePool free
|
||
#endif
|
||
|
||
//
|
||
// Local functions used to access the registry.
|
||
//
|
||
|
||
NTSTATUS
|
||
NbOpenRegistry(
|
||
IN PUNICODE_STRING BaseName,
|
||
OUT PHANDLE LinkageHandle,
|
||
OUT PHANDLE ParametersHandle
|
||
);
|
||
|
||
VOID
|
||
NbCloseRegistry(
|
||
IN HANDLE LinkageHandle,
|
||
IN HANDLE ParametersHandle
|
||
);
|
||
|
||
NTSTATUS
|
||
NbReadLinkageInformation(
|
||
IN HANDLE LinkageHandle,
|
||
IN HANDLE ParametersHandle,
|
||
IN PFCB pfcb,
|
||
IN BOOL bDeviceCreate
|
||
);
|
||
|
||
ULONG
|
||
NbReadSingleParameter(
|
||
IN HANDLE ParametersHandle,
|
||
IN PWCHAR ValueName,
|
||
IN LONG DefaultValue
|
||
);
|
||
|
||
BOOLEAN
|
||
NbCheckLana (
|
||
PUNICODE_STRING DeviceName
|
||
);
|
||
|
||
|
||
//
|
||
// Local function used to determine is specified device is Pnp enabled
|
||
//
|
||
|
||
#ifdef ALLOC_PRAGMA
|
||
#pragma alloc_text(PAGE, GetIrpStackSize)
|
||
#pragma alloc_text(PAGE, ReadRegistry)
|
||
#pragma alloc_text(PAGE, NbFreeRegistryInfo)
|
||
#pragma alloc_text(PAGE, NbOpenRegistry)
|
||
#pragma alloc_text(PAGE, NbCloseRegistry)
|
||
#pragma alloc_text(PAGE, NbReadLinkageInformation)
|
||
#pragma alloc_text(PAGE, NbReadSingleParameter)
|
||
#pragma alloc_text(PAGE, NbCheckLana)
|
||
#endif
|
||
|
||
CCHAR
|
||
GetIrpStackSize(
|
||
IN PUNICODE_STRING RegistryPath,
|
||
IN CCHAR DefaultValue
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine is called by NbCreateDeviceContext to get the IRP
|
||
stack size to be "exported" by the NetBIOS device.
|
||
|
||
Arguments:
|
||
|
||
RegistryPath - The name of Nb's node in the registry.
|
||
DefaultValue - IRP stack size to be used if no registry value present.
|
||
|
||
Return Value:
|
||
|
||
CCHAR - IRP stack size to be stored in the device object.
|
||
|
||
--*/
|
||
{
|
||
HANDLE LinkageHandle;
|
||
HANDLE ParametersHandle;
|
||
NTSTATUS Status;
|
||
ULONG stackSize;
|
||
|
||
PAGED_CODE();
|
||
|
||
Status = NbOpenRegistry (RegistryPath, &LinkageHandle, &ParametersHandle);
|
||
|
||
if (Status != STATUS_SUCCESS) {
|
||
return DefaultValue;
|
||
}
|
||
|
||
//
|
||
// Read the stack size value from the registry.
|
||
//
|
||
|
||
stackSize = NbReadSingleParameter(
|
||
ParametersHandle,
|
||
REGISTRY_IRP_STACK_SIZE,
|
||
DefaultValue );
|
||
|
||
if ( stackSize > 255 ) {
|
||
stackSize = 255;
|
||
}
|
||
|
||
NbCloseRegistry (LinkageHandle, ParametersHandle);
|
||
|
||
return (CCHAR)stackSize;
|
||
|
||
}
|
||
|
||
NTSTATUS
|
||
ReadRegistry(
|
||
IN PUNICODE_STRING pusRegistryPath,
|
||
IN PFCB NewFcb,
|
||
IN BOOLEAN bDeviceCreate
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine is called by Nb to get information from the registry,
|
||
starting at RegistryPath to get the parameters.
|
||
|
||
Arguments:
|
||
|
||
DeviceContext - Supplies RegistryPath. The name of Nb's node in the registry.
|
||
NewFcb - Destination for the configuration information.
|
||
|
||
Return Value:
|
||
|
||
NTSTATUS - STATUS_SUCCESS if everything OK, STATUS_INSUFFICIENT_RESOURCES
|
||
otherwise.
|
||
|
||
--*/
|
||
{
|
||
HANDLE LinkageHandle;
|
||
HANDLE ParametersHandle;
|
||
NTSTATUS Status;
|
||
|
||
PAGED_CODE();
|
||
|
||
NewFcb->RegistrySpace = NULL; // No registry workspace.
|
||
NewFcb->LanaEnum.length = 0;
|
||
|
||
|
||
Status = NbOpenRegistry ( pusRegistryPath, &LinkageHandle, &ParametersHandle);
|
||
|
||
if (Status != STATUS_SUCCESS) {
|
||
return STATUS_UNSUCCESSFUL;
|
||
}
|
||
|
||
|
||
//
|
||
// Read in the NDIS binding information (if none is present
|
||
// the array will be filled with all known drivers).
|
||
//
|
||
|
||
Status = NbReadLinkageInformation (
|
||
LinkageHandle,
|
||
ParametersHandle,
|
||
NewFcb,
|
||
bDeviceCreate);
|
||
|
||
NbCloseRegistry (LinkageHandle, ParametersHandle);
|
||
|
||
return Status;
|
||
|
||
}
|
||
|
||
|
||
//----------------------------------------------------------------------------
|
||
// GetLanaMap
|
||
//
|
||
// retrieves the lana map structure.
|
||
// Allocates the memory required for the lana map structure that must be
|
||
// deallocated after use.
|
||
//----------------------------------------------------------------------------
|
||
|
||
NTSTATUS
|
||
GetLanaMap(
|
||
IN PUNICODE_STRING pusRegistryPath,
|
||
IN OUT PKEY_VALUE_FULL_INFORMATION * ppkvfi
|
||
)
|
||
{
|
||
HANDLE hLinkage = NULL;
|
||
HANDLE hParameters = NULL;
|
||
NTSTATUS nsStatus;
|
||
|
||
PKEY_VALUE_FULL_INFORMATION pkvfiValue = NULL;
|
||
ULONG ulValueSize;
|
||
|
||
PWSTR wsLanaMapName = REGISTRY_LANA_MAP;
|
||
UNICODE_STRING usLanaMap;
|
||
|
||
ULONG ulBytesWritten;
|
||
|
||
|
||
|
||
PAGED_CODE();
|
||
|
||
|
||
do
|
||
{
|
||
*ppkvfi = NULL;
|
||
|
||
|
||
//
|
||
// open registry keys
|
||
//
|
||
|
||
nsStatus = NbOpenRegistry ( pusRegistryPath, &hLinkage, &hParameters );
|
||
|
||
if ( !NT_SUCCESS( nsStatus ) )
|
||
{
|
||
break;
|
||
}
|
||
|
||
|
||
//
|
||
// allocate for lana map.
|
||
//
|
||
|
||
pkvfiValue = ExAllocatePoolWithTag(
|
||
PagedPool, MAXIMUM_LANA * sizeof( LANA_MAP ), 'rSBN'
|
||
);
|
||
|
||
if ( pkvfiValue == NULL )
|
||
{
|
||
nsStatus = STATUS_UNSUCCESSFUL;
|
||
NbPrint( (
|
||
"GetLanaMap : Allocation failed for %d bytes\n", DEFAULT_VALUE_SIZE
|
||
) );
|
||
break;
|
||
}
|
||
|
||
ulValueSize = MAXIMUM_LANA * sizeof( LANA_MAP );
|
||
|
||
|
||
//
|
||
// query "LanaMap" value
|
||
//
|
||
|
||
RtlInitUnicodeString (&usLanaMap, wsLanaMapName);
|
||
|
||
nsStatus = ZwQueryValueKey(
|
||
hLinkage,
|
||
&usLanaMap,
|
||
KeyValueFullInformation,
|
||
pkvfiValue,
|
||
ulValueSize,
|
||
&ulBytesWritten
|
||
);
|
||
|
||
if (!NT_SUCCESS(nsStatus))
|
||
{
|
||
NbPrint ( (
|
||
"GetLanaMap : failed querying lana map key %x", nsStatus
|
||
) );
|
||
break;
|
||
}
|
||
|
||
if ( ulBytesWritten == 0 )
|
||
{
|
||
nsStatus = STATUS_UNSUCCESSFUL;
|
||
NbPrint ( ("GetLanaMap : querying lana map key returned 0 bytes") );
|
||
break;
|
||
}
|
||
|
||
|
||
*ppkvfi = pkvfiValue;
|
||
|
||
NbCloseRegistry (hLinkage, hParameters);
|
||
|
||
return nsStatus;
|
||
|
||
} while (FALSE);
|
||
|
||
|
||
if ( pkvfiValue != NULL )
|
||
{
|
||
ExFreePool( pkvfiValue );
|
||
}
|
||
|
||
NbCloseRegistry (hLinkage, hParameters);
|
||
|
||
return nsStatus;
|
||
}
|
||
|
||
//----------------------------------------------------------------------------
|
||
// GetMaxLana
|
||
//
|
||
// retrieves the MaxLana value from the netbios parameters key.
|
||
//----------------------------------------------------------------------------
|
||
|
||
NTSTATUS
|
||
GetMaxLana(
|
||
IN PUNICODE_STRING pusRegistryPath,
|
||
IN OUT PULONG pulMaxLana
|
||
)
|
||
{
|
||
HANDLE hLinkage = NULL;
|
||
HANDLE hParameters = NULL;
|
||
NTSTATUS nsStatus;
|
||
|
||
UCHAR ucBuffer[ 256 ];
|
||
PKEY_VALUE_FULL_INFORMATION pkvfiValue =
|
||
(PKEY_VALUE_FULL_INFORMATION) ucBuffer;
|
||
ULONG ulValueSize;
|
||
|
||
|
||
PWSTR wsMaxLana = REGISTRY_MAX_LANA;
|
||
UNICODE_STRING usMaxLana;
|
||
|
||
ULONG ulBytesWritten;
|
||
|
||
|
||
|
||
PAGED_CODE();
|
||
|
||
do
|
||
{
|
||
*pulMaxLana = 0;
|
||
|
||
|
||
//
|
||
// open registry keys
|
||
//
|
||
|
||
nsStatus = NbOpenRegistry ( pusRegistryPath, &hLinkage, &hParameters );
|
||
|
||
if ( !NT_SUCCESS( nsStatus ) )
|
||
{
|
||
NbPrint( ("GetMaxLana : Failed to open registry" ) );
|
||
nsStatus = STATUS_UNSUCCESSFUL;
|
||
break;
|
||
}
|
||
|
||
|
||
//
|
||
// allocate for key value.
|
||
//
|
||
|
||
ulValueSize = sizeof( ucBuffer );
|
||
|
||
|
||
//
|
||
// query "MaxLana" value
|
||
//
|
||
|
||
RtlInitUnicodeString (&usMaxLana, wsMaxLana);
|
||
|
||
nsStatus = ZwQueryValueKey(
|
||
hParameters,
|
||
&usMaxLana,
|
||
KeyValueFullInformation,
|
||
pkvfiValue,
|
||
ulValueSize,
|
||
&ulBytesWritten
|
||
);
|
||
|
||
if (!NT_SUCCESS(nsStatus))
|
||
{
|
||
NbPrint ( (
|
||
"GetMaxLana : failed querying lana map key %x", nsStatus
|
||
) );
|
||
break;
|
||
}
|
||
|
||
if ( ulBytesWritten == 0 )
|
||
{
|
||
NbPrint ( ("GetMaxLana : querying lana map key returned 0 bytes") );
|
||
nsStatus = STATUS_UNSUCCESSFUL;
|
||
break;
|
||
}
|
||
|
||
*pulMaxLana = *( (PULONG) ( (PUCHAR) pkvfiValue + pkvfiValue-> DataOffset ) );
|
||
|
||
NbCloseRegistry (hLinkage, hParameters);
|
||
|
||
return nsStatus;
|
||
|
||
} while ( FALSE );
|
||
|
||
|
||
NbCloseRegistry (hLinkage, hParameters);
|
||
|
||
return nsStatus;
|
||
}
|
||
|
||
|
||
|
||
VOID
|
||
NbFreeRegistryInfo (
|
||
IN PFCB pfcb
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine is called by Nb to get free any storage that was allocated
|
||
by NbConfigureTransport in producing the specified CONFIG_DATA structure.
|
||
|
||
Arguments:
|
||
|
||
ConfigurationInfo - A pointer to the configuration information structure.
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
{
|
||
PAGED_CODE();
|
||
|
||
if ( pfcb->RegistrySpace != NULL ) {
|
||
ExFreePool( pfcb->RegistrySpace );
|
||
pfcb->RegistrySpace = NULL;
|
||
}
|
||
|
||
}
|
||
|
||
NTSTATUS
|
||
NbOpenRegistry(
|
||
IN PUNICODE_STRING BaseName,
|
||
OUT PHANDLE LinkageHandle,
|
||
OUT PHANDLE ParametersHandle
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine is called by Nb to open the registry. If the registry
|
||
tree exists, then it opens it and returns an error. If not, it
|
||
creates the appropriate keys in the registry, opens it, and
|
||
returns STATUS_SUCCESS.
|
||
|
||
NOTE: If the key "ClearRegistry" exists in ntuser.cfg, then
|
||
this routine will remove any existing registry values for Nb
|
||
(but still create the tree if it doesn't exist) and return
|
||
FALSE.
|
||
|
||
Arguments:
|
||
|
||
BaseName - Where in the registry to start looking for the information.
|
||
|
||
LinkageHandle - Returns the handle used to read linkage information.
|
||
|
||
ParametersHandle - Returns the handle used to read other
|
||
parameters.
|
||
|
||
Return Value:
|
||
|
||
The status of the request.
|
||
|
||
--*/
|
||
{
|
||
|
||
HANDLE NbConfigHandle;
|
||
NTSTATUS Status;
|
||
HANDLE LinkHandle;
|
||
HANDLE ParamHandle;
|
||
PWSTR LinkageString = REGISTRY_LINKAGE;
|
||
PWSTR ParametersString = REGISTRY_PARAMETERS;
|
||
UNICODE_STRING LinkageKeyName;
|
||
UNICODE_STRING ParametersKeyName;
|
||
OBJECT_ATTRIBUTES TmpObjectAttributes;
|
||
ULONG Disposition;
|
||
|
||
PAGED_CODE();
|
||
|
||
//
|
||
// Open the registry for the initial string.
|
||
//
|
||
|
||
InitializeObjectAttributes(
|
||
&TmpObjectAttributes,
|
||
BaseName, // name
|
||
OBJ_CASE_INSENSITIVE, // attributes
|
||
NULL, // root
|
||
NULL // security descriptor
|
||
);
|
||
|
||
Status = ZwCreateKey(
|
||
&NbConfigHandle,
|
||
KEY_WRITE,
|
||
&TmpObjectAttributes,
|
||
0, // title index
|
||
NULL, // class
|
||
0, // create options
|
||
&Disposition); // disposition
|
||
|
||
if (!NT_SUCCESS(Status)) {
|
||
return STATUS_UNSUCCESSFUL;
|
||
}
|
||
|
||
//
|
||
// Open the Nb linkages key.
|
||
//
|
||
|
||
RtlInitUnicodeString (&LinkageKeyName, LinkageString);
|
||
|
||
InitializeObjectAttributes(
|
||
&TmpObjectAttributes,
|
||
&LinkageKeyName, // name
|
||
OBJ_CASE_INSENSITIVE, // attributes
|
||
NbConfigHandle, // root
|
||
NULL // security descriptor
|
||
);
|
||
|
||
Status = ZwOpenKey(
|
||
&LinkHandle,
|
||
KEY_READ,
|
||
&TmpObjectAttributes);
|
||
|
||
if (!NT_SUCCESS(Status)) {
|
||
|
||
ZwClose (NbConfigHandle);
|
||
return Status;
|
||
}
|
||
|
||
|
||
//
|
||
// Now open the parameters key.
|
||
//
|
||
|
||
RtlInitUnicodeString (&ParametersKeyName, ParametersString);
|
||
|
||
InitializeObjectAttributes(
|
||
&TmpObjectAttributes,
|
||
&ParametersKeyName, // name
|
||
OBJ_CASE_INSENSITIVE, // attributes
|
||
NbConfigHandle, // root
|
||
NULL // security descriptor
|
||
);
|
||
|
||
Status = ZwOpenKey(
|
||
&ParamHandle,
|
||
KEY_READ,
|
||
&TmpObjectAttributes);
|
||
if (!NT_SUCCESS(Status)) {
|
||
|
||
ZwClose (LinkHandle);
|
||
ZwClose (NbConfigHandle);
|
||
return Status;
|
||
}
|
||
|
||
*LinkageHandle = LinkHandle;
|
||
*ParametersHandle = ParamHandle;
|
||
|
||
|
||
//
|
||
// All keys successfully opened or created.
|
||
//
|
||
|
||
ZwClose (NbConfigHandle);
|
||
return STATUS_SUCCESS;
|
||
|
||
} /* NbOpenRegistry */
|
||
|
||
VOID
|
||
NbCloseRegistry(
|
||
IN HANDLE LinkageHandle,
|
||
IN HANDLE ParametersHandle
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine is called by Nb to close the registry. It closes
|
||
the handles passed in and does any other work needed.
|
||
|
||
Arguments:
|
||
|
||
LinkageHandle - The handle used to read linkage information.
|
||
|
||
ParametersHandle - The handle used to read other parameters.
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
|
||
{
|
||
PAGED_CODE();
|
||
|
||
ZwClose (LinkageHandle);
|
||
ZwClose (ParametersHandle);
|
||
|
||
} /* NbCloseRegistry */
|
||
|
||
NTSTATUS
|
||
NbReadLinkageInformation(
|
||
IN HANDLE LinkageHandle,
|
||
IN HANDLE ParametersHandle,
|
||
IN PFCB pfcb,
|
||
IN BOOL bCreateDevice
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine is called by Nb to read its linkage information
|
||
from the registry. If there is none present, then ConfigData
|
||
is filled with a list of all the adapters that are known
|
||
to Nb.
|
||
|
||
Arguments:
|
||
|
||
LinkageHandle - Supplies the Linkage key in netbios
|
||
ParametersHandle
|
||
|
||
pfcb - Describes Nb's current configuration.
|
||
|
||
Return Value:
|
||
|
||
Status
|
||
|
||
--*/
|
||
|
||
{
|
||
PWSTR BindName = REGISTRY_BIND;
|
||
UNICODE_STRING BindString;
|
||
NTSTATUS Status;
|
||
|
||
PKEY_VALUE_FULL_INFORMATION Value = NULL;
|
||
ULONG ValueSize;
|
||
|
||
PWSTR LanaMapName = REGISTRY_LANA_MAP;
|
||
UNICODE_STRING LanaMapString;
|
||
PLANA_MAP pLanaMap;
|
||
|
||
ULONG BytesWritten;
|
||
UINT ConfigBindings = 0;
|
||
PWSTR CurBindValue;
|
||
UINT index;
|
||
|
||
PAGED_CODE();
|
||
|
||
pfcb->MaxLana = NbReadSingleParameter( ParametersHandle, REGISTRY_MAX_LANA, -1 );
|
||
|
||
if (pfcb->MaxLana > MAXIMUM_LANA) {
|
||
return STATUS_INVALID_PARAMETER;
|
||
}
|
||
|
||
NbPrint( (
|
||
"Netbios : NbReadLinkageInformation : MaxLana = %d\n",
|
||
pfcb-> MaxLana
|
||
) );
|
||
|
||
//
|
||
// Read the "Bind" key.
|
||
//
|
||
|
||
RtlInitUnicodeString (&BindString, BindName);
|
||
|
||
#ifdef UTILITY
|
||
Value = malloc( DEFAULT_VALUE_SIZE);
|
||
#else
|
||
Value = ExAllocatePoolWithTag(PagedPool, DEFAULT_VALUE_SIZE, 'rSBN');
|
||
#endif
|
||
|
||
if ( Value == NULL ) {
|
||
return STATUS_INSUFFICIENT_RESOURCES;
|
||
}
|
||
ValueSize = DEFAULT_VALUE_SIZE;
|
||
|
||
pfcb->RegistrySpace = NULL;
|
||
|
||
try {
|
||
|
||
Status = ZwQueryValueKey(
|
||
LinkageHandle,
|
||
&BindString,
|
||
KeyValueFullInformation,
|
||
Value,
|
||
ValueSize,
|
||
&BytesWritten
|
||
);
|
||
|
||
if ( Status == STATUS_BUFFER_OVERFLOW) {
|
||
|
||
ExFreePool( Value );
|
||
|
||
// Now request with exactly the right size
|
||
ValueSize = BytesWritten;
|
||
|
||
#ifdef UTILITY
|
||
Value = malloc( ValueSize);
|
||
#else
|
||
Value = ExAllocatePoolWithTag(PagedPool, ValueSize, 'rSBN');
|
||
#endif
|
||
|
||
if ( Value == NULL ) {
|
||
try_return( Status = STATUS_INSUFFICIENT_RESOURCES);
|
||
}
|
||
|
||
Status = ZwQueryValueKey(
|
||
LinkageHandle,
|
||
&BindString,
|
||
KeyValueFullInformation,
|
||
Value,
|
||
ValueSize,
|
||
&BytesWritten
|
||
);
|
||
}
|
||
|
||
if (!NT_SUCCESS(Status)) {
|
||
try_return( Status );
|
||
}
|
||
|
||
if ( BytesWritten == 0 ) {
|
||
try_return( Status = STATUS_ILL_FORMED_SERVICE_ENTRY);
|
||
}
|
||
|
||
|
||
//
|
||
// Alloc space for Registry stuff as well as pDriverName array.
|
||
//
|
||
#ifdef UTILITY
|
||
pfcb->RegistrySpace = malloc(ROUNDUP_TO_LONG(BytesWritten - Value->DataOffset) +
|
||
(sizeof(UNICODE_STRING) * (pfcb->MaxLana+1)));
|
||
#else
|
||
pfcb->RegistrySpace = ExAllocatePoolWithTag(PagedPool,
|
||
ROUNDUP_TO_LONG(BytesWritten - Value->DataOffset) +
|
||
(sizeof(UNICODE_STRING) * (pfcb->MaxLana+1)), 'rSBN');
|
||
#endif
|
||
|
||
if ( pfcb->RegistrySpace == NULL ) {
|
||
try_return( Status = STATUS_INSUFFICIENT_RESOURCES);
|
||
}
|
||
|
||
RtlMoveMemory(pfcb->RegistrySpace,
|
||
(PUCHAR)Value + Value->DataOffset,
|
||
BytesWritten - Value->DataOffset);
|
||
|
||
pfcb->pDriverName =
|
||
(PUNICODE_STRING) ((PBYTE) pfcb->RegistrySpace +
|
||
ROUNDUP_TO_LONG(BytesWritten-Value->DataOffset));
|
||
|
||
//
|
||
// Read the "LanaMap" key into Storage.
|
||
//
|
||
|
||
RtlInitUnicodeString (&LanaMapString, LanaMapName);
|
||
|
||
Status = ZwQueryValueKey(
|
||
LinkageHandle,
|
||
&LanaMapString,
|
||
KeyValueFullInformation,
|
||
Value,
|
||
ValueSize,
|
||
&BytesWritten
|
||
);
|
||
|
||
if (!NT_SUCCESS(Status)) {
|
||
try_return( Status );
|
||
}
|
||
|
||
if ( BytesWritten == 0 ) {
|
||
try_return( Status = STATUS_ILL_FORMED_SERVICE_ENTRY);
|
||
}
|
||
|
||
// Point pLanaMap at the data from the registry.
|
||
pLanaMap = (PLANA_MAP)((PUCHAR)Value + Value->DataOffset);
|
||
|
||
//
|
||
// For each binding, initialize the drivername string.
|
||
//
|
||
|
||
for ( index = 0 ; index <= pfcb->MaxLana ; index++ ) {
|
||
// Initialize unused drivernames to NULL name
|
||
RtlInitUnicodeString (&pfcb->pDriverName[index], NULL);
|
||
}
|
||
|
||
CurBindValue = (PWCHAR)pfcb->RegistrySpace;
|
||
|
||
|
||
IF_NBDBG( NB_DEBUG_FILE )
|
||
{
|
||
NbPrint( ("NETBIOS: Enumerating lanas ...\n") );
|
||
}
|
||
|
||
while (*CurBindValue != 0) {
|
||
|
||
if ((ConfigBindings > pfcb->MaxLana) ||
|
||
(pLanaMap[ConfigBindings].Lana > pfcb->MaxLana)) {
|
||
try_return( Status = STATUS_INVALID_PARAMETER);
|
||
}
|
||
|
||
RtlInitUnicodeString (
|
||
&pfcb->pDriverName[pLanaMap[ConfigBindings].Lana],
|
||
CurBindValue);
|
||
|
||
//
|
||
// Only non PNP devices are created here. PnP devices
|
||
// are created as required in the bind handler in file.c
|
||
//
|
||
// V Raman
|
||
//
|
||
|
||
if ( bCreateDevice &&
|
||
pLanaMap[ConfigBindings].Enum != FALSE ) {
|
||
|
||
if (NbCheckLana (
|
||
&pfcb->pDriverName[pLanaMap[ConfigBindings].Lana]))
|
||
{
|
||
//
|
||
// Record that the lana number is enabled
|
||
//
|
||
|
||
pfcb->LanaEnum.lana[pfcb->LanaEnum.length] =
|
||
pLanaMap[ConfigBindings].Lana;
|
||
pfcb->LanaEnum.length++;
|
||
|
||
IF_NBDBG( NB_DEBUG_FILE )
|
||
{
|
||
NbPrint( ("NETBIOS: Lana %d (%ls) added OK.\n",
|
||
pLanaMap[ConfigBindings].Lana, CurBindValue) );
|
||
}
|
||
}
|
||
|
||
else
|
||
{
|
||
IF_NBDBG( NB_DEBUG_FILE )
|
||
{
|
||
NbPrint( ("NETBIOS: Lana's %d %ls could not be opened.\n",
|
||
pLanaMap[ConfigBindings].Lana, CurBindValue) );
|
||
}
|
||
}
|
||
}
|
||
|
||
else
|
||
{
|
||
IF_NBDBG( NB_DEBUG_FILE )
|
||
{
|
||
NbPrint( ("NbReadLinkageInformation : Lana %d (%ls) is not enumerated.\n",
|
||
pLanaMap[ConfigBindings].Lana, CurBindValue) );
|
||
}
|
||
}
|
||
|
||
++ConfigBindings;
|
||
|
||
//
|
||
// Now advance the "Bind" value.
|
||
//
|
||
|
||
CurBindValue += wcslen(CurBindValue) + 1;
|
||
|
||
}
|
||
|
||
try_return( Status = STATUS_SUCCESS);
|
||
|
||
try_exit:NOTHING;
|
||
} finally {
|
||
|
||
if ( !NT_SUCCESS(Status) ) {
|
||
ExFreePool( pfcb->RegistrySpace );
|
||
pfcb->RegistrySpace = NULL;
|
||
}
|
||
|
||
if ( Value != NULL ) {
|
||
ExFreePool( Value );
|
||
}
|
||
}
|
||
|
||
return Status;
|
||
|
||
} /* NbReadLinkageInformation */
|
||
|
||
ULONG
|
||
NbReadSingleParameter(
|
||
IN HANDLE ParametersHandle,
|
||
IN PWCHAR ValueName,
|
||
IN LONG DefaultValue
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine is called by Nb to read a single parameter
|
||
from the registry. If the parameter is found it is stored
|
||
in Data.
|
||
|
||
Arguments:
|
||
|
||
ParametersHandle - A pointer to the open registry.
|
||
|
||
ValueName - The name of the value to search for.
|
||
|
||
DefaultValue - The default value.
|
||
|
||
Return Value:
|
||
|
||
The value to use; will be the default if the value is not
|
||
found or is not in the correct range.
|
||
|
||
--*/
|
||
|
||
{
|
||
ULONG InformationBuffer[16]; // declare ULONG to get it aligned
|
||
PKEY_VALUE_FULL_INFORMATION Information =
|
||
(PKEY_VALUE_FULL_INFORMATION)InformationBuffer;
|
||
UNICODE_STRING ValueKeyName;
|
||
ULONG InformationLength;
|
||
LONG ReturnValue;
|
||
NTSTATUS Status;
|
||
|
||
PAGED_CODE();
|
||
|
||
RtlInitUnicodeString (&ValueKeyName, ValueName);
|
||
|
||
Status = ZwQueryValueKey(
|
||
ParametersHandle,
|
||
&ValueKeyName,
|
||
KeyValueFullInformation,
|
||
(PVOID)Information,
|
||
sizeof (InformationBuffer),
|
||
&InformationLength);
|
||
|
||
if ((Status == STATUS_SUCCESS) && (Information->DataLength == sizeof(ULONG))) {
|
||
|
||
RtlMoveMemory(
|
||
(PVOID)&ReturnValue,
|
||
((PUCHAR)Information) + Information->DataOffset,
|
||
sizeof(ULONG));
|
||
|
||
if (ReturnValue < 0) {
|
||
|
||
ReturnValue = DefaultValue;
|
||
|
||
}
|
||
|
||
} else {
|
||
|
||
ReturnValue = DefaultValue;
|
||
|
||
}
|
||
|
||
return ReturnValue;
|
||
|
||
} /* NbReadSingleParameter */
|
||
|
||
|
||
BOOLEAN
|
||
NbCheckLana (
|
||
PUNICODE_STRING DeviceName
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine uses the transport to create an entry in the NetBIOS
|
||
table with the value of "Name". It will re-use an existing entry if
|
||
"Name" already exists.
|
||
|
||
Note: This synchronous call may take a number of seconds. If this matters
|
||
then the caller should specify ASYNCH and a post routine so that it is
|
||
performed by the thread created by the netbios dll routines.
|
||
|
||
If pdncb == NULL then a special handle is returned that is capable of
|
||
administering the transport. For example to execute an ASTAT.
|
||
|
||
Arguments:
|
||
|
||
FileHandle - Pointer to where the filehandle is to be returned.
|
||
|
||
*Object - Pointer to where the file object pointer is to be stored
|
||
|
||
pfcb - supplies the device names for the lana number.
|
||
|
||
LanNumber - supplies the network adapter to be opened.
|
||
|
||
pdncb - Pointer to either an NCB or NULL.
|
||
|
||
Return Value:
|
||
|
||
The function value is the status of the operation.
|
||
|
||
--*/
|
||
{
|
||
IO_STATUS_BLOCK IoStatusBlock;
|
||
NTSTATUS Status;
|
||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||
HANDLE FileHandle;
|
||
|
||
PAGED_CODE();
|
||
|
||
InitializeObjectAttributes (
|
||
&ObjectAttributes,
|
||
DeviceName,
|
||
0,
|
||
NULL,
|
||
NULL);
|
||
|
||
Status = ZwCreateFile (
|
||
&FileHandle,
|
||
GENERIC_READ | GENERIC_WRITE, // desired access.
|
||
&ObjectAttributes, // object attributes.
|
||
&IoStatusBlock, // returned status information.
|
||
NULL, // Allocation size (unused).
|
||
FILE_ATTRIBUTE_NORMAL, // file attributes.
|
||
FILE_SHARE_WRITE,
|
||
FILE_CREATE,
|
||
0, // create options.
|
||
NULL,
|
||
0
|
||
);
|
||
|
||
|
||
if ( NT_SUCCESS( Status )) {
|
||
Status = IoStatusBlock.Status;
|
||
}
|
||
|
||
if (NT_SUCCESS( Status )) {
|
||
NTSTATUS localstatus;
|
||
|
||
localstatus = ZwClose( FileHandle);
|
||
|
||
ASSERT(NT_SUCCESS(localstatus));
|
||
return TRUE;
|
||
}
|
||
else {
|
||
|
||
NbPrint( (
|
||
"NbCheckLana : Create file failed for %s with code %x iostatus %x\n",
|
||
DeviceName-> Buffer, Status, IoStatusBlock.Status
|
||
) );
|
||
return FALSE;
|
||
}
|
||
}
|
||
|
||
|
||
#ifdef UTILITY
|
||
void
|
||
_cdecl
|
||
main (argc, argv)
|
||
int argc;
|
||
char *argv[];
|
||
{
|
||
DEVICE_CONTEXT DeviceContext;
|
||
FCB NewFcb;
|
||
RtlInitUnicodeString(&DeviceContext.RegistryPath, L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\Netbios");
|
||
ReadRegistry(
|
||
&DeviceContext,
|
||
&NewFcb
|
||
);
|
||
|
||
}
|
||
#endif
|