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.

290 lines
7.8 KiB

  1. //
  2. // MSDOS.C Wizard started by SHELL.VxD
  3. //
  4. // Copyright (C) Microsoft, 1994,1995 All Rights Reserved.
  5. //
  6. // History:
  7. // 3/20/95 [stevecat] - NT port & real clean up, unicode, etc.
  8. //
  9. //
  10. #include "priv.h"
  11. #include "appwiz.h"
  12. #include <wshioctl.h>
  13. //
  14. // This exported entry point is called by RUNDLL32 when a VxD calls the
  15. // Shell_SuggestSingleMSDOSMode service.
  16. //
  17. void WINAPI SingleMSDOSWizard(HWND hwnd, HINSTANCE hAppInstance, LPTSTR lpszCmdLine, int nCmdShow)
  18. {
  19. WIZDATA wd;
  20. memset(&wd, 0, sizeof(wd));
  21. wd.hwnd = hwnd;
  22. if (GetSingleAppInfo(&wd))
  23. {
  24. if (wd.hProps != 0)
  25. {
  26. MSDOSPropOnlyWizard(&wd);
  27. }
  28. else
  29. {
  30. wd.dwFlags |= WDFLAG_SINGLEAPP;
  31. LinkWizard(&wd);
  32. }
  33. }
  34. //
  35. // Note, we close properties here in case GetSingleAppInfo returned false,
  36. // but still had opened the hProps.
  37. //
  38. if (wd.hProps != 0)
  39. {
  40. PifMgr_CloseProperties(wd.hProps, CLOSEPROPS_NONE);
  41. }
  42. }
  43. //
  44. // Inline helper function. If the name ends with the extension .EXE, .BAT,
  45. // or .COM then we'll accept it. Otherwise, try to take the given name and
  46. // convert it to a program name we can execute. This fixes the case where
  47. // Flight Simulator's setup program runs FS5.OVL. The user should really
  48. // run FS5.BAT.
  49. //
  50. HRESULT _inline CleanUpName(LPWIZDATA lpwd)
  51. {
  52. LPCTSTR PathDirs[2];
  53. LPTSTR pszExt;
  54. LPTSTR pszCurExt;
  55. TCHAR szValidExt[100];
  56. ASSERT(lpwd);
  57. pszExt = PathFindExtension(lpwd->szExeName);
  58. if (!pszExt)
  59. {
  60. return E_FAIL;
  61. }
  62. PathDirs[0] = lpwd->szWorkingDir;
  63. PathDirs[1] = NULL;
  64. if (*pszExt)
  65. pszExt++; // NSL: *pszExt == '.' so this should be fine
  66. //
  67. // Make sure that the extension is a real progarm extension (not .OVL
  68. // for example. If it is, search for the matching name.
  69. //
  70. szValidExt[0] = TEXT('\0');
  71. if (!LoadAndStrip(IDS_EXTENSIONS, szValidExt, ARRAYSIZE(szValidExt)))
  72. {
  73. return E_FAIL;
  74. }
  75. pszCurExt = szValidExt;
  76. while (*pszCurExt)
  77. {
  78. if (lstrcmpi(pszExt, pszCurExt) == 0)
  79. {
  80. if (PathResolve(lpwd->szExeName, PathDirs, PRF_VERIFYEXISTS | PRF_TRYPROGRAMEXTENSIONS))
  81. {
  82. return S_OK;
  83. }
  84. else
  85. {
  86. return S_FALSE;
  87. }
  88. }
  89. pszCurExt = SkipStr(pszCurExt);
  90. }
  91. pszCurExt = szValidExt;
  92. while (*pszCurExt)
  93. {
  94. lstrcpy(pszExt, pszCurExt);
  95. if (PathResolve(lpwd->szExeName, PathDirs, PRF_VERIFYEXISTS | PRF_TRYPROGRAMEXTENSIONS))
  96. {
  97. return S_OK;
  98. }
  99. pszCurExt = SkipStr(pszCurExt);
  100. }
  101. return S_FALSE;
  102. }
  103. BOOL GetSingleAppInfo(LPWIZDATA lpwd)
  104. {
  105. HANDLE hDevice;
  106. BOOL bMakeLink = FALSE;
  107. SINGLEAPPSTRUC SAS;
  108. DWORD dwRetSize;
  109. LPDWORD lpResult;
  110. HRESULT hr;
  111. hDevice = CreateFile(SHELLFILENAME, GENERIC_WRITE, FILE_SHARE_WRITE, NULL,
  112. OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
  113. if (hDevice == INVALID_HANDLE_VALUE)
  114. {
  115. return(FALSE);
  116. }
  117. if (DeviceIoControl(hDevice, WSHIOCTL_GET1APPINFO, NULL, 0,
  118. &SAS, sizeof(SAS), &dwRetSize, NULL))
  119. {
  120. #define fVMDead ((BOOL)(SAS.SSA_dwFlags & SSAMFLAG_KILLVM))
  121. int idString = fVMDead ? IDS_VMCLOSED : IDS_VMSTILLALIVE;
  122. TraceMsg(TF_ERROR, "%s", "Got info on a single MS-DOS mode app. Now will show Exe, Command line params, directory, and PIF.");
  123. TraceMsg(TF_ERROR, "%s", SAS.SSA_ProgName);
  124. TraceMsg(TF_ERROR, "%s", SAS.SSA_CommandLine);
  125. TraceMsg(TF_ERROR, "%s", SAS.SSA_CurDir);
  126. TraceMsg(TF_ERROR, "%s", SAS.SSA_PIFPath);
  127. if (SAS.SSA_dwFlags & SSAMFLAG_FROMREGLIST)
  128. {
  129. SHELLEXECUTEINFO ei;
  130. lpResult = (LPVOID)SAS.SSA_ResultPtr;
  131. *lpResult = SSR_KILLAPP;
  132. DeviceIoControl(hDevice, WSHIOCTL_SIGNALSEM, &SAS, sizeof(SAS),
  133. NULL, 0, NULL, NULL);
  134. ei.cbSize = sizeof(ei);
  135. ei.hwnd = lpwd->hwnd;
  136. ei.lpVerb = NULL;
  137. ei.fMask = 0;
  138. ei.lpFile = SAS.SSA_ProgName;
  139. if (SAS.SSA_CommandLine[0] == 0)
  140. {
  141. ei.lpParameters = NULL;
  142. }
  143. else
  144. {
  145. ei.lpParameters = SAS.SSA_CommandLine;
  146. }
  147. if (SAS.SSA_CurDir == TEXT('\0'))
  148. {
  149. ei.lpDirectory = NULL;
  150. }
  151. else
  152. {
  153. ei.lpDirectory = SAS.SSA_CurDir;
  154. }
  155. ei.lpClass = NULL;
  156. ei.nShow = SW_SHOWDEFAULT;
  157. ei.hInstApp = g_hinst;
  158. ShellExecuteEx(&ei);
  159. goto CloseHandleExit;
  160. }
  161. if (SAS.SSA_dwFlags & SSAMFLAG_REQREALMODE)
  162. {
  163. lpwd->dwFlags |= WDFLAG_REALMODEONLY;
  164. }
  165. lstrcpyn(lpwd->szExeName, SAS.SSA_ProgName, ARRAYSIZE(lpwd->szExeName));
  166. lstrcpyn(lpwd->szParams, SAS.SSA_CommandLine, ARRAYSIZE(lpwd->szParams));
  167. lstrcpyn(lpwd->szWorkingDir, SAS.SSA_CurDir, ARRAYSIZE(lpwd->szWorkingDir));
  168. hr = CleanUpName(lpwd);
  169. if (FAILED(hr))
  170. {
  171. bMakeLink = FALSE;
  172. goto CloseHandleExit;
  173. }
  174. else if (hr == S_OK)
  175. {
  176. DetermineExeType(lpwd);
  177. lpwd->dwFlags |= WDFLAG_NOBROWSEPAGE;
  178. //
  179. // There are three different possibilities with SSA_PIFPath:
  180. // Empty string indicates program run from command line.
  181. // " " indicates exe run from shell, but no PIF exists
  182. // Name of PIF that was run.
  183. // If the program was run from command.com then we will force
  184. // the user to create a shortcut. If not started from a specific
  185. // PIF then we'll set the default properties for the program. If
  186. // started from a specific PIF then we'll set the properties for
  187. // that PIF.
  188. //
  189. if (SAS.SSA_PIFPath[0] != 0)
  190. {
  191. lpwd->hProps = PifMgr_OpenProperties((SAS.SSA_PIFPath[0] == TEXT(' ')) ?
  192. lpwd->szExeName : SAS.SSA_PIFPath,
  193. NULL, 0, OPENPROPS_NONE);
  194. if (lpwd->hProps != 0)
  195. {
  196. idString = fVMDead ? IDS_CHGPROPCLOSED
  197. : IDS_CHGPROPSTILLALIVE;
  198. }
  199. }
  200. }
  201. else
  202. {
  203. LPTSTR pszStartName = PathFindFileName(lpwd->szExeName);
  204. *pszStartName = 0;
  205. LoadStringA(g_hinst, IDS_GENERICNAME,
  206. lpwd->PropPrg.achTitle, ARRAYSIZE(lpwd->PropPrg.achTitle));
  207. }
  208. bMakeLink = (IDYES == ShellMessageBox(g_hinst,
  209. lpwd->hwnd,
  210. MAKEINTRESOURCE(idString),
  211. MAKEINTRESOURCE(IDS_1APPWARNTITLE),
  212. MB_YESNO | MB_DEFBUTTON1 | MB_ICONEXCLAMATION,
  213. lpwd->PropPrg.achTitle));
  214. lpResult = (LPVOID)SAS.SSA_ResultPtr;
  215. if (!fVMDead && lpResult != NULL)
  216. {
  217. if (bMakeLink)
  218. {
  219. *lpResult = (SAS.SSA_dwFlags & SSAMFLAG_FROMREGLIST) ?
  220. SSR_KILLAPP : SSR_CLOSEVM;
  221. }
  222. else
  223. {
  224. *lpResult = SSR_CONTINUE;
  225. }
  226. DeviceIoControl(hDevice, WSHIOCTL_SIGNALSEM, &SAS, sizeof(SAS),
  227. NULL, 0, NULL, NULL);
  228. }
  229. }
  230. CloseHandleExit:
  231. CloseHandle(hDevice);
  232. return(bMakeLink);
  233. #undef fVMDead
  234. }
  235.