?? reg_perfcount.c
字號(hào):
/* * Unix SMB/CIFS implementation. * Virtual Windows Registry Layer * * Copyright (C) Marcin Krzysztof Porwit 2005, * Copyright (C) Gerald (Jerry) Carter 2005. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */#include "includes.h"#undef DBGC_CLASS#define DBGC_CLASS DBGC_RPC_SRV#define PERFCOUNT_MAX_LEN 256#define PERFCOUNTDIR "perfmon"#define NAMES_DB "names.tdb"#define DATA_DB "data.tdb"/******************************************************************************************************************************************/static char* counters_directory( const char *dbname ){ static pstring fname; fstring path; if ( !dbname ) return NULL; fstr_sprintf( path, "%s/%s", PERFCOUNTDIR, dbname ); pstrcpy( fname, lock_path( path ) ); return fname;}/******************************************************************************************************************************************/void perfcount_init_keys( void ){ char *p = lock_path(PERFCOUNTDIR); /* no registry keys; just create the perfmon directory */ if ( !directory_exist( p, NULL ) ) mkdir( p, 0755 ); return;}/******************************************************************************************************************************************/uint32 reg_perfcount_get_base_index(void){ const char *fname = counters_directory( NAMES_DB ); TDB_CONTEXT *names; TDB_DATA kbuf, dbuf; char key[] = "1"; uint32 retval = 0; char buf[PERFCOUNT_MAX_LEN]; names = tdb_open_log(fname, 0, TDB_DEFAULT, O_RDONLY, 0444); if ( !names ) { DEBUG(1, ("reg_perfcount_get_base_index: unable to open [%s].\n", fname)); return 0; } /* needs to read the value of key "1" from the counter_names.tdb file, as that is where the total number of counters is stored. We're assuming no holes in the enumeration. The format for the counter_names.tdb file is: key value 1 num_counters 2 perf_counter1 3 perf_counter1_help 4 perf_counter2 5 perf_counter2_help even_num perf_counter<even_num> even_num+1 perf_counter<even_num>_help and so on. So last_counter becomes num_counters*2, and last_help will be last_counter+1 */ kbuf.dptr = key; kbuf.dsize = strlen(key); dbuf = tdb_fetch(names, kbuf); if(dbuf.dptr == NULL) { DEBUG(1, ("reg_perfcount_get_base_index: failed to find key \'1\' in [%s].\n", fname)); tdb_close(names); return 0; } else { tdb_close(names); memset(buf, 0, PERFCOUNT_MAX_LEN); memcpy(buf, dbuf.dptr, dbuf.dsize); retval = (uint32)atoi(buf); SAFE_FREE(dbuf.dptr); return retval; } return 0;}/******************************************************************************************************************************************/uint32 reg_perfcount_get_last_counter(uint32 base_index){ uint32 retval; if(base_index == 0) retval = 0; else retval = base_index * 2; return retval;}/******************************************************************************************************************************************/uint32 reg_perfcount_get_last_help(uint32 last_counter){ uint32 retval; if(last_counter == 0) retval = 0; else retval = last_counter + 1; return retval;}/******************************************************************************************************************************************/static uint32 _reg_perfcount_multi_sz_from_tdb(TDB_CONTEXT *tdb, int keyval, char **retbuf, uint32 buffer_size){ TDB_DATA kbuf, dbuf; char temp[256]; char *buf1 = *retbuf, *buf2 = NULL; uint32 working_size = 0; UNISTR2 name_index, name; memset(temp, 0, sizeof(temp)); snprintf(temp, sizeof(temp), "%d", keyval); kbuf.dptr = temp; kbuf.dsize = strlen(temp); dbuf = tdb_fetch(tdb, kbuf); if(dbuf.dptr == NULL) { /* If a key isn't there, just bypass it -- this really shouldn't happen unless someone's mucking around with the tdb */ DEBUG(3, ("_reg_perfcount_multi_sz_from_tdb: failed to find key [%s] in [%s].\n", temp, tdb->name)); return buffer_size; } /* First encode the name_index */ working_size = (kbuf.dsize + 1)*sizeof(uint16); buf2 = SMB_REALLOC(buf1, buffer_size + working_size); if(!buf2) { SAFE_FREE(buf1); buffer_size = 0; return buffer_size; } buf1 = buf2; init_unistr2(&name_index, kbuf.dptr, UNI_STR_TERMINATE); memcpy(buf1+buffer_size, (char *)name_index.buffer, working_size); buffer_size += working_size; /* Now encode the actual name */ working_size = (dbuf.dsize + 1)*sizeof(uint16); buf2 = SMB_REALLOC(buf1, buffer_size + working_size); if(!buf2) { SAFE_FREE(buf1); buffer_size = 0; return buffer_size; } buf1 = buf2; memset(temp, 0, sizeof(temp)); memcpy(temp, dbuf.dptr, dbuf.dsize); SAFE_FREE(dbuf.dptr); init_unistr2(&name, temp, UNI_STR_TERMINATE); memcpy(buf1+buffer_size, (char *)name.buffer, working_size); buffer_size += working_size; *retbuf = buf1; return buffer_size;}/******************************************************************************************************************************************/uint32 reg_perfcount_get_counter_help(uint32 base_index, char **retbuf){ char *buf1 = NULL, *buf2 = NULL; uint32 buffer_size = 0; TDB_CONTEXT *names; const char *fname = counters_directory( NAMES_DB ); int i; if(base_index == 0) return 0; names = tdb_open_log(fname, 0, TDB_DEFAULT, O_RDONLY, 0444); if(names == NULL) { DEBUG(1, ("reg_perfcount_get_counter_help: unable to open [%s].\n", fname)); return 0; } for(i = 1; i <= base_index; i++) { buffer_size = _reg_perfcount_multi_sz_from_tdb(names, (i*2)+1, retbuf, buffer_size); } tdb_close(names); /* Now terminate the MULTI_SZ with a double unicode NULL */ buf1 = *retbuf; buf2 = SMB_REALLOC(buf1, buffer_size + 2); if(!buf2) { SAFE_FREE(buf1); buffer_size = 0; } else { buf1 = buf2; buf1[buffer_size++] = '\0'; buf1[buffer_size++] = '\0'; } *retbuf = buf1; return buffer_size;}/******************************************************************************************************************************************/uint32 reg_perfcount_get_counter_names(uint32 base_index, char **retbuf){ char *buf1 = NULL, *buf2 = NULL; uint32 buffer_size = 0; TDB_CONTEXT *names; const char *fname = counters_directory( NAMES_DB ); int i; if(base_index == 0) return 0; names = tdb_open_log(fname, 0, TDB_DEFAULT, O_RDONLY, 0444); if(names == NULL) { DEBUG(1, ("reg_perfcount_get_counter_names: unable to open [%s].\n", fname)); return 0; } buffer_size = _reg_perfcount_multi_sz_from_tdb(names, 1, retbuf, buffer_size); for(i = 1; i <= base_index; i++) { buffer_size = _reg_perfcount_multi_sz_from_tdb(names, i*2, retbuf, buffer_size); } tdb_close(names); /* Now terminate the MULTI_SZ with a double unicode NULL */ buf1 = *retbuf; buf2 = SMB_REALLOC(buf1, buffer_size + 2); if(!buf2) { SAFE_FREE(buf1); buffer_size = 0; } else { buf1 = buf2; buf1[buffer_size++] = '\0'; buf1[buffer_size++] = '\0'; } *retbuf=buf1; return buffer_size;}/******************************************************************************************************************************************/static void _reg_perfcount_make_key(TDB_DATA *key, char *buf, int buflen, int key_part1, const char *key_part2){ memset(buf, 0, buflen); if(key_part2 != NULL) snprintf(buf, buflen,"%d%s", key_part1, key_part2); else snprintf(buf, buflen, "%d", key_part1); key->dptr = buf; key->dsize = strlen(buf); return;}/******************************************************************************************************************************************/static BOOL _reg_perfcount_isparent(TDB_DATA data){ if(data.dsize > 0) { if(data.dptr[0] == 'p') return True; else return False; } return False;}/******************************************************************************************************************************************/static BOOL _reg_perfcount_ischild(TDB_DATA data){ if(data.dsize > 0) { if(data.dptr[0] == 'c') return True; else return False; } return False;}/******************************************************************************************************************************************/static uint32 _reg_perfcount_get_numinst(int objInd, TDB_CONTEXT *names){ TDB_DATA key, data; char buf[PERFCOUNT_MAX_LEN]; _reg_perfcount_make_key(&key, buf, PERFCOUNT_MAX_LEN, objInd, "inst"); data = tdb_fetch(names, key); if(data.dptr == NULL) return (uint32)PERF_NO_INSTANCES; memset(buf, 0, PERFCOUNT_MAX_LEN); memcpy(buf, data.dptr, data.dsize); return (uint32)atoi(buf);}/******************************************************************************************************************************************/static BOOL _reg_perfcount_add_object(PERF_DATA_BLOCK *block, prs_struct *ps, int num, TDB_DATA data, TDB_CONTEXT *names){ int i; BOOL success = False; PERF_OBJECT_TYPE *obj; block->objects = (PERF_OBJECT_TYPE *)TALLOC_REALLOC_ARRAY(ps->mem_ctx, block->objects, PERF_OBJECT_TYPE, block->NumObjectTypes+1); if(block->objects == NULL) return False; obj = &(block->objects[block->NumObjectTypes]); memset((void *)&(block->objects[block->NumObjectTypes]), 0, sizeof(PERF_OBJECT_TYPE)); block->objects[block->NumObjectTypes].ObjectNameTitleIndex = num; block->objects[block->NumObjectTypes].ObjectNameTitlePointer = 0; block->objects[block->NumObjectTypes].ObjectHelpTitleIndex = num+1; block->objects[block->NumObjectTypes].ObjectHelpTitlePointer = 0; block->objects[block->NumObjectTypes].NumCounters = 0; block->objects[block->NumObjectTypes].DefaultCounter = 0; block->objects[block->NumObjectTypes].NumInstances = _reg_perfcount_get_numinst(num, names); block->objects[block->NumObjectTypes].counters = NULL; block->objects[block->NumObjectTypes].instances = NULL; block->objects[block->NumObjectTypes].counter_data.ByteLength = sizeof(uint32); block->objects[block->NumObjectTypes].counter_data.data = NULL; block->objects[block->NumObjectTypes].DetailLevel = PERF_DETAIL_NOVICE; block->NumObjectTypes+=1; for(i = 0; i < (int)obj->NumInstances; i++) { success = _reg_perfcount_add_instance(obj, ps, i, names); } return True;}/******************************************************************************************************************************************/BOOL _reg_perfcount_get_counter_data(TDB_DATA key, TDB_DATA *data){ TDB_CONTEXT *counters; const char *fname = counters_directory( DATA_DB ); counters = tdb_open_log(fname, 0, TDB_DEFAULT, O_RDONLY, 0444); if(counters == NULL) { DEBUG(1, ("reg_perfcount_get_counter_data: unable to open [%s].\n", fname)); return False; } *data = tdb_fetch(counters, key); tdb_close(counters); return True;}/******************************************************************************************************************************************/static uint32 _reg_perfcount_get_size_field(uint32 CounterType){ uint32 retval;
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -