Monday, December 04, 2006

Less MSIĆ©rables

Yeah, I thought it was a clever name too ... :) This is a little but very useful utility, with a great feature that allows to peek inside an MSI package and extract files out of it. Now, I found it useful at times when I needed to grab individual files out of an MSI without the need to install the whole product.

Get it here: http://blogs.pingpoet.com/overflow/archive/2005/11/16/14995.aspx

VS2005 debugger - unable to resolve a symbol

VS2005 is a lot better then its predecessor in guessing what exactly do you mean when typing an expression into Watch window (or the cool Immediate view - try it if you havent used it before!). It will correctly evaluate all the variable references, and will even let you execute methods and see their results (but watch out for side-effects, if method modifies some data).

Occasionally, however, it will complain that it cannot find the symbol you are referring to. This can be rather frustrating, but there are actually a few things to try to resolve this successfully:

1) If you are using namespaces, type the fully qualified name, starting with the top namespace, e.g. MyNamespace::SubNamespace::blah. Sometimes VS2005 gets confused with the "using namespace" directives - but to be fair, most of the time its pretty good at it. This works 99% of the time.

2) Some constructs actually do not have proper C++ syntax to get to them, like local struct/class definitions. Last resort is to get a mangled name from the map file, and use that - VS2005 understands it as well.

3) Finally, be creative - there are usually several ways to get to a certain variable or method. If all fails, you can quickly write a dummy method which you can call from debugger, but this is rarely necessary.

Vista UAC privelege elevation

No doubt everyone has already seen UAC in action, and the privilege elevation prompt - the one that grays out the whole screen and asks whether user wants to continue with the operation that requested such elevation.

Well, just be aware that legacy means for launching external processes within your application no longer work (well they do work, if new process does not require higher privileges). For example, CreateProcess will return a new error code ERROR_ELEVATION_REQUIRED, if the external process application is trying to launch requires higher privileges.

According to Microsoft, we must now use ShellExecuteEx (or ShellExecute), with lpVerb = "open". This will correctly prompt user with the new Vista elevation UI.

Here's a link to Vista compatibility team blog talking about this: http://blogs.msdn.com/vistacompatteam/archive/2006/10/02/Elevation-and-process-creation-APIs.aspx

Note:My comment about using lpVerb = "open" relates to the fact that "open" is the default verb and is normally used to launch .exe files. According to the blog, you can also use a "runas" verb, to force privilege elevation regardless of the .exe manifest, but I personally wouldn't do that unless it was absolutely necessary - we should let target process determine (via manifest) whether it needs special privileges or not.

C++ Name Mangling/Demangling

Before you say anything, yes I know, mangling is compiler specific and can change with each compiler version. But for purposes of debugging it is sometimes useful to decipher function signature from linker's outptut.

We already know that DBGHELP.DLL provides a function UnDecorateSymbolName. Just came across this page on the net, with links to various mangling/demangling resources and a comprehensive reverse engineering summary of Microsoft C++ compiler name mangling.

Hope this is useful to someone.

Swapping values without temporary variable

Just ran across it while browsing for something else, and I think it's pretty cool... in a useless kind of way! (Also I think I saw this once before, but can't remember when...) template <class T> inline void swap (T& x, T& y) { x = x ^ y; y = x ^ y; x = x ^ y; } Of course, it will only work with primitive types, for which operator^ is well defined!