Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

194 lines
5.8 KiB

  1. #include "precomp.h" // pch file
  2. #pragma hdrstop
  3. #define DECL_CRTFREE
  4. #include <crtfree.h>
  5. // deal with IShellLinkA/W uglyness...
  6. HRESULT ShellLinkSetPath(IUnknown *punk, LPCTSTR pszPath)
  7. {
  8. IShellLinkW *pslW;
  9. HRESULT hres = punk->QueryInterface(IID_PPV_ARG(IShellLinkW, &pslW));
  10. if (SUCCEEDED(hres))
  11. {
  12. hres = pslW->SetPath(pszPath);
  13. pslW->Release();
  14. }
  15. return hres;
  16. }
  17. // deal with IShellLinkA/W uglyness...
  18. HRESULT ShellLinkGetPath(IUnknown *punk, LPTSTR pszPath, UINT cch)
  19. {
  20. HRESULT hres;
  21. IShellLinkW *pslW;
  22. hres = punk->QueryInterface(IID_PPV_ARG(IShellLinkW, &pslW));
  23. if (SUCCEEDED(hres))
  24. {
  25. hres = pslW->GetPath(pszPath, cch, NULL, SLGP_UNCPRIORITY);
  26. pslW->Release();
  27. }
  28. return hres;
  29. }
  30. // is a file a shortcut? check its attributes
  31. BOOL IsShortcut(LPCTSTR pszFile)
  32. {
  33. SHFILEINFO sfi;
  34. return SHGetFileInfo(pszFile, 0, &sfi, sizeof(sfi), SHGFI_ATTRIBUTES)
  35. && (sfi.dwAttributes & SFGAO_LINK);
  36. }
  37. // like OLE GetClassFile(), but it only works on ProgID\CLSID type registration
  38. // not real doc files or pattern matched files
  39. HRESULT CLSIDFromExtension(LPCTSTR pszExt, CLSID *pclsid)
  40. {
  41. TCHAR szProgID[80];
  42. LONG cb = SIZEOF(szProgID);
  43. if (RegQueryValue(HKEY_CLASSES_ROOT, pszExt, szProgID, &cb) == ERROR_SUCCESS)
  44. {
  45. StrCatBuff(szProgID, TEXT("\\CLSID"), ARRAYSIZE(szProgID));
  46. TCHAR szCLSID[80];
  47. cb = SIZEOF(szCLSID);
  48. if (RegQueryValue(HKEY_CLASSES_ROOT, szProgID, szCLSID, &cb) == ERROR_SUCCESS)
  49. {
  50. return CLSIDFromString(szCLSID, pclsid);
  51. }
  52. }
  53. return E_FAIL;
  54. }
  55. // get the target of a shortcut. this uses IShellLink which
  56. // Internet Shortcuts (.URL) and Shell Shortcuts (.LNK) support so
  57. // it should work generally
  58. HRESULT GetShortcutTarget(LPCTSTR pszPath, LPTSTR pszTarget, UINT cch)
  59. {
  60. *pszTarget = 0; // assume none
  61. if (!IsShortcut(pszPath))
  62. return E_FAIL;
  63. CLSID clsid;
  64. if (FAILED(CLSIDFromExtension(PathFindExtension(pszPath), &clsid)))
  65. clsid = CLSID_ShellLink; // assume it's a shell link
  66. IUnknown *punk;
  67. HRESULT hres = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IUnknown, &punk));
  68. if (SUCCEEDED(hres))
  69. {
  70. IPersistFile *ppf;
  71. if (SUCCEEDED(punk->QueryInterface(IID_PPV_ARG(IPersistFile, &ppf))))
  72. {
  73. WCHAR wszPath[MAX_PATH];
  74. SHTCharToUnicode(pszPath, wszPath, ARRAYSIZE(wszPath));
  75. ppf->Load(wszPath, 0);
  76. ppf->Release();
  77. }
  78. hres = ShellLinkGetPath(punk, pszTarget, cch);
  79. punk->Release();
  80. }
  81. return hres;
  82. }
  83. // get the pathname to a sendto folder item
  84. HRESULT GetDropTargetPath(LPTSTR pszPath, int cchPath, int id, LPCTSTR pszExt)
  85. {
  86. ASSERT(cchPath == MAX_PATH);
  87. LPITEMIDLIST pidl;
  88. if (SUCCEEDED(SHGetSpecialFolderLocation(NULL, CSIDL_SENDTO, &pidl)))
  89. {
  90. SHGetPathFromIDList(pidl, pszPath);
  91. SHFree(pidl);
  92. TCHAR szFileName[128], szBase[64];
  93. LoadString(g_hinst, id, szBase, ARRAYSIZE(szBase));
  94. StringCchPrintf(szFileName, ARRAYSIZE(szFileName), TEXT("\\%s.%s"), szBase, pszExt);
  95. StrCatBuff(pszPath, szFileName, cchPath);
  96. return S_OK;
  97. }
  98. return E_FAIL;
  99. }
  100. // do common registration
  101. #define NEVERSHOWEXT TEXT("NeverShowExt")
  102. #define SHELLEXT_DROPHANDLER TEXT("shellex\\DropHandler")
  103. void CommonRegister(HKEY hkCLSID, LPCTSTR pszCLSID, LPCTSTR pszExtension, int idFileName)
  104. {
  105. HKEY hk;
  106. TCHAR szKey[80];
  107. RegSetValueEx(hkCLSID, NEVERSHOWEXT, 0, REG_SZ, (BYTE *)TEXT(""), SIZEOF(TCHAR));
  108. if (RegCreateKeyEx(hkCLSID, SHELLEXT_DROPHANDLER, 0, NULL, 0, KEY_SET_VALUE, NULL, &hk, NULL) == ERROR_SUCCESS)
  109. {
  110. RegSetValueEx(hk, NULL, 0, REG_SZ, (LPBYTE)pszCLSID, (lstrlen(pszCLSID) + 1) * SIZEOF(TCHAR));
  111. RegCloseKey(hk);
  112. }
  113. StringCchPrintf(szKey, ARRAYSIZE(szKey), TEXT(".%s"), pszExtension);
  114. if (RegCreateKeyEx(HKEY_CLASSES_ROOT, szKey, 0, NULL, 0, KEY_SET_VALUE, NULL, &hk, NULL) == ERROR_SUCCESS)
  115. {
  116. TCHAR szProgID[80];
  117. StringCchPrintf(szProgID, ARRAYSIZE(szProgID), TEXT("CLSID\\%s"), pszCLSID);
  118. RegSetValueEx(hk, NULL, 0, REG_SZ, (LPBYTE)szProgID, (lstrlen(szProgID) + 1) * SIZEOF(TCHAR));
  119. RegCloseKey(hk);
  120. }
  121. TCHAR szFile[MAX_PATH];
  122. if (SUCCEEDED(GetDropTargetPath(szFile, ARRAYSIZE(szFile), idFileName, pszExtension)))
  123. {
  124. HANDLE hfile = CreateFile(szFile, 0, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  125. if (hfile != INVALID_HANDLE_VALUE)
  126. {
  127. CloseHandle(hfile);
  128. SHSetLocalizedName(szFile, L"sendmail.dll", idFileName);
  129. }
  130. }
  131. }
  132. // SHPathToAnsi creates an ANSI version of a pathname. If there is going to be a
  133. // loss when converting from Unicode, the short pathname is obtained and stored in the
  134. // destination.
  135. //
  136. // pszSrc : Source buffer containing filename (of existing file) to be converted
  137. // pszDest : Destination buffer to receive converted ANSI string.
  138. // cbDest : Size of the destination buffer, in bytes.
  139. //
  140. // returns:
  141. // TRUE, the filename was converted without change
  142. // FALSE, we had to convert to short name
  143. //
  144. BOOL SHPathToAnsi(LPCTSTR pszSrc, LPSTR pszDest, int cbDest)
  145. {
  146. BOOL bUsedDefaultChar = FALSE;
  147. WideCharToMultiByte(CP_ACP, 0, pszSrc, -1, pszDest, cbDest, NULL, &bUsedDefaultChar);
  148. if (bUsedDefaultChar)
  149. {
  150. TCHAR szTemp[MAX_PATH];
  151. if (GetShortPathName(pszSrc, szTemp, ARRAYSIZE(szTemp)))
  152. SHTCharToAnsi(szTemp, pszDest, cbDest);
  153. }
  154. return !bUsedDefaultChar;
  155. }