Beispiel #1
0
// Find Next path in nameSpace
eEsifError EsifConfigFindNext (
	EsifDataPtr nameSpace,
	EsifDataPtr path,
	EsifDataPtr value,
	UInt32 *context
	)
{
	eEsifError rc   = ESIF_E_NOT_FOUND;
	DataVaultPtr DB = 0;
	ASSERT(nameSpace && path && value && context);
	DB = DataBank_GetNameSpace(g_DataBankMgr, (StringPtr)(nameSpace->buf_ptr));
	if (DB) {
		UInt32 item = *context;
		if (item >= DB->cache->size) {
			return rc;
		}
		(*context)++;

		if (path->buf_len && path->buf_len < DB->cache->elements[item].value.data_len) {
			return ESIF_E_NEED_LARGER_BUFFER;
		}
		EsifData_Set(path, ESIF_DATA_STRING, esif_ccb_strdup(
						 (char*)DB->cache->elements[item].key.buf_ptr), DB->cache->elements[item].key.data_len, DB->cache->elements[item].key.data_len);
		return EsifConfigGet(nameSpace, path, value);
	}
	return rc;
}
Beispiel #2
0
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;
}
Beispiel #3
0
// 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;
}
Beispiel #4
0
/* 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;
}
Beispiel #5
0
// Find Next path in nameSpace
eEsifError EsifConfigFindNext(
	EsifDataPtr nameSpace,
	EsifDataPtr path,
	EsifDataPtr value,
	EsifConfigFindContextPtr context
	)
{
	eEsifError rc = ESIF_E_NOT_FOUND;
	DataVaultPtr DB = 0;

	ESIF_ASSERT(nameSpace && path && context);
	DB = DataBank_GetNameSpace(g_DataBankMgr, (StringPtr)(nameSpace->buf_ptr));
	if (DB) {
		UInt32 item = 0;

		esif_ccb_read_lock(&DB->lock);

		for (item = 0; item < DB->cache->size; item++) {
			if (*context == NULL || esif_ccb_stricmp(DB->cache->elements[item].key.buf_ptr, *context) > 0) {
				break;
			}
		}

		// Find next matching key
		while (item < DB->cache->size && EsifConfigKeyMatch(path, &DB->cache->elements[item].key) != ESIF_TRUE) {
			item++;
		}

		// Return matching item, if any
		if (item < DB->cache->size) {
			esif_ccb_free(*context);
			*context = esif_ccb_strdup(DB->cache->elements[item].key.buf_ptr);
			
			if (path->buf_len && path->buf_len < DB->cache->elements[item].key.data_len) {
				rc = ESIF_E_NEED_LARGER_BUFFER;
			}
			else {
				EsifData_Set(path, 
							 ESIF_DATA_STRING,
							 esif_ccb_strdup((char*)DB->cache->elements[item].key.buf_ptr),
							 DB->cache->elements[item].key.data_len,
							 DB->cache->elements[item].key.data_len);

				// If no value buffer for result, just return next matching key
				if (NULL == value)
					rc = ESIF_OK;
				else
					rc = EsifConfigGet(nameSpace, path, value);
			}
		}
		else if (*context != NULL) {
			rc = ESIF_E_ITERATION_DONE;
		}
		esif_ccb_read_unlock(&DB->lock);
	}

	if (rc != ESIF_OK) {
		EsifConfigFindClose(context);
	}
	return rc;
}
Beispiel #6
0
// 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;
}