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 傳遞的事件控制碼位址。 傳遞的事件控制碼會重新排列。 如果 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
程式庫 Crypt32.lib
Dll Crypt32.dll

另請參閱

憑證存放區函式

CreateEvent

WaitForSingleObjectEx