764 lines
18 KiB
C
764 lines
18 KiB
C
/*++
|
||
|
||
Copyright (c) 1987-1999 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
nlcommon.c
|
||
|
||
Abstract:
|
||
|
||
Routines shared by logonsrv\server and logonsrv\common
|
||
|
||
Author:
|
||
|
||
Cliff Van Dyke (cliffv) 20-July-1996
|
||
|
||
Environment:
|
||
|
||
User mode only.
|
||
Contains NT-specific code.
|
||
Requires ANSI C extensions: slash-slash comments, long external names.
|
||
|
||
Revision History:
|
||
|
||
--*/
|
||
|
||
|
||
//
|
||
// Common include files.
|
||
//
|
||
|
||
#ifndef _NETLOGON_SERVER
|
||
#include <nt.h>
|
||
#include <ntrtl.h>
|
||
#include <nturtl.h>
|
||
#include <ntlsa.h>
|
||
#include <rpc.h> // RPC_STATUS
|
||
|
||
#include <windef.h>
|
||
#include <winsock2.h>
|
||
|
||
#include <lmcons.h> // General net defines
|
||
#include <dsgetdc.h> // DsGetDcName()
|
||
#include <align.h> // ROUND_UP_COUNT()
|
||
#include <lmerr.h> // System Error Log definitions
|
||
#include <lmapibuf.h> // NetapipBufferAllocate
|
||
#include <netlib.h> // NetpMemoryAllcate(
|
||
#include <netlibnt.h> // NetpApiStatusToNtStatus();
|
||
#include <netlogon.h> // Definition of mailslot messages
|
||
#include <ntddbrow.h> // Needed by nlcommon.h
|
||
#include <ntrpcp.h>
|
||
|
||
#if DBG
|
||
#define NETLOGONDBG 1
|
||
#endif // DBG
|
||
#include <nldebug.h> // NlPrint()
|
||
#include <nlbind.h> // Definitions shared with netlogon
|
||
#include <nlcommon.h> // Definitions shared with netlogon
|
||
#include <stdlib.h> // C library functions (rand, etc)
|
||
|
||
|
||
#endif // _NETLOGON_SERVER
|
||
|
||
//
|
||
// Include nlcommon.h again allocating the actual variables
|
||
// this time around.
|
||
//
|
||
|
||
// #define NLCOMMON_ALLOCATE
|
||
// #include "nlcommon.h"
|
||
// #undef NLCOMMON_ALLOCATE
|
||
|
||
|
||
#ifndef WIN32_CHICAGO
|
||
|
||
|
||
VOID
|
||
NlForestRelocationRoutine(
|
||
IN DWORD Level,
|
||
IN OUT PBUFFER_DESCRIPTOR BufferDescriptor,
|
||
IN PTRDIFF_T Offset
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Routine to relocate the pointers from the fixed portion of a NetGroupEnum
|
||
enumeration
|
||
buffer to the string portion of an enumeration buffer. It is called
|
||
as a callback routine from NetpAllocateEnumBuffer when it re-allocates
|
||
such a buffer. NetpAllocateEnumBuffer copied the fixed portion and
|
||
string portion into the new buffer before calling this routine.
|
||
|
||
Arguments:
|
||
|
||
Level - Level of information in the buffer.
|
||
|
||
BufferDescriptor - Description of the new buffer.
|
||
|
||
Offset - Offset to add to each pointer in the fixed portion.
|
||
|
||
Return Value:
|
||
|
||
Returns the error code for the operation.
|
||
|
||
--*/
|
||
|
||
{
|
||
DWORD EntryCount;
|
||
DWORD EntryNumber;
|
||
DWORD FixedSize;
|
||
|
||
|
||
//
|
||
// Local macro to add a byte offset to a pointer.
|
||
//
|
||
|
||
#define RELOCATE_ONE( _fieldname, _offset ) \
|
||
if ( (_fieldname) != NULL ) { \
|
||
_fieldname = (PVOID) ((LPBYTE)(_fieldname) + (_offset)); \
|
||
}
|
||
|
||
//
|
||
// Compute the number of fixed size entries
|
||
//
|
||
|
||
FixedSize = sizeof(DS_DOMAIN_TRUSTSW);
|
||
|
||
EntryCount =
|
||
((DWORD)(BufferDescriptor->FixedDataEnd - BufferDescriptor->Buffer)) /
|
||
FixedSize;
|
||
|
||
//
|
||
// Loop relocating each field in each fixed size structure
|
||
//
|
||
|
||
for ( EntryNumber=0; EntryNumber<EntryCount; EntryNumber++ ) {
|
||
|
||
LPBYTE TheStruct = BufferDescriptor->Buffer + FixedSize * EntryNumber;
|
||
|
||
RELOCATE_ONE( ((PDS_DOMAIN_TRUSTSW)TheStruct)->NetbiosDomainName, Offset );
|
||
RELOCATE_ONE( ((PDS_DOMAIN_TRUSTSW)TheStruct)->DnsDomainName, Offset );
|
||
RELOCATE_ONE( ((PDS_DOMAIN_TRUSTSW)TheStruct)->DomainSid, Offset );
|
||
|
||
}
|
||
|
||
return;
|
||
|
||
UNREFERENCED_PARAMETER( Level );
|
||
|
||
}
|
||
|
||
|
||
NTSTATUS
|
||
NlAllocateForestTrustListEntry (
|
||
IN PBUFFER_DESCRIPTOR BufferDescriptor,
|
||
IN PUNICODE_STRING InNetbiosDomainName OPTIONAL,
|
||
IN PUNICODE_STRING InDnsDomainName OPTIONAL,
|
||
IN ULONG Flags,
|
||
IN ULONG ParentIndex,
|
||
IN ULONG TrustType,
|
||
IN ULONG TrustAttributes,
|
||
IN PSID DomainSid OPTIONAL,
|
||
IN GUID *DomainGuid,
|
||
OUT PULONG RetSize,
|
||
OUT PDS_DOMAIN_TRUSTSW *RetTrustedDomain
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Add a DS_DOMAIN_TRUSTSW structure to the buffer described by BufferDescriptor.
|
||
|
||
Arguments:
|
||
|
||
BufferDescriptor - Buffer entry is to be added to.
|
||
|
||
NetbiosDomainName, DnsDomainName, Flags, ParentIndex, TrustType,
|
||
TrustAttributes, DomainSid, DomainGuid - Fields to fill into
|
||
the DS_DOMAIN_TRUSTSW structure
|
||
|
||
RetSize - Returns the size in bytes of the allocated entry
|
||
|
||
RetTrustedDomain - Returns a pointer to the newly allocated structure
|
||
|
||
Return Value:
|
||
|
||
Status of the operation.
|
||
|
||
--*/
|
||
{
|
||
NTSTATUS Status;
|
||
NET_API_STATUS NetStatus;
|
||
|
||
PDS_DOMAIN_TRUSTSW TrustedDomain = NULL;
|
||
UNICODE_STRING NetbiosDomainName;
|
||
UNICODE_STRING DnsDomainName;
|
||
|
||
ULONG Size;
|
||
ULONG VariableSize;
|
||
|
||
//
|
||
// Initialization
|
||
//
|
||
|
||
if ( InNetbiosDomainName == NULL ) {
|
||
RtlInitUnicodeString( &NetbiosDomainName, NULL );
|
||
} else {
|
||
NetbiosDomainName = *InNetbiosDomainName;
|
||
}
|
||
|
||
if ( InDnsDomainName == NULL ) {
|
||
RtlInitUnicodeString( &DnsDomainName, NULL );
|
||
} else {
|
||
DnsDomainName = *InDnsDomainName;
|
||
}
|
||
|
||
//
|
||
// Determine the size of this entry
|
||
//
|
||
|
||
Size = sizeof(DS_DOMAIN_TRUSTSW);
|
||
VariableSize = 0;
|
||
if ( DnsDomainName.Length != 0 ) {
|
||
VariableSize += DnsDomainName.Length + sizeof(WCHAR);
|
||
}
|
||
if ( NetbiosDomainName.Length != 0 ) {
|
||
VariableSize += NetbiosDomainName.Length + sizeof(WCHAR);
|
||
}
|
||
if ( DomainSid != NULL ) {
|
||
VariableSize += RtlLengthSid( DomainSid );
|
||
}
|
||
VariableSize = ROUND_UP_COUNT( VariableSize, ALIGN_DWORD );
|
||
*RetSize = Size + VariableSize;
|
||
|
||
Size += VariableSize;
|
||
Size += sizeof(DWORD); // Size is really a function of alignment of EndOfVariableData
|
||
|
||
|
||
NetStatus = NetpAllocateEnumBufferEx(
|
||
BufferDescriptor,
|
||
FALSE, // Not a 'get' operation
|
||
0xFFFFFFFF, // PrefMaxLen,
|
||
Size,
|
||
NlForestRelocationRoutine,
|
||
0,
|
||
512 ); // Grow by at most 512 bytes more than Size
|
||
|
||
if (NetStatus != NERR_Success) {
|
||
Status = NetpApiStatusToNtStatus( NetStatus );
|
||
goto Cleanup;
|
||
}
|
||
|
||
//
|
||
// Copy this entry into the buffer
|
||
//
|
||
|
||
TrustedDomain = (PDS_DOMAIN_TRUSTSW)(BufferDescriptor->FixedDataEnd);
|
||
*RetTrustedDomain = TrustedDomain;
|
||
BufferDescriptor->FixedDataEnd += sizeof(DS_DOMAIN_TRUSTSW);
|
||
|
||
//
|
||
// Copy the fixed size data
|
||
//
|
||
|
||
TrustedDomain->Flags = Flags;
|
||
TrustedDomain->ParentIndex = ParentIndex;
|
||
TrustedDomain->TrustType = TrustType;
|
||
TrustedDomain->TrustAttributes = TrustAttributes;
|
||
if ( DomainGuid == NULL ) {
|
||
RtlZeroMemory( &TrustedDomain->DomainGuid, sizeof(GUID) );
|
||
} else {
|
||
TrustedDomain->DomainGuid = *DomainGuid;
|
||
}
|
||
|
||
|
||
//
|
||
// Copy the information into the buffer.
|
||
//
|
||
|
||
//
|
||
// Copy the DWORD aligned data
|
||
//
|
||
if ( DomainSid != NULL ) {
|
||
if ( !NetpCopyDataToBuffer (
|
||
(LPBYTE)DomainSid,
|
||
RtlLengthSid( DomainSid ),
|
||
BufferDescriptor->FixedDataEnd,
|
||
&BufferDescriptor->EndOfVariableData,
|
||
(LPBYTE *)&TrustedDomain->DomainSid,
|
||
sizeof(DWORD) ) ) {
|
||
|
||
Status = STATUS_INTERNAL_ERROR;
|
||
goto Cleanup;
|
||
}
|
||
} else {
|
||
TrustedDomain->DomainSid = NULL;
|
||
}
|
||
|
||
|
||
//
|
||
// Copy the WCHAR aligned data.
|
||
//
|
||
|
||
if ( NetbiosDomainName.Length != 0 ) {
|
||
if ( !NetpCopyStringToBuffer(
|
||
NetbiosDomainName.Buffer,
|
||
NetbiosDomainName.Length/sizeof(WCHAR),
|
||
BufferDescriptor->FixedDataEnd,
|
||
(LPWSTR *)&BufferDescriptor->EndOfVariableData,
|
||
&TrustedDomain->NetbiosDomainName ) ) {
|
||
|
||
Status = STATUS_INTERNAL_ERROR;
|
||
goto Cleanup;
|
||
}
|
||
} else {
|
||
TrustedDomain->NetbiosDomainName = NULL;
|
||
}
|
||
|
||
if ( DnsDomainName.Length != 0 ) {
|
||
if ( !NetpCopyStringToBuffer(
|
||
DnsDomainName.Buffer,
|
||
DnsDomainName.Length/sizeof(WCHAR),
|
||
BufferDescriptor->FixedDataEnd,
|
||
(LPWSTR *)&BufferDescriptor->EndOfVariableData,
|
||
&TrustedDomain->DnsDomainName ) ) {
|
||
|
||
Status = STATUS_INTERNAL_ERROR;
|
||
goto Cleanup;
|
||
}
|
||
} else {
|
||
TrustedDomain->DnsDomainName = NULL;
|
||
}
|
||
|
||
|
||
Status = STATUS_SUCCESS;
|
||
|
||
|
||
//
|
||
//
|
||
Cleanup:
|
||
|
||
return Status;
|
||
}
|
||
|
||
|
||
NTSTATUS
|
||
NlGetNt4TrustedDomainList (
|
||
IN LPWSTR UncDcName,
|
||
IN PUNICODE_STRING InNetbiosDomainName OPTIONAL,
|
||
IN PUNICODE_STRING InDnsDomainName OPTIONAL,
|
||
IN PSID DomainSid OPTIONAL,
|
||
IN GUID *DomainGuid OPTIONAL,
|
||
OUT PDS_DOMAIN_TRUSTSW *ForestTrustList,
|
||
OUT PULONG ForestTrustListSize,
|
||
OUT PULONG ForestTrustListCount
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Get the list of trusted domains from the specified DC using NT 4 protocols.
|
||
|
||
Arguments:
|
||
|
||
UncDcName - Specifies the name of a DC in the domain.
|
||
|
||
InNetbiosDomainName - Netbios domain of the domain Dc is in.
|
||
|
||
InDnsDomainName - Dns domain of the domain Dc is in.
|
||
|
||
DomainSid - Sid of the domain Dc is in.
|
||
|
||
DomainGuid - Guid of the domain Dc is in.
|
||
|
||
ForestTrustList - Returns a list of trusted domains.
|
||
Must be freed using NetApiBufferFree
|
||
|
||
ForestTrustListSize - Size (in bytes) of ForestTrustList
|
||
|
||
ForestTrustListCount - Number of entries in ForestTrustList
|
||
|
||
Return Value:
|
||
|
||
STATUS_SUCCESS - if the trust list was successfully returned
|
||
|
||
--*/
|
||
{
|
||
NTSTATUS Status;
|
||
NET_API_STATUS NetStatus;
|
||
|
||
LSA_HANDLE LsaHandle = NULL;
|
||
UNICODE_STRING UncDcNameString;
|
||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||
|
||
LSA_ENUMERATION_HANDLE EnumerationContext;
|
||
BOOLEAN AllDone = FALSE;
|
||
PPOLICY_PRIMARY_DOMAIN_INFO PrimaryDomainInfo = NULL;
|
||
|
||
PLSA_TRUST_INFORMATION TrustList = NULL;
|
||
BUFFER_DESCRIPTOR BufferDescriptor;
|
||
PDS_DOMAIN_TRUSTSW TrustedDomain;
|
||
DWORD Size;
|
||
|
||
//
|
||
// Initialization
|
||
//
|
||
|
||
*ForestTrustListCount = 0;
|
||
*ForestTrustListSize = 0;
|
||
*ForestTrustList = NULL;
|
||
BufferDescriptor.Buffer = NULL;
|
||
|
||
|
||
//
|
||
// Open the policy database on the DC
|
||
//
|
||
|
||
RtlInitUnicodeString( &UncDcNameString, UncDcName );
|
||
|
||
InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL, NULL );
|
||
|
||
Status = LsaOpenPolicy( &UncDcNameString,
|
||
&ObjectAttributes,
|
||
POLICY_VIEW_LOCAL_INFORMATION,
|
||
&LsaHandle );
|
||
|
||
if ( !NT_SUCCESS(Status) ) {
|
||
|
||
NlPrint((NL_CRITICAL,
|
||
"NlGetNt4TrustedDomainList: %ws: LsaOpenPolicy failed: %lx\n",
|
||
UncDcName,
|
||
Status ));
|
||
|
||
LsaHandle = NULL;
|
||
goto Cleanup;
|
||
|
||
}
|
||
|
||
//
|
||
// If the caller didn't specify primary domain information,
|
||
// get it from the DC
|
||
//
|
||
|
||
|
||
if ( InNetbiosDomainName == NULL ) {
|
||
|
||
//
|
||
// Get the name of the primary domain from LSA
|
||
//
|
||
Status = LsaQueryInformationPolicy(
|
||
LsaHandle,
|
||
PolicyPrimaryDomainInformation,
|
||
(PVOID *) &PrimaryDomainInfo
|
||
);
|
||
|
||
if (! NT_SUCCESS(Status)) {
|
||
NlPrint(( NL_CRITICAL,
|
||
"NlGetNt4TrustedDomainList: LsaQueryInformationPolicy failed %lx\n",
|
||
Status));
|
||
goto Cleanup;
|
||
}
|
||
|
||
|
||
//
|
||
// Grab the returned information
|
||
//
|
||
|
||
InNetbiosDomainName = &PrimaryDomainInfo->Name;
|
||
InDnsDomainName = NULL;
|
||
DomainSid = PrimaryDomainInfo->Sid;
|
||
DomainGuid = NULL;
|
||
}
|
||
|
||
//
|
||
// The LsaEnumerateTrustedDomain doesn't have the PrimaryDomain in the trust list.
|
||
// Add it to our list here.
|
||
//
|
||
|
||
Status = NlAllocateForestTrustListEntry (
|
||
&BufferDescriptor,
|
||
InNetbiosDomainName,
|
||
InDnsDomainName,
|
||
DS_DOMAIN_PRIMARY,
|
||
0, // No ParentIndex
|
||
TRUST_TYPE_DOWNLEVEL,
|
||
0, // No TrustAttributes
|
||
DomainSid,
|
||
DomainGuid,
|
||
&Size,
|
||
&TrustedDomain );
|
||
|
||
if ( !NT_SUCCESS(Status) ) {
|
||
goto Cleanup;
|
||
}
|
||
|
||
*ForestTrustListSize += Size;
|
||
(*ForestTrustListCount) ++;
|
||
|
||
//
|
||
// Loop getting a list of trusted domains
|
||
//
|
||
|
||
EnumerationContext = 0;
|
||
|
||
do {
|
||
ULONG i;
|
||
ULONG CountReturned;
|
||
|
||
//
|
||
// Free any buffers from a previous iteration.
|
||
//
|
||
if ( TrustList != NULL ) {
|
||
(VOID) LsaFreeMemory( TrustList );
|
||
}
|
||
|
||
//
|
||
// Get more trusted domains names
|
||
//
|
||
|
||
Status = LsaEnumerateTrustedDomains(
|
||
LsaHandle,
|
||
&EnumerationContext,
|
||
(PVOID *) &TrustList,
|
||
0xFFFFFFFF,
|
||
&CountReturned );
|
||
|
||
if ( Status == STATUS_NO_MORE_ENTRIES ) {
|
||
AllDone = TRUE;
|
||
Status = STATUS_SUCCESS;
|
||
}
|
||
|
||
if ( !NT_SUCCESS(Status) ) {
|
||
|
||
NlPrint((NL_CRITICAL,
|
||
"NlGetNt4TrustedDomainList: %ws: LsaEnumerateTrustedDomains failed: %lx\n",
|
||
UncDcName,
|
||
Status ));
|
||
|
||
TrustList = NULL;
|
||
goto Cleanup;
|
||
}
|
||
|
||
|
||
//
|
||
// Handle each trusted domain.
|
||
//
|
||
|
||
for ( i=0; i<CountReturned; i++ ) {
|
||
|
||
Status = NlAllocateForestTrustListEntry (
|
||
&BufferDescriptor,
|
||
&TrustList[i].Name,
|
||
NULL, // No DNS domain name
|
||
DS_DOMAIN_DIRECT_OUTBOUND,
|
||
0, // No ParentIndex
|
||
TRUST_TYPE_DOWNLEVEL,
|
||
0, // No TrustAttributes
|
||
TrustList[i].Sid,
|
||
NULL, // No DomainGuid
|
||
&Size,
|
||
&TrustedDomain );
|
||
|
||
if ( !NT_SUCCESS(Status) ) {
|
||
goto Cleanup;
|
||
}
|
||
|
||
//
|
||
// Account for the newly allocated entry
|
||
//
|
||
|
||
*ForestTrustListSize += Size;
|
||
(*ForestTrustListCount) ++;
|
||
|
||
}
|
||
|
||
} while ( !AllDone );
|
||
|
||
*ForestTrustList = (PDS_DOMAIN_TRUSTSW) BufferDescriptor.Buffer;
|
||
BufferDescriptor.Buffer = NULL;
|
||
Status = STATUS_SUCCESS;
|
||
|
||
//
|
||
// Free any locally used resources.
|
||
//
|
||
Cleanup:
|
||
|
||
if ( LsaHandle != NULL ) {
|
||
(VOID) LsaClose( LsaHandle );
|
||
}
|
||
|
||
if ( TrustList != NULL ) {
|
||
(VOID) LsaFreeMemory( TrustList );
|
||
}
|
||
|
||
if ( BufferDescriptor.Buffer != NULL ) {
|
||
NetApiBufferFree( BufferDescriptor.Buffer );
|
||
}
|
||
|
||
if ( PrimaryDomainInfo != NULL ) {
|
||
(void) LsaFreeMemory( PrimaryDomainInfo );
|
||
}
|
||
|
||
return Status;
|
||
}
|
||
|
||
|
||
|
||
NTSTATUS
|
||
NlRpcpBindRpc(
|
||
IN LPWSTR ServerName,
|
||
IN LPWSTR ServiceName,
|
||
IN LPWSTR NetworkOptions,
|
||
IN NL_RPC_BINDING RpcBindingType,
|
||
OUT RPC_BINDING_HANDLE *pBindingHandle
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Binds to the RPC server if possible.
|
||
|
||
Arguments:
|
||
|
||
ServerName - Name of server to bind with.
|
||
|
||
ServiceName - Name of service to bind with.
|
||
|
||
RpcBindingType - Determines whether to use unauthenticated TCP/IP transport instead of
|
||
a named pipe.
|
||
|
||
pBindingHandle - Location where binding handle is to be placed
|
||
|
||
Return Value:
|
||
|
||
STATUS_SUCCESS - The binding has been successfully completed.
|
||
|
||
STATUS_INVALID_COMPUTER_NAME - The ServerName syntax is invalid.
|
||
|
||
STATUS_NO_MEMORY - There is not sufficient memory available to the
|
||
caller to perform the binding.
|
||
|
||
--*/
|
||
|
||
{
|
||
RPC_STATUS RpcStatus;
|
||
LPWSTR StringBinding;
|
||
WCHAR ComputerName[MAX_COMPUTERNAME_LENGTH + 1];
|
||
LPWSTR NewServerName = NULL;
|
||
DWORD bufLen = MAX_COMPUTERNAME_LENGTH + 1;
|
||
|
||
//
|
||
// If we're supposed to use named pipes,
|
||
// call the standard routine.
|
||
//
|
||
|
||
if ( RpcBindingType == UseNamedPipe ) {
|
||
return RpcpBindRpc( ServerName, ServiceName, NetworkOptions, pBindingHandle );
|
||
}
|
||
|
||
//
|
||
// Otherwise, use TCP/IP directly.
|
||
//
|
||
|
||
*pBindingHandle = NULL;
|
||
|
||
if (ServerName != NULL) {
|
||
if (GetComputerNameW(ComputerName,&bufLen)) {
|
||
if ((_wcsicmp(ComputerName,ServerName) == 0) ||
|
||
((ServerName[0] == '\\') &&
|
||
(ServerName[1] == '\\') &&
|
||
(_wcsicmp(ComputerName,&(ServerName[2]))==0))) {
|
||
NewServerName = NULL;
|
||
}
|
||
else {
|
||
NewServerName = ServerName;
|
||
}
|
||
}
|
||
}
|
||
|
||
//
|
||
// Ditch the \\
|
||
//
|
||
if ( NewServerName != NULL &&
|
||
NewServerName[0] == '\\' &&
|
||
NewServerName[1] == '\\' ) {
|
||
NewServerName += 2;
|
||
}
|
||
|
||
//
|
||
// Enpoint isn't known.
|
||
// Rpc will contact the endpoint mapper for it.
|
||
//
|
||
RpcStatus = RpcStringBindingComposeW(0, L"ncacn_ip_tcp", NewServerName,
|
||
NULL, NetworkOptions, &StringBinding);
|
||
|
||
if ( RpcStatus != RPC_S_OK ) {
|
||
return( STATUS_NO_MEMORY );
|
||
}
|
||
|
||
RpcStatus = RpcBindingFromStringBindingW(StringBinding, pBindingHandle);
|
||
RpcStringFreeW(&StringBinding);
|
||
if ( RpcStatus != RPC_S_OK ) {
|
||
*pBindingHandle = NULL;
|
||
if ( RpcStatus == RPC_S_INVALID_ENDPOINT_FORMAT ||
|
||
RpcStatus == RPC_S_INVALID_NET_ADDR ) {
|
||
|
||
return( STATUS_INVALID_COMPUTER_NAME );
|
||
}
|
||
if ( RpcStatus == RPC_S_PROTSEQ_NOT_SUPPORTED ) {
|
||
return RPC_NT_PROTSEQ_NOT_SUPPORTED;
|
||
}
|
||
return(STATUS_NO_MEMORY);
|
||
}
|
||
return(STATUS_SUCCESS);
|
||
}
|
||
|
||
|
||
BOOLEAN
|
||
NlDoingSetup(
|
||
VOID
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Returns TRUE if we're running setup.
|
||
|
||
Arguments:
|
||
|
||
NONE.
|
||
|
||
Return Status:
|
||
|
||
TRUE - We're currently running setup
|
||
FALSE - We're not running setup or aren't sure.
|
||
|
||
--*/
|
||
|
||
{
|
||
DWORD Value;
|
||
|
||
if ( !NlReadDwordHklmRegValue( "SYSTEM\\Setup",
|
||
"SystemSetupInProgress",
|
||
&Value ) ) {
|
||
return FALSE;
|
||
}
|
||
|
||
if ( Value != 1 ) {
|
||
// NlPrint(( 0, "NlDoingSetup: not doing setup\n" ));
|
||
return FALSE;
|
||
}
|
||
|
||
NlPrint(( 0, "NlDoingSetup: doing setup\n" ));
|
||
return TRUE;
|
||
}
|
||
|
||
#endif // WIN32_CHICAGO
|