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.

409 lines
11 KiB

  1. /*++
  2. Copyright (c) 2000-2002 Microsoft Corporation
  3. Module Name:
  4. AOLFindBundledInstaller_Shim.cpp
  5. Abstract:
  6. This shim is to provide a way to verify existance of
  7. America Online bundled in OEM machines when user runs older
  8. version of AOL/CS program (waol.exe or wcs2000.exe) or setup.
  9. If it exists, it will provide Apphelp dialog to tell user that
  10. there is newer America Online installer available.
  11. If user chose "Run this program", shim will launch the bundled installer.
  12. If user chose "Cancel", then shim will continue with current process.
  13. Apphelp dialog only get displayed if LocateInstaller function says to do so.
  14. History:
  15. 04/30/2001 markder Created
  16. 05/16/2001 andyseti Implemented LocateInstaller and ApphelpShowDialog.
  17. 03/07/2002 robkenny Security changes
  18. --*/
  19. #include "precomp.h"
  20. #include <Softpub.h>
  21. #include <WinCrypt.h>
  22. #include <WinTrust.h>
  23. #include "AOLFindBundledInstaller_AOLCode.h"
  24. IMPLEMENT_SHIM_BEGIN(AOLFindBundledInstaller)
  25. #include "ShimHookMacro.h"
  26. #include "shimdb.h"
  27. APIHOOK_ENUM_BEGIN
  28. APIHOOK_ENUM_ENTRY(GetCommandLineA)
  29. APIHOOK_ENUM_ENTRY(GetStartupInfoA)
  30. APIHOOK_ENUM_ENTRY(GetModuleFileNameA)
  31. APIHOOK_ENUM_ENTRY(CreateWindowExA)
  32. APIHOOK_ENUM_END
  33. #define MAX_PARAM 4
  34. BOOL g_bDoneIt = FALSE;
  35. CString g_csHTMLHelpID_BundledFound;
  36. CString g_csHTMLHelpID_Incompatible;
  37. DWORD g_dwHTMLHelpID_BundledFound = 0;
  38. DWORD g_dwHTMLHelpID_Incompatible = 0;
  39. CString g_csAppName;
  40. CString g_csGUID;
  41. #define APPHELP_DIALOG_FAILED ((DWORD)-1)
  42. // from sdbapi\shimdb.w
  43. /*
  44. typedef struct _APPHELP_INFO {
  45. //
  46. // html help id mode
  47. //
  48. DWORD dwHtmlHelpID; // html help id
  49. DWORD dwSeverity; // must have
  50. LPCTSTR lpszAppName;
  51. GUID guidID; // entry guid
  52. //
  53. // Conventional mode
  54. //
  55. TAGID tiExe; // the TAGID of the exe entry within the DB
  56. GUID guidDB; // the guid of the DB that has the EXE entry
  57. BOOL bOfflineContent;
  58. BOOL bUseHTMLHelp;
  59. LPCTSTR lpszChmFile;
  60. LPCTSTR lpszDetailsFile;
  61. } APPHELP_INFO, *PAPPHELP_INFO;
  62. */
  63. typedef BOOL (*_pfn_ApphelpShowDialog)(
  64. IN PAPPHELP_INFO pAHInfo, // the info necessary to find the apphelp data
  65. IN PHANDLE phProcess // [optional] returns the process handle of
  66. // the process displaying the apphelp.
  67. // When the process completes, the return value
  68. // (from GetExitCodeProcess()) will be zero
  69. // if the app should not run, or non-zero
  70. // if it should run.
  71. );
  72. /*++
  73. Parse the command line.
  74. The format of the command line is:
  75. MODE:AOL|CS;APPNAME:xxxxxx;HTMLHELPID:99999;GUID:xxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx
  76. --*/
  77. BOOL
  78. ParseCommandLine(
  79. LPCSTR lpCommandLine
  80. )
  81. {
  82. int iTotalParam = 0;
  83. CSTRING_TRY
  84. {
  85. CStringToken csTok(lpCommandLine, L" ;");
  86. CString token;
  87. while (csTok.GetToken(token))
  88. {
  89. CStringToken csSingleTok(token, L":");
  90. CString csParam;
  91. CString csValue;
  92. csSingleTok.GetToken(csParam);
  93. csSingleTok.GetToken(csValue);
  94. if (csParam.CompareNoCase(L"APPNAME") == 0)
  95. {
  96. g_csAppName = csValue;
  97. ++iTotalParam;
  98. }
  99. if (csParam.CompareNoCase(L"HTMLHELPID_BUNDLED") == 0)
  100. {
  101. g_csHTMLHelpID_BundledFound = csValue;
  102. g_dwHTMLHelpID_BundledFound = _wtol(csValue.Get());
  103. ++iTotalParam;
  104. }
  105. if (csParam.CompareNoCase(L"HTMLHELPID_INCOMPAT") == 0)
  106. {
  107. g_csHTMLHelpID_Incompatible = csValue;
  108. g_dwHTMLHelpID_Incompatible = _wtol(csValue.Get());
  109. ++iTotalParam;
  110. }
  111. if (csParam.CompareNoCase(L"GUID") == 0)
  112. {
  113. g_csGUID = csValue;
  114. ++iTotalParam;
  115. }
  116. }
  117. }
  118. CSTRING_CATCH
  119. {
  120. DPF("FindAOL", eDbgLevelInfo, "Error in CString.Exiting\n");
  121. return FALSE;
  122. }
  123. if (iTotalParam < MAX_PARAM)
  124. {
  125. DPF("FindAOL", eDbgLevelInfo, "Total Parameter = %d is less than = %d\n",iTotalParam, MAX_PARAM);
  126. return FALSE;
  127. }
  128. //
  129. // Dump results of command line parse
  130. //
  131. DPF("FindAOL", eDbgLevelInfo, "===================================\n");
  132. DPF("FindAOL", eDbgLevelInfo, " FindAOL \n");
  133. DPF("FindAOL", eDbgLevelInfo, "===================================\n");
  134. DPF("FindAOL", eDbgLevelInfo, "COMMAND_LINE(%s)", lpCommandLine);
  135. DPF("FindAOL", eDbgLevelInfo, "-----------------------------------\n");
  136. DPF("FindAOL", eDbgLevelInfo, "APPNAME = %S\n", g_csAppName);
  137. DPF("FindAOL", eDbgLevelInfo, "HTMLHELPID_BUNDLED = %S\n", g_csHTMLHelpID_BundledFound);
  138. DPF("FindAOL", eDbgLevelInfo, "HTMLHELPID_INCOMPAT = %S\n", g_csHTMLHelpID_Incompatible);
  139. DPF("FindAOL", eDbgLevelInfo, "GUID = %S\n", g_csGUID);
  140. DPF("FindAOL", eDbgLevelInfo, "-----------------------------------\n");
  141. return TRUE;
  142. }
  143. BOOL InvokeApphelpShowDialog(DWORD dwHTMLHelpID)
  144. {
  145. _pfn_ApphelpShowDialog pfnApphelpShowDialog = NULL;
  146. APPHELP_INFO AHInfo = { 0 };
  147. HMODULE hAppHelpDLL = NULL;
  148. hAppHelpDLL = LoadLibrary(L"APPHELP.DLL");
  149. DPF("FindAOL", eDbgLevelWarning, "Apphelp:%d\n",hAppHelpDLL );
  150. if (hAppHelpDLL)
  151. {
  152. pfnApphelpShowDialog = (_pfn_ApphelpShowDialog) GetProcAddress(hAppHelpDLL, "ApphelpShowDialog");
  153. if (pfnApphelpShowDialog == NULL)
  154. {
  155. DPF("FindAOL", eDbgLevelInfo, "Unable to get APPHELP!ApphelpShowDialog procedure address.\n");
  156. return FALSE;
  157. }
  158. AHInfo.dwHtmlHelpID = dwHTMLHelpID;
  159. AHInfo.dwSeverity = APPHELP_NOBLOCK;
  160. AHInfo.lpszAppName = g_csAppName.Get();
  161. AHInfo.bPreserveChoice = TRUE;
  162. UNICODE_STRING ustrGuid;
  163. NTSTATUS ntstatus;
  164. RtlInitUnicodeString(&ustrGuid, g_csGUID.Get());
  165. ntstatus = RtlGUIDFromString(&ustrGuid, &AHInfo.guidID);
  166. if (NT_SUCCESS(ntstatus)==FALSE)
  167. {
  168. DPF("FindAOL", eDbgLevelInfo, "RtlGUIDFromString failed!\n");
  169. return FALSE;
  170. }
  171. if (pfnApphelpShowDialog(&AHInfo,NULL))
  172. {
  173. DPF("FindAOL", eDbgLevelInfo, "!\n");
  174. }
  175. else
  176. {
  177. DPF("FindAOL", eDbgLevelInfo, "RtlGUIDFromString FAILED!\n");
  178. return FALSE;
  179. }
  180. }
  181. else
  182. {
  183. DPF("FindAOL", eDbgLevelInfo, "LoadLibrary FAILED!\n");
  184. return FALSE;
  185. }
  186. return TRUE;
  187. }
  188. void DoIt()
  189. {
  190. CHAR lpszInstaller[MAX_PATH];
  191. BOOL bBundledInstallerFound = FALSE;
  192. BOOL bDisplayAppHelpDialog = FALSE;
  193. BOOL bKillCurrentProcess = FALSE;
  194. BOOL bLaunchBundledInstaller = FALSE;
  195. BOOL bReturnValue = FALSE;
  196. UINT uiWinExecReturned = 0;
  197. if (!g_bDoneIt) {
  198. if (!ParseCommandLine(COMMAND_LINE)) {
  199. goto eh;
  200. }
  201. bBundledInstallerFound = LocateInstaller(lpszInstaller, MAX_PATH, &bDisplayAppHelpDialog);
  202. if (bBundledInstallerFound) {
  203. DPF("FindAOL", eDbgLevelWarning, "Bundled installer found in %s.\n",lpszInstaller);
  204. }
  205. if (bBundledInstallerFound == FALSE && bDisplayAppHelpDialog == FALSE) {
  206. DPF("FindAOL", eDbgLevelWarning, "Bundled installer not found. Let client run normally.\n");
  207. goto eh;
  208. }
  209. if (bBundledInstallerFound == FALSE && bDisplayAppHelpDialog == TRUE) {
  210. bReturnValue = InvokeApphelpShowDialog(g_dwHTMLHelpID_Incompatible);
  211. // if user chose Cancel button, then just kill current process.
  212. if (FALSE == bReturnValue) {
  213. bKillCurrentProcess = TRUE;
  214. }
  215. }
  216. if (bBundledInstallerFound == TRUE && bDisplayAppHelpDialog == TRUE) {
  217. bReturnValue = InvokeApphelpShowDialog(g_dwHTMLHelpID_BundledFound);
  218. // if user chose Continue button, then launch bundled installer.
  219. if (TRUE == bReturnValue) {
  220. bKillCurrentProcess = TRUE;
  221. bLaunchBundledInstaller = TRUE;
  222. }
  223. }
  224. if (bBundledInstallerFound == TRUE && bDisplayAppHelpDialog == FALSE) {
  225. // Launch bundled installer.
  226. bKillCurrentProcess = TRUE;
  227. bLaunchBundledInstaller = TRUE;
  228. }
  229. if (bLaunchBundledInstaller) {
  230. // launch bundled installer instead
  231. uiWinExecReturned = WinExec(lpszInstaller, SW_SHOW);
  232. if (uiWinExecReturned <= 31) {
  233. DPF("FindAOL", eDbgLevelError, "Can not launch program. Error: %d\n",GetLastError());
  234. goto eh;
  235. }
  236. }
  237. if (bKillCurrentProcess) {
  238. ExitProcess(0);
  239. }
  240. }
  241. eh:
  242. g_bDoneIt = TRUE;
  243. }
  244. LPSTR
  245. APIHOOK(GetCommandLineA)()
  246. {
  247. DoIt();
  248. return ORIGINAL_API(GetCommandLineA)();
  249. }
  250. VOID
  251. APIHOOK(GetStartupInfoA)(
  252. LPSTARTUPINFOA lpStartupInfo)
  253. {
  254. DoIt();
  255. ORIGINAL_API(GetStartupInfoA)(lpStartupInfo);
  256. }
  257. DWORD
  258. APIHOOK(GetModuleFileNameA)(
  259. HMODULE hModule, // handle to module
  260. LPSTR lpFilename, // file name of module
  261. DWORD nSize // size of buffer
  262. )
  263. {
  264. DoIt();
  265. return ORIGINAL_API(GetModuleFileNameA)(hModule, lpFilename, nSize);
  266. }
  267. HWND
  268. APIHOOK(CreateWindowExA)(
  269. DWORD dwExStyle,
  270. LPCSTR lpClassName,
  271. LPCSTR lpWindowName,
  272. DWORD dwStyle,
  273. int x,
  274. int y,
  275. int nWidth,
  276. int nHeight,
  277. HWND hWndParent,
  278. HMENU hMenu,
  279. HINSTANCE hInstance,
  280. LPVOID lpParam
  281. )
  282. {
  283. DoIt();
  284. return ORIGINAL_API(CreateWindowExA)(
  285. dwExStyle,
  286. lpClassName,
  287. lpWindowName,
  288. dwStyle,
  289. x,
  290. y,
  291. nWidth,
  292. nHeight,
  293. hWndParent,
  294. hMenu,
  295. hInstance,
  296. lpParam );
  297. }
  298. /*++
  299. Register hooked functions
  300. --*/
  301. HOOK_BEGIN
  302. APIHOOK_ENTRY(KERNEL32.DLL, GetCommandLineA)
  303. APIHOOK_ENTRY(KERNEL32.DLL, GetStartupInfoA)
  304. APIHOOK_ENTRY(KERNEL32.DLL, GetModuleFileNameA)
  305. APIHOOK_ENTRY(USER32.DLL, CreateWindowExA)
  306. HOOK_END
  307. IMPLEMENT_SHIM_END