This question already has an answer here:
How to use Rundll32 to execute DLL Function?
(1 answer)
Closed 7 years ago.
How I could properly call the SetCursorPos function from windows RunDll32 application?
If I try this, it sends the cursor to bottom-right corner:
RunDll32.exe user32.dll,SetCursorPos 100, 100
But I'm passing the proper values to its parameters:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms648394%28v=vs.85%29.aspx
PS: I'm not interested in alternatives like for example NirCMD application, I know them, I only would like to know the answer to the question I did, thankyou.
This isn't possible. RunDll32 can only call functions with this signature:
void CALLBACK EntryPoint(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow);
So if you do
RunDll32.exe user32.dll,SetCursorPos 100 100
You are telling RunDll32.exe to do this:
SetCursorPos(0x314159, 0x265358, "100 100", 1)
...were the first two parameters are not in your control (for example, in my machine the call moves the cursor to the upper right).
More info from the docs:
hwnd - window handle that should be used as the owner window for
any windows your DLL creates
hinst - your DLL's instance handle
lpszCmdLine - ASCIIZ command line your DLL should parse
nCmdShow - describes how your DLL's windows should be displayed
Related
Win32 programs have an entry parameter HINSTANCE for the Win32 entry function WinMain(). When you create your own window, the CreateWindow() API call needs this parameter.
My first idea in my mind is that this HINSTANCE should be some unique identify to distinguish different windows belong to different processes. Until recently, in some occasions, I use this HINSTANCE. Wow! If you open the same Win32 program (EXE) twice, each process has the same HINSTANCE value.
Later I figured out, it was some resource identifier (memory address) in the process. It's a virtual address for the process which is related to its PE structure in memory.
Now, if I have the two windows' HWND handles, and I want to check whether the two windows are from the same process, what is the best choice?
You can use the GetWindowThreadProcessId function to retrieve the ID of the process that created a window, given that window's HWND.
Below is a brief C code snippet showing how. We check that the return value of each GetWindowThreadProcessId() call is not zero (see this answer or this blog by Raymond Chen), to ensure that we have passed valid HWND handles.
// win1 and win2 are both HWND handles to check...
DWORD proc1, proc2;
if (!GetWindowThreadProcessId(win1, &proc1)) { // Error (invalid HWND?)
//.. error handling
}
if (!GetWindowThreadProcessId(win2, &proc2)) {
//..
}
if (proc1 == proc2) {
// Windows created by same process
}
else {
// Windows created by different processes
}
GetWindowThreadProcessId can do the work. Record here.
An interactive way to do this would be to use Microsoft's Spy++, which lets you find the Process ID, Thread ID, and parents/children of a window by point-and-clicking its GUI.
You can also find window handles (and plenty of other window-specific data) in this way.
I'd like to use PrintUIEntryW (of printui.dll ) to install a printer driver on Windows system. My code looks like following (pseudo).
m = LoadLibrary(L"printui.dll");
printuientry = GetProcAddress(m, "PrintUIEntryW");
// set arg_string
printuientry(NULL, m, arg_string, SW_SHOW);
Could I check the return value of the function or something like GetLastError() to check if the desired call is successful? There seems no msdn entry for this function.
Thanks in advance.
PrintUIEntry is documented here:
Rundll32 printui.dll,PrintUIEntry
rundll32 is documented is here:
INFO: Windows Rundll and Rundll32 Interface
Most importantly:
In your DLL, write the function with the following prototype:
16-bit DLL:
void FAR PASCAL __loads EntryPoint(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow);
32-bit DLL:
void CALLBACK EntryPoint(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow);
...
On Windows NT, Windows 2000, and Windows XP the behavior of Rundll32.exe is slightly different, in order to accommodate UNICODE command lines.
Windows NT first attempts to GetProcAddress for W. If this entry point is found, then the prototype is assumed to be:
void CALLBACK EntryPointW(HWND hwnd, HINSTANCE hinst, LPWSTR lpszCmdLine, int nCmdShow);
This is the same as the ANSI EntryPoint, except that the lpszCmdLine parameter is now a UNICODE string.
As you can see, functions designed to be used with rundll32 do not have a return value. And PrintUIEntry is not documented as using SetLastError() for error reporting. So, in this case, you cannot do any kind of error handling. You will have to use a different API that reports errors.
I'm trying to use function SetForegroundWindow(HWND hWnD). I have some handles but it's not working as parameter of above function. My handle is a thread and I want to run it in foreground.
What are the differences between a HWND and a HANDLE?
They are just abstract data types.
According to MSDN, HANDLE and HWND are defined as:
HANDLE is a handle to an object.
HWND is a handle to a window.
So, a HWND is a HANDLE, but not all HANDLEs are HWND. In fact:
typedef void *PVOID;
typedef PVOID HANDLE;
typedef HANDLE HWND;
Example
You should only pass HWND to SetForegroundWindow unless you know what you are doing.
HWND hWnd = FindWindow(NULL, "Calculator");
SetForegroundWindow(hWnd);
This first gets the handle to a window titled "Calculator" with FindWindow and then brings that window to foreground.
A "handle" is the general term used to refer to a token that identifies a resource on the system (a menu, a DLL module, a block of memory, etc). Often referred to as a "magic cookie", it's normally returned when you first create the resource. You then pass that handle to other functions in the API responsible for processing the resource. You normally need not know what the handle is however. Sometimes it may be a pointer, other times a number, perhaps a structure, or whatever. That's why they hide it using names like HWND which is simply the handle used to identify a window (returned by the API function "CreateWindow()"). You therefore don't convert a "handle" to an HWND and back again since an HWND is already a "handle" (one that merely identifies windows you create).
Found here http://forums.codeguru.com/showthread.php?135438-Handle-and-HWND
You can use FindWindow to get the hwnd from an application http://msdn.microsoft.com/en-us/library/windows/desktop/ms633499(v=vs.85).aspx
This should allow you to get the HWND provided you have the handle to what you're looking for C++ Handle as HWND?
The HWND is also a HANDLE, but a global one.
I.e. a HWND valid in the context of one process is also valid in the context of another process.
Some undocumented info at https://winterdom.com/dev/ui/wnd/.
I've always been curious on what nCmdShow means in WinMain of a C program using Windows API.
I looked up the formal explanation: "Controls how the window is to be shown. This parameter can be one of the following values.".
I do not understand what that means, as a Windows program can contain more than one window, or no windows at all. In addition, as program begins, there is no window to be shown to begin with, which makes me question this argument even more.
Also from what I read, it always stays 10, which isn't even on the list of options in "http://msdn.microsoft.com/en-us/library/windows/desktop/ms633559%28v=vs.85%29.aspx"...
Is it obsolete? Can somebody explain its purpose, or provide any references explaining its use? I tried googling but saw nothing.
Thanks!
REVISITED:
When you right click a shortcut and go to properties, there is an option to start the window Minimized, Maximized, or Normal(ly).
Windows provides an nCmdShow to your program in case it wants to act in a special way if it was launched in any of these three ways. For example, it may hide itself inside notification bar if it was requested to be started minimized.
For exhaustiveness:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms633548(v=vs.85).aspx describes all the different ways that may be passed.
It is basically a hint to the application how it should show its main window. Although it is legacy, it is not as legacy as the hPrevInstance parameter. But, I digress...
The value of the nCmdShow parameter will be one of the constants specified in ShowWindow's API reference. It can be set by another process or system launching your application via CreateProcess. The STARTUPINFO struct that can optionally be passed to CreateProcess contains a wShowWindow member variable that will get passed to WinMain through the nCmdShow parameter.
Another way the nCmdShow parameter is passed is via calls to ShellExecute.
Off the top of my head, I can't think of any scenario (in recent versions of Windows) in which the operating system will explicitly pass a value other than SW_SHOW when launching an application.
It's not uncommon nor bad for an application to ignore the nCmdShow flag passed to WinMain[?].
Note this section from the ShowWindow documentation:
nCmdShow: This parameter is ignored the first time an application calls ShowWindow, if the program that launched the application provides a STARTUPINFO structure.
Even though your program has no window when it starts, the specified value gets implicitly used the first time you eventually call ShowWindow. (It's not read directly from WinMain's local nCmdShow variable, though, so you can't change its value within WinMain and expect to get different results. In that sense, it's not particularly useful unless your program needs to do something special if it's started minimized or maximized.)
The "n" in nCmdShow means "Short int".
(This is what I wanted to know when I came to this stack overflow page)
Source:
https://msdn.microsoft.com/en-us/library/windows/desktop/aa378932(v=vs.85).aspx
nCmdShow is integer type,this parameter specifies how the application windows should be display( to O.S.)
If no value is specified by you than by default Windows O.S. say SW_NORMAL value of this param.
You can specify values of this parameter , but those who passed to WinMain() only for Windows O.S
I'm playing around with SetWindowsHookEx, specifically I would like be able to find out about any window (on my desktop) thats been activated, via mouse or keyboard.
Reading through MSDN docs for SetWindowsHookEx it would appear that a WH_CBT type would do the job. I've created a dll and put all the code in there, which I control from a gui app (which also handles the unhook).
BUT I only appear to be getting the activation code when I activate my gui app though, any other app I activate is ignored.
In my dll I have the setup code and the CBTProc like so:
LRESULT WINAPI CBTProc(int Code, WPARAM W, LPARAM L) {
if(Code<0) CallN....
if (Code == HCBT_ACTIVATE) { // never get unless I activate my app
HWND a = reinterpret_cast<HWND>(W);
TRACE("this window was activated %d\n", a);
}
CallNext....
}
EXPORTED HHOOK WINAPI Setup(HWND MyWind) {
...
// gDllUInstance set in dllmain
return SetWindowsHookEx(WH_CBT, CBTProc, gDllUInstance, 0);
}
All pretty simple stuff, i've tried moving the setup out of the dll but I still get the same effect.
It would appear that the dll is getting loaded into other processes, I'm counting the number of DLL_PROCESS_ATTACHs I'm getting and can see its going up (not very scientific i know.
NOTE that this is 32 bit code running on 32bit OS - win2k3.
Are my expectations of the hooking mechanism wrong? should I only be getting the activation of my app or do I need a different type of hook?
EDIT: the trace function writes to a file telling me whats sending me activations
TIA.
Turns out its working ok, as Hans points out, i'm just not seeing the output from the debugger from the other processes, if I put in some extra tracing code - one trace file per attached process - I can see can see that things are working after all.
Many thanks for the replies.