home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / mfc / internet / pinball / pinball.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-03-27  |  7.5 KB  |  309 lines

  1. // PINBALL.CPP - Implementation file for your Internet Server
  2. //    Pinball Extension
  3. //
  4. // This is a part of the Microsoft Foundation Classes C++ library.
  5. // Copyright (C) 1992-1998 Microsoft Corporation
  6. // All rights reserved.
  7. //
  8. // This source code is only intended as a supplement to the
  9. // Microsoft Foundation Classes Reference and related
  10. // electronic documentation provided with the library.
  11. // See these sources for detailed information regarding the
  12. // Microsoft Foundation Classes product.
  13.  
  14. #include "stdafx.h"
  15. #include "Pinball.h"
  16.  
  17. ///////////////////////////////////////////////////////////////////////
  18. // The one and only CWinApp object
  19.  
  20. CWinApp theApp;
  21.  
  22. ///////////////////////////////////////////////////////////////////////
  23. // command-parsing map
  24.  
  25. BEGIN_PARSE_MAP(CPinballExtension, CHttpServer)
  26.     // TODO: insert your ON_PARSE_COMMAND() and
  27.     // ON_PARSE_COMMAND_PARAMS() here to hook up your commands.
  28.     // For example:
  29.  
  30.     ON_PARSE_COMMAND(Default, CPinballExtension, ITS_EMPTY)
  31.     DEFAULT_PARSE_COMMAND(Default, CPinballExtension)
  32.     ON_PARSE_COMMAND(GetImage, CPinballExtension, ITS_I4)
  33.     ON_PARSE_COMMAND_PARAMS("Favorite")
  34. END_PARSE_MAP(CPinballExtension)
  35.  
  36.  
  37. ///////////////////////////////////////////////////////////////////////
  38. // The one and only CPinballExtension object
  39.  
  40. CPinballExtension theExtension;
  41.  
  42.  
  43. ///////////////////////////////////////////////////////////////////////
  44. // CPinballExtension implementation
  45.  
  46. CPinballExtension::CPinballExtension()
  47. {
  48. }
  49.  
  50. CPinballExtension::~CPinballExtension()
  51. {
  52. }
  53.  
  54. BOOL CPinballExtension::GetExtensionVersion(HSE_VERSION_INFO* pVer)
  55. {
  56.     // Call default implementation for initialization
  57.     CHttpServer::GetExtensionVersion(pVer);
  58.  
  59.     // Load description string
  60.     TCHAR sz[HSE_MAX_EXT_DLL_NAME_LEN+1];
  61.     ISAPIVERIFY(::LoadString(AfxGetResourceHandle(),
  62.             IDS_SERVER, sz, HSE_MAX_EXT_DLL_NAME_LEN));
  63.     _tcscpy(pVer->lpszExtensionDesc, sz);
  64.     return TRUE;
  65. }
  66.  
  67. BOOL CPinballExtension::TerminateExtension(DWORD dwFlags)
  68. {
  69.     // extension is being terminated
  70.     //TODO: Clean up any per-instance resources
  71.     return TRUE;
  72. }
  73.  
  74. BOOL CPinballExtension::LoadLongResource(CString& str, UINT nID)
  75. {
  76.     HRSRC hRes;
  77.     HINSTANCE hInst = AfxGetResourceHandle();
  78.     BOOL bResult = FALSE;
  79.  
  80.     hRes = FindResource(hInst, MAKEINTRESOURCE(nID), RT_HTML);
  81.     if (hRes == NULL)
  82.         ISAPITRACE1("Error: Resource %d could not be found\r\n", nID);
  83.     else
  84.     {
  85.         DWORD dwSize = SizeofResource(hInst, hRes);
  86.         if (dwSize == 0)
  87.         {
  88.             str.Empty();
  89.             bResult = TRUE;
  90.         }
  91.         else
  92.         {
  93.             LPTSTR pszStorage = str.GetBufferSetLength(dwSize);
  94.  
  95.             HGLOBAL hGlob = LoadResource(hInst, hRes);
  96.             if (hGlob != NULL)
  97.             {
  98.                 LPVOID lpData = LockResource(hGlob);
  99.  
  100.                 if (lpData != NULL)
  101.                 {
  102.                     memcpy(pszStorage, lpData, dwSize);
  103.                     bResult = TRUE;
  104.                 }
  105.  
  106.                 FreeResource(hGlob);
  107.             }
  108.         }
  109.     }
  110.  
  111. #ifdef _DEBUG
  112.     if (!bResult)
  113.         str.Format(_T("<b>Could not find string %d</b>"), nID);
  114. #endif
  115.  
  116.     return bResult;
  117. }
  118.  
  119.  
  120.  
  121. ///////////////////////////////////////////////////////////////////////
  122. // CPinballExtension command handlers
  123.  
  124. void CPinballExtension::Default(CHttpServerContext* pCtxt)
  125. {
  126.     StartContent(pCtxt);
  127.     WriteTitle(pCtxt);
  128.  
  129.     // show the user our regular HTML
  130.  
  131.     CString str;
  132.     if (LoadLongResource(str, IDR_DEFAULT_HTML))
  133.         *pCtxt << str;
  134.     else
  135.         *pCtxt << _T("Could not load default page from HTML resource.");
  136.  
  137.     EndContent(pCtxt);
  138. }
  139.  
  140. BOOL CPinballExtension::SendAFile(CHttpServerContext* pCtxt,
  141.     LPCTSTR pstrFullPath, LPCTSTR pstrContentType)
  142. {
  143.     BOOL bResult = FALSE;
  144.  
  145.     // open the file using SEQUENTIAL_SCAN and OVERLAPPED so we can
  146.     // pass the resulting handle to IIS
  147.  
  148.     HANDLE hFile = ::CreateFile(pstrFullPath,
  149.                     GENERIC_READ, 0, NULL, OPEN_EXISTING,
  150.                     FILE_FLAG_SEQUENTIAL_SCAN | FILE_FLAG_OVERLAPPED, NULL);
  151.  
  152.     // If the file open failed, write an error message to the user.
  153.     if (hFile == INVALID_HANDLE_VALUE)
  154.     {
  155.         DWORD dwError = GetLastError();
  156.         *pCtxt << _T("File open failed on ");
  157.         *pCtxt << pstrFullPath << _T("!  Error was ");
  158.         *pCtxt << long(dwError);
  159.         *pCtxt << _T("<br>");
  160.  
  161.         *pCtxt << _T("Did you correctly copy all the graphics files, too?<br>");
  162.     }
  163.     else
  164.     {
  165.         // try to transmit the file we've opened
  166.  
  167.         DWORD dwLength = GetFileSize(hFile, NULL);
  168.  
  169.         // formulate a proper header
  170.         CString strHeader;
  171.         strHeader.Format(
  172.             _T("HTTP/1.0 200 OK\r\n%s\r\nContent-length: %d\r\n\r\n"),
  173.             pstrContentType, dwLength);
  174.  
  175.         // double-cast is necessary because TransmitFile()
  176.         // params are not const
  177.  
  178.         bResult = pCtxt->TransmitFile(hFile, HSE_IO_ASYNC,
  179.             (LPVOID)(LPCTSTR) strHeader);
  180.  
  181.         // if it failed, explain it to the user
  182.         if (!bResult)
  183.         {
  184.             StartContent(pCtxt);
  185.             WriteTitle(pCtxt);
  186.  
  187.             DWORD dwError = GetLastError();
  188.             *pCtxt << _T("TransmitFile called failed!  Error was ");
  189.             *pCtxt << long(dwError) << _T("<br>");
  190.  
  191.             EndContent(pCtxt);
  192.             CloseHandle(hFile);
  193.         }
  194.  
  195.         // If the call to TransmitFile() was successful, we don't
  196.         // need to do anything else.
  197.     }
  198.  
  199.     return bResult;
  200. }
  201.  
  202. BOOL CPinballExtension::SendJPGFile(CHttpServerContext* pCtxt,
  203.     LPCTSTR pstrFile,   LPCTSTR pstrPath)
  204. {
  205.     // specify content type
  206.     static const TCHAR szJPGContent[] = _T("Content-Type: image/jpeg");
  207.  
  208.     // build the local file name
  209.     CString str(pstrPath);
  210.     str += pstrFile;
  211.  
  212.     // send it off
  213.     return SendAFile(pCtxt, str, szJPGContent);
  214. }
  215.  
  216. BOOL CPinballExtension::SendGIFFile(CHttpServerContext* pCtxt,
  217.     LPCTSTR pstrFile,   LPCTSTR pstrPath)
  218. {
  219.     // specify content type
  220.     static const TCHAR szGIFContent[] = _T("Content-Type: image/gif");
  221.  
  222.     // build the local file name
  223.     CString str(pstrPath);
  224.     str += pstrFile;
  225.  
  226.     // send it off
  227.     return SendAFile(pCtxt, str, szGIFContent);
  228. }
  229.  
  230. void CPinballExtension::GetImage(CHttpServerContext* pCtxt, long dwChoice)
  231. {
  232.     // find the local directory where we live, as we'll assume all
  233.     // the graphics files are nearby
  234.  
  235.     TCHAR szBuffer[_MAX_PATH];
  236.     DWORD dwSize = _MAX_PATH;
  237.     pCtxt->GetServerVariable("URL", szBuffer, &dwSize);
  238.  
  239.     LPTSTR pstrWhack = _tcsrchr(szBuffer, '/');
  240.     if (pstrWhack == NULL)
  241.     {
  242.         StartContent(pCtxt);
  243.         WriteTitle(pCtxt);
  244.         *pCtxt << _T("Wierd response from GetServerVariable: ");
  245.         *pCtxt << szBuffer << _T("<br>");
  246.         EndContent(pCtxt);
  247.     }
  248.     else
  249.     {
  250.         // convert the URL into a useable local path
  251.         dwSize = _MAX_PATH;
  252.         *pstrWhack = NULL;
  253.         pCtxt->ServerSupportFunction(HSE_REQ_MAP_URL_TO_PATH, szBuffer, &dwSize, 0);
  254.         _tcscat(szBuffer, _T("/"));
  255.  
  256.         // depending on what the user asked for, send them something
  257.         switch (dwChoice)
  258.         {
  259.         case 0:
  260.             {
  261.             StartContent(pCtxt);
  262.             WriteTitle(pCtxt);
  263.             CString str;
  264.             if (LoadLongResource(str, IDR_REDIR_HTML))
  265.                 *pCtxt << str;
  266.             else
  267.                 *pCtxt << _T("Could not load redir page from HTML resource.");
  268.             }
  269.             EndContent(pCtxt);
  270.             break;
  271.  
  272.         case 1:
  273.             SendJPGFile(pCtxt, _T("mars.jpg"), szBuffer);
  274.             break;
  275.  
  276.         case 2:
  277.             SendGIFFile(pCtxt, _T("tz.gif"), szBuffer);
  278.             break;
  279.  
  280.         case 3:
  281.             SendGIFFile(pCtxt, _T("taf.gif"), szBuffer);
  282.             break;
  283.  
  284.         case 4:
  285.             SendGIFFile(pCtxt, _T("cv.gif"), szBuffer);
  286.             break;
  287.  
  288.         default:
  289.             StartContent(pCtxt);
  290.             WriteTitle(pCtxt);
  291.             // how could this happen?
  292.             *pCtxt << _T("Choice # ");
  293.             *pCtxt << dwChoice;
  294.             *pCtxt << _T(" is invlaid!<br>");
  295.             EndContent(pCtxt);
  296.             break;
  297.         }
  298.     }
  299. }
  300.  
  301.  
  302. // Do not edit the following lines, which are needed by ClassWizard.
  303. #if 0
  304. BEGIN_MESSAGE_MAP(CPinballExtension, CHttpServer)
  305.     //{{AFX_MSG_MAP(CPinballExtension)
  306.     //}}AFX_MSG_MAP
  307. END_MESSAGE_MAP()
  308. #endif  // 0
  309.