203 lines
5.6 KiB
C++
203 lines
5.6 KiB
C++
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
|
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
|
|
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
|
// PARTICULAR PURPOSE.
|
|
//
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
|
//
|
|
// This file contains sample of CRYPT_XML_DATA_PROVIDER implementation
|
|
// to resolve extrenal references
|
|
//
|
|
|
|
#include "pch.h"
|
|
|
|
/****************************************************************************
|
|
SAMPLE_FILE_DATA_PROVIDER_CLOSE
|
|
|
|
This is a callback function for CRYPT_XML_DATA_PROVIDER,
|
|
used to release the resources created by this data provider.
|
|
|
|
****************************************************************************/
|
|
static
|
|
HRESULT
|
|
CALLBACK
|
|
SAMPLE_FILE_DATA_PROVIDER_CLOSE(
|
|
void *pvCallbackState
|
|
)
|
|
{
|
|
HRESULT hr = NO_ERROR;
|
|
HANDLE hFile = (HANDLE)pvCallbackState;
|
|
|
|
if( INVALID_HANDLE_VALUE != hFile )
|
|
{
|
|
if( !CloseHandle( hFile ) )
|
|
{
|
|
hr = HRESULT_FROM_WIN32( GetLastError() );
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
/****************************************************************************
|
|
SAMPLE_FILE_DATA_PROVIDER_READ
|
|
|
|
This is a callback function for CRYPT_XML_DATA_PROVIDER,
|
|
used to read data from external reference (FILE).
|
|
|
|
****************************************************************************/
|
|
static
|
|
HRESULT
|
|
CALLBACK
|
|
SAMPLE_FILE_DATA_PROVIDER_READ(
|
|
void *pvCallbackState,
|
|
BYTE *pbData,
|
|
ULONG cbData,
|
|
ULONG *pcbRead
|
|
)
|
|
{
|
|
HRESULT hr = NO_ERROR;
|
|
HANDLE hFile = (HANDLE)pvCallbackState;
|
|
|
|
if( INVALID_HANDLE_VALUE == hFile )
|
|
{
|
|
hr = E_INVALIDARG;
|
|
}
|
|
else
|
|
if( !ReadFile(
|
|
hFile,
|
|
pbData,
|
|
cbData,
|
|
pcbRead,
|
|
NULL
|
|
))
|
|
{
|
|
hr = HRESULT_FROM_WIN32( GetLastError() );
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
HrSampleResolveExternalXmlReference
|
|
|
|
This function creates CRYPT_XML_DATA_PROVIDER for the provided URI.
|
|
For the sample purposes, it supports local files only.
|
|
|
|
For more information, see documentation on CryptXmlDigestReference.
|
|
****************************************************************************/
|
|
HRESULT
|
|
WINAPI
|
|
HrSampleResolveExternalXmlReference(
|
|
LPCWSTR wszUri,
|
|
CRYPT_XML_DATA_PROVIDER *pProviderOut
|
|
)
|
|
{
|
|
HRESULT hr = S_FALSE;
|
|
HANDLE hFile = INVALID_HANDLE_VALUE;
|
|
|
|
static WCHAR _wsHttp[] = L"http://";
|
|
const ULONG cwHttp = 7;
|
|
static WCHAR _wsHttps[] = L"https://";
|
|
const ULONG cwHttps = 8;
|
|
|
|
static WCHAR _wsFile[] = L"file://";
|
|
const ULONG cwFile = 7;
|
|
|
|
ULONG cw = 0;
|
|
|
|
ZeroMemory( pProviderOut, sizeof( CRYPT_XML_DATA_PROVIDER ));
|
|
|
|
if( NULL == wszUri || 0 == *wszUri )
|
|
{
|
|
goto CleanUp;
|
|
}
|
|
|
|
LPWSTR wsUri = (LPWSTR)wszUri;
|
|
cw = lstrlenW( wsUri );
|
|
|
|
//
|
|
// Try http
|
|
//
|
|
|
|
if( ( cw > cwHttp &&
|
|
CSTR_EQUAL == CompareStringW(
|
|
LOCALE_NEUTRAL,
|
|
NORM_IGNORECASE,
|
|
wsUri,
|
|
cwHttp,
|
|
_wsHttp,
|
|
cwHttp
|
|
)) ||
|
|
( cw > cwHttps &&
|
|
CSTR_EQUAL == CompareStringW(
|
|
LOCALE_NEUTRAL,
|
|
NORM_IGNORECASE,
|
|
wsUri,
|
|
cwHttps,
|
|
_wsHttps,
|
|
cwHttps
|
|
)))
|
|
{
|
|
//
|
|
// TODO: Retrive from HTTP
|
|
// Add here your implementation to retrieve URI from HTTP
|
|
//
|
|
|
|
hr = E_NOTIMPL;
|
|
goto CleanUp;
|
|
}
|
|
else
|
|
if( cw > cwFile &&
|
|
CSTR_EQUAL == CompareStringW(
|
|
LOCALE_NEUTRAL,
|
|
NORM_IGNORECASE,
|
|
wsUri,
|
|
cwFile,
|
|
_wsFile,
|
|
cwFile
|
|
))
|
|
{
|
|
wsUri += cwFile;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Not supported schema
|
|
//
|
|
// hr = E_INVALIDARG;
|
|
// goto CleanUp;
|
|
|
|
// SAMPLE: here we accept URI without the schema, just a file name
|
|
}
|
|
|
|
//
|
|
// Open the file
|
|
//
|
|
|
|
hFile = CreateFileW(
|
|
wsUri,
|
|
GENERIC_READ,
|
|
FILE_SHARE_READ,
|
|
NULL,
|
|
OPEN_EXISTING,
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
NULL
|
|
);
|
|
if( INVALID_HANDLE_VALUE != hFile )
|
|
{
|
|
pProviderOut->pvCallbackState = hFile;
|
|
pProviderOut->cbBufferSize = 0;
|
|
pProviderOut->pfnRead = SAMPLE_FILE_DATA_PROVIDER_READ;
|
|
pProviderOut->pfnClose = SAMPLE_FILE_DATA_PROVIDER_CLOSE;
|
|
|
|
hr = NO_ERROR;
|
|
goto CleanUp;
|
|
}
|
|
|
|
CleanUp:
|
|
|
|
return hr;
|
|
} |