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.

390 lines
11 KiB

  1. #include "pch.hxx"
  2. #include "strings.h"
  3. #define DEFINE_UTIL
  4. #include "util.h"
  5. ASSERTDATA
  6. HINSTANCE g_hInstance = NULL;
  7. LPMALLOC g_pMalloc = NULL;
  8. #ifdef DEBUG
  9. DWORD dwDOUTLevel = 0;
  10. DWORD dwDOUTLMod = 0;
  11. DWORD dwDOUTLModLevel = 0;
  12. #endif
  13. /****************************************************************************
  14. NAME: GetTextToNextDelim
  15. SYNOPSIS: Gets text up to next space, colon or end of string, places in
  16. output buffer
  17. ****************************************************************************/
  18. LPSTR GetTextToNextDelim(LPSTR pszText, LPSTR pszOutBuf, UINT cbOutBuf)
  19. {
  20. Assert(pszText);
  21. Assert(pszOutBuf);
  22. Assert(*pszText);
  23. StrCpyN(pszOutBuf, c_szEmpty, cbOutBuf);
  24. // advance past whitespace
  25. while ((*pszText == ' ') || (*pszText == '\t') || (':' == *pszText))
  26. pszText++;
  27. // Copy parameter until we hit a delimiter
  28. while (*pszText && ((*pszText != ' ') && (*pszText != '\t') && (*pszText != ':')) && cbOutBuf>1)
  29. {
  30. *pszOutBuf = *pszText;
  31. pszOutBuf ++;
  32. cbOutBuf --;
  33. pszText ++;
  34. }
  35. if (cbOutBuf)
  36. *pszOutBuf = '\0'; // null-terminate
  37. // advance past whitespace
  38. while ((*pszText == ' ') || (*pszText == '\t'))
  39. pszText++;
  40. return pszText;
  41. }
  42. /*******************************************************************
  43. NAME: ParseCmdLine
  44. ********************************************************************/
  45. void ParseCmdLine(LPSTR pszCmdLine)
  46. {
  47. LOG("Command Line:");
  48. LOG2(pszCmdLine);
  49. while (pszCmdLine && *pszCmdLine)
  50. {
  51. CHAR szCommand[64];
  52. pszCmdLine = GetTextToNextDelim(pszCmdLine, szCommand, sizeof(szCommand));
  53. if (!lstrcmpi(szCommand, c_szUninstallFlag))
  54. {
  55. si.smMode = MODE_UNINSTALL;
  56. }
  57. else if (!lstrcmpi(szCommand, c_szInstallFlag))
  58. {
  59. si.smMode = MODE_INSTALL;
  60. }
  61. else if (!lstrcmpi(szCommand, c_szUserFlag))
  62. {
  63. si.stTime = TIME_USER;
  64. }
  65. else if (!lstrcmpi(szCommand, c_szPromptFlag))
  66. {
  67. si.fPrompt = TRUE;
  68. }
  69. else if (!lstrcmpi(szCommand, c_szCallerFlag))
  70. {
  71. pszCmdLine = GetTextToNextDelim(pszCmdLine, szCommand, sizeof(szCommand));
  72. if (!lstrcmpi(szCommand, c_szWIN9X))
  73. si.caller = CALLER_WIN9X;
  74. else if (!lstrcmpi(szCommand, c_szWINNT))
  75. si.caller = CALLER_WINNT;
  76. }
  77. else if (!lstrcmpi(szCommand, c_szAppFlag))
  78. {
  79. pszCmdLine = GetTextToNextDelim(pszCmdLine, szCommand, sizeof(szCommand));
  80. if (!lstrcmpi(szCommand, c_szAppOE))
  81. si.saApp = APP_OE;
  82. else if (!lstrcmpi(szCommand, c_szAppWAB))
  83. si.saApp = APP_WAB;
  84. }
  85. else if (!lstrcmpi(szCommand, c_szINIFlag))
  86. {
  87. pszCmdLine = GetTextToNextDelim(pszCmdLine, si.szINI, sizeof(si.szINI));
  88. }
  89. else if (!lstrcmpi(szCommand, c_szIconsFlag))
  90. {
  91. pszCmdLine = GetTextToNextDelim(pszCmdLine, szCommand, sizeof(szCommand));
  92. si.smMode = MODE_ICONS;
  93. if (!lstrcmpi(szCommand, c_szOFF))
  94. si.fNoIcons = TRUE;
  95. }
  96. }
  97. }
  98. void ParseINIFile()
  99. {
  100. }
  101. /*******************************************************************
  102. NAME: Initialize
  103. ********************************************************************/
  104. HRESULT Initialize(LPSTR pszCmdLine)
  105. {
  106. UINT uLen, uAppID;
  107. HKEY hkey;
  108. HRESULT hr = S_OK;
  109. DWORD cb;
  110. // Needs to be static as it must outlive this func call
  111. static TCHAR s_szAltINF[MAX_PATH];
  112. si.osv.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  113. if (!GetVersionEx(&(si.osv)))
  114. {
  115. LOG("[ERROR] Couldn't get windows version info");
  116. goto generror;
  117. }
  118. // set up the win directory
  119. // We need the true system Windows directory, not the user's version
  120. if (!(uLen = GetSystemWindowsDirectoryWrap(si.szWinDir, ARRAYSIZE(si.szWinDir))))
  121. {
  122. LOG("[ERROR] Couldn't get Windows Directory");
  123. goto generror;
  124. }
  125. // Slash terminate
  126. if (*CharPrev(si.szWinDir, si.szWinDir+uLen) != '\\')
  127. {
  128. si.szWinDir[uLen++] = '\\';
  129. si.szWinDir[uLen] = 0;
  130. }
  131. // set up the inf directory
  132. StrCpyN(si.szInfDir, si.szWinDir, ARRAYSIZE(si.szInfDir));
  133. StrCpyN(&si.szInfDir[uLen], c_szINFSlash, ARRAYSIZE(si.szInfDir)-uLen);
  134. // Figure out the current directory
  135. if (!GetModuleFileName(NULL, si.szCurrentDir, ARRAYSIZE(si.szCurrentDir)) ||
  136. !PathRemoveFileSpec(si.szCurrentDir))
  137. {
  138. LOG("[ERROR] Couldn't get module's file name");
  139. goto generror;
  140. }
  141. if (!(uLen = GetSystemDirectory(si.szSysDir, MAX_PATH)))
  142. {
  143. LOG("[ERROR] Couldn't get System Directory");
  144. goto generror;
  145. }
  146. // Slash terminate
  147. if (*CharPrev(si.szSysDir, si.szSysDir+uLen) != '\\')
  148. {
  149. si.szSysDir[uLen++] = '\\';
  150. si.szSysDir[uLen] = 0;
  151. }
  152. // Load Advpack
  153. if (!(si.hInstAdvPack = LoadLibrary(c_szAdvPackDll)))
  154. {
  155. MsgBox(NULL, IDS_ERR_ADVLOAD, MB_ICONSTOP, MB_OK);
  156. hr = E_FAIL;
  157. goto exit;
  158. }
  159. // Thunk to short names on Win95 in case we use these paths in RepairBeta1
  160. if (VER_PLATFORM_WIN32_WINDOWS == si.osv.dwPlatformId)
  161. {
  162. GetShortPathName(si.szWinDir, si.szWinDir, ARRAYSIZE(si.szWinDir));
  163. GetShortPathName(si.szSysDir, si.szSysDir, ARRAYSIZE(si.szSysDir));
  164. GetShortPathName(si.szInfDir, si.szInfDir, ARRAYSIZE(si.szInfDir));
  165. }
  166. // Obtain Mandatory ADVPACK Entry points
  167. si.pfnRunSetup = (RUNSETUPCOMMAND)GetProcAddress(si.hInstAdvPack, achRUNSETUPCOMMANDFUNCTION);
  168. si.pfnLaunchEx = (LAUNCHINFSECTIONEX)GetProcAddress(si.hInstAdvPack, achLAUNCHINFSECTIONEX);
  169. si.pfnCopyFile = (ADVINSTALLFILE)GetProcAddress(si.hInstAdvPack, achADVINSTALLFILE);
  170. if (!si.pfnRunSetup || !si.pfnLaunchEx || !si.pfnCopyFile)
  171. {
  172. MsgBox(NULL, IDS_ERR_ADVCORR, MB_ICONSTOP, MB_OK);
  173. FreeLibrary(si.hInstAdvPack);
  174. hr = E_FAIL;
  175. goto exit;
  176. }
  177. // Obtain Optional ADVPACK Entry points used for repairing a Beta1 Install
  178. si.pfnAddDel = (ADDDELBACKUPENTRY)GetProcAddress(si.hInstAdvPack, "AddDelBackupEntry");
  179. si.pfnRegRestore = (REGSAVERESTORE)GetProcAddress(si.hInstAdvPack, "RegSaveRestore");
  180. // Get info from cmd line - like the app being installed
  181. ParseCmdLine(pszCmdLine);
  182. switch (si.saApp)
  183. {
  184. case APP_OE:
  185. si.pszInfFile = c_szMsimnInf;
  186. uAppID = IDS_APPNAME_OE;
  187. si.pszVerInfo = c_szRegVerInfo;
  188. break;
  189. case APP_WAB:
  190. si.pszInfFile = c_szWABInf;
  191. uAppID = IDS_APPNAME_WAB;
  192. si.pszVerInfo = c_szRegWABVerInfo;
  193. break;
  194. default:
  195. goto exit;
  196. }
  197. if (!LoadString(g_hInstance, uAppID, si.szAppName, ARRAYSIZE(si.szAppName)))
  198. {
  199. LOG("[ERROR] Setup50.exe is missing resources")
  200. goto generror;
  201. }
  202. // Allow reg override on INF file for non-IE installs
  203. // BUGBUG: Convert NT5 setup to Memphis methodology
  204. if ((CALLER_WIN9X == si.caller) && (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, si.pszVerInfo, 0, KEY_QUERY_VALUE, &hkey)))
  205. {
  206. cb = sizeof(s_szAltINF);
  207. if (ERROR_SUCCESS == RegQueryValueEx(hkey, c_szLatestINF, 0, NULL, (LPBYTE)s_szAltINF, &cb))
  208. {
  209. si.pszInfFile = s_szAltINF;
  210. }
  211. RegCloseKey(hkey);
  212. }
  213. // Allow INI file to override
  214. ParseINIFile();
  215. goto exit;
  216. generror:
  217. MsgBox(NULL, IDS_ERR_INIT, MB_ICONSTOP, MB_OK);
  218. hr = E_FAIL;
  219. exit:
  220. return hr;
  221. }
  222. /****************************************************************************
  223. NAME: Process
  224. ****************************************************************************/
  225. HRESULT Process()
  226. {
  227. HRESULT hr = S_OK;
  228. // If we weren't told which app, be helpful
  229. if (APP_UNKNOWN == si.saApp)
  230. si.smMode = MODE_UNKNOWN;
  231. LOG("MODE: ");
  232. switch (si.smMode)
  233. {
  234. case MODE_INSTALL:
  235. LOG2("Install TIME: ");
  236. if (TIME_MACHINE == si.stTime)
  237. {
  238. LOG2("Machine");
  239. hr = InstallMachine();
  240. }
  241. else
  242. {
  243. LOG2("User");
  244. InstallUser();
  245. }
  246. break;
  247. case MODE_ICONS:
  248. LOG2("Icons");
  249. //HandleIcons();
  250. break;
  251. case MODE_UNINSTALL:
  252. LOG2("Uninstall TIME: ");
  253. if (TIME_MACHINE == si.stTime)
  254. {
  255. LOG2("Machine");
  256. MsgBox(NULL, UnInstallMachine() ? IDS_UNINSTALL_COMPLETE : IDS_NO_UNINSTALL, MB_OK, MB_ICONINFORMATION);
  257. }
  258. else
  259. {
  260. LOG2("User");
  261. UnInstallUser();
  262. }
  263. break;
  264. case MODE_UNKNOWN:
  265. LOG2("Options");
  266. DisplayMenu();
  267. break;
  268. default:
  269. AssertSz(FALSE, "Setup MODE is undefined!");
  270. }
  271. return hr;
  272. }
  273. /****************************************************************************
  274. NAME: Shutdown
  275. ****************************************************************************/
  276. void Shutdown()
  277. {
  278. if (si.hInstAdvPack)
  279. FreeLibrary(si.hInstAdvPack);
  280. }
  281. /*******************************************************************
  282. NAME: WinMain
  283. SYNOPSIS: App entry point
  284. ********************************************************************/
  285. int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
  286. {
  287. HRESULT hr = S_OK;
  288. ZeroMemory(&si, sizeof(SETUPINFO));
  289. g_hInstance = hInstance; // save instance handle away
  290. CoInitialize(NULL);
  291. LOG_OPEN;
  292. // init global memory allocator
  293. // We will use it to free some Shell memory, so use SHGetMalloc
  294. SHGetMalloc(&g_pMalloc);
  295. if (NULL == g_pMalloc)
  296. {
  297. MsgBox(NULL, IDS_ERR_NOALLOC, MB_OK, MB_ICONSTOP);
  298. hr = E_OUTOFMEMORY;
  299. goto exit;
  300. }
  301. if (SUCCEEDED(hr = Initialize(lpCmdLine)))
  302. {
  303. hr = Process();
  304. Shutdown();
  305. }
  306. // release the global memory allocator
  307. g_pMalloc->Release();
  308. exit:
  309. LOG_CLOSE;
  310. CoUninitialize();
  311. return hr;
  312. }