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.

263 lines
6.9 KiB

  1. #include "pch.h"
  2. #include <advpub.h>
  3. #include <cguid.h>
  4. #include "thisguid.h"
  5. #include "thisdll.h"
  6. #include "resource.h"
  7. #include <comcat.h> // Catagory registration.
  8. #define DECL_CRTFREE
  9. #include <crtfree.h>
  10. // {0CD7A5C0-9F37-11CE-AE65-08002B2E1262}
  11. const GUID CLSID_CabFolder = {0x0CD7A5C0L, 0x9F37, 0x11CE, 0xAE, 0x65, 0x08, 0x00, 0x2B, 0x2E, 0x12, 0x62};
  12. CThisDll g_ThisDll;
  13. STDAPI_(BOOL) DllMain(HINSTANCE hDll, DWORD dwReason, void *lpRes)
  14. {
  15. switch(dwReason)
  16. {
  17. case DLL_PROCESS_ATTACH:
  18. SHFusionInitializeFromModule(hDll);
  19. g_ThisDll.SetInstance(hDll);
  20. break;
  21. case DLL_PROCESS_DETACH:
  22. SHFusionUninitialize();
  23. break;
  24. }
  25. return TRUE;
  26. }
  27. STDAPI DllCanUnloadNow()
  28. {
  29. return (g_ThisDll.m_cRef.GetRef() == 0) && (g_ThisDll.m_cLock.GetRef() == 0) ?
  30. S_OK : S_FALSE;
  31. }
  32. // Procedure for uninstalling this DLL (given an INF file)
  33. void CALLBACK Uninstall(HWND hwndStub, HINSTANCE hInstance, LPTSTR lpszCmdLine, int nCmdShow)
  34. {
  35. RUNDLLPROC pfnCheckAPI = Uninstall;
  36. TCHAR szTitle[100];
  37. TCHAR szPrompt[100 + MAX_PATH];
  38. OSVERSIONINFO osvi;
  39. LPTSTR pszSetupDll;
  40. LPTSTR pszRunDllExe;
  41. if (!lpszCmdLine || lstrlen(lpszCmdLine)>=MAX_PATH)
  42. {
  43. return;
  44. }
  45. LoadString(g_ThisDll.GetInstance(),IDS_SUREUNINST,szPrompt,ARRAYSIZE(szPrompt));
  46. LoadString(g_ThisDll.GetInstance(),IDS_THISDLL,szTitle,ARRAYSIZE(szTitle));
  47. if (MessageBox(hwndStub, szPrompt, szTitle, MB_YESNO|MB_ICONSTOP) != IDYES)
  48. {
  49. return;
  50. }
  51. ZeroMemory(&osvi, sizeof(osvi));
  52. osvi.dwOSVersionInfoSize = sizeof(osvi);
  53. GetVersionEx(&osvi);
  54. if (osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
  55. {
  56. /* Windows 95 uses SetupX */
  57. pszRunDllExe = TEXT("rundll.exe");
  58. pszSetupDll = TEXT("setupx.dll");
  59. }
  60. else
  61. {
  62. /* Windows NT uses SetupAPI */
  63. pszRunDllExe = TEXT("rundll32.exe");
  64. pszSetupDll = TEXT("setupapi.dll");
  65. }
  66. WCHAR szFullPathSetupDll[MAX_PATH];
  67. GetSystemDirectory(szFullPathSetupDll, ARRAYSIZE(szFullPathSetupDll));
  68. PathAppend(szFullPathSetupDll, pszSetupDll);
  69. wnsprintf(szPrompt, ARRAYSIZE(szPrompt), TEXT("%s,InstallHinfSection DefaultUninstall 132 %s"), szFullPathSetupDll, lpszCmdLine);
  70. // Try to win the race before setup finds this DLL still in use.
  71. // If we lose, a reboot will be required to get rid of the DLL.
  72. SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_ABOVE_NORMAL);
  73. WCHAR szFullPathRunDllExe[MAX_PATH];
  74. GetSystemDirectory(szFullPathRunDllExe, ARRAYSIZE(szFullPathRunDllExe));
  75. PathAppend(szFullPathRunDllExe, pszRunDllExe);
  76. ShellExecute(hwndStub, NULL, szFullPathRunDllExe, szPrompt, NULL, SW_SHOWMINIMIZED);
  77. }
  78. // Call ADVPACK for the given section of our resource based INF>
  79. // hInstance = resource instance to get REGINST section from
  80. // szSection = section name to invoke
  81. HRESULT CallRegInstall(HINSTANCE hInstance, LPCSTR szSection)
  82. {
  83. HRESULT hr = E_FAIL;
  84. HINSTANCE hinstAdvPack = LoadLibrary(TEXT("ADVPACK.DLL"));
  85. if (hinstAdvPack)
  86. {
  87. REGINSTALL pfnri = (REGINSTALL)GetProcAddress(hinstAdvPack, "RegInstall");
  88. if ( pfnri )
  89. {
  90. #ifdef WINNT
  91. STRENTRY seReg[] =
  92. {
  93. // These two NT-specific entries must be at the end
  94. { "25", "%SystemRoot%" },
  95. { "11", "%SystemRoot%\\system32" },
  96. };
  97. STRTABLE stReg = { ARRAYSIZE(seReg), seReg };
  98. hr = pfnri(hInstance, szSection, &stReg);
  99. #else
  100. hr = pfnri(hInstance, szSection, NULL);
  101. #endif
  102. }
  103. FreeLibrary(hinstAdvPack);
  104. }
  105. return hr;
  106. }
  107. STDAPI DllRegisterServer(void)
  108. {
  109. CallRegInstall(g_ThisDll.GetInstance(), "RegDll");
  110. // Register as a browseable shell extension.
  111. ICatRegister *pcr;
  112. HRESULT hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr,
  113. NULL, CLSCTX_INPROC_SERVER,
  114. IID_ICatRegister, (void**)&pcr);
  115. if (SUCCEEDED(hr))
  116. {
  117. CATID acatid[1];
  118. acatid[0] = CATID_BrowsableShellExt;
  119. pcr->RegisterClassImplCategories(CLSID_CabFolder, 1, acatid);
  120. pcr->Release();
  121. }
  122. return S_OK;
  123. }
  124. STDAPI DllUnregisterServer(void)
  125. {
  126. CallRegInstall(g_ThisDll.GetInstance(), "UnregDll");
  127. return S_OK;
  128. }
  129. class CThisDllClassFactory : public IClassFactory
  130. {
  131. public:
  132. CThisDllClassFactory(REFCLSID rclsid);
  133. // *** IUnknown methods ***
  134. STDMETHODIMP QueryInterface(REFIID riid, void ** ppvObj);
  135. STDMETHODIMP_(ULONG) AddRef(void);
  136. STDMETHODIMP_(ULONG) Release(void);
  137. // *** IClassFactory methods ***
  138. STDMETHODIMP CreateInstance(IUnknown *pUnkOuter, REFIID riid, void ** ppvObject);
  139. STDMETHODIMP LockServer(BOOL fLock);
  140. private:
  141. CRefDll m_cRefDll;
  142. LONG m_cRef;
  143. CLSID m_clsid;
  144. };
  145. STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppvObj)
  146. {
  147. HRESULT hres;
  148. *ppvObj = NULL;
  149. if ((rclsid == CLSID_CabFolder) || (rclsid == CLSID_CabViewDataObject))
  150. {
  151. CThisDllClassFactory *pcf = new CThisDllClassFactory(rclsid);
  152. if (pcf)
  153. {
  154. hres = pcf->QueryInterface(riid, ppvObj);
  155. pcf->Release();
  156. }
  157. else
  158. hres = E_OUTOFMEMORY;
  159. }
  160. else
  161. hres = E_FAIL;
  162. return hres;
  163. }
  164. STDMETHODIMP CThisDllClassFactory::QueryInterface(REFIID riid, void ** ppvObj)
  165. {
  166. if ((riid == IID_IUnknown) || (riid == IID_IClassFactory))
  167. {
  168. *ppvObj = (void *)(IClassFactory *)this;
  169. }
  170. else
  171. {
  172. *ppvObj = NULL;
  173. return E_NOINTERFACE;
  174. }
  175. ((IUnknown *)*ppvObj)->AddRef();
  176. return NOERROR;
  177. }
  178. CThisDllClassFactory::CThisDllClassFactory(REFCLSID rclsid) : m_cRef(1), m_clsid(rclsid)
  179. {
  180. }
  181. STDMETHODIMP_(ULONG) CThisDllClassFactory::AddRef(void)
  182. {
  183. return InterlockedIncrement(&m_cRef);
  184. }
  185. STDMETHODIMP_(ULONG) CThisDllClassFactory::Release(void)
  186. {
  187. #if DBG==1
  188. if ( 0 == m_cRef )
  189. {
  190. DebugBreak( ); // ref counter problem
  191. }
  192. #endif
  193. ULONG cRef = InterlockedDecrement(&m_cRef);
  194. if ( 0 == cRef )
  195. {
  196. delete this;
  197. }
  198. return cRef;
  199. }
  200. STDMETHODIMP CThisDllClassFactory::CreateInstance(IUnknown *pUnkOuter, REFIID riid, void ** ppvObj)
  201. {
  202. if (pUnkOuter)
  203. return CLASS_E_NOAGGREGATION;
  204. return (CLSID_CabFolder == m_clsid) ?
  205. ::CabFolder_CreateInstance(riid, ppvObj) :
  206. ::CabViewDataObject_CreateInstance(riid, ppvObj);
  207. }
  208. STDMETHODIMP CThisDllClassFactory::LockServer(BOOL fLock)
  209. {
  210. if (fLock)
  211. {
  212. g_ThisDll.m_cLock.AddRef();
  213. }
  214. else
  215. {
  216. g_ThisDll.m_cLock.Release();
  217. }
  218. return NOERROR;
  219. }