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.

303 lines
7.2 KiB

  1. //****************************************************************************
  2. //
  3. // BLClient sample for Microsoft Messenger SDK
  4. //
  5. // Module: BLClient.exe
  6. // File: clUtil.cpp
  7. // Content: Usefull clases for COM and Connection points
  8. //
  9. //
  10. // Copyright (c) Microsoft Corporation 1997-1998
  11. //
  12. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  13. // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  14. // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  15. // PARTICULAR PURPOSE.
  16. //****************************************************************************
  17. #include "pch.hxx"
  18. #include "clUtil.h"
  19. #include <instance.h>
  20. #include "demand.h"
  21. #define ASSERT _ASSERTE
  22. //****************************************************************************
  23. //
  24. // CLASS RefCount
  25. //
  26. //****************************************************************************
  27. //****************************************************************************
  28. //
  29. // Constructor
  30. //
  31. //****************************************************************************
  32. RefCount::RefCount(void)
  33. {
  34. m_cRef = 1;
  35. Assert(NULL != g_pInstance);
  36. CoIncrementInit("RefCount::RefCount", MSOEAPI_START_SHOWERRORS, NULL, NULL);
  37. }
  38. //****************************************************************************
  39. //
  40. // Destructor
  41. //
  42. //****************************************************************************
  43. RefCount::~RefCount(void)
  44. {
  45. CoDecrementInit("RefCount::RefCount", NULL);
  46. }
  47. //****************************************************************************
  48. //
  49. // ULONG STDMETHODCALLTYPE RefCount::AddRef(void)
  50. //
  51. //****************************************************************************
  52. ULONG STDMETHODCALLTYPE RefCount::AddRef(void)
  53. {
  54. ASSERT(m_cRef >= 0);
  55. InterlockedIncrement(&m_cRef);
  56. return (ULONG) m_cRef;
  57. }
  58. //****************************************************************************
  59. //
  60. // ULONG STDMETHODCALLTYPE RefCount::Release(void)
  61. //
  62. //****************************************************************************
  63. ULONG STDMETHODCALLTYPE RefCount::Release(void)
  64. {
  65. if (0 == InterlockedDecrement(&m_cRef))
  66. {
  67. delete this;
  68. return 0;
  69. }
  70. ASSERT(m_cRef > 0);
  71. return (ULONG) m_cRef;
  72. }
  73. //****************************************************************************
  74. //
  75. // CLASS CNotify
  76. //
  77. //****************************************************************************
  78. //****************************************************************************
  79. //
  80. // Constructor
  81. //
  82. //****************************************************************************
  83. CNotify::CNotify() :
  84. m_pcnpcnt(NULL),
  85. m_pcnp(NULL),
  86. m_dwCookie(0),
  87. m_pUnk(NULL)
  88. {
  89. }
  90. //****************************************************************************
  91. //
  92. // destructor
  93. //
  94. //****************************************************************************
  95. CNotify::~CNotify()
  96. {
  97. Disconnect(); // Make sure we're disconnected
  98. }
  99. //****************************************************************************
  100. //
  101. // HRESULT CNotify::Connect(IUnknown *pUnk, REFIID riid, IUnknown *pUnkN)
  102. //
  103. // Connects the sink to the container
  104. //
  105. //****************************************************************************
  106. HRESULT CNotify::Connect(IUnknown *pUnk, REFIID riid, IUnknown *pUnkN)
  107. {
  108. HRESULT hr;
  109. ASSERT(0 == m_dwCookie);
  110. // Get the connection container
  111. hr = pUnk->QueryInterface(IID_IConnectionPointContainer, (void **)&m_pcnpcnt);
  112. if (SUCCEEDED(hr))
  113. {
  114. // Find an appropriate connection point
  115. hr = m_pcnpcnt->FindConnectionPoint(riid, &m_pcnp);
  116. if (SUCCEEDED(hr))
  117. {
  118. ASSERT(NULL != m_pcnp);
  119. // Connect the sink object
  120. hr = m_pcnp->Advise((IUnknown *)pUnkN, &m_dwCookie);
  121. }
  122. }
  123. if (FAILED(hr))
  124. {
  125. m_dwCookie = 0;
  126. }
  127. else
  128. {
  129. m_pUnk = pUnk; // keep around for caller
  130. }
  131. return hr;
  132. }
  133. //****************************************************************************
  134. //
  135. // HRESULT CNotify::Disconnect (void)
  136. //
  137. // Disconnects the sink from the container
  138. //
  139. //****************************************************************************
  140. HRESULT CNotify::Disconnect (void)
  141. {
  142. if (0 != m_dwCookie)
  143. {
  144. // Disconnect the sink object
  145. m_pcnp->Unadvise(m_dwCookie);
  146. m_dwCookie = 0;
  147. m_pcnp->Release();
  148. m_pcnp = NULL;
  149. m_pcnpcnt->Release();
  150. m_pcnpcnt = NULL;
  151. m_pUnk = NULL;
  152. }
  153. return S_OK;
  154. }
  155. //****************************************************************************
  156. //
  157. // CLASS BSTRING
  158. //
  159. //****************************************************************************
  160. //****************************************************************************
  161. //
  162. // Constructor
  163. //
  164. //****************************************************************************
  165. // We don't support construction from an ANSI string in the Unicode build.
  166. #ifndef UNICODE
  167. BSTRING::BSTRING(LPCSTR lpcString)
  168. {
  169. m_bstr = NULL;
  170. // Compute the length of the required BSTR, including the null
  171. int cWC = MultiByteToWideChar(CP_ACP, 0, lpcString, -1, NULL, 0);
  172. if (cWC <= 0)
  173. return;
  174. // Allocate the BSTR, including the null
  175. m_bstr = SysAllocStringLen(NULL, cWC - 1); // SysAllocStringLen adds another 1
  176. ASSERT(NULL != m_bstr);
  177. if (NULL == m_bstr)
  178. {
  179. return;
  180. }
  181. // Copy the string
  182. MultiByteToWideChar(CP_ACP, 0, lpcString, -1, (LPWSTR) m_bstr, cWC);
  183. // Verify that the string is null terminated
  184. ASSERT(0 == m_bstr[cWC - 1]);
  185. }
  186. #endif // #ifndef UNICODE
  187. //****************************************************************************
  188. //
  189. // CLASS BTSTR
  190. //
  191. //****************************************************************************
  192. //****************************************************************************
  193. //
  194. // Constructor
  195. //
  196. //****************************************************************************
  197. BTSTR::BTSTR(BSTR bstr)
  198. {
  199. m_psz = LPTSTRfromBstr(bstr);
  200. }
  201. //****************************************************************************
  202. //
  203. // Destructor
  204. //
  205. //****************************************************************************
  206. BTSTR::~BTSTR()
  207. {
  208. if (NULL != m_psz)
  209. MemFree(m_psz);
  210. }
  211. //****************************************************************************
  212. //
  213. // LPTSTR LPTSTRfromBstr(BSTR bstr)
  214. //
  215. // Converts a BSTR to a LPTSTR
  216. //
  217. //****************************************************************************
  218. LPTSTR LPTSTRfromBstr(BSTR bstr)
  219. {
  220. if (NULL == bstr)
  221. return NULL;
  222. int cch = WideCharToMultiByte(CP_ACP, 0, (LPWSTR)bstr, -1, NULL, 0, NULL, NULL);
  223. if (cch <= 0)
  224. return NULL;
  225. LPTSTR psz;
  226. if (!MemAlloc((void **)&psz, sizeof(TCHAR) * (cch+1)))
  227. return NULL;
  228. #ifndef UNICODE
  229. WideCharToMultiByte(CP_ACP, 0, (LPWSTR)bstr, -1, psz, cch+1, NULL, NULL);
  230. #else
  231. StrCpyN(psz, bstr, cch+1);
  232. wcscpy(psz, bstr);
  233. #endif
  234. return psz;
  235. }