📄 reg.c
字号:
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
* DESCRIBE IT HERE!
*
****************************************************************************/
#include <stdio.h>
#include <windows.h>
#include <process.h>
#include "drwatcom.h"
#include <ctype.h>
#include "mem.h"
#define PERFLIB_MAX "software\\microsoft\\windows nt\\currentversion"\
"\\perflib"
#define PERFLIB_STRING "software\\microsoft\\windows nt\\currentversion"\
"\\perflib\\009"
#define WRITE_SEM_NAME "dr_nt_reg_write_mutex"
#define COSTLY_WRITE_SEM_NAME "dr_nt_costly_reg_write_mutex"
#define INIT_BUF_SIZE 0x10000
#define BUF_SIZE_INCR 0x10000
#define N_IMAGE "Image"
#define N_THREAD "Thread"
#define N_THREADID "ID Thread"
#define N_PROCESS "Process"
#define N_PROCID "ID Process"
#define N_BASE_PRIORITY "Priority Base"
#define N_CUR_PRIORITY "Priority Current"
#define N_THREAD_STATE "Thread State"
#define N_WAIT_REASON "Thread Wait Reason"
#define N_PROCESS_ADDR_SPACE "Process Address Space"
#define N_MAP_SPACE_NO_ACC "Mapped Space No Access"
#define N_MAP_SPACE_READ "Mapped Space Read Only"
#define N_MAP_SPACE_WRITE "Mapped Space Read/Write"
#define N_MAP_SPACE_COPY "Mapped Space Write Copy"
#define N_MAP_SPACE_EXEC "Mapped Space Executable"
#define N_MAP_SPACE_EXECREAD "Mapped Space Exec Read Only"
#define N_MAP_SPACE_EXECWRITE "Mapped Space Exec Read/Write"
#define N_MAP_SPACE_EXECCOPY "Mapped Space Exec Write Copy"
#define N_RES_SPACE_NO_ACC "Reserved Space No Access"
#define N_RES_SPACE_READ "Reserved Space Read Only"
#define N_RES_SPACE_WRITE "Reserved Space Read/Write"
#define N_RES_SPACE_COPY "Reserved Space Write Copy"
#define N_RES_SPACE_EXEC "Reserved Space Executable"
#define N_RES_SPACE_EXECREAD "Reserved Space Exec Read Only"
#define N_RES_SPACE_EXECWRITE "Reserved Space Exec Read/Write"
#define N_RES_SPACE_EXECCOPY "Reserved Space Exec Write Copy"
#define N_IMAGE_SPACE_NO_ACC "Image Space No Access"
#define N_IMAGE_SPACE_READ "Image Space Read Only"
#define N_IMAGE_SPACE_WRITE "Image Space Read/Write"
#define N_IMAGE_SPACE_COPY "Image Space Write Copy"
#define N_IMAGE_SPACE_EXEC "Image Space Executable"
#define N_IMAGE_SPACE_EXECREAD "Image Space Exec Read Only"
#define N_IMAGE_SPACE_EXECWRITE "Image Space Exec Read/Write"
#define N_IMAGE_SPACE_EXECCOPY "Image Space Exec Write Copy"
#define N_NO_ACCESS "No Access"
#define N_READ_ONLY "Read Only"
#define N_READ_WRITE "Read/Write"
#define N_WRITE_COPY "Write Copy"
#define N_EXEC "Executable"
#define N_EXEC_READ "Exec Read Only"
#define N_EXEC_WRITE "Exec Read/Write"
#define N_EXEC_COPY "Exec Write Copy"
static char *titleBuf;
static char **titleIndex;
static DWORD indexSize;
static PERF_DATA_BLOCK *regData;
static PERF_OBJECT_TYPE *processObject;
static PERF_OBJECT_TYPE *threadObject;
static PERF_DATA_BLOCK *costlyData;
static PERF_OBJECT_TYPE *imageObject;
static PERF_OBJECT_TYPE *costlyThreadObject;
static PERF_OBJECT_TYPE *procAddrObject;
static CRITICAL_SECTION readCntSection;
static DWORD readCounter;
static HANDLE writeMutex;
static CRITICAL_SECTION costlyReadCntSection;
static DWORD costlyReadCounter;
static HANDLE costlyWriteMutex;
static CRITICAL_SECTION dataRefreshSection;
/*
* getIndex - fill in the titleIndex array
*/
static DWORD genIndex( void ) {
DWORD rc;
DWORD type;
DWORD datasize;
DWORD item;
char *begin;
HKEY keyhdl;
rc = RegOpenKeyEx( HKEY_LOCAL_MACHINE, PERFLIB_MAX , 0, KEY_READ,
&keyhdl );
if( rc == ERROR_SUCCESS ) {
datasize = sizeof( DWORD );
rc = RegQueryValueEx( keyhdl, "Last Counter", NULL,
&type, (char *)&indexSize, &datasize );
}
indexSize++;
if( rc == ERROR_SUCCESS ) {
titleIndex = MemAlloc( indexSize * sizeof( char * ) );
if( titleIndex == NULL ) rc = ERROR_OUTOFMEMORY;
}
if( rc == ERROR_SUCCESS ) {
memset( titleIndex, 0, indexSize * sizeof( char * ) );
begin = titleBuf;
while( *begin != '\0' ) {
item = atoi( begin );
#ifdef DEBUG
if( item >= indexSize ) {
MessageBox( NULL, "Writting past end of title array",
"reg.c", MB_OK );
}
#endif
while( *begin != '\0' ) begin++;
begin ++;
titleIndex[item] = begin;
while( *begin != '\0' ) begin++;
begin++;
}
}
return( rc );
}
/*
* getTitles - get the strings refrerenced by the performance registry
*/
static DWORD getTitles( void ) {
DWORD rc;
DWORD type;
DWORD datasize;
HKEY keyhdl;
rc = RegOpenKeyEx( HKEY_LOCAL_MACHINE, PERFLIB_STRING, 0, KEY_READ,
&keyhdl );
if( rc == ERROR_SUCCESS ) {
rc = RegQueryValueEx( keyhdl, "Counters", NULL, &type, NULL, &datasize );
}
if( rc == ERROR_SUCCESS ) {
titleBuf = MemAlloc( datasize );
if( titleBuf == NULL ) {
return( ERROR_OUTOFMEMORY );
}
rc = RegQueryValueEx( keyhdl, "Counters", NULL, &type, titleBuf,
&datasize );
}
if( rc == ERROR_SUCCESS ) {
rc = genIndex();
}
return( rc );
}
/*
* findIndex - return the index of the given string
*/
static DWORD findIndex( char *str ) {
DWORD i;
for( i=0; i < indexSize; i++ ) {
if( titleIndex[i] != NULL ) {
if( !stricmp( titleIndex[i], str ) ) {
return( i );
}
}
}
return( -1 );
}
/*
* getData - retrieve some data
*/
static DWORD getData( char *name, PERF_DATA_BLOCK **data ) {
DWORD datasize;
DWORD type;
WORD i;
LONG rc;
/* NB: The RegQueryEx call is VERY expensive. The loop must be constructed
* such that it finds the buffer size after minimal number of iterations -
* even if we waste a few kilobytes of memory.
*/
for( i=0; ; i++ ) {
datasize = INIT_BUF_SIZE + (BUF_SIZE_INCR << i);
*data = MemAlloc( datasize );
if( *data == NULL ) {
rc = ERROR_OUTOFMEMORY;
break;
}
EnterCriticalSection( &dataRefreshSection );
#if 0
{
FILE *fp;
fp = fopen( "c:\\t.lst", "at" );
fprintf( fp, "OPEN - %s\n", name );
fclose( fp );
}
#endif
rc = RegQueryValueEx( HKEY_PERFORMANCE_DATA, name, NULL, &type,
(void *)*data, &datasize );
#if 0
{
FILE *fp;
fp = fopen( "c:\\t.lst", "at" );
fprintf( fp, "CLOSE - %s\n", name );
fclose( fp );
}
#endif
LeaveCriticalSection( &dataRefreshSection );
if( rc != ERROR_MORE_DATA ) {
break;
}
MemFree( *data );
}
if( rc != ERROR_SUCCESS ) {
MemFree( *data );
*data = NULL;
}
return( rc );
}
/*
* findObject
*/
static PERF_OBJECT_TYPE *findObject( char *data, char *str ) {
DWORD index;
PERF_OBJECT_TYPE *obj;
PERF_DATA_BLOCK *dblock;
DWORD i;
if( data == NULL ) return( NULL );
index = findIndex( str );
if( index == -1 ) return( NULL );
dblock = (PERF_DATA_BLOCK *)data;
obj = (PERF_OBJECT_TYPE *) ( data + dblock->HeaderLength );
for( i=0; i < dblock->NumObjectTypes; i++ ) {
if( obj->ObjectNameTitleIndex == index ) {
return( obj );
}
data = (char *)obj;
obj = (PERF_OBJECT_TYPE *) ( data + obj->TotalByteLength );
}
return( NULL );
}
/*
* findCounter
*/
static PERF_COUNTER_DEFINITION *findCounter( PERF_OBJECT_TYPE *obj, char *str )
{
PERF_COUNTER_DEFINITION *counter;
DWORD i;
DWORD index;
if( obj == NULL ) return( NULL );
index = findIndex( str );
if( index == -1 ) return( NULL );
counter = (PERF_COUNTER_DEFINITION *)
( (char *)obj + obj->HeaderLength );
for( i=0; i < obj->NumCounters; i++ ) {
if( counter->CounterNameTitleIndex == index ) {
return( counter );
}
counter = (PERF_COUNTER_DEFINITION *)
( (char *)counter + counter->ByteLength );
}
return( NULL );
}
/*
* getCounterDWORD
*/
static DWORD getCounterDWORD( PERF_INSTANCE_DEFINITION *inst,
PERF_COUNTER_DEFINITION *counterinfo )
{
DWORD *ret;
ret = (DWORD *)
( (char *)inst + inst->ByteLength + counterinfo->CounterOffset );
return( *ret );
}
/*
* getNextInstance - get the next instance
* NB. this does not check for reading past the end of the list
*/
static PERF_INSTANCE_DEFINITION *getNextInstance( PERF_INSTANCE_DEFINITION *inst )
{
PERF_INSTANCE_DEFINITION *ret;
PERF_COUNTER_BLOCK *cntblock;
cntblock = (PERF_COUNTER_BLOCK *) ( (char *)inst + inst->ByteLength );
ret = (PERF_INSTANCE_DEFINITION *)
( (char *)cntblock + cntblock->ByteLength );
return( ret );
}
/*
* getFirstInstance
*/
static PERF_INSTANCE_DEFINITION *getFirstInstance( PERF_OBJECT_TYPE *obj ) {
PERF_INSTANCE_DEFINITION *inst;
if( obj == NULL ) return( NULL );
if( obj->NumInstances == 0 ) return( NULL );
inst = (PERF_INSTANCE_DEFINITION *)
( (char *)obj + obj->DefinitionLength );
return( inst );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -