{"id":2263,"date":"2013-12-26T07:00:00","date_gmt":"2013-12-26T07:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2013\/12\/26\/why-is-getwindowlongptr-returning-a-garbage-value-on-64-bit-windows\/"},"modified":"2013-12-26T07:00:00","modified_gmt":"2013-12-26T07:00:00","slug":"why-is-getwindowlongptr-returning-a-garbage-value-on-64-bit-windows","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20131226-00\/?p=2263","title":{"rendered":"Why is GetWindowLongPtr returning a garbage value on 64-bit Windows?"},"content":{"rendered":"<p>\nA customer was running into problems with their application\non 64-bit Windows&nbsp;8.\nThey claimed that on Windows&nbsp;8, the\n<code>Get&shy;Window&shy;Long&shy;Ptr<\/code>\nis returning a garbage pointer,\nwhich causes their program to crash.\nThe same program works fine on 64-bit Windows&nbsp;7.\nThey asked the Windows team why they broke\n<code>Get&shy;Window&shy;Long&shy;Ptr<\/code>.\n<\/p>\n<p>\nAn investigation of the customer&#8217;s code quickly turned up the issue:\n<\/p>\n<pre>\nINT_PTR CALLBACK AwesomeDialogProc(\n    HWND hdlg, UINT uMsg, WPARAM wParam, LPARAM lParam)\n{\n  Awesome *pThis = (Awesome*)GetWindowLongPtr(hdlg, DWLP_USER);\n  switch (uMsg) {\n  case WM_INITDIALOG:\n    pThis = (Awesome*)lParam;\n    SetWindowLongPtr(hdlg, DWLP_USER, (LONG)pThis);\n    ...\n    return TRUE;\n   case WM_COMMAND:\n     if (pThis != nullptr) {\n       \/\/ This line crashes with pThis = garbage nonzero value\n       return pThis-&gt;OnCommand(wParam, lParam);\n     }\n     return FALSE;\n   ...\n  }\n  return FALSE;\n}\n<\/pre>\n<p>\nSee if you can spot the problem.\n<\/p>\n<p>\nThe error is in the line that calls\n<code>Set&shy;Window&shy;Long&shy;Ptr<\/code>.\nIt takes the 64-bit pointer value <code>pThis<\/code>\nand casts it to a <code>LONG<\/code>,\n<a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2005\/01\/31\/363790.aspx\">\nwhich is a 32-bit integer type<\/a>.\nThis truncates the pointer and throws away the upper 32 bits of data.\nTherefore, when read back, the pointer looks like garbage\nbecause the top 32 bits were set to zero (or to <code>0xFFFFFFFF<\/code>,\ndepending on the value of bit 31).\n<\/p>\n<p>\nWindows&nbsp;8 made some improvements to the memory manager,\nand a side effect was a seemingly harmless change\nto the way memory is allocated in 64-bit processes.\nAs a result of the change, pointer values greater than\n4<a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2009\/06\/11\/9725386.aspx\">GB<\/a>\nare much more common, which means that the pointer truncation\nwill actually destroy data.\n(In Windows&nbsp;7, the default heap tended to hang out below the 2GB\nboundary, so the code merely truncated zeros, which is\n<a HREF=\"http:\/\/www.amazon.com\/dp\/0345418778?tag=tholneth=20\">\nmostly harmless<\/a>.)\n<\/p>\n<p>\nWhat I found particularly interesting about this error is that\nthe <code>DWL_USER<\/code> window long was specifically\nrenamed to <code>DWLP_USER<\/code> in 64-bit Windows in order to force\na build break.\nTherefore, developers had to go in and convert each separate use of\n<code>[GS]et&shy;Window&shy;Long<\/code> with\n<code>DWL_USER<\/code>\nto a version that used\n<code>[GS]et&shy;Window&shy;Long&shy;Ptr<\/code> with\n<code>DWLP_USER<\/code>,\nbeing careful not to truncate the pointer.\n<\/p>\n<p>\nThis customer missed that last little bit about not truncating the pointer,\nand all they did was a global search\/replace:\n<\/p>\n<pre>\ns\/\\bGetWindowLong\\b\/GetWindowLongPtr\/g;\ns\/\\bSetWindowLong\\b\/SetWindowLongPtr\/g;\ns\/\\bDWL_USER\\b\/DWLP_USER\/g;\n<\/pre>\n<p>\n&#8220;<a HREF=\"http:\/\/failblog.cheezburger.com\/thereifixedit\">There,\nI fixed it<\/a>.&#8221;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A customer was running into problems with their application on 64-bit Windows&nbsp;8. They claimed that on Windows&nbsp;8, the Get&shy;Window&shy;Long&shy;Ptr is returning a garbage pointer, which causes their program to crash. The same program works fine on 64-bit Windows&nbsp;7. They asked the Windows team why they broke Get&shy;Window&shy;Long&shy;Ptr. An investigation of the customer&#8217;s code quickly turned [&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-2263","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>A customer was running into problems with their application on 64-bit Windows&nbsp;8. They claimed that on Windows&nbsp;8, the Get&shy;Window&shy;Long&shy;Ptr is returning a garbage pointer, which causes their program to crash. The same program works fine on 64-bit Windows&nbsp;7. They asked the Windows team why they broke Get&shy;Window&shy;Long&shy;Ptr. An investigation of the customer&#8217;s code quickly turned [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/2263","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=2263"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/2263\/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=2263"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=2263"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=2263"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}