You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
763 lines
19 KiB
763 lines
19 KiB
/*++
|
|
|
|
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
|