/********************************************************************** * * startbrowser.cpp * Copyright (C) 1999 The New Zealand Digital Library Project * * A component of the Greenstone digital library software * from the New Zealand Digital Library Project at the * University of Waikato, New Zealand. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * *********************************************************************/ #include "startbrowser.h" #include #include #include #include #include #include "locate.h" #define SB_COMLEN 1024 #define SB_DDETIMEOUT 60000UL // One minute in milliseconds int numbrowserstarted = 0; static int inited = 0; static DWORD idInst = 0; static HINSTANCE hinst = NULL; static HSZ hszNetscapeName = NULL; static HSZ hszIExploreName = NULL; static HSZ hszOpenURLTopic = NULL; static HSZ hszActivateTopic = NULL; // budget callback HDDEDATA CALLBACK DdeCallback(UINT uType, /* transaction type */ UINT uFmt, /* clipboard data format */ HCONV hconv, /* handle of conversation */ HSZ hsz1, /* handle of string */ HSZ hsz2, /* handle of string */ HDDEDATA hdata, /* handle of global memory object */ DWORD dwData1, /* transaction-specific data */ DWORD dwData2) /* transaction-specific data */ { return (HDDEDATA) NULL; } // returns 0 on failure static int talkdde (HSZ hszServName, HSZ hszSysTopic, char *requeststr) { HSZ hszRequest; HCONV hConv; HDDEDATA result; // try to connect to the newly started browser hConv = DdeConnect (idInst, hszServName, hszSysTopic, (PCONVCONTEXT) NULL); if (hConv == NULL) return 0; hszRequest = DdeCreateStringHandle (idInst, requeststr, CP_WINANSI); result = DdeClientTransaction ( NULL, // pointer to data to pass to server 0, // length of data hConv, // handle to conversation hszRequest, // handle to item name string CF_TEXT, // clipboard data format XTYP_REQUEST, // transaction type SB_DDETIMEOUT, // time-out duration NULL // pointer to transaction result ); if (result != NULL) DdeFreeDataHandle (result); DdeDisconnect(hConv); DdeFreeStringHandle (idInst, hszRequest); return 1; } // returns 0 on failure static int openurl(HSZ hszServName, HSZ hszActivateTopic, HSZ hszOpenURLTopic, char *url) { char requeststr[65600]; // bring the browser to the front, don't worry if this fails talkdde (hszServName, hszActivateTopic, "0xFFFFFFFF,0x0"); // tell the browser to open a url strcpy (requeststr, "\""); strcat (requeststr, url); strcat (requeststr, "\",,0xFFFFFFFF,0x0,,,"); return talkdde (hszServName, hszOpenURLTopic, requeststr); } // returns 0 on failure static int tryconnect(HSZ hszServName, HSZ hszSysTopic) { // try to connect to a running browser HCONV hConv = DdeConnect (idInst, hszServName, hszSysTopic, (PCONVCONTEXT) NULL); if (hConv == NULL) return 0; DdeDisconnect(hConv); return 1; } static void freestrings () { // free up any currently allocated strings if (hszNetscapeName != NULL) DdeFreeStringHandle (idInst, hszNetscapeName); hszNetscapeName = NULL; if (hszIExploreName != NULL) DdeFreeStringHandle (idInst, hszIExploreName); hszIExploreName = NULL; if (hszOpenURLTopic != NULL) DdeFreeStringHandle (idInst, hszOpenURLTopic); hszOpenURLTopic = NULL; if (hszActivateTopic != NULL) DdeFreeStringHandle (idInst, hszActivateTopic); hszActivateTopic = NULL; } static void getbrowserinfo() { freestrings(); hszNetscapeName = DdeCreateStringHandle(idInst,"NETSCAPE",CP_WINANSI); hszIExploreName = DdeCreateStringHandle(idInst,"IExplore",CP_WINANSI); hszOpenURLTopic = DdeCreateStringHandle(idInst,"WWW_OpenURL",CP_WINANSI); hszActivateTopic = DdeCreateStringHandle(idInst,"WWW_Activate",CP_WINANSI); } // returns SB_NOERROR on success, // SB_ALREADYINIT or SB_DDE_FAILINIT on failure int initstartbrowser () { if (inited) return SB_ALREADYINIT; // from nstest if(DdeInitialize(&CDDEObject::m_dwidInst, NstestDdeCallBack, APPCLASS_STANDARD, 0ul)) if (DdeInitialize (&idInst, (PFNCALLBACK) DdeCallback, APPCLASS_STANDARD, 0) != DMLERR_NO_ERROR) { freestrings(); inited = 0; return SB_DDE_FAILINIT; } getbrowserinfo(); inited = 1; return SB_NOERROR; } // returns SB_NOERROR on success, // SB_DDE_FAILDEINIT of failure int deinitstartbrowser () { // make sure this has been inited // not being inited here, however, is not // important if (!inited) return SB_NOERROR; inited = 0; freestrings(); if (DdeUninitialize(idInst)) return SB_NOERROR; return SB_DDE_FAILDEINIT; } // startbrowser will try to start a browser (or connect to a running browser). // // Returns SB_NOERROR on success, // SB_NOTINITED, SB_FAIL_BADFORMAT, SB_FAIL_NOTFOUND, SB_FAIL_NORESOURCES, or // SB_FAILCONNECTBROWSER on failure int startbrowser (char *url, char *browser_exe, char *startdir) { char newcommand[SB_COMLEN]; int usingnetscape = 0; int usingiexplore = 0; if (!inited) return SB_NOTINITED; // has to be inited first // find out which browser we are dealing with strcpy (newcommand, browser_exe); _strlwr (newcommand); if (strstr (newcommand, "netscape.exe") != NULL) { // netscape usingnetscape = 1; } else if (strstr (newcommand, "iexplore.exe") != NULL) { // internet explorer usingiexplore = 1; } // only try to communicate with a running browser if a startdir // is not specified if (startdir == NULL) { if (usingnetscape && hszNetscapeName != NULL && openurl(hszNetscapeName, hszActivateTopic, hszOpenURLTopic, url)) { return SB_NOERROR; } if (usingiexplore && hszIExploreName != NULL && openurl(hszIExploreName, hszActivateTopic, hszOpenURLTopic, url)) { return SB_NOERROR; } } strcpy (newcommand, browser_exe); // don't put the url on the command line for internet explorer if (usingiexplore) { strcat (newcommand, " -nohome"); } else { // will have to put the url on the command line strcat (newcommand, " \""); strcat (newcommand, url); strcat (newcommand, "\""); } // change the working directory (if needed) char cwd[1024]; cwd[0] = '\0'; if (startdir != NULL) { _getcwd(cwd, 1024); _chdir(startdir); } // attempt to start the browser int res = WinExec(newcommand, SW_SHOW); // change the working directory back (if needed) if (startdir != NULL) _chdir(cwd); if (res == ERROR_BAD_FORMAT) return SB_FAIL_BADFORMAT; if ((res == ERROR_FILE_NOT_FOUND) || (res == ERROR_PATH_NOT_FOUND)) return SB_FAIL_NOTFOUND; if (res <= 31) return SB_FAIL_NORESOURCES; ++numbrowserstarted; // if we aren't using iexplore then the url was // put on the command line and there is nothing left to do if (!usingiexplore) return SB_NOERROR; // connect to the browser and get it to open a page, // time out after 1 minute DWORD lastcheck = GetTickCount (); while (DiffTickCounts (lastcheck, GetTickCount()) <= 60000) { if (usingnetscape && hszNetscapeName != NULL && openurl(hszNetscapeName, hszActivateTopic, hszOpenURLTopic, url)) { return SB_NOERROR; } if (usingiexplore && hszIExploreName != NULL && openurl(hszIExploreName, hszActivateTopic, hszOpenURLTopic, url)) { return SB_NOERROR; } } // timed out trying to connect to the browser return SB_FAILCONNECTBROWSER; } // returns SB_NOERROR on success, // SB_NOTINITED, SB_FAILCONNECTBROWSER on failure int browserrunning (char *browser_exe) { char newcommand[SB_COMLEN]; if (!inited) return SB_NOTINITED; // has to be inited first strcpy (newcommand, browser_exe); _strlwr (newcommand); if ((strstr (newcommand, "netscape.exe") != NULL) && (hszNetscapeName != NULL) && tryconnect(hszNetscapeName, hszOpenURLTopic)) { // succeeded connecting to netscape return SB_NOERROR; } else if ((strstr (newcommand, "iexplore.exe") != NULL) && (hszIExploreName != NULL) && tryconnect(hszIExploreName, hszOpenURLTopic)) { // succeeded connecting to internet explorer return SB_NOERROR; } return SB_FAILCONNECTBROWSER; }