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.

1441 lines
39 KiB

  1. #include "precomp.h"
  2. #pragma hdrstop
  3. /**************************************************************************/
  4. /***** Shell Component - Init routines ************************************/
  5. /**************************************************************************/
  6. //#ifdef SYMTAB_STATS
  7. //extern void SymTabStatDump(void);
  8. //#endif
  9. extern SZ SzGetNextCmdLineString(PSZ);
  10. extern BOOL fFullScreen;
  11. extern PSTR LOCAL_SOURCE_DIRECTORY;
  12. extern VOID Usage(HANDLE);
  13. //
  14. // Helper macro to make object attribute initialization a little cleaner.
  15. //
  16. #define INIT_OBJA(Obja,UnicodeString,UnicodeText) \
  17. \
  18. RtlInitUnicodeString((UnicodeString),(UnicodeText)); \
  19. \
  20. InitializeObjectAttributes( \
  21. (Obja), \
  22. (UnicodeString), \
  23. OBJ_CASE_INSENSITIVE, \
  24. NULL, \
  25. NULL \
  26. )
  27. SZ szShlScriptSection = NULL;
  28. CHP szArcPrefix[] = "\\ArcName\\";
  29. #define ArcPrefixLen ((sizeof(szArcPrefix) / sizeof(CHP)) - 1)
  30. CHP szNtPrefix[] = "\\Device\\";
  31. #define NtPrefixLen ((sizeof(szNtPrefix) / sizeof(CHP)) - 1)
  32. //
  33. // Define a work area for path manipulation (note that we make
  34. // it large enough for Unicode as well, so it can do dual duty.)
  35. //
  36. CHP TemporaryPathBuffer[cchlFullPathMax * sizeof(WCHAR)];
  37. //
  38. // Buffer used in querying object directories
  39. //
  40. UCHAR ObjBuffer[1024];
  41. SZ szDosType = "DOS";
  42. SZ szUncType = "UNC";
  43. typedef struct _INITSYMHANDLE *PINITSYMHANDLE;
  44. typedef struct _INITSYMHANDLE {
  45. SZ szName;
  46. HANDLE Handle;
  47. } INITSYMHANDLE;
  48. typedef struct _INITSYMNUMBER *PINITSYMNUMBER;
  49. typedef struct _INITSYMNUMBER {
  50. SZ szName;
  51. DWORD dwNumber;
  52. } INITSYMNUMBER;
  53. INITSYMHANDLE InitSymHandle[] = {
  54. //
  55. // Predefined registry handles
  56. //
  57. { "REG_H_LOCAL", HKEY_LOCAL_MACHINE },
  58. { "REG_H_CLASSES", HKEY_CLASSES_ROOT },
  59. { "REG_H_USERS", HKEY_USERS },
  60. { "REG_H_CUSER", HKEY_CURRENT_USER },
  61. //
  62. { NULL, 0 }
  63. };
  64. INITSYMNUMBER InitSymNumber[] = {
  65. //
  66. // Registry key creation options
  67. //
  68. { "REG_OPT_VOLATILE", REG_OPTION_VOLATILE },
  69. { "REG_OPT_NONVOL", REG_OPTION_NON_VOLATILE },
  70. //
  71. // Registry value types
  72. //
  73. { "REG_VT_NONE", REG_NONE },
  74. { "REG_VT_BIN", REG_BINARY },
  75. { "REG_VT_SZ", REG_SZ },
  76. { "REG_VT_EXPAND_SZ", REG_EXPAND_SZ },
  77. { "REG_VT_MULTI_SZ", REG_MULTI_SZ },
  78. { "REG_VT_DWORD", REG_DWORD },
  79. { "REG_VT_RESOURCE_LIST", REG_RESOURCE_LIST },
  80. { "REG_VT_FULL_RESOURCE_DESCRIPTOR", REG_FULL_RESOURCE_DESCRIPTOR },
  81. { "REG_VT_RESOURCE_REQUIREMENTS_LIST", REG_RESOURCE_REQUIREMENTS_LIST },
  82. //
  83. // Registry access mask bits
  84. //
  85. { "REG_KEY_QUERY_VALUE", KEY_QUERY_VALUE },
  86. { "REG_KEY_SET_VALUE", KEY_SET_VALUE },
  87. { "REG_KEY_CREATE_SUB_KEY", KEY_CREATE_SUB_KEY },
  88. { "REG_KEY_ENUMERATE_SUB_KEYS", KEY_ENUMERATE_SUB_KEYS },
  89. { "REG_KEY_NOTIFY", KEY_NOTIFY },
  90. { "REG_KEY_READ", KEY_READ },
  91. { "REG_KEY_WRITE", KEY_WRITE },
  92. { "REG_KEY_READWRITE", KEY_READ | KEY_WRITE },
  93. { "REG_KEY_EXECUTE", KEY_EXECUTE },
  94. { "REG_KEY_ALL_ACCESS", KEY_ALL_ACCESS },
  95. //
  96. // Registry errors BugBug** should replace with values from winerror.h
  97. //
  98. { "REG_ERROR_SUCCESS", 0L },
  99. //
  100. // Service Types (Bit Mask)
  101. //
  102. { "SERVICE_KERNEL_DRIVER", SERVICE_KERNEL_DRIVER },
  103. { "SERVICE_FILE_SYSTEM_DRIVER", SERVICE_FILE_SYSTEM_DRIVER },
  104. { "SERVICE_ADAPTER", SERVICE_ADAPTER },
  105. { "SERVICE_WIN32_OWN_PROCESS", SERVICE_WIN32_OWN_PROCESS },
  106. { "SERVICE_WIN32_SHARE_PROCESS", SERVICE_WIN32_SHARE_PROCESS },
  107. //
  108. // Start Type
  109. //
  110. { "SERVICE_BOOT_START", SERVICE_BOOT_START },
  111. { "SERVICE_SYSTEM_START", SERVICE_SYSTEM_START },
  112. { "SERVICE_AUTO_START", SERVICE_AUTO_START },
  113. { "SERVICE_DEMAND_START", SERVICE_DEMAND_START },
  114. { "SERVICE_DISABLED", SERVICE_DISABLED },
  115. //
  116. // Error control type
  117. //
  118. { "SERVICE_ERROR_IGNORE", SERVICE_ERROR_IGNORE },
  119. { "SERVICE_ERROR_NORMAL", SERVICE_ERROR_NORMAL },
  120. { "SERVICE_ERROR_SEVERE", SERVICE_ERROR_SEVERE },
  121. { "SERVICE_ERROR_CRITICAL", SERVICE_ERROR_CRITICAL },
  122. //
  123. // ShellCode values
  124. //
  125. { "SHELL_CODE_OK", SHELL_CODE_OK },
  126. { "SHELL_CODE_NO_SUCH_INF", SHELL_CODE_NO_SUCH_INF },
  127. { "SHELL_CODE_NO_SUCH_SECTION", SHELL_CODE_NO_SUCH_SECTION },
  128. { "SHELL_CODE_ERROR", SHELL_CODE_ERROR },
  129. //
  130. // Exit_Code values
  131. //
  132. { "SETUP_ERROR_SUCCESS", SETUP_ERROR_SUCCESS },
  133. { "SETUP_ERROR_USERCANCEL", SETUP_ERROR_USERCANCEL },
  134. { "SETUP_ERROR_GENERAL", SETUP_ERROR_GENERAL },
  135. //
  136. { NULL, 0 }
  137. };
  138. BOOL fCheckInfValidity = fFalse;
  139. BOOL FMakeWindows(HANDLE hInstance);
  140. BOOL FProcessForDriveType(SZ, SZ, SZ, SZ);
  141. BOOL FProcessInfSrcPath( SZ szInf, SZ szCWD, SZ szProcessedDir );
  142. HWND FindProperParent ( void ) ;
  143. HANDLE hVerDLL = NULL;
  144. #define FExistFile(sz) ((BOOL)(PfhOpenFile(sz, ofmExistRead) != (PFH)NULL))
  145. //
  146. // Symbols that are defined in the command line are kept in a list of
  147. // VALUE_BLOCKs until the symbol table is created, point at which they
  148. // are added to the symbol table and the VALUE_BLOCK list is destroyed.
  149. //
  150. typedef struct _VALUE_BLOCK *PVALUE_BLOCK;
  151. typedef struct _VALUE_BLOCK {
  152. PVALUE_BLOCK pNext; // Next in chain
  153. SZ szSymbol; // Symbol
  154. SZ szValue; // Value
  155. } VALUE_BLOCK;
  156. PVALUE_BLOCK pCmdLineSymbols = NULL;
  157. /*
  158. ** Purpose:
  159. ** Generates a Usage message.
  160. ** Arguments:
  161. ** hInst: For retrieving string resources.
  162. ** Returns:
  163. ** none
  164. ***************************************************************************/
  165. VOID Usage(hInst)
  166. HANDLE hInst;
  167. {
  168. CHP rgch[1024];
  169. CCHP cchpBuf = 1024;
  170. CCHP cchp, cchpCurrent = 0;
  171. UINT wID[] = { IDS_USAGE_MSG1, IDS_USAGE_MSG2, IDS_USAGE_USAGE,
  172. IDS_USAGE_F, IDS_USAGE_I, IDS_USAGE_C,
  173. IDS_USAGE_S, IDS_USAGE_T, IDS_USAGE_V
  174. } ;
  175. INT i, j;
  176. EvalAssert(LoadString(hInst, IDS_USAGE_TITLE, rgchBufTmpShort,
  177. cchpBufTmpShortMax));
  178. for( i = 0, j = sizeof( wID ) / sizeof( UINT ); i < j; i++ ) {
  179. Assert(cchpBuf > 0);
  180. EvalAssert((cchp = LoadString(hInst, wID[i], rgch + cchpCurrent,
  181. cchpBuf)) != 0);
  182. cchpCurrent = cchpCurrent + cchp;
  183. cchpBuf = cchpBuf - cchp;
  184. }
  185. while (!MessageBox(hWndShell, rgch, rgchBufTmpShort, MB_OK)) {
  186. if (!FHandleOOM(hWndShell)) {
  187. break;
  188. }
  189. }
  190. }
  191. /*
  192. ** Purpose:
  193. ** Generates a message indicating that maintenance-mode setup
  194. ** functionality is now accessible via Control Panel applets.
  195. ** Arguments:
  196. ** hInst: For retrieving string resources.
  197. ** Returns:
  198. ** none
  199. ***************************************************************************/
  200. VOID MaintSetupObsoleteMsg(hInst)
  201. HANDLE hInst;
  202. {
  203. CHP rgch[1024];
  204. CCHP cchpBuf = 1024;
  205. CCHP cchp, cchpCurrent = 0;
  206. UINT wID[] = { IDS_MAINTOBS_MSG1 };
  207. INT i, j;
  208. EvalAssert(LoadString(hInst, IDS_WINDOWS_NT_SETUP, rgchBufTmpShort,
  209. cchpBufTmpShortMax));
  210. for( i = 0, j = sizeof( wID ) / sizeof( UINT ); i < j; i++ ) {
  211. Assert(cchpBuf > 0);
  212. EvalAssert((cchp = LoadString(hInst, wID[i], rgch + cchpCurrent,
  213. cchpBuf)) != 0);
  214. cchpCurrent = cchpCurrent + cchp;
  215. cchpBuf = cchpBuf - cchp;
  216. }
  217. while (!MessageBox(hWndShell, rgch, rgchBufTmpShort, MB_ICONINFORMATION | MB_OK)) {
  218. if (!FHandleOOM(hWndShell)) {
  219. break;
  220. }
  221. }
  222. }
  223. /*
  224. ** Purpose:
  225. ** Gets the next string on the Command Line.
  226. ** Arguments:
  227. ** pszCmdLine: Command Line argument as received in WinMain().
  228. ** Returns:
  229. ** SZ
  230. ***************************************************************************/
  231. SZ SzGetNextCmdLineString(pszCmdLine)
  232. PSZ pszCmdLine;
  233. {
  234. SZ szCur = *pszCmdLine;
  235. SZ szAnswer;
  236. while (FWhiteSpaceChp(*szCur))
  237. szCur = SzNextChar(szCur);
  238. if (*szCur == '"')
  239. {
  240. SZ szWriteCur;
  241. CB cbWrite = (CB)0;
  242. while ((szWriteCur = szAnswer = (SZ)SAlloc((CB)4096)) == (SZ)NULL)
  243. if (!FHandleOOM(hWndShell))
  244. return((SZ)NULL);
  245. szCur = SzNextChar(szCur);
  246. while (fTrue)
  247. {
  248. SZ szNext;
  249. if (*szCur == '"' &&
  250. *(szCur = SzNextChar(szCur)) != '"')
  251. break;
  252. if (*szCur == '\0')
  253. {
  254. SFree(szAnswer);
  255. return((SZ)NULL);
  256. }
  257. szNext = SzNextChar(szCur);
  258. while (szCur < szNext)
  259. {
  260. if (++cbWrite >= 4096)
  261. {
  262. SFree(szAnswer);
  263. return((SZ)NULL);
  264. }
  265. *szWriteCur++ = *szCur++;
  266. }
  267. }
  268. *szWriteCur = '\0';
  269. Assert(strlen(szAnswer) == cbWrite);
  270. Assert(cbWrite + 1 <= (CB)4096);
  271. if (cbWrite + 1 < (CB)4096)
  272. szAnswer = SRealloc((PB)szAnswer, cbWrite + 1);
  273. Assert(szAnswer != (SZ)NULL);
  274. }
  275. else if (*(*pszCmdLine = szCur) == '\0')
  276. return((SZ)NULL);
  277. else
  278. {
  279. CHP chpSav;
  280. while (*szCur != '\0' &&
  281. !FWhiteSpaceChp(*szCur))
  282. szCur = SzNextChar(szCur);
  283. chpSav = *szCur;
  284. *szCur = '\0';
  285. while ((szAnswer = SzDupl(*pszCmdLine)) == (SZ)NULL)
  286. if (!FHandleOOM(hWndShell))
  287. break;
  288. *szCur = chpSav;
  289. }
  290. while (*szCur != '\0' &&
  291. FWhiteSpaceChp(*szCur))
  292. szCur = SzNextChar(szCur);
  293. *pszCmdLine = szCur;
  294. return(szAnswer);
  295. }
  296. /*
  297. ** Purpose:
  298. ** Parses the Command Line received in WinMain().
  299. ** Arguments:
  300. ** ??
  301. ** Returns:
  302. ** BOOL
  303. ***************************************************************************/
  304. INT
  305. ParseCmdLine(
  306. HANDLE hInst,
  307. SZ szCmdLine,
  308. PSZ pszInfSrcPath,
  309. PSZ pszDestDir,
  310. PSZ pszSrcDir,
  311. PSZ pszCWD,
  312. INT * pwModeSetup
  313. )
  314. {
  315. BOOL fSetupInfSpecified = fFalse;
  316. BOOL fScriptSectionSpecified = fFalse;
  317. BOOL fSourcePathSpecified = fFalse;
  318. SZ szBase;
  319. INT cchp;
  320. SZ szCur;
  321. SZ szLastBackSlash = NULL;
  322. CHAR szInfPath[MAX_PATH];
  323. BOOL bStatus;
  324. *pwModeSetup = wModeSetupNormal;
  325. while(FWhiteSpaceChp(*szCmdLine)) {
  326. szCmdLine = SzNextChar(szCmdLine);
  327. }
  328. while(*szCmdLine) {
  329. if (*szCmdLine == '-' || *szCmdLine == '/') {
  330. szCmdLine++;
  331. switch (*szCmdLine++){
  332. case 'c':
  333. case 'C':
  334. if(fScriptSectionSpecified
  335. || (szShlScriptSection = SzGetNextCmdLineString(&szCmdLine)) == NULL) {
  336. Usage(hInst);
  337. return(CMDLINE_ERROR);
  338. }
  339. if(*(szShlScriptSection) == '\0'
  340. || *(szShlScriptSection) == ']'
  341. || *(szShlScriptSection) == '[') {
  342. LoadString(
  343. hInst,
  344. IDS_ERROR,
  345. rgchBufTmpShort,
  346. cchpBufTmpShortMax
  347. );
  348. LoadString(
  349. hInst,
  350. IDS_BAD_SHL_SCRIPT_SECT,
  351. rgchBufTmpLong,
  352. cchpBufTmpLongMax
  353. );
  354. MessageBox(
  355. hWndShell,
  356. rgchBufTmpLong,
  357. rgchBufTmpShort,
  358. MB_OK | MB_ICONHAND
  359. );
  360. Usage(hInst);
  361. return(CMDLINE_ERROR);
  362. }
  363. fScriptSectionSpecified = fTrue;
  364. break;
  365. //
  366. // Allow /k but ignore it. It's processed in setup.c.
  367. //
  368. case 'f':
  369. case 'F':
  370. case 'k':
  371. case 'K':
  372. break;
  373. case 'w':
  374. case 'W':
  375. //
  376. // Since the /w parameter has already been handled
  377. // (see SETUP.C), eat the argument.
  378. //
  379. if(szBase = SzGetNextCmdLineString(&szCmdLine)) {
  380. SFree(szBase);
  381. }
  382. break;
  383. case 'i':
  384. case 'I':
  385. if (fSetupInfSpecified ||
  386. (*pszInfSrcPath = SzGetNextCmdLineString(&szCmdLine)) == (SZ)NULL)
  387. {
  388. Usage(hInst);
  389. return(CMDLINE_ERROR);
  390. }
  391. if (**pszInfSrcPath == '\0') {
  392. LoadString(hInst, IDS_ERROR, rgchBufTmpShort,
  393. cchpBufTmpShortMax);
  394. LoadString(hInst, IDS_BAD_INF_SRC, rgchBufTmpLong,
  395. cchpBufTmpLongMax);
  396. MessageBox(hWndShell, rgchBufTmpLong, rgchBufTmpShort,
  397. MB_OK | MB_ICONHAND);
  398. Usage(hInst);
  399. return(CMDLINE_ERROR);
  400. }
  401. fSetupInfSpecified = fTrue;
  402. break;
  403. case 'g':
  404. case 'G':
  405. if (*pwModeSetup != wModeSetupNormal)
  406. {
  407. Usage(hInst);
  408. return(CMDLINE_ERROR);
  409. }
  410. *pwModeSetup = wModeGuiInitialSetup;
  411. break;
  412. case 's':
  413. case 'S':
  414. *pszSrcDir = SzGetNextCmdLineString(&szCmdLine);
  415. if(*pszSrcDir == NULL) {
  416. Usage(hInst);
  417. return(CMDLINE_ERROR);
  418. }
  419. if(**pszSrcDir == '\0') {
  420. LoadString(
  421. hInst,
  422. IDS_ERROR,
  423. rgchBufTmpShort,
  424. cchpBufTmpShortMax
  425. );
  426. LoadString(
  427. hInst,
  428. IDS_BAD_SRC_PATH,
  429. rgchBufTmpLong,
  430. cchpBufTmpLongMax
  431. );
  432. MessageBox(
  433. hWndShell,
  434. rgchBufTmpLong,
  435. rgchBufTmpShort,
  436. MB_OK | MB_ICONHAND
  437. );
  438. Usage(hInst);
  439. return(CMDLINE_ERROR);
  440. }
  441. fSourcePathSpecified = fTrue;
  442. break;
  443. case 't':
  444. case 'T':
  445. {
  446. SZ szSymbol;
  447. SZ szEqual;
  448. SZ szValue;
  449. PVALUE_BLOCK pVb;
  450. if ( ( szSymbol = SzGetNextCmdLineString( &szCmdLine ) ) == NULL ) {
  451. Usage(hInst);
  452. return CMDLINE_ERROR;
  453. }
  454. if ( ( szEqual = SzGetNextCmdLineString( &szCmdLine ) ) == NULL ) {
  455. Usage(hInst);
  456. return CMDLINE_ERROR;
  457. }
  458. if ( ( szValue = SzGetNextCmdLineString( &szCmdLine ) ) == NULL ) {
  459. Usage(hInst);
  460. return CMDLINE_ERROR;
  461. }
  462. if ( (*szEqual != '=') || (*(szEqual+1) != '\0' ) ) {
  463. Usage(hInst);
  464. return CMDLINE_ERROR;
  465. }
  466. while ( (pVb = (PVALUE_BLOCK)SAlloc( sizeof( VALUE_BLOCK ) )) == NULL ) {
  467. if ( !FHandleOOM(hWndShell)) {
  468. return CMDLINE_ERROR;
  469. }
  470. }
  471. pVb->szSymbol = szSymbol;
  472. pVb->szValue = szValue;
  473. if ( pCmdLineSymbols ) {
  474. pVb->pNext = pCmdLineSymbols;
  475. } else {
  476. pVb->pNext = NULL;
  477. }
  478. pCmdLineSymbols = pVb;
  479. }
  480. break;
  481. case 'v':
  482. case 'V':
  483. fCheckInfValidity = fTrue;
  484. break;
  485. case '?':
  486. default:
  487. Usage(hInst);
  488. return(CMDLINE_SETUPDONE);
  489. } // switch
  490. } else {
  491. Usage(hInst);
  492. return(CMDLINE_ERROR);
  493. } // if we have - or /
  494. while (FWhiteSpaceChp(*szCmdLine)) {
  495. szCmdLine = SzNextChar(szCmdLine);
  496. }
  497. } // while unseen chars on cmd line
  498. while((szCur = *pszCWD = (SZ)SAlloc((CB)4096)) == NULL) {
  499. if(!FHandleOOM(hWndShell)) {
  500. return(CMDLINE_ERROR);
  501. }
  502. }
  503. //
  504. // Want name of exe, not name of this dll.
  505. //
  506. if ((cchp = GetModuleFileName(hInst, (LPSTR)szCur, 4095)) >= 4095) {
  507. LoadString(hInst, IDS_ERROR, rgchBufTmpShort, cchpBufTmpShortMax);
  508. LoadString(hInst, IDS_EXE_PATH_LONG, rgchBufTmpLong,cchpBufTmpLongMax);
  509. MessageBox(hWndShell, rgchBufTmpLong, rgchBufTmpShort,MB_OK | MB_ICONHAND);
  510. SFree(szCur);
  511. return(CMDLINE_ERROR);
  512. }
  513. if (PfhOpenFile(szCur, ofmExistRead) == NULL) {
  514. LoadString(hInst, IDS_INTERNAL_ERROR, rgchBufTmpShort,
  515. cchpBufTmpShortMax);
  516. LoadString(hInst, IDS_GET_MOD_FAIL, rgchBufTmpLong,
  517. cchpBufTmpLongMax);
  518. MessageBox(hWndShell, rgchBufTmpLong, rgchBufTmpShort,
  519. MB_OK | MB_ICONHAND);
  520. SFree(*pszCWD);
  521. return(CMDLINE_ERROR);
  522. }
  523. while(*szCur) {
  524. if(*szCur++ == '\\') {
  525. szLastBackSlash = szCur;
  526. }
  527. }
  528. if (szLastBackSlash == (SZ)NULL) {
  529. LoadString(hInst, IDS_INTERNAL_ERROR, rgchBufTmpShort,
  530. cchpBufTmpShortMax);
  531. LoadString(hInst, IDS_GET_MOD_FAIL, rgchBufTmpLong,
  532. cchpBufTmpLongMax);
  533. MessageBox(hWndShell, rgchBufTmpLong, rgchBufTmpShort,
  534. MB_OK | MB_ICONHAND);
  535. SFree(*pszCWD);
  536. return(CMDLINE_ERROR);
  537. }
  538. if(!fSetupInfSpecified) {
  539. szCur = szLastBackSlash;
  540. while (*szCur != '\0') {
  541. if (*szCur == '.') {
  542. *szCur = '\0';
  543. break;
  544. }
  545. szCur++;
  546. }
  547. while((szBase = SzDupl(szLastBackSlash)) == (SZ)NULL) {
  548. if(!FHandleOOM(hWndShell)) {
  549. return(CMDLINE_ERROR);
  550. }
  551. }
  552. }
  553. *szLastBackSlash = '\0';
  554. if(strlen(*pszCWD) + 1 < 4096) {
  555. *pszCWD = SRealloc(*pszCWD,strlen(*pszCWD)+1);
  556. }
  557. if(!fSourcePathSpecified) {
  558. while((*pszSrcDir = SzDupl(*pszCWD)) == (SZ)NULL) {
  559. if (!FHandleOOM(hWndShell)) {
  560. return(CMDLINE_ERROR);
  561. }
  562. }
  563. }
  564. //
  565. // if setup inf is not specified, then user is attempting to enter
  566. // maintenance-mode setup, which is obsolete. Give the user a friendly
  567. // message informing them of this, and directing them to the new functionality
  568. // in the Control Panel.
  569. //
  570. if(!fSetupInfSpecified) {
  571. Assert(szBase);
  572. SFree(szBase);
  573. MaintSetupObsoleteMsg(hInst);
  574. return CMDLINE_ERROR;
  575. /*
  576. LoadString(hInst,IDS_SETUP_INF,rgchBufTmpLong,cchpBufTmpLongMax);
  577. while((*pszInfSrcPath = SAlloc(strlen(szBase)+strlen(rgchBufTmpLong)+2)) == NULL) {
  578. if (!FHandleOOM(hWndShell)) {
  579. return( CMDLINE_ERROR );
  580. }
  581. }
  582. strcpy(*pszInfSrcPath,szBase);
  583. lstrcat(*pszInfSrcPath,".");
  584. lstrcat(*pszInfSrcPath,rgchBufTmpLong);
  585. */
  586. }
  587. //
  588. // Process the setup inf found ( check to see if it exists ) in the
  589. // cwd or in windows system .. and get a full path back to the processed
  590. // setup inf location
  591. //
  592. bStatus = FProcessInfSrcPath(*pszInfSrcPath,*pszCWD,szInfPath);
  593. if(!bStatus) {
  594. LoadString( hInst, IDS_ERROR, rgchBufTmpShort, cchpBufTmpShortMax );
  595. LoadString( hInst, IDS_BAD_INF_SRC, rgchBufTmpLong, cchpBufTmpLongMax);
  596. MessageBox(hWndShell, rgchBufTmpLong, rgchBufTmpShort,MB_OK | MB_ICONHAND);
  597. Usage(hInst);
  598. return(CMDLINE_ERROR);
  599. }
  600. SFree(*pszInfSrcPath);
  601. *pszInfSrcPath = SAlloc(strlen( szInfPath ) + 1 );
  602. strcpy(*pszInfSrcPath, szInfPath);
  603. *pszDestDir = NULL;
  604. if(!fScriptSectionSpecified) {
  605. LoadString(hInst,IDS_SHELL_CMDS_SECT,rgchBufTmpShort,cchpBufTmpShortMax);
  606. while((szShlScriptSection = SzDupl(rgchBufTmpShort)) == (SZ)NULL) {
  607. if(!FHandleOOM(hWndShell)) {
  608. return(CMDLINE_ERROR);
  609. }
  610. }
  611. }
  612. return(CMDLINE_SUCCESS);
  613. }
  614. BOOL
  615. CreateShellWindow(
  616. IN HANDLE hInstance,
  617. IN INT nCmdShow,
  618. IN BOOL CleanUp
  619. )
  620. {
  621. HDC hdc;
  622. TEXTMETRIC tm;
  623. WNDCLASS wc;
  624. BOOL RegisterStatus;
  625. if(!CleanUp) {
  626. nCmdShow = SW_SHOWMAXIMIZED;
  627. hInst = hInstance;
  628. wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
  629. wc.lpfnWndProc = ShellWndProc;
  630. wc.cbClsExtra = 0;
  631. wc.cbWndExtra = 0;
  632. wc.hInstance = hInstance;
  633. wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_STF_ICON));
  634. wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  635. wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  636. wc.lpszMenuName = NULL;
  637. }
  638. wc.lpszClassName = "Stuff-Shell";
  639. if(CleanUp) {
  640. ProInit(FALSE);
  641. ControlInit(FALSE);
  642. DlgDefClassInit(hInstance,FALSE);
  643. ButtonControlTerm();
  644. UnregisterClass(wc.lpszClassName,hInst);
  645. return(TRUE);
  646. } else {
  647. RegisterStatus = RegisterClass(&wc);
  648. RegisterStatus &= ButtonControlInit(hInstance);
  649. RegisterStatus &= DlgDefClassInit(hInstance,TRUE);
  650. RegisterStatus &= ControlInit(TRUE);
  651. RegisterStatus &= ProInit(TRUE);
  652. }
  653. if(!RegisterStatus) {
  654. LoadString(hInstance,IDS_ERROR,rgchBufTmpShort,cchpBufTmpShortMax);
  655. LoadString(hInstance,IDS_REGISTER_CLASS,rgchBufTmpLong,cchpBufTmpLongMax);
  656. MessageBox(
  657. NULL,
  658. rgchBufTmpLong,
  659. rgchBufTmpShort,
  660. MB_OK | MB_ICONHAND | MB_SYSTEMMODAL
  661. );
  662. return(fFalse);
  663. }
  664. hdc = GetDC(NULL);
  665. if (hdc) {
  666. GetTextMetrics(hdc, &tm);
  667. dxChar = tm.tmAveCharWidth;
  668. dyChar = tm.tmHeight;
  669. ReleaseDC(NULL, hdc);
  670. }
  671. if(!FMakeWindows(hInstance)) {
  672. LoadString(hInstance,IDS_ERROR,rgchBufTmpShort,cchpBufTmpShortMax);
  673. LoadString(hInstance,IDS_CREATE_WINDOW,rgchBufTmpLong,cchpBufTmpLongMax);
  674. MessageBox(
  675. NULL,
  676. rgchBufTmpLong,
  677. rgchBufTmpShort,
  678. MB_OK | MB_ICONHAND | MB_SYSTEMMODAL
  679. );
  680. return(fFalse);
  681. }
  682. if ( ! fFullScreen ) {
  683. RECT rWind ;
  684. GetWindowRect( hWndShell, & rWind ) ;
  685. MoveWindow( hWndShell,
  686. 20000,
  687. 20000,
  688. rWind.right - rWind.left,
  689. rWind.bottom - rWind.top,
  690. FALSE ) ;
  691. nCmdShow = SW_SHOWNOACTIVATE ;
  692. }
  693. ShowWindow(hWndShell,nCmdShow);
  694. UpdateWindow(hWndShell);
  695. if (!FInitHook()) {
  696. //
  697. // BUGBUG.. Do we need to process this error, or do we just lose
  698. // the capability to process keyboard hooks
  699. //
  700. }
  701. return(fTrue);
  702. }
  703. /*
  704. ** Purpose:
  705. ** Initializes structures.
  706. ** Arguments:
  707. ** ??
  708. ** Returns:
  709. ** BOOL
  710. ***************************************************************************/
  711. BOOL
  712. FInitApp(
  713. HANDLE hInstance,
  714. SZ szInfSrcPath,
  715. SZ szDestDir,
  716. SZ szSrcDir,
  717. SZ szCWD,
  718. INT wModeSetup
  719. )
  720. {
  721. GRC grc = grcOkay;
  722. INT Line;
  723. CHAR szName[cchlFullPathMax];
  724. CHAR szDriveType[10];
  725. CHAR szProcessedDir[cchlFullPathMax];
  726. PINFCONTEXT pContext;
  727. PINFTEMPINFO pTempInfo;
  728. SZ szInstallType;
  729. ChkArg(hInstance != (HANDLE)NULL, 1, fFalse);
  730. ChkArg(szInfSrcPath != (SZ)NULL && *szInfSrcPath != '\0', 2, fFalse);
  731. ChkArg(szSrcDir != (SZ)NULL && *szSrcDir != '\0', 4, fFalse);
  732. ChkArg(szCWD != (SZ)NULL && *szCWD != '\0', 5, fFalse);
  733. Assert(szShlScriptSection != (SZ)NULL && *(szShlScriptSection) != '\0');
  734. //
  735. // Create INF permanent and temporary info.
  736. //
  737. PathToInfName( szInfSrcPath, szName );
  738. while ( !(pTempInfo = (PINFTEMPINFO)CreateInfTempInfo( AddInfPermInfo( szName ) )) ) {
  739. if (!FHandleOOM(hWndShell))
  740. return(fFalse);
  741. }
  742. //
  743. // Create global context.
  744. //
  745. while ( !(pContext = (PINFCONTEXT)SAlloc( (CB)sizeof(CONTEXT) )) ) {
  746. if (!FHandleOOM(hWndShell))
  747. return(fFalse);
  748. }
  749. pContext->pInfTempInfo = pTempInfo;
  750. pContext->pNext = NULL;
  751. PushContext( pContext );
  752. pLocalContext()->szShlScriptSection = szShlScriptSection;
  753. //
  754. // Add all the symbols specified in the command line
  755. //
  756. while ( pCmdLineSymbols ) {
  757. PVALUE_BLOCK p = pCmdLineSymbols;
  758. pCmdLineSymbols = pCmdLineSymbols->pNext;
  759. while (!FAddSymbolValueToSymTab(p->szSymbol, p->szValue)) {
  760. if (!FHandleOOM(hWndShell)) {
  761. return(fFalse);
  762. }
  763. }
  764. SFree( p->szSymbol );
  765. SFree( p->szValue );
  766. SFree( p );
  767. }
  768. FInitParsingTables();
  769. GetWindowsDirectory(szProcessedDir,sizeof(szProcessedDir));
  770. while(!FAddSymbolValueToSymTab("STF_WINDOWS_DIR",szProcessedDir)) {
  771. if(!FHandleOOM(hWndShell)) {
  772. return(fFalse);
  773. }
  774. }
  775. GetSystemDirectory(szProcessedDir,sizeof(szProcessedDir));
  776. while(!FAddSymbolValueToSymTab("STF_SYSTEM_DIR",szProcessedDir)) {
  777. if(!FHandleOOM(hWndShell)) {
  778. return(fFalse);
  779. }
  780. }
  781. //
  782. // Process SRC DIR
  783. //
  784. if (!FProcessForDriveType(szSrcDir, szDriveType, szCWD, szProcessedDir)) {
  785. return(fFalse);
  786. }
  787. while (!FAddSymbolValueToSymTab("STF_SRCTYPE", szDriveType)) {
  788. if (!FHandleOOM(hWndShell)) {
  789. return(fFalse);
  790. }
  791. }
  792. while (!FAddSymbolValueToSymTab("STF_SRCDIR", szProcessedDir)) {
  793. if (!FHandleOOM(hWndShell)) {
  794. return(fFalse);
  795. }
  796. }
  797. //
  798. // Process DEST DIR
  799. //
  800. if (szDestDir != NULL) {
  801. if (!FProcessForDriveType(szDestDir, szDriveType, szCWD, szProcessedDir)) {
  802. return(fFalse);
  803. }
  804. while (!FAddSymbolValueToSymTab("STF_DSTTYPE", szDriveType)) {
  805. if (!FHandleOOM(hWndShell)) {
  806. return(fFalse);
  807. }
  808. }
  809. while (!FAddSymbolValueToSymTab("STF_DSTDIR", szProcessedDir)) {
  810. if (!FHandleOOM(hWndShell)) {
  811. return(fFalse);
  812. }
  813. }
  814. }
  815. else {
  816. while (!FAddSymbolValueToSymTab("STF_DSTTYPE", "NONE")) {
  817. if (!FHandleOOM(hWndShell)) {
  818. return(fFalse);
  819. }
  820. }
  821. }
  822. //
  823. // Process INF SRC PATH
  824. //
  825. while (!FAddSymbolValueToSymTab("STF_SRCINFPATH", szInfSrcPath))
  826. if (!FHandleOOM(hWndShell))
  827. return(fFalse);
  828. while (!FAddSymbolValueToSymTab("STF_CONTEXTINFNAME", szInfSrcPath))
  829. if (!FHandleOOM(hWndShell))
  830. return(fFalse);
  831. //
  832. // Get the SETUP working directory
  833. //
  834. while (!FAddSymbolValueToSymTab("STF_CWDDIR", szCWD))
  835. if (!FHandleOOM(hWndShell))
  836. return(fFalse);
  837. while (!FAddSymbolValueToSymTab("STF_SYS_INIT", "NO"))
  838. if (!FHandleOOM(hWndShell))
  839. return(fFalse);
  840. {
  841. char NumTmp[9];
  842. HWND hw ;
  843. hw = hwParam
  844. ? FindProperParent()
  845. : hWndShell ;
  846. wsprintf(NumTmp,"%lx",hw);
  847. while (!FAddSymbolValueToSymTab("STF_HWND", NumTmp))
  848. {
  849. if (!FHandleOOM(hWndShell)) {
  850. return(fFalse);
  851. }
  852. }
  853. }
  854. {
  855. //
  856. // Registry constants
  857. //
  858. char NumTmp[20];
  859. PINITSYMHANDLE pSymHandle;
  860. PINITSYMNUMBER pSymNumber;
  861. //
  862. // Handles
  863. //
  864. pSymHandle = InitSymHandle;
  865. while ( pSymHandle->szName ) {
  866. wsprintf(NumTmp,"|%ld", pSymHandle->Handle );
  867. while (!FAddSymbolValueToSymTab(pSymHandle->szName, NumTmp)) {
  868. if (!FHandleOOM(hWndShell)) {
  869. return(fFalse);
  870. }
  871. }
  872. pSymHandle++;
  873. }
  874. //
  875. // Numeric values
  876. //
  877. pSymNumber = InitSymNumber;
  878. while ( pSymNumber->szName ) {
  879. wsprintf(NumTmp,"%ld", pSymNumber->dwNumber );
  880. while (!FAddSymbolValueToSymTab(pSymNumber->szName, NumTmp)) {
  881. if (!FHandleOOM(hWndShell)) {
  882. return(fFalse);
  883. }
  884. }
  885. pSymNumber++;
  886. }
  887. }
  888. if (wModeSetup == wModeSetupNormal) {
  889. szInstallType = "NORMAL";
  890. }
  891. #if 0
  892. else if (wModeSetup == wModeSetupToShare) {
  893. szInstallType = "SETUPTOSHARE";
  894. }
  895. #endif
  896. else if (wModeSetup == wModeGuiInitialSetup) {
  897. szInstallType = "SETUPBOOTED";
  898. }
  899. else {
  900. AssertRet(fFalse, fFalse);
  901. }
  902. while (!FAddSymbolValueToSymTab("STF_INSTALL_TYPE", szInstallType)) {
  903. if (!FHandleOOM(hWndShell)) {
  904. return(fFalse);
  905. }
  906. }
  907. #if DBG
  908. fCheckInfValidity = fTrue;
  909. #endif /* DBG */
  910. while ((grc = GrcOpenInf(szInfSrcPath, pGlobalContext()->pInfTempInfo)) != grcOkay)
  911. if (EercErrorHandler(hWndShell, grc, fTrue, szInfSrcPath, 0, 0)
  912. != eercRetry)
  913. return(fFalse);
  914. while ((grc = GrcFillSrcDescrListFromInf()) != grcOkay)
  915. if (EercErrorHandler(hWndShell, grc, fTrue, szInfSrcPath, 0, 0)
  916. != eercRetry)
  917. return(fFalse);
  918. if ((Line = FindFirstLineFromInfSection(pLocalContext()->szShlScriptSection)) == -1)
  919. {
  920. LoadString(hInstance, IDS_ERROR, rgchBufTmpShort, cchpBufTmpShortMax);
  921. LoadString(hInstance, IDS_CANT_FIND_SHL_SECT, rgchBufTmpLong,
  922. cchpBufTmpLongMax);
  923. MessageBox(hWndShell, rgchBufTmpLong, rgchBufTmpShort,
  924. MB_OK | MB_ICONHAND);
  925. return(fFalse);
  926. }
  927. if ((psptShellScript = PsptInitParsingTable(rgscp)) == (PSPT)NULL ||
  928. !FInitFlowPspt())
  929. {
  930. Assert(fFalse);
  931. return(fFalse);
  932. }
  933. PostMessage(hWndShell, STF_SHL_INTERP, Line+1, 0L);
  934. return(fTrue);
  935. }
  936. /*
  937. * FMakeWindows -- create Windows used by Setup
  938. */
  939. BOOL
  940. FMakeWindows(
  941. IN HANDLE hInstance
  942. )
  943. {
  944. int xSize = GetSystemMetrics(SM_CXSCREEN),
  945. ySize = GetSystemMetrics(SM_CYSCREEN) ;
  946. DWORD dwStyle = WS_POPUP | WS_CLIPCHILDREN ;
  947. if ( ! fFullScreen )
  948. {
  949. xSize = 2 ;
  950. ySize = 2 ;
  951. dwStyle = WS_POPUP ;
  952. }
  953. if ( hwParam )
  954. {
  955. DWORD dwThreadId = GetCurrentThreadId() ;
  956. DWORD dwParentThreadId = GetWindowThreadProcessId( hwParam,
  957. NULL ) ;
  958. AttachThreadInput( dwThreadId,
  959. dwParentThreadId,
  960. TRUE ) ;
  961. }
  962. //
  963. // Create the main setup window
  964. //
  965. hWndShell = CreateWindowEx(
  966. fFullScreen ? 0 : WS_EX_TRANSPARENT,
  967. "Stuff-Shell",
  968. "Setup",
  969. dwStyle,
  970. 0,
  971. 0,
  972. xSize,
  973. ySize,
  974. hwParam,
  975. NULL,
  976. hInstance,
  977. NULL
  978. );
  979. //
  980. // return status of operation
  981. //
  982. if ( hWndShell == (HWND)NULL ) {
  983. return( fFalse );
  984. }
  985. return( fTrue );
  986. }
  987. BOOL
  988. FProcessForDriveType(
  989. SZ szDir,
  990. SZ szDriveType,
  991. SZ szCWD,
  992. SZ szProcessedDir
  993. )
  994. {
  995. ChkArg(szDir != (SZ)NULL, 1, fFalse);
  996. ChkArg(szDriveType != (SZ)NULL, 2, fFalse);
  997. ChkArg(szProcessedDir != (SZ)NULL, 3, fFalse);
  998. //
  999. // Only drive types are DOS and UNC.
  1000. //
  1001. if(ISUNC(szDir)) {
  1002. lstrcpy(szDriveType,szUncType);
  1003. lstrcpy(szProcessedDir,szDir);
  1004. } else {
  1005. lstrcpy(szDriveType,szDosType);
  1006. //
  1007. // Handle drive-relative paths.
  1008. //
  1009. if(*szDir == '\\') {
  1010. //
  1011. // root relative szDir, get current drive and slap it in
  1012. //
  1013. *szProcessedDir = (UCHAR)_getdrive() + (UCHAR)'A' - (UCHAR)1;
  1014. *(szProcessedDir + 1) = ':';
  1015. *(szProcessedDir + 2) = '\0';
  1016. } else {
  1017. if(*(szDir + 1) == ':') {
  1018. //
  1019. // Drive relative path (we don't need to do anything)
  1020. //
  1021. *szProcessedDir = '\0';
  1022. } else {
  1023. //
  1024. // No root specified, so we assume the directory is relative to
  1025. // szCWD
  1026. //
  1027. lstrcpy(szProcessedDir,szCWD);
  1028. }
  1029. }
  1030. lstrcat(szProcessedDir,szDir);
  1031. }
  1032. //
  1033. // The szProcessedDir should be terminated by a '\\'
  1034. //
  1035. if (*(szProcessedDir + lstrlen(szProcessedDir) - 1) != '\\') {
  1036. lstrcat(szProcessedDir,"\\");
  1037. }
  1038. return(fTrue);
  1039. }
  1040. BOOL
  1041. FProcessInfSrcPath(
  1042. SZ szInf,
  1043. SZ szCWD,
  1044. SZ szProcessedDir
  1045. )
  1046. {
  1047. #define INF_ABSOLUTE 0
  1048. #define INF_RELATIVE 1
  1049. INT PathType = INF_RELATIVE;
  1050. PFH pfh = (PFH)NULL;
  1051. //
  1052. // Check to see if the inf path specified is a relative path or
  1053. // an absolute path
  1054. //
  1055. if ( lstrlen( szInf ) >= 2 ) {
  1056. //
  1057. // See if the INF has a drive relative src path spec
  1058. //
  1059. if (ISUNC( szInf ) ) {
  1060. lstrcpy(szProcessedDir, szInf);
  1061. PathType = INF_ABSOLUTE;
  1062. }
  1063. else if (*szInf == '\\') {
  1064. //
  1065. // root relative szInf
  1066. //
  1067. *szProcessedDir = (UCHAR)_getdrive() + (UCHAR)'A' - (UCHAR)1;
  1068. *(szProcessedDir + 1) = ':';
  1069. *(szProcessedDir + 2) = '\0';
  1070. lstrcat(szProcessedDir, szInf);
  1071. PathType = INF_ABSOLUTE;
  1072. }
  1073. else if (*(szInf + 1) == ':') {
  1074. //
  1075. // drive relative path (we don't need to do anything)
  1076. //
  1077. lstrcpy(szProcessedDir, szInf);
  1078. PathType = INF_ABSOLUTE;
  1079. }
  1080. }
  1081. //
  1082. // If it is an absolute path try opening the INF as is
  1083. //
  1084. if ( PathType == INF_ABSOLUTE ) {
  1085. if (( pfh = PfhOpenFile(szProcessedDir, ofmRead)) != (PFH)NULL ) {
  1086. EvalAssert(FCloseFile(pfh));
  1087. return( TRUE );
  1088. }
  1089. else {
  1090. return( FALSE );
  1091. }
  1092. }
  1093. //
  1094. // Path is a relative path, try first combining the szCWD and the inf.
  1095. //
  1096. lstrcpy( szProcessedDir, szCWD );
  1097. lstrcat( szProcessedDir, szInf );
  1098. if (( pfh = PfhOpenFile(szProcessedDir, ofmRead)) != (PFH)NULL ) {
  1099. EvalAssert(FCloseFile(pfh));
  1100. return( TRUE );
  1101. }
  1102. //
  1103. // Then try combining the windows system directory and the INF
  1104. //
  1105. EvalAssert( GetSystemDirectory( szProcessedDir, MAX_PATH ) <= MAX_PATH );
  1106. lstrcat( szProcessedDir, "\\" );
  1107. lstrcat( szProcessedDir, szInf );
  1108. if (( pfh = PfhOpenFile(szProcessedDir, ofmRead)) != (PFH)NULL ) {
  1109. EvalAssert(FCloseFile(pfh));
  1110. return( TRUE );
  1111. }
  1112. //
  1113. // Inf not found
  1114. //
  1115. return( FALSE );
  1116. }
  1117. HWND FindProperParent ( void )
  1118. {
  1119. RECT rect ;
  1120. HWND hwMaster, hwParent ;
  1121. POINT ptMax ;
  1122. hwParent = hwMaster = GetDesktopWindow() ;
  1123. // If we have a main window that is not the blue screen,
  1124. // make sure that we have a valid parent that is visible.
  1125. if ( hwParam )
  1126. {
  1127. BOOL bOk = FALSE ;
  1128. ptMax.x = GetSystemMetrics( SM_CXFULLSCREEN ) ;
  1129. ptMax.y = GetSystemMetrics( SM_CYFULLSCREEN ) ;
  1130. hwMaster = hwParam ;
  1131. do
  1132. {
  1133. if ( IsWindow( hwMaster )
  1134. && GetWindowRect( hwMaster, & rect ) )
  1135. {
  1136. bOk = rect.left >= 0
  1137. && rect.left < ptMax.x
  1138. && rect.top >= 0
  1139. && rect.top < ptMax.y ;
  1140. }
  1141. if ( ! bOk )
  1142. {
  1143. hwMaster = GetParent( hwMaster ) ;
  1144. }
  1145. } while ( ! bOk && hwMaster != NULL ) ;
  1146. if ( bOk )
  1147. hwParent = hwMaster ;
  1148. }
  1149. return hwPseudoParent = hwParent ;
  1150. }