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.

640 lines
15 KiB

  1. #ifndef __GUIDEDB_H_
  2. #define __GUIDEDB_H_
  3. #include "resource.h" // main symbols
  4. #include "stdprop.h"
  5. #include "SharedMemory.h"
  6. // External classes
  7. class CObject;
  8. class CObjectType;
  9. class CObjectTypes;
  10. class CGuideDB;
  11. /////////////////////////////////////////////////////////////////////////////
  12. // CGuideDB
  13. class ATL_NO_VTABLE CGuideDB :
  14. public CComObjectRootEx<CComObjectThreadModel>,
  15. public IConnectionPointContainerImpl<CGuideDB>,
  16. public CategoriesPropSet,
  17. public ChannelPropSet,
  18. public ChannelsPropSet,
  19. public CopyrightPropSet,
  20. public TimePropSet,
  21. public DescriptionPropSet,
  22. public ProviderPropSet,
  23. public RatingsPropSet,
  24. public MPAARatingsPropSet,
  25. public ScheduleEntryPropSet,
  26. public ServicePropSet
  27. {
  28. public:
  29. CGuideDB() : m_cacheObj(128), m_cacheObjs(0)
  30. {
  31. #if defined(_ATL_FREE_THREADED)
  32. m_pUnkMarshaler = NULL;
  33. #endif
  34. m_fSQLServer = FALSE;
  35. m_pobjtypes = NULL;
  36. m_pobjtypeGeneric = NULL;
  37. m_pobjtypeGuideDataProvider = NULL;
  38. m_pobjtypeService = NULL;
  39. m_pobjtypeScheduleEntry = NULL;
  40. m_pobjtypeProgram = NULL;
  41. m_pobjtypeChannel = NULL;
  42. m_pobjtypeChannelLineup = NULL;
  43. m_hwnd = NULL;
  44. m_rgmsgItemEvent[Added] = NULL;
  45. m_rgmsgItemEvent[Removed] = NULL;
  46. m_rgmsgItemEvent[Changed] = NULL;
  47. m_iTransLevel = 0;
  48. }
  49. ~CGuideDB()
  50. {
  51. if (m_hwnd != NULL)
  52. DestroyWindow(m_hwnd);
  53. }
  54. HRESULT GetDB(CGuideDB **ppdb)
  55. {
  56. *ppdb = this;
  57. return S_OK;
  58. }
  59. _bstr_t & get_UUID()
  60. {
  61. return m_bstrUUID;
  62. }
  63. DECLARE_GET_CONTROLLING_UNKNOWN()
  64. #if defined(_ATL_FREE_THREADED)
  65. DECLARE_PROTECT_FINAL_CONSTRUCT()
  66. #endif
  67. BEGIN_COM_MAP(CGuideDB)
  68. COM_INTERFACE_ENTRY(IConnectionPointContainer)
  69. #if defined(_ATL_FREE_THREADED)
  70. COM_INTERFACE_ENTRY_AGGREGATE(IID_IMarshal, m_pUnkMarshaler.p)
  71. #endif
  72. END_COM_MAP()
  73. BEGIN_CONNECTION_POINT_MAP(CGuideDB)
  74. END_CONNECTION_POINT_MAP()
  75. #if defined(_ATL_FREE_THREADED)
  76. HRESULT FinalConstruct()
  77. {
  78. return CoCreateFreeThreadedMarshaler(
  79. GetControllingUnknown(), &m_pUnkMarshaler.p);
  80. }
  81. void FinalRelease()
  82. {
  83. m_pUnkMarshaler.Release();
  84. }
  85. CComPtr<IUnknown> m_pUnkMarshaler;
  86. #endif
  87. public:
  88. HRESULT CreateDB(const TCHAR *szDBName, const TCHAR *szDBFileName, const TCHAR *szConnection);
  89. HRESULT CreateSQLDB(const TCHAR *szDBName, const TCHAR *szDBFileName, const TCHAR *szConnection);
  90. HRESULT InitDB(ADOX::_Catalog *pcatalog);
  91. HRESULT InitSQLDB(SQLDMO::_Database *pdb);
  92. HRESULT OpenDB(IGuideStore *pgs, const TCHAR *szDBName);
  93. boolean FSQLServer()
  94. {
  95. return m_fSQLServer;
  96. }
  97. enum ItemEvent {Added = 0, Removed, Changed};
  98. UINT m_rgmsgItemEvent[3];
  99. void Broadcast_ItemEvent(enum ItemEvent ev, long idObj, long idType);
  100. void Broadcast_ItemAdded(long idObj, long idType)
  101. {
  102. Broadcast_ItemEvent(Added, idObj, idType);
  103. }
  104. void Broadcast_ItemRemoved(long idObj, long idType)
  105. {
  106. Broadcast_ItemEvent(Removed, idObj, idType);
  107. }
  108. void Broadcast_ItemChanged(long idObj, long idType)
  109. {
  110. Broadcast_ItemEvent(Changed, idObj, idType);
  111. }
  112. void Broadcast_ItemChanged(long idObj);
  113. void Broadcast_ItemsChanged(long idType)
  114. {
  115. Broadcast_ItemEvent(Changed, 0, idType);
  116. }
  117. void Fire_ItemEvent(enum ItemEvent ev, long idObj, long lExtra);
  118. static ATOM s_atomWindowClass;
  119. static LRESULT _WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
  120. {
  121. CGuideDB *pdb = (CGuideDB *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
  122. if (msg == WM_CREATE)
  123. {
  124. LPCREATESTRUCT pcreatestruct = (LPCREATESTRUCT) lparam;
  125. pdb = (CGuideDB *) pcreatestruct->lpCreateParams;
  126. SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR) pdb);
  127. }
  128. if (pdb == NULL)
  129. return DefWindowProc(hwnd, msg, wparam, lparam);;
  130. return pdb->WindowProc(msg, wparam, lparam);
  131. }
  132. LRESULT WindowProc(UINT msg, WPARAM wparam, LPARAM lparam)
  133. {
  134. if (msg == m_rgmsgItemEvent[Added])
  135. Fire_ItemEvent(Added, wparam, lparam);
  136. else if (msg == m_rgmsgItemEvent[Removed])
  137. Fire_ItemEvent(Removed, wparam, lparam);
  138. else if (msg == m_rgmsgItemEvent[Changed])
  139. Fire_ItemEvent(Changed, wparam, lparam);
  140. else
  141. return DefWindowProc(m_hwnd, msg, wparam, lparam);
  142. return 0;
  143. }
  144. HRESULT CreateEventSinkWindow()
  145. {
  146. if (s_atomWindowClass == NULL)
  147. {
  148. WNDCLASS wndclass;
  149. wndclass.style = 0;
  150. wndclass.lpfnWndProc = _WindowProc;
  151. wndclass.cbClsExtra = 0;
  152. wndclass.cbWndExtra = 0;
  153. wndclass.hInstance = _Module.GetModuleInstance();
  154. wndclass.hIcon = NULL;
  155. wndclass.hCursor = NULL;
  156. wndclass.hbrBackground = NULL;
  157. wndclass.lpszMenuName = NULL;
  158. wndclass.lpszClassName = _T("GuideStoreEventSink");
  159. s_atomWindowClass = RegisterClass(&wndclass);
  160. if (s_atomWindowClass == NULL)
  161. return HRESULT_FROM_WIN32(GetLastError());
  162. }
  163. if (m_rgmsgItemEvent[Added] == 0)
  164. {
  165. TCHAR szMsg[128];
  166. _bstr_t bstrUUID = get_UUID();
  167. wsprintf(szMsg, _T("ItemAdded(%s)"), (LPCTSTR) bstrUUID);
  168. m_rgmsgItemEvent[Added] = RegisterWindowMessage(szMsg);
  169. wsprintf(szMsg, _T("ItemRemoved(%s)"), (LPCTSTR) bstrUUID);
  170. m_rgmsgItemEvent[Removed] = RegisterWindowMessage(szMsg);
  171. wsprintf(szMsg, _T("ItemChanged(%s)"), (LPCTSTR) bstrUUID);
  172. m_rgmsgItemEvent[Changed] = RegisterWindowMessage(szMsg);
  173. }
  174. m_hwnd = CreateWindow( (LPCTSTR)(LONG_PTR)MAKELONG(s_atomWindowClass, 0), // registered class name
  175. _T(""), // window name
  176. WS_POPUP, // window style
  177. 0, 0, 0, 0, // window size and position
  178. NULL, // handle to parent or owner window
  179. NULL, // menu handle or child identifier
  180. _Module.GetModuleInstance(),
  181. (LPVOID) this // window-creation data
  182. );
  183. if (m_hwnd == NULL)
  184. return HRESULT_FROM_WIN32(GetLastError());
  185. return S_OK;
  186. }
  187. CComPtr<IGuideDataProvider> m_pdataprovider;
  188. long GetIDGuideDataProvider();
  189. HRESULT get_GuideDataProvider(IGuideDataProvider **ppdataprovider);
  190. HRESULT putref_GuideDataProvider(IGuideDataProvider *pdataprovider);
  191. HRESULT BeginTrans()
  192. {
  193. HRESULT hr;
  194. long iLevel;
  195. hr = m_pdb->BeginTrans(&iLevel);
  196. if (FAILED(hr))
  197. return hr;
  198. m_iTransLevel++;
  199. if (m_iTransLevel != iLevel)
  200. return E_FAIL;
  201. return S_OK;
  202. }
  203. HRESULT CommitTrans()
  204. {
  205. HRESULT hr;
  206. hr = m_pdb->CommitTrans();
  207. if (FAILED(hr))
  208. return hr;
  209. //UNDONE: Fire a bulk update event.
  210. m_iTransLevel--;
  211. if (m_iTransLevel == 0)
  212. TransactionDone(TRUE);
  213. return S_OK;
  214. }
  215. HRESULT RollbackTrans()
  216. {
  217. HRESULT hr;
  218. hr = m_pdb->RollbackTrans();
  219. if (FAILED(hr))
  220. return hr;
  221. m_iTransLevel--;
  222. if (m_iTransLevel == 0)
  223. TransactionDone(FALSE);
  224. return S_OK;
  225. }
  226. void TransactionDone(boolean fCommit);
  227. HRESULT NewQuery(_bstr_t bstrQuery, ADODB::_Recordset **pprs)
  228. {
  229. _variant_t varDB((IDispatch *)m_pdb);
  230. _variant_t varQuery(bstrQuery);
  231. ADODB::_RecordsetPtr prs;
  232. HRESULT hr;
  233. DeclarePerfTimer("CGuideDB::NewQuery");
  234. PerfTimerReset();
  235. hr = prs.CreateInstance(__uuidof(ADODB::Recordset));
  236. if (FAILED(hr))
  237. return hr;
  238. hr = prs->Open(varQuery,
  239. varDB, ADODB::adOpenUnspecified, ADODB::adLockPessimistic, ADODB::adCmdText);
  240. if (FAILED(hr))
  241. return hr;
  242. *pprs = prs;
  243. if (*pprs != NULL)
  244. (*pprs)->AddRef();
  245. PerfTimerDump("Succeeded");
  246. return S_OK;
  247. }
  248. HRESULT Execute(BSTR bstrCmd, VARIANT *pvarCount = NULL,
  249. long lOptions = ADODB::adExecuteNoRecords, ADODB::_Recordset **pprs = NULL)
  250. {
  251. HRESULT hr;
  252. hr = m_pdb->Execute(bstrCmd, pvarCount, lOptions, pprs);
  253. if (FAILED(hr))
  254. {
  255. DumpObjsCache(_T("CGuideDB::Execute() - After Fail\n"), TRUE);
  256. CloseRels();
  257. hr = m_pdb->Execute(bstrCmd, pvarCount, lOptions, pprs);
  258. DumpObjsCache(_T("CGuideDB::Execute() - After Retry\n"), FALSE);
  259. }
  260. return hr;
  261. }
  262. HRESULT get_StringsRS(ADODB::_Recordset **pprs)
  263. {
  264. *pprs = m_prsStrings;
  265. if (*pprs != NULL)
  266. (*pprs)->AddRef();
  267. return S_OK;
  268. }
  269. HRESULT get_PropSetsRS(ADODB::_Recordset **pprs)
  270. {
  271. *pprs = m_prsPropSets;
  272. if (*pprs != NULL)
  273. (*pprs)->AddRef();
  274. return S_OK;
  275. }
  276. HRESULT get_PropTypesRS(ADODB::_Recordset **pprs)
  277. {
  278. *pprs = m_prsPropTypes;
  279. if (*pprs != NULL)
  280. (*pprs)->AddRef();
  281. return S_OK;
  282. }
  283. HRESULT get_PropsRS(ADODB::_Recordset **pprs)
  284. {
  285. *pprs = m_prsProps;
  286. if (*pprs != NULL)
  287. (*pprs)->AddRef();
  288. return S_OK;
  289. }
  290. HRESULT get_PropsIndexed(ADODB::_Recordset **pprs)
  291. {
  292. *pprs = m_prsPropsIndexed;
  293. if (*pprs != NULL)
  294. (*pprs)->AddRef();
  295. return S_OK;
  296. }
  297. HRESULT get_ObjTypesRS(ADODB::_Recordset **pprs)
  298. {
  299. *pprs = m_prsObjTypes;
  300. if (*pprs != NULL)
  301. (*pprs)->AddRef();
  302. return S_OK;
  303. }
  304. void RequeryObjectsTables()
  305. {
  306. m_prsObjs = NULL;
  307. m_prsObjsByID = NULL;
  308. m_prsObjsByType = NULL;
  309. }
  310. HRESULT get_ObjsRS(ADODB::_Recordset **pprs);
  311. HRESULT get_ObjsByType(ADODB::_Recordset **pprs);
  312. HRESULT get_ObjsByID(ADODB::_Recordset **pprs);
  313. HRESULT get_RelsByID1Rel(ADODB::_Recordset **pprs);
  314. HRESULT get_RelsByID2Rel(ADODB::_Recordset **pprs);
  315. void CloseRels()
  316. {
  317. if (m_prsRelsByID1Rel != NULL)
  318. m_prsRelsByID1Rel.Release();
  319. if (m_prsRelsByID2Rel != NULL)
  320. m_prsRelsByID2Rel.Release();
  321. }
  322. HRESULT get_MetaPropertySet(BSTR bstrName, IMetaPropertySet **pppropset)
  323. {
  324. return m_ppropsets->get_AddNew(bstrName, pppropset);
  325. }
  326. HRESULT get_MetaPropertyType(BSTR bstrName, IMetaPropertyType **ppproptype)
  327. {
  328. if (m_ppropsets == NULL)
  329. return E_INVALIDARG;
  330. return m_ppropsets->get_Lookup(bstrName, ppproptype);
  331. }
  332. HRESULT get_MetaPropertyType(long idPropType, IMetaPropertyType **ppproptype);
  333. HRESULT put_MetaPropertyType(long idPropType, IMetaPropertyType *pproptype);
  334. HRESULT SaveObject(IUnknown *punk, long *pid);
  335. void DumpObjsCache(const TCHAR *psz, boolean fPurge);
  336. HRESULT CacheCollection(IObjects *pobjs)
  337. {
  338. return m_cacheObjs.Cache((LONG_PTR)pobjs, pobjs);
  339. }
  340. HRESULT CacheObject(long idObj, long idObjType, IUnknown **ppobj);
  341. HRESULT CacheObject(long idObj, CObjectType *pobjtype, IUnknown **ppobj);
  342. HRESULT UncacheObject(long idObj);
  343. HRESULT get_Object(long idObj, IUnknown **ppobj);
  344. HRESULT get_IdOf(IUnknown *pobj, long *pid);
  345. HRESULT get_MetaPropertiesOf(long id, IMetaProperties **ppprops);
  346. STDMETHOD(get_MetaPropertiesOf)(/*[in]*/ IUnknown *punk, /*[out, retval]*/ IMetaProperties **ppprops)
  347. {
  348. ENTER_API
  349. {
  350. long idObj;
  351. HRESULT hr;
  352. hr = get_IdOf(punk, &idObj);
  353. if (FAILED(hr))
  354. return hr;
  355. return get_MetaPropertiesOf(idObj, ppprops);
  356. }
  357. LEAVE_API
  358. }
  359. HRESULT get_ObjectsWithType(long idType, IObjects **ppobjs);
  360. HRESULT get_ObjectsWithType(CObjectType *pobjtype, IObjects **ppobjs);
  361. HRESULT get_ObjectsWithType(CLSID clsid, IObjects **ppobjs)
  362. {
  363. CObjectType *pobjtype;
  364. get_ObjectType(clsid, &pobjtype);
  365. return get_ObjectsWithType(pobjtype, ppobjs);
  366. }
  367. HRESULT get_ObjectType(long idObjType, CObjectType **ppobjtype);
  368. HRESULT put_ObjectType(long idObjType, CObjectType *pobjtype);
  369. HRESULT get_ObjectTypes(CObjectTypes **ppobjtypes);
  370. HRESULT get_ObjectType(BSTR bstrCLSID, CObjectType **ppobjtype);
  371. HRESULT get_ObjectType(CLSID clsid, CObjectType **ppobjtype);
  372. HRESULT get_GenericObjectType(CObjectType **ppobjtype)
  373. {
  374. HRESULT hr;
  375. if (m_pobjtypeGeneric == NULL)
  376. {
  377. hr = get_ObjectType(__uuidof(IUnknown), &m_pobjtypeGeneric);
  378. if (FAILED(hr))
  379. return hr;
  380. }
  381. if ((*ppobjtype = m_pobjtypeGeneric) == NULL)
  382. return E_FAIL;
  383. return S_OK;
  384. }
  385. HRESULT get_GuideDataProviderObjectType(CObjectType **ppobjtype)
  386. {
  387. HRESULT hr;
  388. if (m_pobjtypeGuideDataProvider == NULL)
  389. {
  390. hr = get_ObjectType(CLSID_GuideDataProvider, &m_pobjtypeGuideDataProvider);
  391. if (FAILED(hr))
  392. return hr;
  393. }
  394. if ((*ppobjtype = m_pobjtypeGuideDataProvider) == NULL)
  395. return E_FAIL;
  396. return S_OK;
  397. }
  398. HRESULT get_ServiceObjectType(CObjectType **ppobjtype)
  399. {
  400. HRESULT hr;
  401. if (m_pobjtypeService == NULL)
  402. {
  403. hr = get_ObjectType(CLSID_Service, &m_pobjtypeService);
  404. if (FAILED(hr))
  405. return hr;
  406. }
  407. if ((*ppobjtype = m_pobjtypeService) == NULL)
  408. return E_FAIL;
  409. return S_OK;
  410. }
  411. HRESULT get_ProgramObjectType(CObjectType **ppobjtype)
  412. {
  413. HRESULT hr;
  414. if (m_pobjtypeProgram == NULL)
  415. {
  416. hr = get_ObjectType(CLSID_Program, &m_pobjtypeProgram);
  417. if (FAILED(hr))
  418. return hr;
  419. }
  420. if ((*ppobjtype = m_pobjtypeProgram) == NULL)
  421. return E_FAIL;
  422. return S_OK;
  423. }
  424. HRESULT get_ScheduleEntryObjectType(CObjectType **ppobjtype)
  425. {
  426. HRESULT hr;
  427. if (m_pobjtypeScheduleEntry == NULL)
  428. {
  429. hr = get_ObjectType(CLSID_ScheduleEntry, &m_pobjtypeScheduleEntry);
  430. if (FAILED(hr))
  431. return hr;
  432. }
  433. if ((*ppobjtype = m_pobjtypeScheduleEntry) == NULL)
  434. return E_FAIL;
  435. return S_OK;
  436. }
  437. HRESULT get_ChannelObjectType(CObjectType **ppobjtype)
  438. {
  439. HRESULT hr;
  440. if (m_pobjtypeChannel == NULL)
  441. {
  442. hr = get_ObjectType(CLSID_Channel, &m_pobjtypeChannel);
  443. if (FAILED(hr))
  444. return hr;
  445. }
  446. if ((*ppobjtype = m_pobjtypeChannel) == NULL)
  447. return E_FAIL;
  448. return S_OK;
  449. }
  450. HRESULT get_ChannelLineupObjectType(CObjectType **ppobjtype)
  451. {
  452. HRESULT hr;
  453. if (m_pobjtypeChannelLineup == NULL)
  454. {
  455. hr = get_ObjectType(CLSID_ChannelLineup, &m_pobjtypeChannelLineup);
  456. if (FAILED(hr))
  457. return hr;
  458. }
  459. if ((*ppobjtype = m_pobjtypeChannelLineup) == NULL)
  460. return E_FAIL;
  461. return S_OK;
  462. }
  463. long ObjectCount()
  464. {
  465. return m_cacheObj.Count();
  466. }
  467. IUnknown * Object(long i)
  468. {
  469. return m_cacheObj.Item(i);
  470. }
  471. long CachedObjectCount()
  472. {
  473. return m_cacheObj.CachedCount();
  474. }
  475. HRESULT PurgeCachedObjects()
  476. {
  477. m_cacheObj.Keep(0);
  478. m_cacheObj.Keep(128);
  479. return S_OK;
  480. }
  481. CComObjectCacheByID & CacheObjs() { return m_cacheObjs; }
  482. protected:
  483. CComPtr<IMetaPropertySets> m_ppropsets;
  484. ADODB::_ConnectionPtr m_pdb;
  485. boolean m_fSQLServer;
  486. ADODB::_RecordsetPtr m_prsStrings;
  487. ADODB::_RecordsetPtr m_prsPropSets;
  488. ADODB::_RecordsetPtr m_prsPropTypes;
  489. ADODB::_RecordsetPtr m_prsProps;
  490. ADODB::_RecordsetPtr m_prsPropsIndexed;
  491. ADODB::_RecordsetPtr m_prsObjTypes;
  492. ADODB::_RecordsetPtr m_prsObjs;
  493. ADODB::_RecordsetPtr m_prsObjsByType;
  494. ADODB::_RecordsetPtr m_prsObjsByID;
  495. ADODB::_RecordsetPtr m_prsRelsByID1Rel;
  496. ADODB::_RecordsetPtr m_prsRelsByID2Rel;
  497. typedef map<long, IMetaPropertyType *> t_mapPropTypes;
  498. t_mapPropTypes m_mapPropTypes;
  499. CComObjectCacheByID m_cacheObj;
  500. CComObjectCacheByID m_cacheObjs;
  501. typedef map<long, IMetaProperties *> t_mapIdProps;
  502. t_mapIdProps m_mapIdProps;
  503. typedef map<long, IObjects *> t_mapObjsWithType;
  504. t_mapObjsWithType m_mapObjsWithType;
  505. typedef map<long, CObjectType *> t_mapObjTypes;
  506. t_mapObjTypes m_mapObjTypes;
  507. CObjectTypes *m_pobjtypes;
  508. CObjectType *m_pobjtypeGeneric;
  509. CObjectType *m_pobjtypeGuideDataProvider;
  510. CObjectType *m_pobjtypeService;
  511. CObjectType *m_pobjtypeScheduleEntry;
  512. CObjectType *m_pobjtypeProgram;
  513. CObjectType *m_pobjtypeChannel;
  514. CObjectType *m_pobjtypeChannelLineup;
  515. _bstr_t m_bstrUUID;
  516. HWND m_hwnd;
  517. long m_iTransLevel;
  518. };
  519. ATOM __declspec(selectany) CGuideDB::s_atomWindowClass = NULL;
  520. #endif //__GUIDEDB_H_