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.

245 lines
8.0 KiB

  1. // setup.cpp : Defines the entry point for the application.
  2. //
  3. #include "stdafx.h"
  4. #define REBOOT_EQUALS_REALLY_SUPPRESS _T("REBOOT=ReallySuppress")
  5. DWORD LaunchInstallation(LPSTR lpCmdLine);
  6. int APIENTRY WinMain(HINSTANCE hInstance,
  7. HINSTANCE hPrevInstance,
  8. LPSTR lpCmdLine,
  9. int nCmdShow)
  10. {
  11. OSVERSIONINFO osv;
  12. HMODULE hModule = NULL;
  13. int iRes = 1;
  14. LPCTSTR lpctstrMsiDllName = _T("MSI.DLL");
  15. HKEY hKey = NULL;
  16. LONG lRes = ERROR_SUCCESS;
  17. DWORD dwData = 1;
  18. DBG_ENTER(TEXT("WinMain"),iRes);
  19. // Check if this is Win98
  20. osv.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  21. if (!GetVersionEx(&osv))
  22. {
  23. VERBOSE(GENERAL_ERR,_T("GetVersionEx failed: (ec=%d)"),GetLastError());
  24. iRes = 0;
  25. goto exit;
  26. }
  27. if ((osv.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) &&
  28. (osv.dwMinorVersion > 0))
  29. {
  30. VERBOSE (DBG_MSG,TEXT("This is Win98 OS"));
  31. }
  32. else
  33. {
  34. VERBOSE (DBG_MSG,TEXT("This is not Win98 OS, no need to force reboot"));
  35. iRes = 0;
  36. goto exit;
  37. }
  38. // check if msi.dll exists
  39. hModule = LoadLibrary(lpctstrMsiDllName);
  40. if (hModule)
  41. {
  42. VERBOSE (DBG_MSG,TEXT("Msi.dll found, no need to force reboot"));
  43. FreeLibrary(hModule);
  44. hModule = NULL;
  45. iRes = 0;
  46. goto exit;
  47. }
  48. // write registry DeferredBoot value
  49. lRes = RegCreateKey(HKEY_LOCAL_MACHINE,REGKEY_SBS2000_FAX_SETUP,&hKey);
  50. if (!((lRes==ERROR_SUCCESS) || (lRes==ERROR_ALREADY_EXISTS)))
  51. {
  52. VERBOSE(GENERAL_ERR,_T("RegCreateKey failed: (ec=%d)"),GetLastError());
  53. iRes = 0;
  54. goto exit;
  55. }
  56. lRes = RegSetValueEx( hKey,
  57. DEFERRED_BOOT,
  58. 0,
  59. REG_DWORD,
  60. (LPBYTE) &dwData,
  61. sizeof(DWORD)
  62. );
  63. if (lRes!=ERROR_SUCCESS)
  64. {
  65. VERBOSE(GENERAL_ERR,_T("RegSetValueEx failed: (ec=%d)"),GetLastError());
  66. iRes = 0;
  67. goto exit;
  68. }
  69. exit:
  70. if (hKey)
  71. {
  72. RegCloseKey(hKey);
  73. }
  74. // launch Install Shield's setup.exe
  75. iRes = LaunchInstallation(lpCmdLine);
  76. return iRes;
  77. }
  78. ///////////////////////////////////////////////////////////////////////////////////////
  79. // Function:
  80. // LaunchInstallation
  81. //
  82. // Purpose:
  83. // This function launches the MSI client installation
  84. // it waits for the installation to complete and writes
  85. // to the registry in case a reboot was reqeuired.
  86. //
  87. // Params:
  88. // LPSTR lpCmdLine - command line passed in to setup.exe
  89. //
  90. // Return Value:
  91. // NO_ERROR - everything was ok.
  92. // Win32 Error code in case if failure.
  93. //
  94. // Author:
  95. // Mooly Beery (MoolyB) 31-Jan-2002
  96. ///////////////////////////////////////////////////////////////////////////////////////
  97. DWORD LaunchInstallation(LPSTR lpCmdLine)
  98. {
  99. DWORD dwRet = ERROR_SUCCESS;
  100. TCHAR szSystemDirectory[MAX_PATH] = {0};
  101. CHAR* pcRebootPropInCmdLine = NULL;
  102. SHELLEXECUTEINFO executeInfo = {0};
  103. BOOL bCheckExitCode = FALSE;
  104. DWORD dwWaitRes = 0;
  105. DWORD dwExitCode = 0;
  106. HKEY hKey = NULL;
  107. LONG lRes = ERROR_SUCCESS;
  108. DWORD dwData = 1;
  109. TCHAR* tpBuf = NULL;
  110. HRESULT hr = ERROR_SUCCESS;
  111. DBG_ENTER(TEXT("LaunchInstallation"),dwRet);
  112. // launch Install Shield's setup.exe
  113. if (GetModuleFileName(NULL,szSystemDirectory,MAX_PATH)==0)
  114. {
  115. VERBOSE(GENERAL_ERR,_T("GetModuleFileName failed: (ec=%d)"),GetLastError());
  116. return 0;
  117. }
  118. if ((tpBuf = _tcsrchr(szSystemDirectory,_T('\\')))==NULL)
  119. {
  120. VERBOSE(GENERAL_ERR,_T("_tcsrchr failed"));
  121. return 0;
  122. }
  123. _tcscpy(_tcsinc(tpBuf),_T("fxssetup.exe"));
  124. VERBOSE (DBG_MSG,TEXT("Running %s"),szSystemDirectory);
  125. // if the command line contains REBOOT=ReallySuppress we will check
  126. // the return value of the Installer
  127. pcRebootPropInCmdLine = strstr(lpCmdLine,REBOOT_EQUALS_REALLY_SUPPRESS);
  128. if (pcRebootPropInCmdLine)
  129. {
  130. VERBOSE (DBG_MSG,TEXT("REBOOT=ReallySuppress is included in the command line, checking for reboot after setup"));
  131. bCheckExitCode = TRUE;
  132. }
  133. else
  134. {
  135. VERBOSE (DBG_MSG,TEXT("REBOOT=ReallySuppress is not included in the command line, ignoring exit code of setup"));
  136. }
  137. executeInfo.cbSize = sizeof(executeInfo);
  138. executeInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
  139. executeInfo.lpVerb = TEXT("open");
  140. executeInfo.lpFile = szSystemDirectory;
  141. executeInfo.lpParameters = lpCmdLine;
  142. executeInfo.nShow = SW_RESTORE;
  143. //
  144. // Execute an aplication
  145. //
  146. if (!ShellExecuteEx(&executeInfo))
  147. {
  148. VERBOSE(GENERAL_ERR,_T("ShellExecuteEx failed: (ec=%d)"),GetLastError());
  149. return 0;
  150. }
  151. if (executeInfo.hProcess==NULL)
  152. {
  153. VERBOSE(GENERAL_ERR, _T("hProcess in NULL, can't wait"),GetLastError());
  154. return 1;
  155. }
  156. if ((dwWaitRes=WaitForSingleObject(executeInfo.hProcess, INFINITE))==WAIT_FAILED)
  157. {
  158. VERBOSE(GENERAL_ERR,_T("WaitForSingleObject failed: (ec=%d)"),GetLastError());
  159. }
  160. else if (dwWaitRes==WAIT_OBJECT_0)
  161. {
  162. VERBOSE(DBG_MSG, _T("fxssetup.exe terminated"));
  163. // now let's get the process's return code, see if we need a reboot.
  164. if (!GetExitCodeProcess( executeInfo.hProcess, &dwExitCode ))
  165. {
  166. VERBOSE (GENERAL_ERR,TEXT("GetExitCodeProcess failed! (err=%ld)"),GetLastError());
  167. }
  168. else
  169. {
  170. VERBOSE (DBG_MSG,TEXT("GetExitCodeProcess returned %ld."),dwExitCode);
  171. if ( bCheckExitCode && (dwExitCode==ERROR_SUCCESS_REBOOT_REQUIRED))
  172. {
  173. VERBOSE (DBG_MSG,TEXT("Installation requires reboot, notify AppLauncher"));
  174. // notify AppLauncher that we need a reboot...
  175. lRes = RegCreateKey(HKEY_LOCAL_MACHINE,REGKEY_SBS2000_FAX_SETUP,&hKey);
  176. if ((lRes==ERROR_SUCCESS) || (lRes==ERROR_ALREADY_EXISTS))
  177. {
  178. lRes = RegSetValueEx( hKey,
  179. DEFERRED_BOOT,
  180. 0,
  181. REG_DWORD,
  182. (LPBYTE) &dwData,
  183. sizeof(DWORD)
  184. );
  185. if (lRes!=ERROR_SUCCESS)
  186. {
  187. VERBOSE(GENERAL_ERR,_T("RegSetValueEx failed: (ec=%d)"),GetLastError());
  188. dwRet = ERROR_SUCCESS;
  189. }
  190. RegCloseKey(hKey);
  191. }
  192. else
  193. {
  194. VERBOSE(GENERAL_ERR,_T("RegCreateKey failed: (ec=%d)"),GetLastError());
  195. dwRet = ERROR_SUCCESS;
  196. }
  197. }
  198. else if (dwExitCode!=ERROR_SUCCESS)
  199. {
  200. VERBOSE (GENERAL_ERR,TEXT("Installation failed"));
  201. }
  202. }
  203. }
  204. else
  205. {
  206. VERBOSE(GENERAL_ERR,_T("WaitForSingleObject returned unexpected result: (ec=%d)"),dwWaitRes);
  207. }
  208. if(!CloseHandle(executeInfo.hProcess))
  209. {
  210. VERBOSE(GENERAL_ERR,_T("CloseHandle failed: (ec=%d)"),GetLastError());
  211. }
  212. return dwRet;
  213. }