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.

186 lines
4.4 KiB

  1. #include "pch.h"
  2. #include <advpub.h>
  3. #include "thisdll.h"
  4. #include <cguid.h>
  5. #define DECL_CRTFREE
  6. #include <crtfree.h>
  7. #define DECLARE_DEBUG
  8. #define SZ_DEBUGINI "ccshell.ini"
  9. #define SZ_DEBUGSECTION "Media Handlers"
  10. #define SZ_MODULE "SHMEDIA.DLL"
  11. #include <debug.h>
  12. HINSTANCE m_hInst = NULL;
  13. LONG g_cRefThisDll = 0;
  14. STDAPI_(BOOL) DllMain(HINSTANCE hDll, DWORD dwReason, void *lpRes)
  15. {
  16. switch(dwReason)
  17. {
  18. case DLL_PROCESS_ATTACH:
  19. m_hInst = hDll;
  20. break;
  21. }
  22. return TRUE;
  23. }
  24. STDAPI DllCanUnloadNow(void)
  25. {
  26. return g_cRefThisDll ? S_FALSE : S_OK;
  27. }
  28. // Call ADVPACK for the given section of our resource based INF>
  29. // hInstance = resource instance to get REGINST section from
  30. // szSection = section name to invoke
  31. HRESULT CallRegInstall(HINSTANCE hInstance, LPCSTR szSection)
  32. {
  33. HRESULT hr = E_FAIL;
  34. HINSTANCE hinstAdvPack = LoadLibrary(TEXT("ADVPACK.DLL"));
  35. if (hinstAdvPack)
  36. {
  37. REGINSTALL pfnri = (REGINSTALL)GetProcAddress(hinstAdvPack, "RegInstall");
  38. if (pfnri)
  39. {
  40. STRENTRY seReg[] =
  41. {
  42. { "25", "%SystemRoot%" },
  43. { "11", "%SystemRoot%\\system32" },
  44. };
  45. STRTABLE stReg = { ARRAYSIZE(seReg), seReg };
  46. hr = pfnri(hInstance, szSection, &stReg);
  47. }
  48. FreeLibrary(hinstAdvPack);
  49. }
  50. return hr;
  51. }
  52. STDAPI DllRegisterServer(void)
  53. {
  54. CallRegInstall(m_hInst, "RegDll");
  55. return S_OK;
  56. }
  57. STDAPI DllUnregisterServer(void)
  58. {
  59. CallRegInstall(m_hInst, "UnregDll");
  60. return S_OK;
  61. }
  62. CF_TABLE_BEGIN(g_ObjectInfo)
  63. CF_TABLE_ENTRY(&CLSID_MediaDeviceFolder, CMediaDeviceFolder_CreateInstance, COCREATEONLY),
  64. CF_TABLE_ENTRY(&CLSID_OrganizeFolder, COrganizeFiles_CreateInstance, COCREATEONLY),
  65. CF_TABLE_END(g_ObjectInfo)
  66. // constructor for CObjectInfo.
  67. CObjectInfo::CObjectInfo(CLSID const* pclsidin, LPFNCREATEOBJINSTANCE pfnCreatein, IID const* piidIn,
  68. IID const* piidEventsIn, long lVersionIn, DWORD dwOleMiscFlagsIn,
  69. DWORD dwClassFactFlagsIn)
  70. {
  71. pclsid = pclsidin;
  72. pfnCreateInstance = pfnCreatein;
  73. piid = piidIn;
  74. piidEvents = piidEventsIn;
  75. lVersion = lVersionIn;
  76. dwOleMiscFlags = dwOleMiscFlagsIn;
  77. dwClassFactFlags = dwClassFactFlagsIn;
  78. }
  79. // static class factory (no allocs!)
  80. STDMETHODIMP CClassFactory::QueryInterface(REFIID riid, void **ppvObj)
  81. {
  82. if (IsEqualIID(riid, IID_IClassFactory) || IsEqualIID(riid, IID_IUnknown))
  83. {
  84. *ppvObj = (void *)GET_ICLASSFACTORY(this);
  85. DllAddRef();
  86. return S_OK;
  87. }
  88. *ppvObj = NULL;
  89. return E_NOINTERFACE;
  90. }
  91. STDMETHODIMP_(ULONG) CClassFactory::AddRef()
  92. {
  93. DllAddRef();
  94. return 2;
  95. }
  96. STDMETHODIMP_(ULONG) CClassFactory::Release()
  97. {
  98. DllRelease();
  99. return 1;
  100. }
  101. STDMETHODIMP CClassFactory::CreateInstance(IUnknown *punkOuter, REFIID riid, void **ppv)
  102. {
  103. *ppv = NULL;
  104. if (punkOuter && !IsEqualIID(riid, IID_IUnknown))
  105. {
  106. // It is technically illegal to aggregate an object and request
  107. // any interface other than IUnknown. Enforce this.
  108. //
  109. return CLASS_E_NOAGGREGATION;
  110. }
  111. else
  112. {
  113. LPOBJECTINFO pthisobj = (LPOBJECTINFO)this;
  114. if (punkOuter && !(pthisobj->dwClassFactFlags & OIF_ALLOWAGGREGATION))
  115. return CLASS_E_NOAGGREGATION;
  116. IUnknown *punk;
  117. HRESULT hr = pthisobj->pfnCreateInstance(punkOuter, &punk, pthisobj);
  118. if (SUCCEEDED(hr))
  119. {
  120. hr = punk->QueryInterface(riid, ppv);
  121. punk->Release();
  122. }
  123. return hr;
  124. }
  125. }
  126. STDMETHODIMP CClassFactory::LockServer(BOOL fLock)
  127. {
  128. if (fLock)
  129. DllAddRef();
  130. else
  131. DllRelease();
  132. return S_OK;
  133. }
  134. STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppv)
  135. {
  136. if (IsEqualIID(riid, IID_IClassFactory) || IsEqualIID(riid, IID_IUnknown))
  137. {
  138. for (LPCOBJECTINFO pcls = g_ObjectInfo; pcls->pclsid; pcls++)
  139. {
  140. if (IsEqualGUID(rclsid, *(pcls->pclsid)))
  141. {
  142. *ppv = (void*)pcls;
  143. DllAddRef(); // class factory holds DLL ref count
  144. return S_OK;
  145. }
  146. }
  147. }
  148. *ppv = NULL;
  149. return CLASS_E_CLASSNOTAVAILABLE;
  150. }
  151. STDAPI_(void) DllAddRef(void)
  152. {
  153. InterlockedIncrement(&g_cRefThisDll);
  154. }
  155. STDAPI_(void) DllRelease(void)
  156. {
  157. InterlockedDecrement(&g_cRefThisDll);
  158. }