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.

289 lines
7.8 KiB

  1. /* cmdpif.c - PIF Handling Routines For SCS
  2. *
  3. *
  4. * Modification History:
  5. *
  6. * Sudeepb 19-Aug-1992 Created
  7. * williamh 10-Nov-1992 (1). get params from w386 extention if exist
  8. * (2). null terminate caption
  9. * williamh 27-May-1993 almost rewrote for better pif support
  10. */
  11. #include "cmd.h"
  12. #include <ctype.h>
  13. #include <pif.h>
  14. #include <cmdsvc.h>
  15. #include <softpc.h>
  16. #include <mvdm.h>
  17. #include <oemuni.h>
  18. #include "nt_pif.h"
  19. VOID cmdCheckForPIF (PVDMINFO pvi)
  20. {
  21. PCHAR pCmdLine = pvi->CmdLine;
  22. PCHAR pDot;
  23. ULONG size;
  24. UCHAR ch;
  25. DWORD dw;
  26. CHAR lpszEnvDir [] = "=?:";
  27. CHAR FullPathName[MAX_PATH + 1];
  28. CHAR * pFilePart;
  29. BOOL IsPIFFile, IsFromForceDos;
  30. CHAR AppFullPathName[MAX_PATH + 1];
  31. //
  32. // Advance CmdLine pointer to beg of command tail
  33. //
  34. while (*pCmdLine && !isgraph(*pCmdLine)) { // skip to first nonwhite
  35. pCmdLine++;
  36. }
  37. pDot = strrchr(pvi->AppName, '.');
  38. if (pDot)
  39. IsPIFFile = pDot && !_strnicmp(pDot, ".pif", 4);
  40. else
  41. IsPIFFile = FALSE;
  42. // if the command is not a pif file and it is not
  43. // running on a new console
  44. if (!IsPIFFile && !DosSessionId)
  45. goto CleanUpAndReturn;
  46. if (IsPIFFile) {
  47. if (!IsFirstVDM) {
  48. //
  49. // Get the pif data. If no pif data, or not from forcedos
  50. // just return -- command.com will receive the pif file
  51. // name and fail.
  52. //
  53. pfdata.AppHasPIFFile =
  54. pfdata.IgnoreStartDirInPIF =
  55. pfdata.IgnoreTitleInPIF =
  56. pfdata.IgnoreCmdLineInPIF =
  57. pfdata.IgnoreConfigAutoexec = 1;
  58. if (!GetPIFData(&pfdata, pvi->AppName))
  59. goto CleanUpAndReturn;
  60. }
  61. // we only run a pif file on two occasions:
  62. // (1). it is from a new console
  63. // (2). it is from forcedos.
  64. if (!DosSessionId && pfdata.SubSysId != SUBSYS_DOS)
  65. goto CleanUpAndReturn;
  66. }
  67. if (IsFirstVDM) {
  68. // if this is the first vdm, take cmdline, startupdir and title
  69. // if they are there
  70. if (pfdata.StartDir){
  71. dw = cmdExpandEnvironmentStrings(NULL,
  72. pfdata.StartDir,
  73. FullPathName,
  74. MAX_PATH + 1
  75. );
  76. if (dw != 0 && dw <= MAX_PATH) {
  77. dw = GetFullPathNameOem(FullPathName,
  78. MAX_PATH + 1,
  79. pfdata.StartDir,
  80. &pFilePart
  81. );
  82. }
  83. if (dw != 0 && dw <= MAX_PATH)
  84. dw = GetFileAttributesOem(pfdata.StartDir);
  85. else
  86. dw = 0;
  87. if (dw == 0 || dw == 0xFFFFFFFF || !(dw & FILE_ATTRIBUTE_DIRECTORY))
  88. {
  89. RcMessageBox(EG_PIF_STARTDIR_ERR,
  90. NULL,
  91. NULL,
  92. RMB_ICON_BANG | RMB_ABORT);
  93. goto CleanUpAndReturn;
  94. }
  95. dw = GetShortPathNameOem(pfdata.StartDir,
  96. pfdata.StartDir,
  97. MAX_PATH + 1
  98. );
  99. if (dw == 0 || dw > MAX_PATH || dw > 64) {
  100. RcMessageBox(EG_PIF_STARTDIR_ERR,
  101. NULL,
  102. NULL,
  103. RMB_ICON_BANG | RMB_ABORT);
  104. goto CleanUpAndReturn;
  105. }
  106. lpszEnvDir[1] = pfdata.StartDir[0];
  107. SetEnvironmentVariableOem(lpszEnvDir, pfdata.StartDir);
  108. SetCurrentDirectoryOem(pfdata.StartDir);
  109. pvi->CurDrive = toupper(pfdata.StartDir[0]) - 'A';
  110. }
  111. if (pfdata.WinTitle) {
  112. strcpy(FullPathName, pfdata.WinTitle);
  113. dw = cmdExpandEnvironmentStrings(NULL,
  114. FullPathName,
  115. pfdata.WinTitle,
  116. MAX_PATH + 1
  117. );
  118. pfdata.WinTitle[MAX_PATH] = '\0';
  119. }
  120. if (!*pCmdLine && pfdata.CmdLine) {
  121. // if the optinal parameter is '?'
  122. // prompt the user
  123. pDot = pfdata.CmdLine;
  124. while (*pDot && *pDot <= ' ')
  125. pDot++;
  126. if (*pDot == '?') {
  127. pfdata.CmdLine[0] = '\0';
  128. RcMessageBox(EG_PIF_ASK_CMDLINE,
  129. NULL,
  130. pfdata.CmdLine,
  131. RMB_EDIT | RMB_ICON_INFO | (128 << 16)
  132. );
  133. }
  134. if (*pfdata.CmdLine) {
  135. strcpy(FullPathName, pfdata.CmdLine);
  136. dw = cmdExpandEnvironmentStrings(NULL,
  137. FullPathName,
  138. pfdata.CmdLine,
  139. MAX_PATH + 1
  140. );
  141. }
  142. }
  143. }
  144. if(IsPIFFile) {
  145. dw = cmdExpandEnvironmentStrings(NULL,
  146. pfdata.StartFile,
  147. FullPathName,
  148. MAX_PATH + 1
  149. );
  150. if (!dw || dw > MAX_PATH) {
  151. RcMessageBox(EG_PIF_STARTFILE_ERR,
  152. NULL, NULL, RMB_ICON_BANG | RMB_ABORT);
  153. goto CleanUpAndReturn;
  154. }
  155. // search from the current directory
  156. // note that the startup directory specified in
  157. // the pif file has been set as our current directory
  158. // when we got here
  159. dw = SearchPathOem(".",
  160. FullPathName,
  161. NULL,
  162. MAX_PATH + 1,
  163. AppFullPathName,
  164. &pFilePart
  165. );
  166. // if couldn't find the file from the current dir
  167. // ask win32api help
  168. if (dw == 0 || dw > MAX_PATH) {
  169. dw = SearchPathOem(NULL,
  170. FullPathName,
  171. NULL,
  172. MAX_PATH + 1,
  173. AppFullPathName,
  174. &pFilePart
  175. );
  176. }
  177. // couldn't find the file, give up
  178. if (dw == 0 || dw > MAX_PATH) {
  179. RcMessageBox(EG_PIF_STARTFILE_ERR,
  180. NULL, NULL, RMB_ICON_BANG | RMB_ABORT);
  181. goto CleanUpAndReturn;
  182. }
  183. dw = GetFileAttributesOem(AppFullPathName);
  184. if (dw == (DWORD)(-1) || (dw & FILE_ATTRIBUTE_DIRECTORY)) {
  185. RcMessageBox(EG_PIF_STARTFILE_ERR, NULL, NULL,
  186. RMB_ICON_BANG | RMB_ABORT
  187. );
  188. goto CleanUpAndReturn;
  189. }
  190. // convert to shortfilename
  191. dw = GetShortPathNameOem(AppFullPathName, pvi->AppName,
  192. MAX_PATH + 1);
  193. if (dw == 0 || dw > MAX_PATH) {
  194. RcMessageBox(EG_PIF_STARTFILE_ERR, NULL, NULL,
  195. RMB_ICON_BANG | RMB_ABORT
  196. );
  197. goto CleanUpAndReturn;
  198. }
  199. // update the application path name length(including the terminate NULL)
  200. pvi->AppLen = strlen(pvi->AppName) + 1;
  201. // pvi->AppName contains the application short name.
  202. // verify that it has the correct extension(.EXE, .COM or .BAT).
  203. pDot = (PCHAR)pvi->AppName + pvi->AppLen - 5;
  204. if (pvi->AppLen < 5 ||
  205. (_strnicmp(pDot, EXE_EXTENTION_STRING, EXTENTION_STRING_LEN) &&
  206. _strnicmp(pDot, COM_EXTENTION_STRING, EXTENTION_STRING_LEN) &&
  207. _strnicmp(pDot, BAT_EXTENTION_STRING, EXTENTION_STRING_LEN)))
  208. {
  209. RcMessageBox(EG_DOS_PROG_EXTENSION,AppFullPathName, NULL, RMB_ICON_BANG | RMB_ABORT);
  210. goto CleanUpAndReturn;
  211. }
  212. }
  213. //
  214. // Copy in pif command tail if original command tail is empty
  215. //
  216. if (!*pCmdLine && pfdata.CmdLine) {
  217. strcpy(FullPathName, pfdata.CmdLine);
  218. strcat(FullPathName, "\x0d\x0a");
  219. if (strlen(FullPathName) >= 128 - 13) {
  220. // too bad, the command line is too long
  221. RcMessageBox(EG_PIF_CMDLINE_ERR,NULL,NULL,RMB_ICON_BANG | RMB_ABORT);
  222. goto CleanUpAndReturn;
  223. }
  224. strcpy(pvi->CmdLine, FullPathName);
  225. pvi->CmdSize = strlen(FullPathName) + 1;
  226. }
  227. if (IsPIFFile)
  228. // we don't know the binary type at this point.
  229. *pIsDosBinary = 0;
  230. if (pfdata.WinTitle)
  231. SetConsoleTitle(pfdata.WinTitle);
  232. DontCheckDosBinaryType = (pfdata.SubSysId == SUBSYS_DOS);
  233. CleanUpAndReturn:
  234. if (pfdata.CmdLine) {
  235. free(pfdata.CmdLine);
  236. pfdata.CmdLine = NULL;
  237. }
  238. if (pfdata.StartDir) {
  239. free(pfdata.StartDir);
  240. pfdata.StartDir = NULL;
  241. }
  242. if (pfdata.StartFile) {
  243. free(pfdata.StartFile);
  244. pfdata.StartFile = NULL;
  245. }
  246. if (pfdata.WinTitle) {
  247. free(pfdata.WinTitle);
  248. pfdata.WinTitle = NULL;
  249. }
  250. return;
  251. }