int NInstances (VOID) { int i, n = 0; if (g_InstanceHash) { for (i = 0; i < N_INSTANCE_BUCKETS; ++i) { BOOLEAN got_lock; INSTANCE_BUCKET *ib = &g_InstanceHash->buckets[i]; ACQUIRE_MUTEX_ADAPTIVE (&ib->lock, got_lock); if (got_lock) { INSTANCE *current; for (current = ib->list; current != NULL; current = current->next) ++n; RELEASE_MUTEX (&ib->lock); } else return -1; } } return n; }
struct giga_directory* lru_cache_lookup(lru_cache_t* lru, DIR_handle_t handle) { ACQUIRE_MUTEX(&(lru->mutex_), "lru_cache_lookup(%d)", handle); struct giga_directory* entry; HASH_FIND_INT(lru->table, &handle, entry); /* if (entry != NULL) { printf("LOOKUP: %d %d\n", handle, entry->split_flag); } else { printf("LOOKUP: %d NULL\n", handle); } */ if (entry != NULL) { entry->refcount ++; double_list_remove(entry); double_list_append(&(lru->dummy), entry); } RELEASE_MUTEX(&(lru->mutex_), "lru_cache_lookup(%d)", handle); return entry; }
BOOLEAN AddAdapterToInstanceList (TapAdapterPointer p_Adapter) { BOOLEAN got_lock; BOOLEAN ret = FALSE; const int hash = InstanceHashValue(INSTANCE_KEY(p_Adapter)); INSTANCE_BUCKET *ib = &g_InstanceHash->buckets[hash]; DEBUGP (("[TAP] AddAdapterToInstanceList hash=%d\n", hash)); ACQUIRE_MUTEX_ADAPTIVE (&ib->lock, got_lock); if (got_lock) { INSTANCE *i = MemAlloc (sizeof (INSTANCE), FALSE); if (i) { MYASSERT (p_Adapter); i->m_Adapter = p_Adapter; i->next = ib->list; ib->list = i; ret = TRUE; } RELEASE_MUTEX (&ib->lock); } return ret; }
BOOLEAN RemoveAdapterFromInstanceList (TapAdapterPointer p_Adapter) { BOOLEAN got_lock; BOOLEAN ret = FALSE; INSTANCE_BUCKET *ib = &g_InstanceHash->buckets[InstanceHashValue(INSTANCE_KEY(p_Adapter))]; ACQUIRE_MUTEX_ADAPTIVE (&ib->lock, got_lock); if (got_lock) { INSTANCE *current, *prev=NULL; for (current = ib->list; current != NULL; current = current->next) { if (current->m_Adapter == p_Adapter) // found match { if (prev) prev->next = current->next; else ib->list = current->next; MemFree (current->m_Adapter, sizeof (TapAdapter)); MemFree (current, sizeof (INSTANCE)); ret = TRUE; break; } prev = current; } RELEASE_MUTEX (&ib->lock); } return ret; }
void lru_cache_insert(lru_cache_t* lru, DIR_handle_t handle, struct giga_directory* entry) { ACQUIRE_MUTEX(&(lru->mutex_), "lru_cache_insert(%d)", handle); // printf("INSERT %d %d, length: %ld, cap: %ld\n", handle, entry->split_flag, lru->length_+1, lru->capacity_); struct giga_directory* old; HASH_FIND_INT(lru->table, &handle, old); if (old != NULL) { HASH_DEL(lru->table, old); double_list_remove(old); lru_cache_unref(old); } else { ++lru->length_; } HASH_ADD_INT(lru->table, handle, entry); double_list_append(&(lru->dummy), entry); entry->refcount = 2; while (lru->length_ > lru->capacity_ && lru->dummy.next != &(lru->dummy)) { struct giga_directory* old = lru->dummy.next; // printf("EVICT ENTRY %d\n", old->handle); HASH_DEL(lru->table, old); double_list_remove(old); lru_cache_unref(old); --lru->length_; } RELEASE_MUTEX(&(lru->mutex_), "lru_cache_insert(%d)", handle); }
TapAdapterPointer LookupAdapterInInstanceList (PDEVICE_OBJECT p_DeviceObject) { BOOLEAN got_lock; TapAdapterPointer ret = NULL; INSTANCE_BUCKET *ib = &g_InstanceHash->buckets[InstanceHashValue((PVOID)p_DeviceObject)]; ACQUIRE_MUTEX_ADAPTIVE (&ib->lock, got_lock); if (got_lock) { INSTANCE *current, *prev=NULL; for (current = ib->list; current != NULL; current = current->next) { if (p_DeviceObject == INSTANCE_KEY (current->m_Adapter)) // found match { // move it to head of list if (prev) { prev->next = current->next; current->next = ib->list; ib->list = current; } ret = ib->list->m_Adapter; break; } prev = current; } RELEASE_MUTEX (&ib->lock); } return ret; }
BOOLEAN GetDebugLine (char *buf, const int len) { static const char *truncated = "[OUTPUT TRUNCATED]\n"; BOOLEAN ret = FALSE; NdisZeroMemory (buf, len); if (g_Debug.text && g_Debug.capacity > 0) { BOOLEAN owned; ACQUIRE_MUTEX_ADAPTIVE (&g_Debug.lock, owned); if (owned) { int i = 0; if (g_Debug.error || NewlineExists (g_Debug.text + g_Debug.in, (int)g_Debug.out - (int)g_Debug.in)) { while (i < (len - 1) && g_Debug.in < g_Debug.out) { const char c = g_Debug.text[g_Debug.in++]; if (c == '\n') break; buf[i++] = c; } if (i < len) buf[i] = '\0'; } if (!i) { if (g_Debug.in == g_Debug.out) { g_Debug.in = g_Debug.out = 0; if (g_Debug.error) { const unsigned int tlen = strlen (truncated); if (tlen < g_Debug.capacity) { NdisMoveMemory (g_Debug.text, truncated, tlen+1); g_Debug.out = tlen; } g_Debug.error = FALSE; } } } else ret = TRUE; RELEASE_MUTEX (&g_Debug.lock); } } return ret; }
PDH_FUNCTION PdhSetCounterScaleFactor ( IN HCOUNTER hCounter, IN LONG lFactor ) /*++ Routine Description: sets the counter multiplication scale factor used in computing formatted counter values. The legal range of values is -7 to +7 which equates to a factor of .0000007 to 10,000,000. Arguments: IN HCOUNTER hCounter handle of the counter to update IN LONG lFactor integer value of the exponent of the factor (i.e. the multiplier is 10 ** lFactor.) Return Value: The WIN32 Error status of the function's operation. Common values returned are: ERROR_SUCCESS when all requested data is returned PDH_INVALID_ARGUMENT if the scale value is out of range PDH_INVALID_HANDLE if the handle is not recognized as valid --*/ { PPDHI_COUNTER pCounter; if (!IsValidCounter(hCounter)) { // not a valid counter return PDH_INVALID_HANDLE; } else if ((lFactor > PDH_MAX_SCALE) || (lFactor < PDH_MIN_SCALE)) { return PDH_INVALID_ARGUMENT; } else { pCounter = (PPDHI_COUNTER)hCounter; WAIT_FOR_AND_LOCK_MUTEX(pCounter->pOwner->hMutex); pCounter->lScale = lFactor; pCounter->dFactor = pow (10.0, (double)lFactor); RELEASE_MUTEX(pCounter->pOwner->hMutex); return ERROR_SUCCESS; } }
VOID MyDebugPrint (const unsigned char* format, ...) { if (g_Debug.text && g_Debug.capacity > 0 && CAN_WE_PRINT) { BOOLEAN owned; ACQUIRE_MUTEX_ADAPTIVE (&g_Debug.lock, owned); if (owned) { const int remaining = (int)g_Debug.capacity - (int)g_Debug.out; if (remaining > 0) { va_list args; NTSTATUS status; char *end; #ifdef DBG_PRINT va_start (args, format); vDbgPrintEx (DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, format, args); va_end (args); #endif va_start (args, format); status = RtlStringCchVPrintfExA (g_Debug.text + g_Debug.out, remaining, &end, NULL, STRSAFE_NO_TRUNCATION | STRSAFE_IGNORE_NULLS, format, args); va_end (args); va_start (args, format); vDbgPrintEx(DPFLTR_IHVDRIVER_ID , 1, format, args); va_end (args); if (status == STATUS_SUCCESS) g_Debug.out = (unsigned int) (end - g_Debug.text); else g_Debug.error = TRUE; } else g_Debug.error = TRUE; RELEASE_MUTEX (&g_Debug.lock); } else g_Debug.error = TRUE; } }
void lru_cache_erase(lru_cache_t* lru, DIR_handle_t handle) { ACQUIRE_MUTEX(&(lru->mutex_), "lru_cache_erase(%d)", handle); struct giga_directory* old; HASH_FIND_INT(lru->table, &handle, old); if (old != NULL) { // printf("DEL %d %d %d\n", old->handle, old->split_flag, old->refcount); double_list_remove(old); HASH_DEL(lru->table, old); lru_cache_unref(old); --lru->length_; } RELEASE_MUTEX(&(lru->mutex_), "lru_cache_erase(%d)", handle); }
/* Adapter Device Events ********************************************************/ static void adapterdeviceevents_callback (void *data, HBA_WWN PortWWN, HBA_UINT32 eventType, HBA_UINT32 fabricPortID) { HBA_NPIVADAPTERCALLBACK_ELEM *acbp; DEBUG(3, "AdapterDeviceEvent, port:%s, eventType:%d fabricPortID:0X%06x", WWN2STR1(&PortWWN), eventType, fabricPortID); GRAB_MUTEX(&_hbaapi_APE_mutex); for(acbp = _hbaapi_adapterdeviceevents_callback_list; acbp != NULL; acbp = acbp->next) { if(data == (void *)acbp) { (*acbp->callback)(acbp->userdata, PortWWN, eventType, fabricPortID); break; } } RELEASE_MUTEX(&_hbaapi_APE_mutex); }
PDH_FUNCTION PdhGetRawCounterValue ( IN HCOUNTER hCounter, IN LPDWORD lpdwType, IN PPDH_RAW_COUNTER pValue ) /*++ Routine Description: Function to retrieve the specified counter's current raw value. The values used are those currently in the counter buffer. (The data is not collected by this routine.) Arguments: IN HCOUNTER hCounter the handle to the counter whose value should be returned IN LPDWORD lpdwType an optional buffer in which the counter type value can be returned. This value must be NULL if this info is not desired. For the prototype, the flag values are defined in WINPERF.H IN PPDH_RAW_COUNTER pValue the pointer to the data buffer passed by the caller to receive the data requested. Return Value: The WIN32 Error status of the function's operation. Common values returned are: ERROR_SUCCESS when all requested data is returned PDH_INVALID_HANDLE if the handle is not recognized as valid PDH_INVALID_ARGUMENT if an argument is formatted incorrectly --*/ { PDH_STATUS Status = ERROR_SUCCESS; PPDHI_COUNTER pCounter; // validate arguments before retrieving the data if (!IsValidCounter(hCounter)) { Status = PDH_INVALID_HANDLE; } else { // the handle is good so try the rest of the args __try { // try to write to the arguments passed in pValue->CStatus = 0; if (lpdwType != NULL) { *lpdwType = 0; } // NULL is OK } __except (EXCEPTION_EXECUTE_HANDLER) { Status = PDH_INVALID_ARGUMENT; } } if (Status == ERROR_SUCCESS) { pCounter = (PPDHI_COUNTER)hCounter; WAIT_FOR_AND_LOCK_MUTEX(pCounter->pOwner->hMutex); *pValue = pCounter->ThisValue; if (lpdwType != NULL) { *lpdwType = pCounter->plCounterInfo.dwCounterType; } RELEASE_MUTEX(pCounter->pOwner->hMutex); } return Status; }
static int QueryDNSListenUDP(void *ID){ socklen_t AddrLen; CompatibleAddr ClientAddr; int State; ThreadContext Context; char RequestEntity[1024]; InitContext(&Context, RequestEntity); /* Listen and accept requests */ while(TRUE) { memset(&ClientAddr, 0, sizeof(ClientAddr)); GET_MUTEX(ListenMutex); if( Family == AF_INET ) { AddrLen = sizeof(struct sockaddr); State = recvfrom(ListenSocketUDP, RequestEntity, sizeof(RequestEntity), 0, (struct sockaddr *)&(ClientAddr.Addr4), &AddrLen ); } else { AddrLen = sizeof(struct sockaddr_in6); State = recvfrom(ListenSocketUDP, RequestEntity, sizeof(RequestEntity), 0, (struct sockaddr *)&(ClientAddr.Addr6), &AddrLen ); } RELEASE_MUTEX(ListenMutex); if(State < 1) { if( ErrorMessages == TRUE ) { int ErrorNum = GET_LAST_ERROR(); char ErrorMessage[320]; ErrorMessage[0] ='\0'; GetErrorMsg(ErrorNum, ErrorMessage, sizeof(ErrorMessage)); if( Family == AF_INET ) { printf("An error occured while receiving from %s : %d : %s .\n", inet_ntoa(ClientAddr.Addr4.sin_addr), ErrorNum, ErrorMessage ); } else { char Addr[LENGTH_OF_IPV6_ADDRESS_ASCII] = {0}; IPv6AddressToAsc(&(ClientAddr.Addr6.sin6_addr), Addr); printf("An error occured while receiving from %s : %d : %s .\n", Addr, ErrorNum, ErrorMessage ); } } continue; } Context.RequestLength = State; Query(&Context, &ClientAddr); ExtendableBuffer_Reset(Context.ResponseBuffer); } return 0; }
/* * The API used to use fixed size tables as its primary data structure. * Indexing from 1 to N identified each adapters. Now the adapters are * on a linked list. There is a unique "index" foreach each adapter. * Adapters always keep their index, even if they are removed from the * hardware. The only time the indexing is reset is on HBA_FreeLibrary */ HBA_UINT32 Sun_HBA_GetNumberOfTgtAdapters() { int j=0; HBA_LIBRARY_INFO *lib_infop; Sun_HBAGetNumberOfTgtAdaptersFunc GetNumberOfTgtAdaptersFunc = NULL; Sun_HBAGetTgtAdapterNameFunc GetTgtAdapterNameFunc = NULL; HBA_BOOLEAN found_name; HBA_TGTADAPTER_INFO *adapt_infop; HBA_STATUS status; char adaptername[256]; int num_adapters; /* local */ if(_hbaapi_librarylist == NULL) { return (0); } GRAB_MUTEX(&_hbaapi_LL_mutex); /* pay attention to order */ GRAB_MUTEX(&_hbaapi_tgtAL_mutex); for (lib_infop = _hbaapi_librarylist; lib_infop != NULL; lib_infop = lib_infop->next) { if (lib_infop->status != HBA_LIBRARY_LOADED) { continue; } if (lib_infop->hLibrary != NULL) { GetNumberOfTgtAdaptersFunc = (Sun_HBAGetNumberOfTgtAdaptersFunc) dlsym(lib_infop->hLibrary, "Sun_fcGetNumberOfTgtAdapters"); GetTgtAdapterNameFunc = (Sun_HBAGetTgtAdapterNameFunc) dlsym(lib_infop->hLibrary, "Sun_fcGetTgtAdapterName"); if (GetNumberOfTgtAdaptersFunc == NULL || GetTgtAdapterNameFunc == NULL) { GetNumberOfTgtAdaptersFunc = GetTgtAdapterNameFunc = NULL; continue; } } else { continue; } num_adapters = ((GetNumberOfTgtAdaptersFunc)()); #ifndef WIN32 DEBUG(1, "HBAAPI: number of target mode adapters for %s = %d\n", lib_infop->LibraryName, num_adapters, 0); #else DEBUG(1, "HBAAPI: number of target mode_adapters for %s = %d\n", lib_infop->LibraryPath, num_adapters, 0); #endif for (j = 0; j < num_adapters; j++) { found_name = 0; status = (GetTgtAdapterNameFunc)(j, (char *)&adaptername); if(status == HBA_STATUS_OK) { for(adapt_infop = _hbaapi_tgtadapterlist; adapt_infop != NULL; adapt_infop = adapt_infop->next) { /* * check for duplicates, really, this may just be a second * call to this function * ??? how do we know when a name becomes stale? */ if(strcmp(adaptername, adapt_infop->name) == 0) { /* already got this one */ found_name++; break; } } if(found_name != 0) { continue; } } adapt_infop = (HBA_TGTADAPTER_INFO *) calloc(1, sizeof(HBA_TGTADAPTER_INFO)); if(adapt_infop == NULL) { #ifndef WIN32 fprintf(stderr, "HBA_GetNumberOfAdapters: calloc failed on sizeof:%d\n", sizeof(HBA_TGTADAPTER_INFO)); #endif RELEASE_MUTEX(&_hbaapi_tgtAL_mutex); RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, _hbaapi_total_tgtadapter_count); } if((adapt_infop->GNstatus = status) == HBA_STATUS_OK) { adapt_infop->name = strdup(adaptername); } else { char dummyname[512]; sprintf(dummyname, "NULLADAPTER-%s-%03d", lib_infop->LibraryPath, _hbaapi_total_tgtadapter_count); dummyname[255] = '\0'; adapt_infop->name = strdup(dummyname); } adapt_infop->library = lib_infop; adapt_infop->next = _hbaapi_tgtadapterlist; adapt_infop->index = _hbaapi_total_tgtadapter_count; _hbaapi_tgtadapterlist = adapt_infop; _hbaapi_total_tgtadapter_count++; } GetNumberOfTgtAdaptersFunc = GetTgtAdapterNameFunc = NULL; } RELEASE_MUTEX(&_hbaapi_tgtAL_mutex); RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, _hbaapi_total_tgtadapter_count); }
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; }
PDH_FUNCTION PdhComputeCounterStatistics ( IN HCOUNTER hCounter, IN DWORD dwFormat, IN DWORD dwFirstEntry, IN DWORD dwNumEntries, IN PPDH_RAW_COUNTER lpRawValueArray, IN PPDH_STATISTICS data ) /*++ Routine Description: Reads an array of raw value structures of the counter type specified in the dwType field, computes the counter values of each and formats and returns a statistics structure that contains the following statistical data from the counter information: Minimum The smallest value of the computed counter values Maximum The largest value of the computed counter values Mean The arithmetic mean (average) of the computed values Median The median value of the computed counter values Arguments: IN HCOUNTER hCounter The handle of the counter to use in order to determine the calculation functions for interpretation of the raw value buffer IN DWORD dwFormat Format in which the requested data should be returned. The values for this field are described in the PDH.H header file. IN DWORD dwNumEntries the number of raw value entries for the specified counter type IN PPDH_RAW_COUNTER lpRawValueArray pointer to the array of raw value entries to be evaluated IN PPDH_STATISTICS data the pointer to the data buffer passed by the caller to receive the data requested. Return Value: The WIN32 Error status of the function's operation. Note that the function can return successfully even though no data was calc- ulated. The status value in the statistics data buffer must be tested to insure the data is valid before it's used by an application. Common values returned are: ERROR_SUCCESS when all requested data is returned PDH_INVALID_HANDLE if the counter handle is incorrect PDH_INVALID_ARGUMENT if an argument is incorrect --*/ { PPDHI_COUNTER pCounter; PDH_STATUS Status = ERROR_SUCCESS; if (!IsValidCounter(hCounter)) { Status = PDH_INVALID_HANDLE; } else { // counter handle is valid so test the rest of the // arguments __try { DWORD dwTypeMask; DWORD dwTest; // validate format flags: // only one of the following can be set at a time dwTypeMask = dwFormat & (PDH_FMT_LONG | PDH_FMT_DOUBLE | PDH_FMT_LARGE); if (!((dwTypeMask == PDH_FMT_LONG) || (dwTypeMask == PDH_FMT_DOUBLE) || (dwTypeMask == PDH_FMT_LARGE))) { Status = PDH_INVALID_ARGUMENT; } if (Status == ERROR_SUCCESS) { // we should have read access to the Raw Data dwTest = (volatile) lpRawValueArray->CStatus; } if (Status == ERROR_SUCCESS) { // and we should have write access to the statistics // buffer data->dwFormat = 0; } if (dwFirstEntry >= dwNumEntries) { Status = PDH_INVALID_ARGUMENT; } } __except (EXCEPTION_EXECUTE_HANDLER) { Status = PDH_INVALID_ARGUMENT; } } if (Status == ERROR_SUCCESS) { pCounter = (PPDHI_COUNTER)hCounter; WAIT_FOR_AND_LOCK_MUTEX(pCounter->pOwner->hMutex); // call satistical function for this counter Status = (*pCounter->StatFunc)( pCounter, dwFormat, dwFirstEntry, dwNumEntries, lpRawValueArray, data); RELEASE_MUTEX(pCounter->pOwner->hMutex); } return Status; }
PDH_FUNCTION PdhGetFormattedCounterValue ( IN HCOUNTER hCounter, IN DWORD dwFormat, IN LPDWORD lpdwType, IN PPDH_FMT_COUNTERVALUE pValue ) /*++ Routine Description: Function to retrieve, computer and format the specified counter's current value. The values used are those currently in the counter buffer. (The data is not collected by this routine.) Arguments: IN HCOUNTER hCounter the handle to the counter whose value should be returned IN DWORD dwFormat the format flags that define how the counter value should be formatted prior for return. These flags are defined in the PDH.H header file. IN LPDWORD lpdwType an optional buffer in which the counter type value can be returned. For the prototype, the flag values are defined in WINPERF.H IN PPDH_FMT_COUNTERVALUE pValue the pointer to the data buffer passed by the caller to receive the data requested. Return Value: The WIN32 Error status of the function's operation. Common values returned are: ERROR_SUCCESS when all requested data is returned PDH_INVALID_HANDLE if the handle is not recognized as valid PDH_INVALID_ARGUMENT if an argument is not correct or is incorrectly formatted. PDH_INVALID_DATA if the counter does not contain valid data or a successful status code --*/ { PPDHI_COUNTER pCounter; PDH_STATUS lStatus = ERROR_SUCCESS; if (!IsValidCounter(hCounter)) { lStatus = PDH_INVALID_HANDLE; } else { __try { DWORD dwTypeMask; if (lpdwType != NULL) { *lpdwType = 0; } // NULL is OK, the counter type will not be returned, though if (pValue != NULL) { pValue->CStatus = (DWORD)-1; pValue->longValue = (LONGLONG)0; } else { lStatus = PDH_INVALID_ARGUMENT; } // validate format flags: // only one of the following can be set at a time dwTypeMask = dwFormat & (PDH_FMT_LONG | PDH_FMT_DOUBLE | PDH_FMT_LARGE); if (!((dwTypeMask == PDH_FMT_LONG) || (dwTypeMask == PDH_FMT_DOUBLE) || (dwTypeMask == PDH_FMT_LARGE))) { lStatus = PDH_INVALID_ARGUMENT; } } __except (EXCEPTION_EXECUTE_HANDLER) { lStatus = PDH_INVALID_ARGUMENT; } } if (lStatus == ERROR_SUCCESS) { // get counter pointer pCounter = (PPDHI_COUNTER)hCounter; // lock query while reading the data WAIT_FOR_AND_LOCK_MUTEX(pCounter->pOwner->hMutex); // compute and format current value lStatus = PdhiComputeFormattedValue ( pCounter, dwFormat, &pCounter->ThisValue, &pCounter->LastValue, &pCounter->TimeBase, 0L, pValue); if (lpdwType != NULL) { *lpdwType = pCounter->plCounterInfo.dwCounterType; } // NULL is OK, the counter type will not be returned, though RELEASE_MUTEX(pCounter->pOwner->hMutex); } return lStatus; }
PDH_FUNCTION PdhCalculateCounterFromRawValue ( IN HCOUNTER hCounter, IN DWORD dwFormat, IN PPDH_RAW_COUNTER rawValue1, IN PPDH_RAW_COUNTER rawValue2, IN PPDH_FMT_COUNTERVALUE fmtValue ) /*++ Routine Description: Calculates the formatted counter value using the data in the RawValue buffer in the format requested by the format field using the calculation functions of the counter type defined by the dwType field. Arguments: IN HCOUNTER hCounter The handle of the counter to use in order to determine the calculation functions for interpretation of the raw value buffer IN DWORD dwFormat Format in which the requested data should be returned. The values for this field are described in the PDH.H header file. IN PPDH_RAW_COUNTER rawValue1 pointer to the buffer that contains the first raw value structure IN PPDH_RAW_COUNTER rawValue2 pointer to the buffer that contains the second raw value structure. This argument may be null if only one value is required for the computation. IN PPDH_FMT_COUNTERVALUE fmtValue the pointer to the data buffer passed by the caller to receive the data requested. If the counter requires 2 values, (as in the case of a rate counter), rawValue1 is assumed to be the most recent value and rawValue2, the older value. Return Value: The WIN32 Error status of the function's operation. Common values returned are: ERROR_SUCCESS when all requested data is returned PDH_INVALID_HANDLE if the counter handle is incorrect PDH_INVALID_ARGUMENT if an argument is incorrect --*/ { PDH_STATUS lStatus = ERROR_SUCCESS; PPDHI_COUNTER pCounter; // validate arguments if (!IsValidCounter(hCounter)) { lStatus = PDH_INVALID_HANDLE; } else { // the handle is valid so check the rest of the arguments __try { DWORD dwTempStatus; DWORD dwTypeMask; // we should have read access to the rawValues dwTempStatus = (volatile)rawValue1->CStatus; // this one could be NULL if (rawValue2 != NULL) { dwTempStatus = (volatile)rawValue2->CStatus; } // and write access to the fmtValue fmtValue->CStatus = 0; // validate format flags: // only one of the following can be set at a time dwTypeMask = dwFormat & (PDH_FMT_LONG | PDH_FMT_DOUBLE | PDH_FMT_LARGE); if (!((dwTypeMask == PDH_FMT_LONG) || (dwTypeMask == PDH_FMT_DOUBLE) || (dwTypeMask == PDH_FMT_LARGE))) { lStatus = PDH_INVALID_ARGUMENT; } } __except (EXCEPTION_EXECUTE_HANDLER) { lStatus = PDH_INVALID_ARGUMENT; } } if (lStatus == ERROR_SUCCESS) { pCounter = (PPDHI_COUNTER)hCounter; WAIT_FOR_AND_LOCK_MUTEX(pCounter->pOwner->hMutex); lStatus = PdhiComputeFormattedValue ( (PPDHI_COUNTER)hCounter, dwFormat, rawValue1, rawValue2, &pCounter->TimeBase, 0L, fmtValue); RELEASE_MUTEX(pCounter->pOwner->hMutex); } return lStatus; }
HBA_STATUS Sun_HBA_RegisterForAdapterDeviceEvents ( void (*callback) ( void *data, HBA_WWN PortWWN, HBA_UINT32 eventType, HBA_UINT32 fabricPortID ), void *userData, HBA_HANDLE handle, HBA_WWN PortWWN, HBA_CALLBACKHANDLE *callbackHandle) { HBA_NPIVADAPTERCALLBACK_ELEM *acbp; HBA_STATUS status; HBA_LIBRARY_INFO *lib_infop; HBA_HANDLE vendorHandle; Sun_HBARegisterForAdapterDeviceEventsFunc registeredfunc; if (callbackHandle == NULL) { return(HBA_STATUS_ERROR_ARG); } NPIVCHECKLIBRARY(); registeredfunc = (Sun_HBARegisterForAdapterDeviceEventsFunc) dlsym(lib_infop->hLibrary, "Sun_fcRegisterForAdapterDeviceEvents"); if (registeredfunc == NULL) { RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR_NOT_SUPPORTED); } acbp = (HBA_NPIVADAPTERCALLBACK_ELEM *) calloc(1, sizeof(HBA_NPIVADAPTERCALLBACK_ELEM)); if(acbp == NULL) { RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_ERROR); } *callbackHandle = (HBA_CALLBACKHANDLE) acbp; acbp->callback = callback; acbp->userdata = userData; acbp->lib_info = lib_infop; status = (registeredfunc)(adapterdeviceevents_callback, (void *)acbp, vendorHandle, PortWWN, &acbp->vendorcbhandle); if(status != HBA_STATUS_OK) { free(acbp); RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, status); } GRAB_MUTEX(&_hbaapi_APE_mutex); acbp->next = _hbaapi_adapterdeviceevents_callback_list; _hbaapi_adapterdeviceevents_callback_list = acbp; RELEASE_MUTEX(&_hbaapi_APE_mutex); RELEASE_MUTEX_RETURN(&_hbaapi_LL_mutex, HBA_STATUS_OK); }
void lru_cache_release(lru_cache_t* lru, struct giga_directory* entry) { ACQUIRE_MUTEX(&(lru->mutex_), "lru_cache_release(%d)", entry->handle); lru_cache_unref(entry); RELEASE_MUTEX(&(lru->mutex_), "lru_cache_release(%d)", entry->handle); }