7+ Taskbar Tweaking Library

7+ Taskbar Tweaking Library is a library for manipulating the taskbar of Windows 7 and above. It’s inspired by the 7+ Taskbar Tweaker program, and it allows you, as a programmer, to manipulate the Windows taskbar, which is virtually impossible to do with the documented Windows API.

You can take a quick look at the provided API here. For a more extensive look, refer to the examples which are provided together with the library.

In general, the library allows you to:

  • Get extensive information about the taskbar items and groups on all taskbars.
  • Reorder taskbar items, and reorder buttons within groups.
  • Set per-AppId settings.

For example, if you’d like to have the taskbar button of your program to never show labels, you can easily do it with the library:

Download

You can get 7+ Taskbar Tweaking Library here:

zip TTLib.zip (399.58 kB)

Please note that the library is free for non-commercial use only. If you’re interested in using the library for a commercial application, please contact me.

Command line tool

A command line tool based on the 7+ Taskbar Tweaking Library was created by the user Wasfi Jaouad. You can get it on GitHub:
https://github.com/WasfiJ/move_TaskBar_Buttons/releases

Example usage: mv_tb_btn.exe -g Notepad -f 5 -t 2
Moves button 5 to position 2 in button group named Notepad in the taskbar.

Please note that the tool wasn’t created and isn’t maintained by Ramen Software. I’m posting it here since it might be useful for users.

Posted in Programming on October 31st, 2014. 90 Comments.

C as a portable assembly: porting RAEdit to 64-bit

In the Multiline Ultimate Assembler plugin for OllyDbg, I use an editor component called RAEdit, written by KetilO in 32-bit x86 assembly. It’s a great component, lightweight and simple to use.

Recently, I’ve been working on a port of Multiline Ultimate Assembler for the x64_dbg debugger. After porting the 32-bit version of the plugin, I realized that there’s a problem porting it to 64-bit: the RAEdit component is written in 32-bit x86 assembly. While it’s somewhat similar to 64-bit x86 assembly, there’s no way to automatically port an assembly codebase from 32-bit to 64-bit. I had a couple of options:

  • Finding an alternative editor component.
  • Using a hack, e.g. running the editor window as a separate 32-bit process.
  • Porting RAEdit to 64-bit.

I looked for an alternative, but didn’t find a decent one. Also, I didn’t like the second option, so I’ve decided to port RAEdit. But how do I port an assembly codebase from 32-bit to 64-bit? I’m not familiar with MASM syntax, which the codebase uses. Perhaps it was possible to port the codebase to 64-bit MASM using macros and such. But I came up with a more creative idea: to port it to C first! After all, C is considered by some as a portable assembly.

The code uses MASM macros such as .if/.while extensively, which can be easily translated to C. Most assembly commands can be translated to C as well. I had to manually change some of the exotic stuff (such as usage of the CARRY flag), but most of the code was ready for automatic translation.

Then, I wrote a script which uses regular expression search/replace to translate every line of assembly to C. The initial result can be seen here. After some tweaking, I could get the code to compile. Due to the fact that there’s no type correctness in assembly, GCC displayed more than 1,000 warnings, most of which complain about incompatibility of types. I was actually surprised that it was able to compile.

Obviously, the code didn’t work right away. I had to fix a couple of things manually, but after some tweaking, it actually worked! And after some more tweaks for 64-bit portability (mainly adjusting pointer vs integer types and pointer size constants), the compiled 64-bit library worked as well!

It’s interesting to compare manually written assembly code with code generated by a compiler. Mostly, the original code is slimmer and looks more optimized. For example, assembly vs C of the SkipSpace function (clickable):

So there we have it, originally written in 32-bit x86 assembly, the library can now be (theoretically) compiled on every platform. It would be interesting to check whether it works on ARM/Windows RT, too. The main repository of the C port can be found here: https://github.com/m417z/RAEditC

Posted in Programming on August 20th, 2014. 3 Comments.

MinHook – The Minimalistic x86/x64 API Hooking Library (fork)

MinHook is a Windows API hooking library originally written by Tsuda Kageyu.
It’s probably the best free WinAPI library out there which supports both x86 and x64.
But it’s not perfect, and didn’t completely fit my needs, so I created a fork on GitHub which addresses some of its limitations.

Below you’ll see how the fork improves upon the original MinHook library.
Read More…

Posted in Programming on September 30th, 2013. 6 Comments.

