CertControlStore 函数 (wincrypt.h)

CertControlStore 函数允许应用程序在使用中的缓存存储的内容与该存储的内容存在差异时收到通知,因为它被保存到存储中。 当另一个 进程 进行更改时,可能会发生差异,该更改会影响存储区,因为它被持久保存。

CertControlStore 函数可用于同步缓存存储(如有必要),并提供将缓存存储中所做的更改提交到持久存储的方法。

语法

BOOL CertControlStore(
  [in] HCERTSTORE hCertStore,
  [in] DWORD      dwFlags,
  [in] DWORD      dwCtrlType,
  [in] void const *pvCtrlPara
);

参数

[in] hCertStore

证书存储的句柄。

[in] dwFlags

如果 dwCtrlType 参数设置为 CERT_STORE_CTRL_COMMIT,则此参数可以是以下值之一。

含义
CERT_STORE_CTRL_COMMIT_FORCE_FLAG
强制将缓存内存存储的内容复制到永久存储,即使缓存尚未更改。
CERT_STORE_CTRL_COMMIT_CLEAR_FLAG
禁止将缓存内存存储的内容复制到永久存储,即使存储已关闭也是如此。
CERT_STORE_CTRL_INHIBIT_DUPLICATE_HANDLE_FLAG
禁止事件 HANDLE 的重复句柄。 如果设置了此标志,则必须为此事件 HANDLE 调用传递了CERT_STORE_CTRL_CANCEL_NOTIFY的 CertControlStore ,然后才能关闭 hCertStore 句柄。
 

如果将 dwCtrlType 设置为 CERT_STORE_CTRL_NOTIFY_CHANGE 或 CERT_STORE_CTRL_RESYNC,则不使用 dwFlags 参数,并且必须设置为零。

[in] dwCtrlType

CertControlStore 将采取的控制操作。 pvCtrlParadwFlags 的解释取决于 dwCtrlType 的值。 目前,定义了以下操作。

含义
CERT_STORE_CTRL_RESYNC
缓存的存储将重新同步并使其与持久存储区匹配。
CERT_STORE_CTRL_NOTIFY_CHANGE
在 pvCtrlPara 指向的空间中返回一个信号,指示缓存存储的当前内容与存储的持久状态不同。
CERT_STORE_CTRL_COMMIT
对缓存存储所做的任何更改将复制到持久存储。 如果在打开缓存存储后或上次提交后未进行任何更改,则忽略调用。 如果存储提供程序是自动立即保存更改的提供程序,则也会忽略该调用。
CERT_STORE_CTRL_AUTO_RESYNC
每次枚举或查找存储调用开始时,都会进行检查,以确定是否已在存储中进行更改。 如果存储已更改,则重新同步完成。 当 pPrevContextNULL 时,此检查仅在第一次枚举或查找调用上完成。

不使用 pvCtrPara 成员,必须设置为 NULL

CERT_STORE_CTRL_CANCEL_NOTIFY
取消上一个CERT_STORE_CTRL_NOTIFY_CHANGE或CERT_STORE_CTRL_RESYNC中传递的事件 HANDLE 的通知信号。 pvCtrlPara 参数指向要取消的事件 HANDLE。

[in] pvCtrlPara

如果 dwCtrlType CERT_STORE_NOTIFY_CHANGE, 则 pvCtrlPara 设置为句柄的地址,当检测到存储区持久 状态 的更改时,系统在此地址中发出通知更改事件信号。 必须使用对 函数 CreateEvent 的调用初始化句柄。 对于基于注册表的存储, pvCtrlPara 参数可以设置为 NULL 。 如果 pvCtrlParaNULL,则创建并注册内部通知更改事件以发出信号。 仅当存储已更改时,使用内部通知更改事件才允许重新同步操作。

如果 dwCtrlType CERT_STORE_CTRL_RESYNC,请将 pvCtrlPara 设置为事件句柄的地址,以在持久存储中的下一次更改时发出信号。 通常,此地址是在初始化期间使用 CERT_STORE_CTRL_NOTIFY_CHANGE 传递的事件句柄的地址。 传递的事件句柄将重新mmed。 如果 pvCtrlPara 设置为 NULL,则不会重新调整事件。

如果 dwCtrlType CERT_STORE_CTRL_COMMIT,则不使用 pvCtrlPara ,并且必须设置为 NULL

返回值

如果函数成功,则函数返回非零值。

如果函数失败,则返回零。 有关扩展的错误信息,请调用 GetLastError

