Thursday, July 22, 2010

Time sensitive material

I received this prospectus, dated 12/2009, yesterday.

Tuesday, July 20, 2010

World's most inefficient way to check for primeness (via Reddit)

http://www.noulakaz.net/weblog/2007/03/18/a-regular-expression-to-check-for-prime-numbers/

Fire your perl interpreter, feed this function 982451653, and watch your computer die a slow and painful death...

The only democracy in the Middle East (TM) (via Reddit)

A Palestinian man has been convicted of rape after having consensual sex with an Israeli woman who believed he was Jewish because he introduced himself as "Daniel".

http://www.telegraph.co.uk/news/worldnews/middleeast/israel/7901025/Palestinian-jailed-for-rape-after-claiming-to-be-Jewish.html

Sunday, July 18, 2010

Inception

Watched the highly acclaimed "Inception" on Friday. Below is my take.

Short version: "Titanic" is better.

And I don't say this because I like "Titanic".

My two favorite stories about "Titanic" are as follows. When the movie was first released on VHS, the MicroNews - internal MS paper that back then was a print edition - published this classified ad: "Titanic on VHS. First tape watched once. Second tape never watched".

Second story: among Windows developers Intel's Itanium chip is known as "Itanic". Although this one has nothing to do with the movie...

Long version: If you consider "Matrix" brainy and captivating, "Inception" is for you!

It is extremely similar to "Matrix". Both movies take a trivial idea ("Matrix": reality is actually a computer generated dream; "Inception": reality is influenced by a human-induced shared dreams) and make a movie out of it by adding large number of superficialities.

In "Matrix" it's tough looking impeccably clothed men beating main heroes up in highly choreographed fight scenes. I guess it must be the Hollywood's idea of what's going on inside a computer. I suppose if I had majored in communications, I would have thought about computers like that, too.

In "Inception" it is impeccably "architected" dreamscapes where the heroes get to confront - and conquer! - their demons. I guess it must be the Hollywood's idea of what's going on inside a human brain. I suppose if I had majored in said communications, I would have thought about the mechanics of human brain like that as well.

Why do I think "Titanic" is better? There, if one abstracts from the plot, one still gets to enjoy the vistas. In "Inception", unfortunately, there is no way to abstract from the plot...

How to make a service in .NET

Here's a complete, self-contained way to build a system service using .NET. I was looking for a way to do it on the internets, but most of the examples rely on .NET template (which relies on designer, which is ugly) and don't have a way to install the service programmatically.

Without much ado, here's the code. All of it. Just replace ServiceMainThread with your code, and you're done. It even supports installing multiple instances of itself.

//-----------------------------------------------------------------------
// <copyright>
// Copyright (C) Sergey Solyanik.
//
// This file is subject to the terms and conditions of the Microsoft Public License (MS-PL).
// See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL for more details.
// </copyright>
//----------------------------------------------------------------------- 
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.ServiceProcess;
using System.Text;
using System.Threading;

namespace CSServiceHost
{
    /// <summary>
    /// Main service class.
    /// </summary>
    public class MyService : ServiceBase
    {
        /// <summary>
        /// The thread that contains the execution path for the service.
        /// </summary>
        Thread runner;

        /// <summary>
        /// Event which gets signalled when the service stops.
        /// </summary>
        EventWaitHandle stop;

        /// <summary>
        /// Processes the start event for service.
        /// </summary>
        /// <param name="args"></param>
        protected override void OnStart(string[] args)
        {
            stop = new EventWaitHandle(false, EventResetMode.ManualReset);
            runner = new Thread(ServiceMainThread);
            runner.Start();
        }

        /// <summary>
        /// Processes the stop event for service.
        /// </summary>
        protected override void OnStop()
        {
            stop.Set();
            runner.Join();
        }

        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        /// <param name="args"> Program arguments. See help.</param>
        static void Main(string[] args)
        {
            if (args.Length > 0)
            {
                ProcessServiceCommand(args);
                return;
            }

            ServiceBase[] ServicesToRun;
            ServicesToRun = new ServiceBase[] 
            { 
                new MyService() 
            };

            ServiceBase.Run(ServicesToRun);
        }

