1

I am migrating some VB6 code to C# (.NET 4.5.2) and got stuck into a piece of code that is calling the gethostname method from the WSOCK32.DLL to apparently retrieve the computer name. All the code samples that I have found so far point to this code. And since I haven't been able to successfully PInvoke the gethostname method in C#, I can't help asking if is there an alternative to it.

This

[DllImport("WSOCK32.DLL", SetLastError = true)]
internal static extern long gethostname(string name, int nameLen);


string host = string.Empty;
var res = gethostname(host, 256);

fails with the following error:

The runtime has encountered a fatal error. The address of the error was at 0x6a13a84e, on thread 0xd88. The error code is 0xc0000005. This error may be a bug in the CLR or in the unsafe or non-verifiable portions of user code. Common sources of this bug include user marshaling errors for COM-interop or PInvoke, which may corrupt the stack.

I also read about using System.Environment.MachineName or the "COMPUTERNAME" environment variable, but I am interested in how the result differs than what gethostname method returns.

What options do I have?

  • I am developing on a 64bit system but I don't know if/how this affects working with WSOCK32.DLL since I found no documentation about it.
dvlsc
  • 542
  • 6
  • 14
  • 2
    Don't pinvoke this. Use the .net library. – David Heffernan May 19 '16 at 13:58
  • @DavidHeffernan Can you please be a little more specific? I mentioned some other possible options in my initial message but I am not sure whether or not the result is always the same. – dvlsc May 20 '16 at 06:39
  • I expect some research would tell you what you need to know. Websearch took me here http://stackoverflow.com/questions/1768198/how-do-i-get-the-computer-name-in-net – David Heffernan May 20 '16 at 06:47
  • @DavidHeffernan Thank you for the link, but I already knew and wrote about _possible_ solutions. The problem is that, having no documentation on `gethostname`, I have no idea on what's the difference (if any) between pinvoke-ing it and using any other alternative in all possible scenarios. – dvlsc May 20 '16 at 07:56
  • `gethostname` is documented: https://msdn.microsoft.com/en-us/library/windows/desktop/ms738527(v=vs.85).aspx Think about it this way. If you don't know what `gethostname` does, why do you want to use it? – David Heffernan May 20 '16 at 08:07
  • @DavidHeffernan The sole reason for using it was that it was used in the legacy code that I am migrating and I was not sure if I can achieve the same result using .NET. I browsed the web for about two hours before asking here, I don't know how I missed that link. Thank you! – dvlsc May 20 '16 at 08:26
  • It's the top hit when you type the name of the function into a search engine. I cannot imagine what you were searching for! My point really though is that you should be thinking about what you want the new program to do. It's entirely plausible that you might take a different approach now. – David Heffernan May 20 '16 at 08:29
  • I prefixed it: "WSOCK32 gethostname", thought it might narrow down the search results. I understand that, @DavidHeffernan, thank you for your time! – dvlsc May 20 '16 at 08:33
  • That search comes up with the doc as the second hit! Anyway, it's worth remembering that all Win32 API functions are documented. – David Heffernan May 20 '16 at 08:40
  • I think I found my problem :) [print screen here](http://tinypic.com/r/2lnziw9/9) – dvlsc May 20 '16 at 08:51
  • Ah, the wrong search engine! Amazing to me considering that Bing is from MS, that it won't rank MSDN hits highly! Google is better in that regard. – David Heffernan May 20 '16 at 08:54
  • Didn't even realize it. I switched to Windows 10 recently and using Edge now, but I forgot about the search engine. I had this kind of issues with Bing before. – dvlsc May 20 '16 at 09:08

1 Answers1

2

You cannot send an zero-length immutable C# string and expect it to get turned into something new. You are probably experiencing a buffer overflow. You need to use a StringBuilder instead:

[DllImport("WSOCK32.DLL", SetLastError = true)]
internal static extern long gethostname(StringBuilder name, int nameLen);

var builder = new StringBuilder(256);
var res = gethostname(builder, 256);
string host = builder.ToString();

More info here:

Also, there is really no reason for using that really old DLL function to get the name of the local computer. Just use System.Environment.MachineName instead.

Community
  • 1
  • 1
Anders Marzi Tornblad
  • 18,896
  • 9
  • 51
  • 66
  • I've been browsing the web for about two hours, never got into those links. Also first time using PInvoke. Thank you! – dvlsc May 19 '16 at 10:46