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.

909 lines
26 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. renregfn.c
  5. Abstract:
  6. Implements code-based registry rename.
  7. Author:
  8. Jim Schmidt (jimschm) 15-Sep-2000
  9. Revision History:
  10. <alias> <date> <comments>
  11. --*/
  12. //
  13. // Includes
  14. //
  15. #include "pch.h"
  16. #include "v1p.h"
  17. #define DBG_RENREGFN "RenRegFn"
  18. //
  19. // Strings
  20. //
  21. // None
  22. //
  23. // Constants
  24. //
  25. // None
  26. //
  27. // Macros
  28. //
  29. // None
  30. //
  31. // Types
  32. //
  33. typedef VOID(RENREGFNINIT)(MIG_PLATFORMTYPEID);
  34. typedef RENREGFNINIT *PRENREGFNINIT;
  35. typedef BOOL (STDMETHODCALLTYPE RENAMERULE)(
  36. IN PCTSTR OldNode,
  37. IN PCTSTR NewNode,
  38. IN PCTSTR Leaf,
  39. IN BOOL NoRestoreObject,
  40. OUT PMIG_FILTEROUTPUT OutputData
  41. );
  42. typedef RENAMERULE FAR *LPRENAMERULE;
  43. //
  44. // Globals
  45. //
  46. PTSTR g_DestIdentityGUID = NULL;
  47. BOOL g_OERulesMigrated = FALSE;
  48. //
  49. // Macro expansion list
  50. //
  51. //
  52. // DEFMAC(<script tag>, <enum callback>, <operation name>, <op init>, <operation callback>)
  53. //
  54. // It is assumed that <operation callback> is a tree filter (it can modify part of a path).
  55. // The code does not currently support the contrary.
  56. //
  57. #define DEFAULT_ENUM pDefaultRenRegFnQueueCallback
  58. #define DEFAULT_INIT pNulInit
  59. #define RENAME_FUNCTIONS \
  60. DEFMAC(ConvertOE4, DEFAULT_ENUM, MOVE.ConvertOE4, pConvertOE4Init, pConvertOE4Move ) \
  61. DEFMAC(ConvertOE4IAM, DEFAULT_ENUM, MOVE.ConvertOE4IAM, pConvertOE4Init, pConvertOEIAMMove ) \
  62. DEFMAC(ConvertOE5IAM, DEFAULT_ENUM, MOVE.ConvertOE5IAM, pConvertOE5IAMInit, pConvertOEIAMMove ) \
  63. DEFMAC(ConvertOE5IdIAM, DEFAULT_ENUM, MOVE.ConvertOE5IdIAM, DEFAULT_INIT, pConvertOEIdIAMMove) \
  64. DEFMAC(ConvertOE5MailRules, DEFAULT_ENUM, MOVE.ConvertOE5MailRules, DEFAULT_INIT, pConvertOE5MailRulesMove) \
  65. DEFMAC(ConvertOE5NewsRules, DEFAULT_ENUM, MOVE.ConvertOE5NewsRules, DEFAULT_INIT, pConvertOE5NewsRulesMove) \
  66. DEFMAC(ConvertOE5Block, DEFAULT_ENUM, MOVE.ConvertOE5Block, DEFAULT_INIT, pConvertOE5BlockMove) \
  67. //
  68. // Private function prototypes
  69. //
  70. // None
  71. //
  72. // Macro expansion definition
  73. //
  74. //
  75. // Declare special rename operation apply callback functions
  76. //
  77. #define DEFMAC(ifn,ec,opn,opi,opc) SGMENUMERATIONCALLBACK ec; RENREGFNINIT opi; OPMFILTERCALLBACK opc;
  78. RENAME_FUNCTIONS
  79. #undef DEFMAC
  80. //
  81. // This is the structure used for handling action functions
  82. //
  83. typedef struct {
  84. PCTSTR InfFunctionName;
  85. PSGMENUMERATIONCALLBACK EnumerationCallback;
  86. PCTSTR OperationName;
  87. MIG_OPERATIONID OperationId;
  88. PRENREGFNINIT OperationInit;
  89. POPMFILTERCALLBACK OperationCallback;
  90. } RENAME_STRUCT, *PRENAME_STRUCT;
  91. //
  92. // Declare a global array of rename functions
  93. //
  94. #define DEFMAC(ifn,ec,opn,opi,opc) {TEXT("\\")TEXT(#ifn),ec,TEXT(#opn),0,opi,opc},
  95. static RENAME_STRUCT g_RenameFunctions[] = {
  96. RENAME_FUNCTIONS
  97. {NULL, NULL, NULL, 0, NULL, NULL}
  98. };
  99. #undef DEFMAC
  100. //
  101. // Code
  102. //
  103. VOID
  104. pNulInit (
  105. IN MIG_PLATFORMTYPEID Platform
  106. )
  107. {
  108. }
  109. UINT
  110. pDefaultRenRegFnQueueCallback (
  111. IN PCMIG_OBJECTENUMDATA Data,
  112. IN ULONG_PTR CallerArg
  113. )
  114. {
  115. PRENAME_STRUCT p = (PRENAME_STRUCT)CallerArg;
  116. IsmSetOperationOnObject (Data->ObjectTypeId, Data->ObjectName, p->OperationId, NULL, NULL);
  117. return CALLBACK_ENUM_CONTINUE;
  118. }
  119. PRENAME_STRUCT
  120. pGetRenameStruct (
  121. IN PCTSTR FunctionName
  122. )
  123. {
  124. PRENAME_STRUCT p = g_RenameFunctions;
  125. INT i = 0;
  126. while (p->InfFunctionName != NULL) {
  127. if (StringIMatch (p->InfFunctionName, FunctionName)) {
  128. return p;
  129. }
  130. p++;
  131. i++;
  132. }
  133. return NULL;
  134. }
  135. VOID
  136. InitSpecialRename (
  137. IN MIG_PLATFORMTYPEID Platform
  138. )
  139. {
  140. PRENAME_STRUCT p = g_RenameFunctions;
  141. while (p->InfFunctionName) {
  142. p->OperationId = IsmRegisterOperation (p->OperationName, FALSE);
  143. if (Platform == PLATFORM_DESTINATION) {
  144. IsmRegisterOperationFilterCallback (p->OperationId, p->OperationCallback, TRUE, TRUE, FALSE);
  145. }
  146. p->OperationInit(Platform);
  147. p++;
  148. }
  149. }
  150. VOID
  151. TerminateSpecialRename (
  152. VOID
  153. )
  154. {
  155. if (g_DestIdentityGUID) {
  156. FreeText (g_DestIdentityGUID);
  157. }
  158. }
  159. BOOL
  160. AddSpecialRenameRule (
  161. IN PCTSTR Pattern,
  162. IN PCTSTR Function
  163. )
  164. {
  165. PRENAME_STRUCT functionStruct = NULL;
  166. BOOL result = FALSE;
  167. functionStruct = pGetRenameStruct (Function);
  168. if (functionStruct) {
  169. result = IsmHookEnumeration (
  170. g_RegType,
  171. Pattern,
  172. functionStruct->EnumerationCallback?
  173. functionStruct->EnumerationCallback:
  174. pDefaultRenRegFnQueueCallback,
  175. (ULONG_PTR)functionStruct,
  176. functionStruct->InfFunctionName
  177. );
  178. } else {
  179. LOG ((
  180. LOG_ERROR,
  181. (PCSTR) MSG_DATA_RENAME_BAD_FN,
  182. Function,
  183. Pattern
  184. ));
  185. }
  186. return result;
  187. }
  188. BOOL
  189. pProcessDataRenameSection (
  190. IN PINFSTRUCT InfStruct,
  191. IN HINF InfHandle,
  192. IN PCTSTR Section
  193. )
  194. {
  195. PCTSTR pattern;
  196. ENCODEDSTRHANDLE encodedPattern = NULL;
  197. PCTSTR functionName;
  198. BOOL result = FALSE;
  199. __try {
  200. if (InfFindFirstLine (InfHandle, Section, NULL, InfStruct)) {
  201. do {
  202. if (IsmCheckCancel()) {
  203. __leave;
  204. }
  205. pattern = InfGetStringField (InfStruct, 0);
  206. if (!pattern) {
  207. continue;
  208. }
  209. encodedPattern = TurnRegStringIntoHandle (pattern, TRUE, NULL);
  210. functionName = InfGetStringField (InfStruct, 1);
  211. if (functionName) {
  212. AddSpecialRenameRule(encodedPattern, functionName);
  213. } else {
  214. LOG ((LOG_ERROR, (PCSTR) MSG_DATA_RENAME_NO_FN, pattern));
  215. }
  216. IsmDestroyObjectHandle (encodedPattern);
  217. encodedPattern = NULL;
  218. } while (InfFindNextLine (InfStruct));
  219. }
  220. result = TRUE;
  221. }
  222. __finally {
  223. InfCleanUpInfStruct (InfStruct);
  224. }
  225. return result;
  226. }
  227. BOOL
  228. DoRegistrySpecialRename (
  229. IN HINF InfHandle,
  230. IN PCTSTR Section
  231. )
  232. {
  233. PCTSTR osSpecificSection;
  234. BOOL b;
  235. INFSTRUCT is = INITINFSTRUCT_PMHANDLE;
  236. b = pProcessDataRenameSection (&is, InfHandle, Section);
  237. if (b) {
  238. osSpecificSection = GetMostSpecificSection (&is, InfHandle, Section);
  239. if (osSpecificSection) {
  240. b = pProcessDataRenameSection (&is, InfHandle, osSpecificSection);
  241. FreeText (osSpecificSection);
  242. }
  243. }
  244. InfCleanUpInfStruct (&is);
  245. return b;
  246. }
  247. //
  248. // Helpers below
  249. //
  250. VOID
  251. pConvertOE4Init (
  252. IN MIG_PLATFORMTYPEID Platform
  253. )
  254. {
  255. if (Platform == PLATFORM_DESTINATION &&
  256. IsmGetRealPlatform() == PLATFORM_DESTINATION &&
  257. IsmIsComponentSelected (S_OE_COMPONENT, 0) &&
  258. IsmIsEnvironmentFlagSet (PLATFORM_SOURCE, NULL, S_OE4_APPDETECT))
  259. {
  260. if (g_DestIdentityGUID != NULL) {
  261. // Already got it.. punt
  262. return;
  263. }
  264. // pull out the GUID from dest
  265. g_DestIdentityGUID = OEGetDefaultId (PLATFORM_DESTINATION);
  266. if (g_DestIdentityGUID == NULL)
  267. {
  268. // This is when we created a new user
  269. g_DestIdentityGUID = OECreateFirstIdentity();
  270. } else {
  271. // This is when applying to a user who never ran OE
  272. OEInitializeIdentity();
  273. }
  274. }
  275. }
  276. BOOL
  277. WINAPI
  278. pConvertOE4Move (
  279. IN PCMIG_FILTERINPUT InputData,
  280. OUT PMIG_FILTEROUTPUT OutputData,
  281. IN BOOL NoRestoreObject,
  282. IN PCMIG_BLOB SourceOperationData, OPTIONAL
  283. IN PCMIG_BLOB DestinationOperationData OPTIONAL
  284. )
  285. {
  286. PCTSTR srcNode = NULL;
  287. PCTSTR srcLeaf = NULL;
  288. PTSTR newNode = NULL;
  289. PTSTR ptr = NULL;
  290. MIG_OBJECTSTRINGHANDLE newName;
  291. if (g_DestIdentityGUID == NULL) {
  292. return FALSE;
  293. }
  294. IsmCreateObjectStringsFromHandle (InputData->CurrentObject.ObjectName, &srcNode, &srcLeaf);
  295. // srcNode should be "HKCU\Software\Microsoft\Outlook Express\..."
  296. if (!srcNode) {
  297. return FALSE;
  298. }
  299. ptr = (PTSTR)_tcsistr (srcNode, TEXT("\\Outlook Express"));
  300. if (!ptr) {
  301. return FALSE;
  302. }
  303. ptr += 16;
  304. newNode = AllocText (CharCount (srcNode) + CharCount (g_DestIdentityGUID) + 17);
  305. StringCopy (newNode, TEXT("HKCU\\Identities\\")); // +12
  306. StringCat (newNode, g_DestIdentityGUID);
  307. StringCat (newNode, TEXT("\\Software\\Microsoft\\Outlook Express\\5.0")); // +4
  308. StringCat (newNode, ptr);
  309. // newNode should be "HKCU\Identities\{GUID}\Software\Microsoft\Outlook Express\5.0\..."
  310. newName = IsmCreateObjectHandle (newNode, srcLeaf);
  311. FreeText (newNode);
  312. IsmDestroyObjectString (srcLeaf);
  313. IsmDestroyObjectString (srcNode);
  314. OutputData->NewObject.ObjectName = newName;
  315. return TRUE;
  316. }
  317. VOID
  318. pConvertOE5IAMInit (
  319. IN MIG_PLATFORMTYPEID Platform
  320. )
  321. {
  322. BOOL remap = TRUE;
  323. PTSTR srcAssocId;
  324. PTSTR newIdentity;
  325. PTSTR srcDefaultId;
  326. PTSTR destDefaultId;
  327. if (Platform == PLATFORM_DESTINATION &&
  328. IsmGetRealPlatform() == PLATFORM_DESTINATION &&
  329. IsmIsComponentSelected (S_OE_COMPONENT, 0) &&
  330. IsmIsEnvironmentFlagSet (PLATFORM_SOURCE, NULL, S_OE5_APPDETECT))
  331. {
  332. // g_DestIdentityGUID should remain NULL if we do not want to remap the IAM tree
  333. // This is true when the destination user profile has not been created yet. We also
  334. // want to leave it alone when the IAM has not yet been initialized (assume that [AssociatedID]
  335. // has not yet been written.. if this is not a valid assumption, compare to source's AssociatedID)
  336. if (g_DestIdentityGUID != NULL) {
  337. // Already got it.. punt
  338. return;
  339. }
  340. srcAssocId = OEGetAssociatedId (PLATFORM_SOURCE);
  341. if (srcAssocId) {
  342. newIdentity = OEGetRemappedId (srcAssocId);
  343. if (newIdentity) {
  344. if (OEIsIdentityAssociated(newIdentity)) {
  345. FreeText(newIdentity);
  346. } else {
  347. g_DestIdentityGUID = newIdentity;
  348. }
  349. }
  350. FreeText(srcAssocId);
  351. }
  352. OEInitializeIdentity();
  353. }
  354. }
  355. BOOL
  356. WINAPI
  357. pConvertOE5IAMMove (
  358. IN PCMIG_FILTERINPUT InputData,
  359. OUT PMIG_FILTEROUTPUT OutputData,
  360. IN BOOL NoRestoreObject,
  361. IN PCMIG_BLOB SourceOperationData, OPTIONAL
  362. IN PCMIG_BLOB DestinationOperationData OPTIONAL
  363. )
  364. {
  365. PCTSTR srcNode = NULL;
  366. PCTSTR srcLeaf = NULL;
  367. PTSTR newNode = NULL;
  368. PTSTR ptr = NULL;
  369. BOOL retval = FALSE;
  370. if (g_DestIdentityGUID == NULL ||
  371. OEIsIdentityAssociated (g_DestIdentityGUID)) {
  372. // Do Nothing
  373. return TRUE;
  374. }
  375. IsmCreateObjectStringsFromHandle (InputData->CurrentObject.ObjectName, &srcNode, &srcLeaf);
  376. if (srcNode) {
  377. // srcNode should be "HKCU\Software\Microsoft\Internet Account Manager\..."
  378. ptr = _tcschr (srcNode, TEXT('\\'));
  379. if (ptr) {
  380. newNode = AllocText (CharCount (srcNode) + CharCount (g_DestIdentityGUID) + 13);
  381. StringCopy (newNode, TEXT("HKCU\\Identities\\")); // +12
  382. StringCat (newNode, g_DestIdentityGUID);
  383. StringCat (newNode, ptr);
  384. // newNode should be "HKCU\Identities\{GUID}\Software\Microsoft\Internet Account Manager\..."
  385. OutputData->NewObject.ObjectName = IsmCreateObjectHandle (newNode, srcLeaf);
  386. FreeText (newNode);
  387. retval = TRUE;
  388. }
  389. }
  390. IsmDestroyObjectString (srcNode);
  391. IsmDestroyObjectString (srcLeaf);
  392. return retval;
  393. }
  394. BOOL
  395. pConcatRuleIndex (
  396. IN PCTSTR Node,
  397. IN PCTSTR SearchStr
  398. )
  399. {
  400. MIG_OBJECTSTRINGHANDLE objectName;
  401. MIG_CONTENT objectContent;
  402. PTSTR tmpNode;
  403. PTSTR ptr;
  404. TCHAR number[5];
  405. PTSTR newStr;
  406. tmpNode = DuplicateText(Node);
  407. if (tmpNode) {
  408. ptr = (PTSTR)_tcsistr (tmpNode, SearchStr);
  409. if (ptr) {
  410. ptr += CharCount(SearchStr);
  411. StringCopyCharCount(number, ptr, 4);
  412. number[4] = 0;
  413. *ptr = 0;
  414. objectName = IsmCreateObjectHandle (tmpNode, TEXT("Order"));
  415. if (IsmAcquireObject(g_RegType | PLATFORM_DESTINATION,
  416. objectName,
  417. &objectContent)) {
  418. if (IsValidRegSz(&objectContent)) {
  419. if (!_tcsistr ((PCTSTR)objectContent.MemoryContent.ContentBytes, number)) {
  420. newStr = IsmGetMemory(objectContent.MemoryContent.ContentSize + SizeOfString(number) + 1);
  421. StringCopy(newStr, (PCTSTR)objectContent.MemoryContent.ContentBytes);
  422. StringCat(newStr, TEXT(" "));
  423. StringCat(newStr, number);
  424. IsmReleaseMemory(objectContent.MemoryContent.ContentBytes);
  425. objectContent.MemoryContent.ContentSize = SizeOfString(newStr);
  426. objectContent.MemoryContent.ContentBytes = (PCBYTE)newStr;
  427. IsmReplacePhysicalObject (g_RegType, objectName, &objectContent);
  428. }
  429. }
  430. IsmReleaseObject(&objectContent);
  431. }
  432. IsmDestroyObjectHandle(objectName);
  433. }
  434. FreeText(tmpNode);
  435. }
  436. return TRUE;
  437. }
  438. BOOL
  439. pRenameEx
  440. (
  441. IN PCTSTR OldNode,
  442. IN PCTSTR NewNode,
  443. IN PCTSTR Leaf,
  444. IN BOOL NoRestoreObject,
  445. IN PCTSTR PrevKey,
  446. IN PCTSTR FormatStr,
  447. OUT PMIG_FILTEROUTPUT OutputData,
  448. IN BOOL ZeroBase
  449. )
  450. {
  451. BOOL result = FALSE;
  452. PTSTR patternNode;
  453. PTSTR tmpNode;
  454. PTSTR ptr;
  455. PTSTR searchStr;
  456. DWORD prevCount;
  457. DWORD keySize = 1;
  458. MIG_FILTERINPUT filterInput;
  459. MIG_FILTEROUTPUT filterOutput;
  460. MIG_BLOB migBlob;
  461. MIG_BLOB zeroBaseBlob;
  462. PTSTR filteredNode = NULL;
  463. tmpNode = DuplicateText(NewNode);
  464. if (tmpNode) {
  465. prevCount = CharCount(PrevKey);
  466. searchStr = AllocText(prevCount + 3);
  467. if (searchStr) {
  468. _stprintf(searchStr, TEXT("\\%s\\"), PrevKey);
  469. ptr = (PTSTR)_tcsistr (tmpNode, searchStr);
  470. if (ptr) {
  471. ptr += (prevCount + 2); // Advance to next portion
  472. *ptr = 0;
  473. ptr = _tcsinc(ptr);
  474. while (*ptr && *ptr != TEXT('\\')) {
  475. ptr = _tcsinc(ptr);
  476. keySize++;
  477. }
  478. patternNode = AllocText(CharCount(NewNode) + (CharCount(FormatStr) - keySize));
  479. if (patternNode) {
  480. StringCopy(patternNode, tmpNode);
  481. StringCat(patternNode, FormatStr);
  482. StringCat(patternNode, ptr);
  483. filterInput.OriginalObject.ObjectTypeId = g_RegType;
  484. filterInput.OriginalObject.ObjectName = IsmCreateObjectHandle (OldNode, NULL);
  485. filterInput.CurrentObject.ObjectTypeId = g_RegType;
  486. filterInput.CurrentObject.ObjectName = IsmCreateObjectHandle (OldNode, NULL);
  487. migBlob.Type = BLOBTYPE_STRING;
  488. migBlob.String = IsmCreateObjectHandle (patternNode, NULL);
  489. if (ZeroBase) {
  490. zeroBaseBlob.Type = BLOBTYPE_BINARY;
  491. zeroBaseBlob.BinarySize = sizeof(PCBYTE);
  492. zeroBaseBlob.BinaryData = (PCBYTE)TRUE;
  493. FilterRenameExFilter (&filterInput, &filterOutput, NoRestoreObject, &zeroBaseBlob, &migBlob);
  494. } else {
  495. FilterRenameExFilter (&filterInput, &filterOutput, NoRestoreObject, NULL, &migBlob);
  496. }
  497. IsmDestroyObjectHandle (migBlob.String);
  498. IsmDestroyObjectHandle (filterInput.CurrentObject.ObjectName);
  499. IsmDestroyObjectHandle (filterInput.OriginalObject.ObjectName);
  500. IsmCreateObjectStringsFromHandle (filterOutput.NewObject.ObjectName, &filteredNode, NULL);
  501. IsmDestroyObjectHandle (filterOutput.NewObject.ObjectName);
  502. OutputData->NewObject.ObjectName = IsmCreateObjectHandle (filteredNode, Leaf);
  503. if (0 == *ptr) {
  504. pConcatRuleIndex(filteredNode, searchStr);
  505. }
  506. FreeText (filteredNode);
  507. FreeText(patternNode);
  508. }
  509. } else {
  510. OutputData->NewObject.ObjectName = IsmCreateObjectHandle (tmpNode, Leaf);
  511. }
  512. FreeText(searchStr);
  513. } else {
  514. OutputData->NewObject.ObjectName = IsmCreateObjectHandle (tmpNode, Leaf);
  515. }
  516. FreeText(tmpNode);
  517. }
  518. return TRUE;
  519. }
  520. BOOL
  521. pRenameNewsRule
  522. (
  523. IN PCTSTR OldNode,
  524. IN PCTSTR NewNode,
  525. IN PCTSTR Leaf,
  526. IN BOOL NoRestoreObject,
  527. OUT PMIG_FILTEROUTPUT OutputData
  528. )
  529. {
  530. return pRenameEx(OldNode, NewNode, Leaf, NoRestoreObject, TEXT("News"), TEXT("<%03d>"), OutputData, TRUE);
  531. }
  532. BOOL
  533. pRenameMailRule
  534. (
  535. IN PCTSTR OldNode,
  536. IN PCTSTR NewNode,
  537. IN PCTSTR Leaf,
  538. IN BOOL NoRestoreObject,
  539. OUT PMIG_FILTEROUTPUT OutputData
  540. )
  541. {
  542. return pRenameEx(OldNode, NewNode, Leaf, NoRestoreObject, TEXT("Mail"), TEXT("<%03d>"), OutputData, TRUE);
  543. }
  544. BOOL
  545. pRenameBlockRule
  546. (
  547. IN PCTSTR OldNode,
  548. IN PCTSTR NewNode,
  549. IN PCTSTR Leaf,
  550. IN BOOL NoRestoreObject,
  551. OUT PMIG_FILTEROUTPUT OutputData
  552. )
  553. {
  554. return pRenameEx(OldNode, NewNode, Leaf, NoRestoreObject, TEXT("Criteria"), TEXT("<%03d>"), OutputData, TRUE);
  555. }
  556. BOOL
  557. pRenameAccount
  558. (
  559. IN PCTSTR OldNode,
  560. IN PCTSTR NewNode,
  561. IN PCTSTR Leaf,
  562. IN BOOL NoRestoreObject,
  563. OUT PMIG_FILTEROUTPUT OutputData
  564. )
  565. {
  566. return pRenameEx(OldNode, NewNode, Leaf, NoRestoreObject, TEXT("Accounts"), TEXT("<%08d>"), OutputData, FALSE);
  567. }
  568. BOOL
  569. WINAPI
  570. pConvertOE5RulesMove (
  571. IN PCMIG_FILTERINPUT InputData,
  572. OUT PMIG_FILTEROUTPUT OutputData,
  573. IN BOOL NoRestoreObject,
  574. IN LPRENAMERULE fnRename
  575. )
  576. {
  577. PCTSTR srcNode = NULL;
  578. PCTSTR srcLeaf = NULL;
  579. PTSTR newNode = NULL;
  580. PTSTR tmpText;
  581. TCHAR *endId;
  582. TCHAR *srcIdentity;
  583. PTSTR newIdentity;
  584. // Move tree and Merge account name
  585. IsmCreateObjectStringsFromHandle (InputData->CurrentObject.ObjectName, &srcNode, &srcLeaf);
  586. if (srcNode) {
  587. // srcNode should be "HKCU\Identities\{GUID}\Software\Microsoft\Outlook Express\Rules\Mail\..."
  588. tmpText = DuplicateText(srcNode);
  589. if (tmpText) {
  590. srcIdentity = _tcschr(tmpText, TEXT('{'));
  591. if (srcIdentity) {
  592. endId = _tcschr(srcIdentity, TEXT('\\'));
  593. if (endId) {
  594. *endId = 0;
  595. endId = _tcsinc(endId);
  596. // endId should be "Software\Microsoft\Outlook Express\Rules\Mail\..."
  597. // srcIdentity should be "{GUID}"
  598. newIdentity = OEGetRemappedId (srcIdentity);
  599. if (newIdentity) {
  600. newNode = AllocText (CharCount(srcNode) + 1);
  601. StringCopy (newNode, TEXT("HKCU\\Identities\\"));
  602. StringCat (newNode, newIdentity);
  603. StringCat (newNode, TEXT("\\"));
  604. StringCat (newNode, endId);
  605. if (newNode) {
  606. if (srcLeaf &&
  607. !g_OERulesMigrated &&
  608. !StringIMatch(srcLeaf, TEXT("Version"))) {
  609. g_OERulesMigrated = TRUE;
  610. }
  611. fnRename(srcNode, newNode, srcLeaf, NoRestoreObject, OutputData);
  612. FreeText(newNode);
  613. }
  614. FreeText(newIdentity);
  615. }
  616. }
  617. }
  618. FreeText(tmpText);
  619. }
  620. IsmDestroyObjectString (srcNode);
  621. }
  622. IsmDestroyObjectString (srcLeaf);
  623. return TRUE;
  624. }
  625. BOOL
  626. WINAPI
  627. pConvertOE5NewsRulesMove (
  628. IN PCMIG_FILTERINPUT InputData,
  629. OUT PMIG_FILTEROUTPUT OutputData,
  630. IN BOOL NoRestoreObject,
  631. IN PCMIG_BLOB SourceOperationData, OPTIONAL
  632. IN PCMIG_BLOB DestinationOperationData OPTIONAL
  633. )
  634. {
  635. return pConvertOE5RulesMove(InputData, OutputData, NoRestoreObject, pRenameNewsRule);
  636. }
  637. BOOL
  638. WINAPI
  639. pConvertOE5MailRulesMove (
  640. IN PCMIG_FILTERINPUT InputData,
  641. OUT PMIG_FILTEROUTPUT OutputData,
  642. IN BOOL NoRestoreObject,
  643. IN PCMIG_BLOB SourceOperationData, OPTIONAL
  644. IN PCMIG_BLOB DestinationOperationData OPTIONAL
  645. )
  646. {
  647. return pConvertOE5RulesMove(InputData, OutputData, NoRestoreObject, pRenameMailRule);
  648. }
  649. BOOL
  650. WINAPI
  651. pConvertOE5BlockMove (
  652. IN PCMIG_FILTERINPUT InputData,
  653. OUT PMIG_FILTEROUTPUT OutputData,
  654. IN BOOL NoRestoreObject,
  655. IN PCMIG_BLOB SourceOperationData, OPTIONAL
  656. IN PCMIG_BLOB DestinationOperationData OPTIONAL
  657. )
  658. {
  659. return pConvertOE5RulesMove(InputData, OutputData, NoRestoreObject, pRenameBlockRule);
  660. }
  661. BOOL
  662. WINAPI
  663. pConvertOEIdIAMMove (
  664. IN PCMIG_FILTERINPUT InputData,
  665. OUT PMIG_FILTEROUTPUT OutputData,
  666. IN BOOL NoRestoreObject,
  667. IN PCMIG_BLOB SourceOperationData, OPTIONAL
  668. IN PCMIG_BLOB DestinationOperationData OPTIONAL
  669. )
  670. {
  671. PCTSTR srcNode = NULL;
  672. PCTSTR srcLeaf = NULL;
  673. PTSTR newNode = NULL;
  674. PTSTR tmpText;
  675. TCHAR *endId;
  676. TCHAR *srcIdentity;
  677. PTSTR newIdentity;
  678. // Move tree and Merge account name
  679. IsmCreateObjectStringsFromHandle (InputData->CurrentObject.ObjectName, &srcNode, &srcLeaf);
  680. if (srcNode) {
  681. // srcNode should be "HKCU\Identities\{GUID}\Software\Microsoft\Internet Account Manager\..."
  682. tmpText = DuplicateText(srcNode);
  683. if (tmpText) {
  684. srcIdentity = _tcschr(tmpText, TEXT('{'));
  685. if (srcIdentity) {
  686. endId = _tcschr(srcIdentity, TEXT('\\'));
  687. if (endId) {
  688. *endId = 0;
  689. endId = _tcsinc(endId);
  690. // endId should be "Software\Microsoft\Internet Account Manager\..."
  691. // srcIdentity should be "{GUID}"
  692. newIdentity = OEGetRemappedId (srcIdentity);
  693. if (newIdentity) {
  694. if (OEIsIdentityAssociated (newIdentity)) {
  695. // allocText below does include 1 extra for Null
  696. newNode = AllocText (CharCount(endId) + 6);
  697. StringCopy (newNode, TEXT("HKCU\\")); // +5
  698. StringCat (newNode, endId);
  699. // newNode should be "HKCU\Software\Microsoft\Internet Account Manager\..."
  700. } else {
  701. newNode = AllocText (CharCount(srcNode) + 1);
  702. StringCopy (newNode, TEXT("HKCU\\Identities\\"));
  703. StringCat (newNode, newIdentity);
  704. StringCat (newNode, TEXT("\\"));
  705. StringCat (newNode, endId);
  706. }
  707. if (newNode) {
  708. pRenameAccount(srcNode,
  709. newNode,
  710. srcLeaf,
  711. NoRestoreObject,
  712. OutputData);
  713. FreeText(newNode);
  714. }
  715. FreeText(newIdentity);
  716. }
  717. }
  718. }
  719. FreeText(tmpText);
  720. }
  721. IsmDestroyObjectString (srcNode);
  722. }
  723. IsmDestroyObjectString (srcLeaf);
  724. return TRUE;
  725. }
  726. BOOL
  727. WINAPI
  728. pConvertOEIAMMove (
  729. IN PCMIG_FILTERINPUT InputData,
  730. OUT PMIG_FILTEROUTPUT OutputData,
  731. IN BOOL NoRestoreObject,
  732. IN PCMIG_BLOB SourceOperationData, OPTIONAL
  733. IN PCMIG_BLOB DestinationOperationData OPTIONAL
  734. )
  735. {
  736. PCTSTR srcNode = NULL;
  737. PCTSTR srcLeaf = NULL;
  738. PTSTR newNode = NULL;
  739. PTSTR filteredNode = NULL;
  740. PTSTR ptr = NULL;
  741. // Move tree and Merge account name
  742. IsmCreateObjectStringsFromHandle (InputData->CurrentObject.ObjectName, &srcNode, &srcLeaf);
  743. if (srcNode) {
  744. // srcNode should be "HKCU\Software\Microsoft\Internet Account Manager\..."
  745. if (g_DestIdentityGUID != NULL &&
  746. !OEIsIdentityAssociated (g_DestIdentityGUID)) {
  747. ptr = _tcschr (srcNode, TEXT('\\'));
  748. if (ptr) {
  749. newNode = AllocText (TcharCount (srcNode) + TcharCount (g_DestIdentityGUID) + 13);
  750. StringCopy (newNode, TEXT("HKCU\\Identities\\")); // +12
  751. StringCat (newNode, g_DestIdentityGUID);
  752. StringCat (newNode, ptr);
  753. // newNode should be "HKCU\Identities\{GUID}\Software\Microsoft\Internet Account Manager\..."
  754. }
  755. } else {
  756. newNode = DuplicateText (srcNode);
  757. }
  758. if (newNode) {
  759. pRenameAccount(srcNode,
  760. newNode,
  761. srcLeaf,
  762. NoRestoreObject,
  763. OutputData);
  764. FreeText (newNode);
  765. }
  766. IsmDestroyObjectString (srcNode);
  767. }
  768. IsmDestroyObjectString (srcLeaf);
  769. return TRUE;
  770. }