reshuffling of dlls
[reactos.git] / reactos / lib / kernel32 / mem / procmem.c
1 /* $Id$
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: lib/kernel32/mem/procmem.c
6 * PURPOSE:
7 * PROGRAMMER: Boudewijn Dekker
8 */
9
10 /* INCLUDES ******************************************************************/
11
12 #include <k32.h>
13
14 #define NDEBUG
15 #include "../include/debug.h"
16
17 /* FUNCTIONS *****************************************************************/
18
19 /*
20 * @implemented
21 */
22 BOOL
23 STDCALL
24 ReadProcessMemory (
25 HANDLE hProcess,
26 LPCVOID lpBaseAddress,
27 LPVOID lpBuffer,
28 DWORD nSize,
29 LPDWORD lpNumberOfBytesRead
30 )
31 {
32
33 NTSTATUS Status;
34
35 Status = NtReadVirtualMemory( hProcess, (PVOID)lpBaseAddress,lpBuffer, nSize,
36 (PULONG)lpNumberOfBytesRead
37 );
38
39 if (!NT_SUCCESS(Status))
40 {
41 SetLastErrorByStatus (Status);
42 return FALSE;
43 }
44 return TRUE;
45 }
46
47
48 /*
49 * @implemented
50 */
51 BOOL
52 STDCALL
53 WriteProcessMemory (
54 HANDLE hProcess,
55 LPVOID lpBaseAddress,
56 LPCVOID lpBuffer,
57 SIZE_T nSize,
58 SIZE_T *lpNumberOfBytesWritten
59 )
60 {
61 NTSTATUS Status, ProtectStatus = STATUS_SUCCESS;
62 MEMORY_BASIC_INFORMATION MemInfo;
63 ULONG Length;
64 BOOLEAN UnProtect;
65
66 if (lpNumberOfBytesWritten)
67 {
68 *lpNumberOfBytesWritten = 0;
69 }
70
71 while (nSize)
72 {
73 Status = NtQueryVirtualMemory(hProcess,
74 lpBaseAddress,
75 MemoryBasicInformation,
76 &MemInfo,
77 sizeof(MEMORY_BASIC_INFORMATION),
78 NULL);
79
80 if (!NT_SUCCESS(Status))
81 {
82 SetLastErrorByStatus(Status);
83 return FALSE;
84 }
85 Length = MemInfo.RegionSize - ((ULONG_PTR)lpBaseAddress - (ULONG_PTR)MemInfo.BaseAddress);
86 if (Length > nSize)
87 {
88 Length = nSize;
89 }
90 UnProtect = MemInfo.Protect & (PAGE_READWRITE|PAGE_WRITECOPY|PAGE_EXECUTE_READWRITE|PAGE_EXECUTE_WRITECOPY) ? FALSE : TRUE;
91 if (UnProtect)
92 {
93 MemInfo.BaseAddress = lpBaseAddress;
94 MemInfo.RegionSize = Length;
95 if (MemInfo.Protect & (PAGE_EXECUTE|PAGE_EXECUTE_READ))
96 {
97 MemInfo.Protect &= ~(PAGE_EXECUTE|PAGE_EXECUTE_READ);
98 MemInfo.Protect |= PAGE_EXECUTE_READWRITE;
99 }
100 else
101 {
102 MemInfo.Protect &= ~(PAGE_READONLY|PAGE_NOACCESS);
103 MemInfo.Protect |= PAGE_READWRITE;
104 }
105
106 ProtectStatus = NtProtectVirtualMemory(hProcess,
107 &MemInfo.BaseAddress,
108 &MemInfo.RegionSize,
109 MemInfo.Protect,
110 &MemInfo.Protect);
111 if (!NT_SUCCESS(ProtectStatus))
112 {
113 SetLastErrorByStatus(ProtectStatus);
114 return FALSE;
115 }
116 Length = MemInfo.RegionSize - ((ULONG_PTR)lpBaseAddress - (ULONG_PTR)MemInfo.BaseAddress);
117 if (Length > nSize)
118 {
119 Length = nSize;
120 }
121 }
122
123 Status = NtWriteVirtualMemory(hProcess,
124 lpBaseAddress,
125 (LPVOID)lpBuffer,
126 Length,
127 &Length);
128 if (UnProtect)
129 {
130 ProtectStatus = NtProtectVirtualMemory(hProcess,
131 &MemInfo.BaseAddress,
132 &MemInfo.RegionSize,
133 MemInfo.Protect,
134 &MemInfo.Protect);
135 }
136 if (!NT_SUCCESS(Status))
137 {
138 SetLastErrorByStatus (Status);
139 return FALSE;
140 }
141 if (UnProtect && !NT_SUCCESS(ProtectStatus))
142 {
143 SetLastErrorByStatus (ProtectStatus);
144 return FALSE;
145 }
146 lpBaseAddress = (LPVOID)((ULONG_PTR)lpBaseAddress + Length);
147 lpBuffer = (LPCVOID)((ULONG_PTR)lpBuffer + Length);
148 nSize -= Length;
149 if (lpNumberOfBytesWritten)
150 {
151 *lpNumberOfBytesWritten += Length;
152 }
153 }
154 return TRUE;
155 }
156
157 /* EOF */