<div dir="ltr"><div dir="ltr"><br></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div><div><div>This is incorrect. WriteFile() indicates an error, but GetLastError() returns 0 (= NO_ERROR). Could it be that the debugger calls another Windows API function between those two functions, resetting the last error?</div><div><br></div><div>In my project that's a major issue. Since the software behaves incorrectly with the debugger, the software can no longer be debugged. This doesn't just affect it when debugging this particular piece of code but anytime this code is run in a debugging session.</div></div></div></div></blockquote><div><br></div><div><br></div><div>This would be a blocker for all applications of Windows API functions via panama.</div><div>Windows Sockets has a similar mechanism called WSAGetLastError.</div><div><br></div><div>As far as I know, GetLastError and WSAGetLastError are getter-like functions for effectively thread local data.</div><div>It is safe to call Windows API functions from inside the same process but another thread.</div><div>If some piece of software infrastructure has perturbed your program, then it has called a Windows API function from inside our program</div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div><div>Is there something I'm not doing incorrectly? Or is there a fix or workaround?<br></div><div><br></div><div>Here's the Java code:</div><div><br></div><div><pre style="background-color:rgb(43,43,43);color:rgb(169,183,198);font-family:"JetBrains Mono",monospace;font-size:9.8pt"><span style="color:rgb(204,120,50)">import </span>java.lang.foreign.*<span style="color:rgb(204,120,50)">;<br></span><span style="color:rgb(204,120,50)">import </span>java.lang.invoke.MethodHandle<span style="color:rgb(204,120,50)">;<br></span><span style="color:rgb(204,120,50)"><br></span><span style="color:rgb(204,120,50)">import static </span>java.lang.foreign.MemoryAddress.<span style="color:rgb(152,118,170);font-style:italic">NULL</span><span style="color:rgb(204,120,50)">;<br></span><span style="color:rgb(204,120,50)">import static </span>java.lang.foreign.ValueLayout.<span style="color:rgb(152,118,170);font-style:italic">ADDRESS</span><span style="color:rgb(204,120,50)">;<br></span><span style="color:rgb(204,120,50)">import static </span>java.lang.foreign.ValueLayout.<span style="color:rgb(152,118,170);font-style:italic">JAVA_INT</span><span style="color:rgb(204,120,50)">;<br></span><span style="color:rgb(204,120,50)"><br></span><span style="color:rgb(204,120,50)">public class </span>WinApi {<br>    <span style="color:rgb(204,120,50)">static final </span>MethodHandle <span style="color:rgb(152,118,170);font-style:italic">WriteFile$Func</span><span style="color:rgb(204,120,50)">;<br></span><span style="color:rgb(204,120,50)">    static final </span>MethodHandle <span style="color:rgb(152,118,170);font-style:italic">GetLastError$Func</span><span style="color:rgb(204,120,50)">;<br></span><span style="color:rgb(204,120,50)">    static final </span>MemoryAddress <span style="color:rgb(152,118,170);font-style:italic">INVALID_HANDLE_VALUE </span>= MemoryAddress.<span style="font-style:italic">ofLong</span>(-<span style="color:rgb(104,151,187)">1</span>)<span style="color:rgb(204,120,50)">;<br></span><span style="color:rgb(204,120,50)"><br></span><span style="color:rgb(204,120,50)">    static </span>{<br>        <span style="color:rgb(204,120,50)">var </span>linker = Linker.<span style="font-style:italic">nativeLinker</span>()<span style="color:rgb(204,120,50)">;<br></span><span style="color:rgb(204,120,50)">        var </span>lookup = SymbolLookup.<span style="font-style:italic">libraryLookup</span>(<span style="color:rgb(106,135,89)">"Kernel32"</span><span style="color:rgb(204,120,50)">, </span>MemorySession.<span style="font-style:italic">global</span>())<span style="color:rgb(204,120,50)">;<br></span><span style="color:rgb(204,120,50)"><br></span><span style="color:rgb(204,120,50)">        </span><span style="color:rgb(152,118,170);font-style:italic">WriteFile$Func </span>= linker.downcallHandle(<br>                lookup.lookup(<span style="color:rgb(106,135,89)">"WriteFile"</span>).get()<span style="color:rgb(204,120,50)">,<br></span><span style="color:rgb(204,120,50)">                </span>FunctionDescriptor.<span style="font-style:italic">of</span>(<span style="color:rgb(152,118,170);font-style:italic">JAVA_INT</span><span style="color:rgb(204,120,50)">, </span><span style="color:rgb(152,118,170);font-style:italic">ADDRESS</span><span style="color:rgb(204,120,50)">, </span><span style="color:rgb(152,118,170);font-style:italic">ADDRESS</span><span style="color:rgb(204,120,50)">, </span><span style="color:rgb(152,118,170);font-style:italic">JAVA_INT</span><span style="color:rgb(204,120,50)">, </span><span style="color:rgb(152,118,170);font-style:italic">ADDRESS</span><span style="color:rgb(204,120,50)">, </span><span style="color:rgb(152,118,170);font-style:italic">ADDRESS</span>)<br>        )<span style="color:rgb(204,120,50)">;<br></span><span style="color:rgb(204,120,50)">        </span><span style="color:rgb(152,118,170);font-style:italic">GetLastError$Func </span>= linker.downcallHandle(<br>                lookup.lookup(<span style="color:rgb(106,135,89)">"GetLastError"</span>).get()<span style="color:rgb(204,120,50)">,<br></span><span style="color:rgb(204,120,50)">                </span>FunctionDescriptor.<span style="font-style:italic">of</span>(<span style="color:rgb(152,118,170);font-style:italic">JAVA_INT</span>)<br>        )<span style="color:rgb(204,120,50)">;<br></span><span style="color:rgb(204,120,50)">    </span>}<br><br>    <span style="color:rgb(204,120,50)">public static void </span><span style="color:rgb(255,198,109)">main</span>(String[] args) {<br>        <span style="color:rgb(204,120,50)">var </span>res = <span style="font-style:italic">WriteFile</span>(<span style="color:rgb(152,118,170);font-style:italic">INVALID_HANDLE_VALUE</span><span style="color:rgb(204,120,50)">, </span><span style="color:rgb(152,118,170);font-style:italic">NULL</span><span style="color:rgb(204,120,50)">, </span><span style="color:rgb(104,151,187)">0</span><span style="color:rgb(204,120,50)">, </span><span style="color:rgb(152,118,170);font-style:italic">NULL</span><span style="color:rgb(204,120,50)">, </span><span style="color:rgb(152,118,170);font-style:italic">NULL</span>)<span style="color:rgb(204,120,50)">;<br></span><span style="color:rgb(204,120,50)">        var </span>err = <span style="font-style:italic">GetLastError</span>()<span style="color:rgb(204,120,50)">;<br></span><span style="color:rgb(204,120,50)">        </span>System.<span style="color:rgb(152,118,170);font-style:italic">out</span>.printf(<span style="color:rgb(106,135,89)">"WriteFile result: %d, GetLastError result: %d</span><span style="color:rgb(204,120,50)">\n</span><span style="color:rgb(106,135,89)">"</span><span style="color:rgb(204,120,50)">, </span>res<span style="color:rgb(204,120,50)">, </span>err)<span style="color:rgb(204,120,50)">;<br></span><span style="color:rgb(204,120,50)">    </span>}<br><br>    <span style="color:rgb(204,120,50)">static int </span><span style="color:rgb(255,198,109)">WriteFile</span>(MemoryAddress hFile<span style="color:rgb(204,120,50)">, </span>MemoryAddress lpBuffer<span style="color:rgb(204,120,50)">, int </span>nNumberOfBytesToWrite<span style="color:rgb(204,120,50)">,<br></span><span style="color:rgb(204,120,50)">                         </span>MemoryAddress lpNumberOfBytesWritten<span style="color:rgb(204,120,50)">, </span>MemoryAddress lpOverlapped) {<br>        <span style="color:rgb(204,120,50)">try </span>{<br>            <span style="color:rgb(204,120,50)">return </span>(<span style="color:rgb(204,120,50)">int</span>) <span style="color:rgb(152,118,170);font-style:italic">WriteFile$Func</span>.invokeExact((Addressable)hFile<span style="color:rgb(204,120,50)">, </span>(Addressable)lpBuffer<span style="color:rgb(204,120,50)">, </span>nNumberOfBytesToWrite<span style="color:rgb(204,120,50)">,<br></span><span style="color:rgb(204,120,50)">                    </span>(Addressable)lpNumberOfBytesWritten<span style="color:rgb(204,120,50)">, </span>(Addressable)lpOverlapped)<span style="color:rgb(204,120,50)">;<br></span><span style="color:rgb(204,120,50)">        </span>} <span style="color:rgb(204,120,50)">catch </span>(Throwable e) {<br>            <span style="color:rgb(204,120,50)">throw new </span>RuntimeException(e)<span style="color:rgb(204,120,50)">;<br></span><span style="color:rgb(204,120,50)">        </span>}<br>    }<br><br>    <span style="color:rgb(204,120,50)">static int </span><span style="color:rgb(255,198,109)">GetLastError</span>() {<br>        <span style="color:rgb(204,120,50)">try </span>{<br>            <span style="color:rgb(204,120,50)">return </span>(<span style="color:rgb(204,120,50)">int</span>) <span style="color:rgb(152,118,170);font-style:italic">GetLastError$Func</span>.invokeExact()<span style="color:rgb(204,120,50)">;<br></span><span style="color:rgb(204,120,50)">        </span>} <span style="color:rgb(204,120,50)">catch </span>(Throwable e) {<br>            <span style="color:rgb(204,120,50)">throw new </span>RuntimeException(e)<span style="color:rgb(204,120,50)">;<br></span><span style="color:rgb(204,120,50)">        </span>}<br>    }<br>}</pre></div><div><br></div></div><div>Cheers</div><div>Manuel</div><div><br><br></div></div>
</blockquote></div><br clear="all"><div><br></div>-- <br><div dir="ltr" class="gmail_signature"><div dir="ltr"><div>Pedro Lamarão</div><div><a href="https://www.prodist.com.br" target="_blank">https://www.prodist.com.br</a></div><div>Securing Critical Systems</div><div>Tel: +55 11 4380-6585</div><div><img src="https://ci3.googleusercontent.com/mail-sig/AIorK4wgjsxiTyEHhb40ITzhw-mChttfn1y6GautnhGEr5tVa82AzYOrJJ9lEh-34sfDfoCQkFlQ7oY"><br></div><div><div style="color:rgb(34,34,34)"><p class="MsoNormal" style="margin-bottom:12pt"><span style="font-size:8pt;font-family:Arial,sans-serif;color:rgb(0,51,102)">Antes de imprimir esta mensagem e seus anexos, certifique-se que seja realmente necessário.<br></span><span lang="EN-US" style="font-size:8pt;font-family:Arial,sans-serif;color:rgb(0,51,102)">Proteger o meio ambiente é nosso dever.<br>Before printing this e-mail or attachments, be sure it is necessary.<br>It is in our hands to protect the environment.</span></p></div></div></div></div></div>