2017-02-19 14 views
1

Я пытаюсь преобразовать косвенные строки в свойстве Grouping правил брандмауэра, возвращенных HNetCfg.FwPolicy2. В PowerShell:Как загрузить строку ресурса с помощью косвенной строки?

$fw = New-Object -ComObject 'HNetCfg.FwPolicy2' 
$fw.Rules | Select-Object -ExpandProperty 'Grouping' | Select-Object -Unique 

Возвращает то, что MSDN docs refer to as "indirect strings":

@mqutil.dll,-6102 
@%windir%\system32\inetsrv\iisres.dll,-30503 
@%windir%\system32\inetsrv\iisres.dll,-30501 
@%ProgramFiles%\Hyper-V\SnapInAbout.dll,-211 
@FirewallAPI.dll,-32752 

Как преобразовать эти косвенные строки для фактических имен групп в управляемом коде?

Я пытаюсь использовать GetModuleHandle, чтобы загрузить модуль/узел, а затем использовать LoadString, чтобы загрузить строку, но LoadString не загружает ресурс. Вот мой код:

[DllImport("kernel32.dll", CharSet = CharSet.Auto)] 
private static extern IntPtr GetModuleHandle(string lpModuleName); 

[DllImport("user32.dll", CharSet = CharSet.Auto)] 
static extern int LoadString(IntPtr hInstance, uint uID, StringBuilder lpBuffer, int nBufferMax); 

[DllImport("kernel32.dll")] 
private static extern uint GetLastError(); 

public static string GetGroupingFromResource(string resourceInfo) 
{ 
    if (String.IsNullOrEmpty(resourceInfo)) 
    { 
     return resourceInfo; 
    } 

    var matches = Regex.Match(resourceInfo, @"^@([^,]+),-(\d+)$"); 
    if (! matches.Success) 
    { 
     return resourceInfo; 
    } 

    var modulePath = matches.Groups[1].Value; 
    UInt32 resourceID; 
    if (!UInt32.TryParse(matches.Groups[2].Value, out resourceID)) 
    { 
     return resourceInfo; 
    } 

    resourceID += 10000; 

    Console.Out.WriteLine(string.Format("Assembly Path: {0}", modulePath)); 
    Console.Out.WriteLine(string.Format("Resource ID: {0}", resourceID)); 

    modulePath = Environment.ExpandEnvironmentVariables(modulePath); 

    var searchPaths = Environment.GetEnvironmentVariable("PATH").Split(';'); 
    if (! System.IO.Path.IsPathRooted(modulePath)) 
    { 
     foreach (var searchPath in searchPaths) 
     { 
      var fullModulePath = System.IO.Path.Combine(searchPath, modulePath); 
      if (System.IO.File.Exists(fullModulePath)) 
      { 
       modulePath = fullModulePath; 
       break; 
      } 
     } 
    } 

    Console.Out.WriteLine(string.Format("Module Path: {0}", modulePath)); 
    var moduleHandle = GetModuleHandle(modulePath); 
    var lastError = GetLastError(); 
    Console.Out.WriteLine("Last Error: {0}", lastError); 
    if (lastError != 0x0) 
    { 
     return null; 
    } 

    var grouping = new StringBuilder(); 
    LoadString(moduleHandle, resourceID, grouping, 255); 
    lastError = GetLastError(); 
    Console.Out.WriteLine("Last Error: {0}", lastError); 
    if (lastError != Win32ErrorCodes.Ok) 
    { 
     return null; 
    } 

    Console.Out.WriteLine(grouping.ToString()); 
    return grouping.ToString(); 

} 
+0

вам нужно использовать [SHLoadIndirectString] (https://msdn.microsoft.com/en-us/library/windows/desktop/bb759919 (v = vs.85) .aspx) – RbMm

+0

на C++-коде, как этот 'WCHAR sz [1024]; if (S_OK == SHLoadIndirectString (L" @ FirewallAPI.dll, -32752 ", sz, RTL_NUMBER_OF (sz), 0)) {..}' – RbMm

+0

@RbMm Если вы добавите это в качестве ответа, я приму это. Однако не код C++. –

ответ

0
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Runtime.InteropServices; 

namespace ConsoleApp 
{ 
    class Program 
    { 
     [DllImport("shlwapi.dll", CharSet = CharSet.Unicode, ExactSpelling = true)] 
     public static extern int SHLoadIndirectString(string pszSource, StringBuilder pszOutBuf, int cchOutBuf, IntPtr ppvReserved); 

     static void Main(string[] args) 
     { 
      StringBuilder buffer = new StringBuilder(1024); 

      string resourcePath = "@FirewallAPI.dll,-32752"; 

      int result = SHLoadIndirectString(resourcePath, buffer, buffer.Capacity, IntPtr.Zero); 

      if (result == 0) Console.WriteLine(buffer.ToString()); // return "Network Discovery" on Windows 10 (1607) 

      Console.ReadKey(); 
     } 
    } 
}