getservbyname C# PInvoke

N

NanoWizard

Can anyone verify if this is the correct way to do this? Thanks.

using System;
using System.Threading;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace WSockImport
{
/// <summary>
/// Summary description for WSock.
/// </summary>
public class WSock
{
// Used to shutdown Winsock
private static WSock sm_WSock = new WSock();
private static int sm_ciInitializeCounter = 0;

public WSock()
{
if ( Interlocked.Increment( ref sm_ciInitializeCounter ) == 1 )
{
Initialize();
}
}

~WSock()
{
if ( Interlocked.Decrement( ref sm_ciInitializeCounter ) == 0 )
{
Shutdown();
}
}

private const int WSADESCRIPTION_LEN = 256;

public static void Initialize()
{
WSADATA WSAD = new WSADATA();
ushort wVersion = MAKEWORD(1,1);
int iVal = WSAStartup( wVersion, ref WSAD );
if ( iVal != 0 )
{
Marshal.ThrowExceptionForHR( WSAGetLastError( ) );
}
}

public static void Shutdown()
{
int iVal = WSACleanup();
if ( iVal != 0 )
{
Marshal.ThrowExceptionForHR( WSAGetLastError( ) );
}
}

public static ushort MAKEWORD(byte LoByte,byte HiByte)
{
return (ushort)(LoByte + (HiByte << 8) );
}

public static uint MAKEDWORD(ushort LoWord,ushort HiWord)
{
return (uint)(LoWord + (HiWord << 16));
}

[StructLayoutAttribute(LayoutKind.Sequential)]
public struct servent
{
public string s_name;
public IntPtr s_aliases;
public short s_port;
public string s_proto;
}

public static servent GetServByName( string strName, string strProto
)
{
IntPtr ptr = getservbyname( strName, strProto );
if ( ptr != IntPtr.Zero )
{
servent s = (servent)Marshal.PtrToStructure( ptr, typeof(servent)
);
string strAliases = Marshal.PtrToStringAnsi( s.s_aliases );
return s;
}
int iLastError = WSAGetLastError( );
Marshal.ThrowExceptionForHR( iLastError );
throw new ApplicationException( "Unable to retrieve Servent
structure." );
}

[DllImport("Ws2_32.dll", EntryPoint="getservbyname",
SetLastError=true,
CharSet=CharSet.Ansi, ExactSpelling=true,
CallingConvention=CallingConvention.StdCall)]
public static extern IntPtr getservbyname( string strName, string
strProto );

[DllImport("Ws2_32.dll", EntryPoint="WSAGetLastError",
SetLastError=true,
CharSet=CharSet.Ansi, ExactSpelling=true,
CallingConvention=CallingConvention.StdCall)]
public static extern int WSAGetLastError( );

[StructLayoutAttribute(LayoutKind.Sequential)]
public struct WSADATA
{
public short wVersion;
public short wHighVersion;
[MarshalAs(UnmanagedType.ByValTStr,SizeConst=WSADESCRIPTION_LEN +
1)]
public string szDescription ;
[MarshalAs(UnmanagedType.ByValTStr,SizeConst=WSADESCRIPTION_LEN +
1)]
public string szSystemStatus ;
public int wMaxSockets;
public int wMAXUDPDG;
public IntPtr dwVendorInfo;
}

[DllImport("wsock32.dll")]
public static extern int WSAStartup( ushort wVersionRequired, ref
WSADATA lpWSDATA);

[DllImport("wsock32.dll")]
public static extern int WSACleanup( );
}
}
 
J

Joerg Jooss

NanoWizard wrote:

[snip]

Out of curiosity: Is this an exercise in P/Invoke programming, or why
don't you use System.Net.Dns?

Cheers,
 
N

NanoWizard

Can you retrieve the corresponding port using only a service name using
System.Net.Dns? I didn't see it in there. Seems like that class is
only used for domain name retrieval.
 
J

Joerg Jooss

NanoWizard said:
Can you retrieve the corresponding port using only a service name
using System.Net.Dns? I didn't see it in there. Seems like that
class is only used for domain name retrieval.

My error -- I somehow figured that getservbyname is a DNS API :-S

Cheers,
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top