MagiWOL 3.00

Illustration

MagiWOL has moved to version 3.00.

Compared to version 2.21, changes are:

  • No registry writes will be performed if application is not installed.
  • Double-click now wakes computer instead of editing entry.
  • Broadcast address now can be host name (useful for waking over Internet).
  • Works with Citrix virtualization.
  • Brand new icon.
  • A lot of bug fixing.

Special thanks to all those among you who supported me with bug fixing and installed many wrong versions to make one right. :)

Download is available now.

IB-NAS902StUS2-B Kinda Works

Illustration

I bought Icybox IB-NAS902 to serve as cheap backup solution. It seemed like a perfect device for job. It supports SATA 3.5" HDD and it has both USB and Ethernet connectivity. And it is dirt-cheap.

For my particular scenario 100 Mbps network was good enough and, since samba was supported, Windows should connect like a charm. That was partially true since Windows XP did connect but Windows 7 refused to cooperate. Short investigation has shown that device uses ancient version of samba protocol and solution was to lower Windows 7 security a bit. Not an ideal solution, but good enough.

I was little worried about using FAT32 as file system since there is no support for files larger than 4 GB but that proved not to be a problem. When drive got accessed over network it would just split and combine large files seamlessly. When I connected over USB, I would see them as separate files. That seemed like bearable solution since all big files I had were DVD backups and, in worst case scenario, I could just grab originals and recreate them.

Configuration itself was ugly but simple and it would almost always work. It had tendency to turn on DHCP server after every restart but since it was slow to respond, my DHCP server ended up winning all the time. This was not something I liked but, again, I was willing to accept it.

Daily synchronization discovered another fault. As long as there was single computer accessing it everything was going fine. When two computers did synchronization at same time (or there was heavy traffic) everything would break apart. First it would slow down and then it would reboot. To make things even worse, data consistency would go to hell. After doing daily sync (diff-only) for a month I did chkdsk. Over an hour I looked at errors that touched almost every file on disk. This is not something that you can tolerate in your backups.

At the end, I gave up. I just connected this drive to my existing file server as another USB drive. For now it seems that direct SATA-to-USB bridge works just fine.

I cannot recommend this enclosure to anyone. It is probably cheapest 100 Mbps NAS you can find but it is useless in that mode. It does work as USB enclosure but it is both bigger and pricier than anything else out there.

It is a great idea ruined by the lousy firmware.

How to Initialize Disk

Illustration

When new EMPTY disk is added to Windows first thing that needs to be done is initialization. Only after this step Windows will recognize disk as their own and allow you to create partitions.

Part of (bigger) script was automatic disk initialization. Surfing Internet yielded just few results for this particular problem. Most of them were using DISKPART and this was not acceptable. I needed something in Win32 API.

Theory is simple enough. Single function that does it all is DeviceIoControl. Unfortunately this function is ridiculously overloaded. Little bit of investigation will bring us to IOCTL_DISK_CREATE_DISK control code which does disk initialization. Even better - almost all parameters can be ignored or set to default.

Only parameter that we must understand is CREATE_DISK structure so it is only appropriate to have it use unions. As you might know, there is no meaningful support for unions in C#. There is a way around it with FieldOffset(0) but it does not look nice.

Rest of code is fairly straightforward. To call it just use DiskIO.InitializeDisk("\\.\PHYSICALDRIVE4") (substitute number for whichever drive you wish to initialize).

Full code follows:

internal static class DiskIO {

