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.

417 lines
12 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1994.
  5. //
  6. // File: winmain.cxx
  7. //
  8. // Contents: Main DFS Administrator file
  9. //
  10. // History: 05-May-93 WilliamW Created
  11. // 11-Jul-95 WayneSc Bug Fixes
  12. //
  13. //--------------------------------------------------------------------------
  14. #include "headers.hxx"
  15. #pragma hdrstop
  16. #include "cmd.hxx"
  17. #include "myutil.hxx"
  18. //
  19. // Debug flag
  20. //
  21. DECLARE_INFOLEVEL(DfsAdmin)
  22. //////////////////////////////////////////////////////////////////////////////
  23. HINSTANCE g_hInstance;
  24. #define MAX_ARGS 25
  25. //////////////////////////////////////////////////////////////////////////////
  26. //+-------------------------------------------------------------------------
  27. //
  28. // Function: WinMain
  29. //
  30. // Synopsis: main routine for the Sharing app.
  31. //
  32. // History: 11-May-93 WilliamW Created.
  33. // 16-Sep-93 DavidMun Added load & free of ccsvr.dll; move
  34. // InfoLevel init inside #if DBG.
  35. //
  36. // The command line accepted by this program is described in message
  37. // MSG_USAGE, in messages.mc. In addition to that, the following options are
  38. // accepted in debug builds. These must preceed any retail options.
  39. //
  40. // Debug options:
  41. // /debug
  42. // -- dump basic error information
  43. // /fulldebug
  44. // -- dump all error and trace information
  45. //
  46. //--------------------------------------------------------------------------
  47. int APIENTRY
  48. WinMain(
  49. IN HINSTANCE hInst,
  50. IN HINSTANCE hPrevInstance,
  51. IN LPSTR lpszCommandLineAnsi,
  52. IN int cmdShow
  53. )
  54. {
  55. HRESULT hr;
  56. HACCEL hAccel;
  57. MSG msg;
  58. PWSTR pszInitialDfs = NULL;
  59. PWSTR pszCommandLine = GetCommandLine(); // get the unicode command line
  60. BOOLEAN fBatch = FALSE;
  61. BOOLEAN fRestore = FALSE;
  62. //
  63. // Store the current instance away.
  64. //
  65. g_hInstance = hInst;
  66. #if DBG == 1
  67. DebugInitialize();
  68. //
  69. // Set debug info level
  70. //
  71. DfsAdminInfoLevel = DEB_ERROR | DEB_WARN;
  72. if (NULL != wcsstr(pszCommandLine, L"/debug"))
  73. {
  74. DfsAdminInfoLevel =
  75. DEB_ERROR
  76. | DEB_WARN
  77. | DEB_TRACE
  78. ;
  79. }
  80. if (NULL != wcsstr(pszCommandLine, L"/fulldebug"))
  81. {
  82. DfsAdminInfoLevel =
  83. DEB_ERROR
  84. | DEB_WARN
  85. | DEB_TRACE
  86. | DEB_IERROR
  87. | DEB_IWARN
  88. | DEB_ITRACE
  89. ;
  90. }
  91. // For some reason, the MessageBox call done for ASSRT_POPUP
  92. // is failing with error 2 (???), and although the assert message gets
  93. // printed, it doesn't break.
  94. DebugSetAssertLevel(ASSRT_MESSAGE | ASSRT_BREAK);
  95. #endif
  96. //
  97. // Parse the command line. First, break everything out into separate
  98. // strings (kind of like argv/argc). Note that the program name doesn't
  99. // appear in pszCommandLine.
  100. //
  101. DWORD cArgs = 0;
  102. DWORD iArg;
  103. LPWSTR apszArgs[MAX_ARGS];
  104. LPWSTR pT = pszCommandLine;
  105. if (NULL != pT)
  106. {
  107. for (; cArgs < MAX_ARGS;)
  108. {
  109. while (L' ' == *pT || L'\t' == *pT) { pT++; } // eat whitespace
  110. if (L'\0' == *pT)
  111. {
  112. break;
  113. }
  114. // We found a parameter. Find how long it is, allocate a string
  115. // to store it, and copy it. If the argument begins with a double
  116. // quote, we continue until we find the next double quote. To allow
  117. // double-quotes within strings, we allow these two special
  118. // sequences:
  119. // \" => " backslash escapes quotes
  120. // \\ => \ backslash escapes backslash
  121. // \x => x backslash escapes anything!
  122. // First, determine the string size
  123. DWORD cchArg = 0;
  124. BOOL fQuoted = (L'"' == *pT);
  125. if (fQuoted)
  126. {
  127. ++pT;
  128. }
  129. // count the # of characters in the string
  130. LPWSTR pT2 = pT;
  131. if (fQuoted)
  132. {
  133. while (L'"' != *pT2 && L'\0' != *pT2)
  134. {
  135. if (L'\\' == *pT2 && L'"' == *(pT2+1))
  136. {
  137. pT2 += 2;
  138. }
  139. else
  140. {
  141. pT2 += 1;
  142. }
  143. ++cchArg;
  144. }
  145. if (L'\0' == *pT2)
  146. {
  147. // no trailing quotes
  148. Usage();
  149. }
  150. else
  151. {
  152. // we're on a ", so skip it
  153. ++pT2;
  154. if (L' ' != *pT2 && L'\t' != *pT2 && L'\0' != *pT2)
  155. {
  156. // garbage after the "
  157. Usage();
  158. }
  159. }
  160. }
  161. else
  162. {
  163. while (L' ' != *pT2 && L'\t' != *pT2 && L'\0' != *pT2)
  164. {
  165. ++pT2;
  166. ++cchArg;
  167. }
  168. }
  169. // allocate storage for the parameter
  170. LPWSTR pszNew = new WCHAR[cchArg + 1];
  171. if (NULL == pszNew)
  172. {
  173. ErrorMessage(MSG_OUTOFMEMORY);
  174. }
  175. LPWSTR pCopy = pszNew;
  176. // copy the string
  177. pT2 = pT;
  178. if (fQuoted)
  179. {
  180. while (L'"' != *pT2 && L'\0' != *pT2)
  181. {
  182. if (L'\\' == *pT2 && L'"' == *(pT2+1))
  183. {
  184. ++pT2; // skip the backslash
  185. }
  186. *pCopy++ = *pT2++;
  187. }
  188. if (L'\0' == *pT2)
  189. {
  190. // no trailing quotes
  191. appAssert(FALSE);
  192. }
  193. else
  194. {
  195. // we're on a ", so skip it
  196. ++pT2;
  197. if (L' ' != *pT2 && L'\t' != *pT2 && L'\0' != *pT2)
  198. {
  199. // garbage after the "
  200. appAssert(FALSE);
  201. }
  202. }
  203. }
  204. else
  205. {
  206. while (L' ' != *pT2 && L'\t' != *pT2 && L'\0' != *pT2)
  207. {
  208. *pCopy++ = *pT2++;
  209. }
  210. }
  211. *pCopy = L'\0';
  212. apszArgs[cArgs++] = pszNew;
  213. pT = pT2;
  214. }
  215. if (cArgs >= MAX_ARGS)
  216. {
  217. Usage();
  218. }
  219. //
  220. // We've got the arguments parsed out now, so do something with them
  221. //
  222. iArg = 1; // skip the first one, which is the program name
  223. #if DBG == 1
  224. for (; iArg < cArgs; )
  225. {
  226. if ( 0 == _wcsicmp(apszArgs[iArg], L"/debug")
  227. || 0 == _wcsicmp(apszArgs[iArg], L"/fulldebug")
  228. )
  229. {
  230. ++iArg; // skip it
  231. }
  232. else
  233. {
  234. break;
  235. }
  236. }
  237. #endif // DBG == 1
  238. if (iArg < cArgs)
  239. {
  240. if ( 0 == _wcsicmp(apszArgs[iArg], L"/help")
  241. || 0 == _wcsicmp(apszArgs[iArg], L"/h")
  242. || 0 == _wcsicmp(apszArgs[iArg], L"/?")
  243. || 0 == _wcsicmp(apszArgs[iArg], L"-help")
  244. || 0 == _wcsicmp(apszArgs[iArg], L"-h")
  245. || 0 == _wcsicmp(apszArgs[iArg], L"-?")
  246. )
  247. {
  248. Usage();
  249. }
  250. else if (0 == _wcsicmp(apszArgs[iArg], L"/map"))
  251. {
  252. LPWSTR pszComment = NULL;
  253. if (
  254. iArg + 2 > cArgs - 1
  255. || iArg + 4 < cArgs - 1)
  256. {
  257. Usage();
  258. }
  259. if (iArg + 3 <= cArgs - 1)
  260. {
  261. if (0 == _wcsicmp(apszArgs[iArg + 3], L"/restore"))
  262. fRestore = TRUE;
  263. else
  264. pszComment = apszArgs[iArg + 3];
  265. }
  266. if (iArg + 4 <= cArgs - 1)
  267. {
  268. if (0 == _wcsicmp(apszArgs[iArg + 4], L"/restore"))
  269. fRestore = TRUE;
  270. else if (pszComment != NULL)
  271. Usage();
  272. else
  273. pszComment = apszArgs[iArg + 4];
  274. }
  275. CmdMap(apszArgs[iArg + 1], apszArgs[iArg + 2], pszComment, fRestore);
  276. }
  277. else if (0 == _wcsicmp(apszArgs[iArg], L"/unmap"))
  278. {
  279. if (iArg + 1 != cArgs - 1)
  280. {
  281. Usage();
  282. }
  283. CmdUnmap(apszArgs[iArg + 1]);
  284. }
  285. else if (0 == _wcsicmp(apszArgs[iArg], L"/add"))
  286. {
  287. if (iArg + 2 > cArgs - 1
  288. || iArg + 3 < cArgs - 1)
  289. {
  290. Usage();
  291. }
  292. if (iArg + 3 <= cArgs - 1)
  293. {
  294. if (0 == _wcsicmp(apszArgs[iArg + 3], L"/restore"))
  295. fRestore = TRUE;
  296. else
  297. Usage();
  298. }
  299. CmdAdd(apszArgs[iArg + 1], apszArgs[iArg + 2], fRestore);
  300. }
  301. else if (0 == _wcsicmp(apszArgs[iArg], L"/remove"))
  302. {
  303. if (iArg + 2 != cArgs - 1)
  304. {
  305. Usage();
  306. }
  307. CmdRemove(apszArgs[iArg + 1], apszArgs[iArg + 2]);
  308. }
  309. else if (0 == _wcsicmp(apszArgs[iArg], L"/view"))
  310. {
  311. if ( iArg + 1 > cArgs - 1
  312. || iArg + 2 < cArgs - 1
  313. )
  314. {
  315. Usage();
  316. }
  317. DWORD level = 1;
  318. if (iArg + 2 == cArgs - 1)
  319. {
  320. if (0 == _wcsicmp(apszArgs[iArg + 2], L"/partial"))
  321. {
  322. level = 2;
  323. }
  324. else if (0 == _wcsicmp(apszArgs[iArg + 2], L"/full"))
  325. {
  326. level = 3;
  327. }
  328. else if (0 == _wcsicmp(apszArgs[iArg + 2], L"/batch"))
  329. {
  330. fBatch = TRUE;
  331. level = 3;
  332. }
  333. else if (0 == _wcsicmp(apszArgs[iArg + 2], L"/batchrestore"))
  334. {
  335. fBatch = TRUE;
  336. fRestore = TRUE;
  337. level = 3;
  338. }
  339. else
  340. {
  341. Usage();
  342. }
  343. }
  344. CmdView(apszArgs[iArg + 1], level, fBatch, fRestore);
  345. }
  346. #ifdef MOVERENAME
  347. else if (0 == _wcsicmp(apszArgs[iArg], L"/move"))
  348. {
  349. if (iArg + 2 != cArgs - 1)
  350. {
  351. Usage();
  352. }
  353. CmdMove(apszArgs[iArg + 1], apszArgs[iArg + 2]);
  354. }
  355. else if (0 == _wcsicmp(apszArgs[iArg], L"/rename"))
  356. {
  357. if (iArg + 2 != cArgs - 1)
  358. {
  359. Usage();
  360. }
  361. CmdRename(apszArgs[iArg + 1], apszArgs[iArg + 2]);
  362. }
  363. #endif
  364. else
  365. {
  366. Usage();
  367. }
  368. }
  369. else
  370. {
  371. Usage();
  372. }
  373. }
  374. else
  375. {
  376. Usage();
  377. }
  378. StatusMessage(MSG_SUCCESSFUL);
  379. return 0;
  380. }