Skip to content

Reducing OPTLINK's Message Box of Death

Vladimir Panteleev edited this page Oct 15, 2015 · 3 revisions

The following D program will launch another command and return 0 if it encountered and closed an OPTLINK MBoD, and 1 otherwise. Note that you need to pass the entire child command as the first argument.

Caveat: this program will also detect and close OPTLINK message boxes not caused by the reduction process, which will result in a false positive and lead DustMite astray. If you plan to do any D development on the same machine during the reduction process, consider running the reduction in a separate Windows desktop (e.g. using SysInternals Desktops).

import std.c.windows.windows;
import core.thread;
import std.process;

extern(Windows)
{
	HWND FindWindowA(LPCSTR, LPCSTR);
	HWND FindWindowExA(HWND, HWND, LPCSTR, LPCSTR);
}

enum title = "Unexpected OPTLINK Termination at EIP=0042785B";

int main(string[] args)
{
	bool optlinkCrashed = false;
	bool done = false;
	
	auto thread = new Thread({
		while (!done)
		{
			auto h = FindWindowA("#32770", title);
			while (h)
			{
				auto h2 = FindWindowExA(h, null, "Button", "OK");
				if (h2)
				{
					optlinkCrashed = true;
					SendMessageA(h2, BM_CLICK, 0, 0);
				}
				h = FindWindowExA(null, h, "#32770", title);
			}
			Sleep(1);
		}
	});

	thread.start();
	spawnProcess(args[1..$]).wait();
	done = true;
	return optlinkCrashed ? 0 : 1;
}