enum esif_rc esif_get_action_systemio( const struct esif_lp *lp_ptr, const struct esif_lp_primitive *primitive_ptr, const struct esif_lp_action *action_ptr, struct esif_data *req_data_ptr, struct esif_data *rsp_data_ptr ) { enum esif_rc rc = ESIF_OK; u32 val = 1234; UNREFERENCED_PARAMETER(lp_ptr); UNREFERENCED_PARAMETER(primitive_ptr); UNREFERENCED_PARAMETER(action_ptr); UNREFERENCED_PARAMETER(req_data_ptr); if (NULL == rsp_data_ptr) { rc = ESIF_E_PARAMETER_IS_NULL; goto exit; } ESIF_TRACE_DYN_GET("val = %d\n", val); switch (rsp_data_ptr->type) { case ESIF_DATA_UINT8: rsp_data_ptr->data_len = sizeof(u8); if (rsp_data_ptr->buf_len >= sizeof(u8)) *((u8 *)rsp_data_ptr->buf_ptr) = (u8)val; else rc = ESIF_E_OVERFLOWED_RESULT_TYPE; break; case ESIF_DATA_UINT16: rsp_data_ptr->data_len = sizeof(u16); if (rsp_data_ptr->buf_len >= sizeof(u16)) *((u16 *)rsp_data_ptr->buf_ptr) = (u16)val; else rc = ESIF_E_OVERFLOWED_RESULT_TYPE; break; case ESIF_DATA_UINT32: rsp_data_ptr->data_len = sizeof(u32); if (rsp_data_ptr->buf_len >= sizeof(u32)) *((u32 *)rsp_data_ptr->buf_ptr) = (u32)val; else rc = ESIF_E_OVERFLOWED_RESULT_TYPE; break; default: ESIF_TRACE_DYN_GET("Data Type Not Implemented = %s\n", esif_data_type_str(rsp_data_ptr->type)); rc = ESIF_E_NOT_IMPLEMENTED; break; } exit: ESIF_TRACE_DYN_GET("RC: %s(%d)\n", esif_rc_str(rc), rc); return rc; }
// Debug Output void EqlCmd_DebugDump (EqlCmdPtr self) { if (self) { int i; CMD_DEBUG( "\n" "EQLCMD:\n" " adapter = %s\n" " subtype = %s\n" " action = %s\n", String_Get(self->adapter), String_Get(self->subtype), String_Get(self->action)); for (i = 0; i < self->messages->items; i++) CMD_DEBUG( " messages[%d] = %s\n", i, self->messages->list[i]); for (i = 0; i < self->parameters->items; i++) CMD_DEBUG( " parameters[%d] = %s\n", i, self->parameters->list[i]); for (i = 0; i < self->values->items; i++) CMD_DEBUG( " values[%d] = %s (%s)\n", i, self->datatypes->list[i], self->values->list[i]); for (i = 0; i < self->options->items; i++) CMD_DEBUG( " options[%d] = %s\n", i, self->options->list[i]); for (i = 0; i < self->results->size; i++) { EsifDataPtr data = &self->results->elements[i]; char *strdata = EsifData_ToString(data); if (strdata) { CMD_DEBUG( " results[%d] = %s (buf_len=%d data_len=%d)\n" "%s\n", i, esif_data_type_str(self->results->elements[i].type), self->results->elements[i].buf_len, self->results->elements[i].data_len, strdata); esif_ccb_free(strdata); } } CMD_DEBUG("\n"); } }
// Bind Optional Binary Arguments to the Command eEsifError EqlCmd_BindArguments ( EqlCmdPtr self, EsifDataPtr *arguments ) { eEsifError rc = ESIF_OK; int bin = 0, val = 0; // Replace Binary Values with parameters for (val = 0; val < self->values->items; val++) if (strcmp(self->datatypes->list[val], "%") == 0) { if (arguments && arguments[bin]) { self->datatypes->list[val] = esif_data_type_str(arguments[bin]->type); esif_ccb_free(self->values->list[val]); self->values->list[val] = EsifData_ToString(arguments[bin]); // temp hack: convert to string bin++; } else { return ESIF_E_PARAMETER_IS_NULL; } } return rc; }
eEsifError ESIF_CALLCONV EsifEventMgr_RegisterEventByGuid( esif_guid_t *guidPtr, UInt8 participantId, UInt16 domainId, EVENT_OBSERVER_CALLBACK eventCallback, void *contextPtr ) { eEsifError rc = ESIF_OK; EsifFpcEventPtr fpcEventPtr = NULL; EsifUpPtr upPtr = NULL; char guidStr[ESIF_GUID_PRINT_SIZE]; UNREFERENCED_PARAMETER(guidStr); if((NULL == guidPtr) || (NULL == eventCallback)) { rc = ESIF_E_PARAMETER_IS_NULL; goto exit; } /* Find Our Participant */ upPtr = EsifUpPm_GetAvailableParticipantByInstance(participantId); if (NULL == upPtr) { rc = ESIF_E_PARTICIPANT_NOT_FOUND; goto exit; } /* Find the event associated with the participant */ fpcEventPtr = EsifUp_GetFpcEventByGuid(upPtr, guidPtr); if (NULL == fpcEventPtr) { rc = ESIF_E_EVENT_NOT_FOUND; goto exit; } ESIF_TRACE_DEBUG( "Registering event\n" " Alias: %s\n" " GUID: %s\n" " Type: %s(%d)\n" " Data: %s(%d)\n" " Key: %s\n" " Group: %s\n", fpcEventPtr->event_name, esif_guid_print((esif_guid_t *)fpcEventPtr->event_guid, guidStr), esif_event_type_str(fpcEventPtr->esif_event), fpcEventPtr->esif_event, esif_data_type_str(fpcEventPtr->esif_group_data_type), fpcEventPtr->esif_group_data_type, esif_guid_print((esif_guid_t *)fpcEventPtr->event_key, guidStr), esif_event_group_enum_str(fpcEventPtr->esif_group)); rc = EsifEventMgr_AddEntry( fpcEventPtr, participantId, domainId, eventCallback, contextPtr); exit: if (upPtr != NULL) { EsifUp_PutRef(upPtr); } return rc; }
static eEsifError EsifEventMgr_ProcessEvent( UInt8 participantId, UInt16 domainId, eEsifEventType eventType, EsifDataPtr eventDataPtr ) { eEsifError rc = ESIF_OK; EsifLinkListPtr listPtr = NULL; EsifLinkListNodePtr nodePtr = NULL; EsifLinkListNodePtr nextNodePtr = NULL; EventMgrEntryPtr entryPtr = NULL; char domain_str[8] = ""; atomic_t refCount = 0; UInt8 shouldDumpGarbage = ESIF_FALSE; UNREFERENCED_PARAMETER(domain_str); if (NULL == eventDataPtr) { ESIF_TRACE_DEBUG("APPLICATION_EVENT_NO_DATA:\n" " ParticipantID: %u\n" " Domain: %s(%04X)\n" " EventType: %s(%d)\n", participantId, esif_primitive_domain_str(domainId, domain_str, sizeof(domain_str)), domainId, esif_event_type_str(eventType), eventType); } else { ESIF_TRACE_DEBUG("APPLICATION_EVENT\n" " ParticipantID: %u\n" " Domain: %s(%04X)\n" " EventType: %s(%d)\n" " EventDataType: %s(%d)\n" " EventData: %p\n" " buf_ptr %p\n" " buf_len %d\n" " data_len %d\n", participantId, esif_primitive_domain_str(domainId, domain_str, 8), domainId, esif_event_type_str(eventType), eventType, esif_data_type_str(eventDataPtr->type), eventDataPtr->type, eventDataPtr, eventDataPtr->buf_ptr, eventDataPtr->buf_len, eventDataPtr->data_len ); if ((ESIF_DATA_STRING == eventDataPtr->type) && (NULL != eventDataPtr->buf_ptr)) { ESIF_TRACE_DEBUG( " Data Length: %d\n" " Data: %s\n", eventDataPtr->data_len, (EsifString)eventDataPtr->buf_ptr); } } esif_ccb_write_lock(&g_EsifEventMgr.listLock); listPtr = g_EsifEventMgr.observerLists[(unsigned)eventType % NUM_EVENT_LISTS]; if(NULL == listPtr) { rc = ESIF_E_UNSPECIFIED; esif_ccb_write_unlock(&g_EsifEventMgr.listLock); goto exit; } nodePtr = listPtr->head_ptr; while (NULL != nodePtr) { nextNodePtr = nodePtr->next_ptr; entryPtr = (EventMgrEntryPtr)nodePtr->data_ptr; ESIF_ASSERT(entryPtr != NULL); if ((eventType == entryPtr->fpcEvent.esif_event) && ((entryPtr->participantId == participantId) || (entryPtr->participantId == EVENT_MGR_MATCH_ANY)) && ((entryPtr->domainId == domainId) || (entryPtr->domainId == EVENT_MGR_MATCH_ANY) || (domainId == EVENT_MGR_DOMAIN_NA)) && (entryPtr->refCount > 0)) { /* * Increment the reference count so that the node is not removed while in use, * then release the lock so that we avoid a deadlock condition */ atomic_inc(&entryPtr->refCount); esif_ccb_write_unlock(&g_EsifEventMgr.listLock); entryPtr->callback(entryPtr->contextPtr, participantId, domainId, &entryPtr->fpcEvent, eventDataPtr); /* * Get the lock back and decrement the reference count. Remove the node now * if the reference count is 0 */ esif_ccb_write_lock(&g_EsifEventMgr.listLock); nextNodePtr = nodePtr->next_ptr; refCount = atomic_dec(&entryPtr->refCount); if (refCount <= 0) { EsifEventMgr_MoveEntryToGarbage(entryPtr); esif_link_list_node_remove(listPtr, nodePtr); shouldDumpGarbage = ESIF_TRUE; } } nodePtr = nextNodePtr; } esif_ccb_write_unlock(&g_EsifEventMgr.listLock); if (shouldDumpGarbage) { EsifEventMgr_DumpGarbage(); } exit: return rc; }
eEsifError esif_fpc_load( EsifFpcPtr fpcPtr, EsifDspPtr dspPtr ) { eEsifError rc = ESIF_OK; EsifFpcDomainPtr domainPtr; EsifFpcPrimitivePtr primitivePtr; EsifFpcAlgorithmPtr algoPtr; EsifFpcEventPtr eventPtr; unsigned long offset = 0; UInt8 *basePtr = (UInt8 *)fpcPtr; UInt32 numPrim = 0; UInt32 i; UInt32 j; if ((fpcPtr == NULL) || (dspPtr == NULL)) { ESIF_TRACE_ERROR("The fpc pointer or dsp pointer is NULL\n"); rc = ESIF_E_PARAMETER_IS_NULL; goto exit; } if (fpcPtr->number_of_domains < 1) { ESIF_TRACE_WARN("No domain error, number_of_domain = %d (less than 1)\n", fpcPtr->number_of_domains); rc = ESIF_E_PARAMETER_IS_NULL; goto exit; } dspPtr->domain_count = &fpcPtr->number_of_domains; /* Allocate Hash and List. Hash Size 31 Is Hard-Coded And Chosen By DSP Compiler */ dspPtr->ht_ptr = esif_ht_create(ESIF_DSP_HASHTABLE_SIZE); dspPtr->algo_ptr = esif_link_list_create(); dspPtr->domain_ptr = esif_link_list_create(); dspPtr->cap_ptr = esif_link_list_create(); dspPtr->evt_ptr = esif_link_list_create(); if (!dspPtr->ht_ptr || !dspPtr->algo_ptr || !dspPtr->domain_ptr || !dspPtr->cap_ptr || !dspPtr->evt_ptr) { ESIF_TRACE_ERROR("Fail to allocate linked list or hash table\n"); rc = ESIF_E_NO_MEMORY; goto exit; } ESIF_TRACE_DEBUG("<fpc @ %p> FPC name '%s' ver %x,%x desc '%s' size %u num_domains %d num_algorithms %d num_events %d", fpcPtr, fpcPtr->header.name, fpcPtr->header.ver_major, fpcPtr->header.ver_minor, fpcPtr->header.description, fpcPtr->size, fpcPtr->number_of_domains, fpcPtr->number_of_algorithms, fpcPtr->number_of_events); /* First Domain, Ok To Have Zero Primitive Of A Domain */ domainPtr = (EsifFpcDomainPtr)(fpcPtr + 1); for (i = 0; i < fpcPtr->number_of_domains; i++) { offset = (unsigned long)((UInt8 *)domainPtr - basePtr); ESIF_TRACE_DEBUG("<%04lu> Domain[%d] name %s size %d num_of_primitives %d " "num_of_capabilites %u (0x%x)", offset, i, domainPtr->descriptor.name, domainPtr->size, domainPtr->number_of_primitives, domainPtr->capability_for_domain.number_of_capability_flags, domainPtr->capability_for_domain.capability_flags); /* Insert Domain Into Linked List */ rc = dspPtr->insert_domain(dspPtr, domainPtr); if (ESIF_OK != rc) { ESIF_TRACE_ERROR("Fail to insert domain #%d\n", i); goto exit; } /* Capability */ for (j = 0; j < domainPtr->capability_for_domain.number_of_capability_flags; j++) { offset = (unsigned long)(((UInt8 *)&domainPtr->capability_for_domain) - basePtr); ESIF_TRACE_DEBUG("<%04lu> Capability[%d] 0x%x", offset, j, domainPtr->capability_for_domain.capability_mask[j]); } /* First Primtive */ primitivePtr = (EsifFpcPrimitivePtr)(domainPtr + 1); for (j = 0; j < domainPtr->number_of_primitives; j++, numPrim++) { offset = (unsigned long)(((UInt8 *)primitivePtr) - basePtr); ESIF_TRACE_DEBUG("<%04lu> Primitive[%03d]: size %3d tuple_id <%03u %03u %03u> " "operation %u(%s) req_type %u(%s) res_type %u(%s) num_actions %u", offset, j, primitivePtr->size, primitivePtr->tuple.id, primitivePtr->tuple.domain, primitivePtr->tuple.instance, primitivePtr->operation, esif_primitive_opcode_str(primitivePtr->operation), primitivePtr->request_type, esif_data_type_str(primitivePtr->request_type), primitivePtr->result_type, esif_data_type_str(primitivePtr->result_type), primitivePtr->num_actions); /* Insert Primitive Into Hash */ rc = dspPtr->insert_primitive(dspPtr, primitivePtr); if (ESIF_OK != rc) { ESIF_TRACE_ERROR("Fail to insert primitive (id = %d)\n", primitivePtr->tuple.id); goto exit; } /* Next Primitive */ primitivePtr = (EsifFpcPrimitivePtr)((UInt8 *)primitivePtr + primitivePtr->size); } /* Next Domain */ domainPtr = (EsifFpcDomainPtr)((UInt8 *)domainPtr + domainPtr->size); } /* First Algorithm (Laid After The Last Domain) */ algoPtr = (EsifFpcAlgorithmPtr)domainPtr; for (i = 0; i < fpcPtr->number_of_algorithms; i++) { offset = (unsigned long)((UInt8 *)algoPtr - basePtr); ESIF_TRACE_DEBUG("<%04lu> Algorithm[%03d]: action_type %u(%s) temp_xform %u " "tempC1 %u percent_xform %u size %u", offset, i, algoPtr->action_type, esif_action_type_str(algoPtr->action_type), algoPtr->temp_xform, algoPtr->tempC1, algoPtr->percent_xform, algoPtr->size); /* Insert Algorithm Into Linked List */ rc = dspPtr->insert_algorithm(dspPtr, algoPtr); if (ESIF_OK != rc) { ESIF_TRACE_ERROR("Fail to insert algorithm - %s\n", esif_action_type_str(algoPtr->action_type)); goto exit; } /* Next Algorithm */ algoPtr = (EsifFpcAlgorithmPtr)(algoPtr + 1); } /* First Event (Laid After The Last Algorithm) */ eventPtr = (EsifFpcEventPtr)algoPtr; for (i = 0; i < fpcPtr->number_of_events; i++) { offset = (unsigned long)((UInt8 *)eventPtr - basePtr); ESIF_TRACE_DEBUG("<%04lu> Event [%03d] type %s(%d)\n", offset, i, esif_event_type_str(eventPtr->esif_event), eventPtr->esif_event); /* Insert Algorithm Into Linked List */ rc = dspPtr->insert_event(dspPtr, eventPtr); if (ESIF_OK != rc) { ESIF_TRACE_ERROR("Fail to insert event - %s\n", esif_event_type_str(eventPtr->esif_event)); goto exit; } /* Next Event */ eventPtr = (EsifFpcEventPtr)(eventPtr + 1); } exit: if (fpcPtr != NULL) { ESIF_TRACE_DEBUG("%u domains, %u primitives and %u algorithms %u events inserted! status %s", fpcPtr->number_of_domains, numPrim, fpcPtr->number_of_algorithms, fpcPtr->number_of_events, esif_rc_str(rc)); } return rc; }
/* Dispatch */ struct esif_ipc *esif_execute_ipc_command( struct esif_ipc *ipc_ptr ) { struct esif_ipc_command *command_ptr = (struct esif_ipc_command *)(ipc_ptr + 1); u32 data_size = 0; command_ptr->return_code = ESIF_E_COMMAND_DATA_INVALID; if (ESIF_COMMAND_VERSION != command_ptr->version) goto exit; data_size = ipc_ptr->data_len - sizeof(*command_ptr); if(((command_ptr->req_data_offset + command_ptr->req_data_len) > data_size) || ((command_ptr->rsp_data_offset + command_ptr->rsp_data_len) > data_size)) goto exit; ESIF_TRACE_DYN_COMMAND("%s: COMMAND Received: ipc %p\n", ESIF_FUNC, ipc_ptr); ESIF_TRACE_DYN_DECODE(" Version: %d\n" " Type: %s(%d)\n" " Priority: %s(%d)\n" " Payload Length: %d\n" " Request Data Type: %s(%d)\n" " Request Data Offset: %d\n" " Request Data Length: %d\n" " Response Data Type: %s(%d)\n" " Response Data Offset: %d\n" " Response Data Length: %d\n", (int)command_ptr->version, esif_command_type_str(command_ptr->type), (int)command_ptr->type, esif_command_priority_str(command_ptr->priority), (int)command_ptr->priority, (int)command_ptr->payload_len, esif_data_type_str(command_ptr->req_data_type), (int)command_ptr->req_data_type, (int)command_ptr->req_data_offset, (int)command_ptr->req_data_len, esif_data_type_str(command_ptr->rsp_data_type), (int)command_ptr->rsp_data_type, (int)command_ptr->rsp_data_offset, (int)command_ptr->rsp_data_len); switch (command_ptr->type) { case ESIF_COMMAND_TYPE_SET_DEBUG_MODULES: esif_execute_ipc_command_set_debug_modules(command_ptr); break; case ESIF_COMMAND_TYPE_SET_DEBUG_MODULE_LEVEL: esif_execute_ipc_command_set_debug_module_level(command_ptr); break; case ESIF_COMMAND_TYPE_GET_DEBUG_MODULE_LEVEL: esif_execute_ipc_command_get_debug_module_level(command_ptr); break; case ESIF_COMMAND_TYPE_GET_KERNEL_INFO: esif_execute_ipc_command_get_kernel_info(command_ptr); break; case ESIF_COMMAND_TYPE_GET_MEMORY_STATS: esif_execute_ipc_command_get_memory_stats(command_ptr); break; case ESIF_COMMAND_TYPE_GET_PARTICIPANTS: esif_execute_ipc_command_get_participants(command_ptr); break; case ESIF_COMMAND_TYPE_GET_PARTICIPANT_DETAIL: esif_execute_ipc_command_get_participant_detail(command_ptr); break; default: ESIF_TRACE_DYN_COMMAND("%s: Unknown Command Type %d:\n", ESIF_FUNC, command_ptr->type); break; } ESIF_TRACE_DYN_COMMAND("%s: COMMAND return result: %s(%d)\n", ESIF_FUNC, esif_rc_str( command_ptr->return_code), command_ptr->return_code); exit: /* Send To User */ return ipc_ptr; }
/* Copy/Merge Keys from one NameSpace to Another */ eEsifError EsifConfigCopy( EsifDataPtr nameSpaceFrom, // Source DV EsifDataPtr nameSpaceTo, // Target DV EsifDataPtr keyspecs, // Tab-separated Keyspec List (wildcards OK) esif_flags_t flags, // Item Flags Bool replaceKeys, // TRUE=COPY Keys (Replace if exists), FALSE=MERGE Keys (Do Not Replace) UInt32 *keycount) // Optional pointer to variable to hold Key Count copied/merged { eEsifError rc = ESIF_OK; EsifConfigFindContext context = NULL; EsifDataPtr data_key = NULL; EsifDataPtr data_value = NULL; esif_string keylist = NULL; esif_string keyspec = NULL; esif_string keyspec_context = NULL; char **keyset = NULL; size_t keyset_count = 0; UInt32 exported = 0; esif_context_t qsort_ctx = 0; size_t key = 0; ESIF_ASSERT(nameSpaceFrom && nameSpaceTo && keyspecs && nameSpaceFrom->buf_ptr && nameSpaceTo->buf_ptr && keyspecs->buf_ptr); // Parse Key List (optionally Tab-separated) keylist = esif_ccb_strdup((esif_string)keyspecs->buf_ptr); if (keylist == NULL) { rc = ESIF_E_NO_MEMORY; goto exit; } // Create sorted keyset with exclude keyspecs ("!keyspec") listed first keyspec = esif_ccb_strtok(keylist, "\t", &keyspec_context); while (keyspec != NULL) { char **new_keyset = (char **)esif_ccb_realloc(keyset, sizeof(char *) * (keyset_count + 1)); if (new_keyset == NULL) { rc = ESIF_E_NO_MEMORY; goto exit; } keyset = new_keyset; keyset[keyset_count++] = keyspec; keyspec = esif_ccb_strtok(NULL, "\t", &keyspec_context); } esif_ccb_qsort(keyset, keyset_count, sizeof(char *), esif_ccb_qsort_stricmp, qsort_ctx); // Enumerate Each Matching keyspec for (key = 0; (rc == ESIF_OK && key < keyset_count); key++) { // Skip excludes for now so we can compare to each maching keyspec later if (keyset[key][0] == '!') { continue; } EsifData_Destroy(data_key); data_key = EsifData_CreateAs(ESIF_DATA_STRING, keyset[key], 0, ESIFAUTOLEN); if (data_key == NULL) { rc = ESIF_E_NO_MEMORY; goto exit; } if ((rc = EsifConfigFindFirst(nameSpaceFrom, data_key, NULL, &context)) == ESIF_OK) { do { // Skip if matching key matches any exclude keyspecs Bool skip_key = ESIF_FALSE; size_t ex = 0; for (ex = 0; (ex < key && keyset[ex][0] == '!'); ex++) { if (esif_ccb_strmatch((esif_string)data_key->buf_ptr, &keyset[ex][1])) { skip_key = ESIF_TRUE; break; } } // copy = always replace existing key in target if it already exists // merge = never replace existing key in target if it already exists if ((skip_key == ESIF_FALSE) && (replaceKeys == ESIF_TRUE || DataBank_KeyExists(g_DataBankMgr, (esif_string)nameSpaceTo->buf_ptr, (esif_string)data_key->buf_ptr) == ESIF_FALSE)) { EsifData_Destroy(data_value); data_value = EsifData_CreateAs(ESIF_DATA_AUTO, NULL, ESIF_DATA_ALLOCATE, 0); if (data_value == NULL) { rc = ESIF_E_NO_MEMORY; break; } rc = EsifConfigGet(nameSpaceFrom, data_key, data_value); if (rc != ESIF_OK) { break; } rc = EsifConfigSet(nameSpaceTo, data_key, flags, data_value); if (rc != ESIF_OK) { break; } ESIF_TRACE_DEBUG("DV %s: @%s => @%s [%s] {%s, %u bytes}\n", (replaceKeys ? "Copy" : "Merge"), (esif_string)nameSpaceFrom->buf_ptr, (esif_string)nameSpaceTo->buf_ptr, (esif_string)data_key->buf_ptr, esif_data_type_str(data_value->type), data_value->data_len); exported++; } // Reset Key for next search EsifData_Set(data_key, ESIF_DATA_STRING, keyset[key], 0, ESIFAUTOLEN); } while ((rc = EsifConfigFindNext(nameSpaceFrom, data_key, NULL, &context)) == ESIF_OK); EsifConfigFindClose(&context); } if (rc == ESIF_E_ITERATION_DONE || rc == ESIF_E_NOT_FOUND) { rc = ESIF_OK; } } exit: if (rc == ESIF_OK && keycount != NULL) { *keycount = exported; } EsifData_Destroy(data_key); EsifData_Destroy(data_value); esif_ccb_free(keylist); esif_ccb_free(keyset); return rc; }
// Retrieve a single value from a DataVault eEsifError DataVault_GetValue ( DataVaultPtr self, EsifDataPtr path, EsifDataPtr value ) { eEsifError rc = ESIF_E_NOT_FOUND; DataCacheEntryPtr keypair = NULL; if (!self) return ESIF_E_PARAMETER_IS_NULL; // TODO: Locking // Debug: Dump Entire Contents of DataVault if path="*" if (strcmp((esif_string)path->buf_ptr, "*") == 0) { UInt32 context = 0; EsifDataPtr nameSpace = EsifData_CreateAs(ESIF_DATA_STRING, esif_ccb_strdup(self->name), ESIFAUTOLEN, ESIFAUTOLEN); EsifDataPtr key = EsifData_CreateAs(ESIF_DATA_AUTO, NULL, ESIF_DATA_ALLOCATE, 0); EsifDataPtr value = EsifData_CreateAs(ESIF_DATA_AUTO, NULL, ESIF_DATA_ALLOCATE, 0); #ifdef _DEBUG // Dump DataCache if Debug Mode UInt32 i; for (i = 0; i < self->cache->size; i++) { DataCacheEntryPtr keypair = &self->cache->elements[i]; CMD_DEBUG("\n" "id=%d\n" "key=%s\n" "flags=%08X\n" "value.type = %s (%d)\n" "value.buf_ptr = %p %s\n" "value.buf_len = %d\n" "value.data_len= %d\n", i, (char*)keypair->key.buf_ptr, keypair->flags, esif_data_type_str(keypair->value.type), keypair->value.type, keypair->value.buf_ptr, ((keypair->flags & (ESIF_SERVICE_CONFIG_FILELINK | ESIF_SERVICE_CONFIG_REGLINK)) ? (esif_string)keypair->value.buf_ptr : ""), keypair->value.buf_len, keypair->value.data_len ); } if (i > 0) { CMD_DEBUG("*****************\n"); } #endif // Iterate the Contents of the Data Cache if ((rc = EsifConfigFindFirst(nameSpace, key, value, &context)) == ESIF_OK) { do { StringPtr valuestr = EsifData_ToString(value); CMD_DEBUG("\n" "EsifFind%s(\"%s\",%d):\n" " path = %s\n" " value= %s%s%s\n" " type = %s, len=%d\n", (context <= 1 ? "First" : "Next"), (char*)nameSpace->buf_ptr, context - 1, (char*)key->buf_ptr, (value->type == ESIF_DATA_STRING ? "\"" : ""), (valuestr ? valuestr : ""), (value->type == ESIF_DATA_STRING ? "\"" : ""), esif_data_type_str(value->type), value->data_len ); esif_ccb_free(valuestr); EsifData_Set(key, ESIF_DATA_AUTO, NULL, ESIF_DATA_ALLOCATE, 0); EsifData_Set(value, ESIF_DATA_AUTO, NULL, ESIF_DATA_ALLOCATE, 0); } while ((rc = EsifConfigFindNext(nameSpace, key, value, &context)) == ESIF_OK); if (rc == ESIF_E_NOT_FOUND) { rc = ESIF_OK; } } EsifData_Destroy(nameSpace); EsifData_Destroy(key); EsifData_Destroy(value); return ESIF_OK; } // Write to Log before retrieval if AUTO if (value->type == ESIF_DATA_AUTO || value->buf_len == ESIF_DATA_ALLOCATE) { DataVault_WriteLog(self, "AUTO", (esif_string)(self->name), path, 0, value); } keypair = DataCache_GetValue(self->cache, (esif_string)path->buf_ptr); if (NULL != keypair) { UInt32 data_len = keypair->value.data_len; void *buf_ptr = keypair->value.buf_ptr; // File Redirect? if (keypair->flags & ESIF_SERVICE_CONFIG_FILELINK) { if (DataVault_ReadFile(self, (esif_string)buf_ptr, &buf_ptr, &data_len) != ESIF_OK) { value->data_len = 0; if (value->type == ESIF_DATA_AUTO) { value->type = keypair->value.type; } if (value->buf_len == ESIF_DATA_ALLOCATE) { value->buf_len = 0; value->buf_ptr = 0; } return ESIF_OK; // return OK and a blank buffer if file not found/error } } #ifdef ESIF_ATTR_OS_WINDOWS // Registry Redirect? else if (keypair->flags & ESIF_SERVICE_CONFIG_REGLINK) { if (DataVault_ReadRegistry(self, (esif_string)buf_ptr, &buf_ptr, &data_len) != ESIF_OK) { value->data_len = 0; if (value->type == ESIF_DATA_AUTO) { value->type = keypair->value.type; } if (value->buf_len == ESIF_DATA_ALLOCATE) { value->buf_len = 0; value->buf_ptr = 0; } return ESIF_OK; // return OK and a blank buffer if Registry value not found/error } } #endif // Match Found. Verify Data Type matches unless AUTO if (value->type != keypair->value.type && value->type != ESIF_DATA_AUTO) { rc = ESIF_E_UNSUPPORTED_RESULT_DATA_TYPE; // TODO: ESIF_E_INVALID_DATA_TYPE } // Verify Data Buffer is large enough unless Auto-Allocate else if (value->buf_len < data_len && value->buf_len != ESIF_DATA_ALLOCATE) { value->buf_len = data_len; rc = ESIF_E_NEED_LARGER_BUFFER; } // Return pointer to static contents if this is a static vault else if ((self->flags & ESIF_SERVICE_CONFIG_STATIC) && (value->type == ESIF_DATA_AUTO) && (value->buf_len == ESIF_DATA_ALLOCATE)) { value->type = keypair->value.type; value->data_len = data_len; value->buf_len = 0; // Caller MUST NOT Free! value->buf_ptr = buf_ptr; rc = ESIF_OK; } else { // Set Data Type and Auto-Allocate Buffer? if (value->type == ESIF_DATA_AUTO) { value->type = keypair->value.type; } if (ESIF_DATA_ALLOCATE == value->buf_len) { value->buf_len = data_len; value->buf_ptr = esif_ccb_malloc(value->buf_len); if (!value->buf_ptr) { return ESIF_E_NO_MEMORY; } } // Read from file if NOCACHE option if ((keypair->flags & ESIF_SERVICE_CONFIG_NOCACHE) && keypair->value.buf_len == 0) { size_t offset = (size_t)keypair->value.buf_ptr; if (DataVault_ReadBlock(self, (esif_string)value->buf_ptr, data_len, offset) != ESIF_OK) { data_len = 0; return ESIF_E_NOT_FOUND; } // Decrypt? if (keypair->flags & ESIF_SERVICE_CONFIG_ENCRYPT) { UInt32 byte; for (byte = 0; byte < data_len; byte++) ((UInt8*)(value->buf_ptr))[byte] = ~((UInt8*)(value->buf_ptr))[byte]; } } else { esif_ccb_memcpy(value->buf_ptr, buf_ptr, data_len); } value->data_len = data_len; rc = ESIF_OK; } } // Write to Log DataVault_WriteLog(self, "GET", (esif_string)self->name, path, 0, value); return rc; }