835 lines
19 KiB
C++
835 lines
19 KiB
C++
|
/*++
|
|||
|
|
|||
|
Copyright (C) Microsoft Corporation, 1992 - 1999
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
cbind.cxx
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
This is the client side NSI service support layer. These functions
|
|||
|
provide for binding to the locator or other name server.
|
|||
|
|
|||
|
Author:
|
|||
|
|
|||
|
Steven Zeck (stevez) 03/04/92
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
#include <nsi.h>
|
|||
|
|
|||
|
#ifndef NTENV
|
|||
|
|
|||
|
#include <netcons.h>
|
|||
|
#include <neterr.h>
|
|||
|
#include <server.h>
|
|||
|
#include <access.h>
|
|||
|
#include <regapi.h>
|
|||
|
#include <mailslot.h>
|
|||
|
#include <wksta.h>
|
|||
|
|
|||
|
#ifndef USHORT
|
|||
|
#define USHORT unsigned short
|
|||
|
#endif
|
|||
|
|
|||
|
#else
|
|||
|
|
|||
|
#include <lmcons.h>
|
|||
|
#include <lmapibuf.h>
|
|||
|
#include <lmaccess.h>
|
|||
|
#include <lmserver.h>
|
|||
|
#include <stdlib.h>
|
|||
|
#include "startsvc.h"
|
|||
|
#endif
|
|||
|
|
|||
|
#include <string.h>
|
|||
|
|
|||
|
#ifndef NTENV
|
|||
|
#include "locquery.h"
|
|||
|
#endif
|
|||
|
|
|||
|
extern "C"
|
|||
|
{
|
|||
|
unsigned long RPC_ENTRY
|
|||
|
I_GetDefaultEntrySyntax(
|
|||
|
);
|
|||
|
}
|
|||
|
|
|||
|
void RpcNsLmDiscard(void);
|
|||
|
|
|||
|
#ifndef NTENV
|
|||
|
unsigned short BroadcastAQuery(unsigned long Query,
|
|||
|
char __RPC_FAR * Buffer,
|
|||
|
unsigned short Count);
|
|||
|
|
|||
|
#define MAXLOCATORSTOTRY 8
|
|||
|
#endif
|
|||
|
|
|||
|
#ifdef NTENV
|
|||
|
#define LOCALLOCATOR "\\\\."
|
|||
|
#endif
|
|||
|
|
|||
|
#if defined(DOS) && !defined(WIN)
|
|||
|
|
|||
|
extern int _NsAllocatorInitialized;
|
|||
|
extern __RPC_API NsAllocatorSetup();
|
|||
|
|
|||
|
#define INIT_DOS_ALLOCATOR_IF_NECESSARY \
|
|||
|
{ if (!_NsAllocatorInitialized) NsAllocatorSetup(); }
|
|||
|
|
|||
|
#else // DOS only
|
|||
|
#define INIT_DOS_ALLOCATOR_IF_NECESSARY
|
|||
|
#endif // DOS only
|
|||
|
|
|||
|
unsigned char * NsiStringBinding;
|
|||
|
|
|||
|
enum {
|
|||
|
BindingReadRegistry = 0,
|
|||
|
BindingNotYetTried,
|
|||
|
BindingContinueRegistry,
|
|||
|
BindingFound,
|
|||
|
#ifndef NTENV
|
|||
|
BindingBackupFirst,
|
|||
|
BindingBackup,
|
|||
|
BindToBackupViaBC,
|
|||
|
BindToAnyViaBC
|
|||
|
#endif
|
|||
|
};
|
|||
|
|
|||
|
#define NilOffset (-1)
|
|||
|
|
|||
|
typedef struct
|
|||
|
{
|
|||
|
unsigned char *ProtoSeq;
|
|||
|
unsigned char *NetworkAddress;
|
|||
|
unsigned char *Endpoint;
|
|||
|
|
|||
|
HKEY RegHandle;
|
|||
|
unsigned int NumberServers;
|
|||
|
int AddressOffset;
|
|||
|
void *Buffer;
|
|||
|
char *ServerList;
|
|||
|
int State;
|
|||
|
int NextState;
|
|||
|
|
|||
|
} RPC_LOCATOR_BIND_CONTEXT, *PRPC_LOCATOR_BIND_CONTEXT;
|
|||
|
|
|||
|
DWORD GblBindId = 0;
|
|||
|
|
|||
|
#define MAX_SERVER_NAME 20
|
|||
|
|
|||
|
static RPC_LOCATOR_BIND_CONTEXT near BindSearch;
|
|||
|
|
|||
|
WIDE_STRING *DefaultName;
|
|||
|
long DefaultSyntax = RPC_C_NS_SYNTAX_DCE;
|
|||
|
int fSyntaxDefaultsLoaded;
|
|||
|
|
|||
|
#ifndef NTENV
|
|||
|
|
|||
|
char __RPC_FAR * MailslotName = "\\\\*\\mailslot\\Resp_s";
|
|||
|
char __RPC_FAR * LocalMS = "\\mailslot\\Resp_c";
|
|||
|
|
|||
|
#define RESPONSETIME 4096L
|
|||
|
#endif
|
|||
|
|
|||
|
|
|||
|
|
|||
|
unsigned char *
|
|||
|
RegGetString(
|
|||
|
IN void * RegHandle,
|
|||
|
IN char * KeyName
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Get a string from the registery.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
KeyName - name of key to lookup.
|
|||
|
|
|||
|
Returns:
|
|||
|
|
|||
|
pointer to the allocated string, or Nil if not found
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
char Buffer[300];
|
|||
|
DWORD BufferLength = sizeof(Buffer);
|
|||
|
DWORD Type;
|
|||
|
|
|||
|
#ifdef NTENV
|
|||
|
|
|||
|
if (RegQueryValueExA((HKEY)RegHandle, KeyName, 0, &Type,
|
|||
|
(unsigned char far*)Buffer, &BufferLength))
|
|||
|
#else
|
|||
|
|
|||
|
if (RegQueryValueA((HKEY)RegHandle, KeyName,
|
|||
|
(char far*)Buffer, &BufferLength))
|
|||
|
|
|||
|
#endif
|
|||
|
return(0);
|
|||
|
|
|||
|
return(CopyString(Buffer));
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
static RPC_STATUS
|
|||
|
Bind(RPC_BINDING_HANDLE *NsiClntBinding
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Bind to the locator server
|
|||
|
|
|||
|
Returns:
|
|||
|
|
|||
|
RpcBindingFromStringBinding()
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
RPC_STATUS status;
|
|||
|
unsigned char AddressBuffer[100];
|
|||
|
|
|||
|
status = RpcStringFreeA(&NsiStringBinding);
|
|||
|
ASSERT(!status);
|
|||
|
|
|||
|
// Get the next path componet from the NetworkAddress field.
|
|||
|
// Conponets are ; delimited fields.
|
|||
|
|
|||
|
ASSERT(BindSearch.AddressOffset >= 0);
|
|||
|
|
|||
|
for (int i = 0; i < sizeof(AddressBuffer); BindSearch.AddressOffset++, i++)
|
|||
|
{
|
|||
|
|
|||
|
AddressBuffer[i] =
|
|||
|
BindSearch.NetworkAddress[BindSearch.AddressOffset];
|
|||
|
|
|||
|
if (BindSearch.NetworkAddress[BindSearch.AddressOffset] == ';')
|
|||
|
{
|
|||
|
|
|||
|
BindSearch.AddressOffset++;
|
|||
|
|
|||
|
// If there are two ;; in a row, then pass through the ;
|
|||
|
// as a literal instead of a path seperator.
|
|||
|
|
|||
|
if (BindSearch.NetworkAddress[BindSearch.AddressOffset] == ';')
|
|||
|
continue;
|
|||
|
|
|||
|
AddressBuffer[i] = 0;
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
if (BindSearch.NetworkAddress[BindSearch.AddressOffset] == 0)
|
|||
|
{
|
|||
|
BindSearch.AddressOffset = NilOffset;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
status = RpcStringBindingComposeA(0, BindSearch.ProtoSeq,
|
|||
|
AddressBuffer, BindSearch.Endpoint,
|
|||
|
0, &NsiStringBinding);
|
|||
|
|
|||
|
if (status)
|
|||
|
return(status);
|
|||
|
|
|||
|
return (RpcBindingFromStringBindingA(NsiStringBinding, NsiClntBinding));
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
RPC_STATUS RPC_ENTRY
|
|||
|
I_NsClientBindSearch(RPC_BINDING_HANDLE *NsiClntBinding, DWORD *BindId
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
The function binds to the locator, first it tries to bind to a
|
|||
|
local machine, then it attempts to bind to the domain controller.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
BindingSearchContext - context of search for the locator.
|
|||
|
|
|||
|
Returns:
|
|||
|
|
|||
|
RPC_S_OK, RPC_S_NO_BINDINGS, RPC_S_CANNOT_BIND, RPC_S_OUT_OF_RESOURCES
|
|||
|
|
|||
|
rewritten to make it multi-thread capable. ushaji, Mar 98
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
long status;
|
|||
|
|
|||
|
#ifndef NTENV
|
|||
|
unsigned short cbSI;
|
|||
|
#define SERVER_INFO struct server_info_0
|
|||
|
#define ServerName(p) ((struct server_info_0 *)p)->sv0_name
|
|||
|
unsigned short Count = 1;
|
|||
|
QUERYLOCATORREPLY Reply, __RPC_FAR * QueryReply;
|
|||
|
#else
|
|||
|
#define SERVER_INFO SERVER_INFO_100
|
|||
|
#define ServerName(p) ((SERVER_INFO_100 *)p)->sv100_name
|
|||
|
#endif
|
|||
|
|
|||
|
INIT_DOS_ALLOCATOR_IF_NECESSARY;
|
|||
|
|
|||
|
RequestGlobalMutex();
|
|||
|
|
|||
|
switch (BindSearch.State)
|
|||
|
{
|
|||
|
case BindingReadRegistry:
|
|||
|
|
|||
|
if (BindSearch.RegHandle)
|
|||
|
{
|
|||
|
status = RegCloseKey(BindSearch.RegHandle);
|
|||
|
ASSERT(!status);
|
|||
|
BindSearch.RegHandle = 0;
|
|||
|
|
|||
|
delete BindSearch.NetworkAddress;
|
|||
|
delete BindSearch.ProtoSeq;
|
|||
|
delete BindSearch.Endpoint;
|
|||
|
}
|
|||
|
memset(&BindSearch, 0, sizeof(RPC_LOCATOR_BIND_CONTEXT));
|
|||
|
|
|||
|
// We store the binding information on the name service in
|
|||
|
// the registry. Get the information into BindingHandle.
|
|||
|
|
|||
|
#ifdef NTENV
|
|||
|
status = RegOpenKeyExA(RPC_REG_ROOT, REG_NSI, 0L, KEY_READ,
|
|||
|
&BindSearch.RegHandle);
|
|||
|
#else
|
|||
|
status = RegOpenKeyA(RPC_REG_ROOT, REG_NSI, &BindSearch.RegHandle);
|
|||
|
#endif
|
|||
|
|
|||
|
|
|||
|
if (status) {
|
|||
|
status = RPC_S_NAME_SERVICE_UNAVAILABLE;
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
BindSearch.ProtoSeq = RegGetString((void *) BindSearch.RegHandle, "Protocol");
|
|||
|
BindSearch.NetworkAddress = RegGetString((void *) BindSearch.RegHandle,
|
|||
|
"NetworkAddress");
|
|||
|
BindSearch.Endpoint = RegGetString((void *) BindSearch.RegHandle, "Endpoint");
|
|||
|
|
|||
|
GetDefaultEntrys((void *) BindSearch.RegHandle);
|
|||
|
|
|||
|
if (!BindSearch.ProtoSeq || !BindSearch.Endpoint) {
|
|||
|
status = RPC_S_NAME_SERVICE_UNAVAILABLE;
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
#ifdef NTENV
|
|||
|
if (
|
|||
|
(BindSearch.NetworkAddress == NULL)
|
|||
|
|| (BindSearch.NetworkAddress[0] == '\0')
|
|||
|
|| (!strncmp((char *) BindSearch.NetworkAddress, LOCALLOCATOR,
|
|||
|
strlen(LOCALLOCATOR)))
|
|||
|
)
|
|||
|
{
|
|||
|
StartServiceIfNecessary();
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
status = Bind(NsiClntBinding);
|
|||
|
if (status == RPC_S_OK) {
|
|||
|
BindSearch.State = BindingNotYetTried;
|
|||
|
GblBindId++;
|
|||
|
BindSearch.NextState = BindingContinueRegistry;
|
|||
|
}
|
|||
|
|
|||
|
break;
|
|||
|
|
|||
|
|
|||
|
case BindingNotYetTried:
|
|||
|
case BindingFound:
|
|||
|
status = RpcBindingFromStringBindingA(NsiStringBinding, NsiClntBinding);
|
|||
|
break;
|
|||
|
|
|||
|
case BindingContinueRegistry:
|
|||
|
|
|||
|
if (BindSearch.AddressOffset != NilOffset) {
|
|||
|
status = Bind(NsiClntBinding);
|
|||
|
|
|||
|
if (status == RPC_S_OK) {
|
|||
|
BindSearch.State = BindingNotYetTried;
|
|||
|
GblBindId++;
|
|||
|
}
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
#ifdef NTENV
|
|||
|
status = RPC_S_NAME_SERVICE_UNAVAILABLE;
|
|||
|
break;
|
|||
|
#else
|
|||
|
|
|||
|
if (BindSearch.NetworkAddress)
|
|||
|
delete BindSearch.NetworkAddress;
|
|||
|
|
|||
|
// Don't search the Net if we aren't looking for the locator.
|
|||
|
if (strcmp((char *)BindSearch.Endpoint, "\\pipe\\locator"))
|
|||
|
{
|
|||
|
status = RPC_S_NAME_SERVICE_UNAVAILABLE;
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
BindSearch.NetworkAddress = new unsigned char [MAX_SERVER_NAME];
|
|||
|
|
|||
|
// second, try the domain controller
|
|||
|
|
|||
|
|
|||
|
if (NetGetDCName(0, 0, (char far *) BindSearch.NetworkAddress,
|
|||
|
MAX_SERVER_NAME))
|
|||
|
{
|
|||
|
status = RPC_S_NAME_SERVICE_UNAVAILABLE;
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
BindSearch.AddressOffset = 0;
|
|||
|
|
|||
|
status = Bind(NsiClntBinding);
|
|||
|
if (status == RPC_S_OK)
|
|||
|
{
|
|||
|
GblBindId++;
|
|||
|
BindSearch.State = BindingNotYetTried;
|
|||
|
BindSearch.NextState = BindingBackupFirst;
|
|||
|
break;
|
|||
|
}
|
|||
|
break;
|
|||
|
|
|||
|
case BindingBackupFirst:
|
|||
|
BindSearch.NumberServers = 0;
|
|||
|
|
|||
|
// third, try all the member servers. First get the # of bytes
|
|||
|
// needed to hold all the names, then retrive them.
|
|||
|
|
|||
|
NetServerEnum2(0, 0, 0, 0,
|
|||
|
(USHORT *) &BindSearch.NumberServers,
|
|||
|
(USHORT *) &BindSearch.NumberServers,
|
|||
|
SV_TYPE_DOMAIN_BAKCTRL, 0);
|
|||
|
|
|||
|
cbSI = (BindSearch.NumberServers+2) * sizeof(SERVER_INFO);
|
|||
|
BindSearch.Buffer = new char [cbSI];
|
|||
|
BindSearch.ServerList = (char *) BindSearch.Buffer;
|
|||
|
|
|||
|
if (!BindSearch.ServerList)
|
|||
|
{
|
|||
|
status = RPC_S_OUT_OF_RESOURCES;
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
if (NetServerEnum2(0, 0, (char far *)BindSearch.ServerList, cbSI,
|
|||
|
(USHORT *) &BindSearch.NumberServers,
|
|||
|
(USHORT *) &BindSearch.NumberServers,
|
|||
|
SV_TYPE_DOMAIN_BAKCTRL, 0))
|
|||
|
|
|||
|
{
|
|||
|
delete BindSearch.Buffer;
|
|||
|
status = RPC_S_NAME_SERVICE_UNAVAILABLE;
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
case BindingBackup:
|
|||
|
|
|||
|
if (BindSearch.NumberServers == 0)
|
|||
|
{
|
|||
|
delete BindSearch.Buffer;
|
|||
|
BindSearch.Buffer = new char [sizeof(QUERYLOCATORREPLY) *
|
|||
|
MAXLOCATORSTOTRY];
|
|||
|
if (BindSearch.Buffer == NULL)
|
|||
|
{
|
|||
|
status = RPC_S_NAME_SERVICE_UNAVAILABLE;
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
BindSearch.ServerList = (char *)BindSearch.Buffer;
|
|||
|
BindSearch.NumberServers = BroadcastAQuery(
|
|||
|
QUERY_DC_LOCATOR,
|
|||
|
(char __RPC_FAR *)BindSearch.Buffer,
|
|||
|
MAXLOCATORSTOTRY
|
|||
|
);
|
|||
|
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
BindSearch.NumberServers--;
|
|||
|
BindSearch.NetworkAddress[0] = '\\';
|
|||
|
BindSearch.NetworkAddress[1] = '\\';
|
|||
|
|
|||
|
strcpy((char far *)BindSearch.NetworkAddress+2,
|
|||
|
ServerName(BindSearch.ServerList));
|
|||
|
|
|||
|
BindSearch.ServerList += sizeof(SERVER_INFO);
|
|||
|
|
|||
|
BindSearch.AddressOffset = 0;
|
|||
|
status = Bind(NsiClntBinding);
|
|||
|
if (status == RPC_S_OK) {
|
|||
|
GblBindId++;
|
|||
|
BindSearch.NextState = BindSearch.State;
|
|||
|
BindSearch.State = BindingNotYetTried;
|
|||
|
}
|
|||
|
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
case BindToBackupViaBC:
|
|||
|
|
|||
|
if (BindSearch.NumberServers == 0)
|
|||
|
{
|
|||
|
//The buffer is already setup, use it for next phase
|
|||
|
BindSearch.NumberServers = BroadcastAQuery(
|
|||
|
QUERY_ANY_LOCATOR,
|
|||
|
(char __RPC_FAR *)BindSearch.Buffer,
|
|||
|
MAXLOCATORSTOTRY
|
|||
|
);
|
|||
|
BindSearch.State = BindToAnyViaBC;
|
|||
|
BindSearch.ServerList = (char *) BindSearch.Buffer;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
BindSearch.NumberServers--;
|
|||
|
QueryReply = (QUERYLOCATORREPLY __RPC_FAR *)
|
|||
|
BindSearch.ServerList;
|
|||
|
UnicodeToAscii(QueryReply->SenderName);
|
|||
|
strcpy((char __RPC_FAR *) BindSearch.NetworkAddress,
|
|||
|
(char __RPC_FAR *)QueryReply->SenderName);
|
|||
|
BindSearch.ServerList = (char __RPC_FAR *)(QueryReply+1);
|
|||
|
BindSearch.AddressOffset = 0;
|
|||
|
status = Bind(NsiClntBinding);
|
|||
|
|
|||
|
if (status == RPC_S_OK) {
|
|||
|
GblBindId++;
|
|||
|
BindSearch.NextState = BindSearch.State;
|
|||
|
BindSearch.State = BindingNotYetTried;
|
|||
|
}
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
//In the If case - we intentionally fall through to the
|
|||
|
//BindAny state.
|
|||
|
|
|||
|
case BindToAnyViaBC:
|
|||
|
if (BindSearch.NumberServers == 0)
|
|||
|
{
|
|||
|
delete BindSearch.Buffer;
|
|||
|
status = RPC_S_NAME_SERVICE_UNAVAILABLE;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
BindSearch.NumberServers--;
|
|||
|
QueryReply = (QUERYLOCATORREPLY __RPC_FAR *)
|
|||
|
BindSearch.ServerList;
|
|||
|
UnicodeToAscii(QueryReply->SenderName);
|
|||
|
strcpy((char __RPC_FAR *) BindSearch.NetworkAddress,
|
|||
|
(char __RPC_FAR *)QueryReply->SenderName);
|
|||
|
BindSearch.ServerList = (char __RPC_FAR *)(QueryReply+1);
|
|||
|
BindSearch.AddressOffset = 0;
|
|||
|
status = Bind(NsiClntBinding);
|
|||
|
|
|||
|
if (status == RPC_S_OK) {
|
|||
|
GblBindId++;
|
|||
|
BindSearch.NextState = BindSearch.State;
|
|||
|
BindSearch.State = BindingNotYetTried;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
break;
|
|||
|
#endif
|
|||
|
|
|||
|
default:
|
|||
|
ASSERT(!"Bad Search State");
|
|||
|
BindSearch.State = BindingReadRegistry;
|
|||
|
status = RPC_S_NAME_SERVICE_UNAVAILABLE;
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
*BindId = GblBindId;
|
|||
|
ClearGlobalMutex();
|
|||
|
return(status);
|
|||
|
}
|
|||
|
|
|||
|
RPC_STATUS RPC_ENTRY
|
|||
|
I_NsBindingFoundBogus(RPC_BINDING_HANDLE *NsiClntBinding, DWORD BindId
|
|||
|
)
|
|||
|
{
|
|||
|
long status;
|
|||
|
|
|||
|
if (*NsiClntBinding)
|
|||
|
{
|
|||
|
status = RpcBindingFree(NsiClntBinding);
|
|||
|
ASSERT(!status);
|
|||
|
}
|
|||
|
*NsiClntBinding = NULL;
|
|||
|
|
|||
|
RequestGlobalMutex();
|
|||
|
|
|||
|
switch (BindSearch.State)
|
|||
|
{
|
|||
|
case BindingNotYetTried:
|
|||
|
if (BindId == GblBindId)
|
|||
|
BindSearch.State = BindSearch.NextState;
|
|||
|
break;
|
|||
|
case BindingFound:
|
|||
|
if (BindId == GblBindId)
|
|||
|
BindSearch.State = BindingReadRegistry;
|
|||
|
break;
|
|||
|
default:
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
ClearGlobalMutex();
|
|||
|
return(RPC_S_OK);
|
|||
|
}
|
|||
|
|
|||
|
void RPC_ENTRY
|
|||
|
I_NsClientBindDone(RPC_BINDING_HANDLE *NsiClntBinding, DWORD BindId
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
The function cleans up after binding to the locator.
|
|||
|
|
|||
|
Returns:
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
long status;
|
|||
|
RPC_STATUS RpcStatus;
|
|||
|
|
|||
|
RequestGlobalMutex();
|
|||
|
|
|||
|
switch (BindSearch.State)
|
|||
|
{
|
|||
|
case BindingFound:
|
|||
|
break;
|
|||
|
|
|||
|
case BindingReadRegistry:
|
|||
|
break;
|
|||
|
|
|||
|
case BindingNotYetTried:
|
|||
|
if (BindId == GblBindId) {
|
|||
|
BindSearch.State = BindingFound;
|
|||
|
|
|||
|
if (BindSearch.RegHandle)
|
|||
|
{
|
|||
|
status = RegCloseKey(BindSearch.RegHandle);
|
|||
|
ASSERT(!status);
|
|||
|
BindSearch.RegHandle = 0;
|
|||
|
|
|||
|
delete BindSearch.NetworkAddress;
|
|||
|
delete BindSearch.ProtoSeq;
|
|||
|
delete BindSearch.Endpoint;
|
|||
|
}
|
|||
|
}
|
|||
|
break;
|
|||
|
|
|||
|
case BindingContinueRegistry:
|
|||
|
if (BindId == GblBindId) {
|
|||
|
BindSearch.State = BindingReadRegistry;
|
|||
|
if (BindSearch.RegHandle)
|
|||
|
{
|
|||
|
status = RegCloseKey(BindSearch.RegHandle);
|
|||
|
ASSERT(!status);
|
|||
|
BindSearch.RegHandle = 0;
|
|||
|
|
|||
|
delete BindSearch.NetworkAddress;
|
|||
|
delete BindSearch.ProtoSeq;
|
|||
|
delete BindSearch.Endpoint;
|
|||
|
}
|
|||
|
}
|
|||
|
break;
|
|||
|
|
|||
|
#ifndef NTENV
|
|||
|
case BindToAnyViaBC:
|
|||
|
case BindToBackupViaBC:
|
|||
|
case BindingBackup:
|
|||
|
delete BindSearch.Buffer;
|
|||
|
|
|||
|
case BindingBackupFirst:
|
|||
|
|
|||
|
status = RegSetValue(BindSearch.RegHandle, "NetworkAddress",
|
|||
|
REG_SZ, (LPSTR) BindSearch.NetworkAddress,
|
|||
|
strlen((CONST_CHAR *)BindSearch.NetworkAddress) + 1);
|
|||
|
|
|||
|
BindSearch.State = BindingFound;
|
|||
|
ASSERT(!status);
|
|||
|
break;
|
|||
|
#endif
|
|||
|
|
|||
|
default:
|
|||
|
ASSERT(!"Bad State - \n");
|
|||
|
}
|
|||
|
|
|||
|
#if defined(DOS) && !defined(WIN)
|
|||
|
|
|||
|
// Unloaded the big fat lanman stuff now that we are done searching.
|
|||
|
|
|||
|
RpcNsLmDiscard();
|
|||
|
|
|||
|
#endif
|
|||
|
|
|||
|
RpcStatus = RpcBindingFree(NsiClntBinding);
|
|||
|
|
|||
|
ClearGlobalMutex();
|
|||
|
|
|||
|
// ASSERT(!RpcStatus);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
unsigned long RPC_ENTRY
|
|||
|
I_GetDefaultEntrySyntax(
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Called by the runtime DLL when it needs to know the default syntax.
|
|||
|
Currently this is used only by RpcBindingInqEntry().
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
none
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
the entry syntax
|
|||
|
|
|||
|
Exceptions:
|
|||
|
|
|||
|
none
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
return (unsigned long) DefaultSyntax;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
#ifndef NTENV
|
|||
|
|
|||
|
unsigned short BroadcastAQuery(
|
|||
|
unsigned long Type,
|
|||
|
char __RPC_FAR * Buffer,
|
|||
|
unsigned short Count
|
|||
|
)
|
|||
|
{
|
|||
|
|
|||
|
unsigned short Err;
|
|||
|
unsigned MSHandle;
|
|||
|
unsigned short Returned, NextSize, NextPri, Avail;
|
|||
|
unsigned short RetCount = 0;
|
|||
|
QUERYLOCATOR Query;
|
|||
|
unsigned long TimeRemaining = RESPONSETIME;
|
|||
|
wksta_info_10 __RPC_FAR * Wkio10;
|
|||
|
char __RPC_FAR * pBuf;
|
|||
|
unsigned short __RPC_FAR * pUZ;
|
|||
|
//First try and get the computer name
|
|||
|
|
|||
|
Err = NetWkstaGetInfo(
|
|||
|
0L,
|
|||
|
10,
|
|||
|
(char __RPC_FAR *) 0L,
|
|||
|
0,
|
|||
|
&Avail);
|
|||
|
|
|||
|
ASSERT(Err == NERR_BufTooSmall);
|
|||
|
|
|||
|
Wkio10 = (wksta_info_10 __RPC_FAR *) new char [Avail];
|
|||
|
|
|||
|
if (Wkio10 == 0L)
|
|||
|
{
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
Err = NetWkstaGetInfo(
|
|||
|
0L,
|
|||
|
10,
|
|||
|
(char __RPC_FAR *) Wkio10,
|
|||
|
Avail,
|
|||
|
&Avail
|
|||
|
);
|
|||
|
|
|||
|
//Format the Query!
|
|||
|
Query.MessageType = Type;
|
|||
|
Query.SenderOsType= OS_WIN31DOS;
|
|||
|
|
|||
|
for (pBuf = &Wkio10->wki10_computername[0],pUZ = &Query.RequesterName[0];
|
|||
|
*pBuf !=0;
|
|||
|
pBuf++, pUZ++)
|
|||
|
*pUZ = *pBuf;
|
|||
|
|
|||
|
*pUZ = 0;
|
|||
|
|
|||
|
|
|||
|
Err = DosMakeMailslot(
|
|||
|
LocalMS,
|
|||
|
sizeof(QUERYLOCATORREPLY),
|
|||
|
0,
|
|||
|
&MSHandle
|
|||
|
);
|
|||
|
|
|||
|
if (Err != NERR_Success)
|
|||
|
{
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
Err = DosWriteMailslot(
|
|||
|
MailslotName,
|
|||
|
(char __RPC_FAR *) &Query,
|
|||
|
sizeof(Query),
|
|||
|
0, //Priority
|
|||
|
2, //Class
|
|||
|
0 //Timeout
|
|||
|
);
|
|||
|
|
|||
|
if (Err != NERR_Success)
|
|||
|
goto CleanupAndExit;
|
|||
|
|
|||
|
//Now sit in a loop and wait
|
|||
|
//for WAITRESPONSE secs
|
|||
|
|
|||
|
while ((TimeRemaining) && (RetCount < Count))
|
|||
|
{
|
|||
|
|
|||
|
Err = DosReadMailslot(
|
|||
|
MSHandle,
|
|||
|
Buffer,
|
|||
|
&Returned,
|
|||
|
&NextSize,
|
|||
|
&NextPri,
|
|||
|
TimeRemaining
|
|||
|
);
|
|||
|
|
|||
|
if (Err == NERR_Success)
|
|||
|
{
|
|||
|
ASSERT (Returned == sizeof(QUERYLOCATORREPLY));
|
|||
|
Buffer += sizeof(QUERYLOCATORREPLY);
|
|||
|
RetCount ++;
|
|||
|
TimeRemaining >> 1;
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
break;
|
|||
|
|
|||
|
} //end of while ReadMS
|
|||
|
|
|||
|
|
|||
|
CleanupAndExit:
|
|||
|
DosDeleteMailslot(MSHandle);
|
|||
|
return (RetCount);
|
|||
|
|
|||
|
}
|
|||
|
#endif
|