Skip to content

Commit 37b4327

Browse files
Merge pull request #7 from zippy1981/ManagedOnly
Managed only
2 parents 3681fad + 4504aca commit 37b4327

File tree

2 files changed

+71
-40
lines changed

2 files changed

+71
-40
lines changed

Source/ManagedTest/ManagedTest.csproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,12 @@
101101
<Name>Sysinternals.log4net</Name>
102102
</ProjectReference>
103103
</ItemGroup>
104+
<ItemGroup>
105+
<ProjectReference Include="..\Sysinternals.Debug\Sysinternals.Debug.csproj">
106+
<Project>{fb1d522e-1acb-49dd-93d4-123e6ea13aed}</Project>
107+
<Name>Sysinternals.Debug</Name>
108+
</ProjectReference>
109+
</ItemGroup>
104110
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
105111
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
106112
Other similar extension points exist, see Microsoft.Common.targets.

Source/Sysinternals.Debug/NativeMethods.cs

Lines changed: 65 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -8,27 +8,78 @@
88
// - Moved to VS 2013 and .NET 4.5.1
99
//////////////////////////////////////////////////////////////////////////////*/
1010

11+
using System.Text;
12+
using Microsoft.Win32.SafeHandles;
13+
1114
namespace Sysinternals.Debug
1215
{
1316
using System;
1417
using System.Diagnostics;
15-
using System.Reflection;
1618
using System.Runtime.InteropServices;
1719

1820
/// <summary>
1921
/// A class to wrap all the native code needed by this assembly.
2022
/// </summary>
2123
internal static class NativeMethods
2224
{
25+
// Constants to represent C preprocessor macros for PInvokes
26+
const uint GENERIC_WRITE = 0x40000000;
27+
const uint OPEN_EXISTING = 3;
28+
const uint FILE_WRITE_ACCESS = 0x0002;
29+
const uint FILE_SHARE_WRITE = 0x00000002;
30+
const uint FILE_ATTRIBUTE_NORMAL = 0x00000080;
31+
const uint METHOD_BUFFERED = 0;
32+
33+
// Procmon Constants
34+
const uint FILE_DEVICE_PROCMON_LOG = 0x00009535;
35+
const string PROCMON_DEBUGGER_HANDLER = "\\\\.\\Global\\ProcmonDebugLogger";
36+
2337
/// <summary>
24-
/// Flag to check if we've already done the process lookup.
38+
/// The handle to the procmon log device.
2539
/// </summary>
26-
private static bool lookedUpProcessType;
40+
private static SafeFileHandle hProcMon;
2741

2842
/// <summary>
29-
/// True if the process is 64-bit.
43+
/// Get the IO Control code for the ProcMon log.
3044
/// </summary>
31-
private static bool is64BitProcess;
45+
private static uint IOCTL_EXTERNAL_LOG_DEBUGOUT { get { return CTL_CODE(); } }
46+
47+
/// <seealso href="http://msdn.microsoft.com/en-us/library/windows/hardware/ff543023(v=vs.85).aspx"/>
48+
private static uint CTL_CODE(
49+
uint DeviceType = FILE_DEVICE_PROCMON_LOG,
50+
uint Function = 0x81,
51+
uint Method = METHOD_BUFFERED,
52+
uint Access = FILE_WRITE_ACCESS)
53+
{
54+
return ((DeviceType << 16) | (Access << 14) | (Function << 2) | Method);
55+
}
56+
57+
/// <remarks>This is only used for opening the procmon log handle, hence the default parameters.</remarks>
58+
/// <seealso href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa363858(v=vs.85).aspx"/>
59+
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
60+
private static extern SafeFileHandle CreateFile(
61+
string lpFileName = PROCMON_DEBUGGER_HANDLER,
62+
uint dwDesiredAccess = GENERIC_WRITE,
63+
uint dwShareMode = FILE_SHARE_WRITE,
64+
IntPtr lpSecurityAttributes = default(IntPtr),
65+
uint dwCreationDisposition = OPEN_EXISTING,
66+
uint dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL,
67+
IntPtr hTemplateFile = default(IntPtr));
68+
69+
[DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true, CharSet = CharSet.Auto)]
70+
private static extern bool DeviceIoControl(
71+
SafeFileHandle hDevice, uint dwIoControlCode,
72+
StringBuilder lpInBuffer, uint nInBufferSize,
73+
IntPtr lpOutBuffer, uint nOutBufferSize,
74+
out uint lpBytesReturned, IntPtr lpOverlapped);
75+
76+
static NativeMethods()
77+
{
78+
AppDomain.CurrentDomain.ProcessExit += (sender, args) =>
79+
{
80+
if (!hProcMon.IsInvalid) hProcMon.Close();
81+
};
82+
}
3283

3384
/// <summary>
3485
/// Does the actual tracing to Process Monitor.
@@ -44,30 +95,20 @@ internal static class NativeMethods
4495
/// </returns>
4596
public static bool ProcMonDebugOutput(string message, params object[] args)
4697
{
47-
if (false == lookedUpProcessType)
48-
{
49-
lookedUpProcessType = true;
50-
51-
Assembly mscorlibAssem = Assembly.GetAssembly(typeof(object));
52-
Module[] mods = mscorlibAssem.GetModules();
53-
PortableExecutableKinds peK;
54-
ImageFileMachine ifn;
55-
mods[0].GetPEKind(out peK, out ifn);
56-
is64BitProcess = ImageFileMachine.I386 != ifn;
57-
}
58-
5998
bool returnValue = false;
6099
try
61100
{
62-
string renderedMessage = string.Format(message, args);
63-
if (true == is64BitProcess)
64-
{
65-
returnValue = ProcMonDebugOutputx64(renderedMessage);
66-
}
67-
else
101+
StringBuilder renderedMessage = new StringBuilder();
102+
renderedMessage.AppendFormat(message, args);
103+
uint outLen;
104+
if (hProcMon == null || hProcMon.IsInvalid)
68105
{
69-
returnValue = ProcMonDebugOutputWin32(renderedMessage);
106+
hProcMon = CreateFile();
70107
}
108+
DeviceIoControl(
109+
hProcMon, IOCTL_EXTERNAL_LOG_DEBUGOUT,
110+
renderedMessage, (uint)(message.Length * Marshal.SizeOf(typeof(char))),
111+
IntPtr.Zero, 0, out outLen, IntPtr.Zero);
71112
}
72113
catch (EntryPointNotFoundException notFoundException)
73114
{
@@ -79,21 +120,5 @@ public static bool ProcMonDebugOutput(string message, params object[] args)
79120

80121
return returnValue;
81122
}
82-
83-
[DllImport("ProcMonDebugOutputx64.dll",
84-
CharSet = CharSet.Unicode,
85-
EntryPoint = "ProcMonDebugOutput",
86-
SetLastError = true,
87-
CallingConvention = CallingConvention.StdCall)]
88-
[return: MarshalAs(UnmanagedType.Bool)]
89-
private static extern bool ProcMonDebugOutputx64(string lpOutput);
90-
91-
[DllImport("ProcMonDebugOutputWin32.dll",
92-
CharSet = CharSet.Unicode,
93-
EntryPoint = "ProcMonDebugOutput",
94-
SetLastError = true,
95-
CallingConvention = CallingConvention.StdCall)]
96-
[return: MarshalAs(UnmanagedType.Bool)]
97-
private static extern bool ProcMonDebugOutputWin32(string lpOutput);
98123
}
99124
}

0 commit comments

Comments
 (0)