Source code of Windows XP (NT5)
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.

589 lines
14 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. internal.c
  5. Abstract:
  6. Routines to support hidden or internal-only functionlity.
  7. Author:
  8. Ted Miller (tedm) 4 Nov 1996
  9. Revision History:
  10. --*/
  11. #include "precomp.h"
  12. #pragma hdrstop
  13. //
  14. // Value used internally to automatically fetch
  15. // alternate setup hives for differing # of processors.
  16. //
  17. UINT NumberOfLicensedProcessors;
  18. //
  19. // internal value used to turn off processing of "exception packages"
  20. //
  21. BOOL IgnoreExceptionPackages;
  22. //
  23. // Where to get missing files.
  24. //
  25. TCHAR AlternateSourcePath[MAX_PATH];
  26. BOOL
  27. AddCopydirIfExists(
  28. IN LPTSTR pszPathToCopy,
  29. IN UINT Flags
  30. )
  31. /*++
  32. Routine Description:
  33. If pszPathToCopy exists, then act like "/copydir:pszPathToCopy" was passed
  34. on the cmd line.
  35. Arguments:
  36. pszPathToCopy - path that we want to additionally copy if it exists.
  37. Flags - one of the OPTDIR_xxx flags to specify how to treat this optional directory
  38. Return Value:
  39. TRUE - pszPathToCopy existed and we added this to list of extra dirs to copy.
  40. FALSE - pszPathToCopy did not exist or we failed to add it to our list of extra dirs
  41. --*/
  42. {
  43. TCHAR szFullPath[MAX_PATH], szRealPath[MAX_PATH];
  44. PTSTR p;
  45. if( !pszPathToCopy )
  46. return FALSE;
  47. if (NativeSourcePaths[0][0]) {
  48. lstrcpy(szFullPath, NativeSourcePaths[0]);
  49. } else {
  50. if (!GetModuleFileName(NULL, szFullPath, MAX_PATH) ||
  51. !(p = _tcsrchr(szFullPath, TEXT('\\')))
  52. ) {
  53. return FALSE;
  54. }
  55. // remove "\winnt32.exe" part
  56. *p = TEXT('\0');
  57. }
  58. ConcatenatePaths(szFullPath, pszPathToCopy, MAX_PATH);
  59. if(GetFullPathName( szFullPath, MAX_PATH, szRealPath, NULL )){
  60. if (FileExists (szRealPath, NULL))
  61. {
  62. DebugLog (Winnt32LogInformation, TEXT("AddCopyDirIfExists for <%1> <%2>"), 0, szRealPath, pszPathToCopy);
  63. return RememberOptionalDir(pszPathToCopy, Flags);
  64. }else{
  65. DebugLog (Winnt32LogInformation, TEXT("AddCopyDirIfExists FileExists failed for <%1>"), 0, szRealPath);
  66. }
  67. }else{
  68. DebugLog (Winnt32LogInformation, TEXT("AddCopyDirIfExists GetFullPathName failed for <%1>"), 0, szFullPath );
  69. }
  70. return FALSE;
  71. }
  72. VOID
  73. CopyExtraBVTDirs(
  74. )
  75. /*++
  76. Routine Description:
  77. Copies the extra dirs that are good to have when running bvt's:
  78. symbols.pri, idw, mstools, and debugger extensions.
  79. Arguments:
  80. None.
  81. Return Value:
  82. None.
  83. --*/
  84. {
  85. LPTSTR psz;
  86. if (CopySymbols)
  87. {
  88. // copy symbols.pri\retail
  89. if (AddCopydirIfExists(TEXT("..\\..\\sym\\retail"), 0) ||
  90. AddCopydirIfExists(TEXT("..\\..\\symbols.pri\\retail"), 0) || // for dev postbuild installs
  91. AddCopydirIfExists(TEXT("..\\..\\sym\\netfx"), 0) ||
  92. AddCopydirIfExists(TEXT("..\\..\\symbols.pri\\netfx"), 0)) // for dev postbuild installs
  93. {}
  94. }
  95. // copy idw
  96. if (AddCopydirIfExists(TEXT("..\\..\\bin\\idw"), 0) ||
  97. AddCopydirIfExists(TEXT("..\\..\\idw"), 0)) // for dev postbuild installs
  98. {}
  99. // copy mstools
  100. if (AddCopydirIfExists(TEXT("..\\..\\bin\\mstools"), 0) ||
  101. AddCopydirIfExists(TEXT("..\\..\\mstools"), 0)) // for dev postbuild installs
  102. {}
  103. // copy bldtools
  104. if (AddCopydirIfExists(TEXT("..\\..\\bin\\bldtools"), 0) ||
  105. AddCopydirIfExists(TEXT("..\\..\\bldtools"), 0)) // for dev postbuild installs
  106. {}
  107. // copy private debugger extensions
  108. if (AddCopydirIfExists(TEXT("..\\..\\bin\\dbg\\files\\bin\\pri"), OPTDIR_DEBUGGEREXT) ||
  109. AddCopydirIfExists(TEXT("..\\..\\dbg\\files\\bin\\pri"), OPTDIR_DEBUGGEREXT)) // for dev postbuild installs
  110. {}
  111. // copy public debugger extensions
  112. if (AddCopydirIfExists(TEXT("..\\..\\bin\\dbg\\files\\bin\\winxp"), OPTDIR_DEBUGGEREXT) ||
  113. AddCopydirIfExists(TEXT("..\\..\\dbg\\files\\bin\\winxp"), OPTDIR_DEBUGGEREXT)) // for dev postbuild installs
  114. {}
  115. }
  116. BOOL
  117. AppendUpgradeOption (
  118. IN PCTSTR String
  119. )
  120. {
  121. BOOL result = FALSE;
  122. UINT lengthInBytes;
  123. UINT lengthPlusTerminator;
  124. __try {
  125. //
  126. // Ensure there is enough room.
  127. //
  128. lengthInBytes = UpgradeOptionsLength + ((_tcslen(String) + 1) * sizeof (TCHAR));
  129. lengthPlusTerminator = lengthInBytes + sizeof (TCHAR);
  130. if (lengthPlusTerminator > UpgradeOptionsSize) {
  131. //
  132. // Allocate more space, aligned to 256 bytes.
  133. //
  134. UpgradeOptionsSize = ((lengthPlusTerminator / 256) + 1) * 256;
  135. UpgradeOptions = REALLOC(UpgradeOptions,UpgradeOptionsSize);
  136. }
  137. if (UpgradeOptions) {
  138. //
  139. // Ok, memory was successfully allocated. Save the new option onto the end
  140. // of the list.
  141. //
  142. wsprintf (
  143. (PTSTR) ((PBYTE) UpgradeOptions + UpgradeOptionsLength),
  144. TEXT("%s%c"),
  145. String,
  146. 0
  147. );
  148. UpgradeOptionsLength = lengthInBytes;
  149. } else {
  150. //
  151. // This is bad. realloc failed.
  152. //
  153. __leave;
  154. }
  155. result = TRUE;
  156. }
  157. __finally {
  158. }
  159. return result;
  160. }
  161. VOID
  162. InternalProcessCmdLineArg(
  163. IN LPCTSTR Arg
  164. )
  165. /*++
  166. Routine Description:
  167. Parse a command line arg that is thought to be internal-only.
  168. The caller should call this routine only if the switch arg char
  169. is # (ie something like /#x:foo).
  170. /#[n]:sharename internal distribution
  171. n can be a digit from 1-9 to indicate source
  172. count, default is 3 n win9x and 5 on nt.
  173. /#L:number number of licensed processors
  174. /#N auto skip missing files
  175. /#U:[Option] Upgrade option. All upgrade options are packed together
  176. into a multisz and passed to the plugin-dll.
  177. /#bvt:[Option]:[Option] Setup machine for running bvt's. Options include :nosymbols,
  178. :baudrate=XXXX, and :debugport=X
  179. /#asr[{t|f}:[AsrSifPath]] Setup machine for running ASR coverage tests, using the
  180. asr.sif specified. This includes adding /DEBUG
  181. /BAUDRATE=115200 (on IA64 use 19200 and /DEBUGPORT=COM1),
  182. in addition to setting setupcmdlineprepend="ntsd -odgGx",
  183. and adding other options as appropriate.
  184. Arguments:
  185. Arg - supplies comment line argument, starting with the switch
  186. character itself (ie, - or /). This routine assumes that
  187. the interesting part of the argument starts at Arg[2].
  188. Return Value:
  189. None.
  190. --*/
  191. {
  192. UINT NumSources;
  193. UINT u;
  194. UINT length;
  195. LPTSTR src;
  196. if(!Arg[0] || !Arg[1]) {
  197. return;
  198. }
  199. NumSources = ISNT() ? 5 : 3;
  200. switch(_totupper(Arg[2])) {
  201. case TEXT('1'): case ('2'): case ('3'):
  202. case TEXT('4'): case ('5'): case ('6'):
  203. case TEXT('7'): case ('8'): case ('9'):
  204. if(Arg[3] != TEXT(':')) {
  205. break;
  206. }
  207. NumSources = Arg[2] - TEXT('0');
  208. Arg++;
  209. //
  210. // Fall through
  211. //
  212. case TEXT(':'):
  213. //
  214. // Internal distribution stuff
  215. //
  216. //
  217. // handle cases where
  218. // -they put a "\" before path
  219. // -they map a net drive and put "f:" first
  220. // -they map a net driver and put "f:\" first
  221. //
  222. src = (LPTSTR)(Arg+3);
  223. for(u=0; u<NumSources; u++) {
  224. if(SourceCount < MAX_SOURCE_COUNT) {
  225. if (GetFullPathName (
  226. src,
  227. sizeof(NativeSourcePaths[SourceCount])/sizeof(TCHAR),
  228. NativeSourcePaths[SourceCount],
  229. NULL
  230. )) {
  231. SourceCount++;
  232. }
  233. }
  234. }
  235. break;
  236. case TEXT('A'):
  237. if (_tcsnicmp(Arg+2,TEXT("asr"),3) == 0) {
  238. //
  239. // Setup machine for running ASR tests
  240. //
  241. AsrQuickTest = 3; // Assume default is full
  242. if (Arg[5] == TEXT('t') || Arg[5] == TEXT('T')) {
  243. AsrQuickTest = 2; // Text mode only
  244. }
  245. if (Arg[5] == TEXT('f') || Arg[5] == TEXT('F')) {
  246. AsrQuickTest = 3; // Full mode
  247. }
  248. if(Arg[6] == TEXT(':')) {
  249. //
  250. // User specified asr.sif to use
  251. //
  252. _tcscpy(AlternateSourcePath, Arg+7);
  253. }
  254. else {
  255. //
  256. // Use default asr.sif (%systemroot%\repair\asr.sif)
  257. //
  258. ExpandEnvironmentStrings(
  259. TEXT("%systemroot%\\repair"),
  260. AlternateSourcePath,
  261. MAX_PATH
  262. );
  263. }
  264. RememberOptionalDir(AlternateSourcePath,OPTDIR_OVERLAY);
  265. //
  266. // Don't block if we can't find enough disk space.
  267. //
  268. BlockOnNotEnoughSpace = FALSE;
  269. //
  270. // Run in unattended mode
  271. //
  272. UnattendedOperation = TRUE;
  273. //
  274. // Pretend we're running from CD
  275. //
  276. RunFromCD = TRUE;
  277. //
  278. // Make sure we're not upgrading
  279. //
  280. Upgrade = FALSE;
  281. //
  282. // Skip EULA
  283. //
  284. EulaComplete = TRUE;
  285. }
  286. break;
  287. case TEXT('B'):
  288. if (_tcsnicmp(Arg+2,TEXT("bvt"),3) == 0)
  289. {
  290. TCHAR* pszTemp = (TCHAR*)Arg;
  291. // setup for running BVT's
  292. RunningBVTs = TRUE;
  293. // replace all ":"'s with spaces so that _ttol will work properly
  294. while (*pszTemp)
  295. {
  296. if (*pszTemp == TEXT(':'))
  297. {
  298. *pszTemp = TEXT(' ');
  299. }
  300. pszTemp++;
  301. }
  302. // check for other #bvt switches (eg "/#bvt:nosymbols:baudrate=19200:debugport=1")
  303. if (_tcsstr(Arg, TEXT("nosymbols")))
  304. {
  305. CopySymbols = FALSE;
  306. }
  307. pszTemp = _tcsstr(Arg, TEXT("baudrate="));
  308. if (pszTemp)
  309. {
  310. pszTemp = pszTemp + ((sizeof(TEXT("baudrate=")) - sizeof(TCHAR))/sizeof(TCHAR));
  311. lDebugBaudRate = _ttol(pszTemp);
  312. }
  313. pszTemp = _tcsstr(Arg, TEXT("debugport="));
  314. if (pszTemp)
  315. {
  316. if ( _tcsstr(pszTemp, TEXT("com")) ) {
  317. pszTemp = pszTemp + ((sizeof(TEXT("debugport=com")) - sizeof(TCHAR))/sizeof(TCHAR));
  318. lDebugComPort = _ttol(pszTemp);
  319. }
  320. else {
  321. pszTemp = pszTemp + ((sizeof(TEXT("debugport=")) - sizeof(TCHAR))/sizeof(TCHAR));
  322. lDebugComPort = _ttol(pszTemp);
  323. }
  324. }
  325. break;
  326. }
  327. //
  328. // Don't block if we can't find enough disk space.
  329. //
  330. BlockOnNotEnoughSpace = FALSE;
  331. break;
  332. case TEXT('C'):
  333. //
  334. // Don't block if we can't find enough disk space.
  335. //
  336. UseBIOSToBoot = TRUE;
  337. break;
  338. #ifdef _X86_
  339. case TEXT('F'):
  340. //
  341. // temp variable to allow compliance checking
  342. //
  343. Floppyless = FALSE;
  344. break;
  345. #endif
  346. case TEXT('L'):
  347. //
  348. // Licensed processors
  349. //
  350. if(Arg[3] == TEXT(':')) {
  351. NumberOfLicensedProcessors = _tcstoul(Arg+4,NULL,10);
  352. }
  353. break;
  354. case TEXT('M'):
  355. //
  356. // Alternate source for missing files
  357. //
  358. if(Arg[3] == TEXT(':')) {
  359. _tcscpy(AlternateSourcePath, Arg+4);
  360. RememberOptionalDir(AlternateSourcePath,OPTDIR_OVERLAY); //behave like /m:
  361. }
  362. break;
  363. case TEXT('I'):
  364. if (!_tcsicmp(Arg+2,TEXT("IgnoreExceptionPackages"))) {
  365. IgnoreExceptionPackages = TRUE;
  366. }
  367. break;
  368. case TEXT('N'):
  369. #ifdef PRERELEASE
  370. if (!_tcsicmp(Arg+2,TEXT("NODEBUGBOOT"))) {
  371. AppendDebugDataToBoot = FALSE;
  372. } else
  373. //
  374. // this is PRERELEASE code only, intended to help testing of winnt32
  375. // the use of this switch is not supported in any way!
  376. //
  377. if (!_tcsicmp (Arg+2, TEXT("nopid"))) {
  378. extern BOOL NoPid;
  379. NoPid = TRUE;
  380. }
  381. else
  382. #endif
  383. {
  384. //
  385. // Skip missing files mode
  386. //
  387. AutoSkipMissingFiles = TRUE;
  388. }
  389. break;
  390. case TEXT('H'):
  391. //
  392. // Hide windows dir
  393. //
  394. HideWinDir = TRUE;
  395. break;
  396. case TEXT('P'):
  397. //
  398. // allow the user to select a partition during textmode setup
  399. //
  400. ChoosePartition = TRUE;
  401. break;
  402. case TEXT('R'):
  403. //
  404. // Pretending to run from CD.
  405. //
  406. RunFromCD = TRUE;
  407. break;
  408. case TEXT('Q'):
  409. //
  410. // Denote running from MSI file.
  411. //
  412. RunFromMSI = TRUE;
  413. break;
  414. case TEXT('S'):
  415. //
  416. // use signature based arc paths
  417. //
  418. UseSignatures = !UseSignatures;
  419. break;
  420. case TEXT('D'):
  421. //
  422. // specify the directory to install into
  423. //
  424. if(Arg[3] == TEXT(':')) {
  425. _tcscpy(InstallDir, Arg+4);
  426. }
  427. break;
  428. case TEXT('T'):
  429. //
  430. // Give the user detailed timing info during file copy.
  431. //
  432. DetailedCopyProgress = TRUE;
  433. break;
  434. case TEXT('U'):
  435. //
  436. // Plugin option. Add it to the multisz that will be passed to the plugin.
  437. //
  438. if (Arg[3] == TEXT(':')) {
  439. if (!AppendUpgradeOption (Arg+4)) {
  440. break;
  441. }
  442. //
  443. // winnt32 uses the anylocale and virusscanersok switches itself.
  444. //
  445. if (!_tcsicmp(Arg+4,TEXT("ANYLOCALE"))) {
  446. SkipLocaleCheck = TRUE;
  447. } else if (!_tcsicmp(Arg+4,TEXT("VIRUSSCANNERSOK"))) {
  448. SkipVirusScannerCheck = TRUE;
  449. } else if (!_tcsicmp(Arg+4,TEXT("NOLS"))) {
  450. NoLs = TRUE;
  451. } else if (!_tcsicmp(Arg+4,TEXT("NOBUILDCHECK"))) {
  452. CCDisableBuildCheck();
  453. }
  454. #ifdef PRERELEASE
  455. if (!_tcsicmp(Arg+4,TEXT("NOCOMPLIANCE"))) {
  456. NoCompliance = TRUE;
  457. }
  458. #endif
  459. }
  460. break;
  461. }
  462. }