我需要在证书链验证期间将自定义自签名根证书标记为受信任,总的来说,我希望尽可能地依赖系统 API。
我创建了一个临时内存存储。
HCERTSTORE certStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, 0, 0);
Run Code Online (Sandbox Code Playgroud)
然后我将自定义根证书放入商店。
CertAddCertificateContextToStore(certStore, rootCertContext, CERT_STORE_ADD_REPLACE_EXISTING, 0);
Run Code Online (Sandbox Code Playgroud)
CertGetCertificateChain MSDN 文档说
hAdditionalStore 用于搜索支持证书和证书信任列表 (CTL) 的任何其他存储的句柄。
据我所知,如果我使用根证书创建 CTL 并将其放入商店,CertGetCertificateChain 将信任它。因此,我在分配的缓冲区中创建根证书 CTL 条目,然后将其复制到std::vector ctlEntries
CertCreateCTLEntryFromCertificateContextProperties(rootCertContext, 0, nullptr, CTL_ENTRY_FROM_PROP_CHAIN_FLAG, nullptr, ctlEntry, &size);
Run Code Online (Sandbox Code Playgroud)
然后我创建 CTL 本身。
const std::wstring ctlID(L"TrustedRoots");
// I do not know what OIDs to use here. I tried different options.
std::vector<LPSTR> usageList;
usageList.push_back(szOID_SORTED_CTL);
usageList.push_back(szOID_PKIX_KP_CLIENT_AUTH);
usageList.push_back(szOID_PKIX_KP_SERVER_AUTH);
CTL_INFO ctlInfo;
ZeroMemory(&ctlInfo, sizeof(ctlInfo));
ctlInfo.dwVersion = CTL_V1;
ctlInfo.SubjectUsage.cUsageIdentifier = static_cast<DWORD>(usageList.size());
ctlInfo.SubjectUsage.rgpszUsageIdentifier = usageList.data();
ctlInfo.ListIdentifier.cbData = static_cast<DWORD>((ctlID.size() + …Run Code Online (Sandbox Code Playgroud) 我尝试通过发送日志消息到syslog
logger -is -t TestApp -p user.error TEST MESSAGE1
Run Code Online (Sandbox Code Playgroud)
然后我检查它是否在那里
tail system.log
...
Apr 12 16:33:00 HOSTNAME TestApp[3024]: TEST MESSAGE1
Run Code Online (Sandbox Code Playgroud)
所以它有效.然后我尝试通过编译的应用程序执行相同的操作.
openlog("TestApp", LOG_PID, LOG_USER);
setlogmask(LOG_UPTO(LOG_DEBUG));
syslog(LOG_ERR, "TEST MESSAGE2");
closelog();
Run Code Online (Sandbox Code Playgroud)
我运行应用程序然后检查system.log
tail system.log
...
Apr 12 16:33:00 HOSTNAME TestApp[3024]: TEST MESSAGE1
....
Run Code Online (Sandbox Code Playgroud)
我在那里找不到"TEST MESSAGE 2".我也尝试通过"syslog"检查它
syslog -s -l er TEST MESSAGE3
Run Code Online (Sandbox Code Playgroud)
结果相同.我无法在日志文件中看到该消息.好.日志设置可能存在一些问题.所以我尝试配置记录到特定文件.我创建/ etc/asl/TestApp
# ASL configuration for TestApp
#
> /var/log/TestApp.log mode=0640 format=bsd rotate=seq compress file_max=1M all_max=5M
#
? [= Sender TestApp] file /var/log/TestApp.log
? [= Sender TestApp] [<= Level debug] …Run Code Online (Sandbox Code Playgroud) 我开发了一个在窗口中显示类似视频的应用程序。我使用在Direct2D 1.1简介中介绍的技术。就我而言,唯一的区别是最终我使用
ID2D1DeviceContext::CreateBitmap
Run Code Online (Sandbox Code Playgroud)
然后我用
ID2D1Bitmap::CopyFromMemory
Run Code Online (Sandbox Code Playgroud)
复制原始RGB数据到它,然后我打电话
ID2D1DeviceContext::DrawBitmap
Run Code Online (Sandbox Code Playgroud)
绘制位图。我使用高质量的三次插值模式D2D1_INTERPOLATION_MODE_HIGH_QUALITY_CUBIC进行缩放以具有最佳图像,但是在某些情况下(RDP,Citrix,虚拟机等),它非常慢并且具有很高的CPU消耗。发生这种情况是因为在这种情况下,使用了非硬件视频适配器。因此,对于非硬件适配器,我正在尝试关闭插值并使用更快的方法。问题是我无法准确检查系统是否具有真正的硬件适配器。
当我打电话D3D11CreateDevice,我用它来与D3D_DRIVER_TYPE_HARDWARE但在虚拟机上它通常返回“微软基础渲染驱动程序”,它是一个软件驱动程序,不使用GPU(它消耗CPU)。因此,目前我检查供应商ID。如果供应商是AMD(ATI),NVIDIA或Intel,那么我将使用三次插值。在另一种情况下,我使用最快的方法,不会消耗很多CPU。
Microsoft::WRL::ComPtr<IDXGIDevice> dxgiDevice;
if (SUCCEEDED(m_pD3dDevice->QueryInterface(...)))
{
Microsoft::WRL::ComPtr<IDXGIAdapter> adapter;
if (SUCCEEDED(dxgiDevice->GetAdapter(&adapter)))
{
DXGI_ADAPTER_DESC desc;
if (SUCCEEDED(adapter->GetDesc(&desc)))
{
// NVIDIA
if (desc.VendorId == 0x10DE ||
// AMD
desc.VendorId == 0x1002 || // 0x1022 ?
// Intel
desc.VendorId == 0x8086) // 0x163C, 0x8087 ?
{
bSupported = true;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
即使在虚拟机中,它也适用于物理(控制台)Windows会话。但是对于RDP会话,如果使用的是真实计算机,IDXGIAdapter仍会返回供应商,但它不使用GPU(我可以通过Process Hacker 2和AMD System Monitor(对于ATI Radeon)看到它),因此在三次插值。如果使用ATI Radeon与Windows 7进行RDP会话,则它比通过物理控制台大10%。
还是我弄错了,RDP以某种方式使用了GPU资源,这就是为什么它通过IDXGIAdapter :: GetDesc返回真正的硬件适配器的原因?
DirectDraw
我也看了DirectX诊断工具。看起来“ DirectDraw Acceleration”信息字段恰好返回了我所需要的。如果是物理(控制台)会话,则显示“已启用”。对于RDP和虚拟机(无硬件视频加速)会话,它会显示“不可用”。我查看了来源,从理论上讲我可以使用验证算法。但这实际上是DirectDraw,我没有在应用程序中使用它。我想使用直接链接到ID3D11Device,IDXGIDevice,IDXGIAdapter等的东西。
IDXGIAdapter1 :: GetDesc1和DXGI_ADAPTER_FLAG
我也尝试使用IDXGIAdapter1 :: GetDesc1并检查标志。 …