use c++ automatic configure RemoteX USB redirection via modify windows policy group

来源:互联网 发布:电脑写小说的软件 编辑:程序博客网 时间:2024/06/18 10:36

今天用注册表快照比对工具找到了usb设备重定向策略修改的注册表键值, 但是手工修改是不生效的. 查资料, cppblog上的一个同学给出了例子,只不过注册表键值不同. 就改改键值, 就可以实现和手工操作策略编辑器gpedit一样的效果.

注册表监测工具的选择

开始用regshot, 通过操作前后的快照, 可以找到操作点,但是要边猜边找,不方便.
后来看cppblog那同学用regfromapp, 下载了一个regfromappx64, 是针对进程的(本实验选mmc.exe, gpedit启动后,进程是mmc.exe), 操作完, 立刻有提示. 还可以保存成注册表文件.reg, 很方便.

工程和工具下载点

工程: src_usb_redirection_enable_or_disable_console.zip
注册表监测工具:regfromapp-x64.zip

效果

在测试程序中每执行一次bool usb_redirection(bool bEnable), 就可以重新打开gpedit去看看, 好使.

工程预览

// usb_redirection_enable_or_disable_console.cpp : Defines the entry point for the console application.// @brief 对策略组中的usb重定向选项进行允许或禁止//          编译环境 : vs2015 vc++ console + win10x64//          实验环境 : win10x64 + gpedit#include "stdafx.h"#include <windows.h>#include <stdlib.h>#include <stdio.h>#include "prj_const_define.h"// @fn usb_redirection// @brief 对策略组中的usb重定向进行允许或禁止// @note//      usb_redirection 函数要以管理员权限来运行//      工程属性 => Linker => Manifest File => UAC Execution Level => requireAdministrator//      查看函数效果: cmd => gpedit => 计算机配置 => 管理模板 => Windows组件 => 远程桌面管理 => //              远程桌面连接客户端 => RemoteX USB 设备重定向 => //              右面键值(允许此计算机中支持的其他RemoteFX USB 设备的RDP重定向)// @param bool bEnable, true = 允许usb重定向, false = 禁止usb重定向// @return bool, true = 成功, flase = 失败bool usb_redirection(bool bEnable);// @fn please_check_gpedit// @brief 辅助函数, 请使用者检查gpedit中的usb重定向设置的效果, 按任意键返回// @param const char* pszTip, 提示信息// @return voidvoid please_check_gpedit(const char* pszTip);int main(){    bool bRc = false;    bRc = usb_redirection(true);    if (!bRc) {        printf("usb_redirection failed, please run it as admin user\n");    }    else {        please_check_gpedit("gpedit's usb redirection is open now!");    }    bRc = usb_redirection(false);    if (!bRc) {        printf("usb_redirection failed, please run it as admin user\n");    }    else {        please_check_gpedit("gpedit's usb redirection is close now!");    }    bRc = usb_redirection(true);    if (!bRc) {        printf("usb_redirection failed, please run it as admin user\n");    }    else {        please_check_gpedit("gpedit's usb redirection is open now!");    }    system("pause");    return 0;}bool usb_redirection(bool bEnable){    bool brc1 = false;    bool brc2 = false;    DWORD dwValue = 0;    HRESULT hr = NULL;    IGroupPolicyObject* pGpEdit = NULL;    HKEY hKeyLM = NULL;    HKEY hKeyObj = NULL;    GUID guid_ex = REGISTRY_EXTENSION_GUID;    GUID guid_my_prj = MY_PRJ_GUID;    try {        hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);        if (FAILED(hr)) {            throw("Failed to initialize COM library");        }        hr = CoCreateInstance(                CLSID_GroupPolicyObject,                NULL,                CLSCTX_INPROC_SERVER,                IID_IGroupPolicyObject,                (LPVOID*)&pGpEdit);        if (NULL == pGpEdit) {            throw("(NULL == pGpEdit)");        }        pGpEdit->OpenLocalMachineGPO(GPO_OPEN_LOAD_REGISTRY);        pGpEdit->GetRegistryKey(GPO_SECTION_MACHINE, &hKeyLM);        if (NULL == hKeyLM) {            throw("(NULL == hKeyLM)");        }        RegCreateKeyEx(hKeyLM, L"SOFTWARE\\Policies\\Microsoft\\Windows NT\\Terminal Services\\Client",            0, NULL, 0, KEY_SET_VALUE | KEY_QUERY_VALUE, NULL, &hKeyObj, NULL);        if (NULL == hKeyObj) {            throw("(NULL == hKeyObj)");        }        dwValue = bEnable ? 1 : 0;        RegSetKeyValue(hKeyObj, NULL, L"fUsbRedirectionEnableMode", REG_DWORD, &dwValue, sizeof(dwValue));        pGpEdit->Save(TRUE, TRUE, &guid_ex, &guid_my_prj);        brc1 = true;    }    catch (...) {        printf("1 : catch ...\n");    }    try {        if (NULL != hKeyObj) {            RegCloseKey(hKeyObj);        }        if (NULL != hKeyLM) {            RegCloseKey(hKeyLM);        }        if (NULL != pGpEdit) {            pGpEdit->Release();        }        brc2 = true;    }    catch (...) {        printf("2 : catch ...\n");    }    return (brc1 && brc2);}void please_check_gpedit(const char* pszTip){    if (NULL != pszTip) {        printf("please check : %s\n", pszTip);        printf("press any key do next step\n");        getchar();    }}
// @file prj_const_define.h#ifndef __PRJ_CONST_DEFINE_H__#define __PRJ_CONST_DEFINE_H__#include <initguid.h>#include <guiddef.h>#include <gpedit.h>#define MY_DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \        const GUID name \                = { l, w1, w2, { b1, b2,  b3,  b4,  b5,  b6,  b7,  b8 } }MY_DEFINE_GUID(MY_PRJ_GUID, 0xf7a4217a, 0x72cd, 0x44f1, 0xb5, 0x67, 0xa5, 0xeb, 0x9, 0x54, 0x34, 0x55);#endif // #ifndef __PRJ_CONST_DEFINE_H__

总结

用注册表监视工具看到的不是设置策略的全过程.
只用组策略API得到的注册表分支句柄去设置”通过监测工具得到的注册表项”是不好使的, 是无法使”RemoteX USB redirection”有实际效果的. 换句话说: 只设置监测工具得到的注册表项, 只会在gpedit的UI中看到同样的效果, 但是实际上没生效.
因为regfromapp监测的注册表项只针对mmc, 在手工设置组策略时, 还有别的进程写了注册表项. 这已经不是我实验出来的基础内容了, 沉默是必须的.
要解决这种写入注册表使系统有不同效果的通用解决方法 : 在一个干净的系统上, 做一个注册表大项(注册表根节点下就4,5个大项)导出为org.reg, 然后手工用MS提供的gpedit或其他MS内建的工具进行UI上的设置. 设置完成后, 导出注册表各大项为文件before_reboot.reg. 重新启动计算机后, 进入桌面, 再导出注册表各大项为文件after_reboot.reg.
这时, 对after_reboot.reg, before_reboot.reg进行文本比对(用BC), 同时结合org.reg排除掉原始内容. 这时发现的注册表区别点,大概有几百处之多. 剩下就是实验, 能生效的注册表项就在这几百处区别之间. 可以用程序写, 也可以手工导入注册表差异. 这时比拼的就是实验方法和耐力了.
对找出这区别的同事太佩服了.

原创粉丝点击