Source code of Windows XP (NT5)
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.

508 lines
13 KiB

  1. /********************************************************************/
  2. /** Microsoft LAN Manager **/
  3. /** Copyright(c) Microsoft Corp., 1990-1991 **/
  4. /********************************************************************/
  5. //***
  6. //
  7. // Filename: Parse.c
  8. //
  9. // Description:
  10. // This module contains the entry point of DIAL.EXE.
  11. // This module will parse the command line. It will validate the syntax
  12. // and the arguments on the command line. On any error, the exit
  13. // module will be invoked with the appropriate error code.
  14. // If any default values are required, they will be supplied by
  15. // this module.
  16. //
  17. // History:
  18. // September 1, 1990 Narendra Gidwani Created original version
  19. //
  20. #include <windows.h>
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #ifdef DBCS
  24. #include <locale.h>
  25. #endif /* DBCS */
  26. #include "cmd.h"
  27. //** Global data structures and variables used. **
  28. //* These variables are pointers to ASCIIZ which will be set to
  29. // point to switch values of the command line by GetSwitchValue.
  30. // These pointers are global within this module.
  31. CHAR * gblEntity = NULL;
  32. CHAR * gblCommand = NULL;
  33. CHAR * gblServer = NULL;
  34. CHAR * gblName = NULL;
  35. CHAR * gblPath = NULL;
  36. CHAR * gblPassword = NULL;
  37. CHAR * gblReadOnly = NULL;
  38. CHAR * gblMaxUses = NULL;
  39. CHAR * gblOwnerName = NULL;
  40. CHAR * gblGroupName = NULL;
  41. CHAR * gblPermissions = NULL;
  42. CHAR * gblLoginMessage = NULL;
  43. CHAR * gblMaxSessions = NULL;
  44. CHAR * gblGuestsAllowed = NULL;
  45. CHAR * gblMacServerName = NULL;
  46. CHAR * gblUAMRequired = NULL;
  47. CHAR * gblAllowSavedPasswords = NULL;
  48. CHAR * gblType = NULL;
  49. CHAR * gblCreator = NULL;
  50. CHAR * gblDataFork = NULL;
  51. CHAR * gblResourceFork = NULL;
  52. CHAR * gblTargetFile = NULL;
  53. CHAR * gblHelp = NULL;
  54. // Non translatable text
  55. //
  56. CHAR * pszVolume = "Volume";
  57. CHAR * pszAdd = "/Add";
  58. CHAR * pszDelete = "/Remove";
  59. CHAR * pszSet = "/Set";
  60. CHAR * pszDirectory = "Directory";
  61. CHAR * pszServer = "Server";
  62. CHAR * pszForkize = "Forkize";
  63. CMD_FMT DelVolArgFmt[] = {
  64. { "/Server", (CHAR *)&gblServer, 0},
  65. { "/Name", (CHAR *)&gblName, 0},
  66. { "/Help", (CHAR *)&gblHelp, 0},
  67. { "/?", (CHAR *)&gblHelp, 0},
  68. { NULL, (CHAR *)NULL, 0}
  69. };
  70. CMD_FMT AddVolArgFmt[] = {
  71. { "/Server", (CHAR *)&gblServer, 0},
  72. { "/Name", (CHAR *)&gblName, 0},
  73. { "/Path", (CHAR *)&gblPath, 0},
  74. { "/Password", (CHAR *)&gblPassword, 0},
  75. { "/ReadOnly", (CHAR *)&gblReadOnly, 0},
  76. { "/GuestsAllowed", (CHAR *)&gblGuestsAllowed, 0},
  77. { "/MaxUsers", (CHAR *)&gblMaxUses, 0},
  78. { "/Help", (CHAR *)&gblHelp, 0},
  79. { "/?", (CHAR *)&gblHelp, 0},
  80. { NULL, (CHAR *)NULL, 0}
  81. };
  82. CMD_FMT SetVolArgFmt[] = {
  83. { "/Server", (CHAR *)&gblServer, 0},
  84. { "/Name", (CHAR *)&gblName, 0},
  85. { "/Password", (CHAR *)&gblPassword, 0},
  86. { "/ReadOnly", (CHAR *)&gblReadOnly, 0},
  87. { "/GuestsAllowed", (CHAR *)&gblGuestsAllowed, 0},
  88. { "/MaxUsers", (CHAR *)&gblMaxUses, 0},
  89. { "/Help", (CHAR *)&gblHelp, 0},
  90. { "/?", (CHAR *)&gblHelp, 0},
  91. { NULL, (CHAR *)NULL, 0}
  92. };
  93. CMD_FMT DirArgFmt[] = {
  94. { "/Server", (CHAR *)&gblServer, 0},
  95. { "/Path", (CHAR *)&gblPath, 0},
  96. { "/Owner", (CHAR *)&gblOwnerName, 0},
  97. { "/Group", (CHAR *)&gblGroupName, 0},
  98. { "/Permissions", (CHAR *)&gblPermissions, 0},
  99. { "/Help", (CHAR *)&gblHelp, 0},
  100. { "/?", (CHAR *)&gblHelp, 0},
  101. { NULL, (CHAR *)NULL, 0}
  102. };
  103. CMD_FMT ServerArgFmt[] = {
  104. { "/Server", (CHAR *)&gblServer, 0},
  105. { "/MaxSessions", (CHAR *)&gblMaxSessions, 0},
  106. { "/LoginMessage", (CHAR *)&gblLoginMessage, 0},
  107. { "/GuestsAllowed", (CHAR *)&gblGuestsAllowed, 0},
  108. { "/UAMRequired", (CHAR *)&gblUAMRequired, 0},
  109. { "/AllowSavedPasswords",(CHAR *)&gblAllowSavedPasswords,0},
  110. { "/MacServerName", (CHAR *)&gblMacServerName, 0},
  111. { "/Help", (CHAR *)&gblHelp, 0},
  112. { "/?", (CHAR *)&gblHelp, 0},
  113. { NULL, (CHAR *)NULL, 0}
  114. };
  115. CMD_FMT ForkizeArgFmt[] = {
  116. { "/Server", (CHAR *)&gblServer, 0},
  117. { "/Type", (CHAR *)&gblType, 0},
  118. { "/Creator", (CHAR *)&gblCreator, 0},
  119. { "/DataFork", (CHAR *)&gblDataFork, 0},
  120. { "/ResourceFork", (CHAR *)&gblResourceFork, 0},
  121. { "/TargetFile", (CHAR *)&gblTargetFile, 0},
  122. { "/Help", (CHAR *)&gblHelp, 0},
  123. { "/?", (CHAR *)&gblHelp, 0},
  124. { NULL, (CHAR *)NULL, 0}
  125. };
  126. //**
  127. //
  128. // Call: main
  129. //
  130. // Entry: int argc; - Number of command line arguments
  131. // char *argv[]; - Array of pointers to ASCIIZ command line
  132. // arguments.
  133. //
  134. // Exit: none.
  135. //
  136. // Returns: none.
  137. //
  138. // Description: Calls the command line parser with the command line
  139. // arguments.
  140. //
  141. VOID _cdecl
  142. main( INT argc, CHAR * argv[] )
  143. {
  144. #ifdef DBCS
  145. setlocale( LC_ALL, "" );
  146. #endif /* DBCS */
  147. // This will act like xacc or yacc. It will parse the command line
  148. // and call the appropriate function to carry out an action.
  149. // Thus this procedure will never return.
  150. ParseCmdArgList( argc, argv );
  151. }
  152. //**
  153. //
  154. // Call: ParseCmdArgList
  155. //
  156. // Entry: int argc; - Number of command line arguments.
  157. // char *argv[]; - Array of pointers to ASCIIZ command line
  158. // arguments.
  159. //
  160. // Exit: none.
  161. //
  162. // Returns: none.
  163. //
  164. // Description:
  165. // Will parse command line for any errors and determine
  166. // from the syntax what the user wishes to do. Command
  167. // line arguments will be validated.
  168. //
  169. VOID
  170. ParseCmdArgList(
  171. INT argc,
  172. CHAR * argv[]
  173. )
  174. {
  175. DWORD ArgCount = 0;
  176. if ( argc == 1 )
  177. PrintMessageAndExit( IDS_GENERAL_SYNTAX, NULL );
  178. //
  179. // What is the entity being operated on ?
  180. //
  181. gblEntity = argv[++ArgCount];
  182. if ( _strnicmp( pszVolume, gblEntity, strlen( gblEntity ) ) == 0 )
  183. {
  184. if ( argc == 2 )
  185. PrintMessageAndExit( IDS_VOLUME_SYNTAX, NULL );
  186. gblCommand = argv[++ArgCount];
  187. if ( _strnicmp( pszAdd, gblCommand, strlen( gblCommand ) ) == 0 )
  188. {
  189. GetArguments( AddVolArgFmt, argv, argc, ArgCount );
  190. if ( gblHelp != (CHAR*)NULL )
  191. PrintMessageAndExit( IDS_VOLUME_SYNTAX, NULL );
  192. DoVolumeAdd( gblServer, gblName, gblPath, gblPassword, gblReadOnly,
  193. gblGuestsAllowed, gblMaxUses );
  194. }
  195. else if ( _strnicmp( pszDelete, gblCommand, strlen( gblCommand ) ) == 0 )
  196. {
  197. GetArguments( DelVolArgFmt, argv, argc, ArgCount );
  198. if ( gblHelp != (CHAR*)NULL )
  199. PrintMessageAndExit( IDS_VOLUME_SYNTAX, NULL );
  200. DoVolumeDelete( gblServer, gblName );
  201. }
  202. else if ( _strnicmp( pszSet, gblCommand, strlen( gblCommand ) ) == 0 )
  203. {
  204. GetArguments( SetVolArgFmt, argv, argc, ArgCount );
  205. if ( gblHelp != (CHAR*)NULL )
  206. PrintMessageAndExit( IDS_VOLUME_SYNTAX, NULL );
  207. DoVolumeSet( gblServer, gblName, gblPassword, gblReadOnly,
  208. gblGuestsAllowed, gblMaxUses );
  209. }
  210. else
  211. PrintMessageAndExit( IDS_VOLUME_SYNTAX, NULL );
  212. }
  213. else if ( _strnicmp( pszDirectory, gblEntity, strlen( gblEntity ) ) == 0 )
  214. {
  215. if ( argc == 2 )
  216. PrintMessageAndExit( IDS_DIRECTORY_SYNTAX, NULL );
  217. GetArguments( DirArgFmt, argv, argc, ArgCount );
  218. if ( gblHelp != (CHAR*)NULL )
  219. PrintMessageAndExit( IDS_DIRECTORY_SYNTAX, NULL );
  220. DoDirectorySetInfo( gblServer, gblPath, gblOwnerName, gblGroupName,
  221. gblPermissions );
  222. }
  223. else if ( _strnicmp( pszServer, gblEntity, strlen( gblEntity ) ) == 0 )
  224. {
  225. if ( argc == 2 )
  226. PrintMessageAndExit( IDS_SERVER_SYNTAX, NULL );
  227. GetArguments( ServerArgFmt, argv, argc, ArgCount );
  228. if ( gblHelp != (CHAR*)NULL )
  229. PrintMessageAndExit( IDS_SERVER_SYNTAX, NULL );
  230. DoServerSetInfo( gblServer, gblMaxSessions, gblLoginMessage,
  231. gblGuestsAllowed, gblUAMRequired,
  232. gblAllowSavedPasswords, gblMacServerName );
  233. }
  234. else if ( _strnicmp( pszForkize, gblEntity, strlen( gblEntity ) ) == 0 )
  235. {
  236. GetArguments( ForkizeArgFmt, argv, argc, ArgCount );
  237. if ( gblHelp != (CHAR*)NULL )
  238. PrintMessageAndExit( IDS_FORKIZE_SYNTAX, NULL );
  239. DoForkize( gblServer, gblType, gblCreator, gblDataFork,
  240. gblResourceFork, gblTargetFile );
  241. }
  242. else
  243. PrintMessageAndExit( IDS_GENERAL_SYNTAX, NULL );
  244. }
  245. VOID
  246. GetArguments(
  247. CMD_FMT * pArgFmt,
  248. CHAR * argv[],
  249. DWORD argc,
  250. DWORD ArgCount
  251. )
  252. {
  253. //
  254. // To determine by the syntax what the user wishes to do we first
  255. // run through the arguments and get switch values.
  256. //
  257. while ( ++ArgCount < argc )
  258. {
  259. //
  260. // If it is a switch, get its value.
  261. //
  262. if ( argv[ArgCount][0] == '/' )
  263. GetSwitchValue( pArgFmt, argv[ArgCount] );
  264. else
  265. PrintMessageAndExit( IDS_GENERAL_SYNTAX, NULL );
  266. }
  267. }
  268. //**
  269. //
  270. // Call: GetSwitchValue
  271. //
  272. // Entry: CHAR * SwitchPtr; - Pointer to ASCIIZ containing a command
  273. // line argument.
  274. // ex. - /phoneb:c:\subdir
  275. //
  276. // CHAR ** LastArg; - Nothing.
  277. //
  278. // Exit: CHAR * SwitchPtr; - same as entry.
  279. //
  280. // CHAR ** LastArg; - Pointer to a pointer to ASCIIZ containig
  281. // the text of the first bad switch if
  282. // there were any.
  283. //
  284. // Returns: 0 - Success.
  285. // AMBIGIOUS_SWITCH_ERRROR - failure.
  286. // UNKNOWN_SWITCH_ERROR - failure.
  287. // MEM_ALLOC_ERROR - failure.
  288. // MULTIPLE_SWITCH_ERROR - failure.
  289. //
  290. // Description: This procedure will run through all the valid switches
  291. // in the cmdfmt structure and retrieve the value of the
  292. // the switch. The value of the switch will be inserted into the
  293. // cmdfmt structure. It will expand abbreviated switches. If
  294. // the switch had no value, it will insert a null character
  295. // as the value. If the switch did not appear, the value
  296. // pointer of the switch (in the cmdfmt structure)
  297. // will remain unchanged ( should be initialized to NULL ).
  298. // This procedure uses the same data structure as GetCmdArgs5,
  299. // hence some fields may be ignored. This is done to make the
  300. // functionality of this procedure extendable.
  301. //
  302. //
  303. VOID
  304. GetSwitchValue(
  305. CMD_FMT * pArgFmt,
  306. IN CHAR * pchSwitchPtr
  307. )
  308. {
  309. INT intFound = -1;
  310. DWORD dwIndex;
  311. DWORD dwSwitchLen;
  312. CHAR * pchSeparatorPtr;
  313. //
  314. // Get length of the switch part of the argument.
  315. //
  316. if ( ( pchSeparatorPtr = strchr( pchSwitchPtr, ':' )) != NULL )
  317. dwSwitchLen = (DWORD)(pchSeparatorPtr - pchSwitchPtr);
  318. else
  319. //
  320. // If the switch had no value.
  321. //
  322. dwSwitchLen = strlen( pchSwitchPtr );
  323. //
  324. // Run through all switches.
  325. //
  326. for ( dwIndex = 0; pArgFmt[dwIndex].cf_parmstr != NULL; dwIndex++ )
  327. {
  328. //
  329. // If this switch matches (partly or completely) one of the
  330. // valid switches.
  331. //
  332. if ( !_strnicmp( pArgFmt[dwIndex].cf_parmstr,
  333. pchSwitchPtr,
  334. dwSwitchLen ) )
  335. {
  336. if ( intFound < 0 )
  337. intFound = dwIndex;
  338. else
  339. {
  340. //
  341. // If this argument has matched another switch also.
  342. //
  343. if ( pchSeparatorPtr )
  344. *pchSeparatorPtr = '\0';
  345. PrintMessageAndExit( IDS_AMBIGIOUS_SWITCH_ERROR, pchSwitchPtr );
  346. }
  347. }
  348. }
  349. //
  350. // If we could not find a match for this switch.
  351. //
  352. if ( intFound < 0 )
  353. {
  354. if ( pchSeparatorPtr )
  355. *pchSeparatorPtr = '\0';
  356. PrintMessageAndExit( IDS_UNKNOWN_SWITCH_ERROR, pchSwitchPtr );
  357. }
  358. //
  359. // If this switch is appearing for the second time.
  360. //
  361. if ( pArgFmt[intFound].cf_usecount > 0 )
  362. {
  363. if ( pchSeparatorPtr )
  364. *pchSeparatorPtr = '\0';
  365. PrintMessageAndExit( IDS_DUPLICATE_SWITCH_ERROR, pchSwitchPtr );
  366. }
  367. else
  368. pArgFmt[intFound].cf_usecount++;
  369. //
  370. // Get the switch value if there is one.
  371. //
  372. if ( ( pchSeparatorPtr ) && ((CHAR *)(pchSeparatorPtr + 1)) )
  373. {
  374. *(CHAR **)pArgFmt[intFound].cf_ptr = ++pchSeparatorPtr;
  375. }
  376. else
  377. {
  378. *(CHAR **)pArgFmt[intFound].cf_ptr = (CHAR *)"";
  379. }
  380. }
  381. /*******************************************************************
  382. NAME: IsDriveGreaterThan2Gig
  383. SYNOPSIS: Determines if the disk is bigger than 2Gig. If it, return
  384. TRUE so that a warning can be displayed to the user
  385. RETURNS: TRUE if disk is larger than 2Gig
  386. FALSE otherwise
  387. HISTORY:
  388. NarenG 11/18/92 Modified for AFPMGR
  389. ********************************************************************/
  390. BOOL IsDriveGreaterThan2Gig( LPSTR lpDrivePath )
  391. {
  392. DWORD SectorsPerCluster;
  393. DWORD BytesPerSector;
  394. DWORD NumberOfFreeClusters;
  395. DWORD TotalNumberOfClusters;
  396. DWORDLONG DriveSize;
  397. DWORDLONG TwoGig = MAXLONG;
  398. //
  399. // If this drive volume is greater than 2G then we print warning
  400. //
  401. if ( !GetDiskFreeSpace( lpDrivePath,
  402. &SectorsPerCluster,
  403. &BytesPerSector,
  404. &NumberOfFreeClusters,
  405. &TotalNumberOfClusters
  406. ))
  407. {
  408. // some error: can't do much, so just assume this drive is smaller than 2GB. That's
  409. // probably better than alarming the customer by putting the warning?
  410. return FALSE;
  411. }
  412. DriveSize = UInt32x32To64( SectorsPerCluster * BytesPerSector,
  413. TotalNumberOfClusters ) ;
  414. if ( DriveSize > TwoGig )
  415. {
  416. return TRUE;
  417. }
  418. else
  419. {
  420. return FALSE;
  421. }
  422. }