Source code of Windows XP (NT5)
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.

520 lines
14 KiB

  1. /*++
  2. Copyright (c) 1998 Microsoft Corporation
  3. Module Name:
  4. cpropbag.h
  5. Abstract:
  6. This module contains the definition of the
  7. generic property bag class
  8. Author:
  9. Keith Lau (keithlau@microsoft.com)
  10. Revision History:
  11. keithlau 06/30/98 created
  12. --*/
  13. #ifndef _CPROPBAG_H_
  14. #define _CPROPBAG_H_
  15. #include "filehc.h"
  16. #include "mailmsg.h"
  17. #include "cmmtypes.h"
  18. #include "cleanback.h"
  19. //
  20. //Logging facilities
  21. //
  22. #include "inetcom.h"
  23. #include "logtype.h"
  24. /***************************************************************************/
  25. // Definitions
  26. //
  27. #define GENERIC_PTABLE_INSTANCE_SIGNATURE_VALID ((DWORD)'PTGv')
  28. /***************************************************************************/
  29. // CMailMsgPropertyBag
  30. //
  31. //
  32. // Disable warning about using the this pointer in the constructor
  33. // (CCleanBack only saves the pointer, so this is safe)
  34. //
  35. #pragma warning( disable: 4355 )
  36. class CMailMsgPropertyBag :
  37. public IMailMsgPropertyBag,
  38. public CCleanBack
  39. {
  40. public:
  41. CMailMsgPropertyBag() :
  42. CCleanBack((IUnknown *)(IMailMsgPropertyBag *)this),
  43. m_bmBlockManager(NULL),
  44. m_ptProperties(
  45. PTT_PROPERTY_TABLE,
  46. GENERIC_PTABLE_INSTANCE_SIGNATURE_VALID,
  47. &m_bmBlockManager,
  48. &m_InstanceInfo,
  49. CompareProperty,
  50. NULL,
  51. NULL
  52. )
  53. {
  54. m_lRefCount = 1;
  55. // Copy the default instance into our instance
  56. MoveMemory(
  57. &m_InstanceInfo,
  58. &s_DefaultInstanceInfo,
  59. sizeof(PROPERTY_TABLE_INSTANCE));
  60. }
  61. ~CMailMsgPropertyBag()
  62. {
  63. //
  64. // Call all registered callbacks BEFORE destroying member
  65. // variables (so that properties will still be accessible)
  66. //
  67. CallCallBacks();
  68. }
  69. HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, LPVOID *ppvObj)
  70. {
  71. if (riid == IID_IUnknown)
  72. *ppvObj = (IUnknown *)(IMailMsgPropertyBag *)this;
  73. else if (riid == IID_IMailMsgPropertyBag)
  74. *ppvObj = (IMailMsgPropertyBag *)this;
  75. else if (riid == IID_IMailMsgRegisterCleanupCallback)
  76. *ppvObj = (IMailMsgRegisterCleanupCallback *)this;
  77. else
  78. return(E_NOINTERFACE);
  79. AddRef();
  80. return(S_OK);
  81. }
  82. unsigned long STDMETHODCALLTYPE AddRef()
  83. {
  84. return(InterlockedIncrement(&m_lRefCount));
  85. }
  86. unsigned long STDMETHODCALLTYPE Release()
  87. {
  88. LONG lTemp = InterlockedDecrement(&m_lRefCount);
  89. if (!lTemp)
  90. {
  91. // Extra releases are bad!
  92. _ASSERT(lTemp);
  93. }
  94. return(lTemp);
  95. }
  96. HRESULT STDMETHODCALLTYPE PutProperty(
  97. DWORD dwPropID,
  98. DWORD cbLength,
  99. LPBYTE pbValue
  100. )
  101. {
  102. GLOBAL_PROPERTY_ITEM piItem;
  103. piItem.idProp = dwPropID;
  104. return(m_ptProperties.PutProperty(
  105. (LPVOID)&dwPropID,
  106. (LPPROPERTY_ITEM)&piItem,
  107. cbLength,
  108. pbValue));
  109. }
  110. HRESULT STDMETHODCALLTYPE GetProperty(
  111. DWORD dwPropID,
  112. DWORD cbLength,
  113. DWORD *pcbLength,
  114. LPBYTE pbValue
  115. )
  116. {
  117. GLOBAL_PROPERTY_ITEM piItem;
  118. return(m_ptProperties.GetPropertyItemAndValue(
  119. (LPVOID)&dwPropID,
  120. (LPPROPERTY_ITEM)&piItem,
  121. cbLength,
  122. pcbLength,
  123. pbValue));
  124. }
  125. HRESULT STDMETHODCALLTYPE PutStringA(
  126. DWORD dwPropID,
  127. LPCSTR pszValue
  128. )
  129. {
  130. return(PutProperty(dwPropID, pszValue?strlen(pszValue)+1:0, (LPBYTE)pszValue));
  131. }
  132. HRESULT STDMETHODCALLTYPE GetStringA(
  133. DWORD dwPropID,
  134. DWORD cchLength,
  135. LPSTR pszValue
  136. )
  137. {
  138. DWORD dwLength;
  139. return(GetProperty(dwPropID, cchLength, &dwLength, (LPBYTE)pszValue));
  140. }
  141. HRESULT STDMETHODCALLTYPE PutStringW(
  142. DWORD dwPropID,
  143. LPCWSTR pszValue
  144. )
  145. {
  146. return(PutProperty(dwPropID, pszValue?(wcslen(pszValue)+1)*sizeof(WCHAR):0, (LPBYTE)pszValue));
  147. }
  148. HRESULT STDMETHODCALLTYPE GetStringW(
  149. DWORD dwPropID,
  150. DWORD cchLength,
  151. LPWSTR pszValue
  152. )
  153. {
  154. DWORD dwLength;
  155. return(GetProperty(dwPropID, cchLength*sizeof(WCHAR), &dwLength, (LPBYTE)pszValue));
  156. }
  157. HRESULT STDMETHODCALLTYPE PutDWORD(
  158. DWORD dwPropID,
  159. DWORD dwValue
  160. )
  161. {
  162. return(PutProperty(dwPropID, sizeof(DWORD), (LPBYTE)&dwValue));
  163. }
  164. HRESULT STDMETHODCALLTYPE GetDWORD(
  165. DWORD dwPropID,
  166. DWORD *pdwValue
  167. )
  168. {
  169. DWORD dwLength;
  170. return(GetProperty(dwPropID, sizeof(DWORD), &dwLength, (LPBYTE)pdwValue));
  171. }
  172. HRESULT STDMETHODCALLTYPE PutBool(
  173. DWORD dwPropID,
  174. DWORD dwValue
  175. )
  176. {
  177. dwValue = dwValue ? 1 : 0;
  178. return(PutProperty(dwPropID, sizeof(DWORD), (LPBYTE)&dwValue));
  179. }
  180. HRESULT STDMETHODCALLTYPE GetBool(
  181. DWORD dwPropID,
  182. DWORD *pdwValue
  183. )
  184. {
  185. HRESULT hrRes;
  186. DWORD dwLength;
  187. hrRes = GetProperty(dwPropID, sizeof(DWORD), &dwLength, (LPBYTE)pdwValue);
  188. if (pdwValue)
  189. *pdwValue = *pdwValue ? 1 : 0;
  190. return (hrRes);
  191. }
  192. private:
  193. // The specific compare function for this type of property table
  194. static HRESULT CompareProperty(
  195. LPVOID pvPropKey,
  196. LPPROPERTY_ITEM pItem
  197. );
  198. private:
  199. // Usage count
  200. LONG m_lRefCount;
  201. // Property table instance
  202. PROPERTY_TABLE_INSTANCE m_InstanceInfo;
  203. static PROPERTY_TABLE_INSTANCE s_DefaultInstanceInfo;
  204. // IMailMsgProperties is an instance of CPropertyTable
  205. CPropertyTable m_ptProperties;
  206. // An instance of the block memory manager
  207. CBlockManager m_bmBlockManager;
  208. };
  209. //
  210. // Restore original warning settings
  211. //
  212. #pragma warning ( default: 4355 )
  213. /***************************************************************************/
  214. // CMailMsgLoggingPropertyBag
  215. //
  216. class __declspec(uuid("58f9a2d2-21ca-11d2-aa6b-00c04fa35b82")) CMailMsgLoggingPropertyBag :
  217. public CMailMsgPropertyBag,
  218. public IMailMsgLoggingPropertyBag
  219. {
  220. public:
  221. CMailMsgLoggingPropertyBag()
  222. {
  223. m_lRefCount = 1;
  224. m_pvLogHandle = NULL;
  225. }
  226. HRESULT STDMETHODCALLTYPE PutProperty(
  227. DWORD dwPropID,
  228. DWORD cbLength,
  229. LPBYTE pbValue
  230. )
  231. {
  232. HRESULT hrRes = S_OK;
  233. m_rwLock.ExclusiveLock();
  234. hrRes = CMailMsgPropertyBag::PutProperty(
  235. dwPropID,
  236. cbLength,
  237. pbValue);
  238. m_rwLock.ExclusiveUnlock();
  239. return(hrRes);
  240. }
  241. HRESULT STDMETHODCALLTYPE GetProperty(
  242. DWORD dwPropID,
  243. DWORD cbLength,
  244. DWORD *pcbLength,
  245. LPBYTE pbValue
  246. )
  247. {
  248. HRESULT hrRes = S_OK;
  249. m_rwLock.ExclusiveLock();
  250. hrRes = CMailMsgPropertyBag::GetProperty(
  251. dwPropID,
  252. cbLength,
  253. pcbLength,
  254. pbValue);
  255. m_rwLock.ExclusiveUnlock();
  256. return(hrRes);
  257. }
  258. HRESULT STDMETHODCALLTYPE PutStringA(
  259. DWORD dwPropID,
  260. LPCSTR pszValue
  261. )
  262. {
  263. return(PutProperty(dwPropID, pszValue?strlen(pszValue)+1:0, (LPBYTE)pszValue));
  264. }
  265. HRESULT STDMETHODCALLTYPE GetStringA(
  266. DWORD dwPropID,
  267. DWORD cchLength,
  268. LPSTR pszValue
  269. )
  270. {
  271. DWORD dwLength;
  272. return(GetProperty(dwPropID, cchLength, &dwLength, (LPBYTE)pszValue));
  273. }
  274. HRESULT STDMETHODCALLTYPE PutStringW(
  275. DWORD dwPropID,
  276. LPCWSTR pszValue
  277. )
  278. {
  279. return(PutProperty(dwPropID, pszValue?(wcslen(pszValue)+1)*sizeof(WCHAR):0, (LPBYTE)pszValue));
  280. }
  281. HRESULT STDMETHODCALLTYPE GetStringW(
  282. DWORD dwPropID,
  283. DWORD cchLength,
  284. LPWSTR pszValue
  285. )
  286. {
  287. DWORD dwLength;
  288. return(GetProperty(dwPropID, cchLength*sizeof(WCHAR), &dwLength, (LPBYTE)pszValue));
  289. }
  290. HRESULT STDMETHODCALLTYPE PutDWORD(
  291. DWORD dwPropID,
  292. DWORD dwValue
  293. )
  294. {
  295. return(PutProperty(dwPropID, sizeof(DWORD), (LPBYTE)&dwValue));
  296. }
  297. HRESULT STDMETHODCALLTYPE GetDWORD(
  298. DWORD dwPropID,
  299. DWORD *pdwValue
  300. )
  301. {
  302. DWORD dwLength;
  303. return(GetProperty(dwPropID, sizeof(DWORD), &dwLength, (LPBYTE)pdwValue));
  304. }
  305. HRESULT STDMETHODCALLTYPE PutBool(
  306. DWORD dwPropID,
  307. DWORD dwValue
  308. )
  309. {
  310. dwValue = dwValue ? 1 : 0;
  311. return(PutProperty(dwPropID, sizeof(DWORD), (LPBYTE)&dwValue));
  312. }
  313. HRESULT STDMETHODCALLTYPE GetBool(
  314. DWORD dwPropID,
  315. DWORD *pdwValue
  316. )
  317. {
  318. HRESULT hrRes;
  319. DWORD dwLength;
  320. hrRes = GetProperty(dwPropID, sizeof(DWORD), &dwLength, (LPBYTE)pdwValue);
  321. if (pdwValue)
  322. *pdwValue = *pdwValue ? 1 : 0;
  323. return (hrRes);
  324. }
  325. HRESULT SetLogging(
  326. LPVOID pvLogHandle
  327. )
  328. {
  329. if (!pvLogHandle)
  330. return(E_POINTER);
  331. m_pvLogHandle = pvLogHandle;
  332. return(S_OK);
  333. }
  334. static void SetInetLogInfoField(
  335. LPCSTR pszInput,
  336. LPSTR *ppszOutput,
  337. DWORD *pdwOutput
  338. )
  339. {
  340. if (pszInput)
  341. {
  342. *ppszOutput = (LPSTR) pszInput;
  343. if (pdwOutput)
  344. *pdwOutput = lstrlen(pszInput);
  345. }
  346. }
  347. unsigned long STDMETHODCALLTYPE AddRef()
  348. {
  349. return(InterlockedIncrement(&m_lRefCount));
  350. }
  351. unsigned long STDMETHODCALLTYPE Release()
  352. {
  353. LONG lTemp = InterlockedDecrement(&m_lRefCount);
  354. if (!lTemp)
  355. {
  356. // Extra releases are bad!
  357. _ASSERT(lTemp);
  358. }
  359. return(lTemp);
  360. }
  361. HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, LPVOID *ppvObj)
  362. {
  363. if (riid == IID_IUnknown)
  364. *ppvObj = (IUnknown *)(IMailMsgLoggingPropertyBag *)this;
  365. else if (riid == IID_IMailMsgLoggingPropertyBag)
  366. *ppvObj = (IMailMsgLoggingPropertyBag *)this;
  367. else if (riid == __uuidof(CMailMsgLoggingPropertyBag))
  368. *ppvObj = (CMailMsgLoggingPropertyBag *)this;
  369. else if (riid == IID_IMailMsgPropertyBag)
  370. *ppvObj = (IMailMsgPropertyBag *)
  371. ((IMailMsgLoggingPropertyBag *)this);
  372. else if (riid == IID_IMailMsgRegisterCleanupCallback)
  373. *ppvObj = (IMailMsgRegisterCleanupCallback *)this;
  374. else
  375. return(E_NOINTERFACE);
  376. AddRef();
  377. return(S_OK);
  378. }
  379. static DWORD LoggingHelper(
  380. LPVOID pvLogHandle,
  381. const INETLOG_INFORMATION *pLogInformation
  382. );
  383. HRESULT STDMETHODCALLTYPE WriteToLog(
  384. LPCSTR pszClientHostName,
  385. LPCSTR pszClientUserName,
  386. LPCSTR pszServerAddress,
  387. LPCSTR pszOperation,
  388. LPCSTR pszTarget,
  389. LPCSTR pszParameters,
  390. LPCSTR pszVersion,
  391. DWORD dwBytesSent,
  392. DWORD dwBytesReceived,
  393. DWORD dwProcessingTimeMS,
  394. DWORD dwWin32Status,
  395. DWORD dwProtocolStatus,
  396. DWORD dwPort,
  397. LPCSTR pszHTTPHeader
  398. )
  399. {
  400. INETLOG_INFORMATION info;
  401. DWORD dwRes;
  402. memset(&info,0,sizeof(info));
  403. SetInetLogInfoField(pszClientHostName,&info.pszClientHostName,&info.cbClientHostName);
  404. SetInetLogInfoField(pszClientUserName,&info.pszClientUserName,NULL);
  405. SetInetLogInfoField(pszServerAddress,&info.pszServerAddress,NULL);
  406. SetInetLogInfoField(pszOperation,&info.pszOperation,&info.cbOperation);
  407. SetInetLogInfoField(pszTarget,&info.pszTarget,&info.cbTarget);
  408. SetInetLogInfoField(pszParameters,&info.pszParameters,NULL);
  409. SetInetLogInfoField(pszVersion,&info.pszVersion,NULL);
  410. info.dwBytesSent = dwBytesSent;
  411. info.dwBytesRecvd = dwBytesReceived;
  412. info.msTimeForProcessing = dwProcessingTimeMS;
  413. info.dwWin32Status = dwWin32Status;
  414. info.dwProtocolStatus = dwProtocolStatus;
  415. info.dwPort = dwPort;
  416. SetInetLogInfoField(pszHTTPHeader,&info.pszHTTPHeader,&info.cbHTTPHeaderSize);
  417. dwRes = LoggingHelper(m_pvLogHandle,&info);
  418. return(S_OK);
  419. }
  420. private:
  421. // Usage count
  422. LONG m_lRefCount;
  423. LPVOID m_pvLogHandle;
  424. CShareLockNH m_rwLock;
  425. };
  426. // =================================================================
  427. // Compare function
  428. //
  429. inline HRESULT CMailMsgPropertyBag::CompareProperty(
  430. LPVOID pvPropKey,
  431. LPPROPERTY_ITEM pItem
  432. )
  433. {
  434. if (*(PROP_ID *)pvPropKey == ((LPGLOBAL_PROPERTY_ITEM)pItem)->idProp)
  435. return(S_OK);
  436. return(STG_E_UNKNOWN);
  437. }
  438. #endif