{"id":21723,"date":"2008-07-07T10:00:00","date_gmt":"2008-07-07T10:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2008\/07\/07\/why-is-the-loadparms32-structure-so-messed-up\/"},"modified":"2008-07-07T10:00:00","modified_gmt":"2008-07-07T10:00:00","slug":"why-is-the-loadparms32-structure-so-messed-up","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20080707-00\/?p=21723","title":{"rendered":"Why is the LOADPARMS32 structure so messed up?"},"content":{"rendered":"<p><P>\nIf you look at the <CODE>LOADPARMS32<\/CODE> structure,\nyou&#8217;ll find a horrific mishmash.\nDouble-null-terminated strings,\na null-terminated string,\nsome <CODE>WORD<\/CODE>s, and\neven a Pascal-style string.\n<A HREF=\"http:\/\/blogs.msdn.com\/oldnewthing\/pages\/407234.aspx#516134\">\nWhat&#8217;s going on here<\/A>?\n<\/P>\n<P>\nEach of those members comes from a different era in time.\nThe oldest member is the Pascal-style command line,\nwhich dates back to CP\/M.\nOn CP\/M, command lines were stored at a fixed location,\nnamely 0080h through 00FFh,\nin the form of a Pascal string.\nThe byte at 0080h specified the length of the command line,\nand the bytes at 0081h through 00FFh contained the command line itself.\n<\/P>\n<P>\nMS-DOS based much of its initial interface on CP\/M in order to\nmake porting to the new operating system easier,\nand part of what got carried over was the way command lines were\npassed from one program to another.\nThe MS-DOS function to load a program took two parameters,\na pointer to a null-terminated string (specifying the module to load)\nand a pointer to a parameter block which took the following form:\n<\/P>\n<PRE>\nLOADPARMS       struc\nloadp_environ   dw      ?       ; environment of new process\nloadp_cmdline   dd      ?       ; command line of new process\nloadp_fcb1      dd      ?       ; first FCB\nloadp_fcb2      dd      ?       ; second FCB\nLOADPARMS       ends\n<\/PRE>\n<P>\nTo ease the transition,\nWindows&nbsp;1.0 used the same MS-DOS interface for launching\nprograms:\nYou loaded up the registers and issued an\n<CODE>int&nbsp;21h<\/CODE> instruction.\nAll the parameters had the same meaning.\nGenerally speaking, 16-bit Windows used the old MS-DOS interface\nfor a lot of functionality, especially disk access.\nWant to write to a file?\nPut the file handle in the <CODE>BX<\/CODE> register,\nthe number of bytes in the <CODE>CX<\/CODE> register,\na pointer to the buffer in the <CODE>DS:DX<\/CODE> registers,\nfunction code <CODE>40h<\/CODE> in the <CODE>AH<\/CODE> register,\nand issue an\n<CODE>int&nbsp;21h<\/CODE>,\njust like in MS-DOS.\n<\/P>\n<P>\nWhy do this?\nWell, it saved the Windows team from having to invent a whole\nboatload of functions that duplicated what MS-DOS already did,\nand it meant that existing MS-DOS programs\ndidn&#8217;t need to change a thing in their file I\/O code.\nIf they used a runtime library designed for MS-DOS (C or otherwise),\nthat library would still write to files by setting registers\nand issuing an <CODE>int&nbsp;21h<\/CODE>.\nIf you want people to switch to your new platform, you need to make it easy,\nand &#8220;you don&#8217;t have to change anything; it all just works&#8221; is pretty easy.\n(One minor change was that the first FCB was repurposed to contain\nthe <CODE>nCmdShow<\/CODE>; the magic value of &#8220;2&#8221; in the first word of\nthe FCB signals that it&#8217;s not really an FCB.)\n<\/P>\n<P>\nAs a minor convenience, the\n<CODE>LoadModule<\/CODE> function provided a C-callable version of\nthe low-level <CODE>int&nbsp;21h<\/CODE>, but you still had to provide\nthe parameters in the form of the MS-DOS exec structure.\nIt wasn&#8217;t until later versions of Windows that the\n<CODE>WinExec<\/CODE> function was added,\nthereby providing a much more convenient interface to starting a new\nprogram.\nNo longer did you have to mess with the crazy MS-DOS exec structure\nand its strange way of passing the command line and <CODE>nCmdShow<\/CODE>.\n<\/P>\n<P>\nThe people who were designing Win32 created their own function\n<CODE>CreateProcess<\/CODE> to launch a new process,\nbut for backward compatiblity, they retained the\nold <CODE>WinExec<\/CODE>\nand even older <CODE>LoadModule<\/CODE> mechanisms.\nThe pointers in the crazy 16-bit exec block got converted to 32-bit,\nbut the craziness of what they pointed to was retained to make\nporting old code easier.\nThe <CODE>int&nbsp;21h<\/CODE> interface no longer exists, of course.\nThe craziness is just a leftover from the old MS-DOS days.\nThe <CODE>WinExec<\/CODE> and <CODE>LoadModule<\/CODE> functions\nare now just stub functions that convert their parameters and\ncall the <CODE>CreateProcess<\/CODE> function to do the real work.\n<\/P><\/p>\n","protected":false},"excerpt":{"rendered":"<p>If you look at the LOADPARMS32 structure, you&#8217;ll find a horrific mishmash. Double-null-terminated strings, a null-terminated string, some WORDs, and even a Pascal-style string. What&#8217;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 [&hellip;]<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[2],"class_list":["post-21723","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-history"],"acf":[],"blog_post_summary":"<p>If you look at the LOADPARMS32 structure, you&#8217;ll find a horrific mishmash. Double-null-terminated strings, a null-terminated string, some WORDs, and even a Pascal-style string. What&#8217;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 [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/21723","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=21723"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/21723\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=21723"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=21723"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=21723"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}