PRB: Executing a 16-Bit Process with a Large Command Line on Windows NT/2000/XP (198429)
The information in this article applies to:
- Microsoft Win32 Application Programming Interface (API), when used with:
- the operating system: Microsoft Windows NT 4.0
- the operating system: Microsoft Windows 2000
- the operating system: Microsoft Windows XP
This article was previously published under Q198429 SYMPTOMS
When using CreateProcess(), ShellExecute(), or ShellExecuteEx() to launch a
16-bit executable on Microsoft Windows NT, Microsoft Windows 2000, and Microsoft Windows XP 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.
CAUSELimitation 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 INFORMATIONLimitation 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:
175986
INFO: Understanding CreateProcess and Command-line Arguments
Modification Type: | Major | Last Reviewed: | 4/9/2004 |
---|
Keywords: | kb16bitonly kbAPI kbKernBase kbprb KB198429 |
---|
|