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.

352 lines
7.9 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1994 - 1998.
  5. //
  6. // File: row.cxx
  7. //
  8. // Contents: Implementation of class to fetch rows from an adsi query
  9. //
  10. // Classes: CRow
  11. //
  12. // History: 03-30-1998 DavidMun Created
  13. //
  14. //---------------------------------------------------------------------------
  15. #include "headers.hxx"
  16. #pragma hdrstop
  17. DEBUG_DECLARE_INSTANCE_COUNTER(CRow)
  18. //+--------------------------------------------------------------------------
  19. //
  20. // Member: CRow::CRow
  21. //
  22. // Synopsis: ctor
  23. //
  24. // History: 03-26-1998 DavidMun Created
  25. //
  26. //---------------------------------------------------------------------------
  27. CRow::CRow(
  28. HWND hwndParent,
  29. const CObjectPicker &rop,
  30. IDirectorySearch *pDirSearch,
  31. const String &strQuery,
  32. const AttrKeyVector &rvakAttrToRead):
  33. #if (DBG == 1)
  34. m_fFirstRow(TRUE),
  35. #endif
  36. m_rop(rop),
  37. m_hwndParent(hwndParent),
  38. m_hSearch(NULL),
  39. m_pDirSearch(pDirSearch),
  40. m_strQuery(strQuery),
  41. m_vakAttrToRead(rvakAttrToRead)
  42. {
  43. TRACE_CONSTRUCTOR(CRow);
  44. DEBUG_INCREMENT_INSTANCE_COUNTER(CRow);
  45. ASSERT(pDirSearch);
  46. ASSERT(!strQuery.empty());
  47. ASSERT(!rvakAttrToRead.empty());
  48. ASSERT(rvakAttrToRead.end() ==
  49. find(rvakAttrToRead.begin(), rvakAttrToRead.end(), AK_INVALID));
  50. pDirSearch->AddRef();
  51. }
  52. //+--------------------------------------------------------------------------
  53. //
  54. // Member: CRow::~CRow
  55. //
  56. // Synopsis: dtor
  57. //
  58. // History: 03-26-1998 DavidMun Created
  59. //
  60. //---------------------------------------------------------------------------
  61. CRow::~CRow()
  62. {
  63. TRACE_DESTRUCTOR(CRow);
  64. DEBUG_DECREMENT_INSTANCE_COUNTER(CRow);
  65. if (m_pDirSearch)
  66. {
  67. if (m_hSearch)
  68. {
  69. TIMER("Abandoning search and closing search handle");
  70. m_pDirSearch->AbandonSearch(m_hSearch);
  71. m_pDirSearch->CloseSearchHandle(m_hSearch);
  72. m_hSearch = NULL;
  73. }
  74. m_pDirSearch->Release();
  75. m_pDirSearch = NULL;
  76. }
  77. }
  78. //+--------------------------------------------------------------------------
  79. //
  80. // Member: CRow::Next
  81. //
  82. // Synopsis: Read the next row returned by the query.
  83. //
  84. // Returns: HRESULT
  85. //
  86. // History: 06-22-2000 DavidMun Created
  87. //
  88. //---------------------------------------------------------------------------
  89. HRESULT
  90. CRow::Next()
  91. {
  92. DBG_INDENTER;
  93. HRESULT hr = S_OK;
  94. const CAttributeManager &ram = m_rop.GetAttributeManager();
  95. ULONG i;
  96. do
  97. {
  98. //
  99. // Should have the search interface from Init
  100. //
  101. if (!m_pDirSearch)
  102. {
  103. hr = E_UNEXPECTED;
  104. Dbg(DEB_ERROR, "CRow::Next called but m_pDirSearch NULL\n");
  105. BREAK_ON_FAIL_HRESULT(hr);
  106. }
  107. //
  108. // If the search hasn't been started, do so
  109. //
  110. if (!m_hSearch)
  111. {
  112. ASSERT(m_pDirSearch);
  113. ASSERT(m_strQuery.length());
  114. DBG_DUMP_QUERY("Executing Search:", m_strQuery.c_str());
  115. //
  116. // ExecuteSearch wants an array of pointers to strings, where
  117. // each string is the name of an attribute to fetch. Each of these
  118. // forms a column of the returned row.
  119. //
  120. PWSTR *apwzAttrs = new PWSTR[m_vakAttrToRead.size()];
  121. for (i = 0; i < m_vakAttrToRead.size(); i++)
  122. {
  123. apwzAttrs[i] =
  124. const_cast<PWSTR>(ram.GetAttrAdsiName(m_vakAttrToRead[i]).c_str());
  125. }
  126. hr = m_pDirSearch->ExecuteSearch(const_cast<PWSTR>(m_strQuery.c_str()),
  127. apwzAttrs,
  128. static_cast<DWORD>(m_vakAttrToRead.size()),
  129. &m_hSearch);
  130. delete [] apwzAttrs;
  131. BREAK_ON_FAIL_HRESULT(hr);
  132. ASSERT(m_hSearch);
  133. }
  134. //
  135. // Get the next row
  136. //
  137. m_AttrValueMap.clear();
  138. #if (DBG == 1)
  139. CTimer *pTimer = NULL;
  140. if (m_fFirstRow)
  141. {
  142. pTimer = new CTimer;
  143. pTimer->Init("First call to GetNextRow");
  144. }
  145. #endif
  146. hr = m_pDirSearch->GetNextRow(m_hSearch);
  147. #if (DBG == 1)
  148. if (m_fFirstRow)
  149. {
  150. delete pTimer;
  151. pTimer = NULL;
  152. m_fFirstRow = FALSE;
  153. }
  154. #endif
  155. BREAK_ON_FAIL_HRESULT(hr);
  156. if (hr == S_ADS_NOMORE_ROWS)
  157. {
  158. break;
  159. }
  160. //
  161. // Now put all the columns of the row into our variant vector
  162. //
  163. AttrKeyVector::const_iterator it;
  164. for (it = m_vakAttrToRead.begin();
  165. it != m_vakAttrToRead.end();
  166. it++)
  167. {
  168. ADS_SEARCH_COLUMN Col;
  169. ZeroMemory(&Col, sizeof Col);
  170. hr = m_pDirSearch->GetColumn(m_hSearch,
  171. const_cast<PWSTR>(ram.GetAttrAdsiName(*it).c_str()),
  172. &Col);
  173. if (SUCCEEDED(hr))
  174. {
  175. Variant varFromCol = Col;
  176. m_AttrValueMap[*it] = varFromCol;
  177. hr = m_pDirSearch->FreeColumn(&Col);
  178. CHECK_HRESULT(hr);
  179. }
  180. else
  181. {
  182. hr = S_OK; // failure to get a particular column is not fatal
  183. }
  184. }
  185. }
  186. while (0);
  187. return hr;
  188. }
  189. //+--------------------------------------------------------------------------
  190. //
  191. // Member: CRow::GetColumnStr
  192. //
  193. // Synopsis: Return the string type attribute identified by [ak] from
  194. // the current row
  195. //
  196. // Arguments: [ak] - identifies attribute to fetch
  197. //
  198. // Returns: String attribute value, NULL if not found
  199. //
  200. // History: 06-22-2000 DavidMun Created
  201. //
  202. //---------------------------------------------------------------------------
  203. PCWSTR
  204. CRow::GetColumnStr(
  205. ATTR_KEY ak) const
  206. {
  207. AttrValueMap::const_iterator it;
  208. it = m_AttrValueMap.find(ak);
  209. if (it == m_AttrValueMap.end())
  210. {
  211. return NULL;
  212. }
  213. const Variant &rvar = it->second;
  214. if (rvar.Type() != VT_BSTR)
  215. {
  216. ASSERT(rvar.Empty());
  217. if (!rvar.Empty())
  218. {
  219. Dbg(DEB_ERROR,
  220. "CRow::GetColumnStr: error vt=%uL, expected VT_BSTR or VT_EMPTY\n",
  221. rvar.Type());
  222. }
  223. return NULL;
  224. }
  225. return rvar.GetBstr();
  226. }
  227. PSID
  228. CRow::GetObjectSid()
  229. {
  230. AttrValueMap::iterator it;
  231. it = m_AttrValueMap.find(AK_OBJECT_SID);
  232. if (it == m_AttrValueMap.end())
  233. {
  234. return NULL;
  235. }
  236. Variant &rvar = it->second;
  237. if (rvar.Type() != (VT_ARRAY | VT_UI1))
  238. {
  239. ASSERT(rvar.Empty());
  240. if (!rvar.Empty())
  241. {
  242. Dbg(DEB_ERROR,
  243. "CRow::GetObjectSid: error vt=%uL, expected (VT_ARRAY | VT_UI1) or VT_EMPTY\n",
  244. rvar.Type());
  245. }
  246. return NULL;
  247. }
  248. PSID pSid = NULL;
  249. rvar.SafeArrayAccessData(&pSid);
  250. return pSid;
  251. }
  252. //+--------------------------------------------------------------------------
  253. //
  254. // Member: CRow::GetColumnInt
  255. //
  256. // Synopsis: Return the integer type attribute identified by [ak] from
  257. // the current row.
  258. //
  259. // Arguments: [ak] - identifies the attribute to fetch
  260. //
  261. // Returns: Integer attribute value, or 0 if not found
  262. //
  263. // History: 06-22-2000 DavidMun Created
  264. //
  265. //---------------------------------------------------------------------------
  266. ULONG
  267. CRow::GetColumnInt(
  268. ATTR_KEY ak) const
  269. {
  270. AttrValueMap::const_iterator it;
  271. it = m_AttrValueMap.find(ak);
  272. if (it == m_AttrValueMap.end())
  273. {
  274. return NULL;
  275. }
  276. const Variant &rvar = it->second;
  277. if (rvar.Empty())
  278. {
  279. return 0;
  280. }
  281. ASSERT(rvar.Type() == VT_UI4);
  282. return V_UI4(&rvar);
  283. }