Alexandre Julliard : ntdll:
Implemented NtLockVirtualMemory and NtUnlockVirtualMemory.
Alexandre Julliard
julliard at wine.codeweavers.com
Tue Jan 16 05:22:17 CST 2007
Module: wine
Branch: master
Commit: c122260b9d2f60f78fac610775d3bd767e38680b
URL: http://source.winehq.org/git/wine.git/?a=commit;h=c122260b9d2f60f78fac610775d3bd767e38680b
Author: Alexandre Julliard <julliard at winehq.org>
Date: Tue Jan 16 09:50:08 2007 +0100
ntdll: Implemented NtLockVirtualMemory and NtUnlockVirtualMemory.
---
dlls/ntdll/virtual.c | 56 ++++++++++++++++++++++++++++++++++-----
include/wine/server_protocol.h | 32 +++++++++++++++++++++-
server/protocol.def | 30 ++++++++++++++++++++-
server/thread.c | 2 +
server/trace.c | 18 +++++++++++++
5 files changed, 127 insertions(+), 11 deletions(-)
diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c
index fe92383..ce8b500 100644
--- a/dlls/ntdll/virtual.c
+++ b/dlls/ntdll/virtual.c
@@ -1802,12 +1802,32 @@ NTSTATUS WINAPI NtQueryVirtualMemory( HA
*/
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 result.virtual_lock.status;
}
- return STATUS_SUCCESS;
+
+ *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( HAN
*/
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 result.virtual_unlock.status;
}
- return STATUS_SUCCESS;
+
+ *size = ROUND_SIZE( *addr, *size );
+ *addr = ROUND_ADDR( *addr, page_mask );
+
+ if (munlock( *addr, *size )) status = STATUS_ACCESS_DENIED;
+ return status;
}
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
index 0f4d3f2..ca98f28 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -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 */
diff --git a/server/protocol.def b/server/protocol.def
index 9987fd4..343fbbb 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -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;
/****************************************************************/
diff --git a/server/thread.c b/server/thread.c
index 6c53e5c..5b0268a 100644
--- a/server/thread.c
+++ b/server/thread.c
@@ -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 )))
{
diff --git a/server/trace.c b/server/trace.c
index 7422912..6766faf 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -142,6 +142,14 @@ static void dump_apc_call( const apc_cal
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_r
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;
More information about the wine-cvs
mailing list