Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people, just like you, are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
Solved

C# problem using the GetVersionExA API.

Posted on 2004-09-28
14
1,067 Views
Last Modified: 2008-01-09
Hi.
I'm trying to determine if the operating system is a domain controller using the GetVersionExA function and OSVERSIONINFOEX struct
I tried the exact same code in VB.NET and it worked just fine, but it doesn't in C#.
Any ideas?

Here is the code I have:
[StructLayout(LayoutKind.Sequential)]
public struct OSVERSIONINFOEX
{
      [MarshalAs(UnmanagedType.U4)]
      public int dwOSVersionInfoSize;
      [MarshalAs(UnmanagedType.U4)]
      public int dwMajorVersion;
      [MarshalAs(UnmanagedType.U4)]
      public int dwMinorVersion;
      [MarshalAs(UnmanagedType.U4)]
      public int dwBuildNumber;
      [MarshalAs(UnmanagedType.U4)]
      public int dwPlatformId;
      [MarshalAs(UnmanagedType.LPTStr, SizeConst=128)]
      public string szCSDVersion;
      [MarshalAs(UnmanagedType.U2)]
      public short wServicePackMajor;
      [MarshalAs(UnmanagedType.U2)]
      public short wServicePackMinor;
      [MarshalAs(UnmanagedType.U2)]
      public short wSuiteMask;
      public byte wProductType;
      public byte wReserved;
}

[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool GetVersionExA([MarshalAs(UnmanagedType.Struct)] ref OSVERSIONINFOEX lpVersionInfo);

public bool IsDomainController()
{
bool isDC = false;
OSVERSIONINFOEX os = new OSVERSIONINFOEX();
os.dwOSVersionInfoSize = Marshal.SizeOf(os);
if (GetVersionExA(ref os))
{
      isDC = (os.wProductType == 2);
}
else
{
      Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
}

return isDC;
}

Any help would be greatly appreciated!
0
Comment
Question by:Balder1978
  • 7
  • 7
14 Comments
 
LVL 96

Expert Comment

by:Bob Learned
ID: 12173937
Try something like this instead:

string osVersion = Environment.OSVersion.Platform.ToString();

Bob
0
 
LVL 2

Author Comment

by:Balder1978
ID: 12180802
I don't need the OS version, I need to know if it's a Domain Controller or not.
But thanks for the input!
0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 12181098
Do you still have the VB.NET code?

Bob
0
Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

 
LVL 2

Author Comment

by:Balder1978
ID: 12181126
sure:

<StructLayout(LayoutKind.Sequential)> _
Public Structure OSVERSIONINFOEX
        <MarshalAs(UnmanagedType.U4)> _
        Public dwOSVersionInfoSize As Integer
        <MarshalAs(UnmanagedType.U4)> _
        Public dwMajorVersion As Integer
        <MarshalAs(UnmanagedType.U4)> _
        Public dwMinorVersion As Integer
        <MarshalAs(UnmanagedType.U4)> _
        Public dwBuildNumber As Integer
        <MarshalAs(UnmanagedType.U4)> _
        Public dwPlatformId As Integer
        <MarshalAs(UnmanagedType.ByValArray, SizeConst:=128)> _
        Public szCSDVersion() As Char
        <MarshalAs(UnmanagedType.U2)> _
        Public wServicePackMajor As Short
        <MarshalAs(UnmanagedType.U2)> _
        Public wServicePackMinor As Short
        <MarshalAs(UnmanagedType.U2)> _
        Public wSuiteMask As Short
        Public wProductType As Byte
        Public wReserved As Byte
End Structure

Private Declare Function GetVersionEx Lib "kernel32.dll" Alias "GetVersionExA" (<MarshalAs(UnmanagedType.Struct)> ByRef ByReflpVersionInfo As OSVERSIONINFOEX) As Boolean

Usage:
Dim os As OSVERSIONINFOEX = New OSVERSIONINFOEX
os.dwOSVersionInfoSize = Marshal.SizeOf(os)
GetVersionEx(os)
0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 12181180
In VB.NET, the os.dwOSVersionInfoSize = 156, and in C#, it is 32.  Investigating...

Bob
0
 
LVL 2

Author Comment

by:Balder1978
ID: 12181203
Exactly, and if I set it manually to 156 (which is too dirty programming), I get the OS version numbers, but not the wProductType wich is what I'm looking for.
Thanks!
0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 12181246
The OSVERSIONINFOEX.szCSDVersion appears to be the problem.

In the VB.NET IL code:

szCSDVersion public marshal (fixed array[128]) char[]

In the C# IL code:

szCSDVersion public marshal (lptstr) string

There is clearly a size difference here.

Bob
0
 
LVL 96

Accepted Solution

by:
Bob Learned earned 125 total points
ID: 12181278
Change to this:

      [MarshalAs(UnmanagedType.ByValArray , SizeConst=128)]
      public char[] szCSDVersion;

Bob
0
 
LVL 2

Author Comment

by:Balder1978
ID: 12181308
that didn't work, but this did:

[MarshalAs(UnmanagedType.ByValTStr, SizeConst=128)]
public string szCSDVersion;

The size is now 156, but it still doesn't work...
0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 12181348
It worked for me--return a false.  What .NET version do you have?  I have 2003.

Bob
0
 
LVL 2

Author Comment

by:Balder1978
ID: 12181920
I have 2003 with .NET 1.1 SP1 too... Strange...
0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 12181938
What happened when you used this?

[MarshalAs(UnmanagedType.ByValArray , SizeConst=128)]
      public char[] szCSDVersion;


Bob
0
 
LVL 2

Author Comment

by:Balder1978
ID: 12181952
So sorry, didn't change public char[] szCSDVersion;
I'll test it and get back to u ASAP.
0
 
LVL 2

Author Comment

by:Balder1978
ID: 12182176
Thanks alot, man. Works great!
0

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article introduced a TextBox that supports transparent background.   Introduction TextBox is the most widely used control component in GUI design. Most GUI controls do not support transparent background and more or less do not have the…
This article aims to explain the working of CircularLogArchiver. This tool was designed to solve the buildup of log file in cases where systems do not support circular logging or where circular logging is not enabled
Microsoft Active Directory, the widely used IT infrastructure, is known for its high risk of credential theft. The best way to test your Active Directory’s vulnerabilities to pass-the-ticket, pass-the-hash, privilege escalation, and malware attacks …
This video shows how to quickly and easily add an email signature for all users on Exchange 2016. The resulting signature is applied on a server level by Exchange Online. The email signature template has been downloaded from: www.mail-signatures…

839 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question