[Windows Mobile Development and Hacking General] tiger.woods:
Sorry had to post the remaining source in another thread:

/// <summary>

/// Queries the device state.

/// </summary>

/// <returns>Device state information</returns>

public GpsDeviceState GetDeviceState()

{

GpsDeviceState device = null;

// allocate a buffer on the native side. Since the

IntPtr pGpsDevice = Utils.LocalAlloc(GpsDeviceState.GpsDeviceStructureSize);

// GPS_DEVICE structure has arrays of characters, it's easier to just

// write directly into memory rather than create a managed structure with

// the same layout.

Marshal.WriteInt32(pGpsDevice, 1);	// write out GPS version of 1

Marshal.WriteInt32(pGpsDevice, 4, GpsDeviceState.GpsDeviceStructureSize);	// write out dwSize of structure

int result = GPSGetDeviceState(pGpsDevice);

if (result == 0)

{

// instantiate the GpsDeviceState class passing in the native pointer

device = new GpsDeviceState(pGpsDevice);

}

// free our native memory

Utils.LocalFree(pGpsDevice);

return device;

}

/// <summary>

/// Creates our event thread that will receive native events

/// </summary>

private void CreateGpsEventThread()

{

// we only want to create the thread if we don't have one created already

// and we have opened the gps device

if (gpsEventThread == null && gpsHandle != IntPtr.Zero)

{

// Create and start thread to listen for GPS events

gpsEventThread = new System.Threading.Thread(new System.Threading.ThreadStart(WaitForGpsEvents));

gpsEventThread.Start();

}

}

/// <summary>

/// Method used to listen for native events from the GPS.

/// </summary>

private void WaitForGpsEvents()

{

lock (this)

{

bool listening = true;

// allocate 3 handles worth of memory to pass to WaitForMultipleObjects

IntPtr handles = Utils.LocalAlloc(12);

// write the three handles we are listening for.

Marshal.WriteInt32(handles, 0, stopHandle.ToInt32());

Marshal.WriteInt32(handles, 4, deviceStateChangedHandle.ToInt32());

Marshal.WriteInt32(handles, 8, newLocationHandle.ToInt32());

while (listening)

{

int obj = WaitForMultipleObjects(3, handles, 0, -1);

if (obj != waitFailed)

{

switch (obj)

{

case 0:

// we've been signalled to stop

listening = false;

break;

case 1:

// device state has changed

if (deviceStateChanged != null)

{

deviceStateChanged(this, new DeviceStateChangedEventArgs(GetDeviceState()));

}

break;

case 2:

// location has changed

if (locationChanged != null)

{

locationChanged(this, new LocationChangedEventArgs(GetPosition()));

}

break;

}

}

}

// free the memory we allocated for the native handles

Utils.LocalFree(handles);

// clear our gpsEventThread so that we can recreate this thread again

// if the events are hooked up again.

gpsEventThread = null;

}

}

#region PInvokes to gpsapi.dll

[DllImport("gpsapi.dll")]

static extern IntPtr GPSOpenDevice(IntPtr hNewLocationData, IntPtr hDeviceStateChange, string szDeviceName, int dwFlags);

[DllImport("gpsapi.dll")]

static extern int GPSCloseDevice(IntPtr hGPSDevice);

[DllImport("gpsapi.dll")]

static extern int GPSGetPosition(IntPtr hGPSDevice, IntPtr pGPSPosition, int dwMaximumAge, int dwFlags);

[DllImport("gpsapi.dll")]

static extern int GPSGetDeviceState(IntPtr pGPSDevice);

#endregion

#region PInvokes to coredll.dll

[DllImport("coredll.dll")]

static extern IntPtr CreateEvent(IntPtr lpEventAttributes, int bManualReset, int bInitialState, StringBuilder lpName);

[DllImport("coredll.dll")]

static extern int CloseHandle(IntPtr hObject);

const int waitFailed = -1;

[DllImport("coredll.dll")]

static extern int WaitForMultipleObjects(int nCount, IntPtr lpHandles, int fWaitAll, int dwMilliseconds);

const int eventSet = 3;

[DllImport("coredll.dll")]

static extern int EventModify(IntPtr hHandle, int dwFunc);

#endregion

}

}