// Modify the following defines if you have to target a platform prior to the ones specified below.
// Refer to MSDN for the latest info on corresponding values for different platforms.
#ifndef WINVER                     // Allow use of features specific to Windows XP or later.
#define WINVER 0x0501        // Change this to the appropriate value to target other versions of Windows.
#endif
 
#ifndef _WIN32_WINNT         // Allow use of features specific to Windows XP or later.                  
#define _WIN32_WINNT 0x0501  // Change this to the appropriate value to target other versions of Windows.
#endif                                  
#ifndef _WIN32_WINDOWS       // Allow use of features specific to Windows 98 or later.
#define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later.
#endif
 
#ifndef _WIN32_IE            // Allow use of features specific to IE 6.0 or later.
#define _WIN32_IE 0x0600     // Change this to the appropriate value to target other versions of IE.
#endif
 
#define WIN32_LEAN_AND_MEAN        // Exclude rarely-used stuff from Windows headers
// Windows Header Files:
#include <windows.h>
 
// C RunTime Header Files
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>
 
#include <stdio.h>
#include <tchar.h>
#include <conio.h>
 
#pragma warning (disable : 4313)
#import "C:\\Program Files\\HTTP Debugger SDK\\mfncom.dll" no_namespace raw_interfaces_only
// Global Variables:
HINSTANCE hInst;                                           // current instance
HWND      hEdit;
 
#define   EditTextBufLen (64*1024)
char    szEditTextBuf[EditTextBufLen];
 
// Forward declarations of functions included in this code module:
ATOM                    MyRegisterClass(HINSTANCE hInstance);
BOOL                    InitInstance(HINSTANCE, int);
LRESULT CALLBACK  WndProc(HWND, UINT, WPARAM, LPARAM);
 
// ************************************************************************************************
// HTTP Debugger staff
// ************************************************************************************************
struct MFNHTTPCtrlEvents : public IMFNHTTPCtrlEvents
{
      ULONG m_cRef;
 
      MFNHTTPCtrlEvents()
      {
            m_cRef = 1;
      }
 
      ~MFNHTTPCtrlEvents()
      {

      }
 
      //IUnknown
      ULONG STDMETHODCALLTYPE AddRef ()
      {
            return ++m_cRef;
      }
 
      ULONG STDMETHODCALLTYPE Release ()
      {
            if (--m_cRef != 0)
                  return m_cRef;
           
            delete this;
            return 0;
      }
 
      HRESULT STDMETHODCALLTYPE QueryInterface (REFIID riid, void** ppv)
      {
            *ppv=NULL;
         
            if (riid == IID_IUnknown)  
                  *ppv = this;
         
            if (riid == __uuidof(IMFNHTTPCtrlEvents)) 
                  *ppv = this;
         
            if (NULL==*ppv) 
                  return E_NOINTERFACE;
         
            AddRef();
            return NOERROR;
      }
 
    //IMFNHTTPCtrlEvents
      HRESULT STDMETHODCALLTYPE OnRequestHeader (unsigned long ID, char * UserName, char * ProgramName, char * URL, char * HeaderData )
      {
            int nLen = GetWindowTextLength(hEdit);
            if ( nLen + strlen(HeaderData) < EditTextBufLen )
            {
                  GetWindowText(hEdit, szEditTextBuf, EditTextBufLen-1);
                  strcat_s(szEditTextBuf, EditTextBufLen, HeaderData);
                  SetWindowText(hEdit, szEditTextBuf );
            }
 
            return S_OK;
      }
 
      HRESULT STDMETHODCALLTYPE OnRequestContentPacket ( unsigned long ID, unsigned char * PacketData, unsigned long PacketSize, unsigned long RawPacketSize )
      {
            char szBuf[1024];
            sprintf_s(szBuf, 1024, "HTTP Request Content Packet: Data Buffer: 0x%X, Decoded Data Size: %d, RAW Data Size: %d\r\n\r\n",  PacketData, PacketSize, RawPacketSize );
 
            int nLen = GetWindowTextLength(hEdit);
            if ( nLen + strlen(szBuf) < EditTextBufLen )
            {
                  GetWindowText(hEdit, szEditTextBuf, EditTextBufLen-1);
                  strcat_s(szEditTextBuf, EditTextBufLen, szBuf);
                  SetWindowText(hEdit, szEditTextBuf );
            }
 
            return S_OK;
      }
 
      HRESULT STDMETHODCALLTYPE OnResponseHeader ( unsigned long ID, char * UserName, char * ProgramName, char * Status, char * HeaderData )
      {
            int nLen = GetWindowTextLength(hEdit);
            if ( nLen + strlen(HeaderData) < EditTextBufLen )
            {
                  GetWindowText(hEdit, szEditTextBuf, EditTextBufLen-1);
                  strcat_s(szEditTextBuf, EditTextBufLen, HeaderData);
                  SetWindowText(hEdit, szEditTextBuf );
            }
 
            return S_OK;
      }
 
      HRESULT STDMETHODCALLTYPE OnResponseContentPacket ( unsigned long ID, unsigned char * PacketData, unsigned long PacketSize, unsigned long RawPacketSize )
      {
            char szBuf[1024];
            sprintf_s(szBuf, 1024, "HTTP Response Content Packet: Data Buffer: 0x%X, Decoded Data Size: %d, RAW Data Size: %d\r\n\r\n",  PacketData, PacketSize, RawPacketSize );
 
            int nLen = GetWindowTextLength(hEdit);
            if ( nLen + strlen(szBuf) < EditTextBufLen )
            {
                  GetWindowText(hEdit, szEditTextBuf, EditTextBufLen-1);
                  strcat_s(szEditTextBuf, EditTextBufLen, szBuf);
                  SetWindowText(hEdit, szEditTextBuf );
            }
 
            return S_OK;
      }
 
