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.

586 lines
15 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 (!MyGetModuleFileName(NULL, szFullPath, ARRAYSIZE(szFullPath)) ||
  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 debugger package to %windir%\Debuggers
  108. if (AddCopydirIfExists(TEXT("..\\..\\bin\\dbg\\released"), OPTDIR_DEBUGGER) ||
  109. AddCopydirIfExists(TEXT("..\\..\\dbg\\released"), OPTDIR_DEBUGGER)) // for dev postbuild installs
  110. {}
  111. }
  112. BOOL
  113. AppendUpgradeOption (
  114. IN PCTSTR String
  115. )
  116. {
  117. BOOL result = FALSE;
  118. UINT lengthInBytes;
  119. UINT lengthPlusTerminator;
  120. PTSTR UpgradeOptionsReAllocated = NULL;
  121. __try {
  122. //
  123. // Ensure there is enough room.
  124. //
  125. lengthInBytes = UpgradeOptionsLength + ((_tcslen(String) + 1) * sizeof (TCHAR));
  126. lengthPlusTerminator = lengthInBytes + sizeof (TCHAR);
  127. if (lengthPlusTerminator > UpgradeOptionsSize) {
  128. //
  129. // Allocate more space, aligned to 256 bytes.
  130. //
  131. UpgradeOptionsSize = ((lengthPlusTerminator / 256) + 1) * 256;
  132. UpgradeOptionsReAllocated = REALLOC(UpgradeOptions,UpgradeOptionsSize);
  133. }
  134. if (UpgradeOptionsReAllocated) {
  135. UpgradeOptions = UpgradeOptionsReAllocated;
  136. //
  137. // Ok, memory was successfully allocated. Save the new option onto the end
  138. // of the list.
  139. //
  140. wsprintf (
  141. (PTSTR) ((PBYTE) UpgradeOptions + UpgradeOptionsLength),
  142. TEXT("%s%c"),
  143. String,
  144. 0
  145. );
  146. UpgradeOptionsLength = lengthInBytes;
  147. } else {
  148. //
  149. // This is bad. realloc failed.
  150. //
  151. __leave;
  152. }
  153. result = TRUE;
  154. }
  155. __finally {
  156. }
  157. return result;
  158. }
  159. VOID
  160. InternalProcessCmdLineArg(
  161. IN LPCTSTR Arg
  162. )
  163. /*++
  164. Routine Description:
  165. Parse a command line arg that is thought to be internal-only.
  166. The caller should call this routine only if the switch arg char
  167. is # (ie something like /#x:foo).
  168. /#[n]:sharename internal distribution
  169. n can be a digit from 1-9 to indicate source
  170. count, default is 3 n win9x and 5 on nt.
  171. /#L:number number of licensed processors
  172. /#N auto skip missing files
  173. /#U:[Option] Upgrade option. All upgrade options are packed together
  174. into a multisz and passed to the plugin-dll.
  175. /#bvt:[Option]:[Option] Setup machine for running bvt's. Options include :nosymbols,
  176. :baudrate=XXXX, and :debugport=X
  177. /#asr[{t|f}:[AsrSifPath]] Setup machine for running ASR coverage tests, using the
  178. asr.sif specified. This includes adding /DEBUG
  179. /BAUDRATE=115200 (on IA64 use 19200 and /DEBUGPORT=COM1),
  180. in addition to setting setupcmdlineprepend="ntsd -isd -odgGx",
  181. and adding other options as appropriate.
  182. Arguments:
  183. Arg - supplies comment line argument, starting with the switch
  184. character itself (ie, - or /). This routine assumes that
  185. the interesting part of the argument starts at Arg[2].
  186. Return Value:
  187. None.
  188. --*/
  189. {
  190. UINT NumSources;
  191. UINT u;
  192. UINT length;
  193. LPTSTR src;
  194. if(!Arg[0] || !Arg[1]) {
  195. return;
  196. }
  197. NumSources = ISNT() ? 5 : 3;
  198. switch(_totupper(Arg[2])) {
  199. case TEXT('1'): case ('2'): case ('3'):
  200. case TEXT('4'): case ('5'): case ('6'):
  201. case TEXT('7'): case ('8'): case ('9'):
  202. if(Arg[3] != TEXT(':')) {
  203. break;
  204. }
  205. NumSources = Arg[2] - TEXT('0');
  206. Arg++;
  207. //
  208. // Fall through
  209. //
  210. case TEXT(':'):
  211. //
  212. // Internal distribution stuff
  213. //
  214. //
  215. // handle cases where
  216. // -they put a "\" before path
  217. // -they map a net drive and put "f:" first
  218. // -they map a net driver and put "f:\" first
  219. //
  220. src = (LPTSTR)(Arg+3);
  221. for(u=0; u<NumSources; u++) {
  222. if(SourceCount < MAX_SOURCE_COUNT) {
  223. if (GetFullPathName (
  224. src,
  225. sizeof(NativeSourcePaths[SourceCount])/sizeof(TCHAR),
  226. NativeSourcePaths[SourceCount],
  227. NULL
  228. )) {
  229. SourceCount++;
  230. }
  231. }
  232. }
  233. break;
  234. case TEXT('A'):
  235. if (_tcsnicmp(Arg+2,TEXT("asr"),3) == 0) {
  236. //
  237. // Setup machine for running ASR tests
  238. //
  239. AsrQuickTest = 3; // Assume default is full
  240. if (Arg[5] == TEXT('t') || Arg[5] == TEXT('T')) {
  241. AsrQuickTest = 2; // Text mode only
  242. }
  243. if (Arg[5] == TEXT('f') || Arg[5] == TEXT('F')) {
  244. AsrQuickTest = 3; // Full mode
  245. }
  246. if (Arg[5] != 0 && Arg[6] == TEXT(':')) {
  247. //
  248. // User specified asr.sif to use
  249. //
  250. StringCchCopy(AlternateSourcePath, ARRAYSIZE(AlternateSourcePath), Arg+7);
  251. }
  252. else {
  253. //
  254. // Use default asr.sif (%systemroot%\repair\asr.sif)
  255. //
  256. ExpandEnvironmentStrings(
  257. TEXT("%systemroot%\\repair"),
  258. AlternateSourcePath,
  259. MAX_PATH
  260. );
  261. }
  262. RememberOptionalDir(AlternateSourcePath,OPTDIR_OVERLAY);
  263. //
  264. // Don't block if we can't find enough disk space.
  265. //
  266. BlockOnNotEnoughSpace = FALSE;
  267. //
  268. // Run in unattended mode
  269. //
  270. UnattendedOperation = TRUE;
  271. //
  272. // Pretend we're running from CD
  273. //
  274. RunFromCD = TRUE;
  275. //
  276. // Make sure we're not upgrading
  277. //
  278. Upgrade = FALSE;
  279. //
  280. // Skip EULA
  281. //
  282. EulaComplete = TRUE;
  283. }
  284. break;
  285. case TEXT('B'):
  286. if (_tcsnicmp(Arg+2,TEXT("bvt"),3) == 0)
  287. {
  288. TCHAR* pszTemp = (TCHAR*)Arg;
  289. // setup for running BVT's
  290. RunningBVTs = TRUE;
  291. // replace all ":"'s with spaces so that _ttol will work properly
  292. while (*pszTemp)
  293. {
  294. if (*pszTemp == TEXT(':'))
  295. {
  296. *pszTemp = TEXT(' ');
  297. }
  298. pszTemp++;
  299. }
  300. // check for other #bvt switches (eg "/#bvt:nosymbols:baudrate=19200:debugport=1")
  301. if (_tcsstr(Arg, TEXT("nosymbols")))
  302. {
  303. CopySymbols = FALSE;
  304. }
  305. pszTemp = _tcsstr(Arg, TEXT("baudrate="));
  306. if (pszTemp)
  307. {
  308. pszTemp = pszTemp + ((sizeof(TEXT("baudrate=")) - sizeof(TCHAR))/sizeof(TCHAR));
  309. lDebugBaudRate = _ttol(pszTemp);
  310. }
  311. pszTemp = _tcsstr(Arg, TEXT("debugport="));
  312. if (pszTemp)
  313. {
  314. if ( _tcsstr(pszTemp, TEXT("com")) ) {
  315. pszTemp = pszTemp + ((sizeof(TEXT("debugport=com")) - sizeof(TCHAR))/sizeof(TCHAR));
  316. lDebugComPort = _ttol(pszTemp);
  317. }
  318. else {
  319. pszTemp = pszTemp + ((sizeof(TEXT("debugport=")) - sizeof(TCHAR))/sizeof(TCHAR));
  320. lDebugComPort = _ttol(pszTemp);
  321. }
  322. }
  323. break;
  324. }
  325. //
  326. // Don't block if we can't find enough disk space.
  327. //
  328. BlockOnNotEnoughSpace = FALSE;
  329. break;
  330. case TEXT('C'):
  331. //
  332. // Don't block if we can't find enough disk space.
  333. //
  334. UseBIOSToBoot = TRUE;
  335. break;
  336. #if defined(_AMD64_) || defined(_X86_)
  337. case TEXT('F'):
  338. //
  339. // temp variable to allow compliance checking
  340. //
  341. Floppyless = FALSE;
  342. break;
  343. #endif
  344. case TEXT('L'):
  345. //
  346. // Licensed processors
  347. //
  348. if(Arg[3] == TEXT(':')) {
  349. NumberOfLicensedProcessors = _tcstoul(Arg+4,NULL,10);
  350. }
  351. break;
  352. case TEXT('M'):
  353. //
  354. // Alternate source for missing files
  355. //
  356. if(Arg[3] == TEXT(':')) {
  357. StringCchCopy(AlternateSourcePath, ARRAYSIZE(AlternateSourcePath), Arg+4);
  358. RememberOptionalDir(AlternateSourcePath,OPTDIR_OVERLAY); //behave like /m:
  359. }
  360. break;
  361. case TEXT('I'):
  362. if (!_tcsicmp(Arg+2,TEXT("IgnoreExceptionPackages"))) {
  363. IgnoreExceptionPackages = TRUE;
  364. }
  365. break;
  366. case TEXT('N'):
  367. #ifdef PRERELEASE
  368. if (!_tcsicmp(Arg+2,TEXT("NODEBUGBOOT"))) {
  369. AppendDebugDataToBoot = FALSE;
  370. } else
  371. //
  372. // this is PRERELEASE code only, intended to help testing of winnt32
  373. // the use of this switch is not supported in any way!
  374. //
  375. if (!_tcsicmp (Arg+2, TEXT("nopid"))) {
  376. extern BOOL NoPid;
  377. NoPid = TRUE;
  378. }
  379. else
  380. #endif
  381. {
  382. //
  383. // Skip missing files mode
  384. //
  385. AutoSkipMissingFiles = TRUE;
  386. }
  387. break;
  388. case TEXT('H'):
  389. //
  390. // Hide windows dir
  391. //
  392. HideWinDir = TRUE;
  393. break;
  394. case TEXT('P'):
  395. //
  396. // allow the user to select a partition during textmode setup
  397. //
  398. ChoosePartition = TRUE;
  399. break;
  400. case TEXT('R'):
  401. //
  402. // Pretending to run from CD.
  403. //
  404. RunFromCD = TRUE;
  405. break;
  406. case TEXT('Q'):
  407. //
  408. // Denote running from MSI file.
  409. //
  410. RunFromMSI = TRUE;
  411. break;
  412. case TEXT('S'):
  413. //
  414. // use signature based arc paths
  415. //
  416. UseSignatures = !UseSignatures;
  417. break;
  418. case TEXT('D'):
  419. //
  420. // specify the directory to install into
  421. //
  422. if(Arg[3] == TEXT(':')) {
  423. StringCchCopy(InstallDir, ARRAYSIZE(InstallDir), Arg+4);
  424. }
  425. break;
  426. case TEXT('T'):
  427. //
  428. // Give the user detailed timing info during file copy.
  429. //
  430. DetailedCopyProgress = TRUE;
  431. break;
  432. case TEXT('U'):
  433. //
  434. // Plugin option. Add it to the multisz that will be passed to the plugin.
  435. //
  436. if (Arg[3] == TEXT(':')) {
  437. if (!AppendUpgradeOption (Arg+4)) {
  438. break;
  439. }
  440. //
  441. // winnt32 uses the anylocale and virusscanersok switches itself.
  442. //
  443. if (!_tcsicmp(Arg+4,TEXT("ANYLOCALE"))) {
  444. SkipLocaleCheck = TRUE;
  445. } else if (!_tcsicmp(Arg+4,TEXT("VIRUSSCANNERSOK"))) {
  446. SkipVirusScannerCheck = TRUE;
  447. } else if (!_tcsicmp(Arg+4,TEXT("NOLS"))) {
  448. NoLs = TRUE;
  449. } else if (!_tcsicmp(Arg+4,TEXT("NOBUILDCHECK"))) {
  450. CCDisableBuildCheck();
  451. }
  452. #ifdef PRERELEASE
  453. if (!_tcsicmp(Arg+4,TEXT("NOCOMPLIANCE"))) {
  454. NoCompliance = TRUE;
  455. }
  456. #endif
  457. }
  458. break;
  459. }
  460. }