81 lines
2.9 KiB
C
81 lines
2.9 KiB
C
/*
|
|
* Module Name: instdev.c
|
|
|
|
* Server device handling routine for the CSR stuff.
|
|
|
|
* 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 "dbt.h"
|
|
#include "pnpmgr.h"
|
|
|
|
|
|
/*
|
|
* 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 csr thread to simply send the message.
|
|
|
|
* PaulaT 06/04/97
|
|
*/
|
|
ULONG SrvDeviceEvent(IN OUT PCSR_API_MSG m, IN OUT PCSR_REPLY_STATUS ReplyStatus)
|
|
{
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
|
PDEVICEEVENTMSG a = (PDEVICEEVENTMSG)&m->u.ApiMessageData;
|
|
USERTHREAD_USEDESKTOPINFO utudi;
|
|
|
|
UNREFERENCED_PARAMETER(ReplyStatus);
|
|
|
|
try {
|
|
// 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)) {
|
|
#if DBG
|
|
KdPrint(("--> SrvDeviceEvent: NtUserSetInformationThread failed %d\n", Status));
|
|
#endif
|
|
goto Clean1;
|
|
}
|
|
|
|
// Verify the window handle is still valid, if not, let the caller know
|
|
// so it can be purged from the notification window hand list that the user-mode pnp manager keeps.
|
|
if ((a->hWnd != HWND_BROADCAST) && !IsWindow(a->hWnd)) {
|
|
Status = STATUS_INVALID_HANDLE;
|
|
goto Clean0;
|
|
}
|
|
|
|
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%x, l 0x%x", (ULONG_PTR)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%x, l 0x%x", (ULONG_PTR)a->hWnd, a->wParam, a->lParam);
|
|
if (!PostMessage(a->hWnd, WM_DEVICECHANGE, a->wParam, a->lParam)) {
|
|
Status = STATUS_UNSUCCESSFUL;
|
|
}
|
|
}
|
|
|
|
Clean0:
|
|
// Reset this thread's desktop back to NULL before returning. This decrements the desktop's reference count.
|
|
NtUserSetInformationThread(NtCurrentThread(), UserThreadUseDesktop, &utudi, sizeof(utudi));
|
|
|
|
Clean1:
|
|
;
|
|
} except (EXCEPTION_EXECUTE_HANDLER) {
|
|
KdPrint(("SrvDeviceEvent generated an exception (%d)\n", GetExceptionCode()));
|
|
Status = STATUS_UNSUCCESSFUL;
|
|
}
|
|
|
|
return Status;
|
|
} // SrvDeviceEvent
|