Ver Mensaje Individual
  #3 (permalink)  
Antiguo 11/09/2013, 04:02
vosk
 
Fecha de Ingreso: agosto-2012
Mensajes: 601
Antigüedad: 11 años, 8 meses
Puntos: 83
Respuesta: Recuperar los servicios que utiliza un proceso

No puedo ayudarte en esto de los servicios porque nunca lo he echo antes, pero te comento un par de cosas:

En la linea 27 creas un acceso de consulta al proceso solo para obtener una descripcion de la prioridad de ejecucion que se asigna al proceso (ejecucion p.ej. como salvapantallas cuando el sistema está ocioso, forzado de actualizacion en todos los ciclos para respuestas rápidas, etc). El echo de que no puedas abrir este manejador para la consulta de la prioridad, o el echo de que no puedas obtener la prioridad no significa que tengas que descartar el proceso tal como haces en las lineas 31 (error en abrir manejador para consulta) y 38 (error en recuperar prioridad). En tu codigo cuando se da uno de los dos errores que te he comentado, no solo descartas el proceso sino que retornas nulo finalizando el recorrido de los procesos y ademas sin liberar los recursos de hProcessSnap (antes de los retornos nulos de 31 y 38 deberías cerrar el manejador hProcessSnap); otra cosa, en windows acostumbra a inicializar las estructuras a 0 (este truco puede ahorrarte mas de un dolor de cabeza); te pongo una reorganizacion de tu codigo:

Código C:
Ver original
  1. HANDLE hProcessSnap;
  2. HANDLE hProcess;
  3. PROCESSENTRY32 pe32;
  4. DWORD dwPriorityClass;
  5.  
  6. if((hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0)) != INVALID_HANDLE_VALUE) {
  7.     memset(&pe32, 0, sizeof(pe32));//resetea la struct antes de usarla
  8.     pe32.dwSize = sizeof(PROCESSENTRY32);
  9.     if(Process32First(hProcessSnap, &pe32)) {
  10.         do {
  11.             dwPriorityClass = 0;
  12.             if((hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, pe32.th32ProcessID))) {
  13.                 dwPriorityClass = GetPriorityClass(hProcess);
  14.                 CloseHandle(hProcess);
  15.             }
  16.             //no descartas el proceso pe32.th32ProcessID
  17.             //implementar función para obtener los servicios que son usados por el proceso según el id del proceso
  18.  
  19.         } while(Process32Next(hProcessSnap, &pe32));
  20.     }
  21.     CloseHandle(hProcessSnap);
  22. }


Para lo de EnumServicesStatusEx, solo tienes que proveer los argumentos que te pide:

Código C:
Ver original
  1. BOOL WINAPI EnumServicesStatusEx(
  2.     SC_HANDLE hSCManager,
  3.     SC_ENUM_TYPE InfoLevel,
  4.     DWORD dwServiceType,
  5.     DWORD dwServiceState,
  6.     LPBYTE lpServices,
  7.     DWORD cbBufSize,
  8.     LPDWORD pcbBytesNeeded,
  9.     LPDWORD lpServicesReturned,
  10.     LPDWORD lpResumeHandle,
  11.     LPCTSTR pszGroupName
  12.     );

El SC_HANDLE es una conexion a la base de datos del manejador de servicios, la funcion OpenSCManager abre esta conexion solicitando un nombre de equipo y una base de datos (si provees nulo para todo abre lo que hay por defecto (servicios activos de acceso libre en maquina local) (recuerda de finalizar esta conexion al terminar el trabajo):

Código C:
Ver original
  1. SC_HANDLE sch;
  2. sch = OpenSCManager(0, 0,  SC_MANAGER_ENUMERATE_SERVICE|SC_MANAGER_CONNECT);

El SC_ENUM_TYPE es el flag de filtro, SC_ENUM_PROCESS_INFO para recuperar todos los servicios. Esto implica que el argumento lpServices tenga que ser un buffer donde se copiara la lista de estructuras de servicio. Lo que suele hacerse es ejecutar con un lpServices nulo y un cbBufSize (tamaño del lpServices) de 0 para que te salte el error de memoria insuficiente y te copie en pcbBytesNeeded el tamaño esperado, luego reservas la memoria y ejecutas de forma segura.

Luego tienes dwServiceType y dwServiceState que son mas flags de filtro (en msdn tienes la referencia).

Y por ultimo tienes el puntero de lectura de la lista lpResumeHandle que debes iniciar a nulo antes de comenzar.

Con esto obtienes una lista de ENUM_SERVICE_STATUS_PROCESS (nombre identificador, nombre servicio y estructura de informacion de estado). Esta estructura de informacion SERVICE_STATUS_PROCESS lleva el campo dwProcessId que será el identificador del proceso que corre como servicio.

Y aquí es donde creo que está el truco, tendras que probar a ver si funciona: cuando tienes el identificador del proceso servicio puedes compararlo con la lista de procesos abiertos por cada proceso que encontraste en pe32.th32ProcessID. Tendras que encontrar una lista de procesos hijo y compararlos con lo ids de procesos servicio.

No se si te habré ayudado en algo con esto; siento no poner un ejemplo funcional, si tengo un rato me lo miro a ver que sale.

Saludos
vosk