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.

293 lines
8.4 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 = GetFullPathNameOemSys(FullPathName,
  78. MAX_PATH + 1,
  79. pfdata.StartDir,
  80. &pFilePart,
  81. TRUE
  82. );
  83. }
  84. if (dw != 0 && dw <= MAX_PATH)
  85. dw = GetFileAttributesOemSys(pfdata.StartDir, TRUE);
  86. else
  87. dw = 0;
  88. if (dw == 0 || dw == 0xFFFFFFFF || !(dw & FILE_ATTRIBUTE_DIRECTORY))
  89. {
  90. RcMessageBox(EG_PIF_STARTDIR_ERR,
  91. NULL,
  92. NULL,
  93. RMB_ICON_BANG | RMB_ABORT);
  94. goto CleanUpAndReturn;
  95. }
  96. dw = GetShortPathNameOem(pfdata.StartDir,
  97. pfdata.StartDir,
  98. MAX_PATH + 1
  99. );
  100. if (dw == 0 || dw > MAX_PATH || dw > 64) {
  101. RcMessageBox(EG_PIF_STARTDIR_ERR,
  102. NULL,
  103. NULL,
  104. RMB_ICON_BANG | RMB_ABORT);
  105. goto CleanUpAndReturn;
  106. }
  107. lpszEnvDir[1] = pfdata.StartDir[0];
  108. SetEnvironmentVariableOem(lpszEnvDir, pfdata.StartDir);
  109. SetCurrentDirectoryOem(pfdata.StartDir);
  110. pvi->CurDrive = toupper(pfdata.StartDir[0]) - 'A';
  111. }
  112. if (pfdata.WinTitle) {
  113. strncpy(FullPathName, pfdata.WinTitle,sizeof(FullPathName));
  114. FullPathName[sizeof(FullPathName)-1] = '\0';
  115. dw = cmdExpandEnvironmentStrings(NULL,
  116. FullPathName,
  117. pfdata.WinTitle,
  118. MAX_PATH + 1
  119. );
  120. pfdata.WinTitle[MAX_PATH] = '\0';
  121. }
  122. if (!*pCmdLine && pfdata.CmdLine) {
  123. // if the optinal parameter is '?'
  124. // prompt the user
  125. pDot = pfdata.CmdLine;
  126. while (*pDot && *pDot <= ' ')
  127. pDot++;
  128. if (*pDot == '?') {
  129. pfdata.CmdLine[0] = '\0';
  130. RcMessageBox(EG_PIF_ASK_CMDLINE,
  131. NULL,
  132. pfdata.CmdLine,
  133. RMB_EDIT | RMB_ICON_INFO | (128 << 16)
  134. );
  135. }
  136. if (*pfdata.CmdLine) {
  137. strncpy(FullPathName, pfdata.CmdLine,sizeof(FullPathName));
  138. FullPathName[sizeof(FullPathName)-1] = '\0';
  139. dw = cmdExpandEnvironmentStrings(NULL,
  140. FullPathName,
  141. pfdata.CmdLine,
  142. MAX_PATH + 1
  143. );
  144. }
  145. }
  146. }
  147. if(IsPIFFile) {
  148. dw = cmdExpandEnvironmentStrings(NULL,
  149. pfdata.StartFile,
  150. FullPathName,
  151. MAX_PATH + 1
  152. );
  153. if (!dw || dw > MAX_PATH) {
  154. RcMessageBox(EG_PIF_STARTFILE_ERR,
  155. NULL, NULL, RMB_ICON_BANG | RMB_ABORT);
  156. goto CleanUpAndReturn;
  157. }
  158. // search from the current directory
  159. // note that the startup directory specified in
  160. // the pif file has been set as our current directory
  161. // when we got here
  162. dw = SearchPathOem(".",
  163. FullPathName,
  164. NULL,
  165. MAX_PATH + 1,
  166. AppFullPathName,
  167. &pFilePart
  168. );
  169. // if couldn't find the file from the current dir
  170. // ask win32api help
  171. if (dw == 0 || dw > MAX_PATH) {
  172. dw = SearchPathOem(NULL,
  173. FullPathName,
  174. NULL,
  175. MAX_PATH + 1,
  176. AppFullPathName,
  177. &pFilePart
  178. );
  179. }
  180. // couldn't find the file, give up
  181. if (dw == 0 || dw > MAX_PATH) {
  182. RcMessageBox(EG_PIF_STARTFILE_ERR,
  183. NULL, NULL, RMB_ICON_BANG | RMB_ABORT);
  184. goto CleanUpAndReturn;
  185. }
  186. dw = GetFileAttributesOemSys(AppFullPathName, TRUE);
  187. if (dw == (DWORD)(-1) || (dw & FILE_ATTRIBUTE_DIRECTORY)) {
  188. RcMessageBox(EG_PIF_STARTFILE_ERR, NULL, NULL,
  189. RMB_ICON_BANG | RMB_ABORT
  190. );
  191. goto CleanUpAndReturn;
  192. }
  193. // convert to shortfilename
  194. dw = GetShortPathNameOem(AppFullPathName, pvi->AppName,
  195. MAX_PATH + 1);
  196. if (dw == 0 || dw > MAX_PATH) {
  197. RcMessageBox(EG_PIF_STARTFILE_ERR, NULL, NULL,
  198. RMB_ICON_BANG | RMB_ABORT
  199. );
  200. goto CleanUpAndReturn;
  201. }
  202. // update the application path name length(including the terminate NULL)
  203. pvi->AppLen = strlen(pvi->AppName) + 1;
  204. // pvi->AppName contains the application short name.
  205. // verify that it has the correct extension(.EXE, .COM or .BAT).
  206. pDot = (PCHAR)pvi->AppName + pvi->AppLen - 5;
  207. if (pvi->AppLen < 5 ||
  208. (_strnicmp(pDot, EXE_EXTENTION_STRING, EXTENTION_STRING_LEN) &&
  209. _strnicmp(pDot, COM_EXTENTION_STRING, EXTENTION_STRING_LEN) &&
  210. _strnicmp(pDot, BAT_EXTENTION_STRING, EXTENTION_STRING_LEN)))
  211. {
  212. RcMessageBox(EG_DOS_PROG_EXTENSION,AppFullPathName, NULL, RMB_ICON_BANG | RMB_ABORT);
  213. goto CleanUpAndReturn;
  214. }
  215. }
  216. //
  217. // Copy in pif command tail if original command tail is empty
  218. //
  219. if (!*pCmdLine && pfdata.CmdLine) {
  220. strncpy(FullPathName, pfdata.CmdLine, sizeof(FullPathName)-sizeof("\x0d\x0a"));
  221. FullPathName[sizeof(FullPathName)-sizeof("\x0d\x0a")-1] = '\0';
  222. strcat(FullPathName, "\x0d\x0a");
  223. if (strlen(FullPathName) >= 128 - 13) {
  224. // too bad, the command line is too long
  225. RcMessageBox(EG_PIF_CMDLINE_ERR,NULL,NULL,RMB_ICON_BANG | RMB_ABORT);
  226. goto CleanUpAndReturn;
  227. }
  228. strcpy(pvi->CmdLine, FullPathName);
  229. pvi->CmdSize = strlen(FullPathName) + 1;
  230. }
  231. if (IsPIFFile)
  232. // we don't know the binary type at this point.
  233. *pIsDosBinary = 0;
  234. if (pfdata.WinTitle)
  235. SetConsoleTitle(pfdata.WinTitle);
  236. DontCheckDosBinaryType = (pfdata.SubSysId == SUBSYS_DOS);
  237. CleanUpAndReturn:
  238. if (pfdata.CmdLine) {
  239. free(pfdata.CmdLine);
  240. pfdata.CmdLine = NULL;
  241. }
  242. if (pfdata.StartDir) {
  243. free(pfdata.StartDir);
  244. pfdata.StartDir = NULL;
  245. }
  246. if (pfdata.StartFile) {
  247. free(pfdata.StartFile);
  248. pfdata.StartFile = NULL;
  249. }
  250. if (pfdata.WinTitle) {
  251. free(pfdata.WinTitle);
  252. pfdata.WinTitle = NULL;
  253. }
  254. return;
  255. }