/*
 * Copyright 2002 Mike McCormack for CodeWeavers
 * Copyright 2005-2008 Juan Lang
 * Copyright 2006 Paul Vriens
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include <stdarg.h>
#include <stdio.h>

#include "windef.h"
#include "winbase.h"
#include "wincrypt.h"
#include "winreg.h"
#include "winnls.h"
#include "mssip.h"
#include "winuser.h"

#include "wine/debug.h"
#include "wine/list.h"

WINE_DEFAULT_DEBUG_CHANNEL(crypt);

static const WCHAR szOID[] = {
    'S','o','f','t','w','a','r','e','\\',
    'M','i','c','r','o','s','o','f','t','\\',
    'C','r','y','p','t','o','g','r','a','p','h','y','\\',
    'O','I','D','\\',
    'E','n','c','o','d','i','n','g','T','y','p','e',' ','0','\\',
    'C','r','y','p','t','S','I','P','D','l','l', 0 };

static const WCHAR szPutSigned[] = {
    'P','u','t','S','i','g','n','e','d','D','a','t','a','M','s','g','\\',0};
static const WCHAR szGetSigned[] = {
    'G','e','t','S','i','g','n','e','d','D','a','t','a','M','s','g','\\',0};
static const WCHAR szRemoveSigned[] = {
    'R','e','m','o','v','e','S','i','g','n','e','d','D','a','t','a','M','s','g','\\',0};
static const WCHAR szCreate[] = {
    'C','r','e','a','t','e','I','n','d','i','r','e','c','t','D','a','t','a','\\',0};
static const WCHAR szVerify[] = {
    'V','e','r','i','f','y','I','n','d','i','r','e','c','t','D','a','t','a','\\',0};
static const WCHAR szIsMyFile[] = {
    'I','s','M','y','F','i','l','e','T','y','p','e','\\',0};
static const WCHAR szIsMyFile2[] = {
    'I','s','M','y','F','i','l','e','T','y','p','e','2','\\',0};

static const WCHAR szDllName[] = { 'D','l','l',0 };
static const WCHAR szFuncName[] = { 'F','u','n','c','N','a','m','e',0 };

/* convert a guid to a wide character string */
static void CRYPT_guid2wstr( const GUID *guid, LPWSTR wstr )
{
    char str[40];

    sprintf(str, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
           guid->Data1, guid->Data2, guid->Data3,
           guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
           guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7] );
    MultiByteToWideChar( CP_ACP, 0, str, -1, wstr, 40 );
}

/***********************************************************************
 *              CRYPT_SIPDeleteFunction
 *
 * Helper function for CryptSIPRemoveProvider
 */
static LONG CRYPT_SIPDeleteFunction( const GUID *guid, LPCWSTR szKey )
{
    WCHAR szFullKey[ 0x100 ];
    LONG r = ERROR_SUCCESS;

    /* max length of szFullKey depends on our code only, so we won't overrun */
    lstrcpyW( szFullKey, szOID );
    lstrcatW( szFullKey, szKey );
    CRYPT_guid2wstr( guid, &szFullKey[ lstrlenW( szFullKey ) ] );

    r = RegDeleteKeyW(HKEY_LOCAL_MACHINE, szFullKey);

    return r;
}

/***********************************************************************
 *             CryptSIPRemoveProvider (CRYPT32.@)
 *
 * Remove a SIP provider and its functions from the registry.
 *
 * PARAMS
 *  pgProv     [I] Pointer to a GUID for this SIP provider
 *
 * RETURNS
 *  Success: TRUE.
 *  Failure: FALSE. (Look at GetLastError()).
 *
 * NOTES
 *  Registry errors are always reported via SetLastError(). Every registry
 *  deletion will be tried.
 */
BOOL WINAPI CryptSIPRemoveProvider(GUID *pgProv)
{
    LONG r = ERROR_SUCCESS;
    LONG remove_error = ERROR_SUCCESS;

    TRACE("%s\n", debugstr_guid(pgProv));

    if (!pgProv)
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }


