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.
335 lines
8.2 KiB
335 lines
8.2 KiB
/*++
|
|
|
|
Copyright (c) 1989-91 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
namecmp.c
|
|
|
|
Abstract:
|
|
|
|
Net name comparison functions:
|
|
|
|
NetpwNameCompare
|
|
CompareOemNames
|
|
|
|
Author:
|
|
|
|
Richard L Firth (rfirth) 06-Jan-1992
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "nticanon.h"
|
|
|
|
//
|
|
// prototypes
|
|
//
|
|
|
|
LONG
|
|
CompareOemNames(
|
|
IN LPWSTR Name1,
|
|
IN LPWSTR Name2,
|
|
IN BOOL CaseInsensitive
|
|
);
|
|
|
|
//
|
|
// data
|
|
//
|
|
|
|
static TCHAR szShareTrailChars[] = TEXT(". ");
|
|
|
|
//
|
|
// routines
|
|
//
|
|
|
|
|
|
LONG
|
|
NetpwNameCompare(
|
|
IN LPTSTR Name1,
|
|
IN LPTSTR Name2,
|
|
IN DWORD NameType,
|
|
IN DWORD Flags
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Compares two LANMAN object names to see if they are the same. If the
|
|
supplied names are not canonicalized this function will do the
|
|
canonicalization of the names.
|
|
|
|
This function does not do name validation. It assumes that the two names
|
|
have been validated separately.
|
|
|
|
This function relies on the fact that the only difference between a
|
|
canonicalized object name and an uncanonicalized object name is the case.
|
|
|
|
(say what?...)
|
|
|
|
Arguments:
|
|
|
|
Name1 - The first name to compare.
|
|
|
|
Name2 - The second name to compare.
|
|
|
|
NameType - The type of the LANMAN object names. Valid values are
|
|
specified by NAMETYPE_* manifests in ICANON.H.
|
|
|
|
Flags - Flags to determine operation. Currently defined values are:
|
|
|
|
Xrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrc
|
|
|
|
where:
|
|
|
|
X = LM 2.x Compatibility
|
|
|
|
r = Reserved. MBZ.
|
|
|
|
c = should be set if both of the names have already been
|
|
canonicalized (using NetpwNameCanonicalize).
|
|
|
|
Return Value:
|
|
|
|
0 if the two names match.
|
|
|
|
Non-zero if they don't match, or if an invalid parameter is
|
|
specified.
|
|
|
|
--*/
|
|
|
|
{
|
|
LONG RetVal;
|
|
NET_API_STATUS rc;
|
|
TCHAR tName1[PATHLEN+1];
|
|
TCHAR tName2[PATHLEN+1];
|
|
|
|
#ifdef CANONDBG
|
|
DbgPrint("NetpwNameCompare\n");
|
|
#endif
|
|
|
|
//
|
|
// Parameter validation
|
|
//
|
|
|
|
if (Flags & INNC_FLAGS_RESERVED) {
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
//
|
|
// Determine which of the canonicalization functions to use. We
|
|
// use stricmp() if the names are not canonicalized and are not
|
|
// case sensitive and strcmp() if the names are canonicalized or
|
|
// if they are case sensitive.
|
|
//
|
|
|
|
switch (NameType) {
|
|
|
|
//
|
|
// Case insensitive name types
|
|
//
|
|
|
|
case NAMETYPE_USER:
|
|
case NAMETYPE_GROUP:
|
|
case NAMETYPE_COMPUTER:
|
|
case NAMETYPE_EVENT:
|
|
case NAMETYPE_DOMAIN:
|
|
case NAMETYPE_SERVICE:
|
|
case NAMETYPE_NET:
|
|
case NAMETYPE_WORKGROUP:
|
|
|
|
//
|
|
// Use the case sensitive version if the names have been
|
|
// canonicalized.
|
|
//
|
|
|
|
if (!(Flags & INNC_FLAGS_NAMES_CANONICALIZED)) {
|
|
rc = NetpwNameCanonicalize(Name1,
|
|
tName1,
|
|
sizeof(tName1),
|
|
NameType,
|
|
Flags & LM2X_COMPATIBLE
|
|
);
|
|
if (rc != NERR_Success) {
|
|
return rc;
|
|
}
|
|
rc = NetpwNameCanonicalize(Name2,
|
|
tName2,
|
|
sizeof(tName2),
|
|
NameType,
|
|
Flags & LM2X_COMPATIBLE
|
|
);
|
|
if (rc != NERR_Success) {
|
|
return rc;
|
|
}
|
|
} else {
|
|
LONG Name1Length, Name2Length;
|
|
|
|
Name1Length = STRLEN(Name1);
|
|
Name2Length = STRLEN(Name2);
|
|
|
|
if ((Name1Length > PATHLEN) ||
|
|
(Name2Length > PATHLEN)) {
|
|
return ERROR_INVALID_PARAMETER;
|
|
} else {
|
|
STRCPY(tName1, Name1);
|
|
STRCPY(tName2, Name2);
|
|
}
|
|
}
|
|
if (Flags & (LM2X_COMPATIBLE)) {
|
|
if (NameType == NAMETYPE_COMPUTER
|
|
|| NameType == NAMETYPE_DOMAIN
|
|
|| NameType == NAMETYPE_WORKGROUP) {
|
|
return CompareOemNames(tName1, tName2, FALSE);
|
|
} else {
|
|
return STRCMP(tName1, tName2);
|
|
}
|
|
} else {
|
|
if (NameType == NAMETYPE_COMPUTER
|
|
|| NameType == NAMETYPE_DOMAIN
|
|
|| NameType == NAMETYPE_WORKGROUP) {
|
|
return CompareOemNames(tName1, tName2, TRUE);
|
|
} else {
|
|
return STRICMP(tName1, tName2);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Case sensitive name types
|
|
//
|
|
|
|
case NAMETYPE_PASSWORD:
|
|
case NAMETYPE_SHAREPASSWORD:
|
|
case NAMETYPE_MESSAGE:
|
|
case NAMETYPE_MESSAGEDEST:
|
|
return STRCMP(Name1, Name2);
|
|
|
|
//
|
|
// Special handling for sharenames, since we mustn't consider
|
|
// trailing dots and spaces in the comparison if the names haven't
|
|
// been canonicalized.
|
|
//
|
|
|
|
case NAMETYPE_SHARE:
|
|
if (Flags & INNC_FLAGS_NAMES_CANONICALIZED) {
|
|
if (Flags & LM2X_COMPATIBLE) {
|
|
return STRCMP(Name1, Name2);
|
|
} else {
|
|
return STRICMP(Name1, Name2);
|
|
}
|
|
} else {
|
|
register DWORD RealLen1, RealLen2;
|
|
|
|
RealLen1 = (DWORD)(strtail(Name1, szShareTrailChars) - Name1);
|
|
RealLen2 = (DWORD)(strtail(Name2, szShareTrailChars) - Name2);
|
|
|
|
//
|
|
// If the lengths of the significant portions match, compare
|
|
// these portions. Otherwise, return non-zero based on this
|
|
// length.
|
|
//
|
|
|
|
if (RealLen1 == RealLen2) {
|
|
return STRNICMP(Name1, Name2, RealLen1);
|
|
} else {
|
|
return RealLen1 > RealLen2 ? 1 : -1;
|
|
}
|
|
}
|
|
|
|
default:
|
|
|
|
//
|
|
// The caller specified an invalid name type
|
|
//
|
|
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
}
|
|
|
|
|
|
LONG
|
|
CompareOemNames(
|
|
IN LPWSTR Name1,
|
|
IN LPWSTR Name2,
|
|
IN BOOL CaseInsensitive
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Converts 2 UNICODE name strings to corresponding OEM character set strings
|
|
and then compares them
|
|
|
|
Arguments:
|
|
|
|
Name1 -
|
|
Name2 -
|
|
CaseInsensitive - TRUE if compare without case
|
|
|
|
Return Value:
|
|
|
|
LONG
|
|
<0 Name1 less than Name2
|
|
0 Names match
|
|
>0 Name1 greater than Name2
|
|
|
|
--*/
|
|
|
|
{
|
|
CHAR oemName1[PATHLEN + 1];
|
|
ULONG oemByteLength1;
|
|
ULONG name1Length;
|
|
CHAR oemName2[PATHLEN + 1];
|
|
ULONG oemByteLength2;
|
|
ULONG name2Length;
|
|
NTSTATUS ntStatus;
|
|
|
|
name1Length = wcslen(Name1);
|
|
name2Length = wcslen(Name2);
|
|
|
|
//
|
|
// only prepared to consider names within our upper length limit
|
|
//
|
|
|
|
if (name1Length >= sizeof(oemName1) || name2Length >= sizeof(oemName2)) {
|
|
return -1;
|
|
}
|
|
|
|
//
|
|
// convert UNICODE names to OEM
|
|
//
|
|
|
|
ntStatus = RtlUpcaseUnicodeToOemN(oemName1,
|
|
sizeof(oemName1) - 1,
|
|
&oemByteLength1,
|
|
Name1,
|
|
name1Length * sizeof(*Name1)
|
|
);
|
|
if (!NT_SUCCESS(ntStatus)) {
|
|
return -1;
|
|
} else {
|
|
oemName1[oemByteLength1] = 0;
|
|
}
|
|
ntStatus = RtlUpcaseUnicodeToOemN(oemName2,
|
|
sizeof(oemName2) - 1,
|
|
&oemByteLength2,
|
|
Name2,
|
|
name2Length * sizeof(*Name2)
|
|
);
|
|
if (!NT_SUCCESS(ntStatus)) {
|
|
return -1;
|
|
} else {
|
|
oemName2[oemByteLength2] = 0;
|
|
}
|
|
|
|
if (CaseInsensitive) {
|
|
return _stricmp(oemName1, oemName2);
|
|
}
|
|
else {
|
|
return strcmp(oemName1, oemName2);
|
|
}
|
|
}
|
|
|