Being A Victim Of Success

In the beginning, we are all faced with new challenges with very few real world experiences to rely upon. The challenges can be as varied as learning to take you first baby steps, entering college, or your first real job. In all these challenges we will fall down, wail, hurt our pride, but eventually we “get it” and start being successful. Frequently our successes are actually quite remarkable and we are well rewarded with a new binky or a new car. New challenges will appear and we all will naturally try to apply what we learned from our previous successes. It worked before, it should work again…

In many situations simply putting one step in front of the other doesn’t work and you fall off your bike and are once again forced to learn a new balanced solution and a new success. However, there are a few instances where the lessons from your first success are applicable to the second, further reinforcing that you really “get it.” Repeat this a couple more times and you are really “in the groove,” you have become the master. Unfortunately you may be in an environment that is leading you astray, your success is actually shallow and you have a manager that that values that success at all cost. The approach that has allowed you to be successful on your first small project, one with few interactions with others, may give others on a larger team project a serious rash on their buttocks. Without the proper ointment this can cause you to be a serious victim of your own success and your ability to gain further rewards is suddenly hampered by your inability to translate personal success into larger team success.

There are two important factors that can help prevent you from becoming a victim, self-awareness and strong management. When you are being rewarded for your success on a team, be sure to look around and see how many of your peers are there standing with you. How many of them have been successful because of you? Are you the catalyst on the team or the sole superstar? You want to be the person whom others ask to be on their team because they think you will make them better.

The second factor is having an honest manager who values your growth as much as the project’s success. If you interview any famous actor, musician, or athlete after a performance they will be able to recount the mistakes that were made and small improvements that need to be worked on, even when they appear to be flawless. A good coach must balance their positive feedback with a healthy dose of constructive criticism to improve both the player and the team. It is most important that the coach not shelter the star who scores 50 points a game, while such a star can carry a team to many wins, when up against solid group of players working as a single team the individual star will usually lose. The coach must be willing to make the short term sacrifice of the individual that is necessary to build the collective strength of the team.

If you have had a history of being successful as an individual, but despite your best efforts your team is struggling, it may be that you don’t need to work harder, just differently. If your manager is giving you uncritical praise, challenge them to be honest with you or seek out other’s feedback. Don’t be a victim of your own success, actively seek out new and different success!

Posted in Uncategorized | Tagged | Leave a comment

Clearing the Title in a Push Notification Live Tile

The Windows Phone 7 Live Tile Push Notification Service allows an application to dynamically set the background, title, and count of a live tile when the application is pinned to the main screen. By default the Title is set through the Application Properties in Visual Studio, or by manually editing the <Title> element in Application Manifest file WMAppManifest.xml. Manual editing may be necessary as Visual Studio may prevent some Title values.

In general this is a pretty good mechanism, but there are a number of problems that may complicate a developer attempting to customize their Tile:

  • The Title is rendered in a White font, if the background image is bright it may make the Title very hard to read. For example, map road imagery and some pictures.
  • The application’s background image is a distinctive logo or contains the application name in a custom trademarked font. For example the Facebook “F” logo.
  • The information communicated in the Title is no longer relevant and there is no new status.
  • Aesthetically, the Title placement is just wrong.

All of these points, and others, may lead a developer with the desire to either have a blank Title or, as appropriate, clear the Title. Unfortunately a number of factors can make this difficult, the first is that Visual Studio will not allow you to use an empty string in the Application Properties, but as discussed above this can be worked around by manually editing the manifest.

However, there have been recent reports that the App Marketplace is enforcing section 4.1.1(b) of the Windows Phone Application Certification Requirements:

“The <Title> element in the WMAppManifest.xml file must contain the application title. The <Title> element must not be empty. The Application title entered in Step 2 of the submission process to Windows Phone Marketplace and the title displayed on the phone must be the same.”

Thus you must have a default Title on your Tile. This requirement fails to take into account strongly branded background images and the ineffectiveness of this requirement when the application sends a push notification overwriting the Title on the first use of the application.

All of this goes back to the base question, how do I clear an existing Title on my Tile? The obvious answer would be to simply push a notification with an empty Title, but that will not work because of the following documented behavior:

“If this [Title] value is not set, the already-existing Title will display in the Tile.”

My experiments have shown that the definition of “is not set” means empty or all whitespace (String.IsNullOrWhiteSpace(Title)), thus using spaces will not work. Some have solved the problem by creating a background image that has white (or light) color in the lower left corner and then send one of the smallest character strings, a single period (“.”).