        /// <summary>
        /// Executes service installation/uinstallation, or runs it as a process.
        /// </summary>
        /// <param name="args"> Program arguments.</param>
        private static void ProcessServiceCommand(string[] args)
        {
            string exe = Assembly.GetExecutingAssembly().Location;

            if ("/install".Equals(args[0], StringComparison.OrdinalIgnoreCase))
            {
                object[] assemblyAttributes =
                    Assembly.GetExecutingAssembly().GetCustomAttributes(false);

                string instance =
                    (from a in assemblyAttributes
                     where a is AssemblyTitleAttribute
                     select ((AssemblyTitleAttribute)a).Title).SingleOrDefault();
                string name =
                    (from a in assemblyAttributes
                     where a is AssemblyDescriptionAttribute
                     select ((AssemblyDescriptionAttribute)a).Description).SingleOrDefault();
                string account = null;
                string password = String.Empty;
                for (int i = 1; i < args.Length; ++i)
                {
                    if (args[i].StartsWith(
                        "/instance:", StringComparison.OrdinalIgnoreCase))
                    {
                        instance = args[i].Substring(10);
                    }
                    else if (args[i].StartsWith(
                        "/name:", StringComparison.OrdinalIgnoreCase))
                    {
                        name = args[i].Substring(6);
                    }
                    else if (args[i].StartsWith(
                        "/account:", StringComparison.OrdinalIgnoreCase))
                    {
                        account = args[i].Substring(9);
                    }
                    else if (args[i].StartsWith(
                        "/password:", StringComparison.OrdinalIgnoreCase))
                    {
                        password = args[i].Substring(10);
                    }
                    else
                    {
                        Console.Error.WriteLine("Could not parse: {0}", args[i]);
                    }
                }

                InstallService(exe, instance, name, account, password);
            }
            else if ("/uninstall".Equals(
                args[0], StringComparison.OrdinalIgnoreCase))
            {
                object[] assemblyAttributes =
                    Assembly.GetExecutingAssembly().GetCustomAttributes(false);
                string instance =
                    (from a in assemblyAttributes
                     where a is AssemblyTitleAttribute
                     select ((AssemblyTitleAttribute)a).Title).SingleOrDefault();

                for (int i = 1; i < args.Length; ++i)
                {
                    if (args[i].StartsWith(
                        "/instance:", StringComparison.OrdinalIgnoreCase))
                    {
                        instance = args[i].Substring(10);
                    }
                    else
                    {
                        Console.Error.WriteLine("Could not parse: {0}", args[i]);
                    }
                }

                UninstallService(instance);
            }
            else if ("/run".Equals(args[0], StringComparison.OrdinalIgnoreCase))
            {
                MyService service = new MyService();
                service.OnStart(new string[0]);
                Console.WriteLine("Service is running as a process.");
                Console.WriteLine("Press <ENTER> to stop and exit.");
                Console.ReadLine();
                service.OnStop();
            }
            else
            {
                Console.WriteLine("To install service:");
                Console.WriteLine("    {0} /install", exe);
                Console.WriteLine("        [/instance:instance_name [/name:display_name]]");
                Console.WriteLine("        [/account:account [/password:password]]");
                Console.WriteLine("To uninstall service:");
                Console.WriteLine("    {0} /uninstall [/instance:instance_name]", exe);
                Console.WriteLine("To run as a regular process:");
                Console.WriteLine("    {0} /run", exe);
            }
        }

