OLD | NEW |
| (Empty) |
1 // Copyright 2009 The Native Client Authors. All rights reserved. | |
2 // | |
3 // Use of this source code is governed by a BSD-style license that can | |
4 // | |
5 // be found in the LICENSE file. | |
6 using System; | |
7 using System.Collections.Generic; | |
8 using System.Diagnostics; | |
9 using System.IO; | |
10 using Microsoft.VisualStudio; | |
11 using Microsoft.VisualStudio.Debugger.Interop; | |
12 | |
13 namespace Google.MsAd7.BaseImpl { | |
14 public abstract class DebugProcess : IDebugProcess2 { | |
15 public DebugProcess(IDebugPort2 port, int pid, string imagePath) { | |
16 imagePath_ = imagePath; | |
17 pid_ = pid; | |
18 port_ = port; | |
19 } | |
20 | |
21 public string ImagePath { | |
22 get { return imagePath_; } | |
23 protected set { imagePath_ = value; } | |
24 } | |
25 | |
26 public Guid Guid { | |
27 get { return guid_; } | |
28 } | |
29 | |
30 public int Pid { | |
31 get { return pid_; } | |
32 } | |
33 | |
34 public IDebugPort2 Port { | |
35 get { return port_; } | |
36 } | |
37 | |
38 | |
39 #region Implementation of IDebugProcess2 | |
40 | |
41 public int GetInfo(enum_PROCESS_INFO_FIELDS Fields, | |
42 PROCESS_INFO[] pProcessInfo) { | |
43 Debug.WriteLine("DebugProcess.GetInfo"); | |
44 PROCESS_INFO info = new PROCESS_INFO(); | |
45 | |
46 // Currently Visual Studio seems to be asking for these | |
47 // fields: | |
48 // PIF_FILE_NAME | PIF_BASE_NAME | PIF_TITLE | |
49 // | PIF_SESSION_ID | PIF_ATTACHED_SESSION_NAME | PIF_FLAGS | |
50 | |
51 if ((Fields & enum_PROCESS_INFO_FIELDS.PIF_BASE_NAME) != 0) { | |
52 GetName(enum_GETNAME_TYPE.GN_BASENAME, out info.bstrBaseName); | |
53 info.Fields |= enum_PROCESS_INFO_FIELDS.PIF_BASE_NAME; | |
54 } | |
55 if ((Fields & enum_PROCESS_INFO_FIELDS.PIF_FILE_NAME) != 0) { | |
56 GetName(enum_GETNAME_TYPE.GN_FILENAME, out info.bstrBaseName); | |
57 info.Fields |= enum_PROCESS_INFO_FIELDS.PIF_FILE_NAME; | |
58 } | |
59 if ((Fields & enum_PROCESS_INFO_FIELDS.PIF_TITLE) != 0) { | |
60 GetName(enum_GETNAME_TYPE.GN_TITLE, out info.bstrBaseName); | |
61 info.Fields |= enum_PROCESS_INFO_FIELDS.PIF_TITLE; | |
62 } | |
63 | |
64 if ((Fields & enum_PROCESS_INFO_FIELDS.PIF_PROCESS_ID) != 0) { | |
65 info.ProcessId = MakePhysicalProcessId(); | |
66 info.Fields |= enum_PROCESS_INFO_FIELDS.PIF_PROCESS_ID; | |
67 } | |
68 | |
69 if ((Fields & enum_PROCESS_INFO_FIELDS.PIF_FLAGS) != 0) { | |
70 info.Flags = GetProcessStatus(); | |
71 info.Fields |= enum_PROCESS_INFO_FIELDS.PIF_FLAGS; | |
72 } | |
73 | |
74 if ((Fields & enum_PROCESS_INFO_FIELDS.PIF_SESSION_ID) != 0) { | |
75 // We currently don't support multiple sessions, so all | |
76 // processes are in session 1. | |
77 info.dwSessionId = 1; | |
78 info.Fields |= enum_PROCESS_INFO_FIELDS.PIF_SESSION_ID; | |
79 } | |
80 | |
81 // Oddly enough, SESSION_NAME is requested... even though | |
82 // the docs clearly state that it's deprecated. | |
83 if ((Fields & enum_PROCESS_INFO_FIELDS.PIF_ATTACHED_SESSION_NAME) != 0) { | |
84 info.bstrAttachedSessionName = "[Attached session name is deprecated]"; | |
85 info.Fields |= enum_PROCESS_INFO_FIELDS.PIF_ATTACHED_SESSION_NAME; | |
86 } | |
87 | |
88 | |
89 pProcessInfo[0] = info; | |
90 return VSConstants.S_OK; | |
91 } | |
92 | |
93 public abstract enum_PROCESS_INFO_FLAGS GetProcessStatus(); | |
94 | |
95 public int EnumPrograms(out IEnumDebugPrograms2 ppEnum) { | |
96 Debug.WriteLine("DebugProcess.EnumPrograms"); | |
97 ICollection<IDebugProgram2> programs = GetPrograms(); | |
98 ppEnum = new Ad7Enumerators.ProgramEnumerator(programs); | |
99 return VSConstants.S_OK; | |
100 } | |
101 | |
102 protected abstract ICollection<IDebugProgram2> GetPrograms(); | |
103 | |
104 public int GetName(enum_GETNAME_TYPE gnType, out string pbstrName) { | |
105 Debug.WriteLine("DebugProcess.GetName"); | |
106 switch (gnType) { | |
107 case enum_GETNAME_TYPE.GN_BASENAME: | |
108 pbstrName = Path.GetFileName(imagePath_); | |
109 break; | |
110 case enum_GETNAME_TYPE.GN_FILENAME: | |
111 pbstrName = imagePath_; | |
112 break; | |
113 case enum_GETNAME_TYPE.GN_MONIKERNAME: | |
114 pbstrName = imagePath_; | |
115 break; | |
116 case enum_GETNAME_TYPE.GN_NAME: | |
117 pbstrName = Path.GetFileNameWithoutExtension(imagePath_); | |
118 break; | |
119 case enum_GETNAME_TYPE.GN_STARTPAGEURL: | |
120 pbstrName = "[DebugProcess start page URL goes here]"; | |
121 break; | |
122 case enum_GETNAME_TYPE.GN_TITLE: | |
123 // This actually goes into the "process name" column in the | |
124 // VS UI. | |
125 pbstrName = Path.GetFileName(imagePath_); | |
126 break; | |
127 case enum_GETNAME_TYPE.GN_URL: | |
128 pbstrName = "[DebugProcess URL goes here]"; | |
129 break; | |
130 default: | |
131 throw new ArgumentException("DebugProcess.GetName:gnType"); | |
132 } | |
133 return VSConstants.S_OK; | |
134 } | |
135 | |
136 public int GetServer(out IDebugCoreServer2 ppServer) { | |
137 Debug.WriteLine("DebugProcess.GetServer"); | |
138 throw new NotImplementedException(); | |
139 } | |
140 | |
141 public int Terminate() { | |
142 Debug.WriteLine("DebugProcess.Terminate"); | |
143 try { | |
144 // Try to get the process, so we can kill it. | |
145 // If the process is no longer running, GetProcess | |
146 // will throw an ArgumentException. | |
147 var proc = Process.GetProcessById(Pid); | |
148 proc.Kill(); | |
149 } catch (ArgumentException e) { | |
150 // This happens legitimately if the program-under-debug | |
151 // has already finished. | |
152 // We need to catch this exception or the user gets a | |
153 // confusing message about not being able to terminate | |
154 // the (already finished) program-under-debug. | |
155 Debug.WriteLine("Caught Exception {" + e.Message + | |
156 "} in DebugProcess.cs"); | |
157 } | |
158 return VSConstants.S_OK; | |
159 } | |
160 | |
161 public int Attach(IDebugEventCallback2 pCallback, | |
162 Guid[] rgguidSpecificEngines, | |
163 uint celtSpecificEngines, | |
164 int[] rghrEngineAttach) { | |
165 Debug.WriteLine("DebugProcess.Attach"); | |
166 throw new NotImplementedException(); | |
167 } | |
168 | |
169 public int CanDetach() { | |
170 Debug.WriteLine("DebugProcess.CanDetach"); | |
171 throw new NotImplementedException(); | |
172 } | |
173 | |
174 public int Detach() { | |
175 Debug.WriteLine("DebugProcess.Detach"); | |
176 throw new NotImplementedException(); | |
177 } | |
178 | |
179 public int GetPhysicalProcessId(AD_PROCESS_ID[] pProcessId) { | |
180 Debug.WriteLine("DebugProcess.GetPhysicalProcessId"); | |
181 pProcessId[0] = MakePhysicalProcessId(); | |
182 return VSConstants.S_OK; | |
183 } | |
184 | |
185 public int GetProcessId(out Guid pguidProcessId) { | |
186 Debug.WriteLine("DebugProcess.GetProcessId"); | |
187 pguidProcessId = guid_; | |
188 return VSConstants.S_OK; | |
189 } | |
190 | |
191 public int GetAttachedSessionName(out string pbstrSessionName) { | |
192 Debug.WriteLine("DebugProcess.GetAttachedSessionName"); | |
193 throw new NotImplementedException(); | |
194 } | |
195 | |
196 public int EnumThreads(out IEnumDebugThreads2 ppEnum) { | |
197 Debug.WriteLine("DebugProcess.EnumThreads"); | |
198 throw new NotImplementedException(); | |
199 } | |
200 | |
201 public int CauseBreak() { | |
202 Debug.WriteLine("DebugProcess.CauseBreak"); | |
203 throw new NotImplementedException(); | |
204 } | |
205 | |
206 public int GetPort(out IDebugPort2 ppPort) { | |
207 Debug.WriteLine("DebugProcess.GetPort"); | |
208 ppPort = port_; | |
209 return VSConstants.S_OK; | |
210 } | |
211 | |
212 private AD_PROCESS_ID MakePhysicalProcessId() { | |
213 return new AD_PROCESS_ID { | |
214 dwProcessId = (uint) Pid, | |
215 ProcessIdType = (uint) enum_AD_PROCESS_ID.AD_PROCESS_ID_SYSTEM | |
216 }; | |
217 } | |
218 | |
219 #endregion | |
220 | |
221 #region Private Implementation | |
222 | |
223 private string imagePath_; | |
224 | |
225 // Although the AD_PROCESS_ID structure provides the option to | |
226 // use a GUID pid, the MSVS UI doesn't like anything but | |
227 // ints. | |
228 readonly int pid_; | |
229 | |
230 readonly Guid guid_ = Guid.NewGuid(); | |
231 | |
232 private readonly IDebugPort2 port_; | |
233 | |
234 #endregion | |
235 } | |
236 } | |
OLD | NEW |