本次小学期的题目是windows下的凭证改编。本人负责的是Win7 下的credentials Provider 的编写以及其他杂七杂八的工作。当然给我印象最深的就是credentials provider的部分。作为一个比较新的技术(个人感觉在现在中国的局域网上能找的信息中,只要是在xp之后的技术,资料都是少得可怜。),资料少的可怜。在百度,这个关键词到了第三页的信息中中文信息就没有用了。谷歌被墙了,实际上在谷歌中,基本上也找不到有用的中文信息。至于在msdn中貌似只有英文贴。所以基本上能用的信息算是比较少的。
下面贴出一些我在寻找过程中比较有用的网页。
MSDN 上提供的示例:http://www.microsoft.com/en-us/download/confirmation.aspx?id=5372
WindowsVista Sample Credential Providers Overview 中文翻译http://blog.csdn.net/linbaotong/article/details/7925645
改编一个属于你自己的凭证:http://blog.csdn.net/mikefeng/article/details/1569475
一些相关的知识:http://blog.csdn.net/patdz/article/details/7522195
(下面全部以SampleAllControlsCredentialProvider为例)
首先是界面方面的修改。示例中credential provider 的界面编写的语言不祥。但可以肯定的是界面不是用mfc编写的。实际上,如果是要改写示例的话,千万不要用MFC的任何相关的东西,包括CString。否则就会出现这样的情况。
在改写界面的话,主要改写的内容是:
common.h(line 25), 这一部分的内容,你可以在这部分中添加你想要的元素的序号。注意注释中强调的,SFI_NUM_FIELDS必须放在最后一个,否则会出现奇怪的问题。
之后是staticconstFIELD_STATE_PAIRs_rgFieldStatePairs[]以及staticconstCREDENTIAL_PROVIDER_FIELD_DESCRIPTORs_rgCredProvFieldDescriptors[]的内容。同样是添加你所想要的表项。比如我修改如下:
(图中修改的内容是去掉了checkbox和combobox,commandink,添加了一个pin码的写入框)
至此,common.h上的修改已经结束了。
之后转到CSampleCredentialc.cpp中修改。
HRESULTCSampleCredential::Initialize(
constCREDENTIAL_PROVIDER_FIELD_DESCRIPTOR*rgcpfd,
constFIELD_STATE_PAIR*rgfsp
)
修改初始化函数,按照他自己给你的格式修改即可。
界面的修改就到此结束了。
在界面修改后,如果你要使你的组件工作,只要改写诸如HRESULTCSampleCredential::GetComboBoxValueCount(
DWORDdwFieldID,
DWORD*pcItems,
DWORD*pdwSelectedItem
) 一类的函数既可以了。
之后便是认证的部分。
在认证部分,你只需要修改CSampleCredential::GetSerialization这一部分的内容即可。
关于这一部分,示例中的代码给原理是:
读取账户密码框的数据,写入变量KERB_INTERACTIVE_LOGONkil; 中,然后改写标记:
*pcpgsr=CPGSR_RETURN_CREDENTIAL_FINISHED; 这个标记一旦被写入了。在登陆的过程中我们程序的部分就结束了。
在这一部分中,需要注意的是kil中的账户密码必须是windows中存在的账户密码。也就是
说如果你想要用自己的账户密码来登陆,你的程序中就需要在编写的时候写入系统的账户密码。比如下面这样:
hr=UnicodeStringInitWithString(L"Administrator",&kil.UserName);
hr=UnicodeStringInitWithString(L"",&kil.Password);
整个改写的过程基本上就是这样。Over.
之后是使用你的凭证,运行你的运行包中提供的注册表文件,然后把生成的dll文件复制到system32中即可。注意的是如果要提示你是否覆盖的话,最好先删掉原来的程序再试。
然后就是多个凭证的问题。在win7后会存在有多个凭证。如果你想要系统中只存在一个凭证的话,你就需要这么做:
备份(千万要记得备份!)
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\CredentialProviders里面的东西后,再删除掉所有的东西(这个过程中有一两个凭证不可删除,很正常)。然后安装你自己的凭证,到时候你就会发现登录的时候只存在你自己的凭证。
不过程序中还是没有解决的问题就是示例在锁定之后就无法正常登录,只能切换系统自带的凭证来登陆。
程序的最后效果如下:
最后附上一个肯定会有用的函数,unicode字符转char*。
boolUnicodeToAnsi(constWCHAR*pSrc,char*pDes)
{
chardefaultChar[100];
BOOLbUseDefaultChar;
intiByte=WideCharToMultiByte(CP_ACP,0,pSrc,-1,pDes,1024,defaultChar,&bUseDefaultChar);
if(iByte==0)
{
//_stprintf(tszErrMsg,theApp.GetText(_T("%s, cann't convert the source to ansi code page, theerror code is 0x%x\n")).c_str(), lpszInput, GetLastError());
//AfxMessageBox(tszErrMsg);
}
returntrue;
}