Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

249 lines
8.9 KiB

  1. /********************************************************************
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. PCH_RunningTask.CPP
  5. Abstract:
  6. WBEM provider class implementation for PCH_RunningTask class
  7. Revision History:
  8. Ghim-Sim Chua (gschua) 04/27/99
  9. - Created
  10. Jim Martin (a-jammar) 04/30/99
  11. - Updated to retrieve file info from CIM_DataFile
  12. ********************************************************************/
  13. #include "pchealth.h"
  14. #include "PCH_RunningTask.h"
  15. #include <tlhelp32.h>
  16. /////////////////////////////////////////////////////////////////////////////
  17. // tracing stuff
  18. #ifdef THIS_FILE
  19. #undef THIS_FILE
  20. #endif
  21. static char __szTraceSourceFile[] = __FILE__;
  22. #define THIS_FILE __szTraceSourceFile
  23. #define TRACE_ID DCID_RUNNINGTASK
  24. CPCH_RunningTask MyPCH_RunningTaskSet (PROVIDER_NAME_PCH_RUNNINGTASK, PCH_NAMESPACE) ;
  25. // Property names
  26. //===============
  27. const static WCHAR * pAddress = L"Address" ;
  28. const static WCHAR * pTimeStamp = L"TimeStamp" ;
  29. const static WCHAR * pChange = L"Change" ;
  30. const static WCHAR * pDate = L"Date" ;
  31. const static WCHAR * pDescription = L"Description" ;
  32. const static WCHAR * pManufacturer = L"Manufacturer" ;
  33. const static WCHAR * pName = L"Name" ;
  34. const static WCHAR * pPartOf = L"PartOf" ;
  35. const static WCHAR * pPath = L"Path" ;
  36. const static WCHAR * pSize = L"Size" ;
  37. const static WCHAR * pType = L"Type" ;
  38. const static WCHAR * pVersion = L"Version" ;
  39. //-----------------------------------------------------------------------------
  40. // Gets the process ID (for use with Win32 APIs) for the specified executable.
  41. // The hToolhelp parameter is the handle returned by a call to
  42. // CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0).
  43. //
  44. // Note: if the same executable is loaded more than once, the process ID for
  45. // the first one encountered is returned.
  46. //-----------------------------------------------------------------------------
  47. typedef BOOL (*PROCENUM)(HANDLE, LPPROCESSENTRY32);
  48. HRESULT GetProcessID(HINSTANCE hKernel32, HANDLE hToolhelp, LPCSTR szFile, DWORD * pdwProcessID)
  49. {
  50. TraceFunctEnter("::GetProcessID");
  51. HRESULT hRes = E_FAIL;
  52. PROCESSENTRY32 pe;
  53. PROCENUM ProcFirst, ProcNext;
  54. ProcFirst = (PROCENUM) ::GetProcAddress(hKernel32, "Process32First");
  55. ProcNext = (PROCENUM) ::GetProcAddress(hKernel32, "Process32Next");
  56. pe.dwSize = sizeof(PROCESSENTRY32);
  57. if (ProcFirst && ProcNext && (ProcFirst)(hToolhelp, &pe))
  58. do
  59. {
  60. if (0 == _stricmp(szFile, pe.szExeFile))
  61. {
  62. hRes = S_OK;
  63. *pdwProcessID = pe.th32ProcessID;
  64. break;
  65. }
  66. } while ((ProcNext)(hToolhelp, &pe));
  67. TraceFunctLeave();
  68. return hRes;
  69. }
  70. //-----------------------------------------------------------------------------
  71. // The EnumerateInstances member function is responsible for reporting each
  72. // instance of the PCH_RunningTask class. This is done by performing a query
  73. // against CIMV2 for all of the Win32_Process instances. Each process instance
  74. // corresponds to a running task, and is used to find a CIM_DataFile instance
  75. // to report file information for each running task.
  76. //-----------------------------------------------------------------------------
  77. typedef HANDLE (*CTH32)(DWORD, DWORD);
  78. HRESULT CPCH_RunningTask::EnumerateInstances(MethodContext* pMethodContext, long lFlags)
  79. {
  80. TraceFunctEnter("CPCH_RunningTask::EnumerateInstances");
  81. HRESULT hRes = WBEM_S_NO_ERROR;
  82. LPSTR szFile;
  83. USES_CONVERSION;
  84. // Get the date and time for the time stamp.
  85. SYSTEMTIME stUTCTime;
  86. GetSystemTime(&stUTCTime);
  87. // Create a toolhelp snapshot to get process information. We need to dynamically
  88. // link to the function, because it might not be present on all platforms.
  89. HANDLE hToolhelp = (HANDLE) -1;
  90. HINSTANCE hKernel32 = ::LoadLibrary("kernel32");
  91. if (hKernel32)
  92. {
  93. CTH32 CrtToolhelp32 = (CTH32) ::GetProcAddress(hKernel32, "CreateToolhelp32Snapshot");
  94. if (CrtToolhelp32)
  95. hToolhelp = (*CrtToolhelp32)(TH32CS_SNAPPROCESS, 0);
  96. }
  97. // Execute the query against the Win32_Process class. This will give us the
  98. // list of processes running - then we'll get file information for each of
  99. // the processes.
  100. try
  101. {
  102. CFileVersionInfo fileversioninfo;
  103. CComPtr<IEnumWbemClassObject> pEnumInst;
  104. CComBSTR bstrQuery("SELECT Caption, ExecutablePath FROM Win32_Process");
  105. hRes = ExecWQLQuery(&pEnumInst, bstrQuery);
  106. if (FAILED(hRes))
  107. goto END;
  108. // Enumerate each instance of the Win32_Process query.
  109. IWbemClassObjectPtr pObj;
  110. ULONG ulRetVal;
  111. // CODEWORK: this shouldn't really use WBEM_INFINITE
  112. while (WBEM_S_NO_ERROR == pEnumInst->Next(WBEM_INFINITE, 1, &pObj, &ulRetVal))
  113. {
  114. CInstancePtr pInstance(CreateNewInstance(pMethodContext), false);
  115. // Use the system time to set the timestamp property, and set
  116. // the "Change" field to "Snapshot".
  117. if (!pInstance->SetDateTime(pTimeStamp, WBEMTime(stUTCTime)))
  118. ErrorTrace(TRACE_ID, "SetDateTime on Timestamp Field failed.");
  119. if (!pInstance->SetCHString(pChange, L"Snapshot"))
  120. ErrorTrace(TRACE_ID, "SetCHString on Change Field failed.");
  121. // Copy each property which transfers directly from the source
  122. // class object to the destination CInstance object.
  123. CopyProperty(pObj, L"Caption", pInstance, pName);
  124. CopyProperty(pObj, L"ExecutablePath", pInstance, pPath);
  125. // Get the "ExecutablePath" property, which we'll use to find the
  126. // appropriate CIM_DataFile object.
  127. CComVariant varValue;
  128. CComBSTR bstrExecutablePath("ExecutablePath");
  129. if (FAILED(pObj->Get(bstrExecutablePath, 0, &varValue, NULL, NULL)))
  130. ErrorTrace(TRACE_ID, "GetVariant on ExecutablePath field failed.");
  131. else
  132. {
  133. CComPtr<IWbemClassObject> pFileObj;
  134. CComBSTR ccombstrValue(V_BSTR(&varValue));
  135. if (SUCCEEDED(GetCIMDataFile(ccombstrValue, &pFileObj)))
  136. {
  137. // Using the CIM_DataFile object, copy over the appropriate properties.
  138. CopyProperty(pFileObj, L"Version", pInstance, pVersion);
  139. CopyProperty(pFileObj, L"FileSize", pInstance, pSize);
  140. CopyProperty(pFileObj, L"CreationDate", pInstance, pDate);
  141. CopyProperty(pFileObj, L"Manufacturer", pInstance, pManufacturer);
  142. }
  143. // Use the CFileVersionInfo object to get version attributes.
  144. if (SUCCEEDED(fileversioninfo.QueryFile(ccombstrValue)))
  145. {
  146. if (!pInstance->SetCHString(pDescription, fileversioninfo.GetDescription()))
  147. ErrorTrace(TRACE_ID, "SetCHString on description field failed.");
  148. if (!pInstance->SetCHString(pPartOf, fileversioninfo.GetProduct()))
  149. ErrorTrace(TRACE_ID, "SetCHString on partof field failed.");
  150. }
  151. // Use the toolhelp handle to get the type.
  152. if (hToolhelp != (HANDLE) -1)
  153. {
  154. szFile = W2A(ccombstrValue);
  155. if (szFile)
  156. {
  157. DWORD dwProcessID;
  158. if (SUCCEEDED(GetProcessID(hKernel32, hToolhelp, szFile, &dwProcessID)))
  159. {
  160. TCHAR szBuffer[20];
  161. DWORD dwVersion;
  162. dwVersion = GetProcessVersion(dwProcessID);
  163. wsprintf(szBuffer, _T("%d.%d"), HIWORD(dwVersion), LOWORD(dwVersion));
  164. if (!pInstance->SetCHString(pType, szBuffer))
  165. ErrorTrace(TRACE_ID, "SetCHString on type field failed.");
  166. }
  167. }
  168. }
  169. }
  170. // After all the properties are set, release the instance of the
  171. // class we're getting data from, and commit the new instance.
  172. hRes = pInstance->Commit();
  173. if (FAILED(hRes))
  174. ErrorTrace(TRACE_ID, "Commit on Instance failed.");
  175. }
  176. }
  177. catch (...)
  178. {
  179. if ((HANDLE)-1 != hToolhelp)
  180. CloseHandle(hToolhelp);
  181. if (hKernel32)
  182. FreeLibrary(hKernel32);
  183. throw;
  184. }
  185. END:
  186. if ((HANDLE)-1 != hToolhelp)
  187. CloseHandle(hToolhelp);
  188. if (hKernel32)
  189. FreeLibrary(hKernel32);
  190. TraceFunctLeave();
  191. return hRes;
  192. }