Back in 2008, the Windows Server Performance Team Blog, which I came across recently, ran a series of posts on Designing Applications for High Performance:
Designing Applications for High Performance - Part I Designing Applications for High Performance - Part II Designing Applications for High Performance - Part III If you are interested in developing server side applications for Windows, these articles are definitely worth reading.
Continue »
Although Windows Explorer may actually not be the brightest spot of Windows, it is still, for most users, among the most often used pograms. Customizing it to speed up certain tasks is thus a natural desire.
A while ago, I wrote about how to extend the context menu by new commands that allow MSI packages to be installed/uninstalled with logfiles being created. The registry entries I used were:
Windows Registry Editor Version 5.
Continue »
Almost two years ago, I wrote about how to create multi-language MSI packages. Although using transforms to internationalize an MSI package is a viable solution, one drawback of this approach is that it may require a bootstrap loader.
While it is easy to say that a bootstrap loader is required and many high-profile setups do indeed use bootstrap loaders, bootstrap loaders do have their issues. They not only add complexity to the setup package, there actually are several reasons why a bootstrap loader-free setup may be preferrable.
Continue »
Programming memory leaks in C or C++ is easy. Even careful programming often cannot avoid the little mistakes that finally end up in your program having a memory leak. Thankfully, however, there are plenty of helpful tools that assist in finding leaks as early as possible.
One especially helpful tool for leak detection is the debug CRT. Although the leak detection facilities provided by the debug CRT are not as far-reaching as those of, say, UMDH, using the debug CRT is probably the most friction-less way of identifying leaks.
Continue »
Programming memory leaks in C or C++ is easy. Even careful programming often cannot avoid the little mistakes that finally end up in your program having a memory leak. Thankfully, however, there are plenty of helpful tools that assist in finding leaks as early as possible.
One especially helpful tool for leak detection is the debug CRT. Although the leak detection facilities provided by the debug CRT are not as far-reaching as those of, say, UMDH, using the debug CRT is probably the most friction-less way of identifying leaks.
Continue »
One of the newer additions to the DDK is the aux_klib library, which, among others, offers the routine AuxKlibGetImageExportDirectory. As its name suggests, AuxKlibGetImageExportDirectory offers a handy way to obtain a pointer to the export directory of a kernel module.
There is, however, one issue that – at least in my opinion – renders AuxKlibGetImageExportDirectory pretty much useless in most scenarios: Dealing with forwaders.
The primary motivation to call AuxKlibGetImageExportDirectory is to either enumerate the exports of a module or to find a specific export.
Continue »
StackWalk64 provides a convenient and platform-independent way to walk the stack of a thread. Although useful and powerful indeed, it is definitively one of the less trivial to use functions. The additional fact that the MSDN documentation for StackWalk64 is rather light does not make things easier. There is, however, a decent article on CodeProject covering the usage of StackWalk64.
Although you can walk the stack of any thread using StackWalk64, this post only deals with walking the current thread’s stack.
Continue »
Create a message file Updating the SOURCES file Updating the rc file Although message tables play an important role in Windows, their tool support has always be somewhat limited – at least compared to string tables, for which Visual Studio even provides a graphical editor.
When in comes to creating and embedding message tables into a binary built with the WDK, documentation is light.
Whereas most Verifier error messages are rather descriptive, this one is not really:
VERIFIER STOP 00000200 : pid 0x2B4: Thread cannot own a critical section. 0000104C : Thread ID. 05274FDC : Critical section address. 09D88FE0 : Critical section debug information address. 010135D4 : Critical section initialization stack trace. Why should not this thread be allowed to own a critical section? What is Application Verifier trying to tell us? Luckily, the stack trace gives a hint:
Continue »
As of Windows Vista, basically all applications require a manifest in order to at least declare UAC compliance. Visual Studio has builtin support for creating and embedding manifests, so when using VS to build applications, using manifests is straightforward. However, when building a user mode application with the WDK and build.exe, things are a little different. Looking at the WDK documentation, manifests remain unmentioned – both in the context of UAC and SXS.
Continue »
This concludes the little series about the limitations of Detours:
Part 1: Introduction Part 2: Unexpected Behaviour Part 3: Messing execution flow Part 4: Undetouring Granted, the probability of experiencing any of the problems described in these posts is rather low. Whether these problems should be considered bugs of Detours or rather an inherent problem of the concept is not quite easy to judge – on the one hand, Detours indeed acts a little naive and especially the unhooking problem could have been easily avoided.
Continue »
Having discussed what can go wrong when detouring a function, we will now take a closer look at undetouring. Again, there is a problem – in my opinion an even more severe than the ones discussed previously – that has not been addressed by the Detours library.
Undetouring is a multi-step process and requires the user to follow a certain protocol. The basic idea is as follows: The caller creates a transaction, registers all threads that might have been affected by the detour and specifies which functions to unhook.
Continue »
Last time I showed that as a result of its implementation strategy, Detours is unable to properly instrument certain kinds of functions. Unlike last time, where this merely led to unexpected debugging output, we will see how this can easily lead to a crash.
Consider this code (error checking omitted):
#include <stdio.h> #include <tchar.h> #include <windows.h> #include <detours.h> static PDETOUR_TRAMPOLINE Trampoline; __declspec(noinline) static void DoSomething() { wprintf( L"DoSomething\n" ); Sleep( 100 ); } // // This is the function we want to instrument.
Continue »
Last time I described how to ‘replace’ a function by another using Detours. The important point was that first, we did not care about the original function any more once it has been hooked and second, we used a hook specially crafted for one particular to-be-hooked function.
This time we will make use of the trampoline in order to enable the hook function to call the original function. Furthermore, we do not want to create a separate hook function for every function we wish to hook but rather implement some kind of a generic hook – a hook function that is capable of hooking any possible function.
Continue »
Detours is a library that allows you to hook arbitrary functions by rewriting machine code. While a description of the exact implementation approach can be found in the corresponding paper as well as in numerous other sources, the basic idea is as follows:
In the to-be-hooked function, disassemble the first instructions until you have read at least 5 bytes. As instructions are variable length on x86, we may end up having to read more than 5 bytes to reach the next instruction boundary.
Continue »
For a procedure that is free of side effects, it is a relatively easy task to create a unit test that achieves sufficient code coverage by testing all (or at least all interesting) combinations of input data and verifying the computed results.
If, however, the procedure is not free of side effects, the state (global variables, external data, etc.) modified by the procedure has to be taken into account. A solid testcase has to test both the effects of the state on the correctness of the procedure and the correctness of the procedure’s modifications on the state.
Continue »
Every now and then you need to run an elevated command from the command line. If the application always requires elevation (i.e. the binary has been marked as requireAdministrator), the UAC prompt shows up – but in the case the application supports both non-elevated and elevated usage and you explicitly want it to run elevated, there is little support for you.
I would have expected start.com to have been augmented by something like a /elevate-switch, but unfortunately, this is not the case and you are left with having to open a new elevated command prompt to continue.
Continue »
Registry keys and values have a maximum length, as documented on MSDN. For example, the maximum permitted length of a key is 255 characters – interestingly enough, the question of whether this includes or excludes the NULL terminator is left unanswered. May it be due to this fuzzy documentation or not, Microsoft’s tools and API do not quite seem to agree on a common interpretation of maximum key length, which revealed this little bug in Regedit.
Continue »
There are three common error code formats used throughout Windows. In the kernel and native part, NTSTATUS is used exclusively. The Win32 API uses its own error codes (they do not really have a name, so I will refer to them as Win32 error codes) and COM uses HRESULTs – though the separation is not always so sharp, e.g. the safe string functions (StringCch* and friends) also return HRESULTs although they do not belong to COM.
Continue »
When authoring MSI packages, you frequently need the installation to be logged. Instead of repeatedly opening a console to type in msiexec /l* install.log /i foobar.msi, these shell context menu items may speed this process up a little. They do the same as ‘Install’ and ‘Uninstall’ but log everything (/l) to PackageName.msi-install.log or PackageName.msi-uninstall.log, respectively. Here are the registry entries:
Windows Registry Editor Version 5.00 [HKEY_CLASSES_ROOT\Msi.Package\shell\LoggedInstall] @="&Logged Install" [HKEY_CLASSES_ROOT\Msi.Packageshell\LoggedInstall\command] @="msiexec.exe /l "%1-install.
Continue »