HRESULT: 0x8007007E occur at FindFirstDevice

  • Thread starter Thread starter Chan Cooper
  • Start date Start date
C

Chan Cooper

I had tried as you post but I get an error ?HRESULT: 08007007E at statement FindFirstDevice. I am using Visual Studio 2005 and my code is as the following:


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;


namespace WindowsApplication1
{
public partial class Form1 : Form
{
bool CAMexist = false;

public struct DEVMGR_DEVICE_INFORMATION
{
public uint 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
}


public static readonly Guid GuidCamera = new Guid("CB998A05-122C-4166-846A-933E4D7E3C86");


[DllImport("coredll.dll")]
public static extern IntPtr FindFirstDevice(
[In] DeviceSearchType searchType,
//[In] int searchType,
[In] IntPtr searchParam,
[In, Out] ref DEVMGR_DEVICE_INFORMATION pdi);

[DllImport("coredll.dll")]
public static extern int FindClose([In] IntPtr hFindFile);


public Form1()
{
InitializeComponent();
}


private void timer1_Tick(object sender, EventArgs e)

{
IntPtr handle = IntPtr.Zero;
DeviceSearchType searchType = DeviceSearchType.DeviceSearchByGuid;

IntPtr searchParam = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Guid)));

Marshal.StructureToPtr(GuidCamera, searchParam, false);

DEVMGR_DEVICE_INFORMATION di = new DEVMGR_DEVICE_INFORMATION();

di.dwSize = (uint)Marshal.SizeOf(typeof(DEVMGR_DEVICE_INFORMATION));

handle = FindFirstDevice(searchType, searchParam, ref di);

if (CAMexist == true)
{
CAMtextBox.Text = "Camera exist";
}
else
{
CAMtextBox.Text = "Camera not exist";
}
}
}
}


After compile, I run it under debug mode. Then the error occurs at statement FindFirstDevice with HRESULT: 0x8007007E. What should I do to fix it?

I am just a novice in Visual Studio and the project is very tight in time. I need your help.

Thank you.







Jarvius wrote:

Greetz,I desperately needed some sample C# code using FindFirstDevice, and so
07-Aug-09

Greetz

I desperately needed some sample C# code using FindFirstDevice, and so I started from the code posted here, which has finally been a valuable help for my current project. :

Nevertheless, I had to make some changes, and though I am not allowed to post full code, I guess commenting how to make it work will harm no one... ;

1. First of all, FindFirstDevice will be of no use unless you use FindNextDevice as well, as you will get a list of devices, not just one - it looks like you are stuck on wildcards. :-P Notice that FindNextDevice will use the handle returned by FindFirstDevice as its first argument, which should not be INVALID_HANDLE_VALUE (-1), and will return True if there are more items to be looked for, so it could be used as a stop condition for your search loop besides comparing the values (szLegacyName) in your pdi - you will have to check both the first pdi returned by FindFirstDevice as well as the new ones that you will get when calling FindNextDevice

2. If you are serching for COM#:, do not use DeviceSearchByDeviceName, but DeviceSearchByLegacyName instead. Subsequently, pdi.szLegacyName should be the member to go for. I would strongly recommend you setting breakpoints so that you gt to read the full pdi values and see what you can really expect out of it.

3. Remove the IntPtr searchParam = Marshal.AllocHGlobal(searchParamString.Length); line, which is of no use... The line IntPtr searchParam = Marshal.StringToBSTR(searchParamString); already allocates the required memory. Also, remember to be nice and call Marshal.FreeBSTR after FindFirstDevice, so that the unmanaged memory reserved for your string gets deallocated - usual suspect of memory leaks in .Net apps?

4. Finally, and most important point of it all, FindFirstDevice will fail *unless you set pdi.dwSize to its right value*, which you should do right after doing pdi = new ... - pdi.dwSize = (uint)Marshal.SizeOf(pdi); will do.

I hope it helps anyone who has to go through unmanaged (and poorly documented) code in C# as I have had to these days.

Posted via DevelopmentNow.com Groups
http://www.developmentnow.com/g/

Previous Posts In This Thread:

FindFirstDevice and C#
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
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.
Greetings,

Thanks for your reply.

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.

This code is not working correctly because it can't find the method
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?
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.
it is in coredll.dll, if it is in your OS at all. Back up and tell us wha
you are trying to monitor for, what version of Windows CE, what device, etc

Paul T.

It is a rs-232 device which connects to the pocket pc device via the cf card.
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

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.

Re: FindFirstDevice and C#
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!
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.


That makes sense about why I can't get access to it.
That makes sense about why I can't get access to it.
I didn't notice that in the msdn docs, good find! :)



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.
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.



Thanks! That is exactly what I needed!
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!! :)

Greetz,I desperately needed some sample C# code using FindFirstDevice, and so
Greetz,

I desperately needed some sample C# code using FindFirstDevice, and so I started from the code posted here, which has finally been a valuable help for my current project. :)

Nevertheless, I had to make some changes, and though I am not allowed to post full code, I guess commenting how to make it work will harm no one... ;)

1. First of all, FindFirstDevice will be of no use unless you use FindNextDevice as well, as you will get a list of devices, not just one - it looks like you are stuck on wildcards. :-P Notice that FindNextDevice will use the handle returned by FindFirstDevice as its first argument, which should not be INVALID_HANDLE_VALUE (-1), and will return True if there are more items to be looked for, so it could be used as a stop condition for your search loop besides comparing the values (szLegacyName) in your pdi - you will have to check both the first pdi returned by FindFirstDevice as well as the new ones that you will get when calling FindNextDevice.

2. If you are serching for COM#:, do not use DeviceSearchByDeviceName, but DeviceSearchByLegacyName instead. Subsequently, pdi.szLegacyName should be the member to go for. I would strongly recommend you setting breakpoints so that you gt to read the full pdi values and see what you can really expect out of it.

3. Remove the IntPtr searchParam = Marshal.AllocHGlobal(searchParamString.Length); line, which is of no use... The line IntPtr searchParam = Marshal.StringToBSTR(searchParamString); already allocates the required memory. Also, remember to be nice and call Marshal.FreeBSTR after FindFirstDevice, so that the unmanaged memory reserved for your string gets deallocated - usual suspect of memory leaks in .Net apps?

4. Finally, and most important point of it all, FindFirstDevice will fail *unless you set pdi.dwSize to its right value*, which you should do right after doing pdi = new ... - pdi.dwSize = (uint)Marshal.SizeOf(pdi); will do.

I hope it helps anyone who has to go through unmanaged (and poorly documented) code in C# as I have had to these days.

Posted via DevelopmentNow.com Groups
http://www.developmentnow.com/g/

EggHeadCafe - Software Developer Portal of Choice
Spambot Killer ASP.NET Mailto: Hyperlink Control
http://www.eggheadcafe.com/tutorial...97-f0235cdcb480/spambot-killer-aspnet-ma.aspx
 
Back
Top