I am attempting to use RAPI functions in order to put a signed DLL on the
device and call a function on it to return the device type string to the
desktop. Unfortunately I have been unable to actually get this to work with
C#. My DLL is a C++ signed DLL with the correct signature. Currently the
error I am getting when I try to invoke it is 0x8007007E 'The specified
module could not be found'. The DLL code itself works just fine in a test
harness, but when I attempt to call it something fails when I try to write
the output to the output buffer.
I believe the problem lies in the Reflection calls to DllImport rather than
the actual code. The DLL Is copied to the device properly and is in the right
location. Dependency walker shows that the proper externs have been created
and match the required signature for CeRapiInvoke. If, when calling the code
via DllImport I comment out the code that actually writes to the buffer the
function returns successfully so I am reasonably confident that it is my C#
DLLImport statement that is the culprit.
=====
[DllImport("rapi.dll", EntryPoint = "CeRapiInvoke")]// , CharSet =
CharSet.Unicode, CallingConvention = CallingConvention.StdCall, SetLastError
= true)]
private extern static Int32 internal_CeRapiInvoke(
[MarshalAs(UnmanagedType.LPWStr)] string path,
[MarshalAs(UnmanagedType.LPWStr)] string functionName,
UInt32 nBytesInInputBuffer,
[MarshalAs(UnmanagedType.LPArray)] byte[] inputBuffer,
ref UInt32 outputBufferLength,
[MarshalAs(UnmanagedType.LPArray)] byte[] outputBuffer,
IntPtr ppIRAPIStream,
UInt32 reserved);
public Int32 RapiInvoke(string path, string function, UInt32
inputBufferSize, byte[] inputBuffer, UInt32 outputLength, byte[] outputBuffer
)
{
// Apparently this only works with Native function
Int32 hResults = internal_CeGetLastError();
string unicodePath =
UnicodeEncoding.Unicode.GetString(UnicodeEncoding.Unicode.GetBytes(path));
string unicodeFunction =
UnicodeEncoding.Unicode.GetString(UnicodeEncoding.Unicode.GetBytes(function));
Int32 results = internal_CeRapiInvoke(unicodePath,
unicodeFunction, inputBufferSize, inputBuffer, ref outputLength,
outputBuffer, IntPtr.Zero, 0);
hResults = internal_CeGetLastError();
if (hResults != 0)
Marshal.ThrowExceptionForHR(hResults);
return results;
}
=====
byte[] outputBuffer = new byte[4];
uint outputLength = (uint)outputBuffer.Length;
int results = rapi.RapiInvoke( "\\TestTickle\\GetOEMInfo.dll",
"GetOEMString", 0, null, outputLength, outputBuffer);
results is currently equal to -2147024770 when the function returns
Does anyone have any idea what might be incorrect? Has anyone actually
gotten this working in C#?