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.

380 lines
11 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. mimebag.cpp
  5. Abstract:
  6. This module contains the implementation for the Server
  7. Extension Object Registry Property Bag.
  8. Author:
  9. Andy Jacobs (andyj@microsoft.com)
  10. Revision History:
  11. andyj 01/28/97 created
  12. andyj 02/12/97 Converted PropertyBag's to Dictonary's
  13. --*/
  14. // MIMEBAG.cpp : Implementation of CSEOMimeDictionary
  15. #include "stdafx.h"
  16. #include "seodefs.h"
  17. #include "mimeole.h"
  18. #include "MIMEBAG.h"
  19. inline void AnsiToBstr(BSTR &bstr, LPCSTR lpcstr) {
  20. if(bstr) SysFreeString(bstr);
  21. bstr = A2BSTR(lpcstr);
  22. /*
  23. int iSize = lstrlen(lpcstr); // Number of characters to copy
  24. bstr = SysAllocStringLen(NULL, iSize);
  25. MultiByteToWideChar(CP_ACP, 0, lpcstr, -1, bstr, iSize);
  26. */
  27. }
  28. /////////////////////////////////////////////////////////////////////////////
  29. // CSEOMimeDictionary
  30. HRESULT STDMETHODCALLTYPE CSEOMimeDictionary::get_Item(
  31. /* [in] */ VARIANT __RPC_FAR *pvarName,
  32. /* [retval][out] */ VARIANT __RPC_FAR *pvarResult)
  33. {
  34. ATLTRACENOTIMPL(_T("CSEOMimeDictionary::get_Item"));
  35. }
  36. HRESULT STDMETHODCALLTYPE CSEOMimeDictionary::put_Item(
  37. /* [in] */ VARIANT __RPC_FAR *pvarName,
  38. /* [in] */ VARIANT __RPC_FAR *pvarValue)
  39. {
  40. ATLTRACENOTIMPL(_T("CSEOMimeDictionary::put_Item"));
  41. }
  42. HRESULT STDMETHODCALLTYPE CSEOMimeDictionary::get__NewEnum(
  43. /* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *ppunkResult)
  44. {
  45. ATLTRACENOTIMPL(_T("CSEOMimeDictionary::get__NewEnum"));
  46. }
  47. HRESULT STDMETHODCALLTYPE CSEOMimeDictionary::GetVariantA(
  48. /* [in] */ LPCSTR pszName,
  49. /* [retval][out] */ VARIANT __RPC_FAR *pvarResult)
  50. {
  51. ATLTRACENOTIMPL(_T("CSEOMimeDictionary::GetVariantA"));
  52. }
  53. HRESULT STDMETHODCALLTYPE CSEOMimeDictionary::GetVariantW(
  54. /* [in] */ LPCWSTR pszName,
  55. /* [retval][out] */ VARIANT __RPC_FAR *pvarResult)
  56. {
  57. ATLTRACENOTIMPL(_T("CSEOMimeDictionary::GetVariantW"));
  58. }
  59. HRESULT STDMETHODCALLTYPE CSEOMimeDictionary::SetVariantA(
  60. /* [in] */ LPCSTR pszName,
  61. /* [in] */ VARIANT __RPC_FAR *pvarValue)
  62. {
  63. ATLTRACENOTIMPL(_T("CSEOMimeDictionary::SetVariantA"));
  64. }
  65. HRESULT STDMETHODCALLTYPE CSEOMimeDictionary::SetVariantW(
  66. /* [in] */ LPCWSTR pszName,
  67. /* [in] */ VARIANT __RPC_FAR *pvarValue)
  68. {
  69. ATLTRACENOTIMPL(_T("CSEOMimeDictionary::SetVariantW"));
  70. }
  71. HRESULT STDMETHODCALLTYPE CSEOMimeDictionary::GetStringA(
  72. /* [in] */ LPCSTR pszName,
  73. /* [out][in] */ DWORD __RPC_FAR *pchCount,
  74. /* [retval][size_is][out] */ LPSTR pszResult)
  75. {
  76. ATLTRACENOTIMPL(_T("CSEOMimeDictionary::GetStringA"));
  77. }
  78. HRESULT STDMETHODCALLTYPE CSEOMimeDictionary::GetStringW(
  79. /* [in] */ LPCWSTR pszName,
  80. /* [out][in] */ DWORD __RPC_FAR *pchCount,
  81. /* [retval][size_is][out] */ LPWSTR pszResult)
  82. {
  83. ATLTRACENOTIMPL(_T("CSEOMimeDictionary::GetStringW"));
  84. }
  85. HRESULT STDMETHODCALLTYPE CSEOMimeDictionary::SetStringA(
  86. /* [in] */ LPCSTR pszName,
  87. /* [in] */ DWORD chCount,
  88. /* [size_is][in] */ LPCSTR pszValue)
  89. {
  90. ATLTRACENOTIMPL(_T("CSEOMimeDictionary::SetStringA"));
  91. }
  92. HRESULT STDMETHODCALLTYPE CSEOMimeDictionary::SetStringW(
  93. /* [in] */ LPCWSTR pszName,
  94. /* [in] */ DWORD chCount,
  95. /* [size_is][in] */ LPCWSTR pszValue)
  96. {
  97. ATLTRACENOTIMPL(_T("CSEOMimeDictionary::SetStringW"));
  98. }
  99. HRESULT STDMETHODCALLTYPE CSEOMimeDictionary::GetDWordA(
  100. /* [in] */ LPCSTR pszName,
  101. /* [retval][out] */ DWORD __RPC_FAR *pdwResult)
  102. {
  103. ATLTRACENOTIMPL(_T("CSEOMimeDictionary::GetDWordA"));
  104. }
  105. HRESULT STDMETHODCALLTYPE CSEOMimeDictionary::GetDWordW(
  106. /* [in] */ LPCWSTR pszName,
  107. /* [retval][out] */ DWORD __RPC_FAR *pdwResult)
  108. {
  109. ATLTRACENOTIMPL(_T("CSEOMimeDictionary::GetDWordW"));
  110. }
  111. HRESULT STDMETHODCALLTYPE CSEOMimeDictionary::SetDWordA(
  112. /* [in] */ LPCSTR pszName,
  113. /* [in] */ DWORD dwValue)
  114. {
  115. ATLTRACENOTIMPL(_T("CSEOMimeDictionary::SetDWordA"));
  116. }
  117. HRESULT STDMETHODCALLTYPE CSEOMimeDictionary::SetDWordW(
  118. /* [in] */ LPCWSTR pszName,
  119. /* [in] */ DWORD dwValue)
  120. {
  121. ATLTRACENOTIMPL(_T("CSEOMimeDictionary::SetDWordW"));
  122. }
  123. HRESULT STDMETHODCALLTYPE CSEOMimeDictionary::GetInterfaceA(
  124. /* [in] */ LPCSTR pszName,
  125. /* [in] */ REFIID iidDesired,
  126. /* [retval][iid_is][out] */ IUnknown __RPC_FAR *__RPC_FAR *ppunkResult)
  127. {
  128. ATLTRACENOTIMPL(_T("CSEOMimeDictionary::GetInterfaceA"));
  129. }
  130. HRESULT STDMETHODCALLTYPE CSEOMimeDictionary::GetInterfaceW(
  131. /* [in] */ LPCWSTR pszName,
  132. /* [in] */ REFIID iidDesired,
  133. /* [retval][iid_is][out] */ IUnknown __RPC_FAR *__RPC_FAR *ppunkResult)
  134. {
  135. ATLTRACENOTIMPL(_T("CSEOMimeDictionary::GetInterfaceW"));
  136. }
  137. HRESULT STDMETHODCALLTYPE CSEOMimeDictionary::SetInterfaceA(
  138. /* [in] */ LPCSTR pszName,
  139. /* [in] */ IUnknown __RPC_FAR *punkValue)
  140. {
  141. ATLTRACENOTIMPL(_T("CSEOMimeDictionary::SetInterfaceA"));
  142. }
  143. HRESULT STDMETHODCALLTYPE CSEOMimeDictionary::SetInterfaceW(
  144. /* [in] */ LPCWSTR pszName,
  145. /* [in] */ IUnknown __RPC_FAR *punkValue)
  146. {
  147. ATLTRACENOTIMPL(_T("CSEOMimeDictionary::SetInterfaceW"));
  148. }
  149. /*
  150. STDMETHODIMP CSEOMimePropertyBagEx::Read(LPCOLESTR pszPropName, VARIANT *pVar, IErrorLog *pErrorLog) {
  151. if (!pszPropName || !pVar) return (E_POINTER);
  152. LONG dwIdx;
  153. VARTYPE vtVar = pVar->vt; // Requested type
  154. VariantClear(pVar);
  155. ReadHeader();
  156. /*
  157. if(vtVar == VT_UNKNOWN) || (vtVar == VT_EMPTY)) {
  158. // Look for a matching key
  159. for (dwIdx=0;dwIdx<m_dwKeyCnt;dwIdx++) {
  160. if (_wcsicmp(pszPropName, m_paKey[dwIdx].strName) == 0) {
  161. if(!m_paKey[dwIdx].pKey) { // If object doesn't already exists
  162. HRESULT hrRes = CComObject<CSEORegPropertyBagEx>::CreateInstance(&(m_paKey[dwIdx].pKey));
  163. if (!SUCCEEDED(hrRes)) return (hrRes);
  164. BSTR strTemp = SysAllocStringLen(m_strSubKey, wcslen(m_strSubKey) +
  165. wcslen(m_paKey[dwIdx].strName) + wcslen(PATH_SEP));
  166. if (!strTemp) {
  167. RELEASE_AND_SHREAD_POINTER(m_paKey[dwIdx].pKey);
  168. return (E_OUTOFMEMORY);
  169. }
  170. if(wcslen(strTemp) > 0) wcscat(strTemp, PATH_SEP); // Add separator if needed
  171. wcscat(strTemp,m_paKey[dwIdx].strName);
  172. hrRes = m_paKey[dwIdx].pKey->Load(m_strMachine,(SEO_HKEY) (DWORD) m_hkBaseKey,strTemp,pErrorLog);
  173. SysFreeString(strTemp);
  174. if (!SUCCEEDED(hrRes)) {
  175. RELEASE_AND_SHREAD_POINTER(m_paKey[dwIdx].pKey);
  176. return (hrRes);
  177. }
  178. }
  179. pVar->vt = VT_UNKNOWN;
  180. pVar->punkVal = m_paKey[dwIdx].pKey;
  181. pVar->punkVal->AddRef(); // Increment for the copy we are about to return
  182. return (S_OK);
  183. }
  184. }
  185. if (vtVar != VT_EMPTY) return (E_INVALIDARG); // Didn't find right type to return
  186. }
  187. * /
  188. // Look for a matching value
  189. for (dwIdx = 0; dwIdx < m_dwValueCnt; ++dwIdx) {
  190. if (_wcsicmp(pszPropName, m_paValue[dwIdx].strName) == 0) {
  191. HRESULT hrRes;
  192. VARIANT varResult;
  193. VariantInit(&varResult);
  194. varResult.vt = VT_BSTR; // | VT_BYREF;
  195. varResult.bstrVal = SysAllocString(m_paValue[dwIdx].strData);
  196. if (vtVar == VT_EMPTY) vtVar = varResult.vt;
  197. hrRes = VariantChangeType(pVar, &varResult, 0, vtVar);
  198. VariantClear(&varResult); // Not needed anymore
  199. if (FAILED(hrRes)) {
  200. VariantClear(pVar);
  201. if (pErrorLog) {
  202. // tbd
  203. }
  204. return (hrRes);
  205. }
  206. return (S_OK);
  207. }
  208. }
  209. return (E_INVALIDARG);
  210. }
  211. STDMETHODIMP CSEOMimePropertyBagEx::get_Count(LONG *plResult) {
  212. if(!plResult) return (E_POINTER);
  213. ReadHeader();
  214. *plResult = m_dwValueCnt;
  215. return (S_OK);
  216. }
  217. STDMETHODIMP CSEOMimePropertyBagEx::get_Name(LONG lIndex, BSTR *pstrResult) {
  218. if(!pstrResult) return (E_POINTER);
  219. ReadHeader();
  220. if(lIndex >= m_dwValueCnt) return (E_POINTER);
  221. SysFreeString(*pstrResult); // Free any existing string
  222. *pstrResult = SysAllocString(m_paValue[lIndex].strName);
  223. return (S_OK);
  224. }
  225. STDMETHODIMP CSEOMimePropertyBagEx::get_Type(LONG lIndex, VARTYPE *pvtResult) {
  226. if(!pvtResult) return (E_POINTER);
  227. *pvtResult = VT_BSTR;
  228. return (S_OK);
  229. }
  230. STDMETHODIMP CSEOMimePropertyBagEx::Lock() {
  231. m_csCritSec.Lock();
  232. return (S_OK);
  233. }
  234. STDMETHODIMP CSEOMimePropertyBagEx::Unlock() {
  235. m_csCritSec.Unlock();
  236. return (S_OK);
  237. }
  238. */
  239. HRESULT CSEOMimeDictionary::FinalConstruct() {
  240. m_dwValueCnt = 0;
  241. m_paValue = NULL;
  242. m_csCritSec.Init();
  243. m_pMessageTree = NULL; // Our copy of aggregated object
  244. m_pMalloc = NULL;
  245. HRESULT hr = E_FAIL;
  246. m_pMessageTree = NULL;
  247. // tbd: Combine these using CoCreateInstanceEx()
  248. hr = CoCreateInstance(CLSID_MIMEOLE, NULL, CLSCTX_ALL,
  249. IID_IMimeOleMalloc, (LPVOID *) &m_pMalloc);
  250. IUnknown *pUnkOuter = this;
  251. hr = CoCreateInstance(CLSID_MIMEOLE, pUnkOuter, CLSCTX_INPROC_SERVER, IID_IMimeMessageTree, (LPVOID *)&m_pMessageTree);
  252. // hr = CoCreateInstance(CLSID_MIMEOLE, this, CLSCTX_ALL,
  253. // IID_IMimeMessageTree, (LPVOID *) &m_pMessageTree);
  254. if (SUCCEEDED(hr)) {
  255. hr = CoCreateFreeThreadedMarshaler(GetControllingUnknown(),&m_pUnkMarshaler.p);
  256. }
  257. return (hr);
  258. }
  259. void CSEOMimeDictionary::FinalRelease() {
  260. // Flush(NULL);
  261. for (LONG dwIdx = 0; dwIdx < m_dwValueCnt; ++dwIdx) {
  262. MySysFreeStringInPlace(&m_paValue[dwIdx].strName);
  263. MySysFreeStringInPlace(&m_paValue[dwIdx].strData);
  264. }
  265. m_dwValueCnt = 0;
  266. MyFreeInPlace(&m_paValue);
  267. RELEASE_AND_SHREAD_POINTER(m_pMessageTree);
  268. RELEASE_AND_SHREAD_POINTER(m_pMalloc);
  269. m_csCritSec.Term();
  270. m_pUnkMarshaler.Release();
  271. }
  272. void CSEOMimeDictionary::ReadHeader() {
  273. if(m_paValue) return; // Already read it
  274. IMimeHeader *pHeader = NULL;
  275. IMimeEnumHeaderLines *pEnum = NULL;
  276. HBODY hBody = 0;
  277. HEADERLINE rgLine[1];
  278. ULONG cLines = 0;
  279. LONG iEntries = 0; // Number of Header lines
  280. HRESULT hr = E_FAIL;
  281. // tbd: Error checking
  282. hr = m_pMessageTree->GetBody(IBL_ROOT, NULL, &hBody);
  283. hr = m_pMessageTree->BindToObject(hBody, IID_IMimeHeader, (LPVOID *) &pHeader);
  284. hr = pHeader->EnumHeaderLines(NULL, &pEnum);
  285. while(SUCCEEDED(hr = pEnum->Next(1, rgLine, &cLines))) {
  286. if(hr == S_FALSE) break;
  287. ++iEntries;
  288. // Use rgLine->pszHeader and rgLine->pszLine
  289. m_pMalloc->FreeHeaderLineArray(cLines, rgLine, FALSE);
  290. }
  291. RELEASE_AND_SHREAD_POINTER(pEnum);
  292. m_dwValueCnt = iEntries;
  293. m_paValue = (ValueEntry *) MyMalloc(sizeof(ValueEntry) * m_dwValueCnt);
  294. //if (!m_paValue) return E_FAIL; // Unable to allocate memory
  295. hr = pHeader->EnumHeaderLines(NULL, &pEnum);
  296. iEntries = 0; // Start again
  297. while(SUCCEEDED(hr = pEnum->Next(1, rgLine, &cLines))) {
  298. if(hr == S_FALSE) break;
  299. AnsiToBstr(m_paValue[iEntries].strName, rgLine->pszHeader);
  300. AnsiToBstr(m_paValue[iEntries].strData, rgLine->pszLine);
  301. ++iEntries;
  302. m_pMalloc->FreeHeaderLineArray(cLines, rgLine, FALSE);
  303. }
  304. RELEASE_AND_SHREAD_POINTER(pEnum);
  305. RELEASE_AND_SHREAD_POINTER(pHeader);
  306. }