A command-line screenshot maker

When googling for a command-line screenshot maker, all I found was a bloated 3 MB tool and this nifty piece of code.
So I took it and added some command line options I needed:

-filename "my screeny.png"    file name (default: screenshot.png)
-encoder png                  file encoder: bmp/jpeg/gif/tiff/png (default: png)
-quality 100                  file quality for jpeg (between 0 and 100)
-resize 50                    image size, % of the original size (between 1 and 99)

Perhaps it’s gonna be useful to others, so I’m releasing it.
The code and a compiled binary are attached.

rar source.rar (2.97 KB)
rar binary.rar (20.24 KB)

GitHub repository:
https://github.com/m417z/cmdline-screenshot-maker

Posted in Programming on November 16th, 2009. 8 Comments.

Custom Buffer-Manipulation Routines

Here’s my rewrite of the Custom Buffer-Manipulation Routines by Piotr Mintus.
Optimized for and works on 32-bit and 64-bit environments.

//**********************************************************************
// File: buffer.h
//	
// Custom Buffer-Manipulation Routines
//
// By RaMMicHaeL, 12.10.2009
//**********************************************************************

#ifndef _BUFFER_H_
#define _BUFFER_H_

#ifdef FillMemory
#undef FillMemory
#endif
#ifdef ZeroMemory
#undef ZeroMemory
#endif
#ifdef CopyMemory
#undef CopyMemory
#endif
#ifdef MoveMemory
#undef MoveMemory
#endif

__forceinline 
void FillMemory(PVOID Destination, SIZE_T Length, BYTE Fill)
{
	SIZE_T *sizet_p;
	unsigned char *uchar_p;
	SIZE_T sizet_fill;
	SIZE_T count;

	sizet_p = (SIZE_T *)Destination;

	count = Length/sizeof(SIZE_T);
	if(count)
	{
		sizet_fill = Fill;
		sizet_fill |= sizet_fill << 8;
		sizet_fill |= sizet_fill << 16;

#ifdef _WIN64
		sizet_fill |= sizet_fill << 32;
#endif

		do
			*(sizet_p++) = sizet_fill;
		while(--count);
	}

	uchar_p = (unsigned char *)sizet_p;

	count = Length & (sizeof(SIZE_T)-1);
	if(count)
	{
		do
			*(uchar_p++) = Fill;
		while(--count);
	}
}

#define ZeroMemory(Destination, Length) FillMemory(Destination, Length, 0)

__forceinline 
void CopyMemory(PVOID Destination, const VOID *Source, SIZE_T Length)
{
	SIZE_T *sizet_p_dest, *sizet_p_src;
	unsigned char *uchar_p_dest, *uchar_p_src;
	SIZE_T count;

	sizet_p_dest = (SIZE_T *)Destination;
	sizet_p_src = (SIZE_T *)Source;

	count = Length/sizeof(SIZE_T);
	if(count)
	{
		do
			*(sizet_p_dest++) = *(sizet_p_src++);
		while(--count);
	}

	uchar_p_dest = (unsigned char *)sizet_p_dest;
	uchar_p_src = (unsigned char *)sizet_p_src;

	count = Length & (sizeof(SIZE_T)-1);
	if(count)
	{
		do
			*(uchar_p_dest++) = *(uchar_p_src++);
		while(--count);
	}
}

__forceinline 
void MoveMemory(PVOID Destination, const VOID *Source, SIZE_T Length)
{
	SIZE_T *sizet_p_dest, *sizet_p_src;
	unsigned char *uchar_p_dest, *uchar_p_src;
	SIZE_T count;

	if(Destination > Source)
	{
		// Copy in reverse

		uchar_p_dest = (unsigned char *)Destination+Length;
		uchar_p_src = (unsigned char *)Source+Length;

		count = Length & (sizeof(SIZE_T)-1);
		if(count)
		{
			do
				*(--uchar_p_dest) = *(--uchar_p_src);
			while(--count);
		}

		sizet_p_dest = (SIZE_T *)uchar_p_dest;
		sizet_p_src = (SIZE_T *)uchar_p_src;

		count = Length/sizeof(SIZE_T);
		if(count)
		{
			do
				*(--sizet_p_dest) = *(--sizet_p_src);
			while(--count);
		}
	}
	else
		CopyMemory(Destination, Source, Length);
}

#endif  // _BUFFER_H_
Posted in Programming on October 12th, 2009. No Comments.