• The Old New Thing

    I wouldn't be surprised if O. J. Simpson wrote a new book

    • 9 Comments

    You know, it's gotten to the point where I wouldn't be surprised if O. J. Simpson wrote a new book titled If I Were the Father of Anna Nicole Smith's Baby.

    Just saying.

  • The Old New Thing

    The format of accelerator table resources

    • 9 Comments

    Continuing in the extremely sporadic series on the format of resources, today we'll take a look at accelerator tables. This topic is so simple, I'll cover both 16-bit and 32-bit resources on the same day!

    In 16-bit Windows, the format of an accelerator table resource was simply an array of ACCEL structures.

    typedef struct tagACCEL {
        BYTE fVirt;
        BYTE bPadding; /* making the padding explicit */
        WORD key;
        WORD cmd;
    } ACCEL, *LPACCEL;
    

    This array is the same array you would pass to the CreateAcceleratorTable, with one important difference: The fVirt of the last entry in the accelerator resource has its high bit set to indicate that it is the end of the table.

    The format of 32-bit accelerator table resources is nearly identical to its 16-bit counterpart. The only difference is the addition of an additional word of padding to bring the size of the structure up to a multiple of four bytes.

    typedef struct tagACCEL_RESOURCE {
        BYTE fVirt;
        BYTE bPadding; /* making the padding explicit */
        WORD key;
        WORD cmd;
        WORD wPadding; /* making the padding explicit */
    } ACCEL_RESOURCE;
    

    Once again, the last entry is marked by setting the high bit of the fVirt member. The extra word of padding adds a second obstacle to taking the resource data and passing it to the CreateAcceleratorTable function to create the accelerator table manually. Not only do you have to strip off the high bit of the fVirt, you also have to convert the table to an array of ACCEL structures and pass the converted table to the CreateAcceleratorTable function.

    That's all there is to the format of accelerator table resources. I told you it was pretty simple.

  • The Old New Thing

    What is the underlying object behind a COM interface pointer?

    • 9 Comments

    When you're debugging, you might have a pointer to a COM interface and want to know what the underlying object is. Now, sometimes this trick won't work because the interface pointer actually points to a stub or proxy, but in the case where no marshalling is involved, it works great. (This technique also works for many C++ compilers for any object that has virtual methods and therefore a vtable.)

    Recall that the layout of a COM object requires that the pointer to a COM interface point to the object's vtable, and it's the vtable that is the key.

    0:000> dv
                pstm = 0x000c7568
    0:000> dt psf
    Local var @ 0x7cc2c Type IStream*
    0x000c7568
       +0x000 __VFN_table : 0x1c9c8e84
    

    Okay, so far all we know is that our IStream * lives at 0x000c7568 and its vtable is 0x1c9c8e84. Whose stream implementation is it?

    0:000> ln 0x1c9c8e84
    (1c9c8e84)   ABC!CAlphaStream::`vftable'
    

    Aha, it's a CAlphaStream from ABC.DLL. Let's take a look at it:

    0:000> dt ABC!CAlphaStream 0x000c7568
       +0x000 __VFN_table : 0x1c9c8e84 // our vtable
       +0x004 m_cRef           : 480022128
       +0x008 lpVtbl           : 0x1c9d2d30
       +0x00c lpVtbl           : 0x00000014
       +0x010 m_pszName        : 0x000c7844 "??????????"
       +0x014 m_dwFlags        : 0x3b8
       +0x018 m_pBuffer        : 0x00000005
       +0x01c m_cbBuffer       : 705235565
       +0x020 m_cbPos          : 2031674
    

    "Hey, how did you get the debugger to dump m_pszName as a string?" If you issue the .enable_unicode 1 command, then the debugger will treat pointers to unsigned short as if they were pointers to Unicode strings. (By default, only pointers to wchar_t are treated as pointers to Unicode strings.)

    Okay, back to the structure dump. It doesn't look right at all. The reference count is some absurd value, the vtable at offset 0x00c is a bogus pointer, the name in m_pszName is garbage, pretty much every field aside from the initial vtable and the vtable at offset 0x008 is blatantly wrong.

    What happened? Well, clearly we were given a "q" pointer; i.e., a pointer to one of the vtables other than the first one. We have to adjust the pointer so it points to the start of the object instead of the middle.

    How do we do this adjustment? There's the methodical way and the quick-and-dirty way.

    The methodical way is to use the adjustor thunks to tell you how much the pointer needs to be adjusted in order to move from a secondary vtable to the primary one. (This assumes that the primary IUnknown implementation is the first base class. This is not guaranteed to be the case but it usually is.)

    0:000> dps 1c9c8e84 l1
    1c9c8e84  1c9eb08e ABC![thunk]:CAlphaStream::QueryInterface`adjustor{8}'
    

    Aha, this adjustors adjust by eight bytes, so we just need to subtract eight from our pointer to get the object's starting address.

    0:000> dt ABC!CAlphaStream 0x000c7560-8
       +0x000 __VFN_table : 0x1c9c8ee8
       +0x004 m_cRef           : 2
       +0x008 lpVtbl           : 0x1c9c8e84
       +0x00c lpVtbl           : 0x1c9c8e70
       +0x010 m_pszName        : 0x1c9d2d30 "Scramble"
       +0x014 m_dwFlags        : 0x14
       +0x018 m_pBuffer        : 0x000c7844
       +0x01c m_cbBuffer       : 952
       +0x020 m_cbPos          : 5
    

    Ah, that looks much nicer. Notice that the reference count is a more reasonable value of two, the name pointer looks good, the buffer size and position appear to be much more realistic.

    Now, I don't bother with the whole adjustor thunk thing. Instead I rely on the principle of "Assume it's mostly correct": Assume that the object is not corrupted and just adjust the pointer by eye until the fields line up. Let's take another look at the original (bad) dump:

    0:000> dt ABC!CAlphaStream 0x000c7568
       +0x000 __VFN_table : 0x1c9c8e84
       +0x004 m_cRef           : 480022128
       +0x008 lpVtbl           : 0x1c9d2d30
       +0x00c lpVtbl           : 0x00000014
       +0x010 m_pszName        : 0x000c7844 "??????????"
       +0x014 m_dwFlags        : 0x3b8
       +0x018 m_pBuffer        : 0x00000005
       +0x01c m_cbBuffer       : 705235565
       +0x020 m_cbPos          : 2031674
    

    This obviously doesn't smell right, but what do we have to do to get things to line up? Well, we know that the vtable we have must go into one of the other two vtable slots, either the one at offset 0x008 or the one at offset 0x00c. If we moved it to offset 0x00c, then that would move the 0x00000014 currently at offset 0x00c down twelve bytes, placing it at offset 0x018, right at m_pBuffer. But obviously 0x00000014 is not a valid buffer pointer, so 0x00c can't be the correct adjustment. On the other hand, if we put our vtable at offset 0x008, then that would move 0x000c7844 into the m_pBuffer position, which is not too unreasonable. Therefore, I would guess that the adjustor is eight, yielding the same structure dump that we got by dumping the vtable to see the adjustor.

    In real life, I tend to pay attention to the vtables, the reference count, and any string members because it's usually pretty easy to see whether you got them right. (Vtables reside in code. Reference counts tend to be small integers. Strings are, well, strings.)

  • The Old New Thing

    Male perceptions of body image in Taiwan

    • 9 Comments

    A few years ago, researchers started with "muscle dysmorphia" and body-image perceptions in the United States and Europe and wondered whether the same problems afflict Taiwanese men. Listen for the results. But don't be confused by the chicken meat (肌肉).

    Sean Cole interviews Taiwanese pop star A-Mèi for her opinion. I remember a story in CNN some years ago on the singer, and it referred to her as "Ms. Mei".

    Um, that's not right.

    In Taiwanese, the "A-" prefix is used to form nicknames; compare English which appends "-y" for the same purpose. In English, "Mike" becomes "Mikey"; in Taiwanese, "Huì-Mèi" becomes "A-Mèi". If you want to refer to her formally, it's "Ms. Chang". Using "Ms. Mei" would be like referring to the musician Eddie Van Halen as "Mr. Ed".

  • The Old New Thing

    Oh no, I have an obstructed view of Joshua Roman!

    • 9 Comments

    This past weekend, a group of us attended a subscription concert performance of Beethoven's Missa Solemnis at Benaroya Hall. We collectively hold a block of seats, and it's a mix of regulars and rotating guests. Our seats are close to the stage, made even closer by the hall reconfiguration to accommodate the choir and soloists; we were effectively in the first row. (And if you were wondering what those covered holes in the floor are up near the stage, they're where the supports go for the stage extension.)

    As we filed into our seats, one of our guests for this particular concert exclaimed in mock consternation, "Oh no, I have an obstructed view of Joshua Roman!" I switched seats, giving our guest a slightly better potential view of the young cellist. In exchange, I got a much better view of Elisa Barston, the new principal second who probably would have gotten most of the ooh-aah attention if it weren't for the even younger new cellist. (Normally, I only get to see the left-hand side of her body, since the Seattle Symphony splits the violins left and right, more in keeping with 19th-century practice. It was somewhat strange seeing her from the other side when she led a string quartet and therefore sat on the left-hand side.)

    Ultimately, the seat swap didn't help much with the Joshua Roman viewing opportunities, because the conductor and soloists occupied most of the field of view. Afterwards, we jokingly discussed various ways we could express our Joshua Roman groupie-dom, ranging from giant "We Love You Joshua Roman" placards to floppy-haired wigs. At least I hope they were joking.

  • The Old New Thing

    The three things you need to know about tsunamis

    • 9 Comments

    One of my friends is involved with Science on Tap, a free, informal monthly get-together in the Seattle area covering science topics for the general public. (Recent coverage in the Seattle-PI.) The topic for July 30th is "The three things you need to know about tsunamis", and a title like that pretty much sells itself.

  • The Old New Thing

    If you read any book about traditional weddings in Russian history, there must be a fight

    • 9 Comments

    You can buy a fake vacation for $500 or shell out $300 to $400 for a fake brawl at your wedding.

    "If you read any book about traditional weddings in Russian history, there must be a fight," said Alexander Yermilov, 22, who recently made a living at it.

    If you're looking for counterfeits, fakes, and forgeries, Moscow's your place. Assuming you can spot them.

    Even Putin's doctoral dissertation, researchers from the Brookings Institution revealed this year, contained major sections lifted from a text published by academics from the University of Pittsburgh.

    The revelations barely were repeated in the Moscow press, not because they were scandalous, but because they weren't—government officials routinely rely on fake dissertations patched together by underlings.

  • The Old New Thing

    Creative armed robbery defense: Political asylum

    • 9 Comments

    Step 1: Rob bank.

    Step 2: Flee the country.

    Step 3: Claim political asylum because the robbery was a form of political protest.

    It's creative, I have to grant you that. The theory is that Canadian law prohibits extradition for political crimes. Though it's a strange defense to say "If I did it, it was politically motivated." Isn't the whole point of a political protest to openly admit to the crime and invite the authorities to arrest you? If you deny doing it, then it isn't much of a political statement, now, is it?

    I mean, you don't hear on the news, "A bomb exploded in ABC today. The radical group DEF said that if they were responsible, it was in retaliation for GHI."

    (For more background, you can read a "the story so far" story from the Seattle Times.) In March, the others accused of being involved in the heist pled guilty to armed robbery, which definitely weakens the "We did it as a form of political protest" argument.

    And fleeing from house arrest while awaiting an extradition hearing certainly doesn't help either.

    Neither does running a stock scam.

  • The Old New Thing

    What do bitwise operations mean for colors?

    • 9 Comments

    Someday, you're going to pass a raster operation to the BitBlt function that entails bit manipulation. Something like SRCAND perhaps, or possibly the dreaded SRCINVERT. These bitwise operations make perfect sense for monochrome bitmaps, since those are one bit per pixel anyway. But what does it mean for color bitmaps? What do you get when you "and" together forest green (#228B22) and hot pink (#FF69B4)?

    The bitwise operations are performed in the pixel space of the destination. If the destination is a non-palettized bitmap format (higher than 8bpp), then the pixel values are red, blue and green components packed together (in various ways depending on the format). Those values are "and"ed together as integers to produce the result. For example, in a 565-format bitmap, the color forest green is represented as the value 0x2464 (0y00100`100011`00100) and hot pink is 0xFB56 (0y11111`011010`10110). The bitwise "and" of these two values is 0x2044, which is a very dark purple.

    With palettized bitmaps, the results are much less predictable since the values in the bitmap are not colors but color indices. For example, if a pixel has the value 6, that means that the color of the pixel is determined by the entry in slot 6 of the bitmap's color table, and that color could be anything. There is no rule that even requires that color 0 be black and that the highest available color be white, though most bitmaps adhere to this by convention.

    On an 8bpp bitmap, then, the question of what you get when you "and" together forest green and hot pink is underdetermined. If the color table for example happened to put forest green in slot 6 and hot pink in slot 18, the result of the "and" operation would be 6 & 18 = 2, and the result pixel would therefore be whatever color was in slot 2 of the bitmap's color table.

    What does this mean for you, adventuresome blitter?

    If you're going to use raster operations that involve bitwise operations, one of the pixels involved in the operation should be black or white (zero or all-bits-set) in order to obtain predictable results. You can then use identities like "x and black = black" and "x xor black = x" to predict the result, assuming the bitmap follows the convention for black and white noted above. But if you're going to be xor'ing with forest green, then the results could be anything.

  • The Old New Thing

    How do I prevent multi-line edit controls from eating the Enter key?

    • 9 Comments

    You might decide to put a multi-line edit control in a dialog box, not because you want the user to input multi-line data, but because it's a convenient way to display multi-line text. When you do that, you may notice that the Enter key does not invoke the default dialog button, as you might normally expect. That's because the multi-line edit control tells the dialog manager that it wants the Enter key. So how do you tell the multi-line edit control to stop doing that and let the Enter key do its normal thing?

    You already know the answer to this. As we saw quite some time ago, a control responds to the WM_GETDLGCODE message to influence the behavior of the dialog manager. In this case, the edit control is returning DLGC_WANTMESSAGE in response to the keyboard Enter key. What you want to do is prevent this from happening. You want to change the value that the edit control returns to the WM_GETDLGCODE.

    Since there is no existing window style to specify this behavior, you're left with subclassing the control and removing the DLGC_WANTMESSAGE code if the message is the Enter key.

Page 380 of 457 (4,568 items) «378379380381382»