Welcome to MSDN Blogs Sign in | Join | Help

Why is the LOADPARMS32 structure so messed up?

If you look at the LOADPARMS32 structure, you'll find a horrific mishmash. Double-null-terminated strings, a null-terminated string, some WORDs, and even a Pascal-style string. What's going on here?

Each of those members comes from a different era in time. The oldest member is the Pascal-style command line, which dates back to CP/M. On CP/M, command lines were stored at a fixed location, namely 0080h through 00FFh, in the form of a Pascal string. The byte at 0080h specified the length of the command line, and the bytes at 0081h through 00FFh contained the command line itself.

MS-DOS based much of its initial interface on CP/M in order to make porting to the new operating system easier, and part of what got carried over was the way command lines were passed from one program to another. The MS-DOS function to load a program took two parameters, a pointer to a null-terminated string (specifying the module to load) and a pointer to a parameter block which took the following form:

LOADPARMS       struc
loadp_environ   dw      ?       ; environment of new process
loadp_cmdline   dd      ?       ; command line of new process
loadp_fcb1      dd      ?       ; first FCB
loadp_fcb2      dd      ?       ; second FCB
LOADPARMS       ends

To ease the transition, Windows 1.0 used the same MS-DOS interface for launching programs: You loaded up the registers and issued an int 21h instruction. All the parameters had the same meaning. Generally speaking, 16-bit Windows used the old MS-DOS interface for a lot of functionality, especially disk access. Want to write to a file? Put the file handle in the BX register, the number of bytes in the CX register, a pointer to the buffer in the DS:DX registers, function code 40h in the AH register, and issue an int 21h, just like in MS-DOS.

Why do this? Well, it saved the Windows team from having to invent a whole boatload of functions that duplicated what MS-DOS already did, and it meant that existing MS-DOS programs didn't need to change a thing in their file I/O code. If they used a runtime library designed for MS-DOS (C or otherwise), that library would still write to files by setting registers and issuing an int 21h. If you want people to switch to your new platform, you need to make it easy, and "you don't have to change anything; it all just works" is pretty easy. (One minor change was that the first FCB was repurposed to contain the nCmdShow; the magic value of "2" in the first word of the FCB signals that it's not really an FCB.)

As a minor convenience, the LoadModule function provided a C-callable version of the low-level int 21h, but you still had to provide the parameters in the form of the MS-DOS exec structure. It wasn't until later versions of Windows that the WinExec function was added, thereby providing a much more convenient interface to starting a new program. No longer did you have to mess with the crazy MS-DOS exec structure and its strange way of passing the command line and nCmdShow.

The people who were designing Win32 created their own function CreateProcess to launch a new process, but for backward compatiblity, they retained the old WinExec and even older LoadModule mechanisms. The pointers in the crazy 16-bit exec block got converted to 32-bit, but the craziness of what they pointed to was retained to make porting old code easier. The int 21h interface no longer exists, of course. The craziness is just a leftover from the old MS-DOS days. The WinExec and LoadModule functions are now just stub functions that convert their parameters and call the CreateProcess function to do the real work.

Published Monday, July 07, 2008 7:00 AM by oldnewthing
Filed under:

Comments

# re: Why is the LOADPARMS32 structure so messed up?

Monday, July 07, 2008 12:03 PM by BryanK

And in case anyone's wondering where LOADPARMS32 is documented:

http://msdn.microsoft.com/en-us/library/ms684183(VS.85).aspx

It's part of the LoadModule function docs; it does not have its own doc page, like most of the other Win32 structures do.  (Probably because it isn't a Win32 structure, really.  It's a Win16 structure included for source compatibility.)

# re: Why is the LOADPARMS32 structure so messed up?

Monday, July 07, 2008 12:34 PM by Krai Gahwunao

So let me get this straight: Technically speaking, there's code in Windows Vista that dates back all the way to CP/M. Nice. (Ok, it's "just" a struct, but it's still pretty ancient.)

# re: Why is the LOADPARMS32 structure so messed up?

Monday, July 07, 2008 1:29 PM by Tim Smith

I would bet there is code in almost any system that dates back +20 years.  Why rewrite something just because it is old.

# re: Why is the LOADPARMS32 structure so messed up?

Monday, July 07, 2008 2:54 PM by Daniel Colascione

Because it needs to use $LATEST_PROGRAMMING_FAD, of course!

# re: Why is the LOADPARMS32 structure so messed up?

Monday, July 07, 2008 5:43 PM by Yuhong Bao

Another change for Windows was that once you return from the Int 21/AH=4B, the AX register contain the HINSTANCE of the application.

LoadModule was not documented until Windows 3.0, though LoadModule existed in the header files since at least 2.x. Even after WinExec and LoadModule was added, Int 21/AH=4C had to still be used to terminate an app.

And how did you get the return code of a spawned app? You had to use TOOLHELP (which was introduced in Windows 3.1) to watch for program termination.

Int 21 later became DOS3Call in around Windows 3.0 to reduce call overhead in protected mode.

