Leaked source code of windows server 2003
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.
 
 
 
 
 
 

339 lines
13 KiB

/*++
Copyright (c) 1991 Microsoft Corporation
Module Name:
isremote.c
Abstract:
Contains the NetpIsRemote routine. This checks if a computer name
designates the local machine
Author:
Richard L Firth (rfirth) 24th April 1991
Revision History:
01-Nov-1991 JohnRo
Fixed RAID 3414: allow explicit local server name. (NetpIsRemote was
not canonizaling the computer name from NetWkstaGetInfo, so it was
always saying that the local computer name was remote if it wasn't
already canonicalized.)
07-Jun-1991 rfirth
* Changed name of routine to conform to Nt naming conventions
* Added LocalOrRemote parameter - returning just ISLOCAL or ISREMOTE
is not sufficient - we can return error codes too
* Added CanonicalizedName parameter - now passes back canonicalized
name if requested. This is because, usually, subsequent routines call
to NetRemoteComputerSupports which performs minimal checking on the
name. Ergo, if we hand it a canonicalized name (which we have to do
with this routine anyway) it can't complain. Can it?
* NetpIsRemote no longer a NET_API_FUNCTION
* Made semantics of CanonicalizedName orhogonal - if NULL or NUL passed
in as ComputerName, caller still gets back the local computer name
IF CanonicalizedName NOT NULL AND IF THE REDIRECTOR HAS BEEN STARTED
--*/
#include "nticanon.h"
NET_API_STATUS
NetpIsRemote(
IN LPWSTR ComputerName OPTIONAL,
OUT LPDWORD LocalOrRemote,
OUT LPWSTR CanonicalizedName OPTIONAL,
IN DWORD cchCanonName,
IN DWORD Flags
)
/*++
Routine Description:
Determines whether a computer name designates this machine or a renote
one. Values of ComputerName which equate to the local machine are:
NULL pointer to name
pointer to NULL name
pointer to non-NULL name which is lexically equivalent to this
machine's name
NB. This routine expects that the canonicalized version of ComputerName
will fit into the buffer pointed at by CanonicalizedName. Since this
is an INTERNAL function, this assumption is deemed valid
Arguments:
IN LPTSTR ComputerName OPTIONAL
Pointer to computer name to check. May assume any of
the above forms
If a non-NULL string is passed in, then it may have
preceeding back-slashes. This is kind of expected since
this routine is called by remotable APIs and it is they
who specify that the form a computer name is \\<name>
OUT LPDWORD LocalOrRemote
Points to the DWORD where the specifier for the
symbolic location will be returned. MUST NOT BE NULL. On
return will be one of:
ISLOCAL The name defined by ComputerName specifies
the local machine specifically or by default
(ie. was NULL)
ISREMOTE The name defined by ComputerName was non-NULL
and was not the name of this machine
OUT LPTSTR CanonicalizedName OPTIONAL
Pointer to caller's buffer into which a copy of the
canonicalized name will be placed if requested. This
can then be used in subsequent calls, with the knowledge
that no further checking of the computer name is required.
Note that the format of this buffer will be \\<computername>
on return. The contents of this buffer will not be
modified unless this routine returns success
IN DWORD Flags
A bitmap. Flags are:
NIRFLAG_MAPLOCAL if set, will map (ie canonicalize)
the NULL local name to this
computer's name proper. Used in
conjunction with CanonicalizedName
This stops extraneous calls to
NetpNameCanonicalize with the
inherited CanonicalizedName
parameter. See below for elucidation
Return Value:
NET_API_STATUS
Success = NERR_Success
Failure = return code from:
NetpNameCanonicalize
NetWkstaGetInfo
NetpNameCompare
--*/
{
LPBYTE wksta_buffer_pointer;
BOOL map_local_name = FALSE;
LONG result;
NET_API_STATUS rc;
WCHAR name[MAX_PATH]; // canonicalized version of ComputerName
LPWSTR wksta_name_uncanon; // our computer name (from NetWkstaGetInfo)
WCHAR wksta_name_canon[MAX_PATH]; // our computer name (from canon)
LPWSTR canonicalized_name; // as returned to caller
//
// Assert that we have a valid pointer in LocalOrRemote
//
//
// Once again, shouldn't have to do this, since this routine is internal
// and there is no interpretation about inputs. However, lets catch any
// possible problems...
//
NetpAssert(ARGUMENT_PRESENT(LocalOrRemote));
#ifdef CANONDBG
DbgPrint("NetpIsRemote(%s, %x, %x, %x)\n",
ComputerName,
LocalOrRemote,
CanonicalizedName,
Flags
);
#endif
//
// NB. It is important to check this case first, before we call any Netp
// routines since these could call back to this routine and we may get
// stuck in an infinite loop
//
if (!ARGUMENT_PRESENT(ComputerName) || (*ComputerName == TCHAR_EOS)) {
//
// in this case its probably an internal call from one of our routines
// and we want to return as quickly as possible. This will be borne out
// by the NIRFLAG_MAPLOCAL flag being reset in the Flags parameter
//
//
// A note about NIRFLAG_MAPLOCAL
// This routine makes local calls to NetpNameValidate and
// NetpNameCompare. If the NIRFLAG_MAPLOCAL flag is not reset then
// these routines in turn will cause the local name to be returned
// (because they always pass in non-NULL CanonicalizedName parameter)
// which in most cases is inefficient, since the name won't be used
// so we always say (in the Netp routines) that we don't want local
// name canonicalization
// Therefore, if (local) name canonicalization is implied by non-NULL
// CanonicalizedName, verify this by checking Flags.NIRFLAG_MAPLOCAL
// If it, too, is set then local name canonicalization is performed
//
if (!ARGUMENT_PRESENT(CanonicalizedName) || !(Flags & NIRFLAG_MAPLOCAL)) {
*LocalOrRemote = ISLOCAL;
#ifdef CANONDBG
DbgPrint("NetpIsRemote(%s) - returning early\n", ComputerName);
#endif
return NERR_Success;
} else {
//
// signify that the input name was NULL or NUL string but that the
// caller wants a canonicalized name returned (from NetWkstaGetInfo)
//
map_local_name = TRUE;
}
} else {
//
// if the computername starts with \\ or // or any combination thereof,
// skip the path separators - the canonicalization routines expect
// computer names NOT to have these.
//
if (IS_PATH_SEPARATOR(ComputerName[0]) && IS_PATH_SEPARATOR(ComputerName[1])) {
ComputerName += 2;
}
//
// here's a use for canonicalization (!): ensure that we have been passed
// a real and proper computer name and not some pale imitation
//
rc = NetpNameCanonicalize(
NULL, // performed here, on our own premises
ComputerName, // this is input
name, // this is output
sizeof(name), // how much buffer we have
NAMETYPE_COMPUTER, // what we think it is
INNCA_FLAGS_FULL_BUFLEN // say that o/p buffer must be large
// enough for maximum-sized computer
// name. Why? you ask, well its a fair
// cop - the reason is that we can't
// get into trouble on the one time that
// we exercise the maximum requirement
);
if (rc) {
return rc; // duff name (?)
} else {
canonicalized_name = name;
}
}
//
// get the name of this machine from the redirector. If we can't get the
// name for whatever reason, return the error code.
//
if (rc = NetWkstaGetInfo(NULL, 100, &wksta_buffer_pointer)) {
#ifdef CANONDBG
DbgPrint("error: NetWkstaGetInfo returns %lu\n", rc);
#endif
return rc; // didn't work
}
wksta_name_uncanon =
((LPWKSTA_INFO_100) wksta_buffer_pointer)->wki100_computername;
#ifdef CANONDBG
DbgPrint("NetWkstaGetInfo returns level 100 computer name (uncanon)= %s\n",
wksta_name_uncanon);
#endif
rc = NetpNameCanonicalize(
NULL, // performed here, on our own premises
wksta_name_uncanon, // this is input
wksta_name_canon, // this is output
sizeof(wksta_name_canon), // how much buffer we have
NAMETYPE_COMPUTER, // what we think it is
INNCA_FLAGS_FULL_BUFLEN // say that o/p buffer must be large
// enough for maximum-sized computer
// name. Why? you ask, well its a fair
// cop - the reason is that we can't
// get into trouble on the one time that
// we exercise the maximum requirement
);
NetpAssert( rc == NERR_Success );
//
// compare our name and the name passed to us. NetpNameCompare returns
// 0 if the names match else 1 or -1 (a la strcmp)
//
//
// if the caller gave us a NULL computer name but wants a canonicalized
// name output then get a pointer to the canonicalized name from
// NetWkstaGetInfo
//
if (map_local_name) {
*LocalOrRemote = ISLOCAL;
canonicalized_name = wksta_name_canon;
} else {
//
// otherwise, we have a non-NULL computername to compare with this
// computer's name
//
result = NetpNameCompare(
NULL, // performed here, on our own premises
name, // canonicalized version of passed name
wksta_name_canon, // name of our computer
NAMETYPE_COMPUTER,
INNC_FLAGS_NAMES_CANONICALIZED
);
//
// if the specified name equates to our computer name then its still local
//
*LocalOrRemote = (DWORD)((result == 0) ? ISLOCAL : ISREMOTE);
}
//
// if the caller specified that the canonicalized name be returned, then
// give it to 'em. Note that the returned name is prefixed with \\ - it
// is assumed the name is then used in a call to eg NetRemoteComputerSupports
//
if (ARGUMENT_PRESENT(CanonicalizedName))
{
if (cchCanonName < wcslen(canonicalized_name) + 2 + 1)
{
//
// Buffer's too small for \\ + <name> + \0. Since this is a private
// routine, the too-small buffer size is hardcoded. Return invalid
// parameter instead of buffer too small since there's nothing the
// caller can do at this point (and we're not returning a length).
//
NetApiBufferFree(wksta_buffer_pointer);
return ERROR_INVALID_PARAMETER;
}
wcscpy(CanonicalizedName, L"\\\\");
wcscat(CanonicalizedName, canonicalized_name);
}
//
// free the buffer created by NetWkstaGetInfo
//
NetApiBufferFree(wksta_buffer_pointer);
return NERR_Success;
}