Re: Issue with pinvoking DeviceIoControl: switching USB function driver at run time



Thanks a lot Chris !

It works in C, and I could find out what the error was all about.
Looks like the string needed to exactly match the WinCE data type _TCHAR
array.

All this time I was sending just a 12 byte string. ("Mass_Storage_Class") so
I used
Marshal.StringToBSTR() to get me a IntPtr after allocating a COM-style
Unicode string.

Here's the code I tested for switching to USB function driver to
"mass_storage_class" tested on WM 6.1, CF 3.5:

[DllImport("coredll", SetLastError = true)]
static extern IntPtr CreateFile(String lpFileName,
UInt32 dwDesiredAccess,
UInt32 dwShareMode,
IntPtr lpSecurityAttributes,
UInt32 dwCreationDisposition,
UInt32 dwFlagsAndAttributes,
IntPtr hTemplateFile);

[DllImport("coredll.dll", SetLastError = true, CallingConvention =
CallingConvention.Winapi, CharSet = CharSet.Auto)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CloseHandle(HANDLE hObject);

[DllImport("coredll.dll", EntryPoint = "DeviceIoControl",
SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal unsafe static extern bool DeviceIoControl(
IntPtr hDevice,
uint dwIoControlCode,
IntPtr lpInBuffer, //byte[] lpInBuffer, // LPVOID lpInBuffer -
any input data required for the IOCTL
uint nInBufferSize,
byte[] lpOutBuffer, //IntPtr lpOutBuffer,
uint nOutBufferSize,
ref uint lpBytesReturned,
IntPtr lpOverlapped);

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct UFN_CLIENT_NAME
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
public string szName;
}

public void SwitchToMassStorage()
{
UFN_CLIENT_NAME ClientName = new UFN_CLIENT_NAME();
uint dwBytes = 0;

ClientName.szName = "Mass_Storage_Class";

IntPtr pClientInfo = Marshal.StringToBSTR(ClientName.szName);

bool ioctl_ret;
HANDLE getUSBfnHandle = GetUfnController("UFN*");

ioctl_ret = DeviceIoControl(getUSBfnHandle,
IOCTL_UFN_CHANGE_CURRENT_CLIENT,
pClientInfo,
256,
null, // empty lpOutBuffer
0, // no nOutBufferSize
ref dwBytes,
IntPtr.Zero);

if (ioctl_ret)
{
MessageBox.Show("DeviceIoControl success !\n");
}
else
{
MessageBox.Show("DeviceIoControl failed !\n Error: " +
Marshal.GetLastWin32Error());
}
}

public IntPtr GetUfnController(string searchParamString)
{
IntPtr hUfn = IntPtr.Zero;

if (searchParamString == null)
searchParamString = "UFN*";

IntPtr pguidBus = Marshal.StringToBSTR(searchParamString);

DEVMGR_DEVICE_INFORMATION pdi = new DEVMGR_DEVICE_INFORMATION();
pdi.dwSize = (uint)System.Runtime.InteropServices.Marshal.SizeOf
(typeof(DEVMGR_DEVICE_INFORMATION));

HANDLE hf = FindFirstDevice(0,//DeviceSearchType.
DeviceSearchByDeviceName,
pguidBus,
ref pdi);


if ((int)hf != INVALID_HANDLE_VALUE)
{
//hUfn = CreateFile(pdi.szBusName, GENERIC_READ,
FILE_SHARE_READ,
//NULL, OPEN_EXISTING, 0, NULL);
hUfn = CreateFile(pdi.szBusName,
0x80000000,//GENERIC_READ, // Open
for reading
0,//FILE_SHARE_READ, // Share for
reading
IntPtr.Zero,//NULL, // No
security
3,//OPEN_EXISTING, // Existing file
only
0,//FILE_ATTRIBUTE_NORMAL, // Normal file
IntPtr.Zero);//NULL); // No
template file

CloseHandle(hf);
}
else
{
MessageBox.Show("FindFirstDevice failed ! : "+Marshal.
GetLastWin32Error());
hUfn = (System.IntPtr)INVALID_HANDLE_VALUE;
}

return hUfn;
}

The DLL import may have to be changed slightly (make the byte[] lpOutbuffer
to an IntPtr) if I need to use IOCTL_UFN_GET_CURRENT_CLIENT.

Thanks for all the help,
Rohan

Rohan_Sreeram wrote:
Yes, I tried the Unicode encoding too, but it did not work.
I am sorry I thought native as using WinCE platform dev kit earlier.

I am using Visual Studio 2008 with .Net CF 3.5 for my development, so I will
run a little console app, and try out this in C.

Thanks,
Rohan

If you have the tools for managed development, you have the tools for native
development. testing this with a C console app is probably 10 lines of code
[quoted text clipped - 12 lines]
Thanks,
Rohan

--
Message posted via PocketPCJunkies.com
http://www.pocketpcjunkies.com/Uwe/Forums.aspx/pocketpc-prog/200906/1

.



Relevant Pages

  • Re: Is C# support load device driver?
    ... how to manage driver loading/unloading using both PInvoke interop and WMI. ... string driverName; ... IntPtr fileHandle; ... databaseName, uint dwDesiredAccess); ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: P/Invoking FormatMessage
    ... public static extern int FormatMessage(int dwFlags, IntPtr lpSource, ... int dwMessageId, int dwLanguageId, StringBuilder lpBuffer, int nSize, ... static extern uint FormatMessage(uint dwFlags, IntPtr lpSource, ... public static string GetErrorMessage2 ...
    (microsoft.public.dotnet.framework.compactframework)
  • VirtualAllocEx returns a bad pointer in some processes
    ... (ByVal hWnd As IntPtr, _ ... (ByVal hWndParent As IntPtr, _ ... ByVal lParam As String) As Integer ... Dim aihWnds As ArrayList ...
    (microsoft.public.vc.mfc)
  • Virtual memory C++ problem
    ... (ByVal hWnd As IntPtr, _ ... (ByVal hWndParent As IntPtr, _ ... ByVal lParam As String) As Integer ... Dim aihWnds As ArrayList ...
    (microsoft.public.win32.programmer.kernel)
  • SetPrinter for network printers
    ... Public dmDeviceName As String ... Public pSecurityDescriptor As IntPtr ... Dim pPrinterInfo As IntPtr ...
    (microsoft.public.dotnet.languages.vb)