windows-nt/Source/XPSP1/NT/ds/netapi/api/canonapi.c
2020-09-26 16:20:57 +08:00

704 lines
16 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
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);
}
}