#define CRYPT_SIPREMOVEPROV( key ) \
    r = CRYPT_SIPDeleteFunction( pgProv, key); \
    if (r != ERROR_SUCCESS) remove_error = r

    CRYPT_SIPREMOVEPROV( szPutSigned);
    CRYPT_SIPREMOVEPROV( szGetSigned);
    CRYPT_SIPREMOVEPROV( szRemoveSigned);
    CRYPT_SIPREMOVEPROV( szCreate);
    CRYPT_SIPREMOVEPROV( szVerify);
    CRYPT_SIPREMOVEPROV( szIsMyFile);
    CRYPT_SIPREMOVEPROV( szIsMyFile2);

#undef CRYPT_SIPREMOVEPROV

    if (remove_error != ERROR_SUCCESS)
    {
        SetLastError(remove_error);
        return FALSE;
    }

    return TRUE;
}

/*
 * Helper for CryptSIPAddProvider
 *
 * Add a registry key containing a dll name and function under
 *  "Software\\Microsoft\\Cryptography\\OID\\EncodingType 0\\<func>\\<guid>"
 */
static LONG CRYPT_SIPWriteFunction( const GUID *guid, LPCWSTR szKey,
              LPCWSTR szDll, LPCWSTR szFunction )
{
    WCHAR szFullKey[ 0x100 ];
    LONG r = ERROR_SUCCESS;
    HKEY hKey;

    if( !szFunction )
         return ERROR_SUCCESS;

    /* max length of szFullKey depends on our code only, so we won't overrun */
    lstrcpyW( szFullKey, szOID );
    lstrcatW( szFullKey, szKey );
    CRYPT_guid2wstr( guid, &szFullKey[ lstrlenW( szFullKey ) ] );

    TRACE("key is %s\n", debugstr_w( szFullKey ) );

    r = RegCreateKeyW( HKEY_LOCAL_MACHINE, szFullKey, &hKey );
    if( r != ERROR_SUCCESS ) goto error_close_key;

    /* write the values */
    r = RegSetValueExW( hKey, szFuncName, 0, REG_SZ, (const BYTE*) szFunction,
                        ( lstrlenW( szFunction ) + 1 ) * sizeof (WCHAR) );
    if( r != ERROR_SUCCESS ) goto error_close_key;
    r = RegSetValueExW( hKey, szDllName, 0, REG_SZ, (const BYTE*) szDll,
                        ( lstrlenW( szDll ) + 1) * sizeof (WCHAR) );

error_close_key:

    RegCloseKey( hKey );

    return r;
}

/***********************************************************************
 *             CryptSIPAddProvider (CRYPT32.@)
 *
 * Add a SIP provider and its functions to the registry.
 *
 * PARAMS
 *  psNewProv       [I] Pointer to a structure with information about
 *                      the functions this SIP provider can perform.
 *
 * RETURNS
 *  Success: TRUE.
 *  Failure: FALSE. (Look at GetLastError()).
 *
 * NOTES
 *  Registry errors are always reported via SetLastError(). If a
 *  registry error occurs the rest of the registry write operations
 *  will be skipped.
 */
BOOL WINAPI CryptSIPAddProvider(SIP_ADD_NEWPROVIDER *psNewProv)
{
    LONG r = ERROR_SUCCESS;

    TRACE("%p\n", psNewProv);

    if (!psNewProv ||
        psNewProv->cbStruct != sizeof(SIP_ADD_NEWPROVIDER) ||
        !psNewProv->pwszGetFuncName ||
        !psNewProv->pwszPutFuncName ||
        !psNewProv->pwszCreateFuncName ||
        !psNewProv->pwszVerifyFuncName ||
        !psNewProv->pwszRemoveFuncName)
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

    TRACE("%s %s %s %s %s\n",
          debugstr_guid( psNewProv->pgSubject ),
          debugstr_w( psNewProv->pwszDLLFileName ),
          debugstr_w( psNewProv->pwszMagicNumber ),
          debugstr_w( psNewProv->pwszIsFunctionName ),
          debugstr_w( psNewProv->pwszIsFunctionNameFmt2 ) );

#define CRYPT_SIPADDPROV( key, field ) \
    r = CRYPT_SIPWriteFunction( psNewProv->pgSubject, key, \
           psNewProv->pwszDLLFileName, psNewProv->field); \
    if (r != ERROR_SUCCESS) goto end_function

    CRYPT_SIPADDPROV( szPutSigned, pwszPutFuncName );
    CRYPT_SIPADDPROV( szGetSigned, pwszGetFuncName );
    CRYPT_SIPADDPROV( szRemoveSigned, pwszRemoveFuncName );
    CRYPT_SIPADDPROV( szCreate, pwszCreateFuncName );
    CRYPT_SIPADDPROV( szVerify, pwszVerifyFuncName );
    CRYPT_SIPADDPROV( szIsMyFile, pwszIsFunctionName );
    CRYPT_SIPADDPROV( szIsMyFile2, pwszIsFunctionNameFmt2 );

#undef CRYPT_SIPADDPROV

end_function:

    if (r != ERROR_SUCCESS)
    {
        SetLastError(r);
        return FALSE;
    }

    return TRUE;
}

