why is this function failing? - c

I am trying to understand windows hooks by writing a few keyboard hooks.
I have a function:
bool WriteToFile(WPARAM keyCode, char * fileName)
{
ofstream fout("filename");
if(fout.is_open())
{
if(keyCode>=0x030 && keyCode<0x039)
fout<< (keyCode - 0x030);
fout.close();
return true;
}
else fout.close();
return false;
}
...that i try to call from here but it almost always fails. Why?
LRESULT CALLBACK KbHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if(nCode > 0)
{
WriteToFile(wParam,"log.txt"); //this function always fails . Why
}
else return CallNextHookEx(hCurrentHook, nCode, wParam, lParam);
}

I think it's because you're trying to open a file called “filename”, rather than using whatever filename was provided. I assume you're writing a keylogger. It should read:
bool WriteToFile(WPARAM keyCode, char * fileName)
{
// cause output to go to the end of the file by using ios_base::app
ofstream fout(fileName, ios_base::app);
if(fout.is_open())
{
if(keyCode>=0x030 && keyCode<0x039)
fout<< (keyCode - 0x030);
fout.close();
return true;
}
else fout.close();
return false;
}

Related

SetWindowsHookEx - difference between VK_LSHIFT and "Search" keyboard button

I use SetWindowsHookEx to catch keyboard events
SetWindowsHookEx(WH_KEYBOARD_LL, HookCallback, NULL, 0)
Here is HookCallback
LRESULT __stdcall HookCallback(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode >= 0)
{
// the action is valid: HC_ACTION.
if (wParam == WM_KEYDOWN)
{
kbdStruct = *((KBDLLHOOKSTRUCT*)lParam);
printf("%ld\n", kbdStruct.vkCode);
}
}
}
When press "left shift" output is
160
when press "search" button (button with loupe icon on notebooks) output is
160
91
132
How to check if "left shift" or "search" button is pressed inside HookCallback ?
160 is VK_LSHIFT, 91 is VK_LWIN, and 132 is VK_F21. See Virtual-Key Codes. The only standardized Search key is VK_BROWSER_SEARCH, so clearly your keyboard manufacturer is using a non-standard key for its Search key.
You need to remember the keys you see from one event to the next as needed, eg:
bool LeftShiftIsDown = false;
bool LeftWinIsDown = false;
bool F21IsDown = false;
bool SearchIsDown = false;
LRESULT __stdcall HookCallback(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode == HC_ACTION)
{
KBDLLHOOKSTRUCT *kbdStruct = (KBDLLHOOKSTRUCT*) lParam;
if (wParam == WM_KEYDOWN)
{
printf("%ld is down\n", kbdStruct->vkCode);
switch (kbdStruct->vkCode)
{
case VK_LSHIFT:
LeftShiftIsDown = true;
break;
case VK_LWIN:
LeftWinIsDown = true;
break;
case VK_F21:
F21IsDown = true;
break;
}
if (LeftShiftIsDown && LeftWinIsDown && F21IsDown)
{
if (!SearchIsDown)
{
SearchIsDown = true;
printf("Search is down\n");
}
}
}
else if (wParam == WM_KEYUP)
{
printf("%ld is up\n", kbdStruct->vkCode);
switch (kbdStruct->vkCode)
{
case VK_LSHIFT:
LeftShiftIsDown = false;
break;
case VK_LWIN:
LeftWinIsDown = false;
break;
case VK_F21:
F21IsDown = false;
break;
}
if (!(LeftShiftIsDown && LeftWinIsDown && F21IsDown))
{
if (SearchIsDown)
{
SearchIsDown = false;
printf("Search is up\n");
}
}
}
}
return CallNextHookEx(0, nCode, wParam, lParam);
}

How to block printing functionality(CTRL + P) on windows text editors?

