home *** CD-ROM | disk | FTP | other *** search
- /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- *
- * The contents of this file are subject to the Netscape Public License
- * Version 1.0 (the "NPL"); you may not use this file except in
- * compliance with the NPL. You may obtain a copy of the NPL at
- * http://www.mozilla.org/NPL/
- *
- * Software distributed under the NPL is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
- * for the specific language governing rights and limitations under the
- * NPL.
- *
- * The Initial Developer of this code under the NPL is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1998 Netscape Communications Corporation. All Rights
- * Reserved.
- */
-
- //Created Abe Jarrett: Most of the methods in this class were taken from
- //Garrett's code in dde.cpp. This file is intended only as
- //a means of detecting seconds instance criteria and handling processing
- //of it and any command line content as well.
-
- #include "stdafx.h"
-
- #include "ddecmd.h"
- #include "ddectc.h"
-
-
- // Our DDE instance identifier.
- DWORD CDDECMDWrapper::m_dwidInst;
-
- // Wether or not DDE was successfully initialized.
- BOOL CDDECMDWrapper::m_bDDEActive;
-
- // Our array of hsz strings.
- HSZ CDDECMDWrapper::m_hsz[CDDECMDWrapper::m_MaxHSZ];
-
- // A list of all current conversations. The PtrToPtr map was used since
- // the pointers are known to be 32 bits long, and the HCONV is a
- // DWORD or possibly a pointer, and WordToPtr just wouldn't cut it
- // with 16 bits and all.
- // Sounds good to me!
- CMapPtrToPtr CDDECMDWrapper::m_ConvList;
-
- // Command filter for DDEML
- DWORD CDDECMDWrapper::m_dwafCmd;
-
- // Call back function for use with DDEML
- FARPROC CDDECMDWrapper::m_pfnCallBack;
-
-
- //This kicks it all off.
- void DDEInitCmdLineConversation()
- {
-
- CDDECMDWrapper::m_pfnCallBack = NULL;
-
- #ifdef XP_WIN16
- // Find out if we can even use DDEML (must be in protected mode).
- // Undoubtedly, this is the case since we must be in protected
- // mode to use WINSOCK services, but just to be anal....
- // GetWinFlags() has been removed in MSVC 2.0 and the analog doesn't
- // look like it does the same thing. chouck 29-Dec-94
- if(!(GetWinFlags() & WF_PMODE)) {
- // Not in protected mode, can not continue with DDEML
- return ;
- }
- #endif
-
- // Set up our callback function to be registered with DDEML.
- CDDECMDWrapper::m_pfnCallBack = (FARPROC)CmdLineDdeCallBack;
-
-
- if(DdeInitialize(&CDDECMDWrapper::m_dwidInst,
- (PFNCALLBACK)CDDECMDWrapper::m_pfnCallBack,
- CDDECMDWrapper::m_dwafCmd, 0L)) {
- // Unable to initialize, don't continue.
- return ;
- }
-
-
- CDDECMDWrapper::m_bDDEActive = TRUE;
-
- // Load in all HSZs.
- // Unfortunately, there is really no good way to detect any errors
- // on these string intializations, so let the blame land
- // where it will if something fails.
- CString strCS;
-
- strCS.LoadString(IDS_DDE_CMDLINE_SERVICE_NAME);
- CDDECMDWrapper::m_hsz[CDDECMDWrapper::m_ServiceName] =
- DdeCreateStringHandle(CDDECMDWrapper::m_dwidInst,
- (char *)(const char *)strCS, CP_WINANSI);
-
- strCS.LoadString(IDS_DDE_PROCESS_CMDLINE);
- CDDECMDWrapper::m_hsz[CDDECMDWrapper::m_ProcessCmdLine] =
- DdeCreateStringHandle(CDDECMDWrapper::m_dwidInst,
- (char *)(const char *)strCS, CP_WINANSI);
-
- }
-
-
- // Purpose: Construct a DDECMDWrapper object
- // Arguments: hszService The name of the service we are handling.
- // hszTopic The name of the topic we are handling.
- // hConv The handle of the conversation we are
- // handling.
- // Returns: nothing
- // Comments: Handles all created objects internally through a map.
- // Revision History:
- //
- CDDECMDWrapper::CDDECMDWrapper(HSZ hszService, HSZ hszTopic, HCONV hConv)
- {
- // Set our members passed in.
- m_hszService = hszService;
- m_hszTopic = hszTopic;
- m_hConv = hConv;
-
- // Figure out our enumerated service number.
- // We know this anyhow, we only have one service name at this
- // point.
- m_iService = m_ServiceName;
-
- // Figure out our enumerated topic number.
- m_iTopic = EnumTopic(hszTopic);
-
- // Add ourselves to the current map of conversations.
- m_ConvList.SetAt((void *)hConv, this);
- }
-
-
- // Purpose: Destory a CDDECMDWrapper object
- // Arguments: void
- // Returns: nothing
- // Comments: Removes us from the internally handled list
- // Revision History:
- //
-
- CDDECMDWrapper::~CDDECMDWrapper()
- {
- // Remove ourselves from the list of current conversations.
- m_ConvList.RemoveKey((void *)m_hConv);
- }
-
-
-
- // Purpose: Connect to a service using a specific topic
- // Arguments: cpService The service name of the DDE server
- // hszTopic The topic of the conversation to the server
- // Returns: CDDECMDWrapper * The conversation object if established,
- // otherwise NULL.
- // Comments: Generic connection establishment.
- // Revision History:
- // 01-05-95 created GAB
- CDDECMDWrapper *CDDECMDWrapper::ClientConnect(const char *cpService,
- HSZ& hszTopic)
- {
- CDDECMDWrapper *pConv = NULL;
-
- // Make the service name into an HSZ.
- HSZ hszService = DdeCreateStringHandle(m_dwidInst,
- (char *) cpService,
- CP_WINANSI);
- if(hszService == NULL) {
- return(NULL);
- }
-
- // Establish the connection.
- HCONV hConv = DdeConnect(m_dwidInst, hszService, hszTopic, NULL);
- if(hConv != NULL) {
- // We have a connection, all that's left to do is to create
- // a CDDECMDWrapper, we'll be creating it with the wrong
- // service name of course, but client connections no
- // longer really care about the service connection number,
- // all they need is the conversation handle.
- pConv = new CDDECMDWrapper(m_hsz[m_ServiceName], hszTopic, hConv);
- }
-
- // Free off our created hsz.
- DdeFreeStringHandle(m_dwidInst, hszService);
-
-
- return(pConv);
- }
-
- // Purpose: Figure out which wrapper is associated with a conversation.
- // Arguments: hConv The conversation to find out about.
- // Returns: CDDECMDWrapper * A pointer to the CDDECMDWrapper that is
- // handling the conversation, or NULL
- // if none is present.
- // Comments: Shouldn't ever return NULL really.
- // Revision History:
- // 12-30-94 created GAB
- // 12-04-96 reused by AJ. Probably not necessary, but you never know
- // know when we may have to do more than one conversation.
- CDDECMDWrapper *CDDECMDWrapper::GetConvObj(HCONV hConv)
- {
- // Query our static map of conversations for the object.
- void *pWrap;
-
- if(m_ConvList.Lookup((void *)hConv, pWrap) == 0) {
- return(NULL);
- }
- return((CDDECMDWrapper *)pWrap);
- }
-
-
- // Purpose: Return the offset of the hsz topic string in our static
- // m_hsz array
- // Arguments: hsz The HSZ string to find in our array
- // Returns: int The offset into the array, also correlating to
- // it's enumerated value. If not found, the
- // returned failure value is 0.
- // Comments: Mainly coded to remove redundant lookups. Modularity...
- // Revision History:
- // 12-30-94 created GAB
- // 12-04-96 reused by AJ. Probably not necessary, but you never know
- // know when we may have to handle more than one topic.
- int CDDECMDWrapper::EnumTopic(HSZ& hsz)
- {
- int i_retval = 0;
- int i_counter;
-
- // Just start looking for the HSZ string in our static array.
- for(i_counter = m_TopicStart; i_counter < m_MaxHSZ; i_counter++)
- {
- if(m_hsz[i_counter] == hsz) {
- i_retval = i_counter;
- break;
- }
- }
-
- return(i_retval);
- }
-
- HDDEDATA
- CALLBACK
- #ifndef XP_WIN32
- _export
- #endif
-
- CmdLineDdeCallBack(UINT type, UINT fmt,
- HCONV hconv, HSZ hsz1, HSZ hsz2, HDDEDATA hData, DWORD dwData1,
- DWORD dwData2)
- {
-
-
- // Depending on the class of transaction, we return different data.
- if(type & XCLASS_BOOL) {
- // Must return (HDDEDATA)TRUE or (HDDEDATA)FALSE
- switch(type) {
-
- case XTYP_CONNECT: {
- // We are the server.
- // A client call the DdeConnect specifying a service and
- // topic name which we support.
- HSZ& hszTopic = hsz1;
- HSZ& hszService = hsz2;
-
- // Deny the connection if the service name is not the
- // one we are taking connections for.
- if(hszService !=
- CDDECMDWrapper::m_hsz[CDDECMDWrapper::m_ServiceName]) {
- return((HDDEDATA)FALSE);
- }
-
- // Now, the topic can be NULL, or it can be any one of our
- // topic names to be accepted.
- if(hszTopic == NULL) {
- return((HDDEDATA)TRUE);
- }
-
- // Go through all our topics, see if we match.
- if(0 != CDDECMDWrapper::EnumTopic(hszTopic)) {
- return((HDDEDATA)TRUE);
- }
-
- // Topic not supported
- return((HDDEDATA)FALSE);
- }
- default:
- // unknown
- return((HDDEDATA)FALSE);
- }
-
- // Break handled here
- return((HDDEDATA)FALSE);
- }
- else if(type & XCLASS_DATA) {
- // Must return DDE data handle, CBR_BLOCK, or NULL
- return(NULL);
- }
- else if(type & XCLASS_FLAGS) {
- // Must return DDE_FACK, DDE_BUSY, or DDE_FNOTPROCESSED
- switch(type) {
- case XTYP_ADVDATA: {
- // We are the client.
- // The server gave us a data handle.
- break;
- }
- case XTYP_EXECUTE: {
- // We are the server.
- // A client said XTYP_EXECUTE in DdeClientTransaction
- HDDEDATA& hDataExecute = hData;
- char *pData = (char *)DdeAccessData(hDataExecute, NULL);
- char szCmd[_MAX_PATH+12];
- strcpy ( szCmd, "[cmdline(\"" );
- strcat ( szCmd, pData );
- strcat ( szCmd, "\")]" );
- BOOL bRetval = theApp.OnDDECommand(szCmd);
-
- DdeUnaccessData(hDataExecute);
- return((HDDEDATA) bRetval);
- }
-
- default:
- // unknown
- return(DDE_FNOTPROCESSED);
- }
-
- // Break handled here
- return(DDE_FNOTPROCESSED);
- }
- else if(type & XCLASS_NOTIFICATION) {
- // Must return NULL, as the return value is ignored
- switch(type) {
- case XTYP_ADVSTOP: {
- // We are the server
- // A client said XTYP_ADVSTOP in DdeClientTransaction
- break;
- }
- case XTYP_CONNECT_CONFIRM: {
- // We are the server.
- // We returned 1 to a XTYP_CONNECT transaction.
-
- // This callback is mainly to inform us of the conversation
- // handle that now exists, but we will actually be
- // creating an instance of an object to handle this
- // conversation from now on.
- HSZ& hszTopic = hsz1;
- HSZ& hszService = hsz2;
-
- // Create the object, correctly initialized so that
- // it understands the service, topic, and conversation
- // it is handling.
- // It will add itself to the conversation list.
- CDDECMDWrapper *pObject = new CDDECMDWrapper(hszService, hszTopic,
- hconv);
- break;
- }
- case XTYP_DISCONNECT: {
- // We are either client/server
- // The partner in the conversation called DdeDisconnect
- // causing both client/server to receive this.
-
- // Find out which conversation object we are dealing with.
- CDDECMDWrapper *pWrapper = CDDECMDWrapper::GetConvObj(hconv);
-
- // Simply delete it.
- // The object takes care of removing itself from the list.
- if(pWrapper != NULL) {
- delete pWrapper;
- }
- break;
- }
- case XTYP_ERROR: {
- // We are either client/server
- // A serious error has occurred.
- // DDEML doesn't have any resources left to guarantee
- // good communication.
- break;
- }
- case XTYP_REGISTER: {
- // We are either client/server
- // A server application used DdeNameService to register
- // a new service name.
- break;
- }
- case XTYP_UNREGISTER: {
- // We are either client/server
- // A server applciation used DdeNameService to unregister
- // an old service name.
- break;
- }
- case XTYP_XACT_COMPLETE: {
- // We are the client
- // An asynchronous tranaction, sent when the client specified
- // the TIMEOUT_ASYNC flag in DdeClientTransaction has
- // concluded.
- break;
- }
- default:
- // unknown
- return(NULL);
- }
- return(NULL);
- }
-
- // Unknown class type
- return(NULL);
-
- }
-
-
-