static void *CRYPT_LoadSIPFuncFromKey(HKEY key, HMODULE *pLib)
{
    LONG r;
    DWORD size;
    WCHAR dllName[MAX_PATH];
    char functionName[MAX_PATH];
    HMODULE lib;
    void *func = NULL;

    /* Read the DLL entry */
    size = sizeof(dllName);
    r = RegQueryValueExW(key, szDllName, NULL, NULL, (LPBYTE)dllName, &size);
    if (r) goto end;

    /* Read the Function entry */
    size = sizeof(functionName);
    r = RegQueryValueExA(key, "FuncName", NULL, NULL, (LPBYTE)functionName,
     &size);
    if (r) goto end;

    lib = LoadLibraryW(dllName);
    if (!lib)
        goto end;
    func = GetProcAddress(lib, functionName);
    if (func)
        *pLib = lib;
    else
        FreeLibrary(lib);

end:
    return func;
}

/***********************************************************************
 *             CryptSIPRetrieveSubjectGuid (CRYPT32.@)
 *
 * Determine the right SIP GUID for the given file.
 *
 * PARAMS
 *  FileName   [I] Filename.
 *  hFileIn    [I] Optional handle to the file.
 *  pgSubject  [O] The SIP's GUID.
 *
 * RETURNS
 *  Success: TRUE. pgSubject contains the SIP GUID.
 *  Failure: FALSE. (Look at GetLastError()).
 *
 * NOTES
 *  On failure pgSubject will contain a NULL GUID.
 *  The handle is always preferred above the filename.
 */
