1

I'm trying to count the number of monitors (i.e. screens) attached to the console from a service application. I do the following:

int CountMonitors()
{
    int nCnt = 0;

    if(!EnumDisplayMonitors(NULL, NULL, _countMonitorEnumProc, (LPARAM)&nCnt))
    {
        //Error
        nCnt = -1;
    }

    return nCnt;
}

BOOL _countMonitorEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData)
{
    int* pCnt = (int*)dwData;
    (*pCnt)++;

    return TRUE;
}

but the count is always 1 (when I'm testing it on a dual-monitor Windows 7.) I then do this (which is not exactly what I need due to its limitation):

int nCnt = GetSystemMetrics(SM_CMONITORS);

and the result is also 1.

So how do you count monitors from a service?

c00000fd
  • 20,994
  • 29
  • 177
  • 400

1 Answers1

1

First, why is the console special to a service, vs number of displays attached on a remote session? Then, what about display mirroring / extended desktop / eyefinity?

Now, learn about Window Stations and Desktops. Then learn about shatter attacks.

Finally, if what you're really after is hardware enumeration, there are APIs for that. SetupDiGetClassDevs on the display monitor setup class will tell you how many physical screens the video card(s) expose.

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
  • Shatter attacks? They fixed it since Vista by introducing session separation. And my software totally incorporates it. I also understand why GUI resources are separated between desktops and window stations. In my case though, local monitor(s) is a global resource, so I'm not sure why such info cannot be available from a service. Knowing the number of monitors I can optimize the service code to be more efficient. – c00000fd Dec 21 '12 at 22:26
  • @user843732: Yes, session separation prevents shatter attacks, as long as you leave it in place. But it's also preventing your `EnumMonitors` call from working. So when you tear down the wall of separation, you'd better understand shatter attacks and not leave yourself vulnerable. – Ben Voigt Dec 21 '12 at 23:02
  • OK, that is the answer then. I thought that session separation would be the issue. What is not clear to me, is why `EnumDisplayMonitors` doesn't simply fail instead of returning an incorrect answer ... – c00000fd Dec 21 '12 at 23:21
  • @user843732: Because it is returning the right answer for the (virtual) session the service is associated with. It's session separation, not lack of a session. So much stuff would fail if a service wasn't associated with some window station, since posting window messages is the heart of much of IPC (DCOM, for instance, uses window messages extensively). – Ben Voigt Dec 22 '12 at 00:59
  • I totally disagree with you on your last statement. Giving "illusion of success" for software written prior to introduction of session isolation is much worse than simply returning an error. – c00000fd Dec 22 '12 at 07:37