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.

230 lines
6.7 KiB

  1. // stdafx.cpp : source file that includes just the standard includes
  2. // stdafx.pch will be the pre-compiled header
  3. // stdafx.obj will contain the pre-compiled type information
  4. #include "stdafx.h"
  5. #ifdef _ATL_STATIC_REGISTRY
  6. #include <statreg.h>
  7. #include <statreg.cpp>
  8. #endif
  9. #include <atlimpl.cpp>
  10. #include "ShellExtensions.h"
  11. #include "strsafe.h"
  12. typedef DWORD (*PFNSHDeleteKeyW)(HKEY hkey, LPWSTR pszSubkey);
  13. HRESULT WINAPI
  14. CLayerUIModule::UpdateRegistryCLSID(
  15. const CLSID& clsid,
  16. BOOL bRegister
  17. )
  18. {
  19. static const TCHAR szIPS32[] = _T("InprocServer32");
  20. static const TCHAR szCLSID[] = _T("CLSID");
  21. static const TCHAR szPropPageExt[] = _T("ShimLayer Property Page");
  22. HRESULT hRes = S_OK;
  23. HRESULT hr = S_OK;
  24. LPOLESTR lpOleStrCLSIDValue = NULL;
  25. if (clsid != CLSID_ShimLayerPropertyPage) {
  26. LogMsg(_T("[UpdateRegistryCLSID] unknown CLSID!\n"));
  27. return E_FAIL;
  28. }
  29. hr = ::StringFromCLSID(clsid, &lpOleStrCLSIDValue);
  30. if (hr != S_OK) {
  31. LogMsg(_T("[UpdateRegistryCLSID] can't get string from CLSID!\n"));
  32. return E_FAIL;
  33. }
  34. HKEY hkey = NULL;
  35. LONG lRes;
  36. if (bRegister) {
  37. TCHAR szBuffer[MAX_PATH];
  38. DWORD keyType = 0;
  39. //
  40. // Write the key for registration. Include the value to specify
  41. // the threading model.
  42. //
  43. StringCchPrintf(szBuffer, ARRAYSIZE(szBuffer), _T("%s\\%s\\%s"), szCLSID, lpOleStrCLSIDValue, szIPS32);
  44. lRes = RegCreateKey(HKEY_CLASSES_ROOT, szBuffer, &hkey);
  45. if (lRes != ERROR_SUCCESS) {
  46. LogMsg(_T("[UpdateRegistryCLSID] failed to open/create \"%s\"\n"),
  47. szBuffer);
  48. goto Exit;
  49. }
  50. ::GetModuleFileName(m_hInst, szBuffer, MAX_PATH);
  51. lRes = RegSetValueEx(hkey,
  52. NULL,
  53. 0,
  54. REG_SZ,
  55. (BYTE*)szBuffer,
  56. (lstrlen(szBuffer) + 1) * sizeof(TCHAR));
  57. if (lRes != ERROR_SUCCESS) {
  58. LogMsg(_T("[UpdateRegistryCLSID] failed to write value \"%s\"\n"),
  59. szBuffer);
  60. goto Exit;
  61. }
  62. lRes = RegSetValueEx(hkey,
  63. _T("ThreadingModel"),
  64. 0,
  65. REG_SZ,
  66. (BYTE*)_T("Apartment"),
  67. sizeof(_T("Apartment")));
  68. if (lRes != ERROR_SUCCESS) {
  69. LogMsg(_T("[UpdateRegistryCLSID] failed to write \"ThreadingModel\"\n"));
  70. goto Exit;
  71. }
  72. RegCloseKey(hkey);
  73. hkey = NULL;
  74. //
  75. // Open the key with the name of the .exe extension and
  76. // add the keys to support the shell extensions.
  77. //
  78. StringCchPrintf(szBuffer,
  79. ARRAYSIZE(szBuffer),
  80. _T("lnkfile\\shellex\\PropertySheetHandlers\\%s"),
  81. szPropPageExt);
  82. lRes = RegCreateKey(HKEY_CLASSES_ROOT, szBuffer, &hkey);
  83. if (lRes != ERROR_SUCCESS) {
  84. goto Exit;
  85. }
  86. lRes = RegSetValueEx(hkey,
  87. NULL,
  88. 0,
  89. REG_SZ,
  90. (BYTE*)lpOleStrCLSIDValue,
  91. (lstrlen(lpOleStrCLSIDValue) + 1) * sizeof(TCHAR));
  92. if (lRes != ERROR_SUCCESS) {
  93. LogMsg(_T("[UpdateRegistryCLSID] failed to add the shell extension handler\n"));
  94. goto Exit;
  95. }
  96. RegCloseKey(hkey);
  97. hkey = NULL;
  98. //
  99. // Now add the shell extension to the approved list.
  100. //
  101. lRes = RegCreateKey(HKEY_LOCAL_MACHINE,
  102. _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved"),
  103. &hkey);
  104. if (lRes != ERROR_SUCCESS) {
  105. LogMsg(_T("[UpdateRegistryCLSID] failed to approve the shell extension handler\n"));
  106. goto Exit;
  107. }
  108. lRes = RegSetValueEx(hkey,
  109. lpOleStrCLSIDValue,
  110. 0,
  111. REG_SZ,
  112. (BYTE*)szPropPageExt,
  113. sizeof(szPropPageExt));
  114. if (lRes != ERROR_SUCCESS) {
  115. LogMsg(_T("[UpdateRegistryCLSID] failed to approve the shell extension handler\n"));
  116. goto Exit;
  117. }
  118. Exit:
  119. if (hkey != NULL) {
  120. RegCloseKey(hkey);
  121. hkey = NULL;
  122. }
  123. hRes = HRESULT_FROM_WIN32(lRes);
  124. } else {
  125. //
  126. // Time to clean up.
  127. //
  128. PFNSHDeleteKeyW pfnSHDeleteKey;
  129. HMODULE hmod = LoadLibrary(_T("Shlwapi.dll"));
  130. if (hmod == NULL) {
  131. LogMsg(_T("[UpdateRegistryCLSID] failed to load Shlwapi.dll\n"));
  132. return E_FAIL;
  133. }
  134. pfnSHDeleteKey = (PFNSHDeleteKeyW)GetProcAddress(hmod, "SHDeleteKeyW");
  135. if (pfnSHDeleteKey == NULL) {
  136. FreeLibrary(hmod);
  137. LogMsg(_T("[UpdateRegistryCLSID] cannot get Shlwapi!SHDeleteKeyW\n"));
  138. return E_FAIL;
  139. }
  140. lRes = RegOpenKey(HKEY_CLASSES_ROOT, szCLSID, &hkey);
  141. if (lRes == ERROR_SUCCESS) {
  142. (*pfnSHDeleteKey)(hkey, lpOleStrCLSIDValue);
  143. RegCloseKey(hkey);
  144. hkey = NULL;
  145. }
  146. lRes = RegOpenKey(HKEY_CLASSES_ROOT, _T("lnkfile\\shellex"), &hkey);
  147. if (lRes == ERROR_SUCCESS) {
  148. (*pfnSHDeleteKey)(hkey, _T("PropertySheetHandlers\\ShimLayer Property Page"));
  149. RegCloseKey(hkey);
  150. hkey = NULL;
  151. }
  152. lRes = RegOpenKey(HKEY_LOCAL_MACHINE,
  153. _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved"),
  154. &hkey);
  155. if (lRes == ERROR_SUCCESS) {
  156. RegDeleteValue(hkey, lpOleStrCLSIDValue);
  157. RegCloseKey(hkey);
  158. hkey = NULL;
  159. }
  160. FreeLibrary(hmod);
  161. }
  162. //
  163. // Delete the layer storage.
  164. //
  165. InitLayerStorage(TRUE);
  166. //
  167. // Notify the shell of our changes
  168. //
  169. SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL);
  170. if (lpOleStrCLSIDValue) {
  171. ::CoTaskMemFree(lpOleStrCLSIDValue);
  172. }
  173. return hRes;
  174. }