Sunday, December 12, 2010

A stripped-down Rockbox build for the Archos V2 Recorder

The Archos V2 Recorder has only two megabytes of RAM. This RAM is used for the software running on the device, and whatever RAM remains may be used as a buffer to store MP3 data. It's a very small amount of RAM and even at 128 kbps, most songs cannot fit. Because of this, the hard drive has to spin up frequently to read additional data.

In 2007 I noticed how newer versions of Rockbox left less free buffer space and I decided to make my own build with more free space. The first step was a RomBox build. This helped a lot, but I wasn't satisfied. I saved more RAM by disabling various features which I didn't need: code page loading, language loading and the voice interface. With this build, I have 1.774 MB of buffer space.

I also fixed a few bugs, either by backporting fixes from later versions or by fixing the bug myself. Most notably, I fixed the charging screen issues.

Here are some files associated with this custom build:
This is all based on Rockbox from November 2007. I've used this build for years on my V2 Recorder without running into any significant problems. I view it as a finished product, because I see no need to update the V2 Recorder to newer versions of Rockbox, and my attempts to minimize memory usage encountered diminishing returns.

I did not make any builds for other old Archos devices because I don't have access to those devices for testing. It should not be hard to build for those. The only tricky part is what I did to the language system to save RAM.


This is based on Rockbox r15545. You can now download just the patch. Here's a list of the included fixes and changes:
  • FS#9638 - temp_cue is unused and wasting memory 
  • FS#7631 - Charging screen broken on V2 Recorder. Several fixes enable the charging screen, display of input current on the screen, and proper startup from the charging screen.
  • FS#9635 - Instant backlight turn-off on FM/V2 Recorder
  • FS#8163 - Rockbox (Sansa) hangs in settings menu. This fixes a crash caused by the scrolling title used for setting text horizontal scrolling speed. 
  • Removal of language changing, with English language strings used directly from ROM. (This requires manual intervention when building.)
  • Removal of voice functionality.
  • Removal of codepage changing
  • Removal of the database (this is part of the RomBox instructions).
  • Removal of low battery shutdown
  • Unused conditionals for removing bookmark functionality. This part is probably incomplete and bookmark functionality remains.
In general, the removals are kind of incomplete and messy. I removed the main memory using parts, but I didn't remove all traces of those features. For example, the settings for removed features still remain. I did not extensively test all possibilities, but I did not run into any problems whatsoever over years of use.

Saturday, December 11, 2010 is closing and my files were hosted there

In the past I chose to use for hosting files (other than photos) which are associated with this blog. I just learned that is closing and all files will be deleted on December 15th. I just found out about this as I went there to replace a file with a newer version. The blog post claims that notification e-mails will be sent, but I didn't receive any e-mail despite having an e-mail address associated with my account.

I'm now hosting my files via Dropbox. I think I updated all the links. If you find a broken link, leave a blog comment here or on that particular article.

Wednesday, December 08, 2010

Sometimes, a period doesn't match any character

Recently I found that in regular expressions in GNU sed, ‘.’ failed to match some characters. At first it was very surprising, but there's a simple explanation in the GNU sed manual:
s/.*// does not clear pattern space
This happens if your input stream includes invalid multibyte sequences. POSIX mandates that such sequences are not matched by ‘.’, so that ‘s/.*//’ will not clear pattern space as you would expect. In fact, there is no way to clear sed's buffers in the middle of the script in most multibyte locales (including UTF-8 locales). For this reason, GNU sed provides a `z' command (for `zap') as an extension.

To work around these problems, which may cause bugs in shell scripts, set the LC_COLLATE and LC_CTYPE environment variables to ‘C’.

The used the ISO-8859-1 character set while Cygwin by default uses UTF-8. The characters not being matched formed invalid sequences in UTF-8. Setting ‘LANG=C’ also fixes the problem.

Thursday, December 02, 2010

Hiding a window from the Taskbar using WS_EX_TOOLWINDOW

A window can be hidden from the Taskbar by adding the WS_EX_TOOLWINDOW extended style. As a side-effect, this changes the window frame, but that may not be a problem. When modifying an already existing window, that window needs to be hidden and then showed again for the modification to take effect.

