Friday, September 18, 2009

Why did we do it? Subroto Bagchi explained it best in his book, The High Performance Entrepreneur: Golden Rules for Success in Today's World :

"… starting a company is like deciding to have a baby. Ask most women and they will tell you that there can never be a rational enough reason to get into the problems of bearing a baby. It is a very difficult task, full of discomforts and sacrifices. Yet, when the time comes, a woman would give up everything in the world to bear her child. No pain, no discomfort, no change in lifestyle daunts her from becoming a mother.

Starting your own enterprise is a little like motherhood. You know it when the time has come and you waive all caution and comfort to embrace the little sign of life deep inside you and you would do everything – everything – to bring it to the world."

On the 31st of August, 2009, I, along with a few good friends, brought TetraStorm Technologies Private Limited to life. There's an inexplicable sense of accomplishment that I get every time I see my name in the list of directors in the Memorandum and Articles of Association. Yes, I know this is just the beginning and there's a lot of hard work ahead of us.

But you know what? We're a bunch of explorers with backpacks. We've got a map that we think will lead us to a pot of gold. We've got a heart full of passion and an ounce of skills. We've got vision and we're stubbornly determined. We have our eyes set on the horizon and our feet firmly on the ground. How can we be so sure of success? We're too young and too foolish to even imagine that failure is a possibility. And did I mention we have a map?

Friday, September 18, 2009 10:31:58 PM (India Standard Time, UTC+05:30)  #    Comments [3]  | 
Friday, July 10, 2009
Today is my last day with TCS. It's been a great journey over the past 6 years. I've had the good fortune to have worked with a lot of very smart people who have helped me grow in leaps and bounds. I could not have asked for more from my time at TCS. However, there is this dream of starting my own company that I have been nurturing for many years now. The time has finally come to set those plans in motion.

Over the past few weeks, I've been laying down the groundwork for a startup along with a few friends. I know I haven't exactly been regular in blogging (I think my last post was well over a year ago), but that's something I plan to change for the better. I intend on blogging my startup experiences and thoughts here, along with a good dose of technology posts as well.

I can't believe how quickly six years seem to have passed by. I hope that in another six years I'll be able to look back and have great memories about my new company as well. Here's looking forward to a great future!

Friday, July 10, 2009 7:50:36 AM (India Standard Time, UTC+05:30)  #    Comments [0]  | 
Thursday, May 15, 2008

Guess what's wrong with this code:

char szHostName[128];

struct hostent* pHost;

 

assert(gethostname(szHostName, 128) == 0);

pHost = gethostbyname(szHostName);

 

In a release build, gethostname won't get called. Note to self: watch what you assert!

Thursday, May 15, 2008 11:09:16 PM (India Standard Time, UTC+05:30)  #    Comments [0]  | 
Wednesday, May 14, 2008

Recently I came across a requirement to create an ATL ActiveX control that could be used from JavaScript in the following manner:

o = new ActiveXObject("Test.MyControl");
o.OnStateChanged = MyEventHandler;

I figured this would be pretty simple -- just implement an ActiveX control with connection points. Unfortunately, it doesn't work. Internet Explorer complains thus:

ie7_object_error 

This is because JavaScript can't sink COM events. This seemed odd to me, because the same approach works when you try to use the XMLHttpRequest object. As it turns out, XMLHttpRequest doesn't implement "events" as COM events at all. They're actually properties that accept IDispatch pointers. JavaScript functions are marshalled to ActiveX as objects that implement IDispatch and having a method named "call".

Simply put, this is what we need to do to enable ActiveX events to be handled by JavaScript using the syntax shown above:

1) Implement a property in the ActiveX control that accepts an IDispatch pointer.

STDMETHODIMP CTestCtrl::putref_OnStateChanged(IDispatch* newVal)

STDMETHODIMP CTestCtrl::get_OnStateChanged(IDispatch** pVal)

2) Get the DISPID of the "call" method by calling GetIDsOfNames like so:

newVal->GetIDsOfNames(IID_NULL, &szMember, 1, LOCALE_SYSTEM_DEFAULT, pDispId))

3) When you want to invoke the event, construct a VARIANTARG containing the parameters you want to pass to the event in reverse order. Add a pointer to your own IDispatch implementation as the last element in the array.

