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.

1044 lines
35 KiB

  1. /*++
  2. Copyright(c) Microsoft Corporation
  3. Module Name:
  4. Freedisk.cpp
  5. Abstract:
  6. This file is intended to return whehter there is specified free disk
  7. space is available or not.
  8. Author:
  9. Modification:
  10. Wipro Technologies, 22/6/2001.
  11. Revision History:
  12. --*/
  13. #include "pch.h"
  14. #include "freedisk.h"
  15. #include <strsafe.h>
  16. DWORD _cdecl wmain(
  17. IN DWORD argc,
  18. IN LPCWSTR argv[]
  19. )
  20. /*++
  21. Routine description : Main function which calls all the other
  22. functions depending on the options specified
  23. through command line.
  24. Arguments:
  25. [in] argc : argument count specified in the command line.
  26. [in] argv : arguments specified in the command line.
  27. Return Value : DWORD
  28. EXIT_SUCCESS : If there is enough free disk space.
  29. EXIT_FAILURE : If there is not enough free disk space.
  30. --*/
  31. {
  32. DWORD dwStatus = 0;
  33. LPWSTR szServer = NULL;
  34. LPWSTR szUser = NULL;
  35. WCHAR szPasswd[MAX_RES_STRING] = NULL_STRING;
  36. LPWSTR szDrive = NULL;
  37. WCHAR szValue[MAX_RES_STRING] = NULL_STRING;
  38. long double AllowedDisk = 0;
  39. ULONGLONG lfTotalNumberofFreeBytes = 0;
  40. LPWSTR szTempDrive = NULL;
  41. LPWSTR szTemp1Drive = NULL;
  42. LPWSTR szFullPath = NULL;
  43. LPWSTR szFilePart = NULL;
  44. BOOL bUsage = FALSE;
  45. BOOL bStatus = FALSE;
  46. BOOL bFlagRmtConnectin = FALSE;
  47. BOOL bNeedPasswd = FALSE;
  48. DWORD dwCurdrv = 0;
  49. DWORD dwAttr = 0;
  50. BOOL bLocalSystem = FALSE;
  51. DWORD dwSize = 0;
  52. //Process the options and get the drive name and amount of free space required
  53. dwStatus = ProcessOptions( argc, argv,
  54. &szServer,
  55. &szUser,
  56. szPasswd,
  57. &szDrive,
  58. szValue,
  59. &bUsage,
  60. &bNeedPasswd
  61. );
  62. if( EXIT_FAILURE == dwStatus )
  63. {
  64. ShowLastErrorEx( stderr, SLE_ERROR | SLE_INTERNAL );
  65. ReleaseGlobals();
  66. return(EXIT_FAILURE);
  67. }
  68. //if usage is specified display usage
  69. if( TRUE == bUsage )
  70. {
  71. DisplayHelpUsage();
  72. FreeMemory( (LPVOID *) &szServer );
  73. FreeMemory( (LPVOID *) &szUser );
  74. FreeMemory( (LPVOID *) &szDrive );
  75. ReleaseGlobals();
  76. return EXIT_SUCCESS;
  77. }
  78. // now process the value of free space
  79. if( EXIT_FAILURE == ProcessValue( szValue, &AllowedDisk ))
  80. {
  81. ShowLastErrorEx( stderr, SLE_ERROR | SLE_INTERNAL );
  82. FreeMemory( (LPVOID *) &szServer );
  83. FreeMemory( (LPVOID *) &szUser );
  84. FreeMemory( (LPVOID *) &szDrive );
  85. ReleaseGlobals();
  86. return(EXIT_FAILURE);
  87. }
  88. //Check whether local credentials supplied
  89. //before establishing connection
  90. bLocalSystem = IsLocalSystem(IsUNCFormat(szServer)?szServer+2:szServer);
  91. //establish the connection to remote sytem
  92. if( StringLengthW(szServer, 0) != 0 && !bLocalSystem )
  93. {
  94. bStatus = EstablishConnection( szServer,
  95. szUser,
  96. (StringLength(szUser,0) !=0)?SIZE_OF_ARRAY_IN_CHARS(szUser):MAX_STRING_LENGTH,
  97. szPasswd,
  98. MAX_STRING_LENGTH,
  99. bNeedPasswd );
  100. SecureZeroMemory( szPasswd, SIZE_OF_ARRAY(szPasswd) );
  101. //if establish connection fails get the reason and display error
  102. if( FALSE == bStatus )
  103. {
  104. ShowLastErrorEx( stderr, SLE_ERROR | SLE_INTERNAL);
  105. FreeMemory( (LPVOID *) &szUser );
  106. FreeMemory( (LPVOID *) &szServer );
  107. ReleaseGlobals();
  108. return( EXIT_FAILURE );
  109. }
  110. //set whether to close the connection if it is opened by this program only
  111. switch( GetLastError() )
  112. {
  113. case I_NO_CLOSE_CONNECTION :
  114. bFlagRmtConnectin = TRUE;
  115. break;
  116. case ERROR_SESSION_CREDENTIAL_CONFLICT:
  117. case E_LOCAL_CREDENTIALS:
  118. ShowLastErrorEx( stderr, SLE_TYPE_WARNING | SLE_INTERNAL );
  119. bFlagRmtConnectin = TRUE;
  120. }
  121. }
  122. //if no drive specified, consider it as current drive/volume
  123. if( StringLengthW(szDrive, 0) == 0 )
  124. {
  125. dwSize = GetCurrentDirectory( 0, szTemp1Drive );
  126. if( 0 == dwSize )
  127. {
  128. ShowLastErrorEx( stderr, SLE_TYPE_ERROR | SLE_SYSTEM );
  129. SAFE_CLOSE_CONNECTION(szServer, bFlagRmtConnectin );
  130. FreeMemory((LPVOID *) &szServer );
  131. FreeMemory((LPVOID *) &szUser );
  132. FreeMemory( (LPVOID *) &szDrive );
  133. ReleaseGlobals();
  134. return (EXIT_FAILURE);
  135. }
  136. szTemp1Drive = (LPWSTR) AllocateMemory((dwSize+10)*sizeof(WCHAR));
  137. if( NULL == szTemp1Drive )
  138. {
  139. ShowLastErrorEx( stderr, SLE_TYPE_ERROR | SLE_INTERNAL );
  140. SAFE_CLOSE_CONNECTION(szServer, bFlagRmtConnectin );
  141. FreeMemory((LPVOID *) &szServer );
  142. FreeMemory((LPVOID *) &szUser );
  143. ReleaseGlobals();
  144. return (EXIT_FAILURE);
  145. }
  146. SecureZeroMemory( (LPVOID)szTemp1Drive, GetBufferSize(szTemp1Drive) );
  147. if( FALSE == GetCurrentDirectory( dwSize+10, szTemp1Drive ) )
  148. {
  149. ShowLastErrorEx( stderr, SLE_ERROR | SLE_SYSTEM );
  150. }
  151. dwAttr = GetFileAttributes( szTemp1Drive ); //if the file is not root_dir check again
  152. if( -1!=dwAttr && !(dwAttr & FILE_ATTRIBUTE_REPARSE_POINT) ) // attributes for reparse point
  153. {
  154. dwCurdrv = _getdrive();
  155. StringCchPrintf( szTemp1Drive, dwSize, L"%c:", L'A'+dwCurdrv-1 );
  156. }
  157. //copy null if no drive specified to full path, it is only for display purpose
  158. szFullPath = (WCHAR *) AllocateMemory( MAX_STRING_LENGTH*sizeof(WCHAR) );
  159. if( NULL == szFullPath )
  160. {
  161. ShowLastErrorEx( stderr, SLE_TYPE_ERROR | SLE_INTERNAL );
  162. return( EXIT_FAILURE );
  163. }
  164. StringCopy( szFullPath, NULL_STRING, SIZE_OF_ARRAY_IN_CHARS(szFullPath) );
  165. }
  166. else
  167. {
  168. //get the fullpath of Drive, this is for display purpose only
  169. dwSize=GetFullPathName(szDrive, 0, szFullPath, &szFilePart );
  170. if( dwSize != 0 )
  171. {
  172. szFullPath = (WCHAR *) AllocateMemory( (dwSize+10)*sizeof(WCHAR) );
  173. if( NULL == szFullPath )
  174. {
  175. ShowLastErrorEx( stderr, SLE_TYPE_ERROR | SLE_INTERNAL );
  176. return( EXIT_FAILURE );
  177. }
  178. dwSize=GetFullPathName(szDrive, (DWORD) dwSize+5, szFullPath, &szFilePart );
  179. }
  180. szTemp1Drive = (LPWSTR) AllocateMemory((StringLengthW(szDrive, 0)+10)*sizeof(WCHAR));
  181. if( NULL == szTemp1Drive )
  182. {
  183. ShowLastErrorEx( stderr, SLE_TYPE_ERROR | SLE_INTERNAL );
  184. SAFE_CLOSE_CONNECTION(szServer, bFlagRmtConnectin );
  185. FreeMemory((LPVOID *) &szServer );
  186. FreeMemory((LPVOID *) &szUser );
  187. FreeMemory( (LPVOID *) &szDrive );
  188. ReleaseGlobals();
  189. return (EXIT_FAILURE);
  190. }
  191. StringCopy( szTemp1Drive, szDrive, SIZE_OF_ARRAY_IN_CHARS(szTemp1Drive));
  192. }
  193. szTempDrive = (LPWSTR) AllocateMemory((StringLengthW(szTemp1Drive, 0)+StringLengthW(szServer, 0)+20)*sizeof(WCHAR));
  194. if( NULL == szTempDrive )
  195. {
  196. ShowLastErrorEx( stderr, SLE_TYPE_ERROR | SLE_INTERNAL );
  197. SAFE_CLOSE_CONNECTION(szServer, bFlagRmtConnectin );
  198. FreeMemory((LPVOID *) &szServer );
  199. FreeMemory((LPVOID *) &szUser );
  200. FreeMemory( (LPVOID *) &szDrive );
  201. FreeMemory((LPVOID *) &szTemp1Drive );
  202. FreeMemory((LPVOID *) &szFullPath );
  203. ReleaseGlobals();
  204. return (EXIT_FAILURE);
  205. }
  206. StringCopy( szTempDrive, szTemp1Drive, SIZE_OF_ARRAY_IN_CHARS(szTempDrive) );
  207. //if the remote system is specified build the path name
  208. if( bStatus )
  209. {
  210. if( szTemp1Drive[1]== L':' )
  211. szTemp1Drive[1]=L'$';
  212. if( IsUNCFormat( szServer ) == FALSE )
  213. {
  214. StringCchPrintf( szTempDrive, SIZE_OF_ARRAY_IN_CHARS(szTempDrive), L"\\\\%s\\%s\\", szServer, szTemp1Drive );
  215. }
  216. else
  217. {
  218. StringCchPrintf( szTempDrive, SIZE_OF_ARRAY_IN_CHARS(szTempDrive), L"\\\\%s\\%s\\", szServer+2, szTemp1Drive );
  219. }
  220. }
  221. //free the memory, no need
  222. FreeMemory( (LPVOID *) &szTemp1Drive );
  223. // FreeMemory( (LPVOID *) &szDrive );
  224. //check the given drive is valid drive or not
  225. if(EXIT_FAILURE == ValidateDriveType( szTempDrive ) )
  226. {
  227. ShowLastErrorEx( stderr, SLE_ERROR | SLE_INTERNAL );
  228. SAFE_CLOSE_CONNECTION(szServer, bFlagRmtConnectin );
  229. FreeMemory( (LPVOID *) &szServer );
  230. FreeMemory( (LPVOID *) &szUser );
  231. FreeMemory( (LPVOID *) &szTempDrive );
  232. FreeMemory( (LPVOID *) &szDrive );
  233. ReleaseGlobals();
  234. return EXIT_FAILURE;
  235. }
  236. //get the drive space
  237. lfTotalNumberofFreeBytes = GetDriveFreeSpace( szTempDrive );
  238. if( (ULONGLONG)(-1) == lfTotalNumberofFreeBytes )
  239. {
  240. ShowLastErrorEx( stderr, SLE_ERROR | SLE_INTERNAL );
  241. SAFE_CLOSE_CONNECTION(szServer, bFlagRmtConnectin );
  242. FreeMemory( (LPVOID *) &szServer );
  243. FreeMemory( (LPVOID *) &szUser );
  244. FreeMemory( (LPVOID *) &szTempDrive );
  245. FreeMemory( (LPVOID *) &szDrive );
  246. ReleaseGlobals();
  247. return(EXIT_FAILURE);
  248. }
  249. //output the warning if it matches with the local creadentials
  250. if( StringLengthW(szUser, 0) != 0 && bLocalSystem)
  251. {
  252. ShowMessage( stderr, NEWLINE );
  253. ShowMessage( stderr, GetResString( IDS_LOCAL_CREDENTIALS ) );
  254. }
  255. if( IsLocalSystem( szServer ) )
  256. {
  257. dwStatus = DisplayOutput( AllowedDisk, lfTotalNumberofFreeBytes, szFullPath );
  258. }
  259. else
  260. {
  261. dwStatus = DisplayOutput( AllowedDisk, lfTotalNumberofFreeBytes, szDrive );
  262. }
  263. SAFE_CLOSE_CONNECTION(szServer, bFlagRmtConnectin );
  264. FreeMemory( (LPVOID *) &szServer );
  265. FreeMemory( (LPVOID *) &szUser );
  266. FreeMemory( (LPVOID *) &szTempDrive );
  267. FreeMemory( (LPVOID *) &szDrive );
  268. ReleaseGlobals();
  269. return(dwStatus );
  270. }
  271. DWORD ProcessOptions(
  272. IN DWORD argc,
  273. OUT LPCWSTR argv[],
  274. OUT LPWSTR *lpszServer,
  275. OUT LPWSTR *lpszUser,
  276. OUT LPWSTR lpszPasswd,
  277. OUT LPWSTR *szDrive,
  278. OUT LPWSTR szValue,
  279. OUT PBOOL pbUsage,
  280. OUT PBOOL pbNeedPasswd
  281. )
  282. /*++
  283. Routine Description : Function used to process the main options
  284. Arguments:
  285. [ in ] argc : Number of command line arguments
  286. [ in ] argv : Array containing command line arguments
  287. [ out ] lpszServer : Pointer to string which returns remote system
  288. name if remote system is specified in the command line.
  289. [ out ] lpszUser : Pointer to string which returns User name
  290. if the user name is specified in the command line.
  291. [ out ] lpszPasswd : Pointer to string which returns Password
  292. if the password is specified in the command line.
  293. [ out ] szDrive : Pointer to string which returns Drive name
  294. specified in the command line.
  295. [ out ] szValue : Pointer to string which returns the default value
  296. specified in the command line.
  297. [ out ] pbUsage : Pointer to boolean variable returns true if
  298. usage option specified in the command line.
  299. Return Type : DWORD
  300. A Integer value indicating EXIT_SUCCESS on successful parsing of
  301. command line else EXIT_FAILURE
  302. --*/
  303. {
  304. TCMDPARSER2 cmdOptions[MAX_OPTIONS];
  305. PTCMDPARSER2 pcmdOption;
  306. LPWSTR szTemp = NULL;
  307. BOOL bOthers = FALSE;
  308. StringCopy( lpszPasswd, L"*", MAX_STRING_LENGTH );
  309. // help option
  310. pcmdOption = &cmdOptions[OI_USAGE] ;
  311. pcmdOption->dwType = CP_TYPE_BOOLEAN;
  312. pcmdOption->dwCount = 1 ;
  313. pcmdOption->dwActuals = 0;
  314. pcmdOption->dwFlags = CP_USAGE ;
  315. pcmdOption->pValue = pbUsage ;
  316. pcmdOption->pFunction = NULL ;
  317. pcmdOption->pFunctionData = NULL ;
  318. pcmdOption->dwLength = 0;
  319. pcmdOption->pwszFriendlyName=NULL;
  320. pcmdOption->dwReserved = 0;
  321. pcmdOption->pReserved1 = NULL;
  322. pcmdOption->pReserved2 = NULL;
  323. pcmdOption->pReserved3 = NULL;
  324. pcmdOption->pwszValues=NULL;
  325. pcmdOption->pwszOptions=CMDOPTION_USAGE;
  326. StringCopyA(cmdOptions[OI_USAGE].szSignature, "PARSER2", 8 );
  327. //server name option
  328. pcmdOption = &cmdOptions[OI_SERVER] ;
  329. pcmdOption->dwType = CP_TYPE_TEXT;
  330. pcmdOption->dwCount = 1 ;
  331. pcmdOption->dwActuals = 0;
  332. pcmdOption->dwFlags = CP2_ALLOCMEMORY | CP_VALUE_MANDATORY | CP2_VALUE_TRIMINPUT | CP2_VALUE_NONULL;
  333. pcmdOption->pValue = NULL ;
  334. pcmdOption->pFunction = NULL ;
  335. pcmdOption->pFunctionData = NULL ;
  336. pcmdOption->dwLength = 0;
  337. pcmdOption->dwReserved = 0;
  338. pcmdOption->pReserved1 = NULL;
  339. pcmdOption->pReserved2 = NULL;
  340. pcmdOption->pReserved3 = NULL;
  341. pcmdOption->pwszValues=NULL;
  342. pcmdOption->pwszFriendlyName=NULL;
  343. pcmdOption->pwszOptions=CMDOPTION_SERVER; // _T("s")
  344. StringCopyA(cmdOptions[OI_SERVER].szSignature, "PARSER2", 8 );
  345. //domain\user option
  346. pcmdOption = &cmdOptions[OI_USER] ;
  347. pcmdOption->dwCount = 1 ;
  348. pcmdOption->dwActuals = 0;
  349. pcmdOption->dwFlags = CP2_ALLOCMEMORY | CP_VALUE_MANDATORY | CP2_VALUE_TRIMINPUT | CP2_VALUE_NONULL ;
  350. pcmdOption->pValue = NULL;
  351. pcmdOption->pFunction = NULL ;
  352. pcmdOption->pFunctionData = NULL ;
  353. pcmdOption->dwType = CP_TYPE_TEXT;
  354. pcmdOption->dwLength = 0;
  355. pcmdOption->pwszFriendlyName=NULL;
  356. pcmdOption->dwReserved = 0;
  357. pcmdOption->pReserved1 = NULL;
  358. pcmdOption->pReserved2 = NULL;
  359. pcmdOption->pReserved3 = NULL;
  360. pcmdOption->pwszValues=NULL;
  361. pcmdOption->pwszOptions=CMDOPTION_USER; // _T("u")
  362. StringCopyA(cmdOptions[OI_USER].szSignature, "PARSER2", 8 );
  363. //password option
  364. pcmdOption = &cmdOptions[OI_PASSWORD] ;
  365. pcmdOption->dwCount = 1 ;
  366. pcmdOption->dwActuals = 0;
  367. pcmdOption->dwFlags = CP2_VALUE_OPTIONAL;
  368. pcmdOption->pValue = lpszPasswd;
  369. pcmdOption->pFunction = NULL ;
  370. pcmdOption->pFunctionData = NULL ;
  371. pcmdOption->dwType = CP_TYPE_TEXT;
  372. pcmdOption->dwLength = MAX_RES_STRING;
  373. pcmdOption->dwReserved = 0;
  374. pcmdOption->pReserved1 = NULL;
  375. pcmdOption->pReserved2 = NULL;
  376. pcmdOption->pReserved3 = NULL;
  377. pcmdOption->pwszValues=NULL;
  378. pcmdOption->pwszFriendlyName=NULL;
  379. pcmdOption->pwszOptions=CMDOPTION_PASSWORD; // _T("p")
  380. StringCopyA(cmdOptions[OI_PASSWORD].szSignature, "PARSER2", 8 );
  381. //drive option
  382. pcmdOption = &cmdOptions[OI_DRIVE] ;
  383. pcmdOption->dwCount = 1 ;
  384. pcmdOption->dwActuals = 0;
  385. pcmdOption->dwFlags = CP2_ALLOCMEMORY | CP_VALUE_MANDATORY | CP2_VALUE_TRIMINPUT | CP2_VALUE_NONULL ;
  386. pcmdOption->pValue = NULL;
  387. pcmdOption->pFunction = NULL ;
  388. pcmdOption->pFunctionData = NULL ;
  389. pcmdOption->dwType = CP_TYPE_TEXT;
  390. pcmdOption->dwLength = 0;
  391. pcmdOption->pwszFriendlyName=NULL;
  392. pcmdOption->dwReserved = 0;
  393. pcmdOption->pReserved1 = NULL;
  394. pcmdOption->pReserved2 = NULL;
  395. pcmdOption->pReserved3 = NULL;
  396. pcmdOption->pwszValues=NULL;
  397. pcmdOption->pwszOptions=CMDOPTION_DRIVE; // _T("d")
  398. StringCopyA(cmdOptions[OI_DRIVE].szSignature, "PARSER2", 8 );
  399. //default option
  400. pcmdOption = &cmdOptions[OI_DEFAULT] ;
  401. pcmdOption->dwCount = 1 ;
  402. pcmdOption->dwActuals = 0;
  403. pcmdOption->dwFlags = CP2_DEFAULT;
  404. pcmdOption->pValue = szValue;
  405. pcmdOption->pFunction = NULL ;
  406. pcmdOption->pFunctionData = NULL ;
  407. pcmdOption->dwType = CP_TYPE_TEXT;
  408. pcmdOption->dwLength = MAX_RES_STRING;
  409. pcmdOption->dwReserved = 0;
  410. pcmdOption->pReserved1 = NULL;
  411. pcmdOption->pReserved2 = NULL;
  412. pcmdOption->pReserved3 = NULL;
  413. pcmdOption->pwszValues=NULL;
  414. pcmdOption->pwszFriendlyName=NULL;
  415. pcmdOption->pwszOptions=CMDOPTION_DEFAULT; // _T("")
  416. StringCopyA(cmdOptions[OI_DEFAULT].szSignature, "PARSER2", 8 );
  417. //process the command line options and display error if it fails
  418. if( DoParseParam2( argc, argv, -1, SIZE_OF_ARRAY(cmdOptions ), cmdOptions, 0 ) == FALSE )
  419. {
  420. return( EXIT_FAILURE );
  421. }
  422. //if usage specified with any other value display error and return with failure
  423. if( (( TRUE == *pbUsage ) && ( argc > 2 ) ) || TRUE == bOthers )
  424. {
  425. SetReason( GetResString(IDS_INVALID_SYNTAX) );
  426. return( EXIT_FAILURE );
  427. }
  428. *lpszServer = (LPWSTR)cmdOptions[OI_SERVER].pValue;
  429. *lpszUser = (LPWSTR)cmdOptions[OI_USER].pValue;
  430. *szDrive = (LPWSTR)cmdOptions[OI_DRIVE].pValue;
  431. if( TRUE == *pbUsage )
  432. {
  433. return( EXIT_SUCCESS);
  434. }
  435. TrimString( *lpszServer, TRIM_ALL);
  436. TrimString( *lpszUser, TRIM_ALL);
  437. TrimString( *szDrive, TRIM_ALL);
  438. //validate the value for null string or spaces
  439. if( StringLengthW( szValue, 0 ) != 0 )
  440. {
  441. StrTrim( szValue, L" ");
  442. if( StringLengthW(szValue, 0) == 0 )
  443. {
  444. SetReason(GetResString(IDS_INVALID_BYTES));
  445. return( EXIT_FAILURE );
  446. }
  447. }
  448. if( cmdOptions[OI_DRIVE].dwActuals != 0 && StringLengthW(*szDrive, 0) == 0 )
  449. {
  450. SetReason(GetResString(IDS_ERROR_NULL_DRIVE) );
  451. return EXIT_FAILURE;
  452. }
  453. /*
  454. //if drive is more than two letters and is having a trailing slash at end then failure
  455. //this is because the API for validating drive will pass for paths like a:\.
  456. if( *(szDrive+StringLengthW( *szDrive, 0 )-1) == L'\\' || (szTemp = FindString(szDrive, L"/", 0) )!= NULL)
  457. {
  458. DISPLAY_MESSAGE(stderr, GetResString(IDS_INVALID_DRIVE));
  459. return( EXIT_FAILURE );
  460. }
  461. */
  462. //if drive is having a trailing slash at end then failure
  463. //this is because the API for validating drive will pass for paths like a:/.
  464. if( (szTemp = (LPWSTR)FindString(*szDrive, L"/", 0) )!= NULL)
  465. {
  466. SetReason(GetResString(IDS_INVALID_DRIVE));
  467. return( EXIT_FAILURE );
  468. }
  469. //check if user has specified without specifying remote system
  470. if( cmdOptions[OI_SERVER].dwActuals == 0 && StringLengthW(*lpszUser, 0) != 0 )
  471. {
  472. SetReason(GetResString(IDS_USER_WITHOUT_SERVER) );
  473. return( EXIT_FAILURE );
  474. }
  475. //check if password has specified without specifying user name
  476. if( cmdOptions[OI_USER].dwActuals == 0 && cmdOptions[OI_PASSWORD].dwActuals != 0 )
  477. {
  478. SetReason(GetResString(IDS_PASSWD_WITHOUT_USER) );
  479. return( EXIT_FAILURE );
  480. }
  481. //check if null server is specified
  482. if( cmdOptions[OI_SERVER].dwActuals!=0 && StringLengthW(IsUNCFormat(*lpszServer)?*lpszServer+2:*lpszServer, 0) == 0 )
  483. {
  484. SetReason(GetResString(IDS_ERROR_NULL_SERVER) );
  485. return( EXIT_FAILURE );
  486. }
  487. //check if remote machine specified but drive name is not specified
  488. if( cmdOptions[OI_SERVER].dwActuals !=0 && (0 == cmdOptions[OI_DRIVE].dwActuals || StringLength(*szDrive,0) == 0) )
  489. {
  490. SetReason(GetResString(IDS_REMOTE_DRIVE_NOT_SPECIFIED) );
  491. return( EXIT_FAILURE );
  492. }
  493. //check if /d with null value specified
  494. if( 0 != cmdOptions[OI_DRIVE].dwActuals && StringLengthW(*szDrive, 0) == 0)
  495. {
  496. SetReason(GetResString(IDS_INVALID_DRIVE));
  497. return( EXIT_FAILURE );
  498. }
  499. if(IsLocalSystem( *lpszServer ) == FALSE )
  500. {
  501. // set the bNeedPassword to True or False .
  502. if ( cmdOptions[ OI_PASSWORD ].dwActuals != 0 &&
  503. lpszPasswd != NULL && StringCompare( lpszPasswd, _T( "*" ), TRUE, 0 ) == 0 )
  504. {
  505. // user wants the utility to prompt for the password before trying to connect
  506. *pbNeedPasswd = TRUE;
  507. }
  508. else if ( cmdOptions[ OI_PASSWORD ].dwActuals == 0 &&
  509. ( cmdOptions[ OI_SERVER ].dwActuals != 0 || cmdOptions[ OI_USER ].dwActuals != 0 ) )
  510. {
  511. // -s, -u is specified without password ...
  512. // utility needs to try to connect first and if it fails then prompt for the password
  513. *pbNeedPasswd = TRUE;
  514. if ( lpszPasswd != NULL )
  515. {
  516. StringCopy( lpszPasswd, _T( "" ), MAX_STRING_LENGTH );
  517. }
  518. }
  519. //allocate memory if /u is not specified
  520. if( NULL == *lpszUser )
  521. {
  522. *lpszUser = (LPWSTR) AllocateMemory( MAX_STRING_LENGTH*sizeof(WCHAR) );
  523. if( NULL == *lpszUser )
  524. {
  525. ShowLastErrorEx( stderr, SLE_TYPE_ERROR | SLE_INTERNAL );
  526. return (EXIT_FAILURE);
  527. }
  528. }
  529. }
  530. return( EXIT_SUCCESS );
  531. }
  532. DWORD DisplayOutput( IN long double AllowedDisk,
  533. IN ULONGLONG lfTotalNumberofFreeBytes,
  534. IN LPWSTR szDrive
  535. )
  536. /*++
  537. Routine Description : This displays the output whether specified amount
  538. disk space is available in drive or not.
  539. Arguments:
  540. [ in ] lAllowedDisk: A pointer to string specifying the drive path.
  541. [ in ] szDrive : Drive name to be displayed.
  542. Return Type : void
  543. --*/
  544. {
  545. WCHAR szOutputStr[MAX_STRING_LENGTH] = NULL_STRING;
  546. WCHAR szTempBuf[MAX_STRING_LENGTH] = NULL_STRING;
  547. //display new line
  548. ShowMessage( stdout, NEWLINE );
  549. //check if it is only to know the amount of free space on the disk
  550. //then display the free space
  551. if( (long double)-1 == AllowedDisk )
  552. {
  553. //format the number into string
  554. StringCchPrintf( szTempBuf, SIZE_OF_ARRAY(szTempBuf)-1, L"%I64d", lfTotalNumberofFreeBytes );
  555. //convert into locale
  556. ConvertintoLocale( szTempBuf, szOutputStr );
  557. //if drive name is not specified display for current drive
  558. if( StringLengthW(szDrive, 0) == 0 )
  559. {
  560. ShowMessageEx( stdout, 1, TRUE, GetResString( IDS_AVAILABLE_DISK_SPACE1),_X(szOutputStr) );
  561. }
  562. else
  563. {
  564. ShowMessageEx( stdout, 2, TRUE, GetResString( IDS_AVAILABLE_DISK_SPACE ), _X(szOutputStr), _X2( CharUpper( szDrive ) ) );
  565. }
  566. }
  567. else //check the specified space is available or not
  568. {
  569. if (lfTotalNumberofFreeBytes < AllowedDisk)
  570. {
  571. //if drive letter is specified display as it is otherwise display it as currrent drive
  572. if( StringLengthW(szDrive,0) != 0 )
  573. {
  574. ShowMessageEx( stdout, 1, TRUE, GetResString(IDS_TOO_SMALL), _X(CharUpper(szDrive)) );
  575. }
  576. else
  577. {
  578. ShowMessage(stdout, GetResString(IDS_TOO_SMALL1));
  579. }
  580. return( EXIT_FAILURE );
  581. }
  582. else
  583. {
  584. //format the number into string
  585. StringCchPrintf( szTempBuf, SIZE_OF_ARRAY(szTempBuf)-1, L"%lf", AllowedDisk );
  586. //convert into locale
  587. ConvertintoLocale( szTempBuf, szOutputStr );
  588. //if drive name is not specified display it as current drive
  589. if( StringLength(szDrive, 0) == 0 )
  590. {
  591. ShowMessageEx(stdout, 1, TRUE, GetResString(IDS_OK1), _X(szOutputStr) );
  592. }
  593. else
  594. {
  595. ShowMessageEx(stdout, 2, TRUE, GetResString(IDS_OK), _X(szOutputStr), _X2(CharUpper(szDrive)) );
  596. }
  597. }
  598. }
  599. return( EXIT_SUCCESS );
  600. }
  601. ULONGLONG
  602. GetDriveFreeSpace(
  603. IN LPCWSTR lpszRootPathName
  604. )
  605. /*++
  606. Routine Description : Function used to Check the specified free space available
  607. in the specified disk.
  608. Arguments:
  609. [ in ] lpszRootPathName : A pointer to string specifying the drive path.
  610. Return Type : ULONGLONG
  611. A longlong value returns the no.of free bytes available on disk, if success.
  612. otherwise returns -1 value
  613. --*/
  614. {
  615. DWORD dwRetCode = 0;
  616. ULONGLONG lpFreeBytesAvailable = 0;
  617. ULONGLONG lpTotalNumberofBytes = 0;
  618. ULONGLONG lpTotalNumberofFreeBytes = (ULONGLONG)-1;
  619. //this error mode is not to display the message box
  620. //if drive is not currently available
  621. SetErrorMode( SEM_FAILCRITICALERRORS);
  622. //get the total free disk space using the API
  623. dwRetCode=GetDiskFreeSpaceEx(lpszRootPathName,
  624. (PULARGE_INTEGER) &lpFreeBytesAvailable,
  625. (PULARGE_INTEGER) &lpTotalNumberofBytes,
  626. (PULARGE_INTEGER) &lpTotalNumberofFreeBytes );
  627. //if it fails display the reason and exit with error
  628. if( 0 == dwRetCode )
  629. {
  630. switch( GetLastError() )
  631. {
  632. case ERROR_PATH_NOT_FOUND :
  633. case ERROR_BAD_NETPATH :
  634. case ERROR_INVALID_NAME :
  635. SetReason(GetResString(IDS_INVALID_DRIVE) );
  636. break;
  637. case ERROR_INVALID_PARAMETER :
  638. SetReason( GetResString(IDS_CANT_FIND_DISK));
  639. break;
  640. default :
  641. SaveLastError();
  642. break;
  643. }
  644. }
  645. //reset back the critical error
  646. SetErrorMode(0);
  647. return( lpTotalNumberofFreeBytes );
  648. }
  649. DWORD
  650. ValidateDriveType( LPWSTR szRootPathName )
  651. /*++
  652. Routine Description : Function used to Check the specified drive is valid or not
  653. Arguments:
  654. [ in ] lpszRootPathName : A pointer to string specifying the drive path.
  655. Return Type : ULONGLONG
  656. returns EXIT_SUCCESS if the drive type is valid, returns EXIT_FAILURE otherwise
  657. --*/
  658. {
  659. DWORD dwCode = 0;
  660. DWORD dwAttr = 0xffffffff;
  661. dwCode = GetDriveType( szRootPathName );
  662. switch( dwCode )
  663. {
  664. case DRIVE_UNKNOWN :
  665. // case DRIVE_NO_ROOT_DIR :
  666. //if the file is not not check again for reparse point
  667. dwAttr = GetFileAttributes( szRootPathName );
  668. if( (DWORD)-1!=dwAttr && (dwAttr & FILE_ATTRIBUTE_REPARSE_POINT) )
  669. {
  670. // attributes for reparse point
  671. return EXIT_SUCCESS;
  672. }
  673. else
  674. {
  675. switch( GetLastError() )
  676. {
  677. case ERROR_ACCESS_DENIED :
  678. SaveLastError();
  679. return EXIT_FAILURE;
  680. case ERROR_INVALID_PARAMETER :
  681. SetReason( GetResString(IDS_CANT_FIND_DISK));
  682. default :
  683. SetReason(GetResString(IDS_INVALID_DRIVE) );
  684. return EXIT_FAILURE;
  685. }
  686. }
  687. }
  688. return( EXIT_SUCCESS );
  689. }
  690. DWORD
  691. ProcessValue( IN LPWSTR szValue,
  692. OUT long double *dfValue
  693. )
  694. /*++
  695. Routine Description : This function process the szValue and returns
  696. its decimal number.
  697. Arguments:
  698. [ in ] szValue : A pointer to string specifying the drive path.
  699. [ out ] dfValue : A pointer to long double which returns the numeric value
  700. of the value specified in szValue.
  701. Return Type : DWORD
  702. A Integer value indicating EXIT_SUCCESS on success,
  703. EXIT_FAILURE on failure
  704. --*/
  705. {
  706. LPWSTR pszStoppedString = NULL;
  707. double dfFactor = 1.0;
  708. LPWSTR szTemp = NULL;
  709. WCHAR szDecimalSep[MAX_RES_STRING] = NULL_STRING;
  710. //if free space value is not specified consider it as -1
  711. if( StringLength(szValue,0) == 0 )
  712. {
  713. *dfValue = -1;
  714. }
  715. else
  716. {
  717. //check for language regional settings
  718. if( 0 == GetLocaleInfo( LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, szDecimalSep, MAX_RES_STRING ) )
  719. {
  720. SaveLastError();
  721. return EXIT_FAILURE;
  722. }
  723. //check if decimal point(.) is also specified along with the decimal seperator
  724. if( StringCompare(szDecimalSep, L".", TRUE, 0) != 0 && (szTemp = (LPWSTR)FindString( szValue, L".", 0)) != NULL)
  725. {
  726. SetReason(GetResString(IDS_INVALID_BYTES) );
  727. return(EXIT_FAILURE);
  728. }
  729. if( (szTemp = (LPWSTR)FindString( szValue, szDecimalSep, 0 )) != NULL )
  730. szTemp[0] = L'.';
  731. //read the numeric value
  732. *dfValue = wcstod( szValue, &pszStoppedString );
  733. //check for negative value specified
  734. if( *dfValue < 0 )
  735. {
  736. SetReason(GetResString(IDS_INVALID_BYTES) );
  737. return(EXIT_FAILURE);
  738. }
  739. //now check for whether Units are specified or not
  740. //if specified take the multiplying facter as to that value
  741. StrTrim(pszStoppedString, L" ");
  742. if( StringLengthW(pszStoppedString, 0) )
  743. {
  744. if( StringCompare( pszStoppedString, KB, TRUE, 0) == 0 )
  745. {
  746. dfFactor = 1024;
  747. }
  748. else
  749. if( StringCompare( pszStoppedString, MB, TRUE, 0) == 0 )
  750. {
  751. dfFactor = 1024*1024;
  752. }
  753. else
  754. if( StringCompare( pszStoppedString, GB, TRUE, 0) == 0 )
  755. {
  756. dfFactor = 1024*1024*1024;
  757. }
  758. else
  759. if( StringCompare( pszStoppedString, TB, TRUE, 0) == 0 )
  760. {
  761. dfFactor = (long double)1024*1024*1024*1024;
  762. }
  763. else
  764. if( StringCompare( pszStoppedString, PB, TRUE, 0) == 0 )
  765. {
  766. dfFactor = (long double)1024*1024*1024*1024*1024;
  767. }
  768. else
  769. if( StringCompare( pszStoppedString, EB, TRUE, 0) == 0 )
  770. {
  771. dfFactor = (long double)1024*1024*1024*1024*1024*1024;
  772. }
  773. else
  774. if( StringCompare( pszStoppedString, ZB, TRUE, 0) == 0 )
  775. {
  776. dfFactor = (long double)1024*1024*1024*1024*1024*1024*1024;
  777. }
  778. else
  779. if( StringCompare( pszStoppedString, YB, TRUE, 0) == 0 )
  780. {
  781. dfFactor = (long double)1024*1024*1024*1024*1024*1024*1024*1024;
  782. }
  783. else
  784. {
  785. SetReason(GetResString( IDS_INVALID_BYTES ) );
  786. return( EXIT_FAILURE );
  787. }
  788. //check if only units are specified without any value like KB, MB etc.
  789. if( StringCompare( pszStoppedString, szValue, TRUE, 0 ) == 0 )
  790. {
  791. *dfValue = 1;
  792. }
  793. }
  794. *dfValue *= dfFactor;
  795. //check if no units are specified but fractional value is specified
  796. if( (1.0 == dfFactor) && (szTemp=(LPWSTR)FindString( szValue, L".", 0))!=NULL )
  797. {
  798. SetReason(GetResString( IDS_INVALID_BYTES ) );
  799. return( EXIT_FAILURE );
  800. }
  801. }
  802. return( EXIT_SUCCESS );
  803. }
  804. DWORD
  805. ConvertintoLocale( IN LPWSTR szNumberStr,
  806. OUT LPWSTR szOutputStr )
  807. /*++
  808. Routine Description : This function converts string into locale format
  809. Arguments:
  810. [ in ] szNumberStr : A pointer to string specifying input string to convert.
  811. [ out ] szOutputStr : A pointer to a string specifying output string in locale format.
  812. Return Type : DWORD
  813. A Integer value indicating EXIT_SUCCESS on success,
  814. EXIT_FAILURE on failure
  815. --*/
  816. {
  817. NUMBERFMT numberfmt;
  818. WCHAR szGrouping[MAX_RES_STRING] = NULL_STRING;
  819. WCHAR szDecimalSep[MAX_RES_STRING] = NULL_STRING;
  820. WCHAR szThousandSep[MAX_RES_STRING] = NULL_STRING;
  821. WCHAR szTemp[MAX_RES_STRING] = NULL_STRING;
  822. LPWSTR szTemp1 = NULL;
  823. LPWSTR pszStoppedString = NULL;
  824. DWORD dwStatus = 0;
  825. DWORD dwGrouping = 3;
  826. //make the fractional digits and leading zeros to nothing
  827. numberfmt.NumDigits = 0;
  828. numberfmt.LeadingZero = 0;
  829. //get the decimal seperate character
  830. if( FALSE == GetLocaleInfo( LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, szDecimalSep, MAX_RES_STRING ) )
  831. {
  832. StringCopy(szDecimalSep, L",", SIZE_OF_ARRAY(szDecimalSep));
  833. }
  834. numberfmt.lpDecimalSep = szDecimalSep;
  835. //get the thousand seperator
  836. if(FALSE == GetLocaleInfo( LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, szThousandSep, MAX_RES_STRING ) )
  837. {
  838. StringCopy(szThousandSep, L",", SIZE_OF_ARRAY(szThousandSep) );
  839. }
  840. numberfmt.lpThousandSep = szThousandSep;
  841. if( GetLocaleInfo( LOCALE_USER_DEFAULT, LOCALE_SGROUPING, szGrouping, MAX_RES_STRING ) )
  842. {
  843. szTemp1 = wcstok( szGrouping, L";");
  844. do
  845. {
  846. STRING_CONCAT_STATIC( szTemp, szTemp1);
  847. szTemp1 = wcstok( NULL, L";" );
  848. }while( szTemp1 != NULL && StringCompare( szTemp1, L"0", TRUE, 0) != 0);
  849. dwGrouping = wcstol( szTemp, &pszStoppedString, 10);
  850. }
  851. else
  852. dwGrouping = 33; //set the default grouping
  853. numberfmt.Grouping = (UINT)dwGrouping ;
  854. numberfmt.NegativeOrder = 2;
  855. dwStatus = GetNumberFormat( LOCALE_USER_DEFAULT, 0, szNumberStr, &numberfmt, szOutputStr, MAX_RES_STRING);
  856. return(EXIT_SUCCESS);
  857. }
  858. DWORD
  859. DisplayHelpUsage()
  860. /*++
  861. Routine Description : Function used to to display the help usage.
  862. Arguments:
  863. Return Type : DWORD
  864. A Integer value indicating EXIT_SUCCESS on success else
  865. EXIT_FAILURE on failure
  866. --*/
  867. {
  868. for( DWORD dw=IDS_MAIN_HELP_BEGIN; dw<=IDS_MAIN_HELP_END; dw++)
  869. {
  870. ShowMessage(stdout,GetResString(dw) );
  871. }
  872. return(EXIT_SUCCESS);
  873. }