BOOL WINAPI CryptSIPRetrieveSubjectGuid
      (LPCWSTR FileName, HANDLE hFileIn, GUID *pgSubject)
{
    HANDLE hFile;
    BOOL   bRet = FALSE;
    DWORD  count;
    LARGE_INTEGER zero, oldPos;
    /* FIXME, find out if there is a name for this GUID */
    static const GUID unknown = { 0xC689AAB8, 0x8E78, 0x11D0, { 0x8C,0x47,0x00,0xC0,0x4F,0xC2,0x95,0xEE }};
    static const GUID cabGUID = { 0xc689aaba, 0x8e78, 0x11d0, {0x8c,0x47,0x00,0xc0,0x4f,0xc2,0x95,0xee }};
    static const GUID catGUID = { 0xDE351A43, 0x8E59, 0x11D0, { 0x8C,0x47,0x00,0xC0,0x4F,0xC2,0x95,0xEE }};
    static const WORD dosHdr = IMAGE_DOS_SIGNATURE;
    static const BYTE cabHdr[] = { 'M','S','C','F' };
    BYTE hdr[SIP_MAX_MAGIC_NUMBER];
    WCHAR szFullKey[ 0x100 ];
    LONG r = ERROR_SUCCESS;
    HKEY key;

    TRACE("(%s %p %p)\n", wine_dbgstr_w(FileName), hFileIn, pgSubject);

    if (!pgSubject || (!FileName && !hFileIn))
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

    /* Set pgSubject to zero's */
    memset(pgSubject, 0 , sizeof(GUID));

    if (hFileIn)
        /* Use the given handle, make sure not to close this one ourselves */
        hFile = hFileIn;
    else
    {
        hFile = CreateFileW(FileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
        /* Last error is set by CreateFile */
        if (hFile == INVALID_HANDLE_VALUE) return FALSE;
    }

    zero.QuadPart = 0;
    SetFilePointerEx(hFile, zero, &oldPos, FILE_CURRENT);
    SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
    if (!ReadFile(hFile, hdr, sizeof(hdr), &count, NULL))
        goto cleanup;

    if (count < SIP_MAX_MAGIC_NUMBER)
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        goto cleanup;
    }

    TRACE("file magic = 0x%02x%02x%02x%02x\n", hdr[0], hdr[1], hdr[2], hdr[3]);
    /* As everything is in place now we start looking at the file header */
    if (!memcmp(hdr, &dosHdr, sizeof(dosHdr)))
    {
        *pgSubject = unknown;
        SetLastError(S_OK);
        bRet = TRUE;
        goto cleanup;
    }
    /* Quick-n-dirty check for a cab file. */
    if (!memcmp(hdr, cabHdr, sizeof(cabHdr)))
    {
        *pgSubject = cabGUID;
        SetLastError(S_OK);
        bRet = TRUE;
        goto cleanup;
    }
    /* If it's asn.1-encoded, it's probably a .cat file. */
    if (hdr[0] == 0x30)
    {
        DWORD fileLen = GetFileSize(hFile, NULL);

        TRACE("fileLen = %d\n", fileLen);
        /* Sanity-check length */
        if (hdr[1] < 0x80 && fileLen == 2 + hdr[1])
        {
            *pgSubject = catGUID;
            SetLastError(S_OK);
            bRet = TRUE;
            goto cleanup;
        }
        else if (hdr[1] == 0x80)
        {
            /* Indefinite length, can't verify with just the header, assume it
             * is.
             */
            *pgSubject = catGUID;
            SetLastError(S_OK);
            bRet = TRUE;
            goto cleanup;
        }
        else
        {
            BYTE lenBytes = hdr[1] & 0x7f;

            if (lenBytes == 1 && fileLen == 2 + lenBytes + hdr[2])
            {
                *pgSubject = catGUID;
                SetLastError(S_OK);
                bRet = TRUE;
                goto cleanup;
            }
            else if (lenBytes == 2 && fileLen == 2 + lenBytes +
             (hdr[2] << 8 | hdr[3]))
            {
                *pgSubject = catGUID;
                SetLastError(S_OK);
                bRet = TRUE;
                goto cleanup;
            }
            else if (fileLen > 0xffff)
            {
                /* The file size must be greater than 2 bytes in length, so
                 * assume it is a .cat file
                 */
                *pgSubject = catGUID;
                SetLastError(S_OK);
                bRet = TRUE;
                goto cleanup;
            }
        }
    }

    /* Check for supported functions using CryptSIPDllIsMyFileType */
    /* max length of szFullKey depends on our code only, so we won't overrun */
    lstrcpyW(szFullKey, szOID);
    lstrcatW(szFullKey, szIsMyFile);
    r = RegOpenKeyExW(HKEY_LOCAL_MACHINE, szFullKey, 0, KEY_READ, &key);
    if (r == ERROR_SUCCESS)
    {
        DWORD index = 0, size;
        WCHAR subKeyName[MAX_PATH];

        do {
            size = sizeof(subKeyName) / sizeof(subKeyName[0]);
            r = RegEnumKeyExW(key, index++, subKeyName, &size, NULL, NULL,
             NULL, NULL);
            if (r == ERROR_SUCCESS)
            {
                HKEY subKey;

                r = RegOpenKeyExW(key, subKeyName, 0, KEY_READ, &subKey);
                if (r == ERROR_SUCCESS)
                {
                    HMODULE lib;
                    pfnIsFileSupported isMy = CRYPT_LoadSIPFuncFromKey(subKey,
                     &lib);

                    if (isMy)
                    {
                        bRet = isMy(hFile, pgSubject);
                        FreeLibrary(lib);
                    }
                    RegCloseKey(subKey);
                }
            }
        } while (!bRet && r == ERROR_SUCCESS);
        RegCloseKey(key);
    }

    /* Check for supported functions using CryptSIPDllIsMyFileType2 */
    if (!bRet)
    {
        lstrcpyW(szFullKey, szOID);
        lstrcatW(szFullKey, szIsMyFile2);
        r = RegOpenKeyExW(HKEY_LOCAL_MACHINE, szFullKey, 0, KEY_READ, &key);
        if (r == ERROR_SUCCESS)
        {
            DWORD index = 0, size;
            WCHAR subKeyName[MAX_PATH];

            do {
                size = sizeof(subKeyName) / sizeof(subKeyName[0]);
                r = RegEnumKeyExW(key, index++, subKeyName, &size, NULL, NULL,
                 NULL, NULL);
                if (r == ERROR_SUCCESS)
                {
                    HKEY subKey;

                    r = RegOpenKeyExW(key, subKeyName, 0, KEY_READ, &subKey);
                    if (r == ERROR_SUCCESS)
                    {
                        HMODULE lib;
                        pfnIsFileSupportedName isMy2 =
                         CRYPT_LoadSIPFuncFromKey(subKey, &lib);

                        if (isMy2)
                        {
                            bRet = isMy2((LPWSTR)FileName, pgSubject);
                            FreeLibrary(lib);
                        }
                        RegCloseKey(subKey);
                    }
                }
            } while (!bRet && r == ERROR_SUCCESS);
            RegCloseKey(key);
        }
    }

    if (!bRet)
        SetLastError(TRUST_E_SUBJECT_FORM_UNKNOWN);

cleanup:
    /* If we didn't open this one we shouldn't close it (hFile is a copy),
     * but we should reset the file pointer to its original position.
     */
    if (!hFileIn)
        CloseHandle(hFile);
    else
        SetFilePointerEx(hFile, oldPos, NULL, FILE_BEGIN);

    return bRet;
}

