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.

116 lines
3.4 KiB

  1. /**************************************************************************\
  2. * Module Name: instdev.c
  3. *
  4. * Device handling routine for CSRSS.
  5. *
  6. * Copyright (c) 1985 - 1999, Microsoft Corporation
  7. *
  8. * Created: 13-Mar-97
  9. *
  10. * History:
  11. * 13-Mar-97 created by PaulaT
  12. \**************************************************************************/
  13. #include "precomp.h"
  14. #pragma hdrstop
  15. #include "ntuser.h"
  16. #include <dbt.h>
  17. #include <pnpmgr.h>
  18. /**************************************************************************\
  19. * SrvDeviceEvent
  20. *
  21. * User-mode PNP manager (in services.exe) has a message to deliver to an
  22. * app that has registered for this notification but services.exe isn't
  23. * in WinSta0\Default so we need a CSRSS thread to simply send the message.
  24. *
  25. * PaulaT 06/04/97 Created.
  26. * JasonSch 02/22/01 Removed bogus try/except.
  27. \**************************************************************************/
  28. ULONG
  29. SrvDeviceEvent(
  30. IN OUT PCSR_API_MSG m,
  31. IN OUT PCSR_REPLY_STATUS ReplyStatus)
  32. {
  33. NTSTATUS Status;
  34. PDEVICEEVENTMSG a = (PDEVICEEVENTMSG)&m->u.ApiMessageData;
  35. USERTHREAD_USEDESKTOPINFO utudi;
  36. UNREFERENCED_PARAMETER(ReplyStatus);
  37. //
  38. // Set the desktop to the active desktop before sending the
  39. // message.
  40. //
  41. utudi.hThread = NULL;
  42. utudi.drdRestore.pdeskRestore = NULL;
  43. Status = NtUserSetInformationThread(NtCurrentThread(),
  44. UserThreadUseActiveDesktop,
  45. &utudi, sizeof(utudi));
  46. if (!NT_SUCCESS(Status)) {
  47. RIPMSG1(RIP_WARNING, "SrvDeviceEvent: NtUserSetInformationThread failed 0x%x\n", Status);
  48. goto Exit;
  49. }
  50. //
  51. // Verify the window handle is still valid. If not, let the caller know
  52. // so it can be purged from the notification window list that the
  53. // user-mode pnp manager keeps.
  54. //
  55. if (a->hWnd != HWND_BROADCAST && !IsWindow(a->hWnd)) {
  56. Status = STATUS_INVALID_HANDLE;
  57. goto ResetDesktop;
  58. }
  59. if (a->dwFlags) {
  60. //
  61. // This is a query so we have to send the message but use
  62. // timeouts so an app can't stall us forever.
  63. //
  64. RIPMSG3(RIP_VERBOSE, "SrvDeviceEvent: Sending WM_DEVICECHANGE to 0x%x, w 0x%p, l 0x%p",
  65. a->hWnd,
  66. a->wParam,
  67. a->lParam);
  68. if (!SendMessageTimeout(a->hWnd, WM_DEVICECHANGE, a->wParam, a->lParam,
  69. SMTO_ABORTIFHUNG | SMTO_NORMAL,
  70. PNP_NOTIFY_TIMEOUT, &a->dwResult)) {
  71. Status = STATUS_UNSUCCESSFUL;
  72. }
  73. } else {
  74. //
  75. // It's not a query so just post it and return. We don't
  76. // care what the app returns.
  77. //
  78. RIPMSG3(RIP_VERBOSE, "SrvDeviceEvent: Posting WM_DEVICECHANGE to 0x%x, w 0x%p, l 0x%p",
  79. a->hWnd,
  80. a->wParam,
  81. a->lParam);
  82. if (!PostMessage(a->hWnd, WM_DEVICECHANGE, a->wParam, a->lParam)) {
  83. Status = STATUS_UNSUCCESSFUL;
  84. }
  85. }
  86. ResetDesktop:
  87. //
  88. // Reset this thread's desktop back to NULL before returning. This
  89. // decrements the desktop's reference count.
  90. //
  91. NtUserSetInformationThread(NtCurrentThread(),
  92. UserThreadUseDesktop,
  93. &utudi, sizeof(utudi));
  94. Exit:
  95. return Status;
  96. }