热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

有没有一种方法可以使用CredUIPromptForWindowsCredentialsW而不解压缩缓冲区(C++/CLR)?

我正在编写的一种软件即将采取措施,要求当前登录的用户实际上是采取该措施的用

我正在编写的一种软件即将采取措施,要求当前登录的用户实际上是采取该措施的用户。因此,我想让Windows在允许操作继续之前先询问当前用户的密码或生物识别信息或其他信息。

我在另一篇文章(以下代码)中为UserConsentVerifier使用了互操作性。

using System;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Security.Credentials.UI;
namespace UWPInterop
{
//MIDL_INTERFACE("39E050C3-4E74-441A-8DC0-B81104DF949C")
//IUserConsentVerifierInterop : public IInspectable
//{
//public:
// virtual HRESULT STDMETHODCALLTYPE RequestVerificationForWindowAsync(
// /* [in] */ HWND appWindow,// /* [in] */ HSTRING message,// /* [in] */ REFIID riid,// /* [iid_is][retval][out] */ void** asyncOperation) = 0;
//};
[System.Runtime.InteropServices.Guid("39E050C3-4E74-441A-8DC0-B81104DF949C")]
[System.Runtime.InteropServices.InterfaceType(System.Runtime.InteropServices.ComInterfaceType.InterfaceIsIInspectable)]
public interface IUserConsentVerifierInterop
{
IAsyncOperation RequestVerificationForWindowAsync(IntPtr appWindow,[MarshalAs(UnmanagedType.HString)] string Message,[In] ref Guid riid);
}
//Helper to initialize UserConsentVerifier
public static class UserConsentVerifierInterop
{
public static IAsyncOperation RequestVerificationForWindowAsync(IntPtr hWnd,string Message)
{
IUserConsentVerifierInterop userCOnsentVerifierInterop= (IUserConsentVerifierInterop)WindowsRuntimeMarshal.GetactivationFactory(typeof(UserConsentVerifier));
Guid guid = typeof(IAsyncOperation).GUID;
return userConsentVerifierInterop.RequestVerificationForWindowAsync(hWnd,Message,ref guid);
}
}
}

如果设置了Windows Hello,此方法就可以正常工作。如果没有错误或类似错误,它将返回DeviceNotPresent。尝试查找提供Windows密码的替代方法。该代码有效,但是我对应用程序内存中使用的密码并不满意。 (C ++ / CLR)

bool ValidateUser(String ^caption,String ^message)
{
bool result = false;
String^ username = WindowsIdentity::getcurrent()->Name;
std::wstring strusername = marshal_as(username);
std::wstring strCaption = marshal_as(caption);
std::wstring strMessage = marshal_as(message);
CREDUI_INFOW info;
ZeroMemory(&info,sizeof(info));
info.cbSize = sizeof(info);
info.pszMessageText = strMessage.c_str();
info.pszCaptiOnText= strCaption.c_str();
ULONG authPackage = 0;
LPVOID pOut;
ULONG bufSize;
DWORD inBuffer = 0;
std::vector credBuffer;
if (!CredPackAuthenticationBufferW(CRED_PACK_PROTECTED_CREDENTIALS,(LPWSTR)strusername.c_str(),L"",NULL,&inBuffer)
&& ERROR_INSUFFICIENT_BUFFER == ::GetLastError())
{
credBuffer.resize(inBuffer);
if (!CredPackAuthenticationBufferW(CRED_PACK_PROTECTED_CREDENTIALS,credBuffer.data(),&inBuffer))
{
return false;
}
}
DWORD dwResult = CredUIPromptForWindowsCredentialsW(&info,&authPackage,inBuffer,&pOut,&bufSize,CREDUIWIN_GENERIC | CREDUIWIN_IN_CRED_ONLY);
if (dwResult == ERROR_SUCCESS)
{
DWORD dwUserLength = 0;
DWORD dwDomainLength = 0;
DWORD dwPasswordLength = 0;
try
{
if (!::CredUnPackAuthenticationBufferW(CRED_PACK_PROTECTED_CREDENTIALS,pOut,bufSize,nullptr,&dwUserLength,&dwDomainLength,&dwPasswordLength)
&& ERROR_INSUFFICIENT_BUFFER == ::GetLastError())
{
std::vector bufferUser(dwUserLength);
std::vector bufferDomain(dwDomainLength);
std::vector bufferPassword(dwPasswordLength);
if (::CredUnPackAuthenticationBufferW(CRED_PACK_PROTECTED_CREDENTIALS,bufferUser.data(),bufferDomain.data(),bufferPassword.data(),&dwPasswordLength))
{
HANDLE hToken;
std::wstring strusername = bufferUser.data();
std::wstring strDomain;
if (bufferDomain.size() == 0)
{
std::wstring::size_type pos = strusername.find(L'\\');
if (pos != std::wstring::npos)
{
strDomain = strusername.substr(0,pos);
strusername = strusername.substr(pos + 1,strusername.size() - pos - 1);
}
}
else
{
strDomain = bufferDomain.data();
}
try
{
if (::LogonUserW(strusername.c_str(),strDomain.c_str(),LOGON32_LOGON_INTERactIVE,LOGON32_PROVIDER_DEFAULT,&hToken))
result = true;
}
catch (...) // Catch so memory can be cleared
{
}
ClearBuffer(bufferUser.data(),dwUserLength);
ClearBuffer(bufferDomain.data(),dwDomainLength);
ClearBuffer(bufferPassword.data(),dwPasswordLength);
}
}
}
catch(...) // Catch so memory can be cleared
{
}
ClearBuffer(pOut,bufSize);
CoTaskMemFree(pOut);
}
return result;
}

有没有一种方法可以使用CredUIPromptForWindowsCredentialsW而不解压缩它返回来验证登录名的缓冲区?





推荐阅读
author-avatar
梦-回忆-记忆-梦_429
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有