/**************************************************************************\ * Module Name: instdev.c * * Device handling routine for CSRSS. * * Copyright (c) 1985 - 1999, Microsoft Corporation * * Created: 13-Mar-97 * * History: * 13-Mar-97 created by PaulaT \**************************************************************************/ #include "precomp.h" #pragma hdrstop #include "ntuser.h" #include #include /**************************************************************************\ * SrvDeviceEvent * * User-mode PNP manager (in services.exe) has a message to deliver to an * app that has registered for this notification but services.exe isn't * in WinSta0\Default so we need a CSRSS thread to simply send the message. * * PaulaT 06/04/97 Created. * JasonSch 02/22/01 Removed bogus try/except. \**************************************************************************/ ULONG SrvDeviceEvent( IN OUT PCSR_API_MSG m, IN OUT PCSR_REPLY_STATUS ReplyStatus) { NTSTATUS Status; PDEVICEEVENTMSG a = (PDEVICEEVENTMSG)&m->u.ApiMessageData; USERTHREAD_USEDESKTOPINFO utudi; UNREFERENCED_PARAMETER(ReplyStatus); // // Set the desktop to the active desktop before sending the // message. // utudi.hThread = NULL; utudi.drdRestore.pdeskRestore = NULL; Status = NtUserSetInformationThread(NtCurrentThread(), UserThreadUseActiveDesktop, &utudi, sizeof(utudi)); if (!NT_SUCCESS(Status)) { RIPMSG1(RIP_WARNING, "SrvDeviceEvent: NtUserSetInformationThread failed 0x%x\n", Status); goto Exit; } // // Verify the window handle is still valid. If not, let the caller know // so it can be purged from the notification window list that the // user-mode pnp manager keeps. // if (a->hWnd != HWND_BROADCAST && !IsWindow(a->hWnd)) { Status = STATUS_INVALID_HANDLE; goto ResetDesktop; } if (a->dwFlags) { // // This is a query so we have to send the message but use // timeouts so an app can't stall us forever. // RIPMSG3(RIP_VERBOSE, "SrvDeviceEvent: Sending WM_DEVICECHANGE to 0x%x, w 0x%p, l 0x%p", a->hWnd, a->wParam, a->lParam); if (!SendMessageTimeout(a->hWnd, WM_DEVICECHANGE, a->wParam, a->lParam, SMTO_ABORTIFHUNG | SMTO_NORMAL, PNP_NOTIFY_TIMEOUT, &a->dwResult)) { Status = STATUS_UNSUCCESSFUL; } } else { // // It's not a query so just post it and return. We don't // care what the app returns. // RIPMSG3(RIP_VERBOSE, "SrvDeviceEvent: Posting WM_DEVICECHANGE to 0x%x, w 0x%p, l 0x%p", a->hWnd, a->wParam, a->lParam); if (!PostMessage(a->hWnd, WM_DEVICECHANGE, a->wParam, a->lParam)) { Status = STATUS_UNSUCCESSFUL; } } ResetDesktop: // // Reset this thread's desktop back to NULL before returning. This // decrements the desktop's reference count. // NtUserSetInformationThread(NtCurrentThread(), UserThreadUseDesktop, &utudi, sizeof(utudi)); Exit: return Status; }