summaryrefslogtreecommitdiffstats
path: root/private/nw/nwlib/canon.c
diff options
context:
space:
mode:
Diffstat (limited to 'private/nw/nwlib/canon.c')
-rw-r--r--private/nw/nwlib/canon.c480
1 files changed, 480 insertions, 0 deletions
diff --git a/private/nw/nwlib/canon.c b/private/nw/nwlib/canon.c
new file mode 100644
index 000000000..c33846a66
--- /dev/null
+++ b/private/nw/nwlib/canon.c
@@ -0,0 +1,480 @@
+/*++
+
+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;
+}