        /// <summary>
        /// Installs service.
        /// </summary>
        /// <param name="exe"> Path to the executable. </param>
        /// <param name="instance"> Name of the service instance. </param>
        /// <param name="name"> Display name of the service. </param>
        /// <param name="account"> Account name or NULL for LocalSystem. </param>
        /// <param name="password"> Password or empty string if any of
        /// the machine accounts. </param>
        private static void InstallService(
            string exe,
            string instance,
            string name,
            string account,
            string password)
        {
            IntPtr scm = Win32.OpenSCManager(
                null, null, Win32.SC_MANAGER_CREATE_SERVICE);
            if (scm.ToInt32() == 0)
            {
                Console.Error.WriteLine(
                    "Failed to open SCM (error {0}).", Win32.GetLastError());
                return;
            }

            try
            {
                IntPtr service = Win32.CreateService(
                    scm,
                    instance,
                    name,
                    Win32.SERVICE_ALL_ACCESS,
                    Win32.SERVICE_WIN32_OWN_PROCESS,
                    Win32.SERVICE_AUTO_START,
                    Win32.SERVICE_ERROR_NORMAL,
                    exe,
                    null,
                    0,
                    null,
                    account,
                    password);

                if (service.ToInt32() == 0)
                {
                    Console.Error.WriteLine(
                        "Failed to create service (error {0}).",
                        Win32.GetLastError());
                    return;
                }

                try
                {
                    if (Win32.StartService(service, 0, null) == 0)
                    {
                        Console.Error.WriteLine(
                            "Failed to start service (error {0}).",
                            Win32.GetLastError());
                    }
                    else
                    {
                        Console.WriteLine(
                            "Service installed successfully.");
                    }
                }
                finally
                {
                    Win32.CloseServiceHandle(service);
                }
            }
            finally
            {
                Win32.CloseServiceHandle(scm);
            }
        }

        /// <summary>
        /// Uninstalls service.
        /// </summary>
        /// <param name="instance"> Service instance. </param>
        private static void UninstallService(string instance)
        {
            IntPtr scm = Win32.OpenSCManager(
                null, null, Win32.SC_MANAGER_ALL_ACCESS);
            if(scm.ToInt32() == 0)
            {
                Console.Error.WriteLine(
                    "Failed to open SCM (error {0}).",
                    Win32.GetLastError());
                return;
            }

            try
            {
                IntPtr service = Win32.OpenService(
                    scm, instance, Win32.DELETE | Win32.SERVICE_STOP);
                if (service.ToInt32() == 0)
                {
                    Console.Error.WriteLine(
                        "Failed to open service (error {0}).",
                        Win32.GetLastError());
                    return;
                }

                try
                {
                    Win32.SERVICE_STATUS stat;
                    if (0 == Win32.ControlService(
                        service, Win32.SERVICE_CONTROL_STOP, out stat))
                    {
                        Console.Error.WriteLine(
                            "Could not stop the service (error {0}).",
                            Win32.GetLastError());
                    }

                    while (Win32.QueryServiceStatus(service, out stat) != 0
                        && stat.dwCurrentState != Win32.SERVICE_STOPPED)
                    {
                        Thread.Sleep(1000);
                    }

                    if (Win32.DeleteService(service) == 0)
                    {
                        Console.Error.WriteLine(
                            "Failed to delete service (error {0}).",
                            Win32.GetLastError());
                    }
                    else
                    {
                        Console.WriteLine(
                            "Service successfully uninstalled.");
                    }
                }
                finally
                {
                    Win32.CloseServiceHandle(service);
                }
            }
            finally
            {
                Win32.CloseServiceHandle(scm);
            }
        }

        /// <summary>
        /// The actual logic.
        /// </summary>
        private void ServiceMainThread()
        {
            for (; ; )
            {
                if (stop.WaitOne(10000))
                {
                    break;
                }

                using (StreamWriter w =
                    new StreamWriter(@"c:\temp\testservice.txt", true))
                    w.WriteLine(
                        "Tick {0} {1}",
                        DateTime.Now,
                        Environment.UserName);
            }
        }

        /// <summary>
        /// Win32 thunks.
        /// </summary>
        private static class Win32
        {
            public const UInt32 SC_MANAGER_ALL_ACCESS = 0xF003F;
            public const UInt32 SC_MANAGER_CREATE_SERVICE = 0x0002;

