{"id":9953,"date":"2011-08-08T07:00:00","date_gmt":"2011-08-08T07:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2011\/08\/08\/what-does-the-createprocess-function-do-if-there-is-no-space-between-the-program-name-and-the-arguments\/"},"modified":"2011-08-08T07:00:00","modified_gmt":"2011-08-08T07:00:00","slug":"what-does-the-createprocess-function-do-if-there-is-no-space-between-the-program-name-and-the-arguments","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20110808-00\/?p=9953","title":{"rendered":"What does the CreateProcess function do if there is no space between the program name and the arguments?"},"content":{"rendered":"<p>\nIn an old discussion of\n<a HREF=\"http:\/\/blogs.msdn.com\/oldnewthing\/archive\/2009\/06\/01\/9673254.aspx\">\nwhy the <code>Create&shy;Process<\/code> function modifies its command line<\/a>,\ncommenter Random832 asked,\n&#8220;<a HREF=\"http:\/\/blogs.msdn.com\/oldnewthing\/archive\/2009\/06\/01\/9673254.aspx#9701807\">What if there is no space between the program name and arguments\n&#8211; like &#8220;cmd\/?&#8221; &#8211; where does it put the null then?<\/a>&#8221;\n<\/p>\n<p>\nThe <code>Create&shy;Process<\/code> function requires a space between the\nprogram name and arguments.\nIf you leave out the space, then the arguments are considered as part\nof the program name\n(and you&#8217;ll almost certainly get\n<code>ERROR_FILE_NOT_FOUND<\/code> back).\n<\/p>\n<p>\nIt sounds like Random832 has confused <code>Create&shy;Process<\/code> command\nline parsing with <code>cmd.exe<\/code> command line parsing.\nClearly the two parsers are different; you can see this even without\nplaying with spaces between the program name and the arguments:\n<\/p>\n<pre>\nC:\\&gt;C:\\Program Files\\Windows NT\\Accessories\\wordpad.exe\n'C:\\Program' is not recognized as an internal or external command,\noperable program or batch file.\n<\/pre>\n<p>\nIf the command line had been parsed by <code>Create&shy;Process<\/code>,\nthis would have succeeded in running the Wordpad program,\nbecause, as I noted in the original article,\nthe <code>Create&shy;Process<\/code> function\nmodifies its command line in order to find\nwhere the program name ends and the command lines begin,\nan example of which can be found\n<a HREF=\"http:\/\/msdn.microsoft.com\/ms682425.aspx\">\nin the <code>Create&shy;Process<\/code> documentation<\/a>.\nIn this case, it would have plunked the null character into each\nof the spaces in the command line, finding that each one failed,\nuntil it finally tried treating the entire string as the program name,\nat which point it would have succeeded.\nThe fact that it failed demonstrates that <code>Create&shy;Process<\/code>\ndidn&#8217;t do the parsing.\n<\/p>\n<p>\nThe <code>cmd.exe<\/code> program permits the space between a program\nname and its arguments to be elided if the arguments begin with a character\nnot permitted in file names.\nOnce it figures out what you&#8217;re running, and it determines that what\nyou&#8217;re running is a program,\nit call the <code>Create&shy;Process<\/code> function\nwith an explicit application and command line.\n<\/p>\n<p>\nBut you don&#8217;t have to take my word for it.\nYou can just see for yourself.\n(In fact, this is exactly what I did to investigate the issue\nin the first place.)\n<\/p>\n<pre>\nC:&gt;ntsd -2 cmd.exe\n<\/pre>\n<p>\nTwo windows will open, one for your debugger and one for <code>cmd.exe<\/code>.\n(You are welcome to replace <code>ntsd<\/code> with your favorite debugger.\nI chose <code>ntsd<\/code> because&mdash;at least until Windows&nbsp;XP&mdash;it\ncame preinstalled, thereby avoiding\n<a HREF=\"http:\/\/blogs.msdn.com\/oldnewthing\/archive\/2010\/01\/07\/9944907.aspx#9945268\">\nmultiplying the problem from one to two<\/a>.)\n<\/p>\n<p>\nIn the debugger, set a breakpoint on\n<code>kernel32!Create&shy;ProcessW<\/code>,\nthen resume execution.\nIn the <code>cmd.exe<\/code> window, type <code>cmd\/?<\/code>.\nThe breakpoint will fire, and you can look at the parameters:\n<\/p>\n<pre>\nBreakpoint 0 hit\neax=0046f600 ebx=00000000 ecx=004f8de0 edx=00000000 esi=00000000 edi=00000001\neip=757820ba esp=0046f544 ebp=0046f704 iopl=0         nv up ei pl zr na pe nc\ncs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246\nkernel32!CreateProcessW:\n757820ba 8bff            mov     edi,edi\n0:000&gt; dd esp l4\n0046f544  4a5e3dd7 004f5420 004f8db0 00000000\n0:000&gt; du 004f5420\n004f5420  \"C:\\Windows\\system32\\cmd.exe\"\n0:000&gt; du 004f8db0\n004f8db0  \"cmd \/?\"\n<\/pre>\n<p>\nObserve that <code>cmd.exe<\/code> did its own manual path search\nto arrive at an executable of\n<code>C:\\Windows\\system32\\cmd.exe<\/code>,\nand also that it secretly inserted a space between the\n<code>cmd<\/code> and the slash.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In an old discussion of why the Create&shy;Process function modifies its command line, commenter Random832 asked, &#8220;What if there is no space between the program name and arguments &#8211; like &#8220;cmd\/?&#8221; &#8211; where does it put the null then?&#8221; The Create&shy;Process function requires a space between the program name and arguments. If you leave out [&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":[25],"class_list":["post-9953","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>In an old discussion of why the Create&shy;Process function modifies its command line, commenter Random832 asked, &#8220;What if there is no space between the program name and arguments &#8211; like &#8220;cmd\/?&#8221; &#8211; where does it put the null then?&#8221; The Create&shy;Process function requires a space between the program name and arguments. If you leave out [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/9953","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=9953"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/9953\/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=9953"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=9953"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=9953"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}