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.

700 lines
14 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1995 - 1995.
  5. //
  6. // File: ole.cxx
  7. //
  8. // Contents: IUnknown & IClassFactory for all OLE objects
  9. //
  10. // History: 13-Dec-95 BruceFo Created
  11. //
  12. // Note: There are three types of IUnknown implementations here. The first
  13. // is for the "Shared Folders" COM objects. Each of these interfaces can be
  14. // QueryInterface'd from the others, and all return the same IUnknown. There
  15. // is a single shared object reference count (not interface reference count).
  16. // These interfaces include: IShellFolder, IPersistFolder, IRemoteComputer.
  17. //
  18. // The second type is standard, separate interfaces that get interface-specific
  19. // reference counts. This includes: IShellDetails, IEnumIDList,
  20. // IExtractIcon, IExtractIconA.
  21. //
  22. // The third type is the IUnknown implementation for the "Shared Folders"
  23. // COM object class factory. This object is a global static object, so it
  24. // never gets destructed.
  25. //
  26. //----------------------------------------------------------------------------
  27. #include "headers.hxx"
  28. #pragma hdrstop
  29. #include <initguid.h>
  30. #include "guids.h"
  31. #include "ole.hxx"
  32. #include "shares.h"
  33. #include "shares.hxx"
  34. #include "sdetails.hxx"
  35. #include "sfolder.hxx"
  36. #include "pfolder.hxx"
  37. #include "rcomp.hxx"
  38. #include "menu.hxx"
  39. #include "menusp.hxx"
  40. #include "menubg.hxx"
  41. #include "enum.hxx"
  42. #include "xicon.hxx"
  43. //////////////////////////////////////////////////////////////////////////////
  44. //////////////////////////////////////////////////////////////////////////////
  45. ULONG g_ulcInstances = 0;
  46. //////////////////////////////////////////////////////////////////////////////
  47. //////////////////////////////////////////////////////////////////////////////
  48. //////////////////////////////////////////////////////////////////////////////
  49. STDMETHODIMP
  50. CShares::QueryInterface(REFIID riid, LPVOID* ppvObj)
  51. {
  52. HRESULT hr;
  53. if (IsEqualIID(IID_IUnknown, riid))
  54. {
  55. AddRef();
  56. *ppvObj = (IUnknown*) this;
  57. hr = S_OK;
  58. }
  59. else if (IsEqualIID(IID_IShellFolder, riid))
  60. {
  61. hr = m_ShellFolder.QueryInterface(riid, ppvObj);
  62. }
  63. else if (IsEqualIID(IID_IPersistFolder, riid))
  64. {
  65. hr = m_PersistFolder.QueryInterface(riid, ppvObj);
  66. }
  67. else if (IsEqualIID(IID_IRemoteComputer, riid))
  68. {
  69. hr = m_RemoteComputer.QueryInterface(riid, ppvObj);
  70. }
  71. else
  72. {
  73. *ppvObj = NULL;
  74. hr = E_NOINTERFACE;
  75. }
  76. return hr;
  77. }
  78. STDMETHODIMP_(ULONG)
  79. CShares::AddRef()
  80. {
  81. InterlockedIncrement((LONG*)&g_ulcInstances);
  82. InterlockedIncrement((LONG*)&m_ulRefs);
  83. return m_ulRefs;
  84. }
  85. STDMETHODIMP_(ULONG)
  86. CShares::Release()
  87. {
  88. ULONG cRef = InterlockedDecrement((LONG*)&m_ulRefs);
  89. if (0 == cRef)
  90. {
  91. delete this;
  92. }
  93. InterlockedDecrement((LONG*)&g_ulcInstances);
  94. return cRef;
  95. }
  96. //////////////////////////////////////////////////////////////////////////////
  97. STDMETHODIMP
  98. CSharesSF::QueryInterface(REFIID riid, LPVOID* ppvObj)
  99. {
  100. HRESULT hr;
  101. if (IsEqualIID(IID_IShellFolder, riid))
  102. {
  103. AddRef();
  104. *ppvObj = (IShellFolder*) this;
  105. hr = S_OK;
  106. }
  107. else
  108. {
  109. CShares* This = IMPL(CShares,m_ShellFolder,this);
  110. hr = This->QueryInterface(riid, ppvObj);
  111. }
  112. return hr;
  113. }
  114. STDMETHODIMP_(ULONG)
  115. CSharesSF::AddRef()
  116. {
  117. CShares* This = IMPL(CShares,m_ShellFolder,this);
  118. return This->AddRef();
  119. }
  120. STDMETHODIMP_(ULONG)
  121. CSharesSF::Release()
  122. {
  123. CShares* This = IMPL(CShares,m_ShellFolder,this);
  124. return This->Release();
  125. }
  126. //////////////////////////////////////////////////////////////////////////////
  127. STDMETHODIMP
  128. CSharesPF::QueryInterface(REFIID riid, LPVOID* ppvObj)
  129. {
  130. HRESULT hr;
  131. if (IsEqualIID(IID_IPersistFolder, riid))
  132. {
  133. AddRef();
  134. *ppvObj = (IPersistFolder*) this;
  135. hr = S_OK;
  136. }
  137. else
  138. {
  139. CShares* This = IMPL(CShares,m_PersistFolder,this);
  140. hr = This->QueryInterface(riid, ppvObj);
  141. }
  142. return hr;
  143. }
  144. STDMETHODIMP_(ULONG)
  145. CSharesPF::AddRef()
  146. {
  147. CShares* This = IMPL(CShares,m_PersistFolder,this);
  148. return This->AddRef();
  149. }
  150. STDMETHODIMP_(ULONG)
  151. CSharesPF::Release()
  152. {
  153. CShares* This = IMPL(CShares,m_PersistFolder,this);
  154. return This->Release();
  155. }
  156. //////////////////////////////////////////////////////////////////////////////
  157. STDMETHODIMP
  158. CSharesRC::QueryInterface(REFIID riid, LPVOID* ppvObj)
  159. {
  160. HRESULT hr;
  161. if (IsEqualIID(IID_IRemoteComputer, riid))
  162. {
  163. AddRef();
  164. *ppvObj = (IRemoteComputer*) this;
  165. hr = S_OK;
  166. }
  167. else
  168. {
  169. CShares* This = IMPL(CShares,m_RemoteComputer,this);
  170. hr = This->QueryInterface(riid, ppvObj);
  171. }
  172. return hr;
  173. }
  174. STDMETHODIMP_(ULONG)
  175. CSharesRC::AddRef()
  176. {
  177. CShares* This = IMPL(CShares,m_RemoteComputer,this);
  178. return This->AddRef();
  179. }
  180. STDMETHODIMP_(ULONG)
  181. CSharesRC::Release()
  182. {
  183. CShares* This = IMPL(CShares,m_RemoteComputer,this);
  184. return This->Release();
  185. }
  186. //////////////////////////////////////////////////////////////////////////////
  187. STDMETHODIMP
  188. CSharesSD::QueryInterface(REFIID riid, LPVOID* ppvObj)
  189. {
  190. *ppvObj = NULL;
  191. IUnknown* pUnkTemp = NULL;
  192. HRESULT hr = S_OK;
  193. if (IsEqualIID(IID_IUnknown, riid))
  194. {
  195. pUnkTemp = (IUnknown*)(IShellDetails*) this;
  196. }
  197. else if (IsEqualIID(IID_IShellDetails, riid))
  198. {
  199. pUnkTemp = (IUnknown*)(IShellDetails*) this;
  200. }
  201. else
  202. {
  203. hr = E_NOINTERFACE;
  204. }
  205. if (pUnkTemp != NULL)
  206. {
  207. pUnkTemp->AddRef();
  208. }
  209. *ppvObj = pUnkTemp;
  210. return hr;
  211. }
  212. STDMETHODIMP_(ULONG)
  213. CSharesSD::AddRef()
  214. {
  215. InterlockedIncrement((LONG*)&g_ulcInstances);
  216. InterlockedIncrement((LONG*)&m_ulRefs);
  217. return m_ulRefs;
  218. }
  219. STDMETHODIMP_(ULONG)
  220. CSharesSD::Release()
  221. {
  222. ULONG cRef = InterlockedDecrement((LONG*)&m_ulRefs);
  223. if (0 == cRef)
  224. {
  225. delete this;
  226. }
  227. InterlockedDecrement((LONG*)&g_ulcInstances);
  228. return cRef;
  229. }
  230. //////////////////////////////////////////////////////////////////////////////
  231. STDMETHODIMP
  232. CSharesCM::QueryInterface(REFIID riid, LPVOID* ppvObj)
  233. {
  234. *ppvObj = NULL;
  235. IUnknown* pUnkTemp = NULL;
  236. HRESULT hr = S_OK;
  237. if (IsEqualIID(IID_IUnknown, riid))
  238. {
  239. pUnkTemp = (IUnknown*)(IContextMenu*) this;
  240. }
  241. else if (IsEqualIID(IID_IContextMenu, riid))
  242. {
  243. pUnkTemp = (IUnknown*)(IContextMenu*) this;
  244. }
  245. else
  246. {
  247. hr = E_NOINTERFACE;
  248. }
  249. if (pUnkTemp != NULL)
  250. {
  251. pUnkTemp->AddRef();
  252. }
  253. *ppvObj = pUnkTemp;
  254. return hr;
  255. }
  256. STDMETHODIMP_(ULONG)
  257. CSharesCM::AddRef()
  258. {
  259. InterlockedIncrement((LONG*)&g_ulcInstances);
  260. InterlockedIncrement((LONG*)&m_ulRefs);
  261. return m_ulRefs;
  262. }
  263. STDMETHODIMP_(ULONG)
  264. CSharesCM::Release()
  265. {
  266. ULONG cRef = InterlockedDecrement((LONG*)&m_ulRefs);
  267. if (0 == cRef)
  268. {
  269. delete this;
  270. }
  271. InterlockedDecrement((LONG*)&g_ulcInstances);
  272. return cRef;
  273. }
  274. //////////////////////////////////////////////////////////////////////////////
  275. #ifdef WIZARDS
  276. STDMETHODIMP
  277. CSharesCMSpecial::QueryInterface(REFIID riid, LPVOID* ppvObj)
  278. {
  279. *ppvObj = NULL;
  280. IUnknown* pUnkTemp = NULL;
  281. HRESULT hr = S_OK;
  282. if (IsEqualIID(IID_IUnknown, riid))
  283. {
  284. pUnkTemp = (IUnknown*)(IContextMenu*) this;
  285. }
  286. else if (IsEqualIID(IID_IContextMenu, riid))
  287. {
  288. pUnkTemp = (IUnknown*)(IContextMenu*) this;
  289. }
  290. else
  291. {
  292. hr = E_NOINTERFACE;
  293. }
  294. if (pUnkTemp != NULL)
  295. {
  296. pUnkTemp->AddRef();
  297. }
  298. *ppvObj = pUnkTemp;
  299. return hr;
  300. }
  301. STDMETHODIMP_(ULONG)
  302. CSharesCMSpecial::AddRef()
  303. {
  304. InterlockedIncrement((LONG*)&g_ulcInstances);
  305. InterlockedIncrement((LONG*)&m_ulRefs);
  306. return m_ulRefs;
  307. }
  308. STDMETHODIMP_(ULONG)
  309. CSharesCMSpecial::Release()
  310. {
  311. ULONG cRef = InterlockedDecrement((LONG*)&m_ulRefs);
  312. if (0 == cRef)
  313. {
  314. delete this;
  315. }
  316. InterlockedDecrement((LONG*)&g_ulcInstances);
  317. return cRef;
  318. }
  319. #endif // WIZARDS
  320. //////////////////////////////////////////////////////////////////////////////
  321. STDMETHODIMP
  322. CSharesCMBG::QueryInterface(REFIID riid, LPVOID* ppvObj)
  323. {
  324. *ppvObj = NULL;
  325. IUnknown* pUnkTemp = NULL;
  326. HRESULT hr = S_OK;
  327. if (IsEqualIID(IID_IUnknown, riid))
  328. {
  329. pUnkTemp = (IUnknown*)(IContextMenu*) this;
  330. }
  331. else if (IsEqualIID(IID_IContextMenu, riid))
  332. {
  333. pUnkTemp = (IUnknown*)(IContextMenu*) this;
  334. }
  335. else
  336. {
  337. hr = E_NOINTERFACE;
  338. }
  339. if (pUnkTemp != NULL)
  340. {
  341. pUnkTemp->AddRef();
  342. }
  343. *ppvObj = pUnkTemp;
  344. return hr;
  345. }
  346. STDMETHODIMP_(ULONG)
  347. CSharesCMBG::AddRef()
  348. {
  349. InterlockedIncrement((LONG*)&g_ulcInstances);
  350. InterlockedIncrement((LONG*)&m_ulRefs);
  351. return m_ulRefs;
  352. }
  353. STDMETHODIMP_(ULONG)
  354. CSharesCMBG::Release()
  355. {
  356. ULONG cRef = InterlockedDecrement((LONG*)&m_ulRefs);
  357. if (0 == cRef)
  358. {
  359. delete this;
  360. }
  361. InterlockedDecrement((LONG*)&g_ulcInstances);
  362. return cRef;
  363. }
  364. //////////////////////////////////////////////////////////////////////////////
  365. STDMETHODIMP
  366. CSharesEnum::QueryInterface(REFIID riid, LPVOID* ppvObj)
  367. {
  368. *ppvObj = NULL;
  369. IUnknown* pUnkTemp = NULL;
  370. HRESULT hr = S_OK;
  371. if (IsEqualIID(IID_IUnknown, riid))
  372. {
  373. pUnkTemp = (IUnknown*)(IEnumIDList*) this;
  374. }
  375. else if (IsEqualIID(IID_IEnumIDList, riid))
  376. {
  377. pUnkTemp = (IUnknown*)(IEnumIDList*) this;
  378. }
  379. else
  380. {
  381. hr = E_NOINTERFACE;
  382. }
  383. if (pUnkTemp != NULL)
  384. {
  385. pUnkTemp->AddRef();
  386. }
  387. *ppvObj = pUnkTemp;
  388. return hr;
  389. }
  390. STDMETHODIMP_(ULONG)
  391. CSharesEnum::AddRef()
  392. {
  393. InterlockedIncrement((LONG*)&g_ulcInstances);
  394. InterlockedIncrement((LONG*)&m_ulRefs);
  395. return m_ulRefs;
  396. }
  397. STDMETHODIMP_(ULONG)
  398. CSharesEnum::Release()
  399. {
  400. ULONG cRef = InterlockedDecrement((LONG*)&m_ulRefs);
  401. if (0 == cRef)
  402. {
  403. delete this;
  404. }
  405. InterlockedDecrement((LONG*)&g_ulcInstances);
  406. return cRef;
  407. }
  408. //////////////////////////////////////////////////////////////////////////////
  409. STDMETHODIMP
  410. CSharesEI::QueryInterface(REFIID riid, LPVOID* ppvObj)
  411. {
  412. *ppvObj = NULL;
  413. IUnknown* pUnkTemp = NULL;
  414. HRESULT hr = S_OK;
  415. if (IsEqualIID(IID_IUnknown, riid))
  416. {
  417. pUnkTemp = (IUnknown*)(IExtractIcon*) this;
  418. }
  419. else if (IsEqualIID(IID_IExtractIcon, riid))
  420. {
  421. pUnkTemp = (IUnknown*)(IExtractIcon*) this;
  422. }
  423. else
  424. {
  425. hr = E_NOINTERFACE;
  426. }
  427. if (pUnkTemp != NULL)
  428. {
  429. pUnkTemp->AddRef();
  430. }
  431. *ppvObj = pUnkTemp;
  432. return hr;
  433. }
  434. STDMETHODIMP_(ULONG)
  435. CSharesEI::AddRef()
  436. {
  437. InterlockedIncrement((LONG*)&g_ulcInstances);
  438. InterlockedIncrement((LONG*)&m_ulRefs);
  439. return m_ulRefs;
  440. }
  441. STDMETHODIMP_(ULONG)
  442. CSharesEI::Release()
  443. {
  444. ULONG cRef = InterlockedDecrement((LONG*)&m_ulRefs);
  445. if (0 == cRef)
  446. {
  447. delete this;
  448. }
  449. InterlockedDecrement((LONG*)&g_ulcInstances);
  450. return cRef;
  451. }
  452. //////////////////////////////////////////////////////////////////////////////
  453. #ifdef UNICODE
  454. STDMETHODIMP
  455. CSharesEIA::QueryInterface(REFIID riid, LPVOID* ppvObj)
  456. {
  457. *ppvObj = NULL;
  458. IUnknown* pUnkTemp = NULL;
  459. HRESULT hr = S_OK;
  460. if (IsEqualIID(IID_IUnknown, riid))
  461. {
  462. pUnkTemp = (IUnknown*)(IExtractIconA*) this;
  463. }
  464. else if (IsEqualIID(IID_IExtractIcon, riid))
  465. {
  466. pUnkTemp = (IUnknown*)(IExtractIconA*) this;
  467. }
  468. else
  469. {
  470. hr = E_NOINTERFACE;
  471. }
  472. if (pUnkTemp != NULL)
  473. {
  474. pUnkTemp->AddRef();
  475. }
  476. *ppvObj = pUnkTemp;
  477. return hr;
  478. }
  479. STDMETHODIMP_(ULONG)
  480. CSharesEIA::AddRef()
  481. {
  482. InterlockedIncrement((LONG*)&g_ulcInstances);
  483. InterlockedIncrement((LONG*)&m_ulRefs);
  484. return m_ulRefs;
  485. }
  486. STDMETHODIMP_(ULONG)
  487. CSharesEIA::Release()
  488. {
  489. ULONG cRef = InterlockedDecrement((LONG*)&m_ulRefs);
  490. if (0 == cRef)
  491. {
  492. delete this;
  493. }
  494. InterlockedDecrement((LONG*)&g_ulcInstances);
  495. return cRef;
  496. }
  497. #endif // UNICODE
  498. //////////////////////////////////////////////////////////////////////////////
  499. STDMETHODIMP
  500. CSharesCF::QueryInterface(REFIID riid, LPVOID* ppvObj)
  501. {
  502. *ppvObj = NULL;
  503. IUnknown* pUnkTemp = NULL;
  504. HRESULT hr = S_OK;
  505. if (IsEqualIID(IID_IUnknown, riid))
  506. {
  507. pUnkTemp = (IUnknown*)(IClassFactory*) this;
  508. }
  509. else if (IsEqualIID(IID_IClassFactory, riid))
  510. {
  511. pUnkTemp = (IUnknown*)(IClassFactory*) this;
  512. }
  513. else
  514. {
  515. hr = E_NOINTERFACE;
  516. }
  517. if (pUnkTemp != NULL)
  518. {
  519. pUnkTemp->AddRef();
  520. }
  521. *ppvObj = pUnkTemp;
  522. return hr;
  523. }
  524. STDMETHODIMP_(ULONG)
  525. CSharesCF::AddRef()
  526. {
  527. InterlockedIncrement((LONG*)&g_ulcInstances);
  528. return g_ulcInstances;
  529. }
  530. STDMETHODIMP_(ULONG)
  531. CSharesCF::Release()
  532. {
  533. InterlockedDecrement((LONG*)&g_ulcInstances);
  534. return g_ulcInstances;
  535. }
  536. STDMETHODIMP
  537. CSharesCF::CreateInstance(IUnknown* pUnkOuter, REFIID riid, LPVOID* ppvObj)
  538. {
  539. if (pUnkOuter != NULL)
  540. {
  541. // don't support aggregation
  542. return E_NOTIMPL;
  543. }
  544. CShares* pShare = new CShares();
  545. if (NULL == pShare)
  546. {
  547. return E_OUTOFMEMORY;
  548. }
  549. HRESULT hr = pShare->QueryInterface(riid, ppvObj);
  550. pShare->Release();
  551. return hr;
  552. }
  553. STDMETHODIMP
  554. CSharesCF::LockServer(BOOL fLock)
  555. {
  556. return S_OK; // FEATURE: Whats supposed to happen here?
  557. }
  558. //////////////////////////////////////////////////////////////////////////////
  559. //////////////////////////////////////////////////////////////////////////////
  560. STDAPI
  561. DllCanUnloadNow(
  562. VOID
  563. )
  564. {
  565. if (0 == g_ulcInstances
  566. && 0 == g_NonOLEDLLRefs)
  567. {
  568. return S_OK;
  569. }
  570. else
  571. {
  572. return S_FALSE;
  573. }
  574. }
  575. CSharesCF cfCShares;
  576. STDAPI
  577. DllGetClassObject(
  578. REFCLSID cid,
  579. REFIID iid,
  580. LPVOID* ppvObj
  581. )
  582. {
  583. InterlockedIncrement((LONG*)&g_ulcInstances); // don't nuke me now!
  584. HRESULT hr = E_NOINTERFACE;
  585. if (IsEqualCLSID(cid, CLSID_CShares))
  586. {
  587. hr = cfCShares.QueryInterface(iid, ppvObj);
  588. }
  589. InterlockedDecrement((LONG*)&g_ulcInstances);
  590. return hr;
  591. }