Larry Osterman's WebLog

Confessions of an Old Fogey
  • Larry Osterman's WebLog

    If you live in the US, don’t forget to vote today


    It’s a really big deal, regardless of your political persuasion.


    Already the MSFT internal mailing lists have been filled with people asking “how long are the lines at my polling place”.  The good news is that the times appear to be pretty good – people seem to be getting in and out in very little time (at least in the town in which I live).


    For people living in King and Pierce counties in Washington State, this will be the last time that they will vote in person.  The rest of the state already votes entirely by mail, and starting next year, both counties will also switch to vote-by-mail.


    The state of Oregon has already switched to a 100% vote-by-mail system, with the switchover in King and Pierce counties, Washington state will join Oregon in eliminating the ballot box.


    Valorie and I have been voting absentee for about 5 years now, personally I like it – by voting at home, we have the opportunity to scope out the candidates at our leisure.  That in turn means that we’re going to vote more accurately.


    So if you live in the US, please, PLEASE vote today.

  • Larry Osterman's WebLog

    Where does the time go? Daniel's play premiers on Friday!


    A while ago, I'd mentioned that Daniel was cast as Orin Scridlow in SCT's summer season production of "Little Shop of Horrors".


    Friday August 3rd is his opening night!  He'll be performing at 7PM on August 3rd, 1PM on August 4th, 7PM on the 8th, and 7PM on the 10th.

    This one's going to be worth seeing - I've seen a bit of his Orin, and it reminds me of what Alan Cumming did with the character of MC in the 1998 Roundabout production of Cabaret.  It ain't Steve Martin up on stage there.

    I can't wait :)

  • Larry Osterman's WebLog

    I'm in LA!


    I just got into LA and checked into my hotel for the PDC.  The flight was uneventful, while I was flying down, there was a most amazing sunset (I was in an isle seat so the picture’s kinda blurry – I didn’t have anything to stabilize the shot and it’s a somewhat long exposure):

    PDC 2008 013 Once I got here, I found it was too late to register, that means that I’m going to have to brave the lines tomorrow morning – yech. 

    I’m in the Bonaventure hotel which is quite nice, however the hotel room is annoyingly short of plugs – there are only 2 plugs available in the bedroom, and I’m using both of them for my laptops (I brought two down, one for day-to-day use and the other for the demo during my presentation – my day-to-day laptop acts as a backup  for the demo laptop if it fails) – my camera battery is currently charging in the bathroom.


    I’m going to do daily posts of my overall PDC experiences, preferably with pictures as well.

  • Larry Osterman's WebLog

    PDC 2008, Day 1


    Wow, today’s been a long day.  For whatever reason, I woke up at 4 AM and wasn’t able to get back to sleep :(.  On the other hand, I did get this cool picture from outside my window:

    The View From My Window - 6AM at the Westin Bonaventure

    When I got to the convention center I discovered that they were right – this place is absolutely immense.  You really can’t see it from this picture, but this is just one of the eating areas – there’s another on the opposite side of the “big room” that’s equally large:

    The breakfast nook - cozy eating for 3000

    I know I’m going to get my exercise just walking to and from the keynotes :). 

    The other thing I didn’t realize was the amount of ancillary manpower associated with the conference – there was a veritable army of waiters there to clean up after all 6500 of us.  There are also staff people in front of just about every door in the convention center (and that’s a lot of doors) to help direct people.  

    I’m also really impressed with the logistics – the wireless network works flawlessly throughout the convention center and bandwidth appears to be quite reasonable.  My hat’s off to the organizers they’ve done a great job so far.

    Since there was nothing specifically related to Win7 going on today (the Win7 hoopla starts tomorrow), I mostly hung out at the various lounges and worked on my talk a bit – there was a typo in one of my slides I needed to fix, and I wanted to get some of the colors cleaned up in one of my images.  Fortunately the PDC organizers had a crack team of graphic designers who were able to fix up my slides and dramatically improve the look of the offending slide (the rest of the deck looked fine because the graphic designers had already gone over the deck once). 

    Realistically the day was pretty boring.  I stopped in and watched most of the Windows Azure keynote, I’ve got to say that it looks pretty good – I like what Dave Cutler’s done, it looks like a very impressive piece of work.

    Most of my day was spent chatting with attendees (and other Microsoft people).  I finally met Brandon Paddock, who I’ve known for a while on email and we chatted for a bit.  I also ran into the Channel 9 folks and again we chatted.  I also tried (unsuccessfully) to catch up with my email.

    At about 6:30 I finally gave up and headed back to the hotel.  At the hotel, I ran into some folks from DevDiv who were having drinks with Anders, so I kibitzed on their conversation a bit.

    Then I cam back to my hotel room to rehearse my talk and wait for Valorie’s nightly call. I’m really looking forward to tomorrow – I can’t wait for the Win7 keynote :). 

    One final picture – this one’s for Daniel (who loves taking pictures of architectural elements):

    Architectural elements inside the convention center

    PS: I’ve put these and a number of other photos up on Flickr with the pdc2008 tag.

    ETA: One unexpected side bonus of being at the PDC is running into people I've not seen for years.  I ran into a bunch of co-workers I've not seen for a really long time including Dave Snipp (who worked on NT 3.1), David Treadwell and Dave D'Souza.  That was just cool - kinda like old times.


  • Larry Osterman's WebLog

    See you in LA in October!


    I just got word that the talk we’d proposed for the PDC in October was approved, so I’m going to La-La-Land next month for a couple of days.


    The contents of my talk have not yet been disclosed, so I can’t talk about what I’m talking about at the PDC :(. 


    Disclaimer: Life sometimes happens.  Right now I’m scheduled to talk but who knows whats gonna happen between now and then?  But I AM excited.  This will be my second PDC – the first one was WAY back in 1992 (I need to make sure that I remember to bring my speaker badge from that (yes, I still have it)).

  • Larry Osterman's WebLog

    Off to the 5th Avenue Awards tonight!


    Tonight we're going to be attending the 2008 5th Avenue High School Musical Awards show.  It's the local equivalent of the Tony awards for High School musical productions.  This year Daniel won an Honorable Mention for his performance as Brownlow in Overlake's production of Oliver!  In addition, his cast mate Nick Wright has been nominated for an award for his role as Mr. Bumble.

    It's cool to see Daniel and Nick's hard work being recognized.

  • Larry Osterman's WebLog

    One year ago today (August 2008)…


    I was finishing Windows 7 M3 (the build which eventually was delivered at the PDC).  During M3, I spent most of my time working on the “Ducking” feature.  I was working on my PDC presentation, although the slides I had in August bore almost no resemblance to the slides I eventually presented (I started with 50 some slides and ended up with 23).


    At home, I’d replaced all our 100 megabit switches with new gigabit Ethernet switches to boost performance (I was bored one weekend when Valorie and the kids were out of town).  Daniel was attending the pre-college program at Carnegie-Mellon University, and came back at the end of the week. 


    And long time readers of my blog know where this particular series is going :).

  • Larry Osterman's WebLog

    What was Valorie doing last weekend? Competing at the Sweet Adelines Region 13 competition…


    And her performance video just got posted to YouTube…


    They came in 8th out of 15 in the competition and won best novice quartet. 

    And they rocked :).

  • Larry Osterman's WebLog

    I get still more spam


    This morning I awoke to find the following spam email in my inbox:

    Greetings from Amazon Payments.

    Your bank has contacted us regarding some attempts of charges from your credit card via the Amazon system. We have reasons to believe that you changed your registration information or that someone else has unauthorized access to your Amazon account Due to recent activity, including possible unauthorized listings placed on your account, we will require a second confirmation of your identity with us in order to allow us to investigate this matter further. Your account is not suspended, but if in 48 hours after you receive this message your account is not confirmed we reserve the right to suspend your Amazon registration. If you received this notice and you are not the authorized account holder, please be aware that it is in violation of Amazon policy to represent oneself as another Amazon user. Such action may also be in violation of local, national, and/or international law. Amazon is committed to assist law enforcement with any inquires related to attempts to misappropriate personal information with the intent to commit fraud or theft. Information will be provided at the request of law enforcement agencies to ensure that perpetrators are prosecuted to the full extent of the law.

    To confirm your identity with us click here: <LINK REDACTED>

    After responding to the message, we ask that you allow at least 72 hours for the case to be investigated. Emailing us before that time will result in delays. We apologize in advance for any inconvenience this may cause you and we would like to thank you for your cooperation as we review this matter.

    Thank you for your interest in selling at Customer Help Service

    In many ways this tickled my fancy.  The first paragraph (“Greetings from Amazon Payments”) indicates that it’s directed to one of the Amazon affiliates and I’m not an Amazon affiliate.  if it was directed to customers, it wouldn’t come from Amazon’s Payments department, instead it would come from some other department (maybe Amazon billing?).

    But they immediately discuss “attempts of charges from your credit card” (let’s ignore the fractured English, it’s a phishing email so you sort-of expect crappy English).  If I’m an affiliate, why would Amazon be charging my credit card?

    They then go on and indicate that if this isn’t resolved right away they’ll cancel my Amazon account – very scary.  In fact the risk is so severe, they’re going to ask that I provide a second confirmation of my identity.  And Amazon is going to be totally helpful in ensuring that law enforcement is notified of the charges.  How very helpful of them.


    But what made this email stand out to me is the next to last paragraph.  The one where they say:

    “…we ask that you allow at least 72 hours for the case to be investigated. Emailing us before that time will result in delays.”

    To paraphrase that fragment: “we figure it’s going to take us at least 3 days to clean out your credit card and get away.  So please don’t bother us before then.”




    Somewhat OT: On a more serious note, a friend of the family recently had her email account hacked (we don’t know how it happened but it did).  The criminals who did this then proceed to send fraudulent emails to all the contacts in her address book asking for money.  The good news is that she complained to the Live Mail folks about it and they were able to reclaim the account for her within 24 hours, so hopefully the damage is minimal.  And she’s gone out and changed all her online passwords in case they figured out those passwords while they had access to her email.  Live email also has an excellent “what to do when you think your account’s been stolen” resource which lays out the various options available when this happens.  The local police department also pointed her to the FBI’s Internet Crime Complaint Center, it’s not clear if engaging them will make a difference (especially if the crooks are international) but it’s something.

  • Larry Osterman's WebLog

    Five years ago today (August 2004)


    We were busy in the “Longhorn Reset” where we essentially threw away the work we’d previously done for Longhorn and restarted based on a Server 2003 based codebase.  We took the work we’d done for the Longhorn audio engine and reworked it to create the current audio engine we delivered with WIndows Vista – many of the concepts of the original engine remain (although several of them are gone and some of the functionality was radically reworked (for example in the LH alpha codebase, the waveOutXxx APIs used the MediaFoundation APIs to render audio – in Vista they use WASAPI directly).  Things were pretty hectic, but none of the developers working on Longhorn were really sorry to see the old project go – it truly had become unmaintainable.

    Also in 2004, I started this blog – back then it was hosted on another site, but my blog officially went live on March 15, 2004.

  • Larry Osterman's WebLog

    Elliot Omiya, Frank Yerrace and I make a video…


    Charles just let me know that he’s posted a video that Elliot, Frank and I did talking about the audio features added to Win7 and some of the architectural decisions that went into it.



  • Larry Osterman's WebLog

    Two years ago today (August 2007)


    I was working on Win7 M1, working on the Capture Monitor feature (which enables the ability to listen to your portable media player on your PC speakers without requiring special hardware support).  A good chunk of my time was spent working on the network throttling issue, it required a ton of effort on the part of everyone involved to get this issue fixed (it was a very tricky problem to solve).

    I also bought my current car during that month :).

    Daniel was appearing in SCT’s drama school summer production of Little Shop of Horrors (he played Orin), Sharron was at summer camp.

  • Larry Osterman's WebLog

    Three years ago today (August 2006)


    Back in the summer of 2006, we were all busy trying to finish Windows Vista.  I actually spent most of July and August writing protocol documentation for old protocols that I’d written many years ago – I’m the principal author of the MS-BRWS document (it’s currently owned by the network team) and the MS-RAP protocol.  The MS-RAP protocol was particularly complicated because of the declarative nature of protocol documentation specifications – the original LAN Manager remote admin protocol specification was based on string descriptor values which were parsed to determine how the data sent from the client was marshaled, but for MS-RAP there really was no easy way of expressing this (because the protocol specifications needed to be declarative not descriptive).  Most of the MS-RAP is deprecated with WIndows 7, which is a great relief to me (that particular protocol existed to enable interop with LAN Manager administrative tools and I doubt very much that any of them are still in use today).

    We had just returned from a 10 day cruise from Istanbul to Venice with most of my extended family (Valorie, the kids, my step-mom, my youngest brother and sisters and my kids ��honorary grandparents”) – it was a huge amount of fun and we really enjoyed it – I don’t take vacations very often and this one was just wonderful (if only because I was off the web for almost 2 weeks).

  • Larry Osterman's WebLog

    Nine years ago today (August 2000)


    The biggest event on my plate in August was that I took taken delivery of a brand spanking new Itanium machine that was intended for 64bit Exchange development :).  We also shipped Exchange 2000 during mid 2000.  2000 was a time of some turmoil for the Exchange store development team – after shipping Exchange 2000, much of the store team left Exchange and moved to SQL server (where several of them still remain).  I chose not to remain with the rest of the store team and instead moved onto the SCP team (I wrote about that team yesterday).

  • Larry Osterman's WebLog

    Four years ago today (August 2005)


    I had just finished the Beta3 coding for Windows Vista.  During that time I finished the per-app volume feature work and spent a bunch of time helping other groups finish up their initial coding.  Things were crazy busy, especially during the final weeks as all the features landed.


    August was also quite traumatic because my father died on August 14th of a severe allergic reaction to a bee sting, he was 70. 

  • Larry Osterman's WebLog

    Recursively Deleting a directory–with long filename support.


    I recently was updating some test code to handle long filename (longer than MAX_PATH) support.

    My initial cut at the function was something like the following (don’t worry about the VERIFY_ macros, they’re functionally equivalent to asserts):

    const PCWSTR LongPathPrefix=L"\\\\?\\";
    void RecursivelyDeleteDirectory(const std::wstring &strDirectory)
        //  Canonicalize the input path to guarantee it's a full path.
        std::wstring longDirectory(GetFullPath(strDirectory));
        //  If the path doesn't have the long path prefix, add it now before we instantiate the
        //  directory_list class.
        std::wstring strPath;
        if (longDirectory.find(LongPathPrefix) == std::wstring::npos)
            strPath = LongPathPrefix;
        strPath += longDirectory;
        strPath += L"\\*";
        directory_list dl(strPath);
        for (const auto && it : dl)
            std::wstring str(longDirectory+L"\\"+it);
            //  It’s possible that the addition of the local filename might push the full path over MAX_PATH so ensure that the filename has the LongPathPrefix.
    if (str.find(LongPathPrefix) == std::wstring::npos) { str = LongPathPrefix+str; } DWORD dwAttributes = GetFileAttributes(str.c_str()); VERIFY_ARE_NOT_EQUAL(dwAttributes, INVALID_FILE_ATTRIBUTES); // Check for error. if (dwAttributes & FILE_ATTRIBUTE_DIRECTORY) { if (it != L"." && it != L"..") { RecursivelyDeleteDirectory(str); } else { VERIFY_WIN32_BOOL_SUCCEEDED(DeleteFile(str.c_str())); } } } VERIFY_WIN32_BOOL_SUCCEEDED(RemoveDirectory(longDirectory.c_str())); }

    The weird thing was that this code worked perfectly on files shorter than MAX_PATH. But the call to GetFileAttributes failed 100% of the time as soon as the directory name got longer than MAX_PATH. It wasn’t that the GetFileAttributes API didn’t understand long filenames – it’s documented as working correctly with long filenames.

    So what was going on?

    I wrote a tiny little program that just had the call to GetFileAttributes and tried it on a bunch of input filenames.

    Running the little program showed me that \\?\C:\Directory\FIlename worked perfectly. But \\?\C:\Directory\. (note the trailing “.”) failed every time.

    It took a few minutes but I finally remembered something I learned MANY decades ago: On an NTFS filesystem, the “.” and “..” directories don’t actually exist. Instead they’re pseudo directories inserted into the results of the FindFirstFile/FindNextFile API.

    Normally the fact that these pseudo directories don’t exist isn’t a problem, since the OS canonicalizes the filename and strips off the “.” and “..” paths before it passes it onto the underlying API.

    But if you use the long filename prefix (\\?\) the OS assumes that all filenames are canonical. And on an NTFS filesystem, there is no directory named “.”, so the API call fails!

    What was the fix? Simply reverse the check for “.” and “..” and put it outside the call to GetFileAttributes. That way we never ask the filesystem for these invalid directory names.

  • Larry Osterman's WebLog

    ExpandEnvironmentStringsA returns a different required buffer length than ExpandEnvironmentStringsW


    I was writing some ANSI-only code the other day to handle the case where an environment string expansion could return a buffer larger than MAX_PATH (the test code I was modifying assumed that it could only ever see a MAX_PATH output, I wanted to make it more resilient).

    The way the code worked, I defined a wrapper for ExpandEnvironmentStringsA that returned a std:::string and then appended values to that string. But I found that my strings weren’t working correctly – none of the appended values were actually being appended.

    Digging in, I discovered that there was an embedded null in the string, which didn’t make any sense to me – where did that come from?

    Here’s the wrapper I wrote for the call to ExpandEnvironmentStrings:

    std::string ExpandEnvironmentStringsToString(PCSTR sourceString)
        DWORD dwEvSize;
        dwEvSize = ExpandEnvironmentStrings( sourceString, nullptr, 0);
        if (dwEvSize == 0)
            return std::string();
            std::string returnValue(dwEvSize, L'\0');
            dwEvSize = ExpandEnvironmentStrings( sourceString, &returnValue[0], dwEvSize);
            if (dwEvSize == 0)
                return std::string();
            returnValue.resize(dwEvSize-1); // dwEvSize returned by ExpandEnvironmentStrings includes the trailing null, truncate it.
            return returnValue;

    That code looks like it should be just fine, but there was still that unexpected extra null character.

    On a lark, I switched the code to Unicode and tested the version that returned an std::wstring. That worked perfectly – the string converted the string perfectly.

    Since ExpandEnvironmentStringsW worked perfectly and ExpandEnvironmentStringsA added an embedded null, I started looking at the return value of ExpandEnvironmentStringsA. It turns out that ExpandEnvironmentStringsA always returned enough space for *two* null characters, not the one character it’s documented as requiring.

    Once I figured that out, the solution to my problem was clear. Just change the




    to account for the additional null character.

    Just another day in the strange world that is the Win32 API surface Smile.

  • Larry Osterman's WebLog

    Converting Win32 API results to std::wstring (or std::string)


    Hmm. Just realized that this is a bit out of order and should have been published before the previous post Smile.

    It turns out that there are a significant number of Win32 APIs that have a similar calling pattern – you call the API once to find the size of the buffer needed for the result, allocate a buffer then fill in the resulting buffer. Examples of APIs like this are GetCurrentDirectory, GetEnvironmentVariable, ExpandEnvironmentString, MultiByteToWideChar, etc. The pattern shows up over and over again in the Win32 API surface. It would be really useful if it was possible to define a fairly standard pattern that results in the creation of a std::wstring from one of these APIs (it’s probably not possible to create a template to handle all the possible APIs but that’s ok, defining a working pattern is probably OK). One of the key aspects of such a pattern is that I only ever want to perform one allocation during the call. Otherwise I could simply use malloc to allocate a buffer, fill in the buffer and then construct a new std::wstring for that pattern.

    I did what every developer does in this situation and searched the internet and I found a solution that seemed to work correctly, but I wasn’t really happy with what I came up with (NOTE: DO NOT USE THIS CODE):

    std::wstring UnicodeStringFromAnsiString(_In_ const std::string &ansiString)
        std::wstring unicodeString;
        auto wideCharSize = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, ansiString.c_str(), -1, nullptr, 0);
        if (wideCharSize == 0)
            return L"";
        wideCharSize = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, ansiString.c_str(), -1, &unicodeString[0], wideCharSize);
        return unicodeString;

    There are a couple of issues with this code (ignore the fact that it doesn’t handle errors particularly well). The first is that it is inconsistent in its handling of the failure case, I’m also not happy with the “reserve”/”resize” aspect of the result.

    So I asked the owners of the C++ runtime library on the VC team what they would suggest and they pointed out a huge issue with my solution.

    The code I found above worked but it ignored at least one really important aspect of the implementation of the std::wstring type (and the std::string type). It turns out that the null terminating character in the std::wstring is owned by the STL – are code outside the STL is not allowed to mess with that null terminating character, and that’s exactly what happens when I wrote .reserve (to allocate storage) and .resize (to resize the buffer so it doesn’t contain the trailing null). There’s a more significant problem with this code however. By returning both a named value AND a temporary, it has the side effect of disabling the NRV optimization, which can result in significant performance degradation.

    Instead of my example, they suggested instead that I change the code as follows (follow this pattern instead):

    std::wstring UnicodeStringFromAnsiString(_In_ const std::string &ansiString)
    std::wstring returnValue; auto wideCharSize = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, ansiString.c_str(), -1, nullptr, 0); if (wideCharSize == 0) { return returnValue; } returnValue.resize(wideCharSize); wideCharSize = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, ansiString.c_str(), -1, &returnValue[0], wideCharSize); if (wideCharSize == 0) {
    returnValue.resize(0); return returnValue; } returnValue.resize(wideCharSize-1); return returnValue; }

    The key difference between this version and the previous is that we only allocate a new string once we’ve calculated the size and we initialize the string to the needed buffer size. We then fill the buffer (using the array operator [] to gain access to a non const buffer for the string) and finally resize the string to the actual size of the string. By performing the operations in this order, we ensure that we never overwrite the STL’s null character – it always lies one character beyond the end of the buffer that we’re filling in. And because a resize that decreases the size of a buffer never allocates a new buffer, we preserve the desired behavior that we only ever allocate one buffer. And finally, this version only returns the same local variable (thus enabling NRVO).

    One final note: This technique only works when the output of the Win32 call is relatively static. If you’re retrieving data whose size can change on the fly, it’s probably best to add a loop around the API call to ensure that the buffer is large enough.

  • Larry Osterman's WebLog

    PathCchCanonicalizeEx doesn’t actually canonicalize filenames (AKA: Hey Larry, it helps to RTFM).


    So I was working on some file path parsing logic the other day and I ran into a problem – I was converting a file name passed in on the command line to a long filename acceptable path (one starting with \\?\). As I mentioned before, the Win32 APIs that accept \\?\ filenames assume that the filename specified is a valid path to the filename. That means that filenames with \\?\ prefixes cannot have “.” or “..” characters in the filename.

    The good news is that there’s a convenient API you can call that handles removing the “.” and “..” filename components – PathCchCanonicalizeEx. As the API documentation states, it “Simplifies a path by removing navigation elements such as "." and ".." to produce a direct, well-formed path.”

    What the API documentation doesn’t state (which I unfortunately assumed) was that when presented with a relative pathname, the PathCchCanonicalizeEx API, the PathCchCanonicalizeEx API would convert the relative pathname to an absolute pathname.


    Note to self: Always read the API documentation. And don’t make assumptions about functionality that isn’t actually there.

    Fortunately it appears that contrary to documentation, the PathIsRelative API works just fine in determining if an input filename is relative or absolute. So there’s an easy solution to the problem:

    wstring fileToCanonicalize;
    if (PathIsRelative(inputFilename.c_str())
        fileToCanonicalize = GetCurrentDirectoryAsString();
        fileToCanonicalize += L"\\";
    fileToCanonicalize += inputFilename;
    PathCchCanonicalizeEx(..., fileToCanonicalize.c_str(), ...);
Page 33 of 33 (819 items) «2930313233