704 lines
16 KiB
C
704 lines
16 KiB
C
/*++
|
||
|
||
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);
|
||
}
|
||
}
|