/*++ Copyright (c) 1999-2001 Microsoft Corporation Module Name: service.cpp Abstract: This module implements routines for service specific SSR Knowledge Base processing. Author: Vishnu Patankar (VishnuP) - Oct 2001 Environment: User mode only. Exported Functions: Revision History: Created - Oct 2001 --*/ #include "stdafx.h" #include "kbproc.h" #include "process.h" HRESULT process::SsrpProcessService( IN CComPtr pXMLDocElemRoot, IN CComPtr pXMLServiceNode, IN PWSTR pszMode, OUT BOOL *pbRoleIsSatisfiable, OUT BOOL *pbSomeRequiredServiceDisabled ) /*++ Routine Description: Routine called to process each service Arguments: pXMLDocElemRoot - root of document pXMLServiceNode - service node pszMode - mode value pbRoleIsSatisfiable - boolean to fill regarding role satisfiability pbSomeRequiredServiceDisabled - boolean to fill in if required service is disabled Return: HRESULT error code ++*/ { HRESULT hr = S_OK; CComBSTR bstrName; //CComBSTR bstrRequired; CComPtr pServiceSelect; CComPtr pServiceRequired; CComPtr pSelectChildList; CComPtr pServiceName; DWORD rc = ERROR_SUCCESS; if (pbRoleIsSatisfiable == NULL || pbSomeRequiredServiceDisabled == NULL ) { return E_INVALIDARG; } /* hr = pXMLServiceNode->selectSingleNode(L"Required", &pServiceRequired); if (FAILED(hr) || pServiceRequired == NULL ) { SsrpLogParseError(hr); goto ExitHandler; } pServiceRequired->get_text(&bstrRequired); hr = pXMLServiceNode->selectSingleNode(L"Select", &pServiceSelect); if (FAILED(hr) || pServiceSelect == NULL ) { SsrpLogParseError(hr); goto ExitHandler; } hr = SsrpDeleteChildren(pServiceSelect); if (FAILED(hr) ) { SsrpLogParseError(hr); goto ExitHandler; } */ hr = pXMLServiceNode->selectSingleNode(L"Name", &pServiceName); if (FAILED(hr) || pServiceName == NULL ) { SsrpLogParseError(hr); goto ExitHandler; } pServiceName->get_text(&bstrName); BOOL bIsServiceInstalled = FALSE; bIsServiceInstalled = SsrpIsServiceInstalled(bstrName); BYTE byStartupType = SERVICE_DISABLED; BOOL bServiceIsDisabled = FALSE; rc = SsrpQueryServiceStartupType(bstrName, &byStartupType); if (rc == ERROR_SERVICE_DOES_NOT_EXIST) { rc = ERROR_SUCCESS; } if ( rc != ERROR_SUCCESS ) { SsrpLogError(L"Startup type for some service was not queried\n"); goto ExitHandler; } bServiceIsDisabled = (byStartupType == SERVICE_DISABLED ? TRUE: FALSE); /* BOOL bIsServiceOptional = FALSE; hr = SsrpCheckIfOptionalService( pXMLDocElemRoot, bstrName, &bIsServiceOptional ); if (FAILED(hr) ) { SsrpLogParseError(hr); goto ExitHandler; } */ *pbRoleIsSatisfiable = *pbRoleIsSatisfiable && bIsServiceInstalled; *pbSomeRequiredServiceDisabled = *pbSomeRequiredServiceDisabled || bServiceIsDisabled; /* if (0 == SsrpICompareBstrPwstr(bstrRequired, L"TRUE")) { hr = pServiceSelect->put_text(L"TRUE"); if (FAILED(hr) ) { SsrpLogParseError(hr); goto ExitHandler; } *pbRoleIsSatisfiable = *pbRoleIsSatisfiable && bIsServiceInstalled; *pbSomeRequiredServiceDisabled = *pbSomeRequiredServiceDisabled || bServiceIsDisabled; } else { // // service is not required // BOOL bServiceSelect = FALSE; CComPtr pXMLAttribNode; CComPtr pXMLValueNode; CComPtr pXMLServiceModeNode; hr = pServiceSelect->selectSingleNode(pszMode, &pXMLServiceModeNode ); if (FAILED(hr) || pXMLServiceModeNode == NULL){ SsrpLogParseError(hr); goto ExitHandler; } hr = pXMLServiceModeNode->get_attributes( &pXMLAttribNode ); if (FAILED(hr) || pXMLAttribNode == NULL){ SsrpLogParseError(hr); goto ExitHandler; } hr = pXMLAttribNode->getNamedItem(L"Value", &pXMLValueNode ); if (FAILED(hr) || pXMLValueNode == NULL){ SsrpLogParseError(hr); goto ExitHandler; } CComBSTR bstrValue; hr = pXMLValueNode->get_text(&bstrValue); if (FAILED(hr) || !bstrValue ) { SsrpLogParseError(hr); goto ExitHandler; } if (0 == SsrpICompareBstrPwstr(bstrValue, L"TRUE")) { bServiceSelect = TRUE; } else if (0 == SsrpICompareBstrPwstr(bstrValue, L"FALSE")) { bServiceSelect = TRUE; } else if (0 == SsrpICompareBstrPwstr(bstrValue, L"DEFAULT")) { if (bIsServiceOptional && bIsServiceInstalled && !bServiceIsDisabled ) { bServiceSelect = TRUE; } } else if (0 == SsrpICompareBstrPwstr(bstrValue, L"CUSTOM")) { // // get the attributes "FunctionName" and "DLLName" // CComPtr pXMLFunctionName; CComBSTR bstrFunctionName; hr = pXMLAttribNode->getNamedItem(L"FunctionName", &pXMLFunctionName ); if (FAILED(hr) || pXMLFunctionName == NULL){ SsrpLogParseError(hr); goto ExitHandler; } hr = pXMLFunctionName->get_text(&bstrFunctionName); if (FAILED(hr) || !bstrFunctionName){ SsrpLogParseError(hr); goto ExitHandler; } CComPtr pXMLDLLName; CComBSTR bstrDLLName; hr = pXMLAttribNode->getNamedItem(L"DLLName", &pXMLDLLName ); if (FAILED(hr) || pXMLDLLName == NULL){ SsrpLogParseError(hr); goto ExitHandler; } hr = pXMLDLLName->get_text(&bstrDLLName); if (FAILED(hr) || !bstrDLLName ){ SsrpLogParseError(hr); goto ExitHandler; } rc = SsrpEvaluateCustomFunction(bstrDLLName, bstrFunctionName, &bServiceSelect); if (rc != ERROR_SUCCESS) { SsrpLogWin32Error(rc); goto ExitHandler; } } hr = SsrpDeleteChildren(pServiceSelect); if (FAILED(hr) ) { SsrpLogParseError(hr); goto ExitHandler; } // hr = pServiceSelect->put_text(bServiceSelect ? L"TRUE" : L"FALSE"); if (FAILED(hr) ) { SsrpLogParseError(hr); goto ExitHandler; } } */ ExitHandler: return rc; } DWORD process::SsrpQueryInstalledServicesInfo( IN PWSTR pszMachineName ) /*++ Routine Description: Routine called to initialize service information Arguments: pszMachineName - name of machine to lookup SCM information Return: HRESULT error code ++*/ { DWORD rc = ERROR_SUCCESS; DWORD cbInfo = 0; DWORD dwErr = ERROR_SUCCESS; DWORD dwResume = 0; // // Connect to the service controller. // m_hScm = OpenSCManager( pszMachineName, NULL, GENERIC_READ); if (m_hScm == NULL) { rc = GetLastError(); goto ExitHandler; } if ((!EnumServicesStatusEx( m_hScm, SC_ENUM_PROCESS_INFO, SERVICE_WIN32, SERVICE_STATE_ALL, NULL, 0, &cbInfo, &m_dwNumServices, &dwResume, NULL)) && ERROR_MORE_DATA == GetLastError()) { m_pInstalledServicesInfo = (LPENUM_SERVICE_STATUS_PROCESS)LocalAlloc(LMEM_ZEROINIT, cbInfo); if (m_pInstalledServicesInfo == NULL) { rc = ERROR_NOT_ENOUGH_MEMORY; goto ExitHandler; } } else { rc = GetLastError(); goto ExitHandler; } if (!EnumServicesStatusEx( m_hScm, SC_ENUM_PROCESS_INFO, SERVICE_WIN32, SERVICE_STATE_ALL, (LPBYTE)m_pInstalledServicesInfo, cbInfo, &cbInfo, &m_dwNumServices, &dwResume, NULL)) { rc = GetLastError(); goto ExitHandler; } m_bArrServiceInKB = (DWORD *) LocalAlloc(LMEM_ZEROINIT, m_dwNumServices * sizeof(DWORD)); if (m_bArrServiceInKB == NULL){ rc = ERROR_NOT_ENOUGH_MEMORY; goto ExitHandler; } memset(m_bArrServiceInKB, 0, m_dwNumServices * sizeof(DWORD)); ExitHandler: return rc; } HRESULT process::SsrpCheckIfOptionalService( IN CComPtr pXMLDocElemRoot, IN BSTR bstrServiceName, IN BOOL *pbOptional ) /*++ Routine Description: Routine called to check if service is optional Arguments: pXMLDocElemRoot - root of document bstrServiceName - name of service pbOptional - boolean to fill if optional or not Return: HRESULT error code ++*/ { HRESULT hr; CComPtr pService; CComPtr pOptional; CComPtr pServiceList; if (pbOptional == NULL) { E_INVALIDARG; } *pbOptional = FALSE; hr = pXMLDocElemRoot->selectNodes(L"Services/Service", &pServiceList); if (FAILED(hr) || pServiceList == NULL ) { SsrpLogParseError(hr); goto ExitHandler; } hr = pServiceList->nextNode(&pService); if (FAILED(hr)) { SsrpLogParseError(hr); goto ExitHandler; } while (pService) { CComBSTR bstrText; CComPtr pName; hr = pService->selectSingleNode(L"Name", &pName); if (FAILED(hr) || pName == NULL ) { SsrpLogParseError(hr); goto ExitHandler; } hr = pName->get_text(&bstrText); if (FAILED(hr) || !bstrText ) { SsrpLogParseError(hr); goto ExitHandler; } if (0 == SsrpICompareBstrPwstr(bstrServiceName, bstrText)) { hr = pService->selectSingleNode(L"Optional", &pOptional); if (FAILED(hr) || pOptional == NULL ) { SsrpLogParseError(hr); goto ExitHandler; } CComBSTR bstrOptional; hr = pOptional->get_text(&bstrOptional); if (FAILED(hr) || !bstrOptional ) { SsrpLogParseError(hr); goto ExitHandler; } if (0 == SsrpICompareBstrPwstr(bstrOptional, L"TRUE")) *pbOptional = TRUE; else *pbOptional = FALSE; return hr; } pService.Release(); hr = pServiceList->nextNode(&pService); if (FAILED(hr)) { SsrpLogParseError(hr); goto ExitHandler; } } ExitHandler: return hr; } DWORD process::SsrpQueryServiceStartupType( IN PWSTR pszServiceName, OUT BYTE *pbyStartupType ) /*++ Routine Description: Routine called to check service startup type Arguments: pszServiceName - name of service pbyStartupType - startup type Return: Win32 error code ++*/ { DWORD rc = ERROR_SUCCESS; DWORD dwBytesNeeded = 0; SC_HANDLE hService = NULL; LPQUERY_SERVICE_CONFIG pServiceConfig=NULL; if (pbyStartupType == NULL || pszServiceName == NULL) return ERROR_INVALID_PARAMETER; *pbyStartupType = SERVICE_DISABLED; SsrpConvertBstrToPwstr(pszServiceName); hService = OpenService( m_hScm, pszServiceName, SERVICE_QUERY_CONFIG | READ_CONTROL ); if ( hService == NULL ) { rc = GetLastError(); goto ExitHandler; } if ( !QueryServiceConfig( hService, NULL, 0, &dwBytesNeeded )) { if (ERROR_INSUFFICIENT_BUFFER != (rc = GetLastError())) goto ExitHandler; } rc = ERROR_SUCCESS; pServiceConfig = (LPQUERY_SERVICE_CONFIG)LocalAlloc(LMEM_ZEROINIT, dwBytesNeeded); if ( pServiceConfig == NULL ) { rc = ERROR_NOT_ENOUGH_MEMORY; goto ExitHandler; } if ( !QueryServiceConfig( hService, pServiceConfig, dwBytesNeeded, &dwBytesNeeded) ) { rc = GetLastError(); goto ExitHandler; } *pbyStartupType = (BYTE)(pServiceConfig->dwStartType) ; ExitHandler: if (pServiceConfig) { LocalFree(pServiceConfig); } if (hService) { CloseServiceHandle(hService); } return rc; } HRESULT process::SsrpAddUnknownSection( IN CComPtr pElementRoot, IN CComPtr pXMLDoc ) /*++ Routine Description: Routine called to add extra services Arguments: pElementRoot - the root element pointer pXMLDoc - document pointer Return: HRESULT error code ++*/ { CComPtr pNewChild; CComPtr pXDNodeUnknownNode; CComPtr pXDNodeServices; CComPtr pXDNodeName; CComPtr pXDNodeSatisfiable; CComPtr pXDNodeSelected; CComPtr pXDNodeRole; CComPtr pRolesList; CComPtr pRole; BOOL bOtherRolePresent = FALSE; LPSERVICE_DESCRIPTION pServiceDescription = NULL; CComPtr pServicesNode; CComVariant Type(NODE_ELEMENT); CComVariant vtRefChild; HRESULT hr; DWORD rc = ERROR_SUCCESS; hr = pXMLDoc->createNode( Type, L"Unknown", NULL, &pXDNodeUnknownNode); if (FAILED(hr) || pXDNodeUnknownNode == NULL) { SsrpLogParseError(hr); goto ExitHandler; } hr = SsrpAddWhiteSpace( pXMLDoc, pXDNodeUnknownNode, L"\n\t\t\t" ); if (FAILED(hr)) { SsrpLogParseError(hr); goto ExitHandler; } hr = pXMLDoc->createNode( Type, L"Services", NULL, &pXDNodeServices); if (FAILED(hr) || pXDNodeServices == NULL) { SsrpLogParseError(hr); goto ExitHandler; } hr = pXDNodeUnknownNode->appendChild(pXDNodeServices, NULL); if (FAILED(hr) ) { SsrpLogParseError(hr); goto ExitHandler; } hr = SsrpAddWhiteSpace( pXMLDoc, pXDNodeUnknownNode, L"\n\t\t\t\t\t" ); if (FAILED(hr)) { SsrpLogParseError(hr); goto ExitHandler; } for (DWORD ServiceIndex=0; ServiceIndex < m_dwNumServices; ServiceIndex++ ) { if (m_bArrServiceInKB[ServiceIndex] == 0){ CComPtr pXDNodeService; CComPtr pXDNodeServiceName; CComPtr pXDNodeServiceDescription; CComPtr pXDNodeServiceDisplayName; CComPtr pXDNodeServiceMaximum; CComPtr pXDNodeServiceTypical; hr = SsrpAddWhiteSpace( pXMLDoc, pXDNodeServices, L"\n\t\t\t\t\t" ); if (FAILED(hr)) { SsrpLogParseError(hr); goto ExitHandler; } hr = pXMLDoc->createNode( Type, L"Service", NULL, &pXDNodeService); if (FAILED(hr) || pXDNodeService == NULL) { SsrpLogParseError(hr); goto ExitHandler; } hr = pXDNodeServices->appendChild(pXDNodeService, NULL); if (FAILED(hr)) { SsrpLogParseError(hr); goto ExitHandler; } hr = SsrpAddWhiteSpace( pXMLDoc, pXDNodeService, L"\n\t\t\t\t\t\t" ); if (FAILED(hr)) { SsrpLogParseError(hr); goto ExitHandler; } hr = pXMLDoc->createNode( Type, L"Name", NULL, &pXDNodeServiceName); if (FAILED(hr) || pXDNodeServiceName == NULL) { SsrpLogParseError(hr); goto ExitHandler; } hr = pXDNodeServiceName->put_text(m_pInstalledServicesInfo[ServiceIndex].lpServiceName); if (FAILED(hr)) { SsrpLogParseError(hr); goto ExitHandler; } hr = pXDNodeService->appendChild(pXDNodeServiceName, NULL); if (FAILED(hr)) { SsrpLogParseError(hr); goto ExitHandler; } hr = SsrpAddWhiteSpace( pXMLDoc, pXDNodeService, L"\n\t\t\t\t\t\t" ); if (FAILED(hr)) { SsrpLogParseError(hr); goto ExitHandler; } /* hr = pXMLDoc->createNode( Type, L"DisplayName", NULL, &pXDNodeServiceDisplayName); if (FAILED(hr) || pXDNodeServiceDisplayName == NULL) { SsrpLogParseError(hr); goto ExitHandler; } hr = pXDNodeServiceDisplayName->put_text(m_pInstalledServicesInfo[ServiceIndex].lpDisplayName); if (FAILED(hr)) { SsrpLogParseError(hr); goto ExitHandler; } hr = pXDNodeService->appendChild(pXDNodeServiceDisplayName, NULL); if (FAILED(hr)) { SsrpLogParseError(hr); goto ExitHandler; } hr = SsrpAddWhiteSpace( pXMLDoc, pXDNodeService, L"\n\t\t\t\t\t\t" ); if (FAILED(hr)) { SsrpLogParseError(hr); goto ExitHandler; } hr = pXMLDoc->createNode( Type, L"Description", NULL, &pXDNodeServiceDescription); if (FAILED(hr) || pXDNodeServiceDescription == NULL) { SsrpLogParseError(hr); goto ExitHandler; } rc = SsrpQueryServiceDescription(m_pInstalledServicesInfo[ServiceIndex].lpServiceName, &pServiceDescription); if (rc != ERROR_SUCCESS ) { SsrpLogParseError(hr); goto ExitHandler; } hr = pXDNodeServiceDescription->put_text( (pServiceDescription == NULL) ? L"" : pServiceDescription->lpDescription); if (FAILED(hr)) { SsrpLogParseError(hr); goto ExitHandler; } if (pServiceDescription) { LocalFree(pServiceDescription); pServiceDescription = NULL; } hr = pXDNodeService->appendChild(pXDNodeServiceDescription, NULL); if (FAILED(hr)) { SsrpLogParseError(hr); goto ExitHandler; } hr = SsrpAddWhiteSpace( pXMLDoc, pXDNodeService, L"\n\t\t\t\t\t" ); if (FAILED(hr)) { SsrpLogParseError(hr); goto ExitHandler; } hr = SsrpAddWhiteSpace( pXMLDoc, pXDNodeServiceDescription, L"\n\t\t\t\t\t\t\t" ); if (FAILED(hr)) { SsrpLogParseError(hr); goto ExitHandler; } */ } } hr = pElementRoot->selectSingleNode(L"Services", &pServicesNode); if (FAILED(hr) || pServicesNode == NULL ) { SsrpLogParseError(hr); goto ExitHandler; } vtRefChild = pServicesNode; hr = pElementRoot->insertBefore(pXDNodeUnknownNode, vtRefChild, NULL); if (FAILED(hr)) { SsrpLogParseError(hr); goto ExitHandler; } ExitHandler: return hr; } HRESULT process::SsrpAddUnknownServicesInfoToServiceLoc( IN CComPtr pElementRoot, IN CComPtr pXMLDoc ) /*++ Routine Description: Routine called to add unknown service display and description to Arguments: pElementRoot - the root element pointer pXMLDoc - document pointer Return: HRESULT error code ++*/ { CComPtr pNewChild; CComPtr pXDNodeUnknownNode; CComPtr pXDNodeServices; CComPtr pXDNodeName; CComPtr pXDNodeSatisfiable; CComPtr pXDNodeSelected; CComPtr pXDNodeRole; CComPtr pRolesList; CComPtr pRole; BOOL bOtherRolePresent = FALSE; LPSERVICE_DESCRIPTION pServiceDescription = NULL; CComPtr pServicesNode; CComPtr pServiceLoc; CComVariant Type(NODE_ELEMENT); CComVariant vtRefChild; HRESULT hr; DWORD rc = ERROR_SUCCESS; // // get the "ServiceLocalization" section node // hr = pElementRoot->selectSingleNode(L"ServiceLocalization", &pServiceLoc); if (FAILED(hr) || pServiceLoc == NULL ) { SsrpLogParseError(hr); goto ExitHandler; } for (DWORD ServiceIndex=0; ServiceIndex < m_dwNumServices; ServiceIndex++ ) { if (m_bArrServiceInKB[ServiceIndex] == 0){ CComPtr pXDNodeService; CComPtr pXDNodeServiceName; CComPtr pXDNodeServiceDescription; CComPtr pXDNodeServiceDisplayName; CComPtr pXDNodeServiceMaximum; CComPtr pXDNodeServiceTypical; hr = pXMLDoc->createNode( Type, L"Service", NULL, &pXDNodeService); if (FAILED(hr) || pXDNodeService == NULL) { SsrpLogParseError(hr); goto ExitHandler; } hr = pServiceLoc->appendChild(pXDNodeService, NULL); if (FAILED(hr)) { SsrpLogParseError(hr); goto ExitHandler; } hr = SsrpAddWhiteSpace( pXMLDoc, pXDNodeService, L"\n\t\t\t\t\t\t" ); if (FAILED(hr)) { SsrpLogParseError(hr); goto ExitHandler; } hr = pXMLDoc->createNode( Type, L"Name", NULL, &pXDNodeServiceName); if (FAILED(hr) || pXDNodeServiceName == NULL) { SsrpLogParseError(hr); goto ExitHandler; } hr = pXDNodeServiceName->put_text(m_pInstalledServicesInfo[ServiceIndex].lpServiceName); if (FAILED(hr)) { SsrpLogParseError(hr); goto ExitHandler; } hr = pXDNodeService->appendChild(pXDNodeServiceName, NULL); if (FAILED(hr)) { SsrpLogParseError(hr); goto ExitHandler; } hr = SsrpAddWhiteSpace( pXMLDoc, pXDNodeService, L"\n\t\t\t\t\t\t" ); if (FAILED(hr)) { SsrpLogParseError(hr); goto ExitHandler; } hr = pXMLDoc->createNode( Type, L"DisplayName", NULL, &pXDNodeServiceDisplayName); if (FAILED(hr) || pXDNodeServiceDisplayName == NULL) { SsrpLogParseError(hr); goto ExitHandler; } hr = pXDNodeServiceDisplayName->put_text(m_pInstalledServicesInfo[ServiceIndex].lpDisplayName); if (FAILED(hr)) { SsrpLogParseError(hr); goto ExitHandler; } hr = pXDNodeService->appendChild(pXDNodeServiceDisplayName, NULL); if (FAILED(hr)) { SsrpLogParseError(hr); goto ExitHandler; } hr = SsrpAddWhiteSpace( pXMLDoc, pXDNodeService, L"\n\t\t\t\t\t\t" ); if (FAILED(hr)) { SsrpLogParseError(hr); goto ExitHandler; } hr = pXMLDoc->createNode( Type, L"Description", NULL, &pXDNodeServiceDescription); if (FAILED(hr) || pXDNodeServiceDescription == NULL) { SsrpLogParseError(hr); goto ExitHandler; } rc = SsrpQueryServiceDescription(m_pInstalledServicesInfo[ServiceIndex].lpServiceName, &pServiceDescription); if (rc != ERROR_SUCCESS ) { SsrpLogParseError(hr); goto ExitHandler; } hr = pXDNodeServiceDescription->put_text( (pServiceDescription == NULL) ? L"" : pServiceDescription->lpDescription); if (FAILED(hr)) { SsrpLogParseError(hr); goto ExitHandler; } if (pServiceDescription) { LocalFree(pServiceDescription); pServiceDescription = NULL; } hr = pXDNodeService->appendChild(pXDNodeServiceDescription, NULL); if (FAILED(hr)) { SsrpLogParseError(hr); goto ExitHandler; } hr = SsrpAddWhiteSpace( pXMLDoc, pXDNodeService, L"\n\t\t\t\t\t" ); if (FAILED(hr)) { SsrpLogParseError(hr); goto ExitHandler; } hr = SsrpAddWhiteSpace( pXMLDoc, pXDNodeServiceDescription, L"\n\t\t\t\t\t\t\t" ); if (FAILED(hr)) { SsrpLogParseError(hr); goto ExitHandler; } } } ExitHandler: return hr; } BOOL process::SsrpIsServiceInstalled( IN BSTR bstrService ) /*++ Routine Description: Routine called to check if service is installed Arguments: bstrService - service name Return: TRUE if installed, FALSE otherwise ++*/ { if (bstrService) { for (DWORD ServiceIndex=0; ServiceIndex < m_dwNumServices; ServiceIndex++ ) { if (m_pInstalledServicesInfo[ServiceIndex].lpServiceName && 0 == SsrpICompareBstrPwstr(bstrService, m_pInstalledServicesInfo[ServiceIndex].lpServiceName)) { if (m_bDbg) wprintf(L"SERVICE is installed: %s\n", bstrService); m_bArrServiceInKB[ServiceIndex] = 1; return TRUE; } } } return FALSE; } HRESULT process::SsrpAddServiceStartup( IN CComPtr pXMLDocElemRoot, IN CComPtr pXMLDoc ) /*++ Routine Description: Routine called to add service startup mode Arguments: pXMLDoc - document pointer pXMLDoc - pointer to document Return: HRESULT error code ++*/ { HRESULT hr; CComPtr pService; CComPtr pOptional; CComPtr pServiceList; CComVariant Type(NODE_ELEMENT); WCHAR szStartup[15]; hr = pXMLDocElemRoot->selectNodes(L"Services/Service", &pServiceList); if (FAILED(hr) || pServiceList == NULL ) { SsrpLogParseError(hr); goto ExitHandler; } hr = pServiceList->nextNode(&pService); if (FAILED(hr)) { SsrpLogParseError(hr); goto ExitHandler; } while (pService) { CComBSTR bstrText; CComPtr pName; CComPtr pXDNodeServiceStartup; CComPtr pXDNodeServiceInstalled; hr = pService->selectSingleNode(L"Name", &pName); if (FAILED(hr) || pName == NULL ) { SsrpLogParseError(hr); goto ExitHandler; } hr = pName->get_text(&bstrText); if (FAILED(hr) || !bstrText ) { SsrpLogParseError(hr); goto ExitHandler; } BYTE byStartupType = FALSE; BOOL bIsServiceInstalled = FALSE; DWORD rc = ERROR_SUCCESS; bIsServiceInstalled = SsrpIsServiceInstalled(bstrText); if (bIsServiceInstalled) { rc = SsrpQueryServiceStartupType(bstrText, &byStartupType); if ( rc != ERROR_SUCCESS) { //wprintf(L"\nName is %s error %d", bstrText, rc); goto ExitHandler; } if (byStartupType == SERVICE_DISABLED) { wcscpy(szStartup, L"Disabled"); } else if (byStartupType == SERVICE_AUTO_START) { wcscpy(szStartup, L"Automatic"); } else if (byStartupType == SERVICE_DEMAND_START) { wcscpy(szStartup, L"Manual"); } else if (byStartupType == SERVICE_DEMAND_START) { wcscpy(szStartup, L""); } hr = pXMLDoc->createNode( Type, L"Current_startup", NULL, &pXDNodeServiceStartup); if (FAILED(hr) || pXDNodeServiceStartup == NULL) { SsrpLogParseError(hr); goto ExitHandler; } hr = pXDNodeServiceStartup->put_text(szStartup); if (FAILED(hr)) { SsrpLogParseError(hr); goto ExitHandler; } hr = pService->appendChild(pXDNodeServiceStartup, NULL); if (FAILED(hr)) { SsrpLogParseError(hr); goto ExitHandler; } } hr = pXMLDoc->createNode( Type, L"Installed", NULL, &pXDNodeServiceInstalled); if (FAILED(hr) || pXDNodeServiceInstalled == NULL) { SsrpLogParseError(hr); goto ExitHandler; } hr = pXDNodeServiceInstalled->put_text((bIsServiceInstalled ? L"TRUE" : L"FALSE")); if (FAILED(hr)) { SsrpLogParseError(hr); goto ExitHandler; } hr = pService->appendChild(pXDNodeServiceInstalled, NULL); if (FAILED(hr)) { SsrpLogParseError(hr); goto ExitHandler; } pService.Release(); hr = pServiceList->nextNode(&pService); if (FAILED(hr)) { SsrpLogParseError(hr); goto ExitHandler; } } ExitHandler: return hr; } HRESULT process::SsrpAddUnknownServicestoServices( IN CComPtr pXMLDocElemRoot, IN CComPtr pXMLDoc ) /*++ Routine Description: Routine called to add unknown services to in the following way Browser TRUE [This would always be set to TRUE] Manual [This would be set to whatever the current startup mode is] Manual TRUE [THIS would always be set to TRUE] Arguments: pXMLDoc - document pointer pXMLDoc - pointer to document Return: HRESULT error code ++*/ { HRESULT hr; CComPtr pServices; CComPtr pOptional; CComPtr pServiceList; CComVariant Type(NODE_ELEMENT); WCHAR szStartup[15]; hr = pXMLDocElemRoot->selectSingleNode(L"Services", &pServices); if (FAILED(hr) || pServices == NULL ) { SsrpLogParseError(hr); goto ExitHandler; } for (DWORD ServiceIndex=0; ServiceIndex < m_dwNumServices; ServiceIndex++ ) { if (m_bArrServiceInKB[ServiceIndex] == 0){ CComPtr pXDNodeService; CComPtr pXDNodeServiceName; CComPtr pXDNodeServiceDescription; CComPtr pXDNodeServiceDisplayName; CComPtr pXDNodeServiceMaximum; CComPtr pXDNodeServiceTypical; CComPtr pXDNodeInstalled; CComPtr pXDNodeCurrentStartup; hr = SsrpAddWhiteSpace( pXMLDoc, pServices, L"\n\t\t\t\t\t" ); if (FAILED(hr)) { SsrpLogParseError(hr); goto ExitHandler; } hr = pXMLDoc->createNode( Type, L"Service", NULL, &pXDNodeService); if (FAILED(hr) || pXDNodeService == NULL) { SsrpLogParseError(hr); goto ExitHandler; } hr = pServices->appendChild(pXDNodeService, NULL); if (FAILED(hr)) { SsrpLogParseError(hr); goto ExitHandler; } hr = SsrpAddWhiteSpace( pXMLDoc, pXDNodeService, L"\n\t\t\t\t\t\t" ); if (FAILED(hr)) { SsrpLogParseError(hr); goto ExitHandler; } hr = pXMLDoc->createNode( Type, L"Name", NULL, &pXDNodeServiceName); if (FAILED(hr) || pXDNodeServiceName == NULL) { SsrpLogParseError(hr); goto ExitHandler; } hr = pXDNodeServiceName->put_text(m_pInstalledServicesInfo[ServiceIndex].lpServiceName); if (FAILED(hr)) { SsrpLogParseError(hr); goto ExitHandler; } hr = pXDNodeService->appendChild(pXDNodeServiceName, NULL); if (FAILED(hr)) { SsrpLogParseError(hr); goto ExitHandler; } hr = SsrpAddWhiteSpace( pXMLDoc, pXDNodeService, L"\n\t\t\t\t\t\t" ); if (FAILED(hr)) { SsrpLogParseError(hr); goto ExitHandler; } hr = pXMLDoc->createNode( Type, L"Optional", NULL, &pXDNodeServiceDisplayName); if (FAILED(hr) || pXDNodeServiceDisplayName == NULL) { SsrpLogParseError(hr); goto ExitHandler; } hr = pXDNodeServiceDisplayName->put_text(L"TRUE"); if (FAILED(hr)) { SsrpLogParseError(hr); goto ExitHandler; } hr = pXDNodeService->appendChild(pXDNodeServiceDisplayName, NULL); if (FAILED(hr)) { SsrpLogParseError(hr); goto ExitHandler; } hr = SsrpAddWhiteSpace( pXMLDoc, pXDNodeService, L"\n\t\t\t\t\t\t" ); if (FAILED(hr)) { SsrpLogParseError(hr); goto ExitHandler; } hr = pXMLDoc->createNode( Type, L"Startup_Default", NULL, &pXDNodeServiceDescription); if (FAILED(hr) || pXDNodeServiceDescription == NULL) { SsrpLogParseError(hr); goto ExitHandler; } hr = pXMLDoc->createNode( Type, L"Current_Startup", NULL, &pXDNodeCurrentStartup); if (FAILED(hr) || pXDNodeCurrentStartup == NULL) { SsrpLogParseError(hr); goto ExitHandler; } BYTE byStartupType = SERVICE_DISABLED; DWORD rc = ERROR_SUCCESS; rc = SsrpQueryServiceStartupType(m_pInstalledServicesInfo[ServiceIndex].lpServiceName, &byStartupType); if ( rc != ERROR_SUCCESS) { //wprintf(L"\nName is %s error %d", m_pInstalledServicesInfo[ServiceIndex].lpServiceName, rc); goto ExitHandler; } if (byStartupType == SERVICE_DISABLED) { wcscpy(szStartup, L"Disabled"); } else if (byStartupType == SERVICE_AUTO_START) { wcscpy(szStartup, L"Automatic"); } else if (byStartupType == SERVICE_DEMAND_START) { wcscpy(szStartup, L"Manual"); } else if (byStartupType == SERVICE_DEMAND_START) { wcscpy(szStartup, L""); } hr = pXDNodeServiceDescription->put_text(szStartup); if (FAILED(hr)) { SsrpLogParseError(hr); goto ExitHandler; } hr = pXDNodeCurrentStartup->put_text(szStartup); if (FAILED(hr)) { SsrpLogParseError(hr); goto ExitHandler; } hr = pXDNodeService->appendChild(pXDNodeServiceDescription, NULL); if (FAILED(hr)) { SsrpLogParseError(hr); goto ExitHandler; } hr = pXDNodeService->appendChild(pXDNodeCurrentStartup, NULL); if (FAILED(hr)) { SsrpLogParseError(hr); goto ExitHandler; } hr = pXMLDoc->createNode( Type, L"Installed", NULL, &pXDNodeInstalled); if (FAILED(hr) || pXDNodeInstalled == NULL) { SsrpLogParseError(hr); goto ExitHandler; } hr = pXDNodeInstalled->put_text(L"TRUE"); if (FAILED(hr)) { SsrpLogParseError(hr); goto ExitHandler; } hr = pXDNodeService->appendChild(pXDNodeInstalled, NULL); if (FAILED(hr)) { SsrpLogParseError(hr); goto ExitHandler; } hr = SsrpAddWhiteSpace( pXMLDoc, pXDNodeService, L"\n\t\t\t\t\t\t" ); if (FAILED(hr)) { SsrpLogParseError(hr); goto ExitHandler; } } } ExitHandler: return hr; } DWORD process::SsrpQueryServiceDescription( IN PWSTR pszServiceName, OUT LPSERVICE_DESCRIPTION *ppServiceDescription ) /*++ Routine Description: Routine called to get service description Arguments: pszServiceName - name of service ppServiceDescription - description structure (to be freed outside) Return: Win32 error code ++*/ { DWORD rc = ERROR_SUCCESS; DWORD dwBytesNeeded = 0; SC_HANDLE hService = NULL; LPSERVICE_DESCRIPTION pServiceDescription = NULL; if (ppServiceDescription == NULL || pszServiceName == NULL) return ERROR_INVALID_PARAMETER; *ppServiceDescription = NULL; SsrpConvertBstrToPwstr(pszServiceName); hService = OpenService( m_hScm, pszServiceName, SERVICE_QUERY_CONFIG | READ_CONTROL ); if ( hService == NULL ) { rc = GetLastError(); goto ExitHandler; } if ( !QueryServiceConfig2( hService, SERVICE_CONFIG_DESCRIPTION, NULL, 0, &dwBytesNeeded )) { if (ERROR_INSUFFICIENT_BUFFER != (rc = GetLastError())) goto ExitHandler; } rc = ERROR_SUCCESS; pServiceDescription = (LPSERVICE_DESCRIPTION)LocalAlloc(LMEM_ZEROINIT, dwBytesNeeded); if ( pServiceDescription == NULL ) { rc = ERROR_NOT_ENOUGH_MEMORY; goto ExitHandler; } if ( !QueryServiceConfig2( hService, SERVICE_CONFIG_DESCRIPTION, (LPBYTE)pServiceDescription, dwBytesNeeded, &dwBytesNeeded )) { LocalFree(pServiceDescription); pServiceDescription = NULL; rc = GetLastError(); goto ExitHandler; } *ppServiceDescription = pServiceDescription; ExitHandler: if (hService) { CloseServiceHandle(hService); } return rc; } PWSTR process::SsrpQueryServiceDisplayName( IN BSTR bstrService ) /*++ Routine Description: Routine called to get service display name Arguments: pszServiceName - name of service Return: pointer to display name string ++*/ { for (DWORD ServiceIndex=0; ServiceIndex < m_dwNumServices; ServiceIndex++ ) { if (m_pInstalledServicesInfo[ServiceIndex].lpServiceName && 0 == SsrpICompareBstrPwstr(bstrService, m_pInstalledServicesInfo[ServiceIndex].lpServiceName)) { return m_pInstalledServicesInfo[ServiceIndex].lpDisplayName; } } return NULL; }