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.

903 lines
27 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 (PLATFORM_SOURCE, &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 = JoinPathsInPoolEx ((
  305. NULL,
  306. TEXT("HKCU\\Identities"),
  307. g_DestIdentityGUID,
  308. TEXT("Software\\Microsoft\\Outlook Express\\5.0"),
  309. ptr,
  310. NULL
  311. ));
  312. // newNode should be "HKCU\Identities\{GUID}\Software\Microsoft\Outlook Express\5.0\..."
  313. newName = IsmCreateObjectHandle (newNode, srcLeaf);
  314. FreePathString (newNode);
  315. IsmDestroyObjectString (srcLeaf);
  316. IsmDestroyObjectString (srcNode);
  317. OutputData->NewObject.ObjectName = newName;
  318. return TRUE;
  319. }
  320. VOID
  321. pConvertOE5IAMInit (
  322. IN MIG_PLATFORMTYPEID Platform
  323. )
  324. {
  325. PTSTR srcAssocId;
  326. PTSTR newIdentity;
  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 one of the following is true:
  334. // 1. Destination user profile has not been created yet
  335. // 2. When the IAM has not yet been initialized on the destination (assume that
  336. // [AssociatedID] has not yet been written.. if this is not a valid assumption,
  337. // compare to source's AssociatedID)
  338. // 3. The source's associated ID is being merged into the destination's associated ID
  339. if (g_DestIdentityGUID != NULL) {
  340. // Already got it.. punt
  341. return;
  342. }
  343. srcAssocId = OEGetAssociatedId (PLATFORM_SOURCE);
  344. if (srcAssocId) {
  345. newIdentity = OEGetRemappedId (srcAssocId);
  346. if (newIdentity) {
  347. // NOTE: OEIsIdentityAssociated checks to see if it's associated. If
  348. // the key does not exist, it automatically claims it and returns TRUE
  349. if (OEIsIdentityAssociated(newIdentity)) {
  350. FreeText(newIdentity);
  351. } else {
  352. g_DestIdentityGUID = newIdentity;
  353. }
  354. }
  355. FreeText(srcAssocId);
  356. }
  357. OEInitializeIdentity();
  358. }
  359. }
  360. BOOL
  361. pConcatRuleIndex (
  362. IN PCTSTR Node,
  363. IN PCTSTR SearchStr
  364. )
  365. {
  366. MIG_OBJECTSTRINGHANDLE objectName;
  367. MIG_CONTENT objectContent;
  368. PTSTR tmpNode;
  369. PTSTR ptr;
  370. TCHAR number[5];
  371. PTSTR newStr;
  372. // Node looks like "HKR\Identities\{GUID}\Software\Microsoft\Outlook Express\5.0\Rules\News\008\"
  373. // SearchStr looks like "\News\"
  374. tmpNode = DuplicateText(Node);
  375. if (tmpNode) {
  376. ptr = (PTSTR)_tcsistr (tmpNode, SearchStr);
  377. if (ptr) {
  378. ptr += TcharCount(SearchStr);
  379. StringCopyTcharCount(number, ptr, 4);
  380. number[4] = 0;
  381. *ptr = 0;
  382. // number should now look like "008"
  383. objectName = IsmCreateObjectHandle (tmpNode, TEXT("Order"));
  384. if (IsmAcquireObject(g_RegType | PLATFORM_DESTINATION,
  385. objectName,
  386. &objectContent)) {
  387. if (IsValidRegSz(&objectContent)) {
  388. // Does this index already exist?
  389. if (!_tcsistr ((PCTSTR)objectContent.MemoryContent.ContentBytes, number)) {
  390. // Tack this onto the end of the data, separated by a space
  391. newStr = IsmGetMemory (objectContent.MemoryContent.ContentSize + sizeof (TCHAR) + ByteCount (number));
  392. StringCopy(newStr, (PCTSTR)objectContent.MemoryContent.ContentBytes);
  393. StringCat(newStr, TEXT(" "));
  394. StringCat(newStr, number);
  395. IsmReleaseMemory(objectContent.MemoryContent.ContentBytes);
  396. objectContent.MemoryContent.ContentSize = SizeOfString(newStr);
  397. objectContent.MemoryContent.ContentBytes = (PCBYTE)newStr;
  398. IsmReplacePhysicalObject (g_RegType, objectName, &objectContent);
  399. }
  400. }
  401. IsmReleaseObject(&objectContent);
  402. }
  403. IsmDestroyObjectHandle(objectName);
  404. }
  405. FreeText(tmpNode);
  406. }
  407. return TRUE;
  408. }
  409. BOOL
  410. pRenameEx
  411. (
  412. IN PCTSTR OldNode,
  413. IN PCTSTR NewNode,
  414. IN PCTSTR Leaf,
  415. IN BOOL NoRestoreObject,
  416. IN PCTSTR PrevKey,
  417. IN PCTSTR FormatStr,
  418. OUT PMIG_FILTEROUTPUT OutputData,
  419. IN BOOL ZeroBase
  420. )
  421. {
  422. BOOL result = FALSE;
  423. PTSTR patternNode;
  424. PTSTR tmpNode;
  425. PTSTR ptr;
  426. PTSTR searchStr;
  427. DWORD prevKeyLen;
  428. DWORD keySize = 1;
  429. MIG_FILTERINPUT filterInput;
  430. MIG_FILTEROUTPUT filterOutput;
  431. MIG_BLOB migBlob;
  432. MIG_BLOB zeroBaseBlob;
  433. PTSTR filteredNode = NULL;
  434. // This function basically manually generates a RenRegEx rule and runs the filter
  435. // Then for each base key it updates the associated [Order] key to add the new number, if needed
  436. // Rule keys are something like:
  437. // HKR\Identities\{GUID}\Software\Microsoft\Outlook Express\5.0\Rules\Mail\000\*
  438. // HKR\Identities\{GUID}\Software\Microsoft\Outlook Express\5.0\Rules\News\008\*
  439. // HKR\Identities\{GUID}\Software\Microsoft\Outlook Express\5.0\Block Senders\Mail\Criteria\0AF\*
  440. // PrevKey is the string preceding the numbered key at the end. i.e. "Mail", "Criteria", etc
  441. tmpNode = DuplicateText(NewNode);
  442. if (tmpNode) {
  443. prevKeyLen = TcharCount(PrevKey);
  444. searchStr = AllocText(prevKeyLen + 3);
  445. if (searchStr) {
  446. _stprintf(searchStr, TEXT("\\%s\\"), PrevKey);
  447. ptr = (PTSTR)_tcsistr (tmpNode, searchStr);
  448. if (ptr) {
  449. ptr += (prevKeyLen + 2); // Advance to next portion
  450. *ptr = 0;
  451. ptr = _tcsinc(ptr);
  452. while (*ptr && *ptr != TEXT('\\')) {
  453. ptr = _tcsinc(ptr);
  454. keySize++;
  455. }
  456. patternNode = AllocText (CharCount (tmpNode) + (CharCount (FormatStr) - keySize));
  457. if (patternNode) {
  458. StringCopy(patternNode, tmpNode);
  459. StringCat(patternNode, FormatStr);
  460. StringCat(patternNode, ptr);
  461. filterInput.OriginalObject.ObjectTypeId = g_RegType;
  462. filterInput.OriginalObject.ObjectName = IsmCreateObjectHandle (OldNode, NULL);
  463. filterInput.CurrentObject.ObjectTypeId = g_RegType;
  464. filterInput.CurrentObject.ObjectName = IsmCreateObjectHandle (OldNode, NULL);
  465. migBlob.Type = BLOBTYPE_STRING;
  466. migBlob.String = IsmCreateObjectHandle (patternNode, NULL);
  467. if (ZeroBase) {
  468. zeroBaseBlob.Type = BLOBTYPE_BINARY;
  469. zeroBaseBlob.BinarySize = sizeof(PCBYTE);
  470. zeroBaseBlob.BinaryData = (PCBYTE)TRUE;
  471. FilterRenameExFilter (&filterInput, &filterOutput, NoRestoreObject, &zeroBaseBlob, &migBlob);
  472. } else {
  473. FilterRenameExFilter (&filterInput, &filterOutput, NoRestoreObject, NULL, &migBlob);
  474. }
  475. IsmDestroyObjectHandle (migBlob.String);
  476. IsmDestroyObjectHandle (filterInput.CurrentObject.ObjectName);
  477. IsmDestroyObjectHandle (filterInput.OriginalObject.ObjectName);
  478. IsmCreateObjectStringsFromHandle (filterOutput.NewObject.ObjectName, &filteredNode, NULL);
  479. IsmDestroyObjectHandle (filterOutput.NewObject.ObjectName);
  480. OutputData->NewObject.ObjectName = IsmCreateObjectHandle (filteredNode, Leaf);
  481. // If this is the root numeric key, then update the index
  482. if (0 == *ptr) {
  483. pConcatRuleIndex(filteredNode, searchStr);
  484. }
  485. FreeText (filteredNode);
  486. FreeText(patternNode);
  487. }
  488. } else {
  489. OutputData->NewObject.ObjectName = IsmCreateObjectHandle (tmpNode, Leaf);
  490. }
  491. FreeText(searchStr);
  492. } else {
  493. OutputData->NewObject.ObjectName = IsmCreateObjectHandle (tmpNode, Leaf);
  494. }
  495. FreeText(tmpNode);
  496. }
  497. return TRUE;
  498. }
  499. BOOL
  500. pRenameNewsRule
  501. (
  502. IN PCTSTR OldNode,
  503. IN PCTSTR NewNode,
  504. IN PCTSTR Leaf,
  505. IN BOOL NoRestoreObject,
  506. OUT PMIG_FILTEROUTPUT OutputData
  507. )
  508. {
  509. return pRenameEx(OldNode, NewNode, Leaf, NoRestoreObject, TEXT("News"), TEXT("<%03x>"), OutputData, TRUE);
  510. }
  511. BOOL
  512. pRenameMailRule
  513. (
  514. IN PCTSTR OldNode,
  515. IN PCTSTR NewNode,
  516. IN PCTSTR Leaf,
  517. IN BOOL NoRestoreObject,
  518. OUT PMIG_FILTEROUTPUT OutputData
  519. )
  520. {
  521. return pRenameEx(OldNode, NewNode, Leaf, NoRestoreObject, TEXT("Mail"), TEXT("<%03x>"), OutputData, TRUE);
  522. }
  523. BOOL
  524. pRenameBlockRule
  525. (
  526. IN PCTSTR OldNode,
  527. IN PCTSTR NewNode,
  528. IN PCTSTR Leaf,
  529. IN BOOL NoRestoreObject,
  530. OUT PMIG_FILTEROUTPUT OutputData
  531. )
  532. {
  533. return pRenameEx(OldNode, NewNode, Leaf, NoRestoreObject, TEXT("Criteria"), TEXT("<%03x>"), OutputData, TRUE);
  534. }
  535. BOOL
  536. pRenameAccount
  537. (
  538. IN PCTSTR OldNode,
  539. IN PCTSTR NewNode,
  540. IN PCTSTR Leaf,
  541. IN BOOL NoRestoreObject,
  542. OUT PMIG_FILTEROUTPUT OutputData
  543. )
  544. {
  545. return pRenameEx(OldNode, NewNode, Leaf, NoRestoreObject, TEXT("Accounts"), TEXT("<%08d>"), OutputData, FALSE);
  546. }
  547. BOOL
  548. WINAPI
  549. pConvertOE5RulesMove (
  550. IN PCMIG_FILTERINPUT InputData,
  551. OUT PMIG_FILTEROUTPUT OutputData,
  552. IN BOOL NoRestoreObject,
  553. IN LPRENAMERULE fnRename
  554. )
  555. {
  556. PCTSTR srcNode = NULL;
  557. PCTSTR srcLeaf = NULL;
  558. PTSTR newNode = NULL;
  559. PTSTR tmpText;
  560. TCHAR *endId;
  561. TCHAR *srcIdentity;
  562. PTSTR newIdentity;
  563. // Move tree and Merge account name
  564. // This function just changes the {GUID} to the new value, then calls fnRename to update the
  565. // numeric portion of the keyname
  566. IsmCreateObjectStringsFromHandle (InputData->CurrentObject.ObjectName, &srcNode, &srcLeaf);
  567. if (srcNode) {
  568. // srcNode should be "HKCU\Identities\{GUID}\Software\Microsoft\Outlook Express\Rules\Mail\..."
  569. tmpText = DuplicateText(srcNode);
  570. if (tmpText) {
  571. srcIdentity = _tcschr(tmpText, TEXT('{'));
  572. if (srcIdentity) {
  573. endId = _tcschr(srcIdentity, TEXT('\\'));
  574. if (endId) {
  575. *endId = 0;
  576. endId = _tcsinc(endId);
  577. // endId should be "Software\Microsoft\Outlook Express\Rules\Mail\..."
  578. // srcIdentity should be "{GUID}"
  579. newIdentity = OEGetRemappedId (srcIdentity);
  580. if (newIdentity) {
  581. newNode = JoinPathsInPoolEx ((
  582. NULL,
  583. TEXT("HKCU\\Identities"),
  584. newIdentity,
  585. endId,
  586. NULL
  587. ));
  588. if (newNode) {
  589. if (srcLeaf &&
  590. !g_OERulesMigrated &&
  591. !StringIMatch(srcLeaf, TEXT("Version"))) {
  592. g_OERulesMigrated = TRUE;
  593. }
  594. fnRename(srcNode, newNode, srcLeaf, NoRestoreObject, OutputData);
  595. FreePathString (newNode);
  596. }
  597. FreeText(newIdentity);
  598. }
  599. }
  600. }
  601. FreeText(tmpText);
  602. }
  603. IsmDestroyObjectString (srcNode);
  604. }
  605. IsmDestroyObjectString (srcLeaf);
  606. return TRUE;
  607. }
  608. BOOL
  609. WINAPI
  610. pConvertOE5NewsRulesMove (
  611. IN PCMIG_FILTERINPUT InputData,
  612. OUT PMIG_FILTEROUTPUT OutputData,
  613. IN BOOL NoRestoreObject,
  614. IN PCMIG_BLOB SourceOperationData, OPTIONAL
  615. IN PCMIG_BLOB DestinationOperationData OPTIONAL
  616. )
  617. {
  618. return pConvertOE5RulesMove(InputData, OutputData, NoRestoreObject, pRenameNewsRule);
  619. }
  620. BOOL
  621. WINAPI
  622. pConvertOE5MailRulesMove (
  623. IN PCMIG_FILTERINPUT InputData,
  624. OUT PMIG_FILTEROUTPUT OutputData,
  625. IN BOOL NoRestoreObject,
  626. IN PCMIG_BLOB SourceOperationData, OPTIONAL
  627. IN PCMIG_BLOB DestinationOperationData OPTIONAL
  628. )
  629. {
  630. return pConvertOE5RulesMove(InputData, OutputData, NoRestoreObject, pRenameMailRule);
  631. }
  632. BOOL
  633. WINAPI
  634. pConvertOE5BlockMove (
  635. IN PCMIG_FILTERINPUT InputData,
  636. OUT PMIG_FILTEROUTPUT OutputData,
  637. IN BOOL NoRestoreObject,
  638. IN PCMIG_BLOB SourceOperationData, OPTIONAL
  639. IN PCMIG_BLOB DestinationOperationData OPTIONAL
  640. )
  641. {
  642. return pConvertOE5RulesMove(InputData, OutputData, NoRestoreObject, pRenameBlockRule);
  643. }
  644. BOOL
  645. WINAPI
  646. pConvertOEIdIAMMove (
  647. IN PCMIG_FILTERINPUT InputData,
  648. OUT PMIG_FILTEROUTPUT OutputData,
  649. IN BOOL NoRestoreObject,
  650. IN PCMIG_BLOB SourceOperationData, OPTIONAL
  651. IN PCMIG_BLOB DestinationOperationData OPTIONAL
  652. )
  653. {
  654. PCTSTR srcNode = NULL;
  655. PCTSTR srcLeaf = NULL;
  656. PTSTR newNode = NULL;
  657. PTSTR tmpText;
  658. TCHAR *endId;
  659. TCHAR *srcIdentity;
  660. PTSTR newIdentity;
  661. // Move tree and Merge account name
  662. // This moves the tree in one of the following ways:
  663. // 1. From Identities into HKCU\SoftwareMicrosoft\Internet Account Manager\
  664. // 2. From one Identity into another Identity (for merging case)
  665. // 3. From one Identity into the same Identity (nop)
  666. // In all cases, then call pRenameAccount to update the name (name is actually a DWORD index value)
  667. IsmCreateObjectStringsFromHandle (InputData->CurrentObject.ObjectName, &srcNode, &srcLeaf);
  668. if (srcNode) {
  669. // srcNode should be "HKCU\Identities\{GUID}\Software\Microsoft\Internet Account Manager\..."
  670. tmpText = DuplicateText(srcNode);
  671. if (tmpText) {
  672. srcIdentity = _tcschr(tmpText, TEXT('{'));
  673. if (srcIdentity) {
  674. endId = _tcschr(srcIdentity, TEXT('\\'));
  675. if (endId) {
  676. *endId = 0;
  677. endId = _tcsinc(endId);
  678. // endId should be "Software\Microsoft\Internet Account Manager\..."
  679. // srcIdentity should be "{GUID}"
  680. newIdentity = OEGetRemappedId (srcIdentity);
  681. if (newIdentity) {
  682. if (OEIsIdentityAssociated (newIdentity)) {
  683. newNode = JoinPaths (TEXT("HKCU"), endId);
  684. // newNode should be "HKCU\Software\Microsoft\Internet Account Manager\..."
  685. } else {
  686. newNode = JoinPathsInPoolEx ((
  687. NULL,
  688. TEXT("HKCU\\Identities"),
  689. newIdentity,
  690. endId,
  691. NULL
  692. ));
  693. }
  694. if (newNode) {
  695. pRenameAccount(srcNode,
  696. newNode,
  697. srcLeaf,
  698. NoRestoreObject,
  699. OutputData);
  700. FreePathString (newNode);
  701. }
  702. FreeText(newIdentity);
  703. }
  704. }
  705. }
  706. FreeText(tmpText);
  707. }
  708. IsmDestroyObjectString (srcNode);
  709. }
  710. IsmDestroyObjectString (srcLeaf);
  711. return TRUE;
  712. }
  713. BOOL
  714. WINAPI
  715. pConvertOEIAMMove (
  716. IN PCMIG_FILTERINPUT InputData,
  717. OUT PMIG_FILTEROUTPUT OutputData,
  718. IN BOOL NoRestoreObject,
  719. IN PCMIG_BLOB SourceOperationData, OPTIONAL
  720. IN PCMIG_BLOB DestinationOperationData OPTIONAL
  721. )
  722. {
  723. PCTSTR srcNode = NULL;
  724. PCTSTR srcLeaf = NULL;
  725. PTSTR newNode = NULL;
  726. PTSTR filteredNode = NULL;
  727. PTSTR ptr = NULL;
  728. // Move tree and Merge account name
  729. // This moves the tree in one of the following ways:
  730. // 1. From HKCU\SoftwareMicrosoft\Internet Account Manager\ into an Identity
  731. // 2. From HKCU\SoftwareMicrosoft\Internet Account Manager\ into the same location (nop)
  732. // In all cases, then call pRenameAccount to update the name (name is actually a DWORD index value)
  733. // This might move the accounts from HKCU\Software\Microsoft\Internet Account Manager into an identity
  734. IsmCreateObjectStringsFromHandle (InputData->CurrentObject.ObjectName, &srcNode, &srcLeaf);
  735. if (srcNode) {
  736. // srcNode should be "HKCU\Software\Microsoft\Internet Account Manager\..."
  737. if (g_DestIdentityGUID != NULL &&
  738. !OEIsIdentityAssociated (g_DestIdentityGUID)) {
  739. ptr = _tcschr (srcNode, TEXT('\\'));
  740. if (ptr) {
  741. newNode = AllocText (TcharCount (srcNode) + TcharCount (g_DestIdentityGUID) + 13);
  742. StringCopy (newNode, TEXT("HKCU\\Identities\\")); // +12
  743. StringCat (newNode, g_DestIdentityGUID);
  744. StringCat (newNode, ptr);
  745. // newNode should be "HKCU\Identities\{GUID}\Software\Microsoft\Internet Account Manager\..."
  746. }
  747. } else {
  748. newNode = DuplicateText (srcNode);
  749. }
  750. if (newNode) {
  751. pRenameAccount(srcNode,
  752. newNode,
  753. srcLeaf,
  754. NoRestoreObject,
  755. OutputData);
  756. FreeText (newNode);
  757. }
  758. IsmDestroyObjectString (srcNode);
  759. }
  760. IsmDestroyObjectString (srcLeaf);
  761. return TRUE;
  762. }