Skip to content

Commit af87ea0

Browse files
committed
[ServiceManager] Add DynaLog logging
1 parent 2eabf62 commit af87ea0

File tree

2 files changed

+47
-3
lines changed

2 files changed

+47
-3
lines changed

Elements/ServiceManagement/WindowsServiceHelper.vb

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,10 @@ Module WindowsServiceHelper
2222
Private PrivilegeMappingDictionary As New Dictionary(Of String, String)
2323

2424
Sub FillInConstants()
25+
DynaLog.LogMessage("Clearing dictionaries...")
2526
PrivilegeConstantDictionary.Clear()
2627
PrivilegeMappingDictionary.Clear()
28+
DynaLog.LogMessage("Filling privilege constant dictionary...")
2729
PrivilegeConstantDictionary.Add("SE_ASSIGNPRIMARYTOKEN_NAME",
2830
New NTSecurityPrivilegeConstant(
2931
"SeAssignPrimaryTokenPrivilege",
@@ -205,15 +207,18 @@ Module WindowsServiceHelper
205207
"Not applicable",
206208
"Required to read unsolicited input from a terminal device."))
207209

210+
DynaLog.LogMessage("Filling privilege mapping dictionary...")
208211
For Each key As String In PrivilegeConstantDictionary.Keys
209212
Dim privilegeConstant As NTSecurityPrivilegeConstant = PrivilegeConstantDictionary(key)
210213
PrivilegeMappingDictionary.Add(privilegeConstant.ConstantNameText, key)
211214
Next
212215
End Sub
213216

214217
Private Function ResolveIndirectString(source As String) As String
218+
DynaLog.LogMessage("Resolving indirect string " & source & "...")
215219
Dim buffer As New StringBuilder(260)
216220
Dim hr As Integer = NativeMethods.SHLoadIndirectString(source, buffer, buffer.Capacity, IntPtr.Zero)
221+
DynaLog.LogMessage("Resolver Result: " & hr)
217222
If hr = 0 Then
218223
Return buffer.ToString()
219224
Else
@@ -222,10 +227,14 @@ Module WindowsServiceHelper
222227
End Function
223228

224229
Private Function ParseInfLine(line As String) As Tuple(Of String, String)
230+
DynaLog.LogMessage("Parsing provided INF file line...")
231+
DynaLog.LogMessage("- Line: " & line)
225232
Dim noComment = line.Split(";"c)(0).Trim()
226233
Dim parts = noComment.Split(","c)
227234

235+
DynaLog.LogMessage("Line Parts Length: " & parts.Length)
228236
If parts.Length < 2 Then
237+
DynaLog.LogMessage("Line Parts Length below minimum threshold.")
229238
Return Nothing
230239
End If
231240

@@ -236,9 +245,13 @@ Module WindowsServiceHelper
236245
End Function
237246

238247
Private Function ResolveInfToken(infPath As String, token As String) As String
248+
DynaLog.LogMessage("Resolving INF File Tokens...")
249+
DynaLog.LogMessage("- INF File Path: " & infPath)
250+
DynaLog.LogMessage("- Token: " & token)
239251
Try
240252
Dim key As String = token.Trim("%"c)
241253

254+
DynaLog.LogMessage("Opening file for read access...")
242255
Dim lines As String() = File.ReadAllLines(infPath)
243256
Dim inStrings As Boolean = False
244257
For Each line In lines
@@ -253,12 +266,13 @@ Module WindowsServiceHelper
253266

254267
Dim match = Regex.Match(lineTrim, "^(?<k>[^\s=]+)\s*=\s*""?(?<v>[^""]+)""?$")
255268
If match.Success AndAlso match.Groups("k").Value.Equals(key, StringComparison.OrdinalIgnoreCase) Then
269+
DynaLog.LogMessage("Found a suitable match! Returning...")
256270
Return match.Groups("v").Value
257271
End If
258272
End If
259273
Next
260274
Catch ex As Exception
261-
275+
DynaLog.LogMessage("Could not resolve token. Error message: " & ex.Message)
262276
End Try
263277
Return ""
264278
End Function
@@ -267,21 +281,31 @@ Module WindowsServiceHelper
267281
' For the required privileges a service may have, we have to fill in the constants first so that we don't have things like
268282
' "SeUndockPrivilege", "SeShutdownPrivilege"; but rather "Remove computer from docking station", and so on... we want the
269283
' friendly things.
284+
DynaLog.LogMessage("Preparing to get all services in this image...")
285+
DynaLog.LogMessage("- Mount Path: " & MountPath)
286+
DynaLog.LogMessage("Filling dictionaries...")
270287
FillInConstants()
271288
Dim serviceList As New List(Of WindowsService)
272289

