home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / winfe / ddectc.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  9.4 KB  |  320 lines

  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2.  *
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  *
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  *
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18. #include "stdafx.h"
  19.  
  20. #include "wfedde.h"
  21. #include "ddectc.h"
  22. #include "cxsave.h"
  23. #include "extgen.h"
  24.  
  25. extern "C" int MK_DISK_FULL;     // defined in allxpstr.h
  26.  
  27. CDDEStreamData::CDDEStreamData(const char *pServer, const char *pMimeType,
  28.     DWORD dwSDIFlags, BOOL bQueryViewer) : CStreamData(CStreamData::m_DDE)    {
  29. //    Purpose:    Construct the data stream object.
  30. //    Arguments:    pServer    The name of the server that we should contact
  31. //                            in our data stream.
  32. //                pMimeType    The mime type fo the stream.
  33. //                dwSDIFlags    How we should contact the server.  This will
  34. //                                converted into an internal type.
  35. //                bQueryViewer    Wether or not we should query a remote applciation
  36. //                                    for the file in which we should save our data.
  37. //    Returns:    none
  38. //    Comments:    Note that we initialize the base class to know we are a DDE
  39. //                    viewer.
  40. //    Revision History:
  41. //        01-06-95    created GAB
  42. //
  43.  
  44.     //    Simply assign the members over for now.
  45.     m_csServerName = pServer;
  46.     m_csMimeType = pMimeType;
  47.     m_bQueryViewer = bQueryViewer;
  48.     
  49.     switch(dwSDIFlags)    {
  50.     case 0x1L:
  51.         m_dwHowHandle = m_OpenDocument;
  52.         break;
  53.     case 0x4L:
  54.         m_dwHowHandle = m_ViewDocFile;
  55.         break;
  56.     case 0x8L:
  57.         m_dwHowHandle = m_ViewDocData;
  58.         break;
  59.     }
  60. }
  61.  
  62. CDDEDownloadData::CDDEDownloadData(CDDEStreamData *pCData,
  63.     const char *pAddress, DWORD dwFrameID)    {
  64. //    Purpose:    Create an instance of the download data.
  65. //    Arguments:    pCData    A global object representing our DDE registered
  66. //                            viewer.
  67. //                pAddress    The URL we're loading, we'll use this to
  68. //                                construct a file name, and open it.
  69. //                dwFrameID    The frame performing the download.
  70. //    Returns:    none
  71. //    Comments:    Download instance specific member.
  72. //    Revision History:
  73. //        01-06-95    created GAB
  74. //
  75.  
  76.     //    Assign over our data.
  77.     m_pCData = pCData;
  78.     
  79.     //    Mark so that we know to delete any files that we create at
  80.     //        exit.
  81.     m_bDelete = TRUE;
  82.     
  83.     //    Save the URL/address
  84.     m_csURL = pAddress;
  85.     
  86.     //    Save the frame performing the download.
  87.     m_dwFrameID = dwFrameID;
  88.     
  89.     //    Create the file name.
  90.     //    Attempt to save as much of the file name as possible.
  91.     char *cpFullName = ::fe_URLtoLocalName(pAddress, NULL);
  92.     char *cpTempDir = theApp.m_pTempDir;
  93.     
  94.     if(cpFullName != NULL && cpTempDir != NULL)    {
  95.         char caNameBuffer[_MAX_PATH];
  96.         
  97.         ::sprintf(caNameBuffer, "%s\\%s", cpTempDir, cpFullName);
  98.         if(::_access(caNameBuffer, 0) == -1)    {
  99.             m_csFileName = caNameBuffer;
  100.         }
  101.     }
  102.     
  103.     if(cpFullName != NULL)    {
  104.         ::free(cpFullName);
  105.     }
  106.     
  107.     //    If our file name is still empty, then we must create it another
  108.     //        way, by using only the extension and some random name.
  109.     //  We leave as dot three, as we may be 32 bits yet talking to a 16
  110.     //      bit DDE app.
  111.     if(m_csFileName.IsEmpty())    {
  112.         char caExt[_MAX_EXT];
  113.         DWORD dwFlags = EXT_DOT_THREE;
  114.         size_t stExt = 0;
  115.         
  116.         caExt[0] = '\0';
  117.         stExt = EXT_Invent(caExt, sizeof(caExt), dwFlags, pAddress, NULL);
  118.         
  119.         {
  120.             char* filename = WH_TempFileName(xpTemporary, "M", caExt);
  121.             if (filename) {
  122.                 m_csFileName = filename;
  123.                 XP_FREE(filename);
  124.             }
  125.         }
  126.     }
  127.         
  128.     //    Okay, we've got the file name that will suite our needs.
  129.     TRY    {
  130.         //  Leave as shared readable for DDE apps looking into the file early.
  131.         m_pStream = new CFile(m_csFileName, CFile::modeCreate |
  132.             CFile::modeWrite | CFile::shareDenyWrite);
  133.     }
  134.     CATCH(CFileException, e)    {
  135.         THROW_LAST();        
  136.     }
  137.     END_CATCH
  138. }
  139.  
  140.  
  141. extern "C"    {
  142.  
  143.  NET_StreamClass *dde_stream(int iFormatOut, void *vpDataObj,
  144.     URL_Struct *pURL, MWContext *pContext)    {
  145. //    Purpose:    Return the stream class for our DDE stream.
  146. //    Arguments:    iFormatOut    The representation we are outputting.
  147. //                vpDataObj    Our CDDEStreamData structure.
  148. //                pURL        The URL we're loading.
  149. //                pContext    The current context we're loading in.
  150. //    Returns:    NET_StreamClass    A group of functions that will handle
  151. //                                    the details of the download.
  152. //    Comments:    Set up the data stream.
  153. //                The stream will be lost on completion if the app failed
  154. //                    to unregister itself with us and exited.
  155. //                    Can't really handle.
  156. //    Revision History:
  157. //        01-06-95    created GAB
  158. //        10-20-95    Hacked it up to use a secondary stream through CSaveCX if possible.
  159. //
  160.  
  161.     NET_StreamClass *pRetval = NULL;
  162.  
  163.     //    Convert our data object.
  164.     CDDEStreamData *pCData = (CDDEStreamData *)vpDataObj;
  165.     
  166.     //    Let's not be romantic about this, create our download data
  167.     //        and then the stream class.
  168.     TRY    {
  169.         CDDEDownloadData *pDData =
  170.             new CDDEDownloadData(pCData, pURL->address, FE_GetContextID(pContext));
  171.  
  172.         pRetval = NET_NewStream("PaperbackWriter",
  173.             dde_StreamWrite,
  174.             dde_StreamComplete,
  175.             dde_StreamAbort,
  176.             dde_StreamReady,
  177.             (void *)pDData,
  178.             pContext);
  179.     }
  180.     CATCH(CException, e)    {    //    Any exception will do
  181.         pRetval = NULL;
  182.     }
  183.     END_CATCH
  184.  
  185.     if(pRetval != NULL)    {
  186.         //    Attempt to go beyond, and get a secondary stream going
  187.         //        to split this off into a new context.
  188.         //    I know this says OLE, but it will work anyhow....
  189.         NET_StreamClass *pShunt = CSaveCX::OleStreamObject(pRetval, pURL, pCData->m_csServerName);
  190.         if(pShunt != NULL)    {
  191.             pRetval = pShunt;
  192.         }
  193.     }
  194.     
  195.     return(pRetval);
  196. }
  197.  
  198. int dde_StreamWrite(NET_StreamClass *stream, const char *cpWriteData,
  199.     int32 lLength)    {
  200. //    Purpose:    Write data out to the stream.
  201. //    Arguments:    vpDataObj    Our download instance object.
  202. //                cpWriteData    The data to write.
  203. //                lLength        The amount of data to write.
  204. //    Returns:    int        Return one of the infamous MK_* codes.
  205. //    Comments:    Hacking for a return value, it would seem.
  206. //    Revision History:
  207. //        01-06-95    created GAB
  208. //
  209.  
  210.     //    Obtain our data object.
  211.     CDDEDownloadData *pDData = (CDDEDownloadData *)stream->data_object;    
  212.     
  213.     TRY    {
  214.         ASSERT(lLength < 0x0000FFFFL);
  215.         pDData->m_pStream->Write((const void *)cpWriteData,
  216.             CASTINT(lLength));
  217.     }
  218.     CATCH(CException, e)    {
  219.         //    Just return out of disk space, any exception.
  220.         return(MK_DISK_FULL);
  221.     }
  222.     END_CATCH
  223.         
  224.     return(MK_DATA_LOADED);
  225. }
  226.  
  227. void dde_StreamComplete(NET_StreamClass *stream)    {
  228. //    Purpose:    Called when a stream comes to its successful completion.
  229. //    Arguments:    vpDataObj    Our download instance object
  230. //    Returns:    void
  231. //    Comments:    Just unitialize mainly.
  232. //    Revision History:
  233. //        01-06-95    created
  234. //
  235.  
  236.     //    Get our object.
  237.     CDDEDownloadData *pDData = (CDDEDownloadData *)stream->data_object;    
  238.     
  239.     //    First off, close and free our file object.
  240.     delete(pDData->m_pStream);
  241.     pDData->m_pStream = NULL;
  242.         
  243.     //    Now, see what we're supposed to do with this closed file.
  244.     if(pDData->m_pCData->m_bQueryViewer == TRUE)    {
  245.         //    We're to move the file to a new locale, and then
  246.         //        send whatever open message....
  247.         CDDEWrapper::QueryViewer(pDData);
  248.     }
  249.  
  250.     //    Okay, see if we're supposed to delete this file on exit.
  251.     if(pDData->m_bDelete == TRUE)    {
  252.         FE_DeleteFileOnExit(pDData->m_csFileName, pDData->m_csURL);
  253.     }
  254.         
  255.     //    Switch on how to open.
  256.     switch(pDData->m_pCData->m_dwHowHandle)    {
  257.     case CDDEStreamData::m_OpenDocument:
  258.         //    We're to use a platform specific open, this means
  259.         //        Shell Open to windows.
  260.         CDDEWrapper::OpenDocument(pDData);
  261.         break;
  262.     case CDDEStreamData::m_ViewDocFile:
  263.         //    We're to simply tell the viewer what file to take a
  264.         //        look at.
  265.         //    Have our DDE member handle all the contingencies.
  266.         CDDEWrapper::ViewDocFile(pDData);
  267.         break;
  268.     case CDDEStreamData::m_ViewDocData:
  269.     default:
  270.         //    Not supported.
  271.         ASSERT(0);
  272.         break;
  273.     }
  274.     
  275.     //    We're basically done.
  276.     //    Free off the download specific data.
  277.     delete(pDData);
  278. }
  279.  
  280. void dde_StreamAbort(NET_StreamClass *stream, int iStatus)    {
  281. //    Purpose:    Abort a streaming download.
  282. //    Arguments:    vpDataObj    Our download instance information.
  283. //                iStatus        Our abort status.
  284. //    Returns:    void
  285. //    Comments:    Abort the stream, just as we close a connection.
  286. //                We should send any streaming DDE clients a special
  287. //                    message.
  288. //    Revision History:
  289. //        01-06-95    created GAB
  290. //
  291.  
  292.     //    Get our object.
  293.     CDDEDownloadData *pDData = (CDDEDownloadData *)stream->data_object;    
  294.     
  295.     //    Handle just like a normal file close.
  296.     dde_StreamComplete(stream);
  297. }
  298.  
  299. unsigned int dde_StreamReady(NET_StreamClass *stream)    {
  300. //    Purpose:    Tell the nework library how much data every one is
  301. //                    ready to receive.
  302. //    Arguments:    vpDataObj    Our download instance informational fucntion.
  303. //    Returns:    int    The amount of data the stream is ready for.
  304. //    Comments:    On files, like what we are normally handline, simply
  305. //                    return the maximum amount.
  306. //                On streaming clients, just ask them how much they can
  307. //                    now take.
  308. //    Revision History:
  309. //        01-06-95    created GAB
  310. //
  311.  
  312.     //    Get our object.
  313.     CDDEDownloadData *pDData = (CDDEDownloadData *)stream->data_object;    
  314.     
  315.     //    Return our maximum write value for local files.
  316.     return((unsigned int)MAX_WRITE_READY);
  317. }
  318.  
  319. };
  320.