Martin's technology blog – 5 latest posts
Blog content
Active categories:
- Tip (3)
- GPS (1)
- OpenStreetMap (1)
- OATH (1)
- Windows (1)
By date:
(No recent posts)
Blog calendar
| Mo | Tu | We | Th | Fr | Sa | Su |
|---|---|---|---|---|---|---|
| << Jan | Mar >> | |||||
| 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 | ||||
2011-11-24 | Fixing GPS tracks chopped up by OpenStreetMap's Potlatch
The other day, while uploading some GPS tracks to OpenStreetMap, I noticed that Potlatch reproducibly chops up some of my traces into pieces, which makes them quite hard to turn into paths. Here's an example of an affected track:

Apparently I wasn't the only one with this problem, but with a fix - or even a proper explanation - outstanding, I did a little investigation.
The good news: The gaps in the track don't stand for lost points but for long straight lines. Therefore the easiest fix is to simply convert all track parts into paths and connect their ends. If your track is short or is only cut up into a small number of pieces that works great.
The better news: There's a batch processing solution for it, which works great for longer and more heavily chopped up tracks. Not surprisingly the solution involves GPSBabel.
I didn't spend much time on finding the optimum value, but a quick inspection suggested that Potlatch was cutting up the track between points that were more than about 100 m apart. With GPSBabel's interpolation filter it's an easy task to interpolate points whose distance is less than that:
gpsbabel -i gpx -f chopped.gpx -x interpolate,distance=0.095k -o gpx -F fixed.gpx
And there you go, the fixed track looks just the way it should:

Of course, now that you know the problem you can also tune the settings on your GPS device to make sure the logging interval is low enough. That way at least your future tracks won't cause you the same headaches. Happy mapping!
2011-09-03 | Generating OATH OTPs on Windows with oathtool
While Google's Android market and Apple's App Store are full with little apps that can generate OATH one-time-passwords, finding something similar for Windows proved to be quite a challenge.
The only free one I came across is OathToken for PC, a very simple tool that unfortunately insists on generating its own secret.
If you're looking for something a little more flexible your best shot may be running the original oathtool from the OATH Toolkit.
The quickest way to get it running is to download the sources and build them from scratch using Cygwin, which is refreshingly painless.
Of course, with security related software, you shouldn't trust anything you haven't built yourself, but for those of you who choose convenience over security I'm providing the compiled 1.10.0 version here for download. You have my personal promise that I didn't tamper with the sources - I'm far too lazy for that. ;-)
oathtool-1.10.0-cygwin.rar (829 kB)
2011-06-29 | Querying key states in PowerShell
Did you ever wonder how to check key states in a PowerShell script? This can be handy in situations where you want your script to behave slightly differently when, for example, the Shift key is pressed.
The first instinct would be to use something like the Windows.Forms.Control.ModifierKeys method, which even works for .NET console applications. However, in PowerShell said method always returns None, so that won't work.
Here's a slightly uglier method that provides a workaround:
function Get-KeyState([uint16]$keyCode)
{
$signature = '[DllImport("user32.dll")]public static extern short GetKeyState(int nVirtKey);'
$type = Add-Type -MemberDefinition $signature -Name User32 -Namespace GetKeyState -PassThru
return [bool]($type::GetKeyState($keyCode) -band 0x80)
}
The function can be used as follows:
$VK_SHIFT = 0x10
Write-Host "Shift key pressed:" (Get-KeyState($VK_SHIFT))
For more information on how to query other keys you can consult the documentation on the GetKeyState() function and Virtual Key Codes.
2010-08-05 | SetPoint 6 and the discrimination of the ambidextrous
Plagued by constant trouble with my Logitech mice I recently decided to check for a new version of the infamous SetPoint (infamousness is inheritable). Having been using SetPoint 4.8 I was pleasantly surprised at the double major version jump - despite longstanding experience that new versions hardly ever deliver a net benefit. Maybe it's the profession of software engineering where "this bug is fixed in the latest version" is not only an illusion but the safeguard of your paycheck. But I digress ... Let's just say I was enthusiastically optimistic.
Both my enthusiasm and my optimism were reinforced when my Cordless Optical TrackMan, for which I was already applying for a South European citizenship (you know, because of how often they strike ...), suddenly started working again. The setup program promising to do away with the annoying-to-death and premature battery warnings, and the user interface looking cleaner and feeling less sluggish was just the icing on the cake.
Understandably enthusiastic (and optimistic) I started redoing my settings and soon started noticed that an elementary feature had died the feared death through ominous marketing decisions; the little check box to switch the left and right mouse buttons on a device-by-device basis. The only way to swap the buttons now was Windows' own control panel dialog, which, just as ominously, affects all the mice connected to the system.
"What's the big deal? How many mice do you need for one computer?" you say? The answer is at least two if you're ambidextrous or suffer from mouse overuse syndrome (and at least three if you count the one on the sofa for when you hook up your PC to the TV).
Slightly less enthusiastic (but still optimistic) I decided to e-mail Logitech customer support. I had heard lots of good things about them, plus it's educational to use your own company's customer support, so you can see it the way ordinary customers do.
It only took a few hours to get a response. The friendly support guy told me that he had also failed to accomplish what I was trying to do and that the only solution was to downgrade to SetPoint 4.8; not exactly what I had in mind.
I don't give up easily though. I was already contemplating writing an HID filter driver when I thought of uberOptions, a very dedicated and inspiring project that is the rescue of all people who feel that after buying an expensive input device they deserve to do with its buttons what they want.
Even though SetPoint 6 is not officially supported yet it worked great. After a quick installation I finally got my 'Swap buttons' check box back:

