{"id":91771,"date":"2015-08-20T07:00:00","date_gmt":"2015-08-20T21:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/20150820-00\/?p=91771\/"},"modified":"2019-03-13T12:18:41","modified_gmt":"2019-03-13T19:18:41","slug":"20150820-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20150820-00\/?p=91771","title":{"rendered":"I saw a pinvoke signature that passed a UInt64 instead of a FILETIME, what&#8217;s up with that?"},"content":{"rendered":"<p>A customer had a question about a pinvoke signature that used a <code>UInt64<\/code> to hold a <code>FILETIME<\/code> structure. <!--more--><\/p>\n<blockquote CLASS=\"q\">\n<pre>\n[DllImport(\"kernel32.dll\", SetLastError = true)\nstatic external bool GetProcessTimes(\n    IntPtr hProcess,\n    out UInt64 creationTime,\n    out UInt64 exitTime,\n    out UInt64 kernelTime,\n    out UInt64 userTime);\n<\/pre>\n<p>Is this legal? <a HREF=\"http:\/\/msdn.microsoft.com\/library\/windows\/desktop\/ms724284\">The documentation for <code>FILETIME<\/code><\/a> says <\/p>\n<blockquote CLASS=\"q\"><p>Do not cast a pointer to a <b>FILETIME<\/b> structure to either a <b>ULARGE_INTEGER*<\/b> or <b>__int64*<\/b> value because it can cause alignment faults on 64-bit Windows. <\/p><\/blockquote>\n<p>Are we guilty of this cast in the above code? After all <a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2004\/08\/25\/220195.aspx\">you can&#8217;t treat a <code>FILETIME<\/code> as an <code>__int64<\/code><\/a>. <\/p>\n<\/blockquote>\n<p>There are two types of casts possible in this scenario. <\/p>\n<ul>\n<li>Casting from <code>FILETIME*<\/code> to     <code>__int64*<\/code>. \n<li>Casting from     <code>__int64*<\/code> to     <code>FILETIME*<\/code>. <\/ul>\n<p>The <code>FILETIME<\/code> structure requires 4-byte alignment, and the <code>__int64<\/code> data type requires 8-byte alignment. Therefore the first cast is unsafe, because you are casting from a pointer with lax alignment requirements to one with stricter requirements. The second cast is safe because you are casting from a pointer with strict alignment requirements to one with laxer requirements. <\/p>\n<table BORDER=\"0\" BGCOLOR=\"pink\" STYLE=\"border: solid 1px black;width: 10em;height: 10em\">\n<tr>\n<td WIDTH=\"50%\" VALIGN=\"top\">4-byte aligned<\/td>\n<td WIDTH=\"50%\" VALIGN=\"top\" STYLE=\"border: solid 1px black;background-color: lightblue\">8-byte aligned<\/td>\n<\/tr>\n<\/table>\n<p>Everything in the blue box is also in the pink box, but not vice versa. <\/p>\n<p>Which cast is the one occurring in the above pinvoke signature? <\/p>\n<p>In the above signature, the <code>UInt64<\/code> is being allocated by the interop code, and therefore it is naturally aligned for <code>UInt64<\/code>, which means that it is 8-byte aligned. The <code>Get&shy;Process&shy;Times<\/code> function then treats those eight bytes as a <code>FILETIME<\/code>. So we are in the second case, where we cast from <code>__int64*<\/code> to <code>FILETIME*<\/code>. <\/p>\n<p>Mind you, you can avoid all this worrying by simply declaring your pinvoke more accurately. The correct solution is to declare the last four parameters as <code>ComTypes.FILETIME<\/code>. Now there are no sneaky games. Everything is exactly what it says it is. <\/p>\n<p><b>Bonus reading<\/b>: The article <a HREF=\"https:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/2013\/12\/30\/use-powershell-to-access-registry-last-modified-time-stamp.aspx\">Use PowerShell to access registry last-modified time stamp<\/a> shows how to use the <code>ComTypes.FILETIME<\/code> technique from PowerShell. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>Stricter than necessary, but that&#8217;s okay.<\/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-91771","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Stricter than necessary, but that&#8217;s okay.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/91771","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=91771"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/91771\/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=91771"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=91771"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=91771"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}