Solved

EnumServicesStatus Vs. EnumServicesStatusEx

Posted on 2004-09-03
7
1,366 Views
Last Modified: 2008-01-09
I've a problem when using either EnumServicesStatus or EnumServicesStatusEx.

When using EnumServicesStatus it returns 85 services.

When using EnumServicesStatusEx it returns only 70 services (and no, i haven't deleted any services). I noticed that the Alerter service is showing up when using EnumServicesStatus but not when i'm using EnumServicesStatusEx.

All the parameteres are the same:
SC_ENUM_TYPE       InfoLevel = SC_ENUM_PROCESS_INFO;
DWORD            dwServiceType = SERVICE_WIN32,
            dwServiceState = SERVICE_STATE_ALL,
                      chBufSize = 30720,
            dwServicesReturned,
            dwBytesNeeded,
            dwResumeHandle = 0,
            dwProcID;
LPCTSTR                  pszGroupName = NULL;
LPENUM_SERVICE_STATUS_PROCESS lpServices;

Any1 got any explanations?
0
Comment
Question by:jead99
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
7 Comments
 
LVL 11

Expert Comment

by:KurtVon
ID: 11976798
Check and make sure GetLastError isn't returning ERROR_MORE_DATA.  The current size is about 384 bytes each for 80 items and 438 bytes each for 70.  I know the Ex version returns bigger structs, but only 16 bytes or so.  Still worth checking out though.

Note that the Ex version returns ERROR_MORE_DATA but the original returns ERROR_INSUFFICIENT_BUFFER, so if you are catching the error already, make sure you are checking for the correct one.

Hope this helps.
0
 

Author Comment

by:jead99
ID: 11979347
Allready tried that, it doesn't return any errors.
0
 
LVL 11

Expert Comment

by:KurtVon
ID: 11996508
Keep in mind that if there is more data the function call doesn't return an error.  You still have to check the GetLastError() value.  Dumb, I know, but the logic seems to be that since the function returns as much data as can fit in the buffer you provided it did succeed, even if there was an "error" of the buffer being too small.
0
 
LVL 11

Expert Comment

by:KurtVon
ID: 11996827
By the way, I tried running this code as a test:

    ENUM_SERVICE_STATUS Services[100];
    DWORD cbNeeded, dwRet, dwHandle = 0;
    SC_HANDLE hSC = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT | SC_MANAGER_ENUMERATE_SERVICE);
    EnumServicesStatus(hSC, SERVICE_WIN32, SERVICE_STATE_ALL,
                       Services, sizeof(Services), &cbNeeded,
                       &dwRet, &dwHandle);


    dwHandle = 0;
    ENUM_SERVICE_STATUS_PROCESS ServicesEx[100];
    EnumServicesStatusEx(hSC, SC_ENUM_PROCESS_INFO, SERVICE_WIN32,
                         SERVICE_STATE_ALL, (BYTE*)ServicesEx, sizeof(ServicesEx),
                         &cbNeeded, &dwRet, &dwHandle,
                         NULL);

and despite there being more than enough entries, both required multiple calls to feed through the entire services set, even though there was plenty of room in the array.  In the end they returned the same number of services, though.

I'm surprised about the alerter service.  It showed up first on both lists for me.
0
 
LVL 11

Accepted Solution

by:
KurtVon earned 50 total points
ID: 11997011
This code worked perfectly (the first looped 3 times, the second twice):

    ENUM_SERVICE_STATUS Services[100];
    DWORD dwIndex = 0;
    DWORD cbNeeded, dwRet, dwHandle = 0;
    SC_HANDLE hSC = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT | SC_MANAGER_ENUMERATE_SERVICE);
    do
    {
        EnumServicesStatus(hSC, SERVICE_WIN32, SERVICE_STATE_ALL,
                           &(Services[dwIndex]), sizeof(Services[0]) * (100 - dwIndex), &cbNeeded,
                           &dwRet, &dwHandle);
        dwIndex += dwRet;
    } while ((dwHandle != 0) && (dwIndex < 100));


    dwHandle = 0;
    dwIndex = 0;
    ENUM_SERVICE_STATUS_PROCESS ServicesEx[100];
    do
    {
        EnumServicesStatusEx(hSC, SC_ENUM_PROCESS_INFO, SERVICE_WIN32,
                             SERVICE_STATE_ALL, (BYTE*)&(ServicesEx[dwIndex]),
                             sizeof(ServicesEx[0]) * (100 - dwIndex),
                             &cbNeeded, &dwRet, &dwHandle,
                             NULL);
        dwIndex += dwRet;
    } while ((dwHandle != 0) && (dwIndex < 100));
0

Featured Post

[Live Webinar] The Cloud Skills Gap

As Cloud technologies come of age, business leaders grapple with the impact it has on their team's skills and the gap associated with the use of a cloud platform.

Join experts from 451 Research and Concerto Cloud Services on July 27th where we will examine fact and fiction.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Have you thought about creating an iPhone application (app), but didn't even know where to get started? Here's how: ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ Important pre-programming comments: I’ve never tri…
Windows programmers of the C/C++ variety, how many of you realise that since Window 9x Microsoft has been lying to you about what constitutes Unicode (http://en.wikipedia.org/wiki/Unicode)? They will have you believe that Unicode requires you to use…
The goal of this video is to provide viewers with basic examples to understand and use pointers in the C programming language.
The goal of this video is to provide viewers with basic examples to understand and use switch statements in the C programming language.

624 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question