273290
' Time to load up a registry hive
291+
DynaLog.LogMessage("Loading mount path SYSTEM hive...")
274292
If RegistryHelper.LoadRegistryHive(Path.Combine(MountPath, "Windows", "system32", "config", "SYSTEM"), "HKLM\zSYS") = 0 Then
293+
DynaLog.LogMessage("Load operation succeeded. Continuing...")
275294
Try
276295
' First we need to grab the default control set of the target image
296+
DynaLog.LogMessage("Determining default control set...")
277297
Dim DefaultControlSet As Integer = RegistryHelper.GetDefaultControlSet("zSYS")
298+
DynaLog.LogMessage("Determined control set: " & DefaultControlSet)
278299
If DefaultControlSet = -1 Then
300+
DynaLog.LogMessage("Control set is wrong.")
279301
Throw New Exception("Registry control set could not be obtained")
280302
End If
281303
' We only document a maximum of 999 control sets. CurrentControlSet is not a thing in an offline system, as the registry
282304
' subsystems guess the control set to use based on values in HKLM\SYSTEM\Select.
305+
DynaLog.LogMessage("Opening mount path services key for read access...")
283306
Dim ServiceRk As RegistryKey = Registry.LocalMachine.OpenSubKey(String.Format("zSYS\ControlSet{0}\Services", DefaultControlSet.ToString().PadLeft(3, "0")), False)
284307
' For some stupid reason, .NET keys are stored in HKLM\SYSTEM\ControlSet<nnn>\Services. GUID keys are also not allowed
308+
DynaLog.LogMessage("Getting service names...")
285309
Dim ServiceNames() As String = ServiceRk.GetSubKeyNames().Where(Function(serviceName) Not serviceName.StartsWith(".NET", StringComparison.OrdinalIgnoreCase) AndAlso Not serviceName.StartsWith("{")).ToArray()
286310
ServiceRk.Close()
287311

@@ -305,26 +329,35 @@ Module WindowsServiceHelper
305329
' it will show that value.
306330
serviceImagePath = ServiceInfoRk.GetValue("ImagePath", "", RegistryValueOptions.DoNotExpandEnvironmentNames)
307331
If serviceImagePath = "" Then
332+
DynaLog.LogMessage("The service image path cannot be obtained.")
308333
' This "service" is bogus
309334
Continue For
310335
End If
311336

312337
serviceEntryName = ServiceName
313338
serviceDisplayName = ServiceInfoRk.GetValue("DisplayName", "")
339+
DynaLog.LogMessage("Raw service display name: " & serviceDisplayName)
314340
If serviceDisplayName.StartsWith("@") AndAlso serviceDisplayName.ToLowerInvariant().Contains(".inf") Then
341+
DynaLog.LogMessage("Raw display name points to a device driver. Parsing...")
315342
Dim parsedInf As Tuple(Of String, String) = ParseInfLine(serviceDisplayName)
316343

317344
If parsedInf IsNot Nothing Then
345+
DynaLog.LogMessage("We have grabbed the path and the token. Continuing...")
318346
Dim resolvedString As String = ResolveInfToken(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), "INF", parsedInf.Item1), parsedInf.Item2)
347+
DynaLog.LogMessage("- Resolved string (using current system): " & resolvedString)
319348
If Not String.IsNullOrEmpty(resolvedString) Then
349+
DynaLog.LogMessage("We grabbed the resolved string. Using that...")
320350
serviceDisplayName = resolvedString
321351
End If
322352
End If
323353
ElseIf serviceDisplayName.StartsWith("@") Then
354+
DynaLog.LogMessage("Raw display name indicates an indirect string. Parsing...")
324355
serviceDisplayName = ResolveIndirectString(serviceDisplayName)
325356
End If
326357
serviceDescription = ServiceInfoRk.GetValue("Description", "")
358+
DynaLog.LogMessage("Raw service description: " & serviceDescription)
327359
If serviceDescription.StartsWith("@") Then
360+
DynaLog.LogMessage("Raw description indicates an indirect string. Parsing...")
328361
serviceDescription = ResolveIndirectString(serviceDescription)
329362
End If
330363
serviceObjectName = ServiceInfoRk.GetValue("ObjectName", "")
@@ -339,8 +372,10 @@ Module WindowsServiceHelper
339372
serviceFailActionByteArr = ServiceInfoRk.GetValue("FailureActions", New Byte() {})
340373

