mirror of https://github.com/tongzx/nt5src
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.
703 lines
16 KiB
703 lines
16 KiB
/*++
|
|
|
|
Copyright (c) 1991-1993 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
canonapi.c
|
|
|
|
Abstract:
|
|
|
|
This file contains the remotable API wrappers for the canonicalization
|
|
functions. Now that remotable canonicalization has been moved into the
|
|
server service, these canonicalization routines (in NETAPI.DLL) simply
|
|
decide whether a function should be remoted or runs the local routine
|
|
|
|
The canonicalization functions have been split into these wrappers, the
|
|
local versions and the remote RPC routines to avoid the cylical dependency
|
|
of SRVSVC.DLL/.LIB and NETAPI.DLL/.LIB
|
|
|
|
Contents:
|
|
NetpListCanonicalize
|
|
NetpListTraverse
|
|
NetpNameCanonicalize
|
|
NetpNameCompare
|
|
NetpNameValidate
|
|
NetpPathCanonicalize
|
|
NetpPathCompare
|
|
NetpPathType
|
|
|
|
Author:
|
|
|
|
Richard L Firth (rfirth) 15-May-1992
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include <nt.h>
|
|
#include <ntrtl.h>
|
|
#include <nturtl.h>
|
|
#include <windows.h>
|
|
#include <lmcons.h>
|
|
#include <lmerr.h>
|
|
#include <tstring.h>
|
|
#include <icanon.h>
|
|
#include <netcan.h>
|
|
|
|
|
|
NET_API_STATUS
|
|
NET_API_FUNCTION
|
|
NetpListCanonicalize(
|
|
IN LPTSTR ServerName OPTIONAL,
|
|
IN LPTSTR List,
|
|
IN LPTSTR Delimiters OPTIONAL,
|
|
OUT LPTSTR Outbuf,
|
|
IN DWORD OutbufLen,
|
|
OUT LPDWORD OutCount,
|
|
OUT LPDWORD PathTypes,
|
|
IN DWORD PathTypesLen,
|
|
IN DWORD Flags
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Converts a list to its canonical form. If ServerName is non-NULL then the
|
|
RPC function is called (in SRVSVC.DLL) else the local worker function (in
|
|
NETLIB.LIB)
|
|
|
|
Arguments:
|
|
|
|
ServerName - where to remote this function. May be NULL
|
|
List - input list to canonicalize
|
|
Delimiters - optional list of delimiter characters. May be NULL
|
|
Outbuf - place to write output
|
|
OutbufLen - length of Outbuf
|
|
OutCount - returned number of items in Outbuf
|
|
PathTypes - returned list of types of entries in Outbuf
|
|
PathTypesLen - size of PathTypes array
|
|
Flags - control flags
|
|
|
|
Return Value:
|
|
|
|
NET_API_STATUS
|
|
|
|
--*/
|
|
|
|
{
|
|
NET_API_STATUS status = 0;
|
|
DWORD location;
|
|
TCHAR serverName[MAX_PATH];
|
|
DWORD val;
|
|
BOOL nullDelimiter = FALSE;
|
|
TCHAR ch;
|
|
|
|
//
|
|
// validate parameters
|
|
//
|
|
|
|
try {
|
|
if (ARGUMENT_PRESENT(ServerName)) {
|
|
val = STRLEN(ServerName);
|
|
}
|
|
if (ARGUMENT_PRESENT(Delimiters)) {
|
|
val = STRLEN(Delimiters);
|
|
nullDelimiter = (val == 0);
|
|
} else {
|
|
nullDelimiter = TRUE;
|
|
}
|
|
val = STRLEN(List);
|
|
|
|
//
|
|
// if Delimiters is a NULL pointer or NUL string, then List is a
|
|
// NULL-NULL input list
|
|
//
|
|
|
|
if (nullDelimiter) {
|
|
LPTSTR str = List + val + 1;
|
|
|
|
do {
|
|
val = STRLEN(str);
|
|
str += val + 1;
|
|
} while ( val );
|
|
}
|
|
ch = *((TCHAR volatile *)Outbuf);
|
|
*Outbuf = ch;
|
|
ch = *((TCHAR volatile *)(Outbuf + OutbufLen/sizeof(*Outbuf) - sizeof(*Outbuf)));
|
|
*(Outbuf + OutbufLen/sizeof(*Outbuf) - sizeof(*Outbuf)) = ch;
|
|
*OutCount = 0;
|
|
if (ARGUMENT_PRESENT(PathTypes)) {
|
|
PathTypes[0] = 0;
|
|
PathTypes[PathTypesLen - 1] = 0;
|
|
} else if ((Flags & INLC_FLAGS_MASK_NAMETYPE) == NAMETYPE_PATH) {
|
|
|
|
//
|
|
// NAMETYPE_PATH and NULL PathTypes is illegal
|
|
//
|
|
|
|
status = ERROR_INVALID_PARAMETER;
|
|
}
|
|
} except(EXCEPTION_EXECUTE_HANDLER) {
|
|
status = ERROR_INVALID_PARAMETER;
|
|
}
|
|
if (status) {
|
|
return status;
|
|
}
|
|
if (Flags & INLC_FLAGS_MASK_RESERVED) {
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
//
|
|
// call client-side RPC routine or local canonicalization routine
|
|
//
|
|
|
|
status = NetpIsRemote(ServerName, &location, serverName, 0);
|
|
if (status != NERR_Success) {
|
|
return status;
|
|
}
|
|
|
|
//
|
|
// due to historic precedent, we don't remote this function
|
|
//
|
|
|
|
if (location == ISREMOTE) {
|
|
return ERROR_NOT_SUPPORTED;
|
|
} else {
|
|
return NetpwListCanonicalize(List,
|
|
Delimiters,
|
|
Outbuf,
|
|
OutbufLen,
|
|
OutCount,
|
|
PathTypes,
|
|
PathTypesLen,
|
|
Flags
|
|
);
|
|
}
|
|
}
|
|
|
|
|
|
LPTSTR
|
|
NET_API_FUNCTION
|
|
NetpListTraverse(
|
|
IN LPTSTR Reserved OPTIONAL,
|
|
IN LPTSTR* pList,
|
|
IN DWORD Flags
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This just calls the local traverse function
|
|
|
|
Arguments:
|
|
|
|
Reserved - MBZ
|
|
pList - pointer to list to traverse
|
|
Flags - MBZ
|
|
|
|
Return Value:
|
|
|
|
LPTSTR
|
|
|
|
--*/
|
|
|
|
{
|
|
return NetpwListTraverse(Reserved, pList, Flags);
|
|
}
|
|
|
|
|
|
NET_API_STATUS
|
|
NET_API_FUNCTION
|
|
NetpNameCanonicalize(
|
|
IN LPTSTR ServerName OPTIONAL,
|
|
IN LPTSTR Name,
|
|
OUT LPTSTR Outbuf,
|
|
IN DWORD OutbufLen,
|
|
IN DWORD NameType,
|
|
IN DWORD Flags
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Canonicalizes a name
|
|
|
|
Arguments:
|
|
|
|
ServerName - where to run this API
|
|
Name - name to canonicalize
|
|
Outbuf - where to put canonicalized name
|
|
OutbufLen - length of Outbuf
|
|
NameType - type of name to canonicalize
|
|
Flags - control flags
|
|
|
|
Return Value:
|
|
|
|
NET_API_STATUS
|
|
|
|
--*/
|
|
|
|
{
|
|
NET_API_STATUS status = 0;
|
|
DWORD location;
|
|
TCHAR serverName[MAX_PATH];
|
|
DWORD val;
|
|
TCHAR ch;
|
|
|
|
//
|
|
// validate parameters
|
|
//
|
|
|
|
try {
|
|
if (ARGUMENT_PRESENT(ServerName)) {
|
|
val = STRLEN(ServerName);
|
|
}
|
|
if (ARGUMENT_PRESENT(Name)) {
|
|
val = STRLEN(Name);
|
|
}
|
|
if (ARGUMENT_PRESENT(Outbuf)) {
|
|
ch = *((TCHAR volatile *)Outbuf);
|
|
*Outbuf = ch;
|
|
ch = *((TCHAR volatile *)(Outbuf + OutbufLen/sizeof(*Outbuf) - sizeof(*Outbuf)));
|
|
*(Outbuf + OutbufLen/sizeof(*Outbuf) - sizeof(*Outbuf)) = ch;
|
|
} else {
|
|
status = ERROR_INVALID_PARAMETER;
|
|
}
|
|
} except(EXCEPTION_EXECUTE_HANDLER) {
|
|
status = ERROR_INVALID_PARAMETER;
|
|
}
|
|
if (status) {
|
|
return status;
|
|
}
|
|
if (Flags & INNCA_FLAGS_RESERVED) {
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
//
|
|
// call client-side RPC routine or local canonicalization routine
|
|
//
|
|
|
|
status = NetpIsRemote(ServerName, &location, serverName, 0);
|
|
if (status != NERR_Success) {
|
|
return status;
|
|
}
|
|
if (location == ISREMOTE) {
|
|
return NetpsNameCanonicalize(serverName,
|
|
Name,
|
|
Outbuf,
|
|
OutbufLen,
|
|
NameType,
|
|
Flags
|
|
);
|
|
} else {
|
|
return NetpwNameCanonicalize(Name, Outbuf, OutbufLen, NameType, Flags);
|
|
}
|
|
}
|
|
|
|
|
|
LONG
|
|
NET_API_FUNCTION
|
|
NetpNameCompare(
|
|
IN LPTSTR ServerName OPTIONAL,
|
|
IN LPTSTR Name1,
|
|
IN LPTSTR Name2,
|
|
IN DWORD NameType,
|
|
IN DWORD Flags
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Compares two names. Must be of same type
|
|
|
|
Arguments:
|
|
|
|
ServerName - where to run this API
|
|
Name1 - 1st name to compare
|
|
Name2 - 2nd
|
|
NameType - type of names
|
|
Flags - control flags
|
|
|
|
Return Value:
|
|
|
|
LONG
|
|
|
|
--*/
|
|
|
|
{
|
|
NET_API_STATUS status = 0;
|
|
DWORD location;
|
|
TCHAR serverName[MAX_PATH];
|
|
DWORD val;
|
|
|
|
//
|
|
// validate parameters
|
|
//
|
|
|
|
try {
|
|
if (ARGUMENT_PRESENT(ServerName)) {
|
|
val = STRLEN(ServerName);
|
|
}
|
|
val = STRLEN(Name1);
|
|
val = STRLEN(Name2);
|
|
} except(EXCEPTION_EXECUTE_HANDLER) {
|
|
status = ERROR_INVALID_PARAMETER;
|
|
}
|
|
if (status) {
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
if (Flags & INNC_FLAGS_RESERVED) {
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
//
|
|
// call client-side RPC routine or local canonicalization routine
|
|
//
|
|
|
|
status = NetpIsRemote(ServerName, &location, serverName, 0);
|
|
if (status != NERR_Success) {
|
|
return status;
|
|
}
|
|
if (location == ISREMOTE) {
|
|
return NetpsNameCompare(serverName, Name1, Name2, NameType, Flags);
|
|
} else {
|
|
return NetpwNameCompare(Name1, Name2, NameType, Flags);
|
|
}
|
|
}
|
|
|
|
|
|
NET_API_STATUS
|
|
NET_API_FUNCTION
|
|
NetpNameValidate(
|
|
IN LPTSTR ServerName OPTIONAL,
|
|
IN LPTSTR Name,
|
|
IN DWORD NameType,
|
|
IN DWORD Flags
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Validates a name - checks whether a name of a certain type conforms to
|
|
canonicalization rules for that name type. Canonicalization rules mean
|
|
character set, name syntax and length
|
|
|
|
Arguments:
|
|
|
|
ServerName - where to perform this function
|
|
Name - name to validate
|
|
NameType - what type of name it is
|
|
Flags - MBZ
|
|
|
|
Return Value:
|
|
|
|
NET_API_STATUS
|
|
|
|
--*/
|
|
|
|
{
|
|
NET_API_STATUS status = 0;
|
|
DWORD location;
|
|
TCHAR serverName[MAX_PATH];
|
|
DWORD val;
|
|
|
|
//
|
|
// validate parameters
|
|
//
|
|
|
|
try {
|
|
if (ARGUMENT_PRESENT(ServerName)) {
|
|
val = STRLEN(ServerName);
|
|
}
|
|
if (ARGUMENT_PRESENT(Name)) {
|
|
val = STRLEN(Name);
|
|
} else {
|
|
status = ERROR_INVALID_PARAMETER;
|
|
}
|
|
} except(EXCEPTION_EXECUTE_HANDLER) {
|
|
status = ERROR_INVALID_PARAMETER;
|
|
}
|
|
if (status) {
|
|
return status;
|
|
}
|
|
if (Flags & INNV_FLAGS_RESERVED) {
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
//
|
|
// call client-side RPC routine or local canonicalization routine
|
|
//
|
|
|
|
status = NetpIsRemote(ServerName, &location, serverName, 0);
|
|
if (status != NERR_Success) {
|
|
return status;
|
|
}
|
|
if (location == ISREMOTE) {
|
|
return NetpsNameValidate(serverName, Name, NameType, Flags);
|
|
} else {
|
|
return NetpwNameValidate(Name, NameType, Flags);
|
|
}
|
|
}
|
|
|
|
|
|
NET_API_STATUS
|
|
NET_API_FUNCTION
|
|
NetpPathCanonicalize(
|
|
IN LPTSTR ServerName OPTIONAL,
|
|
IN LPTSTR PathName,
|
|
OUT LPTSTR Outbuf,
|
|
IN DWORD OutbufLen,
|
|
IN LPTSTR Prefix OPTIONAL,
|
|
IN OUT LPDWORD PathType,
|
|
IN DWORD Flags
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Canonicalizes a directory path or a device name
|
|
|
|
Arguments:
|
|
|
|
ServerName - where to run this API
|
|
PathName - path to canonicalize
|
|
Outbuf - where to write the canonicalized version
|
|
OutbufLen - length of Outbuf in bytes
|
|
Prefix - optional prefix which will be prepended to Path
|
|
PathType - the type of path to canonicalize. May be different at output
|
|
Flags - control flags
|
|
|
|
Return Value:
|
|
|
|
NET_API_STATUS
|
|
|
|
--*/
|
|
|
|
{
|
|
NET_API_STATUS status = 0;
|
|
DWORD location;
|
|
TCHAR serverName[MAX_PATH];
|
|
DWORD val;
|
|
TCHAR ch;
|
|
|
|
//
|
|
// validate parameters
|
|
//
|
|
|
|
try {
|
|
if (ARGUMENT_PRESENT(ServerName)) {
|
|
val = STRLEN(ServerName);
|
|
}
|
|
if (ARGUMENT_PRESENT(PathName)) {
|
|
val = STRLEN(PathName);
|
|
}
|
|
if (ARGUMENT_PRESENT(Prefix)) {
|
|
val = STRLEN(Prefix);
|
|
}
|
|
if (ARGUMENT_PRESENT(Outbuf)) {
|
|
ch = *((TCHAR volatile *)Outbuf);
|
|
*Outbuf = ch;
|
|
ch = *((TCHAR volatile *)(Outbuf+OutbufLen/sizeof(*Outbuf) - sizeof(*Outbuf)));
|
|
*(Outbuf+OutbufLen/sizeof(*Outbuf) - sizeof(*Outbuf)) = ch;
|
|
} else {
|
|
status = ERROR_INVALID_PARAMETER;
|
|
}
|
|
val = *PathType ^ 0xf0f0f0f0;
|
|
*PathType = val ^ 0xf0f0f0f0;
|
|
} except(EXCEPTION_EXECUTE_HANDLER) {
|
|
status = ERROR_INVALID_PARAMETER;
|
|
}
|
|
if (status) {
|
|
return status;
|
|
}
|
|
if (Flags & INPCA_FLAGS_RESERVED) {
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
//
|
|
// call client-side RPC routine or local canonicalization routine
|
|
//
|
|
|
|
status = NetpIsRemote(ServerName, &location, serverName, 0);
|
|
if (status != NERR_Success) {
|
|
return status;
|
|
}
|
|
if (location == ISREMOTE) {
|
|
return NetpsPathCanonicalize(serverName,
|
|
PathName,
|
|
Outbuf,
|
|
OutbufLen,
|
|
Prefix,
|
|
PathType,
|
|
Flags
|
|
);
|
|
} else {
|
|
return NetpwPathCanonicalize(PathName,
|
|
Outbuf,
|
|
OutbufLen,
|
|
Prefix,
|
|
PathType,
|
|
Flags
|
|
);
|
|
}
|
|
}
|
|
|
|
|
|
LONG
|
|
NET_API_FUNCTION
|
|
NetpPathCompare(
|
|
IN LPTSTR ServerName OPTIONAL,
|
|
IN LPTSTR PathName1,
|
|
IN LPTSTR PathName2,
|
|
IN DWORD PathType,
|
|
IN DWORD Flags
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Compares two paths. The paths are assumed to be of the same type
|
|
|
|
Arguments:
|
|
|
|
ServerName - where to run this API
|
|
PathName1 - 1st path to compare
|
|
PathName2 - 2nd
|
|
PathType - types of paths
|
|
Flags - control flags
|
|
|
|
Return Value:
|
|
|
|
LONG
|
|
|
|
--*/
|
|
|
|
{
|
|
NET_API_STATUS status = 0;
|
|
DWORD location;
|
|
TCHAR serverName[MAX_PATH];
|
|
DWORD val;
|
|
|
|
//
|
|
// validate parameters
|
|
//
|
|
|
|
try {
|
|
if (ARGUMENT_PRESENT(ServerName)) {
|
|
val = STRLEN(ServerName);
|
|
}
|
|
if (ARGUMENT_PRESENT(PathName1)) {
|
|
val = STRLEN(PathName1);
|
|
}
|
|
if (ARGUMENT_PRESENT(PathName2)) {
|
|
val = STRLEN(PathName2);
|
|
}
|
|
} except(EXCEPTION_EXECUTE_HANDLER) {
|
|
status = ERROR_INVALID_PARAMETER;
|
|
}
|
|
if (status) {
|
|
return status;
|
|
}
|
|
if (Flags & INPC_FLAGS_RESERVED) {
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
//
|
|
// call client-side RPC routine or local canonicalization routine
|
|
//
|
|
|
|
status = NetpIsRemote(ServerName, &location, serverName, 0);
|
|
if (status != NERR_Success) {
|
|
return status;
|
|
}
|
|
if (location == ISREMOTE) {
|
|
return NetpsPathCompare(serverName, PathName1, PathName2, PathType, Flags);
|
|
} else {
|
|
return NetpwPathCompare(PathName1, PathName2, PathType, Flags);
|
|
}
|
|
}
|
|
|
|
|
|
NET_API_STATUS
|
|
NET_API_FUNCTION
|
|
NetpPathType(
|
|
IN LPTSTR ServerName OPTIONAL,
|
|
IN LPTSTR PathName,
|
|
OUT LPDWORD PathType,
|
|
IN DWORD Flags
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Determines the type of a path
|
|
|
|
Arguments:
|
|
|
|
ServerName - where to run this API
|
|
PathName - to find type of
|
|
PathType - returned path type
|
|
Flags - control flags
|
|
|
|
Return Value:
|
|
|
|
NET_API_STATUS
|
|
|
|
--*/
|
|
|
|
{
|
|
NET_API_STATUS status = 0;
|
|
DWORD location;
|
|
TCHAR serverName[MAX_PATH];
|
|
DWORD val;
|
|
|
|
//
|
|
// validate parameters
|
|
//
|
|
|
|
try {
|
|
if (ARGUMENT_PRESENT(ServerName)) {
|
|
val = STRLEN(ServerName);
|
|
}
|
|
if (ARGUMENT_PRESENT(PathName)) {
|
|
val = STRLEN(PathName);
|
|
} else {
|
|
val = 0;
|
|
}
|
|
if (!val || (val > MAX_PATH - 1)) {
|
|
status = ERROR_INVALID_NAME;
|
|
}
|
|
*PathType = 0;
|
|
} except(EXCEPTION_EXECUTE_HANDLER) {
|
|
status = ERROR_INVALID_PARAMETER;
|
|
}
|
|
if (status) {
|
|
return status;
|
|
}
|
|
if (Flags & INPT_FLAGS_RESERVED) {
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
//
|
|
// call client-side RPC routine or local canonicalization routine
|
|
//
|
|
|
|
status = NetpIsRemote(ServerName, &location, serverName, 0);
|
|
if (status != NERR_Success) {
|
|
return status;
|
|
}
|
|
if (location == ISREMOTE) {
|
|
return NetpsPathType(serverName, PathName, PathType, Flags);
|
|
} else {
|
|
return NetpwPathType(PathName, PathType, Flags);
|
|
}
|
|
}
|