diff options
author | Adam <you@example.com> | 2020-05-17 05:51:50 +0200 |
---|---|---|
committer | Adam <you@example.com> | 2020-05-17 05:51:50 +0200 |
commit | e611b132f9b8abe35b362e5870b74bce94a1e58e (patch) | |
tree | a5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/nw/nwscript/nwapi3.c | |
download | NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2 NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip |
Diffstat (limited to 'private/nw/nwscript/nwapi3.c')
-rw-r--r-- | private/nw/nwscript/nwapi3.c | 1457 |
1 files changed, 1457 insertions, 0 deletions
diff --git a/private/nw/nwscript/nwapi3.c b/private/nw/nwscript/nwapi3.c new file mode 100644 index 000000000..5408d286e --- /dev/null +++ b/private/nw/nwscript/nwapi3.c @@ -0,0 +1,1457 @@ +/************************************************************************* +* +* NWAPI3.C +* +* NetWare routines ported from DOS +* +* Copyright (c) 1995 Microsoft Corporation +* +* $Log: N:\NT\PRIVATE\NW4\NWSCRIPT\VCS\NWAPI3.C $ +* +* Rev 1.4 18 Apr 1996 16:52:14 terryt +* Various enhancements +* +* Rev 1.3 10 Apr 1996 14:23:20 terryt +* Hotfix for 21181hq +* +* Rev 1.5 13 Mar 1996 18:49:28 terryt +* Support directory maps +* +* Rev 1.4 12 Mar 1996 19:55:10 terryt +* Relative NDS names and merge +* +* Rev 1.2 22 Dec 1995 14:26:02 terryt +* Add Microsoft headers +* +* Rev 1.1 22 Nov 1995 15:41:56 terryt +* Fix MAP ROOT of search drives +* +* Rev 1.0 15 Nov 1995 18:07:38 terryt +* Initial revision. +* +* Rev 1.3 25 Aug 1995 16:23:22 terryt +* Capture support +* +* Rev 1.2 26 Jul 1995 16:02:08 terryt +* Allow deletion of current drive +* +* Rev 1.1 23 Jun 1995 09:49:22 terryt +* Add error message for mapping over MS network drive +* +* Rev 1.0 15 May 1995 19:10:54 terryt +* Initial revision. +* +*************************************************************************/ + +/* +Module Name: + nwapi3.c + +Abstract: + can : + - view current mapping + - create/change a drive mapping + - create/change a search drive mapping + - map a drive to a fake root + - map the next available drive + + SYNTAX (Command line) + View current mapping. + MAP [drive:] + Create or change network drive mappings + MAP path + MAP drive:=[drive:|path] + MAP [DEL[ete] | REM[ove]] drive: + Create or change search dirve mappings + MAP [INS[ert]] drive:=[drive:|path] + Map a drive to a fake root directory + MAP ROOT drive:=[drive:|path] + Map the next available dirve + MAP N[ext] [drive:|path] + + + +Author : Thierry TABARD (thierryt) + +Revision history : + - 03/10/94 thierryt started + - 05/13/94 congpay rewrote. +*/ + +#include <ctype.h> +#include <direct.h> +#include "common.h" + +/* Local functions*/ +int IsDrive( char * input); +int GetSearchNumber( char * input); +int IsNetwareDrive (int driveNum); +int IsLocalDrive (int driveNum); +int IsNonNetwareNetworkDrive (int driveNum); +int GetDriveFromSearchNumber (int searchNumber); + +void DisplayDriveMapping(WORD drive); +void DisplaySearchDriveMapping(int searchNumber); + +int ParseMapPath(char * mapPath, char * volName, char * dirPath, char * serverName, int fMapErrorsOn, char *lpCommand); +int MapDrive (int driveNum, int searchNum, char * mapPath, int bRoot, int bInsert, int fMapErrorsOn, char *lpCommand); +int MapNonSearchDrive (int driveNum, char *mapPath, int bRoot, int fMapDisplayOn, int fMapErrorsOn, char *lpCommand); +int MapSearchDrive (int searchNum, int driveNum, char *mapPath, int bInsert, int bRoot, int fMapDisplayOn, int fMapErrorsOn, char *lpCommand); +int MapNextAvailableDrive (char *mapPath, int fMapDisplayOn, int fMapErrorsOn, char *lpCommand); + +void RemoveDriveFromPath(int searchNumber, int fMapErrorsOn); +int RemoveDrive (WORD drive, int fMapDisplayOn, int fMapErrorsOn); +void RemoveSearchDrive (int searchNumber, int fMapDisplayOn, int fMapErrorsOn); +int InsertSearchDrive(int searchNum, int driveNum, int bInsert, char * insertPath); + +#define CM_MAP 0 +#define CM_DEL 1 +#define CM_NEXT 2 +#define CM_HELP 3 +#define MAX_INPUT_PATH_LEN 128 + +int fMapDisplayOn = TRUE; +int fMapErrorsOn = TRUE; +int SafeDisk = 2; + +int GetFlag (char *buffer, int *pfInsert, int *pfRoot, char **ppPath) +{ + int nFlag, nLen; + char *lpSpace, *lpTemp; + + if (((*buffer == '/') || (*buffer == '-') || (*buffer == '\\')) && + (*(buffer+1) == '?')) + return CM_HELP; + + lpSpace = strchr (buffer, ' '); + + nFlag = CM_MAP; // A bug! + + if (lpSpace == NULL) + { + *ppPath = buffer; + return CM_MAP; + } + + nLen = lpSpace - buffer; + lpSpace++; + + if (!strncmp(buffer, __DEL__, max (3, nLen)) || + !strncmp(buffer, __REM__, max (3, nLen))) + nFlag = CM_DEL; + else if (!strncmp(buffer, __NEXT__, nLen)) + nFlag = CM_NEXT; + else if (!strncmp(buffer, __INS__, max (3, nLen))) + { + *pfInsert = TRUE; + if (lpTemp = strchr (lpSpace, ' ')) + { + nLen = lpTemp - lpSpace; + if (!strncmp(lpSpace, __ROOT__, nLen)) + { + *pfRoot = TRUE; + lpSpace = lpTemp+1; + } + } + } + else if (!strncmp(buffer, __ROOT__, nLen)) + { + *pfRoot = TRUE; + if (lpTemp = strchr (lpSpace, ' ')) + { + nLen = lpTemp - lpSpace; + if (!strncmp(lpSpace, __INS__, max (3, nLen))) + { + *pfInsert = TRUE; + lpSpace = lpTemp+1; + } + } + } + else + lpSpace = buffer; + + *ppPath = lpSpace; + + return(nFlag); +} + +int Map (char * buffer) +{ + WORD status, driveNum; + char *lpCommand, *inputPath, *lpEqual; + int fRoot, fInsert, fSpace, fCommandHandled; + int nFlag, searchNumber, iRet; + + // Fix for NWCS. + // NWGetDriveStatus() always returns 1800 on first call for non-Network + // drives on NWCS. So we call with c: first to pass the first call. + GetDriveStatus (3, + NETWARE_FORMAT_SERVER_VOLUME, + &status, + NULL, + NULL, + NULL, + NULL); + + lpCommand = strtok (buffer, ";"); + + if (lpCommand == NULL) + { + DisplayMapping(); + return(0); + } + + do + { + fRoot = FALSE; + fInsert = FALSE; + fSpace = FALSE; + fCommandHandled = TRUE; + + // Make sure first and last char of the command are not spaces. + if (*lpCommand == ' ') + lpCommand++; + + if (*(lpCommand+strlen (lpCommand)-1) == ' ') + *(lpCommand+strlen (lpCommand)-1) = 0; + + if (!strcmp (lpCommand, "DISPLAY ON")) + { + fMapDisplayOn = TRUE; + continue; + } + else if (!strcmp (lpCommand, "DISPLAY OFF")) + { + fMapDisplayOn = FALSE; + continue; + } + else if (!strcmp (lpCommand, "ERROR ON") || !strcmp (lpCommand, "ERRORS ON")) + { + fMapErrorsOn = TRUE; + continue; + } + else if (!strcmp (lpCommand, "ERROR OFF") || !strcmp (lpCommand, "ERRORS OFF")) + { + fMapErrorsOn = FALSE; + continue; + } + + nFlag = GetFlag (lpCommand, &fInsert, &fRoot, &inputPath); + + /* + * The 4X login program is much more forgiving about spaces + * in the map command. + */ + { + char *lpTemp; + char *lpCur; + int inquote = FALSE; + + lpTemp = inputPath; + lpCur = inputPath; + + /* + * Compress blanks unless the string is quoted + */ + while ( *lpTemp ) + { + if ( *lpTemp == '\"' ) + { + if ( inquote ) + inquote = FALSE; + else + inquote = TRUE; + } + else if ( !inquote && + (( *lpTemp == ' ' ) || + ( *lpTemp == '\t' ) ) ) + { + } + else + { + *lpCur++ = *lpTemp; + } + lpTemp = NWAnsiNext(lpTemp); + } + *lpCur = '\0'; + } + + + if (nFlag == CM_HELP && fMapErrorsOn) + DisplayMessage(IDR_MAP_USAGE); + else if (nFlag == CM_NEXT) + { + if (strchr (inputPath, '=') || + strchr (inputPath, ' ') || + strchr (inputPath, '\t')) + fCommandHandled = FALSE; + else + iRet = MapNextAvailableDrive (inputPath, fMapDisplayOn, fMapErrorsOn, lpCommand); + } + else if (nFlag == CM_DEL) + { + if (driveNum = IsDrive (inputPath)) + iRet = RemoveDrive (driveNum, fMapDisplayOn, fMapErrorsOn); + else if (searchNumber = GetSearchNumber(inputPath)) + RemoveSearchDrive (searchNumber, fMapDisplayOn, fMapErrorsOn); + else + fCommandHandled = FALSE; + } + else //nFlag = CM_MAP + { + if (driveNum = IsDrive (inputPath)) + { + if (fInsert) + fCommandHandled = FALSE; + else if (fRoot) + iRet = MapNonSearchDrive (0, inputPath, TRUE, fMapDisplayOn, fMapErrorsOn, lpCommand); + else + DisplayDriveMapping(driveNum); + } + else if (searchNumber = GetSearchNumber (inputPath)) + { + if (fInsert || fRoot) + fCommandHandled = FALSE; + else + DisplaySearchDriveMapping(searchNumber); + } + else if ((lpEqual = strchr (inputPath, '=')) == NULL) + { + if (fInsert || strchr (inputPath, ' ')) + fCommandHandled = FALSE; + else + { + /* + * We must cope with MAP K:DIR which means change the + * directory on K: + */ + driveNum = 0; + if (isalpha(inputPath[0]) && (inputPath[1] == ':')) + { + driveNum = toupper(inputPath[0]) - 'A' + 1; + if ( !IsNetwareDrive(driveNum) ) + { + driveNum = 0; + } + } + iRet = MapNonSearchDrive (driveNum, inputPath, fRoot, fMapDisplayOn, fMapErrorsOn, lpCommand); + } + } + else + { + if ( ( !fNDS && strchr (lpEqual+2, ' ') ) + || lpEqual == inputPath) { + fCommandHandled = FALSE; + } + else + { + if (*AnsiPrev(inputPath, lpEqual) == ' ') + { + fSpace = TRUE; + *(lpEqual-1) = 0; + } + else + *lpEqual = 0; + + if (*(lpEqual+1) == ' ') + lpEqual++; + + driveNum = IsDrive (inputPath); + searchNumber = GetSearchNumber (inputPath); + *(inputPath+strlen(inputPath)) = fSpace? ' ' : '='; + + /* + * This is to handle the cases: + * + * map x:=s3:=sys:public + * map s3:=x:=sys:public + * + * Unfortuneatly the underlying parsing routines + * want everything null terminated, so we need + * to do the following shuffle. + * + */ + if ( driveNum || searchNumber ) + { + if ((strchr (lpEqual+1, '=')) != NULL) + { + char * lpEqual2; + char *tmpPath = _strdup( lpEqual+1 ); + + lpEqual2 = strchr (tmpPath, '='); + + if (*AnsiPrev(tmpPath, lpEqual2) == ' ') + { + fSpace = TRUE; + *(lpEqual2-1) = 0; + } + else + *lpEqual2 = 0; + + if (*(lpEqual2+1) == ' ') + lpEqual2++; + + if ( searchNumber ) + { + driveNum = IsDrive (tmpPath); + } + else + { + searchNumber = GetSearchNumber (tmpPath); + } + + if ( driveNum && searchNumber ) + { + lpEqual += (lpEqual2 - tmpPath) + 1; + } + + free (tmpPath); + + } + } + + if (searchNumber) + { + iRet = MapSearchDrive (searchNumber, driveNum, lpEqual+1, fInsert, fRoot, fMapDisplayOn, fMapErrorsOn, lpCommand); + } + else if (driveNum) + { + if (fInsert) + fCommandHandled = FALSE; + else + iRet = MapNonSearchDrive (driveNum, lpEqual+1, fRoot, fMapDisplayOn, fMapErrorsOn, lpCommand); + } + else + fCommandHandled = FALSE; + } + } + } + + if (!fCommandHandled && fMapErrorsOn) + { + DisplayMessage(IDR_MAP_INVALID_PATH, lpCommand); + } + }while ((lpCommand = strtok (NULL, ";")) != NULL); + + return(iRet & 0xFF); +} + +/* Return drive number if input is a drive specified as a letter followed + by ':' for example if input is "A:", return 1 + or netware drive could be specified as *1: for example. + Otherwise, return 0. + */ +int IsDrive( char * input) +{ + unsigned short driveNum = 0, n; + + if (isalpha(input[0]) && (input[1] == ':') && (input[2] == 0)) + driveNum = toupper(input[0]) - 'A' + 1; + else if (input[0] == '*' && isdigit (input[1]) && input[1] != '0') + { + if (isdigit (input[2]) && input[3] == ':' && input[4] == 0) + n = (input[1]-'0')*10+(input[2]-'0'); + else if (input[2] == ':' && input[3] == 0) + n = input[1]-'0'; + + if (n) + { + GetFirstDrive (&driveNum); + driveNum += (n-1); + if (driveNum < 1 || driveNum > 26) + driveNum = 0; + } + } + + return driveNum; +} + +/* + If the input is "Sn:", return n, where n > 0 && n <= 16. + Otherwise return 0. + */ +int GetSearchNumber( char * input) +{ + int searchNumber = 0; + char *lpTemp; + + if (input[0] != 'S') + return(0); + + lpTemp = input+1; + while (*lpTemp && isalpha(*lpTemp)) + lpTemp++; + + if (strncmp (input, "SEARCH", lpTemp-input)) + return(0); + + if ((lpTemp[0] > '0') && + (lpTemp[0] <= '9')) + { + if ((lpTemp[1] == ':') && + (lpTemp[2] == 0)) + { + searchNumber = lpTemp[0] - '0'; + } + else if ((lpTemp[0] == '1') && + (lpTemp[1] >= '0') && + (lpTemp[1] <= '6') && + (lpTemp[2] == ':') && + (lpTemp[3] == 0)) + { + searchNumber = 10 + lpTemp[1] - '0'; + } + } + + return(searchNumber); +} + +/* + Return TRUE if the drive is a NetWare drive. + FALSE otherwise. + */ +int IsNetwareDrive (int driveNum) +{ + unsigned int iRet=0; + WORD status; + + if (iRet = GetDriveStatus ((unsigned short)driveNum, + NETWARE_FORMAT_SERVER_VOLUME, + &status, + NULL, + NULL, + NULL, + NULL)) + { + return FALSE; + } + + return (status & NETWARE_NETWARE_DRIVE); +} + +/* + Return TRUE if the drive is a local drive. + FALSE otherwise. + */ +int IsLocalDrive (int driveNum) +{ + unsigned int iRet=0; + WORD status; + + if (iRet = GetDriveStatus ((unsigned short)driveNum, + NETWARE_FORMAT_SERVER_VOLUME, + &status, + NULL, + NULL, + NULL, + NULL)) + { + return FALSE; + } + + return ((status & NETWARE_LOCAL_DRIVE) && !(status & NETWARE_NETWORK_DRIVE)); +} + +/* + Return TRUE if the drive is a network drive that is not netware + FALSE otherwise. + */ +int IsNonNetwareNetworkDrive (int driveNum) +{ + unsigned int iRet=0; + WORD status; + + if (iRet = GetDriveStatus ((unsigned short)driveNum, + NETWARE_FORMAT_SERVER_VOLUME, + &status, + NULL, + NULL, + NULL, + NULL)) + { + return FALSE; + } + + return ((status & NETWARE_NETWORK_DRIVE) && !(status & NETWARE_NETWARE_DRIVE)); +} + +/* + Return the drive number of search drive n. + Return 0 if search drive n does not exist. + */ +int GetDriveFromSearchNumber (int searchNumber) +{ + char *path; + int i; + + path = getenv("PATH"); + + for (i = 1; i < searchNumber; i++) + { + path =strchr (path, ';'); + + if (path == NULL || *(path+1) == 0) + return(0); + + path++; + } + + return(toupper(*path) - 'A' + 1); +} + +/* + Display a specific drive's mapping. + */ +void DisplayDriveMapping(WORD drive) +{ + unsigned int iRet = 0; + WORD status = 0; + char rootPath[MAX_PATH_LEN], relativePath[MAX_PATH_LEN]; + + iRet = GetDriveStatus (drive, + NETWARE_FORMAT_SERVER_VOLUME, + &status, + NULL, + rootPath, + relativePath, + NULL); + if (iRet) + { + DisplayError (iRet, "GetDriveStatus"); + return; + } + + if (status & NETWARE_NETWARE_DRIVE) + DisplayMessage(IDR_NETWARE_DRIVE, 'A'+drive-1, rootPath, relativePath); + else if ((status & NETWARE_NETWORK_DRIVE) || (status & NETWARE_LOCAL_DRIVE)) + DisplayMessage(IDR_LOCAL_DRIVE, 'A'+drive-1); + else + DisplayMessage(IDR_UNDEFINED, 'A'+drive-1); +} + +/* + Display a specific search drive's mapping. + */ +void DisplaySearchDriveMapping(int searchNumber) +{ + unsigned int iRet = 0; + char *p, *searchPath; + int i; + WORD status; + char path[MAX_PATH_LEN], rootPath[MAX_PATH_LEN], relativePath[MAX_PATH_LEN]; + + searchPath = NWGetPath(); + + for (i = 0; i < searchNumber-1; i++) + { + searchPath = strchr (searchPath, ';'); + if (searchPath != NULL) + searchPath++; + else + return; + } + + p = strchr (searchPath, ';'); + if (p != NULL) + { + i= p-searchPath; + strncpy (path, searchPath, i); + path[i] = 0; + } + else + strcpy (path, searchPath); + + if (isalpha(*path) && *(path+1) == ':') + { + iRet = GetDriveStatus ((unsigned short)(toupper(*path)-'A'+1), + NETWARE_FORMAT_SERVER_VOLUME, + &status, + NULL, + rootPath, + relativePath, + NULL); + + if (iRet) + { + DisplayError (iRet, "GetDriveStatus"); + return; + } + else + { + if (status & NETWARE_NETWARE_DRIVE) + DisplayMessage(IDR_NETWARE_SEARCH, searchNumber, path, rootPath, relativePath); + else + DisplayMessage(IDR_LOCAL_SEARCH, searchNumber, path); + } + } + else + DisplayMessage(IDR_LOCAL_SEARCH, searchNumber, path); +} + +/* + Return TRUE if the mapPath is parsed, FALSE otherwise. + */ +int ParseMapPath(char * mapPath, char * volName, char * dirPath, char * serverName, int fMapErrorsOn, char * lpCommand) +{ + unsigned int iRet=0; + char *pColon, inputPath[MAX_PATH_LEN]; + int drive, nDriveNum; + + // fix g:=:sys:\public case. + if (*mapPath == ':') + mapPath++; + + if (strlen (mapPath) > MAX_INPUT_PATH_LEN) + { + if (fMapErrorsOn) + DisplayMessage(IDR_INVALID_PATH, mapPath); + return FALSE; + } + + // Get the drive or volume part if there is one. + if (pColon = strchr (mapPath, ':')) + { + char *directory = pColon+1; + int searchNumber; + + // Assing drive: part to input. + strncpy (inputPath, mapPath, directory-mapPath); + inputPath[directory-mapPath] = 0; + + if (nDriveNum = IsDrive (inputPath)) + { + if (*inputPath == '*') + { + *inputPath = 'A' + nDriveNum - 1; + *(inputPath+1) = ':'; + *(inputPath+2) = 0; + } + else if (!IsNetwareDrive(nDriveNum)) + { + if (fMapErrorsOn) + DisplayMessage(IDR_NOT_NETWORK_DRIVE); + return(FALSE); + } + } + else if (searchNumber = GetSearchNumber(inputPath)) + { + int drive = GetDriveFromSearchNumber (searchNumber); + + if (!drive) + { + if (fMapErrorsOn) + DisplayMessage(IDR_SEARCH_DRIVE_NOT_EXIST, searchNumber); + return FALSE; + } + + if (!IsNetwareDrive(drive)) + { + if (fMapErrorsOn) + DisplayMessage(IDR_NOT_NETWORK_DRIVE); + return(FALSE); + } + + inputPath[0] = 'A' + drive - 1; + inputPath[1] = ':'; + inputPath[2] = 0; + } + + strcat (inputPath, directory); + } + else + { + if ( fNDS ) + { + CHAR fullname[MAX_PATH]; + if ( !NDSCanonicalizeName( mapPath, fullname, MAX_PATH, TRUE ) ) + if ( !ConverNDSPathToNetWarePathA( fullname, DSCL_DIRECTORY_MAP, + inputPath ) ) + goto ParseThePath; + } + + // If drive is not specified, the current drive is used. + drive = _getdrive(); + if (!IsNetwareDrive(drive)) + { + if (fMapErrorsOn) + DisplayMessage(IDR_NOT_NETWORK_DRIVE); + return(FALSE); + } + + inputPath[0] = 'A'+drive-1; + inputPath[1] = ':'; + inputPath[2] = 0; + + strcat (inputPath, mapPath); + } + +ParseThePath: + + iRet = ParsePath (inputPath, + serverName, + volName, + dirPath); + if (iRet) + { + if (iRet == 0x880F) + { + DisplayMessage(IDR_MAP_NOT_ATTACHED_SERVER, lpCommand); + return(FALSE); + } + else + { + if (fMapErrorsOn) + DisplayMessage(IDR_INVALID_PATH, inputPath); + return(FALSE); + } + } + + return(TRUE); +} + +/* + Map drive to mapPath + */ +int MapDrive (int drive, int searchNum, char * mapPath, int bRoot, int bInsert, int fMapErrorsOn, char *lpCommand) +{ + unsigned int iRet=0; + char volName[MAX_VOLUME_LEN+1]; //+1 for append ':'. + char dirPath[MAX_DIR_PATH_LEN]; + int currentDrive; + int OvermapDrive = -1; + char serverName[MAX_NAME_LEN]; + + if (!ParseMapPath(mapPath, volName, dirPath, serverName, fMapErrorsOn, lpCommand)) + return(3); + + if (IsNetwareDrive(drive)) + { + if ( drive == _getdrive() ) { + OvermapDrive = drive; + _chdrive (SafeDisk); + } + if (iRet = DeleteDriveBase ((unsigned short)drive)) + { + if (fMapErrorsOn) { + /* Cannot delete the drive you are on */ + if (iRet == ERROR_DEVICE_IN_USE) + DisplayMessage(IDR_CAN_NOT_CHANGE_DRIVE); + else + DisplayError (iRet, "DeleteDriveBase"); + } + return iRet; + } + } + else if ( IsNonNetwareNetworkDrive(drive) ) { + if (fMapErrorsOn) + DisplayMessage(IDR_NON_NETWARE_NETWORK_DRIVE, lpCommand); + return 3; + } + + if (bRoot) + { + // +2 is for strcat with ":". + char *fullPath = malloc( MAX_VOLUME_LEN + strlen (dirPath) + 2); + if (fullPath == NULL) + { + if (fMapErrorsOn) + DisplayMessage(IDR_NOT_ENOUGH_MEMORY); + return 8; + } + + strcpy (fullPath, volName); + strcat (fullPath, ":"); + strcat (fullPath, dirPath); + + iRet = SetDriveBase ((unsigned short)drive, + serverName, + 0, + fullPath); + + // Relative names need to be expanded for the redirector + + if ( iRet && fNDS && ( volName[strlen(volName) - 1] == '.' ) ) + { + char canonName[MAX_VOLUME_LEN+1]; + if ( !NDSCanonicalizeName( volName, canonName, MAX_VOLUME_LEN, TRUE ) ) + { + strcpy (fullPath, canonName); + strcat (fullPath, ":"); + strcat (fullPath, dirPath); + + iRet = SetDriveBase ((unsigned short)drive, + serverName, + 0, + fullPath); + } + } + + if (iRet == 0) + { + if (searchNum) + searchNum = InsertSearchDrive(searchNum, drive, bInsert, NULL); + + currentDrive = _getdrive(); + _chdrive (drive); + _chdir( "\\" ); + _chdrive (currentDrive); + ExportCurrentDirectory( drive ); + + if (fMapDisplayOn) + { + if (searchNum) + DisplaySearchDriveMapping (searchNum); + else + DisplayDriveMapping((unsigned short)drive); + } + } + else + { + if (fMapErrorsOn) + { + switch ( iRet ) + { + case ERROR_DEVICE_IN_USE: + DisplayMessage(IDR_CAN_NOT_CHANGE_DRIVE); + break; + case ERROR_BAD_NETPATH: + case ERROR_BAD_NET_NAME: + DisplayMessage(IDR_VOLUME_NOT_EXIST, volName); + iRet = 3; + break; + case ERROR_EXTENDED_ERROR: + NTPrintExtendedError(); + iRet = 3; + break; + default: + DisplayMessage(IDR_MAP_ERROR, iRet); + DisplayMessage(IDR_MAP_FAILED, lpCommand); + iRet = 3; + break; + } + } + } + + free (fullPath); + } + else + { + // NETX requires to end the volName with ':'. + strcat (volName, ":"); + + iRet = SetDriveBase ((unsigned short)drive, + serverName, + 0, + volName); + + // Relative names need to be expanded for the redirector + + if ( iRet && fNDS && ( volName[strlen(volName) - 2] == '.' ) ) + { + char canonName[MAX_VOLUME_LEN+1]; + + volName[strlen(volName)-1] = '\0'; + if ( !NDSCanonicalizeName( volName, canonName, MAX_VOLUME_LEN, TRUE ) ) + { + strcat (canonName, ":"); + + iRet = SetDriveBase ((unsigned short)drive, + serverName, + 0, + canonName); + } + } + + if (iRet) + { + if (fMapErrorsOn) + { + switch ( iRet ) + { + case ERROR_DEVICE_IN_USE: + DisplayMessage(IDR_CAN_NOT_CHANGE_DRIVE); + break; + case ERROR_EXTENDED_ERROR: + NTPrintExtendedError(); + iRet = 3; + break; + case ERROR_BAD_NETPATH: + case ERROR_BAD_NET_NAME: + default: + DisplayMessage(IDR_MAP_INVALID_PATH, lpCommand); + iRet = 3; + break; + } + } + } + else + { + // Succeed. + + if (searchNum) + searchNum = InsertSearchDrive(searchNum, drive, bInsert, NULL); + + currentDrive = _getdrive(); + _chdrive (drive); + if (!iRet && *dirPath) + { + iRet = _chdir( "\\" ); + if ( !iRet ) + iRet = _chdir (dirPath); + if ( iRet ) { + if (fMapErrorsOn) + { + DisplayMessage(IDR_MAP_INVALID_PATH, lpCommand); + } + + iRet = 3; + } + + } + else + { + _chdir( "\\" ); + } + _chdrive (currentDrive); + ExportCurrentDirectory( drive ); + + if (iRet == 0 && fMapDisplayOn) + { + if (searchNum) + DisplaySearchDriveMapping (searchNum); + else + DisplayDriveMapping((unsigned short)drive); + } + + } + } + + if ( OvermapDrive != -1 ) + _chdrive (OvermapDrive); + + return(iRet); +} + +/* + Map drive secified by driveNum to mapPath. + If bRoot is TRUE, use mapPath as the drive base. + */ +int MapNonSearchDrive (int driveNum, char *mapPath, int bRoot, int fMapDisplayOn, int fMapErrorsOn, char *lpCommand) +{ + int driveLetter, iRet = 0; + + if ((driveNum == 0) && (!strchr(mapPath, ':') && !bRoot)) + { + // map current drive to different directory. + if (_chdir(mapPath) && fMapErrorsOn) + { + DisplayMessage(IDR_DIRECTORY_NOT_FOUND, mapPath); + iRet = 3; + } + else { + ExportCurrentDirectory( _getdrive() ); + if (fMapDisplayOn) + DisplayDriveMapping((unsigned short)driveNum); + } + return(iRet); + } + else if ( (driveNum) && (isalpha(mapPath[0]) && (mapPath[1] == ':'))) + { + int mapdriveNum = toupper(mapPath[0]) - 'A' + 1; + + if ( driveNum == mapdriveNum ) + { + // map drive to different directory. + // map k:=k:\dir + + WORD currentDrive; + currentDrive = _getdrive(); + _chdrive (driveNum); + if (_chdir(mapPath) && fMapErrorsOn) + { + DisplayMessage(IDR_DIRECTORY_NOT_FOUND, mapPath); + iRet = 3; + } + else + { + ExportCurrentDirectory( _getdrive() ); + if (fMapDisplayOn) + DisplayDriveMapping((unsigned short)driveNum); + } + _chdrive (currentDrive); + return(iRet); + } + } + + if (driveNum == 0) + driveNum = _getdrive(); + + driveLetter = 'A' + driveNum -1; + + return MapDrive (driveNum, 0, mapPath, bRoot, 0, fMapErrorsOn, lpCommand); +} + +/* + Map the last free drive to mapPath and put it in the search path. + If bInsert is TRUE, don't replace search drive n, otherwise, + replace. + If bRoot is TRUE, use mapPath as the drive base. + */ +int MapSearchDrive (int searchNum, int driveNum, char *mapPath, int bInsert, int bRoot, int fMapDisplayOn, int fMapErrorsOn, char *lpCommand) +{ + unsigned int iRet=0; + int i; + WORD status; + char * lpEqual; + + /* + * Handle syntax map s2:=w:=volume: + * Handle syntax map w:=s2:=volume: + */ + if ( driveNum ) + { + return MapDrive (driveNum, searchNum, mapPath, bRoot, bInsert, fMapErrorsOn, lpCommand); + } + + // Check if mapPath is local path. + if (mapPath[1] == ':' && + IsLocalDrive (toupper(mapPath[0])-'A'+1)) + { + i = 0; // a bug? + searchNum = InsertSearchDrive(searchNum, i, bInsert, mapPath); + if ((searchNum != 0) && fMapDisplayOn) + DisplayMessage(IDR_LOCAL_SEARCH, searchNum, mapPath); + return 0; + } + + // Try to find the last available drive. + for (i = 26; i >= 1; i--) + { + iRet = GetDriveStatus ((unsigned short)i, + NETWARE_FORMAT_SERVER_VOLUME, + &status, + NULL, + NULL, + NULL, + NULL); + if (iRet) + continue; + + if (!(status & NETWARE_LOCAL_DRIVE) && + !(status & NETWARE_NETWORK_DRIVE)) + { + // Found. Map it to the path. + return MapDrive (i, searchNum, mapPath, bRoot, bInsert, fMapErrorsOn, lpCommand); + } + } + + if (fMapErrorsOn) + DisplayMessage (IDR_NO_DRIVE_AVAIL); + return(0); +} + +/* + Map the next available drive to the mapPath. + */ +int MapNextAvailableDrive (char *mapPath, int fMapDisplayOn, int fMapErrorsOn, char *lpCommand) +{ + unsigned int iRet = 0; + int i; + WORD status; + + // Find a free drive that is not mapped. + // Then map it to the mapPath. + for (i = 1; i <= 26; i++) + { + iRet = GetDriveStatus ((unsigned short)i, + NETWARE_FORMAT_SERVER_VOLUME, + &status, + NULL, + NULL, + NULL, + NULL); + if (iRet) + { + if (fMapErrorsOn) + DisplayError (iRet, "GetDriveStatus"); + return iRet; + } + + if (!(status & NETWARE_LOCAL_DRIVE) && + !(status & NETWARE_NETWORK_DRIVE)) + { + iRet = MapNonSearchDrive (i, mapPath, FALSE, fMapDisplayOn, fMapErrorsOn, lpCommand); + return iRet; + } + } + + if (fMapErrorsOn) + DisplayMessage(IDR_NO_DRIVE_AVAIL); + + return(0); +} + +/* + Remove a drive mapping. + */ +int RemoveDrive (WORD drive, int fMapDisplayOn, int fMapErrorsOn) +{ + unsigned int iRet=0; + int searchNum; + + if (IsNetwareDrive (drive)) + { + if (searchNum = IsSearchDrive(drive)) + { + RemoveSearchDrive (searchNum, fMapDisplayOn, fMapErrorsOn); + } + else + { + /* + * Can't delete current drive on NT + */ + if ( drive == _getdrive() ) { + _chdrive (SafeDisk); + } + if (iRet = DeleteDriveBase (drive)) + { + if (fMapErrorsOn) + DisplayError (iRet, "DeleteDriveBase"); + } + else + { + if (fMapDisplayOn) + DisplayMessage(IDR_DEL_DRIVE, 'A'+drive-1); + } + } + } + else + { + if (fMapErrorsOn) + DisplayMessage(IDR_WRONG_DRIVE, 'A'+drive-1); + + return(50); //error level. + } + + return(0); +} + +/* + Remove a search drive. + */ +void RemoveSearchDrive (int searchNumber, int fMapDisplayOn, int fMapErrorsOn) +{ + WORD drive; + + // Get the drive number. + drive = GetDriveFromSearchNumber (searchNumber); + + if (!drive) + { + if (fMapErrorsOn) + DisplayMessage(IDR_SEARCH_DRIVE_NOT_EXIST, searchNumber); + return; + } + + // If the drive is a netware drive, remove the drive mapping. + if (IsNetwareDrive (drive)) + { + unsigned int iRet=0; + /* + * Can't delete current drive on NT + */ + if ( drive == _getdrive() ) { + _chdrive (SafeDisk); + } + if (iRet = DeleteDriveBase (drive)) + { + if (fMapErrorsOn) + DisplayError (iRet, "DeleteDriveBase"); + return; + } + } + + RemoveDriveFromPath (searchNumber, fMapErrorsOn); + + if (fMapDisplayOn) + DisplayMessage(IDR_DEL_SEARCH_DRIVE, 'A'+drive-1); + + // If the drive is not a local drive, remove all reference + // to the drive in the path. + if (!IsLocalDrive (drive)) + { + while (searchNumber = IsSearchDrive (drive)) + { + RemoveDriveFromPath (searchNumber, fMapErrorsOn); + } + } +} + +/* + Remove a search drive from the path. + */ +void RemoveDriveFromPath(int searchNumber, int fMapErrorsOn) +{ + char *pOldPath, *pNewPath, *restEnvSeg, *pPath, *Path; + int i, n; + + // Move pOldPath to where we want to put the new path string. + pOldPath = NWGetPath(); + pPath = malloc( strlen(pOldPath) + 5 + 1 + 1 ); + strcpy(pPath, "PATH="); + strcat(pPath, pOldPath); + pOldPath = pPath + 5; + + for (i = 1; i < searchNumber; i++) + { + pOldPath=strchr (pOldPath, ';'); + + if (pOldPath == NULL) + { + if (fMapErrorsOn) + DisplayMessage(IDR_SEARCH_DRIVE_NOT_EXIST, searchNumber); + free( pPath ); + return; + } + + pOldPath++; + } + + // Move pNewPath to the beginning of the path string that + // needs to be moved. + if (pNewPath = strchr (pOldPath, ';')) + pNewPath++ ; + else + pNewPath = pOldPath + strlen (pOldPath); + + // Calculate the number of characters needs to be moved. + n = strlen (pNewPath) + 1; + restEnvSeg = pNewPath + n; + + n++; + + // Move the path string to overwrite the search drive. + memmove (pOldPath, pNewPath, n); + + Path = malloc (strlen (pPath)+1); + strcpy (Path, pPath); + _putenv (Path); + ExportEnv( pPath ); + free( pPath ); +} + + +/* + If bInsert is TRUE, insert dirve specified by driveNum as search + drive specified by searchNum. Otherwise replace search drive + specified by searchNum with drive specified by driveNum. + */ +int InsertSearchDrive(int searchNum, int driveNum, int bInsert, char * insertPath) +{ + char *pOldPath, *pNewPath, *restEnvSeg, *pPath, *Path; + int i, n = 0, bSemiColon, nInsertChar; + + nInsertChar = (insertPath == NULL)? 3 : strlen (insertPath); + + // Check if memory block is large enough. + if (!MemorySegmentLargeEnough (nInsertChar+1)) + return 0; + + // Move pNewPath to where we put the new drive. + pNewPath = NWGetPath(); + pPath = malloc( strlen(pNewPath) + 5 + 1 + nInsertChar + 1 + 1 ); + strcpy(pPath, "PATH="); + strcat(pPath, pNewPath); + pNewPath = pPath + 5; + + for (i = 1; i < searchNum; i++) + { + if (strchr (pNewPath, ';')) + { + pNewPath = strchr (pNewPath, ';'); + } + else + { + pNewPath += strlen (pNewPath); + bInsert = TRUE; + i++; + break; + } + + pNewPath++; + } + + // Move pOldPath to the begining of the path string that needs + // to be moved. + if (bInsert) + pOldPath = pNewPath; + else + { + if ((pOldPath = strchr (pNewPath, ';')) == NULL) + pOldPath = pNewPath + strlen (pNewPath); + else + pOldPath++; + } + + // Figure out the number of characters that need to be moved. + n = strlen (pOldPath) + 1; + restEnvSeg = pOldPath + strlen (pOldPath) + 1; + + n++; + + // If we insert a new drive to the end of the path which ends with + // a ';', or if we replace the last search drive, no ';' is needed. + bSemiColon = bInsert ? (*(pNewPath-1) != ';' || *pOldPath != 0) + : (*pOldPath != 0); + + // Move the old path so that we will have space for the new search drive. + memmove (pNewPath + (bSemiColon? nInsertChar+1:nInsertChar), pOldPath, n); + + if ((*pNewPath == 0)&& bSemiColon) + { + // Insert as the last one to the path. + // Put ';' at the begining. + *pNewPath = ';'; + if (insertPath == NULL) + { + *(pNewPath+1) = 'A' + driveNum - 1; + *(pNewPath+2) = ':'; + *(pNewPath+3) = '.'; + } + else + memcpy (pNewPath+1, insertPath, nInsertChar); + } + else + { + if (insertPath == NULL) + { + *pNewPath = 'A' + driveNum - 1; + *(pNewPath+1) = ':'; + *(pNewPath+2) = '.'; + } + else + memcpy (pNewPath, insertPath, nInsertChar); + if (bSemiColon) + *(pNewPath+nInsertChar) = ';'; + } + + Path = malloc (strlen (pPath)+1); + strcpy (Path, pPath); + _putenv (Path); + ExportEnv( pPath ); + free( pPath ); + + return (i); +} + +/* + * Used by SetEnv(). + * Return the number of bytes of environment variable pointed by lpRest + */ +int GetRestEnvLen (char *lpRest) +{ + int nTotal = 1; + nTotal += strlen (lpRest); + + return(nTotal); +} |