From: allen on
Hi,
On both a pocket pc and a smart phone, I am trying to retrieve the devices
manufacture, model, revision, serial number, and subscriber id using
lineGetGeneralInfo.

The issue I am having is that lineGetGeneralInfo always returns a
-2147483595 (LINEERR_INVALPOINTER).

Below is the code and P/Invoke declarations that i am using:

~~~ CODE BEGIN ~~~
// lineInitializeEx
int result = NativeTapi.lineInitializeEx(out hLine, IntPtr.Zero,
IntPtr.Zero, null,
out dwNumDev, ref num1, ref lineInitializeParams);

if (result != 0) {
MessageBox.Show(string.Format("lineInitializeEx failed!\n\nError Code:
{0}", result.ToString()));
return;
}

// lineNegotiateAPIVerison
int version;
int dwAPIVersionLow = 0x10004;
int dwAPIVersionHigh = 0x20000;
LINEEXTENSIONID lineExtensionID;
result = NativeTapi.lineNegotiateAPIVersion(hLine, 0, dwAPIVersionLow,
dwAPIVersionHigh, out version, out lineExtensionID);

if (result != 0) {
MessageBox.Show(string.Format("lineNegotiateAPIVersion failed!\n\nError
Code: {0}", result.ToString()));
return;
}

// lineOpen
IntPtr hLine2;
result = NativeTapi.lineOpen(hLine, 0, out hLine2, version, 0, IntPtr.Zero,
0x00000002, 0x00000004, IntPtr.Zero);

if (result != 0) {
MessageBox.Show(string.Format("lineNegotiateAPIVersion failed!\n\nError
Code: {0}", result.ToString()));
return;
}

// lineGetGeneralInfo
byte[] bytes = new byte[512];

result = NativeTapi.lineGetGeneralInfo(hLine2, bytes);

// process
string manufacture;
string model;
string revision;
string serialNumber;
string subscriberID;

int size;
int offset;

// manufacture
size = BitConverter.ToInt32(bytes, 12);
offset = BitConverter.ToInt32(bytes, 16);
manufacture = Encoding.Unicode.GetString(bytes, offset, size);

// model
size = BitConverter.ToInt32(bytes, 20);
offset = BitConverter.ToInt32(bytes, 24);
model = Encoding.Unicode.GetString(bytes, offset, size);

// revision
size = BitConverter.ToInt32(bytes, 28);
offset = BitConverter.ToInt32(bytes, 32);
revision = Encoding.Unicode.GetString(bytes, offset, size);

// serial number
size = BitConverter.ToInt32(bytes, 36);
offset = BitConverter.ToInt32(bytes, 40);
serialNumber = Encoding.Unicode.GetString(bytes, offset, size);

// subscriber id
size = BitConverter.ToInt32(bytes, 44);
offset = BitConverter.ToInt32(bytes, 48);
subscriberID = Encoding.Unicode.GetString(bytes, offset, size);

// do something with the data

// lineClose for hLine2
NativeTapi.lineClose(hLine2);

// lineShutdown for hLine
NativeTapi.lineShutdown(hLine);

~~~ CODE END ~~~

~~~ P/Invoke BEGIN ~~~
[StructLayout(LayoutKind.Sequential)]
public struct LINEEXTENSIONID {
public IntPtr dwExtensionID0;
public IntPtr dwExtensionID1;
public IntPtr dwExtensionID2;
public IntPtr dwExtensionID3;
}

[StructLayout(LayoutKind.Sequential)]
public struct LINEINITIALIZEEXPARAMS {
public uint dwTotalSize;
public uint dwNeededSize;
public uint dwUsedSize;
public uint dwOptions;
public System.IntPtr hEvent;
public System.IntPtr hCompletionPort;
public uint dwCompletionKey;
}

internal class NativeTapi {
[DllImport("coredll")]
public static extern int lineInitializeEx(out IntPtr lpm_hLineApp, IntPtr
hInstance, IntPtr lpfnCallback, string lpszFriendlyAppName, out int
lpdwNumDevs,
ref int lpdwAPIVersion, ref LINEINITIALIZEEXPARAMS
lpLineInitializeExParams);

[DllImport("coredll")]
public static extern int lineOpen(IntPtr m_hLineApp, int dwDeviceID, out
IntPtr lphLine, int dwAPIVersion, int dwExtVersion, IntPtr
dwCallbackInstance,
int dwPrivileges, int dwMediaModes, IntPtr lpCallParams);

[DllImport("coredll")]
public static extern int lineNegotiateAPIVersion(IntPtr m_hLineApp, int
dwDeviceID, int dwAPILowVersion, int dwAPIHighVersion, out int
lpdwAPIVersion,
out LINEEXTENSIONID lpExtensionID);

[DllImport("cellcore")]
public static extern int lineGetGeneralInfo(IntPtr hLine, byte[] bytes);

[DllImport("coredll")]
public static extern int lineClose(IntPtr hLine);

[DllImport("coredll")]
public static extern int lineShutdown(IntPtr m_hLineApp);
}
~~~ P/Invoke END ~~~

thanks in advance for your help,
allen
From: Alex Feinman [MVP] on
Welll, for starters you are not populating the dwTotalSize field of the byte
array that you pass in lieu of LINEGENERALINFO pointer
Where exactly you get the invalid pointer error?

"allen" <allen(a)discussions.microsoft.com> wrote in message
news:68D1F07B-ECB0-4A15-AFCA-2A911FC3234C(a)microsoft.com...
> Hi,
> On both a pocket pc and a smart phone, I am trying to retrieve the devices
> manufacture, model, revision, serial number, and subscriber id using
> lineGetGeneralInfo.
>
> The issue I am having is that lineGetGeneralInfo always returns a
> -2147483595 (LINEERR_INVALPOINTER).
>
> Below is the code and P/Invoke declarations that i am using:
>
> ~~~ CODE BEGIN ~~~
> // lineInitializeEx
> int result = NativeTapi.lineInitializeEx(out hLine, IntPtr.Zero,
> IntPtr.Zero, null,
> out dwNumDev, ref num1, ref lineInitializeParams);
>
> if (result != 0) {
> MessageBox.Show(string.Format("lineInitializeEx failed!\n\nError Code:
> {0}", result.ToString()));
> return;
> }
>
> // lineNegotiateAPIVerison
> int version;
> int dwAPIVersionLow = 0x10004;
> int dwAPIVersionHigh = 0x20000;
> LINEEXTENSIONID lineExtensionID;
> result = NativeTapi.lineNegotiateAPIVersion(hLine, 0, dwAPIVersionLow,
> dwAPIVersionHigh, out version, out lineExtensionID);
>
> if (result != 0) {
> MessageBox.Show(string.Format("lineNegotiateAPIVersion failed!\n\nError
> Code: {0}", result.ToString()));
> return;
> }
>
> // lineOpen
> IntPtr hLine2;
> result = NativeTapi.lineOpen(hLine, 0, out hLine2, version, 0,
> IntPtr.Zero,
> 0x00000002, 0x00000004, IntPtr.Zero);
>
> if (result != 0) {
> MessageBox.Show(string.Format("lineNegotiateAPIVersion failed!\n\nError
> Code: {0}", result.ToString()));
> return;
> }
>
> // lineGetGeneralInfo
> byte[] bytes = new byte[512];
>
> result = NativeTapi.lineGetGeneralInfo(hLine2, bytes);
>
> // process
> string manufacture;
> string model;
> string revision;
> string serialNumber;
> string subscriberID;
>
> int size;
> int offset;
>
> // manufacture
> size = BitConverter.ToInt32(bytes, 12);
> offset = BitConverter.ToInt32(bytes, 16);
> manufacture = Encoding.Unicode.GetString(bytes, offset, size);
>
> // model
> size = BitConverter.ToInt32(bytes, 20);
> offset = BitConverter.ToInt32(bytes, 24);
> model = Encoding.Unicode.GetString(bytes, offset, size);
>
> // revision
> size = BitConverter.ToInt32(bytes, 28);
> offset = BitConverter.ToInt32(bytes, 32);
> revision = Encoding.Unicode.GetString(bytes, offset, size);
>
> // serial number
> size = BitConverter.ToInt32(bytes, 36);
> offset = BitConverter.ToInt32(bytes, 40);
> serialNumber = Encoding.Unicode.GetString(bytes, offset, size);
>
> // subscriber id
> size = BitConverter.ToInt32(bytes, 44);
> offset = BitConverter.ToInt32(bytes, 48);
> subscriberID = Encoding.Unicode.GetString(bytes, offset, size);
>
> // do something with the data
>
> // lineClose for hLine2
> NativeTapi.lineClose(hLine2);
>
> // lineShutdown for hLine
> NativeTapi.lineShutdown(hLine);
>
> ~~~ CODE END ~~~
>
> ~~~ P/Invoke BEGIN ~~~
> [StructLayout(LayoutKind.Sequential)]
> public struct LINEEXTENSIONID {
> public IntPtr dwExtensionID0;
> public IntPtr dwExtensionID1;
> public IntPtr dwExtensionID2;
> public IntPtr dwExtensionID3;
> }
>
> [StructLayout(LayoutKind.Sequential)]
> public struct LINEINITIALIZEEXPARAMS {
> public uint dwTotalSize;
> public uint dwNeededSize;
> public uint dwUsedSize;
> public uint dwOptions;
> public System.IntPtr hEvent;
> public System.IntPtr hCompletionPort;
> public uint dwCompletionKey;
> }
>
> internal class NativeTapi {
> [DllImport("coredll")]
> public static extern int lineInitializeEx(out IntPtr lpm_hLineApp, IntPtr
> hInstance, IntPtr lpfnCallback, string lpszFriendlyAppName, out int
> lpdwNumDevs,
> ref int lpdwAPIVersion, ref LINEINITIALIZEEXPARAMS
> lpLineInitializeExParams);
>
> [DllImport("coredll")]
> public static extern int lineOpen(IntPtr m_hLineApp, int dwDeviceID, out
> IntPtr lphLine, int dwAPIVersion, int dwExtVersion, IntPtr
> dwCallbackInstance,
> int dwPrivileges, int dwMediaModes, IntPtr lpCallParams);
>
> [DllImport("coredll")]
> public static extern int lineNegotiateAPIVersion(IntPtr m_hLineApp, int
> dwDeviceID, int dwAPILowVersion, int dwAPIHighVersion, out int
> lpdwAPIVersion,
> out LINEEXTENSIONID lpExtensionID);
>
> [DllImport("cellcore")]
> public static extern int lineGetGeneralInfo(IntPtr hLine, byte[] bytes);
>
> [DllImport("coredll")]
> public static extern int lineClose(IntPtr hLine);
>
> [DllImport("coredll")]
> public static extern int lineShutdown(IntPtr m_hLineApp);
> }
> ~~~ P/Invoke END ~~~
>
> thanks in advance for your help,
> allen

From: allen on
invalid pointer (LINEERR_INVALPOINTER - 0x80000035) is happening at the
lineGetGeneralInfo() call.

i have replaced that code with the following using and initializing the
LINEGENERALINFO , but am still getting an invalid pointer.

i have also tried defining this as a struct instead of a class (including
p/invoke signature update), but again i get an invalid pointer.

thanks again for your input,
allen


~~~ CODE BEGIN ~~~

LINEGENERALINFO lgi = new LINEGENERALINFO();
lgi.dwTotalSize = Marshal.SizeOf(lgi);
result = NativeTapi.lineGetGeneralInfo(hLine2, ref lgi);

~~~ CODE END ~~~

~~~ P/Invoke BEGIN ~~~

public class LINEGENERALINFO {
public int dwManufacturerOffset;
public int dwManufacturerSize;
public int dwModelOffset;
public int dwModelSize;
public int dwNeededSize;
public int dwRevisionOffset;
public int dwRevisionSize;
public int dwSerialNumberOffset;
public int dwSerialNumberSize;
public int dwSubscriberNumberOffset;
public int dwSubscriberNumberSize;
public int dwTotalSize;
public int dwUsedSize;
}

[DllImport("cellcore")]
public static extern int lineGetGeneralInfo(IntPtr hLine,
ref LINEGENERALINFO lineGenerlInfo);

~~~ P/Invoke END ~~~

"Alex Feinman [MVP]" wrote:

> Welll, for starters you are not populating the dwTotalSize field of the byte
> array that you pass in lieu of LINEGENERALINFO pointer
> Where exactly you get the invalid pointer error?
>
> "allen" <allen(a)discussions.microsoft.com> wrote in message
> news:68D1F07B-ECB0-4A15-AFCA-2A911FC3234C(a)microsoft.com...
> > Hi,
> > On both a pocket pc and a smart phone, I am trying to retrieve the devices
> > manufacture, model, revision, serial number, and subscriber id using
> > lineGetGeneralInfo.
> >
> > The issue I am having is that lineGetGeneralInfo always returns a
> > -2147483595 (LINEERR_INVALPOINTER).
> >
> > Below is the code and P/Invoke declarations that i am using:
> >
> > ~~~ CODE BEGIN ~~~
> > // lineInitializeEx
> > int result = NativeTapi.lineInitializeEx(out hLine, IntPtr.Zero,
> > IntPtr.Zero, null,
> > out dwNumDev, ref num1, ref lineInitializeParams);
> >
> > if (result != 0) {
> > MessageBox.Show(string.Format("lineInitializeEx failed!\n\nError Code:
> > {0}", result.ToString()));
> > return;
> > }
> >
> > // lineNegotiateAPIVerison
> > int version;
> > int dwAPIVersionLow = 0x10004;
> > int dwAPIVersionHigh = 0x20000;
> > LINEEXTENSIONID lineExtensionID;
> > result = NativeTapi.lineNegotiateAPIVersion(hLine, 0, dwAPIVersionLow,
> > dwAPIVersionHigh, out version, out lineExtensionID);
> >
> > if (result != 0) {
> > MessageBox.Show(string.Format("lineNegotiateAPIVersion failed!\n\nError
> > Code: {0}", result.ToString()));
> > return;
> > }
> >
> > // lineOpen
> > IntPtr hLine2;
> > result = NativeTapi.lineOpen(hLine, 0, out hLine2, version, 0,
> > IntPtr.Zero,
> > 0x00000002, 0x00000004, IntPtr.Zero);
> >
> > if (result != 0) {
> > MessageBox.Show(string.Format("lineNegotiateAPIVersion failed!\n\nError
> > Code: {0}", result.ToString()));
> > return;
> > }
> >
> > // lineGetGeneralInfo
> > byte[] bytes = new byte[512];
> >
> > result = NativeTapi.lineGetGeneralInfo(hLine2, bytes);
> >
> > // process
> > string manufacture;
> > string model;
> > string revision;
> > string serialNumber;
> > string subscriberID;
> >
> > int size;
> > int offset;
> >
> > // manufacture
> > size = BitConverter.ToInt32(bytes, 12);
> > offset = BitConverter.ToInt32(bytes, 16);
> > manufacture = Encoding.Unicode.GetString(bytes, offset, size);
> >
> > // model
> > size = BitConverter.ToInt32(bytes, 20);
> > offset = BitConverter.ToInt32(bytes, 24);
> > model = Encoding.Unicode.GetString(bytes, offset, size);
> >
> > // revision
> > size = BitConverter.ToInt32(bytes, 28);
> > offset = BitConverter.ToInt32(bytes, 32);
> > revision = Encoding.Unicode.GetString(bytes, offset, size);
> >
> > // serial number
> > size = BitConverter.ToInt32(bytes, 36);
> > offset = BitConverter.ToInt32(bytes, 40);
> > serialNumber = Encoding.Unicode.GetString(bytes, offset, size);
> >
> > // subscriber id
> > size = BitConverter.ToInt32(bytes, 44);
> > offset = BitConverter.ToInt32(bytes, 48);
> > subscriberID = Encoding.Unicode.GetString(bytes, offset, size);
> >
> > // do something with the data
> >
> > // lineClose for hLine2
> > NativeTapi.lineClose(hLine2);
> >
> > // lineShutdown for hLine
> > NativeTapi.lineShutdown(hLine);
> >
> > ~~~ CODE END ~~~
> >
> > ~~~ P/Invoke BEGIN ~~~
> > [StructLayout(LayoutKind.Sequential)]
> > public struct LINEEXTENSIONID {
> > public IntPtr dwExtensionID0;
> > public IntPtr dwExtensionID1;
> > public IntPtr dwExtensionID2;
> > public IntPtr dwExtensionID3;
> > }
> >
> > [StructLayout(LayoutKind.Sequential)]
> > public struct LINEINITIALIZEEXPARAMS {
> > public uint dwTotalSize;
> > public uint dwNeededSize;
> > public uint dwUsedSize;
> > public uint dwOptions;
> > public System.IntPtr hEvent;
> > public System.IntPtr hCompletionPort;
> > public uint dwCompletionKey;
> > }
> >
> > internal class NativeTapi {
> > [DllImport("coredll")]
> > public static extern int lineInitializeEx(out IntPtr lpm_hLineApp, IntPtr
> > hInstance, IntPtr lpfnCallback, string lpszFriendlyAppName, out int
> > lpdwNumDevs,
> > ref int lpdwAPIVersion, ref LINEINITIALIZEEXPARAMS
> > lpLineInitializeExParams);
> >
> > [DllImport("coredll")]
> > public static extern int lineOpen(IntPtr m_hLineApp, int dwDeviceID, out
> > IntPtr lphLine, int dwAPIVersion, int dwExtVersion, IntPtr
> > dwCallbackInstance,
> > int dwPrivileges, int dwMediaModes, IntPtr lpCallParams);
> >
> > [DllImport("coredll")]
> > public static extern int lineNegotiateAPIVersion(IntPtr m_hLineApp, int
> > dwDeviceID, int dwAPILowVersion, int dwAPIHighVersion, out int
> > lpdwAPIVersion,
> > out LINEEXTENSIONID lpExtensionID);
> >
> > [DllImport("cellcore")]
> > public static extern int lineGetGeneralInfo(IntPtr hLine, byte[] bytes);
> >
> > [DllImport("coredll")]
> > public static extern int lineClose(IntPtr hLine);
> >
> > [DllImport("coredll")]
> > public static extern int lineShutdown(IntPtr m_hLineApp);
> > }
> > ~~~ P/Invoke END ~~~
> >
> > thanks in advance for your help,
> > allen
>
>
From: Alex Feinman [MVP] on
Right.. So here are couple more problems:
LINEGENERALINFO is a VARSTRING structure. It needs to have much more than
Marshal.SizeOf(lgi) bytes
By the way, for compatibility with CF2 I suggest to use
Marshal.SizeOf(typeof(LINEGENERALINFO))

Modify you P/Invoke call to take byte[] instead of ref LINEGENERALINFO and
allocate say 1024 bytes - should be enough.
Then get your information out of the byte array using known offsets.

On a semi-related note - I know it works because I have written aTAPI
wrapper a couple of years ago (including lineGeneralInof calls) and it is
now a part of OpenNETCF library. If you are interested - send me an email.


"allen" <allen(a)discussions.microsoft.com> wrote in message
news:811CFCEB-72E5-42E6-A662-F0CF36282EF0(a)microsoft.com...
> invalid pointer (LINEERR_INVALPOINTER - 0x80000035) is happening at the
> lineGetGeneralInfo() call.
>
> i have replaced that code with the following using and initializing the
> LINEGENERALINFO , but am still getting an invalid pointer.
>
> i have also tried defining this as a struct instead of a class (including
> p/invoke signature update), but again i get an invalid pointer.
>
> thanks again for your input,
> allen
>
>
> ~~~ CODE BEGIN ~~~
>
> LINEGENERALINFO lgi = new LINEGENERALINFO();
> lgi.dwTotalSize = Marshal.SizeOf(lgi);
> result = NativeTapi.lineGetGeneralInfo(hLine2, ref lgi);
>
> ~~~ CODE END ~~~
>
> ~~~ P/Invoke BEGIN ~~~
>
> public class LINEGENERALINFO {
> public int dwManufacturerOffset;
> public int dwManufacturerSize;
> public int dwModelOffset;
> public int dwModelSize;
> public int dwNeededSize;
> public int dwRevisionOffset;
> public int dwRevisionSize;
> public int dwSerialNumberOffset;
> public int dwSerialNumberSize;
> public int dwSubscriberNumberOffset;
> public int dwSubscriberNumberSize;
> public int dwTotalSize;
> public int dwUsedSize;
> }
>
> [DllImport("cellcore")]
> public static extern int lineGetGeneralInfo(IntPtr hLine,
> ref LINEGENERALINFO lineGenerlInfo);
>
> ~~~ P/Invoke END ~~~
>
> "Alex Feinman [MVP]" wrote:
>
>> Welll, for starters you are not populating the dwTotalSize field of the
>> byte
>> array that you pass in lieu of LINEGENERALINFO pointer
>> Where exactly you get the invalid pointer error?
>>
>> "allen" <allen(a)discussions.microsoft.com> wrote in message
>> news:68D1F07B-ECB0-4A15-AFCA-2A911FC3234C(a)microsoft.com...
>> > Hi,
>> > On both a pocket pc and a smart phone, I am trying to retrieve the
>> > devices
>> > manufacture, model, revision, serial number, and subscriber id using
>> > lineGetGeneralInfo.
>> >
>> > The issue I am having is that lineGetGeneralInfo always returns a
>> > -2147483595 (LINEERR_INVALPOINTER).
>> >
>> > Below is the code and P/Invoke declarations that i am using:
>> >
>> > ~~~ CODE BEGIN ~~~
>> > // lineInitializeEx
>> > int result = NativeTapi.lineInitializeEx(out hLine, IntPtr.Zero,
>> > IntPtr.Zero, null,
>> > out dwNumDev, ref num1, ref lineInitializeParams);
>> >
>> > if (result != 0) {
>> > MessageBox.Show(string.Format("lineInitializeEx failed!\n\nError Code:
>> > {0}", result.ToString()));
>> > return;
>> > }
>> >
>> > // lineNegotiateAPIVerison
>> > int version;
>> > int dwAPIVersionLow = 0x10004;
>> > int dwAPIVersionHigh = 0x20000;
>> > LINEEXTENSIONID lineExtensionID;
>> > result = NativeTapi.lineNegotiateAPIVersion(hLine, 0, dwAPIVersionLow,
>> > dwAPIVersionHigh, out version, out lineExtensionID);
>> >
>> > if (result != 0) {
>> > MessageBox.Show(string.Format("lineNegotiateAPIVersion failed!\n\nError
>> > Code: {0}", result.ToString()));
>> > return;
>> > }
>> >
>> > // lineOpen
>> > IntPtr hLine2;
>> > result = NativeTapi.lineOpen(hLine, 0, out hLine2, version, 0,
>> > IntPtr.Zero,
>> > 0x00000002, 0x00000004, IntPtr.Zero);
>> >
>> > if (result != 0) {
>> > MessageBox.Show(string.Format("lineNegotiateAPIVersion failed!\n\nError
>> > Code: {0}", result.ToString()));
>> > return;
>> > }
>> >
>> > // lineGetGeneralInfo
>> > byte[] bytes = new byte[512];
>> >
>> > result = NativeTapi.lineGetGeneralInfo(hLine2, bytes);
>> >
>> > // process
>> > string manufacture;
>> > string model;
>> > string revision;
>> > string serialNumber;
>> > string subscriberID;
>> >
>> > int size;
>> > int offset;
>> >
>> > // manufacture
>> > size = BitConverter.ToInt32(bytes, 12);
>> > offset = BitConverter.ToInt32(bytes, 16);
>> > manufacture = Encoding.Unicode.GetString(bytes, offset, size);
>> >
>> > // model
>> > size = BitConverter.ToInt32(bytes, 20);
>> > offset = BitConverter.ToInt32(bytes, 24);
>> > model = Encoding.Unicode.GetString(bytes, offset, size);
>> >
>> > // revision
>> > size = BitConverter.ToInt32(bytes, 28);
>> > offset = BitConverter.ToInt32(bytes, 32);
>> > revision = Encoding.Unicode.GetString(bytes, offset, size);
>> >
>> > // serial number
>> > size = BitConverter.ToInt32(bytes, 36);
>> > offset = BitConverter.ToInt32(bytes, 40);
>> > serialNumber = Encoding.Unicode.GetString(bytes, offset, size);
>> >
>> > // subscriber id
>> > size = BitConverter.ToInt32(bytes, 44);
>> > offset = BitConverter.ToInt32(bytes, 48);
>> > subscriberID = Encoding.Unicode.GetString(bytes, offset, size);
>> >
>> > // do something with the data
>> >
>> > // lineClose for hLine2
>> > NativeTapi.lineClose(hLine2);
>> >
>> > // lineShutdown for hLine
>> > NativeTapi.lineShutdown(hLine);
>> >
>> > ~~~ CODE END ~~~
>> >
>> > ~~~ P/Invoke BEGIN ~~~
>> > [StructLayout(LayoutKind.Sequential)]
>> > public struct LINEEXTENSIONID {
>> > public IntPtr dwExtensionID0;
>> > public IntPtr dwExtensionID1;
>> > public IntPtr dwExtensionID2;
>> > public IntPtr dwExtensionID3;
>> > }
>> >
>> > [StructLayout(LayoutKind.Sequential)]
>> > public struct LINEINITIALIZEEXPARAMS {
>> > public uint dwTotalSize;
>> > public uint dwNeededSize;
>> > public uint dwUsedSize;
>> > public uint dwOptions;
>> > public System.IntPtr hEvent;
>> > public System.IntPtr hCompletionPort;
>> > public uint dwCompletionKey;
>> > }
>> >
>> > internal class NativeTapi {
>> > [DllImport("coredll")]
>> > public static extern int lineInitializeEx(out IntPtr lpm_hLineApp,
>> > IntPtr
>> > hInstance, IntPtr lpfnCallback, string lpszFriendlyAppName, out int
>> > lpdwNumDevs,
>> > ref int lpdwAPIVersion, ref LINEINITIALIZEEXPARAMS
>> > lpLineInitializeExParams);
>> >
>> > [DllImport("coredll")]
>> > public static extern int lineOpen(IntPtr m_hLineApp, int dwDeviceID,
>> > out
>> > IntPtr lphLine, int dwAPIVersion, int dwExtVersion, IntPtr
>> > dwCallbackInstance,
>> > int dwPrivileges, int dwMediaModes, IntPtr lpCallParams);
>> >
>> > [DllImport("coredll")]
>> > public static extern int lineNegotiateAPIVersion(IntPtr m_hLineApp, int
>> > dwDeviceID, int dwAPILowVersion, int dwAPIHighVersion, out int
>> > lpdwAPIVersion,
>> > out LINEEXTENSIONID lpExtensionID);
>> >
>> > [DllImport("cellcore")]
>> > public static extern int lineGetGeneralInfo(IntPtr hLine, byte[]
>> > bytes);
>> >
>> > [DllImport("coredll")]
>> > public static extern int lineClose(IntPtr hLine);
>> >
>> > [DllImport("coredll")]
>> > public static extern int lineShutdown(IntPtr m_hLineApp);
>> > }
>> > ~~~ P/Invoke END ~~~
>> >
>> > thanks in advance for your help,
>> > allen
>>
>>

From: allen on
ok, so i figured out what i was doing wrong. first, the LINEGENERALINFO
struct elements were not in the correct order as specified by MSDN. once
that was fixed, the key here is exactly what you mention here alex in that
the LINEGENERALINFO is a variable length structure.

what i did was to allocate a byte array to the default size (52) of
LINEGENERALINFO and update the dwTotalSize byte array element(s) and make an
initial call to lineGetGeneralInfo to retrieve the necessary size.

i then extract the necessary size from the returned byte array, reallocate
the byte array accordingly and then write that new size to the dwTotalSize
byte array element(s).

this second call then returns successfully and i can then parse the
manufacture, model, revision, serial number (IMEI), and subscriber id (IMSI)
from the returned byte array.

thank you alex for your feedback, it proved invaluable in helping diagnose
the true error.

for those interested, below is the full working source in c# of a simple
mobile winform app demonstrating how to use the lineGetGeneralInfo and
associated api's.

enjoy,
allen

~~~ CODE BEGIN ~~~

using System;
using System.Drawing;
using System.Collections;
using System.Windows.Forms;
using System.Data;
using System.Runtime.InteropServices;
using System.Text;
using System.Xml;
using System.IO;

namespace SPTapi {
public class Form1 : System.Windows.Forms.Form {
private System.Windows.Forms.MainMenu mainMenu1;

public Form1() {
InitializeComponent();
}

protected override void Dispose(bool disposing) {
base.Dispose(disposing);
}

private void InitializeComponent() {
this.mainMenu1 = new System.Windows.Forms.MainMenu();
//
// Form1
//
this.ClientSize = new System.Drawing.Size(176, 180);
this.Menu = this.mainMenu1;
this.Text = "Form1";
this.Load += new System.EventHandler(this.Form1_Load);

}

static void Main() {
Application.Run(new Form1());
}

private void Form1_Load(object sender, EventArgs e) {
IntPtr hLine;
int dwNumDev;
int num1 = 0x20000;
LINEINITIALIZEEXPARAMS lineInitializeParams = new LINEINITIALIZEEXPARAMS();
lineInitializeParams.dwTotalSize = (uint)
Marshal.SizeOf(lineInitializeParams);
lineInitializeParams.dwNeededSize = lineInitializeParams.dwTotalSize;
lineInitializeParams.dwUsedSize = lineInitializeParams.dwUsedSize;
lineInitializeParams.dwOptions = 2;
lineInitializeParams.hEvent = IntPtr.Zero;
lineInitializeParams.hCompletionPort = IntPtr.Zero;

// lineInitializeEx
int result = NativeTapi.lineInitializeEx(out hLine, IntPtr.Zero,
IntPtr.Zero, null,
out dwNumDev, ref num1, ref lineInitializeParams);

if (result != 0) {
MessageBox.Show(string.Format("lineInitializeEx failed!\n\nError Code:
{0}", result.ToString()));
this.Close();
return;
}

// lineNegotiateAPIVerison
int version;
int dwAPIVersionLow = 0x10004;
int dwAPIVersionHigh = 0x20000;
LINEEXTENSIONID lineExtensionID;
result = NativeTapi.lineNegotiateAPIVersion(hLine, 0, dwAPIVersionLow,
dwAPIVersionHigh, out version, out lineExtensionID);

if (result != 0) {
MessageBox.Show(string.Format("lineNegotiateAPIVersion failed!\n\nError
Code: {0}", result.ToString()));
this.Close();
return;
}

// lineOpen
IntPtr hLine2 = IntPtr.Zero;
result = NativeTapi.lineOpen(hLine, 0, out hLine2, version, 0,
IntPtr.Zero, 0x00000002, 0x00000004, IntPtr.Zero);

if (result != 0) {
MessageBox.Show(string.Format("lineNegotiateAPIVersion failed!\n\nError
Code: {0}", result.ToString()));
this.Close();
return;
}

// lineGetGeneralInfo
int structSize = Marshal.SizeOf(new LINEGENERALINFO());
byte[] bytes = new byte[structSize];
byte[] tmpBytes = BitConverter.GetBytes(structSize);

for (int index = 0; index < tmpBytes.Length; index++) {
bytes[index] = tmpBytes[index];
}

// make initial query to retrieve necessary size
result = NativeTapi.lineGetGeneralInfo(hLine2, bytes);

// get the needed size
int neededSize = BitConverter.ToInt32(bytes, 4);

// resize the array
bytes = new byte[neededSize];

// write out the new allocated size to the byte stream
tmpBytes = BitConverter.GetBytes(neededSize);
for (int index = 0; index < tmpBytes.Length; index++) {
bytes[index] = tmpBytes[index];
}

// fetch the information with properly size buffer
result = NativeTapi.lineGetGeneralInfo(hLine2, bytes);

if (result != 0) {
MessageBox.Show(Marshal.GetLastWin32Error().ToString());
this.Close();
return;
}

// process
string manufacture;
string model;
string revision;
string serialNumber;
string subscriberID;

int size;
int offset;

// manufacture
size = BitConverter.ToInt32(bytes, 12);
offset = BitConverter.ToInt32(bytes, 16);
manufacture = Encoding.Unicode.GetString(bytes, offset, size);
manufacture = manufacture.Substring(0, manufacture.IndexOf('\0'));

// model
size = BitConverter.ToInt32(bytes, 20);
offset = BitConverter.ToInt32(bytes, 24);
model = Encoding.Unicode.GetString(bytes, offset, size);
model = model.Substring(0, model.IndexOf('\0'));

// revision
size = BitConverter.ToInt32(bytes, 28);
offset = BitConverter.ToInt32(bytes, 32);
revision = Encoding.Unicode.GetString(bytes, offset, size);
revision = revision.Substring(0, revision.IndexOf('\0'));

// serial number
size = BitConverter.ToInt32(bytes, 36);
offset = BitConverter.ToInt32(bytes, 40);
serialNumber = Encoding.Unicode.GetString(bytes, offset, size);
serialNumber = serialNumber.Substring(0, serialNumber.IndexOf('\0'));

// subscriber id
size = BitConverter.ToInt32(bytes, 44);
offset = BitConverter.ToInt32(bytes, 48);
subscriberID = Encoding.Unicode.GetString(bytes, offset, size);
subscriberID = subscriberID.Substring(0, subscriberID.IndexOf('\0'));

string msg = string.Format("Manufacture: {0}\n\nModel: {1}\n\nRevision:
{2}\n\nSerial Number: {3}\n\nSubscriber ID: {4}", manufacture, model,
revision, serialNumber, subscriberID);
MessageBox.Show(msg);

// lineClose for hLine2
NativeTapi.lineClose(hLine2);

// lineShutdown for hLine
NativeTapi.lineShutdown(hLine);

this.Close();
}
}

[StructLayout(LayoutKind.Sequential)]
public struct LINEEXTENSIONID {
public IntPtr dwExtensionID0;
public IntPtr dwExtensionID1;
public IntPtr dwExtensionID2;
public IntPtr dwExtensionID3;
}

[StructLayout(LayoutKind.Sequential)]
public struct LINEINITIALIZEEXPARAMS {
public uint dwTotalSize;
public uint dwNeededSize;
public uint dwUsedSize;
public uint dwOptions;
public System.IntPtr hEvent;
public System.IntPtr hCompletionPort;
public uint dwCompletionKey;
}

[StructLayout(LayoutKind.Sequential)]
public struct LINEGENERALINFO {
public int dwTotalSize;
public int dwNeededSize;
public int dwUsedSize;
public int dwManufacturerSize;
public int dwManufacturerOffset;
public int dwModelSize;
public int dwModelOffset;
public int dwRevisionSize;
public int dwRevisionOffset;
public int dwSerialNumberSize;
public int dwSerialNumberOffset;
public int dwSubscriberNumberSize;
public int dwSubscriberNumberOffset;
}

internal class NativeTapi {
[DllImport("coredll")]
public static extern int lineClose(IntPtr hLine);

[DllImport("cellcore")]
public static extern int lineGetGeneralInfo(IntPtr hLine, byte[] bytes);

[DllImport("coredll")]
public static extern int lineGetAddressCaps(IntPtr hLineApp, int
dwDeviceID, int dwAddressID, int dwAPIVersion, int dwExtVersion, byte[]
lpAddressCaps);

[DllImport("coredll")]
public static extern int lineInitializeEx(out IntPtr lpm_hLineApp, IntPtr
hInstance, IntPtr lpfnCallback, string lpszFriendlyAppName, out int
lpdwNumDevs, ref int lpdwAPIVersion, ref LINEINITIALIZEEXPARAMS
lpLineInitializeExParams);

[DllImport("coredll")]
public static extern int lineNegotiateAPIVersion(IntPtr m_hLineApp, int
dwDeviceID, int dwAPILowVersion, int dwAPIHighVersion, out int
lpdwAPIVersion, out LINEEXTENSIONID lpExtensionID);

[DllImport("coredll")]
public static extern int lineOpen(IntPtr m_hLineApp, int dwDeviceID, out
IntPtr lphLine, int dwAPIVersion, int dwExtVersion, IntPtr
dwCallbackInstance, int dwPrivileges, int dwMediaModes, IntPtr lpCallParams);

[DllImport("coredll")]
public static extern int lineShutdown(IntPtr m_hLineApp);
}
}


~~~ CODE END ~~~


"Alex Feinman [MVP]" wrote:

> Right.. So here are couple more problems:
> LINEGENERALINFO is a VARSTRING structure. It needs to have much more than
> Marshal.SizeOf(lgi) bytes
> By the way, for compatibility with CF2 I suggest to use
> Marshal.SizeOf(typeof(LINEGENERALINFO))
>
> Modify you P/Invoke call to take byte[] instead of ref LINEGENERALINFO and
> allocate say 1024 bytes - should be enough.
> Then get your information out of the byte array using known offsets.
>
> On a semi-related note - I know it works because I have written aTAPI
> wrapper a couple of years ago (including lineGeneralInof calls) and it is
> now a part of OpenNETCF library. If you are interested - send me an email.
>
>
> "allen" <allen(a)discussions.microsoft.com> wrote in message
> news:811CFCEB-72E5-42E6-A662-F0CF36282EF0(a)microsoft.com...
> > invalid pointer (LINEERR_INVALPOINTER - 0x80000035) is happening at the
> > lineGetGeneralInfo() call.
> >
> > i have replaced that code with the following using and initializing the
> > LINEGENERALINFO , but am still getting an invalid pointer.
> >
> > i have also tried defining this as a struct instead of a class (including
> > p/invoke signature update), but again i get an invalid pointer.
> >
> > thanks again for your input,
> > allen
> >
> >
> > ~~~ CODE BEGIN ~~~
> >
> > LINEGENERALINFO lgi = new LINEGENERALINFO();
> > lgi.dwTotalSize = Marshal.SizeOf(lgi);
> > result = NativeTapi.lineGetGeneralInfo(hLine2, ref lgi);
> >
> > ~~~ CODE END ~~~
> >
> > ~~~ P/Invoke BEGIN ~~~
> >
> > public class LINEGENERALINFO {
> > public int dwManufacturerOffset;
> > public int dwManufacturerSize;
> > public int dwModelOffset;
> > public int dwModelSize;
> > public int dwNeededSize;
> > public int dwRevisionOffset;
> > public int dwRevisionSize;
> > public int dwSerialNumberOffset;
> > public int dwSerialNumberSize;
> > public int dwSubscriberNumberOffset;
> > public int dwSubscriberNumberSize;
> > public int dwTotalSize;
> > public int dwUsedSize;
> > }
> >
> > [DllImport("cellcore")]
> > public static extern int lineGetGeneralInfo(IntPtr hLine,
> > ref LINEGENERALINFO lineGenerlInfo);
> >
> > ~~~ P/Invoke END ~~~
> >
> > "Alex Feinman [MVP]" wrote:
> >
> >> Welll, for starters you are not populating the dwTotalSize field of the
> >> byte
> >> array that you pass in lieu of LINEGENERALINFO pointer
> >> Where exactly you get the invalid pointer error?
> >>
> >> "allen" <allen(a)discussions.microsoft.com> wrote in message
> >> news:68D1F07B-ECB0-4A15-AFCA-2A911FC3234C(a)microsoft.com...
> >> > Hi,
> >> > On both a pocket pc and a smart phone, I am trying to retrieve the
> >> > devices
> >> > manufacture, model, revision, serial number, and subscriber id using
> >> > lineGetGeneralInfo.
> >> >
> >> > The issue I am having is that lineGetGeneralInfo always returns a
> >> > -2147483595 (LINEERR_INVALPOINTER).
> >> >
> >> > Below is the code and P/Invoke declarations that i am using:
> >> >
> >> > ~~~ CODE BEGIN ~~~
> >> > // lineInitializeEx
> >> > int result = NativeTapi.lineInitializeEx(out hLine, IntPtr.Zero,
> >> > IntPtr.Zero, null,
> >> > out dwNumDev, ref num1, ref lineInitializeParams);
> >> >
> >> > if (result != 0) {
> >> > MessageBox.Show(string.Format("lineInitializeEx failed!\n\nError Code:
> >> > {0}", result.ToString()));
> >> > return;
> >> > }
> >> >
> >> > // lineNegotiateAPIVerison
> >> > int version;
> >> > int dwAPIVersionLow = 0x10004;
> >> > int dwAPIVersionHigh = 0x20000;
> >> > LINEEXTENSIONID lineExtensionID;
> >> > result = NativeTapi.lineNegotiateAPIVersion(hLine, 0, dwAPIVersionLow,
> >> > dwAPIVersionHigh, out version, out lineExtensionID);
> >> >
> >> > if (result != 0) {
> >> > MessageBox.Show(string.Format("lineNegotiateAPIVersion failed!\n\nError
> >> > Code: {0}", result.ToString()));
> >> > return;
> >> > }
> >> >
> >> > // lineOpen
> >> > IntPtr hLine2;
> >> > result = NativeTapi.lineOpen(hLine, 0, out hLine2, version, 0,
> >> > IntPtr.Zero,
> >> > 0x00000002, 0x00000004, IntPtr.Zero);
> >> >
> >> > if (result != 0) {
> >> > MessageBox.Show(string.Format("lineNegotiateAPIVersion failed!\n\nError
> >> > Code: {0}", result.ToString()));
> >> > return;
> >> > }
> >> >
> >> > // lineGetGeneralInfo
> >> > byte[] bytes = new byte[512];
> >> >
> >> > result = NativeTapi.lineGetGeneralInfo(hLine2, bytes);
> >> >
> >> > // process
> >> > string manufacture;
> >> > string model;
> >> > string revision;
> >> > string serialNumber;
> >> > string subscriberID;
> >> >
> >> > int size;
> >> > int offset;
> >> >
> >> > // manufacture
> >> > size = BitConverter.ToInt32(bytes, 12);
> >> > offset = BitConverter.ToInt32(bytes, 16);
> >> > manufacture = Encoding.Unicode.GetString(bytes, offset, size);
> >> >
> >> > // model
> >> > size = BitConverter.ToInt32(bytes, 20);
> >> > offset = BitConverter.ToInt32(bytes, 24);
> >> > model = Encoding.Unicode.GetString(bytes, offset, size);
> >> >
> >> > // revision
> >> > size = BitConverter.ToInt32(bytes, 28);
> >> > offset = BitConverter.ToInt32(bytes, 32);
> >> > revision = Encoding.Unicode.GetString(bytes, offset, size);
> >> >
> >> > // serial number
> >> > size = BitConverter.ToInt32(bytes, 36);
> >> > offset = BitConverter.ToInt32(bytes, 40);
> >> > serialNumber = Encoding.Unicode.GetString(bytes, offset, size);
> >> >
> >> > // subscriber id
> >> > size = BitConverter.ToInt32(bytes, 44);
> >> > offset = BitConverter.ToInt32(bytes, 48);
> >> > subscriberID = Encoding.Unicode.GetString(bytes, offset, size);
> >> >
> >> > // do something with the data
> >> >
> >> > // lineClose for hLine2
> >> > NativeTapi.lineClose(hLine2);
> >> >
> >> > // lineShutdown for hLine
> >> > NativeTapi.lineShutdown(hLine);
> >> >
> >> > ~~~ CODE END ~~~
> >> >
> >> > ~~~ P/Invoke BEGIN ~~~
> >> > [StructLayout(LayoutKind.Sequential)]
> >> > public struct LINEEXTENSIONID {
> >> > public IntPtr dwExtensionID0;
> >> > public IntPtr dwExtensionID1;
> >> > public IntPtr dwExtensionID2;
> >> > public IntPtr dwExtensionID3;
> >> > }
> >> >
> >> > [StructLayout(LayoutKind.Sequential)]
> >> > public struct LINEINITIALIZEEXPARAMS {
> >> > public uint dwTotalSize;
> >> > public uint dwNeededSize;
> >> > public uint dwUsedSize;
> >> > public uint dwOptions;
> >> > public System.IntPtr hEvent;
> >> > public System.IntPtr hCompletionPort;
> >> > public uint dwCompletionKey;
> >> > }
> >> >
> >> > internal class NativeTapi {
> >> > [DllImport("coredll")]
> >> > public static extern int lineInitializeEx(out IntPtr lpm_hLineApp,
> >> > IntPtr
> >> > hInstance, IntPtr lpfnCallback, string lpszFriendlyAppName, out int
> >> > lpdwNumDevs,
> >> > ref int lpdwAPIVersion, ref LINEINITIALIZEEXPARAMS
> >> > lpLineInitializeExParams);
> >> >
> >> > [DllImport("coredll")]
> >> > public static extern int lineOpen(IntPtr m_hLineApp, int dwDeviceID,
> >> > out
> >> > IntPtr lphLine, int dwAPIVersion, int dwExtVersion, IntPtr
> >> > dwCallbackInstance,
> >> > int dwPrivileges, int dwMediaModes, IntPtr lpCallParams);
> >> >
> >> > [DllImport("coredll")]
> >> > public static extern int lineNegotiateAPIVersion(IntPtr m_hLineApp, int
> >> > dwDeviceID, int dwAPILowVersion, int dwAPIHighVersion, out int
> >> > lpdwAPIVersion,
> >> > out LINEEXTENSIONID lpExtensionID);
> >> >
> >> > [DllImport("cellcore")]
> >> > public static extern int lineGetGeneralInfo(IntPtr hLine, byte[]
> >> > bytes);
> >> >
> >> > [DllImport("coredll")]
> >> > public static extern int lineClose(IntPtr hLine);
> >> >
> >> > [DllImport("coredll")]
> >> > public static extern int lineShutdown(IntPtr m_hLineApp);
> >> > }
> >> > ~~~ P/Invoke END ~~~
> >> >
> >> > thanks in advance for your help,
> >> > allen
> >>
> >>
>
>