DISPPARAMS dispParams;
VARIANTARG args[2];

VariantInit(&args[0]);
args[0].vt = VT_BSTR;
args[0].bstrVal = ::SysAllocString(L"The event says hello!");

IDispatch* pDisp;
HRESULT hRes = this->QueryInterface(IID_IDispatch, (void**)&pDisp);

VariantInit(&args[1]);
args[1].vt = VT_DISPATCH;
args[1].pdispVal= pDisp;

memset(&dispParams, 0, sizeof(dispParams));
dispParams.rgvarg = args;
dispParams.cArgs = sizeof(args)/sizeof(args[0]);

EXCEPINFO excepinfo; 
UINT uArgErr;

pEventHandler->Invoke(*pDispId, IID_NULL, LOCALE_SYSTEM_DEFAULT,
    DISPATCH_METHOD, &dispParams, NULL, &excepinfo, &uArgErr);

4) Clean up when you're done by calling VariantClear on both elements of the args array.

Wednesday, May 14, 2008 9:23:31 PM (India Standard Time, UTC+05:30)  #    Comments [5]  | 
Wednesday, April 02, 2008

Looks like a lot has been happening since the last time I blogged!

Silverlight 2 beta 1 is out

http://silverlight.net/GetStarted/

IE8 is on it's way

http://www.microsoft.com/windows/products/winfamily/ie/ie8/readiness/Install.htm

Singularity source code is now available

http://www.codeplex.com/singularity

Wednesday, April 02, 2008 10:49:37 PM (India Standard Time, UTC+05:30)  #    Comments [0]  | 
Thursday, January 03, 2008

HPIM0992This is where I spend most of my time when I'm at home. OK, that's not entirely true. This is where I spend ALL of my time when I'm at home.

What you're looking at here is "Wolverine". Here are the specs:

Processor: Core 2 Duo E6420 (2.13 GHz, 4MB L2 Cache)

Motherboard: Intel DG965WH Media Series Desktop Board

RAM: 1GB 667 MHz DDR2 Kingston ValueRAM

Storage: 640 GB (Internal: 2 x 160 GB 7200 RPM (1 Seagate, 1 Hitachi), External: 320 GB 5400 RPM Seagate)

Graphics: BFG GeForce 7300 GT OC (256 MB)

Display: LG 20.1" Widescreen LCD (1680 x 1050), Samsung 17" CRT (1024 x 768)

Networking: Linksys Compact Wireless Router (WRT56GC)

OS: Windows Server 2003 Small Business Server

The only thing missing in this shot is "Trinity", my laptop, which usually sits to the right of the CRT. I use Synergy to share my mouse and keyboard across the machines. I use the LCD for the main task I'm focusing on -- generally an IDE, browser or PDF I'm reading. Usually only the IDE or PDFs are allowed to take over the whole screen (as in the picture above). I use the CRT for secondary tasks, like live TV, FeedDemon or Outlook.

And, yes, the lights aren't turned out just for the picture. I prefer dim lighting. It helps me concentrate better. Well, actually it helps me avoid the general mess in the rest of the room. Whatever. :)

Thursday, January 03, 2008 3:30:34 PM (India Standard Time, UTC+05:30)  #    Comments [0]  | 
Wednesday, January 02, 2008

Dreaming up a feature is easy. Just think about the most annoying experience you've had with a product and come up with a simple alternative. Designing a feature is a whole different ball game. When you design a feature, you need to worry about a whole bunch of things like:

  • How is the new feature going to affect existing applications/interfaces/UI?
  • How might this feature evolve in the future?
  • What about the various "-abilities" (manageability, accessibility, programmability, and so on)?
  • How will we support this feature as time goes on?

That's just four questions, and it's only the tip of the iceberg. Let's take a look at some real world examples:

Per-application volume

One of the cool features that debuted in Vista is per application volume control. If you have multiple applications playing sounds, Vista's volume control now lets you set the volume level for each application independently. Sounds simple.