static LONG CRYPT_OpenSIPFunctionKey(const GUID *guid, LPCWSTR function,
 HKEY *key)
{
    WCHAR szFullKey[ 0x100 ];

    lstrcpyW(szFullKey, szOID);
    lstrcatW(szFullKey, function);
    CRYPT_guid2wstr(guid, &szFullKey[lstrlenW(szFullKey)]);
    return RegOpenKeyExW(HKEY_LOCAL_MACHINE, szFullKey, 0, KEY_READ, key);
}

/* Loads the function named function for the SIP specified by pgSubject, and
 * returns it if found.  Returns NULL on error.  If the function is loaded,
 * *pLib is set to the library in which it is found.
 */
static void *CRYPT_LoadSIPFunc(const GUID *pgSubject, LPCWSTR function,
 HMODULE *pLib)
{
    LONG r;
    HKEY key;
    void *func = NULL;

    TRACE("(%s, %s)\n", debugstr_guid(pgSubject), debugstr_w(function));

    r = CRYPT_OpenSIPFunctionKey(pgSubject, function, &key);
    if (!r)
    {
        func = CRYPT_LoadSIPFuncFromKey(key, pLib);
        RegCloseKey(key);
    }
    TRACE("returning %p\n", func);
    return func;
}

typedef struct _WINE_SIP_PROVIDER {
    GUID              subject;
    SIP_DISPATCH_INFO info;
    struct list       entry;
} WINE_SIP_PROVIDER;

static struct list providers = { &providers, &providers };
static CRITICAL_SECTION providers_cs;
static CRITICAL_SECTION_DEBUG providers_cs_debug =
{
    0, 0, &providers_cs,
    { &providers_cs_debug.ProcessLocksList,
    &providers_cs_debug.ProcessLocksList },
    0, 0, { (DWORD_PTR)(__FILE__ ": providers_cs") }
};
static CRITICAL_SECTION providers_cs = { &providers_cs_debug, -1, 0, 0, 0, 0 };

static void CRYPT_CacheSIP(const GUID *pgSubject, SIP_DISPATCH_INFO *info)
{
    WINE_SIP_PROVIDER *prov = CryptMemAlloc(sizeof(WINE_SIP_PROVIDER));

    if (prov)
    {
        prov->subject = *pgSubject;
        prov->info = *info;
        EnterCriticalSection(&providers_cs);
        list_add_tail(&providers, &prov->entry);
        LeaveCriticalSection(&providers_cs);
    }
}

static WINE_SIP_PROVIDER *CRYPT_GetCachedSIP(const GUID *pgSubject)
{
    WINE_SIP_PROVIDER *provider = NULL, *ret = NULL;

    EnterCriticalSection(&providers_cs);
    LIST_FOR_EACH_ENTRY(provider, &providers, WINE_SIP_PROVIDER, entry)
    {
        if (IsEqualGUID(pgSubject, &provider->subject))
            break;
    }
    if (provider && IsEqualGUID(pgSubject, &provider->subject))
        ret = provider;
    LeaveCriticalSection(&providers_cs);
    return ret;
}

