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.

192 lines
6.5 KiB

  1. #include "precomp.h"
  2. #include "shutil.h"
  3. HRESULT GetFileInfoByHandle(LPCTSTR pszFile, BY_HANDLE_FILE_INFORMATION *pInfo)
  4. {
  5. HRESULT hr;
  6. HANDLE hFile = CreateFile(pszFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
  7. if (INVALID_HANDLE_VALUE != hFile)
  8. {
  9. if (GetFileInformationByHandle(hFile, pInfo))
  10. {
  11. hr = S_OK;
  12. }
  13. else
  14. {
  15. hr = HRESULT_FROM_WIN32(GetLastError());
  16. }
  17. CloseHandle(hFile);
  18. }
  19. else
  20. {
  21. hr = HRESULT_FROM_WIN32(GetLastError());
  22. }
  23. return hr;
  24. }
  25. // S_OK -> YES, S_FALSE -> NO, FAILED(hr) otherwise
  26. STDAPI IsSameFile(LPCTSTR pszFile1, LPCTSTR pszFile2)
  27. {
  28. HRESULT hr;
  29. // use CRT str cmp semantics as localized strcmp should not be used for the file system
  30. if (0 == StrCmpIC(pszFile1, pszFile2))
  31. {
  32. hr = S_OK; // test the names
  33. }
  34. else
  35. {
  36. // very clever here... we can test for alias names that map to the same
  37. // file. for example the short name vs long name of the same file
  38. // the UNC name vs drive letter version of the name
  39. BY_HANDLE_FILE_INFORMATION hfi1;
  40. hr = GetFileInfoByHandle(pszFile1, &hfi1);
  41. if (SUCCEEDED(hr))
  42. {
  43. BY_HANDLE_FILE_INFORMATION hfi2;
  44. hr = GetFileInfoByHandle(pszFile2, &hfi2);
  45. if (SUCCEEDED(hr))
  46. {
  47. if (hfi1.dwVolumeSerialNumber == hfi2.dwVolumeSerialNumber &&
  48. hfi1.nFileIndexHigh == hfi2.nFileIndexHigh &&
  49. hfi1.nFileIndexLow == hfi2.nFileIndexLow)
  50. {
  51. hr = S_OK; // same!
  52. }
  53. else
  54. {
  55. hr = S_FALSE; // different
  56. }
  57. }
  58. }
  59. }
  60. return hr;
  61. }
  62. UINT FindInDecoderList(ImageCodecInfo *pici, UINT cDecoders, LPCTSTR pszFile)
  63. {
  64. LPCTSTR pszExt = PathFindExtension(pszFile); // speed up PathMatchSpec calls
  65. // look at the list of decoders to see if this format is there
  66. for (UINT i = 0; i < cDecoders; i++)
  67. {
  68. if (PathMatchSpec(pszExt, pici[i].FilenameExtension))
  69. return i;
  70. }
  71. return (UINT)-1; // not found!
  72. }
  73. HRESULT GetUIObjectFromPath(LPCTSTR pszFile, REFIID riid, void **ppv)
  74. {
  75. *ppv = NULL;
  76. LPITEMIDLIST pidl;
  77. HRESULT hr = SHILCreateFromPath(pszFile, &pidl, NULL);
  78. if (SUCCEEDED(hr))
  79. {
  80. hr = SHGetUIObjectFromFullPIDL(pidl, NULL, riid, ppv);
  81. ILFree(pidl);
  82. }
  83. return hr;
  84. }
  85. BOOL FmtSupportsMultiPage(IShellImageData *pData, GUID *pguidFmt)
  86. {
  87. BOOL bRet = FALSE;
  88. EncoderParameters *pencParams;
  89. if (SUCCEEDED(pData->GetEncoderParams(pguidFmt, &pencParams)))
  90. {
  91. for (UINT i=0;!bRet && i<pencParams->Count;i++)
  92. {
  93. if (EncoderSaveFlag == pencParams->Parameter[i].Guid)
  94. {
  95. if (EncoderValueMultiFrame == *((ULONG*)pencParams->Parameter[i].Value))
  96. {
  97. bRet = TRUE;
  98. }
  99. }
  100. }
  101. CoTaskMemFree(pencParams);
  102. }
  103. return bRet;
  104. }
  105. HRESULT SetWallpaperHelper(LPCWSTR pszPath)
  106. {
  107. IActiveDesktop* pad;
  108. HRESULT hr = CoCreateInstance(CLSID_ActiveDesktop, NULL, CLSCTX_INPROC, IID_PPV_ARG(IActiveDesktop, &pad));
  109. if (SUCCEEDED(hr))
  110. {
  111. IShellImageDataFactory* pidf;
  112. hr = CoCreateInstance(CLSID_ShellImageDataFactory, NULL, CLSCTX_INPROC, IID_PPV_ARG(IShellImageDataFactory, &pidf));
  113. if (SUCCEEDED(hr))
  114. {
  115. IShellImageData* pid;
  116. hr = pidf->CreateImageFromFile(pszPath, &pid);
  117. if (SUCCEEDED(hr))
  118. {
  119. hr = pid->Decode(SHIMGDEC_DEFAULT, 0,0);
  120. if (SUCCEEDED(hr))
  121. {
  122. // we are basing this on a best fit to the primary screen
  123. ULONG cxScreen = GetSystemMetrics(SM_CXSCREEN);
  124. ULONG cyScreen = GetSystemMetrics(SM_CYSCREEN);
  125. SIZE szImg;
  126. pid->GetSize(&szImg);
  127. hr = pad->SetWallpaper(pszPath, 0);
  128. if (SUCCEEDED(hr))
  129. {
  130. WALLPAPEROPT wpo;
  131. wpo.dwSize = sizeof(wpo);
  132. wpo.dwStyle = WPSTYLE_CENTER;
  133. // if the image is small on either axis then tile
  134. if (((ULONG)szImg.cx*2 < cxScreen) || ((ULONG)szImg.cy*2 < cyScreen))
  135. {
  136. wpo.dwStyle = WPSTYLE_TILE;
  137. }
  138. // if the image is larger than the screen then stretch
  139. else if ((ULONG)szImg.cx > cxScreen && (ULONG)szImg.cy > cyScreen)
  140. {
  141. wpo.dwStyle = WPSTYLE_STRETCH;
  142. }
  143. else
  144. {
  145. // If the aspect ratio matches the screen then stretch.
  146. // I'm checking is the aspect ratios are *close* to matching.
  147. // Here's the logic behind this:
  148. //
  149. // a / b == c / d
  150. // a * d == c * b
  151. // (a * d) / (c * b) == 1
  152. // 0.75 <= (a * d) / (c * b) < 1.25 <-- our *close* factor
  153. // 3 <= 4 * (a * d) / (c * b) < 5
  154. //
  155. // We do an integer division which will floor the result meaning
  156. // that if the result is 3 or 4 we are inside the rang we want.
  157. DWORD dwRes = (4 * (ULONG)szImg.cx * cyScreen) / (cxScreen * (ULONG)szImg.cy);
  158. if (dwRes == 4 || dwRes == 3)
  159. wpo.dwStyle = WPSTYLE_STRETCH;
  160. }
  161. hr = pad->SetWallpaperOptions(&wpo, 0);
  162. if (SUCCEEDED(hr))
  163. {
  164. hr = pad->ApplyChanges(AD_APPLY_ALL | AD_APPLY_DYNAMICREFRESH);
  165. }
  166. }
  167. }
  168. pid->Release();
  169. }
  170. pidf->Release();
  171. }
  172. pad->Release();
  173. }
  174. return hr;
  175. }