Pop quiz, genius -- what's an application? Most developers would instantly blurt out "Well, that's easy -- applications are processes!". Except that users don't see processes. User's see windows in the taskbar. A single application can have multiple windows sitting in the taskbar. Should each of those windows get their own volume control? What about sounds that come from web pages within browser tabs? If you're running Firefox, all your tabs are in the same process. Should each tab get a volume control? Maybe I want to listen to YouTube at full blast, and silence out some annoying midi sounds playing on some other tab.

Head over to hanselminutes, and listen to Scott Hanselman and Larry Osterman talk about this feature (and a whole bunch of other stuff about Microsoft and Windows). Larry's the guy who spent 4 years re-writing the audio system for Vista. Or, as he likes to put it, "I'm the guy who makes Windows go 'ding'!"

Windows Vista User Interface Privilege Isolation (UIPI)

First, a little background for those who aren't familiar with the new User Account Control features of Windows Vista. UAC is a new set of rules that allows the system to run processes with different privileges even when they're being run under the same user account. Until Windows XP and Windows Server 2003, if your user account had admin privileges, so did every application that you run while you're logged in with that account. Yes, even Notepad could format your hard disk if it wanted to. Starting with Vista, however, even applications that are started by a user logged in with an account that has admin privileges aren't capable of doing certain things. Let's not get into the details of what those things are, or how the whole system works for now; all of that is orthogonal to our current topic.

Effectively, processes in Vista are assigned privilege levels. Processes with higher privilege levels can do more things than those with lower privilege levels.

Now, all this privilege assignment is meaningless if a process with lower privileges can simply send window messages to a process with higher privilege and get it to do things. Imagine Notepad sending a window message to Explorer asking it to delete everything on your hard disk. Needless to say, this is undesirable.

The answer, of course, is to introduce a new rule in the message pipeline that says, "Hey, you've got lower privileges than Explorer. You can't send any messages to any of Explorer's windows."

Sounds perfect. Except now, you can't drag and drop from Explorer to the Command Prompt anymore. I've gotten so used to relying on this feature in command prompts that I can't imagine not living without it. Yes, I want the protective coolness of UAC and UIPI, but darn it does it really have to break CMD!? (BTW, you can workaround this by doing a Shift+Right click on the files/folders and choosing "Copy as Path". Yes, it's not drag n' drop but it's the only solution.)

Apparently, it does have to be broken. As Raymond Chen says in this post, the problem is that all console windows are owned by the Client Server Runtime System (CSRSS). CSRSS runs as a system service. Explorer runs with lower privileges. Bye bye, Explorer window messages. Bye bye, drag and drop. Check out the post and the comments that follow. Raymond's posts are always gems.

 

So, do you really want to be the guy that designs a feature today? Think about it.

Wednesday, January 02, 2008 10:43:33 PM (India Standard Time, UTC+05:30)  #    Comments [0]  | 
Saturday, December 15, 2007

H.L. Mencken once said:

There is always a well-known solution to every human problem--neat, plausible, and wrong.

It's generally agreed in the programming world that simple, easy to understand code is preferred over highly convoluted code even if it is at the expense of some efficiency.

A few days ago, Jeff Attwood wrote about what seemed to be a trivial programming exercise -- shuffling a deck of cards. Jeff's first idea went something like this:

for (int i = 0; i < cards.Length; i++)
{
    int n = rand.Next(cards.Length);
    Swap(ref cards[i], ref cards[n]);
}

It is only a couple of lines of code. How hard can it be to get it right? If only it were that simple!

Jeff explains in a later post how seriously flawed that shuffle algorithm is. The seemingly simple shuffle algorithm has a distinct bias. This becomes apparent only when it's tested over a very large number of runs.

The right way to shuffle is the Knuth-Fisher-Yates algorithm:

for (int i = cards.Length - 1; i > 0; i--)
{
    int n = rand.Next(i + 1);
    Swap(ref cards[i], ref cards[n]);
}

The difference in the code is subtle, to say the least. But as Jeff explains quite beautifully, it makes a world of difference in the net result.

This simple example explains excellently the need for two things:

  1. A well thought out testing strategy, and
  2. A deep understanding of the domain you're working in.

Who would've thought shuffling a deck of cards would be so hard to get right?

Saturday, December 15, 2007 7:10:15 PM (India Standard Time, UTC+05:30)  #    Comments [0]  |