341374
Dim serviceRequiredPrivilegeList As New List(Of NTSecurityPrivilegeConstant)
375+
DynaLog.LogMessage("Privilege items defined by the service: " & serviceRequiredPrivilegesString.Count)
342376

343377
If serviceRequiredPrivilegesString.Count > 0 Then
378+
DynaLog.LogMessage("This service defines privileges. Getting privilege constant representations...")
344379
' Parse the items themselves to keys that are available in the dictionary we filled
345380
' stuff in
346381
For Each serviceRequiredPrivilegeString In serviceRequiredPrivilegesString
@@ -352,6 +387,7 @@ Module WindowsServiceHelper
352387
Next
353388
End If
354389

390+
DynaLog.LogMessage("Adding service " & serviceEntryName & " to service list...")
355391
serviceList.Add(New WindowsService(serviceEntryName,
356392
serviceDisplayName,
357393
serviceDescription,
@@ -386,21 +422,28 @@ Module WindowsServiceHelper
386422
secondDelay As Long = 0,
387423
subsequentDelay As Long = 0
388424
Dim resetDelay As Integer = 0
425+
DynaLog.LogMessage("Parsing specified failure action byte array...")
426+
DynaLog.LogMessage("Byte array length: " & FailureActions.Count)
389427

390428
If FailureActions.Count >= 1 Then
429+
DynaLog.LogMessage("Some failure actions have been defined.")
391430
Try
431+
DynaLog.LogMessage("Getting service reset delay...")
392432
resetDelay = GetDelay(FailureActions.Skip(0).Take(4).ToArray())
393433

394434
' We have to get the number of byte elements twice because undefined failure measures
395435
' cause our byte array to be smaller than expected, therefore causing indexes out of bounds.
436+
DynaLog.LogMessage("Getting 1st failure action and delay (in ms)...")
396437
firstFail = FailureActions(20)
397438
firstDelay = GetDelay(FailureActions.Skip(24).Take(4).ToArray())
398439
If FailureActions.Count > 28 Then
440+
DynaLog.LogMessage("Byte array is long enough for second failure measures. Getting 2nd failure action and delay (in ms)...")
399441
' We have defined second failure measures
400442
secondFail = FailureActions(28)
401443
secondDelay = GetDelay(FailureActions.Skip(32).Take(4).ToArray())
402444
End If
403445
If FailureActions.Count > 36 Then
446+
DynaLog.LogMessage("Byte array is long enough for subsequent failure measures. Getting subsequent failure actions and delays (in ms)...")
404447
' We have defined subsequent failure measures
405448
subsequentFails = FailureActions(36)
406449
subsequentDelay = GetDelay(FailureActions.Skip(40).Take(4).ToArray())
@@ -415,6 +458,7 @@ Module WindowsServiceHelper
415458
End Function
416459

417460
Private Function GetDelay(ByteArray As Byte()) As Long
461+
DynaLog.LogMessage("Getting numeric delay from our byte array...")
418462
Dim binary As String = ""
419463

420464
For x = ByteArray.Length - 1 To 0 Step -1

Panels/Img_Ops/Services/ServiceManagementForm.vb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,9 +97,9 @@
9797
Dim handle As IntPtr = MainForm.GetWindowHandle(Me)
9898
If MainForm.IsWindowsVersionOrGreater(10, 0, 18362) Then MainForm.EnableDarkTitleBar(handle, CurrentTheme.IsDark)
9999

100+
DynaLog.DisableLogging()
100101
ServiceList = WindowsServiceHelper.GetServiceList(MainForm.MountDir)
101-
102-
'MsgBox("Services: " & ServiceList.Count)
102+
DynaLog.EnableLogging()
103103

104104
For Each Service In ServiceList
105105
ListView1.Items.Add(New ListViewItem(New String() {Service.Name, Service.DisplayName, Service.Description, Service.StartTypeToString}))

0 commit comments

Comments
 (0)