One day, in 2009, Windows 7 came out. At that time I was sitting on Vista, which slowed down on my old computer, and I decided to transfer to the seven right after it was released.
The first thing I noticed after installation is the new taskbar. More specifically, the fact that it groups the buttons according to the program to which they belong.

')
Immediately I got into the settings to disable this disgrace, and was surprised to find that the group is not turned off. The closest option to the desired, Never Combine, still groups the buttons.

I thought that, like me, many people would not like it, and I was sure that a week or two later a solution to this problem would come up on the Internet. But I did not find anything worthwhile, and I realized that I would have to act on my own.
Under the cut:
- A detailed demonstration of how you can independently tweak the principle of a system process such as explorer, for yourself, using the OllyDbg debugger.
- Ready solution to the problem described above.
Getting started
To understand the process described below, it is advisable to have a basic knowledge of the assembler.In order to wean the taskbar from grouping, we need
OllyDbg , a
free, proprietary 32-bit assembler-level debugger for Windows operating systems, designed to analyze and modify compiled executable files and libraries operating in user mode (ring-3) ©
Wikipedia .
You can repeat the process on Windows 7 or Windows 8. Unfortunately, at the moment there is only a 32-bit version of OllyDbg, so if you have a 64-bit OS, you will not be able to repeat the following steps (in this case you can use a virtual machine ).
Installation OllyDbg
OllyDbg is a portable program and does not need installation. Create a folder with write permissions, and copy files from
this archive there .
Configure Microsoft Symbol Server
Microsoft Symbol Server - Microsoft's debugging symbols server, thanks to which we, in addition to the pure assembler, will also see the names of functions and variables. This is very helpful in analyzing the code.
To do this, do the following:
- Download this archive and place its content in the OllyDbg program folder.
What are these files?- symsrv.dll - Microsoft's DLL file, designed to work with their server debugging symbols. Signed by Microsoft.
- symsrv.yes is an empty file. Indicates that you agree to the terms of service provided.
- symsrv.ini - excludes all files except those that start with exp - for our explorer.exe. Otherwise, if all the characters swing, you will have to wait a very long time, and we don’t need it for this demonstration.
- Turn on OllyDbg, open the settings (Alt + O), and mark the option Demangle symbolic names . This option decodes symbolic names, making them more readable for us humans.
- In the settings, open the Debugging data page, and mark Allow access to Microsoft Symbol Server . Then create a folder for characters, and select it in the settings, as in the screenshot.
- Restart OllyDbg.
Joining the explorer process
As you know, the taskbar is part of the Windows Explorer process. Run OllyDbg, and select
File -> Attach .... Then, select the
explorer and click on
Attach .
Attach, from English - to attach - that is, we attach our debugger to the conductor to debug it.
Then we wait until all modules are loaded. This may take several minutes, and at this time the conductor will not respond. After the download is completed, Paused will be written on the yellow background in the status bar on the right - that is, the process is suspended. Click F9 to resume the process.
Attention, exceptions : if the process pauses and
Exception xxxxxxxx appears on the status bar (as in the screenshot below), press Shift + F9 to send the exception to its intended purpose.
Overview of Explorer Functions
Now the conductor is working under the supervision of our debugger, OllyDbg. If the connection to the server debugging characters passed as it should, we can look at the functions of the explorer.
First, open the explorer process module in the CPU window of the debugger. To do this, open the modules window (the letter E on a blue background), right-click on
Explorer , and select
View code in CPU .
Then, right click on the code and select
Search for -> Names . Before us will be a list of functions that are present in the explorer. For more convenient work with the list, sort it by name, copy it and paste it into the text into your favorite text editor.
So, we need to disable grouping. It is logical to start the search with the word group. Two classes immediately strike the eye:
CTaskBtnGroup and
CTaskGroup . Together, these two classes have 131 functions — not very much for a quick look at the titles.
It’s hard for me to say if we can find the function we need by just learning the names, since I’m already well acquainted with many of them. In any case, the function we need -
CTaskGroup :: DoesWindowMatch , the name of which translates to
whether the window matches , and it does exactly that - answers whether the window is suitable for a specific group.
View selected function
We found a function with an interesting name, now let's see what it is. Let's go back to OllyDbg, press Ctrl + G and go to the address of the function (that eight-digit number at the beginning of the line, in our case 00973629).
PS I advise you to turn on the highlight of
Jumps and calls , thanks to which function calls and conditional / unconditional jumps are clearly visible.
So, here is our function:

Columns, from left to right: address, bytes, commands (assembler), comments.
Functions are marked in blue, transitions in yellow. We will focus on them.
First of all, some function is called, and a transition occurs depending on the result. Here I will not linger on them, I will only note that they have nothing to do with our task.
Then we see three transitions. The first one jumps over the second and third. The second and third go somewhere far away - let's see where ...
The firstThe WinAPI function
ILIsEqual , which compares two structures, is immediately apparent. After some analysis, it becomes clear that the compared structures are associated with groups. Our goal is to cancel any grouping, so we patch the code so that the conductor thinks that the structures are not equal.

To do this, we write an unconditional jump JMP, as in the screenshot above.
SecondAs in the first time, immediately see the WinAPI function for comparison, this time the text -
CompareStringOrdinal . Again, after experimenting it becomes clear that this comparison is also related to groups. This time, the so-called Application ID is compared - the application ID, according to which the taskbar groups the buttons.

Again, we set an unconditional jump, forcing the conductor to think that all identifiers are different.
We try
The big advantage of the debugger from, for example, a simple disassembler is that the changes take effect immediately, since we modify the memory of the running process directly. For the same reason, you need to be very careful, as an error can lead to the collapse of the process.
Let's try to open several copies of the notebook, and see that they are not grouped together:

Happened :)
Since we changed the code only in the memory of the running process, our modification will last only until the completion of the process.
Bonus - decompiled version of the CTaskGroup function :: DoesWindowMatch
In spite of the fact that the original language of this code is C ++, the samopisny decompilation on pure C is shown below.
HRESULT CTaskGroup_DoesWindowMatch(void *this, HWND hCompareWnd, ITEMIDLIST *pCompareItemIdList, WCHAR *pCompareAppId, int *pnMatch, void **pTaskItem) { void *CompareWndTaskItem; int nMatch; HRESULT hr; nMatch = 0; hr = this->lpVtbl->GetItemFromWindow(this, hCompareWnd, &CompareWndTaskItem); if(SUCCEEDED(hr))
Turnkey solution
The
7+ Taskbar Tweaker program, authored by me, is able to disable grouping both globally and selectively by the Application ID. In addition, there are in the presence of several interesting settings on the taskbar.

Conclusion
Sometimes I open an article on a habr that seems interesting to me, but after I start reading, I understand that it is not that interesting (or not very clear). In such cases, I often immediately turn down to the conclusion / conclusions.
If you are here for the same reason, I will tell you briefly what was discussed:
I took the debugger, and attached it to the conductor. Then I found the necessary function, and changed it so that the conductor would think that any window created would not fit into any of the existing groups. Due to this change, Explorer has stopped grouping buttons on the taskbar.