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.

147 lines
3.7 KiB

  1. //
  2. // event.cxx - simple eventing mechanism for ras/offline/logon events
  3. //
  4. #include "wininetp.h"
  5. #include <docobj.h>
  6. //
  7. // Globals
  8. //
  9. static const TCHAR szEventKey[] = REGSTR_PATH_INETEVENTS;
  10. CLSID clsidEventGroup = { /* ab8ed004-b86a-11d1-b1f8-00c04fa357fa */
  11. 0xab8ed004,
  12. 0xb86a,
  13. 0x11d1,
  14. {0xb1, 0xf8, 0x00, 0xc0, 0x4f, 0xa3, 0x57, 0xfa}
  15. };
  16. //
  17. // remember events so we don't repeat them
  18. //
  19. static DWORD g_dwOffline = 0;
  20. //
  21. // SendEvent - deliver an event to a single client
  22. //
  23. BOOL SendEvent(DWORD dwEvent, VARIANTARG *pva, LPTSTR pszValue)
  24. {
  25. CLSID clsid;
  26. IOleCommandTarget *poct;
  27. HRESULT hr = E_FAIL;
  28. #ifdef UNICODE
  29. if(FAILED(CLSIDFromString(pszValue, &clsid)))
  30. return FALSE;
  31. #else
  32. WCHAR wszCLSID[80];
  33. MultiByteToWideChar(CP_ACP, 0, pszValue, -1, wszCLSID, sizeof(wszCLSID) / sizeof(WCHAR));
  34. if(FAILED(CLSIDFromString(wszCLSID, &clsid)))
  35. return FALSE;
  36. #endif
  37. hr = (CoCreateInstance(clsid, NULL, CLSCTX_ALL,
  38. IID_IOleCommandTarget, (void **)&poct));
  39. if(SUCCEEDED(hr))
  40. {
  41. // ensure client likes our group
  42. hr = poct->Exec(&clsidEventGroup, dwEvent, 0, pva, NULL);
  43. poct->Release();
  44. }
  45. return SUCCEEDED(hr);
  46. }
  47. //
  48. // EnumClients - send all events to clients in a reg key
  49. //
  50. DWORD EnumClients(HKEY hkey, DWORD dwEvent, LPWSTR pwsEventDesc, DWORD dwEventData)
  51. {
  52. DWORD cbData, cbValue, dwType, i, dwMask;
  53. TCHAR szValueName[80];
  54. VARIANTARG va;
  55. va.vt = VT_EMPTY;
  56. //
  57. // Enumerate everyone
  58. //
  59. for (i = 0; ; i++)
  60. {
  61. LONG lEnum;
  62. cbValue = sizeof(szValueName) / sizeof(TCHAR);
  63. cbData = sizeof(DWORD);
  64. // BUGBUG (Unicode, Davepl) I'm assuming that the data is UNICODE,
  65. // but I'm not sure who put it there yet... double check.
  66. if( ( lEnum = RegEnumValue( hkey, i, szValueName, &cbValue, NULL,
  67. &dwType, (LPBYTE)&dwMask, &cbData ) ) == ERROR_MORE_DATA )
  68. {
  69. // ERROR_MORE_DATA means the value name or data was too large
  70. // skip to the next item
  71. continue;
  72. }
  73. else if( lEnum != ERROR_SUCCESS )
  74. {
  75. // could be ERROR_NO_MORE_ENTRIES, or some kind of failure
  76. // we can't recover from any other registry problem, anyway
  77. break;
  78. }
  79. if(0 != (dwMask & dwEvent)) {
  80. // this guy wants this event
  81. SendEvent(dwEvent, &va, szValueName);
  82. }
  83. }
  84. return 0;
  85. }
  86. //
  87. // DispatchEvent - enumerate all clients and deliver the event to them
  88. //
  89. DWORD InternetDispatchEvent(DWORD dwEvent, LPWSTR pwsEventDesc, DWORD dwEventData)
  90. {
  91. HKEY hkey;
  92. // get rid of repeated events here
  93. switch(dwEvent) {
  94. case INETEVT_OFFLINE:
  95. if(g_dwOffline == dwEvent)
  96. return 0;
  97. g_dwOffline = dwEvent;
  98. break;
  99. case INETEVT_ONLINE:
  100. if(g_dwOffline == dwEvent)
  101. return 0;
  102. g_dwOffline = dwEvent;
  103. break;
  104. default:
  105. return ERROR_INVALID_PARAMETER;
  106. }
  107. // fire up com
  108. if(SUCCEEDED(CoInitialize(NULL))) {
  109. if (REGOPENKEY(HKEY_CURRENT_USER, szEventKey, &hkey) == ERROR_SUCCESS) {
  110. EnumClients(hkey, dwEvent, pwsEventDesc, dwEventData);
  111. REGCLOSEKEY(hkey);
  112. }
  113. if (REGOPENKEY(HKEY_LOCAL_MACHINE, szEventKey, &hkey) == ERROR_SUCCESS) {
  114. EnumClients(hkey, dwEvent, pwsEventDesc, dwEventData);
  115. REGCLOSEKEY(hkey);
  116. }
  117. CoUninitialize();
  118. }
  119. return 0;
  120. }