Source code of Windows XP (NT5)
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.

293 lines
8.8 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. Casper.cpp
  5. Abstract:
  6. Casper copies a LNK file into %windir%\desktop. This file is hardcoded to
  7. point to c:\program files. The EXE that actually places the file into the
  8. wrong place is 16-bit, so we cannot use CorrectFilePaths to fix the problem.
  9. We hook IPersistFile::Save to accomplish the fixup of the incorrect link,
  10. IPersistFile::Save is not modified in any way.
  11. App uses some 16-bit stuff when showing the intro video (see #200495) which
  12. we have yet to fix (probably will never fix). After it calls CreateWindowEx
  13. to create the "Full-screen animation" window it assigns the return value
  14. to a variable. Later on the app plays videos in SmackWin windows. And it
  15. checks this var to see if it's 0 - if it is, it calls DestroyWindow on the
  16. SmackWin window. Now if the intro video were shown successfully it would
  17. have set this var to 0 when the video exits but since in this case the
  18. video is not shown, the variable still has the value equal to the
  19. "Full-screen animation" window handle. We fix this by setting the return
  20. value of the "Full-screen animation" window creation to 0.
  21. History:
  22. 1/21/1999 robkenny
  23. 03/15/2000 robkenny converted to use the CorrectPathChangesAllUser class
  24. 11/07/2000 maonis added hooks for CreateWindowExA and SetFocus (this is
  25. for the actual casper.exe)
  26. 01/04/2001 maonis tester found more problem with the smackwin windows.
  27. rewrote the fix to fix all of them.
  28. --*/
  29. #include "precomp.h"
  30. #include "ClassCFP.h"
  31. IMPLEMENT_SHIM_BEGIN(Casper)
  32. #include "ShimHookMacro.h"
  33. APIHOOK_ENUM_BEGIN
  34. APIHOOK_ENUM_ENTRY(CreateDialogParamA)
  35. APIHOOK_ENUM_ENTRY(CreateWindowExA)
  36. APIHOOK_ENUM_END
  37. /*++
  38. We return 0 when creating the "Full-screen animation" window.
  39. --*/
  40. HWND
  41. APIHOOK(CreateWindowExA)(
  42. DWORD dwExStyle, // extended window style
  43. LPCSTR lpClassName, // registered class name
  44. LPCSTR lpWindowName, // window name
  45. DWORD dwStyle, // window style
  46. int x, // horizontal position of window
  47. int y, // vertical position of window
  48. int nWidth, // window width
  49. int nHeight, // window height
  50. HWND hWndParent, // handle to parent or owner window
  51. HMENU hMenu, // menu handle or child identifier
  52. HINSTANCE hInstance, // handle to application instance
  53. LPVOID lpParam // window-creation data
  54. )
  55. {
  56. HWND hWnd = ORIGINAL_API(CreateWindowExA)(
  57. dwExStyle,
  58. lpClassName,
  59. lpWindowName,
  60. dwStyle,
  61. x,
  62. y,
  63. nWidth,
  64. nHeight,
  65. hWndParent,
  66. hMenu,
  67. hInstance,
  68. lpParam);
  69. if (lpWindowName)
  70. {
  71. CSTRING_TRY
  72. {
  73. CString csWindowName(lpWindowName);
  74. if (csWindowName.Compare(L"Full-screen animation") == 0)
  75. {
  76. hWnd = 0;
  77. }
  78. }
  79. CSTRING_CATCH
  80. {
  81. // Do nothing
  82. }
  83. }
  84. return hWnd;
  85. }
  86. /*++
  87. Our path changing class. We want to convert paths to All User
  88. --*/
  89. CorrectPathChangesAllUser * g_PathCorrector = NULL;
  90. static bool g_bLinkCorrected = false;
  91. /*++
  92. Return a pointer to the PathCorrecting object
  93. --*/
  94. inline CorrectPathChangesBase * GetPathcorrecter()
  95. {
  96. if (g_PathCorrector == NULL)
  97. {
  98. // Create our correct file path object
  99. g_PathCorrector = new CorrectPathChangesAllUser;
  100. g_PathCorrector->AddPathChangeW(L"\\MsM\\", L"\\MorningStar\\" );
  101. }
  102. return g_PathCorrector;
  103. }
  104. /*++
  105. Call CorrectPathAllocA and print a debug message if the two strings differ
  106. --*/
  107. WCHAR * CorrectPathAllocDebugW(const WCHAR * uncorrect, const char * debugMsg)
  108. {
  109. if (uncorrect == NULL)
  110. return NULL;
  111. WCHAR * strCorrectFile = GetPathcorrecter()->CorrectPathAllocW(uncorrect);
  112. if (strCorrectFile && uncorrect && _wcsicmp(strCorrectFile, uncorrect) != 0)
  113. {
  114. DPFN( eDbgLevelInfo, "%s corrected path:\n %S\n %S\n",
  115. debugMsg, uncorrect, strCorrectFile);
  116. }
  117. else // Massive Spew:
  118. {
  119. DPFN( eDbgLevelSpew, "%s unchanged %S\n", debugMsg, uncorrect);
  120. }
  121. return strCorrectFile;
  122. }
  123. /*++
  124. Casper *copies* a link to %windir%\Desktop; it contains hardcoded paths to incorrect places.
  125. Move the link to the proper desktop directory.
  126. Correct the Path, Working Directory, and Icon values--all which are wrong.
  127. --*/
  128. void CorrectCasperLink()
  129. {
  130. if (!g_bLinkCorrected)
  131. {
  132. // The path to the incorrect desktop link
  133. WCHAR * lpIncorrectCasperPath = GetPathcorrecter()->ExpandEnvironmentValueW(L"%windir%\\Desktop\\casper.lnk");
  134. // Correct the bad desktop link path
  135. WCHAR * lpCorrectCasperPath = GetPathcorrecter()->CorrectPathAllocW(lpIncorrectCasperPath);
  136. DPFN( eDbgLevelInfo, "CorrectCasperLink MoveFileW(%S, %S)\n", lpIncorrectCasperPath, lpCorrectCasperPath);
  137. // Move the file to the correct location.
  138. MoveFileW(lpIncorrectCasperPath, lpCorrectCasperPath);
  139. // All finished with the bad path, I never want to see it again.
  140. free(lpIncorrectCasperPath);
  141. HRESULT hres = CoInitialize(NULL);
  142. if (SUCCEEDED(hres))
  143. {
  144. // Get a pointer to the IShellLink interface.
  145. IShellLinkW *psl;
  146. hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLinkW, (void **)&psl);
  147. if (SUCCEEDED(hres))
  148. {
  149. // Get a pointer to the IPersistFile interface.
  150. IPersistFile *ppf;
  151. hres = psl->QueryInterface(IID_IPersistFile, (void **)&ppf);
  152. if (SUCCEEDED(hres))
  153. {
  154. // Load the shortcut.
  155. hres = ppf->Load(lpCorrectCasperPath, STGM_READ);
  156. if (SUCCEEDED(hres))
  157. {
  158. // We have successfully loaded the link
  159. g_bLinkCorrected = true;
  160. DPFN( eDbgLevelInfo, "CorrectCasperLink %S\n", lpCorrectCasperPath);
  161. // Correct the path to the shortcut target.
  162. WCHAR szBadPath[MAX_PATH];
  163. WCHAR * szCorrectPath;
  164. WIN32_FIND_DATAW wfd;
  165. hres = psl->GetPath(szBadPath, MAX_PATH, &wfd, SLGP_UNCPRIORITY);
  166. if (SUCCEEDED(hres))
  167. {
  168. szCorrectPath = CorrectPathAllocDebugW(szBadPath, "CorrectCasperLink, SetPath");
  169. psl->SetPath(szCorrectPath);
  170. free(szCorrectPath);
  171. }
  172. // Correct the working directory
  173. hres = psl->GetWorkingDirectory(szBadPath, MAX_PATH);
  174. if (SUCCEEDED(hres))
  175. {
  176. szCorrectPath = CorrectPathAllocDebugW(szBadPath, "CorrectCasperLink, SetWorkingDirectory");
  177. psl->SetWorkingDirectory(szCorrectPath);
  178. free(szCorrectPath);
  179. }
  180. // Correct the icon
  181. int iIcon;
  182. hres = psl->GetIconLocation(szBadPath, MAX_PATH, &iIcon);
  183. if (SUCCEEDED(hres))
  184. {
  185. szCorrectPath = CorrectPathAllocDebugW(szBadPath, "CorrectCasperLink, SetIconLocation");
  186. psl->SetIconLocation(szCorrectPath, iIcon);
  187. free(szCorrectPath);
  188. }
  189. // Save the shortcut.
  190. ppf->Save(NULL, TRUE);
  191. }
  192. }
  193. // Release the pointer to IShellLink.
  194. ppf->Release();
  195. }
  196. // Release the pointer to IPersistFile.
  197. psl->Release();
  198. }
  199. CoUninitialize();
  200. free(lpCorrectCasperPath);
  201. }
  202. }
  203. /*++
  204. Do nothing to the CreateDialogParamA call, just an opportunity to correct the casper link
  205. --*/
  206. HWND
  207. APIHOOK(CreateDialogParamA)(
  208. HINSTANCE hInstance, // handle to module
  209. LPCSTR lpTemplateName, // dialog box template
  210. HWND hWndParent, // handle to owner window
  211. DLGPROC lpDialogFunc, // dialog box procedure
  212. LPARAM dwInitParam // initialization value
  213. )
  214. {
  215. CorrectCasperLink();
  216. HWND returnValue = ORIGINAL_API(CreateDialogParamA)(
  217. hInstance,
  218. lpTemplateName,
  219. hWndParent,
  220. lpDialogFunc,
  221. dwInitParam);
  222. return returnValue;
  223. }
  224. /*++
  225. Register hooked functions
  226. --*/
  227. HOOK_BEGIN
  228. APIHOOK_ENTRY(USER32.DLL, CreateDialogParamA)
  229. APIHOOK_ENTRY(USER32.DLL, CreateWindowExA)
  230. HOOK_END
  231. IMPLEMENT_SHIM_END