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.

237 lines
7.0 KiB

  1. #include "precomp.hxx"
  2. #pragma hdrstop
  3. #include <shguidp.h>
  4. #include <advpub.h> // RegInstall stuff
  5. #include "util.h"
  6. #include "resource.h"
  7. #include "version.h"
  8. // {ECF03A32-103D-11d2-854D-006008059367} CLSID_MyDocsDropTarget
  9. const CLSID CLSID_MyDocsDropTarget = { 0xecf03a32, 0x103d, 0x11d2, { 0x85, 0x4d, 0x0, 0x60, 0x8, 0x5, 0x93, 0x67 } };
  10. // {ECF03A33-103D-11d2-854D-006008059367} CLSID_MyDocsCopyHook
  11. const CLSID CLSID_MyDocsCopyHook = { 0xecf03a33, 0x103d, 0x11d2, { 0x85, 0x4d, 0x0, 0x60, 0x8, 0x5, 0x93, 0x67 } };
  12. // {4a7ded0a-ad25-11d0-98a8-0800361b1103} CLSID_MyDocsProp
  13. const CLSID CLSID_MyDocsProp = {0x4a7ded0a, 0xad25, 0x11d0, 0x98, 0xa8, 0x08, 0x00, 0x36, 0x1b, 0x11, 0x03};
  14. HINSTANCE g_hInstance = 0;
  15. LONG g_cRefThisDll = 0; // DLL global reference count
  16. STDAPI_(void) DllAddRef(void)
  17. {
  18. InterlockedIncrement(&g_cRefThisDll);
  19. }
  20. STDAPI_(void) DllRelease(void)
  21. {
  22. ASSERT( 0 != g_cRefThisDll );
  23. InterlockedDecrement(&g_cRefThisDll);
  24. }
  25. STDAPI DllCanUnloadNow(void)
  26. {
  27. return g_cRefThisDll ? S_FALSE : S_OK;
  28. }
  29. HRESULT CMyDocsCopyHook_CreateInstance(IUnknown *punkOuter, IUnknown **ppunk, LPCOBJECTINFO poi);
  30. HRESULT CMyDocsSendTo_CreateInstance(IUnknown *punkOuter, IUnknown **ppunk, LPCOBJECTINFO poi);
  31. HRESULT CMyDocsProp_CreateInstance(IUnknown *punkOuter, IUnknown **ppunk, LPCOBJECTINFO poi);
  32. CF_TABLE_BEGIN(g_ObjectInfo)
  33. CF_TABLE_ENTRY(&CLSID_MyDocsCopyHook, CMyDocsCopyHook_CreateInstance, COCREATEONLY),
  34. CF_TABLE_ENTRY(&CLSID_MyDocsDropTarget, CMyDocsSendTo_CreateInstance, COCREATEONLY),
  35. CF_TABLE_ENTRY(&CLSID_MyDocsProp, CMyDocsProp_CreateInstance, COCREATEONLY),
  36. CF_TABLE_END(g_ObjectInfo)
  37. STDMETHODIMP CClassFactory::QueryInterface(REFIID riid, void **ppvObj)
  38. {
  39. if (IsEqualIID(riid, IID_IClassFactory) || IsEqualIID(riid, IID_IUnknown))
  40. {
  41. *ppvObj = (void *)GET_ICLASSFACTORY(this);
  42. DllAddRef();
  43. return NOERROR;
  44. }
  45. *ppvObj = NULL;
  46. return E_NOINTERFACE;
  47. }
  48. STDMETHODIMP_(ULONG) CClassFactory::AddRef()
  49. {
  50. DllAddRef();
  51. return 2;
  52. }
  53. STDMETHODIMP_(ULONG) CClassFactory::Release()
  54. {
  55. DllRelease();
  56. return 1;
  57. }
  58. STDMETHODIMP CClassFactory::CreateInstance(IUnknown *punkOuter, REFIID riid, void **ppv)
  59. {
  60. *ppv = NULL;
  61. if (punkOuter && !IsEqualIID(riid, IID_IUnknown))
  62. {
  63. return CLASS_E_NOAGGREGATION;
  64. }
  65. else
  66. {
  67. LPOBJECTINFO pthisobj = (LPOBJECTINFO)this;
  68. if (punkOuter) // && !(pthisobj->dwClassFactFlags & OIF_ALLOWAGGREGATION))
  69. return CLASS_E_NOAGGREGATION;
  70. IUnknown *punk;
  71. HRESULT hr = pthisobj->pfnCreateInstance(punkOuter, &punk, pthisobj);
  72. if (SUCCEEDED(hr))
  73. {
  74. hr = punk->QueryInterface(riid, ppv);
  75. punk->Release();
  76. }
  77. return hr;
  78. }
  79. }
  80. STDMETHODIMP CClassFactory::LockServer(BOOL fLock)
  81. {
  82. if (fLock)
  83. DllAddRef();
  84. else
  85. DllRelease();
  86. return S_OK;
  87. }
  88. STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppv)
  89. {
  90. if (IsEqualIID(riid, IID_IClassFactory) || IsEqualIID(riid, IID_IUnknown))
  91. {
  92. for (LPCOBJECTINFO pcls = g_ObjectInfo; pcls->pclsid; pcls++)
  93. {
  94. if (IsEqualGUID(rclsid, *(pcls->pclsid)))
  95. {
  96. *ppv = (void*)pcls;
  97. DllAddRef(); // class factory holds DLL ref count
  98. return NOERROR;
  99. }
  100. }
  101. }
  102. *ppv = NULL;
  103. return CLASS_E_CLASSNOTAVAILABLE;
  104. }
  105. // Call ADVPACK for the given section of our resource based INF>
  106. // hInstance = resource instance to get REGINST section from
  107. // szSection = section name to invoke
  108. HRESULT CallRegInstall(HINSTANCE hInstance, LPCSTR szSection)
  109. {
  110. HRESULT hr = E_FAIL;
  111. HINSTANCE hinstAdvPack = LoadLibrary(TEXT("ADVPACK.DLL"));
  112. if (hinstAdvPack)
  113. {
  114. REGINSTALL pfnri = (REGINSTALL)GetProcAddress(hinstAdvPack, "RegInstall");
  115. if (pfnri)
  116. {
  117. STRENTRY seReg[] =
  118. {
  119. // These two NT-specific entries must be at the end
  120. { "25", "%SystemRoot%" },
  121. { "11", "%SystemRoot%\\system32" },
  122. };
  123. STRTABLE stReg = { ARRAYSIZE(seReg), seReg };
  124. hr = pfnri(hInstance, szSection, &stReg);
  125. }
  126. FreeLibrary(hinstAdvPack);
  127. }
  128. return hr;
  129. }
  130. // export that ie4unit.exe calls at per user install time
  131. // this lets us execute code instead of depending on the "DefaultUser" template
  132. // that is used to init new accounts. this deals with upgrade cases too, very important
  133. STDAPI_(void) PerUserInit(void)
  134. {
  135. TCHAR szPath[MAX_PATH];
  136. SHGetFolderPath(NULL, CSIDL_PERSONAL | CSIDL_FLAG_CREATE | CSIDL_FLAG_PER_USER_INIT, NULL, SHGFP_TYPE_CURRENT, szPath);
  137. // Don't install these guys on server builds
  138. if (!IsOS(OS_ANYSERVER))
  139. {
  140. SHGetFolderPath(NULL, CSIDL_MYPICTURES | CSIDL_FLAG_CREATE | CSIDL_FLAG_PER_USER_INIT, NULL, SHGFP_TYPE_CURRENT, szPath);
  141. SHGetFolderPath(NULL, CSIDL_MYMUSIC | CSIDL_FLAG_CREATE | CSIDL_FLAG_PER_USER_INIT, NULL, SHGFP_TYPE_CURRENT, szPath);
  142. }
  143. UpdateSendToFile();
  144. }
  145. STDAPI DllRegisterServer(void)
  146. {
  147. CallRegInstall(g_hInstance, "RegDll");
  148. return S_OK;
  149. }
  150. STDAPI DllUnregisterServer(void)
  151. {
  152. CallRegInstall(g_hInstance, "UnregDll");
  153. return S_OK;
  154. }
  155. STDAPI DllInstall(BOOL bInstall, LPCWSTR pszCmdLine)
  156. {
  157. if (pszCmdLine && *pszCmdLine)
  158. {
  159. if (0 == StrCmpIW(pszCmdLine, L"UseReadOnly"))
  160. {
  161. // Add key for system to use read only bit on shell folders...
  162. HKEY hkey;
  163. if (ERROR_SUCCESS == RegCreateKeyEx(HKEY_LOCAL_MACHINE, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer"),
  164. 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, NULL))
  165. {
  166. if (bInstall)
  167. {
  168. DWORD dwValue = 1;
  169. RegSetValueEx(hkey, TEXT("UseReadOnlyForSystemFolders"), 0, REG_DWORD, (LPBYTE)&dwValue, sizeof(dwValue));
  170. }
  171. else
  172. {
  173. RegDeleteValue(hkey, TEXT("UseReadOnlyForSystemFolders"));
  174. }
  175. RegCloseKey(hkey);
  176. }
  177. }
  178. else if (0 == StrCmpIW(pszCmdLine, L"U"))
  179. {
  180. // not currently used, but for testing (and consistency with shell32.dll)
  181. // REGSVR32.EXE /n /i:U mydocs.dll
  182. PerUserInit();
  183. }
  184. }
  185. return S_OK;
  186. }
  187. STDAPI_(BOOL) DllMain(HINSTANCE hInstance, DWORD dwReason, void *pReserved)
  188. {
  189. switch (dwReason)
  190. {
  191. case DLL_PROCESS_ATTACH:
  192. g_hInstance = hInstance;
  193. DisableThreadLibraryCalls(hInstance);
  194. SHFusionInitializeFromModule(hInstance);
  195. break;
  196. case DLL_PROCESS_DETACH:
  197. SHFusionUninitialize();
  198. break;
  199. }
  200. return TRUE;
  201. }