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.

245 lines
7.0 KiB

  1. #include "precomp.h" // pch file
  2. #include "cfdefs.h" // CClassFactory, LPOBJECTINFO
  3. #pragma hdrstop
  4. STDAPI MailRecipient_RegUnReg(BOOL bReg, HKEY hkCLSID, LPCTSTR pszCLSID, LPCTSTR pszModule);
  5. STDAPI MailRecipient_CreateInstance(IUnknown *punkOuter, IUnknown **ppunk, LPCOBJECTINFO poi);
  6. STDAPI DesktopShortcut_RegUnReg(BOOL bReg, HKEY hkCLSID, LPCTSTR pszCLSID, LPCTSTR pszModule);
  7. STDAPI DesktopShortcut_CreateInstance(IUnknown *punkOuter, IUnknown **ppunk, LPCOBJECTINFO poi);
  8. // tables for object construction and registration
  9. CF_TABLE_BEGIN( g_ObjectInfo )
  10. CF_TABLE_ENTRY(&CLSID_MailRecipient, MailRecipient_CreateInstance, COCREATEONLY),
  11. CF_TABLE_ENTRY(&CLSID_DesktopShortcut, DesktopShortcut_CreateInstance, COCREATEONLY),
  12. CF_TABLE_END( g_ObjectInfo )
  13. typedef struct
  14. {
  15. const CLSID *pclsid;
  16. HRESULT (STDMETHODCALLTYPE *pfnRegUnReg)(BOOL bReg, HKEY hkCLSID, LPCTSTR pszCLSID, LPCTSTR pszModule);
  17. } REGISTRATIONINFO;
  18. const REGISTRATIONINFO c_ri[] =
  19. {
  20. { &CLSID_MailRecipient, MailRecipient_RegUnReg },
  21. { &CLSID_DesktopShortcut, DesktopShortcut_RegUnReg },
  22. { NULL },
  23. };
  24. LONG g_cRefDll = 0; // reference count for this DLL
  25. HINSTANCE g_hinst = NULL; // HMODULE for this DLL
  26. // life-time manangement and registration
  27. STDAPI_(void) DllAddRef()
  28. {
  29. InterlockedIncrement(&g_cRefDll);
  30. }
  31. STDAPI_(void) DllRelease()
  32. {
  33. ASSERT( 0 != g_cRefDll );
  34. InterlockedDecrement(&g_cRefDll);
  35. }
  36. STDAPI DllCanUnloadNow(void)
  37. {
  38. return g_cRefDll == 0 ? S_OK : S_FALSE;
  39. }
  40. STDAPI_(BOOL) DllMain(HINSTANCE hDll, DWORD dwReason, LPVOID lpReserved)
  41. {
  42. if (dwReason == DLL_PROCESS_ATTACH)
  43. {
  44. g_hinst = hDll;
  45. SHFusionInitializeFromModule(hDll);
  46. DisableThreadLibraryCalls(hDll);
  47. }
  48. else if (dwReason == DLL_PROCESS_DETACH)
  49. {
  50. SHFusionUninitialize();
  51. }
  52. return TRUE;
  53. }
  54. #define INPROCSERVER32 TEXT("InProcServer32")
  55. #define CLSID TEXT("CLSID")
  56. #define THREADINGMODEL TEXT("ThreadingModel")
  57. #define APARTMENT TEXT("Apartment")
  58. #define APPROVED TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved")
  59. #define DESC TEXT("Sendmail service")
  60. STDAPI DllRegisterServer(void)
  61. {
  62. const REGISTRATIONINFO *pcls;
  63. TCHAR szPath[MAX_PATH];
  64. GetModuleFileName(g_hinst, szPath, ARRAYSIZE(szPath)); // get path to this DLL
  65. for (pcls = c_ri; pcls->pclsid; pcls++)
  66. {
  67. HKEY hkCLSID;
  68. if (RegOpenKeyEx(HKEY_CLASSES_ROOT, CLSID, 0, KEY_CREATE_SUB_KEY, &hkCLSID) == ERROR_SUCCESS)
  69. {
  70. HKEY hkOurs;
  71. LONG err;
  72. TCHAR szGUID[80];
  73. SHStringFromGUID(*pcls->pclsid, szGUID, ARRAYSIZE(szGUID));
  74. err = RegCreateKeyEx(hkCLSID, szGUID, 0, NULL, 0, KEY_CREATE_SUB_KEY, NULL, &hkOurs, NULL);
  75. if (err == ERROR_SUCCESS)
  76. {
  77. HKEY hkInproc;
  78. err = RegCreateKeyEx(hkOurs, INPROCSERVER32, 0, NULL, 0, KEY_SET_VALUE, NULL, &hkInproc, NULL);
  79. if (err == ERROR_SUCCESS)
  80. {
  81. err = RegSetValueEx(hkInproc, NULL, 0, REG_SZ, (LPBYTE)szPath, (lstrlen(szPath) + 1) * sizeof(TCHAR));
  82. if (err == ERROR_SUCCESS)
  83. {
  84. err = RegSetValueEx(hkInproc, THREADINGMODEL, 0, REG_SZ, (LPBYTE)APARTMENT, sizeof(APARTMENT));
  85. }
  86. RegCloseKey(hkInproc);
  87. }
  88. if (pcls->pfnRegUnReg)
  89. pcls->pfnRegUnReg(TRUE, hkOurs, szGUID, szPath);
  90. if (err == ERROR_SUCCESS)
  91. {
  92. HKEY hkApproved;
  93. err = RegOpenKeyEx(HKEY_LOCAL_MACHINE, APPROVED, 0, KEY_SET_VALUE, &hkApproved);
  94. if (err == ERROR_SUCCESS)
  95. {
  96. err = RegSetValueEx(hkApproved, szGUID, 0, REG_SZ, (LPBYTE)DESC, sizeof(DESC));
  97. RegCloseKey(hkApproved);
  98. }
  99. }
  100. RegCloseKey(hkOurs);
  101. }
  102. RegCloseKey(hkCLSID);
  103. if (err != ERROR_SUCCESS)
  104. return HRESULT_FROM_WIN32(err);
  105. }
  106. }
  107. return S_OK;
  108. }
  109. STDAPI DllUnregisterServer(void)
  110. {
  111. const REGISTRATIONINFO *pcls;
  112. for (pcls = c_ri; pcls->pclsid; pcls++)
  113. {
  114. HKEY hkCLSID;
  115. if (RegOpenKeyEx(HKEY_CLASSES_ROOT, CLSID, 0, KEY_CREATE_SUB_KEY, &hkCLSID) == ERROR_SUCCESS)
  116. {
  117. TCHAR szGUID[80];
  118. HKEY hkApproved;
  119. SHStringFromGUID(*pcls->pclsid, szGUID, ARRAYSIZE(szGUID));
  120. SHDeleteKey(hkCLSID, szGUID);
  121. if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, APPROVED, 0, KEY_SET_VALUE, &hkApproved) == ERROR_SUCCESS)
  122. {
  123. RegDeleteValue(hkApproved, szGUID);
  124. RegCloseKey(hkApproved);
  125. }
  126. RegCloseKey(hkCLSID);
  127. if (pcls->pfnRegUnReg)
  128. pcls->pfnRegUnReg(FALSE, NULL, szGUID, NULL);
  129. }
  130. }
  131. return S_OK;
  132. }
  133. // class factory stuff
  134. STDMETHODIMP CClassFactory::QueryInterface(REFIID riid,void**ppvObj)
  135. {
  136. if (IsEqualIID(riid, IID_IClassFactory) || IsEqualIID(riid, IID_IUnknown))
  137. {
  138. *ppvObj = (void *)GET_ICLASSFACTORY(this);
  139. DllAddRef();
  140. return NOERROR;
  141. }
  142. *ppvObj = NULL;
  143. return E_NOINTERFACE;
  144. }
  145. STDMETHODIMP_(ULONG) CClassFactory::AddRef()
  146. {
  147. DllAddRef();
  148. return 2;
  149. }
  150. STDMETHODIMP_(ULONG) CClassFactory::Release()
  151. {
  152. DllRelease();
  153. return 1;
  154. }
  155. STDMETHODIMP CClassFactory::CreateInstance(IUnknown *punkOuter, REFIID riid,void**ppv)
  156. {
  157. *ppv = NULL;
  158. if (punkOuter && !IsEqualIID(riid, IID_IUnknown))
  159. {
  160. return CLASS_E_NOAGGREGATION;
  161. }
  162. else
  163. {
  164. LPOBJECTINFO pthisobj = (LPOBJECTINFO)this;
  165. if (punkOuter) // && !(pthisobj->dwClassFactFlags & OIF_ALLOWAGGREGATION))
  166. return CLASS_E_NOAGGREGATION;
  167. IUnknown *punk;
  168. HRESULT hr = pthisobj->pfnCreateInstance(punkOuter, &punk, pthisobj);
  169. if (SUCCEEDED(hr))
  170. {
  171. hr = punk->QueryInterface(riid, ppv);
  172. punk->Release();
  173. }
  174. return hr;
  175. }
  176. }
  177. STDMETHODIMP CClassFactory::LockServer(BOOL fLock)
  178. {
  179. if (fLock)
  180. DllAddRef();
  181. else
  182. DllRelease();
  183. return S_OK;
  184. }
  185. STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid,void**ppv)
  186. {
  187. if (IsEqualIID(riid, IID_IClassFactory) || IsEqualIID(riid, IID_IUnknown))
  188. {
  189. for (LPCOBJECTINFO pcls = g_ObjectInfo; pcls->pclsid; pcls++)
  190. {
  191. if (IsEqualGUID(rclsid, *(pcls->pclsid)))
  192. {
  193. *ppv = (void*)pcls;
  194. DllAddRef(); // class factory holds DLL ref count
  195. return NOERROR;
  196. }
  197. }
  198. }
  199. *ppv = NULL;
  200. return CLASS_E_CLASSNOTAVAILABLE;
  201. }