summaryrefslogtreecommitdiffhomepage
path: root/src/vmount/ntapi_vms_cache.c
diff options
context:
space:
mode:
authormidipix <writeonce@midipix.org>2015-07-27 04:01:18 -0400
committermidipix <writeonce@midipix.org>2015-07-27 04:01:18 -0400
commitdd89bb8ad4fe184a34b5dbdda237e640fc82121b (patch)
tree5e80d2da35f5892f92be29f57982b2708e6bd99b /src/vmount/ntapi_vms_cache.c
parentdcdadc2702712fa750ed255ed1dfa354522797a0 (diff)
downloadntapi-dd89bb8ad4fe184a34b5dbdda237e640fc82121b.tar.bz2
ntapi-dd89bb8ad4fe184a34b5dbdda237e640fc82121b.tar.xz
entered advanced internal development stage.
Diffstat (limited to 'src/vmount/ntapi_vms_cache.c')
-rw-r--r--src/vmount/ntapi_vms_cache.c209
1 files changed, 209 insertions, 0 deletions
diff --git a/src/vmount/ntapi_vms_cache.c b/src/vmount/ntapi_vms_cache.c
new file mode 100644
index 0000000..97fe32f
--- /dev/null
+++ b/src/vmount/ntapi_vms_cache.c
@@ -0,0 +1,209 @@
+/********************************************************/
+/* ntapi: Native API core library */
+/* Copyright (C) 2013,2014,2015 Z. Gilboa */
+/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */
+/********************************************************/
+
+#include <psxtypes/psxtypes.h>
+#include <ntapi/nt_port.h>
+#include <ntapi/nt_vmount.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+
+
+typedef struct nt_vms_cache_interface {
+ nt_vms_system * vms_sys;
+ struct dalist_ex cache;
+ size_t alloc_size;
+ uintptr_t buffer[1];
+} nt_vms_cache_context;
+
+
+typedef struct _nt_vms_cache_record {
+ void * hfile;
+ uint32_t dev_name_hash;
+ nt_large_integer index_number;
+ intptr_t client_key;
+ intptr_t server_key;
+} nt_vms_cache_record;
+
+
+int32_t __stdcall __ntapi_vms_cache_free(
+ __in nt_vms_cache vms_cache)
+{
+ int32_t status;
+ void * region_addr;
+ size_t region_size;
+
+ /* validation */
+ if (!vms_cache)
+ return NT_STATUS_INVALID_PARAMETER;
+
+ /* free memory */
+ region_addr = vms_cache;
+ region_size = vms_cache->alloc_size;
+
+ status = __ntapi->zw_free_virtual_memory(
+ NT_CURRENT_PROCESS_HANDLE,
+ &region_addr,
+ &region_size,
+ NT_MEM_RELEASE);
+
+ return status;
+}
+
+/* vms optional cache functions */
+nt_vms_cache __stdcall __ntapi_vms_cache_alloc(
+ __in nt_vms_system * vms_sys,
+ __in uint32_t flags __reserved,
+ __in void * options __reserved,
+ __out int32_t * status __optional)
+{
+ int32_t _status;
+ void * buffer;
+ size_t buffer_size;
+ nt_vms_cache_context * vms_cache;
+
+ /* status */
+ if (!status) status = &_status;
+
+ /* validation */
+ if (!vms_sys) {
+ *status = NT_STATUS_INVALID_PARAMETER;
+ return (nt_vms_cache)0;
+ }
+
+ /* calculate size */
+ buffer_size = sizeof(nt_vms_cache_context);
+ buffer_size += vms_sys->vms_points_cap * (sizeof(nt_vms_cache_record) - sizeof(uintptr_t));
+
+ /* allocate buffer */
+ *status = __ntapi->zw_allocate_virtual_memory(
+ NT_CURRENT_PROCESS_HANDLE,
+ &buffer,
+ 0,
+ &buffer_size,
+ NT_MEM_COMMIT,
+ NT_PAGE_READWRITE);
+
+ if (*status) return (nt_vms_cache)0;
+
+ /* init vms cache */
+ vms_cache = (nt_vms_cache_context *)buffer;
+ vms_cache->vms_sys = vms_sys;
+ vms_cache->alloc_size = buffer_size;
+
+ /* init list */
+ *status = dalist_init_ex(
+ &vms_cache->cache,
+ sizeof(nt_vms_cache_record),
+ 0x1000,
+ __ntapi->zw_allocate_virtual_memory,
+ DALIST_MEMFN_NT_ALLOCATE_VIRTUAL_MEMORY);
+
+ if (*status != DALIST_OK) {
+ *status = NT_STATUS_UNSUCCESSFUL;
+ __ntapi_vms_cache_free(vms_cache);
+ return (nt_vms_cache)0;
+ }
+
+ /* set list buffer */
+ buffer_size -= (size_t)&(((nt_vms_cache_context *)0)->buffer);
+
+ *status = dalist_deposit_memory_block(
+ &vms_cache->cache,
+ &vms_cache->buffer,
+ buffer_size);
+
+ return vms_cache;
+}
+
+
+int32_t __stdcall __ntapi_vms_cache_record_append(
+ __in nt_vms_cache cache,
+ __in void * hfile,
+ __in uint32_t dev_name_hash,
+ __in nt_large_integer index_number,
+ __in intptr_t client_key,
+ __in intptr_t server_key)
+{
+ int32_t status;
+ struct dalist_node_ex * node;
+ nt_vms_cache_record * cache_record;
+
+ status = dalist_get_node_by_key(
+ &cache->cache,
+ &node,
+ (uintptr_t)hfile,
+ DALIST_NODE_TYPE_EXISTING,
+ (uintptr_t *)0);
+
+ if (status != DALIST_OK)
+ status = NT_STATUS_INTERNAL_ERROR;
+ else if (node)
+ status = NT_STATUS_OBJECTID_EXISTS;
+ else {
+ status = dalist_get_free_node(&cache->cache,(void **)&node);
+
+ if (status == DALIST_OK) {
+ cache_record = (nt_vms_cache_record *)&node->dblock;
+
+ __ntapi->tt_aligned_block_memset(
+ node,
+ 0,
+ (uintptr_t)&((struct dalist_node_ex *)0)->dblock + sizeof(*cache_record));
+
+ node->key = (uintptr_t)hfile;
+
+ cache_record->hfile = hfile;
+ cache_record->dev_name_hash = dev_name_hash;
+ cache_record->index_number.quad = index_number.quad;
+ cache_record->client_key = client_key;
+ cache_record->server_key = server_key;
+
+ status = dalist_insert_node_by_key(
+ &cache->cache,
+ node);
+
+ if (status != DALIST_OK)
+ dalist_deposit_free_node(
+ &cache->cache,
+ node);
+ }
+ }
+
+ return status;
+}
+
+
+int32_t __stdcall __ntapi_vms_cache_record_remove(
+ __in nt_vms_cache cache,
+ __in void * hfile,
+ __in uint32_t dev_name_hash,
+ __in nt_large_integer index_number)
+{
+ int32_t status;
+ struct dalist_node_ex * node;
+
+ status = dalist_get_node_by_key(
+ &cache->cache,
+ &node,
+ (uintptr_t)hfile,
+ DALIST_NODE_TYPE_EXISTING,
+ (uintptr_t *)0);
+
+ if (status != DALIST_OK)
+ status = NT_STATUS_INTERNAL_ERROR;
+ else if (node)
+ status = NT_STATUS_INVALID_PARAMETER;
+ else {
+ status = dalist_discard_node(
+ &cache->cache,
+ node);
+
+ if (status != DALIST_OK)
+ status = NT_STATUS_INTERNAL_ERROR;
+ }
+
+ return status;
+}