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.

1466 lines
28 KiB

  1. #include "StdAfx.h"
  2. #include "Parameter.h"
  3. #define NO_WBEM
  4. #include "T_SafeVector.h"
  5. namespace Parameter_cpp
  6. {
  7. inline bool IsPrefix(_TCHAR ch)
  8. {
  9. return ((ch == _T('/')) || (ch == _T('-')));
  10. }
  11. struct SNameToTask
  12. {
  13. LPCTSTR pszName;
  14. int nTask;
  15. };
  16. SNameToTask s_TaskValues[] =
  17. {
  18. { _T("User"), TASK_USER },
  19. { _T("Group"), TASK_GROUP },
  20. { _T("Computer"), TASK_COMPUTER },
  21. { _T("Security"), TASK_SECURITY },
  22. { _T("Service"), TASK_SERVICE },
  23. { _T("Report"), TASK_REPORT },
  24. { _T("Key"), TASK_KEY },
  25. { NULL, TASK_NONE },
  26. };
  27. struct SNameToBool
  28. {
  29. LPCTSTR pszName;
  30. bool bValue;
  31. };
  32. SNameToBool s_BoolValues[] =
  33. {
  34. { _T("Yes"), true },
  35. { _T("No"), false },
  36. { _T("True"), true },
  37. { _T("False"), false },
  38. { NULL, false },
  39. };
  40. struct SNameToLong
  41. {
  42. LPCTSTR pszName;
  43. long lValue;
  44. };
  45. SNameToLong s_RenameOptionValues[] =
  46. {
  47. { _T("Dont"), admtDoNotRename },
  48. { _T("Prefix"), admtRenameWithPrefix },
  49. { _T("Suffix"), admtRenameWithSuffix },
  50. { NULL, -1L },
  51. };
  52. SNameToLong s_PasswordOptionValues[] =
  53. {
  54. { _T("Name"), admtPasswordFromName },
  55. { _T("Complex"), admtComplexPassword },
  56. { _T("Copy"), admtCopyPassword },
  57. { NULL, -1L },
  58. };
  59. SNameToLong s_ConflictOptionValues[] =
  60. {
  61. { _T("Ignore"), admtIgnoreConflicting },
  62. { _T("Replace"), admtReplaceConflicting },
  63. { _T("Prefix"), admtRenameConflictingWithPrefix },
  64. { _T("Suffix"), admtRenameConflictingWithSuffix },
  65. { NULL, -1L },
  66. };
  67. SNameToLong s_ConflictOptionFlagValues[] =
  68. {
  69. { _T("RemoveUserRights"), admtRemoveExistingUserRights },
  70. { _T("RemoveMembers"), admtRemoveExistingMembers },
  71. { _T("MoveReplacedAccounts"), admtMoveReplacedAccounts },
  72. { NULL, -1L },
  73. };
  74. SNameToLong s_DisableOptionValues[] =
  75. {
  76. { _T("Neither"), admtEnableTarget },
  77. { _T("Source"), admtDisableSource },
  78. { _T("Target"), admtDisableTarget },
  79. { _T("SameAsSource"), admtTargetSameAsSource },
  80. { NULL, -1L },
  81. };
  82. SNameToLong s_SourceExpirationValues[] =
  83. {
  84. { _T("None"), admtNoExpiration },
  85. { NULL, 0L },
  86. };
  87. SNameToLong s_TranslationOptionValues[] =
  88. {
  89. { _T("Replace"), admtTranslateReplace },
  90. { _T("Add"), admtTranslateAdd },
  91. { _T("Remove"), admtTranslateRemove },
  92. { NULL, -1L },
  93. };
  94. SNameToLong s_ReportTypeValues[] =
  95. {
  96. { _T("MigratedAccounts"), admtReportMigratedAccounts },
  97. { _T("MigratedComputers"), admtReportMigratedComputers },
  98. { _T("ExpiredComputers"), admtReportExpiredComputers },
  99. { _T("AccountReferences"), admtReportAccountReferences },
  100. { _T("NameConflicts"), admtReportNameConflicts },
  101. { NULL, -1L },
  102. };
  103. SNameToLong s_DomainOptionFlagAValues[] =
  104. {
  105. { _T("Recurse"), admtRecurse },
  106. { NULL, -1L },
  107. };
  108. SNameToLong s_DomainOptionFlagBValues[] =
  109. {
  110. { _T("Flatten"), admtFlattenHierarchy },
  111. { _T("Maintain"), admtMaintainHierarchy },
  112. { NULL, -1L },
  113. };
  114. bool GetBoolValue(LPCTSTR pszArg);
  115. bool GetBoolFromName(LPCTSTR pszName, SNameToBool* pNameToBool);
  116. long GetLongValue(LPCTSTR pszArg, SNameToLong* pNameToLong);
  117. long GetLongFromName(LPCTSTR pszName, SNameToLong* pNameToLong);
  118. bool GetPasswordFromUser(LPCTSTR pszKeyId, _bstr_t& strPassword);
  119. _bstr_t LoadStringHelper(UINT uId);
  120. }
  121. using namespace Parameter_cpp;
  122. //---------------------------------------------------------------------------
  123. // Parameter Map
  124. //---------------------------------------------------------------------------
  125. // Public Methods -----------------------------------------------------------
  126. // GetValue Method
  127. bool CParameterMap::GetValue(int nParam, bool& bValue)
  128. {
  129. bool bGet = false;
  130. iterator it = find(nParam);
  131. if (it != end())
  132. {
  133. bValue = it->second;
  134. bGet = true;
  135. }
  136. return bGet;
  137. }
  138. // GetValue Method
  139. bool CParameterMap::GetValue(int nParam, long& lValue)
  140. {
  141. bool bGet = false;
  142. iterator it = find(nParam);
  143. if (it != end())
  144. {
  145. lValue = it->second;
  146. bGet = true;
  147. }
  148. return bGet;
  149. }
  150. // GetValue Method
  151. bool CParameterMap::GetValue(int nParam, _bstr_t& strValue)
  152. {
  153. bool bGet = false;
  154. iterator it = find(nParam);
  155. if (it != end())
  156. {
  157. strValue = it->second;
  158. bGet = true;
  159. }
  160. return bGet;
  161. }
  162. // GetValues Method
  163. bool CParameterMap::GetValues(int nParam, _variant_t& vntValues)
  164. {
  165. bool bGet = false;
  166. iterator it = find(nParam);
  167. if (it != end())
  168. {
  169. vntValues = it->second;
  170. bGet = true;
  171. }
  172. return bGet;
  173. }
  174. // GetValues Method
  175. bool CParameterMap::GetValues(int nParam, StringVector& vecValues)
  176. {
  177. bool bGet = false;
  178. iterator it = find(nParam);
  179. if (it != end())
  180. {
  181. vecValues = T_SafeVector2<VT_BSTR, _bstr_t, StringVector, T_Extract_bstr_t<StringVector> >(it->second);
  182. bGet = true;
  183. }
  184. return bGet;
  185. }
  186. // Protected Methods --------------------------------------------------------
  187. // Initialize Method
  188. void CParameterMap::Initialize(CArguments& rArgs)
  189. {
  190. if (DoTask(rArgs.Value()))
  191. {
  192. long lTask;
  193. if (GetValue(SWITCH_TASK, lTask))
  194. {
  195. if (lTask == TASK_KEY)
  196. {
  197. DoTaskKey(rArgs);
  198. }
  199. else
  200. {
  201. DoSwitches(rArgs);
  202. VerifyIncludeExclude();
  203. }
  204. }
  205. }
  206. // if (empty())
  207. // {
  208. // ThrowError(E_INVALIDARG, IDS_E_NO_ARGUMENTS);
  209. // }
  210. }
  211. // DoTask
  212. bool CParameterMap::DoTask(LPCTSTR pszArg)
  213. {
  214. bool bTask = false;
  215. if (pszArg != NULL)
  216. {
  217. // first switch must specify task or help
  218. int nSwitch = m_mapSwitchs.GetSwitch(pszArg);
  219. if (nSwitch == SWITCH_TASK)
  220. {
  221. int nTask = TASK_NONE;
  222. for (SNameToTask* p = s_TaskValues; p->pszName; p++)
  223. {
  224. if (_tcsicmp(p->pszName, pszArg) == 0)
  225. {
  226. nTask = p->nTask;
  227. break;
  228. }
  229. }
  230. insert(value_type(SWITCH_TASK, _variant_t(long(nTask))));
  231. bTask = true;
  232. }
  233. else
  234. {
  235. _TCHAR chPrefix;
  236. _TCHAR szSwitch[16];
  237. if ((_stscanf(pszArg, _T(" %c%15s "), &chPrefix, szSwitch) == 2) && IsPrefix(chPrefix) && (m_mapSwitchs.GetSwitch(szSwitch) == SWITCH_HELP))
  238. {
  239. insert(value_type(SWITCH_HELP, _variant_t(true)));
  240. }
  241. else
  242. {
  243. ThrowError(E_INVALIDARG, IDS_E_INVALID_FIRST_ARGUMENT, pszArg);
  244. }
  245. }
  246. }
  247. else
  248. {
  249. // ThrowError(E_INVALIDARG, IDS_E_NO_ARGUMENTS);
  250. }
  251. return bTask;
  252. }
  253. // DoSwitches Method
  254. void CParameterMap::DoSwitches(CArguments& rArgs)
  255. {
  256. LPCTSTR pszArg = NULL;
  257. while (rArgs.Next())
  258. {
  259. pszArg = rArgs.Value();
  260. _TCHAR chPrefix;
  261. _TCHAR szSwitch[64];
  262. if ((_stscanf(pszArg, _T(" %c%63[A-Za-z?] "), &chPrefix, szSwitch) == 2) && IsPrefix(chPrefix))
  263. {
  264. int nSwitch = m_mapSwitchs.GetSwitch(szSwitch);
  265. if (nSwitch == -1)
  266. {
  267. ThrowError(E_INVALIDARG, IDS_E_OPTION_UNRECOGNIZED, pszArg);
  268. }
  269. if (nSwitch == SWITCH_TASK)
  270. {
  271. ThrowError(E_INVALIDARG, IDS_E_TASK_NOT_FIRST, pszArg);
  272. }
  273. if (nSwitch == SWITCH_HELP)
  274. {
  275. insert(value_type(SWITCH_HELP, _variant_t(true)));
  276. break;
  277. }
  278. DoSwitch(nSwitch, rArgs);
  279. }
  280. else
  281. {
  282. ThrowError(E_INVALIDARG, IDS_E_INVALID_OPTION_FORMAT, pszArg);
  283. }
  284. }
  285. // if no switches/options then display help
  286. if (pszArg == NULL)
  287. {
  288. insert(value_type(SWITCH_HELP, _variant_t(true)));
  289. }
  290. }
  291. // DoSwitch Method
  292. void CParameterMap::DoSwitch(int nSwitch, CArguments& rArgs)
  293. {
  294. _variant_t& vntValue = Insert(nSwitch);
  295. switch (nSwitch)
  296. {
  297. // boolean values
  298. case SWITCH_TEST_MIGRATION:
  299. case SWITCH_INTRA_FOREST:
  300. case SWITCH_MIGRATE_SIDS:
  301. case SWITCH_TRANSLATE_ROAMING_PROFILE:
  302. case SWITCH_UPDATE_USER_RIGHTS:
  303. case SWITCH_MIGRATE_GROUPS:
  304. case SWITCH_UPDATE_PREVIOUSLY_MIGRATED_OBJECTS:
  305. case SWITCH_FIX_GROUP_MEMBERSHIP:
  306. case SWITCH_MIGRATE_SERVICE_ACCOUNTS:
  307. case SWITCH_UPDATE_GROUP_RIGHTS:
  308. case SWITCH_MIGRATE_MEMBERS:
  309. case SWITCH_TRANSLATE_FILES_AND_FOLDERS:
  310. case SWITCH_TRANSLATE_LOCAL_GROUPS:
  311. case SWITCH_TRANSLATE_PRINTERS:
  312. case SWITCH_TRANSLATE_REGISTRY:
  313. case SWITCH_TRANSLATE_SHARES:
  314. case SWITCH_TRANSLATE_USER_PROFILES:
  315. case SWITCH_TRANSLATE_USER_RIGHTS:
  316. {
  317. vntValue = GetBoolValue(rArgs.Value());
  318. break;
  319. }
  320. // long values
  321. case SWITCH_RENAME_OPTION:
  322. {
  323. vntValue = GetLongValue(rArgs.Value(), s_RenameOptionValues);
  324. break;
  325. }
  326. case SWITCH_PASSWORD_OPTION:
  327. {
  328. vntValue = GetLongValue(rArgs.Value(), s_PasswordOptionValues);
  329. break;
  330. }
  331. case SWITCH_CONFLICT_OPTIONS:
  332. {
  333. _TCHAR szValueA[32];
  334. _TCHAR szValueB[32];
  335. _TCHAR szValueC[32];
  336. _TCHAR szValueD[32];
  337. int cFields = _stscanf(rArgs.Value(), _T("%*[^:]: %31[A-Za-z] + %31[A-Za-z] + %31[A-Za-z] + %31[A-Za-z]"), szValueA, szValueB, szValueC, szValueD);
  338. if (cFields <= 0)
  339. {
  340. ThrowError(E_INVALIDARG, IDS_E_OPTION_FORMAT_INVALID, rArgs.Value());
  341. }
  342. long lValue = GetLongFromName(szValueA, s_ConflictOptionValues);
  343. if (cFields >= 2)
  344. {
  345. lValue |= GetLongFromName(szValueB, s_ConflictOptionFlagValues);
  346. }
  347. if (cFields >= 3)
  348. {
  349. lValue |= GetLongFromName(szValueC, s_ConflictOptionFlagValues);
  350. }
  351. if (cFields >= 4)
  352. {
  353. lValue |= GetLongFromName(szValueD, s_ConflictOptionFlagValues);
  354. }
  355. vntValue = lValue;
  356. break;
  357. }
  358. case SWITCH_DISABLE_OPTION:
  359. {
  360. _TCHAR szValueA[32];
  361. _TCHAR szValueB[32];
  362. int cFields = _stscanf(rArgs.Value(), _T("%*[^:]: %31[A-Za-z] + %31[A-Za-z]"), szValueA, szValueB);
  363. if (cFields <= 0)
  364. {
  365. ThrowError(E_INVALIDARG, IDS_E_OPTION_FORMAT_INVALID, rArgs.Value());
  366. }
  367. long lValue = GetLongFromName(szValueA, s_DisableOptionValues);
  368. if (cFields >= 2)
  369. {
  370. lValue |= GetLongFromName(szValueB, s_DisableOptionValues);
  371. }
  372. vntValue = lValue;
  373. break;
  374. }
  375. case SWITCH_SOURCE_EXPIRATION:
  376. {
  377. long lValue;
  378. _TCHAR szValue[32];
  379. if (_stscanf(rArgs.Value(), _T("%*[^:]: %31[A-Za-z]"), szValue) == 1)
  380. {
  381. vntValue = GetLongFromName(szValue, s_SourceExpirationValues);
  382. }
  383. else if (_stscanf(rArgs.Value(), _T("%*[^:]: %ld"), &lValue) == 1)
  384. {
  385. vntValue = lValue;
  386. }
  387. else
  388. {
  389. ThrowError(E_INVALIDARG, IDS_E_OPTION_FORMAT_INVALID, rArgs.Value());
  390. }
  391. break;
  392. }
  393. case SWITCH_TRANSLATION_OPTION:
  394. {
  395. vntValue = GetLongValue(rArgs.Value(), s_TranslationOptionValues);
  396. break;
  397. }
  398. case SWITCH_RESTART_DELAY:
  399. {
  400. long lValue;
  401. if (_stscanf(rArgs.Value(), _T("%*[^:]: %ld"), &lValue) == 1)
  402. {
  403. vntValue = lValue;
  404. }
  405. else
  406. {
  407. ThrowError(E_INVALIDARG, IDS_E_OPTION_FORMAT_INVALID, rArgs.Value());
  408. }
  409. break;
  410. }
  411. case SWITCH_INCLUDE_DOMAIN:
  412. {
  413. _TCHAR szValueA[32];
  414. _TCHAR szValueB[32];
  415. int cFields = _stscanf(rArgs.Value(), _T("%*[^:]: %31[A-Za-z] + %31[A-Za-z]"), szValueA, szValueB);
  416. if (cFields < 0)
  417. {
  418. ThrowError(E_INVALIDARG, IDS_E_OPTION_FORMAT_INVALID, rArgs.Value());
  419. }
  420. long lValue = 0;
  421. if (cFields >= 1)
  422. {
  423. lValue |= GetLongFromName(szValueA, s_DomainOptionFlagAValues);
  424. }
  425. if (cFields >= 2)
  426. {
  427. lValue |= GetLongFromName(szValueB, s_DomainOptionFlagBValues);
  428. }
  429. vntValue = lValue;
  430. break;
  431. }
  432. case SWITCH_REPORT_TYPE:
  433. {
  434. vntValue = GetLongValue(rArgs.Value(), s_ReportTypeValues);
  435. break;
  436. }
  437. // string values
  438. case SWITCH_SOURCE_DOMAIN:
  439. case SWITCH_SOURCE_OU:
  440. case SWITCH_TARGET_DOMAIN:
  441. case SWITCH_TARGET_OU:
  442. case SWITCH_RENAME_PREFIX_OR_SUFFIX:
  443. case SWITCH_PASSWORD_SERVER:
  444. case SWITCH_PASSWORD_FILE:
  445. case SWITCH_CONFLICT_PREFIX_OR_SUFFIX:
  446. case SWITCH_USER_PROPERTIES_TO_EXCLUDE:
  447. case SWITCH_GROUP_PROPERTIES_TO_EXCLUDE:
  448. case SWITCH_COMPUTER_PROPERTIES_TO_EXCLUDE:
  449. case SWITCH_SID_MAPPING_FILE:
  450. case SWITCH_REPORT_FOLDER:
  451. case SWITCH_INCLUDE_FILE:
  452. case SWITCH_EXCLUDE_FILE:
  453. {
  454. _TCHAR szValue[4096];
  455. if (_stscanf(rArgs.Value(), _T("%*[^:]:%4095[^\0]"), szValue) == 1)
  456. {
  457. if (_tcslen(szValue) > 2047)
  458. {
  459. ThrowError(E_INVALIDARG, IDS_E_OPTION_VALUE_TOO_LONG);
  460. }
  461. vntValue = szValue;
  462. }
  463. else
  464. {
  465. if (rArgs.Next())
  466. {
  467. LPCTSTR pszArg = rArgs.Value();
  468. if (IsPrefix(pszArg[0]))
  469. {
  470. rArgs.Prev();
  471. ThrowError(E_INVALIDARG, IDS_E_NO_OPTION_VALUE, rArgs.Value());
  472. }
  473. if (_tcslen(pszArg) > 2047)
  474. {
  475. ThrowError(E_INVALIDARG, IDS_E_OPTION_VALUE_TOO_LONG);
  476. }
  477. vntValue = pszArg;
  478. }
  479. else
  480. {
  481. ThrowError(E_INVALIDARG, IDS_E_NO_OPTION_VALUE, rArgs.Value());
  482. }
  483. }
  484. break;
  485. }
  486. // multi-string values
  487. case SWITCH_INCLUDE_NAME:
  488. case SWITCH_EXCLUDE_NAME:
  489. {
  490. T_SafeVector2<VT_BSTR, _bstr_t, StringVector, T_Extract_bstr_t<StringVector> > svValues(vntValue);
  491. _TCHAR szValue[4096];
  492. if (_stscanf(rArgs.Value(), _T("%*[^:]:%4095[^\0]"), szValue) == 1)
  493. {
  494. if (_tcslen(szValue) > 2047)
  495. {
  496. ThrowError(E_INVALIDARG, IDS_E_OPTION_VALUE_TOO_LONG);
  497. }
  498. svValues.push_back(_bstr_t(szValue));
  499. }
  500. else
  501. {
  502. while (rArgs.Next())
  503. {
  504. LPCTSTR pszArg = rArgs.Value();
  505. if (IsPrefix(pszArg[0]))
  506. {
  507. rArgs.Prev();
  508. break;
  509. }
  510. if (_tcslen(pszArg) > 2047)
  511. {
  512. ThrowError(E_INVALIDARG, IDS_E_OPTION_VALUE_TOO_LONG);
  513. }
  514. svValues.push_back(_bstr_t(pszArg));
  515. }
  516. }
  517. vntValue = svValues.GetVariant();
  518. break;
  519. }
  520. // option files
  521. case SWITCH_OPTION_FILE:
  522. {
  523. _TCHAR szValue[1024];
  524. if (_stscanf(rArgs.Value(), _T("%*[^:]:%1023[^\0]"), szValue) == 1)
  525. {
  526. DoOptionFile(szValue);
  527. }
  528. else
  529. {
  530. if (rArgs.Next())
  531. {
  532. LPCTSTR pszArg = rArgs.Value();
  533. if (IsPrefix(pszArg[0]))
  534. {
  535. rArgs.Prev();
  536. }
  537. else
  538. {
  539. DoOptionFile(pszArg);
  540. }
  541. }
  542. }
  543. break;
  544. }
  545. // default
  546. default:
  547. {
  548. _ASSERT(false);
  549. break;
  550. }
  551. }
  552. }
  553. // Insert Method
  554. _variant_t& CParameterMap::Insert(int nParam)
  555. {
  556. iterator it = find(nParam);
  557. if (it == end())
  558. {
  559. std::pair<iterator, bool> pair = insert(value_type(nParam, _variant_t()));
  560. it = pair.first;
  561. }
  562. return it->second;
  563. }
  564. // DoOptionFile Method
  565. void CParameterMap::DoOptionFile(LPCTSTR pszFileName)
  566. {
  567. CSwitchMap mapSwitchs;
  568. FILE* fp = OpenOptionFile(pszFileName);
  569. try
  570. {
  571. iterator it = find(SWITCH_TASK);
  572. if (it == end())
  573. {
  574. ThrowError(E_FAIL, IDS_E_OPTION_FILE_TASK, pszFileName);
  575. }
  576. int nCurrentTask = long(it->second);
  577. int nTask;
  578. do
  579. {
  580. nTask = FindTask(fp);
  581. if ((nTask == 0) || (nTask == nCurrentTask))
  582. {
  583. DoTask(fp, mapSwitchs);
  584. }
  585. }
  586. while (nTask >= 0);
  587. }
  588. catch (...)
  589. {
  590. fclose(fp);
  591. throw;
  592. }
  593. fclose(fp);
  594. }
  595. // OpenOptionFile Method
  596. FILE* CParameterMap::OpenOptionFile(LPCTSTR pszFileName)
  597. {
  598. // open in binary mode first in order to check for UNICODE byte order
  599. // mark if the file is UNICODE then it must be read in binary mode
  600. // with the stream i/o functions
  601. FILE* fp = _tfopen(pszFileName, _T("rb"));
  602. if (fp == NULL)
  603. {
  604. ThrowError(E_INVALIDARG, IDS_E_OPTION_FILE_OPEN, pszFileName);
  605. }
  606. // check if file is ANSI or UNICODE or UTF-8
  607. BYTE byteSignature[3];
  608. if (fread(byteSignature, sizeof(BYTE), 3, fp) == 3)
  609. {
  610. static BYTE byteUtf8[] = { 0xEF, 0xBB, 0xBF };
  611. static BYTE byteUnicodeLE[] = { 0xFF, 0xFE };
  612. static BYTE byteUnicodeBE[] = { 0xFE, 0xFF };
  613. // check for signature or byte order mark
  614. if (memcmp(byteSignature, byteUtf8, sizeof(byteUtf8)) == 0)
  615. {
  616. // UTF-8 signature
  617. // TODO: not currently supported
  618. fclose(fp);
  619. ThrowError(E_INVALIDARG, IDS_E_OPTION_FILE_UTF_8, pszFileName);
  620. }
  621. else if (memcmp(byteSignature, byteUnicodeLE, sizeof(byteUnicodeLE)) == 0)
  622. {
  623. // UNICODE Little Endian Byte Order Mark
  624. // supported
  625. // must read in binary mode
  626. // move file pointer back one byte because we read 3 bytes
  627. fseek(fp, -1, SEEK_CUR);
  628. }
  629. else if (memcmp(byteSignature, byteUnicodeBE, sizeof(byteUnicodeBE)) == 0)
  630. {
  631. // UNICODE Big Endian Byte Order Mark
  632. // TODO: not currently supported
  633. fclose(fp);
  634. ThrowError(E_INVALIDARG, IDS_E_OPTION_FILE_UNICODE_BIG_ENDIAN, pszFileName);
  635. }
  636. else
  637. {
  638. // assume ANSI
  639. // re-open file in text mode as the stream i/o functions will
  640. // treat the file as multi-byte characters and will convert them
  641. // to UNICODE
  642. fclose(fp);
  643. fp = _tfopen(pszFileName, _T("rt"));
  644. if (fp == NULL)
  645. {
  646. ThrowError(E_INVALIDARG, IDS_E_OPTION_FILE_OPEN, pszFileName);
  647. }
  648. }
  649. }
  650. else
  651. {
  652. fclose(fp);
  653. ThrowError(E_INVALIDARG, IDS_E_OPTION_FILE_READ_SIGNATURE, pszFileName);
  654. }
  655. return fp;
  656. }
  657. // FindTask Method
  658. int CParameterMap::FindTask(FILE* fp)
  659. {
  660. int nTask = -1;
  661. _TCHAR szBuffer[1024];
  662. while (_fgetts(szBuffer, countof(szBuffer), fp))
  663. {
  664. _TCHAR szTask[64];
  665. if (_stscanf(szBuffer, _T(" [ %63[A-Za-z] ] "), szTask) == 1)
  666. {
  667. // _tprintf(_T("FindTask() : '%s'\n"), szTask);
  668. if (_tcsicmp(szTask, _T("Migration")) == 0)
  669. {
  670. nTask = TASK_NONE;
  671. break;
  672. }
  673. if (_tcsicmp(szTask, _T("UserMigration")) == 0)
  674. {
  675. nTask = TASK_USER;
  676. break;
  677. }
  678. if (_tcsicmp(szTask, _T("GroupMigration")) == 0)
  679. {
  680. nTask = TASK_GROUP;
  681. break;
  682. }
  683. if (_tcsicmp(szTask, _T("ComputerMigration")) == 0)
  684. {
  685. nTask = TASK_COMPUTER;
  686. break;
  687. }
  688. if (_tcsicmp(szTask, _T("SecurityTranslation")) == 0)
  689. {
  690. nTask = TASK_SECURITY;
  691. break;
  692. }
  693. if (_tcsicmp(szTask, _T("ReportGeneration")) == 0)
  694. {
  695. nTask = TASK_REPORT;
  696. break;
  697. }
  698. }
  699. }
  700. return nTask;
  701. }
  702. // DoTask Method
  703. void CParameterMap::DoTask(FILE* fp, CSwitchMap& mapSwitchs)
  704. {
  705. _TCHAR szBuffer[8192];
  706. for (;;)
  707. {
  708. long lOffset = ftell(fp);
  709. if (_fgetts(szBuffer, countof(szBuffer), fp) == NULL)
  710. {
  711. break;
  712. }
  713. _TCHAR szTask[64];
  714. if (_stscanf(szBuffer, _T(" [ %63[A-Za-z] ] "), szTask) == 1)
  715. {
  716. fseek(fp, lOffset, SEEK_SET);
  717. break;
  718. }
  719. _TCHAR szName[64];
  720. _TCHAR szValue[4096];
  721. try
  722. {
  723. if ((szBuffer[0] != _T(';')) && (_stscanf(szBuffer, _T(" %63[A-Za-z] = %4095[^\r\n]"), szName, szValue) == 2))
  724. {
  725. // _tprintf(_T("DoTask() : %s='%s'\n"), szName, szValue);
  726. CSwitchMap::iterator it = mapSwitchs.find(_bstr_t(szName));
  727. if ((it != mapSwitchs.end()) && (it->second != SWITCH_TASK))
  728. {
  729. DoParameter(it->second, szValue);
  730. }
  731. }
  732. }
  733. catch (_com_error& ce)
  734. {
  735. ThrowError(ce, IDS_CANT_GET_OPTION_VALUE, szName, szValue);
  736. }
  737. catch (...)
  738. {
  739. ThrowError(E_FAIL, IDS_CANT_GET_OPTION_VALUE, szName, szValue);
  740. }
  741. }
  742. }
  743. // DoParameter Method
  744. void CParameterMap::DoParameter(int nSwitch, LPCTSTR pszValue)
  745. {
  746. _variant_t& vntValue = Insert(nSwitch);
  747. switch (nSwitch)
  748. {
  749. // boolean values
  750. case SWITCH_TEST_MIGRATION:
  751. case SWITCH_INTRA_FOREST:
  752. case SWITCH_MIGRATE_SIDS:
  753. case SWITCH_TRANSLATE_ROAMING_PROFILE:
  754. case SWITCH_UPDATE_USER_RIGHTS:
  755. case SWITCH_MIGRATE_GROUPS:
  756. case SWITCH_UPDATE_PREVIOUSLY_MIGRATED_OBJECTS:
  757. case SWITCH_FIX_GROUP_MEMBERSHIP:
  758. case SWITCH_MIGRATE_SERVICE_ACCOUNTS:
  759. case SWITCH_UPDATE_GROUP_RIGHTS:
  760. case SWITCH_MIGRATE_MEMBERS:
  761. case SWITCH_TRANSLATE_FILES_AND_FOLDERS:
  762. case SWITCH_TRANSLATE_LOCAL_GROUPS:
  763. case SWITCH_TRANSLATE_PRINTERS:
  764. case SWITCH_TRANSLATE_REGISTRY:
  765. case SWITCH_TRANSLATE_SHARES:
  766. case SWITCH_TRANSLATE_USER_PROFILES:
  767. case SWITCH_TRANSLATE_USER_RIGHTS:
  768. {
  769. vntValue = GetBoolFromName(pszValue, s_BoolValues);
  770. break;
  771. }
  772. // long values
  773. case SWITCH_RENAME_OPTION:
  774. {
  775. vntValue = GetLongFromName(pszValue, s_RenameOptionValues);
  776. break;
  777. }
  778. case SWITCH_PASSWORD_OPTION:
  779. {
  780. vntValue = GetLongFromName(pszValue, s_PasswordOptionValues);
  781. break;
  782. }
  783. case SWITCH_CONFLICT_OPTIONS:
  784. {
  785. _TCHAR szValueA[32];
  786. _TCHAR szValueB[32];
  787. _TCHAR szValueC[32];
  788. _TCHAR szValueD[32];
  789. int cFields = _stscanf(pszValue, _T("%31[A-Za-z] + %31[A-Za-z] + %31[A-Za-z] + %31[A-Za-z]"), szValueA, szValueB, szValueC, szValueD);
  790. if (cFields <= 0)
  791. {
  792. ThrowError(E_INVALIDARG, IDS_E_OPTION_VALUE_INVALID);
  793. }
  794. long lValue = GetLongFromName(szValueA, s_ConflictOptionValues);
  795. if (cFields >= 2)
  796. {
  797. lValue |= GetLongFromName(szValueB, s_ConflictOptionFlagValues);
  798. }
  799. if (cFields >= 3)
  800. {
  801. lValue |= GetLongFromName(szValueC, s_ConflictOptionFlagValues);
  802. }
  803. if (cFields >= 4)
  804. {
  805. lValue |= GetLongFromName(szValueD, s_ConflictOptionFlagValues);
  806. }
  807. vntValue = lValue;
  808. break;
  809. }
  810. case SWITCH_DISABLE_OPTION:
  811. {
  812. _TCHAR szValueA[32];
  813. _TCHAR szValueB[32];
  814. int cFields = _stscanf(pszValue, _T("%31[A-Za-z] + %31[A-Za-z]"), szValueA, szValueB);
  815. if (cFields <= 0)
  816. {
  817. ThrowError(E_INVALIDARG, IDS_E_OPTION_FORMAT_INVALID, pszValue);
  818. }
  819. long lValue = GetLongFromName(szValueA, s_DisableOptionValues);
  820. if (cFields >= 2)
  821. {
  822. lValue |= GetLongFromName(szValueB, s_DisableOptionValues);
  823. }
  824. vntValue = lValue;
  825. break;
  826. }
  827. case SWITCH_SOURCE_EXPIRATION:
  828. {
  829. long lValue;
  830. _TCHAR szValue[32];
  831. if (_stscanf(pszValue, _T("%31[A-Za-z]"), szValue) == 1)
  832. {
  833. vntValue = GetLongFromName(szValue, s_SourceExpirationValues);
  834. }
  835. else if (_stscanf(pszValue, _T("%ld"), &lValue) == 1)
  836. {
  837. vntValue = lValue;
  838. }
  839. else
  840. {
  841. ThrowError(E_INVALIDARG, IDS_E_OPTION_VALUE_INVALID);
  842. }
  843. break;
  844. }
  845. case SWITCH_TRANSLATION_OPTION:
  846. {
  847. vntValue = GetLongFromName(pszValue, s_TranslationOptionValues);
  848. break;
  849. }
  850. case SWITCH_RESTART_DELAY:
  851. {
  852. long lValue;
  853. if (_stscanf(pszValue, _T("%ld"), &lValue) == 1)
  854. {
  855. vntValue = lValue;
  856. }
  857. else
  858. {
  859. ThrowError(E_INVALIDARG, IDS_E_OPTION_VALUE_INVALID);
  860. }
  861. break;
  862. }
  863. case SWITCH_REPORT_TYPE:
  864. {
  865. vntValue = GetLongFromName(pszValue, s_ReportTypeValues);
  866. break;
  867. }
  868. // string values
  869. case SWITCH_SOURCE_DOMAIN:
  870. case SWITCH_SOURCE_OU:
  871. case SWITCH_TARGET_DOMAIN:
  872. case SWITCH_TARGET_OU:
  873. case SWITCH_RENAME_PREFIX_OR_SUFFIX:
  874. case SWITCH_PASSWORD_SERVER:
  875. case SWITCH_PASSWORD_FILE:
  876. case SWITCH_CONFLICT_PREFIX_OR_SUFFIX:
  877. case SWITCH_USER_PROPERTIES_TO_EXCLUDE:
  878. case SWITCH_GROUP_PROPERTIES_TO_EXCLUDE:
  879. case SWITCH_COMPUTER_PROPERTIES_TO_EXCLUDE:
  880. case SWITCH_SID_MAPPING_FILE:
  881. case SWITCH_REPORT_FOLDER:
  882. {
  883. _TCHAR szValue[2048];
  884. UINT cch = _tcslen(pszValue);
  885. if (cch > 2047)
  886. {
  887. ThrowError(E_INVALIDARG, IDS_E_OPTION_VALUE_TOO_LONG);
  888. }
  889. _tcscpy(szValue, pszValue);
  890. if ((szValue[0] == _T('"')) && (szValue[cch - 1] == _T('"')))
  891. {
  892. szValue[cch - 1] = _T('\0');
  893. vntValue = &szValue[1];
  894. }
  895. else
  896. {
  897. vntValue = szValue;
  898. }
  899. break;
  900. }
  901. // default
  902. default:
  903. {
  904. _ASSERT(false);
  905. break;
  906. }
  907. }
  908. }
  909. // DoTaskKey Method
  910. void CParameterMap::DoTaskKey(CArguments& rArgs)
  911. {
  912. // key identifier
  913. LPCTSTR pszKeyId = NULL;
  914. if (rArgs.Next())
  915. {
  916. pszKeyId = rArgs.Value();
  917. _TCHAR chPrefix;
  918. _TCHAR szSwitch[16];
  919. if ((_stscanf(pszKeyId, _T(" %c%15s "), &chPrefix, szSwitch) == 2) && IsPrefix(chPrefix) && (m_mapSwitchs.GetSwitch(szSwitch) == SWITCH_HELP))
  920. {
  921. insert(value_type(SWITCH_HELP, _variant_t(true)));
  922. }
  923. else
  924. {
  925. insert(value_type(SWITCH_KEY_IDENTIFIER, _variant_t(pszKeyId)));
  926. // drive
  927. if (rArgs.Next())
  928. {
  929. insert(value_type(SWITCH_KEY_FOLDER, _variant_t(rArgs.Value())));
  930. // password
  931. _bstr_t strPassword;
  932. if (rArgs.Next())
  933. {
  934. strPassword = rArgs.Value();
  935. }
  936. if (strPassword.length() > 0)
  937. {
  938. if (_tcscmp(strPassword, _T("*")) == 0)
  939. {
  940. if (!GetPasswordFromUser(pszKeyId, strPassword))
  941. {
  942. ThrowError(E_FAIL, IDS_E_CANT_GET_PASSWORD);
  943. }
  944. }
  945. }
  946. insert(value_type(SWITCH_KEY_PASSWORD, _variant_t(strPassword)));
  947. }
  948. }
  949. }
  950. if (pszKeyId == NULL)
  951. {
  952. insert(value_type(SWITCH_HELP, _variant_t(true)));
  953. }
  954. }
  955. // VerifyIncludeExclude Method
  956. void CParameterMap::VerifyIncludeExclude()
  957. {
  958. // verify that only one include option type was specified
  959. int cInclude = 0;
  960. if (find(SWITCH_INCLUDE_NAME) != end())
  961. {
  962. ++cInclude;
  963. }
  964. if (find(SWITCH_INCLUDE_FILE) != end())
  965. {
  966. ++cInclude;
  967. }
  968. if (find(SWITCH_INCLUDE_DOMAIN) != end())
  969. {
  970. ++cInclude;
  971. }
  972. if (cInclude > 1)
  973. {
  974. ThrowError(E_INVALIDARG, IDS_E_MULTIPLE_INCLUDE_OPTIONS);
  975. }
  976. // verify that only one exclude option type was specified
  977. if ((find(SWITCH_EXCLUDE_NAME) != end()) && (find(SWITCH_EXCLUDE_FILE) != end()))
  978. {
  979. ThrowError(E_INVALIDARG, IDS_E_MULTIPLE_EXCLUDE_OPTIONS);
  980. }
  981. }
  982. namespace Parameter_cpp
  983. {
  984. // GetBoolValue Method
  985. bool GetBoolValue(LPCTSTR pszArg)
  986. {
  987. bool bValue;
  988. try
  989. {
  990. _TCHAR szValue[16];
  991. if (_stscanf(pszArg, _T("%*[^:]: %15[A-Za-z]"), szValue) == 1)
  992. {
  993. bValue = GetBoolFromName(szValue, s_BoolValues);
  994. }
  995. else
  996. {
  997. ThrowError(E_INVALIDARG, IDS_E_OPTION_FORMAT_INVALID2, pszArg);
  998. }
  999. }
  1000. catch (_com_error& ce)
  1001. {
  1002. ThrowError(ce, IDS_E_CANT_GET_OPTION_VALUE2, pszArg);
  1003. }
  1004. catch (...)
  1005. {
  1006. ThrowError(E_FAIL, IDS_E_CANT_GET_OPTION_VALUE2, pszArg);
  1007. }
  1008. return bValue;
  1009. }
  1010. // GetBoolFromName Method
  1011. bool GetBoolFromName(LPCTSTR pszName, SNameToBool* pNameToBool)
  1012. {
  1013. bool bValue;
  1014. bool bFound = false;
  1015. for (SNameToBool* p = pNameToBool; p->pszName; p++)
  1016. {
  1017. if (_tcsicmp(p->pszName, pszName) == 0)
  1018. {
  1019. bValue = p->bValue;
  1020. bFound = true;
  1021. break;
  1022. }
  1023. }
  1024. if (!bFound)
  1025. {
  1026. ThrowError(E_INVALIDARG, IDS_E_OPTION_VALUE_UNRECOGNIZED, pszName);
  1027. }
  1028. return bValue;
  1029. }
  1030. // GetLongValue Method
  1031. long GetLongValue(LPCTSTR pszArg, SNameToLong* pNameToLong)
  1032. {
  1033. long lValue;
  1034. try
  1035. {
  1036. _TCHAR szValue[32];
  1037. if (_stscanf(pszArg, _T("%*[^:]: %31[A-Za-z]"), szValue) == 1)
  1038. {
  1039. lValue = GetLongFromName(szValue, pNameToLong);
  1040. }
  1041. else
  1042. {
  1043. ThrowError(E_INVALIDARG, IDS_E_OPTION_FORMAT_INVALID2, pszArg);
  1044. }
  1045. }
  1046. catch (_com_error& ce)
  1047. {
  1048. ThrowError(ce, IDS_E_CANT_GET_OPTION_VALUE2, pszArg);
  1049. }
  1050. catch (...)
  1051. {
  1052. ThrowError(E_FAIL, IDS_E_CANT_GET_OPTION_VALUE2, pszArg);
  1053. }
  1054. return lValue;
  1055. }
  1056. // GetLongFromName Method
  1057. long GetLongFromName(LPCTSTR pszName, SNameToLong* pNameToLong)
  1058. {
  1059. long lValue;
  1060. bool bFound = false;
  1061. for (SNameToLong* p = pNameToLong; p->pszName; p++)
  1062. {
  1063. if (_tcsicmp(p->pszName, pszName) == 0)
  1064. {
  1065. lValue = p->lValue;
  1066. bFound = true;
  1067. break;
  1068. }
  1069. }
  1070. if (!bFound)
  1071. {
  1072. ThrowError(E_INVALIDARG, IDS_E_OPTION_VALUE_UNRECOGNIZED, pszName);
  1073. }
  1074. return lValue;
  1075. }
  1076. // GetPasswordFromUser Method
  1077. bool GetPasswordFromUser(LPCTSTR pszKeyId, _bstr_t& strPassword)
  1078. {
  1079. bool bGet = false;
  1080. #define BUFFER_SIZE 32
  1081. _bstr_t strFormat[2];
  1082. strFormat[0] = LoadStringHelper(IDS_TYPE_PASSWORD);
  1083. strFormat[1] = LoadStringHelper(IDS_CONFIRM_PASSWORD);
  1084. _TCHAR szPassword[2][BUFFER_SIZE];
  1085. szPassword[0][0] = _T('\0');
  1086. szPassword[1][0] = _T('\0');
  1087. HANDLE hInput = GetStdHandle(STD_INPUT_HANDLE);
  1088. HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
  1089. if (hInput != INVALID_HANDLE_VALUE)
  1090. {
  1091. DWORD dwMode;
  1092. if (GetConsoleMode(hInput, &dwMode))
  1093. {
  1094. if (SetConsoleMode(hInput, ENABLE_PROCESSED_INPUT))
  1095. {
  1096. while (bGet == false)
  1097. {
  1098. for (int nPass = 0; nPass < 2; nPass++)
  1099. {
  1100. _tprintf(strFormat[nPass], pszKeyId);
  1101. _TCHAR ch;
  1102. DWORD dwRead;
  1103. int nIndex = 0;
  1104. while (ReadConsole(hInput, &ch, 1, &dwRead, NULL))
  1105. {
  1106. if ((ch == _T('\r')) || (ch == _T('\n')))
  1107. {
  1108. break;
  1109. }
  1110. else if (ch == _T('\b'))
  1111. {
  1112. if (nIndex > 0)
  1113. {
  1114. CONSOLE_SCREEN_BUFFER_INFO csbi;
  1115. if (GetConsoleScreenBufferInfo(hOutput, &csbi))
  1116. {
  1117. --csbi.dwCursorPosition.X;
  1118. if (SetConsoleCursorPosition(hOutput, csbi.dwCursorPosition))
  1119. {
  1120. --nIndex;
  1121. DWORD dwWritten;
  1122. WriteConsole(hOutput, _T(" "), 1, &dwWritten, NULL);
  1123. SetConsoleCursorPosition(hOutput, csbi.dwCursorPosition);
  1124. }
  1125. }
  1126. }
  1127. }
  1128. else if ((nIndex < BUFFER_SIZE - 1) && _istprint(ch))
  1129. {
  1130. szPassword[nPass][nIndex++] = ch;
  1131. DWORD dwWritten;
  1132. WriteConsole(hOutput, _T("*"), 1, &dwWritten, NULL);
  1133. }
  1134. }
  1135. _puttchar(_T('\n'));
  1136. szPassword[nPass][nIndex] = _T('\0');
  1137. }
  1138. if (_tcscmp(szPassword[0], szPassword[1]) == 0)
  1139. {
  1140. strPassword = szPassword[0];
  1141. bGet = true;
  1142. break;
  1143. }
  1144. }
  1145. }
  1146. SetConsoleMode(hInput, dwMode);
  1147. }
  1148. }
  1149. return bGet;
  1150. }
  1151. _bstr_t LoadStringHelper(UINT uId)
  1152. {
  1153. _TCHAR szBuffer[1024];
  1154. if (LoadString(GetModuleHandle(NULL), uId, szBuffer, countof(szBuffer)) <= 0)
  1155. {
  1156. szBuffer[0] = _T('\0');
  1157. }
  1158. return szBuffer;
  1159. }
  1160. }