Hello, everyone! It’s me, Shriraj (a.k.a sr13).
The time has come to summarize all the work I have done in this Summer of Code with ReactOS and complete this journey of my first ever GSoC, though my story with ReactOS is just beginning!
TL;DR of Project Taskbar Shell Extensions:
# Designed & Implemented the Quick Launch Toolbar for ReactOS. # Designed & Added support for Battery Status in notification area (System Tray). # Designed & Added support for Safely Remove Device in notification area (System Tray).
First thing first, The Important links:
1. The Unified Diff: https://drive.google.com/file/d/0B1TQOdFoUycsSU5JLUZsTk1yQ2M/view?usp=sharing
2. ReactOS branch for Project Taskbar Shell Extensions: https://svn.reactos.org/svn/reactos/branches/GSoC_2017/shellext/
3. Link for checking out using svn: https://svn.reactos.org/reactos/branches/GSoC_2017/shellext/reactos
Detailed Summary of Work Done:
Phase I: The Quick Launch ToolbarGIF 1.0 : A working demo of Quick Launch under test in WinXP showing some of the features implemented during this phase.
This phase began with my mentor Giannis introducing me the fundamental technologies i.e. the COM (Component Object Model) and ATL (Active Template Library) along with the basics of Win32 API. Having no prior experience of win32 API was a minus for me, but being experienced with Object Oriented Programming and C/C++ helped me to grasp the underlying concepts fairly fast enough. Thanks to Giannis. The rest was about to learn how to use the win32 libraries and more or less MSDN was enough for it besides the support from ReactOS team.
I began developing Quick Launch Toolbar by first adding a DLL module named ‘qcklnch’. After understanding the basics of DLL servers using COM/ATL, the next thing was about implementing and exposing the CQuickLaunchBand via the qcklnch module. Initially, this class was implemented by instantiating and using internally the CISFBand class provided with windows. Later on, it was changed to use my own implementation of CISFBand.
CISFBand class is a major part of the code which actually does the work of handling the quick launch toolbar. This class is not restricted just for the quick launch, but by design can actually handle any band object and toolbars. As I told earlier, the windows also have its own implementation of this class which I had used initially for testing purposes. To code my own version of this class, I had to implement several interfaces which are required for a CISFBand object by design. They are:
All of these interfaces are well documented in MSDN, and rest of the required documentation is in my code itself. For more details on how I spent my time in this phase, you can check out my personal weekly blogs:
Phase II: The Battery Notification IconGIF 2.0 : A working demo of Batttery notification showing the percentage remaining, battery mode and charging state.
This phase (and the next) was mostly about IOCTLs and understanding the OS from the hardware perspective. Just like the first phase, it began with an introduction of the concepts required for these phase of the project. Again without the support of Giannis, it would have been a hard time for me to code this thing as I had neither much experience of win32 API nor its hardware aspects.
So first thing was to learn how to extract the information regarding the current state of the battery. For that, I made a standalone console app first, before directly adding code to ‘stobject’ (which represents the system tray or notification area of ReactOS). The standalone app made the task of testing and debugging easy thus making the code robust. I understood the basics of enumeration of devices and IOCTLs, extracted the current state of the batteries attached and tested in standalone console app on windows. It may sound simple, but extracting this simple information was not an easy task.
After thoroughly testing the code in the standalone app, I added it to the ‘power’ module of the ‘stobject’. For that, I first learned the design of ‘stobject’, for which my mentor and the ReactOS team helped me. The ‘stobject’ exposes a single object of the class named CSysTray. Basically, it uses function pointer mechanism to handle different notification tray modules. It maintains a list of structures where each represents a notification object. Each of the structures has function pointers as its members which technically points to a set of functions which any generic notification object must have to work as per the design. These functions are:
- ModuleName_Init : Initializes the notification icon.
- ModuleName_Shutdown : Shuts down and closes the notification icon.
- ModuleName_Update : Updates the notification icon.
- ModuleName_Message : Handles messages regarding the particular notification object.
The next thing was to interface the battery state with notification area. The current state of the battery was represented by a real number or a float, which was ok to be displayed as a tooltip of the battery icon. But what about the battery icon itself? Since a limited number of icons are available/feasible to represent various states of the battery, I quantized the float percentage of the battery to integer levels. This was later mapped to a set of battery icons which was updated real-time (ReactOS refreshes system tray icons every 2 sec) to represent the current battery state.
Thats how I spent my time during this phase and for more details, here are my weekly blogs:
Phase III: The Safely Remove Device Notification IconGIF 3.0 : A working demo of Safely Remove Device notification, displaying the ejection of a device and other features implemented in this phase.
Now being familiar with ‘stobject’ and IOCTLs which I used in the earlier phase, you might think this phase would be a piece of cake. But it wasn’t, as I was neither familiar with the PnP manager nor the APIs like 'SetupDiXxxxxxxx' and 'CM_Xxxxxxxx' which belong to win32 API. But hopefully, I was able to grasp these concepts in time.
Just like the last phase, I made a standalone app for detecting and enumerating the safely removable devices. The major hurdle I faced during this phase was the enumeration filters used for properly detecting the required devices. Finding out how exactly windows decides what devices to show proved to be more complex than initially thought. But this problem was solved by the ReactOS expert in this area, sir Thomas. Both my mentor Giannis and Thomas helped me by providing the proper enumeration filters as per their expertise.
In the meantime, I added a module named ‘hotplug’ within ‘stobject’ to represent this safely remove device icon. Following the similar design principles of the ‘power’ module, I implemented this ‘hotplug’ module and I tested the icon and its context menu. While at this task, I also reminded myself how windows used to do this. I went through how windows popped the notification whenever the appropriate device was plugged in (like a USB pen drive) and how it used to eject the same device.
Following the same design philosophy, I implemented the required functionality like handling and keeping track of the list of devices attached and other error handling procedures. Of course, it was possible to code this thing out only after thoroughly understanding the APIs used (which sadly I had no experience with). It was a very nice experience to understand this day to day used service. Not only it was fun to code this module but it also helped me to satisfy my curiosity.
For more details, you can go through my weekly blogs:
As of now, none of the code is merged to the main trunk of the ReactOS. Thing is the ReactOS project is still alpha and many of the things underneath which are required for my project (but not limited to) are either unimplemented or buggy.
Currently, the battery driver (used by my ‘power’ module) doesn't work in ReactOS, and about PnP manager, ejecting is probably unimplemented too. That’s why, during my entire coding period, I used Windows XP virtual machine for testing purpose. Actually that’s the best thing about ReactOS development. This strategy of ReactOS, which I really love is to test against windows first, then correct and improve ReactOS. Thus it helps to do two things in one go, i.e. even if you are coding a particular feature, it helps to debug the entire OS and not just that particular code. As for the quick launch toolbar, it is shown within the ReactOS but the rest of the shell changes its size every few seconds and needs proper integration and support.
So, my code will be merged as soon as the features required for my project are implemented and supported by ReactOS. Also, the unified diff of my work can be applied to the trunk and is compatible with it. Another thing is, my code will also act as a pilot project that uncovers bugs in the rest of the OS. Since my code gets reviewed and works in windows it will be considered correct by the ReactOS project and will be merged gradually. And as a policy in ReactOS, it's preferred not to hack correct code just to make it work in ReactOS.
Plans for Post-GSoC regarding this project:
As per our initial plans and milestones, this project has been completed. But some of the things which we wanted to include would be done post-GSoC. Besides, the real thing would be to support this code after it's merged as it will reveal many unencountered and hidden bugs.
Some of the features which might be implemented post-GSoC are:
- Drag & drop capability for quick launch toolbar.
- Support for more than one battery device.
- Support for handling unrecognized safely removable devices and malfunctioned devices.
- Improvement of UI for the above projects.
Besides using my strong programming fundamentals, I can definitely say that I was able to complete this project (despite my inexperience with Win32 API) through my sheer obsession to understand the code behind and curiosity to learn about how our day to day software work. Thanks to my mentor, he was always there to teach the required concepts and the cooperation among the ReactOS team finally made me complete this project.
I would like to thank GSoC for providing this amazing platform for open source development and thank ReactOS for not only helping me to understand their ecosystem and code-base but also making my childhood dream of 'knowing how windows works' come true (at least partly). Of course knowing how entire OS works is not a child’s play, but I am sure that I am in right direction of realizing this dream and as I had said my GSoC journey might have ended but my story of ReactOS is just beginning and I am excited to know what lies ahead. : )