/*++ Copyright(c) Microsoft Corporation Module Name: Freedisk.cpp Abstract: This file is intended to return whehter there is specified free disk space is available or not. Author: Modification: Wipro Technologies, 22/6/2001. Revision History: --*/ #include "pch.h" #include "freedisk.h" #include DWORD _cdecl wmain( IN DWORD argc, IN LPCWSTR argv[] ) /*++ Routine description : Main function which calls all the other functions depending on the options specified through command line. Arguments: [in] argc : argument count specified in the command line. [in] argv : arguments specified in the command line. Return Value : DWORD EXIT_SUCCESS : If there is enough free disk space. EXIT_FAILURE : If there is not enough free disk space. --*/ { DWORD dwStatus = 0; LPWSTR szServer = NULL; LPWSTR szUser = NULL; WCHAR szPasswd[MAX_RES_STRING] = NULL_STRING; LPWSTR szDrive = NULL; WCHAR szValue[MAX_RES_STRING] = NULL_STRING; long double AllowedDisk = 0; ULONGLONG lfTotalNumberofFreeBytes = 0; LPWSTR szTempDrive = NULL; LPWSTR szTemp1Drive = NULL; LPWSTR szFullPath = NULL; LPWSTR szFilePart = NULL; BOOL bUsage = FALSE; BOOL bStatus = FALSE; BOOL bFlagRmtConnectin = FALSE; BOOL bNeedPasswd = FALSE; DWORD dwCurdrv = 0; DWORD dwAttr = 0; BOOL bLocalSystem = FALSE; DWORD dwSize = 0; //Process the options and get the drive name and amount of free space required dwStatus = ProcessOptions( argc, argv, &szServer, &szUser, szPasswd, &szDrive, szValue, &bUsage, &bNeedPasswd ); if( EXIT_FAILURE == dwStatus ) { ShowLastErrorEx( stderr, SLE_ERROR | SLE_INTERNAL ); ReleaseGlobals(); return(EXIT_FAILURE); } //if usage is specified display usage if( TRUE == bUsage ) { DisplayHelpUsage(); FreeMemory( (LPVOID *) &szServer ); FreeMemory( (LPVOID *) &szUser ); FreeMemory( (LPVOID *) &szDrive ); ReleaseGlobals(); return EXIT_SUCCESS; } // now process the value of free space if( EXIT_FAILURE == ProcessValue( szValue, &AllowedDisk )) { ShowLastErrorEx( stderr, SLE_ERROR | SLE_INTERNAL ); FreeMemory( (LPVOID *) &szServer ); FreeMemory( (LPVOID *) &szUser ); FreeMemory( (LPVOID *) &szDrive ); ReleaseGlobals(); return(EXIT_FAILURE); } //Check whether local credentials supplied //before establishing connection bLocalSystem = IsLocalSystem(IsUNCFormat(szServer)?szServer+2:szServer); //establish the connection to remote sytem if( StringLengthW(szServer, 0) != 0 && !bLocalSystem ) { bStatus = EstablishConnection( szServer, szUser, (StringLength(szUser,0) !=0)?SIZE_OF_ARRAY_IN_CHARS(szUser):MAX_STRING_LENGTH, szPasswd, MAX_STRING_LENGTH, bNeedPasswd ); SecureZeroMemory( szPasswd, SIZE_OF_ARRAY(szPasswd) ); //if establish connection fails get the reason and display error if( FALSE == bStatus ) { ShowLastErrorEx( stderr, SLE_ERROR | SLE_INTERNAL); FreeMemory( (LPVOID *) &szUser ); FreeMemory( (LPVOID *) &szServer ); ReleaseGlobals(); return( EXIT_FAILURE ); } //set whether to close the connection if it is opened by this program only switch( GetLastError() ) { case I_NO_CLOSE_CONNECTION : bFlagRmtConnectin = TRUE; break; case ERROR_SESSION_CREDENTIAL_CONFLICT: case E_LOCAL_CREDENTIALS: ShowLastErrorEx( stderr, SLE_TYPE_WARNING | SLE_INTERNAL ); bFlagRmtConnectin = TRUE; } } //if no drive specified, consider it as current drive/volume if( StringLengthW(szDrive, 0) == 0 ) { dwSize = GetCurrentDirectory( 0, szTemp1Drive ); if( 0 == dwSize ) { ShowLastErrorEx( stderr, SLE_TYPE_ERROR | SLE_SYSTEM ); SAFE_CLOSE_CONNECTION(szServer, bFlagRmtConnectin ); FreeMemory((LPVOID *) &szServer ); FreeMemory((LPVOID *) &szUser ); FreeMemory( (LPVOID *) &szDrive ); ReleaseGlobals(); return (EXIT_FAILURE); } szTemp1Drive = (LPWSTR) AllocateMemory((dwSize+10)*sizeof(WCHAR)); if( NULL == szTemp1Drive ) { ShowLastErrorEx( stderr, SLE_TYPE_ERROR | SLE_INTERNAL ); SAFE_CLOSE_CONNECTION(szServer, bFlagRmtConnectin ); FreeMemory((LPVOID *) &szServer ); FreeMemory((LPVOID *) &szUser ); ReleaseGlobals(); return (EXIT_FAILURE); } SecureZeroMemory( (LPVOID)szTemp1Drive, GetBufferSize(szTemp1Drive) ); if( FALSE == GetCurrentDirectory( dwSize+10, szTemp1Drive ) ) { ShowLastErrorEx( stderr, SLE_ERROR | SLE_SYSTEM ); } dwAttr = GetFileAttributes( szTemp1Drive ); //if the file is not root_dir check again if( -1!=dwAttr && !(dwAttr & FILE_ATTRIBUTE_REPARSE_POINT) ) // attributes for reparse point { dwCurdrv = _getdrive(); StringCchPrintf( szTemp1Drive, dwSize, L"%c:", L'A'+dwCurdrv-1 ); } //copy null if no drive specified to full path, it is only for display purpose szFullPath = (WCHAR *) AllocateMemory( MAX_STRING_LENGTH*sizeof(WCHAR) ); if( NULL == szFullPath ) { ShowLastErrorEx( stderr, SLE_TYPE_ERROR | SLE_INTERNAL ); return( EXIT_FAILURE ); } StringCopy( szFullPath, NULL_STRING, SIZE_OF_ARRAY_IN_CHARS(szFullPath) ); } else { //get the fullpath of Drive, this is for display purpose only dwSize=GetFullPathName(szDrive, 0, szFullPath, &szFilePart ); if( dwSize != 0 ) { szFullPath = (WCHAR *) AllocateMemory( (dwSize+10)*sizeof(WCHAR) ); if( NULL == szFullPath ) { ShowLastErrorEx( stderr, SLE_TYPE_ERROR | SLE_INTERNAL ); return( EXIT_FAILURE ); } dwSize=GetFullPathName(szDrive, (DWORD) dwSize+5, szFullPath, &szFilePart ); } szTemp1Drive = (LPWSTR) AllocateMemory((StringLengthW(szDrive, 0)+10)*sizeof(WCHAR)); if( NULL == szTemp1Drive ) { ShowLastErrorEx( stderr, SLE_TYPE_ERROR | SLE_INTERNAL ); SAFE_CLOSE_CONNECTION(szServer, bFlagRmtConnectin ); FreeMemory((LPVOID *) &szServer ); FreeMemory((LPVOID *) &szUser ); FreeMemory( (LPVOID *) &szDrive ); ReleaseGlobals(); return (EXIT_FAILURE); } StringCopy( szTemp1Drive, szDrive, SIZE_OF_ARRAY_IN_CHARS(szTemp1Drive)); } szTempDrive = (LPWSTR) AllocateMemory((StringLengthW(szTemp1Drive, 0)+StringLengthW(szServer, 0)+20)*sizeof(WCHAR)); if( NULL == szTempDrive ) { ShowLastErrorEx( stderr, SLE_TYPE_ERROR | SLE_INTERNAL ); SAFE_CLOSE_CONNECTION(szServer, bFlagRmtConnectin ); FreeMemory((LPVOID *) &szServer ); FreeMemory((LPVOID *) &szUser ); FreeMemory( (LPVOID *) &szDrive ); FreeMemory((LPVOID *) &szTemp1Drive ); FreeMemory((LPVOID *) &szFullPath ); ReleaseGlobals(); return (EXIT_FAILURE); } StringCopy( szTempDrive, szTemp1Drive, SIZE_OF_ARRAY_IN_CHARS(szTempDrive) ); //if the remote system is specified build the path name if( bStatus ) { if( szTemp1Drive[1]== L':' ) szTemp1Drive[1]=L'$'; if( IsUNCFormat( szServer ) == FALSE ) { StringCchPrintf( szTempDrive, SIZE_OF_ARRAY_IN_CHARS(szTempDrive), L"\\\\%s\\%s\\", szServer, szTemp1Drive ); } else { StringCchPrintf( szTempDrive, SIZE_OF_ARRAY_IN_CHARS(szTempDrive), L"\\\\%s\\%s\\", szServer+2, szTemp1Drive ); } } //free the memory, no need FreeMemory( (LPVOID *) &szTemp1Drive ); // FreeMemory( (LPVOID *) &szDrive ); //check the given drive is valid drive or not if(EXIT_FAILURE == ValidateDriveType( szTempDrive ) ) { ShowLastErrorEx( stderr, SLE_ERROR | SLE_INTERNAL ); SAFE_CLOSE_CONNECTION(szServer, bFlagRmtConnectin ); FreeMemory( (LPVOID *) &szServer ); FreeMemory( (LPVOID *) &szUser ); FreeMemory( (LPVOID *) &szTempDrive ); FreeMemory( (LPVOID *) &szDrive ); ReleaseGlobals(); return EXIT_FAILURE; } //get the drive space lfTotalNumberofFreeBytes = GetDriveFreeSpace( szTempDrive ); if( (ULONGLONG)(-1) == lfTotalNumberofFreeBytes ) { ShowLastErrorEx( stderr, SLE_ERROR | SLE_INTERNAL ); SAFE_CLOSE_CONNECTION(szServer, bFlagRmtConnectin ); FreeMemory( (LPVOID *) &szServer ); FreeMemory( (LPVOID *) &szUser ); FreeMemory( (LPVOID *) &szTempDrive ); FreeMemory( (LPVOID *) &szDrive ); ReleaseGlobals(); return(EXIT_FAILURE); } //output the warning if it matches with the local creadentials if( StringLengthW(szUser, 0) != 0 && bLocalSystem) { ShowMessage( stderr, NEWLINE ); ShowMessage( stderr, GetResString( IDS_LOCAL_CREDENTIALS ) ); } if( IsLocalSystem( szServer ) ) { dwStatus = DisplayOutput( AllowedDisk, lfTotalNumberofFreeBytes, szFullPath ); } else { dwStatus = DisplayOutput( AllowedDisk, lfTotalNumberofFreeBytes, szDrive ); } SAFE_CLOSE_CONNECTION(szServer, bFlagRmtConnectin ); FreeMemory( (LPVOID *) &szServer ); FreeMemory( (LPVOID *) &szUser ); FreeMemory( (LPVOID *) &szTempDrive ); FreeMemory( (LPVOID *) &szDrive ); ReleaseGlobals(); return(dwStatus ); } DWORD ProcessOptions( IN DWORD argc, OUT LPCWSTR argv[], OUT LPWSTR *lpszServer, OUT LPWSTR *lpszUser, OUT LPWSTR lpszPasswd, OUT LPWSTR *szDrive, OUT LPWSTR szValue, OUT PBOOL pbUsage, OUT PBOOL pbNeedPasswd ) /*++ Routine Description : Function used to process the main options Arguments: [ in ] argc : Number of command line arguments [ in ] argv : Array containing command line arguments [ out ] lpszServer : Pointer to string which returns remote system name if remote system is specified in the command line. [ out ] lpszUser : Pointer to string which returns User name if the user name is specified in the command line. [ out ] lpszPasswd : Pointer to string which returns Password if the password is specified in the command line. [ out ] szDrive : Pointer to string which returns Drive name specified in the command line. [ out ] szValue : Pointer to string which returns the default value specified in the command line. [ out ] pbUsage : Pointer to boolean variable returns true if usage option specified in the command line. Return Type : DWORD A Integer value indicating EXIT_SUCCESS on successful parsing of command line else EXIT_FAILURE --*/ { TCMDPARSER2 cmdOptions[MAX_OPTIONS]; PTCMDPARSER2 pcmdOption; LPWSTR szTemp = NULL; BOOL bOthers = FALSE; StringCopy( lpszPasswd, L"*", MAX_STRING_LENGTH ); // help option pcmdOption = &cmdOptions[OI_USAGE] ; pcmdOption->dwType = CP_TYPE_BOOLEAN; pcmdOption->dwCount = 1 ; pcmdOption->dwActuals = 0; pcmdOption->dwFlags = CP_USAGE ; pcmdOption->pValue = pbUsage ; pcmdOption->pFunction = NULL ; pcmdOption->pFunctionData = NULL ; pcmdOption->dwLength = 0; pcmdOption->pwszFriendlyName=NULL; pcmdOption->dwReserved = 0; pcmdOption->pReserved1 = NULL; pcmdOption->pReserved2 = NULL; pcmdOption->pReserved3 = NULL; pcmdOption->pwszValues=NULL; pcmdOption->pwszOptions=CMDOPTION_USAGE; StringCopyA(cmdOptions[OI_USAGE].szSignature, "PARSER2", 8 ); //server name option pcmdOption = &cmdOptions[OI_SERVER] ; pcmdOption->dwType = CP_TYPE_TEXT; pcmdOption->dwCount = 1 ; pcmdOption->dwActuals = 0; pcmdOption->dwFlags = CP2_ALLOCMEMORY | CP_VALUE_MANDATORY | CP2_VALUE_TRIMINPUT | CP2_VALUE_NONULL; pcmdOption->pValue = NULL ; pcmdOption->pFunction = NULL ; pcmdOption->pFunctionData = NULL ; pcmdOption->dwLength = 0; pcmdOption->dwReserved = 0; pcmdOption->pReserved1 = NULL; pcmdOption->pReserved2 = NULL; pcmdOption->pReserved3 = NULL; pcmdOption->pwszValues=NULL; pcmdOption->pwszFriendlyName=NULL; pcmdOption->pwszOptions=CMDOPTION_SERVER; // _T("s") StringCopyA(cmdOptions[OI_SERVER].szSignature, "PARSER2", 8 ); //domain\user option pcmdOption = &cmdOptions[OI_USER] ; pcmdOption->dwCount = 1 ; pcmdOption->dwActuals = 0; pcmdOption->dwFlags = CP2_ALLOCMEMORY | CP_VALUE_MANDATORY | CP2_VALUE_TRIMINPUT | CP2_VALUE_NONULL ; pcmdOption->pValue = NULL; pcmdOption->pFunction = NULL ; pcmdOption->pFunctionData = NULL ; pcmdOption->dwType = CP_TYPE_TEXT; pcmdOption->dwLength = 0; pcmdOption->pwszFriendlyName=NULL; pcmdOption->dwReserved = 0; pcmdOption->pReserved1 = NULL; pcmdOption->pReserved2 = NULL; pcmdOption->pReserved3 = NULL; pcmdOption->pwszValues=NULL; pcmdOption->pwszOptions=CMDOPTION_USER; // _T("u") StringCopyA(cmdOptions[OI_USER].szSignature, "PARSER2", 8 ); //password option pcmdOption = &cmdOptions[OI_PASSWORD] ; pcmdOption->dwCount = 1 ; pcmdOption->dwActuals = 0; pcmdOption->dwFlags = CP2_VALUE_OPTIONAL; pcmdOption->pValue = lpszPasswd; pcmdOption->pFunction = NULL ; pcmdOption->pFunctionData = NULL ; pcmdOption->dwType = CP_TYPE_TEXT; pcmdOption->dwLength = MAX_RES_STRING; pcmdOption->dwReserved = 0; pcmdOption->pReserved1 = NULL; pcmdOption->pReserved2 = NULL; pcmdOption->pReserved3 = NULL; pcmdOption->pwszValues=NULL; pcmdOption->pwszFriendlyName=NULL; pcmdOption->pwszOptions=CMDOPTION_PASSWORD; // _T("p") StringCopyA(cmdOptions[OI_PASSWORD].szSignature, "PARSER2", 8 ); //drive option pcmdOption = &cmdOptions[OI_DRIVE] ; pcmdOption->dwCount = 1 ; pcmdOption->dwActuals = 0; pcmdOption->dwFlags = CP2_ALLOCMEMORY | CP_VALUE_MANDATORY | CP2_VALUE_TRIMINPUT | CP2_VALUE_NONULL ; pcmdOption->pValue = NULL; pcmdOption->pFunction = NULL ; pcmdOption->pFunctionData = NULL ; pcmdOption->dwType = CP_TYPE_TEXT; pcmdOption->dwLength = 0; pcmdOption->pwszFriendlyName=NULL; pcmdOption->dwReserved = 0; pcmdOption->pReserved1 = NULL; pcmdOption->pReserved2 = NULL; pcmdOption->pReserved3 = NULL; pcmdOption->pwszValues=NULL; pcmdOption->pwszOptions=CMDOPTION_DRIVE; // _T("d") StringCopyA(cmdOptions[OI_DRIVE].szSignature, "PARSER2", 8 ); //default option pcmdOption = &cmdOptions[OI_DEFAULT] ; pcmdOption->dwCount = 1 ; pcmdOption->dwActuals = 0; pcmdOption->dwFlags = CP2_DEFAULT; pcmdOption->pValue = szValue; pcmdOption->pFunction = NULL ; pcmdOption->pFunctionData = NULL ; pcmdOption->dwType = CP_TYPE_TEXT; pcmdOption->dwLength = MAX_RES_STRING; pcmdOption->dwReserved = 0; pcmdOption->pReserved1 = NULL; pcmdOption->pReserved2 = NULL; pcmdOption->pReserved3 = NULL; pcmdOption->pwszValues=NULL; pcmdOption->pwszFriendlyName=NULL; pcmdOption->pwszOptions=CMDOPTION_DEFAULT; // _T("") StringCopyA(cmdOptions[OI_DEFAULT].szSignature, "PARSER2", 8 ); //process the command line options and display error if it fails if( DoParseParam2( argc, argv, -1, SIZE_OF_ARRAY(cmdOptions ), cmdOptions, 0 ) == FALSE ) { return( EXIT_FAILURE ); } //if usage specified with any other value display error and return with failure if( (( TRUE == *pbUsage ) && ( argc > 2 ) ) || TRUE == bOthers ) { SetReason( GetResString(IDS_INVALID_SYNTAX) ); return( EXIT_FAILURE ); } *lpszServer = (LPWSTR)cmdOptions[OI_SERVER].pValue; *lpszUser = (LPWSTR)cmdOptions[OI_USER].pValue; *szDrive = (LPWSTR)cmdOptions[OI_DRIVE].pValue; if( TRUE == *pbUsage ) { return( EXIT_SUCCESS); } TrimString( *lpszServer, TRIM_ALL); TrimString( *lpszUser, TRIM_ALL); TrimString( *szDrive, TRIM_ALL); //validate the value for null string or spaces if( StringLengthW( szValue, 0 ) != 0 ) { StrTrim( szValue, L" "); if( StringLengthW(szValue, 0) == 0 ) { SetReason(GetResString(IDS_INVALID_BYTES)); return( EXIT_FAILURE ); } } if( cmdOptions[OI_DRIVE].dwActuals != 0 && StringLengthW(*szDrive, 0) == 0 ) { SetReason(GetResString(IDS_ERROR_NULL_DRIVE) ); return EXIT_FAILURE; } /* //if drive is more than two letters and is having a trailing slash at end then failure //this is because the API for validating drive will pass for paths like a:\. if( *(szDrive+StringLengthW( *szDrive, 0 )-1) == L'\\' || (szTemp = FindString(szDrive, L"/", 0) )!= NULL) { DISPLAY_MESSAGE(stderr, GetResString(IDS_INVALID_DRIVE)); return( EXIT_FAILURE ); } */ //if drive is having a trailing slash at end then failure //this is because the API for validating drive will pass for paths like a:/. if( (szTemp = (LPWSTR)FindString(*szDrive, L"/", 0) )!= NULL) { SetReason(GetResString(IDS_INVALID_DRIVE)); return( EXIT_FAILURE ); } //check if user has specified without specifying remote system if( cmdOptions[OI_SERVER].dwActuals == 0 && StringLengthW(*lpszUser, 0) != 0 ) { SetReason(GetResString(IDS_USER_WITHOUT_SERVER) ); return( EXIT_FAILURE ); } //check if password has specified without specifying user name if( cmdOptions[OI_USER].dwActuals == 0 && cmdOptions[OI_PASSWORD].dwActuals != 0 ) { SetReason(GetResString(IDS_PASSWD_WITHOUT_USER) ); return( EXIT_FAILURE ); } //check if null server is specified if( cmdOptions[OI_SERVER].dwActuals!=0 && StringLengthW(IsUNCFormat(*lpszServer)?*lpszServer+2:*lpszServer, 0) == 0 ) { SetReason(GetResString(IDS_ERROR_NULL_SERVER) ); return( EXIT_FAILURE ); } //check if remote machine specified but drive name is not specified if( cmdOptions[OI_SERVER].dwActuals !=0 && (0 == cmdOptions[OI_DRIVE].dwActuals || StringLength(*szDrive,0) == 0) ) { SetReason(GetResString(IDS_REMOTE_DRIVE_NOT_SPECIFIED) ); return( EXIT_FAILURE ); } //check if /d with null value specified if( 0 != cmdOptions[OI_DRIVE].dwActuals && StringLengthW(*szDrive, 0) == 0) { SetReason(GetResString(IDS_INVALID_DRIVE)); return( EXIT_FAILURE ); } if(IsLocalSystem( *lpszServer ) == FALSE ) { // set the bNeedPassword to True or False . if ( cmdOptions[ OI_PASSWORD ].dwActuals != 0 && lpszPasswd != NULL && StringCompare( lpszPasswd, _T( "*" ), TRUE, 0 ) == 0 ) { // user wants the utility to prompt for the password before trying to connect *pbNeedPasswd = TRUE; } else if ( cmdOptions[ OI_PASSWORD ].dwActuals == 0 && ( cmdOptions[ OI_SERVER ].dwActuals != 0 || cmdOptions[ OI_USER ].dwActuals != 0 ) ) { // -s, -u is specified without password ... // utility needs to try to connect first and if it fails then prompt for the password *pbNeedPasswd = TRUE; if ( lpszPasswd != NULL ) { StringCopy( lpszPasswd, _T( "" ), MAX_STRING_LENGTH ); } } //allocate memory if /u is not specified if( NULL == *lpszUser ) { *lpszUser = (LPWSTR) AllocateMemory( MAX_STRING_LENGTH*sizeof(WCHAR) ); if( NULL == *lpszUser ) { ShowLastErrorEx( stderr, SLE_TYPE_ERROR | SLE_INTERNAL ); return (EXIT_FAILURE); } } } return( EXIT_SUCCESS ); } DWORD DisplayOutput( IN long double AllowedDisk, IN ULONGLONG lfTotalNumberofFreeBytes, IN LPWSTR szDrive ) /*++ Routine Description : This displays the output whether specified amount disk space is available in drive or not. Arguments: [ in ] lAllowedDisk: A pointer to string specifying the drive path. [ in ] szDrive : Drive name to be displayed. Return Type : void --*/ { WCHAR szOutputStr[MAX_STRING_LENGTH] = NULL_STRING; WCHAR szTempBuf[MAX_STRING_LENGTH] = NULL_STRING; //display new line ShowMessage( stdout, NEWLINE ); //check if it is only to know the amount of free space on the disk //then display the free space if( (long double)-1 == AllowedDisk ) { //format the number into string StringCchPrintf( szTempBuf, SIZE_OF_ARRAY(szTempBuf)-1, L"%I64d", lfTotalNumberofFreeBytes ); //convert into locale ConvertintoLocale( szTempBuf, szOutputStr ); //if drive name is not specified display for current drive if( StringLengthW(szDrive, 0) == 0 ) { ShowMessageEx( stdout, 1, TRUE, GetResString( IDS_AVAILABLE_DISK_SPACE1),_X(szOutputStr) ); } else { ShowMessageEx( stdout, 2, TRUE, GetResString( IDS_AVAILABLE_DISK_SPACE ), _X(szOutputStr), _X2( CharUpper( szDrive ) ) ); } } else //check the specified space is available or not { if (lfTotalNumberofFreeBytes < AllowedDisk) { //if drive letter is specified display as it is otherwise display it as currrent drive if( StringLengthW(szDrive,0) != 0 ) { ShowMessageEx( stdout, 1, TRUE, GetResString(IDS_TOO_SMALL), _X(CharUpper(szDrive)) ); } else { ShowMessage(stdout, GetResString(IDS_TOO_SMALL1)); } return( EXIT_FAILURE ); } else { //format the number into string StringCchPrintf( szTempBuf, SIZE_OF_ARRAY(szTempBuf)-1, L"%lf", AllowedDisk ); //convert into locale ConvertintoLocale( szTempBuf, szOutputStr ); //if drive name is not specified display it as current drive if( StringLength(szDrive, 0) == 0 ) { ShowMessageEx(stdout, 1, TRUE, GetResString(IDS_OK1), _X(szOutputStr) ); } else { ShowMessageEx(stdout, 2, TRUE, GetResString(IDS_OK), _X(szOutputStr), _X2(CharUpper(szDrive)) ); } } } return( EXIT_SUCCESS ); } ULONGLONG GetDriveFreeSpace( IN LPCWSTR lpszRootPathName ) /*++ Routine Description : Function used to Check the specified free space available in the specified disk. Arguments: [ in ] lpszRootPathName : A pointer to string specifying the drive path. Return Type : ULONGLONG A longlong value returns the no.of free bytes available on disk, if success. otherwise returns -1 value --*/ { DWORD dwRetCode = 0; ULONGLONG lpFreeBytesAvailable = 0; ULONGLONG lpTotalNumberofBytes = 0; ULONGLONG lpTotalNumberofFreeBytes = (ULONGLONG)-1; //this error mode is not to display the message box //if drive is not currently available SetErrorMode( SEM_FAILCRITICALERRORS); //get the total free disk space using the API dwRetCode=GetDiskFreeSpaceEx(lpszRootPathName, (PULARGE_INTEGER) &lpFreeBytesAvailable, (PULARGE_INTEGER) &lpTotalNumberofBytes, (PULARGE_INTEGER) &lpTotalNumberofFreeBytes ); //if it fails display the reason and exit with error if( 0 == dwRetCode ) { switch( GetLastError() ) { case ERROR_PATH_NOT_FOUND : case ERROR_BAD_NETPATH : case ERROR_INVALID_NAME : SetReason(GetResString(IDS_INVALID_DRIVE) ); break; case ERROR_INVALID_PARAMETER : SetReason( GetResString(IDS_CANT_FIND_DISK)); break; default : SaveLastError(); break; } } //reset back the critical error SetErrorMode(0); return( lpTotalNumberofFreeBytes ); } DWORD ValidateDriveType( LPWSTR szRootPathName ) /*++ Routine Description : Function used to Check the specified drive is valid or not Arguments: [ in ] lpszRootPathName : A pointer to string specifying the drive path. Return Type : ULONGLONG returns EXIT_SUCCESS if the drive type is valid, returns EXIT_FAILURE otherwise --*/ { DWORD dwCode = 0; DWORD dwAttr = 0xffffffff; dwCode = GetDriveType( szRootPathName ); switch( dwCode ) { case DRIVE_UNKNOWN : // case DRIVE_NO_ROOT_DIR : //if the file is not not check again for reparse point dwAttr = GetFileAttributes( szRootPathName ); if( (DWORD)-1!=dwAttr && (dwAttr & FILE_ATTRIBUTE_REPARSE_POINT) ) { // attributes for reparse point return EXIT_SUCCESS; } else { switch( GetLastError() ) { case ERROR_ACCESS_DENIED : SaveLastError(); return EXIT_FAILURE; case ERROR_INVALID_PARAMETER : SetReason( GetResString(IDS_CANT_FIND_DISK)); default : SetReason(GetResString(IDS_INVALID_DRIVE) ); return EXIT_FAILURE; } } } return( EXIT_SUCCESS ); } DWORD ProcessValue( IN LPWSTR szValue, OUT long double *dfValue ) /*++ Routine Description : This function process the szValue and returns its decimal number. Arguments: [ in ] szValue : A pointer to string specifying the drive path. [ out ] dfValue : A pointer to long double which returns the numeric value of the value specified in szValue. Return Type : DWORD A Integer value indicating EXIT_SUCCESS on success, EXIT_FAILURE on failure --*/ { LPWSTR pszStoppedString = NULL; double dfFactor = 1.0; LPWSTR szTemp = NULL; WCHAR szDecimalSep[MAX_RES_STRING] = NULL_STRING; //if free space value is not specified consider it as -1 if( StringLength(szValue,0) == 0 ) { *dfValue = -1; } else { //check for language regional settings if( 0 == GetLocaleInfo( LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, szDecimalSep, MAX_RES_STRING ) ) { SaveLastError(); return EXIT_FAILURE; } //check if decimal point(.) is also specified along with the decimal seperator if( StringCompare(szDecimalSep, L".", TRUE, 0) != 0 && (szTemp = (LPWSTR)FindString( szValue, L".", 0)) != NULL) { SetReason(GetResString(IDS_INVALID_BYTES) ); return(EXIT_FAILURE); } if( (szTemp = (LPWSTR)FindString( szValue, szDecimalSep, 0 )) != NULL ) szTemp[0] = L'.'; //read the numeric value *dfValue = wcstod( szValue, &pszStoppedString ); //check for negative value specified if( *dfValue < 0 ) { SetReason(GetResString(IDS_INVALID_BYTES) ); return(EXIT_FAILURE); } //now check for whether Units are specified or not //if specified take the multiplying facter as to that value StrTrim(pszStoppedString, L" "); if( StringLengthW(pszStoppedString, 0) ) { if( StringCompare( pszStoppedString, KB, TRUE, 0) == 0 ) { dfFactor = 1024; } else if( StringCompare( pszStoppedString, MB, TRUE, 0) == 0 ) { dfFactor = 1024*1024; } else if( StringCompare( pszStoppedString, GB, TRUE, 0) == 0 ) { dfFactor = 1024*1024*1024; } else if( StringCompare( pszStoppedString, TB, TRUE, 0) == 0 ) { dfFactor = (long double)1024*1024*1024*1024; } else if( StringCompare( pszStoppedString, PB, TRUE, 0) == 0 ) { dfFactor = (long double)1024*1024*1024*1024*1024; } else if( StringCompare( pszStoppedString, EB, TRUE, 0) == 0 ) { dfFactor = (long double)1024*1024*1024*1024*1024*1024; } else if( StringCompare( pszStoppedString, ZB, TRUE, 0) == 0 ) { dfFactor = (long double)1024*1024*1024*1024*1024*1024*1024; } else if( StringCompare( pszStoppedString, YB, TRUE, 0) == 0 ) { dfFactor = (long double)1024*1024*1024*1024*1024*1024*1024*1024; } else { SetReason(GetResString( IDS_INVALID_BYTES ) ); return( EXIT_FAILURE ); } //check if only units are specified without any value like KB, MB etc. if( StringCompare( pszStoppedString, szValue, TRUE, 0 ) == 0 ) { *dfValue = 1; } } *dfValue *= dfFactor; //check if no units are specified but fractional value is specified if( (1.0 == dfFactor) && (szTemp=(LPWSTR)FindString( szValue, L".", 0))!=NULL ) { SetReason(GetResString( IDS_INVALID_BYTES ) ); return( EXIT_FAILURE ); } } return( EXIT_SUCCESS ); } DWORD ConvertintoLocale( IN LPWSTR szNumberStr, OUT LPWSTR szOutputStr ) /*++ Routine Description : This function converts string into locale format Arguments: [ in ] szNumberStr : A pointer to string specifying input string to convert. [ out ] szOutputStr : A pointer to a string specifying output string in locale format. Return Type : DWORD A Integer value indicating EXIT_SUCCESS on success, EXIT_FAILURE on failure --*/ { NUMBERFMT numberfmt; WCHAR szGrouping[MAX_RES_STRING] = NULL_STRING; WCHAR szDecimalSep[MAX_RES_STRING] = NULL_STRING; WCHAR szThousandSep[MAX_RES_STRING] = NULL_STRING; WCHAR szTemp[MAX_RES_STRING] = NULL_STRING; LPWSTR szTemp1 = NULL; LPWSTR pszStoppedString = NULL; DWORD dwStatus = 0; DWORD dwGrouping = 3; //make the fractional digits and leading zeros to nothing numberfmt.NumDigits = 0; numberfmt.LeadingZero = 0; //get the decimal seperate character if( FALSE == GetLocaleInfo( LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, szDecimalSep, MAX_RES_STRING ) ) { StringCopy(szDecimalSep, L",", SIZE_OF_ARRAY(szDecimalSep)); } numberfmt.lpDecimalSep = szDecimalSep; //get the thousand seperator if(FALSE == GetLocaleInfo( LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, szThousandSep, MAX_RES_STRING ) ) { StringCopy(szThousandSep, L",", SIZE_OF_ARRAY(szThousandSep) ); } numberfmt.lpThousandSep = szThousandSep; if( GetLocaleInfo( LOCALE_USER_DEFAULT, LOCALE_SGROUPING, szGrouping, MAX_RES_STRING ) ) { szTemp1 = wcstok( szGrouping, L";"); do { STRING_CONCAT_STATIC( szTemp, szTemp1); szTemp1 = wcstok( NULL, L";" ); }while( szTemp1 != NULL && StringCompare( szTemp1, L"0", TRUE, 0) != 0); dwGrouping = wcstol( szTemp, &pszStoppedString, 10); } else dwGrouping = 33; //set the default grouping numberfmt.Grouping = (UINT)dwGrouping ; numberfmt.NegativeOrder = 2; dwStatus = GetNumberFormat( LOCALE_USER_DEFAULT, 0, szNumberStr, &numberfmt, szOutputStr, MAX_RES_STRING); return(EXIT_SUCCESS); } DWORD DisplayHelpUsage() /*++ Routine Description : Function used to to display the help usage. Arguments: Return Type : DWORD A Integer value indicating EXIT_SUCCESS on success else EXIT_FAILURE on failure --*/ { for( DWORD dw=IDS_MAIN_HELP_BEGIN; dw<=IDS_MAIN_HELP_END; dw++) { ShowMessage(stdout,GetResString(dw) ); } return(EXIT_SUCCESS); }