I want to block printing functionality(CTRL + P) on windows platform for specific applications. I am doing it using keyboard hook. I am able to detect CTRL + P but I am not able to stop it. I am returning from hook procedure in case of CTRL + P but application still receives this message and process printing.
LRESULT __declspec(dllexport)__stdcall CALLBACK KeyboardProc(
int nCode,
WPARAM wParam,
LPARAM lParam)
{
FILE* f1;
static WPARAM wPrevParam;
if (((DWORD)lParam & 0x40000000) && (HC_ACTION == nCode))
{
if ((wParam == VK_SPACE) || (wParam == VK_RETURN) || (wParam == VK_CONTROL) || (wParam >= 0x2f) && (wParam <= 0x100))
{
char ch;
f1 = fopen("d:\\report.txt", "a+");
if (wParam == VK_CONTROL)
{
if (wPrevParam == 0x50)// 0x50 = P
{
const char* text = "CTRL-P detected.";
fwrite(text, strlen(text), 1, f1);
fclose(f1);
wParam = 0;
lParam = 0;
return 1;
}
const char *text = "CTRL";
fwrite(text, strlen(text), 1, f1);
fprintf(f1, "%02X\n", (unsigned char)wParam);
}
else
{
wPrevParam = wParam;
}
fclose(f1);
}
}
LRESULT RetVal = CallNextHookEx(hkb, nCode, wParam, lParam);
return RetVal;
}
I want to block printing functionality(CTRL + P) on windows platform
for specific applications. I am doing it using keyboard hook. I am
able to detect CTRL + P but I am not able to stop it.
This blocks [Ctrl] + "P" in a WH_KEYBOARD_LL hook... but won't prevent printing by [File] [Print] or other way of course... =>
LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
DWORD dwKey = 0;
if (HC_ACTION == nCode)
{
KBDLLHOOKSTRUCT *pkbdll = (KBDLLHOOKSTRUCT*)lParam;
dwKey = pkbdll->vkCode;
BOOL bCtlDown = GetKeyState(VK_CONTROL) < 0;
if (bCtlDown && dwKey == 'P')
{
Beep(6000, 10);
return 1;
}
}
return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);
}
Windows application to block CTRL + P using WH_KEYBORAD_LL hook works. So working code snippet will be as follows:
#include<fstream>
#include<windows.h>
using namespace std;
ofstream out("logs.txt", ios::out);
LRESULT CALLBACK keyboardHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
static bool controlPressed = false;
PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT)(lParam);
if (wParam == WM_KEYDOWN)
{
if (p->vkCode == VK_LCONTROL || p->vkCode == VK_RCONTROL)
{
controlPressed = true;
}
else if (char(tolower(p->vkCode)) == 'p' && true == controlPressed)
{
out << "<CONTROL + P Detected>";
return 1;
}
else
{
controlPressed = false;
}
}
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
HHOOK keyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL,
keyboardHookProc,
hInstance,
0
);
MessageBox(NULL, TEXT("Press OK to stop blocking of printing."), TEXT("Information"), MB_OK);
out.close();
return 0;
}

Simple if comparison doesn't work with char

I am creating a DLL to check when the user presses the close button on the application window, it works fine, then I want to do it so that when _text global variable is empty, no message will be shown.
I can't understand why a simple if (_text != "") doesn't work... am I doing something wrong?
#include <windows.h>
#define export extern "C" __declspec (dllexport)
WNDPROC GameWndProc = NULL;
HWND GameHwnd = NULL;
double _button_result = 0;
char* _text;
char* _title;
LRESULT CALLBACK SubClassWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg) {
case WM_CLOSE:
if (_text != "") {
if (MessageBox(GameHwnd, (LPSTR)_text, (LPSTR)_title, MB_YESNO|MB_APPLMODAL) == IDYES) {
_button_result = 1;
return 0;
} else {
return 0;
}
}
_button_result = 1;
return 0;
break;
}
return CallWindowProc(GameWndProc, hwnd, uMsg, wParam, lParam);
}
export double _window_check_close_init(double window_handle, char* _msg_text, char* _msg_title)
{
GameHwnd = (HWND)(int)window_handle;
GameWndProc = (WNDPROC)SetWindowLongPtr(GameHwnd, GWL_WNDPROC, (LONG)SubClassWndProc);
_text = _msg_text;
_title = _msg_title;
if (!GameWndProc) {
return 0;
}
return 1;
}
export double _window_check_close()
{
if (_button_result == 1) {
_button_result = 0;
return 1;
} else {
return 0;
}
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
if (fdwReason == DLL_PROCESS_DETACH) {
if (IsWindow(GameHwnd) && GameWndProc) {
SetWindowLongPtr(GameHwnd, GWL_WNDPROC, (LONG)GameWndProc);
}
}
return TRUE;
}
You're checking if the pointer _text is equal to the empty string, not if the string pointed to by _text is equal to the empty string. You probably want to do something like:
if (strlen(_text) !=0)
... rest of your code...
Use strcmp() to compare strings:
if (strcmp(_text, "") != 0) {
}
Just to clarify the difference between pointers and contents of the location to which pointer points:
char* _text : The variable 'text' is a pointer. If you look at it in a debugger it would hold a hex value which would be a memory address. In your case _text holds the address of the string _msg_text
_text != "" : You are comparing two pointers, not their contents. "" in this statement is returning the location of the null string which would again be some hex value which is a memory address.
What you need to do is compare the contents of _text with the null string ""
The above answers are correct.

