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.

438 lines
11 KiB

  1. //+----------------------------------------------------------------------------
  2. //
  3. // Windows NT Active Directory Property Page Sample
  4. //
  5. // The code contained in this source file is for demonstration purposes only.
  6. // No warrantee is expressed or implied and Microsoft disclaims all liability
  7. // for the consequenses of the use of this source code.
  8. //
  9. // Microsoft Windows
  10. // Copyright (C) Microsoft Corporation, 1992 - 1999
  11. //
  12. // File: host.cxx
  13. //
  14. // Contents: CDsPropPageHost, the class that exposes IShellExtInit and
  15. // IShellPropSheetExt
  16. // Also, the ClassFactory and IUnknown code.
  17. //
  18. // History: 8-Sep-97 Eric Brown created
  19. //
  20. //-----------------------------------------------------------------------------
  21. #include "page.h"
  22. CLIPFORMAT g_cfDsObjectNames = 0;
  23. const CLSID CLSID_SamplePage = { /* cca62184-294f-11d1-bcfe-00c04fd8d5b6 */
  24. 0xcca62184,
  25. 0x294f,
  26. 0x11d1,
  27. {0xbc, 0xfe, 0x00, 0xc0, 0x4f, 0xd8, 0xd5, 0xb6}
  28. };
  29. //+----------------------------------------------------------------------------
  30. //
  31. // Member: CDsPropPageHost::CDsPropPageHost
  32. //
  33. //-----------------------------------------------------------------------------
  34. CDsPropPageHost::CDsPropPageHost() :
  35. m_pDataObj(NULL),
  36. m_uRefs(1)
  37. {
  38. }
  39. //+----------------------------------------------------------------------------
  40. //
  41. // Member: CDsPropPageHost::~CDsPropPageHost
  42. //
  43. //-----------------------------------------------------------------------------
  44. CDsPropPageHost::~CDsPropPageHost()
  45. {
  46. if (m_pDataObj)
  47. {
  48. m_pDataObj->Release();
  49. }
  50. }
  51. //+----------------------------------------------------------------------------
  52. //
  53. // Member: CDsPropPageHost::IShellExtInit::Initialize
  54. //
  55. // Returns: HRESULTS
  56. //
  57. //-----------------------------------------------------------------------------
  58. STDMETHODIMP
  59. CDsPropPageHost::Initialize(LPCITEMIDLIST pIDFolder, LPDATAOBJECT pDataObj,
  60. HKEY hKeyID)
  61. {
  62. if (IsBadReadPtr(pDataObj, sizeof(LPDATAOBJECT)))
  63. {
  64. return E_INVALIDARG;
  65. }
  66. if (m_pDataObj)
  67. {
  68. m_pDataObj->Release();
  69. m_pDataObj = NULL;
  70. }
  71. // Hang onto the IDataObject we are being passed.
  72. m_pDataObj = pDataObj;
  73. if (m_pDataObj)
  74. {
  75. m_pDataObj->AddRef();
  76. }
  77. else
  78. {
  79. return E_INVALIDARG;
  80. }
  81. // Check to see if we have our clipboard format registered, if not then
  82. // lets do it.
  83. if (!g_cfDsObjectNames)
  84. {
  85. g_cfDsObjectNames = (CLIPFORMAT)RegisterClipboardFormat(CFSTR_DSOBJECTNAMES);
  86. }
  87. if (!g_cfDsObjectNames)
  88. {
  89. return E_FAIL;
  90. }
  91. return S_OK;
  92. }
  93. //+----------------------------------------------------------------------------
  94. //
  95. // Member: CDsPropPageHost::IShellExtInit::AddPages
  96. //
  97. // Returns: HRESULTS
  98. //
  99. //-----------------------------------------------------------------------------
  100. STDMETHODIMP
  101. CDsPropPageHost::AddPages(LPFNADDPROPSHEETPAGE pAddPageProc, LPARAM lParam)
  102. {
  103. HRESULT hr = S_OK;
  104. HPROPSHEETPAGE hPage;
  105. STGMEDIUM ObjMedium = {TYMED_NULL};
  106. FORMATETC fmte = {g_cfDsObjectNames, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
  107. LPDSOBJECTNAMES pDsObjectNames;
  108. PWSTR pwzObjName;
  109. PWSTR pwzClass;
  110. CDsPropPage * PropPage;
  111. //
  112. // Get the path to the DS object from the data object.
  113. // Note: This call runs on the caller's main thread. The pages' window
  114. // procs run on a different thread, so don't reference the data object
  115. // from a winproc unless it is first marshalled on this thread.
  116. //
  117. hr = m_pDataObj->GetData(&fmte, &ObjMedium);
  118. if (!SUCCEEDED(hr))
  119. {
  120. return hr;
  121. }
  122. pDsObjectNames = (LPDSOBJECTNAMES)ObjMedium.hGlobal;
  123. if (pDsObjectNames->cItems < 1)
  124. {
  125. hr = E_FAIL;
  126. goto Cleanup;
  127. }
  128. pwzObjName = (PWSTR)ByteOffset(pDsObjectNames,
  129. pDsObjectNames->aObjects[0].offsetName);
  130. pwzClass = (PWSTR)ByteOffset(pDsObjectNames,
  131. pDsObjectNames->aObjects[0].offsetClass);
  132. //
  133. // NOTIFY_OBJ
  134. // Create/contact the notification object.
  135. //
  136. HWND hNotifyObj;
  137. hr = ADsPropCreateNotifyObj(m_pDataObj, pwzObjName, &hNotifyObj);
  138. if (FAILED(hr))
  139. {
  140. goto Cleanup;
  141. }
  142. //
  143. // Create the page.
  144. //
  145. PropPage = new CDsPropPage(hNotifyObj);
  146. hr = PropPage->Init(pwzObjName, pwzClass);
  147. if (!SUCCEEDED(hr))
  148. {
  149. goto Cleanup;
  150. }
  151. hr = PropPage->CreatePage(&hPage);
  152. if (!SUCCEEDED(hr))
  153. {
  154. goto Cleanup;
  155. }
  156. //
  157. // Invoke the callback function, which will add the page to the list of
  158. // pages that will be used to create the property sheet.
  159. //
  160. (*pAddPageProc)(hPage, lParam);
  161. Cleanup:
  162. ReleaseStgMedium(&ObjMedium);
  163. return hr;
  164. }
  165. //+----------------------------------------------------------------------------
  166. //
  167. // Member: CDsPropPageHost::IShellExtInit::ReplacePage
  168. //
  169. // Notes: Not used.
  170. //
  171. //-----------------------------------------------------------------------------
  172. STDMETHODIMP
  173. CDsPropPageHost::ReplacePage(UINT uPageID,
  174. LPFNADDPROPSHEETPAGE lpfnReplaceWith,
  175. LPARAM lParam)
  176. {
  177. return E_NOTIMPL;
  178. }
  179. //+----------------------------------------------------------------------------
  180. //
  181. // Member: CDsPropPageHost::IUnknown::QueryInterface
  182. //
  183. // Synopsis: Returns requested interface pointer
  184. //
  185. //-----------------------------------------------------------------------------
  186. STDMETHODIMP
  187. CDsPropPageHost::QueryInterface(REFIID riid, void ** ppvObject)
  188. {
  189. if (IID_IUnknown == riid)
  190. {
  191. *ppvObject = (IUnknown *)(LPSHELLEXTINIT)this;
  192. }
  193. else if (IID_IShellExtInit == riid)
  194. {
  195. *ppvObject = (LPSHELLEXTINIT)this;
  196. }
  197. else if (IID_IShellPropSheetExt == riid)
  198. {
  199. *ppvObject = (LPSHELLPROPSHEETEXT)this;
  200. }
  201. else
  202. {
  203. *ppvObject = NULL;
  204. return E_NOINTERFACE;
  205. }
  206. AddRef();
  207. return S_OK;
  208. }
  209. //+----------------------------------------------------------------------------
  210. //
  211. // Member: CDsPropPageHost::IUnknown::AddRef
  212. //
  213. // Synopsis: increments reference count
  214. //
  215. // Returns: the reference count
  216. //
  217. //-----------------------------------------------------------------------------
  218. STDMETHODIMP_(ULONG)
  219. CDsPropPageHost::AddRef(void)
  220. {
  221. return InterlockedIncrement((long *)&m_uRefs);
  222. }
  223. //+----------------------------------------------------------------------------
  224. //
  225. // Member: CDsPropPageHost::IUnknown::Release
  226. //
  227. // Synopsis: Decrements the object's reference count and frees it when
  228. // no longer referenced.
  229. //
  230. // Returns: zero if the reference count is zero or non-zero otherwise
  231. //
  232. //-----------------------------------------------------------------------------
  233. STDMETHODIMP_(ULONG)
  234. CDsPropPageHost::Release(void)
  235. {
  236. unsigned long uTmp;
  237. if ((uTmp = InterlockedDecrement((long *)&m_uRefs)) == 0)
  238. {
  239. delete this;
  240. }
  241. return uTmp;
  242. }
  243. //+----------------------------------------------------------------------------
  244. //
  245. // CDsPropPageHostCF - class factory for the CDsPropPageHost object
  246. //
  247. //-----------------------------------------------------------------------------
  248. //+----------------------------------------------------------------------------
  249. //
  250. // Member: CDsPropPageHostCF::Create
  251. //
  252. // Synopsis: creates a new class factory object
  253. //
  254. //-----------------------------------------------------------------------------
  255. IClassFactory *
  256. CDsPropPageHostCF::Create(void)
  257. {
  258. return new CDsPropPageHostCF();
  259. }
  260. //+----------------------------------------------------------------------------
  261. //
  262. // Member: CDsPropPageHostCF::CDsPropPageHostCF
  263. //
  264. // Synopsis: ctor
  265. //
  266. //-----------------------------------------------------------------------------
  267. CDsPropPageHostCF::CDsPropPageHostCF() :
  268. m_uRefs(1)
  269. {
  270. }
  271. //+----------------------------------------------------------------------------
  272. //
  273. // Member: CDsPropPageHostCF::~CDsPropPageHostCF
  274. //
  275. // Synopsis: dtor
  276. //
  277. //-----------------------------------------------------------------------------
  278. CDsPropPageHostCF::~CDsPropPageHostCF(void)
  279. {
  280. }
  281. //+----------------------------------------------------------------------------
  282. //
  283. // Member: CDsPropPageHostCF::IUnknown::QueryInterface
  284. //
  285. // Synopsis: Returns requested interface pointer
  286. //
  287. //-----------------------------------------------------------------------------
  288. STDMETHODIMP
  289. CDsPropPageHostCF::QueryInterface(REFIID riid, void ** ppvObject)
  290. {
  291. if (IID_IUnknown == riid)
  292. {
  293. *ppvObject = (IUnknown *)this;
  294. }
  295. else if (IsEqualIID(IID_IClassFactory, riid))
  296. {
  297. *ppvObject = (IClassFactory *)this;
  298. }
  299. else
  300. {
  301. *ppvObject = NULL;
  302. return E_NOINTERFACE;
  303. }
  304. AddRef();
  305. return S_OK;
  306. }
  307. //+----------------------------------------------------------------------------
  308. //
  309. // Member: CDsPropPageHostCF::IUnknown::AddRef
  310. //
  311. // Synopsis: increments reference count
  312. //
  313. // Returns: the new reference count
  314. //
  315. //-----------------------------------------------------------------------------
  316. STDMETHODIMP_(ULONG)
  317. CDsPropPageHostCF::AddRef(void)
  318. {
  319. return InterlockedIncrement((long *)&m_uRefs);
  320. }
  321. //+----------------------------------------------------------------------------
  322. //
  323. // Member: CDsPropPageHostCF::IUnknown::Release
  324. //
  325. // Synopsis: decrement the refcount
  326. //
  327. // Returns: the new reference count
  328. //
  329. //-----------------------------------------------------------------------------
  330. STDMETHODIMP_(ULONG)
  331. CDsPropPageHostCF::Release(void)
  332. {
  333. unsigned long uTmp;
  334. if ((uTmp = InterlockedDecrement((long *)&m_uRefs)) == 0)
  335. {
  336. delete this;
  337. }
  338. return uTmp;
  339. }
  340. //+----------------------------------------------------------------------------
  341. //
  342. // Member: CDsPropPageHostCF::IClassFactory::CreateInstance
  343. //
  344. // Synopsis: create an incore instance of the proppage host class object
  345. //
  346. // Arguments: [pUnkOuter] - aggregator
  347. // [riid] - requested interface
  348. // [ppvObject] - receptor for itf ptr
  349. //
  350. // Returns: HRESULTS
  351. //
  352. //-----------------------------------------------------------------------------
  353. STDMETHODIMP
  354. CDsPropPageHostCF::CreateInstance(IUnknown *pUnkOuter, REFIID riid,
  355. void **ppvObject)
  356. {
  357. HRESULT hr = S_OK;
  358. *ppvObject = NULL;
  359. CDsPropPageHost * pPropPage = new CDsPropPageHost();
  360. if (pPropPage == NULL)
  361. {
  362. return E_OUTOFMEMORY;
  363. }
  364. hr = pPropPage->QueryInterface(riid, ppvObject);
  365. if (FAILED(hr))
  366. {
  367. pPropPage->Release();
  368. return hr;
  369. }
  370. //
  371. // We got a refcount of one when launched, and the above QI increments it
  372. // to 2, so call release to take it back to 1.
  373. //
  374. pPropPage->Release();
  375. return hr;
  376. }
  377. //+----------------------------------------------------------------------------
  378. //
  379. // Member: CDsPropPageHostCF::IClassFactory::LockServer
  380. //
  381. // Synopsis: Called with fLock set to TRUE to indicate that the server
  382. // should continue to run even if none of its objects are active
  383. //
  384. // Arguments: [fLock] - increment/decrement the instance count
  385. //
  386. // Returns: HRESULTS
  387. //
  388. //-----------------------------------------------------------------------------
  389. STDMETHODIMP
  390. CDsPropPageHostCF::LockServer(BOOL fLock)
  391. {
  392. CDll::LockServer(fLock);
  393. return S_OK;
  394. }