desklink.c
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 5k
Category:

Windows Kernel

Development Platform:

Visual C++

  1. #include "sendmail.h"       // pch file
  2. #include "resource.h"
  3. #include "debug.h"
  4. extern CLIPFORMAT g_cfHIDA;
  5. LPIDA DataObj_GetHIDA(IDataObject *pdtobj, STGMEDIUM *pmedium)
  6. {
  7.     FORMATETC fmte = {g_cfHIDA, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
  8.     if (pmedium)
  9.     {
  10.         pmedium->pUnkForRelease = NULL;
  11.         pmedium->hGlobal = NULL;
  12.     }
  13.     if (!pmedium)
  14.     {
  15.         if (SUCCEEDED(pdtobj->lpVtbl->QueryGetData(pdtobj, &fmte)))
  16.             return (LPIDA)TRUE;
  17.         else
  18.             return (LPIDA)FALSE;
  19.     }
  20.     else if (SUCCEEDED(pdtobj->lpVtbl->GetData(pdtobj, &fmte, pmedium)))
  21.     {
  22.         return (LPIDA)GlobalLock(pmedium->hGlobal);
  23.     }
  24.     return NULL;
  25. }
  26. #define HIDA_GetPIDLItem(pida, i)       (LPCITEMIDLIST)(((LPBYTE)pida)+(pida)->aoffset[i+1])
  27. LPCITEMIDLIST IDA_GetIDListPtr(LPIDA pida, UINT i)
  28. {
  29.     if (NULL == pida)
  30.     {
  31.         return NULL;
  32.     }
  33.     if (i == (UINT)-1 || i < pida->cidl)
  34.     {
  35.         return HIDA_GetPIDLItem(pida, i);
  36.     }
  37.     return NULL;
  38. }
  39. void _ReleaseStgMedium(void *pv, STGMEDIUM *pmedium)
  40. {
  41.     if (pmedium->hGlobal && (pmedium->tymed == TYMED_HGLOBAL))
  42.     {
  43.         GlobalUnlock(pmedium->hGlobal);
  44.     }
  45.     ReleaseStgMedium(pmedium);
  46. }
  47. STDAPI InvokeVerbOnItems(HWND hwnd, LPCTSTR pszVerb, UINT uFlags, IShellFolder *psf, UINT cidl, LPCITEMIDLIST *apidl, LPCTSTR pszDirectory)
  48. {
  49.     IContextMenu *pcm;
  50.     CHAR szVerbA[128];
  51.     WCHAR szVerbW[128];
  52.     CHAR szDirA[MAX_PATH];
  53.     WCHAR szDirW[MAX_PATH];
  54.     HRESULT hr;
  55.     hr = psf->lpVtbl->GetUIObjectOf(psf, hwnd, cidl, apidl, &IID_IContextMenu, NULL, (void **)&pcm);
  56.     if (SUCCEEDED(hr))
  57.     {
  58.         CMINVOKECOMMANDINFOEX ici =
  59.         {
  60.             SIZEOF(CMINVOKECOMMANDINFOEX),
  61.             uFlags | CMIC_MASK_UNICODE | CMIC_MASK_FLAG_NO_UI,
  62.             hwnd,
  63.             NULL,
  64.             NULL,
  65.             NULL,
  66.             SW_NORMAL,
  67.         };
  68.         SHTCharToAnsi(pszVerb, szVerbA, ARRAYSIZE(szVerbA));
  69.         SHTCharToUnicode(pszVerb, szVerbW, ARRAYSIZE(szVerbW));
  70.         if (pszDirectory)
  71.         {
  72.             SHTCharToAnsi(pszDirectory, szDirA, ARRAYSIZE(szDirA));
  73.             SHTCharToUnicode(pszDirectory, szDirW, ARRAYSIZE(szDirW));
  74.             ici.lpDirectory = szDirA;
  75.             ici.lpDirectoryW = szDirW;
  76.         }
  77.         ici.lpVerb = szVerbA;
  78.         ici.lpVerbW = szVerbW;
  79.         hr = pcm->lpVtbl->InvokeCommand(pcm, (CMINVOKECOMMANDINFO*)&ici);
  80.         pcm->lpVtbl->Release(pcm);
  81.     }
  82.     return hr;
  83. }
  84. STDAPI InvokeVerbOnDataObj(HWND hwnd, LPCTSTR pszVerb, UINT uFlags, IDataObject *pdtobj, LPCTSTR pszDirectory)
  85. {
  86.     HRESULT hr;
  87.     STGMEDIUM medium;
  88.     LPIDA pida = DataObj_GetHIDA(pdtobj, &medium);
  89.     IShellFolder *psf;
  90.     hr = SHGetDesktopFolder(&psf);
  91.     if (SUCCEEDED(hr) && pida)
  92.     {
  93.         LPCITEMIDLIST pidlParent = IDA_GetIDListPtr(pida, (UINT)-1);
  94.         if (pidlParent &&
  95.             SUCCEEDED(psf->lpVtbl->BindToObject(psf, pidlParent, NULL, &IID_IShellFolder, (void **)&psf)))
  96.         {
  97.             LPCITEMIDLIST *ppidl = (LPCITEMIDLIST *)LocalAlloc(LPTR, pida->cidl * sizeof(LPCITEMIDLIST));
  98.             if (ppidl)
  99.             {
  100.                 UINT i;
  101.                 for (i = 0; i < pida->cidl; i++) 
  102.                 {
  103.                     ppidl[i] = IDA_GetIDListPtr(pida, i);
  104.                 }
  105.                 hr = InvokeVerbOnItems(hwnd, pszVerb, uFlags, psf, pida->cidl, ppidl, pszDirectory);
  106.                 LocalFree((LPVOID)ppidl);
  107.             }
  108.             psf->lpVtbl->Release(psf);
  109.         }
  110.         _ReleaseStgMedium(pida, &medium);
  111.     }
  112.     return hr;
  113. }
  114. STDAPI DesktopShortcutDropHandler(IDataObject *pdtobj, DWORD grfKeyState, DWORD dwEffect)
  115. {
  116.     TCHAR szDesktop[MAX_PATH];
  117.     if (_SHGetSpecialFolderPath(NULL, szDesktop, CSIDL_DESKTOP, FALSE))
  118.     {
  119.         if (g_cfHIDA == 0)
  120.         {
  121.             g_cfHIDA = (CLIPFORMAT) RegisterClipboardFormat(CFSTR_SHELLIDLIST);
  122.         }
  123.         return InvokeVerbOnDataObj (NULL, TEXT("link"), 0, pdtobj, szDesktop);
  124.     }
  125.     return E_OUTOFMEMORY;
  126. }
  127. STDAPI DesktopShortcut_CreateInstance(IUnknown *punkOuter, REFIID riid, void **ppv)
  128. {
  129.     return DropHandler_CreateInstance(DesktopShortcutDropHandler, punkOuter, riid, ppv);
  130. }
  131. #define DESKLINK_EXTENSION  TEXT("DeskLink")
  132. void CommonRegister(HKEY hkCLSID, LPCTSTR pszCLSID, LPCTSTR pszExtension, int idFileName);
  133. STDAPI DesktopShortcut_RegUnReg(BOOL bReg, HKEY hkCLSID, LPCTSTR pszCLSID, LPCTSTR pszModule)
  134. {
  135.     TCHAR szFile[MAX_PATH];
  136.     if (bReg)
  137.     {
  138.         HKEY hk;
  139.         // get rid of old name "Desktop as Shortcut" link from IE4
  140.         if (SUCCEEDED(GetDropTargetPath(szFile, IDS_DESKTOPLINK_FILENAME, DESKLINK_EXTENSION)))
  141.             DeleteFile(szFile);
  142.         if (RegCreateKey(hkCLSID, DEFAULTICON, &hk) == ERROR_SUCCESS) 
  143.         {
  144.             TCHAR szExplorer[MAX_PATH];
  145.             TCHAR szIcon[MAX_PATH+10];
  146.             GetWindowsDirectory(szExplorer, ARRAYSIZE(szExplorer));
  147.             wnsprintf(szIcon, ARRAYSIZE(szIcon), TEXT("%s\explorer.exe,-103"), szExplorer);    // ICO_DESKTOP res ID
  148.             RegSetValueEx(hk, NULL, 0, REG_SZ, (LPBYTE)szIcon, (lstrlen(szIcon) + 1) * SIZEOF(TCHAR));
  149.             RegCloseKey(hk);
  150.         }
  151.         
  152.         CommonRegister(hkCLSID, pszCLSID, DESKLINK_EXTENSION, IDS_DESKTOPLINK_FILENAME_NEW);
  153.     }
  154.     else
  155.     {
  156.         if (SUCCEEDED(GetDropTargetPath(szFile, IDS_DESKTOPLINK_FILENAME, DESKLINK_EXTENSION)))
  157.             DeleteFile(szFile);
  158.     }
  159.     return S_OK;
  160. }