diff --git a/PInvoke/Kernel32/ProcessThreadsApi.cs b/PInvoke/Kernel32/ProcessThreadsApi.cs
index 5986858a..f2e25eeb 100644
--- a/PInvoke/Kernel32/ProcessThreadsApi.cs
+++ b/PInvoke/Kernel32/ProcessThreadsApi.cs
@@ -265,6 +265,29 @@ namespace Vanara.PInvoke
DYNAMIC_EH_CONTINUATION_TARGET_PROCESSED = 0x00000002
}
+ ///
+ /// Specifies the ways in which an architecture of code can run on a host operating system. More than one bit may be set.
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/ne-processthreadsapi-machine_attributes typedef enum
+ // _MACHINE_ATTRIBUTES { UserEnabled, KernelEnabled, Wow64Container } MACHINE_ATTRIBUTES;
+ [PInvokeData("processthreadsapi.h", MSDNShortId = "NE:processthreadsapi._MACHINE_ATTRIBUTES")]
+ public enum MACHINE_ATTRIBUTES
+ {
+ /// The specified architecture of code can run in user mode.
+ UserEnabled,
+
+ /// The specified architecture of code can run in kernel mode.
+ KernelEnabled,
+
+ ///
+ /// The specified architecture of code runs by relying on WOW64's namespace File System Redirector and Registry
+ /// Redirector. This bit will be set, for example, on x86 code running on a host operating system that is x64 or ARM64. When
+ /// the compatibility layer does not use WOW64 style filesystem and registry namespaces, like x64 on ARM64 which runs on the
+ /// root namespace of the OS, this bit will be reset.
+ ///
+ Wow64Container,
+ }
+
/// The memory priority for the thread or process.
public enum MEMORY_PRIORITY
{
@@ -297,37 +320,90 @@ namespace Vanara.PInvoke
PROCESS_AFFINITY_ENABLE_AUTO_UPDATE
}
- /// Indicates type of structure used in GetProcessInformation and SetProcessInformation calls.
+ ///
+ /// Indicates a specific class of process information. Values from this enumeration are passed into the GetProcessInformation and
+ /// SetProcessInformation functions to specify the type of process information passed in the void pointer argument of the function call.
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/ne-processthreadsapi-process_information_class typedef enum
+ // _PROCESS_INFORMATION_CLASS { ProcessMemoryPriority, ProcessMemoryExhaustionInfo, ProcessAppMemoryInfo, ProcessInPrivateInfo,
+ // ProcessPowerThrottling, ProcessReservedValue1, ProcessTelemetryCoverageInfo, ProcessProtectionLevelInfo, ProcessLeapSecondInfo,
+ // ProcessMachineTypeInfo, ProcessInformationClassMax } PROCESS_INFORMATION_CLASS;
+ [PInvokeData("processthreadsapi.h", MSDNShortId = "NE:processthreadsapi._PROCESS_INFORMATION_CLASS")]
public enum PROCESS_INFORMATION_CLASS
{
- /// Indicates that a MEMORY_PRIORITY_INFORMATION structure is specified for the operation.
- [CorrespondingType(typeof(MEMORY_PRIORITY_INFORMATION))]
+ ///
+ /// The process information is represented by a MEMORY_PRIORITY_INFORMATION structure. Allows applications to lower the default
+ /// memory priority of threads that perform background operations or access files and data that are not expected to be accessed
+ /// again soon.
+ ///
+ [CorrespondingType(typeof(MEMORY_PRIORITY_INFORMATION), CorrespondingAction.GetSet)]
ProcessMemoryPriority,
- /// Indicates that a PROCESS_MEMORY_EXHAUSTION_INFO structure is specified for the operation.
- [CorrespondingType(typeof(PROCESS_MEMORY_EXHAUSTION_INFO))]
+ ///
+ /// The process information is represented by a PROCESS_MEMORY_EXHAUSTION_INFO structure. Allows applications to configure a
+ /// process to terminate if an allocation fails to commit memory.
+ ///
+ [CorrespondingType(typeof(PROCESS_MEMORY_EXHAUSTION_INFO), CorrespondingAction.Set)]
ProcessMemoryExhaustionInfo,
- /// Indicates that a APP_MEMORY_INFORMATION structure is specified for the operation.
- [CorrespondingType(typeof(APP_MEMORY_INFORMATION))]
+ ///
+ /// The process information is represented by a APP_MEMORY_INFORMATION structure. Allows applications to query the commit usage
+ /// and the additional commit available to this process. Does not allow the caller to actually get a commit limit.
+ ///
+ [CorrespondingType(typeof(APP_MEMORY_INFORMATION), CorrespondingAction.Get)]
ProcessAppMemoryInfo,
- /// Undocumented.
+ ///
+ /// If a process is set to ProcessInPrivate mode, and a trace session has set the EVENT_ENABLE_PROPERTY_EXCLUDE_INPRIVATE
+ /// flag, then the trace session will drop all events from that process.
+ ///
ProcessInPrivateInfo,
- /// Indicates that a PROCESS_POWER_THROTTLING_STATE structure is specified for the operation.
- [CorrespondingType(typeof(PROCESS_POWER_THROTTLING_STATE))]
+ ///
+ /// The process information is represented by a PROCESS_POWER_THROTTLING_STATE structure. Allows applications to configure how
+ /// the system should throttle the target process’s activity when managing power.
+ ///
+ [CorrespondingType(typeof(PROCESS_POWER_THROTTLING_STATE), CorrespondingAction.GetSet)]
ProcessPowerThrottling,
- /// Undocumented.
+ /// Reserved.
ProcessReservedValue1,
- /// Undocumented.
+ /// Reserved.
ProcessTelemetryCoverageInfo,
- /// Indicates that a PROCESS_PROTECTION_LEVEL_INFORMATION structure is specified for the operation.
- [CorrespondingType(typeof(PROCESS_PROTECTION_LEVEL_INFORMATION))]
+ /// The process information is represented by a PROCESS_PROTECTION_LEVEL_INFORMATION structure.
+ [CorrespondingType(typeof(PROCESS_PROTECTION_LEVEL_INFORMATION), CorrespondingAction.Get)]
ProcessProtectionLevelInfo,
+
+ /// The process information is represented by a PROCESS_LEAP_SECOND_INFO structure.
+ [CorrespondingType(typeof(PROCESS_LEAP_SECOND_INFO), CorrespondingAction.GetSet)]
+ ProcessLeapSecondInfo,
+
+ /// The process is represented by a PROCESS_MACHINE_INFORMATION structure.
+ [CorrespondingType(typeof(PROCESS_MACHINE_INFORMATION), CorrespondingAction.Get)]
+ ProcessMachineTypeInfo,
+ }
+
+ /// Flags for .
+ [PInvokeData("processthreadsapi.h")]
+ [Flags]
+ public enum PROCESS_LEAP_SECOND_INFO_FLAGS
+ {
+ ///
+ /// This value changes the way positive leap seconds are handled by system. Specifically, it changes how the seconds field
+ /// during a positive leap second is handled by the system. If this value is used, then the positive leap second will be shown
+ /// (For example: 23:59:59 -> 23:59:60 -> 00:00:00. If this value is not used, then "sixty seconds" is disabled, and the
+ /// 59th second preceding a positive leap second will be shown for 2 seconds with the milliseconds value ticking twice as slow.
+ /// So 23:59:59 -> 23:59:59.500 -> 00:00:00, which takes 2 seconds in wall clock time. Disabling "sixty second" can help
+ /// with legacy apps that do not support seeing the seconds value as 60 during the positive leap second. Such apps may crash or
+ /// misbehave. Therefore, in these cases, we display the 59th second for twice as long during the positive leap second. Note
+ /// that this setting is per-process, and does not persist if the process is restarted. Developers should test their app for
+ /// compatibility with seeing the system return "60", and add a call to their app startup routines to either enable or disable
+ /// "sixty seconds". "Sixty seconds" is disabled by default for each process. Obviously, this setting has no effect if leap
+ /// seconds are disabled system-wide, because then the system will never even encounter a leap second.
+ ///
+ PROCESS_LEAP_SECOND_INFO_FLAG = 1
}
/// Represents the different memory exhaustion types.
@@ -2667,67 +2743,110 @@ namespace Vanara.PInvoke
/// Retrieves information about the specified process.
///
- /// A handle to the process. This handle must have the PROCESS_SET_INFORMATION access right. For more information, see Process
- /// Security and Access Rights.
+ /// A handle to the process. This handle must have the PROCESS_SET_INFORMATION access right. For more information, see
+ /// Process Security and Access Rights.
+ ///
+ ///
+ /// A member of the PROCESS_INFORMATION_CLASS enumeration specifying the kind of information to retrieve.
///
- /// The kind of information to retrieve. The only supported value is ProcessMemoryPriority
///
/// Pointer to an object to receive the type of information specified by the ProcessInformationClass parameter.
///
/// If the ProcessInformationClass parameter is ProcessMemoryPriority, this parameter must point to a
- /// MEMORY_PRIORITY_INFORMATION structure.
+ /// MEMORY_PRIORITY_INFORMATION structure.
///
///
/// If the ProcessInformationClass parameter is ProcessPowerThrottling, this parameter must point to a
- /// PROCESS_POWER_THROTTLING_STATE structure.
+ /// PROCESS_POWER_THROTTLING_STATE structure.
///
///
/// If the ProcessInformationClass parameter is ProcessProtectionLevelInfo, this parameter must point to a
- /// PROCESS_PROTECTION_LEVEL_INFORMATION structure.
+ /// PROCESS_PROTECTION_LEVEL_INFORMATION structure.
///
///
- /// If the ProcessInformationClass parameter is ProcessAppMemoryInfo, this parameter must point to a
- /// APP_MEMORY_INFORMATION structure.
+ /// If the ProcessInformationClass parameter is ProcessLeapSecondInfo, this parameter must point to a
+ /// PROCESS_LEAP_SECOND_INFO structure.
+ ///
+ ///
+ /// If the ProcessInformationClass parameter is ProcessAppMemoryInfo, this parameter must point to a APP_MEMORY_INFORMATION structure.
///
///
///
/// The size in bytes of the structure specified by the ProcessInformation parameter.
- /// If the ProcessInformationClass parameter is ProcessMemoryPriority, this parameter must be .
- /// If the ProcessInformationClass parameter is ProcessPowerThrottling, this parameter must be .
- /// If the ProcessInformationClass parameter is ProcessProtectionLevelInfo, this parameter must be .
- /// If the ProcessInformationClass parameter is ProcessAppMemoryInfo, this parameter must be .
+ /// If the ProcessInformationClass parameter is ProcessMemoryPriority, this parameter must be
+ /// sizeof(MEMORY_PRIORITY_INFORMATION)
+ /// .
+ ///
+ /// If the ProcessInformationClass parameter is ProcessPowerThrottling, this parameter must be
+ /// sizeof(PROCESS_POWER_THROTTLING_STATE)
+ /// .
+ ///
+ /// If the ProcessInformationClass parameter is ProcessProtectionLevelInfo, this parameter must be
+ /// sizeof(PROCESS_PROTECTION_LEVEL_INFORMATION)
+ /// .
+ ///
+ /// If the ProcessInformationClass parameter is ProcessLeapSecondInfo, this parameter must be
+ /// sizeof(PROCESS_LEAP_SECOND_INFO)
+ /// .
+ ///
+ /// If the ProcessInformationClass parameter is ProcessAppMemoryInfo, this parameter must be
+ /// sizeof(APP_MEMORY_INFORMATION)
+ /// .
+ ///
///
///
/// If the function succeeds, the return value is nonzero.
- /// If the function fails, the return value is zero. To get extended error information, call GetLastError.
+ /// If the function fails, the return value is zero. To get extended error information, call GetLastError.
///
- // BOOL WINAPI GetProcessInformation( _In_ HANDLE hProcess, _In_ PROCESS_INFORMATION_CLASS ProcessInformationClass,
- // _Out_writes_bytes_(ProcessInformationSize) ProcessInformation, _In_ DWORD ProcessInformationSize); https://msdn.microsoft.com/en-us/library/windows/desktop/hh448381(v=vs.85).aspx
+ // https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getprocessinformation
+ // BOOL GetProcessInformation( HANDLE hProcess, PROCESS_INFORMATION_CLASS ProcessInformationClass, LPVOID ProcessInformation, DWORD ProcessInformationSize );
+ [PInvokeData("processthreadsapi.h", MSDNShortId = "NF:processthreadsapi.GetProcessInformation")]
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
- [PInvokeData("WinBase.h", MSDNShortId = "hh448381")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetProcessInformation(HPROCESS hProcess, PROCESS_INFORMATION_CLASS ProcessInformationClass,
IntPtr ProcessInformation, uint ProcessInformationSize);
/// Retrieves information about the specified process.
- /// The type of information associated with .
+ /// The type to retrive.
///
- /// A handle to the process. This handle must have the PROCESS_SET_INFORMATION access right. For more information, see Process
- /// Security and Access Rights.
+ /// A handle to the process. This handle must have the PROCESS_SET_INFORMATION access right. For more information, see
+ /// Process Security and Access Rights.
///
- /// The kind of information to retrieve. The only supported value is ProcessMemoryPriority
- /// An object containing the type of information specified by the ProcessInformationClass parameter.
- /// Type mismatch.
- [PInvokeData("WinBase.h", MSDNShortId = "hh448381")]
- public static T GetProcessInformation(HPROCESS hProcess, PROCESS_INFORMATION_CLASS ProcessInformationClass) where T : struct
+ ///
+ /// A member of the PROCESS_INFORMATION_CLASS enumeration specifying the kind of information to retrieve.
+ ///
+ ///
+ /// Pointer to an object to receive the type of information specified by the ProcessInformationClass parameter.
+ ///
+ /// If the ProcessInformationClass parameter is ProcessMemoryPriority, this parameter must point to a
+ /// MEMORY_PRIORITY_INFORMATION structure.
+ ///
+ ///
+ /// If the ProcessInformationClass parameter is ProcessPowerThrottling, this parameter must point to a
+ /// PROCESS_POWER_THROTTLING_STATE structure.
+ ///
+ ///
+ /// If the ProcessInformationClass parameter is ProcessProtectionLevelInfo, this parameter must point to a
+ /// PROCESS_PROTECTION_LEVEL_INFORMATION structure.
+ ///
+ ///
+ /// If the ProcessInformationClass parameter is ProcessLeapSecondInfo, this parameter must point to a
+ /// PROCESS_LEAP_SECOND_INFO structure.
+ ///
+ ///
+ /// If the ProcessInformationClass parameter is ProcessAppMemoryInfo, this parameter must point to a APP_MEMORY_INFORMATION structure.
+ ///
+ ///
+ public static T GetProcessInformation(HPROCESS hProcess, PROCESS_INFORMATION_CLASS ProcessInformationClass = (PROCESS_INFORMATION_CLASS)(-1)) where T : struct
{
- if (!CorrespondingTypeAttribute.CanGet(ProcessInformationClass, typeof(T))) throw new ArgumentException("Type mismatch.");
- using (var mem = SafeHGlobalHandle.CreateFromStructure())
- {
- if (!GetProcessInformation(hProcess, ProcessInformationClass, (IntPtr)mem, (uint)mem.Size))
- Win32Error.ThrowLastError();
- return mem.ToStructure();
- }
+ if (!ProcessInformationClass.IsValid() && !CorrespondingTypeAttribute.CanGet(out ProcessInformationClass))
+ throw new ArgumentException("The type specified by the type parameter cannot be retrieved for a process.", nameof(T));
+ else if (!CorrespondingTypeAttribute.CanGet(ProcessInformationClass, typeof(T)))
+ throw new ArgumentException("Type mismatch.");
+ using var mem = new SafeCoTaskMemStruct();
+ if (!GetProcessInformation(hProcess, ProcessInformationClass, mem, mem.Size))
+ Win32Error.ThrowLastError();
+ return mem.Value;
}
/// Retrieves mitigation policy settings for the calling process.
@@ -6151,6 +6270,72 @@ namespace Vanara.PInvoke
public uint dwThreadId;
}
+ /// Specifies how the system handles positive leap seconds.
+ // https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/ns-processthreadsapi-process_leap_second_info
+ // typedef struct _PROCESS_LEAP_SECOND_INFO { ULONG Flags; ULONG Reserved; } PROCESS_LEAP_SECOND_INFO, *PPROCESS_LEAP_SECOND_INFO;
+ [PInvokeData("processthreadsapi.h", MSDNShortId = "NS:processthreadsapi._PROCESS_LEAP_SECOND_INFO")]
+ [StructLayout(LayoutKind.Sequential)]
+ public struct PROCESS_LEAP_SECOND_INFO
+ {
+ ///
+ ///
+ /// Currently, the only valid flag is PROCESS_LEAP_SECOND_INFO_FLAG_ENABLE_SIXTY_SECOND. That flag is described below.
+ ///
+ ///
+ ///
+ /// Value
+ /// Meaning
+ ///
+ /// -
+ /// PROCESS_LEAP_SECOND_INFO_FLAG_ENABLE_SIXTY_SECOND
+ ///
+ /// This value changes the way positive leap seconds are handled by system. Specifically, it changes how the seconds field
+ /// during a positive leap second is handled by the system. If this value is used, then the positive leap second will be shown
+ /// (For example: 23:59:59 -> 23:59:60 -> 00:00:00. If this value is not used, then "sixty seconds" is disabled, and the
+ /// 59th second preceding a positive leap second will be shown for 2 seconds with the milliseconds value ticking twice as slow.
+ /// So 23:59:59 -> 23:59:59.500 -> 00:00:00, which takes 2 seconds in wall clock time. Disabling "sixty second" can help
+ /// with legacy apps that do not support seeing the seconds value as 60 during the positive leap second. Such apps may crash or
+ /// misbehave. Therefore, in these cases, we display the 59th second for twice as long during the positive leap second. Note
+ /// that this setting is per-process, and does not persist if the process is restarted. Developers should test their app for
+ /// compatibility with seeing the system return "60", and add a call to their app startup routines to either enable or disable
+ /// "sixty seconds". "Sixty seconds" is disabled by default for each process. Obviously, this setting has no effect if leap
+ /// seconds are disabled system-wide, because then the system will never even encounter a leap second.
+ ///
+ ///
+ ///
+ ///
+ public PROCESS_LEAP_SECOND_INFO_FLAGS Flags;
+
+ /// Reserved for future use
+ public uint Reserved;
+ }
+
+ ///
+ /// Specifies the architecture of a process and if that architecture of code can run in user mode, kernel mode, and/or under WoW64
+ /// on the host operating system.
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/ns-processthreadsapi-process_machine_information typedef
+ // struct _PROCESS_MACHINE_INFORMATION { USHORT ProcessMachine; USHORT Res0; MACHINE_ATTRIBUTES MachineAttributes; } PROCESS_MACHINE_INFORMATION;
+ [PInvokeData("processthreadsapi.h", MSDNShortId = "NS:processthreadsapi._PROCESS_MACHINE_INFORMATION")]
+ [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
+ public struct PROCESS_MACHINE_INFORMATION
+ {
+ ///
+ /// An IMAGE_FILE_MACHINE_* value indicating the architecture of the associated process. See the list of architecture values in
+ /// Image File Machine Constants.
+ ///
+ public IMAGE_FILE_MACHINE ProcessMachine;
+
+ /// Reserved.
+ public ushort Res0;
+
+ ///
+ /// A value from the MACHINE_ATTRIBUTES enumeration indicating if the process’s architecture can run in user mode, kernel mode,
+ /// and/or under WOW64 on the host operating system.
+ ///
+ public MACHINE_ATTRIBUTES MachineAttributes;
+ }
+
///
/// Allows applications to configure a process to terminate if an allocation fails to commit memory. This structure is used by the
/// PROCESS_INFORMATION_CLASS class.
diff --git a/System/Extensions/ProcessExtension.cs b/System/Extensions/ProcessExtension.cs
index 608ff972..eb29a0a8 100644
--- a/System/Extensions/ProcessExtension.cs
+++ b/System/Extensions/ProcessExtension.cs
@@ -83,6 +83,16 @@ namespace Vanara.Extensions
}
#endif
+ /// Retrieves information about the specified process.
+ /// The type of information to retrieve.
+ ///
+ /// A handle to the process. This handle must have the PROCESS_SET_INFORMATION access right. For more information, see Process
+ /// Security and Access Rights.
+ ///
+ /// An object containing the type of information specified by the ProcessInformationClass parameter.
+ /// Type mismatch.
+ public static T GetInformation(this Process process) where T : struct => GetProcessInformation(process);
+
///
/// The function gets the integrity level of the current process. Integrity level is only available on Windows Vista and newer operating systems, thus
/// GetProcessIntegrityLevel throws an exception if it is called on systems prior to Windows Vista.
@@ -217,6 +227,46 @@ namespace Vanara.Extensions
///
public static bool IsRunningAsAdmin(this Process proc) => UAC.IsRunningAsAdmin(proc);
+ ///
+ /// Reads data from an area of memory in a specified process. The entire area to be read must be accessible or the operation fails.
+ ///
+ /// The type of the structure to read.
+ ///
+ /// A handle to the process with memory that is being read. The handle must have PROCESS_VM_READ access to the process.
+ ///
+ ///
+ /// A pointer to the base address in the specified process from which to read. Before any data transfer occurs, the system verifies
+ /// that all data in the base address and memory of the specified size is accessible for read access, and if it is not accessible
+ /// the function fails.
+ ///
+ /// A value of with the contents from the address space of the specified process.
+ public static T ReadMemory(this Process process, IntPtr baseAddress) where T : struct
+ {
+ using var mem = new SafeCoTaskMemStruct();
+ SizeT req = ReadToMem(process, baseAddress, mem);
+ return mem.Value;
+ }
+
+ ///
+ /// Reads data from an area of memory in a specified process. The entire area to be read must be accessible or the operation fails.
+ ///
+ ///
+ /// A handle to the process with memory that is being read. The handle must have PROCESS_VM_READ access to the process.
+ ///
+ ///
+ /// A pointer to the base address in the specified process from which to read. Before any data transfer occurs, the system verifies
+ /// that all data in the base address and memory of the specified size is accessible for read access, and if it is not accessible
+ /// the function fails.
+ ///
+ /// The number of bytes to be read from the specified process.
+ /// A buffer with the contents from the address space of the specified process.
+ public static byte[] ReadMemory(this Process process, IntPtr baseAddress, SizeT size)
+ {
+ using var mem = new SafeCoTaskMemHandle(size);
+ SizeT req = ReadToMem(process, baseAddress, mem);
+ return mem.GetBytes(0, req);
+ }
+
/// Removes a specified system privilege from a process.
/// The process from which to remove the privilege.
/// The privilege to remove.
@@ -234,6 +284,24 @@ namespace Vanara.Extensions
ResumeThread(hTh);
}
+ /// Sets information for the specified process.
+ /// Type of the value to set.
+ ///
+ /// A handle to the process. This handle must have the PROCESS_SET_INFORMATION access right. For more information, see
+ /// Process Security and Access Rights.
+ ///
+ /// An object used to set information.
+ ///
+ /// If the function succeeds, the return value is nonzero.
+ /// If the function fails, the return value is zero. To get extended error information, call GetLastError.
+ ///
+ public static bool SetInformation(this Process process, in T value) where T : struct
+ {
+ if (!CorrespondingTypeAttribute.CanSet(out var ProcessInformationClass))
+ throw new ArgumentException("The type specified by the type parameter cannot be retrieved for a process.", nameof(T));
+ return SetProcessInformation(process, ProcessInformationClass, value);
+ }
+
/// Extension method to start a process with extra flags.
/// The process to start.
/// The process flags.
@@ -410,6 +478,41 @@ namespace Vanara.Extensions
return false;
}
+ ///
+ /// Writes data to an area of memory in a specified process. The entire area to be written to must be accessible or the operation fails.
+ ///
+ /// The process memory to be modified.
+ ///
+ /// The base address in the specified process to which data is written. Before data transfer occurs, the system verifies that all
+ /// data in the base address and memory of the specified size is accessible for write access, and if it is not accessible, the
+ /// function fails.
+ ///
+ /// A pointer to the buffer that contains data to be written in the address space of the specified process.
+ /// The number of bytes to be written to the specified process.
+ /// The number of bytes transferred into the specified process.
+ public static SizeT WriteMemory(this Process process, IntPtr baseAddress, IntPtr buffer, SizeT bufferSize)
+ {
+ Win32Error.ThrowLastErrorIfFalse(WriteProcessMemory(process, baseAddress, buffer, bufferSize, out var written));
+ return written;
+ }
+
+ ///
+ /// Writes data to an area of memory in a specified process. The entire area to be written to must be accessible or the operation fails.
+ ///
+ /// The process memory to be modified.
+ ///
+ /// The base address in the specified process to which data is written. Before data transfer occurs, the system verifies that all
+ /// data in the base address and memory of the specified size is accessible for write access, and if it is not accessible, the
+ /// function fails.
+ ///
+ /// A pointer to the buffer that contains data to be written in the address space of the specified process.
+ /// The number of bytes transferred into the specified process.
+ public static SizeT WriteMemory(this Process process, IntPtr baseAddress, byte[] buffer)
+ {
+ Win32Error.ThrowLastErrorIfFalse(WriteProcessMemory(process, baseAddress, buffer, buffer.Length, out var written));
+ return written;
+ }
+
private static IEnumerable GetChildProcesses(int pid, Dictionary>> allProcs, string machineName, bool allChildren = true)
{
if (allProcs == null) throw new ArgumentNullException(nameof(allProcs));
@@ -424,5 +527,17 @@ namespace Vanara.Extensions
if (retProc != null) yield return retProc;
}
}
+
+ private static SizeT ReadToMem(Process proc, IntPtr baseAddress, SafeMemoryHandle mem)
+ {
+ bool ret;
+ if ((ret = ReadProcessMemory(proc, baseAddress, mem, mem.Size, out var req)) == false && req > mem.Size)
+ {
+ mem.Size = req;
+ ret = ReadProcessMemory(proc, baseAddress, mem, mem.Size, out req);
+ }
+ if (!ret) Win32Error.ThrowLastError();
+ return req;
+ }
}
}