summaryrefslogtreecommitdiffstats
path: root/src/mspdb.cpp
blob: 76ec6d7a807de899f4cefab1e327f94209fae8b8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
// Convert DMD CodeView debug information to PDB files

// Copyright (c) 2009-2010 by Rainer Schuetze, All Rights Reserved

//

// License for redistribution is given by the Artistic License 2.0

// see file LICENSE for further details


#include "mspdb.h"


#include <windows.h>


#pragma comment(lib, "rpcrt4.lib")


HMODULE modMsPdb;
mspdb::fnPDBOpen2W *pPDBOpen2W;

char* mspdb80_dll = "mspdb80.dll";
char* mspdb100_dll = "mspdb100.dll";

bool mspdb::DBI::isVS10 = false;

bool getInstallDir(const char* version, char* installDir, DWORD size)
{
	char key[260] = "SOFTWARE\\Microsoft\\";
	strcat(key, version);

	HKEY hkey;
	if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, key, 0, KEY_QUERY_VALUE, &hkey) != ERROR_SUCCESS)
		return false;
	
	bool rc = RegQueryValueExA(hkey, "InstallDir", 0, 0, (LPBYTE)installDir, &size) == ERROR_SUCCESS;
	RegCloseKey(hkey);
	return rc;
}

bool tryLoadMsPdb(const char* version, const char* mspdb)
{
	char installDir[260];
	if (!getInstallDir(version, installDir, sizeof(installDir)))
		return false;
	char* p = installDir + strlen(installDir);
	if (p[-1] != '\\' && p[-1] != '/')
		*p++ = '\\';
	strcpy(p, mspdb);

	modMsPdb = LoadLibraryA(installDir);
	return modMsPdb != 0;
}

bool initMsPdb()
{
	if (!modMsPdb)
		modMsPdb = LoadLibraryA(mspdb80_dll);

	if (!modMsPdb)
		tryLoadMsPdb("VisualStudio\\9.0", mspdb80_dll);
	if (!modMsPdb)
		tryLoadMsPdb("VisualStudio\\8.0", mspdb80_dll);
	if (!modMsPdb)
		tryLoadMsPdb("VCExpress\\9.0", mspdb80_dll);
	if (!modMsPdb)
		tryLoadMsPdb("VCExpress\\8.0", mspdb80_dll);

#if 1

	if (!modMsPdb)
	{
		modMsPdb = LoadLibraryA(mspdb100_dll);
		if (!modMsPdb)
			tryLoadMsPdb("VisualStudio\\10.0", mspdb100_dll);
		if (!modMsPdb)
			tryLoadMsPdb("VCExpress\\10.0", mspdb100_dll);
		if (modMsPdb)
			mspdb::DBI::isVS10 = true;
	}
#endif


	if (!modMsPdb)
		return false;

	if (!pPDBOpen2W)
		pPDBOpen2W = (mspdb::fnPDBOpen2W*) GetProcAddress(modMsPdb, "PDBOpen2W");
	if (!pPDBOpen2W)
		return false;

	return true;
}

bool exitMsPdb()
{
	pPDBOpen2W = 0;
	if (modMsPdb)
		FreeLibrary(modMsPdb);
	modMsPdb = 0;
	return true;
}

mspdb::PDB* CreatePDB(wchar_t* pdbname)
{
	if (!initMsPdb ())
		return 0;

	mspdb::PDB* pdb = 0;
	long data[194] = { 193, 0 };
	wchar_t ext[256] = L".exe";
	if (!(*pPDBOpen2W) (pdbname, "wf", data, ext, 0x400, &pdb))
		return 0;

	return pdb;
}