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.

155 lines
4.4 KiB

  1. /*++
  2. Copyright (c) 2002 Microsoft Corporation
  3. Module Name:
  4. OperationsManager.cpp
  5. Abstract:
  6. The setup for OperationsManager needs to have LoadLibraryCWD applied.
  7. However, the setups name is random, so we need to DeRandomizeExeName.
  8. But, DeRandomizeExe name calls MoveFileEx to set the file to be deleted
  9. upon reboot. The setup program detects that there are pending file
  10. deletions, interprets them as an aborted install, and recommends that
  11. the user stop installation.
  12. This shim will shim RegQueryValueExA, watch for the
  13. "PendingFileRenameOperations" key, and remove any of our de-randomized exes
  14. from the return string.
  15. Notes:
  16. This is an app-specific shim.
  17. History:
  18. 05/07/2002 astritz Created
  19. --*/
  20. #include "precomp.h"
  21. #include "StrSafe.h"
  22. IMPLEMENT_SHIM_BEGIN(OperationsManager)
  23. #include "ShimHookMacro.h"
  24. APIHOOK_ENUM_BEGIN
  25. APIHOOK_ENUM_ENTRY(RegQueryValueExA)
  26. APIHOOK_ENUM_END
  27. /*++
  28. Remove any of our de-randomized exe names from the PendingFileRenameOperations key.
  29. --*/
  30. LONG
  31. APIHOOK(RegQueryValueExA)(
  32. HKEY hKey, // handle to key
  33. LPCSTR lpValueName, // value name
  34. LPDWORD lpReserved, // reserved
  35. LPDWORD lpType, // type buffer
  36. LPBYTE lpData, // data buffer
  37. LPDWORD lpcbData // size of data buffer
  38. )
  39. {
  40. CHAR *pchBuff = NULL;
  41. LONG lRet = ORIGINAL_API(RegQueryValueExA)(hKey, lpValueName, lpReserved,
  42. lpType, lpData, lpcbData);
  43. if (ERROR_SUCCESS == lRet) {
  44. if (CompareStringA(MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_NEUTRAL),
  45. SORT_DEFAULT), NORM_IGNORECASE, lpValueName, -1,
  46. "PendingFileRenameOperations", -1) == CSTR_EQUAL) {
  47. //
  48. // Since we're only removing strings from the original data, a buffer
  49. // of the original's size will suffice, and we won't overflow it.
  50. //
  51. CHAR *pchSrc = (CHAR *) lpData;
  52. pchBuff = new CHAR [*lpcbData];
  53. if (NULL != pchBuff) {
  54. CHAR *pchDest = pchBuff;
  55. //
  56. // We want to loop through ALL the data in case there is more than
  57. // one instance of our de-randomized name in the data.
  58. //
  59. while (pchSrc <= (CHAR *)lpData + *lpcbData) {
  60. if (*pchSrc == NULL) {
  61. break;
  62. }
  63. CString csSrc(pchSrc);
  64. CString csFile;
  65. csSrc.GetLastPathComponent(csFile);
  66. if (csFile.CompareNoCase(L"MOM_SETUP_DERANDOMIZED.EXE") == 0) {
  67. // Skip this Src File.
  68. pchSrc += strlen(pchSrc) + 1;
  69. if (pchSrc > (CHAR *)lpData + *lpcbData) {
  70. goto Exit;
  71. }
  72. // Skip the Dest file as well (probably an empty string)
  73. pchSrc += strlen(pchSrc) + 1;
  74. } else {
  75. // Copy the src file.
  76. if (FAILED(StringCchCopyExA(pchDest,
  77. *lpcbData - (pchDest - pchBuff), pchSrc,
  78. &pchDest, NULL, 0))) {
  79. goto Exit;
  80. }
  81. pchSrc += strlen(pchSrc) + 1;
  82. if (pchSrc > (CHAR *)lpData + *lpcbData) {
  83. goto Exit;
  84. }
  85. // Copy the dest file.
  86. if (FAILED(StringCchCopyExA(pchDest,
  87. *lpcbData - (pchDest - pchBuff), pchSrc, &pchDest,
  88. NULL, 0))) {
  89. goto Exit;
  90. }
  91. pchSrc += strlen(pchSrc) + 1;
  92. }
  93. }
  94. // Add the extra NULL to terminate the list of strings.
  95. *pchDest++ = NULL;
  96. // Copy our buffer to the returned buffer.
  97. memcpy(lpData, pchBuff, pchDest - pchBuff);
  98. *lpcbData = pchDest - pchBuff;
  99. }
  100. }
  101. }
  102. Exit:
  103. if (NULL != pchBuff) {
  104. delete [] pchBuff;
  105. }
  106. return lRet;
  107. }
  108. /*++
  109. Register hooked functions
  110. --*/
  111. HOOK_BEGIN
  112. APIHOOK_ENTRY(ADVAPI32.DLL, RegQueryValueExA)
  113. HOOK_END
  114. IMPLEMENT_SHIM_END