I know you are gonna hate me for that kind of question. But could somebody tell me what the following code is doing?
I mean there are some libraries loaded, i get that. plus there are some methods, still I don't get it.
F.e.:
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
Here is the code:
private static class API
{
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr SetWindowsHookEx(
int idHook,
HookDel lpfn,
IntPtr hMod,
uint dwThreadId);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool UnhookWindowsHookEx(IntPtr hhk);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr CallNextHookEx(
IntPtr hhk,
int nCode,
IntPtr wParam,
IntPtr lParam);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr GetModuleHandle(
string lpModuleName);
}
You do not have to explain it to me line for line. At least give me some reference where I can read it up, please.
Thx in advance!
This code is using P/Invoke to allow C# code to call several Win32 API functions related to Windows Hooks.
The posted code only defines the methods; it doesn't call them, so it doesn't do anything by itself. It just allows you to use the methods from other parts of your code.
Here's an older MSDN article explaining P/Invoke and what's going on. Hopefully this helps you.
What the code is doing is allowing your managed C# code to call unmanaged Win32 API functions.
Here's also a tutorial on MSDN that walks you through the P/Invoke process of creating code like your question has.
DllImport is used to call unmanaged code/API in .Net/Managed code. All the code you've posted is trying to work with the window object of Win32 API.
References:
DLLImport
Win32 API
Win32 API to .Net API map
Take a look at this. Your program somewhere is installing a hook into windows hook chain to monitor some events.
The dllimport attribute itself lets the program to invoke win32 api functions like the previous answer mentions.
Related
I'm trying to use a native API method (GetNativeSystemInfo) that is marked as supported for both phone and desktop Store apps on Windows 8.1. In the documentation, it is listed as living in kernel32.dll. Great! So my first attempt at P/Invoke looked like this:
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, ExactSpelling = false, PreserveSig = true)]
private static extern void GetNativeSystemInfo(ref SYSTEM_INFO lpSysInfo);
Unfortunately this fails to run on actual devices - kernel32 is not found! As it happens, there is kernelBase.dll, and thus my second attempt:
[DllImport("kernelBase.dll", CharSet = CharSet.Unicode, ExactSpelling = false, PreserveSig = true)]
private static extern void GetNativeSystemInfo(ref SYSTEM_INFO lpSysInfo);
While this runs fine on my phone, it causes the app to fail certification; the method name and "kernelBase.dll" don't seem to be whitelisted.
Is this an oversight of WACK, or a bug that renders this API unusable in Store apps? My goal is to get information about the running processor (architecture, type, etc), and I'd prefer not to drop in to C++ for something this simple. If this API is not usable in practice, is there another way to get this info?
You'll need different pinvoke signatures for the Windows Phone and the Windows Store versions. For the phone reference GetNativeSystemInfo from api-ms-win-core-sysinfo-l1-2-0.dll
#if WINDOWS_PHONE_APP
[DllImport("api-ms-win-core-sysinfo-l1-2-0.dll", CharSet = CharSet.Unicode, ExactSpelling = false, PreserveSig = true)]
private static extern void GetNativeSystemInfo(ref SYSTEM_INFO lpSysInfo);
#else
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, ExactSpelling = false, PreserveSig = true)]
private static extern void GetNativeSystemInfo(ref SYSTEM_INFO lpSysInfo);
#endif
See Supported Win32 APIs for Windows Phone 8 for a list (targetted for SL, but also valid for your Runtime app). The right reference will be automatically referenced if you call the function natively, but the tooling isn't there to do so for pinvoke. In general wrapping the function in a native Windows Runtime Component is easier than p-invoke, unless you only have a few, simple p-invokes.
I'm writing a super-simple ultra-lite weight .Net wrapper for the LibVLC media library since the only things I need access to are the ability to play, pause and stop media files. I've posted a couple of questions on this and gotten some answers but unfortunately I'm just left with more questions.
We'll start from the top and work down.
The documentation first states I have to initialize VLC with a call to the function with this specification:
libvlc_instance_t* libvlc_new (int argc, const char *const *argv)
for which I have the defined the following method:
[DllImport("libvlc", EntryPoint = "libvlc_new",
CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr NewCore(int argc, IntPtr argv);
And I'm calling the function like this:
private IntPtr Instance;
this.Instance = DGLibVLC.NewCore(0, IntPtr.Zero);
I have tried it several different ways. Initially I did not know about the CallingConvention which was leading to an unbalanced stack which brought me here in the first place. That issue was resolved and the method has gone through several iterations, none of which have proved successful, by which I mean IntPtr is always 0 after the method call. I've tried it like it is above, with the second argument being String[] argc, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPStr)] string[],
I've tried having it return to a Long (which actually resulted in the Long having a value in it), but nothing so far has worked correctly.
Does anyone know the correct way to call this function from the LibVLC DLL Library?
EDIT: On a suggestion I tried calling the error message function of the library:
Specification:
const char* libvlc_errmsg (void)
Implementation:
[DllImport("libvlc", EntryPoint = "libvlc_errmsg",
CallingConvention = CallingConvention.Cdcel)]
public static extern string GetLastError();
Call:
Console.WriteLine(DGLibVLC.GetLastError());
Result:
Null
The documentation states it will return Null if there is no error. This must indicate that the initial function call NewCore was working correctly but something is still going wrong somehow.
To be cover all bases I checked that the DLLs match the documentation, they do. 2.0.6.0. The documentation I am referencing is here.
EDIT: I can confirm there is no error. When using an initialized to zero long variable to store the result of NewCore I can see it returning something. What I am doing wrong here is where I am trying to store the pointer being returned by the unmanaged function that returns the pointer to the object. How do I store the pointer to the opaque structure reference being passed back?
It doesn't have anything to do with the way you call the function. You cannot get anywhere when you get IntPtr.Zero back from libvlc_new(). It means "there was an error". You'll need to focus on error reporting first, call libvlc_errmsg() to try to get a description for the problem.
So after much looking around and asking questions I've come full circle.
I looked deeply into LibVLC.Net and found how they were importing the DLL functions and adapted what they did to my own wrapper and it worked.
To summarize:
There are some Win32 API functions declared in the code at the start:
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool SetDllDirectory(string lpPathName);
[DllImport("kernel32", SetLastError = true)]
private static extern IntPtr LoadLibrary(string lpFileName);
[DllImport("kernel32", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)]
private static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool FreeLibrary(IntPtr hModule);
that handle providing a handle to a dll and setting a directory search path.
I don't know exactly what it all means but when you initialize the LibVLC.Net library (the primary object) it loads pretty much EVERY function like so:
m_libvlc_media_player_new = (libvlc_media_player_new_signature)LoadDelegate<libvlc_media_player_new_signature>("libvlc_media_player_new");
That delegate is defined here like so:
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate IntPtr libvlc_media_player_new_signature(IntPtr p_instance);
//==========================================================================
private readonly libvlc_media_player_new_signature m_libvlc_media_player_new;
//==========================================================================
public IntPtr libvlc_media_player_new(IntPtr p_instance)
{
VerifyAccess();
return m_libvlc_media_player_new(p_instance);
}
And it has a public function that calls the delegate once defined.
I simply stripped down the function that defines the library instance and imported only the functionality I needed.
Thanks very much to everyone who was so patient in helping me along. I likely wouldn't have been able to come to a solution without your help.
EDIT: Okay so it wasn't that. It was the location of the LibVLC Plugin Directory. So it was something stupid -.-;
What is the difference between the usages of DllImport here? Specifically, does "user32" just mean "user32.dll", or does it mean "user32.lib" or something else?
[DllImport("user32")]
protected static extern int GetKeyboardState(byte[] pbKeyState);
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
protected static extern short GetKeyState(int vKey);
You can probably ignore the CharSet and CallingConvention.
If they are the same, I can rewrite this to be more consistent, but if not, I don't want to have a bunch of problems with it.
In this example, there is no difference. The .dll extension will automatically be appended to "user32" to create "user32.dll". However, this is not always the case. If the library file name contains a period, the .dll extension will not be automatically appended.
Some examples:
[DllImport("user32")] --> Resolves "User32.dll". Correct.
[DllImport("user32.dll")] --> Resolves "User32.dll". Correct.
[DllImport("mylib.version5")] --> Resolves "mylib.version5". Incorrect
[DllImport("mylib.version5.dll")] --> Resolves "mylib.version5.dll". Correct.
On Windows there is no difference, the import will be performed successfully if you omit the extension. Normally omitting the extension is desired when running Mono with the <dllmap> configuration section, where the P/Invoke runtime will look for aliases.
I'm having trouble executing this line of code in my MVC application:
IntPtr hModule = LoadLibrary(BondProbeSettings.AssemblyFilePath);
The problem is that hModule is always 0.
If I run the same code with the same value for BondProbeSettings.AssemblyFilePath but from a console application instead of the MVC app hModule is non-zero.
Are there any security issues I need to consider?
The signature for LoadLibrary is:
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
static extern IntPtr LoadLibrary(string lpFileName);
Change the declaration to:
[DllImport("kernel32.dll", CharSet = CharSet.Auto), SetLastError = true)]
static extern IntPtr LoadLibrary(string lpFileName);
And your code to:
IntPtr hModule = LoadLibrary(BondProbeSettings.AssemblyFilePath);
if (hModule == IntPtr.Zero) throw new System.ComponentModel.Win32Exception();
Now you'll know why it doesn't work.
Yep you need to run the site assembly in full trust. I haven't configured this myself but I reckon you need:
to GAC the dll (meaning it has to be strongnamed)
to perhaps configure the application pool in IIS (assuming IIS) to allow full trust (?)
I'm on linux so I can't really help you with screenshots right now
I am developing a Windows Mobile application using WM6 SDK. The application is a Managed code (using C#) & I would like to know the steps to be taken in order to call native functions.
Thanks for the help,
Abdel Olakara
http://www.pinvoke.net/
That should do it.
You need to first declare the native APIs as static extern using DLLImport and then use them like normal methods. Example:
[DllImport("user32.dll", ExactSpelling = true)]
internal static extern IntPtr SetTimer(IntPtr hWnd, IntPtr nIDEvent, int uElapse, IntPtr lpTimerFunc);