Completely new area of tech for me. Trying to communicate with Android device to eventually do read/write of files back and forth. Special requirement, can NOT use ADB.exe which I originally had and worked perfect, but too many security risks/concerns. Can't use 3rd party tools we don't have source control to for static code analysis (such as Fortify).
I have tried to get rid of all the otherwise C/C++ #defines so no guessing at values, and also included the few DLLImports needed.
I found the string for my Android device and get a successful handle via CreateFile(). However, when I try calling the operation code to GetDeviceInfo (0x1001), I get a success = true, but nothing is returned in the buffer. I even tried overpreparing the size to 1k just for grins. This is a complete class self-contained.
So, aside from testing on anybody's own Android device where you would have to find the symbolic name references from the registry, a call to TestConnectToAndroid() is all I am doing. I suspect I will have more questions once I start getting data coming back.
public class IOAndroidTest
{
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern IntPtr CreateFile(
[MarshalAs(UnmanagedType.LPTStr)] string lpFileName,
[MarshalAs(UnmanagedType.U4)] uint dwDesiredAccess, // File Access
[MarshalAs(UnmanagedType.U4)] uint dwShareMode, // File Share
IntPtr lpSecurityAttributes,
[MarshalAs(UnmanagedType.U4)] uint dwCreationDisposition, // File Mode
[MarshalAs(UnmanagedType.U4)] uint dwFlagsAndAttributes, // File Attributes
IntPtr hTemplateFile);
[DllImport("kernel32.dll", CharSet = CharSet.Auto,
CallingConvention = CallingConvention.StdCall,
SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CloseHandle( IntPtr hObject );
[DllImport("kernel32.dll", CharSet = CharSet.Auto,
CallingConvention = CallingConvention.StdCall,
SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool DeviceIoControl(
IntPtr hDevice,
// Control code that tells the device what function to do... and method, access, etc via CTL_CODE()
uint dwIoControlCode, // the I/O Control code
IntPtr lpInBuffer, // pointer to input buffer
uint nInBufferSize, // size of input buffer
IntPtr lpOutBuffer, // pointer to output buffer
uint nOutBufferSize, // size of output buffer
ref uint lpBytesReturned, // ref for return of bytes returned from request
IntPtr lpOverlapped); // pointer if using overlapped
private static uint CTL_CODE(uint DeviceType, uint Function, uint Method, uint Access)
{
return (uint)((DeviceType << 16)
| (Access << 14)
| (Function << 2)
| Method);
}
public void TestConnectToAndroid()
{
var myAndroid = @"\??\USB#VID_05C6&PID_9091#[and rest of device ID and guid from registry]";
uint DesiredAccess = 0x80000000; // generic read
uint ShareMode = 0x1 | 0x2; // Read OR Write share mode
uint BufferedMethod = 0; // for the CTL_CODE building overall op code
uint OpenExisting = 3;
uint InvalidFileHandle = 0xFFFFFFFF;
IntPtr deviceHandle = CreateFile(
myAndroid,
DesiredAccess,
ShareMode,
IntPtr.Zero,
OpenExisting,
0,
IntPtr.Zero);
if (deviceHandle != (IntPtr)InvalidFileHandle)
{
// https://docs.microsoft.com/en-us/windows/win32/api/winioctl/
uint outBufferSize = 1024;
uint requiredLength = 0;
IntPtr readIntoThisBuffer = Marshal.AllocHGlobal((int)outBufferSize);
uint GetDeviceInfo = 0x1001;
// https://docs.microsoft.com/en-us/previous-versions/windows/embedded/ms904001(v=msdn.10)
uint FILE_DEVICE_UNKNOWN = 0x00000022;
uint opCode = CTL_CODE(FILE_DEVICE_UNKNOWN, GetDeviceInfo, BufferedMethod, DesiredAccess);
var success = DeviceIoControl(deviceHandle,
opCode, // GetDeviceInfo built with CTL_CODE above,
IntPtr.Zero, // No input being sent TO the device
0, // input buffer is 0 bytes
readIntoThisBuffer, // IF we are expecting output BACK
outBufferSize, // output buffer size we are PROVIDING
ref requiredLength, // Actual bytes returned IF successful are written to the buffer
IntPtr.Zero );
if (success)
{
if (requiredLength > 0)
Console.WriteLine("There SHOULD be something in the buffer required length");
else
Console.WriteLine("It is always coming here");
}
// Now, free the allocated memory buffer
Marshal.FreeHGlobal(readIntoThisBuffer);
CloseHandle(deviceHandle);
} // end - if good device handle connection
}
}
User contributions licensed under CC BY-SA 3.0