0
我正嘗試使用編譯爲AnyCPU的.NET 2.0應用程序中的CryptUIWizDigitalSign函數對文件進行數字簽名。該調用在x86上運行時工作正常,但在x64上失敗,在編譯爲x86時,該調用也適用於x64操作系統。任何想法如何更好地marshall或從x64呼叫?在x64上從.NET調用CryptUIWizDigitalSign
返回的Win32exception是「在文件的數字簽名期間遇到錯誤...」,本機錯誤代碼爲-2146762749。
代碼的相關部分是:
[StructLayout(LayoutKind.Sequential)]
public struct CRYPTUI_WIZ_DIGITAL_SIGN_INFO {
public Int32 dwSize;
public Int32 dwSubjectChoice;
[MarshalAs(UnmanagedType.LPWStr)]
public string pwszFileName;
public Int32 dwSigningCertChoice;
public IntPtr pSigningCertContext;
[MarshalAs(UnmanagedType.LPWStr)]
public string pwszTimestampURL;
public Int32 dwAdditionalCertChoice;
public IntPtr pSignExtInfo;
}
[DllImport("Cryptui.dll", CharSet=CharSet.Unicode, SetLastError=true)]
public static extern bool CryptUIWizDigitalSign(int dwFlags, IntPtr hwndParent, string pwszWizardTitle, ref CRYPTUI_WIZ_DIGITAL_SIGN_INFO pDigitalSignInfo, ref IntPtr ppSignContext);
CRYPTUI_WIZ_DIGITAL_SIGN_INFO digitalSignInfo = new CRYPTUI_WIZ_DIGITAL_SIGN_INFO();
digitalSignInfo = new CRYPTUI_WIZ_DIGITAL_SIGN_INFO();
digitalSignInfo.dwSize = Marshal.SizeOf(digitalSignInfo);
digitalSignInfo.dwSubjectChoice = 1;
digitalSignInfo.dwSigningCertChoice = 1;
digitalSignInfo.pSigningCertContext = pSigningCertContext;
digitalSignInfo.pwszTimestampURL = timestampUrl;
digitalSignInfo.dwAdditionalCertChoice = 0;
digitalSignInfo.pSignExtInfo = IntPtr.Zero;
digitalSignInfo.pwszFileName = filepath;
CryptUIWizDigitalSign(1, IntPtr.Zero, null, ref digitalSignInfo, ref pSignContext));
這裏是SigningCertContext如何檢索(減去各種錯誤處理)
public IntPtr GetCertContext(String pfxfilename, String pswd)
IntPtr hMemStore = IntPtr.Zero;
IntPtr hCertCntxt = IntPtr.Zero;
IntPtr pProvInfo = IntPtr.Zero;
uint provinfosize = 0;
try {
byte[] pfxdata = PfxUtility.GetFileBytes(pfxfilename);
CRYPT_DATA_BLOB ppfx = new CRYPT_DATA_BLOB();
ppfx.cbData = pfxdata.Length;
ppfx.pbData = Marshal.AllocHGlobal(pfxdata.Length);
Marshal.Copy(pfxdata, 0, ppfx.pbData, pfxdata.Length);
hMemStore = Win32.PFXImportCertStore(ref ppfx, pswd, CRYPT_USER_KEYSET);
pswd = null;
if (hMemStore != IntPtr.Zero) {
Marshal.FreeHGlobal(ppfx.pbData);
while ((hCertCntxt = Win32.CertEnumCertificatesInStore(hMemStore, hCertCntxt)) != IntPtr.Zero) {
if (Win32.CertGetCertificateContextProperty(hCertCntxt, CERT_KEY_PROV_INFO_PROP_ID, IntPtr.Zero, ref provinfosize))
pProvInfo = Marshal.AllocHGlobal((int)provinfosize);
else
continue;
if (Win32.CertGetCertificateContextProperty(hCertCntxt, CERT_KEY_PROV_INFO_PROP_ID, pProvInfo, ref provinfosize))
break;
}
}
finally {
if (pProvInfo != IntPtr.Zero)
Marshal.FreeHGlobal(pProvInfo);
if (hMemStore != IntPtr.Zero)
Win32.CertCloseStore(hMemStore, 0);
}
return hCertCntxt;
}
我沒有看到任何錯誤。我看不到pSigningCertContext是如何初始化的。描述「失敗」和Marshal.GetLastWin32Error返回值。 – 2010-05-17 17:21:28