--- trunk/reactos/lib/kernel32/mem/procmem.c 2005-10-24 17:21:23 UTC (rev 18743)
+++ trunk/reactos/lib/kernel32/mem/procmem.c 2005-10-24 17:23:42 UTC (rev 18744)
@@ -58,17 +58,99 @@
SIZE_T *lpNumberOfBytesWritten
)
{
- NTSTATUS Status;
+ NTSTATUS Status, ProtectStatus;
+ MEMORY_BASIC_INFORMATION MemInfo;
+ ULONG Length;
+ BOOLEAN UnProtect;
- Status = NtWriteVirtualMemory( hProcess, lpBaseAddress, (LPVOID)lpBuffer, nSize,
- (PULONG)lpNumberOfBytesWritten
- );
+ if (lpNumberOfBytesWritten)
+ {
+ *lpNumberOfBytesWritten = 0;
+ }
- if (!NT_SUCCESS(Status))
- {
+ while (nSize)
+ {
+ Status = NtQueryVirtualMemory(hProcess,
+ lpBaseAddress,
+ MemoryBasicInformation,
+ &MemInfo,
+ sizeof(MEMORY_BASIC_INFORMATION),
+ NULL);
+
+ if (!NT_SUCCESS(Status))
+ {
+ SetLastErrorByStatus(Status);
+ return FALSE;
+ }
+ Length = MemInfo.RegionSize - ((ULONG_PTR)lpBaseAddress - (ULONG_PTR)MemInfo.BaseAddress);
+ if (Length > nSize)
+ {
+ Length = nSize;
+ }
+ UnProtect = MemInfo.Protect & (PAGE_READWRITE|PAGE_WRITECOPY|PAGE_EXECUTE_READWRITE|PAGE_EXECUTE_WRITECOPY) ? FALSE : TRUE;
+ if (UnProtect)
+ {
+ MemInfo.BaseAddress = lpBaseAddress;
+ MemInfo.RegionSize = Length;
+ if (MemInfo.Protect & (PAGE_EXECUTE|PAGE_EXECUTE_READ))
+ {
+ MemInfo.Protect &= ~(PAGE_EXECUTE|PAGE_EXECUTE_READ);
+ MemInfo.Protect |= PAGE_EXECUTE_READWRITE;
+ }
+ else
+ {
+ MemInfo.Protect &= ~(PAGE_READONLY|PAGE_NOACCESS);
+ MemInfo.Protect |= PAGE_READWRITE;
+ }
+
+ ProtectStatus = NtProtectVirtualMemory(hProcess,
+ &MemInfo.BaseAddress,
+ &MemInfo.RegionSize,
+ MemInfo.Protect,
+ &MemInfo.Protect);
+ if (!NT_SUCCESS(ProtectStatus))
+ {
+ SetLastErrorByStatus(ProtectStatus);
+ return FALSE;
+ }
+ Length = MemInfo.RegionSize - ((ULONG_PTR)lpBaseAddress - (ULONG_PTR)MemInfo.BaseAddress);
+ if (Length > nSize)
+ {
+ Length = nSize;
+ }
+ }
+
+ Status = NtWriteVirtualMemory(hProcess,
+ lpBaseAddress,
+ (LPVOID)lpBuffer,
+ Length,
+ &Length);
+ if (UnProtect)
+ {
+ ProtectStatus = NtProtectVirtualMemory(hProcess,
+ &MemInfo.BaseAddress,
+ &MemInfo.RegionSize,
+ MemInfo.Protect,
+ &MemInfo.Protect);
+ }
+ if (!NT_SUCCESS(Status))
+ {
SetLastErrorByStatus (Status);
return FALSE;
- }
+ }
+ if (UnProtect && !NT_SUCCESS(ProtectStatus))
+ {
+ SetLastErrorByStatus (ProtectStatus);
+ return FALSE;
+ }
+ lpBaseAddress = (LPVOID)((ULONG_PTR)lpBaseAddress + Length);
+ lpBuffer = (LPCVOID)((ULONG_PTR)lpBuffer + Length);
+ nSize -= Length;
+ if (lpNumberOfBytesWritten)
+ {
+ *lpNumberOfBytesWritten += Length;
+ }
+ }
return TRUE;
}