|
|
/*++
Copyright (c) 1996 Microsoft Corporation
Module Name:
perfimag.c
Abstract:
This file implements an Performance Object that presents Image details performance object data
Created:
Bob Watson 22-Oct-1996
Revision History
--*/ //
// Include Files
//
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
#include <winperf.h>
#include <ntprfctr.h>
#include <perfutil.h>
#include "perfsprc.h"
#include "perfmsg.h"
#include "dataimag.h"
DWORD APIENTRY BuildImageObject ( IN OUT LPVOID *lppData, IN OUT LPDWORD lpcbTotalBytes, IN OUT LPDWORD lpNumObjectTypes, IN BOOL bLongImageName ) /*++
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
IN BOOL bLongImageName TRUE -- use the full path of the library file name in the instance FALSE - use only the file name in the instance
Returns:
0 if successful, else Win 32 error code of failure
--*/ { DWORD TotalLen; // Length of the total return block
PIMAGE_DATA_DEFINITION pImageDataDefinition; PPERF_INSTANCE_DEFINITION pPerfInstanceDefinition; PIMAGE_COUNTER_DATA pICD; DWORD dwNumInstances;
DWORD dwImageNameLength;
DWORD dwProcessIndex;
PPROCESS_VA_INFO pThisProcess; PMODINFO pThisImage;
dwNumInstances = 0;
pImageDataDefinition = (IMAGE_DATA_DEFINITION *) *lppData;
//
// Check for sufficient space for Image object type definition
//
TotalLen = sizeof(IMAGE_DATA_DEFINITION) + sizeof(PERF_INSTANCE_DEFINITION) + MAX_PROCESS_NAME_LENGTH + sizeof(IMAGE_COUNTER_DATA);
if ( *lpcbTotalBytes < TotalLen ) { *lpcbTotalBytes = (DWORD) 0; *lpNumObjectTypes = (DWORD) 0; return ERROR_MORE_DATA; }
//
// Define Page File data block
//
memcpy(pImageDataDefinition, &ImageDataDefinition, sizeof(IMAGE_DATA_DEFINITION));
// update object title index if this is a Long Image object
if (bLongImageName) { pImageDataDefinition->ImageObjectType.ObjectNameTitleIndex = LONG_IMAGE_OBJECT_TITLE_INDEX; pImageDataDefinition->ImageObjectType.ObjectHelpTitleIndex = LONG_IMAGE_OBJECT_TITLE_INDEX + 1; }
pPerfInstanceDefinition = (PERF_INSTANCE_DEFINITION *) &pImageDataDefinition[1];
// Now load data for each Image
pThisProcess = pProcessVaInfo; dwProcessIndex = 0; TotalLen = sizeof(IMAGE_DATA_DEFINITION);
while (pThisProcess) {
pThisImage = pThisProcess->pMemBlockInfo;
while (pThisImage) {
dwImageNameLength = (bLongImageName ? pThisImage->LongInstanceName->Length : pThisImage->InstanceName->Length); dwImageNameLength += sizeof(WCHAR); dwImageNameLength = QWORD_MULTIPLE(dwImageNameLength); // see if this instance will fit
TotalLen += sizeof (PERF_INSTANCE_DEFINITION) + dwImageNameLength + // (MAX_PROCESS_NAME_LENGTH + 1) * sizeof (WCHAR) +
sizeof (DWORD) + sizeof (IMAGE_COUNTER_DATA);
if ( *lpcbTotalBytes < TotalLen ) { *lpcbTotalBytes = (DWORD) 0; *lpNumObjectTypes = (DWORD) 0; return ERROR_MORE_DATA; }
MonBuildInstanceDefinition (pPerfInstanceDefinition, (PVOID *) &pICD, EXPROCESS_OBJECT_TITLE_INDEX, dwProcessIndex, (DWORD)-1, (bLongImageName ? pThisImage->LongInstanceName->Buffer : pThisImage->InstanceName->Buffer));
pICD->CounterBlock.ByteLength = sizeof(IMAGE_COUNTER_DATA);
pICD->ImageAddrNoAccess = pThisImage->CommitVector[NOACCESS]; pICD->ImageAddrReadOnly = pThisImage->CommitVector[READONLY]; pICD->ImageAddrReadWrite = pThisImage->CommitVector[READWRITE]; pICD->ImageAddrWriteCopy = pThisImage->CommitVector[WRITECOPY]; pICD->ImageAddrExecute = pThisImage->CommitVector[EXECUTE]; pICD->ImageAddrExecuteReadOnly = pThisImage->CommitVector[EXECUTEREAD]; pICD->ImageAddrExecuteReadWrite = pThisImage->CommitVector[EXECUTEREADWRITE]; pICD->ImageAddrExecuteWriteCopy = pThisImage->CommitVector[EXECUTEWRITECOPY];
pPerfInstanceDefinition = (PERF_INSTANCE_DEFINITION *)&pICD[1];
// adjust Total Length value to reflect ACTUAL size used
TotalLen = (DWORD)((PCHAR) pPerfInstanceDefinition - (PCHAR) pImageDataDefinition);
dwNumInstances++;
pThisImage = pThisImage->pNextModule; } pThisProcess = pThisProcess->pNextProcess; dwProcessIndex++; }
pImageDataDefinition->ImageObjectType.NumInstances += dwNumInstances;
*lpcbTotalBytes = pImageDataDefinition->ImageObjectType.TotalByteLength = (DWORD)((PCHAR) pPerfInstanceDefinition - (PCHAR) pImageDataDefinition);
#if DBG
if (*lpcbTotalBytes > TotalLen ) { DbgPrint ("\nPERFPROC: Image Perf Ctr. Instance Size Underestimated:"); DbgPrint ("\nPERFPROC: Estimated size: %d, Actual Size: %d", TotalLen, *lpcbTotalBytes); } #endif
*lppData = (LPVOID) pPerfInstanceDefinition;
// increment number of objects in this data block
*lpNumObjectTypes = 1;
return ERROR_SUCCESS; }
DWORD APIENTRY CollectImageObjectData ( 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
--*/ { return BuildImageObject ( lppData, lpcbTotalBytes, lpNumObjectTypes, FALSE); // use short names
}
DWORD APIENTRY CollectLongImageObjectData ( 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
--*/ { return BuildImageObject ( lppData, lpcbTotalBytes, lpNumObjectTypes, TRUE); // use long names
}
|