Friday, June 27, 2008

Prevent Your Desktop From Locking

In corporate environments you usually cannot change your screensaver timeout/desktop locking timeout. In case you have some application, that should be running with the screen off (like media player, Flash presentation etc.) you might ask how to prevent the screen from locking.

And here's a program that does it for you: MouseMoving program. It actually doesn't move the mouse, it sends a message to the input queue, that the mouse is in the same position, thus non disrupting your mouse movements while working.

#define WIN32_LEAN_AND_MEAN
#define WINWER 0x0610
#define _WIN32_WINNT 0x0610
#include <windows.h>

int main(void)
{
 INPUT i;
 while (1)
 {
  i.type = INPUT_MOUSE;
  i.mi.dx = 0;
  i.mi.dy = 0;
  i.mi.mouseData = 0;
  i.mi.dwFlags = (MOUSEEVENTF_MOVE || MOUSEEVENTF_ABSOLUTE);
  i.mi.time = 0;
  i.mi.dwExtraInfo = GetMessageExtraInfo();
  SendInput(1, &i, sizeof(i));
  Sleep(1000);
 }
 return 0;
}

For convenience binary version follows mousemove.zip (6.5 kB)

I found this utility really useful when I had to connect to a remote computer via VNC. I started the TightVNC server on the computer, but I had to come back to the computer in couple of hours. When VNC is not running as a service (and here it wasn't, I had no admin rights to that computer), you can't unlock the computer. So I started the mousemoving utility, which prevented the computer from locking and could connect happily in couple of hours back.

It's of course a completely wrong answer to completely wrong question. The program, that should be running undisrupted should be handling the WM_SYSCOMMAND notification and react to SC_MONITORPOWER/SC_SCREENSAVE messages. However according to MSDN article on WM_SYSCOMMAND:

Microsoft Windows Vista and later: If password protection is enabled by policy, the screen saver is started regardless of what an application does with the SC_SCREENSAVE notification—even if fails to pass it to DefWindowProc.

Currently I have no Vista machine to try it out, so the mousemoving application seemed like a better idea, however the article on SendInput says:

Microsoft Windows Vista. This function is subject to UIPI. Applications are permitted to inject input only into applications that are at an equal or lesser integrity level.

So maybe not even the MouseMove program will work in Windows Vista, I can't really tell without trying it out. You Vista users out there, please send a comment.

Obligatory thanks to Mark James for creating the amazing Silk icons.

Wednesday, June 25, 2008

Reimage is Pure Evil

My work computer is slow. But it's not because of the hardware, it's not because I'm running extremely computationally expensive tasks, it's because of corporate stupidity.

I work for a large multinational company, which has a dedicated department for creating "standard builds". These contain everything from operating system, office, antivirus to our corporate utilities. Since everything in the images is preconfigured, the desktop guys completely lost the ability to troubleshoot. The path of least resistance is to simply reimage every computer they get their hands on.

This has three consequences:

  • the corporate standard build has to fit all employees
  • the desktop guys don't educate themselves
  • even a monkey can be a desktop guy

The economical side of this solution seems favorable at first look, but I actually want to claim otherwise. Having locked down computer with standard builds actually costs more then having educated desktop department.

During my studies I used to work as the desktop department in a company of 70 people and I had never had to do a full reinstall. Everyone had administrative rights, when something went wrong I troubleshooted the computer spending from five minutes to three hours on a problem and I was able to fix everything. I explained the users what went wrong and gradually I had less and less work, because the users actually started to understand how computers work (I admit I was quite lucky).

True the employee to desktop guy ration was only 70:1, whereas in my current company is 199:1, but these guys are not even trying. Something is wrong on your computer? Bring it down for reinstall. No one learns anything and the problem is most likely going to repeat itself.

But that's not the worst part of it, the worst is the one size fits all approach. The computers come preloaded with so many utilities and services, that it literally takes minimum fifteen minutes to start up. In my case I have eight programs running under my account, which I have to kill after every startup, and 19 services which I don't use and which I can't do anything about without administrative privileges.

So for the convenience of the desktop department, everyone in the company spends first fifteen minutes waiting for the computer to start up. For one desktop guy to have easy and convenient work, 199 people have to suffer.

As a result people simply stop turning their computers off, they keep them running the whole night, wasting electricity.

Well done CTOs. I'm sure all the wasted mandays and electricity are much cheaper then to hire a couple more desktop guys.

Tuesday, June 24, 2008

JavaScript Object Inspector

Following my previous little JavaScript hack to display the stacktrace in Internet Explorer, I decided to write myself an object inspector. It lists all the properties and all the subproperties of objects.

There is actually nothing fancy about the script, the most important line is for i in o, which in JavaScript lists all property names of an object. The rest is just syntactic sugar - opening the window, defining stylesheet, onclick handler etc.

function v(o, level)
{
	w = window.open('', 'debug');

	if (level == undefined)
	{
		w.document.write('<style>div {border-style:solid;border-width:1pt;margin-left:10pt;padding:2pt;} .v{display:block} .i{display:none}</style>');
		w.document.write('<script>function d(a){a.className=a.className=="v"?"i":"v";}</script>');
		w.document.write('<div class="v">'); 
	}
	else
		w.document.write('<div class="i">'); 

	if (o == undefined)
		w.document.write('undefined <br />');
	else if (typeof (o) == 'object')
		for (i in o)
			if (o[i] != undefined && typeof (o[i]) == 'object') 
			{
				if ((i != 'parentNode') && (i != 'parentElement') && (i != 'nextSibling') && 
				    (i != 'previousSibling') && (i != 'ownerDocument') && (i != 'offsetParent') && 
				    (i != 'ownerElement') && (i != 'document') && (i != 'namespaces') && (i != 'parentTextEdit'))
				{
					w.document.write('<p onclick="d(this.nextSibling);"><b>['+ i +'] = ' + o[i] +'</b></p>');
					v(o[i], 1);
				}
			}
			else if (typeof (o[i]) != 'function')
				w.document.write('<p>['+ i +'] = ' + o[i] +'</p>');

	w.document.write('</div>');
}

To try it out, click on

this link

. A new window should appear listing all the links properties looking something like this.

Tested in Internet Explorer, Firefox and Opera

Monday, June 23, 2008

Tetris Progress Report 1

So, how's the Tetris going. So far I've spent about four hours on the project and I have window creation, simple GDI drawing, handling of input and timing. I'm quite positively surprised how easy it was so far. For my first Win32 GUI project, it's coming along quite nicely. I basically have all the building blocks in place, I just need to implement the Tetris logic.

Currently I'm at 11776 bytes (stripped executable), which leaves me confident, that I will be able to squeeze in the 17kB I set for a goal :). I've found out, that I can't use any standard libraries, because they introduce too much overhead. I was thinking about using std::vector for some stuff, but I will have to go with simple arrays.

What I'm currently thinking the most about is the data structure I will be using for the Tetris pieces. The obvious 4x4 array is not really suitable for rotations of all pieces, unless I define the centre of gravity for each piece separately. It's a possible solution, but really elegant.

To download this really preliminary version, click here here (10 kB). It's basically just a block falling down, which you can move left and right.

Thursday, June 19, 2008

JavaScript Stacktrace

Just the other day, I was debugging an error in application which works only in Internet Explorer. The application is pretty complicated, so I really missed my favourite Firebug.

I was looking for some way to investigate the stack trace and I came upon the reserved word arguments in the JavaScript language.

Basically it allows you to access the arguments of the function as an array. It has couple of special properties, which come in very handy.

  • arguments.callee - references the function itself (as function object).
  • arguments.callee.caller - references the function that called me
  • arguments.callee.name - Mozilla only extension, which returns the name of the function

As you can see, in IE we can't access the name of the function object as a property. However we can access the whole function body as a text string. So we just use a regular expression to cut out, the first word that follows the function. It's an ugly hack, so that it works in IE, but it works reasonably good.

function stacktrace()
{
 re = /function\W+([\w-]+)/i;

 var f = arguments.callee;
 var s = "";
 while (f)
 {
  s += (re.exec(f))[1] + '('; 

  for (i = 0; i < f.arguments.length - 1; i++)
  {
   s += "'" + f.arguments[i] + "', ";
  }

  if (arguments.length > 0)
  {
   s += "'" + f.arguments[i] + "'";
  }

  s += ")\n\n";

  f = f.arguments.callee.caller;
 }
 alert(s);
}

It would be much more elegant, if split into two functions, where one would be providing the name of the function from the string, but for copy pasting purposes, it's much easier to have one function in total.

To try it out, just click here - some_function('first', 'second', true);

You should get result, that looks like this:

Wednesday, June 18, 2008

Tetris Raytracer Compiler

It is being said, that every man in course of his life should build a house, plant a tree and father a son. These three crucial tasks can be find in the life of a programmer as well - write a tetris game, write a raytracer and write a compiler.

Since I didn't actually wrote any of these things, I think it's the highest time to do so. Once I wrote Nibbles in assembler and lightmapper in C, but these don't really count, so let's start with the real deal then.

I will start with the easiest one - Tetris. I assume I can finish it in less than two weeks time (bear in mind I do work for a living and I will not work on it during weekends). I will work about an hour / two hours a day. I will semi-regularly write updates about my progress and if I actually manage to finish on time, I will buy myself something fancy and expensive :)

