static eEsifError esif_dsp_file_scan() { eEsifError rc = ESIF_OK; struct esif_ccb_file *ffdPtr = NULL; esif_ccb_file_enum_t findHandle = ESIF_INVALID_FILE_ENUM_HANDLE; char path[MAX_PATH] = {0}; char pattern[MAX_PATH] = {0}; StringPtr namesp = ESIF_DSP_NAMESPACE; DataVaultPtr DB = DataBank_GetDataVault(namesp); // 1. Load all EDP's in the DSP Configuration Namespace, if any exist if (DB) { EsifDataPtr nameSpace = EsifData_CreateAs(ESIF_DATA_AUTO, namesp, 0, 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); EsifConfigFindContext context = NULL; ESIF_TRACE_DEBUG("SCAN CONFIG For DSP Files NameSpace = %s, Pattern %s", namesp, pattern); if (nameSpace != NULL && key != NULL && value != NULL && (rc = EsifConfigFindFirst(nameSpace, key, value, &context)) == ESIF_OK) { do { // Load all keys from the DataVault with an ".edp" extension if (key->data_len >= 5 && esif_ccb_stricmp(((StringPtr)(key->buf_ptr)) + key->data_len - 5, ".edp") == 0) { ffdPtr = (struct esif_ccb_file *)esif_ccb_malloc(sizeof(*ffdPtr)); esif_ccb_strcpy(ffdPtr->filename, (StringPtr)key->buf_ptr, sizeof(ffdPtr->filename)); if (esif_dsp_entry_create(ffdPtr) != ESIF_OK) { esif_ccb_free(ffdPtr); } } 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); EsifConfigFindClose(&context); if (rc == ESIF_E_ITERATION_DONE) { rc = ESIF_OK; } } EsifData_Destroy(nameSpace); EsifData_Destroy(key); EsifData_Destroy(value); } // 2. Load all EDP's from the DSP folder, if any exist, except ones already loaded from DataBank esif_build_path(path, MAX_PATH, ESIF_PATHTYPE_DSP, NULL, NULL); esif_ccb_strcpy(pattern, "*.edp", MAX_PATH); ESIF_TRACE_DEBUG("SCAN File System For DSP Files Path = %s, Pattern %s", path, pattern); /* Find the first file in the directory that matches are search */ ffdPtr = (struct esif_ccb_file *)esif_ccb_malloc(sizeof(*ffdPtr)); if (ffdPtr == NULL) { ESIF_TRACE_ERROR("Fail to allocate esif_ccb file\n"); rc = ESIF_E_NO_MEMORY; goto exit; } findHandle = esif_ccb_file_enum_first(path, pattern, ffdPtr); if (ESIF_INVALID_FILE_ENUM_HANDLE == findHandle) { rc = ESIF_E_UNSPECIFIED; goto exit; } /* Process Each File */ do { // Don't process the file if it the same name was already loaded from a DataVault if (DB == NULL || DataCache_GetValue(DB->cache, ffdPtr->filename) == NULL) { if (esif_dsp_entry_create(ffdPtr) != ESIF_OK) { esif_ccb_free(ffdPtr); } ffdPtr = (struct esif_ccb_file *)esif_ccb_malloc(sizeof(*ffdPtr)); } } while (esif_ccb_file_enum_next(findHandle, pattern, ffdPtr)); esif_ccb_file_enum_close(findHandle); exit: if (ffdPtr != NULL) { esif_ccb_free(ffdPtr); } return rc; }
// Send DSP enum esif_rc esif_send_dsp( char *filename, u8 dstId ) { enum esif_rc rc = ESIF_OK; int edpSize = 512; int cmdSize = 0; struct esif_ipc *ipcPtr = NULL; struct esif_ipc_command *commandPtr = NULL; struct esif_command_send_dsp *dspCommandPtr = NULL; struct edp_dir edpDir; size_t bytesRead; char *edpName = 0; IOStreamPtr ioPtr = IOStream_Create(); EsifDataPtr nameSpace = 0; EsifDataPtr key = 0; EsifDataPtr value = 0; if (ioPtr == NULL) { ESIF_TRACE_ERROR("Fail to create IOStream\n"); rc = ESIF_E_NO_MEMORY; goto exit; } // // If we have a filename provided use the contents of the file as the CPC // note this is opaque it is up to the receiver to verify that this is in fact // a CPC. // if (NULL == filename) { ESIF_TRACE_ERROR("Filename is null\n"); rc = ESIF_E_PARAMETER_IS_NULL; goto exit; } // Use name portion of filename for the DataVault key (C:\path\file.edp = file.edp) edpName = strrchr(filename, *ESIF_PATH_SEP); edpName = (edpName ? ++edpName : filename); nameSpace = EsifData_CreateAs(ESIF_DATA_STRING, ESIF_DSP_NAMESPACE, 0, ESIFAUTOLEN); key = EsifData_CreateAs(ESIF_DATA_STRING, edpName, 0, ESIFAUTOLEN); value = EsifData_CreateAs(ESIF_DATA_AUTO, NULL, ESIF_DATA_ALLOCATE, 0); if (nameSpace == NULL || key == NULL || value == NULL) { rc = ESIF_E_NO_MEMORY; goto exit; } // Look for EDP file on disk first then DataVault (static or file) if (!esif_ccb_file_exists(filename) && EsifConfigGet(nameSpace, key, value) == ESIF_OK) { filename = edpName; IOStream_SetMemory(ioPtr, (BytePtr)value->buf_ptr, value->data_len); } else { IOStream_SetFile(ioPtr, filename, (char *)"rb"); } /* FIND CPC within EDP file */ if (IOStream_Open(ioPtr) != 0) { ESIF_TRACE_ERROR("File not found (%s)\n", filename); rc = ESIF_E_IO_OPEN_FAILED; goto exit; } bytesRead = IOStream_Read(ioPtr, &edpDir, sizeof(struct edp_dir)); if (!esif_verify_edp(&edpDir, bytesRead)) { ESIF_TRACE_ERROR("Invalid EDP Header: Signature=%4.4s Version=%d\n", (char *)&edpDir.signature, edpDir.version); rc = ESIF_E_NOT_SUPPORTED; goto exit; } edpSize = edpDir.fpc_offset - edpDir.cpc_offset; IOStream_Seek(ioPtr, edpDir.cpc_offset, SEEK_SET); if (edpSize > MAX_EDP_SIZE) { ESIF_TRACE_ERROR("The edp size %d is larger than maximum edp size\n", edpSize); rc = -ESIF_E_UNSPECIFIED; goto exit; } cmdSize = edpSize + sizeof(*dspCommandPtr); ipcPtr = esif_ipc_alloc_command(&commandPtr, cmdSize); if (NULL == ipcPtr || NULL == commandPtr) { ESIF_TRACE_ERROR("Fail to allocate esif_ipc/esif_ipc_command\n"); rc = ESIF_E_NO_MEMORY; goto exit; } commandPtr->type = ESIF_COMMAND_TYPE_SEND_DSP; commandPtr->req_data_type = ESIF_DATA_STRUCTURE; commandPtr->req_data_offset = 0; commandPtr->req_data_len = cmdSize; commandPtr->rsp_data_type = ESIF_DATA_VOID; commandPtr->rsp_data_offset = 0; commandPtr->rsp_data_len = 0; dspCommandPtr = (struct esif_command_send_dsp *)(commandPtr + 1); dspCommandPtr->id = dstId; dspCommandPtr->data_len = edpSize; bytesRead = IOStream_Read(ioPtr, dspCommandPtr + 1, edpSize); ESIF_TRACE_DEBUG("loaded file %s bytes %d\n", filename, (int)bytesRead); ESIF_TRACE_INFO("CPC file %s(%d) sent to participant %d\n", filename, edpSize, dstId); ipc_execute(ipcPtr); if (ESIF_OK != ipcPtr->return_code) { ESIF_TRACE_ERROR("ipc error code = %s(%d)\n", esif_rc_str(ipcPtr->return_code), ipcPtr->return_code); rc = ipcPtr->return_code; goto exit; } rc = commandPtr->return_code; if ((rc != ESIF_OK) && (rc != ESIF_E_DSP_ALREADY_LOADED)) { ESIF_TRACE_ERROR("primitive error code = %s(%d)\n", esif_rc_str(commandPtr->return_code), commandPtr->return_code); goto exit; } exit: if (NULL != ipcPtr) { esif_ipc_free(ipcPtr); } if (NULL != ioPtr) { IOStream_Close(ioPtr); IOStream_Destroy(ioPtr); } EsifData_Destroy(nameSpace); EsifData_Destroy(key); EsifData_Destroy(value); return rc; }
static eEsifError EsifGetActionDelegateCnfg( const EsifUpDomainPtr domainPtr, const EsifDataPtr requestPtr, EsifDataPtr responsePtr ) { extern int g_shell_enabled; // ESIF Shell Enabled Flag extern Bool g_ws_restricted;// Web Server Restricted Mode Flag eEsifError rc = ESIF_OK; EsifPrimitiveTuple dcfgTuple = { GET_CONFIG_ACCESS_CONTROL_SUR, 0, 255 }; EsifPrimitiveTuple gddvTuple = { GET_CONFIG_DATAVAULT_SUR, 0, 255 }; EsifData dcfgData = { ESIF_DATA_UINT32, NULL, ESIF_DATA_ALLOCATE, 0 }; EsifData gddvData = { ESIF_DATA_AUTO, NULL, ESIF_DATA_ALLOCATE, 0 }; ESIF_ASSERT(NULL != domainPtr); ESIF_ASSERT(NULL != requestPtr); UNREFERENCED_PARAMETER(responsePtr); // Not currently used by DPTF dcfgTuple.domain = domainPtr->domain; gddvTuple.domain = domainPtr->domain; // Execute DCFG to read Access Control List Bitmask from BIOS, if it exists rc = EsifUp_ExecutePrimitive(domainPtr->upPtr, &dcfgTuple, requestPtr, &dcfgData); if (rc == ESIF_OK && dcfgData.buf_ptr != NULL && dcfgData.buf_len >= sizeof(UInt32)) { DCfgOptions newmask = { .asU32 = *(UInt32 *)dcfgData.buf_ptr }; DCfg_Set(newmask); ESIF_TRACE_INFO("DCFG Loaded: 0x%08X\n", newmask.asU32); // Disable ESIF Shell if Access Control forbids it if (DCfg_Get().opt.ShellAccessControl) { g_shell_enabled = 0; } // Stop Web Server (if Started) if Restricted or Generic Access Control forbids it if (EsifWebIsStarted() && ((!g_ws_restricted && DCfg_Get().opt.GenericUIAccessControl)|| (g_ws_restricted && DCfg_Get().opt.RestrictedUIAccessControl)) ) { EsifWebStop(); } } // Execute GDDV to read DataVault from BIOS, if it exists rc = EsifUp_ExecutePrimitive(domainPtr->upPtr, &gddvTuple, requestPtr, &gddvData); if (rc != ESIF_OK) { // Always Return OK if no ESIF_LF or GDDV object in BIOS if (rc == ESIF_E_NO_LOWER_FRAMEWORK || rc == ESIF_E_ACPI_OBJECT_NOT_FOUND) { rc = ESIF_OK; } } else { char *dv_name = "__merge"; // Temporary DV Name DataVaultPtr DB = DataBank_GetNameSpace(g_DataBankMgr, dv_name); if (DB != NULL) { DataBank_CloseNameSpace(g_DataBankMgr, dv_name); } DB = DataBank_OpenNameSpace(g_DataBankMgr, dv_name); // Load Datavault into temporary namespace. DV may or may not be preceded by a variant if (DB) { u32 skipbytes = 0; void *buffer = NULL; // // This is in place to resolve a static code analysis issue. // This should never happen if EsifUp_ExecutePrimitive is successful above. // if (NULL == gddvData.buf_ptr) { DataBank_CloseNameSpace(g_DataBankMgr, dv_name); ESIF_TRACE_DEBUG("No data returned for BIOS datavault.\n"); goto exit; } skipbytes = (memcmp(gddvData.buf_ptr, "\xE5\x1F", 2) == 0 ? 0 : sizeof(union esif_data_variant)); buffer = esif_ccb_malloc(gddvData.data_len); if (NULL == buffer) { DataBank_CloseNameSpace(g_DataBankMgr, dv_name); ESIF_TRACE_DEBUG("Unable to allocate memory\n"); rc = ESIF_E_NO_MEMORY; goto exit; } esif_ccb_memcpy(buffer, (u8*)gddvData.buf_ptr + skipbytes, gddvData.data_len - skipbytes); IOStream_SetMemory(DB->stream, buffer, gddvData.data_len - skipbytes); if ((rc = DataVault_ReadVault(DB)) != ESIF_OK) { DataBank_CloseNameSpace(g_DataBankMgr, dv_name); ESIF_TRACE_DEBUG("Unable to Open DataVault: %s\n", esif_rc_str(rc)); rc = ESIF_OK; } else { EsifDataPtr data_nspace = NULL; EsifDataPtr data_key = NULL; EsifDataPtr data_targetdv = NULL; esif_flags_t options = 0; // NOPERSIST esif_string keyspec = "*"; // Merge All Keys esif_string targetdv = g_DataVaultDefault; DB->flags |= (ESIF_SERVICE_CONFIG_READONLY); // Merge Contents into Default DataVault data_nspace = EsifData_CreateAs(ESIF_DATA_STRING, dv_name, 0, ESIFAUTOLEN); data_targetdv = EsifData_CreateAs(ESIF_DATA_STRING, targetdv, 0, ESIFAUTOLEN); data_key = EsifData_CreateAs(ESIF_DATA_STRING, keyspec, 0, ESIFAUTOLEN); if (data_nspace == NULL || data_key == NULL || data_targetdv == NULL) { rc = ESIF_E_NO_MEMORY; } else { rc = EsifConfigCopy(data_nspace, data_targetdv, data_key, options, ESIF_FALSE, NULL); } ESIF_TRACE_INFO("GDDV Loaded: %d bytes, %d keys => %s.dv [%s]\n", (int)IOStream_GetSize(DB->stream), DataCache_GetCount(DB->cache), targetdv, esif_rc_str(rc)); EsifData_Destroy(data_nspace); EsifData_Destroy(data_key); EsifData_Destroy(data_targetdv); DataBank_CloseNameSpace(g_DataBankMgr, dv_name); } esif_ccb_free(buffer); } } exit: esif_ccb_free(dcfgData.buf_ptr); esif_ccb_free(gddvData.buf_ptr); return rc; }
/* Add DSP Entry */ static eEsifError esif_dsp_entry_create(struct esif_ccb_file *file_ptr) { eEsifError rc = ESIF_E_UNSPECIFIED; EsifDspPtr dspPtr = NULL; EsifFpcPtr fpcPtr = NULL; UInt32 fpcIsStatic = ESIF_FALSE; UInt8 i = 0; char path[MAX_PATH]={0}; UInt32 fpcSize = 0; UInt32 edpSize = 0; size_t numFpcBytesRead = 0; struct edp_dir edp_dir; EsifDataPtr nameSpace = 0; EsifDataPtr key = 0; EsifDataPtr value = 0; IOStreamPtr ioPtr = IOStream_Create(); if ((NULL == file_ptr) || (NULL == ioPtr)) { ESIF_TRACE_ERROR("The file pointer or IO stream is NULL\n"); goto exit; } nameSpace = EsifData_CreateAs(ESIF_DATA_STRING, ESIF_DSP_NAMESPACE, 0, ESIFAUTOLEN); key = EsifData_CreateAs(ESIF_DATA_STRING, file_ptr->filename, 0, ESIFAUTOLEN); value = EsifData_CreateAs(ESIF_DATA_AUTO, NULL, ESIF_DATA_ALLOCATE, 0); if (nameSpace == NULL || key == NULL || value == NULL) { rc = ESIF_E_NO_MEMORY; goto exit; } ESIF_TRACE_DEBUG("Filename: %s", file_ptr->filename); dspPtr = esif_dsp_create(); if (NULL == dspPtr) { ESIF_TRACE_ERROR("Fail to allocate dsp entry\n"); goto exit; } // Look for EDP file on disk first then in DataVault (static or file) esif_build_path(path, sizeof(path), ESIF_PATHTYPE_DSP, file_ptr->filename, NULL); if (!esif_ccb_file_exists(path) && EsifConfigGet(nameSpace, key, value) == ESIF_OK) { esif_ccb_strcpy(path, file_ptr->filename, MAX_PATH); IOStream_SetMemory(ioPtr, StoreReadOnly, (BytePtr)value->buf_ptr, value->data_len); } else { IOStream_SetFile(ioPtr, StoreReadOnly, path, "rb"); } ESIF_TRACE_DEBUG("Fullpath: %s", path); if (IOStream_Open(ioPtr) != 0) { ESIF_TRACE_ERROR("File not found (%s)", path); goto exit; } /* Read FPC From EDP File */ if (esif_ccb_strstr(&path[0], ".edp")) { /* EDP - Only Read The FPC Part */ edpSize = (UInt32)IOStream_GetSize(ioPtr); if (!edpSize) { goto exit; } numFpcBytesRead = IOStream_Read(ioPtr, &edp_dir, sizeof(edp_dir)); if (!esif_verify_edp(&edp_dir, numFpcBytesRead)) { ESIF_TRACE_ERROR("Invalid EDP Header: Signature=%4.4s Version=%d\n", (char *)&edp_dir.signature, edp_dir.version); goto exit; } if (edpSize > MAX_EDP_SIZE || edp_dir.fpc_offset > MAX_FPC_SIZE || edp_dir.fpc_offset > edpSize) { ESIF_TRACE_ERROR("The edp or fpc file size is larger than maximum\n"); goto exit; } fpcSize = edpSize - edp_dir.fpc_offset; IOStream_Seek(ioPtr, edp_dir.fpc_offset, SEEK_SET); ESIF_TRACE_DEBUG("File found (%s) size %u, FPC size %u from offset %u", path, edpSize, fpcSize, edp_dir.fpc_offset); } else { ESIF_TRACE_DEBUG("File %s does not have .fpc and .edp format!", path); } // use static DataVault buffer (if available), otherwise allocate space for our FPC file contents (which will not be freed) if (IOStream_GetType(ioPtr) == StreamMemory && value->buf_len == 0) { fpcPtr = (EsifFpcPtr)IOStream_GetMemoryBuffer(ioPtr); if (NULL == fpcPtr) { ESIF_TRACE_ERROR("NULL buffer"); goto exit; } fpcPtr = (EsifFpcPtr) (((BytePtr) fpcPtr) + IOStream_GetOffset(ioPtr)); numFpcBytesRead = fpcSize; ESIF_TRACE_DEBUG("Static vault size %u buf_ptr=0x%p\n", (int)numFpcBytesRead, fpcPtr); fpcIsStatic = ESIF_TRUE; } else { fpcPtr = (EsifFpcPtr)esif_ccb_malloc(fpcSize); if (NULL == fpcPtr) { ESIF_TRACE_ERROR("malloc failed to allocate %u bytes\n", fpcSize); goto exit; } ESIF_TRACE_DEBUG("File malloc size %u", fpcSize); // read file contents numFpcBytesRead = IOStream_Read(ioPtr, fpcPtr, fpcSize); if (numFpcBytesRead < fpcSize) { ESIF_TRACE_ERROR("Read short received %u of %u bytes\n", (int)numFpcBytesRead, fpcSize); goto exit; } ESIF_TRACE_DEBUG("File read size %u", (int)numFpcBytesRead); } ESIF_TRACE_DEBUG("\nDecode Length: %u", fpcPtr->size); ESIF_TRACE_DEBUG("Code: %s", fpcPtr->header.code); ESIF_TRACE_DEBUG("Ver Major: %u", fpcPtr->header.ver_major); ESIF_TRACE_DEBUG("Ver Minor: %u", fpcPtr->header.ver_minor); ESIF_TRACE_DEBUG("Name: %s", fpcPtr->header.name); ESIF_TRACE_DEBUG("Description: %s", fpcPtr->header.description); ESIF_TRACE_DEBUG("Type: %s", fpcPtr->header.type); ESIF_TRACE_DEBUG("Bus Enumerator: %u", fpcPtr->header.bus_enum); ESIF_TRACE_DEBUG("ACPI Device: %s", fpcPtr->header.acpi_device); ESIF_TRACE_DEBUG("ACPI Scope: %s", fpcPtr->header.acpi_scope); ESIF_TRACE_DEBUG("ACPI Type: %s", fpcPtr->header.acpi_type); ESIF_TRACE_DEBUG("ACPI UID: %s", fpcPtr->header.acpi_UID); ESIF_TRACE_DEBUG("PCI Vendor ID: %s", fpcPtr->header.pci_vendor_id); ESIF_TRACE_DEBUG("PCI Device ID: %s", fpcPtr->header.pci_device_id); ESIF_TRACE_DEBUG("PCI Bus: %s", fpcPtr->header.pci_bus); ESIF_TRACE_DEBUG("PCI Device: %s", fpcPtr->header.pci_device); ESIF_TRACE_DEBUG("PCI Function: %s", fpcPtr->header.pci_function); dspPtr->code_ptr = (EsifString)fpcPtr->header.name; dspPtr->bus_enum = (UInt8 *)&fpcPtr->header.bus_enum; dspPtr->type = (EsifString)fpcPtr->header.type; dspPtr->ver_major_ptr = (UInt8 *)&fpcPtr->header.ver_major; dspPtr->ver_minor_ptr = (UInt8 *)&fpcPtr->header.ver_minor; dspPtr->acpi_device = (EsifString)fpcPtr->header.acpi_device; dspPtr->acpi_scope = (EsifString)fpcPtr->header.acpi_scope; dspPtr->acpi_type = (EsifString)fpcPtr->header.acpi_type; dspPtr->acpi_uid = (EsifString)fpcPtr->header.acpi_UID; dspPtr->vendor_id = (EsifString)fpcPtr->header.pci_vendor_id; dspPtr->device_id = (EsifString)fpcPtr->header.pci_device_id; dspPtr->pci_bus = (EsifString)&fpcPtr->header.pci_bus; dspPtr->pci_bus_device = (EsifString)&fpcPtr->header.pci_device; dspPtr->pci_function = (EsifString)&fpcPtr->header.pci_function; /* Assign Function Pointers */ dspPtr->get_code = get_code; dspPtr->get_ver_minor = get_ver_minor; dspPtr->get_ver_major = get_ver_major; dspPtr->get_temp_tc1 = get_temp_c1; dspPtr->get_percent_xform = get_percent_xform; dspPtr->insert_primitive = insert_primitive; dspPtr->insert_algorithm = insert_algorithm; dspPtr->insert_domain = insert_domain; dspPtr->insert_event = insert_event; dspPtr->get_primitive = get_primitive; dspPtr->get_action = get_action; dspPtr->get_algorithm = get_algorithm; dspPtr->get_domain = get_domain; dspPtr->get_event_by_type = get_event_by_type; dspPtr->get_event_by_guid = get_event_by_guid; dspPtr->init_fpc_iterator = init_fpc_iterator; dspPtr->get_next_fpc_domain = get_next_fpc_domain; dspPtr->get_domain_count = get_domain_count; rc = esif_fpc_load(fpcPtr, dspPtr); if (ESIF_OK == rc) { ESIF_TRACE_DEBUG("FPC %s load successfully", path); } else { ESIF_TRACE_DEBUG("Unable to load FPC %s, rc %s", path, esif_rc_str(rc)); goto exit; } /* Lock DSP Manager */ esif_ccb_write_lock(&g_dm.lock); /* Simple Table Lookup For Now. Scan Table And Find First Empty Slot */ /* Empty slot indicated by AVAILABLE state */ for (i = 0; i < MAX_DSP_MANAGER_ENTRY; i++) { if (NULL == g_dm.dme[i].dsp_ptr) { break; } } /* If No Available Slots Return */ if (i >= MAX_DSP_MANAGER_ENTRY) { esif_ccb_write_unlock(&g_dm.lock); ESIF_TRACE_ERROR("No free dsp manager entry is available for %s\n", file_ptr->filename); goto exit; } /* ** Take Slot */ g_dm.dme[i].dsp_ptr = dspPtr; g_dm.dme[i].file_ptr = file_ptr; g_dm.dme[i].fpc_ptr = (fpcIsStatic ? 0 : fpcPtr); g_dm.dme_count++; dspPtr = NULL; // Prevent deallocate on exit fpcPtr = NULL; // Prevent deallocate on exit esif_ccb_write_unlock(&g_dm.lock); rc = ESIF_OK; ESIF_TRACE_INFO("Create entry in dsp manager successfully for %s\n", file_ptr->filename); exit: IOStream_Destroy(ioPtr); EsifData_Destroy(nameSpace); EsifData_Destroy(key); EsifData_Destroy(value); esif_dsp_destroy(dspPtr); if (!fpcIsStatic) { esif_ccb_free(fpcPtr); } return rc; }
static eEsifError EsifSetActionDelegateRset( const EsifUpDomainPtr domainPtr, const EsifDataPtr requestPtr) { eEsifError rc = ESIF_E_PRIMITIVE_ACTION_FAILURE; EsifPrimitiveTupleParameter parameters = { 0 }; EsifPrimitiveTuple tuple = { 0 }; Bool signal_event = ESIF_FALSE; char domain_str[8] = { 0 }; int j = 0; ESIF_ASSERT(domainPtr != NULL); ESIF_ASSERT(requestPtr != NULL); if (requestPtr->buf_ptr == NULL) { rc = ESIF_E_PARAMETER_IS_NULL; goto exit; } if (requestPtr->data_len != sizeof(parameters)) { rc = ESIF_E_REQUEST_DATA_OUT_OF_BOUNDS; goto exit; } // Convert BINARY Parameters to Primitive Tuple esif_ccb_memcpy(¶meters, requestPtr->buf_ptr, sizeof(parameters)); ESIF_TRACE_DEBUG("CONFIG RESET: { %s (%hd), %s, %hd }\n", esif_primitive_str(parameters.id.integer.value), (u16)parameters.id.integer.value, esif_primitive_domain_str((u16)parameters.domain.integer.value, domain_str, sizeof(domain_str)), (u16)parameters.instance.integer.value ); // Look up Primitive Tuple in the DSP and verify it is a valid SET primtive EsifDspPtr dspPtr = EsifUp_GetDsp(domainPtr->upPtr); if (dspPtr == NULL) { rc = ESIF_E_NEED_DSP; goto exit; } tuple.id = (u16) parameters.id.integer.value; tuple.domain = (u16) parameters.domain.integer.value; tuple.instance = (u16) parameters.instance.integer.value; EsifFpcPrimitivePtr primitivePtr = dspPtr->get_primitive(dspPtr, &tuple); if (primitivePtr == NULL) { rc = ESIF_E_PRIMITIVE_NOT_FOUND_IN_DSP; goto exit; } if (primitivePtr->operation != ESIF_PRIMITIVE_OP_SET) { rc = ESIF_E_INVALID_REQUEST_TYPE; goto exit; } // Find first CONFIG Action and Delete its Key from its DataVault for (j = 0; j < (int)primitivePtr->num_actions; j++) { EsifFpcActionPtr fpcActionPtr = dspPtr->get_action(dspPtr, primitivePtr, (u8)j); DataItemPtr paramDataVault = EsifFpcAction_GetParam(fpcActionPtr, (const UInt8)0); DataItemPtr paramKeyName = EsifFpcAction_GetParam(fpcActionPtr, (const UInt8)1); EsifString expandedKeyName = NULL; if (fpcActionPtr->type != ESIF_ACTION_CONFIG) { continue; } if (paramDataVault == NULL || paramKeyName == NULL || paramDataVault->data_type != ESIF_DSP_PARAMETER_TYPE_STRING || paramKeyName->data_type != ESIF_DSP_PARAMETER_TYPE_STRING) { rc = ESIF_E_PARAMETER_IS_OUT_OF_BOUNDS; goto exit; } // Replace "%nm%" tokens in the key name or make a copy of the key name for static keys expandedKeyName = EsifUp_CreateTokenReplacedParamString(domainPtr->upPtr, primitivePtr, (StringPtr)paramKeyName->data); if (expandedKeyName == NULL) { expandedKeyName = esif_ccb_strdup((StringPtr)paramKeyName->data); if (expandedKeyName == NULL) { rc = ESIF_E_NO_MEMORY; goto exit; } } // Valid SET CONFIG Primitive found with valid DV/Key Name; Delete the associated Key from the DataVault EsifDataPtr data_nspace = EsifData_CreateAs(ESIF_DATA_STRING, (StringPtr)paramDataVault->data, 0, ESIFAUTOLEN); EsifDataPtr data_key = EsifData_CreateAs(ESIF_DATA_STRING, expandedKeyName, 0, ESIFAUTOLEN); // Do not signal an Event if Key does not exist in DataVault if (DataBank_KeyExists(g_DataBankMgr, (StringPtr)paramDataVault->data, expandedKeyName) == ESIF_FALSE) { rc = ESIF_OK; } else if (data_nspace == NULL || data_key == NULL) { rc = ESIF_E_NO_MEMORY; } else { // Delete Existing Key from DataVault rc = EsifConfigDelete(data_nspace, data_key); if (rc == ESIF_OK) { signal_event = ESIF_TRUE; } ESIF_TRACE_DEBUG("CONFIG RESET: config delete @%s %s [rc=%s (%d)]\n", (StringPtr)data_nspace->buf_ptr, (StringPtr)data_key->buf_ptr, esif_rc_str(rc), rc ); } // Signal any Event(s) associated with this SET Primitive if (signal_event) { EsifActConfigSignalChangeEvents(domainPtr->upPtr, tuple, NULL); } EsifData_Destroy(data_nspace); EsifData_Destroy(data_key); esif_ccb_free(expandedKeyName); break; } if (j >= (int)primitivePtr->num_actions) { rc = ESIF_E_UNSUPPORTED_ACTION_TYPE; } exit: return rc; }
/* Set */ eEsifError DataVault_SetValue( DataVaultPtr self, EsifDataPtr path, EsifDataPtr value, esif_flags_t flags ) { eEsifError rc = ESIF_OK; DataCacheEntryPtr keypair; if (FLAGS_TEST(self->flags, ESIF_SERVICE_CONFIG_STATIC | ESIF_SERVICE_CONFIG_READONLY)) { return ESIF_E_READONLY; } // Ignore value for DELETEs if (FLAGS_TEST(flags, ESIF_SERVICE_CONFIG_DELETE)) { value = NULL; } // AUTO data types or AUTO_ALLOCATE are not allowed for SET if (value && (value->type == ESIF_DATA_AUTO || value->buf_len == ESIF_DATA_ALLOCATE)) { return ESIF_E_UNSUPPORTED_RESULT_DATA_TYPE; } // Reject SETs for static-sized data types whose buffer is too small if (value) { u32 len = (u32) esif_data_type_sizeof(value->type); if (len > 0 && value->buf_len < len) { value->data_len = len; return ESIF_E_NEED_LARGER_BUFFER; } } // Write to Log DataVault_WriteLog(self, (flags & ESIF_SERVICE_CONFIG_DELETE ? "DELETE" : "SET"), self->name, path, flags, value); // Delete DataVault Key(s)? if (esif_ccb_strpbrk((esif_string)path->buf_ptr, "*?") != NULL) { if (flags & ESIF_SERVICE_CONFIG_DELETE) { UInt32 item = 0; while (item < self->cache->size) { if (esif_ccb_strmatch((esif_string)self->cache->elements[item].key.buf_ptr, (esif_string)path->buf_ptr)) { flags |= FLAGS_TEST(self->cache->elements[item].flags, ESIF_SERVICE_CONFIG_PERSIST); if (DataCache_DeleteValue(self->cache, (esif_string)self->cache->elements[item].key.buf_ptr) == ESIF_OK) { continue; } } item++; } goto exit; } return ESIF_E_NOT_SUPPORTED; // Keys may not contain "*" or "?" } // Read data from File // TODO: Change Parser Logic and Syntax instead if (value && value->buf_ptr && esif_ccb_strncmp((char*)value->buf_ptr, "<<", 2) == 0) { void *buffer = 0; UInt32 buflen = 0; if (ReadFileIntoBuffer((char*)value->buf_ptr + 2, &buffer, &buflen) == ESIF_OK) { if (value->buf_len) { esif_ccb_free(value->buf_ptr); } value->buf_ptr = buffer; if (value->type == ESIF_DATA_STRING) { buflen++; // Include Null Terminator } value->buf_len = value->data_len = buflen; } else { return ESIF_E_UNSPECIFIED; // TODO: File Not Found } } // Get the Data Row or create it if it does not exist keypair = DataCache_GetValue(self->cache, (esif_string)path->buf_ptr); if (keypair) { // Match Found // READONLY? if (keypair->flags & ESIF_SERVICE_CONFIG_READONLY) { rc = ESIF_E_READONLY; } // DELETE? else if (flags & ESIF_SERVICE_CONFIG_DELETE) { flags |= keypair->flags; DataCache_DeleteValue(self->cache, (esif_string)path->buf_ptr); } else if (value && value->buf_ptr) { // UPDATE if (keypair->value.buf_len > 0 && value->data_len != keypair->value.buf_len) { void *new_buf = NULL; u32 new_buf_len = 0; // Grow or shrink buffer if it was allocated, otherwise ask for a larger buffer new_buf_len = esif_ccb_max(1, value->data_len); new_buf= (void *)esif_ccb_realloc(keypair->value.buf_ptr, new_buf_len); if (new_buf == NULL) { return ESIF_E_NEED_LARGER_BUFFER; } else { keypair->value.buf_len = new_buf_len; keypair->value.buf_ptr = new_buf; } } // Replace the File Offset stored in buf_ptr with a copy of the data for updated NOCACHE values if (keypair->flags & ESIF_SERVICE_CONFIG_NOCACHE && keypair->value.buf_len == 0) { keypair->value.buf_len = esif_ccb_max(1, value->data_len); keypair->value.buf_ptr = esif_ccb_malloc(value->buf_len); } keypair->flags = flags; keypair->value.type = value->type; keypair->value.data_len = value->data_len; esif_ccb_memcpy(keypair->value.buf_ptr, value->buf_ptr, value->data_len); rc = ESIF_OK; } } else if (value && value->buf_ptr && !(flags & ESIF_SERVICE_CONFIG_DELETE)) { EsifDataPtr valueClonePtr = NULL; // // The data passed in may be in a buffer owned elsewhere, so clone the data // valueClonePtr = EsifData_Clone(value); if (NULL == valueClonePtr) { rc = ESIF_E_NO_MEMORY; goto exit; } DataCache_InsertValue(self->cache, (esif_string)path->buf_ptr, valueClonePtr, flags); EsifData_Destroy(valueClonePtr); } exit: // If Persisted, Flush to disk if (rc == ESIF_OK && FLAGS_TEST(flags, ESIF_SERVICE_CONFIG_PERSIST)) { rc = DataVault_WriteVault(self); } return rc; }
// Retrieve a single value from a DataVault eEsifError DataVault_GetValue( DataVaultPtr self, EsifDataPtr path, EsifDataPtr value, esif_flags_t *flagsPtr ) { eEsifError rc = ESIF_E_NOT_FOUND; DataCacheEntryPtr keypair = NULL; if (!self) return ESIF_E_PARAMETER_IS_NULL; if (flagsPtr) *flagsPtr = 0; // Return "keyname1|keyname2|..." if path contains "*" or "?" if (esif_ccb_strpbrk((esif_string)path->buf_ptr, "*?") != NULL) { EsifDataPtr nameSpace = EsifData_CreateAs(ESIF_DATA_STRING, esif_ccb_strdup(self->name), ESIFAUTOLEN, ESIFAUTOLEN); EsifDataPtr key = EsifData_CreateAs(ESIF_DATA_STRING, path->buf_ptr, 0, ESIFAUTOLEN); EsifConfigFindContext context = NULL; esif_string keylist = NULL; u32 data_len = 0; // Verify valid Data Type and Data Buffer size if (value->type != ESIF_DATA_STRING && value->type != ESIF_DATA_AUTO) { rc = ESIF_E_UNSUPPORTED_RESULT_DATA_TYPE; } if (rc == ESIF_E_NOT_FOUND && nameSpace != NULL && key != NULL && (rc = EsifConfigFindFirst(nameSpace, key, NULL, &context)) == ESIF_OK) { do { data_len += (u32)key->data_len; esif_string newlist = esif_ccb_realloc(keylist, data_len); if (newlist == NULL) { EsifData_Set(key, ESIF_DATA_STRING, "", 0, ESIFAUTOLEN); rc = ESIF_E_NO_MEMORY; break; } keylist = newlist; esif_ccb_sprintf_concat(data_len, keylist, "%s%s", (*keylist ? "|" : ""), (char *)key->buf_ptr); EsifData_Set(key, ESIF_DATA_STRING, path->buf_ptr, 0, ESIFAUTOLEN); } while ((rc = EsifConfigFindNext(nameSpace, key, NULL, &context)) == ESIF_OK); EsifConfigFindClose(&context); if (rc == ESIF_E_ITERATION_DONE) { rc = ESIF_OK; } } EsifData_Destroy(nameSpace); EsifData_Destroy(key); if (!keylist || rc != ESIF_OK) { esif_ccb_free(keylist); return rc; } // Return keylist value and data type if (value->type == ESIF_DATA_AUTO) { value->type = ESIF_DATA_STRING; } if (value->buf_len == ESIF_DATA_ALLOCATE) { esif_ccb_free(value->buf_ptr); value->buf_ptr = esif_ccb_strdup(keylist); value->buf_len = data_len; value->data_len = data_len; } else if (value->buf_len < data_len) { rc = ESIF_E_NEED_LARGER_BUFFER; value->data_len = data_len; } else if (value->buf_ptr) { esif_ccb_strcpy(value->buf_ptr, keylist, value->buf_len); value->data_len = data_len; } esif_ccb_free(keylist); return rc; } // 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; UInt32 buf_len = 0; Bool buf_alloc = ESIF_FALSE; // File Redirect? if (keypair->flags & ESIF_SERVICE_CONFIG_FILELINK) { if (ReadFileIntoBuffer((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 } // Include Null Terminator if result is STRING if (value->buf_len == ESIF_DATA_ALLOCATE && (value->type == ESIF_DATA_STRING || (value->type == ESIF_DATA_AUTO && keypair->value.type == ESIF_DATA_STRING))) { data_len++; } buf_len = data_len; buf_alloc = ESIF_TRUE; } // 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->data_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 = esif_ccb_max(1, data_len); value->buf_ptr = esif_ccb_malloc(value->buf_len); if (!value->buf_ptr) { if (buf_alloc) { esif_ccb_free(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_GetFromSource(self, (esif_string)value->buf_ptr, data_len, offset) != ESIF_OK) { if (buf_alloc) { esif_ccb_free(buf_ptr); } return ESIF_E_NOT_FOUND; } // Unscramble Data? if (keypair->flags & ESIF_SERVICE_CONFIG_SCRAMBLE) { 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; } // Return flags if (rc == ESIF_OK) { if (flagsPtr != NULL) *flagsPtr = keypair->flags; } // Destroy Dynamically copied data, such as FILELINK contents if (buf_alloc) { esif_ccb_free(buf_ptr); } } // Write to Log DataVault_WriteLog(self, "GET", (esif_string)self->name, path, 0, value); return rc; }
/* 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; }