But I have found a perfect solution. Fortunately .Net strings are all built around Unicode characters which gives us a lot of code points that we can use. Unicode designates a number of code points as whitespace and the .Net Char.IsWhiteSpace uses those designated code points (and others) to implement String.Trim and String.IsNullOrWhiteSpace (Note: the definition changed slightly between 3.5 and 4.0). So what is a code point that will have a blank glyph but will not be considered whitespace? The “Zero-Width Non Joiner” or U+200C, what this code point is used for is interesting but beyond this write up.

So how have I used this? In the Push Notification Service I have been experimenting with I have a method that converts a Title, Count, and Background Uri into the proper XML Push payload. In that method I simply check for an whitespace string and replace it with a ZWNJ string:

            const string EmptyTitle = “\u200c”;  // Zero-Width Non Joiner

            if (String.IsNullOrWhiteSpace(title))
                title = EmptyTitle;

Now as needed, I can clear the Title on a Live Tile through a push notification!

Posted in Windows Phone 7 | Tagged , , , , , , , , , | 1 Comment

Hello world!

Welcome to WordPress.com. This is your first post. Edit or delete it and start blogging!

Posted in Uncategorized | Leave a comment

A Constant Size Bing Maps PushPin With Silverlight

Chris Pietschmann has written an excellent article on how to resize and auto-scale pushpins using the Bing Maps Silverlight control. I found it very useful but quickly stumbled on to the fact that his simple scaling algorithm:

var scaleVal = (0.05 * (currentZoomLevel + 1)) + 0.3;

did not show much difference in size across the ZoomLevels and didn’t do what I desired.

In the default Bing Map, a PushPin always has the same size (35 pixels) regardless of the ZoomLevel, what I was looking for was a PushPin that always had the same size in meters regardless of the ZoomLevel. In other words, a PushPin that was sized to 100 meters would be really big at ZoomLevel 18, and too small to be seen at ZoomLevel 1.

Using the published scaling factors for Bing Maps (conveniently powers of 2) it was pretty straight forward to write a IValueConverter. Internally there are actually two methods, one assumes that the PushPin is at the equator, and the second allows you to specify a Latitude that will further scale the PushPin to compensate for the projection. This would be useful in an IMultiValueConverter.

This could probably also have been done with custom PushPins on a MapLayer.

I hope you enjoy this.

    -David

 

//
// Copyright 2010 David Robinson  All Rights Reserved
//
// Redistribution and use in source and binary forms, with or
// without modification, are permitted provided that any
// reedistributions of source code must retain the above
// copyright notice and this condition.
//

using System;
using System.Windows.Data;
using System.Windows.Media;

namespace DaRobins
{
    /// <summary>
    /// Convert a ZoomLevel into to ScaleTransform
    /// </summary>
    public class PushPinScaleConverter : IValueConverter
    {
        #region IValueConverter Members

        /// <summary>
        /// Convert a ZoomLevel into to Scale
        /// </summary>
        //
        // The published Bing Maps Zoom scaling factors, in meters/pixel
        //     http://msdn.microsoft.com/en-us/library/aa940990.aspx
        //
        // Bing maps resolution in meters/pixel is defined are by the equation:
        //     (78271.52 / (2^(ZoomLevel-1))) * Cos(Latitude)
        //

        static private double[] BingMapsScaleFactor = { 78271.52, 78271.52, 39135.76, 19567.88,
                                                         9783.94,  4891.97,  2445.98,  1222.99,
                                                          611.50,   305.75,   152.87,    76.44,
                                                           38.22,    19.11,     9.55,     4.78,
                                                            2.39,     1.19,     0.60,     0.30 };

        /// <summary>
        /// Convert a Bing Maps ZoomLevel into meters per pixel, assumes at the equator.
        /// </summary>
        /// <param name="zoomLevel">The current ZoomLevel</param>
        /// <returns>The scale in meters per pixel</returns>
        static public double BingMapsScaleMetersPerPixel(double zoomLevel)
        {
            if (zoomLevel < 0 || zoomLevel > (BingMapsScaleFactor.Length - 1))
                return BingMapsScaleFactor[0];

            return BingMapsScaleFactor[(int)Math.Round(zoomLevel)];
        }

