/*++ Copyright (c) 1996 Microsoft Corporation Module Name: perfexpr.c Abstract: This file implements an Performance Object that presents Extended Process performance object data Created: Bob Watson 22-Oct-1996 Revision History --*/ // // Include Files // #include #include #include #include #include #include #include #include "perfsprc.h" #include "perfmsg.h" #include "dataexpr.h" DWORD APIENTRY CollectExProcessObjectData ( IN OUT LPVOID *lppData, IN OUT LPDWORD lpcbTotalBytes, IN OUT LPDWORD lpNumObjectTypes ) /*++ Routine Description: This routine will return the data for the processor object Arguments: IN OUT LPVOID *lppData IN: pointer to the address of the buffer to receive the completed PerfDataBlock and subordinate structures. This routine will append its data to the buffer starting at the point referenced by *lppData. OUT: points to the first byte after the data structure added by this routine. This routine updated the value at lppdata after appending its data. IN OUT LPDWORD lpcbTotalBytes IN: the address of the DWORD that tells the size in bytes of the buffer referenced by the lppData argument OUT: the number of bytes added by this routine is writted to the DWORD pointed to by this argument IN OUT LPDWORD NumObjectTypes IN: the address of the DWORD to receive the number of objects added by this routine OUT: the number of objects added by this routine is writted to the DWORD pointed to by this argument Returns: 0 if successful, else Win 32 error code of failure --*/ { DWORD TotalLen; // Length of the total return block DWORD NumExProcessInstances; PPROCESS_VA_INFO pThisProcess; // pointer to current process PERF_INSTANCE_DEFINITION *pPerfInstanceDefinition; EXPROCESS_DATA_DEFINITION *pExProcessDataDefinition; PEXPROCESS_COUNTER_DATA pECD; if (pProcessVaInfo) { // process only if a buffer is available pExProcessDataDefinition = (EXPROCESS_DATA_DEFINITION *)*lppData; // check for sufficient space in buffer for at least one entry TotalLen = sizeof(EXPROCESS_DATA_DEFINITION) + sizeof(PERF_INSTANCE_DEFINITION) + (MAX_PROCESS_NAME_LENGTH + 1) * sizeof (WCHAR) + sizeof(EXPROCESS_COUNTER_DATA); if (*lpcbTotalBytes < TotalLen) { *lpcbTotalBytes = 0; *lpNumObjectTypes = 0; return ERROR_MORE_DATA; } // copy process data block to buffer memcpy (pExProcessDataDefinition, &ExProcessDataDefinition, sizeof(EXPROCESS_DATA_DEFINITION)); NumExProcessInstances = 0; pThisProcess = pProcessVaInfo; TotalLen = sizeof(EXPROCESS_DATA_DEFINITION); pPerfInstanceDefinition = (PERF_INSTANCE_DEFINITION *) &pExProcessDataDefinition[1]; while (pThisProcess) { // see if this instance will fit TotalLen += sizeof (PERF_INSTANCE_DEFINITION) + (MAX_PROCESS_NAME_LENGTH + 1) * sizeof (WCHAR) + sizeof (DWORD) + sizeof (EXPROCESS_COUNTER_DATA); if (*lpcbTotalBytes < TotalLen) { *lpcbTotalBytes = 0; *lpNumObjectTypes = 0; return ERROR_MORE_DATA; } MonBuildInstanceDefinition (pPerfInstanceDefinition, (PVOID *) &pECD, 0, 0, (DWORD)-1, pThisProcess->pProcessName->Buffer); NumExProcessInstances++; pECD->CounterBlock.ByteLength = sizeof (EXPROCESS_COUNTER_DATA); // load counters from the process va data structure pECD->ProcessId = pThisProcess->dwProcessId; pECD->ImageReservedBytes = pThisProcess->ImageReservedBytes; pECD->ImageFreeBytes = pThisProcess->ImageFreeBytes; pECD->ReservedBytes = pThisProcess->ReservedBytes; pECD->FreeBytes = pThisProcess->FreeBytes; pECD->CommitNoAccess = pThisProcess->MappedCommit[NOACCESS]; pECD->CommitReadOnly = pThisProcess->MappedCommit[READONLY]; pECD->CommitReadWrite = pThisProcess->MappedCommit[READWRITE]; pECD->CommitWriteCopy = pThisProcess->MappedCommit[WRITECOPY]; pECD->CommitExecute = pThisProcess->MappedCommit[EXECUTE]; pECD->CommitExecuteRead = pThisProcess->MappedCommit[EXECUTEREAD]; pECD->CommitExecuteWrite = pThisProcess->MappedCommit[EXECUTEREADWRITE]; pECD->CommitExecuteWriteCopy = pThisProcess->MappedCommit[EXECUTEWRITECOPY]; pECD->ReservedNoAccess = pThisProcess->PrivateCommit[NOACCESS]; pECD->ReservedReadOnly = pThisProcess->PrivateCommit[READONLY]; pECD->ReservedReadWrite = pThisProcess->PrivateCommit[READWRITE]; pECD->ReservedWriteCopy = pThisProcess->PrivateCommit[WRITECOPY]; pECD->ReservedExecute = pThisProcess->PrivateCommit[EXECUTE]; pECD->ReservedExecuteRead = pThisProcess->PrivateCommit[EXECUTEREAD]; pECD->ReservedExecuteWrite = pThisProcess->PrivateCommit[EXECUTEREADWRITE]; pECD->ReservedExecuteWriteCopy = pThisProcess->PrivateCommit[EXECUTEWRITECOPY]; pECD->UnassignedNoAccess = pThisProcess->OrphanTotals.CommitVector[NOACCESS]; pECD->UnassignedReadOnly = pThisProcess->OrphanTotals.CommitVector[READONLY]; pECD->UnassignedReadWrite = pThisProcess->OrphanTotals.CommitVector[READWRITE]; pECD->UnassignedWriteCopy = pThisProcess->OrphanTotals.CommitVector[WRITECOPY]; pECD->UnassignedExecute = pThisProcess->OrphanTotals.CommitVector[EXECUTE]; pECD->UnassignedExecuteRead = pThisProcess->OrphanTotals.CommitVector[EXECUTEREAD]; pECD->UnassignedExecuteWrite = pThisProcess->OrphanTotals.CommitVector[EXECUTEREADWRITE]; pECD->UnassignedExecuteWriteCopy = pThisProcess->OrphanTotals.CommitVector[EXECUTEWRITECOPY]; pECD->ImageTotalNoAccess = pThisProcess->MemTotals.CommitVector[NOACCESS]; pECD->ImageTotalReadOnly = pThisProcess->MemTotals.CommitVector[READONLY]; pECD->ImageTotalReadWrite = pThisProcess->MemTotals.CommitVector[READWRITE]; pECD->ImageTotalWriteCopy = pThisProcess->MemTotals.CommitVector[WRITECOPY]; pECD->ImageTotalExecute = pThisProcess->MemTotals.CommitVector[EXECUTE]; pECD->ImageTotalExecuteRead = pThisProcess->MemTotals.CommitVector[EXECUTEREAD]; pECD->ImageTotalExecuteWrite = pThisProcess->MemTotals.CommitVector[EXECUTEREADWRITE]; pECD->ImageTotalExecuteWriteCopy = pThisProcess->MemTotals.CommitVector[EXECUTEWRITECOPY]; pPerfInstanceDefinition = (PERF_INSTANCE_DEFINITION *)&pECD[1]; pThisProcess = pThisProcess->pNextProcess; // point to next process } // end while not at end of list } // end if valid process info buffer else { // pProcessVaInfo is NULL. Initialize the DataDef and return // with no data pExProcessDataDefinition = (EXPROCESS_DATA_DEFINITION *)*lppData; TotalLen = sizeof(EXPROCESS_DATA_DEFINITION) + sizeof (PERF_INSTANCE_DEFINITION) + (MAX_PROCESS_NAME_LENGTH + 1) * sizeof (WCHAR) + sizeof (DWORD) + sizeof (EXPROCESS_COUNTER_DATA); if (*lpcbTotalBytes < TotalLen) { *lpcbTotalBytes = 0; *lpNumObjectTypes = 0; return ERROR_MORE_DATA; } // copy process data block to buffer memcpy (pExProcessDataDefinition, &ExProcessDataDefinition, sizeof(EXPROCESS_DATA_DEFINITION)); NumExProcessInstances = 0; pPerfInstanceDefinition = (PERF_INSTANCE_DEFINITION *) &pExProcessDataDefinition[1]; } pExProcessDataDefinition->ExProcessObjectType.NumInstances = NumExProcessInstances; *lpcbTotalBytes = pExProcessDataDefinition->ExProcessObjectType.TotalByteLength = (DWORD)((PCHAR) pPerfInstanceDefinition - (PCHAR) pExProcessDataDefinition); *lppData = (LPVOID) pPerfInstanceDefinition; *lpNumObjectTypes = 1; return ERROR_SUCCESS; }