{"id":1273,"date":"2014-04-11T07:00:00","date_gmt":"2014-04-11T07:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2014\/04\/11\/windows-is-not-a-microsoft-visual-cc-run-time-delivery-channel\/"},"modified":"2014-04-11T07:00:00","modified_gmt":"2014-04-11T07:00:00","slug":"windows-is-not-a-microsoft-visual-cc-run-time-delivery-channel","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20140411-00\/?p=1273","title":{"rendered":"Windows is not a Microsoft Visual C\/C++ Run-Time delivery channel"},"content":{"rendered":"<p>\nThere&#8217;s a DLL in the system directory called\n<code>MSVCRT.DLL<\/code>,\nand from its name, you might think that it is the\nMicrosoft Visual C\/C++ Run-Time library.\nThat is a perfectly reasonable guess.\n<\/p>\n<p>\nBut it would also be wrong.\n<\/p>\n<p>\nThe Microsoft Visual C\/C++ Run-Time libraries go by names\nlike\n<code>MSVCR71.DLL<\/code> or\n<code>MSVCR80.DLL<\/code> or\n<code>MSVCR90.DLL<\/code> or\n<code>MSVCR100.DLL<\/code>,\nand the debugging versions have a <code>D<\/code> in there, too.\nAnd\n<a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2008\/01\/11\/7065021.aspx\">\nlike MFC<\/a>,\nthese binaries might be on your machine as a side effect\nof the implementation of a particular Windows component,\nbut they are not contractual.\nIf your program requires the\nVisual C\/C++ Run-Time library,\nthen your program needs to install the appropriate version.\n(There are redistributable packages you can\ninclude with your application.)\n<\/p>\n<p>\nOkay, so what&#8217;s with the DLL with the misleading name\n<code>MSVCRT.DLL<\/code>?\nThe unfortunate name is a consequence of history.\n<\/p>\n<p>\nBack in Windows&nbsp;95,\n<code>MSVCRT.DLL<\/code> <i>was<\/i> the\nMicrosoft Visual C\/C++ Run-Time library,\nor at least it was the runtime library for Visual C\/C++ 4.2.\nAs each new version of Visual C\/C++ came out, the Windows team\nhad to go update their copy of <code>MSVCRT.DLL<\/code>\nto match.\nAnd if the Windows team wanted to fix a bug in\n<code>MSVCRT.DLL<\/code>,\nthey had to make sure that the Visual C\/C++ team made the corresponding\nchange in their version.\n<\/p>\n<p>\nThis high degree of co&ouml;rdination became untenable,\nespecially since it required the Windows team to do things like\npush a new version of <code>MSVCRT.DLL<\/code> to all downlevel\nplatforms whenever a new version of Visual C\/C++ came out.\n(Good luck doing this in the days before Windows Update!)\n<\/p>\n<p>\nAnd sometimes these fixes caused compatibility problems.\nFor example, I remember there was a fix for a Y2K problem\nwhich\n<a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2011\/10\/06\/10220920.aspx#10222088\">\ncaused one application to crash<\/a>\nbecause the fix\naltered the stack usage in such a way that exposed an\nuninitialized variable bug.\n<\/p>\n<p>\nOne serious problem with the <code>MVSCRT.DLL<\/code>\n&#8220;one runtime to rule them all&#8221; model is that\nmultiple versions of Visual C++ would all use the same library,\nand keeping one DLL compatible with all versions of Visual C++\nwas a maintenance nightmare.\nFor example, if a new C++ language feature required a change\nto the <code>ostream<\/code> class,\nyou had to be careful to design your change so that the\nclass was still binary-compatible with the older version\nof the class.\nThis meant not changing the size of the class (because somebody\nmay have derived from it)\nand not changing the offsets of any members,\nand being careful which virtual methods you call.\nThis was in practice not done, and the result was that (for example)\nWindows&nbsp;95 and Windows&nbsp;98 both had DLLs called\n<code>MSVCRT.DLL<\/code> that were not compatible with each other.\n<\/p>\n<p>\nAnd of course there was the problem of some application installer\nunwittingly overwriting the existing copy of\n<code>MSVCRT.DLL<\/code> with an older one,\ncausing <i>the entire operating system<\/i> to stop working.\n<\/p>\n<p>\nAt some point, the decision was made to just give up\nand declare it an operating system DLL,\nto be used only by operating system components.\nAll newer versions of Visual C\/C++ used specifically-numbered\nDLLs for their runtime libraries.\n(Giving different names to each version of the run-time library\nsolves the problem of trying to make one DLL service multiple\nversions of clients,\nas well as addressing the <i>accidental downgrade<\/i> problem.)\n<\/p>\n<p>\nAlthough <code>MSVCRT.DLL<\/code> has been an operating system DLL\nfor a long time,\n<a HREF=\"http:\/\/msdn.microsoft.com\/en-us\/library\/abx4dbyh%28VS.80%29.aspx#sectiontoggle2\">\nand has been documented as off-limits to applications<\/a>,\nthere are still\n<a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2011\/08\/03\/10192225.aspx#10192991\">\na lot of people<\/a>\nwho\n<a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2010\/06\/07\/10020654.aspx#10020962\">\ntreat it as a C runtime delivery channel<\/a>,\nand those programs create a lot of grief for the product team.\n<\/p>\n<p>\nI remember one change that the runtime library folks made to\n<code>MSVCRT.DLL<\/code> that had to be backed out and revisited\nbecause they found an application that not only linked to\n<code>MSVCRT.DLL<\/code> instead of the runtime library the\ncompiler intended,\nbut also groveled into an internal array and manipulated\nprivate members.\n(I was one of the people who investigated this compatibility\nissue, but I was not the one who solved it.)\n<\/p>\n<pre>\n\/\/ Note: The issue has been simplified for expository purposes\nstruct SomethingInternal\n{\n    int widget;\n    short widgetFlags;\n    char widgetLevel;\n    int needs_more_time;\n};\nSomethingInternal InternalArray[80];\n<\/pre>\n<p>\nThe runtime library folks added a new member to the structure:\n<\/p>\n<pre>\nstruct SomethingInternal\n{\n    int widget;\n    short widgetFlags;\n    char widgetLevel;\n    int needs_more_time;\n    <font COLOR=\"blue\">int needs_<a STYLE=\"color: blue\" HREF=\"http:\/\/www.nbc.com\/saturday-night-live\/video\/more-cowbell-with-will-ferrell-on-snl--video--saturday-night-live--nbc\/n41046\">more_cowbell<\/a>;<\/font>\n};\n<\/pre>\n<p>\nThis change increased the size of the\n<code>Something&shy;Internal<\/code> structure,\nwhich in turn meant that when the application did\n<\/p>\n<pre>\n\/\/ Redeclare this internal structure in MSVCRT.DLL\n\/\/ so we can poke the needs_more_time member to get more time.\nstruct SomethingInternal\n{\n    int widget;\n    short widgetFlags;\n    char widgetLevel;\n    int needs_more_time;\n};\nextern SomethingInternal InternalArray[80];\n...\n    InternalArray[i].needs_more_time = 1;\n...\n<\/pre>\n<p>\nit ended up poking the wrong byte because the structure\nsize didn&#8217;t match.\n<\/p>\n<p>\nThe runtime library folks had to go back and squeeze the cowbell\nflag into the structure in a way that didn&#8217;t alter the size\nof the <code>Something&shy;Internal<\/code> structure.\nI don&#8217;t remember exactly what the fix was,\nbut one way they could&#8217;ve done it was by squeezing the flag\ninto the one byte of padding between\n<code>widgetLevel<\/code> and\n<code>needs_more_time<\/code>.\n<\/p>\n<pre>\nstruct SomethingInternal\n{\n    int widget;\n    short widgetFlags;\n    char widgetLevel;\n    <font COLOR=\"blue\">char needs_more_cowbell;<\/font>\n    int needs_more_time;\n};\n<\/pre>\n<p>\n<b>Bonus chatter<\/b>:\nThe application had an easy time messing with the internal array\nbecause the source code to the C runtime library\nis included with the compiler,\nSo much for &#8220;All these compatibility problems would go away\nif you published the source code.&#8221;\nPublishing the source code makes it <i>easier<\/i> to introduce\ncompatibility problems,\nbecause it lays bare all the internal undocumented behaviors.\nInstead of trying to reverse-engineer the runtime library,\nyou can just sit down and read it,\nand if you want to do something sneaky,\nyou can just\ncopy the\ndeclaration of the internal array\nand\n<a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2014\/02\/11\/10498299.aspx\">\nparty on<\/a>\nthe\n<code>needs_more_time<\/code> member.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>There&#8217;s a DLL in the system directory called MSVCRT.DLL, and from its name, you might think that it is the Microsoft Visual C\/C++ Run-Time library. That is a perfectly reasonable guess. But it would also be wrong. The Microsoft Visual C\/C++ Run-Time libraries go by names like MSVCR71.DLL or MSVCR80.DLL or MSVCR90.DLL or MSVCR100.DLL, and [&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-1273","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>There&#8217;s a DLL in the system directory called MSVCRT.DLL, and from its name, you might think that it is the Microsoft Visual C\/C++ Run-Time library. That is a perfectly reasonable guess. But it would also be wrong. The Microsoft Visual C\/C++ Run-Time libraries go by names like MSVCR71.DLL or MSVCR80.DLL or MSVCR90.DLL or MSVCR100.DLL, and [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/1273","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=1273"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/1273\/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=1273"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=1273"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=1273"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}