FindFirstDevice and C#

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

Greetings,

I am not sure how I would use "FindFirstDevice" while programming in C#.
I am sure I use [DllImport("<some dll")], but I am not sure which one to use?

Has anyone tried using this before while in programming in C#?

Thanks in advance for any suggestions.
 
Seems pretty strightforward to marshal, but the larger question is what
problem are you trying to solve? There may be a better, faster,
already-done way to get the info you want.


--

Chris Tacke, Embedded MVP
OpenNETCF Consulting
Managed Code in an Embedded World
www.OpenNETCF.com
 
Greetings,

Thanks for your reply.
Seems pretty strightforward to marshal, but the larger question is what
problem are you trying to solve? There may be a better, faster,
already-done way to get the info you want.
I need to get a handle to a device, so I can monitor the plug of play of it
using
RegisterDeviceNotification via the "WM_DEVICECHANGE" message.

I have done this before in C++ under the windows platform, but I had to use
"SetupDiEnumDeviceInfo", and "SetupDiEnumDeviceInfo". Which is not
supported under the windows ce enviornment.

So basically what I need is a handle to the device to pass to
"RegisterDeviceNotification".

I already have the wm_device change working in ce 2003 (pocket pc) under c#,
but now I need a way to register the device.

I do not see any docs any where which tell you what dll to import via
marshalling.
 
Seems pretty strightforward to marshal, but the larger question is what
problem are you trying to solve? There may be a better, faster,
already-done way to get the info you want.
This code is not working correctly because it can't find the method
"FindFirstDevice", but this is what i have now.

code snippet:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct DEVMGR_DEVICE_INFORMATION
{
public UInt32 dwSize;
public IntPtr hDevice;
public IntPtr hParentDevice;

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 6)]
public string szLegacyName;

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string szDeviceKey;

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string szDeviceName;

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string szBusName;
}

public enum DeviceSearchType : int
{
DeviceSearchByLegacyName = 0,
DeviceSearchByDeviceName = 1,
DeviceSearchByBusName = 2,
DeviceSearchByGuid = 3,
DeviceSearchByParent = 4
}

[DllImport("coredll.dll", SetLastError = true)]
public static extern IntPtr FindFirstDevice(DeviceSearchType
searchType, IntPtr searchParam, ref DEVMGR_DEVICE_INFORMATION pdi);

In my c# class I try to test it.

void testCode()
{
try
{
DeviceSearchType searchType =
DeviceSearchType.DeviceSearchByDeviceName;

DEVMGR_DEVICE_INFORMATION pdi =
new DEVMGR_DEVICE_INFORMATION();

string searchParamString = "COM*";
IntPtr searchParam = Marshal.AllocHGlobal(searchParamString.Length);
IntPtr searchParam = Marshal.StringToBSTR(searchParamString);
IntPtr deviceHandle = FindFirstDevice(searchType,searchParam, ref pdi);

}
catch (Exception err)
{
}
}

I get the exception "Can't find an Entry Point 'FindFirstDevice' in a
PInvoke DLL 'coredll.dll'."
The "FindFirstDevice" is not found in the "coredll.dll", so I am not sure on
how to proceed since I do not know which dll to use.
 
Are you sure that the device supports notifications? Or I guess I should
ask, what, specifically are you trying to detect?

As to the actual question, in most cases, base OS functions will always be
in coredll.dll.

Paul T.
 
It's in coredll.dll, if it's in your OS at all. Back up and tell us what
you're trying to monitor for, what version of Windows CE, what device, etc.

Paul T.

BartMan said:
Seems pretty strightforward to marshal, but the larger question is what
problem are you trying to solve? There may be a better, faster,
already-done way to get the info you want.
This code is not working correctly because it can't find the method
"FindFirstDevice", but this is what i have now.

code snippet:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct DEVMGR_DEVICE_INFORMATION
{
public UInt32 dwSize;
public IntPtr hDevice;
public IntPtr hParentDevice;

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 6)]
public string szLegacyName;

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string szDeviceKey;

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string szDeviceName;

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string szBusName;
}

public enum DeviceSearchType : int
{
DeviceSearchByLegacyName = 0,
DeviceSearchByDeviceName = 1,
DeviceSearchByBusName = 2,
DeviceSearchByGuid = 3,
DeviceSearchByParent = 4
}

[DllImport("coredll.dll", SetLastError = true)]
public static extern IntPtr FindFirstDevice(DeviceSearchType
searchType, IntPtr searchParam, ref DEVMGR_DEVICE_INFORMATION pdi);

In my c# class I try to test it.

void testCode()
{
try
{
DeviceSearchType searchType =
DeviceSearchType.DeviceSearchByDeviceName;

DEVMGR_DEVICE_INFORMATION pdi =
new DEVMGR_DEVICE_INFORMATION();

string searchParamString = "COM*";
IntPtr searchParam = Marshal.AllocHGlobal(searchParamString.Length);
IntPtr searchParam = Marshal.StringToBSTR(searchParamString);
IntPtr deviceHandle = FindFirstDevice(searchType,searchParam, ref pdi);

}
catch (Exception err)
{
}
}

I get the exception "Can't find an Entry Point 'FindFirstDevice' in a
PInvoke DLL 'coredll.dll'."
The "FindFirstDevice" is not found in the "coredll.dll", so I am not sure
on
how to proceed since I do not know which dll to use.
 
