cnpack / cnvcl

CnPack VCL Components

Home Page:http://www.cnpack.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

CnRandom单元的StopRandom在 Windows x64 程序退出时会触发异常

winddriver opened this issue · comments

只要引用了 CnRandom 单元,什么操作都不用做,启动程序,然后直接退出就会触发异常,100%出现

随便新建一个 VCL 或者 Console 程序,目标平台选择 Windows 64-bit,然后uses CnRandom,然后运行程序,然后关闭程序,异常就触发了

我这边没能复现此问题,但我刚给StopRandom加了一些保护,请尝试git pull最新代码再尝试一下?
如果仍有问题,怀疑是advapi32初始化失败导致。

应该是这几个函数的定义有问题:
function CryptAcquireContext(phProv: PULONG; pszContainer: PAnsiChar;
pszProvider: PAnsiChar; dwProvType: LongWord; dwFlags: LongWord): BOOL;
stdcall; external ADVAPI32 name 'CryptAcquireContextA';

function CryptReleaseContext(hProv: ULONG; dwFlags: LongWord): BOOL;
stdcall; external ADVAPI32 name 'CryptReleaseContext';

function CryptGenRandom(hProv: ULONG; dwLen: LongWord; pbBuffer: PAnsiChar): BOOL;
stdcall; external ADVAPI32 name 'CryptGenRandom';

我去翻了微软的msdn文档,这几个函数第一个参数类型是 * HCRYPTPROV 和 HCRYPTPROV,HCRYPTPROV的原始定义其实是 ULONG_PTR,而不是ULONG,ULONG_PTR在64位下其实是8个字节而不是4个字节,所以就出异常了

改成这样就没问题了:
type
HCRYPTPROV = ULONG_PTR;
PHCRYPTPROV = ^HCRYPTPROV;

function CryptAcquireContext(phProv: PHCRYPTPROV; pszContainer: PAnsiChar;
pszProvider: PAnsiChar; dwProvType: LongWord; dwFlags: LongWord): BOOL;
stdcall; external ADVAPI32 name 'CryptAcquireContextA';

function CryptReleaseContext(hProv: HCRYPTPROV; dwFlags: LongWord): BOOL;
stdcall; external ADVAPI32 name 'CryptReleaseContext';

function CryptGenRandom(hProv: HCRYPTPROV; dwLen: LongWord; pbBuffer: PAnsiChar): BOOL;
stdcall; external ADVAPI32 name 'CryptGenRandom';

再补充一点,Winapi.Windows.pas中ULONG和ULONG_PTR的定义,一眼就能看出来问题了
ULONG = Cardinal;
ULONG_PTR = NativeUInt;

感谢分析,我查查。

感谢指正,我们将其改成了PHandle和THandle,不引入新类型,应该也能解决问题。