Martin's technology blog – 5 latest posts

Blog content

Latest posts

Active categories:

More tags ...

By date:

    (No recent posts)

Blog calendar

June 2017
Mo Tu We Th Fr Sa Su
 << May Jul >>
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30

Blog features

RSS feed icon RSS feed

RSS comment feed icon RSS comment feed

Vista: User profile startup programs not executed

posted by Martin Rubli at 17:34

If you thought buying a new computer and installing a fresh copy of the latest and greatest (only in terms of disk space usage, obviously) Windows Vista is a good start for productive computing then you obviously haven't reckoned with Microsoft's talent to break the simplest of features.

While setting up my system I eventually noticed some strange behavior: The startup programs that I had placed into the start menu were not executed. On the other hand, some startup programs seemed to be executed twice; in my case I ended up with two OneNote icons in the tray bar.

I didn't make the connection at first but a closer analysis showed that the links in

C:\Users\martin\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup

were not executed on log in whereas the ones in

C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup

were executed twice.

A quick scan of the registry (which brought up a whole new bug, but more about that in the next article) quickly found the reason of this strange behavior.

In the

HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders

path there is an entry called Start Menu, which, in my case, contained the following, erroneous path:

%ALLUSERSPROFILE%\Microsoft\Windows\Start Menu\Programs\Startup

This obviously makes no sense because, as the registry path already indicates, these are the User Shell Folders. All the other entries in the same registry location were correct though.

The fix was trivial, I simply just replaced it with the following:

%USERPROFILE%\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup

Sidenote: There's a second registry location that also contained the wrong folder, though as a REG_SZ instead REG_EXPAND_SZ string and therefore without the environment variables:

HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders

Changing that one alone didn't have any immediately visible effect but to be on the safe side I would recommend changing that too.

It's also funny to see that when you right click the Startup folder in the start menu and choose 'Open' or 'Open All Users' Explorer doesn't seem to retrieve the path from any of the above registry locations.

How the wrong path had gotten there in the first place is beyond me. But when I started thinking about it I suddenly remembered that I had fixed the exact same problem at one point during my very first Vista experiment. Apparently more than a year and one service pack later things haven't changed. Let's wait for Service Pack 2, maybe that will ... Nah ... Put a lid on that hope's coffin and nail it shut. Six (6.0?) feet under is where Vista hopes are at home.

ASUS NX1101 跟Vista六十四bit不能用

posted by Martin Rubli at 14:08

"ASUS Networks - Built to connect ..." Well, temporarily.

When I buy a network card there's one thing, above all, that I want it to do: connect and stay connected. Is that too much to ask for? Apparently it is when you buy an ASUS NX1101 and try to run it on a 64-bit Windows Vista.

It all started so well. After being scared off by the prices of PCIe network cards I decided to go with a good old PCI one. I bought it and headed home. After a quick search on Windows Update Vista automatically downloaded and installed the drivers. That's how it should be.

The next time I my computer wakes up from hibernation the first surprise. No network. Been there, done that, so I restart the Corega wireless/Ethernet router (necessary about two to three times per week even with the latest firmware) and try again. Nothing. Even pinging the router doesn't work. Only disabling the network and reenabling it brings the connection back to life.

Unfortunately it's not a one time thing, it's reproducible every single time, but not on XP 32-bit. So I start looking for an updated driver and, of course, I find one on their website. Actually, I find two of them - only ASUS knows why, - so I take the newer one because the older one is identical to the one that Windows downloaded automatically.

In an optimistic mood I start installing it but after a while Windows complains the driver is not intended for my platform. I double check that I have the right driver but the folder name says 64-bit and the INF file looks okay. Awesome.

More or less by accident I notice something:


That's right. The driver binary is 0 bytes in size. Either this is just the slimmest driver ever or somebody at ASUS' quality assurance lab must have a very sound sleep. And some other people too given that the "driver" has been online for about four months.

Being a driver developer myself I'm pretty understanding when it comes to power management bugs, but putting up a zero byte driver is far from excusable. Especially if the support form and live chats don't work.

Today I brought my card back to the store and got a new D-Link one (DGE-530T). So far it works like a charm, even after hibernating.

There's an upside to the story though: Apparently my Chinese, limited as it is, is now good enough to get a broken network card exchanged and buy a new one. By the amount my confidence in ASUS has shrunk my self-conficence has grown. That's not half bad. :-)

Quoting strings in INF AddReg sections

posted by Martin Rubli at 07:35

The syntax of the INF files controlling Windows driver installation can be a little tricky at times. In this particular case I was trying to add a registry key whose value contains some quoted paths. It took me several attempts to get it right and the help on INF strings sections was also rather cryptic and not very helpful with its lack of examples.

I wanted to create a key with the following value (of course the actual example was slightly different but this will do to illustrate the problem):

"C:\Program Files\MyTool\Run.exe" -datadir"C:\Program Files\MyTool\data\" -debug -title"MyTool" -verbose

Here's the solution (or should I say: the closest I got):