The rules for Tetris

  1. Deadline 30th June 2008
  2. Pure Win32 GDI drawing (I already know SDL, Allegro, Cairo etc, so it wouldn't be a learning experience)
  3. Pretty code (preferably C++, so that I can create a multiplayer version later easily)
  4. No external libraries whatsoever, no external graphics, all resources included - one exe file
  5. max 17kB (I just made this number up, there was no thinking/assessing process involved :) )

So enough chatting, let's start coding :)

Tuesday, June 17, 2008

Vacuum your Firefox 3

Today the new iteration of Firefox will come out and I want to share a tip with you, how to speed up your Firefox 3.

I was using nightly builds of Firefox 3 for about half a year and it was quite fun to observe the development - especially the different design decisions in the look and functionality of the Awesomebar, but in such a long time you visit a lot of sites and collect a lot of cookies. Since this information has to be in memory all the time for places to be fast and responsive, I will show you, how to optimize your Firefox database.

In previous versions Firefox stored this information in the worst possible format - Mork. Format extremely complicated, barely machine readable that gave the users no possibility to parse the data (for a lot of laugh check out the specification on the Wikipedia page). This was finally replaced in the new Firefox by SQLite - self contained, small footprint database.

Having database store your browsing data has one drawback, you have to optimize the database from time to time to get rid of old, deleted data, re-index the columns etc. Otherwise you keep all the junk data mixed in with your real data.

