home *** CD-ROM | disk | FTP | other *** search
-
- /* OLE-CGI: interface to OLE servers created by VB from standard CGI */
-
- #include "stdio.h"
- #include "malloc.h"
- #include "fcntl.h"
- #include "windows.h"
- #include "tchar.h"
- #include "oleauto.h"
- #include "io.h"
- #include "noafxstr.h"
-
- /* text macros borrowed from MFC header files */
-
- LPWSTR NoAfxA2WHelper(LPWSTR lpw, LPCSTR lpa, int nChars)
- {
- if (lpa == NULL)
- return NULL;
- // verify that no illegal character present
- // since lpw was allocated based on the size of lpa
- // don't worry about the number of chars
- lpw[0] = '\0';
- MultiByteToWideChar(CP_ACP, 0, lpa, -1, lpw, nChars);
- return lpw;
- }
-
- LPSTR NoAfxW2AHelper(LPSTR lpa, LPCWSTR lpw, int nChars)
- {
- if (lpw == NULL)
- return NULL;
- // verify that no illegal character present
- // since lpa was allocated based on the size of lpw
- // don't worry about the number of chars
- lpa[0] = '\0';
- WideCharToMultiByte(CP_ACP, 0, lpw, -1, lpa, nChars, NULL, NULL);
- return lpa;
- }
-
- extern char *getenv();
- extern char *strrchr();
- extern int atoi();
-
- int glob_argc = 0;
- char **glob_argv = NULL;
- char **glob_env = NULL;
- int glob_clen = 0;
- char *glob_content = NULL;
-
- int glob_cgiwin = 0; /* if true, running under CGI-WIN interface */
- char glob_cgiwin_out[_MAX_PATH];
-
- /* ---- cgi_error ---- */
-
- int cgi_error(char *s, int ret_code)
- {
- int i = 0;
- FILE *fp = stdout;
-
- if(glob_cgiwin)
- fp = fopen(glob_cgiwin_out,"w");
-
- fprintf(fp,"Content-type: text/plain\n\n");
-
- fprintf(fp,"Error in CGI-OLE gateway script.\n\nReason: %s.\n\n",s);
-
- fprintf(fp,"-----------------------------------------\n");
- fprintf(fp,"Command-line arguments (%d)\n\n",glob_argc);
- for(i=0;i<glob_argc;i++)
- fprintf(fp,"\t[%d]: '%s'\n",i,glob_argv[i]);
- fprintf(fp,"-----------------------------------------\n");
- fprintf(fp,"Environment variables\n\n");
- for(i=0;glob_env[i] != NULL;i++)
- fprintf(fp,"\t'%s'\n",glob_env[i]);
-
- if(glob_clen > 0)
- {
- fprintf(fp,"-----------------------------------------\n");
- fprintf(fp,"Content (%d)\n\n",glob_clen);
- for(i=0;i<glob_clen;i++)
- fputc(glob_content[i],fp);
- }
-
- fflush(fp);
-
- return ret_code;
- }
-
- char *strsave(char *s)
- {
- char *p = NULL;
- int len = 0;
- if(!s)
- return NULL;
- len = strlen(s);
- p = (char *)malloc(len+1);
- if(!p)
- return NULL;
- strcpy(p,s);
- return p;
- }
-
- char *UrlEncode(char *s)
- {
- char *out = (char *)malloc(strlen(s)*3 + 1);
- char *p = out;
- int i = 0;
- int slen = strlen(s);
- int ch;
-
- for(i=0;i<slen;i++)
- {
- ch = s[i];
- if(ch == ' ')
- *p++ = '+';
- else if(ch > ' ' && ch <= '~' && ch != '&' && ch != '+' && ch != '%' && ch != '=')
- *p++ = ch;
- else
- {
- // convert to hex
- *p++ = '%';
- sprintf(p,"%02x",ch);
- p += 2;
- }
- }
-
- *p = 0;
-
- return out;
- }
-
- char *make_env_str()
- {
- int tlen = 0;
- int i = 0;
-
- /* get required length */
- for(i=0;glob_env[i] != NULL;i++)
- {
- tlen += strlen(glob_env[i]);
- }
-
- char *str = (char *)malloc(tlen * 3 + 1);
- str[0] = 0;
- char *p = str;
- int first = 1;
-
- /* create form-url-encoded dictionary string */
- for(i=0;glob_env[i] != NULL;i++)
- {
- if(first)
- first = 0;
- else
- *p++ = '&';
- char *attr = strsave(glob_env[i]);
- char *value = strchr(attr,'=');
- *value++ = 0;
- char *u_attr = UrlEncode(attr);
- char *u_value = UrlEncode(value);
- sprintf(p,"%s=%s",u_attr,u_value);
- p += strlen(p);
- free(attr);
- free(u_attr);
- free(u_value);
- }
-
- return str;
- }
-
- int do_ole_stuff()
- {
- CLSID clsid;
- HRESULT hresult;
- char *path_info = getenv("PATH_INFO");
- char progid[_MAX_PATH];
- char msg[_MAX_PATH];
- int failed = 0;
- DISPID dispid;
- DISPPARAMS dispparams;
- VARIANTARG varg[2];
- VARIANTARG vargResult;
- int MaxParms = 2;
- int i;
- char *envstr = NULL;
- IDispatch FAR *pIDispatch;
- IUnknown FAR *punk = NULL;
- char *pMeth = _T("CGI");
- OLECHAR FAR *szMethodName = NULL;
- BSTR arg1 = NULL;
- BSTR arg2 = NULL;
- EXCEPINFO exinfo;
- char *emsg = NULL;
-
- USES_CONVERSION;
- szMethodName = T2OLE(pMeth);
-
- if(!path_info)
- {
- return cgi_error("script wasn't given PATH_INFO argument",1);
- }
-
- if(OleInitialize(NULL) != S_OK)
- {
- return cgi_error("unable to initialize OLE library",1);
- }
-
- sprintf(progid,"CGIHandler.%s",path_info+1); // skip initial slash
- hresult = CLSIDFromProgID(T2OLE(progid),&clsid);
- if(FAILED(hresult))
- {
- sprintf(msg,"unable to find OLE object '%s' in registry",progid);
- cgi_error(msg,1);
- goto OleShutdown;
- }
-
- hresult = CoCreateInstance(clsid,NULL,CLSCTX_SERVER,
- IID_IUnknown,(void FAR * FAR *)&punk);
- if(FAILED(hresult))
- {
- sprintf(msg,"unable to get OLE IUnknown interface to object '%s'",progid);
- cgi_error(msg,1);
- goto OleShutdown;
- }
-
- hresult = punk->QueryInterface(IID_IDispatch,(void FAR * FAR *)&pIDispatch);
- if(FAILED(hresult))
- {
- punk->Release();
- sprintf(msg,"unable to get OLE IDispatch interface to object '%s'",progid);
- cgi_error(msg,1);
- goto OleShutdown;
- }
-
- punk->Release();
-
- // init variables
- for(i=0;i<MaxParms;i++)
- VariantInit(&varg[i]);
- VariantInit(&vargResult);
-
- envstr = make_env_str();
-
- arg1 = envstr ? SysAllocString(T2OLE(envstr)) : SysAllocString(T2OLE(""));
- arg2 = glob_content ? SysAllocString(T2OLE(glob_content)) : SysAllocString(T2OLE(""));
-
- /* sending to VB OLE server, arg passing order gets reversed;
- like arg3=arg1, arg2=arg2, arg3=arg1; so reverse them here */
- V_VT(&varg[0]) = VT_BSTR;
- V_BSTR(&varg[0]) = arg2;
- V_VT(&varg[1]) = VT_BSTR;
- V_BSTR(&varg[1]) = arg1;
-
- dispparams.rgvarg = varg;
- dispparams.rgdispidNamedArgs = NULL;
- dispparams.cArgs = MaxParms;
- dispparams.cNamedArgs = 0;
-
- hresult = pIDispatch->GetIDsOfNames(IID_NULL,&szMethodName,1,
- LOCALE_SYSTEM_DEFAULT,&dispid);
- if(FAILED(hresult))
- {
- sprintf(msg,"unable to get OLE DispID for '%s' method of object '%s'",pMeth,progid);
- cgi_error(msg,1);
- failed = 1;
- goto ClearArgs;
- }
-
- hresult = pIDispatch->Invoke(dispid,IID_NULL,LOCALE_SYSTEM_DEFAULT,
- DISPATCH_METHOD,&dispparams,&vargResult,&exinfo,NULL);
- if(FAILED(hresult))
- {
- sprintf(msg,"unable to perform OLE Invoke of '%s' method of object '%s'",pMeth,progid);
- cgi_error(msg,1);
- if(hresult == DISP_E_EXCEPTION)
- {
- if(exinfo.pfnDeferredFillIn != NULL)
- (*exinfo.pfnDeferredFillIn)(&exinfo);
- printf("\n\n-----------------------\n");
- printf("OLE Dispatch Exception Info\n\n");
- emsg = exinfo.bstrSource ? OLE2T(exinfo.bstrSource) : "(not set)";
- printf("Object: %s\n",emsg);
- emsg = exinfo.bstrDescription ? OLE2T(exinfo.bstrDescription) : "(not set)";
- printf("Description: %s\n",emsg);
- printf("wCode: %d\n",exinfo.wCode);
- printf("scode: 0x%08x\n",exinfo.scode);
- SysFreeString(exinfo.bstrDescription);
- SysFreeString(exinfo.bstrHelpFile);
- }
- failed = 1;
- goto ClearReturn;
- }
-
- /* see if got a BSTR */
- if(V_VT(&vargResult) != VT_BSTR)
- {
- sprintf(msg,"value returned from OLE Invoke of '%s' method of object '%s' is not BSTR",szMethodName,progid);
- cgi_error(msg,1);
- failed = 1;
- }
-
- /* send results back to server */
- fwrite(OLE2T(V_BSTR(&vargResult)),1,strlen(OLE2T(V_BSTR(&vargResult))),stdout);
-
- ClearReturn:
- VariantClear(&vargResult);
- ClearArgs:
- for(i=0;i<MaxParms;i++)
- VariantClear(&varg[i]);
-
- pIDispatch->Release();
-
- OleShutdown:
- OleUninitialize();
-
- if(envstr)
- free(envstr);
-
- return failed;
- }
-
- /* ---- main --------- */
-
- int main(int argc, char *argv[], char *env[])
- {
- char *exe_path = NULL;
- int clen = 0;
- char *p = NULL;
- char *query_info = NULL;
- int tmpnum = 0;
- FILE *fp = NULL;
- int i = 0;
-
- /* set up globals so cgi_error can report them */
- glob_argc = argc;
- glob_argv = &argv[0];
- glob_env = &env[0];
-
- /* XXX - if we're running under CGI-WIN interface, should report
- error and exit; but it doesn't work yet */
-
- /*
- p = getenv("GATEWAY_INTERFACE");
- if(!p || strstr(p,"(Win)"))
- {
- if(argc > 1)
- {
- glob_cgiwin = 1;
- glob_cgiwin_out[0] = 0;
- return 0;
- }
- }
- else
- return cgi_error("expected GATEWAY_INTERFACE environment variable",0);
- */
-
- /* read in any content */
-
- p = getenv("CONTENT_LENGTH");
- if(p)
- clen = atoi(p);
- if(clen > 0)
- {
- // extern int _setmode(int,int);
- int fd = -1;
- /* must reset to binary mode to read in content */
- p = (char *)malloc(clen+1);
- if(!p)
- return cgi_error("out of memory",0);
- fd = _fileno(stdin);
- _setmode(fd,_O_BINARY);
- if(fread(p,1,clen,stdin) != (unsigned int)clen)
- {
- free(p);
- return cgi_error("couldn't read content",0);
- }
- glob_content = p;
- glob_clen = clen;
- glob_content[glob_clen] = 0;
- }
-
- /* attach OLE server, pass data to it, get results, return them, detach server */
- do_ole_stuff();
-
- if(glob_content)
- free(glob_content);
-
- return 0;
- }
-
-