cbthook.c
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 6k
Category:

Windows Kernel

Development Platform:

Visual C++

  1. //---------------------------------------------------------------------------
  2. //
  3. // Copyright (c) Microsoft Corporation 1991-1992
  4. //
  5. //---------------------------------------------------------------------------
  6. #include "shellprv.h"
  7. #pragma  hdrstop
  8. #include <regstr.h>
  9. // this is for backwards compat only.
  10. HWND       hwndMainShell = NULL;
  11. HWND       hwndTaskMan = NULL;
  12. const TCHAR s_szHKEYExplorerVolatile[] = REGSTR_PATH_EXPLORER TEXT("\Volatile");
  13. //----------------------------------------------------------------------------
  14. // ShellHookProc was mistakenly exported in the original NT SHELL32.DLL when
  15. // it didn't need to be (hookproc's, like wndproc's don't need to be exported
  16. // in the 32-bit world).  In order to maintain loadability of some stupid app
  17. // which might have linked to it, we stub it here.  If some app ended up really
  18. // using it, then we'll look into a specific fix for that app.
  19. //
  20. // -BobDay
  21. //
  22. LONG WINAPI ShellHookProc( INT code, WPARAM wParam, LPARAM lParam)
  23. {
  24.     return 0;
  25. }
  26. //---------------------------------------------------------------------------
  27. // RegisterShellHook - This function is meant to allow applications to set
  28. // themselves up as shell replacements.  One of the things they need to do
  29. // is watch alot of the WH_CBT hook events.  But to simplify things for them,
  30. // the old code used to translate the hook events into messages and then
  31. // either post or send the messages.  The new method, implemented below, lets
  32. // USER do most of the real work.  This allows USER to convert the hook event
  33. // directly into a message and thereby save having to load hook callback
  34. // code (in this case us, SHELL32.DLL) into any processes address space where
  35. // a CBT hook event occurred.
  36. BOOL WINAPI RegisterShellHook(HWND hwnd, BOOL fInstall)
  37. {
  38.     BOOL    fOk = TRUE;
  39.     // gross hacks galore...
  40.     switch (fInstall) {
  41.     case 2:
  42.         // from win 3.1 to know what to activate on the fault
  43.         // and because they use special registered messages
  44.         //
  45.         // Special magic from PROGMAN - They want only certain CBT
  46.         // hook events as messages.
  47.         //
  48.         if ( hwndMainShell != NULL )
  49.         {
  50.             SetProgmanWindow(NULL);
  51.             hwndMainShell = NULL;
  52.         }
  53.         fOk = SetProgmanWindow(hwnd);
  54.         if ( fOk )
  55.         {
  56.             hwndMainShell = hwnd;
  57.         }
  58.         break;
  59.     case 3:
  60.         //
  61.         // Special magic from TASKMAN & TRAY - They want only certain
  62.         // CBT hook events as messages.
  63.         //
  64.         if ( hwndTaskMan != NULL )
  65.         {
  66.             SetTaskmanWindow(NULL);
  67.             hwndTaskMan = NULL;
  68.         }
  69.         fOk = SetTaskmanWindow(hwnd);
  70.         if ( fOk )
  71.         {
  72.             hwndTaskMan = hwnd;
  73.         }
  74.         break;
  75.     case 4:
  76.         //
  77.         // Special magic from TRAY / EXPLORER - It wants to know if
  78.         // there is already a taskman window installed so it can fix
  79.         // itself if there was some sort of explorer restart.
  80.         //
  81. #if 1
  82.         // The GetTaskmanWindow function was not reliable as it will only return
  83.         // back valid windows so if we crashed we would not have a valid handle and
  84.         // it returned NULL
  85.         {
  86.             HKEY hk;
  87.             DWORD dw;
  88.             DWORD dwType;
  89.             DWORD cbData;
  90.             FILETIME ft;
  91.             FILETIME ftLast;
  92.             if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SYSTEM\CurrentControlSet\Control\Windows"),
  93.                              0, KEY_READ, &hk) != ERROR_SUCCESS)
  94.                 return TRUE;    // Assume that it is ok to try again...
  95.             cbData = sizeof(ftLast);
  96.             SHQueryValueEx(hk, TEXT("ShutDownTime"), NULL, &dwType, (LPBYTE)&ftLast, &cbData);
  97.             RegCloseKey(hk);
  98.             if (RegCreateKeyEx(HKEY_CURRENT_USER, s_szHKEYExplorerVolatile, 0, TEXT(""), REG_OPTION_VOLATILE, 
  99.                     KEY_READ | KEY_WRITE, NULL, &hk, &dw) == ERROR_SUCCESS)
  100.             {
  101.                 // Do we need to set a value here?
  102.                 if (dw != REG_CREATED_NEW_KEY)
  103.                 {
  104.                     cbData = sizeof(ft);
  105.                     if ((SHQueryValueEx(hk, TEXT("ShutDownTime"), NULL, &dwType, (LPBYTE)&ft, &cbData)
  106.                             == ERROR_SUCCESS) && (memcmp(&ftLast, &ft, sizeof(FILETIME)) == 0))
  107.                     {
  108.                         RegCloseKey(hk);
  109.                         return FALSE;   // Been here so don't try rerunning things again
  110.                     }
  111.                 }
  112.                 // Ok save away the last shutdown time into our temporay area...
  113.                 RegSetValueEx(hk, TEXT("ShutdownTime"), 0, REG_BINARY, (LPBYTE)&ftLast, sizeof(ftLast)); 
  114.                 RegCloseKey(hk);                 
  115.             }
  116.             return TRUE;
  117.         }
  118.         
  119. #else
  120.         hwndTaskMan = GetTaskmanWindow();
  121.         return ( hwndTaskMan == NULL );
  122. #endif
  123.     case 5:
  124.         // Not needed in NT -- this is used for overflow processing in Win95.
  125.         return TRUE;
  126.     case 0:
  127.         //
  128.         // Process un-installation of fake shell hooks
  129.         //
  130.         hwndMainShell = GetProgmanWindow();
  131.         hwndTaskMan   = GetTaskmanWindow();
  132.         if ( hwnd == hwndMainShell )
  133.         {
  134.             SetProgmanWindow(NULL);
  135.         }
  136.         if ( hwnd == hwndTaskMan )
  137.         {
  138.             SetTaskmanWindow(NULL);
  139.         }
  140.         DeregisterShellHookWindow(hwnd);
  141.         return TRUE;
  142.     }
  143.     //
  144.     // Process installation of fake shell hooks
  145.     //
  146.     return RegisterShellHookWindow(hwnd);
  147. }