M-A's

technology blog

Sunday, 13 January 2008

The undocumented frustration

I had some frustration when updating WINVER and _WIN32_WINNT from 0x501 to 0600 (okay we're late but better be late than sorry). I came across two things I'd like to document.

---

First I need to reference Nicolas Sylvain post about GENERIC_MAPPING changes to give some background. Then all I have to say is that there are other access masks that changed, but explicitly. The ones we hit were PROCESS_ALL_ACCESS and THREAD_ALL_ACCESS. They have a new bitmask. Here are the definition:
#if (NTDDI_VERSION >= NTDDI_LONGHORN)
#define PROCESS_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xFFFF)
#else
#define PROCESS_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xFFF)
#endif

#if (NTDDI_VERSION >= NTDDI_LONGHORN)
#define THREAD_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xFFFF)
#else
#define THREAD_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x3FF)
#endif
The nice thing is that the new bitmasks are refused by Windows XP. So you need to use different flags depending on the OS, which you need to define yourself. Not great! The easiest work around is to use MAXIMUM_ALLOWED but this is not always what you want.

---

The second one is nasty. The NONCLIENTMETRICS structure's size silently changed between XP and Vista. Here is the definition:
typedef struct tagNONCLIENTMETRICSW
{
UINT cbSize;
int iBorderWidth;
int iScrollWidth;
int iScrollHeight;
int iCaptionWidth;
int iCaptionHeight;
LOGFONTW lfCaptionFont;
int iSmCaptionWidth;
int iSmCaptionHeight;
LOGFONTW lfSmCaptionFont;
int iMenuWidth;
int iMenuHeight;
LOGFONTW lfMenuFont;
LOGFONTW lfStatusFont;
LOGFONTW lfMessageFont;
#if(WINVER >= 0x0600)
int iPaddedBorderWidth;
#endif /* WINVER >= 0x0600 */
} NONCLIENTMETRICSW, *PNONCLIENTMETRICSW, FAR* LPNONCLIENTMETRICSW;

WTL 8.0 has a workaround for this
but let's face it, it looks more as a hack than anything else. It looks like the guy at Microsoft that changed the structure should have wrote a unit test...
Anything that is written that looks like this is bound to fail:
NONCLIENTMETRICS cm = { sizeof(NONCLIENTMETRICS) };
SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &cm, 0);
I don't blame Microsoft for doing small errors like this. Managing an operating system is a tremendous task and we all know errors can slip through. The real problem I see is that even one year after the release, it's still not documented. Let's hope the Vista SP1 SDK will define PROCESS_ALL_ACCESS_XP, THREAD_ALL_ACCESS_XP and NONCLIENTMETRICS_v1.

Friday, 4 January 2008

Risk of using embedded MSHTML

There is always some risks involved in using third parties in UI.



This one is cute: It is the "My Web Sites on MSN" wizard that is hit by the IE ActiveX security bar. But this is really nice inside a dialog box, knowing that it is pure Microsoft code.

It is funny because it gives the feeling that it is less secure while in reality it doesn't change anything since it is simply a side-effect of using MSHTML for rendering.

Tuesday, 18 December 2007

Software Update Rant

Dear "software updater" software programmer,
  • Please don't "update" software that I haven't installed yet.
  • Please don't reinstall quicklaunch icons that I deliberately removed.
  • Please stop asking me to update, simply update. I don't care if I have the "Latest and greatest version", I just want to have my software work. Don't tell me to visit a web site to update it, I won't. (Actually I do but shhh!)
  • Please stop installing "[Insert name here] Speed Launcher", "[Insert name here] Task" or "[insert name here]UpdateSched" autoloading crap in my startup menu or even worst, in the registry; to be sure to increase the commit charge (total memory usage) of my system. A program can easily look at updating itself when it is actually started. If it is never started, I don't mind it to be never updated.
  • Please don't write updater that fails. (It happens on my system, no names here) I'm not even talking about bad software, simply bad updaters. If you're too dumb replace some files, get another job.
  • No, I won't reboot my system to install a media player. The next time I'll reboot will probably be because of a corporate enforced software BSOD'ing my system.
I know doing an installer is hard. I know the amount of work is high. Then, why don't you just do less during updates?


Here's a few examples:

#1 Apple Software "Update"

They should have called it "Apple installer". Yes I have Safari Beta and QuickTime installed. No I don't have iTunes nor I want that "update" installed on my computer.

Apple folks, please, look to see if the software is actually installed before "updating" it.

#2
Also, Apple folks, don't add back the quicklaunch icons on updates. If I removed them, I probably don't want them back. This also applies to Acrobat Reader updates and Office 2003 service packs.

#3
Auto start crap. Sun's Java and QuickTime are notorious to add their entries back in the registry on each update. Stop doing that!

Monday, 10 December 2007

Detect if building with Visual Studio 2005 RTM or SP1

#include "windows.h"
extern char VisualStudio2005ServicePack1Detection[10];
C_ASSERT(sizeof(&VisualStudio2005ServicePack1Detection) == 4);

On VS2005 RTM, sizeof(&VisualStudio2005ServicePack1Detection) == 10.

Wednesday, 5 September 2007

DTE.Debugger is not reentrant

Disclaimer: blogspot is really bad at including code.
I tried to make an auto-debug-child processes in VB.NET in VS2005.

First define the breakpoint,
Function SetBreakPoint(ByVal Symbol As String, ByVal Offset As Integer) As EnvDTE.Breakpoints
Dim x As String = DTE.Debugger.GetExpression(Symbol).Value
' Poor's man calculation in VB...
Dim y As String = "0x" + Hex(CULng("&H" + x.Substring(2)) + Offset)
SetBreakPoint = DTE.Debugger.Breakpoints.Add(y)
End Function

Sub SetAutoDebugChildren()
' Set a breakpoint on function return.
Const offset As Integer = 44
SetBreakPoint("{,,kernel32.dll}_CreateProcessA@40", offset)
SetBreakPoint("{,,kernel32.dll}_CreateProcessW@40", offset)
End Sub

Ok, but I haven't found any programmatic way to set the "When Hit..." flag. So I added them manually after. So right click on the breakpoint, "When Hit..." run a macro and continue execution.

I set the macro to something like this:
Sub AttachToProcesses(ByVal process_name As String)
For Each process As EnvDTE.Process In DTE.Debugger.LocalProcesses
If (process.Name.IndexOf(process_name) <> -1) Then
process.Attach()
End If
Next
End Sub

Sub AttachMyExe()
AttachToProcesses("my.exe")
End Sub

So everything seems nice. The problem is that at the process.Attach() line, I was granted with a nice message box:
---------------------------
Error
---------------------------
A macro called a debugger action which is not allowed while responding to an event or while being run because a breakpoint was hit.
---------------------------
OK
---------------------------

Humm OK. If anyone has a solution beside using WinDbg, please comment.

Tuesday, 4 September 2007

How to wipe free space (note to myself)

cipher /w:c

That works on XP and Vista.

Tuesday, 7 August 2007

Save the earth, kill your AV

Can you imagine how much power would be saved if everyone would uninstall their AV? My personal computers have been running AV-virgin for more than a decade now without an itch. What a relief!