If you don't already have the Windows 2003 Server Driver Development Kit, download and install it. You will need the XP and Windows 2003 x64 libraries. (I believe this is the current link but I'm not sure: http://download.microsoft.com/download/ ... sa_ddk.iso) I'll assume you installed it to C:\WinDDK\3790.1830.
Warning
Do not download a newer version! If you do, you'll introduce dependencies on newer versions of msvcrt.dll that won't work on Windows XP.
1. Open the project in Visual Studio 2010. Go to the Project Settings for the Process Hacker project, and then select "Release" configuration on All Platforms. (I've personally found it easier to leave the debug build untouched, but I think you can also change that one if you want to, provided that you also make some other changes on your own.)
* Under C/C++ Code Generation, change the Runtime Library to the default, then press Apply. (It should switch to Multithreaded DLL.)
* Change the Buffer Security Check to No. (this may not be required; I don't remember.)
2. Under C/C++ Command Line (Additional Options), type in: /QIfist
3. Switch the platform to Win32:
* Under VC++ Directories, add these directories to the Library Directories path, before everything else:
C:\WinDDK\3790.1830\lib\crt\i386
C:\WinDDK\3790.1830\lib\wxp\i386
* Under Linker->Input, add BufferOverflow.lib as a dependency.
4. Switch the platform to x64:
* Under VC++ Directories, add these directories to the Library Directories path, before everything else:
C:\WinDDK\3790.1830\lib\crt\amd64
C:\WinDDK\3790.1830\lib\wnet\amd64
5. Press OK; you're done with the configuration. Now time to modify the source files.

6. Inside the source files, do a Find/Replace for the function names below, and replace the patterns by hand. There should be somewhere between 3 to 10 of each, so replacing them by hand shouldn't be hard (regular expressions might break them, but you could try):
Code: Select all
wcscpy_s(<dest>, <len>, <source>) ----> wcsncpy(<dest>, <source>, <len>)
wcsncpy_s(<dest>, <len>, <source>, _TRUNCATE) ----> wcsncpy(<dest>, <source>, <len>)
7. Change all instances of wcstok_s to remove the context parameter. So, wcstok_s(line, delims, &context) should become wcstok(line, delims), wcstok_s(NULL, delims, &context) should become wcstok(NULL, delims), etc. (This is risky if the code turns out to depend on it! I haven't verified it well!)
8. Find the lines saying:
Code: Select all
if (PhpFormatDecimalSeparator != '.')
PhpFormatUserLocale = _create_locale(LC_ALL, "");
9. Add these to support.c (this should be a non-breaking change):
Code: Select all
const IID IID_IFileDialog = { 0x42F85136, 0xDB7E, 0x439C, 0x85, 0xF1, 0xE4, 0x07, 0x5D, 0x13, 0x5F, 0xC8 };
const IID CLSID_FileSaveDialog = { 0xC0B4E2F3, 0xBA21, 0x4773, 0x8D, 0xBA, 0x33, 0x5E, 0xC9, 0x46, 0xEB, 0x8B };
const IID CLSID_FileOpenDialog = { 0xDC1C5A9C, 0xE88A, 0x4dde, 0xA5, 0xA1, 0x60, 0xF8, 0x2A, 0x20, 0xAE, 0xF7 };

Code: Select all
static errno_t __cdecl _cfltcvt_l(double *arg, char *buffer, size_t sizeInBytes, int format, int precision, int caps, _locale_t plocinfo)
{ sprintf(buffer, "%.*f", precision, *arg); return 0; }
static void __cdecl _cropzeros_l(char *buf, _locale_t locale)
{
// This is REALLY ugly and I don't even know if it works for international users, but I tried. You might have Unicode problems and such, so be careful...
char zero[64];
char* pZero;
int l = sprintf(zero, "%0.1f", 0);
pZero = &zero[1];
l--;
if (l > 0)
{
size_t end = strlen(buf);
while (end > l && buf[end - 1] == pZero[l - 1] && strncmp(&buf[end - l], pZero, l) != 0) { end--; }
if (end == 0 || strncmp(&buf[end - l], pZero, l) == 0) { buf[end - l] = '\0'; }
}
}
Code: Select all
typedef int (__cdecl * Comparator)(void*, const void *, const void *);
static Comparator staticComparator;
static void* staticComparatorContext;
int __cdecl staticComparatorCaller(const void * a, const void * b)
{ return staticComparator(staticComparatorContext, a, b); }
int myqsort_s(void* base, size_t count, size_t elemSize, Comparator comparator, void* context)
{
staticComparator = comparator;
staticComparatorContext = context;
qsort(base, count, elemSize, &staticComparatorCaller);
return 0; //I return a value because I was trying to avoid declaring this function (since the default return type is int), but you can make this void too
}
Code: Select all
typedef int (__cdecl * Comparator)(void*, const void *, const void *);
int myqsort_s(void* base, size_t count, size_t elemSize, Comparator comparator, void* context);
Now compile in Release mode and hope for the best.