如果 dwCtrlType CERT_STORE_NOTIFY_CHANGE,则成功设置事件信号的句柄后,函数将返回非零值。 如果未设置事件句柄,则函数返回零。

如果 dwCtrlType CERT_STORE_CTRL_RESYNC,则重新同步成功后,函数将返回非零值。 如果重新同步失败,则函数返回零。

如果 dwCtrlType CERT_STORE_CTRL_COMMIT,该函数将返回非零值,以指示提交到持久存储的成功完成。 如果提交失败,则函数返回零。

某些提供程序可能不支持特定的控件类型。 在这些情况下, CertControlStore 返回零, GetLastError 设置为ERROR_NOT_SUPPORTED代码。

注解

随时可以重新同步存储。 它不需要遵循已发出信号的通知更改事件。

使用 RegNotifyChangeKeyValue 函数在基于注册表的存储提供程序上支持CERT_STORE_CTRL_NOTIFY_CHANGE。

使用 CERT_STORE_CTRL_NOTIFY_CHANGE 的 CertControlStore 对于要随 CERT_STORE_CTRL_RESYNC 传递的每个事件句柄调用一次。 使用 CERT_STORE_CTRL_NOTIFY_CHANGE 的这些调用必须在创建每个事件后进行,而不是在事件发出信号后进行。

示例

以下示例演示了当正在使用的缓存存储的内容与该存储的内容在保存到存储时存在差异时,允许应用程序收到通知。 有关包含此示例的完整上下文的完整示例,请参阅 示例 C 程序:设置和获取证书存储属性


//--------------------------------------------------------------------
// Declare and initialize variables.

HCERTSTORE hCertStore;     // Original certificate store
HANDLE     hEvent;
BOOL       fSignal;

//--------------------------------------------------------------------
// Initialize an event.

if(hEvent = CreateEvent(
    NULL,
    FALSE,          // Manual reset is FALSE
    FALSE,          // The initial state of the event is FALSE
    NULL))
{
     printf("An event has been created. \n");
}
else
{
     printf("The event was not created. \n");
     exit(1);
}

//--------------------------------------------------------------------
// Open the MY certificate store. 

if ( hCertStore = CertOpenStore(
    CERT_STORE_PROV_SYSTEM,
    0,
    NULL,
    CERT_SYSTEM_STORE_CURRENT_USER,
    L"MY"))
{
    printf("The MY store is open. \n");
}
else
{
    printf("The MY store did not open. \n");
    exit(1);
}

//--------------------------------------------------------------------
//  Call CertControlStore the first time with 
//  CERT_CONTROL_STORE_NOTIFY_CHANGE.

if(CertControlStore(
    hCertStore,                        //  The store to be controlled
    0,                                 //  Not used 
    CERT_STORE_CTRL_NOTIFY_CHANGE,     //  Control action type
    &hEvent))                          //  Points to the event handle
                           //  When a change is detected,
                           //  a signal is written to the 
                    //  memory location pointed to by
                    //  hHandle.
{
    printf("Notify change worked. \n");
}
else
{
    printf("Notify change failed. \n");
    exit(1);
}

//--------------------------------------------------------------------
// Wait for the store to change.

fSignal = (WAIT_OBJECT_0 == WaitForSingleObjectEx(
    hEvent,
    1000,        // Number of milliseconds to wait;
            // Use INFINITE to wait indefinitely for
            // a change
    FALSE));

if (fSignal)
{

//--------------------------------------------------------------------
// The store has changed.
// Call the function a second time with CERT_STORE_CTRL_RESYNC.

    if(CertControlStore(
        hCertStore,             // The store to be controlled
        0,                      // Not used
        CERT_STORE_CTRL_RESYNC, // Control action type
        &hEvent))               // The handle of the event 
                                // to be rearmed

    printf("Resynchronization worked. \n");
    
    else
    {
        printf("Resynchronization failed. \n");
        exit(1);
    }
}
else
{
      printf("The store was not changed. \n");
      printf("Resynchronization was not needed. \n");
}

// Release the handle to the store.

if(CertCloseStore(hCertStore,
                   0))
{
        printf("The MY store was closed. \n");
}
else
{
        printf("An error occurred. The MY store was not closed. \n");
}

要求

   
最低受支持的客户端 Windows XP [桌面应用 | UWP 应用]
最低受支持的服务器 Windows Server 2003 [桌面应用 | UWP 应用]
目标平台 Windows
标头 wincrypt.h
Library Crypt32.lib
DLL Crypt32.dll

另请参阅

证书存储函数

CreateEvent

WaitForSingleObjectEx