    public static void InitializeDisk(string path) {
        var signature = new byte[4];
        RandomNumberGenerator.Create().GetBytes(signature); //lazy way to generate "unique" signature

        using (SafeFileHandle handle = NativeMethods.CreateFile(path, NativeMethods.GENERIC_READ | NativeMethods.GENERIC_WRITE, 0, IntPtr.Zero, NativeMethods.OPEN_EXISTING, 0, IntPtr.Zero)) {
            if (handle.IsInvalid) { throw new Win32Exception(); }

            var cd = new NativeMethods.CREATE_DISK();
            cd.PartitionStyle = NativeMethods.PARTITION_STYLE.PARTITION_STYLE_MBR;
            cd.MbrGpt.Mbr.Signature = BitConverter.ToInt32(signature, 0);
            Int32 bytesOut = 0;
            if (NativeMethods.DeviceIoControl(handle, NativeMethods.IOCTL_DISK_CREATE_DISK, ref cd, Marshal.SizeOf(cd), IntPtr.Zero, 0, ref bytesOut, IntPtr.Zero) == false) { throw new Win32Exception(); }
        }
    }


    private static class NativeMethods {

        public const int GENERIC_READ = -2147483648;
        public const int GENERIC_WRITE = 1073741824;
        public const int OPEN_EXISTING = 3;

        public const int IOCTL_DISK_CREATE_DISK = 0x7C058;


        public enum PARTITION_STYLE {
            PARTITION_STYLE_MBR = 0,
            PARTITION_STYLE_GPT = 1,
            PARTITION_STYLE_RAW = 2,
        }


        [StructLayoutAttribute(LayoutKind.Sequential)]
        public struct CREATE_DISK {
            public PARTITION_STYLE PartitionStyle;
            public CREATE_DISK_UNION_MBR_GPT MbrGpt;
        }

        [StructLayoutAttribute(LayoutKind.Explicit)]
        public struct CREATE_DISK_UNION_MBR_GPT {
            [FieldOffset(0)]
            public CREATE_DISK_MBR Mbr;
            [FieldOffset(0)]
            public CREATE_DISK_GPT Gpt;
        }


        [StructLayoutAttribute(LayoutKind.Sequential)]
        public struct CREATE_DISK_MBR {
            public Int32 Signature;
        }

        [StructLayoutAttribute(LayoutKind.Sequential)]
        public struct CREATE_DISK_GPT {
            public Guid DiskId;
            public Int32 MaxPartitionCount;
        }


        [DllImportAttribute("kernel32.dll", EntryPoint = "CreateFileW", SetLastError = true)]
        public static extern SafeFileHandle CreateFile([MarshalAsAttribute(UnmanagedType.LPWStr)] string lpFileName, Int32 dwDesiredAccess, Int32 dwShareMode, IntPtr lpSecurityAttributes, Int32 dwCreationDisposition, Int32 dwFlagsAndAttributes, IntPtr hTemplateFile);

        [DllImportAttribute("kernel32.dll", EntryPoint = "DeviceIoControl", SetLastError = true)]
        [return: MarshalAsAttribute(UnmanagedType.Bool)]
        public static extern Boolean DeviceIoControl(SafeFileHandle hDevice, Int32 dwIoControlCode, ref CREATE_DISK lpInBuffer, int nInBufferSize, IntPtr lpOutBuffer, Int32 nOutBufferSize, ref Int32 lpBytesReturned, IntPtr lpOverlapped);

    }

}

Wording

Illustration

I was in airplane few days ago and we were late (of course). After some twenty minutes of waiting captain told us what happened:

Sorry for wait but airplane in front of us managed to hit some birds during takeoff. We are still waiting for someone to pick up remains.

At that moment you could see difference between frequent travelers and some lady that was there for the first time. Most of travelers made no notice of this announcement, some of them were smiling and few were even laughing (unsurprisingly I was in last group).

Lady was scared. What she probably heard was that we are waiting for someone to pick up remains of airplane in front of us. In any case airplane got rolling and some gentlemen siting next to her took some time explaining exact situation so rest of flight went fine.

This only shows that understanding message highly depends on personal context and that care should be exercised in choosing exact wording. Whether it is airplane announcement or critical error text that users might see.

Cloud Reader

Amazon Cloud Reader is finally available. It does not bring anything new regarding functionality but it does enable to read your books on any platform that supports HTML 5. For me this platform is Chrome.

Biggest loser in this story will be Kindle for PC since there is no more reason why would anybody install it.