            public const UInt32 SERVICE_WIN32_OWN_PROCESS = 0x00000010;
            public const UInt32 SERVICE_AUTO_START = 0x00000002;
            public const UInt32 SERVICE_ERROR_NORMAL = 0x00000001;

            public const UInt32 STANDARD_RIGHTS_REQUIRED = 0xF0000;
            public const UInt32 SERVICE_QUERY_CONFIG = 0x0001;
            public const UInt32 SERVICE_CHANGE_CONFIG = 0x0002;
            public const UInt32 SERVICE_QUERY_STATUS = 0x0004;
            public const UInt32 SERVICE_ENUMERATE_DEPENDENTS = 0x0008;
            public const UInt32 SERVICE_START = 0x0010;
            public const UInt32 SERVICE_STOP = 0x0020;
            public const UInt32 SERVICE_PAUSE_CONTINUE = 0x0040;
            public const UInt32 SERVICE_INTERROGATE = 0x0080;
            public const UInt32 SERVICE_USER_DEFINED_CONTROL = 0x0100;
            public const UInt32 SERVICE_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED |
                SERVICE_QUERY_CONFIG | SERVICE_CHANGE_CONFIG |
                SERVICE_QUERY_STATUS | SERVICE_ENUMERATE_DEPENDENTS |
                SERVICE_START | SERVICE_STOP | SERVICE_PAUSE_CONTINUE |
                SERVICE_INTERROGATE | SERVICE_USER_DEFINED_CONTROL;

            public const UInt32 DELETE = 0x10000;

            public const UInt32 SERVICE_CONTROL_STOP = 0x00000001;
            public const UInt32 SERVICE_STOPPED = 0x00000001;

            [StructLayout(LayoutKind.Sequential)]
            public struct SERVICE_STATUS
            {
                public UInt32 dwServiceType;
                public UInt32 dwCurrentState;
                public UInt32 dwControlAccepted;
                public UInt32 dwWin32ExitCode;
                public UInt32 dwServiceSpecificExitCode;
                public UInt32 dwCheckPoint;
                public UInt32 dwWaitHint;
            };

            [DllImport("advapi32.dll")]
            public static extern IntPtr OpenSCManager(
                string lpMachineName,
                string lpSCDB,
                UInt32 scParameter);
            
            [DllImport("advapi32.dll")]
            public static extern IntPtr CreateService(
                IntPtr SC_HANDLE,
                string lpSvcName,
                string lpDisplayName,
                UInt32 dwDesiredAccess,
                UInt32 dwServiceType,
                UInt32 dwStartType,
                UInt32 dwErrorControl,
                string lpPathName,
                string lpLoadOrderGroup,
                int lpdwTagId,
                string lpDependencies,
                string lpServiceStartName,
                string lpPassword);

            [DllImport("advapi32.dll")]
            public static extern void CloseServiceHandle(IntPtr SCHANDLE);

            [DllImport("advapi32.dll")]
            public static extern int StartService(
                IntPtr SVHANDLE,
                UInt32 dwNumServiceArgs,
                string lpServiceArgVectors);

            [DllImport("advapi32.dll", SetLastError = true)]
            public static extern IntPtr OpenService(
                IntPtr SCHANDLE,
                string lpSvcName,
                UInt32 dwNumServiceArgs);

            [DllImport("advapi32.dll", SetLastError = true)]
            public static extern int ControlService(
                IntPtr SCHANDLE,
                UInt32 dwControl,
                [MarshalAs(UnmanagedType.Struct)]
                out SERVICE_STATUS lpServiceStatus);

            [DllImport("advapi32.dll", SetLastError = true)]
            public static extern int QueryServiceStatus(
                IntPtr SCHANDLE,
                [MarshalAs(UnmanagedType.Struct)]
                out SERVICE_STATUS lpServiceStatus);