static inline BOOL CRYPT_IsSIPCached(const GUID *pgSubject)
{
    return CRYPT_GetCachedSIP(pgSubject) != NULL;
}

void crypt_sip_free(void)
{
    WINE_SIP_PROVIDER *prov, *next;

    LIST_FOR_EACH_ENTRY_SAFE(prov, next, &providers, WINE_SIP_PROVIDER, entry)
    {
        list_remove(&prov->entry);
        FreeLibrary(prov->info.hSIP);
        CryptMemFree(prov);
    }
}

/* Loads the SIP for pgSubject into the global cache.  Returns FALSE if the
 * SIP isn't registered or is invalid.
 */
static BOOL CRYPT_LoadSIP(const GUID *pgSubject)
{
    SIP_DISPATCH_INFO sip = { 0 };
    HMODULE lib = NULL, temp = NULL;

    sip.pfGet = CRYPT_LoadSIPFunc(pgSubject, szGetSigned, &lib);
    if (!sip.pfGet)
        goto error;
    sip.pfPut = CRYPT_LoadSIPFunc(pgSubject, szPutSigned, &temp);
    if (!sip.pfPut || temp != lib)
        goto error;
    FreeLibrary(temp);
    sip.pfCreate = CRYPT_LoadSIPFunc(pgSubject, szCreate, &temp);
    if (!sip.pfCreate || temp != lib)
        goto error;
    FreeLibrary(temp);
    sip.pfVerify = CRYPT_LoadSIPFunc(pgSubject, szVerify, &temp);
    if (!sip.pfVerify || temp != lib)
        goto error;
    FreeLibrary(temp);
    sip.pfRemove = CRYPT_LoadSIPFunc(pgSubject, szRemoveSigned, &temp);
    if (!sip.pfRemove || temp != lib)
        goto error;
    FreeLibrary(temp);
    sip.hSIP = lib;
    CRYPT_CacheSIP(pgSubject, &sip);
    return TRUE;

error:
    FreeLibrary(lib);
    FreeLibrary(temp);
    SetLastError(TRUST_E_SUBJECT_FORM_UNKNOWN);
    return FALSE;
}

/***********************************************************************
 *             CryptSIPLoad (CRYPT32.@)
 *
 * Load some internal crypt32 functions into a SIP_DISPATCH_INFO structure.
 *
 * PARAMS
 *  pgSubject    [I] The GUID.
 *  dwFlags      [I] Flags.
 *  pSipDispatch [I] The loaded functions.
 *
 * RETURNS
 *  Success: TRUE. pSipDispatch contains the functions.
 *  Failure: FALSE. (Look at GetLastError()).
 *
 * NOTES
 *  CryptSIPLoad uses caching for the list of GUIDs and whether a SIP is
 *  already loaded.
 *
 *  An application calls CryptSipLoad which will return a structure with the
 *  function addresses of some internal crypt32 functions. The application will
 *  then call these functions which will be forwarded to the appropriate SIP.
 *
 *  CryptSIPLoad will load the needed SIP but doesn't unload this dll. The unloading
 *  is done when crypt32 is unloaded.
 */
BOOL WINAPI CryptSIPLoad
       (const GUID *pgSubject, DWORD dwFlags, SIP_DISPATCH_INFO *pSipDispatch)
{
    TRACE("(%s %d %p)\n", debugstr_guid(pgSubject), dwFlags, pSipDispatch);

    if (!pgSubject || dwFlags != 0 || !pSipDispatch)
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }
    if (!CRYPT_IsSIPCached(pgSubject) && !CRYPT_LoadSIP(pgSubject))
        return FALSE;

    pSipDispatch->hSIP = NULL;
    pSipDispatch->pfGet = CryptSIPGetSignedDataMsg;
    pSipDispatch->pfPut = CryptSIPPutSignedDataMsg;
    pSipDispatch->pfCreate = CryptSIPCreateIndirectData;
    pSipDispatch->pfVerify = CryptSIPVerifyIndirectData;
    pSipDispatch->pfRemove = CryptSIPRemoveSignedDataMsg;

    return TRUE;
}

