#include <stdio.h>
#include <tchar.h>
#include <conio.h>
 
#import "C:\\Program Files\\HTTP Debugger SDK\\mfncom.dll" no_namespace raw_interfaces_only

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 )
      {
            printf("HTTP Request Header: User Name: %s, Program Name: %s, Requested URL: %s\n%s\n",  UserName, ProgramName, URL, HeaderData );
            return S_OK;
      }

      HRESULT STDMETHODCALLTYPE OnRequestContentPacket ( unsigned long ID, unsigned char * PacketData, unsigned long PacketSize, unsigned long RawPacketSize )
      {
            printf("HTTP Request Content Packet: Data Buffer: 0x%X, Decoded Data Size: %d, RAW Data Size: %d\n\n",  PacketData, PacketSize, RawPacketSize );
            return S_OK;
      }

      HRESULT STDMETHODCALLTYPE OnResponseHeader ( unsigned long ID, char * UserName, char * ProgramName, char * Status, char * HeaderData )
      {
            printf("HTTP Response Header: User Name: %s, Program Name: %s, Status Code: %s\n%s\n",  UserName, ProgramName, Status, HeaderData );
            return S_OK;
      }

      HRESULT STDMETHODCALLTYPE OnResponseContentPacket ( unsigned long ID, unsigned char * PacketData, unsigned long PacketSize, unsigned long RawPacketSize )
      {
            printf("HTTP Response Content Packet: Data Buffer: 0x%X, Decoded Data Size: %d, RAW Data Size: %d\n\n",  PacketData, PacketSize, RawPacketSize );
            return S_OK;
      }

      HRESULT STDMETHODCALLTYPE OnClose ( unsigned long ID )
      {
            return S_OK;
      }

};
 
int _tmain(int argc, _TCHAR* argv[])
{
      HRESULT hr;
      IMFNHTTPCtrlPtr pHTTPCtrl;
      MFNHTTPCtrlEvents eHTTPCtrlEvents;
      CoInitialize(NULL);

      hr = pHTTPCtrl.CreateInstance(__uuidof(MFNHTTPCtrl));
      if (pHTTPCtrl)
      {
            // set listener for pHTTPCtrl events
            DWORD dwCookie;
            IUnknown *pUnk = NULL;
            IUnknown *pHandler = NULL;
            IConnectionPointContainer* pCPC = NULL;
            IConnectionPoint* pCP = 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 'RealTime' mode. If you need to use the 'Scripting' mode please see the 'Scripting_C++' sample
            pHTTPCtrl->InitHTTP( HTTP_RealTime, HTTP_DecodeContent, nSerialNumber );

            printf("Launch your browser and open a website in it.\n");
            printf("Or press any key to close...\n\n\n");

            _getch();

            pCP->Unadvise(dwCookie);
            pCP->Release();

            //stop intercepting engine
            pHTTPCtrl->TermHTTP();
            pHTTPCtrl.Release();
      }

      CoUninitialize();
      return 0;
}