HKLM,Software\Me\MyTool,Command,0x00000000,"""C:\Program Files\MyTool\Run.exe""" -debug -datadir"""C:\Program Files\MyTool\data\""" -title"""MyTool""" -verbose""

The documentation states:

[...] any string [...] that is itself a quoted string, must be enclosed in a pair of double quotation marks characters [...]
The INF parser not only discards the outermost pair of enclosing double quotation marks for any "quoted string" in this section, but also condenses each subsequent sequential pair of double quotation marks into a single double quotation marks character. That is, """some string""" also becomes "some string" when it has been parsed.

The second paragraph is slightly beyond my understanding, in particular considering some of my intermediary test results that you can find at the bottom.

The first paragraph at least explains the double quotes at the end. Inside the string all quotes also need to be tripled.

The beginning of the remains somewhat of a mystery to me. The triple quote at the beginning of the string is converted into a single quote in the registry.

To make matters worse, Microsoft's own ChkInf, which comes with the DDK, doesn't like any of the working solutions. It doesn't accept any less than four quotes at the end of the string. However, with more than two quotes at the end of the string, the resulting registry ends up containing a trailing quote. Anything with two or fewer (one and zero also work but at least seem syntactically incorrect to me) works fine with regard to the end result.

As I promised, here are some of my intermediary results. The slightly simplified AddReg commands and the corresponding result behind the semicolon:

HKLM,,TestA,0x00000000,"""Some string"""              ; "Some string"
HKLM,,TestB,0x00000000,""Some ""quoted"" string""     ; Some string
HKLM,,TestC,0x00000000,""Some "quoted" string""       ; Some string
HKLM,,TestD,0x00000000,""Some \"quoted\" string""     ; Some \quoted\ string
HKLM,,TestE,0x00000000,""Some """quoted""" string""   ; Some "quoted" string

Is anyone wondering why Microsoft didn't just adopt the syntax of one of the many programming languages out there where similar problems are unheard of? The developers could have just copied the code from MSVC (or any of the other hundreds of MS implementations of the same algorithm) and users wouldn't have to even read the documentation. But heaven forbid a win-win situation!

OS detection in a Windows shell script

posted by Martin Rubli at 07:26

There seem to be many ways to detect the Windows version (e.g. XP vs. Vista) from a batch file, some of them fairly complicated. It's not exactly as easy as it should be because there's no decent environment variable and the output of ver is difficult to parse.

However, I found the following to work just fine:

: OS detection
for /f "tokens=3" %%i in ('reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion" /v CurrentVersion') do (
	set WindowsVersion=%%i
if "%WindowsVersion%"=="5.1" set IsWindowsXP=1
if "%WindowsVersion%"=="6.0" set IsWindowsVista=1
: Show some debug information echo Windows version: %WindowsVersion% if defined IsWindowsXP echo IsWindowsXP = true if defined IsWindowsVista echo IsWindowsVista = true

Integrating Flex and Bison into Visual Studio

posted by Martin Rubli at 08:18

There's a pretty good tutorial from Microsoft (what do you know, they do like open source ;-) about how to integrate Flex and Bison into Visual Studio:

Understanding Custom Build Rules in Visual C++ 2005: Building Flex and Bison Files from the IDE

Unfortunately I ran into a problem after integrating it into my project. Flex kept crashing with the following output:

1>------ Build started: Project: MyProject, Configuration: Debug Win32 ------
1>Generating lexical analyser...
1>flex: fatal internal error, exec failed
1>Project : error PRJ0002 : Error result 1 returned from 'C:\WINDOWS\system32\cmd.exe'.
1>Build log was saved at "file://C:\MyProject\Debug\BuildLog.htm"
1>MyProject - 1 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

Some experiments showed that Flex was unable to find M4 (i.e. m4.exe) and then crashed with the above not-so-helpful error message.

The workaround is easy: Make sure that either m4.exe is in the path or set the M4 environment variable. Since I use a somewhat special directory structure for Flex, Bison, and some other tools I already had a wrapper script in place, so integration was easy:

: Wrapper script for Flex
: This script sets some environment variables that are required for Flex to
: find all its libraries and helper files/tools.
@echo off
: Determine the path of the wrapper script set GNU_PATH=%~d0%~ps0
: Set PATH for cygwin1.dll and M4 for the M4 tool itself. : If we don't define M4 Flex fails with the following error message: : "flex: fatal internal error, exec failed" set PATH=%GNU_PATH%\lib;%PATH% set M4=%GNU_PATH%\bin\m4.exe
: Launch the real Flex executable with the same arguments %GNU_PATH%\bin\flex.exe %*

In case you're wondering, the directory structure I'm using looks something like this:

¦   bison.cmd
¦   flex.cmd
¦       bison.exe
¦       flex.exe
¦       m4.exe
¦       cygwin1.dll

You can see the two wrapper scripts at the top level.

For completeness' sake the wrapper script for Bison, which defines one additional variable, so that Bison can find its M4 helper files:

: Wrapper script for Bison
: This script sets some environment variables that are required for Bison to
: find all its libraries and helper files/tools.
@echo off
: Determine the path of the wrapper script set GNU_PATH=%~d0%~ps0
: Set PATH for cygwin1.dll, BISON_PKGDATADIR for the M4 meta files : and M4 for the M4 tool itself. set PATH=%GNU_PATH%\lib;%PATH% set BISON_PKGDATADIR=%GNU_PATH%\share\bison set M4=%GNU_PATH%\bin\m4.exe
: Launch the real Bison executable with the same arguments %GNU_PATH%\bin\bison.exe %*

By the way, if you use Lex in your Visual Studio project, you may also want to check out this article which documents a bug in Microsoft's original FlexBison.rules file.