Are you sure that the device supports notifications? Or I guess I should
ask, what, specifically are you trying to detect?
It is a rs-232 device which connects to the pocket pc device via the cf card.
It is basically a cf card with a rs-232 cable attached to it.
Currently when I pull the card out it does post a WM_DEVICECHANGE message,
but doesn't give me the device information. Which is why I would like to
register the device, so I can tell if a removed device is indeed this card
with the rs-232 attached to it.
As to the actual question, in most cases, base OS functions will always be
in coredll.dll.
I did try this, and it says that the FindFirstDevice entry point cannot be
found.
I did post this code in another post, but it is included in this example:

code snippet:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct DEVMGR_DEVICE_INFORMATION
{
public UInt32 dwSize;
public IntPtr hDevice;
public IntPtr hParentDevice;

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 6)]
public string szLegacyName;

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string szDeviceKey;

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string szDeviceName;

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string szBusName;
}

public enum DeviceSearchType : int
{
DeviceSearchByLegacyName = 0,
DeviceSearchByDeviceName = 1,
DeviceSearchByBusName = 2,
DeviceSearchByGuid = 3,
DeviceSearchByParent = 4
}

[DllImport("coredll.dll", SetLastError = true)]
public static extern IntPtr FindFirstDevice(DeviceSearchType
searchType, IntPtr searchParam, ref DEVMGR_DEVICE_INFORMATION pdi);

In my c# class I try to test it.

void testCode()
{
try
{
DeviceSearchType searchType =
DeviceSearchType.DeviceSearchByDeviceName;

DEVMGR_DEVICE_INFORMATION pdi =
new DEVMGR_DEVICE_INFORMATION();

string searchParamString = "COM*";
IntPtr searchParam = Marshal.AllocHGlobal(searchParamString.Length);
IntPtr searchParam = Marshal.StringToBSTR(searchParamString);
IntPtr deviceHandle = FindFirstDevice(searchType,searchParam, ref pdi);

}
catch (Exception err)
{
}
}

I get the exception "Can't find an Entry Point 'FindFirstDevice' in a
PInvoke DLL 'coredll.dll'."
The "FindFirstDevice" is not found in the "coredll.dll", so I am not sure on
how to proceed since I do not know which dll to use.
 
It's in coredll.dll, if it's in your OS at all. Back up and tell us what
you're trying to monitor for, what version of Windows CE, what device, etc.

CPU and Version:
Dell Axim X50v with Windows Mobile 2003 Second Edition. (4.21.1088)

Device I am trying to monitor:
The Device is a CF card with a rs-232 connection attached to it.
It uses a 3rd party software package which is installed via a CAB file.

Purpose:
I am trying to track a basic plug-n-play removal and addition of the cf card
for this device. I can get the device removal, and addition of it via the
WM_DEVICECHANGE.
I just want more detailed information about the device that is removed.
 
Ah! As far as I can tell, that API is unsupported in Pocket PC 2003. It's
not declared in the Pocket PC native SDK, for example.

It seems to me that you should be able to get adequate information from the
WM_DEVICECHANGE. You're looking at wParam and lParam to see that it's a
device removal complete event and that the name of the device being removed
is COMn: or something? And that's not enough?

Paul T.
 
Ah! As far as I can tell, that API is unsupported in Pocket PC 2003. It's
not declared in the Pocket PC native SDK, for example.
That makes sense about why I can't get access to it.
I didn't notice that in the msdn docs, good find! :)

It seems to me that you should be able to get adequate information from the
WM_DEVICECHANGE. You're looking at wParam and lParam to see that it's a
device removal complete event and that the name of the device being removed
is COMn: or something? And that's not enough?

Yes, that would be enough. I can't seem to get the name from the lparam, or
wparam. Do you have a recommendation about how I can parse that from the
values?
 
MSDN has good documentation on the parameters that come with that message.
That's how I found out that it seems like it should be good enough. Here's
some of the C I used:

-----
void DeviceChange( HWND hWnd, DWORD typ, void *param )
{
switch( typ )
{
case DBT_DEVICEARRIVAL:
RETAILMSG( 1, ( TEXT( "DBT_DEVICEARRIVAL\r\n" ) ) );
break;
case DBT_DEVICEREMOVECOMPLETE:
RETAILMSG( 1, ( TEXT( "DBT_DEVICEREMOVECOMPLETE\r\n" ) ) );
{
DEV_BROADCAST_HDR *hdr = (DEV_BROADCAST_HDR *)param;
switch( hdr->dbch_devicetype )
{
case DBT_DEVTYP_DEVICEINTERFACE:
RETAILMSG( 1, ( TEXT( "DBT_DEVTYP_DEVICEINTERFACE\r\n" ) ) );
break;
case DBT_DEVTYP_OEM:
RETAILMSG( 1, ( TEXT( "DBT_DEVTYP_OEM\r\n" ) ) );
break;
case DBT_DEVTYP_PORT:
RETAILMSG( 1, ( TEXT( "DBT_DEVTYP_PORT\r\n" ) ) );
{
DEV_BROADCAST_PORT *port = (DEV_BROADCAST_PORT *)hdr;
RETAILMSG( 1, ( TEXT( "Device = %s\r\n" ), port->dbcp_name ) );
}
break;
}
}
break;
}
}
-----

I don't have a serial card to try, but network cards return DBG_DEVTYP_PORT
and the docs seem to indicate that the same would be true of serial ports.

Paul T.
 
MSDN has good documentation on the parameters that come with that message.
That's how I found out that it seems like it should be good enough. Here's
some of the C I used:
I don't have a serial card to try, but network cards return DBG_DEVTYP_PORT
and the docs seem to indicate that the same would be true of serial ports.

Thanks! That is exactly what I needed! It does return the port name for my
serial card as you mentioned.
Thank you for all of your help!! :)
 
Back
Top