枚举Service状态的源代码

Windows内核

枚举Service状态的源代码


Shirley 2006-05-02, 11:19 上午
/*******************************************************

   Copyright (c) 2004 by Michel van Kerkhof, ( michel000@planet.nl  http://home.wxs.nl/~wijk0550/ )                 
                                                                                                                                                                   
   This program is free software; you can redistribute it     
   and/or modify it under the terms of the GNU         
   General Public License as published by the Free     
   Software Foundation; either version 2 of the        
   License, or (at your option) any later version.     
                                                       
   This program is distributed in the hope that it will       
   be useful, but WITHOUT ANY WARRANTY; without        
   even the implied warranty of  MERCHANTABILITY       
   or FITNESS FOR A PARTICULAR PURPOSE.  See the       
   GNU General Public License for more details.        
                                                       
   You should have received a copy of the GNU          
   General Public License along with this program; 
   if not, write to:
   the Free Software Foundation, Inc.,        
   59 Temple Place,                                    
   Suite 330, Boston,                                  
   MA  02111-1307  USA                                 
                                                       
*******************************************************

   This source shows you how to use EnumServicesStatusEx  
  
*******************************************************/



#include <windows.h>
#include <stdio.h>

typedef enum _SC_ENUM_TYPE { 
	SC_ENUM_PROCESS_INFO=0 
} SC_ENUM_TYPE;


typedef BOOL (WINAPI *pEnumServicesStatusExA)(
	SC_HANDLE,
	SC_ENUM_TYPE,
	DWORD,
	DWORD,
	LPBYTE,
	DWORD,
	LPDWORD,
	LPDWORD,
	LPDWORD,
	LPCSTR
);

typedef struct _SERVICE_STATUS_PROCESS { 
	DWORD dwServiceType; 
	DWORD dwCurrentState;
	DWORD dwControlsAccepted; 
	DWORD dwWin32ExitCode; 
	DWORD dwServiceSpecificExitCode;
	DWORD dwCheckPoint; 
	DWORD dwWaitHint; 
	DWORD dwProcessId; 
	DWORD dwServiceFlags;
} SERVICE_STATUS_PROCESS,*LPSERVICE_STATUS_PROCESS;



typedef struct _ENUM_SERVICE_STATUS_PROCESSA {
	LPSTR lpServiceName;
	LPSTR lpDisplayName;
	SERVICE_STATUS_PROCESS ServiceStatusProcess;
} ENUM_SERVICE_STATUS_PROCESSA,*LPENUM_SERVICE_STATUS_PROCESSA;


/*
	Function shows all running services including process id and description
	lpMachineName = Name of the computer to enum the services for or NULL for the local computer
*/


int EnumServices(LPCTSTR lpMachineName)
{

	pEnumServicesStatusExA fnEnumServicesStatusExA;

	HMODULE hAdvapi32;

	ENUM_SERVICE_STATUS_PROCESSA *lpServiceStatus;

	DWORD	dwSize=0,
			dwNumServices=0,
			dwResumeHandle=0;

	SC_HANDLE scHandle=NULL;
	
	int iRet;

	void *lpBuffer=NULL;

	char szBuffer[1024];

	try {

		//load advapi32.dll
		hAdvapi32=LoadLibrary("advapi32.dll");

		if (hAdvapi32 == NULL) {
			throw("Could not load advapi32.dll");
		}

		//load EnumServicesStatusExA from advapi32.dll

		fnEnumServicesStatusExA=(pEnumServicesStatusExA)GetProcAddress(hAdvapi32,"EnumServicesStatusExA");
	
		if (fnEnumServicesStatusExA == NULL) {
			throw("Could not load EnumServicesStatusExA\n");
		}

		/*
			establishes a connection to the service control manager on the specified computer
			if lpMachineName == NULL its the local computer
		*/

		scHandle=OpenSCManager(lpMachineName,NULL,SC_MANAGER_ALL_ACCESS);

		if (scHandle == NULL) {
			throw("Could not connect to the service control manager\n");
		}
		
		
		do {
			/*
				First time dwResumeHandle needs to be 0 
				and dwSize = 0  after return it is set to the size needed
				normaly it will only loop 2 times
				first time to get size of the buffer
				second time to fill the allocated buffer
			*/
			iRet=fnEnumServicesStatusExA(
					scHandle,
					SC_ENUM_PROCESS_INFO,
					SERVICE_WIN32,
					SERVICE_ACTIVE,
					(LPBYTE)lpBuffer,
					dwSize,
					&dwSize,
					&dwNumServices,
					&dwResumeHandle,
					0
			);

			/*
				iRet is always 0 the first time because dwSize was 0
			*/

			if (iRet == 0 && GetLastError() != ERROR_MORE_DATA) {
				throw("Error getting list with services\n");
			}

			lpServiceStatus=(ENUM_SERVICE_STATUS_PROCESSA *)lpBuffer;

			//first time dwNumServices == 0 so we dont loop the first time

			if (dwNumServices > 0) {
				
				HKEY hKey,hSubKey;

				/*
					Connect to registry to get service description
					this is not needed if lpMachineName is the local computer or NULL
				*/
				
				if (RegConnectRegistry(lpMachineName,HKEY_LOCAL_MACHINE,&hKey) != ERROR_SUCCESS) {
					hKey=NULL;
				}
				

				for (DWORD dwCount=0;dwCount<dwNumServices;dwCount++)
				{
					printf("Pid:%i %s: %s\n",
						lpServiceStatus[dwCount].ServiceStatusProcess.dwProcessId,
						lpServiceStatus[dwCount].lpServiceName,
						lpServiceStatus[dwCount].lpDisplayName
					);
				
					if (hKey) {
						//create registry string
							
						sprintf(szBuffer,"SYSTEM\\CurrentControlSet\\Services\\%s",lpServiceStatus[dwCount].lpServiceName);

						if (RegOpenKeyEx(hKey,szBuffer,0,KEY_QUERY_VALUE,&hSubKey) == ERROR_SUCCESS) {
							
							DWORD dwType,dwSize=sizeof(szBuffer);

							if (RegQueryValueEx(hSubKey,"Description",NULL,&dwType,(unsigned char *)szBuffer,&dwSize) == ERROR_SUCCESS && dwType == REG_SZ) {

								printf("Service description:%s\n",szBuffer);

							}

							RegCloseKey(hSubKey);
						}
					}

					printf("\n");
				
				}		
				
				//close the key opened by RegConnectRegistry

				if (hKey) RegCloseKey(hKey);
			}
			
			if (lpBuffer) {
				free(lpBuffer);
				lpBuffer=NULL;
			}

			if (iRet == 0) { //not all entry's returned normaly this only happens the first time we loop
				//allocate memory 
				lpBuffer=malloc(dwSize);

				if (lpBuffer == NULL) throw("Error allocating memory for buffer");
			}

		} while (iRet == 0); 

		throw("End EnumServices"); 
	}

	catch(char * szError)
	{
		if (scHandle)	CloseServiceHandle(scHandle);
		if (lpBuffer)	free(lpBuffer);

		printf("%s\n",szError);
	}

	return 0;
}


int main()
{

	printf("\nEnumServicesStatusEx example\n");
	printf("Refer any questions to michel000@planet.nl\n\n");

	EnumServices(NULL); //enum services for the local computer

	return 0;
}

Re: 枚举Service状态的源代码


onlyrainbow 2008-10-11, 22:54 下午
我很奇怪这篇文章怎么发在了Windows内核区??

Powered by Community Server Powered by CnForums.Net