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排除掉原始内容. 这时发现的注册表区别点,大概有几百处之多. 剩下就是实验, 能生效的注册表项就在这几百处区别之间. 可以用程序写, 也可以手工导入注册表差异. 这时比拼的就是实验方法和耐力了.
对找出这区别的同事太佩服了.
相关文章推荐
- Working with Group Policy Objects Programmatically - simple C++ example illustrating how to modify a
- Add a favourite to Internet Explorer via group policy Windows 2003
- Windows Sqlserver Automatic Log Audit Via C/C++
- Windows Via C/C++:用户模式下的线程同步——临界区 Critical Sections
- 年底好书真多--《Windows via C/C++ 》
- Windows Via C/C++ Part Ⅰ Chapter4: 进程—第一个Windows程序(1)
- Windows Via C/C++:内核模式下的线程同步——事件内核对象
- OD: Windows Security Techniques & GS Bypassing via C++ Virtual Function
- Adding Pop up blocker exception via group policy
- Windows Via C/C++ 读书笔记 3
- Windows via C/C++.pdf
- 《Windows via C/C++》学习笔记 —— Windows 线程
- Windows Via C/C++:用户模式下的线程同步——原子操作:Interlocked函数族
- Windows via C/C++ notes
- Windows Via C/C++:用户模式下的线程同步——原子操作:Interlocked函数族
- How to configure the windows firewall using group policies
- 《Windows via C/C++》学习笔记 —— 内核对象的“线程同步”之“信号量”
- 《Windows via C/C++》学习笔记 —— “线程同步”之“检测死锁”
- Windows via C/C++ 学习(10)子进程
- Windows via C/C++ 学习(11)管理员用户作为标准用户运行