make webcam device invisible to a process

六月ゝ 毕业季﹏ 提交于 2021-01-29 14:00:19

问题


Some context:

I have an application that opens the first webcam device on Windows 10 64bit (whatever index 0 is during enumeration of devices) and does some processing on the frames. The application's source code is not accessible.

Question:

I need to make this application to work with two webcams at the same time. I thought maybe there is a way to do the following:

  1. hide webcam 2
  2. run application (picks up webcam 1)
  3. hide webcam 1, unhide webcam 2
  4. run application (picks up webcam 2)

Is there a way to do this without interrupting camera's operation? Note that both applications are running at the same time so hard-disabling a camera is not an option. Calling either a Win32 api or doing this in PowerShell is acceptable.

Thanks!


回答1:


Thanks to comments on my original question, I managed to solve my problem by hooking into CM_Get_Device_Interface_List_ExW Win32 API call.

I had to verify what API is being called, so I used and API tracer tool (API monitor v2 64bit). Debugger should work too but for some reason my VS debugger did not show me any symbols (possibly missing pdbs).

The original process I tried to hook into is written in C# so I hooked into the call via an injected C# DLL containing EasyHook. Here is my code snippet (actual injection code left out):

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;
    }
}


来源:https://stackoverflow.com/questions/52728671/make-webcam-device-invisible-to-a-process

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!