            [DllImport("advapi32.dll")]
            public static extern int DeleteService(IntPtr SVHANDLE);

            [DllImport("kernel32.dll")]
            public static extern int GetLastError();
        }
    }
}

Thursday, July 8, 2010

Microsoft Mini

Microsoft Mini blog has a lot of angst today with new round of layoffs at Microsoft.

http://minimsft.blogspot.com/2010/07/kin-fusing-kin-clusion-to-kin-and-fy11.html

I tried to comment, but the Blogger was broken and wouldn't accept it. Since I already typed it up, I am posting it here instead...

I worked at Microsoft for 10 years, then went to Google, then back to Microsoft.

All companies have problems. Apple. Google. Microsoft. They are just different problems, and they look bigger when you are closer to them.

Yes, Microsoft is failing in consumer markets, always have, maybe always will. We don't get consumer. Vista (AKA Abby & Toby platform), Windows Mobile, Kin... Even XBox - it is successful because it was built more for a typical Microsoft employee than for a regular person, it's just MS people love the same kind of videogames that 14 years old males do :-). But if you look at kids or family games on XBox - total failure.

The problem is that we target some mythical "dumb" customer, we don't really know who that is, and we overshoot the level of dumbness by a wide margin. I worked on the first version of Windows Home Server and we had people on the team - not developers, obviously - who seriously tried to argue that our customers don't know what a file share is. I kid you not.

However, just like Microsoft doesn't get consumers, Google and Apple don't get the enterprise. I have participated in creation of a business product at Google, and the people around me did not understand basic concepts like the need for customer service, a refund process, or the like. The entire Google internal system is antithetic to schedule predictability and release stability that is required for a corporate product. People who say that Gmail and Google Docs somehow threaten Exchange and Office have obviously never used these products in a work setting for an extended period of time.

One thing that is going for Microsoft is the plentitude of cultures. We have Xbox team, and an Office team, and Windows team, and Bing, and all these organizations are as unlike each others as they can be. My advice to people, especially developers, who complain about politics, poor managers, boring products, etc - check out the career site! Plenty of teams are hiring, and there are tons of really fun places which will match your preferred style, values, or culture. Just keep moving until you find the right place for YOU. Trust me, it does exist. (By the way, I am hiring, too! If you dream in code and can implement a semaphore if I woke you up at 3am, and like a blend of "old Microsoft" and "new Google" cultures, look me up on career site!)

Finally, it is true that often leaders make companies/armies/countries great. But not always, and never alone, and certainly not in democratic societies :-). I don't think that success of Microsoft in the 90's is directly attributable to BillG and BillG alone, and the steam somehow magically went out of the company the day he left the building. Yes, we have plenty of people at the high places that probably should not have been there. So does Google, so does Apple, so does Oracle, Intel, ..., ..., ... These aren't the people who (most of) you work with, they aren't the people who you meet every day, and I'll let you in on a secret - they aren't the people who make YOUR product a success or a failure. YOU do. They can't affect the stock price much - YOU can, by shipping great products, and by making environment around YOU better, so it attracts more people like YOU.

So don't get consumed by paranoia and politics, focus on your job and your team, and everything else will follow.

And if not, as long as you do the above, you will still be very employable. At Google, at Amazon, or in my team :-).

Sunday, July 4, 2010

Republican party, circa 1956

Republican Party Platform of 1956

http://www.presidency.ucsb.edu/ws/print.php?pid=25838

This is what DemocraticUnderground.com had to say about it:

"By these standards, modern Democrats have become Republicans, and modern Republicans have become batshit crazy. I think I’ve heard Kucinich mention Taft-Hartley, but you get a blank stare if you mention it to anybody under the age of 40. And to think that it used to be a topic of polite conversation among the political classes only 54 years ago."

This: http://journals.democraticunderground.com/eridani/449 has TL;DR.

Incidentally, I am hearing that the health care reform passed by Obama is very, very similar to the Republican counter-offer to the Clinton health plan.