| |
| |
| |
| |
| |
| |
| #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; |
| |
| |
| if (!vms_cache) |
| return NT_STATUS_INVALID_PARAMETER; |
| |
| |
| region_addr = vms_cache; |
| region_size = vms_cache->alloc_size; |
| |
| status = __ntapi->zw_free_virtual_memory( |
| NT_CURRENT_PROCESS_HANDLE, |
| ®ion_addr, |
| ®ion_size, |
| NT_MEM_RELEASE); |
| |
| return status; |
| } |
| |
| |
| 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; |
| |
| |
| (void)flags; |
| (void)options; |
| |
| |
| if (!status) status = &_status; |
| |
| |
| if (!vms_sys) { |
| *status = NT_STATUS_INVALID_PARAMETER; |
| return (nt_vms_cache)0; |
| } |
| |
| |
| buffer_size = sizeof(nt_vms_cache_context); |
| buffer_size += vms_sys->vms_points_cap * (sizeof(nt_vms_cache_record) - sizeof(uintptr_t)); |
| |
| |
| *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; |
| |
| |
| vms_cache = (nt_vms_cache_context *)buffer; |
| vms_cache->vms_sys = vms_sys; |
| vms_cache->alloc_size = buffer_size; |
| |
| |
| *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; |
| } |
| |
| |
| 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; |
| |
| (void)dev_name_hash; |
| (void)index_number; |
| |
| 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; |
| } |