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.

165 lines
5.4 KiB

  1. /*++
  2. Copyright (c) 2002 Microsoft Corporation
  3. Module Name:
  4. UltraWinCleaner2002.cpp
  5. Abstract:
  6. Ultra WinCleaner 2002 - WinJunk Cleaner removes files under
  7. %WINDIR%\Resource\Themes. This causes themes to fail to load. Fixed by
  8. hiding everything under %WINDIR%\Resource from FindFirstFileA.
  9. Notes:
  10. This is a application specific shim.
  11. History:
  12. 5/13/2002 mikrause Created
  13. --*/
  14. #include "precomp.h"
  15. #include <nt.h>
  16. IMPLEMENT_SHIM_BEGIN(UltraWinCleaner2002)
  17. #include "ShimHookMacro.h"
  18. APIHOOK_ENUM_BEGIN
  19. APIHOOK_ENUM_ENTRY(NtQueryDirectoryFile)
  20. APIHOOK_ENUM_END
  21. UNICODE_STRING g_strWinResourceDir;
  22. typedef NTSTATUS (WINAPI *_pfn_NtQueryDirectoryFile)(HANDLE, HANDLE,
  23. PIO_APC_ROUTINE, PVOID, PIO_STATUS_BLOCK, PVOID, ULONG,
  24. FILE_INFORMATION_CLASS, BOOLEAN, PUNICODE_STRING, BOOLEAN);
  25. NTSTATUS
  26. APIHOOK(NtQueryDirectoryFile)(
  27. IN HANDLE FileHandle,
  28. IN HANDLE Event OPTIONAL,
  29. IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
  30. IN PVOID ApcContext OPTIONAL,
  31. OUT PIO_STATUS_BLOCK IoStatusBlock,
  32. OUT PVOID FileInformation,
  33. IN ULONG FileInformationLength,
  34. IN FILE_INFORMATION_CLASS FileInformationClass,
  35. IN BOOLEAN ReturnSingleEntry,
  36. IN PUNICODE_STRING FileName OPTIONAL,
  37. IN BOOLEAN RestartScan
  38. )
  39. {
  40. //
  41. // If caller wants any async behavior, skip.
  42. // FileName must be valid.
  43. //
  44. if (Event == NULL && ApcRoutine == NULL && ApcContext == NULL && FileName != NULL) {
  45. // Only trap complete wildcard searches.
  46. if (lstrcmpW(FileName->Buffer, L"*.*") == 0 ||
  47. lstrcmpW(FileName->Buffer, L"*") == 0) {
  48. DWORD dwSize = MAX_PATH * sizeof(WCHAR) + sizeof(OBJECT_NAME_INFORMATION);
  49. PBYTE pbBuffer = new BYTE[dwSize];
  50. if (pbBuffer) {
  51. ULONG RetLen;
  52. ZeroMemory(pbBuffer, dwSize);
  53. POBJECT_NAME_INFORMATION poni = (POBJECT_NAME_INFORMATION)pbBuffer;
  54. // Get the name of the directory
  55. NTSTATUS status = NtQueryObject(FileHandle, ObjectNameInformation,
  56. poni, dwSize, &RetLen);
  57. // Retry if not enough buffer
  58. if (status == STATUS_BUFFER_TOO_SMALL) {
  59. delete [] pbBuffer;
  60. pbBuffer = new BYTE[RetLen];
  61. if (pbBuffer) {
  62. poni = (POBJECT_NAME_INFORMATION)pbBuffer;
  63. status = NtQueryObject(FileHandle, ObjectNameInformation,
  64. poni, RetLen, &RetLen);
  65. }
  66. }
  67. // Check if it is the Windows Resource directory.
  68. if (NT_SUCCESS(status)) {
  69. if (CompareString(LOCALE_INVARIANT, NORM_IGNORECASE,
  70. poni->Name.Buffer, poni->Name.Length / sizeof(WCHAR),
  71. g_strWinResourceDir.Buffer, g_strWinResourceDir.Length / sizeof(WCHAR)) == CSTR_EQUAL) {
  72. // Pretend this directory doesn't exist.
  73. DPFN(eDbgLevelInfo, "[NtQueryDirectoryFile] Ignoring all file searches in %S",
  74. poni->Name.Buffer);
  75. delete [] pbBuffer;
  76. return STATUS_NO_SUCH_FILE;
  77. }
  78. }
  79. if (pbBuffer) {
  80. delete [] pbBuffer;
  81. }
  82. }
  83. }
  84. }
  85. return ORIGINAL_API(NtQueryDirectoryFile)(FileHandle, Event, ApcRoutine,
  86. ApcContext, IoStatusBlock, FileInformation, FileInformationLength,
  87. FileInformationClass, ReturnSingleEntry, FileName, RestartScan);
  88. }
  89. BOOL
  90. NOTIFY_FUNCTION(
  91. DWORD fdwReason
  92. )
  93. {
  94. if (fdwReason == DLL_PROCESS_ATTACH)
  95. {
  96. CSTRING_TRY
  97. {
  98. // Get the Windows Resource directory (which holds themes)
  99. CString csWinResourceDir;
  100. csWinResourceDir.GetWindowsDirectoryW();
  101. csWinResourceDir.AppendPath(L"Resources");
  102. //
  103. // Convert the DOS name like C:\Windows\Resources to
  104. // \Device\HarddiskVolume0\Windows\Resources which NT likes.
  105. //
  106. CString csWinDrive;
  107. csWinResourceDir.GetDrivePortion(csWinDrive);
  108. WCHAR wszBuffer[1024];
  109. if (QueryDosDeviceW(csWinDrive, wszBuffer, 1024)) {
  110. csWinResourceDir.Replace(csWinDrive, wszBuffer);
  111. ZeroMemory(&g_strWinResourceDir, sizeof(g_strWinResourceDir));
  112. PWSTR wsz = new WCHAR[csWinResourceDir.GetLength()+1];
  113. if (wsz) {
  114. StringCchCopyW(wsz, csWinResourceDir.GetLength() + 1, csWinResourceDir);
  115. DPFN(eDbgLevelInfo, "Ignoring all file searches in %S", wsz);
  116. RtlInitUnicodeString(&g_strWinResourceDir, wsz);
  117. } else {
  118. return FALSE;
  119. }
  120. } else {
  121. return FALSE;
  122. }
  123. }
  124. CSTRING_CATCH
  125. {
  126. DPFN(eDbgLevelError, "CString exception in NotifyFunc!\n");
  127. return FALSE;
  128. }
  129. }
  130. return TRUE;
  131. }
  132. HOOK_BEGIN
  133. CALL_NOTIFY_FUNCTION
  134. APIHOOK_ENTRY(NTDLL.DLL, NtQueryDirectoryFile)
  135. HOOK_END
  136. IMPLEMENT_SHIM_END