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.

333 lines
9.7 KiB

  1. // This file specilizes two function for IEHardUser subcomponent.
  2. // the change basically takes care of exclusion cases with TS.
  3. // 1) when the IEHardUser component is installed the 1st time, this change will turn if off, if termsrv is also being installed.
  4. // 2) 2nd change in query selection of IeHardenUser, this change will prompt user about the incompatibility.
  5. //
  6. #include <stdlib.h>
  7. #include <assert.h>
  8. #include <tchar.h>
  9. #include <objbase.h>
  10. #include <shlwapi.h>
  11. #include <lm.h>
  12. #include "ocgen.h"
  13. const TCHAR TERMINAL_SERVER_COMPONENT[] = TEXT("TerminalServer");
  14. const TCHAR IEHARDEN_USER_SUBCOMPONENT[] = TEXT("IEHardenUser");
  15. const TCHAR IEHARDEN_COMPONENT[] = TEXT("IEHarden");
  16. PPER_COMPONENT_DATA LocateComponent(LPCTSTR ComponentId);
  17. /*
  18. * Defaults for IEharduser as decided by Mode=... in ieharden.inf files are ON for all installations.
  19. * it means, the component will be ON for all configs.
  20. * But TerminalServer really want this component to be off, if terminal server is selected.
  21. * Here is a matrix for this component
  22. if (was installed previously)
  23. {
  24. // keep the original setting. goto Done.
  25. Q:Do we need to turn it off if TS is selected through AnswerFile?
  26. }
  27. else
  28. {
  29. if (Attended Setup)
  30. {
  31. //
  32. // we cant do much in this case. as administrator can decide for himself this component's setting.
  33. // terminal will just warn him about the recommended setting for this component.
  34. //
  35. }
  36. else
  37. {
  38. //
  39. // if this is fresh install for this component (this is new compoent)
  40. // we have to choose defaults depending on the terminal server state.
  41. //
  42. if (Terminal server is going to be installed / or retained)
  43. {
  44. // our defaults for this component is OFF.
  45. }
  46. else
  47. {
  48. // let ocmanager choose the defaults per inf file of this component
  49. }
  50. }
  51. }
  52. *
  53. *
  54. *
  55. * here we apply all the logic above in query state.
  56. *
  57. */
  58. DWORD MsgBox(HWND hwnd, UINT textID, UINT type, ... );
  59. DWORD MsgBox(HWND hwnd, UINT textID, UINT captioniID, UINT type, ... );
  60. BOOL ReadStringFromAnsewerFile (LPCTSTR ComponentId, LPCTSTR szSection, LPCTSTR szKey, LPTSTR szValue, DWORD dwBufferSize)
  61. {
  62. assert(szSection);
  63. assert(szKey);
  64. assert(szValue);
  65. assert(dwBufferSize > 0);
  66. PPER_COMPONENT_DATA cd;
  67. if (!(cd = LocateComponent(ComponentId)))
  68. return FALSE;
  69. HINF hInf = cd->HelperRoutines.GetInfHandle(INFINDEX_UNATTENDED,cd->HelperRoutines.OcManagerContext);
  70. if (hInf)
  71. {
  72. INFCONTEXT InfContext;
  73. if (SetupFindFirstLine(hInf, szSection, szKey, &InfContext))
  74. {
  75. return SetupGetStringField (&InfContext, 1, szValue, dwBufferSize, NULL);
  76. }
  77. }
  78. return FALSE;
  79. }
  80. BOOL StateSpecifiedInAnswerFile(LPCTSTR ComponentId, LPCTSTR SubcomponentId, BOOL *pbState)
  81. {
  82. TCHAR szBuffer[256];
  83. if (ReadStringFromAnsewerFile(ComponentId, _T("Components"), SubcomponentId, szBuffer, 256))
  84. {
  85. *pbState = (0 == _tcsicmp(_T("on"), szBuffer));
  86. return TRUE;
  87. }
  88. return FALSE;
  89. }
  90. BOOL IsNewComponent(LPCTSTR ComponentId, LPCTSTR SubcomponentId)
  91. {
  92. static BOOL sbNewComponent = TRUE;
  93. static BOOL sbCalledOnce = FALSE;
  94. DWORD dwError, Type;
  95. HKEY hKey;
  96. if (!sbCalledOnce)
  97. {
  98. sbCalledOnce = TRUE;
  99. if (NO_ERROR == (dwError = RegOpenKeyEx(
  100. HKEY_LOCAL_MACHINE,
  101. TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup\\OC Manager\\Subcomponents"),
  102. 0,
  103. KEY_QUERY_VALUE,
  104. &hKey)))
  105. {
  106. DWORD dwInstalled;
  107. DWORD dwBufferSize = sizeof (dwInstalled);
  108. dwError = RegQueryValueEx(
  109. hKey,
  110. SubcomponentId,
  111. NULL,
  112. &Type,
  113. (LPBYTE)&dwInstalled,
  114. &dwBufferSize);
  115. if (dwError == NOERROR)
  116. {
  117. //
  118. // since the registry already exists for this.
  119. // this is not a new component.
  120. //
  121. sbNewComponent = FALSE;
  122. }
  123. RegCloseKey(hKey);
  124. }
  125. }
  126. return sbNewComponent;
  127. }
  128. BOOL IsTerminalServerGettingInstalled(LPCTSTR ComponentId)
  129. {
  130. PPER_COMPONENT_DATA cd;
  131. if (!(cd = LocateComponent(ComponentId)))
  132. return FALSE;
  133. return(
  134. cd->HelperRoutines.QuerySelectionState(
  135. cd->HelperRoutines.OcManagerContext,
  136. TERMINAL_SERVER_COMPONENT,
  137. OCSELSTATETYPE_CURRENT
  138. )
  139. );
  140. }
  141. BOOL IsStandAlone(LPCTSTR ComponentId)
  142. {
  143. PPER_COMPONENT_DATA cd;
  144. if (!(cd = LocateComponent(ComponentId)))
  145. return FALSE;
  146. return (cd->Flags & SETUPOP_STANDALONE ? TRUE : FALSE);
  147. }
  148. DWORD OnQueryStateIEHardenUser(
  149. LPCTSTR ComponentId,
  150. LPCTSTR SubcomponentId,
  151. UINT state)
  152. {
  153. BOOL bState;
  154. switch (state)
  155. {
  156. case OCSELSTATETYPE_ORIGINAL:
  157. case OCSELSTATETYPE_FINAL:
  158. return SubcompUseOcManagerDefault;
  159. break;
  160. case OCSELSTATETYPE_CURRENT:
  161. log(_T("makarp:OnQueryStateIEHardenUser:OCSELSTATETYPE_CURRENT\n"));
  162. //
  163. // if this is not the first time installation of this component let OCM decide.
  164. //
  165. if (!IsNewComponent(ComponentId, SubcomponentId))
  166. {
  167. log(_T("makarp:OnQueryStateIEHardenUser: it's not a newcomp. returning\n"));
  168. return SubcompUseOcManagerDefault;
  169. }
  170. //
  171. // if admin explicitely choose state in answer file, respect that.
  172. //
  173. if (StateSpecifiedInAnswerFile(ComponentId, SubcomponentId, &bState))
  174. {
  175. log(_T("makarp:OnQueryStateIEHardenUser: state is specified in anserer file(%s). returning\n"), bState? _T("On") : _T("Off"));
  176. return SubcompUseOcManagerDefault;
  177. }
  178. //
  179. // if terminal server is not selected, let OCM decide.
  180. //
  181. if (!IsTerminalServerGettingInstalled(ComponentId))
  182. {
  183. log(_T("makarp:OnQueryStateIEHardenUser: ts comp is not on selected, returning\n"));
  184. return SubcompUseOcManagerDefault;
  185. }
  186. if (IsStandAlone(ComponentId))
  187. {
  188. log(_T("makarp:its standalone\n"));
  189. assert(FALSE); // if its add remove program setup, this cannot be NewComponent
  190. return SubcompUseOcManagerDefault;
  191. }
  192. log(_T("makarp:OnQueryStateIEHardenUser: this the case we want to catch - returning SubcompOff\n"));
  193. return SubcompOff;
  194. default:
  195. assert(FALSE);
  196. return ERROR_BAD_ARGUMENTS;
  197. }
  198. }
  199. DWORD OnQuerySelStateChangeIEHardenUser(LPCTSTR ComponentId,
  200. LPCTSTR SubcomponentId,
  201. UINT state,
  202. UINT flags)
  203. {
  204. HWND hWnd;
  205. PPER_COMPONENT_DATA cd;
  206. BOOL bDirectSelection = flags & OCQ_ACTUAL_SELECTION;
  207. //
  208. // if the component is not turning on as a result of selection, we dont care
  209. //
  210. if (!state)
  211. {
  212. log(_T("makarp:OnQuerySelStateChangeIEHardenUser: new state is off, returning\n"));
  213. return TRUE;
  214. }
  215. //
  216. // TerminalServer is not recommended with IEHardUser component. Lets notify user about it.
  217. //
  218. if (!(cd = LocateComponent(ComponentId)))
  219. {
  220. log(_T("makarp:OnQuerySelStateChangeIEHardenUser: LocateComponentit failed, returning\n"));
  221. return TRUE; // if we fail to load this, just let selection go through.
  222. }
  223. if (!IsTerminalServerGettingInstalled(ComponentId))
  224. {
  225. //
  226. // if terminal server component is not getting installed, then its ok.
  227. //
  228. log(_T("makarp:OnQuerySelStateChangeIEHardenUser: TS is not selected, returning\n"));
  229. return TRUE;
  230. }
  231. hWnd = cd->HelperRoutines.QueryWizardDialogHandle(cd->HelperRoutines.OcManagerContext);
  232. // HACK...
  233. // For some weird reasons we get called twice if the selection comes from top level component.
  234. // we dont want to shot the message box twice though. the hacky fix i found was to always skip the 1st message we get
  235. // and return TRUE TO IT. we will subsequently get one more message, show messagebox on the 2nd message and return the real
  236. // value.
  237. //
  238. static BOOL sbSkipNextMessage = true;
  239. if (sbSkipNextMessage)
  240. {
  241. log(_T("DirectSelection = %s, SKIPPING true\n"), bDirectSelection ? _T("true") : _T("false"));
  242. sbSkipNextMessage = false;
  243. return TRUE;
  244. }
  245. sbSkipNextMessage = true;
  246. //
  247. // information about exclusion
  248. // IDS_IEHARD_EXCLUDES_TS "Internet Explorer Enhanced Security for Users on a Terminal Server will substantially limit the users ability to browse the internet from their Terminal Server sessions\n\nContinue the install with this combination?"
  249. //
  250. int iMsg = MsgBox(hWnd, IDS_IEHARD_EXCLUDES_TS, IDS_DIALOG_CAPTION_CONFIG_WARN, MB_YESNO | MB_ICONEXCLAMATION);
  251. if (iMsg == IDYES)
  252. {
  253. log(_T("DirectSelection = %s, returning true\n"), bDirectSelection ? _T("true") : _T("false"));
  254. return TRUE;
  255. }
  256. else
  257. {
  258. log(_T("DirectSelection = %s, returning false\n"), bDirectSelection ? _T("true") : _T("false"));
  259. return FALSE;
  260. }
  261. assert(false);
  262. }