LoadModule could not load a Win32s application because Win32s used a hook into the Windows 3.1 loader that was not invoked if you called LoadModule.

# re: Why is the LOADPARMS32 structure so messed up?

Monday, July 07, 2008 8:28 PM by Antonio Rodrí­guez

When I saw the topic of this post, I was hoping to see some Windows Vista bashing in the comments... and you haven't deceived me ;-) . Windows has code dating from the early 80s for compatibility, true. But both Linux and Mac OS are Unixes, and thus should have code from the early 70s, ten years older than the first version of MS-DOS. Are they worse OSes because of that? No, they aren't. But still, it is quite fun to attack Vista at any chance, isn't it?

# re: Why is the LOADPARMS32 structure so messed up?

Monday, July 07, 2008 8:30 PM by Daniel Colascione

<nit>

Linux was actually written from the ground up. It contains no Unix code (aside from xfs, these days), and so is technically a Unix-like operating system.

But close enough for practical purposes, sure.

</nit>

# re: Why is the LOADPARMS32 structure so messed up?

Monday, July 07, 2008 10:36 PM by Joel

I'm a Linux user (Mac user at work), and not too fond of Vista, but I do also hate the Vista bashing that goes on in internet forums and blogs.  If there are problems with Vista, it's not the fact that LOADPARM32 has double terminated null strings.  For every weird API "feature" in Win32, I can find one or more in the Linux world, some of them introduced even later than the wacko Win32 ones, and with worse rationale.  And let's not even talk about the pile of crap that is X11...

# re: Why is the LOADPARMS32 structure so messed up?

Monday, July 07, 2008 10:55 PM by James Day

Antonio, you're too sensitive this time. It's interesting to know how old bits are and that's not necessarily an attack.

It prompted me to check the oldest executable of of a program I wrote that I still use reasonably regularly. That's from July 1997 and is a console application using the 1992-copyrighted version of the Microsoft libraries. Fifteen years of backwards compatibility is quite respectable.

One less regularly used (last in October 2007) has a copyright date of 1988 and is written in Borland Turbo Pascal. Nineteen years of backwards compatibility is getting to be pretty good.

# re: Why is the LOADPARMS32 structure so messed up?

Monday, July 07, 2008 11:11 PM by ATZ Man

The "GNU/" part of GNU/Linux is older than Linux. The nit to be picked here (I know enough to know its there but not enough to actually pick it) lies in the difference between an Operating System and a kernel.

# re: Why is the LOADPARMS32 structure so messed up?

Monday, July 07, 2008 11:18 PM by hexatron

Gulp. I still sometimes use WinExec. But not shamelessly.

Well, hell. If it does what you want...

# re: Why is the LOADPARMS32 structure so messed up?

Monday, July 07, 2008 11:41 PM by Yuhong Bao

"If you want people to switch to your new platform, you need to make it easy, and "you don't have to change anything; it all just works" is pretty easy."

Some DOS functions do require minor changes to ensure code using them are compatible with Windows, for example the interrupt handler code and any data it touches had to be marked as FIXED, which in Windows 3.1 requires it to be placed in a DLL because older linkers default any additional data segments as FIXED because real-mode Windows was not able to fix reference to them when these segments move, and 386 enhanced mode Windows not only fixes but even pagelocks FIXED segments. Even in protected-mode Windows, EXEs that define additional data segments are limited to a single instance for a similar reason.

# re: Why is the LOADPARMS32 structure so messed up?

Tuesday, July 08, 2008 1:33 AM by Worf

Honestly, the oldest code in Linux proper would date to around 1991, when Linux 0.1 was released. The oldest code in a full GNU/Linux system would probably date to the 60s or 70s, as the beginnings of Emacs. Most Linux systems don't have a version of vi derived from Bill Joy's code, instead using nvi (a free clone), or more commonly, vim.

OTOH, since this structure is more of an interface than code itself... this would date Linux' (and BSD and MacOS X...) interface to the 70's as well. After all, the syscalls haven't changed too much over the years.

# re: Why is the LOADPARMS32 structure so messed up?

Tuesday, July 08, 2008 4:49 AM by Neil

386 enhanced mode pagelocks fixed segments because software written for older versions of Windows wouldn't have known about pagelocking.

# re: Why is the LOADPARMS32 structure so messed up?

Tuesday, July 08, 2008 7:32 AM by SuperKoko

From Daniel Colascione:

"Linux was actually written from the ground up. It contains no Unix code (aside from xfs, these days), and so is technically a Unix-like operating system."

MS-DOS and Windows have no CP/M code either, they just have a little bit of CP/M-like interface.

Further, I think that there's very small to no MS-DOS code in Windows NT/2000/XP/Vista.

# re: Why is the LOADPARMS32 structure so messed up?

Tuesday, July 08, 2008 1:40 PM by Ray

backwards compatibility is a real double edged sword isn't it.

If you keep doing it, you end up with hacks on top of kludges on top of workarounds and the code continues to bloat.