        /// <summary>
        /// Convert a Bing Maps ZoomLevel into meters per pixel, scaled with latitude
        /// </summary>
        /// <param name="zoomLevel">The current ZoomLevel</param>
        /// <param name="latitude">The current Latitude</param>
        /// <returns>The scale in meters per pixel</returns>
        static public double BingMapsScaleMetersPerPixel(double zoomLevel, double latitude)
        {
            if (zoomLevel < 0 || zoomLevel > BingMapsScaleFactor.Length)
                return BingMapsScaleFactor[0];

            return BingMapsScaleFactor[(int)Math.Round(zoomLevel)] * Math.Cos(Math.PI * latitude / 180);
        }

        /// <summary>
        /// Convert a ZoomLevel into to ScaleTransform
        /// </summary>
        /// <param name="value">The current ZoomLevel</param>
        /// <param name="targetType">The type of the target (unused)</param>
        /// <param name="parameter">The parameter (unused)</param>
        /// <param name="culture">The current culture (unused)</param>
        /// <returns>A ScaleTransform</returns>
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            double currentZoomLevel = (double)value;

            //
            // A PushPin is normally 35x35 pixels, at zoom level 15 we wouldlike that to be 1:1
            //

            var ScaleVal = BingMapsScaleFactor[15] / BingMapsScaleMetersPerPixel(currentZoomLevel);

            var transform = new ScaleTransform();
            transform.ScaleX = ScaleVal;
            transform.ScaleY = ScaleVal;

            //
            // Set the transform center X and Y so the Pushpin stays at the correct location.
            // The Default Pushpin's height is 35 and width is 34
            // Since the Default Pushpin's PositionOrigin is set to BottomCenter, we need to
            // set the CenterX to half the width (17), and CenterY to the height (35).
            //

            transform.CenterX = 17;
            transform.CenterY = 35;

            return transform;
        }

        /// <summary>
        /// Convert a ScaleTransform into to ZoomeLevel
        /// </summary>
        /// <param name="value">The current ScaleTransform</param>
        /// <param name="targetType">The type of the target (unused)</param>
        /// <param name="parameter">The parameter (unused)</param>
        /// <param name="culture">The current culture (unused)</param>
        /// <returns>A ZoomeLevel</returns>
        /// <exception cref="NotImplementedException">Always thrown</exception>
        /// <remarks>Unimplemented</remarks>
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }

        #endregion
    }
}
Posted in Uncategorized | Leave a comment

Google GPolyline Decode in C#

I started playing with the Google Maps GPolyline format and discovered that there are many implementations in many languages that allow you to Encode a GPolyline, but very few to Decode a GPolyline. The most common implementations that can be found were written in dynamic languages like JavaScript or Python. I am currently working in C#/Silverlight and found very few examples. The challenge is how to use data formatted for Google Maps in Bing Maps?
 
So I decided to write my own decoder. Because I was interested in understanding the algorithm and not trying to minimize code size or maximally optimize performance, you will see that the methods are rather verbose. But a good compiler should be able to optimize it enough to get decent performance.
 
The Encode algorithm is defined at  http://code.google.com/apis/maps/documentation/polylinealgorithm.html as a sequence steps needed to present a list of latitudes and longitudes into a string to be used by Google Maps. So you will see that my comments are these steps presented in reverse order.
 
There are two methods, the first is the generic algorithm to convert a GPolyline string into a Collection of floating point numbers. Although typically used for pairs of lattitude and longitude, there is strictly no requirement that there be an even number of values. The second method is simply a wrapper to pair up the floating point numbers into a Collection of Bing Maps Locations (LocationCollection). You will note that it is passed an existing Collection, I did this because I wanted to merge a number of GPolyline strings into a single Collection without extra copies.
 
I hope you enjoy this and find it useful.
    -David
 

//
// Copyright 2010 David Robinson  All Rights Reserved
//
// Redistribution and use in source and binary forms, with or
// without modification, are permitted provided that any
// reedistributions of source code must retain the above
// copyright notice and this condition.
//

using System;
using System.Collections.ObjectModel;
using System.Text;
using Microsoft.Maps.MapControl;

namespace DaRobins
{
    /// <summary>
    /// Utility class to manipulate Google Encoded GPolylines
    /// </summary>
    public class GPolyline
    {
        /// <summary>
        /// No constructor
        /// </summary>
        private GPolyline() { }

