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.

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