But if you lose backwards compatibility, you end up being crucified in the press and people won't buy your product because Lotus 1.0 doesn't work anymore, or being crucified in the sales department because a lot of apps don't work anymore.

# re: Why is the LOADPARMS32 structure so messed up?

Tuesday, July 08, 2008 2:52 PM by steveshe

I hereby submit Yuhong Bao for the BDIU award! Raymond, he doesn't just pollute your blog, he is doign this crap on every technical blog our there.

# re: Why is the LOADPARMS32 structure so messed up?

Tuesday, July 08, 2008 3:31 PM by Jan Ouen

@Steveshe: Bao wrote some very interesting comments here, so I don't see your problem.

# re: Why is the LOADPARMS32 structure so messed up?

Tuesday, July 08, 2008 3:54 PM by mjb

"Linux was actually written from the ground up. It contains no Unix code (aside from xfs, these days), and so is technically a Unix-like operating system."

Come now. Are you saying no code has been donated to the kernel which originally was from other sources. (appropriately licensed to GPL2 at that point) That seems unlikely to me.

# re: Why is the LOADPARMS32 structure so messed up?

Tuesday, July 08, 2008 5:15 PM by Ulric

I'm not really at ease with these articles.

All they seem to do is get people worked up about APIs and structures in Windows that are obsolete, perpetuating the myth that Windows is old and trapped in backward compatibility.  

This is doing to harm to Microsoft.  it'll just end up as fodder on sites that are campaigning against Vista.  

I can't see any positive aspect to these articles.  It's dead code, just leave it alone.  

Right now Microsoft is in a critically wounded state with Vista, and us third party developers are struggling with clients who want away from Windows because of Vista. Information about CP/M structure in Vista is not helping anyone, it's information that is useless for everyone except the competition.

# re: Why is the LOADPARMS32 structure so messed up?

Tuesday, July 08, 2008 6:10 PM by Timothy Fries

> it'll just end up as fodder on sites that are campaigning against Vista.

Those sites that have such an obvious axe to grind against Microsoft that they'd use something as benign as a legacy API as a hammer are going to find things to complain about anyway.  Most of the complaints about Vista on the net are based solely in fiction as it is (such as the statement that Microsoft is "in a critically wounded state with Vista").

Raymond's blog is a fantastic source of, if nothing else, trivia about why these old APIs are the way they are; and it's a shame that you're suggesting such a useful and interesting resource stop being so because people who hate Microsoft with every breath might find ammunition here.

# re: Why is the LOADPARMS32 structure so messed up?

Tuesday, July 08, 2008 6:12 PM by SuperKoko

From Ray:

"If you keep doing it, you end up with hacks on top of kludges on top of workarounds and the code continues to bloat."

There're no hack or workaround to make LoadModule work in Windows Vista. It's a trivial thunk to CreateProcess that most programmers safely ignore. It simply doesn't harm (unlike some backward-compatibility hacks described in other blogs entries).

From Ulric:

"I can't see any positive aspect to these articles."

So, don't read them and don't flood the comment system.

Read the title of the blog before starting reading entries.

The OLD new thing.

# re: Why is the LOADPARMS32 structure so messed up?

Tuesday, July 08, 2008 6:13 PM by James Day

Ulric, so help your clients do what they believe is best for their business. If that's not Windows for some clients, then you should be considering whether and how to service the various markets that make sense.

Meanwhile Raymond is effectively explaining that if they buy a Windows-based application, Microsoft is going to try to make sure that their large investment isn't made obsolete in only a couple of years. And that is of considerable value.

Unless your product is tied to Vista or Windows and can't possibly work on other systems, stop blaming Raymond and go out and service the markets your customers want you to service. Or let the competition do it, if you're really determined not to adapt.

# re: Why is the LOADPARMS32 structure so messed up?

Tuesday, July 08, 2008 9:18 PM by Yuhong Bao

BTW, back in 1975, C did not exist on anything other than UNIX.

In contrast, by 1983, C compilers are beginning to appear for MS-DOS, and even MS had it's own version of Unix called Xenix.

# re: Why is the LOADPARMS32 structure so messed up?

Wednesday, July 09, 2008 12:04 PM by John Topley

"Further, I think that there's very small to no MS-DOS code in Windows NT/2000/XP/Vista."

I don't think that's quite true. IIRC, ntvdm.exe is based on the MS-DOS 5.0 source code. If you were going to provide an environment for running old MS-DOS programs then it would make sense to use at least some of the original code from the original operating system itself. It is probably a small percentage of the overall Windows Vista code base though.

# re: Why is the LOADPARMS32 structure so messed up?

Saturday, July 12, 2008 1:53 AM by Yuhong Bao

In fact, I don't think even the changes to Int 21/4B was documented until Windows 3.0. A MS employee posted back in the 2.x days in a newsgroup sample code for spawning a Windows app. Google in Groups "Spawning Windows Applications" to take a look at this code.

New Comments to this post are disabled
 
Page view tracker