/***********************************************************************
 *             CryptSIPCreateIndirectData (CRYPT32.@)
 */
BOOL WINAPI CryptSIPCreateIndirectData(SIP_SUBJECTINFO* pSubjectInfo, DWORD* pcbIndirectData,
                                       SIP_INDIRECT_DATA* pIndirectData)
{
    WINE_SIP_PROVIDER *sip;
    BOOL ret = FALSE;

    TRACE("(%p %p %p)\n", pSubjectInfo, pcbIndirectData, pIndirectData);

    if ((sip = CRYPT_GetCachedSIP(pSubjectInfo->pgSubjectType)))
        ret = sip->info.pfCreate(pSubjectInfo, pcbIndirectData, pIndirectData);
    TRACE("returning %d\n", ret);
    return ret;
}

/***********************************************************************
 *             CryptSIPGetSignedDataMsg (CRYPT32.@)
 */
BOOL WINAPI CryptSIPGetSignedDataMsg(SIP_SUBJECTINFO* pSubjectInfo, DWORD* pdwEncodingType,
                                       DWORD dwIndex, DWORD* pcbSignedDataMsg, BYTE* pbSignedDataMsg)
{
    WINE_SIP_PROVIDER *sip;
    BOOL ret = FALSE;

    TRACE("(%p %p %d %p %p)\n", pSubjectInfo, pdwEncodingType, dwIndex,
          pcbSignedDataMsg, pbSignedDataMsg);

    if ((sip = CRYPT_GetCachedSIP(pSubjectInfo->pgSubjectType)))
        ret = sip->info.pfGet(pSubjectInfo, pdwEncodingType, dwIndex,
         pcbSignedDataMsg, pbSignedDataMsg);
    TRACE("returning %d\n", ret);
    return ret;
}

/***********************************************************************
 *             CryptSIPPutSignedDataMsg (CRYPT32.@)
 */
BOOL WINAPI CryptSIPPutSignedDataMsg(SIP_SUBJECTINFO* pSubjectInfo, DWORD pdwEncodingType,
                                       DWORD* pdwIndex, DWORD cbSignedDataMsg, BYTE* pbSignedDataMsg)
{
    WINE_SIP_PROVIDER *sip;
    BOOL ret = FALSE;

    TRACE("(%p %d %p %d %p)\n", pSubjectInfo, pdwEncodingType, pdwIndex,
          cbSignedDataMsg, pbSignedDataMsg);

    if ((sip = CRYPT_GetCachedSIP(pSubjectInfo->pgSubjectType)))
        ret = sip->info.pfPut(pSubjectInfo, pdwEncodingType, pdwIndex,
         cbSignedDataMsg, pbSignedDataMsg);
    TRACE("returning %d\n", ret);
    return ret;
}

/***********************************************************************
 *             CryptSIPRemoveSignedDataMsg (CRYPT32.@)
 */
BOOL WINAPI CryptSIPRemoveSignedDataMsg(SIP_SUBJECTINFO* pSubjectInfo,
                                       DWORD dwIndex)
{
    WINE_SIP_PROVIDER *sip;
    BOOL ret = FALSE;

    TRACE("(%p %d)\n", pSubjectInfo, dwIndex);

    if ((sip = CRYPT_GetCachedSIP(pSubjectInfo->pgSubjectType)))
        ret = sip->info.pfRemove(pSubjectInfo, dwIndex);
    TRACE("returning %d\n", ret);
    return ret;
}

/***********************************************************************
 *             CryptSIPVerifyIndirectData (CRYPT32.@)
 */
BOOL WINAPI CryptSIPVerifyIndirectData(SIP_SUBJECTINFO* pSubjectInfo,
                                       SIP_INDIRECT_DATA* pIndirectData)
{
    WINE_SIP_PROVIDER *sip;
    BOOL ret = FALSE;

    TRACE("(%p %p)\n", pSubjectInfo, pIndirectData);

    if ((sip = CRYPT_GetCachedSIP(pSubjectInfo->pgSubjectType)))
        ret = sip->info.pfVerify(pSubjectInfo, pIndirectData);
    TRACE("returning %d\n", ret);
    return ret;
}
