Howdy,

I've been trying to write an ISAPI compatible server (keep reading even if you don't know what ISAPI is, its probably something totally unrelated). Heres what I've managed to get so far:
Code:
#include <iostream>
#include <windows.h>
#include <httpext.h>
#include <httpfilt.h>
#include <header.h>
#include <string>

using namespace std;


HINSTANCE gMyDLL = NULL;
typedef DWORD (WINAPI *HTTPEXTENSIONPROC)( EXTENSION_CONTROL_BLOCK *pECB );
HTTPEXTENSIONPROC pHttpExtensionProc;
typedef DWORD (WINAPI *GETEXTENSIONVERSION)( HSE_VERSION_INFO* hse );
GETEXTENSIONVERSION pGetExtensionVersion;

BOOL WINAPI pReadClient(HCONN      ConnID,
                                  LPVOID     lpvBuffer,
                                  LPDWORD    lpdwSize)
{
	cout << "Readclient()" << endl;
	cout << "ReadClient() called with " /*<<  (char *)lpvBuffer*/ << endl;
	return true;
}

BOOL WINAPI pWriteClient(HCONN      ConnID,
                                   LPVOID     Buffer,
                                   LPDWORD    lpdwBytes,
                                   DWORD      dwReserved )
{
	cout << "WriteClient() called with: " << (char *)Buffer<< endl;
	return true;
}

BOOL WINAPI pServerSupportFunction(HCONN      hConn,
                                           DWORD      dwHSERequest,
                                           LPVOID     lpvBuffer,
                                           LPDWORD    lpdwSize,
                                           LPDWORD    lpdwDataType)
{
	cout << "ServerSupportFunction() called" << endl;
	switch(dwHSERequest) 
	{
		case SF_STATUS_REQ_READ_NEXT: cout << "SF_STATUS_REQ_READ_NEXT";
		break;
		case SF_STATUS_REQ_ERROR: cout << "SF_STATUS_REQ_ERROR";
		break;
		case SF_STATUS_REQ_HANDLED_NOTIFICATION: cout << "SF_STATUS_REQ_HANDLED_NOTIFICATION";
		break;
		case SF_STATUS_REQ_NEXT_NOTIFICATION: cout << "SF_STATUS_REQ_NEXT_NOTIFICATION";
		break;
		case SF_STATUS_REQ_FINISHED_KEEP_CONN: cout << "SF_STATUS_REQ_FINISHED_KEEP_CONN";
		break;
		case HSE_REQ_MAP_URL_TO_PATH_EX: cout << "HSE_REQ_MAP_URL_TO_PATH_EX";
		break;
		case HSE_REQ_SEND_RESPONSE_HEADER_EX: cout << "HSE_REQ_SEND_RESPONSE_HEADER_EX";
			HSE_SEND_HEADER_EX_INFO * hse = (HSE_SEND_HEADER_EX_INFO *) lpvBuffer;
			cout << "hse->pszHeader: " << hse->pszHeader << endl;
			cout << "hse->pszStatus" << hse->pszStatus << endl;
		break;
	}

	cout << dwHSERequest;
	cout << endl << endl;
	return true;
}

BOOL WINAPI pGetServerVariable(HCONN hConn, LPSTR lpszVariableName, LPVOID lpvBuffer, LPDWORD lpdwSize)
{
	cout << "GetServerVariable() called with: " << lpszVariableName << endl;
	if (!strcmpi(lpszVariableName, "HTTP_COOKIE"))
	{
		strcpy((char *)lpvBuffer ,"user=john");
	}
	else if (!strcmpi(lpszVariableName, "ALL_HTTP"))
	{
		strcpy((char *)lpvBuffer ,"POST /test.php HTTP/1.0\r\n\r\n");
	}
	else if (!strcmpi(lpszVariableName, "HTTPS"))
	{
		strcpy((char *)lpvBuffer ,"OFF");
	}
	else if (!strcmpi(lpszVariableName, "SCRIPT_NAME"))
	{
		strcpy((char *)lpvBuffer ,"C:\\SWS\\WEBROOT\\test.php");
	}
	else if (!strcmpi(lpszVariableName, "SCRIPT_FILENAME"))
	{
		strcpy((char *)lpvBuffer ,"C:\\SWS\\WEBROOT\\test.php");
	}
	else strcpy((char *)lpvBuffer ,"OFF");
	
	lpdwSize = (LPDWORD) strlen((char *) lpvBuffer);
	return false;
}



int main()
{
	// Create an Extension Control Block
	EXTENSION_CONTROL_BLOCK ECB;
	//ECB.cbSize = sizeof(ECB);
	//ECB.ConnID = (HCONN) 10;
	ECB.dwHttpStatusCode = 200;
	ECB.lpszMethod = "POST";
	ECB.lpszPathInfo = "/test.php";
	ECB.lpszPathTranslated = "C:\\SWS\\Webroot\\test.php";
	ECB.lpszQueryString = "user=john";
	ECB.lpszContentType = "text/html";
	ECB.cbAvailable = 1000000;
	ECB.cbTotalBytes = 3000;

    EXTENSION_CONTROL_BLOCK * ECB2 = &ECB;
	HSE_VERSION_INFO hse;

	// Load the DLL
	gMyDLL = LoadLibrary("C:\\PHP\\php-4.3.1-Win32\\SAPI\\php4isapi.dll");
	if (gMyDLL == NULL)
	{
		cout << "ERROR LOADING DLL\n\n";
		return 0;
	}

	pHttpExtensionProc  = (HTTPEXTENSIONPROC) GetProcAddress(gMyDLL, "HttpExtensionProc");
	pGetExtensionVersion = (GETEXTENSIONVERSION) GetProcAddress(gMyDLL, "GetExtensionVersion");

	ECB.ReadClient = &pReadClient;
	ECB.WriteClient = &pWriteClient;
	ECB.ServerSupportFunction = &pServerSupportFunction;
	ECB.GetServerVariable = &pGetServerVariable;

	pGetExtensionVersion(&hse);
	cout << "hse.dwExtensionVersion: " << (int)hse.dwExtensionVersion << endl;
	cout << "hse.lpszExtensionDesc: " << hse.lpszExtensionDesc << endl;
	pHttpExtensionProc(ECB2);

	cout << "";
	
	return 0;	
}
The code above loads the DLL, finds the functions GetExtensionVersion and HttpExtensionProc, and calls HttpExtensionProc with an EXTENSION_CONTROL_BLOCK its created with information about the request.

When I run that code, I am sent a line saying:
WriteClient() called with: PHP has encoutered an access violation at 1000145E

Which was sent just after "ServerSupportFunction()" was called.

From the code above I cant see anywhere where I have made an access violation, but if anyone else can, please tell me