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.

262 lines
6.7 KiB

  1. // Active Directory Display Specifier Upgrade Tool
  2. //
  3. // Copyright (c) 2001 Microsoft Corporation
  4. //
  5. // class Repairer
  6. //
  7. // keeps a list of the localeIds to be extracted from the dcpromo.csv file,
  8. // and a list of operations to be represented in an LDIF file.
  9. //
  10. // 7 Mar 2001 sburns
  11. #include "headers.hxx"
  12. #include "Repairer.hpp"
  13. // // // make sure that the ldif operations are executed in advance of the csv
  14. // // // operations. this is so the object creates will not conflict with object
  15. // // // deletes
  16. Repairer::Repairer(
  17. const String& dcpromoCsvFilePath_)
  18. :
  19. dcpromoCsvFilePath(dcpromoCsvFilePath_)
  20. {
  21. LOG_CTOR(Repairer);
  22. ASSERT(!dcpromoCsvFilePath.empty());
  23. }
  24. bool
  25. Repairer::IsLocaleInObjectsToCreateTable(int localeId) const
  26. {
  27. LOG_FUNCTION2(
  28. Repairer::IsLocaleInObjectsToCreateTable,
  29. String::format(L"%1!d!", localeId));
  30. ASSERT(localeId);
  31. bool result = false;
  32. for (
  33. LocaleIdObjectNamePairList::iterator i = objectsToCreate.begin();
  34. i != objectsToCreate.end();
  35. ++i)
  36. {
  37. if (i->first == localeId)
  38. {
  39. result = true;
  40. break;
  41. }
  42. }
  43. LOG_BOOL(result);
  44. return result;
  45. }
  46. void
  47. Repairer::AddCreateContainerWorkItem(int localeId)
  48. {
  49. LOG_FUNCTION2(
  50. Repairer::AddCreateContainerWorkItem,
  51. String::format(L"%1!d!", localeId));
  52. ASSERT(localeId);
  53. do
  54. {
  55. LocaleIdList::iterator i =
  56. std::find(
  57. containersToCreate.begin(),
  58. containersToCreate.end(),
  59. localeId);
  60. if (i != containersToCreate.end())
  61. {
  62. // The locale should not already be in the list, since each locale
  63. // container is evaluated only once.
  64. LOG(L"locale already in list");
  65. ASSERT(false);
  66. break;
  67. }
  68. if (IsLocaleInObjectsToCreateTable(localeId))
  69. {
  70. // We don't expect any entries for this locale to be present in the
  71. // objects-to-create list, because the containers are evaluated first.
  72. LOG(L"objects for locale already in object list");
  73. ASSERT(false);
  74. // CODEWORK: we should handle this situation anyway, just for
  75. // robustness' sake. To deal with it, all entires in the objects-
  76. // to-create list for this locale id should be removed.
  77. break;
  78. }
  79. containersToCreate.push_back(localeId);
  80. }
  81. while (0);
  82. }
  83. void
  84. Repairer::AddCreateObjectWorkItem(
  85. int localeId,
  86. const String& displaySpecifierObjectName)
  87. {
  88. LOG_FUNCTION2(
  89. Repairer::AddCreateObjectWorkItem,
  90. String::format(
  91. L"%1!d! %2", localeId, displaySpecifierObjectName.c_str()));
  92. ASSERT(localeId);
  93. ASSERT(!displaySpecifierObjectName.empty());
  94. do
  95. {
  96. LocaleIdList::iterator i =
  97. std::find(
  98. containersToCreate.begin(),
  99. containersToCreate.end(),
  100. localeId);
  101. if (i != containersToCreate.end())
  102. {
  103. // The locale is already in the containers-to-create list, which
  104. // we don't expect, since if the container does not exist, we should
  105. // not be evaluating which objects should be created in that container.
  106. ASSERT(false);
  107. // do nothing, as the object will be created as part of the container
  108. // creation.
  109. break;
  110. }
  111. LocaleIdObjectNamePair p(localeId, displaySpecifierObjectName);
  112. LocaleIdObjectNamePairList::iterator j =
  113. std::find(
  114. objectsToCreate.begin(),
  115. objectsToCreate.end(),
  116. p);
  117. if (j != objectsToCreate.end())
  118. {
  119. // The object is already in the list. We don't expect this, since
  120. // each object should be evaluated only once per locale.
  121. ASSERT(false);
  122. // do nothing, if the object is already present, then fine.
  123. break;
  124. }
  125. objectsToCreate.push_back(p);
  126. }
  127. while (0);
  128. }
  129. void
  130. Repairer::AddDeleteObjectWorkItem(
  131. int localeId,
  132. const String& displaySpecifierObjectName)
  133. {
  134. //CODEWORK:
  135. //lucios: Inserted to remove link error
  136. localeId++;
  137. String x=displaySpecifierObjectName;
  138. }
  139. HRESULT
  140. Repairer::BuildRepairFiles()
  141. {
  142. LOG_FUNCTION(Repairer::BuildRepairFiles);
  143. HRESULT hr = S_OK;
  144. // CODEWORK
  145. // csv file:
  146. //
  147. // create a (temp) file
  148. // copy out the first line of the dcpromo.csv file (the column labels)
  149. // for each localeid in the list
  150. // copy out all of the lines in the dcpromo.csv file for that locale
  151. // for each <localeid, objectname> entry
  152. // copy out that line from the dcpromo.csv file
  153. //
  154. // ldif file:
  155. LOG_HRESULT(hr);
  156. return hr;
  157. }
  158. HRESULT
  159. Repairer::ApplyRepairs()
  160. {
  161. LOG_FUNCTION(Repairer::ApplyRepairs);
  162. HRESULT hr = S_OK;
  163. // CODEWORK: needs finishing
  164. LOG_HRESULT(hr);
  165. return hr;
  166. }
  167. // could have gone with a architecture like:
  168. //
  169. // repairer.workQueue.Add(new CreateContainerWorkItem(localeId));
  170. //
  171. // but while that certainly seems more OO, more "extensible" because new work
  172. // item types could be derived. Upon further thought, it seems like a worse
  173. // solution to me, since there are them lots of trivial classes involved, and
  174. // the coordination of those classes becomes a real nuisance. Once all the
  175. // work items are collected, who's responsible for translating them into the
  176. // csv/ldif files? It would have to be an additional manager class. The
  177. // extensibility turns out to be an illusion, since adding a new work item
  178. // type requires modifying the manager class. So the added complexity buys
  179. // nothing.
  180. //
  181. // The other design choice was whether to make the Repairer a "static class"
  182. // -- my name for a class that is really a namespace, which instead of members
  183. // uses static data that is hidden in a single translation unit as though it
  184. // were private class data. This is a technique that makes the private data
  185. // truly secret, as there is no mention of the data in the header declaration
  186. // for the class at all. It also is a nice way to implement the Singleton
  187. // pattern: there are no instances, and therefore no need to worry about
  188. // constructors, destructors, assignment, stack or heap allocation, no
  189. // "GetInstance" methods, and no lifetime issues.
  190. //
  191. // The technique gives a slightly nicer syntax as:
  192. //
  193. // Repairer::AddCreateContainerWorkItem(localeId)
  194. //
  195. // as opposed to
  196. //
  197. // Repairer::GetInstance()->AddCreateContainerWorkItem(localeId);
  198. //
  199. // I decided to go with a real, fully-contained object implementation, instead
  200. // of a singleton, thinking that maybe someday multiple instances could be
  201. // repairing multiple forests at once. Not likely, but why not?