        /// <summary>
        /// Decode a Google Encoded GPolyline
        /// </summary>
        /// <remarks>
        /// The Google Encoded GPolyline specification is defined
        /// at http://code.google.com/apis/maps/documentation/polylinealgorithm.html
        /// </remarks>
        /// <param name="gPolyString">Encoded GPolyline</param>
        /// <returns>Ordered list of floating point numbers</returns>
        /// <exception cref="System.ArgumentOutOfRangeException">Thrown when the GPolyline has a malformed byte</exception>
        public static Collection<double> DecodeGPolyline(string gPolyString)
        {
            const int MaxGPolyChunks = 7;
            var GPolyElementList = new Collection<double>();

            //
            // Step 11: Convert the GPolyline string back into an array of chunks
            //

            var GPolyBytes = Encoding.UTF8.GetBytes(gPolyString);

            //
            // Walk through the array of chunks splitting it into a list of elements
            //

            var TempChunk = new byte[MaxGPolyChunks];
            int TempChunkIndex = 0;

            for (int i = 0; i < GPolyBytes.Length; i++)
            {
                //
                // A element cannot have more than 7 chunks
                //

                if (TempChunkIndex >= MaxGPolyChunks)
                    throw new ArgumentOutOfRangeException();

                //
                // Step 10 & 9: Chunks are ASCII "base" 63 values
                //

                if (GPolyBytes[i] < 63)
                    throw new ArgumentOutOfRangeException();

                TempChunk[TempChunkIndex] = (byte)(GPolyBytes[i] - 63);

                //
                // A chunk is a 6 bit value: 5 bits data with an upper continuation bit
                //

                if ((TempChunk[TempChunkIndex] & 0xC0) != 0)
                    throw new ArgumentOutOfRangeException();

                if ((TempChunk[TempChunkIndex] & 0x20) != 0)
                {
                    //
                    // Step 8: Clear the continuation bit
                    //

                    TempChunk[TempChunkIndex] &= 0x1F;

                    TempChunkIndex++;

                    continue;
                }

                //
                // Step 7 & 6: Reverse the chunk order and convert to a 32-bit integer
                //

                uint PolyPointDecimal = 0;

                for (var l = 0; l < TempChunkIndex + 1; l++)
                {
                    PolyPointDecimal += (uint)((1 << (5 * l)) * TempChunk[l]);
                }

                //
                // Step 5: If the low order bit is set, the original value was negative, invert.
                //

                if ((PolyPointDecimal & 0x1) == 1)
                    PolyPointDecimal = ~PolyPointDecimal;

                //
                // Step 4: Right shift the value 1 bit
                // Step 3 & 2: Convert back to floating point by dividing by 1e5
                //

                var PolyPoint = (double)((int)PolyPointDecimal >> 1) / 100000;

                //
                // Add chunks to the element list
                //

                GPolyElementList.Add(PolyPoint);

                //
                // Start a new chunk
                //

                Array.Clear(TempChunk, 0, MaxGPolyChunks);
                TempChunkIndex = 0;
            }

            //
            // The last chunk in the GPolyline must not be a continution chunk
            //

            if (TempChunkIndex != 0)
                throw new ArgumentOutOfRangeException();

            return GPolyElementList;
        }

        /// <summary>
        /// Decode a Google Encoded GPolyline into a LocationCollection
        /// </summary>
        /// <remarks>
        /// The Google Encoded GPolyline specification is defined
        /// at http://code.google.com/apis/maps/documentation/polylinealgorithm.html
        /// </remarks>
        /// <param name="gPolyString">Encoded GPolyline</param>
        /// <param name="GPolyLocationCollection">Collection Locations will be added to</param>
        /// <returns>Void</returns>
        /// <exception cref="System.ArgumentException">Thrown when there are no points in the GPolyline or an odd number of points</exception>
        public static void DecodeGPolylineToLocationCollection(string gPolyString, LocationCollection GPolyLocationCollection)
        {
            //
            // The caller may have sent us an empty string
            //

            if (String.IsNullOrWhiteSpace(gPolyString))
                return;

            var GPolyElementList = DecodeGPolyline(gPolyString);

            if ((GPolyElementList.Count % 2) != 0)
                throw new ArgumentException();

            if (GPolyElementList.Count == 0)
                return;

            var LastLocation = new Location(0.0, 0.0);
            bool IsLat = true;
            Location ElLoc = null;

            foreach (var El in GPolyElementList)
            {
                if (IsLat)
                {
                    ElLoc = new Location();

                    ElLoc.Latitude = El + LastLocation.Latitude;
                    IsLat = false;
                }
                else
                {
                    ElLoc.Longitude = El + LastLocation.Longitude;
                    IsLat = true;
                    GPolyLocationCollection.Add(ElLoc);
                    LastLocation = ElLoc;
                }
            }

            return;
        }
    }
}