      HRESULT STDMETHODCALLTYPE OnClose ( unsigned long ID )
      {
            return S_OK;
      }
};
 
 
IMFNHTTPCtrlPtr pHTTPCtrl;
MFNHTTPCtrlEvents eHTTPCtrlEvents;
IConnectionPoint* pCP = NULL;
DWORD dwCookie;
 
void InitHTTPEngine()
{
      CoInitialize(NULL);
 
      HRESULT hr = pHTTPCtrl.CreateInstance(__uuidof(MFNHTTPCtrl));
      if (pHTTPCtrl)
      {
            // set listener for pHTTPCtrl events
            IUnknown *pUnk = NULL;
            IUnknown *pHandler = NULL;
            IConnectionPointContainer* pCPC = NULL;
 
            hr = pHTTPCtrl->QueryInterface(IID_IUnknown, (void**)&pUnk);
            hr = eHTTPCtrlEvents.QueryInterface(IID_IUnknown, (void**)&pHandler);
 
            hr = pUnk->QueryInterface(IID_IConnectionPointContainer, (void**)&pCPC);
            if (SUCCEEDED(hr))
            {
                  // Find the connection point.
                  hr = pCPC->FindConnectionPoint(__uuidof(IMFNHTTPCtrlEvents), &pCP);
 
                  if (SUCCEEDED(hr))
                  {
                        // Advise the connection point.
                        hr = pCP->Advise(pHandler, &dwCookie);
 
                        if (SUCCEEDED(hr))
                        {
 
                        }
                  }
 
                  pCPC->Release();
            }
            pUnk->Release();
           
            //replace with your serial number
            const long nSerialNumber = 0;
 
            //this sample works only in 'Scripting' mode. If you need to use the 'RealTime' mode please see the 'RealTime_C++' sample
            pHTTPCtrl->InitHTTP( HTTP_Scripting, HTTP_DecodeContent, nSerialNumber );
      }
}
 
void TermHTTPEngine()
{
      if (pHTTPCtrl)
      {
            pCP->Unadvise(dwCookie);
            pCP->Release();
 
            //stop intercepting engine
            pHTTPCtrl->TermHTTP();
            pHTTPCtrl.Release();
      }
 
      CoUninitialize();
}
 
 
// ************************************************************************************************
// Windows staff
// ************************************************************************************************
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
      UNREFERENCED_PARAMETER(hPrevInstance);
      UNREFERENCED_PARAMETER(lpCmdLine);
 
      // TODO: Place code here.
      MSG msg;
 
      // Initialize global strings
      MyRegisterClass(hInstance);
 
      // Perform application initialization:
      if (!InitInstance (hInstance, nCmdShow))
            return FALSE;
 
      // Main message loop:
      while (GetMessage(&msg, NULL, 0, 0))
      {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
      }
 
      return (int) msg.wParam;
}
 
ATOM MyRegisterClass(HINSTANCE hInstance)
{
      WNDCLASSEX wcex;
 
      wcex.cbSize             = sizeof(WNDCLASSEX);
      wcex.style              = CS_HREDRAW | CS_VREDRAW;
      wcex.lpfnWndProc  = WndProc;
      wcex.cbClsExtra         = 0;
      wcex.cbWndExtra         = 0;
      wcex.hInstance          = hInstance;
      wcex.hIcon              = LoadIcon(NULL, IDI_APPLICATION);
      wcex.hCursor            = LoadCursor(NULL, IDC_ARROW);
      wcex.hbrBackground      = (HBRUSH)(COLOR_WINDOW+1);
      wcex.lpszMenuName = NULL;
      wcex.lpszClassName      = "ScriptingSampleWnd";
      wcex.hIconSm            = LoadIcon(NULL, IDI_APPLICATION);
 
      return RegisterClassEx(&wcex);
}
 
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   HWND hWnd;
 
   hInst = hInstance; // Store instance handle in our global variable
 
   hWnd = CreateWindow("ScriptingSampleWnd", "Scripting Sample", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
   if (!hWnd)
      return FALSE;
 
   ShowWindow(hWnd, nCmdShow);
   UpdateWindow(hWnd);
 
   return TRUE;
}
 
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
      //int wmId, wmEvent;
      PAINTSTRUCT ps;
      HDC hdc;
 
      switch (message)
      {
      case WM_CREATE:
            ZeroMemory(szEditTextBuf, EditTextBufLen);
            hEdit = CreateWindow( "Edit", NULL, WS_CHILD|WS_VISIBLE|WS_VSCROLL|ES_MULTILINE|ES_AUTOVSCROLL|ES_READONLY, 0, 0, 0, 0, hWnd, NULL, hInst, 0);
           
            InitHTTPEngine();
            break;
      case WM_SIZE:
            if (hEdit)
                  MoveWindow(hEdit, 0, 0, LOWORD(lParam), HIWORD(lParam), TRUE);
            break;
      case WM_PAINT:
            hdc = BeginPaint(hWnd, &ps);
            EndPaint(hWnd, &ps);
            break;
      case WM_DESTROY:
            TermHTTPEngine();
           
            PostQuitMessage(0);
            break;
      default:
            return DefWindowProc(hWnd, message, wParam, lParam);
      }
      return 0;
}