您的位置:首页 > 编程语言 > C语言/C++

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

2017-08-23 02:01 453 查看

今天用注册表快照比对工具找到了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 void
void 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排除掉原始内容. 这时发现的注册表区别点,大概有几百处之多. 剩下就是实验, 能生效的注册表项就在这几百处区别之间. 可以用程序写, 也可以手工导入注册表差异. 这时比拼的就是实验方法和耐力了.

对找出这区别的同事太佩服了.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: