#ifndef _DPAPI_H
#define _DPAPI_H

/* Windows Data Protection API */

#if __POCC__ >= 500
#pragma once
#endif

#if (NTDDI_VERSION >= NTDDI_WIN8)
#ifndef DPAPI_IMP
#define DPAPI_IMP
#endif /* DPAPI_IMP */
#else /* NTDDI_VERSION < NTDDI_WIN8 */
#define DPAPI_IMP DECLSPEC_IMPORT
#endif /* NTDDI_VERSION < NTDDI_WIN8 */

#ifdef __cplusplus
extern "C" {
#endif

#ifndef CRYPTO_BLOBS_DEFINED
#define CRYPTO_BLOBS_DEFINED
typedef struct _CRYPTOAPI_BLOB {
    DWORD cbData;
    BYTE *pbData;
} CRYPT_INTEGER_BLOB, *PCRYPT_INTEGER_BLOB,
  CRYPT_UINT_BLOB, *PCRYPT_UINT_BLOB,
  CRYPT_OBJID_BLOB, *PCRYPT_OBJID_BLOB,
  CERT_NAME_BLOB, *PCERT_NAME_BLOB,
  CERT_RDN_VALUE_BLOB, *PCERT_RDN_VALUE_BLOB,
  CERT_BLOB, *PCERT_BLOB,
  CRL_BLOB, *PCRL_BLOB,
  DATA_BLOB, *PDATA_BLOB,
  CRYPT_DATA_BLOB, *PCRYPT_DATA_BLOB,
  CRYPT_HASH_BLOB, *PCRYPT_HASH_BLOB,
  CRYPT_DIGEST_BLOB, *PCRYPT_DIGEST_BLOB,
  CRYPT_DER_BLOB, *PCRYPT_DER_BLOB,
  CRYPT_ATTR_BLOB, *PCRYPT_ATTR_BLOB;
#endif /* CRYPTO_BLOBS_DEFINED */

#define szFORCE_KEY_PROTECTION  "ForceKeyProtection"

#define dwFORCE_KEY_PROTECTION_DISABLED  0x0
#define dwFORCE_KEY_PROTECTION_USER_SELECT  0x1
#define dwFORCE_KEY_PROTECTION_HIGH  0x2

typedef struct _CRYPTPROTECT_PROMPTSTRUCT {
    DWORD cbSize;
    DWORD dwPromptFlags;
    HWND hwndApp;
    LPCWSTR szPrompt;
} CRYPTPROTECT_PROMPTSTRUCT, *PCRYPTPROTECT_PROMPTSTRUCT;

#define CRYPTPROTECT_DEFAULT_PROVIDER  {0xdf9d8cd0,0x1501,0x11d1,{0x8c,0x7a,0x00,0xc0,0x4f,0xc2,0x97,0xeb}}

#define CRYPTPROTECT_PROMPT_ON_UNPROTECT  0x01
#define CRYPTPROTECT_PROMPT_ON_PROTECT  0x02
#define CRYPTPROTECT_PROMPT_RESERVED  0x04
#define CRYPTPROTECT_PROMPT_STRONG  0x08
#define CRYPTPROTECT_PROMPT_REQUIRE_STRONG  0x10

#define CRYPTPROTECT_UI_FORBIDDEN  0x01
#define CRYPTPROTECT_LOCAL_MACHINE  0x04
#define CRYPTPROTECT_CRED_SYNC  0x08
#define CRYPTPROTECT_AUDIT  0x10
#define CRYPTPROTECT_NO_RECOVERY  0x20
#define CRYPTPROTECT_VERIFY_PROTECTION  0x40
#define CRYPTPROTECT_CRED_REGENERATE  0x80

#define CRYPTPROTECT_FIRST_RESERVED_FLAGVAL  0x0FFFFFFF
#define CRYPTPROTECT_LAST_RESERVED_FLAGVAL  0xFFFFFFFF

DPAPI_IMP BOOL WINAPI CryptProtectData(DATA_BLOB *, LPCWSTR, DATA_BLOB *, PVOID, CRYPTPROTECT_PROMPTSTRUCT *, DWORD, DATA_BLOB *);
DPAPI_IMP BOOL WINAPI CryptUnprotectData(DATA_BLOB *, LPWSTR *, DATA_BLOB *, PVOID, CRYPTPROTECT_PROMPTSTRUCT *, DWORD, DATA_BLOB *);

#if (NTDDI_VERSION >= NTDDI_WIN8)
BOOL WINAPI CryptProtectDataNoUI(DATA_BLOB *, LPCWSTR, DATA_BLOB *, PVOID, CRYPTPROTECT_PROMPTSTRUCT *, DWORD, const BYTE *, DWORD, DATA_BLOB *);
BOOL WINAPI CryptUnprotectDataNoUI(DATA_BLOB *, LPWSTR *, DATA_BLOB *, PVOID, CRYPTPROTECT_PROMPTSTRUCT *, DWORD, const BYTE *, DWORD, DATA_BLOB *);
#endif /* NTDDI_VERSION >= NTDDI_WIN8 */

#if (NTDDI_VERSION >= NTDDI_VISTA)
DPAPI_IMP BOOL WINAPI CryptUpdateProtectedState(PSID, LPCWSTR, DWORD, DWORD *, DWORD *);
#endif /* NTDDI_VERSION >= NTDDI_VISTA */

#define CRYPTPROTECTMEMORY_BLOCK_SIZE  16

#define CRYPTPROTECTMEMORY_SAME_PROCESS  0x00
#define CRYPTPROTECTMEMORY_CROSS_PROCESS  0x01
#define CRYPTPROTECTMEMORY_SAME_LOGON  0x02

DPAPI_IMP BOOL WINAPI CryptProtectMemory(LPVOID, DWORD, DWORD);
DPAPI_IMP BOOL WINAPI CryptUnprotectMemory(LPVOID, DWORD, DWORD);

#ifdef __cplusplus
}
#endif

#endif /* _DPAPI_H */
