February, 2009

  • The Old New Thing

    If you get confused by a register dump, then you'll just have to accept that some of my postings won't make any sense

    • 29 Comments

    This Web site is not for beginners. I try to write for advanced programmers, and if you're not an advanced programmer, then you'll just have to accept that there will be times you are baffled by what I write. Often I dial the geek back a notch, explaining some things which should be "obvious" to an advanced programmer, such as why storing a constant pointer into a stack location from dynamically-generated code is a clear indicator of a framework thunk. But I will dial it back only so far, and eventually you may just be forced to (horrors!) do your own background research to get yourself up to speed or simply give up and see if you have better luck with the next entry.

    There are some topics I have sitting in my ideas folder which I will probably never actually post about because they are so advanced that even Don Box, COM guru extraordinaire, admitted in email to me that they're too advanced even for his super-advanced book on COM. At the PDC, talks used to be categorized as 100, 200, 300, or 400-level, mimicking the categorization of classes at most U.S. universities, with 100-level classes being introductory, and 400-classes being college senior seminar type stuff. COM weak QueryInterface would be somewhere at the graduate research level. Stuff so esoteric, nobody would actually need to know it.

    To be honest, I don't think I've written anything truly advanced in a long time. It's all been fairly intermediate for the past few years. People don't seem to mind too much, so I'll just keep it going.

  • The Old New Thing

    A different type of writing exercise, this time in preparation for buying a house

    • 30 Comments

    One of my colleagues was overwhelmed by how many times papers need to be signed when you buy a house. A seemingly endless stack of papers. Sign and date here, initial here, initial here, now sign this, and this, and this, and sign and date here, and sign here, and initial here... By the time it's over, your arm is about to fall off.

    Some years later, my colleague was about to buy a new house and began to dread the signature-fest that would invariably ensue at the closing. Another ten-foot-tall stack of papers that needed to be signed and initialed.

    In preparation, my colleague actually did hand exercises to build up stamina and strength. I'm not sure what the exercises consisted of, but they were probably a mix of strength-building wrist exercises and some stints of extended longhand writing.

    Finally closing day came. My colleague walked into the agent's office, sat down, and prepared for the worst, only to be surprised when the stack of papers was only a dozen pages long. What happened to the ten-foot-tall stack of papers that took hours to sign and initial?

    The difference is that my colleague paid cash for the new house rather than taking out a loan. That ten-foot-tall stack of papers? Nearly all of them were related to the mortgage, not to the actual sale of the house. The paperwork associated with a house sale proper is comparatively light.

    But all was not lost. At least my colleague had pretty strong wrists now.

  • The Old New Thing

    Changes to the the 2009/2010 Seattle Symphony subscription season

    • 4 Comments

    A thank-you to commenter Greg for pointing it out that the Seattle Symphony made changes to their UBS Masterworks 13 series after the brochures were printed. I compared my printed brochure against the online one and updated the 2009/2010 Seattle Symphony subscription season at a glance accordingly. They deleted five concerts and added six, so the Masterworks 13 series actually has 14 concerts. They probably kept the name for backward compatibility.

  • The Old New Thing

    What is the purpose of the RunAsCommand value?

    • 20 Comments

    Commenter c_e_pizano asks what the purpose of the HKLM\Software\Microsoft\Windows\CurrentVersion\App Paths\foo.exe\RunAsCommand registry value is.

    Well, for starters, it isn't documented, so the official answer to that question is "Don't mess with it."

    Kind of makes me wonder why you're asking about the registry value anyway, seeing as it's undocumented in the first place. Are you trying to reverse-engineer Windows?

    To be honest, I don't know what its purpose is, but I do know what happens when you set it: Everything stops working.

    This is one of those abandoned features like EM_SETHILITE. When it got abandoned, not all of the pieces got cleaned up, and there is still code that queries for the key, but the code path that gets executed when the query succeeds simply doesn't work (probably because some of the functionality it relied upon was deleted!) and consequently always returns an error. That's why, if you set the value, you get a weird error message.

    The broken code was deleted in 2004, so Windows Vista doesn't even query for the value any more. It's now just a footnote to history.

  • The Old New Thing

    A process shutdown puzzle: Answers

    • 16 Comments

    Last week, I posed a process shutdown puzzle in honor of National Puzzle Day. Let's see how we did.

    Part One asked us to explain why the ThreadFunction thread no longer exists. That's easy. One of the things that happen inside ExitProcess is that all threads (other than the one calling ExitProcess) are forcibly terminated in the nastiest way possible. This happens before the DLL_PROCESS_DETACH notification is sent. Therefore, the code in StopWorkerThread that waits for the thread completion event waits forever because the ThreadFunction is no longer running. There is nobody around to see the shutdown event and respond by setting the completion event.

    Okay, that was the easy part. Part Two asked us to criticize the replacement solution which replaced the completion event with a call to FreeLibraryAndExitThread and changed the StopWorkerThread function to wait for the thread handle to become signaled. This solution is also flawed.

    Consider the case that the DLL is receiving its DLL_PROCESS_DETACH notification because the DLL is being unloaded by a call to FreeLibrary, rather than due to process termination. In that case, StopWorkerThread sets the shutdown event, and the ThreadFunction proceeds to clean up and call FreeLibraryAndExitThread. But one of the steps in thread shutdown is sending DLL_THREAD_DETACH notifications, which will not happen until the DLL_PROCESS_DETACH notifications are complete. The WaitForSingleObject waits indefinitely because it won't complete until the thread exits, but the thread won't exit until StopWorkerThread returns. Deadlock.

    Finally, Part Three asks us to explain why the code doesn't cause a problem in practice even though the code is flawed. The call to FreeLibraryAndExitThread implies that the code follows the "Worker thread retains its own reference on the DLL" model. After all, that's why the last thing the thread does is free the library. But if that's the case, then a call to FreeLibrary coming from the application won't actually unload the DLL, because the DLL reference count is still nonzero: There is one reference still being held by the worker thread. Therefore, the DLL will never actually unload outside of process termination. All the flaws in the dynamic unload case are masked by the fact that the code never executes.

    Led astray: Some of us mentioned that waiting on ThreadHandle returned immediately because the handle to a thread is automatically closed when the thread exits. This is wrong. Handles do not self-close. You have to call CloseHandle to close them. This is "obvious" if you apply the "imagine if the world actually worked this way" rule: Suppose thread handles were invalidated (and eligible for re-use) when a thread exited. Then how could you use a thread handle at all? Any time you use a thread handle, there would be an unavoidable race condition where the thread might have exited just before you used the handle. And it would be impossible to call GetExitCodeThread at all! (Since it only does anything interesting if you pass the handle to a thread that has exited.)

    A handle to a thread remains valid until you close it. If the thread has exited, then a wait on the thread handle completes, but the handle is still valid because if it went invalid, programming would become impossible.

  • The Old New Thing

    What the various registry data types mean is different from how they are handled

    • 55 Comments

    Although you can tag your registry data with any of a variety of types, such as REG_DWORD or REG_BINARY or REG_EXPAND_SZ. What do these mean, really?

    Well, that depends on what you mean by mean, specifically, who is doing the interpreting.

    At the bottom, the data stored in the registry are opaque chunks of data. The registry itself doesn't care if you lie and write two bytes of data to something you tagged as REG_DWORD. (Try it!) The type is just another user-defined piece of metadata. The registry dutifully remembers the two bytes you stored, and when the next person comes by asking for the data, those two bytes come out, along with the type REG_DWORD. Garbage in, garbage out. The registry doesn't care that what you wrote doesn't many any sense any more than the NTFS file system driver doesn't care that you wrote an invalid XML document to the file config.xml. Its job is just to remember what you wrote and produce it later upon request.

    There is one place where the registry does pay attention to the type, and that's when you use one of the types that involve strings. If you use the RegQueryValueA function to read data which is tagged with one of the string types (such as REG_SZ), then the registry code will read the raw data from its database, and then call WideCharToMultiByte to convert it to ANSI. But that's the extent of its assistance.

    Just as the registry doesn't care whether you really wrote four bytes when you claimed to be writing a REG_DWORD, is also doesn't care whether the various string types actually are of the form they claim to be. If you forget to include the null terminator in your byte count when you write the data to the registry, then the null terminator will not be stored to the registry, and the next person to read from it will not read back a null terminator.

    This simplicity in design pushes the responsibility onto the code that uses the registry. If you read a registry value and the data is tagged with the REG_EXPAND_SZ type, then it's up to you to expand it if that's what you want to do. The REG_EXPAND_SZ value is just part of the secret handshake between the code that wrote the data and the code that is reading it, a secret handshake which is well-understood by convention. After all, if RegQueryValueEx automatically expanded the value, then how could you read the original unexpanded value?

    Windows Vista added a new function RegGetValue which tries to take care of most of the cumbersome parts of reading registry values. You can tell it what data types you are expecting (and it will fail if the data is of an incompatible type), and it coerces the data to match its putative type. For example, it auto-expands REG_EXPAND_SZ data, and if a blob of registry data marked REG_SZ is missing a null terminator, RegGetValue will add one for you. Better late than never.

  • The Old New Thing

    Being lucky is observing what you weren't expecting: An illustration

    • 18 Comments

    I decided to begin searching for a replacement for my current laptop computer since it was by this point literally being held together with electrical tape, and I decided to go against my more common computer replacement policy of "Wait until it breaks, and then panic."

    There was one model I had my eye on, and it was on sale at a local big-box store as one of those doorbuster deals. I didn't feel like waking up at 4am to stand in line for the slim chance of actually snagging one, so I figured I would just wait, and maybe it'll go on sale again after the shopping season. (This is a strategy that isn't available when you use the "Wait until it breaks, and then panic" model.)

    A few weeks later, I happened to be in the shop for an unrelated reason. I naturally stopped by the laptop computer section and, as expected, the model I had in mind was no longer on display. It had presumably sold out. On the other hand, on my way out the store, I saw that very model sitting in the locked cage at the front of the store. The locked cage is one of those loss-prevention techniques, where high-value items are not kept on the shelves. Instead, only a token (such as claim ticket or an empty box) is placed on the shelf, and you bring the token to the customer service desk to exchange it for the actual item.

    If the laptop had sold out, why did they have one in the cage? I asked an employee, who explained, "Oh, yeah, we sold out of these almost immediately, but a few days later, somebody returned one unopened, so that's why we still have one unit up here."

    Is it still for sale?

    "Sure is."

    Not only was it still for sale, it was still for sale at the same price. There was a bit of confusion that followed, since they had to figure out how to sell an item that was not on the shelves and for which there was no token, but everything got straightened out, and I walked out with my new laptop.

  • The Old New Thing

    What is the terminology for describing the various parts of the registry?

    • 23 Comments

    Hives, keys, values, types, and data.

    As I noted some years ago, the file that holds the registry data is called a hive.

    A hive contains a tree of keys.

    Keys contain a list of values.

    Associated with each value is a type and data.

    The terminology is weird and counter-intuitive thanks to the history of the registry. Back in the days before named values, you queried the data associated with (the default value of) a key by calling RegQueryValue, which was a rather natural name since it matches the key/value pattern. But the introduction of named values threw this pattern into disarray. Perhaps a better name could have been chosen for what today are known as values and data, but what's done is done and that's the name we're stuck with.

    I'm sorry.

    "Raymond, you idiot" section:

    "Sure, Raymond, that's the historical reason why the terminology is messed up, but why hasn't anybody fixed it in the meantime?"

    Well, changing terminology at this point would probably create even more confusion. For example, suppose you decide that the terminology should be changed as follows:

    OldNew
    keynode
    subkeysubnode
    valuekey
    typetype
    datavalue

    I agree with you that this terminology would probably be much less confusing, but how do you get there from here? When you update all the documentation to change the terminology, how do you know that you covered everything? Do you grep for the word key everywhere and then decide on a case-by-case whether it should be changed to node? That's probably some hundreds of thousands of hits just inside the MSDN Library. (Even worse with value, type, and data.) And then there are all the comments in source code that are now wrong. And all the magazine articles written prior to the change are now wrong; who's going to go update them? And the existing source code needs to change HKEY to HNODE and RegOpenKey to RegOpenNode. Okay, so maybe you leave the old names around for compatibility, but now you have the problem that RegOpenKey returns a node, not a key, and that you pass a key name to RegQueryValueEx, and what the heck does RegDeleteKey do? Does it delete an old-key or a new-key?

    Bonus chatter: There's also this thing called a class. I have no idea what it's for, so don't ask.

  • The Old New Thing

    The 2009/2010 Seattle Symphony subscription season at a glance

    • 20 Comments

    Every year, I put together a little pocket guide to the Seattle Symphony subscription season for my symphony friends to help them decide which ticket package they want. As before, you might find it helpful, you might not, but either way, you're going to have to suffer through it. Here's the at-a-glance season guide for Gerard Schwarz's 25th and penultimate season as the orchestra's music director.

    Week Program Comments 22 13 10A 10B 7AB 7CD 7EF 7G 4A 4B MS BB MM PC SS
    09/24
    2009
    § Brahms: Variations on a Theme by Haydn
    Mozart: Concerto for Two Pianos #10
    § Golijov: Fantasía sobre La Pasión según San Marcos
    Brahms: Symphony #1
    Awesome
    Awesome
    Nervous
    Excellent
    §
     
    §
     
    *
    §
     
    §
     
    §
     
    §
     
    §
     
    §
     
       
    §
     
    §
     
                 
    10/01
    2009
    Mendelssohn: Violin Concerto
    Mahler: Symphony #5
    Awesome
    Polarizing
      *                          
    10/08
    2009
    Ravel: Alborada del gracioso
    Poulenc: Aubade
    Prokofiev: Piano Concerto #1
    Dvořák: Symphony #8
    Awesome
    Okay
    Good
    Excellent
                       
     
     
     
     
           
    10/22
    2009
    Prokofiev: Symphony #1 "Classical"
    Martinů: Oboe Concerto
    Dvořák: Legends #6, 7, 9
    Haydn: Symphony #88
    Awesome
    Okay
    Excellent
    Excellent
                                 
    10/30
    2009
    Handel: Alexander's Feast Excellent                       §      
    11/01
    2009
    Beethoven: Coriolan Overture
    Beethoven: Piano Concerto #2
    Beethoven: Symphony #6 "Pastoral"
    Excellent
    Excellent
    Awesome
                                 
    11/05
    2009
    § Beethoven: Leonore Overture #1
    § Borodin: Symphony #3
    Tchaikovsky: Violin Concerto
    § R. Strauss: Ein Alpensinphonie
    § Shostakovich: Symphony #15
    Good
    Good
    Awesome
    Good
    Okay
    §
    §
     
    §
    §
    §
    §
     
    §
    §
     
    §
    §
     
    §
    §
     
    §
    §
     
    §
    §
     
    §
    §
     
    §
    §
                 
    11/12
    2009
    § Brahms: Variations on a Theme by Haydn
    § Mendelssohn: Overture Die Heimkehr aus der Fremde
    Spohr: Violin Concerto #8
    § Brahms/Schoenberg: Piano Quartet in g minor
    § Orff: Carmina Burana
    Awesome
    Good
    Good
    Awesome
    Awesome
    §
    §
     
    §
    §
    §
    §
    *
    §
    §
           
    §
    §
     
    §
    §
                   
    11/19
    2009
    Jensen: The Drover
    Mozart Piano Concerto #21
    Tchaikovsky: Symphony #6
    Okay
    Awesome
    Excellent
      *                          
    12/03
    2009
    § Glinka: Russlan and Ludmilla Overture
    Vivaldi: Viola Concerto, RV 417
    § Tchaikovsky: Three Dances from Nutcracker
    Dukas: The Sorcerer's Apprentice
    § Dvořák: Three Slavonic Dances
    § Bizet: Farandole from L'Arlésienne
    § Humperdinck: Prelude to Hansel und Gretel
    § Smetana: The Moldau
    § Rimsky-Korsakov: Polonaise from Christmas Eve
    Tchaikovsky: Swan Lake Suite
    Excellent
    Excellent
    Excellent
    Awesome
    Awesome
    Awesome
    Good
    Excellent

    Excellent
    Awesome
    §
     
    §
     
    §
    §
    §
    §
    §
     
    §
     
    §
     
    §
    §
    §
    §
    §
     
         
    §
     
    §
     
    §
    §
    §
    §
    §
     
         
    §
     
    §
     
    §
    §
    §
    §
    §
     
    §
     
    §
     
    §
    §
     
    §
    §
     
           
    12/30
    2009
    § Bach: Orchestral Suite #3, BWV 1068
    § Brahms: Liebeslieder Waltzes
    Beethoven: Symphony #9
    Excellent
    Excellent
    Awesome
                       
     
     
     
         
    §
    §
     
    01/07
    2010
    Mozart: Symphony #40
    Bruckner: Symphony #4 "Romantic"
    Excellent
    Good
                                 
    01/17
    2010
    Purcell: Indian Queen Suite
    Corelli: Concerto Grosso Op 6 No 4
    Handel: Organ Concerto Op 7 No 1
    Handel: Organ Concerto Op 4 No 5
    Rameau: Les Indes galantes Suite
    Wildcard
    Good
    Good
    Good
    Good
                                 
    01/27
    2010
    Mozart: Symphony #27
    Mozart: Adagio for Violin and Orchestra
    § Mozart: Rondo in C major for Violin and Orchestra
    Beethoven: Romance #2
    Mendelssohn: Symphony #4
    Excellent
    Excellent
    Excellent
    Excellent
    Awesome
                             
     
    §
     
     
       
    02/04
    2010
    Busoni: Turandot Suite
    R. Strauss: Violin Concerto
    Schumann: Symphony #3 "Rhenish"
    Okay
    Okay
    Good
      *                
     
     
     
           
    02/11
    2010
    Barber: Medea's Meditation and Dance of Vengeance
    Barber: Violin Concerto
    § Shostakovich: Symphony #15
    § Brahms/Schoenberg: Piano Quartet in g minor
    Okay
    Okay
    Okay
    Awesome
     
     
    §
    §
           
     
     
    §
    §
                     
    02/26
    2010
    Mozart: Symphony #34
    Mozart: Violin Concerto #5 "Turkish"
    Mozart: Serenade #9 "Posthorn"
    Awesome
    Excellent
    Excellent
                                 
    03/05
    2010
    Rameau: Les Paladins Suite
    Mercadante: Flute Concerto in e minor
    § Handel: Concerto Grosso, Op 3 No 2
    Rossini: String Sonata #1 in G
    Telemann: Suite in C major, TWV 55:C6
    Okay
    Excellent
    Good
    Excellent
    Okay
                         
     
     
    §
     
     
         
    03/11
    2010
    Mendelssohn: Sinfonia #12
    Haydn: Piano Concerto in D, Hob. XVIII
    Mozart: Divertimento, K136
    Mozart: Symphony #29
    Good
    Excellent
    Awesome
    Awesome
                                 
    03/18
    2010
    Brahms: Double Concerto
    Ravel: Daphnis et Chloé
    Excellent
    Excellent
                                 
    03/25
    2010
    § Lutosławski: Symphony #4
    Rachmaninov: Piano Concerto #4
    Sibelius: Symphony #5
    Nervous
    Good
    Excellent
    §
     
     
    §
    *
     
          §
     
     
                  §
     
     
     
    04/01
    2010
    Janáček: The Cunning Little Vixen Suite
    Prokofiev: Piano Concerto #5
    Mussorgsky/Ravel: Pictures at an Exhibition
    Okay
    Okay
    Awesome
      *                          
    04/15
    2010
    Enescu: Romanian Rhapsody
    Beethoven: Piano Concerto #4
    Stravinsky: Pétrouchka (1947)
    Excellent
    Awesome
    Excellent
      *                          
    04/22
    2010
    Haydn: Symphony #93
    Dutilleux: Cello Concerto
    Beethoven: Symphony #5
    Excellent
    Nervous
    Awesome
                       
     
     
     
           
    04/29
    2010
    Sibelius: Pohjola's Daughter
    Rachmaninov: Piano Concerto #2
    Adams: Harmonielehre
    Okay
    Awesome
    Polarizing
      *                          
    05/06
    2010
    Corelli: Concerto Grosso Op 6 No 3
    Tippett: Fantasia Concertante on a Theme of Corelli
    Tallis: When rising from the bed of death
    Elgar: Introduction and Allegro
    Vaughan Williams: Fantasia on a theme by Thomas Tallis
    Good
    Wildcard
    Wildcard
    Good
    Excellent
      *                          
    05/13
    2010
    Wagner: Siegfried Idyll
    Schumann: Piano Concerto
    Beethoven: Symphony #4
    Good
    Excellent
    Excellent
                                 
    06/10
    2010
    Debussy: Prélude à l'Après-midi d'un faune
    Saint-Saëns: Piano Concerto #2
    § Ravel: Pavana pour une infante défunte
    Chausson: Symphony in B-flat major
    Awesome
    Excellent
    Excellent
    Okay
     
     
    §
     
       
     
    §
     
     
     
    §
     
     
     
    §
     
         
     
    §
     
                 
    06/17
    2010
    § Messiaen: Oiseaux exotiques
    § Mozart: Rondo for Piano K382
    § Wagner: Parsifal excerpts
    Mendelssohn: Symphony #2
    Nervous
    Awesome

    Nervous
    Good
    §
    §
    §
     
    §
    §
    §
    *
         
    §
    §
    §
     
         
    §
    §
    §
     
             
    06/24
    2010
    Bernstein: Chichester Psalms
    § Bernstein: Serenade
    § W. Schuman: Symphony #3
    Bernstein: Symphony #2 "The Age of Anxiety"
    Okay
    Okay
    Okay
    Okay
     
    §
    §
     
     
    §
    §
     
     
    §
    §
     
     
    §
    §
     
       
     
    §
    §
     
     
     
    §
    §
     
               
          22 13 10A 10B 7AB 7CD 7EF 7G 4A 4B MS BB MM PC SS
    † Premiere
    MS Musically Speaking
    BB Basically Baroque
    MM Mainly Mozart
    PC Popular Classics
    SS Symphony Specials

    Notes:

    This chart doesn't include "one-off" concert series such as the Visiting Orchestras or Distinguished Artists series.

    The comments column very crudely categorizes the works to assist my less-classically-aware friends. This is, of course, a highly subjective rating system, but I tried to view each piece from the ears of somebody new. Thus, I rated downward pieces that I personally like but which others might not and rated up pieces that I may not find musically satisfying but which nevertheless tend to be crowd-pleasers. These predictions have, of course, proven wrong in the past. For example, my assessments of Bruckner have always been optimistic. (And I haven't learned my lesson, because this year, I'm rating the Bruckner Fourth Symphony as Good, because this time I really think they will like it.)

    Here's what the comments mean. Note that they do not indicate whether the piece is significant in a musicological sense; they're just my guess as to whether my friends are going to like it.

    • Awesome: Guaranteed crowd-pleaser.
    • Excellent: You will definitely like this piece.
    • Good: You will probably like this piece.
    • Okay: You may like this piece.
    • Nervous: I have a bad feeling about this one.
    • Polarizing: Some people will love it; others will hate it.
    • Wildcard: I have no idea what will happen.

    In many cases, I am not familiar with the piece and am basing my evaluation on what I know about the composer (or am just guessing).

    Seattle Symphony notes: Principal Second Violin Elisa Barston had worked under the shadow of heartthrob Joshua Roman, but with Roman's departure last year, she has inherited the mantle of taking the lead in appealing to the "youth audience." She's been given increasingly visible solo performances and even authored an entry on the symphony's blog. I for one am pleased by her more prominent profile. She always seems to be genuinely enjoying herself when I see her performing.

    Update: Minor corrections as noted in comments.

    * Update: Changes were made to the subscription schedule for the UBS Masterworks 13 series after the brochures were printed. (Thanks to Greg for pointing it out.) They have been updated in the chart above. Note that five concerts were deleted but six were added, so the Masterworks 13 concert series actually has 14 concerts.

    § Update: Many changes were made to the subscription schedule in July 2009. They have been updated in the chart above. The concert for the week of October 30, 2009 has been cancelled; ticket-holders will be given tickets for the concert on the week of May 6, 2010.

  • The Old New Thing

    Microspeak: Recommends (noun)

    • 17 Comments

    I have only one citation, but the usage is so egregious to me that one citation is all I need.

    I'm looking for XYZ recommends. My requirements are...

    Why write recommendations when you can shorten it to recommends and sound buzzwordier at the same time!

Page 3 of 4 (32 items) 1234