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.

573 lines
13 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1994 - 1998.
  5. //
  6. // File: pathwrap.cxx
  7. //
  8. // Contents: Utility class for thread safe set/retrieve operations on
  9. // an IADsPathname interface.
  10. //
  11. // Classes: CADsPathWrapper
  12. //
  13. // History: 08-08-1998 DavidMun Created
  14. //
  15. //---------------------------------------------------------------------------
  16. #include "headers.hxx"
  17. #pragma hdrstop
  18. DEBUG_DECLARE_INSTANCE_COUNTER(CADsPathWrapper)
  19. //+--------------------------------------------------------------------------
  20. //
  21. // Member: CADsPathWrapper::CADsPathWrapper
  22. //
  23. // Synopsis: ctor
  24. //
  25. // History: 08-08-1998 DavidMun Created
  26. //
  27. //---------------------------------------------------------------------------
  28. CADsPathWrapper::CADsPathWrapper():
  29. m_cRefs(1),
  30. m_cLocks(0)
  31. {
  32. TRACE_CONSTRUCTOR(CADsPathWrapper);
  33. DEBUG_INCREMENT_INSTANCE_COUNTER(CADsPathWrapper);
  34. HRESULT hr;
  35. // NTRAID#NTBUG9-548146-2002/02/20-lucios. Pending fix.
  36. InitializeCriticalSection(&m_cs);
  37. do
  38. {
  39. hr = m_rpADsPath.AcquireViaCreateInstance(
  40. CLSID_Pathname,
  41. NULL,
  42. CLSCTX_INPROC_SERVER,
  43. IID_IADsPathname);
  44. BREAK_ON_FAIL_HRESULT(hr);
  45. hr = m_rpADsPath->put_EscapedMode(ADS_ESCAPEDMODE_OFF);
  46. ASSERT(SUCCEEDED(hr));
  47. } while (0);
  48. }
  49. //+--------------------------------------------------------------------------
  50. //
  51. // Member: CADsPathWrapper::~CADsPathWrapper
  52. //
  53. // Synopsis: dtor
  54. //
  55. // History: 08-08-1998 DavidMun Created
  56. //
  57. //---------------------------------------------------------------------------
  58. CADsPathWrapper::~CADsPathWrapper()
  59. {
  60. TRACE_DESTRUCTOR(CADsPathWrapper);
  61. DEBUG_DECREMENT_INSTANCE_COUNTER(CADsPathWrapper);
  62. ASSERT(!m_cLocks);
  63. DeleteCriticalSection(&m_cs);
  64. }
  65. //+--------------------------------------------------------------------------
  66. //
  67. // Member: CADsPathWrapper::SetRetrieve
  68. //
  69. // Synopsis: Perform an atomic set and retrieve
  70. //
  71. // Arguments: [ulFmtIn] - ADS_SETTYPE_*
  72. // [pwzIn] - ADs path to set
  73. // [ulFmtOut] - ADS_FORMAT_*
  74. // [pbstrOut] - filled with BSTR containing new format
  75. //
  76. // Returns: HRESULT
  77. //
  78. // Modifies: *[pbstrOut]
  79. //
  80. // History: 08-08-1998 DavidMun Created
  81. //
  82. // Notes: Caller must SysFreeString(*[pbstrOut])
  83. //
  84. //---------------------------------------------------------------------------
  85. HRESULT
  86. CADsPathWrapper::SetRetrieve(
  87. ULONG ulFmtIn,
  88. PCWSTR pwzIn,
  89. ULONG ulFmtOut,
  90. BSTR *pbstrOut)
  91. {
  92. ASSERT(pwzIn);
  93. ASSERT(pbstrOut);
  94. if (!m_rpADsPath.get())
  95. {
  96. return E_FAIL;
  97. }
  98. HRESULT hr = S_OK;
  99. do
  100. {
  101. CAutoCritSec Lock(&m_cs);
  102. *pbstrOut = NULL;
  103. hr = m_rpADsPath->Set(AutoBstr(pwzIn), ulFmtIn);
  104. if (FAILED(hr))
  105. {
  106. Dbg(DEB_TRACE,
  107. "IADsPathName::Set(%ws,%#x) hr=%#x\n",
  108. pwzIn,
  109. ulFmtIn,
  110. hr);
  111. break;
  112. }
  113. hr = m_rpADsPath->Retrieve(ulFmtOut, pbstrOut);
  114. if (FAILED(hr))
  115. {
  116. Dbg(DEB_TRACE,
  117. "IADsPathName::Retrieve(%#x) hr=%#x\n",
  118. ulFmtOut,
  119. hr);
  120. break;
  121. }
  122. } while (0);
  123. return hr;
  124. }
  125. HRESULT
  126. CADsPathWrapper::SetRetrieveContainer(
  127. ULONG ulFmtIn,
  128. PCWSTR pwzIn,
  129. ULONG ulFmtOut,
  130. BSTR *pbstrOut)
  131. {
  132. if (!m_rpADsPath.get())
  133. {
  134. return E_FAIL;
  135. }
  136. HRESULT hr = S_OK;
  137. do
  138. {
  139. CAutoCritSec Lock(&m_cs);
  140. *pbstrOut = NULL;
  141. hr = m_rpADsPath->Set(AutoBstr(pwzIn), ulFmtIn);
  142. BREAK_ON_FAIL_HRESULT(hr);
  143. hr = m_rpADsPath->RemoveLeafElement();
  144. BREAK_ON_FAIL_HRESULT(hr);
  145. hr = m_rpADsPath->Retrieve(ulFmtOut, pbstrOut);
  146. BREAK_ON_FAIL_HRESULT(hr);
  147. } while (0);
  148. return hr;
  149. }
  150. #define LDAP_GC_PORT_STR L":3268"
  151. //+--------------------------------------------------------------------------
  152. //
  153. // Member: CADsPathWrapper::ConvertProvider
  154. //
  155. // Synopsis: Substitute provider string [pwzNewProvider] for the
  156. // provider in ADsPath [pstrPath].
  157. //
  158. // Arguments: [pstrPath] - points to path to modify
  159. // [pwzNewProvider] - new provider
  160. //
  161. // Returns: S_OK or E_INVALIDARG (if [pstrPath] is ill-formed)
  162. //
  163. // Modifies: *[pstrPath]
  164. //
  165. // History: 02-11-1999 DavidMun Created
  166. //
  167. //---------------------------------------------------------------------------
  168. HRESULT
  169. CADsPathWrapper::ConvertProvider(
  170. String *pstrPath,
  171. PCWSTR pwzNewProvider)
  172. {
  173. size_t idxDelim = pstrPath->find(L"://");
  174. if (idxDelim == String::npos || idxDelim == 0)
  175. {
  176. DBG_OUT_HRESULT(E_INVALIDARG);
  177. return E_INVALIDARG;
  178. }
  179. pstrPath->StringBase::replace(0, idxDelim, pwzNewProvider);
  180. //
  181. // If there's a GC port number, remove it.
  182. //
  183. idxDelim = pstrPath->find(LDAP_GC_PORT_STR);
  184. if (idxDelim != String::npos)
  185. {
  186. pstrPath->erase(idxDelim, lstrlen(LDAP_GC_PORT_STR));
  187. }
  188. return S_OK;
  189. }
  190. //+--------------------------------------------------------------------------
  191. //
  192. // Member: CADsPathWrapper::GetMostSignificantElement
  193. //
  194. // Synopsis: Return the path element closest to the provider type.
  195. //
  196. // Arguments: [pwzIn] - ADS path to set
  197. // [pbstrOut] - most significant element
  198. //
  199. // Returns: HRESULT
  200. //
  201. // Modifies: *[pbstrOut]
  202. //
  203. // History: 01-22-1999 DavidMun Created
  204. //
  205. //---------------------------------------------------------------------------
  206. HRESULT
  207. CADsPathWrapper::GetMostSignificantElement(
  208. PCWSTR pwzIn,
  209. BSTR *pbstrOut)
  210. {
  211. if (!m_rpADsPath.get())
  212. {
  213. return E_FAIL;
  214. }
  215. HRESULT hr = S_OK;
  216. do
  217. {
  218. CAutoCritSec Lock(&m_cs);
  219. *pbstrOut = NULL;
  220. hr = m_rpADsPath->Set(AutoBstr(pwzIn), ADS_SETTYPE_FULL);
  221. BREAK_ON_FAIL_HRESULT(hr);
  222. long cElements;
  223. hr = m_rpADsPath->GetNumElements(&cElements);
  224. BREAK_ON_FAIL_HRESULT(hr);
  225. ASSERT(cElements > 0);
  226. hr = m_rpADsPath->GetElement(cElements - 1, pbstrOut);
  227. BREAK_ON_FAIL_HRESULT(hr);
  228. } while (0);
  229. return hr;
  230. }
  231. HRESULT
  232. CADsPathWrapper::GetWinntPathServerName(
  233. PCWSTR pwzIn,
  234. BSTR *pbstrOut)
  235. {
  236. if (!m_rpADsPath.get())
  237. {
  238. return E_FAIL;
  239. }
  240. HRESULT hr = S_OK;
  241. do
  242. {
  243. CAutoCritSec Lock(&m_cs);
  244. *pbstrOut = NULL;
  245. hr = m_rpADsPath->Set(AutoBstr(pwzIn), ADS_SETTYPE_FULL);
  246. BREAK_ON_FAIL_HRESULT(hr);
  247. long cElements;
  248. hr = m_rpADsPath->GetNumElements(&cElements);
  249. BREAK_ON_FAIL_HRESULT(hr);
  250. ASSERT(cElements > 0);
  251. // the server name is the most significant element in some
  252. // cases, like WinNT://server/user (form 1), but not always, as in
  253. // WinNT://workgroup/server/user or WinNT://domain/server/user (form 2)
  254. // Not astonishingly, given the all-around badness of
  255. // IADsPathname, the server format returns the domain name for form
  256. // (2) paths, and the server name for form (1) paths. And the 1st
  257. // element of the path after the provider name is unreachable
  258. // except with Retrieve!
  259. if (cElements >= 2)
  260. {
  261. // form 2 name, so get the next-to-last element
  262. hr = m_rpADsPath->GetElement(1, pbstrOut);
  263. BREAK_ON_FAIL_HRESULT(hr);
  264. }
  265. else
  266. {
  267. // form 1 name
  268. hr = m_rpADsPath->Retrieve(ADS_FORMAT_SERVER, pbstrOut);
  269. BREAK_ON_FAIL_HRESULT(hr);
  270. }
  271. } while (0);
  272. return hr;
  273. }
  274. HRESULT
  275. CADsPathWrapper::GetWinntPathRDN(
  276. PCWSTR pwzIn,
  277. String *pstrRDN)
  278. {
  279. if(!pwzIn || !pstrRDN)
  280. return E_POINTER;
  281. if (!m_rpADsPath.get())
  282. {
  283. return E_FAIL;
  284. }
  285. HRESULT hr = S_OK;
  286. do
  287. {
  288. CAutoCritSec Lock(&m_cs);
  289. pstrRDN->erase();
  290. hr = m_rpADsPath->Set(AutoBstr(pwzIn), ADS_SETTYPE_FULL);
  291. BREAK_ON_FAIL_HRESULT(hr);
  292. long cElements;
  293. hr = m_rpADsPath->GetNumElements(&cElements);
  294. BREAK_ON_FAIL_HRESULT(hr);
  295. ASSERT(cElements > 0);
  296. // path can have following format. (form1) WinNT://servername
  297. // (form2) WinNT://server/user,
  298. // (form3) WinNT://workgroup/server/user or WinNT://domain/server/user
  299. // In form1 there is no rdn while in 2 and 3 least significant element is
  300. // RDN
  301. if (cElements >= 2)
  302. {
  303. // form 2 or 3 name, so get the last element
  304. BSTR bstr;
  305. hr = m_rpADsPath->GetElement(0, &bstr);
  306. BREAK_ON_FAIL_HRESULT(hr);
  307. *pstrRDN = bstr;
  308. SysFreeString(bstr);
  309. }
  310. } while (0);
  311. return hr;
  312. }
  313. //+--------------------------------------------------------------------------
  314. //
  315. // Member: CADsPathWrapper::Set
  316. //
  317. // Synopsis: Wrap IADsPathname::Set.
  318. //
  319. // History: 3-12-1999 DavidMun Created
  320. //
  321. //---------------------------------------------------------------------------
  322. HRESULT
  323. CADsPathWrapper::Set(
  324. PCWSTR pwzPath,
  325. long lSetType)
  326. {
  327. //TRACE_METHOD(CADsPathWrapper, Set);
  328. ASSERT(m_cLocks);
  329. if (!m_rpADsPath.get())
  330. {
  331. return E_FAIL;
  332. }
  333. return m_rpADsPath->Set(AutoBstr(pwzPath), lSetType);
  334. }
  335. //+--------------------------------------------------------------------------
  336. //
  337. // Member: CADsPathWrapper::GetNumElements
  338. //
  339. // Synopsis: Wrap IADsPathname::GetNumElements.
  340. //
  341. // History: 3-12-1999 DavidMun Created
  342. //
  343. //---------------------------------------------------------------------------
  344. HRESULT
  345. CADsPathWrapper::GetNumElements(
  346. long *pcElem)
  347. {
  348. //TRACE_METHOD(CADsPathWrapper, GetNumElements);
  349. ASSERT(m_cLocks);
  350. if (!m_rpADsPath.get())
  351. {
  352. return E_FAIL;
  353. }
  354. return m_rpADsPath->GetNumElements(pcElem);
  355. }
  356. //+--------------------------------------------------------------------------
  357. //
  358. // Member: CADsPathWrapper::Escape
  359. //
  360. // Synopsis: Escape name element [pwzIn].
  361. //
  362. // Arguments: [pwzIn] - element to escape
  363. // [pbstrOut] - filled with BSTR containing escaped element
  364. //
  365. // Returns: HRESULT
  366. //
  367. // Modifies: *[pbstrOut]
  368. //
  369. // History: 5-04-1999 davidmun Created
  370. //
  371. // Notes: Caller must call SysFreeString on returned BSTR.
  372. //
  373. //---------------------------------------------------------------------------
  374. HRESULT
  375. CADsPathWrapper::Escape(
  376. PCWSTR pwzIn,
  377. BSTR *pbstrOut)
  378. {
  379. HRESULT hr = S_OK;
  380. do
  381. {
  382. if (!m_rpADsPath.get())
  383. {
  384. hr = E_FAIL;
  385. DBG_OUT_HRESULT(hr);
  386. break;
  387. }
  388. CAutoCritSec Lock(&m_cs);
  389. hr = m_rpADsPath->Set(AutoBstr(L"LDAP"), ADS_SETTYPE_PROVIDER);
  390. BREAK_ON_FAIL_HRESULT(hr);
  391. hr = m_rpADsPath->GetEscapedElement(0, AutoBstr(pwzIn), pbstrOut);
  392. CHECK_HRESULT(hr);
  393. } while (0);
  394. return hr;
  395. }
  396. //+--------------------------------------------------------------------------
  397. //
  398. // Member: CADsPathWrapper::GetElement
  399. //
  400. // Synopsis: Wrap IADsPathname::GetElement.
  401. //
  402. // History: 3-12-1999 DavidMun Created
  403. //
  404. //---------------------------------------------------------------------------
  405. HRESULT
  406. CADsPathWrapper::GetElement(
  407. long idxElem,
  408. BSTR *pbstrElem)
  409. {
  410. //TRACE_METHOD(CADsPathWrapper, GetElement);
  411. ASSERT(m_cLocks);
  412. if (!m_rpADsPath.get())
  413. {
  414. return E_FAIL;
  415. }
  416. return m_rpADsPath->GetElement(idxElem, pbstrElem);
  417. }
  418. //+--------------------------------------------------------------------------
  419. //
  420. // Member: CADsPathWrapper::RemoveLeafElement
  421. //
  422. // Synopsis: Wrap IADsPathname::RemoveLeafElement.
  423. //
  424. // History: 3-12-1999 DavidMun Created
  425. //
  426. //---------------------------------------------------------------------------
  427. HRESULT
  428. CADsPathWrapper::RemoveLeafElement()
  429. {
  430. //TRACE_METHOD(CADsPathWrapper, RemoveLeafElement);
  431. ASSERT(m_cLocks);
  432. if (!m_rpADsPath.get())
  433. {
  434. return E_FAIL;
  435. }
  436. return m_rpADsPath->RemoveLeafElement();
  437. }