Commit c122260b authored by Alexandre Julliard's avatar Alexandre Julliard

ntdll: Implemented NtLockVirtualMemory and NtUnlockVirtualMemory.

parent 5a1ad74a
......@@ -1802,12 +1802,32 @@ NTSTATUS WINAPI NtQueryVirtualMemory( HANDLE process, LPCVOID addr,
*/
NTSTATUS WINAPI NtLockVirtualMemory( HANDLE process, PVOID *addr, SIZE_T *size, ULONG unknown )
{
if (!is_current_process( process ))
NTSTATUS status = STATUS_SUCCESS;
if (process != NtCurrentProcess())
{
ERR("Unsupported on other process\n");
return STATUS_ACCESS_DENIED;
apc_call_t call;
apc_result_t result;
call.virtual_lock.type = APC_VIRTUAL_LOCK;
call.virtual_lock.addr = *addr;
call.virtual_lock.size = *size;
status = NTDLL_queue_process_apc( process, &call, &result );
if (status != STATUS_SUCCESS) return status;
if (result.virtual_lock.status == STATUS_SUCCESS)
{
*addr = result.virtual_lock.addr;
*size = result.virtual_lock.size;
}
return STATUS_SUCCESS;
return result.virtual_lock.status;
}
*size = ROUND_SIZE( *addr, *size );
*addr = ROUND_ADDR( *addr, page_mask );
if (mlock( *addr, *size )) status = STATUS_ACCESS_DENIED;
return status;
}
......@@ -1817,12 +1837,32 @@ NTSTATUS WINAPI NtLockVirtualMemory( HANDLE process, PVOID *addr, SIZE_T *size,
*/
NTSTATUS WINAPI NtUnlockVirtualMemory( HANDLE process, PVOID *addr, SIZE_T *size, ULONG unknown )
{
if (!is_current_process( process ))
NTSTATUS status = STATUS_SUCCESS;
if (process != NtCurrentProcess())
{
ERR("Unsupported on other process\n");
return STATUS_ACCESS_DENIED;
apc_call_t call;
apc_result_t result;
call.virtual_unlock.type = APC_VIRTUAL_UNLOCK;
call.virtual_unlock.addr = *addr;
call.virtual_unlock.size = *size;
status = NTDLL_queue_process_apc( process, &call, &result );
if (status != STATUS_SUCCESS) return status;
if (result.virtual_unlock.status == STATUS_SUCCESS)
{
*addr = result.virtual_unlock.addr;
*size = result.virtual_unlock.size;
}
return STATUS_SUCCESS;
return result.virtual_unlock.status;
}
*size = ROUND_SIZE( *addr, *size );
*addr = ROUND_ADDR( *addr, page_mask );
if (munlock( *addr, *size )) status = STATUS_ACCESS_DENIED;
return status;
}
......
......@@ -219,7 +219,9 @@ enum apc_type
APC_VIRTUAL_FREE,
APC_VIRTUAL_QUERY,
APC_VIRTUAL_PROTECT,
APC_VIRTUAL_FLUSH
APC_VIRTUAL_FLUSH,
APC_VIRTUAL_LOCK,
APC_VIRTUAL_UNLOCK
};
typedef union
......@@ -280,6 +282,18 @@ typedef union
const void *addr;
unsigned long size;
} virtual_flush;
struct
{
enum apc_type type;
void *addr;
unsigned long size;
} virtual_lock;
struct
{
enum apc_type type;
void *addr;
unsigned long size;
} virtual_unlock;
} apc_call_t;
typedef union
......@@ -326,6 +340,20 @@ typedef union
const void *addr;
unsigned long size;
} virtual_flush;
struct
{
enum apc_type type;
unsigned int status;
void *addr;
unsigned long size;
} virtual_lock;
struct
{
enum apc_type type;
unsigned int status;
void *addr;
unsigned long size;
} virtual_unlock;
} apc_result_t;
......@@ -4547,6 +4575,6 @@ union generic_reply
struct query_symlink_reply query_symlink_reply;
};
#define SERVER_PROTOCOL_VERSION 269
#define SERVER_PROTOCOL_VERSION 270
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
......@@ -235,7 +235,9 @@ enum apc_type
APC_VIRTUAL_FREE,
APC_VIRTUAL_QUERY,
APC_VIRTUAL_PROTECT,
APC_VIRTUAL_FLUSH
APC_VIRTUAL_FLUSH,
APC_VIRTUAL_LOCK,
APC_VIRTUAL_UNLOCK
};
typedef union
......@@ -296,6 +298,18 @@ typedef union
const void *addr; /* requested address */
unsigned long size; /* requested address */
} virtual_flush;
struct
{
enum apc_type type; /* APC_VIRTUAL_LOCK */
void *addr; /* requested address */
unsigned long size; /* requested address */
} virtual_lock;
struct
{
enum apc_type type; /* APC_VIRTUAL_UNLOCK */
void *addr; /* requested address */
unsigned long size; /* requested address */
} virtual_unlock;
} apc_call_t;
typedef union
......@@ -342,6 +356,20 @@ typedef union
const void *addr; /* resulting address */
unsigned long size; /* resulting size */
} virtual_flush;
struct
{
enum apc_type type; /* APC_VIRTUAL_LOCK */
unsigned int status; /* status returned by call */
void *addr; /* resulting address */
unsigned long size; /* resulting size */
} virtual_lock;
struct
{
enum apc_type type; /* APC_VIRTUAL_UNLOCK */
unsigned int status; /* status returned by call */
void *addr; /* resulting address */
unsigned long size; /* resulting size */
} virtual_unlock;
} apc_result_t;
/****************************************************************/
......
......@@ -1159,6 +1159,8 @@ DECL_HANDLER(queue_apc)
case APC_VIRTUAL_QUERY:
case APC_VIRTUAL_PROTECT:
case APC_VIRTUAL_FLUSH:
case APC_VIRTUAL_LOCK:
case APC_VIRTUAL_UNLOCK:
access = (apc->call.type == APC_VIRTUAL_QUERY) ? PROCESS_QUERY_INFORMATION : PROCESS_VM_OPERATION;
if ((process = get_process_from_handle( req->process, access )))
{
......
......@@ -142,6 +142,14 @@ static void dump_apc_call( const apc_call_t *call )
fprintf( stderr, "APC_VIRTUAL_FLUSH,addr=%p,size=%lu",
call->virtual_flush.addr, call->virtual_flush.size );
break;
case APC_VIRTUAL_LOCK:
fprintf( stderr, "APC_VIRTUAL_LOCK,addr=%p,size=%lu",
call->virtual_lock.addr, call->virtual_lock.size );
break;
case APC_VIRTUAL_UNLOCK:
fprintf( stderr, "APC_VIRTUAL_UNLOCK,addr=%p,size=%lu",
call->virtual_unlock.addr, call->virtual_unlock.size );
break;
default:
fprintf( stderr, "type=%u", call->type );
break;
......@@ -185,6 +193,16 @@ static void dump_apc_result( const apc_result_t *result )
get_status_name( result->virtual_flush.status ),
result->virtual_flush.addr, result->virtual_flush.size );
break;
case APC_VIRTUAL_LOCK:
fprintf( stderr, "APC_VIRTUAL_LOCK,status=%s,addr=%p,size=%lu",
get_status_name( result->virtual_lock.status ),
result->virtual_lock.addr, result->virtual_lock.size );
break;
case APC_VIRTUAL_UNLOCK:
fprintf( stderr, "APC_VIRTUAL_UNLOCK,status=%s,addr=%p,size=%lu",
get_status_name( result->virtual_unlock.status ),
result->virtual_unlock.addr, result->virtual_unlock.size );
break;
default:
fprintf( stderr, "type=%u", result->type );
break;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment