Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1045 lines
35 KiB

/*++
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 <strsafe.h>
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);
}