// PINBALL.CPP - Implementation file for your Internet Server // Pinball Extension // // This is a part of the Microsoft Foundation Classes C++ library. // Copyright (C) 1992-1998 Microsoft Corporation // All rights reserved. // // This source code is only intended as a supplement to the // Microsoft Foundation Classes Reference and related // electronic documentation provided with the library. // See these sources for detailed information regarding the // Microsoft Foundation Classes product. #include "stdafx.h" #include "Pinball.h" /////////////////////////////////////////////////////////////////////// // The one and only CWinApp object CWinApp theApp; /////////////////////////////////////////////////////////////////////// // command-parsing map BEGIN_PARSE_MAP(CPinballExtension, CHttpServer) // TODO: insert your ON_PARSE_COMMAND() and // ON_PARSE_COMMAND_PARAMS() here to hook up your commands. // For example: ON_PARSE_COMMAND(Default, CPinballExtension, ITS_EMPTY) DEFAULT_PARSE_COMMAND(Default, CPinballExtension) ON_PARSE_COMMAND(GetImage, CPinballExtension, ITS_I4) ON_PARSE_COMMAND_PARAMS("Favorite") END_PARSE_MAP(CPinballExtension) /////////////////////////////////////////////////////////////////////// // The one and only CPinballExtension object CPinballExtension theExtension; /////////////////////////////////////////////////////////////////////// // CPinballExtension implementation CPinballExtension::CPinballExtension() { } CPinballExtension::~CPinballExtension() { } BOOL CPinballExtension::GetExtensionVersion(HSE_VERSION_INFO* pVer) { // Call default implementation for initialization CHttpServer::GetExtensionVersion(pVer); // Load description string TCHAR sz[HSE_MAX_EXT_DLL_NAME_LEN+1]; ISAPIVERIFY(::LoadString(AfxGetResourceHandle(), IDS_SERVER, sz, HSE_MAX_EXT_DLL_NAME_LEN)); _tcscpy(pVer->lpszExtensionDesc, sz); return TRUE; } BOOL CPinballExtension::TerminateExtension(DWORD dwFlags) { // extension is being terminated //TODO: Clean up any per-instance resources return TRUE; } BOOL CPinballExtension::LoadLongResource(CString& str, UINT nID) { HRSRC hRes; HINSTANCE hInst = AfxGetResourceHandle(); BOOL bResult = FALSE; hRes = FindResource(hInst, MAKEINTRESOURCE(nID), RT_HTML); if (hRes == NULL) ISAPITRACE1("Error: Resource %d could not be found\r\n", nID); else { DWORD dwSize = SizeofResource(hInst, hRes); if (dwSize == 0) { str.Empty(); bResult = TRUE; } else { LPTSTR pszStorage = str.GetBufferSetLength(dwSize); HGLOBAL hGlob = LoadResource(hInst, hRes); if (hGlob != NULL) { LPVOID lpData = LockResource(hGlob); if (lpData != NULL) { memcpy(pszStorage, lpData, dwSize); bResult = TRUE; } FreeResource(hGlob); } } } #ifdef _DEBUG if (!bResult) str.Format(_T("Could not find string %d"), nID); #endif return bResult; } /////////////////////////////////////////////////////////////////////// // CPinballExtension command handlers void CPinballExtension::Default(CHttpServerContext* pCtxt) { StartContent(pCtxt); WriteTitle(pCtxt); // show the user our regular HTML CString str; if (LoadLongResource(str, IDR_DEFAULT_HTML)) *pCtxt << str; else *pCtxt << _T("Could not load default page from HTML resource."); EndContent(pCtxt); } BOOL CPinballExtension::SendAFile(CHttpServerContext* pCtxt, LPCTSTR pstrFullPath, LPCTSTR pstrContentType) { BOOL bResult = FALSE; // open the file using SEQUENTIAL_SCAN and OVERLAPPED so we can // pass the resulting handle to IIS HANDLE hFile = ::CreateFile(pstrFullPath, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN | FILE_FLAG_OVERLAPPED, NULL); // If the file open failed, write an error message to the user. if (hFile == INVALID_HANDLE_VALUE) { DWORD dwError = GetLastError(); *pCtxt << _T("File open failed on "); *pCtxt << pstrFullPath << _T("! Error was "); *pCtxt << long(dwError); *pCtxt << _T("
"); *pCtxt << _T("Did you correctly copy all the graphics files, too?
"); } else { // try to transmit the file we've opened DWORD dwLength = GetFileSize(hFile, NULL); // formulate a proper header CString strHeader; strHeader.Format( _T("HTTP/1.0 200 OK\r\n%s\r\nContent-length: %d\r\n\r\n"), pstrContentType, dwLength); // double-cast is necessary because TransmitFile() // params are not const bResult = pCtxt->TransmitFile(hFile, HSE_IO_ASYNC, (LPVOID)(LPCTSTR) strHeader); // if it failed, explain it to the user if (!bResult) { StartContent(pCtxt); WriteTitle(pCtxt); DWORD dwError = GetLastError(); *pCtxt << _T("TransmitFile called failed! Error was "); *pCtxt << long(dwError) << _T("
"); EndContent(pCtxt); CloseHandle(hFile); } // If the call to TransmitFile() was successful, we don't // need to do anything else. } return bResult; } BOOL CPinballExtension::SendJPGFile(CHttpServerContext* pCtxt, LPCTSTR pstrFile, LPCTSTR pstrPath) { // specify content type static const TCHAR szJPGContent[] = _T("Content-Type: image/jpeg"); // build the local file name CString str(pstrPath); str += pstrFile; // send it off return SendAFile(pCtxt, str, szJPGContent); } BOOL CPinballExtension::SendGIFFile(CHttpServerContext* pCtxt, LPCTSTR pstrFile, LPCTSTR pstrPath) { // specify content type static const TCHAR szGIFContent[] = _T("Content-Type: image/gif"); // build the local file name CString str(pstrPath); str += pstrFile; // send it off return SendAFile(pCtxt, str, szGIFContent); } void CPinballExtension::GetImage(CHttpServerContext* pCtxt, long dwChoice) { // find the local directory where we live, as we'll assume all // the graphics files are nearby TCHAR szBuffer[_MAX_PATH]; DWORD dwSize = _MAX_PATH; pCtxt->GetServerVariable("URL", szBuffer, &dwSize); LPTSTR pstrWhack = _tcsrchr(szBuffer, '/'); if (pstrWhack == NULL) { StartContent(pCtxt); WriteTitle(pCtxt); *pCtxt << _T("Wierd response from GetServerVariable: "); *pCtxt << szBuffer << _T("
"); EndContent(pCtxt); } else { // convert the URL into a useable local path dwSize = _MAX_PATH; *pstrWhack = NULL; pCtxt->ServerSupportFunction(HSE_REQ_MAP_URL_TO_PATH, szBuffer, &dwSize, 0); _tcscat(szBuffer, _T("/")); // depending on what the user asked for, send them something switch (dwChoice) { case 0: { StartContent(pCtxt); WriteTitle(pCtxt); CString str; if (LoadLongResource(str, IDR_REDIR_HTML)) *pCtxt << str; else *pCtxt << _T("Could not load redir page from HTML resource."); } EndContent(pCtxt); break; case 1: SendJPGFile(pCtxt, _T("mars.jpg"), szBuffer); break; case 2: SendGIFFile(pCtxt, _T("tz.gif"), szBuffer); break; case 3: SendGIFFile(pCtxt, _T("taf.gif"), szBuffer); break; case 4: SendGIFFile(pCtxt, _T("cv.gif"), szBuffer); break; default: StartContent(pCtxt); WriteTitle(pCtxt); // how could this happen? *pCtxt << _T("Choice # "); *pCtxt << dwChoice; *pCtxt << _T(" is invlaid!
"); EndContent(pCtxt); break; } } } // Do not edit the following lines, which are needed by ClassWizard. #if 0 BEGIN_MESSAGE_MAP(CPinballExtension, CHttpServer) //{{AFX_MSG_MAP(CPinballExtension) //}}AFX_MSG_MAP END_MESSAGE_MAP() #endif // 0