home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / winfe / shcut.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  12.9 KB  |  406 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.  
  19. #include "stdafx.h"
  20. #include "string.h"
  21. #include "shcut.h"
  22.  
  23. CInternetShortcut::CInternetShortcut (  const char * pszFilename, char * pszURL )
  24. {
  25. #if defined(XP_WIN32) && _MSC_VER >= 1100
  26.  
  27.     HRESULT hres;
  28.     IUniformResourceLocator * purl;
  29.  
  30.     hres = CoCreateInstance (
  31.         CLSID_InternetShortcut, NULL, CLSCTX_INPROC_SERVER,
  32.         IID_IUniformResourceLocator, (void **)&purl );
  33.  
  34.     if ( SUCCEEDED(hres) )
  35.     {
  36.         IPersistFile * ppf;
  37.         WORD wsz[MAX_PATH];
  38.  
  39.         MultiByteToWideChar ( CP_ACP, 0, pszFilename, -1, wsz, MAX_PATH );
  40.         hres = purl->QueryInterface ( IID_IPersistFile, (void **)&ppf );
  41.  
  42.         if ( SUCCEEDED(hres) )
  43.         {
  44.             m_filename = pszFilename;                        
  45.             if ( ( pszFilename != NULL ) && ( pszURL == NULL ) )
  46.             {
  47.                 char * pszURL;
  48.                 IMalloc * pmalloc;
  49.                 hres = ppf->Load ((LPCOLESTR)wsz, STGM_READ );
  50.                 
  51.                 if ( SUCCEEDED(hres) )
  52.                 {
  53.                     purl->GetURL ( (PSTR*)&pszURL );
  54.                     m_URL = pszURL;
  55.                     hres = CoGetMalloc ( MEMCTX_TASK, (LPMALLOC*)&pmalloc);
  56.                     if ( SUCCEEDED(hres) )
  57.                     {
  58.                         if ( pmalloc->DidAlloc ( pszURL ) == 1 )
  59.                             pmalloc->Free( pszURL );
  60.                         pmalloc->Release ( );
  61.                     }
  62.                 }
  63.             }
  64.             else
  65.             {
  66.                 m_URL = pszURL;
  67.                 purl->SetURL ( pszURL, 0 );
  68.                 hres = ppf->Save ((LPCOLESTR)wsz, STGM_READ );
  69.                 
  70.                 if ( !SUCCEEDED(hres) )
  71.                 {
  72.                     switch ( hres ) 
  73.                     {
  74.                         case URL_E_INVALID_SYNTAX:
  75.                             AfxMessageBox ( szLoadString(IDS_URL_INVALID) );
  76.                             break;
  77.  
  78.                         case URL_E_UNREGISTERED_PROTOCOL:
  79.                             AfxMessageBox ( szLoadString(IDS_URL_UNREGISTERED) );
  80.                             break;
  81.  
  82.                         default:
  83.                             AfxMessageBox ( szLoadString(IDS_URL_SAVEFAILED) );
  84.                             break;
  85.                     }
  86.                 }
  87.                 
  88.                 ppf->SaveCompleted ((LPCOLESTR)wsz);
  89.             }
  90.             ppf->Release ( );            
  91.         }
  92.         purl->Release ( );
  93.     }
  94. #endif /* XP_WIN32 */
  95. }
  96.  
  97. void CInternetShortcut::GetURL ( char * urlBuffer, int urlBuffSize )
  98. {
  99.     strncpy ( urlBuffer, m_URL, urlBuffSize );
  100. }
  101.  
  102. CInternetShortcut::CInternetShortcut ( void )
  103. {
  104.     m_URL = _T("");
  105.     m_filename = _T("");
  106. }
  107.  
  108. BOOL CInternetShortcut::ShellSupport ( )
  109. {
  110. #if defined(XP_WIN16) || _MSC_VER < 1100
  111.  
  112.     return(FALSE);
  113.  
  114. #else
  115.  
  116.     int supportsInternetShortcuts = -1;
  117.     if ( supportsInternetShortcuts == -1 )
  118.     {
  119.         HRESULT hres;
  120.         IUniformResourceLocator * purl;
  121.  
  122.         hres = CoCreateInstance (
  123.             CLSID_InternetShortcut, NULL, CLSCTX_INPROC_SERVER,
  124.             IID_IUniformResourceLocator, (void **)&purl );
  125.  
  126.         if ( SUCCEEDED(hres) )
  127.         {
  128.             purl->Release ( );
  129.             supportsInternetShortcuts = (int)TRUE;    
  130.         }
  131.         else
  132.             supportsInternetShortcuts = (int)FALSE;        
  133.     }
  134.     return (BOOL) supportsInternetShortcuts;
  135.  
  136. #endif
  137.  
  138. }
  139.  
  140.  
  141. HRESULT ResolveShortCut ( HWND hwnd, LPCSTR pszShortcutFile, LPSTR pszPath)
  142. {
  143. #if defined(XP_WIN32) && _MSC_VER >= 1100
  144.  
  145.   HRESULT hres;
  146.   IShellLink* psl;
  147.   WIN32_FIND_DATA wfd;
  148.  
  149.   *pszPath = 0;   // assume failure
  150.  
  151.   // Get a pointer to the IShellLink interface.
  152.   hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
  153.                             IID_IShellLink, (void**)&psl);
  154.   if (SUCCEEDED(hres))
  155.   {
  156.     IPersistFile* ppf;
  157.     // Get a pointer to the IPersistFile interface.
  158.     hres = psl->QueryInterface(IID_IPersistFile, (void**)&ppf);
  159.     if (SUCCEEDED(hres))
  160.     {
  161.       WORD wsz[MAX_PATH];
  162.  
  163.       // Ensure string is Unicode.
  164.       MultiByteToWideChar(CP_ACP, 0, pszShortcutFile, -1, wsz,
  165.                                  MAX_PATH);
  166.  
  167.     hres = ppf->Load((LPCOLESTR)wsz, STGM_READ);
  168.      
  169.      if (SUCCEEDED(hres))
  170.      {
  171.         char szGotPath[MAX_PATH];
  172.        // Resolve the link.
  173.        hres = psl->Resolve(hwnd, SLR_ANY_MATCH);
  174.        if (SUCCEEDED(hres))
  175.        {
  176.           strcpy(szGotPath, pszShortcutFile);
  177.           // Get the path to the link target.
  178.           hres = psl->GetPath(szGotPath, MAX_PATH, (WIN32_FIND_DATA *)&wfd, 
  179.                  SLGP_SHORTPATH );
  180.           if (!SUCCEEDED(hres))
  181.              AfxMessageBox( szLoadString(IDS_GETPATH_FAILED) );
  182.           strcpy ( pszPath, szGotPath );
  183.         }
  184.       }
  185.       // Release pointer to IPersistFile interface.
  186.       ppf->Release();
  187.     }
  188.     // Release pointer to IShellLink interface.
  189.     psl->Release();
  190.   }
  191.   return hres;
  192.  
  193. #else
  194.   return 0;
  195. #endif
  196. }
  197.  
  198. // Add internet shortcut info to the data source
  199.  
  200. void DragInternetShortcut ( 
  201.     COleDataSource * pDataSource,       // OleDataSource object to attach data
  202.     LPCSTR lpszTitle,                    // URL description
  203.     LPCSTR lpszAddress )                 // URL
  204. {
  205. #ifdef WIN32
  206.     CInternetShortcut InternetShortcut;
  207.     if ( !InternetShortcut.ShellSupport ( ) )   // support for internet shortcuts?
  208.         return;                                 
  209.  
  210.     // who frees this guy?
  211.     // allocate memory for FILEDESCRIPTOR object which contains a list of droppable
  212.     // files        
  213.     HGLOBAL hfgd = GlobalAlloc(GMEM_ZEROINIT|GMEM_SHARE,sizeof(FILEGROUPDESCRIPTOR));
  214.     if ( !hfgd ) return;
  215.     LPFILEGROUPDESCRIPTOR lpfgd = (LPFILEGROUPDESCRIPTOR) GlobalLock ( hfgd );
  216.  
  217.     char szFilename[ _MAX_PATH ];               // shortcut filename
  218.     static char * invalidChars = ",\\/:*?<>|\"~";   // invalid long filename characters
  219.     unsigned pos;                               // array bad character position
  220.     char szNewTitle[ _MAX_PATH ];               // newly created acceptable title
  221.     
  222.     // if there is a specified and there is some text there, use it
  223.     if ( lpszTitle && strlen ( lpszTitle ) ) {
  224.         strncpy ( szFilename, lpszTitle, _MAX_PATH - 50 );
  225.     }
  226.     else {
  227.         // no title specified, use the host part of the url
  228.         char * pHost = NET_ParseURL ( lpszAddress, GET_HOST_PART );
  229.         if ( pHost )
  230.             strncpy ( szFilename, pHost, _MAX_PATH - 50 );
  231.         else
  232.             return;
  233.         XP_FREE(pHost);
  234.     }
  235.  
  236.     szFilename[_MAX_PATH - 51] = '\0';
  237.     // scan the title string to look for invalid long filename characters
  238.     for ( pos = 0; pos < strlen ( invalidChars ); pos++ )
  239.         if ( strchr ( szFilename, invalidChars[ pos ] ) )
  240.         {
  241.  
  242.             int i, j;
  243.             for ( i = j = 0; i < (int)strlen ( szFilename ); i++ )
  244.                 if ( !strchr ( invalidChars, szFilename[ i ] ) )
  245.                     szNewTitle[ j++ ] = szFilename[ i ];
  246.             szNewTitle[ j ] = '\0';
  247.             break;
  248.         }
  249.  
  250.     if ( pos == strlen ( invalidChars ) )
  251.         strcpy ( szNewTitle, szFilename );
  252.  
  253.     // if no title, parse the url, .URL extensions imply an internet 
  254.     // shortcut file
  255.     PR_snprintf(szFilename, sizeof(szFilename), "%s %s.URL", szLoadString(IDS_SHORTCUT_TO), szNewTitle);
  256.  
  257.     // one file in the file descriptor block
  258.     lpfgd->cItems = 1;
  259.     lpfgd->fgd[0].dwFlags = FD_LINKUI;
  260.     strcpy ( lpfgd->fgd[0].cFileName, szFilename );
  261.     GlobalUnlock ( hfgd );
  262.     
  263.     // register the file descriptor clipboard format
  264.     UINT cfFileDescriptor = RegisterClipboardFormat(CFSTR_FILEDESCRIPTOR);
  265.     pDataSource->CacheGlobalData(cfFileDescriptor,hfgd);
  266.  
  267.     // register the clipboard format for file contents
  268.     UINT cfFileContents = RegisterClipboardFormat ( CFSTR_FILECONTENTS );
  269.  
  270.     // FORMATETC supplies format information beyond the standard clipboard
  271.     // formats.  Set up a file contents block with the lindex indicating 
  272.     // the file at position zero in the file descriptor block
  273.     FORMATETC fmetc = { 0, NULL, DVASPECT_CONTENT, 0, TYMED_FILE };
  274.     fmetc.cfFormat = cfFileContents;
  275.  
  276.     // temporary file contents storage
  277.     char * lpStr = (char *)malloc ( 1024 );
  278.  
  279.     // create the file contents for the internet shortcut file... luckily
  280.     // this is just a text file.  The nIconIndex should actually be retreiving
  281.     // the default icon index
  282.     PR_snprintf( lpStr, 1024, "[InternetShortcut]\nURL=%s", lpszAddress );
  283.  
  284.     // global alloc the file contents block and move the contents into
  285.     // shared memory and free the temporary contents block
  286.     HGLOBAL hContents = GlobalAlloc ( GMEM_ZEROINIT|GMEM_SHARE, strlen (lpStr)+1 );
  287.     LPSTR lpszContents = (LPSTR) GlobalLock ( hContents );
  288.     strcpy ( lpszContents, lpStr );
  289.     free ( lpStr );
  290.     GlobalUnlock ( hContents );
  291.  
  292.     // add the new the contents to the data source
  293.     pDataSource->CacheGlobalData(cfFileContents,hContents,&fmetc);
  294. #endif
  295. }
  296.  
  297. void DragMultipleShortcuts(COleDataSource* pDataSource, CString* titleArray, 
  298.                            CString* urlArray, int count)
  299. {
  300. #ifdef WIN32
  301.     CInternetShortcut InternetShortcut;
  302.     if ( !InternetShortcut.ShellSupport ( ) )   // support for internet shortcuts?
  303.         return;                                 
  304.  
  305.     // who frees this guy?
  306.     // allocate memory for FILEDESCRIPTOR object which contains a list of droppable
  307.     // files        
  308.     HGLOBAL hfgd = GlobalAlloc(GMEM_ZEROINIT|GMEM_SHARE,sizeof(FILEGROUPDESCRIPTOR)+(count-1)*sizeof(FILEDESCRIPTOR));
  309.     if ( !hfgd ) return;
  310.     LPFILEGROUPDESCRIPTOR lpfgd = (LPFILEGROUPDESCRIPTOR) GlobalLock ( hfgd );
  311.     lpfgd->cItems = count;  // Init the count info.
  312.  
  313.     for (int i = 0; i < count; i++)
  314.     {
  315.  
  316.         char szFilename[ _MAX_PATH ];               // shortcut filename
  317.         static char * invalidChars = ",\\/:*?<>|\"~";   // invalid long filename characters
  318.         unsigned pos;                               // array bad character position
  319.         char szNewTitle[ _MAX_PATH ];               // newly created acceptable title
  320.     
  321.         LPCSTR lpszTitle = titleArray[i];
  322.         LPCSTR lpszAddress = urlArray[i];
  323.  
  324.         // if there is a specified and there is some text there, use it
  325.         if ( lpszTitle && strlen ( lpszTitle ) ) 
  326.         {
  327.             strncpy ( szFilename, lpszTitle, _MAX_PATH - 50 );
  328.         }
  329.         else 
  330.         {
  331.             // no title specified, use the host part of the url
  332.             char * pHost = NET_ParseURL ( lpszAddress, GET_HOST_PART );
  333.             if ( pHost )
  334.                 strncpy ( szFilename, pHost, _MAX_PATH - 50 );
  335.             XP_FREE(pHost);
  336.         }
  337.  
  338.         szFilename[_MAX_PATH - 51] = '\0';
  339.         // scan the title string to look for invalid long filename characters
  340.         for ( pos = 0; pos < strlen ( invalidChars ); pos++ )
  341.             if ( strchr ( szFilename, invalidChars[ pos ] ) )
  342.         {
  343.             int i, j;
  344.             for ( i = j = 0; i < (int)strlen ( szFilename ); i++ )
  345.                 if ( !strchr ( invalidChars, szFilename[ i ] ) )
  346.                     szNewTitle[ j++ ] = szFilename[ i ];
  347.             szNewTitle[ j ] = '\0';
  348.             break;
  349.         }
  350.  
  351.         if ( pos == strlen ( invalidChars ) )
  352.             strcpy ( szNewTitle, szFilename );
  353.  
  354.         // if no title, parse the url, .URL extensions imply an internet 
  355.         // shortcut file
  356.         PR_snprintf(szFilename, sizeof(szFilename), "%s %s.URL", szLoadString(IDS_SHORTCUT_TO), szNewTitle);
  357.  
  358.         // one file in the file descriptor block
  359.         
  360.         lpfgd->fgd[i].dwFlags = FD_LINKUI;
  361.         strcpy ( lpfgd->fgd[i].cFileName, szFilename );
  362.  
  363.     }
  364.         
  365.     GlobalUnlock ( hfgd );
  366.     
  367.     // register the file descriptor clipboard format
  368.     UINT cfFileDescriptor = RegisterClipboardFormat(CFSTR_FILEDESCRIPTOR);
  369.     pDataSource->CacheGlobalData(cfFileDescriptor,hfgd);
  370.     
  371.     for (i = 0; i < count; i++)
  372.     {
  373.         LPCSTR lpszAddress = urlArray[i]; // Get the item URL
  374.  
  375.         // register the clipboard format for file contents
  376.         UINT cfFileContents = RegisterClipboardFormat ( CFSTR_FILECONTENTS );
  377.  
  378.         // FORMATETC supplies format information beyond the standard clipboard
  379.         // formats.  Set up a file contents block with the lindex indicating 
  380.         // the file at position i in the file descriptor block
  381.         FORMATETC fmetc = { 0, NULL, DVASPECT_CONTENT, i, TYMED_FILE };
  382.         fmetc.cfFormat = cfFileContents;
  383.  
  384.         // temporary file contents storage
  385.         char * lpStr = (char *)malloc ( 1024 );
  386.  
  387.         // create the file contents for the internet shortcut file... luckily
  388.         // this is just a text file.  The nIconIndex should actually be retreiving
  389.         // the default icon index
  390.         PR_snprintf( lpStr, 1024, "[InternetShortcut]\nURL=%s", lpszAddress );
  391.  
  392.         // global alloc the file contents block and move the contents into
  393.         // shared memory and free the temporary contents block
  394.         HGLOBAL hContents = GlobalAlloc ( GMEM_ZEROINIT|GMEM_SHARE, strlen (lpStr)+1 );
  395.         LPSTR lpszContents = (LPSTR) GlobalLock ( hContents );
  396.         strcpy ( lpszContents, lpStr );
  397.         free ( lpStr );
  398.         GlobalUnlock ( hContents );
  399.  
  400.         // add the new the contents to the data source
  401.         pDataSource->CacheGlobalData(cfFileContents,hContents,&fmetc);
  402.     }
  403. #endif
  404.     
  405. }
  406.