One application can easily do this to a window of another application. For example, here is a bit of code for doing this to Windows Live Messenger:
HWND hw = FindWindow("MSBLWindowClass", NULL);
if (hw == NULL) {
printf("Window not found.\n");
return -1;
ShowWindow(hw, SW_HIDE);
SetWindowLongPtr(hw, GWL_EXSTYLE,
GetWindowLongPtr(hw, GWL_EXSTYLE)
ShowWindow(hw, SW_SHOW);

It works well, but the code has to be run every time the window is created. It's better to actually create the window with WS_EX_TOOLWINDOW, but that requires a bit more work. The simplest way is to intercept the function which the application uses to create windows. Detours provides an easy way to do this. For example, to hide the Windows Live Messenger window, intercept CreateWindowExW. The intercepting function just needs to do the following before calling the real function:
if ((((DWORD)lpClassName) & ~0xFFFF) != 0 &&
!wcscmp(L"MSBLWindowClass", lpClassName)) {

I don't recommend patching of binaries. It's more difficult to understand program flow and devise a patch, and some applications would make it even more difficult via packing and anti-debugger techniques. Patching also needs to be re-done when the application is updated. In this case, it only makes sense as a reverse engineering training exercise. One hint: a Win32 API monitoring program such as WinAPIOverride32 can easily find the location of the call.

Getting elapsed time since last Windows wakeup via CallNtPowerInformation

Windows provides the last system wake time via CallNtPowerInformation. It returns the "interrupt-time count, in 100-nanosecond units". To obtain the time since last wake, this needs to be subtracted from another value, but the documentation doesn't explain what other value can be used. In Windows 7, GetTickCount and GetTickCount64 (which return time in milliseconds) work great. The combination even returns a good result after a bootup, when the system hasn't slept yet. Do not use QueryUnbiasedInterruptTime or QueryPerformanceCounter. The latter will be close enough at first, but every time the system sleeps and wakes, additional error will accumulate.

Wednesday, November 10, 2010

Using Detours Express from GCC

Detours Express must be compiled using a Microsoft C++ compiler. It can be used from GCC, but some significant issues do come up.

When attempting to use Detours from GCC, the first problem is that GNU ld cannot resolve some symbols in static libraries that were created by Microsoft compilers. This can be solved by creating a DLL. First, a .def Module Definition File needs to be created to export the needed symbols. The list of functions can easily be obtained from the header file, using sed -n "s/^.* WINAPI \([^(]*\)(.*$/\1/p" detours.h. Once you have that, you just have to add a single data export and the statements that go at the beginning of the .def file:

..\detoured.lib msvcrt.lib kernel32.lib /out:detours.dll
LIBRARY detours

If you want, you can create a resource file with VERSIONINFO. Simply copy detours.rc in the Detours source directory and then edit it. The only fields that need to be edited are the FileDescription and DLL names. It's probably also a good idea to set the VS_FF_PRIVATEBUILD flag in FILEFLAGS by setting FILEFLAGS to 0x8L, and below provide a "PrivateBuild" VALUE with information about your build.

If you want to name your DLL detours.dll, it must not be built in the lib directory, because that would overwrite detours.lib, which is your input file. So, go to another directory and create the DLL:

set LIB=C:\WinDDK\7600.16385.1\lib\wxp\i386;C:\WinDDK\7600.16385.1\lib\Crt\i386
link /release /machine:x86 /dll /def:detours.def /incremental:no /subsystem:console detours.res ..\detours.lib ..\detoured.lib msvcrt.lib kernel32.lib /out:detours.dll

At this point, you have a usable DLL, but it's a good idea to create a corresponding .dll.a interface library file for GCC. This is a simple process, but a stdcall function decoration issue needs to be dealt with. The Detours Express API uses the stdcall calling convention, but the functions in the DLL have no decoration. (Windows system DLLs like kernel32.dll do the same thing.) It can be a problem, because GCC will attempt to link stdcall functions to decorated names such as DetourAttach@8. To solve this, create an entirely new .def file using gendef. Use the the -a switch, because gendef can't detect that zero-argument functions use stdcall, and do it in a new directory if you want to keep the old detours.def. DetourGetDetouredMarker forwards to Detoured in detoured.dll, so either run gendef on detoured.dll first or add the @0 to that name manually. Use dlltool to create the interface library, using the -k switch so the decorated names in the interface library can dynamically link with the undecorated exports in detours.dll:

dlltool -k -d detours.def -D detours.dll -l libdetours.a

Finally, everything is ready for compilation. The sample programs provide a simple way to test Detours Express, and with some minor changes, they can be compiled with g++. The main issue is that g++ follows the standard and refuses to automatically convert function pointers to void pointers, but that's easy to fix by adding (PVOID) casts.

Unfortunately, when using GNU ld from binutils, functions which are imported from DLLs are intercepted in the current module, bit not in any other modules. For example, the simple sample outputs that it "slept 0 ticks". This is because the thunk (which is an indirect jump to the actual function) is intercepted instead of the actual function. Detours attempts to correct this via DetourCodeFromPointer, but it fails because GNU ld doesn't fill out the data directory structure for the import address table and detour_is_imported returns false. (You can use objdump -p to view the data directory.) This bug was fixed in September 2010, and the binutils-2.21.51.tar.bz2 snapshot contains the fix. (Here is a thread discussing the fix and one CVS log entry from the fix.)

If you're using a buggy ld, it's also possible to work around this problem by declaring imported functions with __declspec(dllimport). When using the MinGW headers, Windows API functions may be declared this way by defining __W32API_USE_DLLIMPORT__ before including header files. This causes the corresponding function addresses to be correct, but no longer constant (due to dynamic linking). When compiling via g++, this is not a problem because the compiler automatically generates code to initialize global variables. However, gcc cannot do this and so code must be added to initialize such global variables at runtime.

Building Detours with the WDK compiler

Detours is a library for intercepting arbitrary Win32 binary functions. A free version called Detours Express is available "for research, non-commercial, and non-production use on 32-bit code".

The Detours Express package only contains source code. It must be compiled using Microsoft's C++ compiler because it uses non-standard extensions such as the try-except statement. I compiled it using the compiler in the WDK (Windows Driver Kit). (To install, download the WDK CD image and install "Build Environments". That list of packages requires 1.37 GB. If you want to reduce this, you can uninstall individual unwanted packages by right-clicking on their .msi files and selecting uninstall.)

Detours Express uses the DbgHelp library, but dbghelp.h is not in the WDK. This may be remedied by downloading Debugging Tools for Windows and installing the included SDK. (Detours Express loads dbghelp.dll via LoadLibraryA, so you don't have to worry about linking that in.)

By default, the compiler isn't in the path and there is no search path for include files or libraries. This may be remedied by setting some environment variables from a batch file:

SET "INCLUDE=c:\WinDDK\7600.16385.1\inc\api;c:\WinDDK\7600.16385.1\inc\crt;C:\Program Files\Debugging Tools for Windows (x86)\sdk\inc"
SET LIB=C:\WinDDK\7600.16385.1\lib\wxp\i386

Recent versions of the WDK do not include lib.exe. This is not a problem, because lib simply called link. Simply replace lib with link /lib in the Makefile. After that, just run nmake and Detours will build.

Saturday, October 30, 2010

Yahoo Messenger also censors messages

I already knew that Windows Live Messenger censors messages at the server. I thought Yahoo Messenger was better. It is not; it does the same thing and it doesn't even notify when message delivery fails. This is happening with messages sent between Trillian and Miranda IM, so it has to be sever-side.

The best solution is encryption. I recommend Off-the-Record Messaging (OTR).

Wednesday, October 20, 2010

Getting rid of my last name in Windows Live Messenger 2011

Windows Live Messenger 2011 tries to force people to use their real first and last name as their display name. There is no more display name option in Messenger, and the only way to change the name is via Windows Live profile settings on the web, where the web page requires a that both a first and last name is input. I went to a page showing unicode spaces and tried pasting those as my last name. Most resulted in an error, but one finally worked. I think it was U+202F narrow no-break space. It seems I don't have a space as my last name; the last name is gone.

Saturday, October 02, 2010

Virtual TI 2.5 Windows 7 compatibility fix

If you run Virtual TI 2.5 beta 5 under Windows 7, it fails with an error dialog which says "Failed to set data for 'LastEmuVersion'". A simple workaround is always running Virtual TI as Administrator, but that gets annoying.

The error means that Virtual TI was unable to save settings in the registry. It attempts to save settings under HKEY_LOCAL_MACHINE\SOFTWARE\ACZ, and it is not allowed to write there. Instead, it should be saving them under HKEY_CURRENT_USER\Software\ACZ. Normally, Windows 7 registry virtualization would automatically fix this problem by redirecting writes HKEY_CURRENT_USER\Software\Classes\VirtualStore\MACHINE\SOFTWARE\ACZ, but something goes wrong.

To fix the problem, open regedit and grant yourself write access to KEY_CURRENT_USER\Software\Classes\VirtualStore\MACHINE\SOFTWARE\ACZ and all of its child objects. If the key doesn't exist, create it.

Wednesday, September 29, 2010

A quick summary of some TI-85 emulators

I tried a few TI-85 emulators, hoping that they would be more convenient than testing code on a real calculator. Here are some observations using my version 9 TI-85 ROM:
  • Wabbitemu has a nice user interface. The TI-86 skin looks great, and it's nice how I get visual feedback when I press buttons. I don't mind that it's not a TI-85 skin. However, there doesn't seem to be any way to transfer TI-85 files to the emulator, so it's useless for development.
  • TilEm 0.972 looks kind of ugly due to the scaled up low resolution skin, and the screen standing out too much. Multiple attempts to transfer a backup to the calculator failed, and so I couldn't use it for running assembler programs. I couldn't get 0.973 to display the skin.
  • Virtual TI 2.5 has some problems, but it is usable. In Windows 7, it has to be run as Administrator (or else I get a "Failed to set data for 'LastEmuVersion'" error). I've had some linking failures, but I was generally able to transfer a backup after resetting the calculator. When transferring variables, I got annoying linking errors whenever a variable under that name exist, so I'm forced to delete variables before re-uploading them. The skin looks worse than Wabbitemu, but it is a TI-85 skin which looks like my TI-85, and it looks a lot better than TilEm.

Sunday, September 26, 2010

Usgard relocation table format

Usgard is the most recent and most capable assembly shell for the TI-85 graphing calculator. It can run ZShell programs, but it also offers additional functionality which can be used when writing programs specifically for Usgard. The primary advantages are relocation and functions for accessing TI-85 variables.

On the TI-85, assembler programs are stored in string variables, and they execute in-place. The initial location of the variable depends on the amount of free RAM, and the variable can me moved when other variables are deleted. Because of this ZShell code cannot rely on being at a fixed address. Usgard's relocation almost removes this concern. At the end of a program is a list which shows what locations in the code need to be updated with the current position. The list contains two kinds of entries:
  • a single byte, whose value is the offset of the current relocation position minus the offset of the previous relocation position.
  • a zero byte, followed by a 16 bit little endian absolute offset of the relocation position.
The single byte form is used whenever possible. At the beginning, the previous relocation position is considered to be zero, and the single byte form can be used for relocations at absolute offsets 1 through 255. The file is assembled starting at offset zero (".org 0") and this determines absolute offsets and initial values of locations requiring relocation. All locations requiring relocation contain little endian 16 bit numbers. The list of relocations is followed by a four byte header which consists of two 16 bit little endian values. The first value is zero minus the number of bytes in the relocation table, and the second value is the number of relocation entries.

To perform relocation, Usgard needs to add the current offset of the program to all of the locations requiring relocation. When the program terminates, Usgard undoes these changes by subtracting the current offset from the locations.

The only disadvantage of Usgard relocation is that the relocation table is created via a sort of kludge using an ancient toolchain which runs in MS-DOS. All operands which require relocation need to be prefixed with an ampersand. Before assembly, the code is preprocessed via SRCWIZ.EXE, which removes the ampersands and adds labels of R_ followed by a number, with the number starting at zero. Then, this code is assembled, and STRING85.EXE creates the relocation table based on the listing produced by the assembler. A batch file ties all this together and at the end replaces the files altered by SRCWIZ with the originals.

Several programs in the Usgard directory were compiled with old Borland Pascal compilers. They fail with "Runtime error 200", meaning divide by zero, because modern computers are too fast for Borland Pascal delay loop calibration. Fortunately, this is easy to fix with TPPATCH.

Overall, the toolchain works, but I would prefer something more modern. Maybe I'll try using the GNU assembler or even the Small Device C Compiler (SDCC).

Wednesday, July 07, 2010

A guide to some Southwestern Ontario fruit

I was born in Zadar, on the Croatian Adriatic coast. Compared to fruit available there, a lot of fruit in Ontario is terrible. It's kind of like listening to a 32kbps MP3 or PC speaker playback instead of a CD. Often, major components of taste are barely noticeable or missing. Some fruit can even be tasteless or a bad mix of unripe and rotten. Sometimes, it's possible to obtain good fruit by buying it from roadside stands and picking your own. Here I will list some of what I discovered.


In spring, some very nice imported strawberries may be found in supermarkets. Many Ontario strawberries are less sweet and tasty and/or more acidic. However, I have repeatedly found good strawberries at Schoger Orchards (432 County Rd. 34, between Essex and Cottam, 519-839-4675) and Raymont's Berries. Usually, local strawberries are only available in June, but at Raymont's Berries, they're available from around mid May to Thanksgiving or beyond. It seems pick your own is only available in late spring, but good prices on already picked flats and large baskets are available year round.

Note that strawberries don't need to be fully dark red. In fact, the really dark ones are overripe, less tasty, and more vulnerable to spoilage. Those with a bit of lighter colour on them can still be ripe, sweet and tasty. Also, note that while larger size makes picking easier, it doesn't guarantee good taste.

Sweet Cherries

Ontario cherries are usually less sweet, less tasty and more acidic. In almost all cases, the imported cherries in the supermarket are better. So far, I've found one exception: Red Barn near Arkona. Unlike most Ontario cherries, theirs are very dark red and almost black. The taste is not quite as amazing as the colour implies but it is good. The orchard is also a pleasant place to pick, because of the beautiful large trees which provide shade. Sturdy ladders are available, but not necessary, because many cherries can be picked from ground level. At least two other nearby farms also have good black sweet cherries.

Sour Cherries

I've never found especially good sour cherries in Ontario. They usually have very little taste other than sourness. So far, the best I've found are in the Arkona area. If you're there for picking sweet cherries, maybe also pick up some sour cherries, but don't expect too much. The cherries can be used to make a nice pie, and free pitting is available if you don't want to pit cherries yourself.


Some very good raspberries may be found in Ontario. They're available two time periods: early summer and late summer through early fall. However, not every place has raspberries during both periods. I've found good raspberries at Schoger Orchards and Awesome Berries & Gardens (where Northville Rd. ends at Townsend Line, near Arkona). The fall raspberries at Parks Blueberries were less tasty.

Note that raspberries are quite easy to grow yourself They're almost like a weed, spreading surprisingly fast via roots. Also, note that like with strawberries, very dark raspberries are overripe.


Blueberries may be the best fruit that Ontario has to offer. They cay be sweet and intensely tasty. Pick your own blueberries are available at Klassen Blueberries and Parks Blueberries.

I prefer Parks, because I've had a more consistently good experience with their blueberries. At Parks, you get a choice of up to four different varieties. I usually chose Bluecrop and I also like Reka.

At Klassen, there was never any choice in what variety to pick, and the blueberries were acidic and less tasty early in the season. However, later on I also found good blueberries at Klassen, and Klassen usually had a longer picking season.


Ontario is definitely capable of producing very good peaches. Unfortunately, such peaches are very rarely available. It seems like most farms pick unripe peaches and store them far too long. I've never seen pick your own peaches because peaches are too delicate. Considering all of this, it's probably better to buy peaches in a supermarket. If you want the best peaches, you need your own peach tree.

It seems that smell is a the best predictor for peach quality. Seek sweet peach smells and avoid acidic unripe smells or unpleasant subtle rot smells. In terms of colour, ignore the red, because even unripe peaches can be very red. Instead, check to see that the other parts are yellow or even yellow-orange and definitely not green.


Ontario can produce excellent apples. My favourite place for picking is Thiessen Orchards. They have plenty of varieties available in their large orchard. My favourites are Royal Gala and Honey Crisp. I used to like Golden Delicious, but apples from their current trees are less delicious than the ones I remember. In general, it seems that varieties which produce a smaller quantity produce more delicious apples. Note that while apple picking is easier and less time consuming because of the smaller size, that also means you save less money by picking your own.

Early apples are available starting around midsummer. They're usually sour, less sweet and with a less appealing texture than the familiar apples. However, around that time their freshness can make up for their inferiority.


Ontario grapes are often small, with tough skin and large seeds. This results in a lot of tough material, and relatively little of the desirable juicy flesh. Fortunately, it's possible to find seedless concord grapes which lack this problem. I highly recommend them, because they are very sweet and tasty. The taste contains some strong components which are not found in typical warm climate grapes in supermarkets, but I like those components.

Wednesday, June 23, 2010

Dell KD476 battery disassembly

I just got a replacement battery for my Dell Inspiron 6400 laptop. The price was so good that I couldn't justify an attempt to replace the cells in my old battery. However, I was still curious about what's inside.

The case consists of two halves: the bottom, which serves as part of the bottom of the laptop, and the top, which slides over the bottom and covers the rest of the battery. The printing on the top is actually a sticker. It may be removed to see the cells, but it does not provide useful access to the battery. In order to gain access, the two halves of the case need to be separated. This is difficult because the bottom slides over the top with considerable overlap, and that overlap is glued together. I decided to carefully pry apart the overlap. I started prying the edges of the bottom away from the top (sideways) using a blade. Once more space was available, I pried apart the overlap using a screwdriver. This did cause a few cracks in the sides of the base and some damage to the overlapping part of the top, but the result is acceptable.

Here you can see the internals of the battery. The cells are connected in parallel in groups of three, and then the three groups are connected in series. At this point, it's possible to measure the voltage of individual groups of cells. The right two groups measure 4.09V and 4.08V, while the left group measures -0.92V. Those measurements imply the right two groups are fully charged and the left group is bad.

The cells are labelled LGDB118650. The number and size make me think they are 18650 cells, just like in many other laptops. At this point, I could replace cells or maybe even build a 6 cell battery out of this 9 cell battery. However, I don't know if the protection circuit needs to be reset using special software.

The protection circuit consists of two circuit boards wrapping around a corner. One board, which I shall call the power board, contains the connector, protection switch MOSFETs and fuses. It is glued to the case with some hard silicone behind the connector. The silicone can be pried away from the case to free the board.

The other board, which I shall call the control board, contains a lot more components. It also has the 5 LED charge state bar graph along one side.

Among other things, the control board has a bq29311 protection IC and a bq20857 IC which seems to be the controller. The latter may be a problem when replacing cells.

Tuesday, June 08, 2010

Microsoft Wheel Mouse Optical button switch replacement

The left button switch on my Microsoft Wheel Mouse Optical started failing. The button did not turn on and off at the point where it clicked; more pressure was needed. This led to failed clicks and unintended double clicks.

The fix was simple. While I didn't have the exact same switch, a larger switch used in many other mice fit perfectly. All I had to do was remove an extra (normally closed) pin from the switch. Before closing the mouse, I also lubricated the wheel to improve the feel and reduce noise.

Thursday, May 27, 2010

Yokohama YK520 tire sidewall cracking

These Yokohama YK520 tires were manufactured and purchased in 2008. In spring 2010 I noticed sidewall cracks in the most central part of the outer sidewall. There was this worryingly big crack, another longer but narrower crack on another tire, and a lot of tiny cracks (or crazing) on all tires. The big crack went all the way through the top layer of rubber, revealing an undamaged black layer underneath.

Sunday, May 16, 2010

Putting 25 fps progressive video on an NTSC DVD

I recently did some research on how to put 25 fps progressive PAL video on an NTSC DVD. Two things became clear quickly: DGPulldown is the best way to deal with the frame rate conversion, and HCenc (HC Encoder) is the best free MPEG-2 encoder.

Those are just two parts of the overall process. There are also other parts, such as resizing, encoding audio and authoring the DVD. Various software packages automate the whole process. I tried out a few of the packages which come with HCenc and DGPulldown. I was disappointed with most. The best package was FAVC.

FAVC is easy to use and reasonably fast, and it produced good quality video. There were only a few minor issues: it encoded with "*AUTOGOP 15" which could lead to a problem after applying DGPulldown, and when testing the "Play all" menu option in Windows Media Player 12, it was only possible to get back to the menu from the first title. Fortunately, it easy to fix some issues and make changes with FAVC. Just stop the process when HCenc starts, edit configuration files, and re-run "Title.bat".

It's possible to create a better and more customized menu using GUI for dvdauthor/MuxMan. That program can be used to continue from the audio and video files created by FAVC. I decided not to use it because of the added complexity and because the "Play all" button worked on my DVD player.

Friday, March 12, 2010

An easy way to enable and disable the second monitor in Windows 7

Both Screen Resolution (desk.cpl) part of Windows 7 Control Panel and NVIDIA Control Panel offer a way to enable and disable a secondary monitor. However, they're annoying. It takes too many clicks, and there is a confirmation prompt which cannot be disabled. There is 3rd party software for this, but installing software for this seems excessive, and paying for it seems ridiculous. The OS and/or display adapter drivers should make this easy.

Fortunately, there is an easy solution. It appears under "Connect to a Projector" in the start menu and corresponds to "%windir%\system32\displayswitch.exe". It can also be started using the Windows+P hotkey. Best of all, it allows command line switches, which can be mapped to hotkeys via a utility like HoeKey:

Extend desktop across both displays:displayswitch /extend
Only use primary display:displayswitch /internal
Display same image on both:displayswitch /clone
Only use secondary display:displayswitch /external

Wednesday, March 10, 2010

Verified by Visa sucks

Last night I learned about another shortcoming of the Verified by Visa program. A single authentication allows the merchant to complete multiple transactions, including past transactions which were stopped by Verified by Visa.

I had forgotten one aspect of my Verified by Visa password, and so I was unable to complete a order. I didn't get any confirmation and the order wasn't listed under the list of orders, and so I assumed the order was aborted. Then I reset my password and repeated the order. After I completed the Verified by Visa authentication, the old order appeared in the list of orders and proceeded as if I had authorized it. In fact, the single Verified by Visa authentication allowed four orders to proceed; each order had been split into two parts by Newegg.

This is not security. A Verified by Visa authentication does not prove consent for anything.

(Yeah, I was able to quickly contact a Newegg customer service representative and void the order. So, everything is ok. The only consequence is decreased confidence in Newegg's website and Verified by Visa.)

Monday, March 01, 2010

Notes on creating an OEM XP disc for an old IBM IntelliStation

  • The computer had all the required files in C:\I386. There was also the VALUEADD folder from the XP CD.
  • C:\I386\UNATTEND.TXT contained the key needed for an OEM pre-activated (SLP) install. That's a better choice than the key on the sticker on the back, because activation not needed. Microsoft provides instructions for preserving OEM pre-activation; basically, just use that key.
  • I verified the files in C:\I386 by comparing MD5 sums with files on an XP CD. There were a few differences, but nothing suspicious. Slipstreamed hotfixes could be identified by searching for the file and its version. There was only one minor error in the files: I386\WIN9XMIG\MAPI\DLL\MKNTFRMCACHE.EXE had been renamed to MKNTFR~1.EXE.
  • SP3 can be slipstreamed onto the initial release (RTM) of XP without obvious errors, but some files won't be updated. Because of this, I first slipstreamed SP2 and then SP3. Because of widely reported problems with slipstreaming SP3 in Vista, I slipstreamed it in XP.
  • Drivers were available in C:\IBMTOOLS\DRIVERS and C:\DRIVERS. The newest drivers were available from IBM's web site, so I used those.
  • I stripped down the UNATTEND.TXT file to create WINNT.SIF file which partly automated the installation. (When installing from a CD, the file must be called WINNT.SIF.)
  • I was able to load mass storage drivers from a floppy. Setup was then able to see the hard drive. However, when copying files to the hard drive, I got a "setup cannot copy the file" error. Eventually I found that the drivers need to be present in A:\$OEM$\TEXTMODE. I wonder if this was because of WINNT.SIF options or it being OEM XP.
  • There are instructions on editing TXTSETUP.SIF to add mass storage drivers to the CD. A better way is to use WINNT.SIF and place the drivers in both \$OEM$\TEXTMODE and \I386\$OEM$\ on the CD.

Changing Windows 7 ICS IP

When Internet Connection Sharing (ICS) is enabled in Windows 7, the local IP address of the computer becomes However, that address isn't locked. I was able to change it to in the usual way (in "Internet Protocol Version 4" properties in the "Local Area Connection" properties.) After this change, DHCP doesn't work right, but NAT works perfectly. So, ICS can be used as an emergency replacement for a router when all the computers have statically assigned IP addresses.

Missing .htc files cause a 404 for the whole page

Last night I was helping a friend fix a web page in Internet Explorer 8.0. The problem was quite weird. The page would load and display properly for a moment, but then Internet Explorer would display its "The webpage cannot be found" page.

We found that this behaviour could be stopped by disabling "Binary and script behaviors" in the ActiveX section of security settings, or by disabling "friendly" HTTP error messages (in advanced settings).

The JavaScript debugger could be used by pausing execution and then reloading the page, but this was not helpful. The location where the 404 appeared changed a bit, and in any case, JavaScript didn't seem to do anything to cause a redirect. JavaScript debugging ended up just being a waste of time.

We eventually found that the problem was due to a missing .htc (HTML Components) file.

Tuesday, February 23, 2010

Windows 7 does USB audio correctly

I wasn't too impressed with USB audio in Windows XP and Vista. I had to manually switch between audio outputs, and I saw a few blue screens when unplugging USB audio device.

USB audio finally works right in Windows 7. When a USB audio device is plugged in, audio output switches to that device. When the device is unplugged, audio output switches back. I can even use my USB wireless headphones to listen to line in on the motherboard. Most importantly of all, USB audio doesn't crash Windows 7.

Tuesday, February 16, 2010

Concatenating DVD titles using Avidemux and Ifoedit

To join VOB files in a single set (such as VTS_01_1.VOB and VTS_01_2.VOB), you can simply concatenate them using a utility like cat. They are actually already concatenated on the DVD; they only appear separate in the filesystem because the standard limits file sizes to 1GB for compatibility purposes.

For joining multiple VOB sets, Avidemux seems like a pretty good choice. An entire VOB set can be opened by opening just the first file. (Avidemux asks if you want to index the file and append the other parts of the set.) Then, other VOB sets can be appended using the Append option in the File menu. Finally the basic video editing features in Avidemux can be used to remove duplicate or unwanted content.

The resulting video can be put onto a new DVD via Ifoedit. First, the audio and video need to be saved separately from Avidemux. Then, the DVD authoring functionality of Ifoedit can transform this into files go in a VIDEO_TS folder. Finally, the result can be burned using any DVD burning software which can burn video DVDs.

What doesn't work?

A lot of software in this area is annoying and/or broken.
  • DVD Shrink can easily put two titles on one DVD. However, it can't create menus or join them into one title. That makes navigation annoying.
  • If the VOBs are just concatenated, only the first title is playable.
  • VobEdit's "Join Clips" feature is useless here. When joining files, it gives each file its own VOB ID. When Ifoedit creates the IFO files, seeking only works within the first VOB ID.
  • Avidemux failed to index the VOB set that Ifoedit created. The VOB set is progressive, but the Avidemux index says it's interlaced. It's easy to change "Image : I" to "Image : P" in the index file; I just wonder whether there's something wrong with the VOB set.
  • MPEG Streamclip requires the MPEG-2 QuickTime component for preview.
  • VirtualDub and related programs can't save in MPEG-2 format.
  • Windows DVD would re-encode all the video even though it's already in the right format.

Tuesday, February 09, 2010

Deleting a file called "nul" in Windows 7

I tried to use "nul" instead of "/dev/null" in Cygwin. That created a file called "nul". When I tried to delete the file in Explorer, I got an interesting "Invalid MS-DOS function" error:

The file can be deleted (and otherwise manipulated) from Cygwin. It can also be deleted from the Windows Command Prompt by prefixing its full path with "\\?\".

Tuesday, January 26, 2010

Eclipse CDT incompatibility with Cygwin 1.7

Eclipse failed to detect the Cygwin GCC toolchain. Attempts to manually set the toolchain in project properties led to an error being displayed below the choice: "The configuration support is not installed on the system". This is because Eclipse gets Cygwin paths from the registry, and Cygwin 1.7 stopped storing them there. To fix the problem, I added the paths to the registry using a .reg file:


[HKEY_LOCAL_MACHINE\SOFTWARE\Cygnus Solutions\Cygwin\mounts v2]
"cygdrive prefix"="/cygdrive"
"cygdrive flags"=dword:00000022

[HKEY_LOCAL_MACHINE\SOFTWARE\Cygnus Solutions\Cygwin\mounts v2\/]

[HKEY_LOCAL_MACHINE\SOFTWARE\Cygnus Solutions\Cygwin\mounts v2\/usr/bin]

[HKEY_LOCAL_MACHINE\SOFTWARE\Cygnus Solutions\Cygwin\mounts v2\/usr/lib]

Customize the "native" values to point to your cygwin directory.

Thursday, January 21, 2010

Compiling HPLIP in Windows using Cygwin

Windows drivers for the HP Color LaserJet 2840 All-in-One Printer are a bloated piece of garbage. Scanning over the network doesn't work, and downloadable drivers only offer printing support for 64-bit versions of Windows. The potentially decent Windows driver alternatives may be to only use the all-in-one for printing or connect the printer via USB to a computer running Windows 7.

Via HPLIP (HP Linux Imaging and Printing), Hewlett-Packard provides Linux drivers for many HP printers and all-in-one devices. The 2840 is fully supported. These drivers consist of applications and dynamically linked libraries which can work in Cygwin in Windows The process of compiling them is not straightforward, but it's certainly not impossible. Here I will concisely describe how to compile a lite version of HPLIP with scanning and printing support.

First, note the dependencies that are listed in the manual installation page. Some of these, (such as gcc, libjpeg and libcrypto) are standard Cygwin packages. They can simply be installed via the setup program. That is the easy part. The next step is compiling the dependencies. The following instructions list the important points (such as problems and workarounds) and omit the obvious things (such as running make and "make install"). They place everything under /opt/hplip, to keep things tidy and somewhat portable.

Net-SNMP 5.5

HPLIP seems to only require a stripped-down version of Net-SNMP; basically only the library is needed. Compiling only the needed parts simplifies things and avoids some issues:

./configure --prefix=/opt/hplip --disable-agent --disable-applications --with-perl-modules=no --disable-embedded-perl

The entire agent subdirectory is not needed; remove it from SUBDIRS in the generated top level Makefile.

Windows DLLs can't have undefined symbols, and because of this libtool normally requires a -no-undefined switch to build shared libraries in Windows. In in the Cygwin section of func_mode_link () in libtool uncomment the allow_undefined=no line and comment out the yes line. Note comments explaining the issue.

CUPS (1.4.2)

Even the network scanner driver depends on CUPS. Fortunately, CUPS is easy to compile. The only problem is that the rules for generating shared libraries are for Unix only. One could add Cygwin-specific rules or set up the project for Automake and Libtool, but it's far simpler to just disable shared libraries:

LIBS=-lz ./configure --prefix=/opt/hplip --disable-shared --with-cups-group=None

After CUPS is installed, create an administration password with "lppasswd -g admin -a root" and change AuthType to BasicDigest in /opt/hplip/etc/cups/cupsd.conf. The administration interface is at http://localhost:631/ and https://localhost:631/. Note that you don't need to let cupsd through your Windows firewall to access the administration interface on localhost.

SANE (sane-backends-1.0.20)

This is easiest to build. I simply configured it using:

./configure --prefix=/opt/hplip --with-group=None --disable-ipv6

When attempting to run "saned -d" before, I got "invalid fd in set, attempting to re-bind" errors. I think disabling IPv6 fixed that. In any case, I don't need IPv6.

While building tools/sane-desc, I got missing include file errors the first time. Surprisingly, retrying fixed that error.

HPLIP (3.9.12)

If you get a .run file, you can get a .tar.gz by starting with the 0x1F byte after the shell script. The contents of the resulting tar.gz are not all in one directory, like with most software. That means you need to create a new directory, change to it and extract there. You can also download a .tar.gz from HP. At this point you definitely need the dependencies, so add /opt/hplip/bin to the path and use CPPFLAGS and LDFLAGS:

CPPFLAGS=-I/opt/hplip/include LDFLAGS=-L/opt/hplip/lib LIBS="-lssl -lz" ./configure --prefix=/opt/hplip --enable-hpijs-only-build=no --enable-hpijs-install=no --enable-gui-build=no --enable-dbus-build=no --enable-cups-drv-install=yes --with-cupsbackenddir=/opt/hplip/lib/cups/backend --with-cupsfilterdir=/opt/hplip/lib/cups/filter --enable-qt4=no --enable-lite-build

After this, the generated libtool again needs to be fixed. Under the "libtool link mode" comment, uncomment "allow_undefined=no" and comment out "allow_undefined=yes". In prnt/hpcups/ErnieFilter.cpp, ensure that math.h is included; remove the conditional around the include.

After "make install" copy data/models/models.dat to /opt/hplip/share/hplip/data/models/models.dat, or maybe move the whole data directory. Also, move /opt/hplip/lib/bin/cygsane-hpaio-1.dll to /opt/hplip/lib/sane/. Then, add a hpaio line to /opt/hplip/etc/sane.d/dll.conf. You can comment out all the other lines in that dll.conf and remove /etc/sane.d and the dll.conf file found there. The only file that remains outside of /opt/hplip is /etc/hp/hplip.conf. That path is hard-coded into several hplip files.

Finally, it's time to configure CUPS. You can create a URI for your printer by probing it with hp-mkuri. For example "hp-mkuri -i" would give you something like hp:/net/HP_Color_LaserJet_2840?ip= if successful. When adding a printer, choose HPLIP and enter that URI. You can find your PPD file in /opt/hplip/share/ppd/HP/ and with the 2840, CUPS can retrieve settings from the printer (it just takes a while). At that point, you can print a test page.

At this point, scanning should work. Scanning from the command line via scanimage does not need saned running because it uses the backend directly. The output goes to standard output, so be sure to redirect it. Scanning from a GUI is possible via xsane-win32 and there even TWAIN frontends for SANE. Note that although saned is designed to run under inetd, it can be run temporarily via "/opt/hplib/sbin/saned -d".

The HPLIP GUI is not available and faxing isn't supported. The LyX instructions for compiling Qt in Cygwin seem promising, but I may not work on that anytime soon because I don't need the fax features and I expect the GUI would be bloated.