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.

221 lines
9.0 KiB

  1. /*--------------------------------------------------------------------------*
  2. *
  3. * Microsoft Windows
  4. * Copyright (C) Microsoft Corporation, 1992 - 00
  5. *
  6. * File: classreg.cpp
  7. *
  8. * Contents: Class registration code
  9. *
  10. * History: 3-Feb-2000 jeffro Created
  11. *
  12. *--------------------------------------------------------------------------*/
  13. #include "stdafx.h"
  14. #ifdef DBG
  15. CTraceTag tagDllRegistration (_T("MMC Dll Registration"), _T("MMC Dll Registration"));
  16. #endif //DBG
  17. /*+-------------------------------------------------------------------------*
  18. * szObjScript
  19. *
  20. * Standard registration script template for all objects. '%' characters
  21. * that we want to end up in the final script must be doubled (i.e. "%%")
  22. * because this string is used as a format string for sprintf. sprintf
  23. * will convert "%%" to "%" during formatting.
  24. *--------------------------------------------------------------------------*/
  25. static const WCHAR szObjScript[] =
  26. L"HKCR" L"\n"
  27. L"{" L"\n"
  28. L" %%VProgID%% = s '%%VClassName%%'" L"\n"
  29. L" {" L"\n"
  30. L" CLSID = s '%%VCLSID%%'" L"\n"
  31. L" }" L"\n"
  32. L" %%VVersionIndependentProgID%% = s '%%VClassName%%'" L"\n"
  33. L" {" L"\n"
  34. L" CLSID = s '%%VCLSID%%'" L"\n"
  35. L" CurVer = s '%%VProgID%%'" L"\n"
  36. L" }" L"\n"
  37. L" NoRemove CLSID" L"\n"
  38. L" {" L"\n"
  39. L" ForceRemove %%VCLSID%% = s '%%VClassName%%'" L"\n"
  40. L" {" L"\n"
  41. L" ProgID = s '%%VProgID%%'" L"\n"
  42. L" VersionIndependentProgID = s '%%VVersionIndependentProgID%%'" L"\n"
  43. L" %%ServerType%% = s '%%VFileName%%'" L"\n"
  44. L" {" L"\n"
  45. L" val ThreadingModel = s 'Apartment'" L"\n"
  46. L" }" L"\n"
  47. L" %s" /* szCtlScript substituted here if necessary */ L"\n"
  48. L" }" L"\n"
  49. L" }" L"\n"
  50. L"}";
  51. /*+-------------------------------------------------------------------------*
  52. * szCtlScript
  53. *
  54. * Additional registration script elements for controls. Note that '%'
  55. * characters we want to end up in the final script DO NOT need to be
  56. * doubled, because this string is used as a sprintf replacement parameter
  57. * (which are substituted as-is) and not the format string (where "%%"'s
  58. * are converted to "%").
  59. *--------------------------------------------------------------------------*/
  60. static const WCHAR szCtlScript[] =
  61. L" ForceRemove 'Programmable'" L"\n"
  62. L" ForceRemove 'Control'" L"\n"
  63. L" ForceRemove 'ToolboxBitmap32' = s '%VFileName%, %VBitmapID%'" L"\n"
  64. L" 'MiscStatus' = s '0'" L"\n"
  65. L" {" L"\n"
  66. L" '1' = s '131473'" L"\n"
  67. L" }" L"\n"
  68. L" 'TypeLib' = s '%VLIBID%'" L"\n"
  69. L" 'Version' = s '%VVersion%'";
  70. /*+-------------------------------------------------------------------------*
  71. * MMCUpdateRegistry
  72. *
  73. * Registers a COM object or control. This function typically isn't used
  74. * directly, but indirectly via DECLARE_MMC_OBJECT_REGISTRATION or
  75. * DECLARE_MMC_CONTROL_REGISTRATION.
  76. *
  77. * This function uses a class (ATL::CRegObject) that ATL only documents
  78. * indirectly. Search MSDN for "StringRegister" to find sketchy details.
  79. *--------------------------------------------------------------------------*/
  80. HRESULT WINAPI MMCUpdateRegistry (
  81. BOOL bRegister, // I:register or unregister?
  82. const CObjectRegParams* pObjParams, // I:object registration parameters
  83. const CControlRegParams* pCtlParams) // I:control registration parameters (optional)
  84. {
  85. DECLARE_SC(sc, TEXT("MMCUpdateRegistry"));
  86. /*
  87. * validate required inputs
  88. */
  89. sc = ScCheckPointers (pObjParams, E_FAIL);
  90. if(sc)
  91. return sc.ToHr();
  92. /*
  93. * string-ify the CLSID
  94. */
  95. CCoTaskMemPtr<WCHAR> spszClsid;
  96. sc = StringFromCLSID (pObjParams->m_clsid, &spszClsid);
  97. if (sc)
  98. return sc.ToHr();
  99. #ifdef _ATL_NAMESPACE_BUG_FIXED
  100. ::ATL::CRegObject ro; // hack around nested namespace bug in ATL30
  101. #else
  102. /*
  103. * specify the standard object substitution parameters for CRegObject
  104. */
  105. ::ATL::ATL::CRegObject ro; // hack around nested namespace bug in ATL30
  106. #endif
  107. _ATL_REGMAP_ENTRY rgObjEntries[] =
  108. {
  109. { L"VCLSID", spszClsid },
  110. { L"VFileName", pObjParams->m_strModuleName.data() },
  111. { L"VClassName", pObjParams->m_strClassName.data() },
  112. { L"VProgID", pObjParams->m_strProgID.data() },
  113. { L"VVersionIndependentProgID", pObjParams->m_strVersionIndependentProgID.data() },
  114. { L"ServerType", pObjParams->m_strServerType.data() },
  115. };
  116. #ifdef DBG
  117. std::wstring strReplacements;
  118. #endif
  119. for (int i = 0; i < countof (rgObjEntries); i++)
  120. {
  121. sc = ro.AddReplacement (rgObjEntries[i].szKey, rgObjEntries[i].szData);
  122. if (sc)
  123. return (sc.ToHr());
  124. AddReplacementTrace (strReplacements,
  125. rgObjEntries[i].szKey,
  126. rgObjEntries[i].szData);
  127. }
  128. /*
  129. * if we're registering a control, add its substitution parameters for CRegObject
  130. */
  131. if (pCtlParams != NULL)
  132. {
  133. /*
  134. * string-ify the LIBID
  135. */
  136. CCoTaskMemPtr<WCHAR> spszLibid;
  137. sc = StringFromCLSID (pCtlParams->m_libid, &spszLibid);
  138. if (sc)
  139. return (sc.ToHr());
  140. _ATL_REGMAP_ENTRY rgCtlEntries[] =
  141. {
  142. { L"VLIBID", spszLibid },
  143. { L"VBitmapID", pCtlParams->m_strToolboxBitmapID.data() },
  144. { L"VVersion", pCtlParams->m_strVersion.data() },
  145. };
  146. for (int i = 0; i < countof (rgCtlEntries); i++)
  147. {
  148. sc = ro.AddReplacement (rgCtlEntries[i].szKey, rgCtlEntries[i].szData);
  149. if (sc)
  150. return (sc.ToHr());
  151. AddReplacementTrace (strReplacements,
  152. rgCtlEntries[i].szKey,
  153. rgCtlEntries[i].szData);
  154. }
  155. }
  156. /*
  157. * format the registration script
  158. */
  159. WCHAR szRegScript[countof(szObjScript) + countof(szCtlScript)];
  160. sc = StringCchPrintfW(szRegScript, countof(szRegScript), szObjScript, (pCtlParams != NULL) ? szCtlScript : L"");
  161. if (sc)
  162. return sc.ToHr();
  163. USES_CONVERSION;
  164. Trace (tagDllRegistration, _T("Registration script:\n%s"), W2T(szRegScript));
  165. Trace (tagDllRegistration, W2CT(strReplacements.data()));
  166. /*
  167. * (un)register!
  168. */
  169. sc = (bRegister) ? ro.StringRegister (szRegScript)
  170. : ro.StringUnregister (szRegScript);
  171. if (sc)
  172. return sc.ToHr();
  173. // change the module path to the absolute one, if we know it
  174. if ( bRegister && pObjParams->m_strModulePath.length() != 0 )
  175. {
  176. // format class ID key.
  177. tstring strKey = tstring(_T("CLSID\\")) + W2CT( spszClsid );
  178. strKey += tstring(_T("\\")) + W2CT( pObjParams->m_strServerType.c_str() );
  179. // see what type of value we need to put
  180. DWORD dwValueType = CModulePath::PlatformSupports_REG_EXPAND_SZ_Values() ?
  181. REG_EXPAND_SZ : REG_SZ;
  182. CRegKey keyServer;
  183. LONG lRet = keyServer.Open(HKEY_CLASSES_ROOT, strKey.c_str() , KEY_WRITE);
  184. if (lRet == ERROR_SUCCESS)
  185. {
  186. RegSetValueEx( keyServer, NULL, 0, dwValueType,
  187. (CONST BYTE *)( W2CT( pObjParams->m_strModulePath.c_str() ) ),
  188. (pObjParams->m_strModulePath.length() + 1) * sizeof(TCHAR) );
  189. }
  190. }
  191. return sc.ToHr();
  192. }