In SQLite is the statement to do this called VACUUM;. So here's how to vacuum your Firefox:

  1. Download sqlite command line client for your platform.
  2. Turn off your Firefox
  3. Go to your profile folder
  4. Issue the command:
    • For Linux
      $ for i in *.sqlite; do echo "VACUUM;" | sqlite3 $i ; done
      
    • For Windows
      for %i in (*.sqlite) do @echo VACUUM; | sqlite3 %i
      

In my case this effectively cut the size of urlclassifier3.sqlite and places.sqlite to half. Thus saving 20 MB in my memory and Firefox's speed improvement was very noticeable. So have fun with the vacuum cleaner :).

Monday, June 16, 2008

Simple WMI client

Let's say you need to acquire couple of statistics from remote Windows server. You're not using a fancy utility like HP OVO or something like that, you just need an ad hoc solution, which can't have any component running on the server.

In my case I needed to check on free space, number of processes and available memory on couple of servers. The easiest way to do it, is to use the WMI - Windows Management Instrumentation. It provides SQL-like access to Windows system information. It allows you to inquire on all sorts of various information, for full list of available classes check this MSDN article.

I decided to write a simple command line client in C#, because it would most probably take quite a lot of effort in C and I should broaden the range of languages I use on a daily basis anyway.

using System;
using System.Management;
using System.Globalization;
using System.Net;
using Microsoft.Win32;

class DisplayInfo
{
 public static int Main(string[] args)
 {
  ManagementScope scope;
  ConnectionOptions options = new ConnectionOptions();
  if ((args.Length == 0) || (args[0] == "--help") || (args[0] == "-h") || (args[0] == "/?"))
  {
   Console.WriteLine("wmi - select information from WMI\n\n" + 
       "Usage: wmi WMI_CLASS [servername username password]\n\n" +
       "Most usefull classes are\n" + 
       "\tWin32_OperatingSystem\n" +
       "\tWin32_Share\n" +
       "\tWin32_DiskDrive\n" +
       "\tWin32_LogicalDisk\n" +
       "\tWin32_Process\n");
   return 0;
  }
  else if (args.Length == 1)
  {
   scope = new ManagementScope();
  }
  else
  {
   string server = args[1];

   options.Username = args[2];
   options.Password = args[3];
   options.Authority = "NTLMDOMAIN:"+server;

   scope = new ManagementScope("\\\\"+server+"\\root\\cimv2", options);
  }

  scope.Connect();

  SelectQuery query = new SelectQuery("SELECT * FROM "+args[0]);

  ManagementObjectSearcher s = new ManagementObjectSearcher(scope, query);
  foreach (ManagementObject o in s.Get())
  {
   PropertyDataCollection properties = o.Properties;
   foreach (PropertyData property in properties)
   {
    Console.WriteLine("{0}: {1}", property.Name, o[property.Name]);
   }
   Console.WriteLine();
  }
  Console.WriteLine();
  return 0;
 }
}

It doesn't do any error checking whatsoever, because it assumes you know what you're doing.

Also note the actual query line


SelectQuery query = new SelectQuery("SELECT * FROM "+args[0]);

which allows you to do a nice SQL injection like this


wmi "Win32_LogicalDisk WHERE Name = 'C:'" 

