{"id":24353,"date":"2007-11-28T10:00:00","date_gmt":"2007-11-28T10:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2007\/11\/28\/the-importance-of-the-format_message_ignore_inserts-flag\/"},"modified":"2007-11-28T10:00:00","modified_gmt":"2007-11-28T10:00:00","slug":"the-importance-of-the-format_message_ignore_inserts-flag","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20071128-00\/?p=24353","title":{"rendered":"The importance of the FORMAT_MESSAGE_IGNORE_INSERTS flag"},"content":{"rendered":"<p>\nYou can use the <code>FormatMessage<\/code> message with the\n<code>FORMAT_MESSAGE_FROM_SYSTEM<\/code> flag to indicate that\nthe message number you passed is an error code and that the\nmessage should be looked up in the system message table.\nThis is a specific case of the more general case where\nyou are not in control of the message,\nand when you are not in control of the message,\nyou had better pass the\n<code>FORMAT_MESSAGE_IGNORE_INSERTS<\/code> flag.\n<\/p>\n<p>\nLet&#8217;s look at what happens when you don&#8217;t.\n<\/p>\n<pre>\n#include &lt;windows.h&gt;\n#include &lt;stdio.h&gt;\n#include &lt;tchar.h&gt;\nint __cdecl main(int argc, char **argv)\n{\n TCHAR buffer[1024];\n DWORD dwError = ERROR_BAD_EXE_FORMAT;\n DWORD dwFlags = FORMAT_MESSAGE_FROM_SYSTEM;\n DWORD dwResult = FormatMessage(dwFlags, NULL, dwError,\n                                0, buffer, 1024, NULL);\n if (dwResult) {\n  _tprintf(_T(\"Message is \\\"%s\\\"\\n\"), buffer);\n } else {\n  _tprintf(_T(\"Failed! Error code %d\\n\"), GetLastError());\n }\n return 0;\n}\n<\/pre>\n<p>\nIf you run this program, you&#8217;ll get\n<\/p>\n<pre>\nFailed! Error code 87\n<\/pre>\n<p>\nError 87 is <code>ERROR_INVALID_PARAMETER<\/code>.\nWhat went wrong?\nLet&#8217;s pass the\n<code>FORMAT_MESSAGE_IGNORE_INSERTS<\/code> flag to see what the\nmessage was.\nChange the value of <code>dwFlags<\/code> to\n<\/p>\n<pre>\n DWORD dwFlags = FORMAT_MESSAGE_FROM_SYSTEM |\n                 FORMAT_MESSAGE_IGNORE_INSERTS;\n<\/pre>\n<p>\nand run the program again. This time you get\n<\/p>\n<pre>\nMessage is \"%1 is not a valid Win32 application.\n\"\n<\/pre>\n<p>\nAha, now we see the problem.\nThe message corresponding to <code>ERROR_BAD_EXE_FORMAT<\/code>\ncontains an insertion <code>%1<\/code>.\nIf you don&#8217;t pass the <code>FORMAT_MESSAGE_IGNORE_INSERTS<\/code>\nflag, the <code>FormatMessage<\/code> function will insert\nthe first parameter in the argument list (or argument array).\nBut we didn&#8217;t pass an argument list, so the function fails.\n<\/p>\n<p>\nActually, we got lucky.\nIf we had passed an argument list or argument array,\nthe function would have inserted the corresponding string,\neven if the argument list we passed didn&#8217;t have a string in\nthe first position.\n<\/p>\n<p>\nIf you are not in control of the format string,\nthen you must pass <code>FORMAT_MESSAGE_IGNORE_INSERTS<\/code> to\nprevent the <code>%1<\/code> from causing trouble.\nIf somebody was being particularly evil,\nthey might decide to give you a format string that contains a\n<code>%9<\/code>,\nwhich is almost certainly more insertions than you provided.\nThe result is a buffer overflow and probably a crash.\n<\/p>\n<p>\nThis may have been obvious to some people,\nin the same way that you shouldn&#8217;t pass a string outside your\ncontrol as the format string to the <code>printf<\/code> function,\nbut I felt it worth mentioning.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>You can use the FormatMessage message with the FORMAT_MESSAGE_FROM_SYSTEM flag to indicate that the message number you passed is an error code and that the message should be looked up in the system message table. This is a specific case of the more general case where you are not in control of the message, 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-24353","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>You can use the FormatMessage message with the FORMAT_MESSAGE_FROM_SYSTEM flag to indicate that the message number you passed is an error code and that the message should be looked up in the system message table. This is a specific case of the more general case where you are not in control of the message, and [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/24353","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=24353"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/24353\/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=24353"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=24353"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=24353"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}