And I clicked happily ever after ...
There's a side story to this one, which is that my MX Revolution mouse recently started refusing to charge, which seems to be a common problem. Luckily, for now, I haven't had to use the soldering iron. Instead, cleaning all the charging contacts and taking out and replacing the very same battery (easy to do; the four screws are under the little rubber pads) seems to have helped.
So, in just a few days I went from having two expensive designer paper weights on my desk back to my proven "2 Logitech mice + 1 Microsoft keyboard" sandwich.
PS: I was trying to find some statistics to confirm my conviction that the French, Italian, Spain, and Greek without a doubt must lead the strike statistics only to be heavily disappointed by the real numbers. But, as one of my friends likes to say, don't let the truth get in the way of a good story. :-)
2009-02-05 | How not to enable fuzzy string matching in Postgres
I have ranted previously about people not being able to read attentively when they're trying to solve problems. Here's another one:
A few years ago I helped teach a class on information systems, namely I was in charge of the fun part - a project where students had to write their own web application.
Because lack of documentation was always the part that bugged me most about projects when I was a student myself I spent a great amount of time writing the project material and how-to guides for the software we were using. After the class I mirrored the material on my own website. (Yes, I'm proud of the project being a success.)
Now, for some reason one of the how-tos shows up quite high if you search Google for words like "postgres fuzzy string matching". At one point it tells students:
[...] if you want to use these functions in your database please send a quick e-mail to Martin so we can activate it for your databases.
And they do! Today is the second time I got an e-mail from some random person (this time a student, last time a post-graduate!) asking me to please enable fuzzy string matching in their database. It looks something like this:
Dear Mr Martin Rubli,
I want to use fuzzy string matching in my database. Can you activate it for my database ?.
I hope to hear from you soon. Thank you.
There are several things that strike me here. The first one is that it should be pretty clear from both the URL and some of the text that this is class material, not some generic tutorial. Then, why do those people think I'm running a charitable Postgres fuzzy string matching activation service instead of just posting the simple instructions on my website? And finally, let's assume I had such a magic service, am I supposed to guess the server addresses and the access data?
I think the message is clear here: If you want me to enable fuzzy string matching in your Postgres database, for god's sake include some IP addresses and credentials, so that I can have some fun with them! :-)
2008-09-17 | Vista: User profile startup programs not executed
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.
2008-09-09 | ASUS NX1101 跟Vista六十四bit不能用
"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. :-)
2008-08-05 | Quoting strings in INF AddReg sections
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):
[MyTool.Addreg]
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!
2008-07-10 | OS detection in a Windows shell script
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
2008-05-19 | Integrating Flex and Bison into Visual Studio
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:
%GNU_PATH%
¦ bison.cmd
¦ flex.cmd
¦
+---bin
¦ bison.exe
¦ flex.exe
¦ m4.exe
¦
+---lib
¦ cygwin1.dll
¦
+---share
+---bison
¦
+---m4sugar
m4sugar.m4
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.