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.

709 lines
15 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. return InterlockedIncrement((LONG*)&m_ulRefs);
  83. }
  84. STDMETHODIMP_(ULONG)
  85. CShares::Release()
  86. {
  87. appAssert( 0 != m_ulRefs );
  88. ULONG cRef = InterlockedDecrement((LONG*)&m_ulRefs);
  89. if (0 == cRef)
  90. {
  91. delete this;
  92. }
  93. appAssert( 0 != g_ulcInstances );
  94. InterlockedDecrement((LONG*)&g_ulcInstances);
  95. return cRef;
  96. }
  97. //////////////////////////////////////////////////////////////////////////////
  98. STDMETHODIMP
  99. CSharesSF::QueryInterface(REFIID riid, LPVOID* ppvObj)
  100. {
  101. HRESULT hr;
  102. if (IsEqualIID(IID_IShellFolder, riid))
  103. {
  104. AddRef();
  105. *ppvObj = (IShellFolder*) this;
  106. hr = S_OK;
  107. }
  108. else
  109. {
  110. CShares* This = IMPL(CShares,m_ShellFolder,this);
  111. hr = This->QueryInterface(riid, ppvObj);
  112. }
  113. return hr;
  114. }
  115. STDMETHODIMP_(ULONG)
  116. CSharesSF::AddRef()
  117. {
  118. CShares* This = IMPL(CShares,m_ShellFolder,this);
  119. return This->AddRef();
  120. }
  121. STDMETHODIMP_(ULONG)
  122. CSharesSF::Release()
  123. {
  124. CShares* This = IMPL(CShares,m_ShellFolder,this);
  125. return This->Release();
  126. }
  127. //////////////////////////////////////////////////////////////////////////////
  128. STDMETHODIMP
  129. CSharesPF::QueryInterface(REFIID riid, LPVOID* ppvObj)
  130. {
  131. HRESULT hr;
  132. if (IsEqualIID(IID_IPersistFolder, riid))
  133. {
  134. AddRef();
  135. *ppvObj = (IPersistFolder*) this;
  136. hr = S_OK;
  137. }
  138. else
  139. {
  140. CShares* This = IMPL(CShares,m_PersistFolder,this);
  141. hr = This->QueryInterface(riid, ppvObj);
  142. }
  143. return hr;
  144. }
  145. STDMETHODIMP_(ULONG)
  146. CSharesPF::AddRef()
  147. {
  148. CShares* This = IMPL(CShares,m_PersistFolder,this);
  149. return This->AddRef();
  150. }
  151. STDMETHODIMP_(ULONG)
  152. CSharesPF::Release()
  153. {
  154. CShares* This = IMPL(CShares,m_PersistFolder,this);
  155. return This->Release();
  156. }
  157. //////////////////////////////////////////////////////////////////////////////
  158. STDMETHODIMP
  159. CSharesRC::QueryInterface(REFIID riid, LPVOID* ppvObj)
  160. {
  161. HRESULT hr;
  162. if (IsEqualIID(IID_IRemoteComputer, riid))
  163. {
  164. AddRef();
  165. *ppvObj = (IRemoteComputer*) this;
  166. hr = S_OK;
  167. }
  168. else
  169. {
  170. CShares* This = IMPL(CShares,m_RemoteComputer,this);
  171. hr = This->QueryInterface(riid, ppvObj);
  172. }
  173. return hr;
  174. }
  175. STDMETHODIMP_(ULONG)
  176. CSharesRC::AddRef()
  177. {
  178. CShares* This = IMPL(CShares,m_RemoteComputer,this);
  179. return This->AddRef();
  180. }
  181. STDMETHODIMP_(ULONG)
  182. CSharesRC::Release()
  183. {
  184. CShares* This = IMPL(CShares,m_RemoteComputer,this);
  185. return This->Release();
  186. }
  187. //////////////////////////////////////////////////////////////////////////////
  188. STDMETHODIMP
  189. CSharesSD::QueryInterface(REFIID riid, LPVOID* ppvObj)
  190. {
  191. *ppvObj = NULL;
  192. IUnknown* pUnkTemp = NULL;
  193. HRESULT hr = S_OK;
  194. if (IsEqualIID(IID_IUnknown, riid))
  195. {
  196. pUnkTemp = (IUnknown*)(IShellDetails*) this;
  197. }
  198. else if (IsEqualIID(IID_IShellDetails, riid))
  199. {
  200. pUnkTemp = (IUnknown*)(IShellDetails*) this;
  201. }
  202. else
  203. {
  204. hr = E_NOINTERFACE;
  205. }
  206. if (pUnkTemp != NULL)
  207. {
  208. pUnkTemp->AddRef();
  209. }
  210. *ppvObj = pUnkTemp;
  211. return hr;
  212. }
  213. STDMETHODIMP_(ULONG)
  214. CSharesSD::AddRef()
  215. {
  216. InterlockedIncrement((LONG*)&g_ulcInstances);
  217. return InterlockedIncrement((LONG*)&m_ulRefs);
  218. }
  219. STDMETHODIMP_(ULONG)
  220. CSharesSD::Release()
  221. {
  222. appAssert( 0 != m_ulRefs );
  223. ULONG cRef = InterlockedDecrement((LONG*)&m_ulRefs);
  224. if (0 == cRef)
  225. {
  226. delete this;
  227. }
  228. appAssert( 0 != g_ulcInstances );
  229. InterlockedDecrement((LONG*)&g_ulcInstances);
  230. return cRef;
  231. }
  232. //////////////////////////////////////////////////////////////////////////////
  233. STDMETHODIMP
  234. CSharesCM::QueryInterface(REFIID riid, LPVOID* ppvObj)
  235. {
  236. *ppvObj = NULL;
  237. IUnknown* pUnkTemp = NULL;
  238. HRESULT hr = S_OK;
  239. if (IsEqualIID(IID_IUnknown, riid))
  240. {
  241. pUnkTemp = (IUnknown*)(IContextMenu*) this;
  242. }
  243. else if (IsEqualIID(IID_IContextMenu, riid))
  244. {
  245. pUnkTemp = (IUnknown*)(IContextMenu*) this;
  246. }
  247. else
  248. {
  249. hr = E_NOINTERFACE;
  250. }
  251. if (pUnkTemp != NULL)
  252. {
  253. pUnkTemp->AddRef();
  254. }
  255. *ppvObj = pUnkTemp;
  256. return hr;
  257. }
  258. STDMETHODIMP_(ULONG)
  259. CSharesCM::AddRef()
  260. {
  261. InterlockedIncrement((LONG*)&g_ulcInstances);
  262. return InterlockedIncrement((LONG*)&m_ulRefs);
  263. }
  264. STDMETHODIMP_(ULONG)
  265. CSharesCM::Release()
  266. {
  267. appAssert( 0 != m_ulRefs );
  268. ULONG cRef = InterlockedDecrement((LONG*)&m_ulRefs);
  269. if (0 == cRef)
  270. {
  271. delete this;
  272. }
  273. appAssert( 0 != g_ulcInstances );
  274. InterlockedDecrement((LONG*)&g_ulcInstances);
  275. return cRef;
  276. }
  277. //////////////////////////////////////////////////////////////////////////////
  278. #ifdef WIZARDS
  279. STDMETHODIMP
  280. CSharesCMSpecial::QueryInterface(REFIID riid, LPVOID* ppvObj)
  281. {
  282. *ppvObj = NULL;
  283. IUnknown* pUnkTemp = NULL;
  284. HRESULT hr = S_OK;
  285. if (IsEqualIID(IID_IUnknown, riid))
  286. {
  287. pUnkTemp = (IUnknown*)(IContextMenu*) this;
  288. }
  289. else if (IsEqualIID(IID_IContextMenu, riid))
  290. {
  291. pUnkTemp = (IUnknown*)(IContextMenu*) this;
  292. }
  293. else
  294. {
  295. hr = E_NOINTERFACE;
  296. }
  297. if (pUnkTemp != NULL)
  298. {
  299. pUnkTemp->AddRef();
  300. }
  301. *ppvObj = pUnkTemp;
  302. return hr;
  303. }
  304. STDMETHODIMP_(ULONG)
  305. CSharesCMSpecial::AddRef()
  306. {
  307. InterlockedIncrement((LONG*)&g_ulcInstances);
  308. return InterlockedIncrement((LONG*)&m_ulRefs);
  309. }
  310. STDMETHODIMP_(ULONG)
  311. CSharesCMSpecial::Release()
  312. {
  313. appAssert( 0 != m_ulRefs );
  314. ULONG cRef = InterlockedDecrement((LONG*)&m_ulRefs);
  315. if (0 == cRef)
  316. {
  317. delete this;
  318. }
  319. appAssert( 0 != g_ulcInstances );
  320. InterlockedDecrement((LONG*)&g_ulcInstances);
  321. return cRef;
  322. }
  323. #endif // WIZARDS
  324. //////////////////////////////////////////////////////////////////////////////
  325. STDMETHODIMP
  326. CSharesCMBG::QueryInterface(REFIID riid, LPVOID* ppvObj)
  327. {
  328. *ppvObj = NULL;
  329. IUnknown* pUnkTemp = NULL;
  330. HRESULT hr = S_OK;
  331. if (IsEqualIID(IID_IUnknown, riid))
  332. {
  333. pUnkTemp = (IUnknown*)(IContextMenu*) this;
  334. }
  335. else if (IsEqualIID(IID_IContextMenu, riid))
  336. {
  337. pUnkTemp = (IUnknown*)(IContextMenu*) this;
  338. }
  339. else
  340. {
  341. hr = E_NOINTERFACE;
  342. }
  343. if (pUnkTemp != NULL)
  344. {
  345. pUnkTemp->AddRef();
  346. }
  347. *ppvObj = pUnkTemp;
  348. return hr;
  349. }
  350. STDMETHODIMP_(ULONG)
  351. CSharesCMBG::AddRef()
  352. {
  353. InterlockedIncrement((LONG*)&g_ulcInstances);
  354. return InterlockedIncrement((LONG*)&m_ulRefs);
  355. }
  356. STDMETHODIMP_(ULONG)
  357. CSharesCMBG::Release()
  358. {
  359. appAssert( 0 != m_ulRefs );
  360. ULONG cRef = InterlockedDecrement((LONG*)&m_ulRefs);
  361. if (0 == cRef)
  362. {
  363. delete this;
  364. }
  365. appAssert( 0 != g_ulcInstances );
  366. InterlockedDecrement((LONG*)&g_ulcInstances);
  367. return cRef;
  368. }
  369. //////////////////////////////////////////////////////////////////////////////
  370. STDMETHODIMP
  371. CSharesEnum::QueryInterface(REFIID riid, LPVOID* ppvObj)
  372. {
  373. *ppvObj = NULL;
  374. IUnknown* pUnkTemp = NULL;
  375. HRESULT hr = S_OK;
  376. if (IsEqualIID(IID_IUnknown, riid))
  377. {
  378. pUnkTemp = (IUnknown*)(IEnumIDList*) this;
  379. }
  380. else if (IsEqualIID(IID_IEnumIDList, riid))
  381. {
  382. pUnkTemp = (IUnknown*)(IEnumIDList*) this;
  383. }
  384. else
  385. {
  386. hr = E_NOINTERFACE;
  387. }
  388. if (pUnkTemp != NULL)
  389. {
  390. pUnkTemp->AddRef();
  391. }
  392. *ppvObj = pUnkTemp;
  393. return hr;
  394. }
  395. STDMETHODIMP_(ULONG)
  396. CSharesEnum::AddRef()
  397. {
  398. InterlockedIncrement((LONG*)&g_ulcInstances);
  399. return InterlockedIncrement((LONG*)&m_ulRefs);
  400. }
  401. STDMETHODIMP_(ULONG)
  402. CSharesEnum::Release()
  403. {
  404. appAssert( 0 != m_ulRefs );
  405. ULONG cRef = InterlockedDecrement((LONG*)&m_ulRefs);
  406. if (0 == cRef)
  407. {
  408. delete this;
  409. }
  410. appAssert( 0 != g_ulcInstances );
  411. InterlockedDecrement((LONG*)&g_ulcInstances);
  412. return cRef;
  413. }
  414. //////////////////////////////////////////////////////////////////////////////
  415. STDMETHODIMP
  416. CSharesEI::QueryInterface(REFIID riid, LPVOID* ppvObj)
  417. {
  418. *ppvObj = NULL;
  419. IUnknown* pUnkTemp = NULL;
  420. HRESULT hr = S_OK;
  421. if (IsEqualIID(IID_IUnknown, riid))
  422. {
  423. pUnkTemp = (IUnknown*)(IExtractIcon*) this;
  424. }
  425. else if (IsEqualIID(IID_IExtractIcon, riid))
  426. {
  427. pUnkTemp = (IUnknown*)(IExtractIcon*) this;
  428. }
  429. else
  430. {
  431. hr = E_NOINTERFACE;
  432. }
  433. if (pUnkTemp != NULL)
  434. {
  435. pUnkTemp->AddRef();
  436. }
  437. *ppvObj = pUnkTemp;
  438. return hr;
  439. }
  440. STDMETHODIMP_(ULONG)
  441. CSharesEI::AddRef()
  442. {
  443. InterlockedIncrement((LONG*)&g_ulcInstances);
  444. return InterlockedIncrement((LONG*)&m_ulRefs);
  445. }
  446. STDMETHODIMP_(ULONG)
  447. CSharesEI::Release()
  448. {
  449. appAssert( 0 != m_ulRefs );
  450. ULONG cRef = InterlockedDecrement((LONG*)&m_ulRefs);
  451. if (0 == cRef)
  452. {
  453. delete this;
  454. }
  455. appAssert( 0 != g_ulcInstances );
  456. InterlockedDecrement((LONG*)&g_ulcInstances);
  457. return cRef;
  458. }
  459. //////////////////////////////////////////////////////////////////////////////
  460. #ifdef UNICODE
  461. STDMETHODIMP
  462. CSharesEIA::QueryInterface(REFIID riid, LPVOID* ppvObj)
  463. {
  464. *ppvObj = NULL;
  465. IUnknown* pUnkTemp = NULL;
  466. HRESULT hr = S_OK;
  467. if (IsEqualIID(IID_IUnknown, riid))
  468. {
  469. pUnkTemp = (IUnknown*)(IExtractIconA*) this;
  470. }
  471. else if (IsEqualIID(IID_IExtractIcon, riid))
  472. {
  473. pUnkTemp = (IUnknown*)(IExtractIconA*) this;
  474. }
  475. else
  476. {
  477. hr = E_NOINTERFACE;
  478. }
  479. if (pUnkTemp != NULL)
  480. {
  481. pUnkTemp->AddRef();
  482. }
  483. *ppvObj = pUnkTemp;
  484. return hr;
  485. }
  486. STDMETHODIMP_(ULONG)
  487. CSharesEIA::AddRef()
  488. {
  489. InterlockedIncrement((LONG*)&g_ulcInstances);
  490. return InterlockedIncrement((LONG*)&m_ulRefs);
  491. }
  492. STDMETHODIMP_(ULONG)
  493. CSharesEIA::Release()
  494. {
  495. appAssert( 0 != m_ulRefs );
  496. ULONG cRef = InterlockedDecrement((LONG*)&m_ulRefs);
  497. if (0 == cRef)
  498. {
  499. delete this;
  500. }
  501. appAssert( 0 != g_ulcInstances );
  502. InterlockedDecrement((LONG*)&g_ulcInstances);
  503. return cRef;
  504. }
  505. #endif // UNICODE
  506. //////////////////////////////////////////////////////////////////////////////
  507. STDMETHODIMP
  508. CSharesCF::QueryInterface(REFIID riid, LPVOID* ppvObj)
  509. {
  510. *ppvObj = NULL;
  511. IUnknown* pUnkTemp = NULL;
  512. HRESULT hr = S_OK;
  513. if (IsEqualIID(IID_IUnknown, riid))
  514. {
  515. pUnkTemp = (IUnknown*)(IClassFactory*) this;
  516. }
  517. else if (IsEqualIID(IID_IClassFactory, riid))
  518. {
  519. pUnkTemp = (IUnknown*)(IClassFactory*) this;
  520. }
  521. else
  522. {
  523. hr = E_NOINTERFACE;
  524. }
  525. if (pUnkTemp != NULL)
  526. {
  527. pUnkTemp->AddRef();
  528. }
  529. *ppvObj = pUnkTemp;
  530. return hr;
  531. }
  532. STDMETHODIMP_(ULONG)
  533. CSharesCF::AddRef()
  534. {
  535. return InterlockedIncrement((LONG*)&g_ulcInstances);
  536. }
  537. STDMETHODIMP_(ULONG)
  538. CSharesCF::Release()
  539. {
  540. appAssert( 0 != g_ulcInstances );
  541. InterlockedDecrement((LONG*)&g_ulcInstances);
  542. return g_ulcInstances;
  543. }
  544. STDMETHODIMP
  545. CSharesCF::CreateInstance(IUnknown* pUnkOuter, REFIID riid, LPVOID* ppvObj)
  546. {
  547. if (pUnkOuter != NULL)
  548. {
  549. // don't support aggregation
  550. return E_NOTIMPL;
  551. }
  552. CShares* pShare = new CShares();
  553. if (NULL == pShare)
  554. {
  555. return E_OUTOFMEMORY;
  556. }
  557. HRESULT hr = pShare->QueryInterface(riid, ppvObj);
  558. pShare->Release();
  559. return hr;
  560. }
  561. STDMETHODIMP
  562. CSharesCF::LockServer(BOOL fLock)
  563. {
  564. return S_OK; // FEATURE: Whats supposed to happen here?
  565. }
  566. //////////////////////////////////////////////////////////////////////////////
  567. //////////////////////////////////////////////////////////////////////////////
  568. STDAPI
  569. DllCanUnloadNow(
  570. VOID
  571. )
  572. {
  573. if (0 == g_ulcInstances
  574. && 0 == g_NonOLEDLLRefs)
  575. {
  576. return S_OK;
  577. }
  578. else
  579. {
  580. return S_FALSE;
  581. }
  582. }
  583. CSharesCF cfCShares;
  584. STDAPI
  585. DllGetClassObject(
  586. REFCLSID cid,
  587. REFIID iid,
  588. LPVOID* ppvObj
  589. )
  590. {
  591. InterlockedIncrement((LONG*)&g_ulcInstances); // don't nuke me now!
  592. HRESULT hr = E_NOINTERFACE;
  593. if (IsEqualCLSID(cid, CLSID_CShares))
  594. {
  595. hr = cfCShares.QueryInterface(iid, ppvObj);
  596. }
  597. appAssert( 0 != g_ulcInstances );
  598. InterlockedDecrement((LONG*)&g_ulcInstances);
  599. return hr;
  600. }