« Back to home

Checking for buffer overflows in unit tests

Posted on

Functions that take a buffer and a corresponding buffer size as a parameter are ubiquitous. As an example, consider this function declaration: /** Routine Description: …queries some value… Parameters: BufferSize - size of buffer in WCHARs. Buffer - buffer to store information in. Return Value: ERROR_SUCCESS on success. ERROR_INSUFFICIENT_BUFFER if the buffer is to small. –*/ DWORD QueryInformation( __in UINT BufferSize, __out_ecount(BufferSize) PWSTR Buffer ); ``` If we are to write a testcase for this function, it is important to check that the function properly handles buffers of insufficient size. Read more »

Launch elevated processes from the command line

Posted on

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. Read more »

A Regedit bug or what happens if API documentation is fuzzy

Posted on

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. Read more »

Error Codes: Win32 vs. HRESULT vs. NTSTATUS

Posted on

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. Read more »

Install MSI with log from shell context menu

Posted on

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. Read more »

Type 1 CustomAction Load Failures

Posted on

When testing a custom action, it is usally practical to have the CA write some information to the installer log, so that you can verify that the CA has been called properly. But what if the installer log does not show up your information but instead the installation aborts and the log only states that the custom action returned 3 (ERROR_INSTALL_FAILURE)? There may be various reasons for this to happen, but the most common reason is probably that your DLL was unable to load because of unsatisfied dependencies. Read more »

Where to place RemoveExistingProducts in a major MSI upgrade

Posted on

When Windows Installer performs a major upgrade, the position of the RemoveExistingProducts action determines when the uninstall of the old product is performed. Despite efficiency, two factors dominate the decision What should happen if either the install or the uninstall fails? Should the new product ‘see’ registry entries/files/etc from the existing product or should the new product install ‘start from scratch’? The following table summarizes the four possible approaches. Read more »

Authoring multi-language MSI packages

Posted on

By default, Windows Installer packages are single-language only – no direct support for multi-language packages is currently provided. Creating a multi-lanuage installation package is thus a little more compex – the following provides a summary of the steps required: Create an english package Compile: candle -dLANG=1033 foo.wxs Link: light -out foo.msi -loc strings-en.wxl foo.wixobj Create the german (or whatever language) package Compile: candle -dLANG=1031 foo.wxs Link: light -out foo-de.msi -loc strings-de. Read more »

Determining the apartment of a thread

Posted on

There are situations in which it would be convenient to list which apartment the threads of a process belong to. In case of managed debugging, the !threads command provided by SOS gives this info: PreEmptive GC Alloc Lock ID ThreadOBJ State GC Context Domain Count APT Exception 0 688 00149528 6020 Enabled 00000000:00000000 00159e68 0 STA 1 f70 00165548 b220 Enabled 00000000:00000000 00159e68 0 MTA (Finalizer) In case of unmanaged debugging, however, no such command exists (at least to my knowledge). Read more »