isshlink.cpp
Upload User: caisha3
Upload Date: 2013-09-21
Package Size: 208739k
Code Size: 25k
Category:

Windows Develop

Development Platform:

Visual C++

  1. /*
  2.  * isshlink.cpp - IShellLink implementation for Intshcut class.
  3.  */
  4. #include "priv.h"
  5. #include "ishcut.h"
  6. #include "resource.h"
  7. #include <mluisupp.h>
  8. /* Types
  9.  ********/
  10. typedef enum isl_getpath_flags
  11. {
  12.     // flag combinations
  13.     ALL_ISL_GETPATH_FLAGS   = (SLGP_SHORTPATH |
  14.                                SLGP_UNCPRIORITY)
  15. }
  16. ISL_GETPATH_FLAGS;
  17. typedef enum isl_resolve_flags
  18. {
  19.     // flag combinations
  20.     ALL_ISL_RESOLVE_FLAGS   = (SLR_NO_UI |
  21.                                SLR_ANY_MATCH |
  22.                                SLR_UPDATE)
  23. }
  24. ISL_RESOLVE_FLAGS;
  25. /********************************** Methods **********************************/
  26. /*----------------------------------------------------------
  27. Purpose: IShellLink::SetPath method for Intshcut
  28. Note:
  29.     1. SetURL clears the internal pidl.
  30. */
  31. STDMETHODIMP
  32. Intshcut::SetPath(
  33.     LPCTSTR pcszPath)
  34. {
  35.     HRESULT hr;
  36.     ASSERT(IS_VALID_STRUCT_PTR(this, CIntshcut));
  37.     ASSERT(IS_VALID_STRING_PTR(pcszPath, -1));
  38.     // Treat path as literal URL.
  39.     hr = SetURL(pcszPath, 0);
  40.     return(hr);
  41. }
  42. /*----------------------------------------------------------
  43. Purpose: IShellLink::GetPath handler for Intshcut
  44. */
  45. STDMETHODIMP
  46. Intshcut::GetPath(
  47.     IN  LPTSTR           pszBuf,        
  48.     IN  int              cchBuf,
  49.     OUT PWIN32_FIND_DATA pwfd,          OPTIONAL
  50.     IN  DWORD            dwFlags)
  51. {
  52.     HRESULT hres = E_FAIL;
  53.     ASSERT(IS_VALID_STRUCT_PTR(this, CIntshcut));
  54.     ASSERT(IS_VALID_WRITE_BUFFER(pszBuf, TCHAR, cchBuf));
  55.     ASSERT(NULL == pwfd || IS_VALID_WRITE_PTR(pwfd, WIN32_FIND_DATA));
  56.     ASSERT(FLAGS_ARE_VALID(dwFlags, ALL_ISL_GETPATH_FLAGS));
  57.     // Init to default values
  58.     if (pwfd)
  59.         ZeroMemory(pwfd, SIZEOF(*pwfd));
  60.     if (cchBuf > 0)
  61.         *pszBuf = '';
  62.     // Ignore dwFlags.
  63.     hres = InitProp();
  64.     if (SUCCEEDED(hres))
  65.         hres = m_pprop->GetProp(PID_IS_URL, pszBuf, cchBuf);
  66.      
  67.     return hres;
  68. }
  69. /*----------------------------------------------------------
  70. Purpose: IShellLink::SetRelativePath method for Intshcut
  71. */
  72. STDMETHODIMP Intshcut::SetRelativePath(LPCTSTR pcszRelativePath, DWORD dwReserved)
  73. {
  74.     HRESULT hr;
  75.     // dwReserved may be any value.
  76.     ASSERT(IS_VALID_STRUCT_PTR(this, CIntshcut));
  77.     ASSERT(IS_VALID_STRING_PTR(pcszRelativePath, -1));
  78.     hr = E_NOTIMPL;
  79.     ASSERT(IS_VALID_STRUCT_PTR(this, CIntshcut));
  80.     return(hr);
  81. }
  82. /*----------------------------------------------------------
  83. Purpose: IShellLink::SetIDList method for Intshcut
  84. Note:
  85.     1. SetIDList also does SetPath implicitly to update the path (URL)
  86.         to match the pidl.
  87.     2. SetPath only clears the pidl to NULL, so internally we know
  88.         if we really have a pidl for the shortcut. Although GetIDList
  89.         will generate a pidl from path (URL) if we don't have a pidl.
  90. */
  91. STDMETHODIMP Intshcut::SetIDList(LPCITEMIDLIST pcidl)
  92. {
  93.     HRESULT hr;
  94.     ASSERT(IS_VALID_STRUCT_PTR(this, CIntshcut));
  95.     ASSERT(IS_VALID_READ_PTR(pcidl, ITEMIDLIST));
  96.     hr = InitProp();
  97.     if (SUCCEEDED(hr))
  98.     {
  99.         hr = m_pprop->SetIDListProp(pcidl);
  100.         if (SUCCEEDED(hr))
  101.         {
  102.             // if the pidl was set successfully, update the path.
  103.             TCHAR szURL[INTERNET_MAX_URL_LENGTH];
  104.             
  105.             hr = IEGetDisplayName(pcidl, szURL, SHGDN_FORPARSING);
  106.             if (SUCCEEDED(hr))
  107.                 m_pprop->SetURLProp(szURL, 0);
  108.         }
  109.     }
  110.     ASSERT(IS_VALID_STRUCT_PTR(this, CIntshcut));
  111.     return(hr);
  112. }
  113. /*----------------------------------------------------------
  114. Purpose: Get the original pidl set by SetIDList.
  115. Note:
  116.     1. Do not generate a pidl from path if we don't have a pidl.
  117.     2. Return S_OK if we have a pidl, caller must NOT check for
  118.         SUCCEEDED() return.
  119. */
  120. STDMETHODIMP Intshcut::GetIDListInternal(LPITEMIDLIST *ppidl)
  121. {
  122.     HRESULT hres = InitProp();
  123.     if (SUCCEEDED(hres))
  124.     {
  125.         IStream *pStream;
  126.         hres = m_pprop->GetProp(PID_IS_IDLIST, &pStream);
  127.         if ((hres == S_OK) && pStream)
  128.         {
  129.             const LARGE_INTEGER li = {0, 0};
  130.             // reset the seek pointer                                           
  131.             hres = pStream->Seek(li, STREAM_SEEK_SET, NULL);
  132.             if (SUCCEEDED(hres))
  133.                 hres = ILLoadFromStream(pStream, ppidl);
  134.         
  135.             pStream->Release();
  136.         }
  137.     }
  138.     return hres;
  139. }
  140.     
  141. /*----------------------------------------------------------
  142. Purpose: IShellLink::GetIDList method for Intshcut
  143. Note:
  144.     1. If we don't have a pidl from SetIDList, generate a pidl
  145.         from path.
  146. */
  147. STDMETHODIMP Intshcut::GetIDList(LPITEMIDLIST *ppidl)
  148. {
  149.     HRESULT hres;
  150.     ASSERT(IS_VALID_WRITE_PTR(ppidl, LPITEMIDLIST));
  151.     
  152.     if (!ppidl)
  153.         return E_INVALIDARG;
  154.     *ppidl = NULL;
  155.     hres = InitProp();
  156.     if (SUCCEEDED(hres))
  157.     {
  158.         // check if it already as a pidl.
  159.         hres = GetIDListInternal(ppidl);
  160.         if (hres != S_OK)
  161.         {
  162.             // it doesn't have a pidl, get the URL and make a pidl.
  163.             TCHAR szURL[INTERNET_MAX_URL_LENGTH];
  164.     
  165.             hres = m_pprop->GetProp(PID_IS_URL, szURL, ARRAYSIZE(szURL));
  166.             if (SUCCEEDED(hres)) 
  167.             {
  168.                 hres = IECreateFromPath(szURL, ppidl);
  169.             }
  170.         }
  171.     }
  172.     return hres;
  173. }
  174. /*----------------------------------------------------------
  175. Purpose: IShellLink::SetDescription method for Intshcut
  176. */
  177. STDMETHODIMP Intshcut::SetDescription(LPCTSTR pcszDescription)
  178. {
  179.     HRESULT hr;
  180.     BOOL bDifferent;
  181.     ASSERT(IS_VALID_STRUCT_PTR(this, CIntshcut));
  182.     ASSERT(IS_VALID_STRING_PTR(pcszDescription, -1));
  183.     // Set m_pszFile to description.
  184.     bDifferent = (! m_pszDescription ||
  185.                   StrCmp(pcszDescription, m_pszDescription) != 0);
  186.     if (Str_SetPtr(&m_pszDescription, pcszDescription))
  187.     {
  188.         if (bDifferent)
  189.            Dirty(TRUE);
  190.         hr = S_OK;
  191.     }
  192.     else
  193.         hr = E_OUTOFMEMORY;
  194.     ASSERT(IS_VALID_STRUCT_PTR(this, CIntshcut));
  195.     return(hr);
  196. }
  197. STDMETHODIMP Intshcut::_ComputeDescription()
  198. {
  199.     HRESULT hres;
  200.     BSTR bstrTitle = NULL;
  201.     if (_punkSite)
  202.     {
  203.         // Get the title element
  204.         IWebBrowser *pwb;
  205.         hres = _punkSite->QueryInterface(IID_IWebBrowser, (void **)&pwb);
  206.         if (S_OK == hres)
  207.         {
  208.             IDispatch *pDisp;
  209.             hres = pwb->get_Document(&pDisp);
  210.             if (S_OK == hres)
  211.             {
  212.                 IHTMLDocument2 *pDoc;
  213.                 hres = pDisp->QueryInterface(IID_IHTMLDocument2, (void **)&pDoc);
  214.                 if (S_OK == hres)
  215.                 {
  216.                     hres = pDoc->get_title(&bstrTitle);
  217.                     pDoc->Release();
  218.                 }
  219.                 pDisp->Release();
  220.             }
  221.             pwb->Release();
  222.         }
  223.     }
  224.     
  225.     TCHAR *pszUrl;  // The url for this shortcut
  226.     hres = GetURL(&pszUrl);
  227.     if (S_OK == hres)
  228.     {
  229.         TCHAR szDescription[MAX_PATH], *pszTitle = NULL;
  230.         pszTitle = bstrTitle;     
  231.         // We gamble that the URL will always have displayable characters. 
  232.         // This is a bad assumption but if this assumption is violated then
  233.         // there is a good chance that the URL probably cannot even
  234.         // be navigated to
  235.         
  236.         // This description is used as the name of the file verbatim
  237.         // during drag drop - hence it should look like a .url file name
  238.         GetShortcutFileName(pszUrl, pszTitle, NULL, szDescription, ARRAYSIZE(szDescription));
  239.         //PathYetAnotherMakeUniqueName(szTempFileName, szTempFileName, NULL, NULL);
  240.         PathCleanupSpec(NULL, szDescription);
  241.         // Sometimes PathCleanupSpec can end up simply mangling the description if
  242.         // it cannot properly convert the title to ANSI
  243.         // hence we check that we have a proper description
  244.         
  245.         
  246.         if((0 == *szDescription) || (0 == StrCmp(szDescription,TEXT(".url"))))
  247.         {
  248.             // recompute the description without the title
  249.             GetShortcutFileName(pszUrl, NULL, NULL, szDescription, ARRAYSIZE(szDescription));
  250.             PathCleanupSpec(NULL, szDescription);
  251.         }
  252.         hres = SetDescription(szDescription);
  253.         SHFree(pszUrl);
  254.     }
  255.     SysFreeString(bstrTitle);
  256.         
  257.     return hres;
  258. }
  259. // IShellLink::GetDescription method for Intshcut
  260. STDMETHODIMP Intshcut::GetDescription(LPTSTR pszDescription, int cchBuf)
  261. {
  262.     HRESULT hr;
  263.     ASSERT(IS_VALID_STRUCT_PTR(this, CIntshcut));
  264.     ASSERT(IS_VALID_WRITE_BUFFER(pszDescription, TCHAR, cchBuf));
  265.     // Get description from m_pszDescription.
  266.     if (NULL == m_pszDescription)
  267.     {
  268.         _ComputeDescription();
  269.     }
  270.     if (m_pszDescription)
  271.         StrCpyN(pszDescription, m_pszDescription, cchBuf);
  272.     else if (m_pszFile)
  273.     {
  274.         StrCpyN(pszDescription, m_pszFile, cchBuf);
  275.     }
  276.     else
  277.     {
  278.         // use default shortcut name 
  279.         MLLoadString(IDS_NEW_INTSHCUT, pszDescription, cchBuf);
  280.     }
  281.     hr = S_OK;
  282.     ASSERT(IS_VALID_STRUCT_PTR(this, CIntshcut));
  283.     ASSERT(hr == S_OK &&
  284.            (cchBuf <= 0 ||
  285.             (IS_VALID_STRING_PTR(pszDescription, -1) &&
  286.              EVAL(lstrlen(pszDescription) < cchBuf))));
  287.     return(hr);
  288. }
  289. // IShellLink::SetArguments method for Intshcut
  290. STDMETHODIMP Intshcut::SetArguments(LPCTSTR pcszArgs)
  291. {
  292.     return E_NOTIMPL;
  293. }
  294. // IShellLink::GetArguments for Intshcut
  295. STDMETHODIMP Intshcut::GetArguments(LPTSTR pszArgs, int cchBuf)
  296. {
  297.     return E_NOTIMPL;
  298. }
  299. // IShellLink::SetWorkingDirectory handler for Intshcut
  300. STDMETHODIMP Intshcut::SetWorkingDirectory(LPCTSTR pcszWorkingDirectory)
  301. {
  302.     HRESULT hres = S_OK;
  303.     TCHAR rgchNewPath[MAX_PATH];
  304.     BOOL bChanged = FALSE;
  305.     ASSERT(IS_VALID_STRUCT_PTR(this, CIntshcut));
  306.     ASSERT(! pcszWorkingDirectory ||
  307.            IS_VALID_STRING_PTR(pcszWorkingDirectory, -1));
  308.     if (! AnyMeat(pcszWorkingDirectory))
  309.         pcszWorkingDirectory = NULL;
  310.     if (pcszWorkingDirectory)
  311.     {
  312.         LPTSTR pszFileName;
  313.         if (GetFullPathName(pcszWorkingDirectory, SIZECHARS(rgchNewPath),
  314.                             rgchNewPath, &pszFileName) > 0)
  315.             pcszWorkingDirectory = rgchNewPath;
  316.         else
  317.             hres = E_PATH_NOT_FOUND;
  318.     }
  319.     if (hres == S_OK)
  320.     {
  321.         TCHAR szDir[MAX_PATH];
  322.         hres = InitProp();
  323.         if (SUCCEEDED(hres))
  324.         {
  325.             hres = m_pprop->GetProp(PID_IS_WORKINGDIR, szDir, SIZECHARS(szDir));
  326.             bChanged = ! ((! pcszWorkingDirectory && S_FALSE == hres) ||
  327.                           (pcszWorkingDirectory && S_OK == hres &&
  328.                            ! StrCmp(pcszWorkingDirectory, szDir)));
  329.             hres = S_OK;
  330.             if (bChanged)
  331.             {
  332.                 hres = m_pprop->SetProp(PID_IS_WORKINGDIR, pcszWorkingDirectory);
  333.             }
  334.         }
  335.     }
  336.     ASSERT(IS_VALID_STRUCT_PTR(this, CIntshcut));
  337.     return hres;
  338. }
  339. /*----------------------------------------------------------
  340. Purpose: IShellLink::GetWorkingDirectory handler for Intshcut
  341. */
  342. STDMETHODIMP
  343. Intshcut::GetWorkingDirectory(
  344.     IN LPTSTR pszBuf,
  345.     IN int    cchBuf)
  346. {
  347.     HRESULT hres;
  348.     ASSERT(IS_VALID_STRUCT_PTR(this, CIntshcut));
  349.     ASSERT(IS_VALID_WRITE_BUFFER(pszBuf, TCHAR, cchBuf));
  350.     if (cchBuf > 0)
  351.         *pszBuf = '';
  352.     hres = InitProp();
  353.     if (SUCCEEDED(hres))
  354.         hres = m_pprop->GetProp(PID_IS_WORKINGDIR, pszBuf, cchBuf);
  355.     return hres;
  356. }
  357. /*----------------------------------------------------------
  358. Purpose: IShellLink::SetHotkey handler for Intshcut
  359. */
  360. STDMETHODIMP
  361. Intshcut::SetHotkey(
  362.     IN WORD wHotkey)
  363. {
  364.     HRESULT hres;
  365.     ASSERT(IS_VALID_STRUCT_PTR(this, CIntshcut));
  366.     hres = InitProp();
  367.     if (SUCCEEDED(hres))
  368.         hres = m_pprop->SetProp(PID_IS_HOTKEY, wHotkey);
  369.     return hres;
  370. }
  371. /*----------------------------------------------------------
  372. Purpose: IShellLink::GetHotkey handler for Intshcut
  373. */
  374. STDMETHODIMP
  375. Intshcut::GetHotkey(
  376.     PWORD pwHotkey)
  377. {
  378.     HRESULT hres;
  379.     ASSERT(IS_VALID_STRUCT_PTR(this, CIntshcut));
  380.     ASSERT(IS_VALID_WRITE_PTR(pwHotkey, WORD));
  381.     hres = InitProp();
  382.     if (SUCCEEDED(hres))
  383.     {
  384.         m_pprop->GetProp(PID_IS_HOTKEY, pwHotkey);
  385.         hres = S_OK;
  386.     }
  387.     return hres;
  388. }
  389. /*----------------------------------------------------------
  390. Purpose: IShellLink::SetShowCmd handler for Intshcut
  391. */
  392. STDMETHODIMP
  393. Intshcut::SetShowCmd(
  394.     IN int nShowCmd)
  395. {
  396.     HRESULT hres;
  397.     ASSERT(IS_VALID_STRUCT_PTR(this, CIntshcut));
  398.     ASSERT(IsValidShowCmd(nShowCmd));
  399.     hres = InitProp();
  400.     if (SUCCEEDED(hres))
  401.         hres = m_pprop->SetProp(PID_IS_SHOWCMD, nShowCmd);
  402.     return hres;
  403. }
  404. /*----------------------------------------------------------
  405. Purpose: IShellLink::GetShowCmd handler for Intshcut
  406. */
  407. STDMETHODIMP
  408. Intshcut::GetShowCmd(
  409.     OUT int *pnShowCmd)
  410. {
  411.     HRESULT hres;
  412.     ASSERT(IS_VALID_STRUCT_PTR(this, CIntshcut));
  413.     ASSERT(IS_VALID_WRITE_PTR(pnShowCmd, INT));
  414.     hres = InitProp();
  415.     if (SUCCEEDED(hres))
  416.     {
  417.         hres = m_pprop->GetProp(PID_IS_SHOWCMD, pnShowCmd);
  418.         if (S_OK != hres)
  419.             *pnShowCmd = SW_NORMAL;
  420.         hres = S_OK;
  421.     }
  422.     return hres;
  423. }
  424. /*----------------------------------------------------------
  425. Purpose: IShellLink::SetIconLocation handler for Intshcut
  426. */
  427. STDMETHODIMP
  428. Intshcut::SetIconLocation(
  429.     IN LPCTSTR pszFile,
  430.     IN int     niIcon)
  431. {
  432.     HRESULT hres = S_OK;
  433.     BOOL bNewMeat;
  434.     TCHAR szNewPath[MAX_PATH];
  435.     ASSERT(IS_VALID_STRUCT_PTR(this, CIntshcut));
  436.     ASSERT(IsValidIconIndex(pszFile ? S_OK : S_FALSE, pszFile, MAX_PATH, niIcon));
  437.     bNewMeat = AnyMeat(pszFile);
  438.     if (bNewMeat)
  439.     {
  440.         if (PathSearchAndQualify(pszFile, szNewPath, SIZECHARS(szNewPath)))
  441.         {
  442.             hres = S_OK;
  443.         }
  444.         else
  445.         {
  446.             hres = E_FILE_NOT_FOUND;
  447.         }
  448.     }
  449.     if (hres == S_OK)
  450.     {
  451.         TCHAR szOldPath[MAX_PATH];
  452.         int niOldIcon;
  453.         UINT uFlags;
  454.         hres = GetIconLocation(0, szOldPath, SIZECHARS(szOldPath), &niOldIcon,
  455.                              &uFlags);
  456.         if (SUCCEEDED(hres))
  457.         {
  458.             BOOL bOldMeat;
  459.             BOOL bChanged = FALSE;
  460.             bOldMeat = AnyMeat(szOldPath);
  461.             ASSERT(! *szOldPath ||
  462.                    bOldMeat);
  463.             bChanged = ((! bOldMeat && bNewMeat) ||
  464.                         (bOldMeat && ! bNewMeat) ||
  465.                         (bOldMeat && bNewMeat &&
  466.                          (StrCmp(szOldPath, szNewPath) != 0 ||
  467.                           niIcon != niOldIcon)));
  468.             hres = S_OK;
  469.             if (bChanged && bNewMeat)
  470.             {
  471.                 hres = InitProp();
  472.                 if (SUCCEEDED(hres))
  473.                 {
  474.                     hres = m_pprop->SetProp(PID_IS_ICONFILE, szNewPath);
  475.                     if (SUCCEEDED(hres))
  476.                         hres = m_pprop->SetProp(PID_IS_ICONINDEX, niIcon);
  477.                 }
  478.             }
  479.         }
  480.     }
  481.     return hres;
  482. }
  483. VOID UrlMunge(
  484.     TCHAR *lpszSrc,
  485.     TCHAR *lpszDest,
  486.     UINT   cchDestBufSize,
  487.     BOOL fRecentlyChanged)
  488. {
  489.    TCHAR *lpszTemp = lpszSrc;
  490.    if(fRecentlyChanged)
  491.         cchDestBufSize--; // Save up a character
  492.    while(*lpszTemp != TEXT('') && (cchDestBufSize > 1)) // not End of line and save up one char for  in munged string
  493.    {
  494.         if(TEXT('/') == *lpszTemp)
  495.         {
  496.             *lpszDest = TEXT('1');
  497.         }
  498.         else
  499.         {
  500.             *lpszDest = *lpszTemp;
  501.         }
  502.         lpszDest++;
  503.         lpszTemp++;
  504.         cchDestBufSize--;
  505.    }
  506.    if(fRecentlyChanged)
  507.    {
  508.         *lpszDest = TEXT('2');  
  509.         lpszDest++;
  510.    }
  511.    *lpszDest =  TEXT('');
  512.    return;
  513. }
  514. HRESULT HelperForReadIconInfoFromPropStg(
  515.     IN  LPTSTR pszBuf,
  516.     IN  int    cchBuf,
  517.     OUT int *  pniIcon,
  518.     IPropertyStorage *pPropStg,
  519.     PROPSPEC *ppropspec,
  520.     IN  LPTSTR pszActualUrlBuf,
  521.     IN INT cchActualUrlBuf,
  522.     BOOL fRecentlyChanged)
  523. {
  524.     HRESULT hres;
  525.     PROPVARIANT rgpropvar[2];
  526.     ASSERT((0 == pszActualUrlBuf) || (cchActualUrlBuf >= MAX_URL_STRING));
  527.     if(pszActualUrlBuf)
  528.         *pszActualUrlBuf = TEXT('');
  529.         
  530.     // Init to default values
  531.     *pniIcon = 0;
  532.     if (cchBuf > 0)
  533.         *pszBuf = TEXT('');
  534.     
  535.     hres = pPropStg->ReadMultiple(2, ppropspec, rgpropvar);
  536.     if (SUCCEEDED(hres))
  537.     {
  538.         if (VT_LPWSTR == rgpropvar[1].vt)
  539.         {
  540.             if(FALSE == PathFileExistsW(rgpropvar[1].pwszVal))
  541.             {
  542.                 UrlMunge(rgpropvar[1].pwszVal, pszBuf, cchBuf, fRecentlyChanged);  
  543.             }
  544.             else
  545.             {
  546.                 // We will just send the icon file and index back with no attempt
  547.                 // to hash it or fill out the URL field
  548.                 if(lstrlenW(rgpropvar[1].pwszVal) >= cchBuf)
  549.                 {
  550.                      // need a larger buf - simply fail it
  551.                     hres = E_FAIL;
  552.                 }
  553.                 else
  554.                 {
  555.                     StrCpyN(pszBuf, rgpropvar[1].pwszVal, cchBuf);
  556.                 }
  557.             }
  558.             if(SUCCEEDED(hres) && pszActualUrlBuf)
  559.             {
  560.                 StrCpyN(pszActualUrlBuf, rgpropvar[1].pwszVal, cchActualUrlBuf);
  561.             }
  562.         }
  563.         if (VT_I4 == rgpropvar[0].vt)
  564.             *pniIcon = rgpropvar[0].lVal;
  565.         FreePropVariantArray(ARRAYSIZE(rgpropvar), rgpropvar);
  566.     }
  567.     return hres;
  568. }
  569. //
  570. // Functions from isexicon.cpp
  571. //
  572. /*----------------------------------------------------------
  573. *
  574. *
  575. Purpose: IShellLink::GetIconLocation handler for Intshcut
  576. *
  577. *----------------------------------------------------------*/
  578. STDMETHODIMP
  579. Intshcut::_GetIconLocationWithURLHelper(
  580.     IN  LPTSTR pszBuf,
  581.     IN  int    cchBuf,
  582.     OUT int *  pniIcon,
  583.     IN  LPTSTR pszActualUrl,
  584.     UINT cchActualUrlBuf,
  585.     BOOL fRecentlyChanged)
  586. {
  587.     HRESULT hres;
  588.     PROPSPEC rgpropspec[2];
  589.     ASSERT(IS_VALID_STRUCT_PTR(this, CIntshcut));
  590.     ASSERT(IS_VALID_WRITE_BUFFER(pszBuf, TCHAR, cchBuf));
  591.     ASSERT(IS_VALID_WRITE_PTR(pniIcon, int));
  592.     if(!pszBuf)
  593.         return E_INVALIDARG;
  594.     rgpropspec[0].ulKind = PRSPEC_PROPID;
  595.     rgpropspec[1].ulKind = PRSPEC_PROPID;
  596.     
  597.     if(pszActualUrl)
  598.         *pszActualUrl = TEXT('');
  599.         
  600.     *pszBuf = TEXT('');
  601.     
  602.     hres = InitProp();
  603.     if (SUCCEEDED(hres))
  604.     {
  605.         rgpropspec[0].propid = PID_IS_ICONINDEX;
  606.         rgpropspec[1].propid = PID_IS_ICONFILE;
  607.         hres = HelperForReadIconInfoFromPropStg(
  608.                             pszBuf, cchBuf, pniIcon, m_pprop, 
  609.                             rgpropspec, pszActualUrl, cchActualUrlBuf,
  610.                             fRecentlyChanged);
  611.         
  612.     }
  613.     if(TEXT('') == *pszBuf) 
  614.     {
  615.         // Didn't find it in the shortcut itself
  616.         // Poke around the intsite database and if it is there,
  617.         // simply stuff it into the shortcut file if you do find
  618.         // one
  619.         IPropertyStorage *ppropstg = NULL;
  620.         hres = Open(FMTID_InternetSite, STGM_READWRITE, &ppropstg);
  621.         if(S_OK == hres)
  622.         {
  623.             // Look for an icon for this specific url
  624.             ASSERT(ppropstg);
  625.             rgpropspec[0].propid = PID_INTSITE_ICONINDEX;
  626.             rgpropspec[1].propid = PID_INTSITE_ICONFILE;
  627.             hres = HelperForReadIconInfoFromPropStg(pszBuf, cchBuf, pniIcon, 
  628.                                                     ppropstg, rgpropspec, pszActualUrl, 
  629.                                                     cchActualUrlBuf, fRecentlyChanged);
  630.             
  631.             
  632.             ppropstg->Release();
  633.         }
  634.         if((S_OK == hres) && (*pszBuf) && pszActualUrl && (*pszActualUrl))
  635.         {
  636.             // Write this info to the shortcut file
  637.             WCHAR *pwszTempBuf;
  638.             pwszTempBuf = pszActualUrl;
  639.             PROPVARIANT var = {0};
  640.             ASSERT(1 == *pniIcon);
  641.             
  642.             var.vt =  VT_BSTR;
  643.             var.bstrVal = SysAllocString(pwszTempBuf);
  644.             if(var.bstrVal)
  645.             {
  646.                 hres = WritePropertyNPB(ISHCUT_INISTRING_SECTIONW, ISHCUT_INISTRING_ICONFILEW,
  647.                                             &var);
  648.                 SysFreeString(var.bstrVal);
  649.                 if(S_OK == hres)
  650.                 {
  651.                     var.bstrVal = SysAllocString(L"1");
  652.                     if(var.bstrVal)
  653.                     {
  654.                         hres = WritePropertyNPB(ISHCUT_INISTRING_SECTIONW, ISHCUT_INISTRING_ICONINDEXW,
  655.                                                     &var);
  656.                         SysFreeString(var.bstrVal);
  657.                     }
  658.                 }
  659.             } 
  660.             hres = S_OK; // retun OK if you found icon and could not write out for whatever reason
  661.         }
  662.     }
  663.     return hres;
  664. }
  665. // IShellLink::GetIconLocation handler for Intshcut
  666. STDMETHODIMP Intshcut::GetIconLocation(LPTSTR pszBuf, int cchBuf, int *pniIcon)
  667. {
  668.     UINT uTmp;
  669.     return GetIconLocation(0, pszBuf, cchBuf, pniIcon, &uTmp);
  670. }
  671. // IShellLink::Resolve method for Intshcut
  672. STDMETHODIMP Intshcut::Resolve(HWND hwnd,  DWORD dwFlags)
  673. {
  674.     return S_OK;
  675. }
  676. //====================================================================================
  677. // Now the A or W functions that depend on unicode or ansi machines...
  678. // Will setup forwarders to the native one for the OS...
  679. //----------------------------------------------------------
  680. STDMETHODIMP Intshcut::SetPath(LPCSTR pcszPath)
  681. {
  682.     WCHAR wszT[INTERNET_MAX_URL_LENGTH];
  683.     if (!pcszPath)
  684.         return SetPath((LPCWSTR)NULL);
  685.     SHAnsiToUnicode(pcszPath, wszT, ARRAYSIZE(wszT));
  686.     return SetPath(wszT);
  687. }
  688. STDMETHODIMP Intshcut::GetPath(LPSTR pszBuf, int cchBuf, PWIN32_FIND_DATAA pwfd, DWORD dwFlags)
  689. {
  690.     WCHAR wszT[INTERNET_MAX_URL_LENGTH];
  691.     HRESULT hres;
  692.     // Init to default values (Note pwfd is not actually set so don't worry about thunking...
  693.     if (pwfd)
  694.         ZeroMemory(pwfd, SIZEOF(*pwfd));
  695.     hres = GetPath(wszT, ARRAYSIZE(wszT), NULL, dwFlags);
  696.     if (SUCCEEDED(hres))
  697.         SHUnicodeToAnsi(wszT, pszBuf, cchBuf);
  698.     return hres;
  699. }
  700. STDMETHODIMP Intshcut::SetRelativePath(LPCSTR pcszRelativePath, DWORD dwReserved)
  701. {
  702.     WCHAR wszT[MAX_PATH];
  703.     if (!pcszRelativePath)
  704.         return SetRelativePath((LPCWSTR)NULL, dwReserved);
  705.     SHAnsiToUnicode(pcszRelativePath, wszT, ARRAYSIZE(wszT));
  706.     return SetRelativePath(wszT, dwReserved);
  707. }
  708. STDMETHODIMP Intshcut::SetDescription(LPCSTR pcszDescription)
  709. {
  710.     WCHAR wszT[MAX_PATH];
  711.     if (!pcszDescription)
  712.         return SetDescription((LPCWSTR)NULL);
  713.     SHAnsiToUnicode(pcszDescription, wszT, ARRAYSIZE(wszT));
  714.     return SetDescription(wszT);
  715. }
  716. STDMETHODIMP Intshcut::GetDescription(LPSTR pszDescription,int cchBuf)
  717. {
  718.     WCHAR wszT[MAX_PATH];
  719.     HRESULT hres;
  720.     hres = GetDescription(wszT, ARRAYSIZE(wszT));
  721.     if (SUCCEEDED(hres))
  722.         SHUnicodeToAnsi(wszT, pszDescription, cchBuf);
  723.     return hres;
  724. }
  725. STDMETHODIMP Intshcut::SetArguments(LPCSTR pcszArgs)
  726. {
  727.     WCHAR wszT[2*MAX_PATH];
  728.     if (!pcszArgs)
  729.         return SetArguments((LPCWSTR)NULL);
  730.     SHAnsiToUnicode(pcszArgs, wszT, ARRAYSIZE(wszT));
  731.     return SetArguments(wszT);
  732. }
  733. STDMETHODIMP Intshcut::GetArguments(LPSTR pszArgs,int cchBuf)
  734. {
  735.     WCHAR wszT[2*MAX_PATH];
  736.     HRESULT hres;
  737.     hres = GetArguments(wszT, ARRAYSIZE(wszT));
  738.     if (SUCCEEDED(hres))
  739.         SHUnicodeToAnsi(wszT, pszArgs, cchBuf);
  740.     return hres;
  741. STDMETHODIMP Intshcut::SetWorkingDirectory(LPCSTR pcszWorkingDirectory)
  742. {
  743.     WCHAR wszT[MAX_PATH];
  744.     if (!pcszWorkingDirectory)
  745.         return SetWorkingDirectory((LPCWSTR)NULL);
  746.     SHAnsiToUnicode(pcszWorkingDirectory, wszT, ARRAYSIZE(wszT));
  747.     return SetWorkingDirectory(wszT);
  748. }
  749. STDMETHODIMP Intshcut::GetWorkingDirectory(LPSTR pszBuf, int cchBuf)
  750. {
  751.     WCHAR wszT[MAX_PATH];
  752.     HRESULT hres;
  753.     hres = GetWorkingDirectory(wszT, ARRAYSIZE(wszT));
  754.     if (SUCCEEDED(hres))
  755.         SHUnicodeToAnsi(wszT, pszBuf, cchBuf);
  756.     return hres;
  757. }
  758. STDMETHODIMP Intshcut::SetIconLocation(LPCSTR pszFile, int niIcon)
  759. {
  760.     WCHAR wszT[MAX_PATH];
  761.     if (!pszFile)
  762.         return SetIconLocation((LPCWSTR)NULL, niIcon);
  763.     SHAnsiToUnicode(pszFile, wszT, ARRAYSIZE(wszT));
  764.     return SetIconLocation(wszT, niIcon);
  765. }
  766. STDMETHODIMP Intshcut::GetIconLocation(LPSTR pszBuf, int cchBuf, int *pniIcon)
  767. {
  768.     WCHAR wszT[MAX_PATH];
  769.     HRESULT hres;
  770.     hres = GetIconLocation(wszT, ARRAYSIZE(wszT), pniIcon);
  771.     if (SUCCEEDED(hres))
  772.         SHUnicodeToAnsi(wszT, pszBuf, cchBuf);
  773.     return hres;
  774. }