It requires minimum .NET 1.1 and can be easily compiled on any computer with .NET (you don't need any SDK or anything). For convenience binary version can be downloaded - wmi.zip (3kB)

Usage: wmi WMI_CLASS [servername user password]

So if you want for example to inquiry on all the drives and their free space on a remote server, you need to do


wmi Win32_LogicalDisk remote_server remote_user remote_password | grep -i \\\(^FreeSpace\\\)\\\|\\\(^Caption\\\) 

Caption: C:
FreeSpace: 3357395456
Caption: D:
FreeSpace:
Caption: F:
FreeSpace: 3357395456
Caption: H:
FreeSpace: 88749633536
Caption: O:
FreeSpace: 33317158912
Caption: P:
FreeSpace: 33317158912
Caption: Q:
FreeSpace: 2288992256
Caption: S:
FreeSpace: 396537856
Caption: T:
FreeSpace: 2888278016

Friday, June 13, 2008

Corrupting your Outlook PST file

Couple of months ago, I accidentally deleted about 1600 emails, some of which were of quite importance. I could have lived without them, but I figured since PST files are basically databases, they will not be deleting emails for real, just flagging them as deleted

I googled around and found this nice tutorial how to get your files back.

The first obstacle I hit was a problem with long filenames. I don't know if my DEBUG.EXE is stupid, but mine wouldn't open a file over 8.3 characters. So I renamed my copy of pst file to something short and upon running again I hit "Insufficient memory" error.


F:\debug a.pst
Insufficient memory

I did a couple of tests and found out, that the size limit for DEBUG.EXE is 574816 bytes. Files larger than that will simply not fit. So if you have more than ten emails in your inbox, you will probably encounter problems as well :).

So I had two options what to do

  1. Download a hex editor and edit it manually
  2. Write a program for corrupting PST files

You already know, which option I chose. It wasn't the geekiness of it, but I figured, that I will be sending this program to my less tech savvy friends and giving them instructions will be much easier if I skip the part with hex editor :).

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[])
{
 FILE *f = fopen(argv[1], "r+b");
 int length = 6;

 unsigned char *a = (unsigned char*)malloc(sizeof(unsigned char)*length);
 memset(a, 20, length);

 fseek(f, 7, SEEK_SET);
 fwrite(a, 1, length , f);
 fclose(f);
 free(a);
 return 0;
}

Usage: In case you accidentally delete some emails, you need to

  1. Turn Outlook off
  2. Locate your PST file
  3. Run corrupt.exe YourOutlookfile.pst
  4. Start "c:\Program Files\Common Files\System\MSMAPI\1033\SCANPST.EXE" or whichever version you have.

For convenience purposes binary version follows corrupt.zip (7kB).

Thanks to Mark James for creating the amazing Silk icons.

Btw. my favourite hex editor is xvi32. It's really good, check it out.

Thursday, June 12, 2008

Changing display frequency

I recently bought an LCD monitor to connect to my notebook at work. It's a widescreen Benq with resolution 1440x900 and from the day I installed it my work turned from boring chore into a beautiful pleasure (more or less :) ).

However for some kind of strange reason every time I reconnect the notebook to the docking station, the monitor sets the refresh frequency 60Hz.

Some people say, they can't see the difference, but I'm really not one of them. I really can't stand looking at 60Hz.

Being the lazy person I am, I decided to write a program, so that I don't have to do eight clicks every time I come to work.

After about a twelve seconds of googling, I've found the function I need is ChangeDisplaySettins

Braindead easy program for changing the frequency follows:

#include <windows.h>

int main(void)
{
 DEVMODE d;
 memset(&d, 0, sizeof d);
 
 d.dmSize = sizeof d;
 d.dmDisplayFrequency = 75;
 d.dmFields = DM_DISPLAYFREQUENCY;

 ChangeDisplaySettings(&d, CDS_UPDATEREGISTRY);

 return 0;
}

For convenience purposes binary version follows frequency.zip (5kB).

Thanks to Mark James for creating the amazing Silk icons.

Sunday, June 1, 2008

Getting Stupid

"I'm getting stupid", couple of weeks ago I realized. My inability to correctly count the sum of a couple of figures struck me, because it wasn't the first time in past days. Thinking about it, I reminded myself of countless occasions, when I couldn't count properly.

"How did this happen?", I asked myself. When I finished my masters degree about year and a half ago I was on top of my game. I even received the best master thesis of the class award. I was the typical abstract mathematician (I'm not mathematician per se, but you know what I mean) preferring x and y over numbers, but still. I could sense something was wrong.

Tracking down the cause was not hard - it was my job. After finishing my degree I joined a large multinational company and everything went downhill from there. The mind-numbing (literally :) ) job showed his effect a mere year later.

Since I can't leave the company for another half a year, I decided to start this site. With every post I will try to become smarter, stress my mind and solve some kind of problem I'm facing. And maybe somewhere along the way, the wheels in my brain start humming again. Maybe.

The Dumb Guy.