|
|
/*++
Copyright (c) 1991-1992 Microsoft Corporation
Module Name:
wksstub.c
Abstract:
Client stubs of the Browser service APIs.
Author:
Rita Wong (ritaw) 10-May-1991 Larry Osterman (LarryO) 23-Mar-1992
Environment:
User Mode - Win32
Revision History:
18-Jun-1991 JohnRo Remote NetUse APIs to downlevel servers. 24-Jul-1991 JohnRo Use NET_REMOTE_TRY_RPC etc macros for NetUse APIs. Moved NetpIsServiceStarted() into NetLib. 25-Jul-1991 JohnRo Quiet DLL stub debug output. 19-Aug-1991 JohnRo Implement downlevel NetWksta APIs. Use NetRpc.h for NetWksta APIs. 07-Nov-1991 JohnRo RAID 4186: assert in RxNetShareAdd and other DLL stub problems. 19-Nov-1991 JohnRo Make sure status is correct for APIs not supported on downlevel. Implement remote NetWkstaUserEnum(). 09-Nov-1992 JohnRo Fix NET_API_FUNCTION references. Avoid compiler warnings. --*/
#include "brclient.h"
#undef IF_DEBUG // avoid wsclient.h vs. debuglib.h conflicts.
#include <debuglib.h> // IF_DEBUG() (needed by netrpc.h).
#include <lmserver.h>
#include <lmsvc.h>
#include <rxuse.h> // RxNetUse APIs.
#include <rxwksta.h> // RxNetWksta and RxNetWkstaUser APIs.
#include <rap.h> // Needed by rxserver.h
#include <rxserver.h> // RxNetServerEnum API.
#include <netlib.h> // NetpServiceIsStarted() (needed by netrpc.h).
#include <ntddbrow.h> // Browser definitions
#include <netrpc.h> // NET_REMOTE macros.
#include <align.h>
#include <tstr.h>
#include <tstring.h> // NetpInitOemString().
#include <brcommon.h> // Routines common between client & server
#include <lmapibuf.h> // NetApiBufferFree().
#include <lmbrowsr.h> // Definition of I_BrowserServerEnum
#include <icanon.h>
#include <lmapibuf.h>
#include "cscp.h"
//-------------------------------------------------------------------//
// //
// Global variables //
// //
//-------------------------------------------------------------------//
#define API_SUCCESS(x) ((x) == NERR_Success || (x) == ERROR_MORE_DATA)
//-------------------------------------------------------------------//
// //
// Global types //
// //
//-------------------------------------------------------------------//
//-------------------------------------------------------------------//
// //
// Private routines //
// //
//-------------------------------------------------------------------//
NET_API_STATUS GetBrowserTransportList( OUT PLMDR_TRANSPORT_LIST *TransportList );
NET_API_STATUS EnumServersForTransport( IN PUNICODE_STRING TransportName, IN LPCWSTR DomainName OPTIONAL, IN ULONG level, IN ULONG prefmaxlen, IN ULONG servertype, IN LPTSTR CurrentComputerName, OUT PINTERIM_SERVER_LIST InterimServerList, OUT PULONG TotalEntriesOnThisTransport, IN LPCWSTR FirstNameToReturn, IN BOOLEAN WannishTransport, IN BOOLEAN RasTransport, IN BOOLEAN IPXTransport );
#if DBG
void ValidateServerList( IN PVOID ServerList, IN ULONG ulLevel, IN ULONG ulEntries ); #else
#define ValidateServerList(x,y,z)
#endif
NET_API_STATUS NET_API_FUNCTION NetServerEnum( IN LPCWSTR servername OPTIONAL, IN DWORD level, OUT LPBYTE *bufptr, IN DWORD prefmaxlen, OUT LPDWORD entriesread, OUT LPDWORD totalentries, IN DWORD servertype, IN LPCWSTR domain OPTIONAL, IN OUT LPDWORD resume_handle OPTIONAL ) /*++
Routine Description:
This is the DLL entrypoint for NetServerEnum.
Arguments:
servername - Supplies the name of server to execute this function
level - Supplies the requested level of information.
bufptr - Returns a pointer to a buffer which contains the requested transport information.
prefmaxlen - Supplies the number of bytes of information to return in the buffer. If this value is MAXULONG, we will try to return all available information if there is enough memory resource.
entriesread - Returns the number of entries read into the buffer. This value is returned only if the return code is NERR_Success or ERROR_MORE_DATA.
totalentries - Returns the total number of entries available. This value is returned only if the return code is NERR_Success or ERROR_MORE_DATA.
servertype - Supplies the type of server to enumerate.
domain - Supplies the name of one of the active domains to enumerate the servers from. If NULL, servers from the primary domain, logon domain and other domains are enumerated.
resume_handle - Supplies and returns the point to continue with enumeration.
Return Value:
NET_API_STATUS - NERR_Success or reason for failure.
--*/ { NET_API_STATUS NetStatus;
//
// NetServerEnum is simply a wrapper to NetServerEnumEx
//
NetStatus = NetServerEnumEx( servername, level, bufptr, prefmaxlen, entriesread, totalentries, servertype, domain, NULL ); // NULL FirstNameToReturn
if (ARGUMENT_PRESENT(resume_handle)) { *resume_handle = 0; }
return NetStatus;
}
NET_API_STATUS NET_API_FUNCTION NetServerEnumEx( IN LPCWSTR servername OPTIONAL, IN DWORD level, OUT LPBYTE *bufptr, IN DWORD prefmaxlen, OUT LPDWORD entriesread, OUT LPDWORD totalentries, IN DWORD servertype, IN LPCWSTR domain OPTIONAL, IN LPCWSTR FirstNameToReturnArg OPTIONAL ) /*++
Routine Description:
This is the DLL entrypoint for NetServerEnum.
Arguments:
servername - Supplies the name of server to execute this function
level - Supplies the requested level of information.
bufptr - Returns a pointer to a buffer which contains the requested transport information.
prefmaxlen - Supplies the number of bytes of information to return in the buffer. If this value is MAXULONG, we will try to return all available information if there is enough memory resource.
entriesread - Returns the number of entries read into the buffer. This value is returned only if the return code is NERR_Success or ERROR_MORE_DATA.
totalentries - Returns the total number of entries available. This value is returned only if the return code is NERR_Success or ERROR_MORE_DATA.
servertype - Supplies the type of server to enumerate.
domain - Supplies the name of one of the active domains to enumerate the servers from. If NULL, servers from the primary domain, logon domain and other domains are enumerated.
FirstNameToReturnArg - Supplies the name of the first domain or server entry to return. The caller can use this parameter to implement a resume handle of sorts by passing the name of the last entry returned on a previous call. (Notice that the specified entry will, also, be returned on this call unless it has since been deleted.) Pass NULL (or a zero length string) to start with the first entry available.
Return Value:
NET_API_STATUS - NERR_Success or reason for failure.
ERROR_MORE_DATA - More servers are available to be enumerated.
It is possible to return ERROR_MORE_DATA and zero entries in the case where the browser server used doesn't support enumerating all the entries it has. (e.g., an NT 3.5x Domain Master Browser that downloaded a domain list from WINS and the WINS list is more than 64Kb long.) The caller should simply ignore the additional data.
It is possible to fail to return ERROR_MORE_DATA and return a truncated list. (e.g., an NT 3.5x Backup browser or WIN 95 backup browser in the above mentioned domain. Such a backup browser replicates only 64kb of data from the DMB (PDC) then represents that list as the entire list.) The caller should ignore this problem. The site should upgrade its browser servers.
--*/ { PLMDR_TRANSPORT_LIST TransportList = NULL; PLMDR_TRANSPORT_LIST TransportEntry = NULL; INTERIM_SERVER_LIST InterimServerList; NET_API_STATUS Status; DWORD DomainNameSize = 0; TCHAR DomainName[DNLEN + 1]; WCHAR FirstNameToReturn[DNLEN+1]; DWORD LocalTotalEntries; BOOLEAN AnyTransportHasMoreData = FALSE;
//
//
// The workstation has to be started for the NetServerEnum API to work.
//
//
if ((Status = CheckForService(SERVICE_WORKSTATION, NULL)) != NERR_Success) { return Status; }
#ifdef ENABLE_PSEUDO_BROWSER
//
// Disabled NetServerEnum check
//
if ( !IsEnumServerEnabled() || GetBrowserPseudoServerLevel() == BROWSER_PSEUDO ) { // NetServerEnum is disabled or pseudo server is
// enabled on box ==> return no entries.
*entriesread = 0; *totalentries = 0; *bufptr = NULL; return NERR_Success; } #endif
//
// Canonicalize the input parameters to make later comparisons easier.
//
if (ARGUMENT_PRESENT(domain)) {
if ( I_NetNameCanonicalize( NULL, (LPWSTR) domain, DomainName, (DNLEN + 1) * sizeof(TCHAR), NAMETYPE_WORKGROUP, LM2X_COMPATIBLE ) != NERR_Success) { return ERROR_INVALID_PARAMETER; }
DomainNameSize = STRLEN(DomainName) * sizeof(WCHAR);
domain = DomainName; }
if (ARGUMENT_PRESENT(FirstNameToReturnArg) && *FirstNameToReturnArg != L'\0') {
if ( I_NetNameCanonicalize( NULL, (LPWSTR) FirstNameToReturnArg, FirstNameToReturn, sizeof(FirstNameToReturn), NAMETYPE_WORKGROUP, LM2X_COMPATIBLE ) != NERR_Success) { return ERROR_INVALID_PARAMETER; }
} else { FirstNameToReturn[0] = L'\0'; }
if ((servername != NULL) && ( *servername != TCHAR_EOS)) {
//
// Call downlevel version of the API
//
Status = RxNetServerEnum( servername, NULL, level, bufptr, prefmaxlen, entriesread, totalentries, servertype, domain, FirstNameToReturn );
return Status; }
//
// Only levels 100 and 101 are valid
//
if ((level != 100) && (level != 101)) { return ERROR_INVALID_LEVEL; }
if (servertype != SV_TYPE_ALL) { if (servertype & SV_TYPE_DOMAIN_ENUM) { if (servertype != SV_TYPE_DOMAIN_ENUM) { return ERROR_INVALID_FUNCTION; } } }
//
// Initialize the buffer to a known value.
//
*bufptr = NULL;
*entriesread = 0;
*totalentries = 0;
//
// If we are off-line, give CSC a chance to do the enumeration
//
if( !ARGUMENT_PRESENT( servername ) && (servertype & SV_TYPE_SERVER) && CSCIsOffline() ) {
Status = CSCNetServerEnumEx( level, bufptr, prefmaxlen, entriesread, totalentries ); if( Status == NERR_Success ) { return Status; } }
Status = InitializeInterimServerList(&InterimServerList, NULL, NULL, NULL, NULL);
try { BOOL AnyEnumServersSucceeded = FALSE; LPTSTR MyComputerName = NULL;
Status = NetpGetComputerName( &MyComputerName);
if ( Status != NERR_Success ) { goto try_exit; }
//
// Retrieve the list of transports from the browser.
//
Status = GetBrowserTransportList(&TransportList);
if (Status != NERR_Success) { goto try_exit; }
TransportEntry = TransportList;
while (TransportEntry != NULL) { UNICODE_STRING TransportName;
TransportName.Buffer = TransportEntry->TransportName; TransportName.Length = (USHORT)TransportEntry->TransportNameLength; TransportName.MaximumLength = (USHORT)TransportEntry->TransportNameLength;
Status = EnumServersForTransport(&TransportName, domain, level, prefmaxlen, servertype, MyComputerName, &InterimServerList, &LocalTotalEntries, FirstNameToReturn, (BOOLEAN)((TransportEntry->Flags & LMDR_TRANSPORT_WANNISH) != 0), (BOOLEAN)((TransportEntry->Flags & LMDR_TRANSPORT_RAS) != 0), (BOOLEAN)((TransportEntry->Flags & LMDR_TRANSPORT_IPX) != 0));
if (API_SUCCESS(Status)) { if ( Status == ERROR_MORE_DATA ) { AnyTransportHasMoreData = TRUE; } AnyEnumServersSucceeded = TRUE; if ( LocalTotalEntries > *totalentries ) { *totalentries = LocalTotalEntries; } }
if (TransportEntry->NextEntryOffset == 0) { TransportEntry = NULL; } else { TransportEntry = (PLMDR_TRANSPORT_LIST)((PCHAR)TransportEntry+TransportEntry->NextEntryOffset); }
}
if ( MyComputerName != NULL ) { (void) NetApiBufferFree( MyComputerName ); }
if (AnyEnumServersSucceeded) {
//
// Pack the interim server list into its final form.
//
Status = PackServerList(&InterimServerList, level, servertype, prefmaxlen, (PVOID *)bufptr, entriesread, &LocalTotalEntries, // Pack thinks it has ALL the entries
NULL ); // The server has already returned us the right entries
if ( API_SUCCESS( Status ) ) { if ( LocalTotalEntries > *totalentries ) { *totalentries = LocalTotalEntries; } } }
try_exit:NOTHING; } finally { if (TransportList != NULL) { MIDL_user_free(TransportList); }
UninitializeInterimServerList(&InterimServerList); }
if ( API_SUCCESS( Status )) {
//
// At this point,
// *totalentries is the largest of:
// The TotalEntries returned from any transport.
// The actual number of entries read.
//
// Adjust TotalEntries returned for reality.
//
if ( Status == NERR_Success ) { *totalentries = *entriesread; } else { if ( *totalentries <= *entriesread ) { *totalentries = *entriesread + 1; } }
//
// Ensure we return ERROR_MORE_DATA if any transport has more data.
//
if ( AnyTransportHasMoreData ) { Status = ERROR_MORE_DATA; } }
return Status; }
NET_API_STATUS EnumServersForTransport( IN PUNICODE_STRING TransportName, IN LPCWSTR DomainName OPTIONAL, IN ULONG level, IN ULONG prefmaxlen, IN ULONG servertype, IN LPTSTR CurrentComputerName, OUT PINTERIM_SERVER_LIST InterimServerList, OUT PULONG TotalEntriesOnThisTransport, IN LPCWSTR FirstNameToReturn, IN BOOLEAN WannishTransport, IN BOOLEAN RasTransport, IN BOOLEAN IpxTransport ) { PWSTR *BrowserList = NULL; ULONG BrowserListLength = 0; NET_API_STATUS Status; PVOID ServerList = NULL; ULONG EntriesInList = 0; ULONG ServerIndex = 0;
//
// Skip over IPX transports - we can't contact machines over them anyway.
//
*TotalEntriesOnThisTransport = 0;
if (IpxTransport) { return NERR_Success; }
//
// Retrieve a new browser list. Do not force a revalidation.
//
Status = GetBrowserServerList(TransportName, DomainName, &BrowserList, &BrowserListLength, FALSE);
//
// If a domain name was specified and we were unable to find the browse
// master for the domain and we are running on a wannish transport,
// invoke the "double hop" code and allow a local browser server
// remote the API to the browse master for that domain (we assume that
// this means that the workgroup is on a different subnet of a WAN).
//
if (!API_SUCCESS(Status) && DomainName != NULL) {
Status = GetBrowserServerList(TransportName, NULL, &BrowserList, &BrowserListLength, FALSE);
}
//
// If we were able to retrieve the list, remote the API. Otherwise
// return.
//
if (API_SUCCESS(Status) && BrowserList) {
do { LPTSTR Transport; LPTSTR ServerName; BOOL AlreadyInTree;
//
// Remote the API to that server.
//
Transport = TransportName->Buffer; ServerName = BrowserList[0]; *TotalEntriesOnThisTransport = 0;
// add 2 to skip double backslash at start of ServerName
if ( STRICMP(ServerName + 2, CurrentComputerName ) == 0 ) {
//
// If we are going to remote the API to ourselves,
// and we are running the browser service, simply
// use RPC to get the information we need, don't
// bother using the redirector. This allows us to
// avoid tying up RPCXLATE thread.
//
Status = I_BrowserServerEnumEx ( NULL, Transport, CurrentComputerName, level, (LPBYTE *)&ServerList, prefmaxlen, &EntriesInList, TotalEntriesOnThisTransport, servertype, DomainName, FirstNameToReturn );
} else {
Status = RxNetServerEnum( ServerName, Transport, level, (LPBYTE *)&ServerList, prefmaxlen, &EntriesInList, TotalEntriesOnThisTransport, servertype, DomainName, FirstNameToReturn );
}
if ( !API_SUCCESS(Status)) { NET_API_STATUS GetBListStatus;
//
// If we failed to remote the API for some reason,
// we want to regenerate the bowsers list of browser
// servers.
//
if (BrowserList != NULL) {
MIDL_user_free(BrowserList);
BrowserList = NULL; }
GetBListStatus = GetBrowserServerList(TransportName, DomainName, &BrowserList, &BrowserListLength, TRUE); if (GetBListStatus != NERR_Success) {
//
// If we were unable to reload the list,
// try the next transport.
//
break; }
ServerIndex += 1;
//
// If we've looped more times than we got servers
// in the list, we're done.
//
if ( ServerIndex > BrowserListLength ) { break; }
} else {
NET_API_STATUS TempStatus;
TempStatus = MergeServerList( InterimServerList, level, ServerList, EntriesInList, *TotalEntriesOnThisTransport );
if ( TempStatus != NERR_Success ) { Status = TempStatus; }
//
// The remote API succeeded.
//
// Now free up the remaining parts of the list.
//
if (ServerList != NULL) { NetApiBufferFree(ServerList); ServerList = NULL; }
// We're done regardless of the success or failure of MergeServerList.
break;
}
} while ( !API_SUCCESS(Status) );
}
//
// Free up the browser list.
//
if (BrowserList != NULL) { MIDL_user_free(BrowserList); BrowserList = NULL; }
return Status; }
NET_API_STATUS GetBrowserTransportList( OUT PLMDR_TRANSPORT_LIST *TransportList )
/*++
Routine Description:
This routine returns the list of transports bound into the browser.
Arguments:
OUT PLMDR_TRANSPORT_LIST *TransportList - Transport list to return.
Return Value:
NET_API_STATUS - NERR_Success or reason for failure.
--*/
{
NET_API_STATUS Status; HANDLE BrowserHandle; LMDR_REQUEST_PACKET RequestPacket;
Status = OpenBrowser(&BrowserHandle);
if (Status != NERR_Success) { return Status; }
ZeroMemory(&RequestPacket, sizeof(RequestPacket)); RequestPacket.Version = LMDR_REQUEST_PACKET_VERSION_DOM;
RequestPacket.Type = EnumerateXports;
RtlInitUnicodeString(&RequestPacket.TransportName, NULL); RtlInitUnicodeString(&RequestPacket.EmulatedDomainName, NULL);
Status = DeviceControlGetInfo( BrowserHandle, IOCTL_LMDR_ENUMERATE_TRANSPORTS, &RequestPacket, sizeof(RequestPacket), (PVOID *)TransportList, 0xffffffff, 4096, NULL);
NtClose(BrowserHandle);
return Status; }
NET_API_STATUS I_BrowserServerEnum ( IN LPCWSTR servername OPTIONAL, IN LPCWSTR transport OPTIONAL, IN LPCWSTR clientname OPTIONAL, IN DWORD level, OUT LPBYTE *bufptr, IN DWORD prefmaxlen, OUT LPDWORD entriesread, OUT LPDWORD totalentries, IN DWORD servertype, IN LPCWSTR domain OPTIONAL, IN OUT LPDWORD resume_handle OPTIONAL )
/*++
Routine Description:
This is the DLL entrypoint for NetWkstaSetInfo.
Arguments:
servername - Supplies the name of server to execute this function
level - Supplies the level of information.
buf - Supplies a buffer which contains the information structure of fields to set. The level denotes the structure in this buffer.
parm_err - Returns the identifier to the invalid parameter in buf if this function returns ERROR_INVALID_PARAMETER.
Return Value:
NET_API_STATUS - NERR_Success or reason for failure.
--*/ { NET_API_STATUS status; GENERIC_INFO_CONTAINER GenericInfoContainer; GENERIC_ENUM_STRUCT InfoStruct;
GenericInfoContainer.Buffer = NULL; GenericInfoContainer.EntriesRead = 0;
InfoStruct.Container = &GenericInfoContainer; InfoStruct.Level = level;
NET_REMOTE_TRY_RPC
//
// Try RPC (local or remote) version of API.
//
status = I_BrowserrServerEnum( (LPWSTR) servername, (LPWSTR) transport, (LPWSTR) clientname, (LPSERVER_ENUM_STRUCT)&InfoStruct, prefmaxlen, totalentries, servertype, (LPWSTR) domain, resume_handle );
if (status == NERR_Success || status == ERROR_MORE_DATA) { *bufptr = (LPBYTE) GenericInfoContainer.Buffer; *entriesread = GenericInfoContainer.EntriesRead;
#if 0
if (((servertype == SV_TYPE_ALL || servertype == SV_TYPE_DOMAIN_ENUM)) && (STRICMP(transport, L"\\Device\\Streams\\NBT"))) { if (*entriesread <= 20) { KdPrint(("RPC API Returned EntriesRead == %ld on transport %ws\n", *entriesread, transport)); } if (*totalentries <= 20) { KdPrint(("RPC API Returned TotalEntries == %ld on transport %ws\n", *totalentries, transport)); } } #endif
}
NET_REMOTE_RPC_FAILED("I_BrServerEnum", servername, status, NET_REMOTE_FLAG_NORMAL, SERVICE_BROWSER )
//
// There is no downlevel version of api.
//
status = ERROR_NOT_SUPPORTED;
NET_REMOTE_END
#if 0
if ((servertype == SV_TYPE_ALL || servertype == SV_TYPE_DOMAIN_ENUM) && (STRICMP(transport, L"\\Device\\Streams\\NBT"))) { if (*entriesread <= 20) { KdPrint(("Client API Returned EntriesRead == %ld on transport %ws\n", *entriesread, transport)); } if (*totalentries <= 20) { KdPrint(("Client API Returned TotalEntries == %ld on transport %ws\n", *totalentries, transport)); } } #endif
return status; }
NET_API_STATUS I_BrowserServerEnumEx ( IN LPCWSTR servername OPTIONAL, IN LPCWSTR transport OPTIONAL, IN LPCWSTR clientname OPTIONAL, IN DWORD level, OUT LPBYTE *bufptr, IN DWORD prefmaxlen, OUT LPDWORD entriesread, OUT LPDWORD totalentries, IN DWORD servertype, IN LPCWSTR domain OPTIONAL, IN LPCWSTR FirstNameToReturn OPTIONAL )
/*++
Routine Description:
This is the DLL entrypoint for NetWkstaSetInfo.
Arguments:
servername - Supplies the name of server to execute this function
level - Supplies the level of information.
buf - Supplies a buffer which contains the information structure of fields to set. The level denotes the structure in this buffer.
parm_err - Returns the identifier to the invalid parameter in buf if this function returns ERROR_INVALID_PARAMETER.
FirstNameToReturn - Supplies the name of the first domain or server entry to return. The caller can use this parameter to implement a resume handle of sorts by passing the name of the last entry returned on a previous call. (Notice that the specified entry will, also, be returned on this call unless it has since been deleted.) Pass NULL to start with the first entry available.
Return Value:
NET_API_STATUS - NERR_Success or reason for failure.
--*/ { NET_API_STATUS status; GENERIC_INFO_CONTAINER GenericInfoContainer; GENERIC_ENUM_STRUCT InfoStruct;
GenericInfoContainer.Buffer = NULL; GenericInfoContainer.EntriesRead = 0;
InfoStruct.Container = &GenericInfoContainer; InfoStruct.Level = level;
NET_REMOTE_TRY_RPC
//
// Try RPC (local or remote) version of API.
//
status = I_BrowserrServerEnumEx( (LPWSTR) servername, (LPWSTR) transport, (LPWSTR) clientname, (LPSERVER_ENUM_STRUCT)&InfoStruct, prefmaxlen, totalentries, servertype, (LPWSTR) domain, (LPWSTR) FirstNameToReturn );
if (status == NERR_Success || status == ERROR_MORE_DATA) { *bufptr = (LPBYTE) GenericInfoContainer.Buffer; *entriesread = GenericInfoContainer.EntriesRead;
#if 0
if (((servertype == SV_TYPE_ALL || servertype == SV_TYPE_DOMAIN_ENUM)) && (STRICMP(transport, L"\\Device\\Streams\\NBT"))) { if (*entriesread <= 20) { KdPrint(("RPC API Returned EntriesRead == %ld on transport %ws\n", *entriesread, transport)); } if (*totalentries <= 20) { KdPrint(("RPC API Returned TotalEntries == %ld on transport %ws\n", *totalentries, transport)); } } #endif
}
NET_REMOTE_RPC_FAILED("I_BrServerEnum", servername, status, NET_REMOTE_FLAG_NORMAL, SERVICE_BROWSER )
//
// There is no downlevel version of api.
//
status = ERROR_NOT_SUPPORTED;
NET_REMOTE_END
#if 0
if ((servertype == SV_TYPE_ALL || servertype == SV_TYPE_DOMAIN_ENUM) && (STRICMP(transport, L"\\Device\\Streams\\NBT"))) { if (*entriesread <= 20) { KdPrint(("Client API Returned EntriesRead == %ld on transport %ws\n", *entriesread, transport)); } if (*totalentries <= 20) { KdPrint(("Client API Returned TotalEntries == %ld on transport %ws\n", *totalentries, transport)); } } #endif
return status; }
NET_API_STATUS NET_API_FUNCTION I_BrowserQueryOtherDomains ( IN LPCWSTR servername OPTIONAL, OUT LPBYTE *bufptr, OUT LPDWORD entriesread, OUT LPDWORD totalentries )
/*++
Routine Description:
This is the DLL entrypoint for NetWkstaSetInfo.
Arguments:
servername - Supplies the name of server to execute this function
buf - Supplies a buffer which contains the information structure of fields to set. The level denotes the structure in this buffer.
Return Value:
NET_API_STATUS - NERR_Success or reason for failure.
--*/ { NET_API_STATUS status; GENERIC_INFO_CONTAINER GenericInfoContainer; GENERIC_ENUM_STRUCT InfoStruct;
GenericInfoContainer.Buffer = NULL; GenericInfoContainer.EntriesRead = 0;
InfoStruct.Container = &GenericInfoContainer; InfoStruct.Level = 100;
NET_REMOTE_TRY_RPC
//
// Try RPC (local or remote) version of API.
//
status = I_BrowserrQueryOtherDomains ( (LPWSTR) servername, (LPSERVER_ENUM_STRUCT)&InfoStruct, totalentries );
if (status == NERR_Success || status == ERROR_MORE_DATA) { *bufptr = (LPBYTE) GenericInfoContainer.Buffer; *entriesread = GenericInfoContainer.EntriesRead; }
NET_REMOTE_RPC_FAILED("I_BrowserQueryOtherDomains", servername, status, NET_REMOTE_FLAG_NORMAL, SERVICE_BROWSER )
//
// There is no downlevel version of api.
//
status = ERROR_NOT_SUPPORTED;
NET_REMOTE_END
return status; } NET_API_STATUS I_BrowserResetNetlogonState ( IN LPCWSTR servername OPTIONAL )
/*++
Routine Description:
This is the DLL entrypoint for NetWkstaSetInfo.
Arguments:
servername - Supplies the name of server to execute this function
buf - Supplies a buffer which contains the information structure of fields to set. The level denotes the structure in this buffer.
Return Value:
NET_API_STATUS - NERR_Success or reason for failure.
--*/ { NET_API_STATUS status;
NET_REMOTE_TRY_RPC
//
// Try RPC (local or remote) version of API.
//
status = I_BrowserrResetNetlogonState ( (LPWSTR) servername );
NET_REMOTE_RPC_FAILED("I_BrowserResetNetlogonState", servername, status, NET_REMOTE_FLAG_NORMAL, SERVICE_BROWSER )
//
// There is no downlevel version of api.
//
status = ERROR_NOT_SUPPORTED;
NET_REMOTE_END
return status; }
NET_API_STATUS I_BrowserDebugCall ( IN LPTSTR servername OPTIONAL, IN DWORD DebugCode, IN DWORD Options ) { NET_API_STATUS status;
NET_REMOTE_TRY_RPC
//
// Try RPC (local or remote) version of API.
//
status = I_BrowserrDebugCall( servername, DebugCode, Options );
NET_REMOTE_RPC_FAILED("I_BrowserDebugCall", servername, status, NET_REMOTE_FLAG_NORMAL, SERVICE_BROWSER )
//
// There is no downlevel version of api.
//
status = ERROR_NOT_SUPPORTED;
NET_REMOTE_END
return status;
}
NET_API_STATUS I_BrowserDebugTrace ( IN LPTSTR servername OPTIONAL, IN PCHAR DebugString ) { NET_API_STATUS status;
NET_REMOTE_TRY_RPC
//
// Try RPC (local or remote) version of API.
//
status = I_BrowserrDebugTrace( servername, DebugString );
NET_REMOTE_RPC_FAILED("I_BrowserDebugTrace", servername, status, NET_REMOTE_FLAG_NORMAL, SERVICE_BROWSER )
//
// There is no downlevel version of api.
//
status = ERROR_NOT_SUPPORTED;
NET_REMOTE_END
return status;
}
NET_API_STATUS I_BrowserQueryStatistics ( IN LPCWSTR servername OPTIONAL, IN OUT LPBROWSER_STATISTICS *Statistics ) { NET_API_STATUS status;
NET_REMOTE_TRY_RPC
//
// Try RPC (local or remote) version of API.
//
status = I_BrowserrQueryStatistics( (LPWSTR) servername, Statistics );
NET_REMOTE_RPC_FAILED("I_BrowserQueryStatistics", servername, status, NET_REMOTE_FLAG_NORMAL, SERVICE_BROWSER )
//
// There is no downlevel version of api.
//
status = ERROR_NOT_SUPPORTED;
NET_REMOTE_END
return status;
}
NET_API_STATUS I_BrowserResetStatistics ( IN LPCWSTR servername OPTIONAL ) { NET_API_STATUS status;
NET_REMOTE_TRY_RPC
//
// Try RPC (local or remote) version of API.
//
status = I_BrowserrResetStatistics( (LPWSTR) servername );
NET_REMOTE_RPC_FAILED("I_BrowserResetStatistics", servername, status, NET_REMOTE_FLAG_NORMAL, SERVICE_BROWSER )
//
// There is no downlevel version of api.
//
status = ERROR_NOT_SUPPORTED;
NET_REMOTE_END
return status;
}
NET_API_STATUS NetBrowserStatisticsGet( IN LPTSTR ServerName, IN DWORD Level, OUT LPBYTE* Buffer )
/*++
Routine Description:
Wrapper for workstation statistics retrieval routine - either calls the client-side RPC function or calls RxNetStatisticsGet to retrieve the statistics from a down-level workstation service
Arguments:
ServerName - where to remote this function Level - of information required (100, or 101) Buffer - pointer to pointer to returned buffer
Return Value:
NET_API_STATUS Success - NERR_Success Failure - ERROR_INVALID_LEVEL Level not 0 ERROR_INVALID_PARAMETER Unsupported options requested ERROR_NOT_SUPPORTED Service is not SERVER or WORKSTATION ERROR_ACCESS_DENIED Caller doesn't have necessary access rights for request
--*/
{ NET_API_STATUS status; GENERIC_INFO_CONTAINER GenericInfoContainer; GENERIC_ENUM_STRUCT InfoStruct;
//
// set the caller's buffer pointer to known value. This will kill the
// calling app if it gave us a bad pointer and didn't use try...except
//
*Buffer = NULL;
//
// validate parms
//
if (Level != 100 && Level != 101) { return ERROR_INVALID_LEVEL; }
GenericInfoContainer.Buffer = NULL; GenericInfoContainer.EntriesRead = 0;
InfoStruct.Container = &GenericInfoContainer; InfoStruct.Level = Level;
NET_REMOTE_TRY_RPC status = NetrBrowserStatisticsGet(ServerName, Level, (PBROWSER_STATISTICS_STRUCT)&InfoStruct );
if (status == NERR_Success || status == ERROR_MORE_DATA) { *Buffer = (LPBYTE) GenericInfoContainer.Buffer; }
NET_REMOTE_RPC_FAILED("NetBrowserStatisticsGet", ServerName, status, NET_REMOTE_FLAG_NORMAL, SERVICE_BROWSER )
status = ERROR_NOT_SUPPORTED;
NET_REMOTE_END
return status; }
NET_API_STATUS I_BrowserSetNetlogonState( IN LPWSTR ServerName, IN LPWSTR DomainName, IN LPWSTR EmulatedComputerName, IN DWORD Role ) /*++
Routine Description:
This is the DLL entrypoint for I_BrowserSetNetlogonState.
Arguments:
servername - Supplies the name of server to execute this function
DomainName - name of the domain who's role is to be updated.
EmulatedComputerName - Name of the computer within DomainName
Role - Role of the specified domain.
Return Value:
NET_API_STATUS - NERR_Success or reason for failure.
--*/ { NET_API_STATUS status;
NET_REMOTE_TRY_RPC
//
// Try RPC (local or remote) version of API.
//
status = I_BrowserrSetNetlogonState ( ServerName, DomainName, EmulatedComputerName, Role );
NET_REMOTE_RPC_FAILED("I_BrowserSetNetlogonState", ServerName, status, NET_REMOTE_FLAG_NORMAL, SERVICE_BROWSER )
//
// There is no downlevel version of api.
//
status = ERROR_NOT_SUPPORTED;
NET_REMOTE_END
return status; }
NET_API_STATUS NET_API_FUNCTION I_BrowserQueryEmulatedDomains ( IN LPTSTR ServerName OPTIONAL, OUT PBROWSER_EMULATED_DOMAIN *EmulatedDomains, OUT LPDWORD EntriesRead )
/*++
Routine Description:
This is the DLL entrypoint for I_BrowserQueryEmulatedDomains.
Arguments:
ServerName - Supplies the name of server to execute this function
EmulatedDomains - Returns a pointer to a an allocated array of emulated domain information.
EntriesRead - Returns the number of entries in 'EmulatedDomains'
Return Value:
NET_API_STATUS - NERR_Success or reason for failure.
--*/ { NET_API_STATUS NetStatus; BROWSER_EMULATED_DOMAIN_CONTAINER Container;
// Force RPC to allocate the buffer
Container.Buffer = NULL; Container.EntriesRead = 0; *EmulatedDomains = NULL; *EntriesRead = 0;
NET_REMOTE_TRY_RPC
//
// Try RPC (local or remote) version of API.
//
NetStatus = I_BrowserrQueryEmulatedDomains ( ServerName, &Container );
if ( NetStatus == NERR_Success ) { *EmulatedDomains = (PBROWSER_EMULATED_DOMAIN) Container.Buffer; *EntriesRead = Container.EntriesRead; }
NET_REMOTE_RPC_FAILED("I_BrowserQueryEmulatedDomains", ServerName, NetStatus, NET_REMOTE_FLAG_NORMAL, SERVICE_BROWSER )
//
// There is no downlevel version of api.
//
NetStatus = ERROR_NOT_SUPPORTED;
NET_REMOTE_END
return NetStatus; }
#if DBG
void ValidateServerList( IN PVOID ServerList, IN ULONG ulLevel, IN ULONG ulEntries ) /*++
Routine Description (ValidateServerList):
Cycle through servers. Validate the content in the list of server
Arguments:
Return Value:
Remarks: None.
--*/ {
LONG i; ULONG ServerElementSize; PSERVER_INFO_101 ServerInfo = (PSERVER_INFO_101)ServerList; static BOOL bDisplayEntries = FALSE;
ASSERT (ulLevel == 100 || ulLevel == 101);
//
// Figure out the size of each element.
//
if (ulLevel == 100) { ServerElementSize = sizeof(SERVER_INFO_100); } else { ASSERT( ulLevel == 101 ); ServerElementSize = sizeof(SERVER_INFO_101); }
//
// Next check to see if the input list is sorted.
//
if ( bDisplayEntries ) { DbgPrint("Server List:\n"); } for (i = 0 ; i < (LONG)ulEntries ; i++ ) {
if ( bDisplayEntries ) { DbgPrint("<%d>: [0x%x] %S\n", i, ServerInfo->sv101_platform_id, ServerInfo->sv101_name); }
ASSERT (ServerInfo->sv101_name && wcslen(ServerInfo->sv101_name) > 0); ServerInfo = (PSERVER_INFO_101)((PCHAR)ServerInfo + ServerElementSize); } } #endif
|