#ifndef _NTSECPKG_H
#define _NTSECPKG_H

/* Authentication or security package API definitions */

#ifdef __cplusplus
extern "C" {
#endif

#define LSA_AP_NAME_INITIALIZE_PACKAGE  "LsaApInitializePackage\0"
#define LSA_AP_NAME_LOGON_USER  "LsaApLogonUser\0"
#define LSA_AP_NAME_LOGON_USER_EX  "LsaApLogonUserEx\0"
#define LSA_AP_NAME_CALL_PACKAGE  "LsaApCallPackage\0"
#define LSA_AP_NAME_LOGON_TERMINATED  "LsaApLogonTerminated\0"
#define LSA_AP_NAME_CALL_PACKAGE_UNTRUSTED  "LsaApCallPackageUntrusted\0"
#define LSA_AP_NAME_CALL_PACKAGE_PASSTHROUGH "LsaApCallPackagePassthrough\0"

#define LSA_AP_NAME_LOGON_USER_EX2 "LsaApLogonUserEx2\0"
#define SP_ACCEPT_CREDENTIALS_NAME "SpAcceptCredentials\0"

#define SECPKG_CALL_KERNEL_MODE 0x00000001
#define SECPKG_CALL_ANSI  0x00000002
#define SECPKG_CALL_URGENT  0x00000004
#define SECPKG_CALL_RECURSIVE  0x00000008
#define SECPKG_CALL_IN_PROC  0x00000010
#define SECPKG_CALL_CLEANUP  0x00000020

#define SECBUFFER_UNMAPPED 0x40000000

#define PRIMARY_CRED_CLEAR_PASSWORD  0x1
#define PRIMARY_CRED_OWF_PASSWORD  0x2
#define PRIMARY_CRED_UPDATE  0x4
#define PRIMARY_CRED_CACHED_LOGON  0x8

#define PRIMARY_CRED_LOGON_PACKAGE_SHIFT 24
#define PRIMARY_CRED_PACKAGE_MASK 0xff000000

#define MAX_CRED_SIZE 1024

#define SECPKG_STATE_ENCRYPTION_PERMITTED  0x01
#define SECPKG_STATE_STRONG_ENCRYPTION_PERMITTED  0x02
#define SECPKG_STATE_DOMAIN_CONTROLLER  0x04
#define SECPKG_STATE_WORKSTATION  0x08
#define SECPKG_STATE_STANDALONE  0x10

#define SECPKG_ATTR_SASL_CONTEXT  0x00010000

#define SECPKG_ATTR_THUNK_ALL  0x00010000

#define NOTIFIER_FLAG_NEW_THREAD  0x00000001
#define NOTIFIER_FLAG_ONE_SHOT  0x00000002
#define NOTIFIER_FLAG_SECONDS  0x80000000

#define NOTIFIER_TYPE_INTERVAL  1
#define NOTIFIER_TYPE_HANDLE_WAIT  2
#define NOTIFIER_TYPE_STATE_CHANGE  3
#define NOTIFIER_TYPE_NOTIFY_EVENT  4
#define NOTIFIER_TYPE_IMMEDIATE 16

#define NOTIFY_CLASS_PACKAGE_CHANGE 1
#define NOTIFY_CLASS_ROLE_CHANGE  2
#define NOTIFY_CLASS_DOMAIN_CHANGE  3

#define SECPKG_PACKAGE_CHANGE_LOAD  0
#define SECPKG_PACKAGE_CHANGE_UNLOAD  1
#define SECPKG_PACKAGE_CHANGE_SELECT  2

#define SECPKG_LSAMODEINIT_NAME  "SpLsaModeInitialize"
#define SECPKG_USERMODEINIT_NAME  "SpUserModeInitialize"

#define SECPKG_INTERFACE_VERSION  0x00010000

#define SecEqualLuid(L1,L2)  ((((PLUID)L1)->LowPart==((PLUID)L2)->LowPart) && (((PLUID)L1)->HighPart==((PLUID)L2)->HighPart))
#define SecIsZeroLuid(L1)  ((L1->LowPart|L1->HighPart)==0)

#define KsecInitializeListEntry(Entry,SigValue) \
    ((PKSEC_LIST_ENTRY)Entry)->List.Flink = ((PKSEC_LIST_ENTRY)Entry)->List.Blink = NULL; \
    ((PKSEC_LIST_ENTRY)Entry)->RefCount = 1; \
    ((PKSEC_LIST_ENTRY)Entry)->Signature = SigValue; \
    ((PKSEC_LIST_ENTRY)Entry)->OwningList = NULL; \
    ((PKSEC_LIST_ENTRY)Entry)->Reserved = NULL;

typedef PVOID *PLSA_CLIENT_REQUEST;

typedef enum _LSA_TOKEN_INFORMATION_TYPE {
    LsaTokenInformationNull,
    LsaTokenInformationV1,
    LsaTokenInformationV2
} LSA_TOKEN_INFORMATION_TYPE, *PLSA_TOKEN_INFORMATION_TYPE;

typedef struct _LSA_TOKEN_INFORMATION_NULL {
    LARGE_INTEGER ExpirationTime;
    PTOKEN_GROUPS Groups;
} LSA_TOKEN_INFORMATION_NULL, *PLSA_TOKEN_INFORMATION_NULL;

typedef struct _LSA_TOKEN_INFORMATION_V1 {
    LARGE_INTEGER ExpirationTime;
    TOKEN_USER User;
    PTOKEN_GROUPS Groups;
    TOKEN_PRIMARY_GROUP PrimaryGroup;
    PTOKEN_PRIVILEGES Privileges;
    TOKEN_OWNER Owner;
    TOKEN_DEFAULT_DACL DefaultDacl;
} LSA_TOKEN_INFORMATION_V1, *PLSA_TOKEN_INFORMATION_V1;

typedef LSA_TOKEN_INFORMATION_V1 LSA_TOKEN_INFORMATION_V2, *PLSA_TOKEN_INFORMATION_V2;

typedef NTSTATUS (NTAPI LSA_CREATE_LOGON_SESSION)(PLUID);
typedef NTSTATUS (NTAPI LSA_DELETE_LOGON_SESSION)(PLUID);
typedef NTSTATUS (NTAPI LSA_ADD_CREDENTIAL)(PLUID,ULONG,PLSA_STRING,PLSA_STRING);
typedef NTSTATUS (NTAPI LSA_GET_CREDENTIALS)(PLUID,ULONG,PULONG,BOOLEAN,PLSA_STRING,PULONG,PLSA_STRING);
typedef NTSTATUS (NTAPI LSA_DELETE_CREDENTIAL)(PLUID,ULONG,PLSA_STRING);
typedef PVOID (NTAPI LSA_ALLOCATE_LSA_HEAP)(ULONG);
typedef VOID (NTAPI LSA_FREE_LSA_HEAP)(PVOID);
typedef NTSTATUS (NTAPI LSA_ALLOCATE_CLIENT_BUFFER)(PLSA_CLIENT_REQUEST,ULONG,PVOID*);
typedef NTSTATUS (NTAPI LSA_FREE_CLIENT_BUFFER)(PLSA_CLIENT_REQUEST,PVOID);
typedef NTSTATUS (NTAPI LSA_COPY_TO_CLIENT_BUFFER)(PLSA_CLIENT_REQUEST,ULONG,PVOID,PVOID);
typedef NTSTATUS (NTAPI LSA_COPY_FROM_CLIENT_BUFFER)(PLSA_CLIENT_REQUEST,ULONG,PVOID,PVOID);

typedef LSA_CREATE_LOGON_SESSION *PLSA_CREATE_LOGON_SESSION;
typedef LSA_DELETE_LOGON_SESSION *PLSA_DELETE_LOGON_SESSION;
typedef LSA_ADD_CREDENTIAL *PLSA_ADD_CREDENTIAL;
typedef LSA_GET_CREDENTIALS *PLSA_GET_CREDENTIALS;
typedef LSA_DELETE_CREDENTIAL *PLSA_DELETE_CREDENTIAL;
typedef LSA_ALLOCATE_LSA_HEAP *PLSA_ALLOCATE_LSA_HEAP;
typedef LSA_FREE_LSA_HEAP *PLSA_FREE_LSA_HEAP;
typedef LSA_ALLOCATE_CLIENT_BUFFER *PLSA_ALLOCATE_CLIENT_BUFFER;
typedef LSA_FREE_CLIENT_BUFFER *PLSA_FREE_CLIENT_BUFFER;
typedef LSA_COPY_TO_CLIENT_BUFFER *PLSA_COPY_TO_CLIENT_BUFFER;
typedef LSA_COPY_FROM_CLIENT_BUFFER *PLSA_COPY_FROM_CLIENT_BUFFER;

typedef struct _LSA_DISPATCH_TABLE {
    PLSA_CREATE_LOGON_SESSION CreateLogonSession;
    PLSA_DELETE_LOGON_SESSION DeleteLogonSession;
    PLSA_ADD_CREDENTIAL AddCredential;
    PLSA_GET_CREDENTIALS GetCredentials;
    PLSA_DELETE_CREDENTIAL DeleteCredential;
    PLSA_ALLOCATE_LSA_HEAP AllocateLsaHeap;
    PLSA_FREE_LSA_HEAP FreeLsaHeap;
    PLSA_ALLOCATE_CLIENT_BUFFER AllocateClientBuffer;
    PLSA_FREE_CLIENT_BUFFER FreeClientBuffer;
    PLSA_COPY_TO_CLIENT_BUFFER CopyToClientBuffer;
    PLSA_COPY_FROM_CLIENT_BUFFER CopyFromClientBuffer;
} LSA_DISPATCH_TABLE, *PLSA_DISPATCH_TABLE;

typedef NTSTATUS (NTAPI LSA_AP_INITIALIZE_PACKAGE)(ULONG,PLSA_DISPATCH_TABLE,PLSA_STRING,PLSA_STRING,PLSA_STRING*);
typedef NTSTATUS (NTAPI LSA_AP_LOGON_USER)(PLSA_CLIENT_REQUEST,SECURITY_LOGON_TYPE,PVOID,PVOID,ULONG,PVOID*,PULONG,PLUID,PNTSTATUS,PLSA_TOKEN_INFORMATION_TYPE,PVOID*,PLSA_UNICODE_STRING*,PLSA_UNICODE_STRING*);
typedef NTSTATUS (NTAPI LSA_AP_LOGON_USER_EX)(PLSA_CLIENT_REQUEST,SECURITY_LOGON_TYPE,PVOID,PVOID,ULONG,PVOID*,PULONG,PLUID,PNTSTATUS,PLSA_TOKEN_INFORMATION_TYPE,PVOID*,PUNICODE_STRING*,PUNICODE_STRING*,PUNICODE_STRING*);
typedef NTSTATUS (NTAPI LSA_AP_CALL_PACKAGE)(PLSA_CLIENT_REQUEST,PVOID,PVOID,ULONG,PVOID*,PULONG,PNTSTATUS);
typedef NTSTATUS (NTAPI LSA_AP_CALL_PACKAGE_PASSTHROUGH)(PLSA_CLIENT_REQUEST,PVOID,PVOID,ULONG,PVOID*,PULONG,PNTSTATUS);
typedef VOID (NTAPI LSA_AP_LOGON_TERMINATED)(PLUID);

typedef LSA_AP_CALL_PACKAGE LSA_AP_CALL_PACKAGE_UNTRUSTED;
typedef LSA_AP_INITIALIZE_PACKAGE *PLSA_AP_INITIALIZE_PACKAGE;
typedef LSA_AP_LOGON_USER *PLSA_AP_LOGON_USER;
typedef LSA_AP_LOGON_USER_EX *PLSA_AP_LOGON_USER_EX;
typedef LSA_AP_CALL_PACKAGE *PLSA_AP_CALL_PACKAGE;
typedef LSA_AP_CALL_PACKAGE_PASSTHROUGH *PLSA_AP_CALL_PACKAGE_PASSTHROUGH;
typedef LSA_AP_LOGON_TERMINATED *PLSA_AP_LOGON_TERMINATED;
typedef LSA_AP_CALL_PACKAGE_UNTRUSTED *PLSA_AP_CALL_PACKAGE_UNTRUSTED;

#ifdef SECURITY_KERNEL
typedef PVOID SEC_THREAD_START;
typedef PVOID SEC_ATTRS;
#else
typedef LPTHREAD_START_ROUTINE SEC_THREAD_START;
typedef LPSECURITY_ATTRIBUTES SEC_ATTRS;
#endif /* SECURITY_KERNEL */

typedef struct _SECPKG_CLIENT_INFO {
    LUID LogonId;
    ULONG ProcessID;
    ULONG ThreadID;
    BOOLEAN HasTcbPrivilege;
    BOOLEAN Impersonating;
    BOOLEAN Restricted;
} SECPKG_CLIENT_INFO, *PSECPKG_CLIENT_INFO;

typedef struct _SECPKG_CALL_INFO {
    ULONG ProcessId;
    ULONG ThreadId;
    ULONG Attributes;
    ULONG CallCount;
} SECPKG_CALL_INFO, *PSECPKG_CALL_INFO;

typedef struct _SECPKG_SUPPLEMENTAL_CRED {
    UNICODE_STRING PackageName;
    ULONG CredentialSize;
    PUCHAR Credentials;
} SECPKG_SUPPLEMENTAL_CRED, *PSECPKG_SUPPLEMENTAL_CRED;

typedef ULONG_PTR LSA_SEC_HANDLE;
typedef LSA_SEC_HANDLE *PLSA_SEC_HANDLE;
typedef struct _SECPKG_SUPPLEMENTAL_CRED_ARRAY {
    ULONG CredentialCount;
    SECPKG_SUPPLEMENTAL_CRED Credentials[1];
} SECPKG_SUPPLEMENTAL_CRED_ARRAY, *PSECPKG_SUPPLEMENTAL_CRED_ARRAY;

typedef NTSTATUS (NTAPI LSA_CALLBACK_FUNCTION)(ULONG_PTR,ULONG_PTR,PSecBuffer,PSecBuffer);
typedef LSA_CALLBACK_FUNCTION *PLSA_CALLBACK_FUNCTION;

typedef struct _SECPKG_PRIMARY_CRED {
    LUID LogonId;
    UNICODE_STRING DownlevelName;
    UNICODE_STRING DomainName;
    UNICODE_STRING Password;
    UNICODE_STRING OldPassword;
    PSID UserSid;
    ULONG Flags;
    UNICODE_STRING DnsDomainName;
    UNICODE_STRING Upn;
    UNICODE_STRING LogonServer;
    UNICODE_STRING Spare1;
    UNICODE_STRING Spare2;
    UNICODE_STRING Spare3;
    UNICODE_STRING Spare4;
} SECPKG_PRIMARY_CRED, *PSECPKG_PRIMARY_CRED;

typedef struct _SECPKG_PARAMETERS {
    ULONG Version;
    ULONG MachineState;
    ULONG SetupMode;
    PSID DomainSid;
    UNICODE_STRING DomainName;
    UNICODE_STRING DnsDomainName;
    GUID DomainGuid;
} SECPKG_PARAMETERS, *PSECPKG_PARAMETERS;

typedef enum _SECPKG_EXTENDED_INFORMATION_CLASS {
    SecpkgGssInfo = 1,
    SecpkgContextThunks,
    SecpkgMutualAuthLevel,
    SecpkgMaxInfo
} SECPKG_EXTENDED_INFORMATION_CLASS;

typedef struct _SECPKG_GSS_INFO {
    ULONG EncodedIdLength;
    UCHAR EncodedId[4];
} SECPKG_GSS_INFO, *PSECPKG_GSS_INFO;

typedef struct _SECPKG_CONTEXT_THUNKS {
    ULONG InfoLevelCount;
    ULONG Levels[1];
} SECPKG_CONTEXT_THUNKS, *PSECPKG_CONTEXT_THUNKS;

typedef struct _SECPKG_MUTUAL_AUTH_LEVEL {
    ULONG MutualAuthLevel;
} SECPKG_MUTUAL_AUTH_LEVEL, *PSECPKG_MUTUAL_AUTH_LEVEL;

typedef struct _SECPKG_EXTENDED_INFORMATION {
    SECPKG_EXTENDED_INFORMATION_CLASS Class;
    union {
        SECPKG_GSS_INFO GssInfo;
        SECPKG_CONTEXT_THUNKS ContextThunks;
        SECPKG_MUTUAL_AUTH_LEVEL MutualAuthLevel;
    } Info;
} SECPKG_EXTENDED_INFORMATION, *PSECPKG_EXTENDED_INFORMATION;

typedef struct _SecPkgContext_SaslContext {
    PVOID SaslContext;
} SecPkgContext_SaslContext, *PSecPkgContext_SaslContext;

#ifndef SECURITY_USER_DATA_DEFINED
#define SECURITY_USER_DATA_DEFINED

#define UNDERSTANDS_LONG_NAMES  1
#define NO_LONG_NAMES  2

typedef struct _SECURITY_USER_DATA {
    SECURITY_STRING UserName;
    SECURITY_STRING LogonDomainName;
    SECURITY_STRING LogonServer;
    PSID pSid;
} SECURITY_USER_DATA, *PSECURITY_USER_DATA;

typedef SECURITY_USER_DATA SecurityUserData, *PSecurityUserData;
#endif /* SECURITY_USER_DATA_DEFINED */

typedef NTSTATUS (NTAPI LSA_IMPERSONATE_CLIENT)(VOID);
typedef NTSTATUS (NTAPI LSA_UNLOAD_PACKAGE)(VOID);
typedef NTSTATUS (NTAPI LSA_DUPLICATE_HANDLE)(HANDLE,PHANDLE);
typedef NTSTATUS (NTAPI LSA_SAVE_SUPPLEMENTAL_CREDENTIALS)(PLUID,ULONG,PVOID,BOOLEAN);
typedef HANDLE (NTAPI LSA_CREATE_THREAD)(SEC_ATTRS,ULONG,SEC_THREAD_START,PVOID,ULONG,PULONG);
typedef NTSTATUS (NTAPI LSA_GET_CLIENT_INFO)(PSECPKG_CLIENT_INFO);
typedef HANDLE (NTAPI LSA_REGISTER_NOTIFICATION)(SEC_THREAD_START,PVOID,ULONG,ULONG,ULONG,ULONG,HANDLE);
typedef NTSTATUS (NTAPI LSA_CANCEL_NOTIFICATION)(HANDLE);
typedef NTSTATUS (NTAPI LSA_MAP_BUFFER)(PSecBuffer,PSecBuffer);
typedef NTSTATUS (NTAPI LSA_CREATE_TOKEN)(PLUID,PTOKEN_SOURCE,SECURITY_LOGON_TYPE,SECURITY_IMPERSONATION_LEVEL,LSA_TOKEN_INFORMATION_TYPE,PVOID,PTOKEN_GROUPS,PUNICODE_STRING,PUNICODE_STRING,PUNICODE_STRING,PUNICODE_STRING,PHANDLE,PNTSTATUS);
typedef VOID (NTAPI LSA_AUDIT_LOGON)(NTSTATUS,NTSTATUS,PUNICODE_STRING,PUNICODE_STRING,PUNICODE_STRING,PSID,SECURITY_LOGON_TYPE,PTOKEN_SOURCE,PLUID);
typedef NTSTATUS (NTAPI LSA_CALL_PACKAGE)(PUNICODE_STRING,PVOID,ULONG,PVOID*,PULONG,PNTSTATUS);
typedef NTSTATUS (NTAPI LSA_CALL_PACKAGEEX)(PUNICODE_STRING,PVOID,PVOID,ULONG,PVOID*,PULONG,PNTSTATUS);
typedef NTSTATUS (NTAPI LSA_CALL_PACKAGE_PASSTHROUGH)(PUNICODE_STRING,PVOID,PVOID,ULONG,PVOID*,PULONG,PNTSTATUS);
typedef BOOLEAN (NTAPI LSA_GET_CALL_INFO)(PSECPKG_CALL_INFO);
typedef PVOID (NTAPI LSA_CREATE_SHARED_MEMORY)(ULONG,ULONG);
typedef PVOID (NTAPI LSA_ALLOCATE_SHARED_MEMORY)(PVOID,ULONG);
typedef VOID (NTAPI LSA_FREE_SHARED_MEMORY)(PVOID,PVOID);
typedef BOOLEAN (NTAPI LSA_DELETE_SHARED_MEMORY)(PVOID);

typedef enum _SECPKG_NAME_TYPE {
    SecNameSamCompatible,
    SecNameAlternateId,
    SecNameFlat,
    SecNameDN
} SECPKG_NAME_TYPE;

typedef NTSTATUS (NTAPI LSA_OPEN_SAM_USER)(PSECURITY_STRING,SECPKG_NAME_TYPE,PSECURITY_STRING,BOOLEAN,ULONG,PVOID*);
typedef NTSTATUS (NTAPI LSA_GET_USER_CREDENTIALS)(PVOID,PVOID*,PULONG,PVOID*,PULONG);
typedef NTSTATUS (NTAPI LSA_GET_USER_AUTH_DATA)(PVOID,PUCHAR*,PULONG);
typedef NTSTATUS (NTAPI LSA_CLOSE_SAM_USER)(PVOID);
typedef NTSTATUS (NTAPI LSA_GET_AUTH_DATA_FOR_USER)(PSECURITY_STRING,SECPKG_NAME_TYPE,PSECURITY_STRING,PUCHAR*,PULONG,PUNICODE_STRING);
typedef NTSTATUS (NTAPI LSA_CONVERT_AUTH_DATA_TO_TOKEN)(PVOID,ULONG,SECURITY_IMPERSONATION_LEVEL,PTOKEN_SOURCE,SECURITY_LOGON_TYPE,PUNICODE_STRING,PHANDLE,PLUID,PUNICODE_STRING,PNTSTATUS);
typedef NTSTATUS (NTAPI LSA_CRACK_SINGLE_NAME)(ULONG,BOOLEAN,PUNICODE_STRING,PUNICODE_STRING,ULONG,PUNICODE_STRING,PUNICODE_STRING,PULONG);
typedef NTSTATUS (NTAPI LSA_AUDIT_ACCOUNT_LOGON)(ULONG,BOOLEAN,PUNICODE_STRING,PUNICODE_STRING,PUNICODE_STRING,NTSTATUS);
typedef NTSTATUS (NTAPI LSA_CLIENT_CALLBACK)(PCHAR,ULONG_PTR,ULONG_PTR,PSecBuffer,PSecBuffer);
typedef NTSTATUS (NTAPI LSA_REGISTER_CALLBACK)(ULONG,PLSA_CALLBACK_FUNCTION);

typedef struct _SECPKG_EVENT_PACKAGE_CHANGE {
    ULONG ChangeType;
    LSA_SEC_HANDLE PackageId;
    SECURITY_STRING PackageName;
} SECPKG_EVENT_PACKAGE_CHANGE, *PSECPKG_EVENT_PACKAGE_CHANGE;

typedef struct _SECPKG_EVENT_ROLE_CHANGE {
    ULONG PreviousRole;
    ULONG NewRole;
} SECPKG_EVENT_ROLE_CHANGE, *PSECPKG_EVENT_ROLE_CHANGE;

typedef struct _SECPKG_PARAMETERS SECPKG_EVENT_DOMAIN_CHANGE;
typedef struct _SECPKG_PARAMETERS *PSECPKG_EVENT_DOMAIN_CHANGE;

typedef struct _SECPKG_EVENT_NOTIFY {
    ULONG EventClass;
    ULONG Reserved;
    ULONG EventDataSize;
    PVOID EventData;
    PVOID PackageParameter;
} SECPKG_EVENT_NOTIFY, *PSECPKG_EVENT_NOTIFY;

typedef NTSTATUS (NTAPI LSA_UPDATE_PRIMARY_CREDENTIALS)(PSECPKG_PRIMARY_CRED,PSECPKG_SUPPLEMENTAL_CRED_ARRAY);

typedef LSA_IMPERSONATE_CLIENT *PLSA_IMPERSONATE_CLIENT;
typedef LSA_UNLOAD_PACKAGE *PLSA_UNLOAD_PACKAGE;
typedef LSA_DUPLICATE_HANDLE *PLSA_DUPLICATE_HANDLE;
typedef LSA_SAVE_SUPPLEMENTAL_CREDENTIALS *PLSA_SAVE_SUPPLEMENTAL_CREDENTIALS;
typedef LSA_CREATE_THREAD *PLSA_CREATE_THREAD;
typedef LSA_GET_CLIENT_INFO *PLSA_GET_CLIENT_INFO;
typedef LSA_REGISTER_NOTIFICATION *PLSA_REGISTER_NOTIFICATION;
typedef LSA_CANCEL_NOTIFICATION *PLSA_CANCEL_NOTIFICATION;
typedef LSA_MAP_BUFFER *PLSA_MAP_BUFFER;
typedef LSA_CREATE_TOKEN *PLSA_CREATE_TOKEN;
typedef LSA_AUDIT_LOGON *PLSA_AUDIT_LOGON;
typedef LSA_CALL_PACKAGE *PLSA_CALL_PACKAGE;
typedef LSA_CALL_PACKAGEEX *PLSA_CALL_PACKAGEEX;
typedef LSA_GET_CALL_INFO *PLSA_GET_CALL_INFO;
typedef LSA_CREATE_SHARED_MEMORY *PLSA_CREATE_SHARED_MEMORY;
typedef LSA_ALLOCATE_SHARED_MEMORY *PLSA_ALLOCATE_SHARED_MEMORY;
typedef LSA_FREE_SHARED_MEMORY *PLSA_FREE_SHARED_MEMORY;
typedef LSA_DELETE_SHARED_MEMORY *PLSA_DELETE_SHARED_MEMORY;
typedef LSA_OPEN_SAM_USER *PLSA_OPEN_SAM_USER;
typedef LSA_GET_USER_CREDENTIALS *PLSA_GET_USER_CREDENTIALS;
typedef LSA_GET_USER_AUTH_DATA *PLSA_GET_USER_AUTH_DATA;
typedef LSA_CLOSE_SAM_USER *PLSA_CLOSE_SAM_USER;
typedef LSA_CONVERT_AUTH_DATA_TO_TOKEN *PLSA_CONVERT_AUTH_DATA_TO_TOKEN;
typedef LSA_CLIENT_CALLBACK *PLSA_CLIENT_CALLBACK;
typedef LSA_REGISTER_CALLBACK *PLSA_REGISTER_CALLBACK;
typedef LSA_UPDATE_PRIMARY_CREDENTIALS *PLSA_UPDATE_PRIMARY_CREDENTIALS;
typedef LSA_GET_AUTH_DATA_FOR_USER *PLSA_GET_AUTH_DATA_FOR_USER;
typedef LSA_CRACK_SINGLE_NAME *PLSA_CRACK_SINGLE_NAME;
typedef LSA_AUDIT_ACCOUNT_LOGON *PLSA_AUDIT_ACCOUNT_LOGON;
typedef LSA_CALL_PACKAGE_PASSTHROUGH *PLSA_CALL_PACKAGE_PASSTHROUGH;

typedef struct _LSA_SECPKG_FUNCTION_TABLE {
    PLSA_CREATE_LOGON_SESSION CreateLogonSession;
    PLSA_DELETE_LOGON_SESSION DeleteLogonSession;
    PLSA_ADD_CREDENTIAL AddCredential;
    PLSA_GET_CREDENTIALS GetCredentials;
    PLSA_DELETE_CREDENTIAL DeleteCredential;
    PLSA_ALLOCATE_LSA_HEAP AllocateLsaHeap;
    PLSA_FREE_LSA_HEAP FreeLsaHeap;
    PLSA_ALLOCATE_CLIENT_BUFFER AllocateClientBuffer;
    PLSA_FREE_CLIENT_BUFFER FreeClientBuffer;
    PLSA_COPY_TO_CLIENT_BUFFER CopyToClientBuffer;
    PLSA_COPY_FROM_CLIENT_BUFFER CopyFromClientBuffer;
    PLSA_IMPERSONATE_CLIENT ImpersonateClient;
    PLSA_UNLOAD_PACKAGE UnloadPackage;
    PLSA_DUPLICATE_HANDLE DuplicateHandle;
    PLSA_SAVE_SUPPLEMENTAL_CREDENTIALS SaveSupplementalCredentials;
    PLSA_CREATE_THREAD CreateThread;
    PLSA_GET_CLIENT_INFO GetClientInfo;
    PLSA_REGISTER_NOTIFICATION RegisterNotification;
    PLSA_CANCEL_NOTIFICATION CancelNotification;
    PLSA_MAP_BUFFER MapBuffer;
    PLSA_CREATE_TOKEN CreateToken;
    PLSA_AUDIT_LOGON AuditLogon;
    PLSA_CALL_PACKAGE CallPackage;
    PLSA_FREE_LSA_HEAP FreeReturnBuffer;
    PLSA_GET_CALL_INFO GetCallInfo;
    PLSA_CALL_PACKAGEEX CallPackageEx;
    PLSA_CREATE_SHARED_MEMORY CreateSharedMemory;
    PLSA_ALLOCATE_SHARED_MEMORY AllocateSharedMemory;
    PLSA_FREE_SHARED_MEMORY FreeSharedMemory;
    PLSA_DELETE_SHARED_MEMORY DeleteSharedMemory;
    PLSA_OPEN_SAM_USER OpenSamUser;
    PLSA_GET_USER_CREDENTIALS GetUserCredentials;
    PLSA_GET_USER_AUTH_DATA GetUserAuthData;
    PLSA_CLOSE_SAM_USER CloseSamUser;
    PLSA_CONVERT_AUTH_DATA_TO_TOKEN ConvertAuthDataToToken;
    PLSA_CLIENT_CALLBACK ClientCallback;
    PLSA_UPDATE_PRIMARY_CREDENTIALS UpdateCredentials;
    PLSA_GET_AUTH_DATA_FOR_USER GetAuthDataForUser;
    PLSA_CRACK_SINGLE_NAME CrackSingleName;
    PLSA_AUDIT_ACCOUNT_LOGON AuditAccountLogon;
    PLSA_CALL_PACKAGE_PASSTHROUGH CallPackagePassthrough;
} LSA_SECPKG_FUNCTION_TABLE, *PLSA_SECPKG_FUNCTION_TABLE;

typedef struct _SECPKG_DLL_FUNCTIONS {
    PLSA_ALLOCATE_LSA_HEAP AllocateHeap;
    PLSA_FREE_LSA_HEAP FreeHeap;
    PLSA_REGISTER_CALLBACK RegisterCallback;
} SECPKG_DLL_FUNCTIONS, *PSECPKG_DLL_FUNCTIONS;

typedef NTSTATUS (NTAPI SpInitializeFn)(ULONG_PTR,PSECPKG_PARAMETERS,PLSA_SECPKG_FUNCTION_TABLE);
typedef NTSTATUS (NTAPI SpShutdownFn)(VOID);
typedef NTSTATUS (NTAPI SpGetInfoFn)(PSecPkgInfo);
typedef NTSTATUS (NTAPI SpGetExtendedInformationFn)(SECPKG_EXTENDED_INFORMATION_CLASS,PSECPKG_EXTENDED_INFORMATION*);
typedef NTSTATUS (NTAPI SpSetExtendedInformationFn)(SECPKG_EXTENDED_INFORMATION_CLASS,PSECPKG_EXTENDED_INFORMATION);
typedef NTSTATUS (LSA_AP_LOGON_USER_EX2)(PLSA_CLIENT_REQUEST,SECURITY_LOGON_TYPE,PVOID,PVOID,ULONG,PVOID*,PULONG,PLUID,PNTSTATUS,PLSA_TOKEN_INFORMATION_TYPE,PVOID*,PUNICODE_STRING*,PUNICODE_STRING*,PUNICODE_STRING*,PSECPKG_PRIMARY_CRED,PSECPKG_SUPPLEMENTAL_CRED_ARRAY*);

typedef LSA_AP_LOGON_USER_EX2 *PLSA_AP_LOGON_USER_EX2;

typedef NTSTATUS (NTAPI SpAcceptCredentialsFn)(SECURITY_LOGON_TYPE,PUNICODE_STRING,PSECPKG_PRIMARY_CRED,PSECPKG_SUPPLEMENTAL_CRED);
typedef NTSTATUS (NTAPI SpAcquireCredentialsHandleFn)(PUNICODE_STRING,ULONG,PLUID,PVOID,PVOID,PVOID,PLSA_SEC_HANDLE,PTimeStamp);
typedef NTSTATUS (NTAPI SpFreeCredentialsHandleFn)(LSA_SEC_HANDLE);
typedef NTSTATUS (NTAPI SpQueryCredentialsAttributesFn)(LSA_SEC_HANDLE,ULONG,PVOID);
typedef NTSTATUS (NTAPI SpAddCredentialsFn)(LSA_SEC_HANDLE,PUNICODE_STRING,PUNICODE_STRING,ULONG,PVOID,PVOID,PVOID,PTimeStamp);
typedef NTSTATUS (NTAPI SpSaveCredentialsFn)(LSA_SEC_HANDLE,PSecBuffer);
typedef NTSTATUS (NTAPI SpGetCredentialsFn)(LSA_SEC_HANDLE,PSecBuffer);
typedef NTSTATUS (NTAPI SpDeleteCredentialsFn)(LSA_SEC_HANDLE,PSecBuffer);
typedef NTSTATUS (NTAPI SpInitLsaModeContextFn)(LSA_SEC_HANDLE,LSA_SEC_HANDLE,PUNICODE_STRING,ULONG,ULONG,PSecBufferDesc,PLSA_SEC_HANDLE,PSecBufferDesc,PULONG,PTimeStamp,PBOOLEAN,PSecBuffer);
typedef NTSTATUS (NTAPI SpDeleteContextFn)(LSA_SEC_HANDLE);
typedef NTSTATUS (NTAPI SpApplyControlTokenFn)(LSA_SEC_HANDLE,PSecBufferDesc);
typedef NTSTATUS (NTAPI SpAcceptLsaModeContextFn)(LSA_SEC_HANDLE,LSA_SEC_HANDLE,PSecBufferDesc,ULONG,ULONG,PLSA_SEC_HANDLE,PSecBufferDesc,PULONG,PTimeStamp,PBOOLEAN,PSecBuffer);
typedef NTSTATUS (NTAPI SpGetUserInfoFn)(PLUID,ULONG,PSecurityUserData*);
typedef NTSTATUS (NTAPI SpQueryContextAttributesFn)(LSA_SEC_HANDLE,ULONG,PVOID);

typedef struct _SECPKG_FUNCTION_TABLE {
    PLSA_AP_INITIALIZE_PACKAGE InitializePackage;
    PLSA_AP_LOGON_USER LogonUser;
    PLSA_AP_CALL_PACKAGE CallPackage;
    PLSA_AP_LOGON_TERMINATED LogonTerminated;
    PLSA_AP_CALL_PACKAGE_UNTRUSTED CallPackageUntrusted;
    PLSA_AP_CALL_PACKAGE_PASSTHROUGH CallPackagePassthrough;
    PLSA_AP_LOGON_USER_EX LogonUserEx;
    PLSA_AP_LOGON_USER_EX2 LogonUserEx2;
    SpInitializeFn *Initialize;
    SpShutdownFn *Shutdown;
    SpGetInfoFn *GetInfo;
    SpAcceptCredentialsFn *AcceptCredentials;
    SpAcquireCredentialsHandleFn *AcquireCredentialsHandle;
    SpQueryCredentialsAttributesFn *QueryCredentialsAttributes;
    SpFreeCredentialsHandleFn *FreeCredentialsHandle;
    SpSaveCredentialsFn *SaveCredentials;
    SpGetCredentialsFn *GetCredentials;
    SpDeleteCredentialsFn *DeleteCredentials;
    SpInitLsaModeContextFn *InitLsaModeContext;
    SpAcceptLsaModeContextFn *AcceptLsaModeContext;
    SpDeleteContextFn *DeleteContext;
    SpApplyControlTokenFn *ApplyControlToken;
    SpGetUserInfoFn *GetUserInfo;
    SpGetExtendedInformationFn *GetExtendedInformation;
    SpQueryContextAttributesFn *QueryContextAttributes;
    SpAddCredentialsFn *AddCredentials;
    SpSetExtendedInformationFn *SetExtendedInformation;
} SECPKG_FUNCTION_TABLE, *PSECPKG_FUNCTION_TABLE;

typedef NTSTATUS (NTAPI SpInstanceInitFn)(ULONG,PSECPKG_DLL_FUNCTIONS,PVOID*);
typedef NTSTATUS (NTAPI SpInitUserModeContextFn)(LSA_SEC_HANDLE,PSecBuffer);
typedef NTSTATUS (NTAPI SpMakeSignatureFn)(LSA_SEC_HANDLE,ULONG,PSecBufferDesc,ULONG);
typedef NTSTATUS (NTAPI SpVerifySignatureFn)(LSA_SEC_HANDLE,PSecBufferDesc,ULONG,PULONG);
typedef NTSTATUS (NTAPI SpSealMessageFn)(LSA_SEC_HANDLE,ULONG,PSecBufferDesc,ULONG);
typedef NTSTATUS (NTAPI SpUnsealMessageFn)(LSA_SEC_HANDLE,PSecBufferDesc,ULONG,PULONG);
typedef NTSTATUS (NTAPI SpGetContextTokenFn)(LSA_SEC_HANDLE,PHANDLE);
typedef NTSTATUS (NTAPI SpExportSecurityContextFn)(LSA_SEC_HANDLE,ULONG,PSecBuffer,PHANDLE);
typedef NTSTATUS (NTAPI SpImportSecurityContextFn)(PSecBuffer,HANDLE,PLSA_SEC_HANDLE);
typedef NTSTATUS (NTAPI SpCompleteAuthTokenFn)(LSA_SEC_HANDLE,PSecBufferDesc);
typedef NTSTATUS (NTAPI SpFormatCredentialsFn)(PSecBuffer,PSecBuffer);
typedef NTSTATUS (NTAPI SpMarshallSupplementalCredsFn)(ULONG,PUCHAR,PULONG,PVOID*);

typedef struct _SECPKG_USER_FUNCTION_TABLE {
    SpInstanceInitFn *InstanceInit;
    SpInitUserModeContextFn *InitUserModeContext;
    SpMakeSignatureFn *MakeSignature;
    SpVerifySignatureFn *VerifySignature;
    SpSealMessageFn *SealMessage;
    SpUnsealMessageFn *UnsealMessage;
    SpGetContextTokenFn *GetContextToken;
    SpQueryContextAttributesFn *QueryContextAttributes;
    SpCompleteAuthTokenFn *CompleteAuthToken;
    SpDeleteContextFn *DeleteUserModeContext;
    SpFormatCredentialsFn *FormatCredentials;
    SpMarshallSupplementalCredsFn *MarshallSupplementalCreds;
    SpExportSecurityContextFn *ExportContext;
    SpImportSecurityContextFn *ImportContext;
} SECPKG_USER_FUNCTION_TABLE, *PSECPKG_USER_FUNCTION_TABLE;

typedef NTSTATUS(SEC_ENTRY *SpLsaModeInitializeFn)(ULONG,PULONG,PSECPKG_FUNCTION_TABLE*,PULONG);
typedef NTSTATUS(SEC_ENTRY *SpUserModeInitializeFn)(ULONG,PULONG,PSECPKG_USER_FUNCTION_TABLE*,PULONG);

typedef enum _KSEC_CONTEXT_TYPE {
    KSecPaged,
    KSecNonPaged
} KSEC_CONTEXT_TYPE;

typedef struct _KSEC_LIST_ENTRY {
    LIST_ENTRY List;
    LONG RefCount;
    ULONG Signature;
    PVOID OwningList;
    PVOID Reserved;
} KSEC_LIST_ENTRY, *PKSEC_LIST_ENTRY;

typedef PVOID (SEC_ENTRY KSEC_CREATE_CONTEXT_LIST)(KSEC_CONTEXT_TYPE);
typedef VOID (SEC_ENTRY KSEC_INSERT_LIST_ENTRY)(PVOID,PKSEC_LIST_ENTRY);
typedef NTSTATUS (SEC_ENTRY KSEC_REFERENCE_LIST_ENTRY)(PKSEC_LIST_ENTRY,ULONG,BOOLEAN);
typedef VOID (SEC_ENTRY KSEC_DEREFERENCE_LIST_ENTRY)(PKSEC_LIST_ENTRY,BOOLEAN*);

KSEC_CREATE_CONTEXT_LIST KSecCreateContextList;
KSEC_INSERT_LIST_ENTRY KSecInsertListEntry;
KSEC_REFERENCE_LIST_ENTRY KSecReferenceListEntry;
KSEC_DEREFERENCE_LIST_ENTRY KSecDereferenceListEntry;

typedef KSEC_CREATE_CONTEXT_LIST *PKSEC_CREATE_CONTEXT_LIST;
typedef KSEC_INSERT_LIST_ENTRY *PKSEC_INSERT_LIST_ENTRY;
typedef KSEC_REFERENCE_LIST_ENTRY *PKSEC_REFERENCE_LIST_ENTRY;
typedef KSEC_DEREFERENCE_LIST_ENTRY *PKSEC_DEREFERENCE_LIST_ENTRY;

typedef struct _SECPKG_KERNEL_FUNCTIONS {
    PLSA_ALLOCATE_LSA_HEAP AllocateHeap;
    PLSA_FREE_LSA_HEAP FreeHeap;
    PKSEC_CREATE_CONTEXT_LIST CreateContextList;
    PKSEC_INSERT_LIST_ENTRY InsertListEntry;
    PKSEC_REFERENCE_LIST_ENTRY ReferenceListEntry;
    PKSEC_DEREFERENCE_LIST_ENTRY DereferenceListEntry;
} SECPKG_KERNEL_FUNCTIONS, *PSECPKG_KERNEL_FUNCTIONS;

typedef NTSTATUS (NTAPI KspInitPackageFn)(PSECPKG_KERNEL_FUNCTIONS);
typedef NTSTATUS (NTAPI KspDeleteContextFn)(LSA_SEC_HANDLE,PLSA_SEC_HANDLE);
typedef NTSTATUS (NTAPI KspInitContextFn)(LSA_SEC_HANDLE,PSecBuffer,PLSA_SEC_HANDLE);
typedef NTSTATUS (NTAPI KspMakeSignatureFn)(LSA_SEC_HANDLE,ULONG,PSecBufferDesc,ULONG);
typedef NTSTATUS (NTAPI KspVerifySignatureFn)(LSA_SEC_HANDLE,PSecBufferDesc,ULONG,PULONG);
typedef NTSTATUS (NTAPI KspSealMessageFn)(LSA_SEC_HANDLE,ULONG,PSecBufferDesc,ULONG);
typedef NTSTATUS (NTAPI KspUnsealMessageFn)(LSA_SEC_HANDLE,PSecBufferDesc,ULONG,PULONG);
typedef NTSTATUS (NTAPI KspGetTokenFn)(LSA_SEC_HANDLE,PHANDLE,PACCESS_TOKEN*);
typedef NTSTATUS (NTAPI KspQueryAttributesFn)(LSA_SEC_HANDLE,ULONG,PVOID);
typedef NTSTATUS (NTAPI KspCompleteTokenFn)(LSA_SEC_HANDLE,PSecBufferDesc);
typedef NTSTATUS (NTAPI KspMapHandleFn)(LSA_SEC_HANDLE,PLSA_SEC_HANDLE);
typedef NTSTATUS (NTAPI KspSetPagingModeFn)(BOOLEAN);

typedef struct _SECPKG_KERNEL_FUNCTION_TABLE {
    KspInitPackageFn *Initialize;
    KspDeleteContextFn *DeleteContext;
    KspInitContextFn *InitContext;
    KspMapHandleFn *MapHandle;
    KspMakeSignatureFn *Sign;
    KspVerifySignatureFn *Verify;
    KspSealMessageFn *Seal;
    KspUnsealMessageFn *Unseal;
    KspGetTokenFn *GetToken;
    KspQueryAttributesFn *QueryAttributes;
    KspCompleteTokenFn *CompleteToken;
    SpExportSecurityContextFn *ExportContext;
    SpImportSecurityContextFn *ImportContext;
    KspSetPagingModeFn *SetPackagePagingMode;
} SECPKG_KERNEL_FUNCTION_TABLE, *PSECPKG_KERNEL_FUNCTION_TABLE;

SECURITY_STATUS SEC_ENTRY KSecRegisterSecurityProvider(PSECURITY_STRING,PSECPKG_KERNEL_FUNCTION_TABLE);

extern SECPKG_KERNEL_FUNCTIONS KspKernelFunctions;

#ifdef __cplusplus
}
#endif

#endif /* _NTSECPKG_ */
