Thursday, June 11, 2009

GetDeviceVersion() in RAPI fix

I have got a desktop application that determines the operating system's version of the device (I have used a Windows Mobile 5.0 device) connected to PC via ActiveSync. When calling the method GetDeviceVersion() exposed in the RAPI class in the OpenNETCF.Desktop.Communication library, the application crashes with the following exceptions:

When running the solution in Debug configuration:
System.NullReferenceException was unhandled
Message="Object reference not set to an instance of an object."


When running the solution in Release configuration:
System.AccessViolationException was unhandled
Message="Attempted to read or write protected memory. This is often an indication that other memory is corrupt."


When running the exe application:
Unhandled exception at 0x00000000 in XXXApplicationNameXXX.exe: 0xC0000005: Access violation reading location 0x00000000.

The solution to any of these issues is to PInvoke the method CeGetVersionEx() rather than the one provided in the RAPI class.

//PInvoke Declarations

[StructLayout(LayoutKind.Sequential,

    CharSet = CharSet.Unicode)]

public struct CEOSVERSIONINFO

{

    internal int dwOSVersionInfoSize;

    public int dwMajorVersion;

    public int dwMinorVersion;

    public int dwBuildNumber;

    public PlatformType dwPlatformId;

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]

    public string szCSDVersion;

}

 

[DllImport("rapi.dll",

    CharSet = CharSet.Unicode,

    SetLastError = true)]

internal static extern int

    CeGetVersionEx(ref CEOSVERSIONINFO lpVersionInformation);



//PInvoke Call

CEOSVERSIONINFO osVersionInfo = new CEOSVERSIONINFO();

CeGetVersionEx(ref osVersionInfo);



Source: opennetcf