home *** CD-ROM | disk | FTP | other *** search
- // IServer.cpp : implementation file
- //
-
- #include "stdafx.h"
- #include "cbisapi.h"
- #include "IServer.h"
- #include <malloc.h>
- #include <afxconv.h> // BSTR conversions
-
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
-
- /////////////////////////////////////////////////////////////////////////////
- // CIsapiServer
-
- IMPLEMENT_DYNCREATE(CIsapiServer, CCmdTarget)
-
- CIsapiServer::CIsapiServer()
- {
- EnableAutomation();
- }
-
- CIsapiServer::~CIsapiServer()
- {
- }
-
-
- void CIsapiServer::OnFinalRelease()
- {
- CCmdTarget::OnFinalRelease();
- }
-
-
- BEGIN_MESSAGE_MAP(CIsapiServer, CCmdTarget)
- //{{AFX_MSG_MAP(CIsapiServer)
- // NOTE - the ClassWizard will add and remove mapping macros here.
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
-
- BEGIN_DISPATCH_MAP(CIsapiServer, CCmdTarget)
- //{{AFX_DISPATCH_MAP(CIsapiServer)
- DISP_PROPERTY(CIsapiServer, "RetVal", m_retVal, VT_I4)
- DISP_PROPERTY(CIsapiServer, "StatCode", m_statCode, VT_I4)
- DISP_PROPERTY_EX(CIsapiServer, "Method", GetMethod, SetNotSupported, VT_BSTR)
- DISP_PROPERTY_EX(CIsapiServer, "QueryString", GetQueryString, SetNotSupported, VT_BSTR)
- DISP_PROPERTY_EX(CIsapiServer, "PathInfo", GetPathInfo, SetNotSupported, VT_BSTR)
- DISP_PROPERTY_EX(CIsapiServer, "PathTranslated", GetPathTranslated, SetNotSupported, VT_BSTR)
- DISP_PROPERTY_EX(CIsapiServer, "ContentLength", GetContentLength, SetNotSupported, VT_I4)
- DISP_PROPERTY_EX(CIsapiServer, "Content", GetContent, SetNotSupported, VT_BSTR)
- DISP_PROPERTY_EX(CIsapiServer, "ContentType", GetContentType, SetNotSupported, VT_BSTR)
- DISP_FUNCTION(CIsapiServer, "Write", Write, VT_BOOL, VTS_VARIANT)
- DISP_FUNCTION(CIsapiServer, "ServerVariable", ServerVariable, VT_BOOL, VTS_VARIANT VTS_PVARIANT)
- DISP_FUNCTION(CIsapiServer, "WriteLine", WriteLine, VT_BOOL, VTS_VARIANT)
- DISP_FUNCTION(CIsapiServer, "WriteByte", WriteByte, VT_BOOL, VTS_VARIANT)
- DISP_FUNCTION(CIsapiServer, "ServerDoneSession", ServerDoneSession, VT_BOOL, VTS_NONE)
- DISP_FUNCTION(CIsapiServer, "Redirect", Redirect, VT_BOOL, VTS_VARIANT)
- DISP_FUNCTION(CIsapiServer, "SendURL", SendURL, VT_BOOL, VTS_VARIANT)
- DISP_FUNCTION(CIsapiServer, "SendHeaders", SendHeaders, VT_BOOL, VTS_VARIANT VTS_VARIANT)
- DISP_FUNCTION(CIsapiServer, "MapURL2Path", MapURL2Path, VT_BOOL, VTS_PVARIANT)
- //}}AFX_DISPATCH_MAP
- END_DISPATCH_MAP()
-
- // Note: we add support for IID_IIsapiServer to support typesafe binding
- // from VBA. This IID must match the GUID that is attached to the
- // dispinterface in the .ODL file.
- // Not really used in any meaningful way, but the wiz puts it here
-
- // {A3B7D305-647C-11D0-A7B2-444553540000}
- static const IID IID_IIsapiServer =
- { 0xa3b7d305, 0x647c, 0x11d0, { 0xa7, 0xb2, 0x44, 0x45, 0x53, 0x54, 0x0, 0x0 } };
-
- BEGIN_INTERFACE_MAP(CIsapiServer, CCmdTarget)
- INTERFACE_PART(CIsapiServer, IID_IIsapiServer, Dispatch)
- END_INTERFACE_MAP()
-
- /////////////////////////////////////////////////////////////////////////////
- // CIsapiServer message handlers
-
- // Write to client
- BOOL CIsapiServer::Write(const VARIANT FAR& idata)
- {
- COleVariant data=idata;
- USES_CONVERSION;
- data.ChangeType(VT_BSTR); // Force to BSTR
- if (data.vt!=VT_BSTR)
- return FALSE;
- char *s=W2A(data.bstrVal); // switch to ANSI
- DWORD siz=strlen(s);
- return ecb->WriteClient(ecb->ConnID,s,&siz,0); // out!
- }
-
- // This fetches a Server Variable into a VARIANT
- // Be careful. Since the second argument is a variant
- // by reference, the formal argument must really be
- // a variant. In other words, NO:
- // dim x as string
- // server.ServerVariable "SCRIPT_NAME",x
- // YES:
- // dim x as variant
- // server.ServerVariable "SCRIPT_NAME",x
- // Probably should have been a function returning VARIANT, but then
- // again...
- BOOL CIsapiServer::ServerVariable(const VARIANT FAR& Variable,
- VARIANT FAR* Result)
- {
- COleVariant var;
- var=Variable;
- var.ChangeType(VT_BSTR);
- if (var.vt!=VT_BSTR) return FALSE;
-
- USES_CONVERSION;
- char *v=W2A(var.bstrVal);
- CString res;
- DWORD siz=1024;
- BOOL rv;
- rv=ecb->GetServerVariable(ecb->ConnID,v,
- (char *)res.GetBufferSetLength(siz),&siz);
- res.ReleaseBuffer(siz-1);
- VariantClear(Result);
- Result->vt=VT_BSTR;
- Result->bstrVal=res.AllocSysString();
- return rv;
- }
-
- // R/O Property -- these all look the same
- BSTR CIsapiServer::GetMethod()
- {
- CString strResult=ecb->lpszMethod;
- BSTR rv;
- rv=strResult.AllocSysString();
- return rv;
- }
-
- // Another R/O Property
- BSTR CIsapiServer::GetQueryString()
- {
- CString strResult=ecb->lpszQueryString;
- BSTR rv;
- rv=strResult.AllocSysString();
- return rv;
- }
-
- // R/O Property
- BSTR CIsapiServer::GetPathInfo()
- {
- CString strResult=ecb->lpszPathInfo;
- BSTR rv;
- rv=strResult.AllocSysString();
- return rv;
- }
-
- // R/O Property
- BSTR CIsapiServer::GetPathTranslated()
- {
- CString strResult=ecb->lpszPathTranslated;
- BSTR rv;
- rv=strResult.AllocSysString();
- return rv;
- }
-
- // R/O Property
- long CIsapiServer::GetContentLength()
- {
- return ecb->cbTotalBytes;
- }
-
- // R/O Property with a twist
- // Apparently sometimes the server calls the
- // extension without having all the content
- // data (does this really happen?)
- // This function reads it all so it is available
- // BTW, the docs say that if the count is
- // 0xFFFFFFFF then MORE than 4G of data
- // is forthcoming and you should call ReadClient
- // until it is empty
- // NEWS BULLETIN: If you expect 4G or more in
- // a request, don't use these functions!
- BSTR CIsapiServer::GetContent()
- {
- CString strResult;
- char *p=strResult.GetBufferSetLength(ecb->cbTotalBytes);
- // put available bytes in CString
- memcpy(p,ecb->lpbData,ecb->cbAvailable);
- // Read excess
- if (ecb->cbAvailable!=ecb->cbTotalBytes)
- {
- DWORD siz=ecb->cbTotalBytes-ecb->cbAvailable;
- ecb->ReadClient(ecb->ConnID,p+ecb->cbAvailable,&siz);
- }
- strResult.ReleaseBuffer(ecb->cbTotalBytes);
- BSTR rv;
- rv=strResult.AllocSysString();
- return rv;
- }
-
- // Another R/O
- BSTR CIsapiServer::GetContentType()
- {
- CString strResult=ecb->lpszContentType;
- BSTR rv;
- rv=strResult.AllocSysString();
- return rv;
- }
-
- // Simple Method to write a line
- // Note that HTML doesn't care one
- // whit about the \r\n -- it just
- // makes the HTML source nicer
- // Use <P> or <BR> to get a newline in HTML
- BOOL CIsapiServer::WriteLine(const VARIANT FAR& idata)
- {
- BOOL rv=Write(idata);
- DWORD siz=2;
- if (rv) rv=ecb->WriteClient(ecb->ConnID,"\r\n",&siz,0);
- return rv;
- }
-
- // Write a byte out
- BOOL CIsapiServer::WriteByte(const VARIANT FAR& byte)
- {
- COleVariant num=byte;
- num.ChangeType(VT_UI1);
- if (num.vt!=VT_UI1)
- return FALSE;
- char s=num.bVal;
- DWORD siz=1;
- return ecb->WriteClient(ecb->ConnID,&s,&siz,0);
- }
-
-
- // Wrap ServerSupportFunction Done with Session
- BOOL CIsapiServer::ServerDoneSession()
- {
- return ecb->ServerSupportFunction(ecb->ConnID,
- HSE_REQ_DONE_WITH_SESSION,NULL,NULL,NULL);
- }
-
- // Redirect to another URL (wrap ServerSupportFunction)
- BOOL CIsapiServer::Redirect(const VARIANT FAR& url)
- {
- COleVariant var;
- var=url;
- var.ChangeType(VT_BSTR);
- if (var.vt!=VT_BSTR) return FALSE;
-
- USES_CONVERSION;
- char *v=W2A(var.bstrVal);
- DWORD siz=strlen(v);
- return ecb->ServerSupportFunction(ecb->ConnID,
- HSE_REQ_SEND_URL_REDIRECT_RESP,v,&siz,NULL);
- }
-
-
- // Send alternate URL (wrap ServerSupportFunction)
- BOOL CIsapiServer::SendURL(const VARIANT FAR& url)
- {
- COleVariant var;
- var=url;
- var.ChangeType(VT_BSTR);
- if (var.vt!=VT_BSTR) return FALSE;
-
- USES_CONVERSION;
- char *v=W2A(var.bstrVal);
- DWORD siz=strlen(v);
- return ecb->ServerSupportFunction(ecb->ConnID,
- HSE_REQ_SEND_URL,v,&siz,NULL);
- }
-
-
- // Send headers (wrap ServerSupport Function)
- BOOL CIsapiServer::SendHeaders(const VARIANT FAR& Status,
- const VARIANT FAR& Headers)
- {
- COleVariant var,var2;
- var=Status;
- var2=Headers;
- var.ChangeType(VT_BSTR);
- if (var.vt!=VT_BSTR) return FALSE;
- var2.ChangeType(VT_BSTR);
- if (var.vt!=VT_BSTR) return FALSE;
-
- USES_CONVERSION;
- char *status=W2A(var.bstrVal);
- char *hdr=W2A(var.bstrVal);
- return ecb->ServerSupportFunction(ecb->ConnID,
- HSE_REQ_SEND_RESPONSE_HEADER,status,NULL,(DWORD *)hdr);
- }
-
- // Map Virtual Path to Real Path (wrap ServerSupportFunction)
- BOOL CIsapiServer::MapURL2Path(VARIANT FAR* urlpath)
- {
- BOOL rv;
- COleVariant var,var2;
- var=urlpath;
- var.ChangeType(VT_BSTR);
- if (var.vt!=VT_BSTR) return FALSE;
- USES_CONVERSION;
- char *varin=W2A(var.bstrVal);
- DWORD siz=1024;
- CString url(varin);
- rv=ecb->ServerSupportFunction(ecb->ConnID,
- HSE_REQ_MAP_URL_TO_PATH,
- url.GetBufferSetLength(siz),&siz,NULL);
- url.ReleaseBuffer(siz-1);
- // set up return value
- VariantClear(urlpath);
- urlpath->vt=VT_BSTR;
- urlpath->bstrVal=url.AllocSysString();
- return rv;
- }
-