The Old New Thing
Practical development throughout the evolution of Windows.
Latest posts
Obtaining the parsing name (and pidl) for a random shell object
The parsing name for a shell item is handy, because it lets you regenerate the item later. Actually, the pidl for the shell item is even better, because that is the official way of saving and restoring objects. It's the pidl that gets saved in a shortcut, and since shortcuts can be copied around from machine to machine, pidls must be transportable and forward compatible. (A shortcut file created on Windows XP needs to keep working on all future versions of Windows.) Here's a handy little tool for grabbing the parsing name and pidl for a random shell object. Start with our scratch program, and add in the ...
The annual sporting event involving a football that dare not speak its name and a digression into the sportsmanship of wasting time in nonproductive activity
I always wonder about people who are so protective of the name of their event that they don't even allow people to mention it by name. One of the most notorious examples is the organization which runs a major international gathering of athletes which takes place every four years (or every two years if you consider warm-weather sports and cold-weather sports). Another example is that you aren't allowed to refer to the championship game of the major professional American football league by its actual name without permission. You have to use some alternate phrasing like the big game. I propose that all media organi...
Psychic debugging: Why your IContextMenu::InvokeCommand doesn’t get called even though you returned success from IContextMenu::QueryContextMenu
A customer was having trouble with their IContextMenu implementation. They observed that their IContextMenu::QueryContextMenu method was being called, but when the user selected their menu item, IContextMenu::InvokeCommand was not being called. Given what you know about shell context menus, you can already direct the investigation. I'll let you read up about it first, especially the part about composition, then we can see how much you've learned. Welcome back. (Okay, I know you didn't actually do the reading, but I'm welcoming you back anyway.) Your first theory as to why IC...
The somewhat misguided question of whether MapViewOfFile or WriteProcessMemory is faster
A customer asked, "Which is faster for copying data from one process to another; or ?" This is one of those "Huh?"-type questions, where the customer has solved half of a problem and is looking for help with the other half, the half that makes no sense. First of all, the question is malformed because does not copy any data at all. It takes existing data and maps it into a process. No copy takes place; both processes are seeing the same memory block, and if the memory is modified via one mapping, the change will be visible in other mappings. It's like asking "Which company has better wireless telephone ...
Why doesn’t HeapValidate detect corruption in the managed heap?
A customer had a program that was corrupting the managed heap by p/invoking incorrectly. The problem didn't show up until the next garbage collection pass, at which point the CLR got all freaked-out-like. "According to Knowledge Base article 286470, the tool is supposed to catch heap corruption, but it doesn't catch squat." Depending on your point of view, this is either a case of the customer not understanding what things mean in context or of the KB article author looking at the world through kernel-colored glasses. The tool, pageheap, full pageheap, and the function all operate on heaps, but the sen...
Poisoning your own DNS for fun and profit
When you type a phrase into the Windows Vista Start menu's search box and click Search the Internet, then the Start menu hands the query off to your default Internet search provider. Or at least that's what the Illuminati would have you believe. A customer reported that when they typed a phrase into the Search box and clicked Search the Internet, they got a screenful of advertisements disguised to look like search results. What kind of evil Microsoft shenanigans is this? If you looked carefully at the URL for the bogus search "results", the results were not coming from Windows Live Search. They were c...
Please hold your head perfectly still while you write up that memo
I dreamed that the original Volkswagen Beetle factory was so cramped that the office workers had to move their desks to the factory floor, with heavy equipment swinging around just inches from their faces. To prevent serious injuries, a template passed through every so often to make sure nothing was out of place.
Finding a printer, and then creating a shortcut to that printer
Today's "Little Program" does two things: It looks for a printer in the Printers folder, and then once it finds it, it creates a shortcut to that printer. As is common with "Little Programs", I don't bother with error checking. I'll leave you to do that. Second part first, since it is handy on its own: Creating a shortcut to an arbitrary item in the shell namespace, provided either in the form of an ID list or a shell item. (The ID list is the thing that identifies an item in the shell namespace.) void CreateShortcutToIDList(PCWSTR pszName, PCUIDLIST_ABSOLUTE pidl) { CComPtr<IShellLink> spsl; spsl....
When you have a SAFEARRAY, you need to know what it is a SAFEARRAY *of*
A customer had a problem with SAFEARRAY, or more specifically, with CComSafeArray. CComSafeArray<VARIANT> sa; GetAwesomeArray(&sa); LONG lb = sa.GetLowerBound(); LONG ub = sa.GetUpperBound(); for (LONG i = lb; i <= ub; i++) { CComVariant item = sa.GetAt(i); ... use the item ... } The GetAt method returns a VARIANT&, and when it is copy-constructed into item, the DISP_E_BADVARTYPE exception is raised. On the other hand, if the offending line is changed to CComQIPtr<IAwesome> pAwesome = sa.GetAt(i).punkVal; then the problem goes away. Your initial reaction to this c...