使网络摄像头设备对过程不可见

时间:2018-10-09 20:15:15

标签: windows powershell winapi

某些上下文:

我有一个应用程序可以在Windows 10 64bit(无论设备枚举期间索引0是什么)上打开第一个网络摄像头设备,并对帧进行一些处理。该应用程序的源代码不可访问。

问题:

我需要使该应用程序同时使用两个网络摄像头。我认为也许可以执行以下操作:

  1. 隐藏网络摄像头2
  2. 运行应用程序(启动摄像头1)
  3. 隐藏网络摄像头1,取消隐藏网络摄像头2
  4. 运行应用程序(启动摄像头2)

有没有一种方法可以不中断相机的操作?请注意,这两个应用程序同时运行,因此不能禁用相机。可以调用Win32 api或在PowerShell中执行此操作。

谢谢!

1 个答案:

答案 0 :(得分:0)

由于对我的原始问题发表了评论,我设法通过加入CM_Get_Device_Interface_List_ExW Win32 API调用来解决了问题。

我必须验证正在调用什么API,因此我使用了API跟踪器工具(API监视器v2 64位)。调试器也应该工作,但是由于某些原因,我的VS调试器没有显示任何符号(可能缺少pdb)。

我试图挂接到的原始进程是用C#编写的,所以我通过包含EasyHook的注入的C#DLL挂接到了调用中。这是我的代码段(实际注入代码未包括在内):

using System;
using System.Runtime.InteropServices;

using EasyHook;

public class HookDevices : IEntryPoint
{
    LocalHook FunctionLocalHook;

    // construct this to hook into calls
    HookDevices()
    {
        try
        {
            FunctionLocalHook = LocalHook.Create(
                LocalHook.GetProcAddress("CfgMgr32.dll", "CM_Get_Device_Interface_List_ExW"),
                new FunctionHookDelegate(CM_Get_Device_Interface_List_Ex_Hooked),
                this);
            FunctionLocalHook.ThreadACL.SetExclusiveACL(new Int32[] { 0 });
        }
        catch (Exception ExtInfo)
        {
            Debug.LogException(ExtInfo);
            return;
        }
    }

    [UnmanagedFunctionPointer(CallingConvention.StdCall,
        CharSet = CharSet.Unicode,
        SetLastError = true)]
    delegate uint FunctionHookDelegate(
        ref Guid interfaceClassGuid,
        string deviceID,
        IntPtr buffer,
        uint bufferLength,
        uint flags,
        IntPtr hMachine);

    [DllImport("CfgMgr32.dll",
        CharSet = CharSet.Unicode,
        SetLastError = true,
        CallingConvention = CallingConvention.StdCall)]
    static extern uint CM_Get_Device_Interface_List_ExW(
        ref Guid interfaceClassGuid,
        string deviceID,
        IntPtr buffer,
        uint bufferLength,
        uint flags,
        IntPtr hMachine);

    // this is where we are intercepting all API accesses!
    static uint CM_Get_Device_Interface_List_Ex_Hooked(
        ref Guid interfaceClassGuid,
        string deviceID,
        IntPtr buffer,
        uint bufferLength,
        uint flags,
        IntPtr hMachine)
    {
        // pass-through original API
        uint ret = CM_Get_Device_Interface_List_ExW(
            ref interfaceClassGuid,
            deviceID,
            buffer,
            bufferLength,
            flags,
            hMachine);
        // do custom logic here and re-arrange "buffer"
        return ret;
    }
}