Posted in Computers and Internet | Leave a comment

Native UEFI Windows 7 Boot on Mac Mini

There is a lot of confusion around the ability to boot Windows 7 using UEFI on a Macintosh. The confusion is based on the interaction with Bootcamp, MDR, GPT, BIOS Compatability Support Modules (CSM), rEFIt, 32-bit, install DVD formats, and bugs, combined with the inherent difficulty in understanding and debugging boot processes.

Facts

  • Windows 7 x64 (64-bit) will NOT boot natively using UEFI on a Macintosh!
  • Windows 7 x64 (64-bit) only supports installation on a UEFI 2.0 firmware using a GPT partitioned disk.
  • The Windows 7 x64 installation DVD is built with support for both BIOS (default) and EFI installation. During setup it is not obvious which version was used.
  • Windows 7 will only install on an MBR disk if booted using BIOS firmware.
  • Windows 7 will only install on a GPT disk if booted using EFI firmware.
  • Apple Macintoshes implement the EFI 1.1 standard, either 32-bit for early (pre-2008) Intel processors or 64-bit for more recent processors.
  • The Mac UEFI firmware contains a legacy CSM that presents a BIOS interface to allow non-UEFI aware OSes to boot and install.
  • Windows 7 x86 and x64 can be installed natively on a Mac in BIOS mode without MacOS or Bootcamp, but MacOS will not boot in BIOS mode.
  • Bootcamp is:
    • Set of Windows device drivers
    • Partitioning tool and MBR hacker
    • BIOS Compatability Support Modules in firmware

The Journey

The System

I purchased a Mac Mini (2.26 Ghz Intel Core 2 Duo, 4 GB DRAM, 320 GB disk) as a small compact desktop to primarily run Windows, but also support a few applications that had been previously running on an old PPC iMac. Primary purchasing decision factors included size, performance, and cost. I don’t have a lot of space in my home office so having a single large screen monitor that I can share is ideal. This ruled out the all-in-one systems like the iMac. I don’t need expandability beyond USB and Firewire, so space for extra PCI cards is wasted. I don’t play serious PC games (XBox if anything) so I only need a adequate 3D graphics. But I need more performance than what a Nettop (aka Atom based) system provides. Thus I ended up considering a number of systems (including a Dell Studio Hybrid), but when all things were balanced out, the Mac Mini had more features for less than a $100 price difference (sorry Steve).

Why Use UEFI?

I am an operating systems geek (Windows and Solaris) who has written more than my share of low level boot code. So with knowledge of Windows 7 support of UEFI, Macintosh support of UEFI, the idea of using Bootcamp tools to provide legacy BIOS support was just distasteful to me. I understand how useful it is for people wanting to run ancient Windows XP, but in the modern world of Windows 7 and Snow Leopard why bother with BIOS firmware? Not to mention 2 TB disks are rapidly approaching $100 and are too big for MBR partitioning. So all this modern technology should allow Windows and MacOS to live happily together in the UEFI world…

Keep It Simple

Of course the first thing anyone should do is to try the obvious, given that Windows 7 isn’t even available for retail systems yet I figured there hasn’t been much experimentation. So I inserted the Windows 7 x64 RTM DVD and booted holding the Alt/Option key, then I selected “EFI Boot” only to discover that just boots MacOS. Try again, this time I selected “Windows”. Success! The Windows 7 installation screens!

Not so fast…

Going through the Custom install menus to the disk screen, all of the partitions are unavailable with the error “The selected partition is of the GPT partition style.” Of course it is GPT, that is what I want. Something is wrong.

A little detective work later I discover that Windows will only install on a GPT partitioned disk if it has been booted using EFI, conversely MBR only if booted using BIOS. The Windows 7 DVD is built using the El Torito multiboot image format, the first (and default) boot catalog image is the BIOS (platform id 0) based etfsboot.com boot code and the secondary (platform id EF) is efisys.bin, the EFI boot application. Mac firmware when it detects a BIOS boot image adds the CSM driver and boots in legacy BIOS mode. I don’t know of any way to force the Mac firmware to pick the second boot catalog image.

EFI Only DVD

If the Mac firmware insists on using the BIOS boot code when present, the obvious solution is to remove it so only the EFI image is present. Microsoft has a nice set of tools (AIK/OPK) that allows you to create custom installation images, in particular the oscdimg.exe command is used to create bootable ISO images. All I need to do is copy the DVD contents to our local disk, create a new ISO image, and burn a new DVD.