Returning HTTRANSPARENT for WM_NCHITTEST in a plugin

How can I get a plugin to make the program have my clicks go though the window? I heard I would have to return HTTRANSPARENT for WM_NCHITTEST. Is it possible to do that with hooking? This is as far as I have got in my hook:
LRESULT CALLBACK myHook(int nCode, WPARAM wParam, LPARAM lParam)
{
CWPSTRUCT* pwp = (CWPSTRUCT*)lParam;
if (nCode >= 0)
{
if (pwp->message==WM_NCHITTEST)
MessageBox(NULL, TEXT("NCHITTEST has been receieved."), TEXT("NCHITTEST"), MB_ICONINFORMATION);
}
return CallNextHookEx(hHook,nCode,wParam,lParam);
}

how to handle click event in win32 API?

I have created a simple win 32 application..in which it has a textbox and a button in a dialog window..first when I created this..it didnt display the dialog window and then what I did is added the code below to handle the close(WM_CLOSE) of the dialog window...but I want to know, how to handle the button click event..
void ValidatePassword(CString encryptedPassword)
{
//create password dialog window
CreateEvent(NULL,true,false,L"TestEvent");
MSG msg;
HWND hwnd = CreateWindowEx(0,WC_DIALOG,L"Security Alert",WS_OVERLAPPEDWINDOW|WS_VISIBLE,
600,300,300,200,NULL,NULL,NULL,NULL);
//create label
CreateWindowEx(NULL,L"Static",L"Requires Password to Run the File:", WS_CHILD|WS_VISIBLE,
10,25,300,20,hwnd,(HMENU)label_id,NULL,NULL);
//create textboxcontrol within the dialog
CreateWindowEx(WS_EX_CLIENTEDGE,L"EDIT",L"",WS_CHILD|WS_VISIBLE | ES_PASSWORD,
10,50,125,25,hwnd,(HMENU)textbox_id,NULL,NULL);
//create button
HWND button = CreateWindowEx(WS_EX_CLIENTEDGE,L"Button",L"OK",WS_CHILD|WS_VISIBLE,
10,100,100,25,hwnd,(HMENU)button_id,NULL,NULL);
ShowWindow (hwnd, SW_SHOW);
UpdateWindow(hwnd);
//SetWindowLong(button,DWL_DLGPROC, (long)myProc);
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
LRESULT WINAPI myProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HWND hwndButton;
switch (message)
{
/* Handles all Windows Messages */
case WM_COMMAND:
{
if(((HWND)lParam) && (HIWORD(wParam) == BN_CLICKED))
{
int iMID;
iMID = LOWORD(wParam);
switch(iMID)
{
case button_id:
{
MessageBox(hwnd, (LPCTSTR)"You just pushed me!", (LPCTSTR) "My Program!", MB_OK|MB_ICONEXCLAMATION);
break;
}
default:
break;
}
}
break;
}
case WM_DESTROY:
{
PostQuitMessage (0); /* send a WM_QUIT to Message Queue, to shut off program */
break;
}
}
return 0;
}
Yikes.
It should not be necessary to call SetWindowLong to set the dialog proc for a dialog. Your "simple" program should look something like
#include <windows.h>
#include "resource.h"
BOOL CALLBACK myProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_INITDIALOG:
return TRUE;
case WM_COMMAND:
if( LOWORD(wParam) == IDCLOSE) // close button click
EndDialog(hwnd,0);
return TRUE;
}
return FALSE;
}
int CALLBACK WinMain(HINSTANCE hExe,HINSTANCE,LPCSTR,INT)
{
return DialogBox(hExe,MAKEINTRESOURCE(IDD_DIALOG),NULL,myProc);
}
Check for WM_COMMAND. LOWORD(wParam) will be your control ID and lParam will be your hWnd for the button.

Resources