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.

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