Ejemplo n.º 1
0
// Reads a key/value pair from the current location in the open DataVault stream
static eEsifError DataVault_ReadNextKeyValuePair(
	DataVaultPtr self,
	esif_flags_t *flagsPtr,
	EsifDataPtr keyPtr,
	EsifDataPtr valuePtr
	)
{
	eEsifError rc = ESIF_OK;
	IOStreamPtr vault = NULL;
	size_t bytes = 0;

	ESIF_ASSERT(self != NULL);
	ESIF_ASSERT(flagsPtr != NULL);
	ESIF_ASSERT(keyPtr != NULL);
	ESIF_ASSERT(valuePtr != NULL);

	vault = self->stream;

	// Read Flags
	if ((bytes = IOStream_Read(vault, flagsPtr, sizeof(*flagsPtr))) != sizeof(*flagsPtr)) {
		// Check if we are done
		if (bytes != 0) {
			rc = ESIF_E_IO_ERROR;
		}
		rc = ESIF_E_ITERATION_DONE;
		goto exit;
	}

	// Read key length
	keyPtr->type = ESIF_DATA_STRING;
	if (IOStream_Read(vault, &keyPtr->data_len, sizeof(keyPtr->data_len)) < sizeof(keyPtr->data_len)) {
		rc = ESIF_E_IO_ERROR;
		goto exit;
	}
	if (keyPtr->data_len > MAX_DV_DATALEN) {
		rc = ESIF_E_PARAMETER_IS_OUT_OF_BOUNDS;
		goto exit;
	}

	// Use Memory Pointers for Static DataVaults, otherwise allocate memory
	if ((IOStream_GetType(vault) == StreamMemory) && (self->flags & ESIF_SERVICE_CONFIG_STATIC)) {
		keyPtr->buf_len = 0;
		keyPtr->buf_ptr = IOStream_GetMemoryBuffer(vault) + IOStream_GetOffset(vault);
		if (IOStream_Seek(vault, keyPtr->data_len, SEEK_CUR) != EOK) {
			rc = ESIF_E_IO_ERROR;
			goto exit;
		}
		*flagsPtr &= ~ESIF_SERVICE_CONFIG_NOCACHE;	// ignore for Static DataVaults
	}
	else {
		keyPtr->buf_len = esif_ccb_max(1, keyPtr->data_len);
		keyPtr->buf_ptr = esif_ccb_malloc(keyPtr->buf_len);
		if (!keyPtr->buf_ptr) {
			rc = ESIF_E_NO_MEMORY;
			goto exit;
		}
		if (IOStream_Read(vault, keyPtr->buf_ptr, keyPtr->data_len) != keyPtr->data_len) {
			rc = ESIF_E_IO_ERROR;
			goto exit;
		}
		else if (keyPtr->data_len) {
			((esif_string)(keyPtr->buf_ptr))[keyPtr->data_len - 1] = 0;
		}
	}

	// Read Value
	if (IOStream_Read(vault, &valuePtr->type, sizeof(valuePtr->type)) != sizeof(valuePtr->type)) {
		rc = ESIF_E_IO_ERROR;
		goto exit;
	}
	if (IOStream_Read(vault, &valuePtr->data_len, sizeof(valuePtr->data_len)) != sizeof(valuePtr->data_len)) {
		rc = ESIF_E_IO_ERROR;
		goto exit;
	}
	if  (valuePtr->data_len > MAX_DV_DATALEN) {
		rc = ESIF_E_PARAMETER_IS_OUT_OF_BOUNDS;
		goto exit;
	}

	// If NOCACHE mode, use buf_ptr to store the file offset of the data and skip the file
	if (*flagsPtr & ESIF_SERVICE_CONFIG_NOCACHE) {
		size_t offset = IOStream_GetOffset(vault);
		if (IOStream_Seek(vault, valuePtr->data_len, SEEK_CUR) != EOK) {
			rc = ESIF_E_IO_ERROR;
			goto exit;
		}
		valuePtr->buf_ptr = (void*)offset; // For non-cached...we save the offset in the file as the buffer pointer. Really???
		valuePtr->buf_len = 0;	// buf_len == 0 so we don't release buffer as not allocated; data_len = original length
	} 
	else {
		// Use static pointer for static data vaults (unless scrambled), otherwise make a dynamic copy
		if ((IOStream_GetType(vault) == StreamMemory) && (self->flags & ESIF_SERVICE_CONFIG_STATIC) && !(*flagsPtr & ESIF_SERVICE_CONFIG_SCRAMBLE)) {
			valuePtr->buf_len = 0;	// static
			valuePtr->buf_ptr = IOStream_GetMemoryBuffer(vault) + IOStream_GetOffset(vault);
			if (valuePtr->buf_ptr == NULL || IOStream_Seek(vault, valuePtr->data_len, SEEK_CUR) != EOK) {
				rc = ESIF_E_IO_ERROR;
				goto exit;
			}
		} 
		else {
			valuePtr->buf_len = esif_ccb_max(1, valuePtr->data_len); // dynamic
			valuePtr->buf_ptr = esif_ccb_malloc(valuePtr->buf_len);
			if (valuePtr->buf_ptr == NULL) {
				rc = ESIF_E_NO_MEMORY;
				goto exit;
			}
			else if (IOStream_Read(vault, valuePtr->buf_ptr, valuePtr->data_len) != valuePtr->data_len) {
				rc = ESIF_E_IO_ERROR;
				goto exit;
			}
		}
			
		//  Unscramble Data?
		if (*flagsPtr & ESIF_SERVICE_CONFIG_SCRAMBLE) {
			UInt32 byte;
			for (byte = 0; byte < valuePtr->data_len; byte++)
				((UInt8*)(valuePtr->buf_ptr))[byte] = ~((UInt8*)(valuePtr->buf_ptr))[byte];
		}
	}
exit:
	return rc;
}
Ejemplo n.º 2
0
/* 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;
}
Ejemplo n.º 3
0
// Read DataVault from Disk
eEsifError DataVault_ReadVault (DataVaultPtr self)
{
	eEsifError rc = ESIF_E_UNSPECIFIED;	// TODO
	int vrc = EPERM;
	DataVaultHeader header;
	UInt32 min_version;
	UInt32 max_version;
	esif_flags_t item_flags;
	IOStreamPtr vault = self->stream;

	// TODO: Locking

	// Open File or Memory Block
	if ((vrc = IOStream_Open(vault)) != 0) {
		if (vrc == ENOENT) {
			rc = ESIF_E_NOT_FOUND;
		}
		return rc;
	}

	// Read and Verify File Header
	// The DataVault's Major.Minor Version must be <= the App's Major.Minor Version and at least Major.0
	memset(&header, 0, sizeof(header));
	IOStream_Read(vault, &header, 4);	// E51F#### where #### is header size, including this
	IOStream_Read(vault, ((UInt8*)&header) + 4, esif_ccb_min(header.headersize, sizeof(header)) - 4);
	min_version = ESIFDV_VERSION(ESIFDV_MAJOR_VERSION, 0, 0);
	max_version = ESIFDV_VERSION(ESIFDV_MAJOR_VERSION, ESIFDV_MINOR_VERSION, ESIFDV_MAX_REVISION);
	if (memcmp(header.signature, ESIFDV_SIGNATURE, sizeof(header.signature)) != 0 || header.version > max_version || header.version < min_version) {
		IOStream_Close(vault);
		return ESIF_E_NOT_SUPPORTED;
	}
	if (header.headersize > sizeof(header)) {
		IOStream_Seek(vault, header.headersize - sizeof(header), SEEK_CUR);
	}
	self->flags = header.flags;
	if (IOStream_GetType(vault) == StreamMemory) {
		self->flags |= ESIF_SERVICE_CONFIG_STATIC;
	}
	rc = ESIF_OK;

	// Read Data and add to DataVault
	while (IOStream_Read(vault, &item_flags, sizeof(item_flags)) == sizeof(item_flags)) {
		EsifData key;
		EsifData value;

		// Read Key
		EsifData_ctor(&key);
		EsifData_ctor(&value);
		key.type = ESIF_DATA_STRING;
		IOStream_Read(vault, &key.data_len, sizeof(key.data_len));
		if (key.data_len > MAX_DV_DATALEN) {
			rc = ESIF_E_PARAMETER_IS_OUT_OF_BOUNDS;
			break;
		}
		switch (IOStream_GetType(vault)) {
		case StreamMemory:
			key.buf_len = 0;
			key.buf_ptr = IOStream_GetMemoryBuffer(vault) + IOStream_GetOffset(vault);
			IOStream_Seek(vault, key.data_len, SEEK_CUR);
			item_flags &= ~ESIF_SERVICE_CONFIG_NOCACHE;	// ignore for Memory Vaults
			break;

		case StreamFile:
		default:
			key.buf_len = key.data_len;
			key.buf_ptr = esif_ccb_malloc(key.buf_len);
			if (!key.buf_ptr) {
				rc = ESIF_E_NO_MEMORY;
				break;
			}
			IOStream_Read(vault, key.buf_ptr, key.data_len);
			((esif_string)(key.buf_ptr))[key.data_len - 1] = 0;
			break;
		}
		if (rc != ESIF_OK) {
			EsifData_dtor(&key);
			break;
		}

		// Read Value
		IOStream_Read(vault, &value.type, sizeof(value.type));
		IOStream_Read(vault, &value.data_len, sizeof(value.data_len));
		if (value.data_len > MAX_DV_DATALEN) {
			EsifData_dtor(&key);
			break;
		}

		// If NOCACHE mode, use buf_ptr to store the file offset of the data and skip the file
		if (item_flags & ESIF_SERVICE_CONFIG_NOCACHE) {
			size_t offset = IOStream_GetOffset(vault);
			IOStream_Seek(vault, value.data_len, SEEK_CUR);
			value.buf_ptr = (void*)offset;
			value.buf_len = 0;	// data_len = original length
		} else {
			// Use static pointer for static data vaults (unless encrypted), otherwise make a dynamic copy
			if (IOStream_GetType(vault) == StreamMemory && !(item_flags & ESIF_SERVICE_CONFIG_ENCRYPT)) {
				value.buf_len = 0;	// static
				value.buf_ptr = IOStream_GetMemoryBuffer(vault) + IOStream_GetOffset(vault);
				IOStream_Seek(vault, value.data_len, SEEK_CUR);
			} else {
				value.buf_len = value.data_len;	// dynamic
				value.buf_ptr = esif_ccb_malloc(value.buf_len);
				if (!value.buf_ptr) {
					EsifData_dtor(&key);
					rc = ESIF_E_NO_MEMORY;
					break;
				}
				IOStream_Read(vault, value.buf_ptr, value.data_len);
			}
			// Decrypt Encrypted Data?
			if (item_flags & ESIF_SERVICE_CONFIG_ENCRYPT) {
				UInt32 byte;
				for (byte = 0; byte < value.data_len; byte++)
					((UInt8*)(value.buf_ptr))[byte] = ~((UInt8*)(value.buf_ptr))[byte];
			}
		}
		// Add value (including allocated buf_ptr) to cache
		DataCache_SetValue(self->cache, (esif_string)key.buf_ptr, value, item_flags);
		value.buf_ptr = 0;
		item_flags    = 0;
		EsifData_dtor(&key);
		EsifData_dtor(&value);
	}
	IOStream_Close(vault);
	return rc;
}