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.

536 lines
15 KiB

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. vs_str.hxx
  5. Abstract:
  6. Various defines for general usage
  7. Author:
  8. Adi Oltean [aoltean] 07/09/1999
  9. Revision History:
  10. Name Date Comments
  11. aoltean 07/09/1999 Created
  12. aoltean 08/11/1999 Adding throw specification
  13. aoltean 09/03/1999 Adding DuplicateXXX functions
  14. aoltean 09/09/1999 dss -> vss
  15. aoltean 09/20/1999 Adding ThrowIf, Err, Msg, MsgNoCR, etc.
  16. --*/
  17. #ifndef __VSS_STR_HXX__
  18. #define __VSS_STR_HXX__
  19. #if _MSC_VER > 1000
  20. #pragma once
  21. #endif
  22. ////////////////////////////////////////////////////////////////////////
  23. // Standard foo for file name aliasing. This code block must be after
  24. // all includes of VSS header files.
  25. //
  26. #ifdef VSS_FILE_ALIAS
  27. #undef VSS_FILE_ALIAS
  28. #endif
  29. #define VSS_FILE_ALIAS "INCSTRH"
  30. //
  31. ////////////////////////////////////////////////////////////////////////
  32. /////////////////////////////////////////////////////////////////////////////
  33. // Misc string routines
  34. inline void VssDuplicateStr(
  35. OUT LPWSTR& pwszDestination,
  36. IN LPCWSTR pwszSource
  37. )
  38. {
  39. BS_ASSERT(pwszDestination == NULL);
  40. if (pwszSource == NULL)
  41. pwszDestination = NULL;
  42. else
  43. {
  44. pwszDestination = (LPWSTR)::CoTaskMemAlloc(sizeof(WCHAR)*(1 + ::wcslen(pwszSource)));
  45. if (pwszDestination != NULL)
  46. ::wcscpy(pwszDestination, pwszSource);
  47. }
  48. }
  49. inline void VssSafeDuplicateStr(
  50. IN CVssFunctionTracer& ft,
  51. OUT LPWSTR& pwszDestination,
  52. IN LPCWSTR pwszSource
  53. ) throw(HRESULT)
  54. {
  55. BS_ASSERT(pwszDestination == NULL);
  56. if (pwszSource == NULL)
  57. pwszDestination = NULL;
  58. else
  59. {
  60. pwszDestination = (LPWSTR)::CoTaskMemAlloc(sizeof(WCHAR)*(1 + ::wcslen(pwszSource)));
  61. if (pwszDestination == NULL)
  62. ft.Throw( VSSDBG_GEN, E_OUTOFMEMORY, L"Memory allocation error");
  63. ::wcscpy(pwszDestination, pwszSource);
  64. }
  65. }
  66. inline LPWSTR VssAllocString(
  67. IN CVssFunctionTracer& ft,
  68. IN size_t nStringLength
  69. )
  70. {
  71. BS_ASSERT(nStringLength > 0);
  72. LPWSTR pwszStr = reinterpret_cast<LPWSTR>(::CoTaskMemAlloc((nStringLength + 1) * sizeof(WCHAR)));
  73. if (pwszStr == NULL)
  74. ft.Throw( VSSDBG_GEN, E_OUTOFMEMORY, L"Memory allocation error");
  75. return pwszStr;
  76. }
  77. inline void VssFreeString(
  78. IN OUT LPCWSTR& pwszString
  79. )
  80. {
  81. ::CoTaskMemFree(const_cast<LPWSTR>(pwszString));
  82. pwszString = NULL;
  83. }
  84. inline LPWSTR VssReallocString(
  85. IN CVssFunctionTracer& ft,
  86. IN LPWSTR pwszString,
  87. IN LONG lNewStrLen // Without the zero character.
  88. )
  89. {
  90. LPWSTR pwszNewString = (LPWSTR)::CoTaskMemRealloc( (PVOID)(pwszString),
  91. sizeof(WCHAR) * (lNewStrLen + 1));
  92. if (pwszNewString == NULL)
  93. ft.Throw( VSSDBG_GEN, E_OUTOFMEMORY, L"Memory allocation error");
  94. return pwszNewString;
  95. }
  96. inline bool VssIsStrEqual(
  97. IN LPCWSTR wsz1,
  98. IN LPCWSTR wsz2
  99. )
  100. {
  101. if ((wsz1 == NULL) && (wsz2 == NULL))
  102. return true;
  103. if (wsz1 && wsz2 && (::wcscmp(wsz1, wsz2) == 0) )
  104. return true;
  105. return false;
  106. }
  107. inline void VssConcatenate(
  108. IN CVssFunctionTracer& ft,
  109. IN OUT LPWSTR pwszDestination,
  110. IN size_t nDestinationLength,
  111. IN LPCWSTR wszSource1,
  112. IN LPCWSTR wszSource2
  113. )
  114. {
  115. BS_ASSERT(pwszDestination);
  116. BS_ASSERT(wszSource1);
  117. BS_ASSERT(wszSource2);
  118. BS_ASSERT(nDestinationLength > 0);
  119. // Check if the buffer is passed
  120. if (::wcslen(wszSource1) + ::wcslen(wszSource2) > nDestinationLength ) {
  121. BS_ASSERT(false);
  122. ft.Throw( VSSDBG_SWPRV, E_UNEXPECTED,
  123. L"Buffer not large enough. ( %d + %d > %d )",
  124. ::wcslen(wszSource1), ::wcslen(wszSource2), nDestinationLength);
  125. }
  126. ::wcscpy(pwszDestination, wszSource1);
  127. ::wcscat(pwszDestination, wszSource2);
  128. }
  129. /////////////////////////////////////////////////////////////////////////////
  130. // Automatic auto-string class
  131. class CVssAutoPWSZ
  132. {
  133. // Constructors/destructors
  134. private:
  135. CVssAutoPWSZ(const CVssAutoPWSZ&);
  136. public:
  137. CVssAutoPWSZ(LPWSTR pwsz = NULL): m_pwsz(pwsz) {};
  138. // Automatically closes the handle
  139. ~CVssAutoPWSZ() {
  140. Clear();
  141. };
  142. // Operations
  143. public:
  144. void Allocate(size_t nCharCount) throw(HRESULT)
  145. {
  146. CVssFunctionTracer ft( VSSDBG_GEN, L"CVssAutoPWSZ::Allocate" );
  147. Clear();
  148. m_pwsz = ::VssAllocString(ft, nCharCount);
  149. }
  150. bool CopyFrom(LPCWSTR pwsz)
  151. {
  152. ::VssFreeString(m_pwsz);
  153. ::VssDuplicateStr(m_pwsz, pwsz);
  154. return (m_pwsz != NULL);
  155. }
  156. void TransferFrom(CVssAutoPWSZ& source)
  157. {
  158. Clear();
  159. m_pwsz = source.Detach();
  160. }
  161. LPWSTR Detach()
  162. {
  163. LPWSTR pwsz = m_pwsz;
  164. m_pwsz = NULL;
  165. return pwsz;
  166. }
  167. // Returns the value of the actual handle
  168. LPWSTR & GetRef() {
  169. return m_pwsz;
  170. }
  171. // Clears the contents of the auto string
  172. void Clear() {
  173. ::VssFreeString(m_pwsz);
  174. }
  175. // Returns the value of the actual handle
  176. operator LPWSTR () const {
  177. return m_pwsz;
  178. }
  179. // Returns the value of the actual handle
  180. operator LPCWSTR () const {
  181. return const_cast<LPCWSTR>(m_pwsz);
  182. }
  183. // Implementation
  184. private:
  185. LPWSTR m_pwsz;
  186. };
  187. class CVssComBSTR
  188. {
  189. public:
  190. BSTR m_str;
  191. CVssComBSTR()
  192. {
  193. m_str = NULL;
  194. }
  195. /*explicit*/ CVssComBSTR(int nSize)
  196. {
  197. m_str = ::SysAllocStringLen(NULL, nSize);
  198. if ((m_str == NULL) && (nSize != 0))
  199. throw(E_OUTOFMEMORY);
  200. }
  201. /*explicit*/ CVssComBSTR(int nSize, LPCOLESTR sz)
  202. {
  203. m_str = ::SysAllocStringLen(sz, nSize);
  204. if ((m_str == NULL) && (nSize != 0))
  205. throw(E_OUTOFMEMORY);
  206. }
  207. /*explicit*/ CVssComBSTR(LPCOLESTR pSrc)
  208. {
  209. m_str = ::SysAllocString(pSrc);
  210. if ((m_str == NULL) && (pSrc != NULL))
  211. throw(E_OUTOFMEMORY);
  212. }
  213. /*explicit*/ CVssComBSTR(const CVssComBSTR& src)
  214. {
  215. m_str = src.Copy();
  216. }
  217. /*explicit*/ CVssComBSTR(REFGUID src)
  218. {
  219. LPOLESTR szGuid;
  220. HRESULT hr = StringFromCLSID(src, &szGuid);
  221. if (hr != S_OK)
  222. throw(hr);
  223. m_str = ::SysAllocString(szGuid);
  224. CoTaskMemFree(szGuid);
  225. if (m_str == NULL)
  226. throw(E_OUTOFMEMORY);
  227. }
  228. CVssComBSTR& operator=(const CVssComBSTR& src)
  229. {
  230. if (m_str != src.m_str)
  231. {
  232. if (m_str)
  233. ::SysFreeString(m_str);
  234. m_str = src.Copy();
  235. }
  236. return *this;
  237. }
  238. CVssComBSTR& operator=(LPCOLESTR pSrc)
  239. {
  240. ::SysFreeString(m_str);
  241. m_str = ::SysAllocString(pSrc);
  242. if ((m_str == NULL) && (pSrc != NULL))
  243. throw(E_OUTOFMEMORY);
  244. return *this;
  245. }
  246. ~CVssComBSTR()
  247. {
  248. ::SysFreeString(m_str);
  249. }
  250. unsigned int Length() const
  251. {
  252. return (m_str == NULL)? 0 : SysStringLen(m_str);
  253. }
  254. operator BSTR() const
  255. {
  256. return m_str;
  257. }
  258. BSTR* operator&()
  259. {
  260. return &m_str;
  261. }
  262. BSTR Copy() const
  263. {
  264. BSTR str = ::SysAllocStringLen(m_str, ::SysStringLen(m_str));
  265. if ((str == NULL) && (m_str != NULL))
  266. throw(E_OUTOFMEMORY);
  267. return str;
  268. }
  269. HRESULT CopyTo(BSTR* pbstr)
  270. {
  271. ATLASSERT(pbstr != NULL);
  272. if (pbstr == NULL)
  273. return E_POINTER;
  274. *pbstr = ::SysAllocStringLen(m_str, ::SysStringLen(m_str));
  275. if (*pbstr == NULL)
  276. return E_OUTOFMEMORY;
  277. return S_OK;
  278. }
  279. void Attach(BSTR src)
  280. {
  281. ATLASSERT(m_str == NULL);
  282. m_str = src;
  283. }
  284. BSTR Detach()
  285. {
  286. BSTR s = m_str;
  287. m_str = NULL;
  288. return s;
  289. }
  290. void Empty()
  291. {
  292. ::SysFreeString(m_str);
  293. m_str = NULL;
  294. }
  295. bool operator!() const
  296. {
  297. return (m_str == NULL);
  298. }
  299. HRESULT Append(const CVssComBSTR& bstrSrc)
  300. {
  301. return Append(bstrSrc.m_str, SysStringLen(bstrSrc.m_str));
  302. }
  303. HRESULT Append(LPCOLESTR lpsz)
  304. {
  305. return Append(lpsz, ocslen(lpsz));
  306. }
  307. // a BSTR is just a LPCOLESTR so we need a special version to signify
  308. // that we are appending a BSTR
  309. HRESULT AppendBSTR(BSTR p)
  310. {
  311. return Append(p, SysStringLen(p));
  312. }
  313. HRESULT Append(LPCOLESTR lpsz, int nLen)
  314. {
  315. int n1 = Length();
  316. BSTR b;
  317. b = ::SysAllocStringLen(NULL, n1+nLen);
  318. if (b == NULL)
  319. return E_OUTOFMEMORY;
  320. memcpy(b, m_str, n1*sizeof(OLECHAR));
  321. memcpy(b+n1, lpsz, nLen*sizeof(OLECHAR));
  322. b[n1+nLen] = NULL;
  323. SysFreeString(m_str);
  324. m_str = b;
  325. return S_OK;
  326. }
  327. HRESULT ToLower()
  328. {
  329. USES_CONVERSION;
  330. if (m_str != NULL)
  331. {
  332. LPTSTR psz = CharLower(OLE2T(m_str));
  333. if (psz == NULL)
  334. return E_OUTOFMEMORY;
  335. BSTR b = T2BSTR(psz);
  336. if (b == NULL)
  337. return E_OUTOFMEMORY;
  338. SysFreeString(m_str);
  339. m_str = b;
  340. }
  341. return S_OK;
  342. }
  343. HRESULT ToUpper()
  344. {
  345. USES_CONVERSION;
  346. if (m_str != NULL)
  347. {
  348. LPTSTR psz = CharUpper(OLE2T(m_str));
  349. if (psz == NULL)
  350. return E_OUTOFMEMORY;
  351. BSTR b = T2BSTR(psz);
  352. if (b == NULL)
  353. return E_OUTOFMEMORY;
  354. SysFreeString(m_str);
  355. m_str = b;
  356. }
  357. return S_OK;
  358. }
  359. bool LoadString(HINSTANCE hInst, UINT nID)
  360. {
  361. USES_CONVERSION;
  362. TCHAR sz[512];
  363. UINT nLen = ::LoadString(hInst, nID, sz, 512);
  364. ATLASSERT(nLen < 511);
  365. SysFreeString(m_str);
  366. m_str = (nLen != 0) ? SysAllocString(T2OLE(sz)) : NULL;
  367. return (nLen != 0);
  368. }
  369. bool LoadString(UINT nID)
  370. {
  371. return LoadString(_pModule->m_hInstResource, nID);
  372. }
  373. CVssComBSTR& operator+=(const CVssComBSTR& bstrSrc)
  374. {
  375. AppendBSTR(bstrSrc.m_str);
  376. return *this;
  377. }
  378. bool operator<(BSTR bstrSrc) const
  379. {
  380. if (bstrSrc == NULL && m_str == NULL)
  381. return false;
  382. if (bstrSrc != NULL && m_str != NULL)
  383. return wcscmp(m_str, bstrSrc) < 0;
  384. return m_str == NULL;
  385. }
  386. bool operator!=(BSTR bstrSrc) const
  387. {
  388. return !((*this) == bstrSrc);
  389. }
  390. bool operator==(BSTR bstrSrc) const
  391. {
  392. if (bstrSrc == NULL && m_str == NULL)
  393. return true;
  394. if (bstrSrc != NULL && m_str != NULL)
  395. return wcscmp(m_str, bstrSrc) == 0;
  396. return false;
  397. }
  398. bool operator<(LPCSTR pszSrc) const
  399. {
  400. if (pszSrc == NULL && m_str == NULL)
  401. return false;
  402. USES_CONVERSION;
  403. if (pszSrc != NULL && m_str != NULL)
  404. return wcscmp(m_str, A2W(pszSrc)) < 0;
  405. return m_str == NULL;
  406. }
  407. bool operator!=(LPCSTR pszSrc) const
  408. {
  409. return !((*this) == pszSrc);
  410. }
  411. bool operator==(LPCSTR pszSrc) const
  412. {
  413. if (pszSrc == NULL && m_str == NULL)
  414. return true;
  415. USES_CONVERSION;
  416. if (pszSrc != NULL && m_str != NULL)
  417. return wcscmp(m_str, A2W(pszSrc)) == 0;
  418. return false;
  419. }
  420. #ifndef OLE2ANSI
  421. CVssComBSTR(LPCSTR pSrc)
  422. {
  423. m_str = A2WBSTR(pSrc);
  424. }
  425. CVssComBSTR(int nSize, LPCSTR sz)
  426. {
  427. m_str = A2WBSTR(sz, nSize);
  428. }
  429. void Append(LPCSTR lpsz)
  430. {
  431. USES_CONVERSION;
  432. LPCOLESTR lpo = A2COLE(lpsz);
  433. Append(lpo, ocslen(lpo));
  434. }
  435. CVssComBSTR& operator=(LPCSTR pSrc)
  436. {
  437. ::SysFreeString(m_str);
  438. m_str = A2WBSTR(pSrc);
  439. return *this;
  440. }
  441. #endif
  442. HRESULT WriteToStream(IStream* pStream)
  443. {
  444. ATLASSERT(pStream != NULL);
  445. ULONG cb;
  446. ULONG cbStrLen = m_str ? SysStringByteLen(m_str)+(ULONG)sizeof(OLECHAR) : 0;
  447. HRESULT hr = pStream->Write((void*) &cbStrLen, sizeof(cbStrLen), &cb);
  448. if (FAILED(hr))
  449. return hr;
  450. return cbStrLen ? pStream->Write((void*) m_str, cbStrLen, &cb) : S_OK;
  451. }
  452. HRESULT ReadFromStream(IStream* pStream)
  453. {
  454. ATLASSERT(pStream != NULL);
  455. ATLASSERT(m_str == NULL); // should be empty
  456. ULONG cbStrLen = 0;
  457. HRESULT hr = pStream->Read((void*) &cbStrLen, sizeof(cbStrLen), NULL);
  458. if ((hr == S_OK) && (cbStrLen != 0))
  459. {
  460. //subtract size for terminating NULL which we wrote out
  461. //since SysAllocStringByteLen overallocates for the NULL
  462. m_str = SysAllocStringByteLen(NULL, cbStrLen-sizeof(OLECHAR));
  463. if (m_str == NULL)
  464. hr = E_OUTOFMEMORY;
  465. else
  466. hr = pStream->Read((void*) m_str, cbStrLen, NULL);
  467. }
  468. if (hr == S_FALSE)
  469. hr = E_FAIL;
  470. return hr;
  471. }
  472. };
  473. #endif // __VSS_STR_HXX__