Vallentin Source

Macros & Repetitive Methods


Right now I'm working on this fine window class, and there's a lot of repetitive methods for setting and getting the various event callbacks. Currently the window class supports 19 type events, that's 19 setters and 19 getters that all look the same, besides the small naming difference, and which member they're dealing with of course.

So how can we make all the repetitive code easier to deal with?

The answer is macros! Macros to the rescue!

When you have 19 setters and getters, which all look the same, then these 4 sets of setters and getters are already getting on my nerve. I love the beauty of programming, but writing the exact same thing over and over, starts to get at you.

This is where macros are awesome! We define some macros containing the template for the set and get methods, and we simply use that macro on each event. The following results in the exact same as the above!

Also if anyone is wondering what ## is, then that's called the Token-Pasting Operator. It simply concatenates two tokens into one. Something to notify is that it also strips white-spaces, so get ##eventname## (void) results in exactly the same as get##eventname##(void).


If you want to use this macro, then here's the basic version. Which works for pass/get by value, reference and pointer.

There's 3 things to note.

  1. It only works within the scope of a class or struct
  2. The name must be the exact type-name
    • The name of the method and the type of the parameter is the same.
  3. All the types that use this macro, must be unique
    • e.g. SET(Texture, tex1) followed by SET(Texture, tex2) would obviously generate a compilation error, as now there's two methods with the same name and parameter count.
#define SET(name, member) void set##name##(const name x) { this->member = x; }
#define SET_REF(name, member) void set##name##(const name &x) { this->member = x; }
#define SET_PTR(name, member) void set##name##(name *x) { this->member = x; }


#define GET(name, member) name get##name##(void) { return this->member; }
#define GET_CONST(name, member) name get##name##(void) const { return this->member; }

#define GET_REF(name, member) name& get##name##(void) { return this->member; }

#define GET_PTR(name, member) name* get##name##(void) { return this->member; }
#define GET_PTR_CONST(name, member) name* get##name##(void) const { return this->member; }


#define SETGET(name, member) SET(name, memeber) GET(name, member)

Windows Draw Directly onto the Screen/Desktop


Okay so this is the last post without proper editing and completed code. Also don't worry, I'm going to fix this later!

But this is the boilerplate for drawing something directly on the screen/desktop.

This sample draws a blue rectangle on the screen, though there need to be something that listens for WM_PAINT messages. Because if not then the blue rectangle disappears probably immediately, as the screen most likely redraws when the console closes or you move your mouse.

#include <iostream>
#include <Windows.h>


int main(int argc, char **argv)
{
	HWND desktop = GetDesktopWindow();
	HDC dc = GetDC(desktop);

	RECT rect = { 20, 20, 200, 200 };
	HBRUSH brush = CreateSolidBrush(RGB(0, 0, 255));
	FillRect(dc, &rect, brush);
	

	return 0;
}

Windows Global Mouse Hooking


Okay, so again this these posts needs some explaining and some more code. But bottom line is, that this is the boilerplate for how you would go about making a global keyboard hook on Windows.

#include <iostream>

#include <Windows.h>
#include <windowsx.h>


LRESULT CALLBACK MouseHookProc(int code, WPARAM wParam, LPARAM lParam)
{
	switch (wParam)
	{
	case WM_MOUSEMOVE:
		{
			MSLLHOOKSTRUCT *mouse = reinterpret_cast<MSLLHOOKSTRUCT*>(lParam);
			printf("Mouse <X: %i, Y: %i>\n", mouse->pt.x, mouse->pt.y);
			break;
		}
		

	case WM_MOUSEWHEEL:
	case WM_MOUSEHWHEEL:
		{
			const short swheel = HIWORD(wParam);
			const int wheel = swheel / WHEEL_DELTA;

			break;
		}


	case WM_LBUTTONDOWN:
		printf("left mouse button down\n");
		break;
	case WM_MBUTTONDOWN:
		printf("middle mouse button down\n");
		break;
	case WM_RBUTTONDOWN:
		printf("right mouse button down\n");
		break;
	case WM_XBUTTONDOWN:
		{
			const UINT button_down = GET_XBUTTON_WPARAM(wParam);
		
			switch (button_down)
			{
			case XBUTTON1:
				printf("x1 mouse button down\n");
				break;
			case XBUTTON2:
				printf("x2 mouse button down\n");
				break;
			default:
				printf("x mouse button down\n");
				break;
			}

			break;
		}


	case WM_LBUTTONUP:
		printf("left mouse button down\n");
		break;
	case WM_MBUTTONUP:
		printf("middle mouse button down\n");
		break;
	case WM_RBUTTONUP:
		printf("right mouse button down\n");
		break;
	case WM_XBUTTONUP:
		{
			const UINT button_up = GET_XBUTTON_WPARAM(wParam);

			switch (button_up)
			{
			case XBUTTON1:
				printf("x1 mouse button up\n");
				break;
			case XBUTTON2:
				printf("x2 mouse button up\n");
				break;
			default:
				printf("x mouse button up\n");
				break;
			}

			break;
		}
	}

	return CallNextHookEx(0, code, wParam, lParam);
}


int main(int argc, char **argv)
{
	HHOOK hook = SetWindowsHookEx(WH_MOUSE_LL, MouseHookProc, nullptr, 0);
	
	MSG msg;
	
	while (true)
	{
		if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
		{
			if (msg.message == WM_QUIT)
			{
				break;
			}

			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}

	UnhookWindowsHookEx(hook);
	
	return 0;
}

Windows Global Keyboard Hooking


Okay, so this post needs some explaining and some more code. But bottom line is, that this is the boilerplate for how you would go about making a global keyboard hook on Windows.

#include <iostream>

#include <Windows.h>
#include <windowsx.h>


LRESULT CALLBACK KeyboardHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
	switch (wParam)
	{
	case WM_KEYDOWN:
	case WM_SYSKEYDOWN:
		printf("key down\n");
		break;

	case WM_KEYUP:
	case WM_SYSKEYUP:
		printf("up down\n");
		break;
	}
	
	return CallNextHookEx(0, nCode, wParam, lParam);
}


int main(int argc, char **argv)
{
	HHOOK hook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProc, nullptr, 0);
	
	MSG msg;
	
	while (true)
	{
		if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
		{
			if (msg.message == WM_QUIT)
			{
				break;
			}

			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}

	UnhookWindowsHookEx(hook);
	
	return 0;
}

Preventing Directory Traversal Attack


Directory Traversal Attack also known as the ../ (dot dot slash) attack, is an attack done entirely using "../". The gain of this attack is to get access to files and directories which you normally wouldn't have!

As an example let's say we have a PHP script called download.php, which allows anybody to give it an arbitrary path to be able to download files from a specific directory.

Let's say we allow people to download files from a directory called files/. Thereby download.php?path=test.txt would make you download files/test.txt.

The danger is when someone requests download.php?path=../../passwords.txt as the server would just jump out of the files directory and let the user download the requested file, which again is outside the files directory.

The simplest way to prevent this is simply resolving the requested path and check if it's inside the files directory or not.

$base_path = $_SERVER["DOCUMENT_ROOT"] . "/files/";
$real_base = realpath($base_path);

$user_path = $base_path . $_GET["path"];
$real_user_path = realpath($user_path);


if (($real_user_path !== false) && (strncmp($real_user_path, $real_base, strlen($real_base)) === 0))
{
    // This is inside "files", move along...
}
else
{
	// Directory Traversal!
}
Stack Overflow
Tags