PRB: Executing a 16-Bit Process with a Large Command Line on NT

ID: Q198429

The information in this article applies to:

SYMPTOMS

When using CreateProcess(), ShellExecute(), or ShellExecuteEx() to launch a 16-bit executable on Windows NT, the file path is limited to 128 characters and the command-line arguments are limited to 130 characters minus the length of the executable file name.

CAUSE

Limitation on Length of File Path

The full path of the executable (the path and file name, excluding any command-line parameters) is subject to a limit of 128 characters. This limitation is imposed, even when using a smaller relative path to execute the 16-bit application, because the system must expand the file name to a full path before passing it on to the Windows On Windows (WOW) subsystem.

This behavior comes from a hard-coded limit in the MS-DOS Program Segment Prefix (PSP) block. Because 16-bit Windows runs on top of MS-DOS, it is subject to this limit. The WOW subsystem was written to emulate 16-bit Windows as closely as possible. Therefore, WOW must enforce all 16-bit limits; it does not give any added functionality because that would allow 16-bit programs to be written for NT that wouldn't run on the original 16- bit Windows operating systems.

RESOLUTION

To work around this problem, you can use the MS-DOS "subst" command to associate a path with a drive letter. For the syntax of this command, type "SUBST /?" from a Command prompt. To accomplish this programmatically, you can use the DefineDosDevice() API.

You can also work around the problem by mapping a drive letter to a shared directory deep within the path. This has more overhead because access to files on the share must go through the network redirector. To accomplish this programmatically, you can use the WNetAddConnection2() API.

STATUS

This behavior is by design.

MORE INFORMATION

Limitation on Length of Command Line Arguments

In addition to the 128-character file path limit, there is a limit on the combined length of the command-line arguments that can be passed to the 16- bit application. This limit is 130 characters minus the length of the executable filename (not including the path).

For example, when executing a 16-bit program "c:\go.exe", the length of the command-line arguments would be limited to 124 characters, because "go.exe" has a length of 6 characters. You are subject to this 124 character limitation even if you attempt to execute "go" (leaving off the ".exe" extension) because the system expands the file name.

If you exceed either of these limits, either the limitation on the length of file path or the limitation on the length of command line arguments, the 16-bit program fails to launch. This failure presents itself in different forms, depending on the function being used to launch the application:

Failure Using CreateProcess()

If you exceed the file path limit, you will cause a GPF in the WOW subsystem. This causes the system to present the following two message boxes simultaneously:

   Can't run 16-bit Windows program
   
      Cannot find file <filename> (or one of its components). Check to
      ensure the path and filename are correct and that all required
      libraries are available.
   
   Application Error
   
      WOWEXEC caused a General Protection Fault in module WOWEXEC.EXE at
      0001:066E. Choose close. WOWEXEC will close.

If you exceed the argument length limit, CreateProcess() will return FALSE and GetLastError() will return error code 87 (ERROR_INVALID_PARAMETER).

Failure Using ShellExecute()

If you exceed either the file path limit or the argument length limit, ShellExecute() will return error code 5 (SE_ERR_ACCESSDENIED).

Failure Using ShellExecuteEx()

If you exceed either the file path limit or the argument length limit, ShellExecuteEx() will return FALSE and GetLastError() will return error code 5 (ERROR_ACCESS_DENIED). The hInstApp member of the SHELLEXECUTEINFO structure passed to ShellExecuteEx() will also contain error code 5.

By default, when ShellExecuteEx() fails in this manner, the system will present a message box with the following error message:

   Access to the specified device, path, or file is denied.

You can prevent this message box by including the flag SEE_MASK_FLAG_NO_UI in the fMask member of the SHELLEXECUTEINFO structure passed to ShellExecuteEx().

REFERENCES

For more information on using CreateProcess() to launch 16-bit programs, please see the following Knowledge Base article:

   ARTICLE ID: Q175986
   TITLE     : INFO: Understanding CreateProcess and Command-line Arguments

Additional query words: kbDSupport
Keywords          : kbAPI kbKernBase kbNTOS400 
Version           : WINNT:4.0
Platform          : winnt
Issue type        : kbprb

Last Reviewed: January 7, 1999