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.

198 lines
4.2 KiB

  1. #include "privcpp.h"
  2. #include "ids.h"
  3. #include <advpub.h>
  4. #define INITGUID
  5. #include <initguid.h>
  6. #include "packguid.h"
  7. #define DECL_CRTFREE
  8. #include <crtfree.h>
  9. UINT g_cRefThisDll = 0;
  10. HINSTANCE g_hinst = NULL;
  11. STDAPI_(BOOL) DllMain(HINSTANCE hDll, DWORD dwReason, LPVOID lpReserved)
  12. {
  13. switch(dwReason) {
  14. case DLL_PROCESS_ATTACH:
  15. g_hinst = hDll;
  16. #ifdef DEBUG
  17. CcshellGetDebugFlags();
  18. #endif // DEBUG
  19. break;
  20. default:
  21. break;
  22. }
  23. return TRUE;
  24. }
  25. class CMyClassFactory : public IClassFactory
  26. {
  27. public:
  28. CMyClassFactory(REFCLSID rclsid);
  29. ~CMyClassFactory() { g_cRefThisDll--; }
  30. // IUnKnown
  31. STDMETHODIMP QueryInterface(REFIID,void **);
  32. STDMETHODIMP_(ULONG) AddRef(void);
  33. STDMETHODIMP_(ULONG) Release(void);
  34. // IClassFactory
  35. STDMETHODIMP CreateInstance(IUnknown* pUnkOuter, REFIID riid, void **ppvObject);
  36. STDMETHODIMP LockServer(BOOL fLock);
  37. protected:
  38. UINT _cRef;
  39. CLSID _clsid;
  40. };
  41. CMyClassFactory::CMyClassFactory(REFCLSID rclsid) : _cRef(1), _clsid(rclsid)
  42. {
  43. g_cRefThisDll++;
  44. }
  45. HRESULT CMyClassFactory::QueryInterface(REFIID riid, void **ppvObject)
  46. {
  47. HRESULT hres;
  48. if (IsEqualGUID(riid, IID_IClassFactory) || IsEqualGUID(riid, IID_IUnknown))
  49. {
  50. DebugMsg(DM_TRACE, "pack cf - QueryInterface called");
  51. _cRef++;
  52. *ppvObject = (IClassFactory *)this;
  53. hres = NOERROR;
  54. }
  55. else
  56. {
  57. *ppvObject = NULL;
  58. hres = E_NOINTERFACE;
  59. }
  60. return hres;
  61. }
  62. ULONG CMyClassFactory::AddRef(void)
  63. {
  64. DebugMsg(DM_TRACE, "pack cf - AddRef called");
  65. return ++_cRef;
  66. }
  67. ULONG CMyClassFactory::Release(void)
  68. {
  69. DebugMsg(DM_TRACE, "pack cf - Release called");
  70. if (--_cRef>0)
  71. return _cRef;
  72. delete this;
  73. return 0;
  74. }
  75. HRESULT CMyClassFactory::CreateInstance(IUnknown* pUnkOuter, REFIID riid, void **ppvObject)
  76. {
  77. DebugMsg(DM_TRACE, "CMyClassFactory::CreateInstance called");
  78. if (pUnkOuter)
  79. return CLASS_E_NOAGGREGATION;
  80. IUnknown* punk;
  81. HRESULT hres;
  82. if (IsEqualGUID(_clsid, CLSID_CPackage))
  83. {
  84. hres = CPackage_CreateInstnace(&punk);
  85. }
  86. else
  87. {
  88. return E_UNEXPECTED;
  89. }
  90. if (SUCCEEDED(hres))
  91. {
  92. hres = punk->QueryInterface(riid, ppvObject);
  93. punk->Release();
  94. }
  95. return hres;
  96. }
  97. HRESULT CMyClassFactory::LockServer(BOOL fLock)
  98. {
  99. DebugMsg(DM_TRACE, "pack cf - LockServer called");
  100. return S_OK;
  101. }
  102. STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID FAR* ppvOut)
  103. {
  104. DebugMsg(DM_TRACE, "pack - DllGetClassObject called");
  105. if (IsEqualGUID(rclsid,CLSID_CPackage))
  106. {
  107. CMyClassFactory *pmycls = new CMyClassFactory(rclsid);
  108. if (pmycls)
  109. {
  110. HRESULT hres = pmycls->QueryInterface(riid, ppvOut);
  111. pmycls->Release();
  112. return hres;
  113. }
  114. return E_OUTOFMEMORY;
  115. }
  116. return CLASS_E_CLASSNOTAVAILABLE;
  117. }
  118. STDAPI DllCanUnloadNow(void)
  119. {
  120. DebugMsg(DM_TRACE, "pack - DllCanUnloadNow called");
  121. if (g_cRefThisDll)
  122. {
  123. return S_FALSE;
  124. }
  125. DebugMsg(DM_TRACE, "pack - DllCanUnloadNow returning S_OK (bye, bye...)");
  126. return S_OK;
  127. }
  128. // Call ADVPACK for the given section of our resource based INF>
  129. // hInstance = resource instance to get REGINST section from
  130. // szSection = section name to invoke
  131. HRESULT CallRegInstall(HINSTANCE hInstance, LPCSTR szSection)
  132. {
  133. HRESULT hr = E_FAIL;
  134. HINSTANCE hinstAdvPack = LoadLibrary(TEXT("ADVPACK.DLL"));
  135. if (hinstAdvPack)
  136. {
  137. REGINSTALL pfnri = (REGINSTALL)GetProcAddress(hinstAdvPack, "RegInstall");
  138. if ( pfnri )
  139. {
  140. #ifdef WINNT
  141. STRENTRY seReg[] =
  142. {
  143. // These two NT-specific entries must be at the end
  144. { "25", "%SystemRoot%" },
  145. { "11", "%SystemRoot%\\system32" },
  146. };
  147. STRTABLE stReg = { ARRAYSIZE(seReg), seReg };
  148. hr = pfnri(hInstance, szSection, &stReg);
  149. #else
  150. hr = pfnri(hInstance, szSection, NULL);
  151. #endif
  152. }
  153. FreeLibrary(hinstAdvPack);
  154. }
  155. return hr;
  156. }
  157. STDAPI DllRegisterServer(void)
  158. {
  159. CallRegInstall(g_hinst, "RegDll");
  160. return S_OK;
  161. }
  162. STDAPI DllUnregisterServer(void)
  163. {
  164. CallRegInstall(g_hinst, "UnregDll");
  165. return S_OK;
  166. }