md win7x64
robocopy /e /copyall e: win7x64
oscdimg -w4 -os -lWin7x64_UEFI_Only -m -o -n -pEF -e -bc:win7x64efimicrosoftbootefisys.bin c:win7x64 c:Win7x64_UEFI_Only.iso

Again, boot using Alt/Option and it fails…

WinPE

WinPE is the Windows Preinstallation Environment that is the stripped down version of Windows used for installation and recovery operations. Since I failed to create a EFI only installation DVD, it was logical to see if I could create a simple WinPE image. Again using the AIK and following the directions for Walkthrough: Create a Bootable Windows PE RAM Disk on CD-ROM I created a new CD.

Again, boot using Alt/Option and this time there is an “Efi Boot” but with a new icon. Selecting it and the CD starts spinning but the screen doesn’t change. Remembering that Windows prompts you to “hit return to boot” from CD, I do so causing more CD activity but ultimately it fails. Sounds like progress, but I can’t really tell.

Maybe some interesting activity or error is being hidden by the Mac graphics image? A bit of searching and there are some posts that indicate any EFI text messages will not be displayed due to the Mac being in graphics mode.

rEFIt

rEFIt is an open source EFI shell which is used by many Mac enthusiasts. It solves the big problem that Apple does not ship a real EFI shell in its firmware. By downloading and installing rEFIt I can intercept the boot process and actually see what is happening.

Although Apple creates the required EFI System Partition (ESP), it does not populate it or use it for anything because its firmware already has all the required drivers (e.g. HFS+) built in (and why would you want to boot anything else?). For my experiments, I don’t want to mount or use the MacOS partitions, so I need to install rEFIt on the hidden EFI system partition using Felipe Alfaro’s “expert” directions.

Now I can boot into rEFIt and get a real EFI shell to play with. (Hint: add “-b” to commands to page output) Running the “ver” command shows that Apple has only implemented the 1.1 specification.

With the original Windows 7 installation DVD inserted, I can select fs2 and execute the BOOTx64.EFI command from the DVD:

Shell> fs2:

fs2:> EFIBOOTBOOTX64.EFI

Now I can see it going through the expected boot messages including the progress bar that indicates that it is loading the Windows files. The DVD disk sounds are similar to what I heard with the WinPE image so I suspect that previous image was correct.

But it does not boot and appears to just hang.

Rebooting into the EFI shell again, I run BOOTX64.EFI again, but this time I hit F8 which brings up the boot menu asking if I want Safe Mode. I select Safe Mode with Command Shell and watch all the boot drivers being loaded, but again it fails to boot.

All of this leads me to the conclusion that I am loading Windows using EFI and getting through the early winload execution, but failing to start the NT kernel. The early winload execution and kernel image is identical between the installation image and a fully installed image, so even if I was able to install Windows in a GPT partition it will not boot using UEFI due to missing firmware features.

Reading the “UEFI Support and Requirements for Windows Operating Systems” document makes it clear that only UEFI 2.0 is supported.

Conclusion

Until Apple upgrades its UEFI firmware to version 2.0 or higher, Windows 7 will not natively boot on a Macintosh. Bootcamp is the only solution and Apple has little motivation to upgrade their firmware.

Links

http://technet.microsoft.com/en-us/library/dd744321(WS.10).aspx

http://support.microsoft.com/kb/947024

http://www.insanelymac.com/forum/lofiversion/index.php/t184349.html

http://technet.microsoft.com/en-us/library/dd799303(WS.10).aspx

http://refit.sourceforge.net/

http://homepages.tesco.net/J.deBoynePollard/FGA/efi-boot-process.html

http://www.felipe-alfaro.org/blog/2006/09/19/installing-refit-on-the-hidden-efi-system-partition/

http://technet.microsoft.com/en-us/library/dd744321(WS.10).aspx

http://www.microsoft.com/whdc/system/platform/firmware/uefireg.mspx

Update: 7/20/2011

It appears that with the more recent Mac systems Apple is moving to UEFI 2.0. Notably the MacBook (Mid 2010), MacBook Pro (13-inch, Mid 2010), and MacBook Air (Late 2010). Logically the 2011 versions as well?

If correct, these systems should be able to native UEFI boot Windows 7 (or Windows Server 2008 R2). Anyone have an extra machine they want to send me to test?

Eventually they may catch up with the UEFI community that has already released 2.3.1.

Useful link: http://support.apple.com/kb/HT1237

 

 

 

Posted in Computers and Internet | 29 Comments