Exemplo n.º 1
0
// backwards compatibility
eEsifError EsifConfigSet(
	EsifDataPtr nameSpace,
	EsifDataPtr path,
	esif_flags_t flags,
	EsifDataPtr value
	)
{
	eEsifError rc = ESIF_OK;

	// Get the NameSpace or create it if it does not exist
	DataVaultPtr DB = DataBank_GetNameSpace(g_DataBankMgr, (StringPtr)(nameSpace->buf_ptr));
	if (!DB) {
		struct esif_ccb_file dv_file = {0};
		DB = DataBank_OpenNameSpace(g_DataBankMgr, (StringPtr)nameSpace->buf_ptr);
		if (!DB) {
			return ESIF_E_NOT_FOUND;
		}

		esif_build_path(dv_file.filename, sizeof(dv_file.filename), ESIF_PATHTYPE_DV, DB->name, ESIFDV_FILEEXT);
		IOStream_SetFile(DB->stream, dv_file.filename, "rb");
		rc = DataVault_ReadVault(DB);
		if (rc == ESIF_E_NOT_FOUND) {
			rc = ESIF_OK;
		}
	}
	if (rc == ESIF_OK) {
		esif_ccb_write_lock(&DB->lock);
		rc = DataVault_SetValue(DB, path, value, flags);
		esif_ccb_write_unlock(&DB->lock);
	}
	return rc;
}
Exemplo n.º 2
0
// Automatically Load all Static DataVaults and *.dv files in the current folder into the DataBank
eEsifError DataBank_LoadDataVaults (DataBankPtr self)
{
	eEsifError rc = ESIF_OK;
	esif_ccb_file_find_handle find_handle = INVALID_HANDLE_VALUE;
	char file_path[MAX_PATH] = {0};
	char file_pattern[MAX_PATH] = {0};
	struct esif_ccb_file *ffd_ptr;
	UInt32 idx;

	ASSERT(self);

	// Import all Static DataVaults into ReadOnly DataVaults
	for (idx = 0; g_StaticDataVaults[idx].name; idx++) {
		DataVaultPtr DB = DataBank_OpenNameSpace(self, g_StaticDataVaults[idx].name);
		if (DB) {
			IOStream_SetMemory(DB->stream, g_StaticDataVaults[idx].buffer, g_StaticDataVaults[idx].buf_len);
			DB->flags |= (ESIF_SERVICE_CONFIG_READONLY | ESIF_SERVICE_CONFIG_NOCACHE);
			DataVault_ReadVault(DB);
		}
	}

	// Create DataVault Directory if it doesn't exit
	esif_build_path(file_path, sizeof(file_path), ESIF_PATHTYPE_DV, NULL, NULL);
	esif_ccb_makepath(file_path);

	// Import all matching *.dv files into ReadWrite DataVaults
	esif_ccb_sprintf(MAX_PATH, file_pattern, "*%s", ESIFDV_FILEEXT);
	ffd_ptr   = (struct esif_ccb_file*)esif_ccb_malloc(sizeof(*ffd_ptr));
	if (NULL == ffd_ptr) {
		rc = ESIF_E_NO_MEMORY;
	}

	if (rc == ESIF_OK) {
		find_handle = esif_ccb_file_enum_first(file_path, file_pattern, ffd_ptr);
	}
	if (INVALID_HANDLE_VALUE != find_handle) {
		do {
			struct esif_ccb_file dv_file = {0};
			DataVaultPtr DB = 0;

			// Read DataVault File, unless it's already been loaded as a Static DataVault
			if (esif_ccb_strlen(ffd_ptr->filename, MAX_PATH) > sizeof(ESIFDV_FILEEXT)) {
				ffd_ptr->filename[esif_ccb_strlen(ffd_ptr->filename, MAX_PATH) - (sizeof(ESIFDV_FILEEXT) - 1)] = 0;	// Truncate ".dv" extension
				if (DataBank_GetNameSpace(self, ffd_ptr->filename) == NULL) {
					DB = DataBank_OpenNameSpace(self, ffd_ptr->filename);
					if (DB) {
						esif_build_path(dv_file.filename, sizeof(dv_file.filename), ESIF_PATHTYPE_DV, DB->name, ESIFDV_FILEEXT);
						IOStream_SetFile(DB->stream, dv_file.filename, "rb");
						DataVault_ReadVault(DB);
					}
				}
			}
		} while (esif_ccb_file_enum_next(find_handle, file_pattern, ffd_ptr));
		esif_ccb_file_enum_close(find_handle);
	}
	esif_ccb_free(ffd_ptr);
	return rc;
}
Exemplo n.º 3
0
// Load an External File into a specified memory buffer
static eEsifError ReadFileIntoBuffer(
	esif_string filename,
	void **buffer,
	UInt32 *buf_size
	)
{
	eEsifError rc    = ESIF_OK;
	IOStreamPtr file = IOStream_Create();
	BytePtr bufPtr = NULL;
	size_t size = 0;
	size_t bytesRead = 0;

	if (IOStream_SetFile(file, filename, "rb") != EOK) {
		rc = ESIF_E_IO_ERROR;
		goto exit;
	}

	size = IOStream_GetSize(file);

	bufPtr = (BytePtr) esif_ccb_malloc(size + 1);
	if (NULL == bufPtr) {
		rc = ESIF_E_NO_MEMORY;
		goto exit;
	}

	if (IOStream_Open(file) != 0) {
		rc = ESIF_E_IO_ERROR;
		goto exit;
	}

	bytesRead = IOStream_ReadAt(file, bufPtr, size, 0);
	if (bytesRead != size) {
		rc = ESIF_E_IO_ERROR;
		goto exit;
	}
	bufPtr[size] = 0;

	*buffer = bufPtr;
	*buf_size = (UInt32)size;
exit:
	IOStream_Destroy(file);
	if (rc != ESIF_OK) {
		esif_ccb_free(bufPtr);
	}
	return rc;
}
Exemplo n.º 4
0
// 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;
}
Exemplo n.º 5
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;
}
Exemplo n.º 6
0
// Write DataVault to Disk
eEsifError DataVault_WriteVault (DataVaultPtr self)
{
	eEsifError rc = ESIF_E_NOT_FOUND;
	DataVaultHeader header;
	struct esif_ccb_file dv_file    = {0};
	struct esif_ccb_file dv_filebak = {0};
	IOStreamPtr vault    = 0;
	IOStreamPtr vaultBak = 0;
	u32 idx;

	if (FLAGS_TEST(self->flags, ESIF_SERVICE_CONFIG_STATIC | ESIF_SERVICE_CONFIG_READONLY)) {
		return ESIF_E_READONLY;
	}

	// TODO: Locking
	vault = IOStream_Create();
	if (!vault) {
		return ESIF_E_NO_MEMORY;
	}

	// If any rows contain NOCACHE PERSIST values, we need to make a copy the original DataVault while creating the new one
	// esif_ccb_sprintf(MAX_PATH, dv_file.filename, "%s%s", esif_build_path(dv_file.filename, MAX_PATH, NULL, self->name), ESIFDV_FILEEXT);
	esif_ccb_sprintf(MAX_PATH, dv_file.filename, "%s%s%s", ESIFDV_DIR, self->name, ESIFDV_FILEEXT);

	for (idx = 0; idx < self->cache->size; idx++)
		if (FLAGS_TESTALL(self->cache->elements[idx].flags, ESIF_SERVICE_CONFIG_NOCACHE | ESIF_SERVICE_CONFIG_PERSIST) &&
			self->cache->elements[idx].value.buf_len == 0) {
			struct stat filebak_stat = {0};
            esif_ccb_sprintf(MAX_PATH, dv_filebak.filename, "%s%s%s", ESIFDV_DIR, self->name, ESIFDV_BAKFILEEXT);

			// Delete BAK file if it exists
			if (esif_ccb_stat(dv_filebak.filename, &filebak_stat) == 0) {
				esif_ccb_unlink(dv_filebak.filename);
			}
			if (esif_ccb_rename(dv_file.filename, dv_filebak.filename) == 0) {
				if ((vaultBak = IOStream_Create()) == NULL) {
					rc = ESIF_E_NO_MEMORY;
				}
				if (!vaultBak || IOStream_OpenFile(vaultBak, dv_filebak.filename, "rb") != 0) {
					IOStream_Destroy(vault);
					IOStream_Destroy(vaultBak);
					return rc;
				}
			}
			break;
		}

	// Create DataVault, Overwrite if necessary
	IOStream_SetFile(vault, self->stream->file.name, "wb");
	if (IOStream_Open(vault) != 0) {
		if (vaultBak) {
			IOStream_Destroy(vaultBak);
			esif_ccb_unlink(dv_filebak.filename);
		}
		IOStream_Destroy(vault);
		return rc;
	}

	// Create File Header
	memset(&header, 0, sizeof(header));
	esif_ccb_memcpy(&header.signature, ESIFDV_SIGNATURE, sizeof(header.signature));
	header.headersize = sizeof(header);
	header.version    = ESIFDV_VERSION(ESIFDV_MAJOR_VERSION, ESIFDV_MINOR_VERSION, ESIFDV_REVISION);
	header.flags = 0;	// TODO: get from self->flags

	// Write File Header
	IOStream_Seek(vault, 0, SEEK_SET);
	IOStream_Write(vault, &header, sizeof(header));
	rc = ESIF_OK;

	// Write All Persisted Rows from Sorted List to DataVault
	for (idx = 0; idx < self->cache->size; idx++) {
		DataCacheEntryPtr keypair = &self->cache->elements[idx];
		if (keypair->flags & ESIF_SERVICE_CONFIG_PERSIST) {
			UInt8 *buffer     = 0;
			UInt32 buffer_len = 0;
			UInt32 byte = 0;

			IOStream_Write(vault, &keypair->flags, sizeof(keypair->flags));
			IOStream_Write(vault, &keypair->key.data_len, sizeof(keypair->key.data_len));
			IOStream_Write(vault, keypair->key.buf_ptr, keypair->key.data_len);

			IOStream_Write(vault, &keypair->value.type, sizeof(keypair->value.type));
			IOStream_Write(vault, &keypair->value.data_len, sizeof(keypair->value.data_len));

			// Read NOCACHE Entries from Backup file
			if (keypair->flags & ESIF_SERVICE_CONFIG_NOCACHE) {
				size_t offset = IOStream_GetOffset(vault);

				// Read Block from BAK file
				if (keypair->value.buf_len == 0) {
					size_t bakoffset = (size_t)keypair->value.buf_ptr;
					buffer     = (UInt8*)esif_ccb_malloc(keypair->value.data_len);
					buffer_len = keypair->value.data_len;
					if (!buffer) {
						rc = ESIF_E_NO_MEMORY;
						break;
					}
					if (IOStream_Seek(vaultBak, bakoffset, SEEK_SET) != 0 || IOStream_Read(vaultBak, buffer, buffer_len) != buffer_len) {
						esif_ccb_free(buffer);
						rc = ESIF_E_UNSPECIFIED;// TODO: ESIF_E_IOERROR;
						break;
					}
					keypair->value.buf_ptr = (void*)offset;
				}
				// Convert internal storage to NOCACHE
				else {
					buffer     = (UInt8*)keypair->value.buf_ptr;
					buffer_len = keypair->value.data_len;
					keypair->value.buf_ptr = (void*)offset;
					keypair->value.buf_len = 0;
				}
			}

			// Encrypt Data?
			if (keypair->flags & ESIF_SERVICE_CONFIG_ENCRYPT) {
				if (!buffer) {
					buffer     = (UInt8*)esif_ccb_malloc(keypair->value.data_len);
					buffer_len = keypair->value.data_len;
					if (!buffer) {
						rc = ESIF_E_NO_MEMORY;
						break;
					}
				}
				for (byte = 0; byte < keypair->value.data_len; byte++)
					buffer[byte] = ~((UInt8*)(keypair->value.buf_ptr))[byte];
			}

			if (buffer) {
				IOStream_Write(vault, buffer, buffer_len);
				esif_ccb_free(buffer);
			} else {
				IOStream_Write(vault, keypair->value.buf_ptr, keypair->value.data_len);
			}
		}
	}

	// Rollback on Error
	if (rc != ESIF_OK) {
		IOStream_Destroy(vaultBak);
		IOStream_Destroy(vault);
		esif_ccb_unlink(dv_file.filename);
		IGNORE_RESULT(esif_ccb_rename(dv_filebak.filename, dv_file.filename));
		return rc;
	}
	// Remove BAK file and Commit
	if (vaultBak) {
		IOStream_Close(vaultBak);
		esif_ccb_unlink(dv_filebak.filename);
		IOStream_Destroy(vaultBak);
	}
	IOStream_Close(vault);
	IOStream_Destroy(vault);
	return rc;
}
Exemplo n.º 7
0
// Automatically Load all Static DataVaults and *.dv files in the current folder into the DataBank
eEsifError DataBank_LoadDataVaults (DataBankPtr self)
{
	eEsifError rc = ESIF_OK;
	esif_ccb_file_find_handle find_handle;
	esif_string file_path = 0;
	char file_pattern[MAX_PATH];
	char file_path_buf[MAX_PATH] = {0};
	struct esif_ccb_file *ffd_ptr;
	UInt32 idx;

	ASSERT(self);
	esif_ccb_lock_init(&self->lock);

	// TODO: Locking

	// Import all Static DataVaults into ReadOnly DataVaults
	for (idx = 0; g_StaticDataVaults[idx].name; idx++) {
		DataVaultPtr DB = DataBank_OpenNameSpace(self, g_StaticDataVaults[idx].name);
		if (DB) {
			IOStream_SetMemory(DB->stream, g_StaticDataVaults[idx].buffer, g_StaticDataVaults[idx].buf_len);
			DB->flags |= (ESIF_SERVICE_CONFIG_READONLY | ESIF_SERVICE_CONFIG_NOCACHE);
			DataVault_ReadVault(DB);
		}
	}

	// Create ESIFDV_DIR if it doesn't exit (only 1 level deep for now)
	esif_ccb_makepath(ESIFDV_DIR);

	// Import all matching *.dv files into ReadWrite DataVaults
	esif_ccb_strcpy(file_path_buf, ESIFDV_DIR, sizeof(file_path_buf));
	file_path = file_path_buf;
	esif_ccb_sprintf(MAX_PATH, file_pattern, "*%s", ESIFDV_FILEEXT);
	ffd_ptr   = (struct esif_ccb_file*)esif_ccb_malloc(sizeof(*ffd_ptr));
	if (NULL == ffd_ptr) {
		return ESIF_E_NO_MEMORY;
	}

	find_handle = esif_ccb_file_enum_first(file_path, file_pattern, ffd_ptr);
	if (INVALID_HANDLE_VALUE == find_handle) {
		rc = ESIF_OK;	// No Persisted DataVaults found
	} else {
		do {
			struct esif_ccb_file dv_file = {0};
			DataVaultPtr DB = 0;

			// Read DataVault File, unless it's already been loaded as a Static DataVault
			if (esif_ccb_strlen(ffd_ptr->filename, MAX_PATH) > sizeof(ESIFDV_FILEEXT)) {
				ffd_ptr->filename[esif_ccb_strlen(ffd_ptr->filename, MAX_PATH) - (sizeof(ESIFDV_FILEEXT) - 1)] = 0;	// Truncate ".dv" extension
				if (DataBank_GetNameSpace(self, ffd_ptr->filename) == NULL) {
					DB = DataBank_OpenNameSpace(self, ffd_ptr->filename);
					if (DB) {
						esif_ccb_sprintf(MAX_PATH, dv_file.filename, "%s%s%s", file_path, DB->name, ESIFDV_FILEEXT);
						IOStream_SetFile(DB->stream, dv_file.filename, "rb");
						DataVault_ReadVault(DB);
					}
				}
			}
		} while (esif_ccb_file_enum_next(find_handle, file_pattern, ffd_ptr));
		esif_ccb_file_enum_close(find_handle);
	}
	esif_ccb_free(ffd_ptr);
	return rc;
}