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.

252 lines
5.4 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. //#define ARRAY_LEN(A) (sizeof(A)/sizeof((A)[0]))
  35. inline void VssDuplicateStr(
  36. OUT LPWSTR& pwszDestination,
  37. IN LPCWSTR pwszSource
  38. )
  39. {
  40. BS_ASSERT(pwszDestination == NULL);
  41. if (pwszSource == NULL)
  42. pwszDestination = NULL;
  43. else
  44. {
  45. pwszDestination = (LPWSTR)::CoTaskMemAlloc(sizeof(WCHAR)*(1 + ::wcslen(pwszSource)));
  46. if (pwszDestination != NULL)
  47. ::wcscpy(pwszDestination, pwszSource);
  48. }
  49. }
  50. inline void VssSafeDuplicateStr(
  51. IN CVssFunctionTracer& ft,
  52. OUT LPWSTR& pwszDestination,
  53. IN LPCWSTR pwszSource
  54. ) throw(HRESULT)
  55. {
  56. BS_ASSERT(pwszDestination == NULL);
  57. if (pwszSource == NULL)
  58. pwszDestination = NULL;
  59. else
  60. {
  61. pwszDestination = (LPWSTR)::CoTaskMemAlloc(sizeof(WCHAR)*(1 + ::wcslen(pwszSource)));
  62. if (pwszDestination == NULL)
  63. ft.Throw( VSSDBG_GEN, E_OUTOFMEMORY, L"Memory allocation error");
  64. ::wcscpy(pwszDestination, pwszSource);
  65. }
  66. }
  67. inline LPWSTR VssAllocString(
  68. IN CVssFunctionTracer& ft,
  69. IN size_t nStringLength
  70. )
  71. {
  72. BS_ASSERT(nStringLength > 0);
  73. LPWSTR pwszStr = reinterpret_cast<LPWSTR>(::CoTaskMemAlloc((nStringLength + 1) * sizeof(WCHAR)));
  74. if (pwszStr == NULL)
  75. ft.Throw( VSSDBG_GEN, E_OUTOFMEMORY, L"Memory allocation error");
  76. return pwszStr;
  77. }
  78. inline void VssFreeString(
  79. IN OUT LPCWSTR& pwszString
  80. )
  81. {
  82. ::CoTaskMemFree(const_cast<LPWSTR>(pwszString));
  83. pwszString = NULL;
  84. }
  85. inline LPWSTR VssReallocString(
  86. IN CVssFunctionTracer& ft,
  87. IN LPWSTR pwszString,
  88. IN LONG lNewStrLen // Without the zero character.
  89. )
  90. {
  91. LPWSTR pwszNewString = (LPWSTR)::CoTaskMemRealloc( (PVOID)(pwszString),
  92. sizeof(WCHAR) * (lNewStrLen + 1));
  93. if (pwszNewString == NULL)
  94. ft.Throw( VSSDBG_GEN, E_OUTOFMEMORY, L"Memory allocation error");
  95. return pwszNewString;
  96. }
  97. inline bool VssIsStrEqual(
  98. IN LPCWSTR wsz1,
  99. IN LPCWSTR wsz2
  100. )
  101. {
  102. if ((wsz1 == NULL) && (wsz2 == NULL))
  103. return true;
  104. if (wsz1 && wsz2 && (::wcscmp(wsz1, wsz2) == 0) )
  105. return true;
  106. return false;
  107. }
  108. inline void VssConcatenate(
  109. IN CVssFunctionTracer& ft,
  110. IN OUT LPWSTR pwszDestination,
  111. IN size_t nDestinationLength,
  112. IN LPCWSTR wszSource1,
  113. IN LPCWSTR wszSource2
  114. )
  115. {
  116. BS_ASSERT(pwszDestination);
  117. BS_ASSERT(wszSource1);
  118. BS_ASSERT(wszSource2);
  119. BS_ASSERT(nDestinationLength > 0);
  120. // Check if the buffer is passed
  121. if (::wcslen(wszSource1) + ::wcslen(wszSource2) > nDestinationLength ) {
  122. BS_ASSERT(false);
  123. ft.Throw( VSSDBG_SWPRV, E_UNEXPECTED,
  124. L"Buffer not large enough. ( %d + %d > %d )",
  125. ::wcslen(wszSource1), ::wcslen(wszSource2), nDestinationLength);
  126. }
  127. ::wcscpy(pwszDestination, wszSource1);
  128. ::wcscat(pwszDestination, wszSource2);
  129. }
  130. /////////////////////////////////////////////////////////////////////////////
  131. // Automatic auto-string class
  132. class CVssAutoPWSZ
  133. {
  134. // Constructors/destructors
  135. private:
  136. CVssAutoPWSZ(const CVssAutoPWSZ&);
  137. public:
  138. CVssAutoPWSZ(LPWSTR pwsz = NULL): m_pwsz(pwsz) {};
  139. // Automatically closes the handle
  140. ~CVssAutoPWSZ() {
  141. Clear();
  142. };
  143. // Operations
  144. public:
  145. void Allocate(size_t nCharCount) throw(HRESULT)
  146. {
  147. CVssFunctionTracer ft( VSSDBG_GEN, L"CVssAutoPWSZ::Allocate" );
  148. Clear();
  149. m_pwsz = ::VssAllocString(ft, nCharCount);
  150. }
  151. bool CopyFrom(LPCWSTR pwsz)
  152. {
  153. ::VssFreeString(m_pwsz);
  154. ::VssDuplicateStr(m_pwsz, pwsz);
  155. return (m_pwsz != NULL);
  156. }
  157. void TransferFrom(CVssAutoPWSZ& source)
  158. {
  159. Clear();
  160. m_pwsz = source.Detach();
  161. }
  162. void Attach(LPWSTR pwsz)
  163. {
  164. Clear();
  165. m_pwsz = pwsz;
  166. }
  167. LPWSTR Detach()
  168. {
  169. LPWSTR pwsz = m_pwsz;
  170. m_pwsz = NULL;
  171. return pwsz;
  172. }
  173. // Returns the value of the actual handle
  174. LPWSTR & GetRef() {
  175. return m_pwsz;
  176. }
  177. // Clears the contents of the auto string
  178. void Clear() {
  179. ::VssFreeString(m_pwsz);
  180. }
  181. // Returns the value of the actual handle
  182. operator LPWSTR () const {
  183. return m_pwsz;
  184. }
  185. // Returns the value of the actual handle
  186. operator LPCWSTR () const {
  187. return const_cast<LPCWSTR>(m_pwsz);
  188. }
  189. // Implementation
  190. private:
  191. LPWSTR m_pwsz;
  192. };
  193. #endif // __VSS_STR_HXX__