static LONG CreateNewLogEntry ( IN LPCWSTR szLogFileName, IN DWORD dwLogFileNameSize, // in chars, including term char IN HQUERY hQuery, IN DWORD dwMaxRecords ) /*++ creates a new log entry and inserts it in the list of open log files --*/ { PLOG_INFO pNewLog; DWORD dwSize; LONG pdhStatus = ERROR_SUCCESS; dwSize = dwLogFileNameSize; dwSize *= sizeof (WCHAR); dwSize *= 2; // double to make room for cat file name dwSize = DWORD_MULTIPLE (dwSize); // ... rounded to the next DWORD dwSize += sizeof (LOG_INFO); // + room for the data block pNewLog = &LogEntry; // set length field (this is used more for validation // than anything else pNewLog->dwLength = sizeof (LOG_INFO); // append filename strings immediately after this block pNewLog->szLogFileName = (LPWSTR)(&pNewLog[1]); lstrcpyW (pNewLog->szLogFileName, szLogFileName); // locate catalog name immediately after log file name pNewLog->szCatFileName = pNewLog->szLogFileName + dwLogFileNameSize; // FIXFIX: for now they are the same, later the log file extension // will be replaced with the catalog file extenstion lstrcpyW (pNewLog->szCatFileName, szLogFileName); // initialize the file handles pNewLog->hLogFileHandle = INVALID_HANDLE_VALUE; pNewLog->hCatFileHandle = INVALID_HANDLE_VALUE; // assign the query pNewLog->hQuery = hQuery; pNewLog->dwMaxRecords = dwMaxRecords; pNewLog->dwLogFormat = 0; // for now return pdhStatus; }
/**************************************************************************** ** ** Name: pfBuildInstanceDefinition - Build an instance of an object ** ** Description: ** ** Inputs: pBuffer - pointer to buffer where instance is to be constructed pBufferNext - pointer to a pointer which will contain next available location, DWORD aligned ParentObjectTitleIndex - Title Index of parent object type; 0 if no parent object ParentObjectInstance - Index into instances of parent object type, starting at 0, for this instances parent object instance UniqueID - a unique identifier which should be used instead of the Name for identifying this instance Name - Name of this instance ** ** Outputs: ** ** Returns: ** ** Exceptions: ** ** Side Effects: ** ** History: ** 10-Oct-1998 (wonst02) ** Original. ** ****************************************************************************/ BOOL pfBuildInstanceDefinition( PERF_INSTANCE_DEFINITION *pBuffer, PVOID *pBufferNext, DWORD ParentObjectTitleIndex, DWORD ParentObjectInstance, DWORD UniqueID, LPCWSTR Name ) { DWORD NameLength; LPWSTR pName; /* ** Include trailing null in name size */ NameLength = (lstrlenW(Name) + 1) * sizeof(WCHAR); pBuffer->ByteLength = sizeof(PERF_INSTANCE_DEFINITION) + DWORD_MULTIPLE(NameLength); pBuffer->ParentObjectTitleIndex = ParentObjectTitleIndex; pBuffer->ParentObjectInstance = ParentObjectInstance; pBuffer->UniqueID = UniqueID; pBuffer->NameOffset = sizeof(PERF_INSTANCE_DEFINITION); pBuffer->NameLength = NameLength; /* copy name to name buffer */ pName = (LPWSTR)&pBuffer[1]; RtlMoveMemory(pName,Name,NameLength); /* update "next byte" pointer */ *pBufferNext = (PVOID) ((PCHAR) pBuffer + pBuffer->ByteLength); return 0; }
BOOL MonBuildInstanceDefinition( PERF_INSTANCE_DEFINITION *pBuffer, PVOID *pBufferNext, DWORD ParentObjectTitleIndex, DWORD ParentObjectInstance, DWORD UniqueId, PUNICODE_STRING Name) /*++ Routine Description: Build an instance of an object Arguments: pBuffer = pointer to buffer where instance is to be contructed pBufferNext = pointer to a pointer which will contain next available location, DWORD aligned ParentObjectTitleIndex = Title index of Parent object type; 0 if no parent object. ParentObjectInstance = Index into instances of parent object type, starting at 0, for this instances parent object instance UniqueID = a unique identifier which should be used instead of the the name for identifying this instance Name = name of this instance Returns 0 --*/ { DWORD NameLength; WCHAR *pName; // // Include Trailing NULL in name size // NameLength = Name->Length; if (!NameLength || Name->Buffer[(NameLength/sizeof(WCHAR)) - 1] != UNICODE_NULL) { NameLength += sizeof(WCHAR); } pBuffer->ByteLength = sizeof(PERF_INSTANCE_DEFINITION) + DWORD_MULTIPLE(NameLength); pBuffer->ParentObjectTitleIndex = ParentObjectInstance; pBuffer->UniqueID = UniqueId; pBuffer->NameOffset = sizeof(PERF_INSTANCE_DEFINITION); pBuffer->NameLength = NameLength; pName = (PWCHAR)&pBuffer[1]; RtlMoveMemory(pName,Name->Buffer,Name->Length); // // Always Null Terminated. Space for this has been reserved // pName[(NameLength/sizeof(WCHAR))-1] = UNICODE_NULL; *pBufferNext = (PVOID) ((PCHAR) pBuffer + pBuffer->ByteLength); return 0; }
static PDH_STATUS PdhiGetCounterInfo ( IN HCOUNTER hCounter, IN BOOLEAN bRetrieveExplainText, IN LPDWORD pdwBufferSize, IN PPDH_COUNTER_INFO_W lpBuffer, IN BOOL bUnicode ) /*++ Routine Description: Examines the specified counter and returns the configuration and status information of the counter. Arguments: IN HCOUNTER hCounter Handle to the desired counter. IN BOOLEAN bRetrieveExplainText TRUE will fill in the explain text structure FALSE will return a null pointer in the explain text IN LPDWORD pcchBufferSize The address of the buffer that contains the size of the data buffer passed by the caller. On entry, the value in the buffer is the size of the data buffer in bytes. On return, this value is the size of the buffer returned. If the buffer is not large enough, then this value is the size that the buffer needs to be in order to hold the requested data. IN LPPDH_COUNTER_INFO_W lpBuffer the pointer to the data buffer passed by the caller to receive the data requested. IN BOOL bUnicode TRUE if wide character strings should be returned FALSE if ANSI strings should be returned Return Value: The WIN32 Error status of the function's operation. Common values returned are: ERROR_SUCCESS when all requested data is returned PDH_MORE_DATA when the buffer passed by the caller is too small PDH_INVALID_HANDLE if the handle is not recognized as valid PDH_INVALID_ARGUMENT if an argument is invalid or incorrect --*/ { PDH_STATUS Status = ERROR_SUCCESS; DWORD dwSizeRequired = 0; DWORD dwPathLength; DWORD dwMachineLength; DWORD dwObjectLength; DWORD dwInstanceLength; DWORD dwParentLength; DWORD dwNameLength; DWORD dwHelpLength; PPDHI_COUNTER pCounter; DWORD dwCharSize; if (!IsValidCounter(hCounter)) { Status = PDH_INVALID_HANDLE; } else { // the counter is valid so test the remaining arguments __try { DWORD dwTemp; if (pdwBufferSize != NULL) { // test read & write access dwTemp = *pdwBufferSize; *pdwBufferSize = 0; *pdwBufferSize = dwTemp; } else { // this cannot be NULL Status = PDH_INVALID_ARGUMENT; } if (Status == ERROR_SUCCESS) { // test return buffer for write access at // both ends of the buffer if ((lpBuffer != NULL) && (*pdwBufferSize > 0)) { *(LPDWORD)lpBuffer = 0; ((LPBYTE)lpBuffer)[*pdwBufferSize - 1] = 0; } } } __except (EXCEPTION_EXECUTE_HANDLER) { Status = PDH_INVALID_ARGUMENT; } } if (Status == ERROR_SUCCESS) { dwCharSize = bUnicode ? sizeof(WCHAR) : sizeof(CHAR); pCounter = (PPDHI_COUNTER) hCounter; WAIT_FOR_AND_LOCK_MUTEX(pCounter->pOwner->hMutex); // compute size of data to return dwSizeRequired = sizeof (PDH_COUNTER_INFO_W) - sizeof(DWORD); // size of struct // this should already end on a DWORD boundry dwPathLength = (lstrlenW (pCounter->szFullName) + 1) * dwCharSize; dwPathLength = DWORD_MULTIPLE (dwPathLength); dwSizeRequired += dwPathLength; dwMachineLength = (lstrlenW (pCounter->pCounterPath->szMachineName) + 1) * dwCharSize; dwMachineLength = DWORD_MULTIPLE (dwMachineLength); dwSizeRequired += dwMachineLength; dwObjectLength = (lstrlenW (pCounter->pCounterPath->szObjectName) + 1) * dwCharSize; dwObjectLength = DWORD_MULTIPLE (dwObjectLength); dwSizeRequired += dwObjectLength; if (pCounter->pCounterPath->szInstanceName != NULL) { dwInstanceLength = (lstrlenW (pCounter->pCounterPath->szInstanceName) + 1) * dwCharSize; dwInstanceLength = DWORD_MULTIPLE (dwInstanceLength); dwSizeRequired += dwInstanceLength; } else { dwInstanceLength = 0; } if (pCounter->pCounterPath->szParentName != NULL) { dwParentLength = (lstrlenW (pCounter->pCounterPath->szParentName) + 1) * dwCharSize; dwParentLength = DWORD_MULTIPLE (dwParentLength); dwSizeRequired += dwParentLength; } else { dwParentLength = 0; } dwNameLength = (lstrlenW (pCounter->pCounterPath->szCounterName) + 1) * dwCharSize; dwNameLength = DWORD_MULTIPLE (dwNameLength); dwSizeRequired += dwNameLength; if (bRetrieveExplainText) { if (pCounter->szExplainText != NULL) { dwHelpLength = (lstrlenW (pCounter->szExplainText) + 1) * dwCharSize; dwHelpLength = DWORD_MULTIPLE (dwHelpLength); } else { dwHelpLength = 0; } dwSizeRequired += dwHelpLength; } if ((*pdwBufferSize < dwSizeRequired) && (*pdwBufferSize > 0)) { // this is only an error if the size available is > 0 // either way, no data will be transferred Status = PDH_MORE_DATA; } else if (*pdwBufferSize > 0) { // should be enough room in the buffer, so continue lpBuffer->dwLength = dwSizeRequired; lpBuffer->dwType = pCounter->plCounterInfo.dwCounterType; lpBuffer->CVersion = pCounter->CVersion; lpBuffer->CStatus = pCounter->ThisValue.CStatus; lpBuffer->lScale = pCounter->lScale; lpBuffer->lDefaultScale = pCounter->plCounterInfo.lDefaultScale; lpBuffer->dwUserData = pCounter->dwUserData; lpBuffer->dwQueryUserData = pCounter->pOwner->dwUserData; // do string data now lpBuffer->szFullPath = (LPWSTR)&lpBuffer->DataBuffer[0]; if (bUnicode) { lstrcpyW (lpBuffer->szFullPath, pCounter->szFullName); } else { wcstombs ((LPSTR)lpBuffer->szFullPath, pCounter->szFullName, dwPathLength); } lpBuffer->szMachineName = (LPWSTR)((LPBYTE)lpBuffer->szFullPath + dwPathLength); if (bUnicode) { lstrcpyW (lpBuffer->szMachineName, pCounter->pCounterPath->szMachineName); } else { wcstombs ((LPSTR)lpBuffer->szMachineName, pCounter->pCounterPath->szMachineName, dwMachineLength); } lpBuffer->szObjectName = (LPWSTR)((LPBYTE)lpBuffer->szMachineName + dwMachineLength); if (bUnicode){ lstrcpyW (lpBuffer->szObjectName, pCounter->pCounterPath->szObjectName); } else { wcstombs ((LPSTR)lpBuffer->szObjectName, pCounter->pCounterPath->szObjectName, dwObjectLength); } lpBuffer->szInstanceName = (LPWSTR)((LPBYTE)lpBuffer->szObjectName + dwObjectLength); if (dwInstanceLength > 0) { if (bUnicode) { lstrcpyW (lpBuffer->szInstanceName, pCounter->pCounterPath->szInstanceName); } else { wcstombs ((LPSTR)lpBuffer->szInstanceName, pCounter->pCounterPath->szInstanceName, dwInstanceLength); } lpBuffer->szParentInstance = (LPWSTR)((LPBYTE)lpBuffer->szInstanceName + dwInstanceLength); } else { lpBuffer->szParentInstance = lpBuffer->szInstanceName; lpBuffer->szInstanceName = NULL; } if (dwParentLength > 0) { if (bUnicode) { lstrcpyW (lpBuffer->szParentInstance, pCounter->pCounterPath->szParentName); } else { wcstombs ((LPSTR)lpBuffer->szParentInstance, pCounter->pCounterPath->szParentName, dwParentLength); } lpBuffer->szCounterName = (LPWSTR)((LPBYTE)lpBuffer->szParentInstance + dwParentLength); } else { lpBuffer->szCounterName = lpBuffer->szParentInstance; lpBuffer->szParentInstance = NULL; } lpBuffer->dwInstanceIndex = pCounter->pCounterPath->dwIndex; if (bUnicode) { lstrcpyW (lpBuffer->szCounterName, pCounter->pCounterPath->szCounterName); } else { wcstombs ((LPSTR)lpBuffer->szCounterName, pCounter->pCounterPath->szCounterName, dwNameLength); } if ((pCounter->szExplainText != NULL) && bRetrieveExplainText) { // copy explain text lpBuffer->szExplainText = (LPWSTR)((LPBYTE)lpBuffer->szCounterName + dwNameLength); if (bUnicode) { lstrcpyW (lpBuffer->szExplainText, pCounter->szExplainText); } else { wcstombs ( (LPSTR)lpBuffer->szExplainText, pCounter->szExplainText, dwHelpLength); } assert ((DWORD)((LPBYTE)lpBuffer->szExplainText - (LPBYTE)lpBuffer + dwHelpLength) == dwSizeRequired); } else { lpBuffer->szExplainText = NULL; assert ((DWORD)((LPBYTE)lpBuffer->szCounterName - (LPBYTE)lpBuffer + dwNameLength) == dwSizeRequired); } } RELEASE_MUTEX(pCounter->pOwner->hMutex); *pdwBufferSize = dwSizeRequired; } return Status; }