Solved

EnumServicesStatus Vs. EnumServicesStatusEx

Posted on 2004-09-03
7
1,306 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
  • 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

NAS Cloud Backup Strategies

This article explains backup scenarios when using network storage. We review the so-called “3-2-1 strategy” and summarize the methods you can use to send NAS data to the cloud

Question has a verified solution.

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

An Outlet in Cocoa is a persistent reference to a GUI control; it connects a property (a variable) to a control.  For example, it is common to create an Outlet for the text field GUI control and change the text that appears in this field via that Ou…
Summary: This tutorial covers some basics of pointer, pointer arithmetic and function pointer. What is a pointer: A pointer is a variable which holds an address. This address might be address of another variable/address of devices/address of fu…
The goal of this video is to provide viewers with basic examples to understand opening and reading files in the C programming language.
The goal of this video is to provide viewers with basic examples to understand how to create, access, and change arrays in the C programming language.

821 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