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.

973 lines
29 KiB

  1. /* cmdconf.c - handles pre-processing of config.sys\autoexec.bat
  2. *
  3. * Modification History:
  4. *
  5. * 21-Nov-1992 Jonle , Created
  6. */
  7. #include "cmd.h"
  8. #include <cmdsvc.h>
  9. #include <demexp.h>
  10. #include <softpc.h>
  11. #include <mvdm.h>
  12. #include <ctype.h>
  13. #include <oemuni.h>
  14. #if defined(NEC_98)
  15. // Global stuff
  16. UINT saveCP;
  17. UINT saveOutputCP;
  18. #endif // NEC_98
  19. //
  20. // local stuff
  21. //
  22. CHAR *pchTmpConfigFile;
  23. CHAR *pchTmpAutoexecFile;
  24. CHAR achSYSROOT[] = "%SystemRoot%";
  25. CHAR achCOMMAND[] = "\\System32\\command.com";
  26. CHAR achSHELL[] = "shell";
  27. CHAR achCOUNTRY[] = "country";
  28. CHAR achREM[] = "rem";
  29. CHAR achENV[] = "/e:";
  30. CHAR achEOL[] = "\r\n";
  31. CHAR achSET[] = "SET";
  32. CHAR achPROMPT[] = "PROMPT";
  33. CHAR achPATH[] = "PATH";
  34. #ifdef JAPAN
  35. // device=...\$disp.sys /hs=%HardwareScroll%
  36. CHAR achHARDWARESCROLL[] = "%HardwareScroll%";
  37. DWORD dwLenHardwareScroll;
  38. CHAR achHardwareScroll[64];
  39. #endif // JAPAN
  40. #if defined(KOREA)
  41. // device=...\hbios.sys /k:#
  42. CHAR achHBIOS[] = "hbios.sys";
  43. CHAR achFontSys[] = "font_win.sys";
  44. CHAR achDispSys[] = "disp_win.sys";
  45. DWORD dwLenHotkeyOption;
  46. CHAR achHotkeyOption[80];
  47. BOOLEAN fKoreanCP;
  48. #define KOREAN_WANSUNG_CP 949
  49. #endif // KOREA
  50. DWORD dwLenSysRoot;
  51. CHAR achSysRoot[64];
  52. void ExpandConfigFiles(BOOLEAN bConfig);
  53. DWORD WriteExpanded(HANDLE hFile, CHAR *pch, DWORD dwBytes);
  54. void WriteFileAssert(HANDLE hFile, CHAR *pBuff, DWORD dwBytes);
  55. #define ISEOL(ch) ( !(ch) || ((ch) == '\n') || ((ch) == '\r'))
  56. #ifdef JAPAN
  57. DWORD GetHardwareScroll( PCHAR achHardwareScroll, int size );
  58. #endif // JAPAN
  59. #if defined(KOREA)
  60. DWORD GetHotkeyOption( PCHAR achHotkeyOption, UINT size );
  61. #endif // KOREA
  62. /** There are still many items we don't supprot for long path name
  63. (1). device, install in config.sys
  64. (2). Third-party shell
  65. (3). lh, loadhigh and any other commands in autoexec.bat
  66. **/
  67. /* cmdGetConfigSys - Creates a temp file to replace c:\config.sys
  68. *
  69. * Entry - Client (DS:DX) pointer to receive file name
  70. *
  71. * EXIT - This routine will Terminate the vdm if it fails
  72. * And will not return
  73. *
  74. * The buffer to receive the file name must be at least 64 bytes
  75. */
  76. VOID cmdGetConfigSys (VOID)
  77. {
  78. UNICODE_STRING Unicode;
  79. OEM_STRING OemString;
  80. ANSI_STRING AnsiString;
  81. ExpandConfigFiles(TRUE);
  82. RtlInitAnsiString(&AnsiString, pchTmpConfigFile);
  83. if (!NT_SUCCESS(RtlAnsiStringToUnicodeString(&Unicode, &AnsiString, TRUE)) )
  84. goto ErrExit;
  85. OemString.Buffer = (char *)GetVDMAddr(getDS(),getDX());
  86. OemString.MaximumLength = 64;
  87. if ( !NT_SUCCESS(RtlUnicodeStringToOemString(&OemString,&Unicode,FALSE)) )
  88. goto ErrExit;
  89. RtlFreeUnicodeString(&Unicode);
  90. return;
  91. ErrExit:
  92. RcErrorDialogBox(ED_INITMEMERR, pchTmpConfigFile, NULL);
  93. TerminateVDM();
  94. }
  95. /* cmdGetAutoexecBat - Creates a temp file to replace c:\autoexec.bat
  96. *
  97. * Entry - Client (DS:DX) pointer to receive file name
  98. *
  99. * EXIT - This routine will Terminate the vdm if it fails
  100. * And will not return
  101. *
  102. *
  103. * The buffer to receive the file name must be at least 64 bytes
  104. */
  105. VOID cmdGetAutoexecBat (VOID)
  106. {
  107. UNICODE_STRING Unicode;
  108. OEM_STRING OemString;
  109. ANSI_STRING AnsiString;
  110. ExpandConfigFiles(FALSE);
  111. #if defined(JAPAN) || defined(KOREA)
  112. // fixed: change code page problem
  113. #if defined(NEC_98)
  114. {
  115. if (!VDMForWOW) { // BugFix: Change IME status by Screen Saver of 16bit
  116. saveCP = GetConsoleCP();
  117. saveOutputCP = GetConsoleOutputCP();
  118. SetConsoleCP( 932 );
  119. SetConsoleOutputCP( 932 );
  120. }
  121. }
  122. #else // !NEC_98
  123. {
  124. extern int BOPFromDispFlag;
  125. if ( !VDMForWOW && !BOPFromDispFlag ) { // mskkbug#2756 10/15/93 yasuho
  126. SetConsoleCP( 437 );
  127. SetConsoleOutputCP( 437 );
  128. }
  129. }
  130. #endif // !NEC_98
  131. #endif // JAPAN || KOREA
  132. RtlInitAnsiString(&AnsiString, pchTmpAutoexecFile);
  133. if (!NT_SUCCESS(RtlAnsiStringToUnicodeString(&Unicode,&AnsiString,TRUE)) )
  134. goto ErrExit;
  135. OemString.Buffer = (char *)GetVDMAddr(getDS(),getDX());
  136. OemString.MaximumLength = 64;
  137. if (!NT_SUCCESS(RtlUnicodeStringToOemString(&OemString,&Unicode,FALSE)) )
  138. goto ErrExit;
  139. RtlFreeUnicodeString(&Unicode);
  140. return;
  141. ErrExit:
  142. RcErrorDialogBox(ED_INITMEMERR, pchTmpConfigFile, NULL);
  143. TerminateVDM(); // skip cleanup since I insist that we exit!
  144. }
  145. /*
  146. * DeleteConfigFiles - Deletes the temporray config files created
  147. * by cmdGetAutoexecBat and cmdGetConfigSys
  148. */
  149. VOID DeleteConfigFiles(VOID)
  150. {
  151. if (pchTmpConfigFile) {
  152. #if DBG
  153. if (!(fShowSVCMsg & KEEPBOOTFILES))
  154. #endif
  155. DeleteFile(pchTmpConfigFile);
  156. free(pchTmpConfigFile);
  157. pchTmpConfigFile = NULL;
  158. }
  159. if (pchTmpAutoexecFile) {
  160. #if DBG
  161. if (!(fShowSVCMsg & KEEPBOOTFILES))
  162. #endif
  163. DeleteFile(pchTmpAutoexecFile);
  164. free(pchTmpAutoexecFile);
  165. pchTmpAutoexecFile = NULL;
  166. }
  167. return;
  168. }
  169. // if it is a config command
  170. // returns pointer to character immediatly following the equal sign
  171. // else
  172. // returns NULL
  173. PCHAR IsConfigCommand(PCHAR pConfigCommand, int CmdLen, PCHAR pLine)
  174. {
  175. PCHAR pch;
  176. if (!_strnicmp(pLine, pConfigCommand, CmdLen)) {
  177. pch = pLine + CmdLen;
  178. while (!isgraph(*pch) && !ISEOL(*pch)) // skip to "="
  179. pch++;
  180. if (*pch++ == '=') {
  181. return pch;
  182. }
  183. }
  184. return NULL;
  185. }
  186. #if defined(KOREA)
  187. // if it is a HBIOS related config command
  188. // returns TRUE
  189. // else
  190. // returns FALSE
  191. BOOLEAN IsHBIOSConfig(PCHAR pCommand, int CmdLen, PCHAR pLine)
  192. {
  193. CHAR *pch = pLine;
  194. CHAR achDevice[] = "Device";
  195. CHAR achRem[] = "REM";
  196. while (*pch && !ISEOL(*pch)) {
  197. if (!_strnicmp(pch, achRem, sizeof(achRem)-sizeof(CHAR)))
  198. return (FALSE);
  199. if (!_strnicmp(pch, achDevice, sizeof(achDevice)-sizeof(CHAR))) {
  200. while (*pch && !ISEOL(*pch)) {
  201. if (!_strnicmp(pch, pCommand, CmdLen))
  202. return (TRUE);
  203. pch++;
  204. }
  205. }
  206. pch++;
  207. }
  208. return (FALSE);
  209. }
  210. #endif
  211. /*
  212. * Preprocesses the specfied config file (config.sys\autoexec.bat)
  213. * into a temporary file.
  214. *
  215. * - expands %SystemRoot%
  216. #ifdef JAPAN
  217. * - expands %HardwareScroll%
  218. #endif // JAPAN
  219. #if defined(KOREA)
  220. * - expands HotkeyOption
  221. #endif // KOREA
  222. * - adds SHELL line for config.sys
  223. *
  224. * entry: BOOLEAN bConfig : TRUE - config.sys
  225. * FALSE - autoexec.bat
  226. */
  227. void ExpandConfigFiles(BOOLEAN bConfig)
  228. {
  229. DWORD dw, dwRawFileSize;
  230. HANDLE hRawFile;
  231. HANDLE hTmpFile;
  232. CHAR **ppTmpFile;
  233. CHAR *pRawBuffer;
  234. CHAR *pLine;
  235. CHAR *pTmp;
  236. CHAR *pEnvParam= NULL;
  237. CHAR *pPartyShell=NULL;
  238. CHAR achRawFile[MAX_PATH+12];
  239. CHAR *lpszzEnv, *lpszName;
  240. int cchEnv;
  241. #ifdef JAPAN
  242. dwLenHardwareScroll = GetHardwareScroll( achHardwareScroll, sizeof(achHardwareScroll) );
  243. #endif // JAPAN
  244. #if defined(KOREA)
  245. // HBIOS.SYS is only support WanSung Codepage.
  246. fKoreanCP = (GetConsoleCP() == KOREAN_WANSUNG_CP) ? TRUE : FALSE;
  247. dwLenHotkeyOption = GetHotkeyOption( achHotkeyOption, sizeof(achHotkeyOption) );
  248. #endif // KOREA
  249. dw = GetSystemWindowsDirectory(achRawFile, sizeof(achRawFile));
  250. dwLenSysRoot = GetShortPathNameA(achRawFile, achSysRoot, sizeof(achSysRoot));
  251. if (dwLenSysRoot >= sizeof(achSysRoot)) {
  252. dwLenSysRoot = 0;
  253. achSysRoot[0] = '\0';
  254. }
  255. #ifdef DBCS
  256. GetPIFConfigFiles(bConfig, achRawFile, FALSE);
  257. #else // !DBCS
  258. GetPIFConfigFiles(bConfig, achRawFile);
  259. #endif // !DBCS
  260. ppTmpFile = bConfig ? &pchTmpConfigFile : &pchTmpAutoexecFile;
  261. hRawFile = CreateFile(achRawFile,
  262. GENERIC_READ,
  263. FILE_SHARE_READ,
  264. NULL,
  265. OPEN_EXISTING,
  266. FILE_ATTRIBUTE_NORMAL,
  267. NULL );
  268. if (hRawFile == (HANDLE)0xFFFFFFFF
  269. || !dwLenSysRoot
  270. || dwLenSysRoot >= sizeof(achSysRoot)
  271. || !(dwRawFileSize = GetFileSize(hRawFile, NULL))
  272. || dwRawFileSize == 0xFFFFFFFF )
  273. {
  274. RcErrorDialogBox(ED_BADSYSFILE, achRawFile, NULL);
  275. TerminateVDM(); // skip cleanup since I insist that we exit!
  276. }
  277. pRawBuffer = malloc(dwRawFileSize+1);
  278. // allocate buffer to save environment settings in autoexec.nt
  279. // I know this is bad to allocate this amount of memory at this
  280. // moment as we dont know if there are anything we want to keep
  281. // at all. This allocation simply provides the following error
  282. // handling easily.
  283. if(!bConfig) {
  284. lpszzEnv = lpszzcmdEnv16 = (PCHAR)malloc(dwRawFileSize);
  285. cchEnv = 0;
  286. }
  287. if (!pRawBuffer || (!bConfig && lpszzcmdEnv16 == NULL)) {
  288. RcErrorDialogBox(ED_INITMEMERR, achRawFile, NULL);
  289. TerminateVDM(); // skip cleanup since I insist that we exit!
  290. }
  291. if (!cmdCreateTempFile(&hTmpFile,ppTmpFile)
  292. || !ReadFile(hRawFile, pRawBuffer, dwRawFileSize, &dw, NULL)
  293. || dw != dwRawFileSize )
  294. {
  295. GetTempPath(MAX_PATH, achRawFile);
  296. achRawFile[63] = '\0';
  297. RcErrorDialogBox(ED_INITTMPFILE, achRawFile, NULL);
  298. TerminateVDM(); // skip cleanup since I insist that we exit!
  299. }
  300. // CHANGE HERE WHEN YOU CHANGE cmdCreateTempFile !!!!!!!!!!
  301. // we depend on the buffer size allocated for the file name
  302. dw = GetShortPathNameA(*ppTmpFile, *ppTmpFile, MAX_PATH +13);
  303. if (dw == 0 || dw > 63)
  304. {
  305. GetTempPath(MAX_PATH, achRawFile);
  306. achRawFile[63] = '\0';
  307. RcErrorDialogBox(ED_INITTMPFILE, achRawFile, NULL);
  308. TerminateVDM(); // skip cleanup since I insist that we exit!
  309. }
  310. // null terminate the buffer so we can use CRT string functions
  311. *(pRawBuffer+dwRawFileSize) = '\0';
  312. // ensure no trailing backslash in System Directory
  313. if (*(achSysRoot+dwLenSysRoot-1) == '\\') {
  314. *(achSysRoot + --dwLenSysRoot) = '\0';
  315. }
  316. pLine = pRawBuffer;
  317. while (dwRawFileSize) {
  318. // skip leading white space
  319. while (dwRawFileSize && !isgraph(*pLine)) {
  320. pLine++;
  321. dwRawFileSize -= sizeof(CHAR);
  322. }
  323. if (!dwRawFileSize) // anything left to do ?
  324. break;
  325. if (bConfig) {
  326. //
  327. // filter out country= setting we will create our own based
  328. // on current country ID and codepage.
  329. //
  330. pTmp = IsConfigCommand(achCOUNTRY, sizeof(achCOUNTRY) - sizeof(CHAR), pLine);
  331. if (pTmp) {
  332. while (dwRawFileSize && !ISEOL(*pLine)) {
  333. pLine++;
  334. dwRawFileSize -= sizeof(CHAR);
  335. }
  336. continue;
  337. }
  338. // filter out shell= command, saving /E:nn parameter
  339. pTmp = IsConfigCommand(achSHELL, sizeof(achSHELL) - sizeof(CHAR),pLine);
  340. if (pTmp) {
  341. // skip leading white space
  342. while (!isgraph(*pTmp) && !ISEOL(*pTmp)) {
  343. dwRawFileSize -= sizeof(CHAR);
  344. pTmp++;
  345. }
  346. /* if for a third party shell (not SCS command.com)
  347. * append the whole thing thru /c parameter
  348. * else
  349. * append user specifed /e: parameter
  350. */
  351. if (!_strnicmp(achSYSROOT,pTmp,sizeof(achSYSROOT)-sizeof(CHAR)))
  352. {
  353. dw = sizeof(achSYSROOT) - sizeof(CHAR);
  354. }
  355. else if (!_strnicmp(achSysRoot,pTmp, strlen(achSysRoot)))
  356. {
  357. dw = strlen(achSysRoot);
  358. }
  359. else {
  360. dw = 0;
  361. }
  362. if (!dw ||
  363. _strnicmp(achCOMMAND,pTmp+dw,sizeof(achCOMMAND)-sizeof(CHAR)) )
  364. {
  365. pPartyShell = pTmp;
  366. }
  367. else {
  368. do {
  369. while (*pTmp != '/' && !ISEOL(*pTmp)) // save "/e:"
  370. pTmp++;
  371. if(ISEOL(*pTmp))
  372. break;
  373. if (!_strnicmp(pTmp,achENV,sizeof(achENV)-sizeof(CHAR)))
  374. pEnvParam = pTmp;
  375. pTmp++;
  376. } while(1); // was: while (!ISEOL(*pTmp));
  377. // we have break form this loop now,
  378. // and don't need in additional macro..
  379. }
  380. // skip the "shell=" line
  381. while (dwRawFileSize && !ISEOL(*pLine)) {
  382. pLine++;
  383. dwRawFileSize -= sizeof(CHAR);
  384. }
  385. continue;
  386. } // END, really is "shell=" line!
  387. }
  388. #if defined(KOREA)
  389. // If current Code page is 437(US), system won't load HBIOS related modules.
  390. if (!fKoreanCP) {
  391. if (IsHBIOSConfig(achFontSys, sizeof(achFontSys)-sizeof(CHAR), pLine)) {
  392. while (dwRawFileSize && !ISEOL(*pLine)) {
  393. pLine++;
  394. dwRawFileSize -= sizeof(CHAR);
  395. }
  396. continue;
  397. }
  398. if (IsHBIOSConfig(achHBIOS, sizeof(achHBIOS)-sizeof(CHAR), pLine)) {
  399. while (dwRawFileSize && !ISEOL(*pLine)) {
  400. pLine++;
  401. dwRawFileSize -= sizeof(CHAR);
  402. }
  403. continue;
  404. }
  405. if (IsHBIOSConfig(achDispSys, sizeof(achDispSys)-sizeof(CHAR), pLine)) {
  406. while (dwRawFileSize && !ISEOL(*pLine)) {
  407. pLine++;
  408. dwRawFileSize -= sizeof(CHAR);
  409. }
  410. continue;
  411. }
  412. }
  413. #endif // KOREA
  414. /** Filter out PROMPT, SET and PATH from autoexec.nt
  415. for environment merging. The output we prepare here is
  416. a multiple strings buffer which has the format as :
  417. "EnvName_1 NULL EnvValue_1 NULL[EnvName_n NULL EnvValue_n NULL] NULL
  418. We don't take them out from the file because command.com needs
  419. them.
  420. **/
  421. if (!bConfig)
  422. if (!_strnicmp(pLine, achPROMPT, sizeof(achPROMPT) - 1)){
  423. // prompt command found.
  424. // the syntax of prompt can be eithe
  425. // prompt xxyyzz or
  426. // prompt=xxyyzz
  427. //
  428. strcpy(lpszzEnv, achPROMPT); // get the name
  429. lpszzEnv += sizeof(achPROMPT);
  430. cchEnv += sizeof(achPROMPT);
  431. pTmp = pLine + sizeof(achPROMPT) - 1;
  432. // skip possible white chars
  433. while (!isgraph(*pTmp) && !ISEOL(*pTmp))
  434. pTmp++;
  435. if (*pTmp == '=') {
  436. pTmp++;
  437. while(!isgraph(*pTmp) && !ISEOL(*pTmp))
  438. pTmp++;
  439. }
  440. while(!ISEOL(*pTmp)){
  441. *lpszzEnv++ = *pTmp++;
  442. cchEnv++;
  443. }
  444. // null terminate this
  445. // it may be "prompt NULL NULL" for delete
  446. // or "prompt NULL something NULL"
  447. *lpszzEnv++ = '\0';
  448. cchEnv++;
  449. }
  450. else if (!_strnicmp(pLine, achPATH, sizeof(achPATH) - 1)) {
  451. // PATH was found, it has the same syntax as
  452. // PROMPT
  453. strcpy(lpszzEnv, achPATH);
  454. lpszzEnv += sizeof(achPATH);
  455. cchEnv += sizeof(achPATH);
  456. pTmp = pLine + sizeof(achPATH) - 1;
  457. while (!isgraph(*pTmp) && !ISEOL(*pTmp))
  458. pTmp++;
  459. if (*pTmp == '=') {
  460. pTmp++;
  461. while(!isgraph(*pTmp) && !ISEOL(*pTmp))
  462. pTmp++;
  463. }
  464. while(!ISEOL(*pTmp)) {
  465. *lpszzEnv++ = *pTmp++;
  466. cchEnv++;
  467. }
  468. *lpszzEnv++ = '\0';
  469. cchEnv++;
  470. }
  471. else if(!_strnicmp(pLine, achSET, sizeof(achSET) -1 )) {
  472. // SET was found, first search for name
  473. pTmp = pLine + sizeof(achSET) - 1;
  474. while(!isgraph(*pTmp) && !ISEOL(*pTmp))
  475. *pTmp ++;
  476. // get the name
  477. lpszName = pTmp;
  478. // looking for the '='
  479. // note that the name can have white characters
  480. while (!ISEOL(*lpszName) && *lpszName != '=')
  481. lpszName++;
  482. if (!ISEOL(*lpszName)) {
  483. // copy the name
  484. while (pTmp < lpszName) {
  485. *lpszzEnv++ = *pTmp++;
  486. cchEnv++;
  487. }
  488. *lpszzEnv++ = '\0';
  489. cchEnv++;
  490. // discard the '='
  491. pTmp++;
  492. // grab the value(may be nothing
  493. while (!ISEOL(*pTmp)) {
  494. *lpszzEnv++ = *pTmp++;
  495. cchEnv++;
  496. }
  497. *lpszzEnv++ = '\0';
  498. cchEnv++;
  499. }
  500. }
  501. dw = WriteExpanded(hTmpFile, pLine, dwRawFileSize);
  502. pLine += dw;
  503. dwRawFileSize -=dw;
  504. WriteFileAssert(hTmpFile,achEOL,sizeof(achEOL) - sizeof(CHAR));
  505. } // END, while (dwRawFileSize)
  506. if (bConfig) {
  507. UINT OemCP;
  508. #if defined(JAPAN) || defined(KOREA)
  509. UINT ConsoleCP;
  510. #endif // JAPAN || KOREA
  511. UINT CtryId;
  512. CHAR szCtryId[64]; // expect "nnn" only
  513. /* Ensure that the country settings are in sync with NT This is
  514. * especially important for DosKrnl file UPCASE tables. The
  515. * doskrnl default is "CTRY_UNITED_STATES, 437". But we add the
  516. * country= line to config.sys, even if is US,437, so that the DOS
  517. * will know where the default country.sys is.
  518. */
  519. if (GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IDEFAULTCOUNTRY,
  520. szCtryId, sizeof(szCtryId) - 1) )
  521. {
  522. CtryId = strtoul(szCtryId,NULL,10);
  523. }
  524. else {
  525. CtryId = CTRY_UNITED_STATES;
  526. }
  527. OemCP = GetOEMCP();
  528. #if defined(JAPAN) || defined(KOREA)
  529. ConsoleCP = GetConsoleOutputCP();
  530. if (OemCP != ConsoleCP)
  531. OemCP = ConsoleCP;
  532. #endif // JAPAN || KOREA
  533. sprintf(achRawFile,
  534. "%s=%3.3u,%3.3u,%s\\system32\\%s.sys%s",
  535. achCOUNTRY, CtryId, OemCP, achSysRoot, achCOUNTRY, achEOL);
  536. WriteFileAssert(hTmpFile,achRawFile,strlen(achRawFile));
  537. /* We cannot allow the user to set an incorrect shell= command
  538. * so we will contruct the correct shell= command appending
  539. * either (in order of precedence):
  540. * 1. /c ThirdPartyShell
  541. * 2. /e:NNNN
  542. * 3. nothing
  543. *
  544. * If there is a third party shell then we must turn the console
  545. * on now since we no longer have control once system32\command.com
  546. * spawns the third party shell.
  547. */
  548. // write shell=....
  549. sprintf(achRawFile,
  550. "%s=%s%s /p %s\\system32",
  551. achSHELL,achSysRoot, achCOMMAND, achSysRoot);
  552. WriteFileAssert(hTmpFile,achRawFile,strlen(achRawFile));
  553. // write extra string (/c ... or /e:nnn)
  554. if (pPartyShell && isgraph(*pPartyShell)) {
  555. pTmp = pPartyShell;
  556. while (!ISEOL(*pTmp))
  557. pTmp++;
  558. }
  559. else if (pEnvParam && isgraph(*pEnvParam)) {
  560. pTmp = pEnvParam;
  561. while (isgraph(*pTmp))
  562. pTmp++;
  563. }
  564. else {
  565. pTmp = NULL;
  566. }
  567. if (pTmp) {
  568. *pTmp = '\0';
  569. if (pPartyShell) {
  570. cmdInitConsole();
  571. strcpy(achRawFile, " /c ");
  572. strcat(achRawFile, pPartyShell);
  573. }
  574. else if (pEnvParam) {
  575. strcpy(achRawFile, " ");
  576. strcat(achRawFile, pEnvParam);
  577. }
  578. WriteExpanded(hTmpFile, achRawFile, strlen(achRawFile));
  579. }
  580. WriteFileAssert(hTmpFile,achEOL,sizeof(achEOL) - sizeof(CHAR));
  581. }
  582. SetEndOfFile(hTmpFile);
  583. CloseHandle(hTmpFile);
  584. CloseHandle(hRawFile);
  585. free(pRawBuffer);
  586. if (!bConfig) {
  587. // shrink(or free) the memory
  588. if (cchEnv && lpszzcmdEnv16) {
  589. // doubld null terminate it
  590. lpszzcmdEnv16[cchEnv++] = '\0';
  591. // shrink the memory. If it fails, simple keep
  592. // it as is
  593. lpszzEnv = realloc(lpszzcmdEnv16, cchEnv);
  594. if (lpszzEnv != NULL)
  595. lpszzcmdEnv16 = lpszzEnv;
  596. }
  597. else {
  598. free(lpszzcmdEnv16);
  599. lpszzcmdEnv16 = NULL;
  600. }
  601. }
  602. }
  603. /*
  604. * WriteExpanded - writes up to dwChars or EOL, expanding %SystemRoot%
  605. * returns number of CHARs processed in buffer
  606. * (not number of bytes actually written)
  607. */
  608. DWORD WriteExpanded(HANDLE hFile, CHAR *pch, DWORD dwChars)
  609. {
  610. DWORD dw;
  611. DWORD dwSave = dwChars;
  612. CHAR *pSave = pch;
  613. while (dwChars && !ISEOL(*pch)) {
  614. if (*pch == '%' &&
  615. !_strnicmp(pch, achSYSROOT, sizeof(achSYSROOT)-sizeof(CHAR)) )
  616. {
  617. dw = pch - pSave;
  618. if (dw) {
  619. WriteFileAssert(hFile, pSave, dw);
  620. }
  621. WriteFileAssert(hFile, achSysRoot, dwLenSysRoot);
  622. pch += sizeof(achSYSROOT)-sizeof(CHAR);
  623. pSave = pch;
  624. dwChars -= sizeof(achSYSROOT)-sizeof(CHAR);
  625. }
  626. #ifdef JAPAN
  627. // device=...\$disp.sys /hs=%HardwareScroll%
  628. else if (*pch == '%' &&
  629. !_strnicmp(pch, achHARDWARESCROLL, sizeof(achHARDWARESCROLL)-sizeof(CHAR)) )
  630. {
  631. dw = pch - pSave;
  632. if (dw) {
  633. WriteFileAssert(hFile, pSave, dw);
  634. }
  635. WriteFileAssert(hFile, achHardwareScroll, dwLenHardwareScroll);
  636. pch += sizeof(achHARDWARESCROLL)-sizeof(CHAR);
  637. pSave = pch;
  638. dwChars -= sizeof(achHARDWARESCROLL)-sizeof(CHAR);
  639. }
  640. #endif // JAPAN
  641. #if defined(KOREA) // looking for hbios.sys
  642. else if (fKoreanCP && *pch == 'h' &&
  643. !_strnicmp(pch, achHBIOS, sizeof(achHBIOS)-sizeof(CHAR)) )
  644. {
  645. dw = pch - pSave;
  646. if (dw) {
  647. WriteFileAssert(hFile, pSave, dw);
  648. }
  649. WriteFileAssert(hFile, achHotkeyOption, dwLenHotkeyOption);
  650. pch += sizeof(achHBIOS)-sizeof(CHAR);
  651. pSave = pch;
  652. dwChars -= sizeof(achHBIOS)-sizeof(CHAR);
  653. }
  654. #endif // KOREA
  655. else {
  656. pch++;
  657. dwChars -= sizeof(CHAR);
  658. }
  659. }
  660. dw = pch - pSave;
  661. if (dw) {
  662. WriteFileAssert(hFile, pSave, dw);
  663. }
  664. return (dwSave - dwChars);
  665. }
  666. /*
  667. * WriteFileAssert
  668. *
  669. * Cecks for error in wrtiting the temp boot file,
  670. * If one occurs displays warning popup and terminates the vdm.
  671. *
  672. */
  673. void WriteFileAssert(HANDLE hFile, CHAR *pBuff, DWORD dwBytes)
  674. {
  675. DWORD dw;
  676. CHAR ach[MAX_PATH];
  677. if (!WriteFile(hFile, pBuff, dwBytes, &dw, NULL) ||
  678. dw != dwBytes)
  679. {
  680. GetTempPath(MAX_PATH, ach);
  681. ach[63] = '\0';
  682. RcErrorDialogBox(ED_INITTMPFILE, ach, NULL);
  683. TerminateVDM(); // skip cleanup since I insist that we exit!
  684. }
  685. }
  686. #ifdef JAPAN
  687. //
  688. // MSKK 8/26/1993 V-KazuyS
  689. // Get HardwareScroll type from registry
  690. // this parameter also use console.
  691. //
  692. DWORD GetHardwareScroll( PCHAR achHardwareScroll, int size )
  693. {
  694. HKEY hKey;
  695. DWORD dwType;
  696. DWORD retCode;
  697. CHAR szBuf[256];
  698. DWORD cbData=256L;
  699. DWORD num;
  700. PCHAR psz;
  701. // Get HardwareScroll type ( ON, LC or OFF ) from REGISTRY file.
  702. // OPEN THE KEY.
  703. retCode = RegOpenKeyEx (
  704. HKEY_LOCAL_MACHINE, // Key handle at root level.
  705. "HARDWARE\\DEVICEMAP\\VIDEO", // Path name of child key.
  706. 0, // Reserved.
  707. KEY_EXECUTE, // Requesting read access.
  708. &hKey ); // Address of key to be returned.
  709. // If retCode != 0 then we cannot find section in Register file
  710. if ( retCode ) {
  711. #ifdef JAPAN_DBG
  712. DbgPrint( "NTVDM: RegOpenKeyEx failed %xh\n", retCode );
  713. #endif
  714. strcpy( achHardwareScroll, "off" );
  715. return ( strlen("off") );
  716. }
  717. dwType = REG_SZ;
  718. // Query for line from REGISTER file
  719. retCode = RegQueryValueEx( hKey,
  720. "\\Device\\Video0",
  721. NULL,
  722. &dwType,
  723. szBuf,
  724. &cbData);
  725. if ( retCode ) {
  726. #ifdef JAPAN_DBG
  727. DbgPrint( "NTVDM: RegQueryValueEx failed %xh\n", retCode );
  728. #endif
  729. strcpy( achHardwareScroll, "off" );
  730. return ( strlen("off") );
  731. }
  732. RegCloseKey(hKey);
  733. #ifdef JAPAN_DBG
  734. DbgPrint( "NTVDM: Get \\Device\\Video0=[%s]\n", szBuf );
  735. #endif
  736. psz = strchr( (szBuf+1), '\\' ); // skip \\REGISTRY\\ *
  737. #ifdef JAPAN_DBG
  738. DbgPrint( "NTVDM: skip \\registry\\ [%s]\n", psz );
  739. #endif
  740. if ( psz != NULL )
  741. psz = strchr( (psz+1), '\\' ); // skip Machine\\ *
  742. if ( psz == NULL ) {
  743. #ifdef JAPAN_DBG
  744. DbgPrint( "NTVDM: Illegal value[%s]h\n", szBuf );
  745. #endif
  746. strcpy( achHardwareScroll, "off" );
  747. return ( strlen("off") );
  748. }
  749. psz++;
  750. #ifdef JAPAN_DBG
  751. DbgPrint( "NTVDM: Open 2nd Key=[%s]\n", psz );
  752. #endif
  753. retCode = RegOpenKeyEx (
  754. HKEY_LOCAL_MACHINE, // Key handle at root level.
  755. psz, // Path name of child key.
  756. 0, // Reserved.
  757. KEY_EXECUTE, // Requesting read access.
  758. &hKey ); // Address of key to be returned.
  759. // If retCode != 0 then we cannot find section in Register file
  760. if ( retCode ) {
  761. #ifdef JAPAN_DBG
  762. DbgPrint( "NTVDM: RegOpenKeyEx failed %xh\n", retCode );
  763. #endif
  764. strcpy( achHardwareScroll, "off" );
  765. return ( strlen("off") );
  766. }
  767. dwType = REG_SZ;
  768. // Query for line from REGISTER file
  769. retCode = RegQueryValueEx( hKey,
  770. "ConsoleFullScreen.HardwareScroll",
  771. NULL,
  772. &dwType,
  773. szBuf,
  774. &cbData);
  775. if ( retCode ) {
  776. #ifdef JAPAN_DBG
  777. DbgPrint( "NTVDM: RegQueryValueEx failed %xh\n", retCode );
  778. #endif
  779. strcpy( achHardwareScroll, "off" );
  780. return ( strlen("off") );
  781. }
  782. RegCloseKey(hKey);
  783. #ifdef JAPAN_DBG
  784. DbgPrint( "NTVDM: Get FullScreenHardwareScroll=[%s]\n", szBuf );
  785. #endif
  786. num = ( lstrlen(szBuf)+1 > size ) ? size : lstrlen(szBuf)+1;
  787. RtlCopyMemory( achHardwareScroll, szBuf, num );
  788. achHardwareScroll[num] = '\0';
  789. #ifdef JAPAN_DBG
  790. DbgPrint( "NTVDM: Set %HardwareScroll%=[%s]\n", achHardwareScroll );
  791. #endif
  792. return num;
  793. }
  794. #endif // JAPAN
  795. #if defined(KOREA)
  796. /*
  797. * 8/05/1996 bklee
  798. * Get keyboard layout from system and set hotkey option for hbios.sys
  799. * Here are hotkey options for HBIOS.SYS.
  800. *
  801. * Keyboard Type Hangul Hanja
  802. * 1 101a r + alt r + ctrl : default
  803. * 2 101b r + ctrl r + alt
  804. * 3 103 Hangul Hanja
  805. * 4 84 alt + shift ctrl + shift
  806. * 5 86 Hangul Hanja
  807. * 6 101c l shift + space l ctrl + space
  808. * 7 64 : N/A. map to default
  809. */
  810. DWORD GetHotkeyOption( PCHAR achHotkeyOption, UINT size )
  811. {
  812. // GetKeyboardType(1) return 1 to 6 as sub-keyboard type.
  813. // No 7 sub-keyboard type will be returned.
  814. UINT HotkeyIndex[6] = { 4, 5, 1, 2, 6, 3 };
  815. UINT SubKeyType, HotkeyOption;
  816. if ( GetKeyboardType(0) == 8 ) { // KOREAN Keyboard layout
  817. SubKeyType = GetKeyboardType(1);
  818. if ( SubKeyType > 0 && SubKeyType < 7 )
  819. HotkeyOption = HotkeyIndex[SubKeyType - 1];
  820. else
  821. HotkeyOption = 1; // Set to default.
  822. wsprintf(achHotkeyOption, "hbios.sys /K:%d", HotkeyOption);
  823. }
  824. else
  825. strcpy(achHotkeyOption, "hbios.sys");
  826. return(strlen(achHotkeyOption));
  827. }
  828. #endif // KOREA