|
|
/*++
Copyright (c) 1993 Microsoft Corporation
Module Name:
canon.c
Abstract:
Contains canonicalization routines for NetWare names.
Author:
Rita Wong (ritaw) 19-Feb-1993
Environment:
Revision History:
--*/
#include <procs.h>
DWORD NwLibValidateLocalName( IN LPWSTR LocalName ) /*++
Routine Description:
This routine checks to see if the supplied name is a valid DOS device name.
Arguments:
LocalName - Supplies a local device name. It can be any of the following:
X: LPTn or LPTn: COMn or COMn: PRN or PRN: AUX or AUX:
Return Value:
NO_ERROR - LocalName is valid.
WN_BAD_NETNAME - LocalName is invalid.
--*/ { DWORD LocalNameLength;
//
// Cannot be a NULL or empty string
//
if (LocalName == NULL || *LocalName == 0) { return WN_BAD_NETNAME; }
LocalNameLength = wcslen(LocalName);
if (LocalNameLength == 1) { return WN_BAD_NETNAME; }
if (LocalName[LocalNameLength - 1] == L':') { if (! IS_VALID_TOKEN(LocalName, LocalNameLength - 1)) { return WN_BAD_NETNAME; } } else { if (! IS_VALID_TOKEN(LocalName, LocalNameLength)) { return WN_BAD_NETNAME; } }
if (LocalNameLength == 2) { //
// Must be in the form of X:
//
if (! iswalpha(*LocalName)) { return WN_BAD_NETNAME; }
if (LocalName[1] != L':') { return WN_BAD_NETNAME; }
return NO_ERROR; }
if (RtlIsDosDeviceName_U(LocalName) == 0) { return WN_BAD_NETNAME; }
//
// Valid DOS device name but invalid redirection name
//
if (_wcsnicmp(LocalName, L"NUL", 3) == 0) { return WN_BAD_NETNAME;
} return NO_ERROR; }
DWORD NwLibCanonLocalName( IN LPWSTR LocalName, OUT LPWSTR *OutputBuffer, OUT LPDWORD OutputBufferLength OPTIONAL ) /*++
Routine Description:
This routine canonicalizes the local name by uppercasing the string and converting the following:
x: -> X: LPTn: -> LPTn COMn: -> COMn PRN or PRN: -> LPT1 AUX or AUX: -> COM1
Arguments:
LocalName - Supplies a local device name.
OutputBuffer - Receives a pointer to the canonicalized LocalName.
OutputBufferLength - Receives the length of the canonicalized name in number of characters, if specified.
Return Value:
NO_ERROR - Successfully canonicalized the local name.
WN_BAD_NETNAME - LocalName is invalid.
ERROR_NOT_ENOUGH_MEMORY - Could not allocate output buffer.
--*/ { DWORD status; DWORD LocalNameLength;
status = NwLibValidateLocalName(LocalName);
if (status != NO_ERROR) { return status; }
LocalNameLength = wcslen(LocalName);
//
// Allocate output buffer. Should be the size of the LocalName
// plus 1 for the special case of PRN -> LPT1 or AUX -> COM1.
//
*OutputBuffer = (PVOID) LocalAlloc( LMEM_ZEROINIT, (LocalNameLength + 2) * sizeof(WCHAR) );
if (*OutputBuffer == NULL) { KdPrint(("NWLIB: NwLibCanonLocalName LocalAlloc failed %lu\n", GetLastError())); return ERROR_NOT_ENOUGH_MEMORY; }
wcscpy(*OutputBuffer, LocalName);
if (LocalNameLength > 2) {
if (_wcsnicmp(*OutputBuffer, L"PRN", 3) == 0) {
//
// Convert PRN or PRN: to LPT1
//
wcscpy(*OutputBuffer, L"LPT1"); LocalNameLength = 4;
} else if (_wcsnicmp(*OutputBuffer, L"AUX", 3) == 0) {
//
// Convert AUX or AUX: to COM1
//
wcscpy(*OutputBuffer, L"COM1"); LocalNameLength = 4; }
//
// Remove trailing colon, if there is one, and decrement the length
// of DOS device name.
//
if ((*OutputBuffer)[LocalNameLength - 1] == L':') { (*OutputBuffer)[--LocalNameLength] = 0; } }
//
// LocalName is always in uppercase.
//
_wcsupr(*OutputBuffer);
if (ARGUMENT_PRESENT(OutputBufferLength)) { *OutputBufferLength = LocalNameLength; }
return NO_ERROR; }
DWORD NwLibCanonRemoteName( IN LPWSTR LocalName OPTIONAL, IN LPWSTR RemoteName, OUT LPWSTR *OutputBuffer, OUT LPDWORD OutputBufferLength OPTIONAL ) /*++
Routine Description:
This routine validates and canonicalizes the supplied NetWare UNC name. It can be of any length in the form of:
\\Server\Volume\Directory\Subdirectory
Arguments:
LocalName - Supplies the local device name. If it is NULL, then \\Server is an acceptable format for the UNC name.
RemoteName - Supplies the UNC name.
OutputBuffer - Receives a pointer to the canonicalized RemoteName.
OutputBufferLength - Receives the length of the canonicalized name in number of characters, if specified.
Return Value:
NO_ERROR - RemoteName is valid.
WN_BAD_NETNAME - RemoteName is invalid.
--*/ { DWORD RemoteNameLength; DWORD i; DWORD TokenLength; LPWSTR TokenPtr; BOOL fFirstToken = TRUE;
//
// Cannot be a NULL or empty string
//
if (RemoteName == NULL || *RemoteName == 0) { return WN_BAD_NETNAME; }
RemoteNameLength = wcslen(RemoteName);
//
// Must be at least \\x\y if local device name is specified.
// Otherwise it must be at least \\x.
//
if ((RemoteNameLength < 5 && ARGUMENT_PRESENT(LocalName)) || (RemoteNameLength < 3)) { return WN_BAD_NETNAME; }
//
// First two characters must be "\\"
//
if (*RemoteName != L'\\' || RemoteName[1] != L'\\') { return WN_BAD_NETNAME; }
if (! ARGUMENT_PRESENT(LocalName) && (IS_VALID_TOKEN(&RemoteName[2], RemoteNameLength - 2))) {
//
// Return success for \\Server case.
//
*OutputBuffer = (PVOID) LocalAlloc( LMEM_ZEROINIT, (RemoteNameLength + 1) * sizeof(WCHAR) );
if (*OutputBuffer == NULL) { KdPrint(("NWLIB: NwLibCanonRemoteName LocalAlloc failed %lu\n", GetLastError())); return ERROR_NOT_ENOUGH_MEMORY; }
wcscpy(*OutputBuffer, RemoteName);
return NO_ERROR; }
//
// Must have at least one more backslash after the third character
//
if (wcschr(&RemoteName[3], L'\\') == NULL) { return WN_BAD_NETNAME; }
//
// Last character cannot a backward slash
//
if (RemoteName[RemoteNameLength - 1] == L'\\') { return WN_BAD_NETNAME; }
//
// Allocate output buffer. Should be the size of the RemoteName
// and space for an extra character to simplify parsing code below.
//
*OutputBuffer = (PVOID) LocalAlloc( LMEM_ZEROINIT, (RemoteNameLength + 2) * sizeof(WCHAR) );
if (*OutputBuffer == NULL) { KdPrint(("NWLIB: NwLibCanonRemoteName LocalAlloc failed %lu\n", GetLastError())); return ERROR_NOT_ENOUGH_MEMORY; }
wcscpy(*OutputBuffer, RemoteName);
//
// Convert all backslashes to NULL terminator, skipping first 2 chars.
//
for (i = 2; i < RemoteNameLength; i++) { if ((*OutputBuffer)[i] == L'\\') {
(*OutputBuffer)[i] = 0;
//
// Two consecutive forward or backslashes is bad.
//
if ((i + 1 < RemoteNameLength) && ((*OutputBuffer)[i + 1] == L'\\')) {
(void) LocalFree((HLOCAL) *OutputBuffer); *OutputBuffer = NULL; return WN_BAD_NETNAME; } } }
//
// Validate each token of the RemoteName, separated by NULL terminator.
//
TokenPtr = *OutputBuffer + 2; // Skip first 2 chars
while (*TokenPtr != 0) {
TokenLength = wcslen(TokenPtr);
if ( ( fFirstToken && !IS_VALID_SERVER_TOKEN(TokenPtr, TokenLength)) || ( !fFirstToken && !IS_VALID_TOKEN(TokenPtr, TokenLength)) ) { (void) LocalFree((HLOCAL) *OutputBuffer); *OutputBuffer = NULL; return WN_BAD_NETNAME; }
fFirstToken = FALSE; TokenPtr += TokenLength + 1; }
//
// Convert NULL separators to backslashes
//
for (i = 0; i < RemoteNameLength; i++) { if ((*OutputBuffer)[i] == 0) { (*OutputBuffer)[i] = L'\\'; } }
if (ARGUMENT_PRESENT(OutputBufferLength)) { *OutputBufferLength = RemoteNameLength; }
return NO_ERROR; }
DWORD NwLibCanonUserName( IN LPWSTR UserName, OUT LPWSTR *OutputBuffer, OUT LPDWORD OutputBufferLength OPTIONAL ) /*++
Routine Description:
This routine canonicalizes the user name by checking to see if the name contains any illegal characters.
Arguments:
UserName - Supplies a username.
OutputBuffer - Receives a pointer to the canonicalized UserName.
OutputBufferLength - Receives the length of the canonicalized name in number of characters, if specified.
Return Value:
NO_ERROR - Successfully canonicalized the username.
WN_BAD_NETNAME - UserName is invalid.
ERROR_NOT_ENOUGH_MEMORY - Could not allocate output buffer.
--*/ { DWORD UserNameLength;
//
// Cannot be a NULL or empty string
//
if (UserName == NULL) { return WN_BAD_NETNAME; }
UserNameLength = wcslen(UserName);
if (! IS_VALID_TOKEN(UserName, UserNameLength)) { return WN_BAD_NETNAME; }
//
// Allocate output buffer. Should be the size of the UserName
// plus 1 for the special case of PRN -> LPT1 or AUX -> COM1.
//
*OutputBuffer = (PVOID) LocalAlloc( LMEM_ZEROINIT, (UserNameLength + 1) * sizeof(WCHAR) );
if (*OutputBuffer == NULL) { KdPrint(("NWLIB: NwLibCanonUserName LocalAlloc failed %lu\n", GetLastError())); return ERROR_NOT_ENOUGH_MEMORY; }
wcscpy(*OutputBuffer, UserName);
if (ARGUMENT_PRESENT(OutputBufferLength)) { *OutputBufferLength = UserNameLength; }
return NO_ERROR; }
|