コード例 #1
0
ファイル: main.c プロジェクト: Dimillian/wine
/*****************************************************************************
 * Main entry point. This is a console application so we have a wmain() not a
 * winmain().
 */
int wmain(int argc, WCHAR *argv[])
{
    static const WCHAR nohomeW[] = {'-','n','o','h','o','m','e',0};

    WCHAR *url = argv[1];
    BSTR display_uri;
    DWORD scheme;
    IUri *uri;
    HRESULT hres;
    int ret = 1;

    /* DDE used only if -nohome is specified; avoids delay in printing usage info
     * when no parameters are passed */
    if (url && !strcmpiW( url, nohomeW ))
        url = argc > 2 ? argv[2] : get_url_from_dde();

    if (!url) {
        WINE_ERR( "Usage: winebrowser URL\n" );
        return -1;
    }

    hres = CreateUri(url, Uri_CREATE_ALLOW_IMPLICIT_FILE_SCHEME|Uri_CREATE_FILE_USE_DOS_PATH, 0, &uri);
    if(FAILED(hres)) {
        WINE_ERR("Failed to parse URL\n");
        ret = open_http_url(url);
        HeapFree(GetProcessHeap(), 0, ddeString);
        return ret;
    }

    HeapFree(GetProcessHeap(), 0, ddeString);
    IUri_GetScheme(uri, &scheme);

    if(scheme == URL_SCHEME_FILE) {
        IUri *file_uri;

        file_uri = convert_file_uri(uri);
        if(file_uri) {
            IUri_Release(uri);
            uri = file_uri;
        }else {
            WINE_ERR("Failed to convert file URL to unix path\n");
        }
    }

    hres = IUri_GetDisplayUri(uri, &display_uri);
    IUri_Release(uri);
    if(FAILED(hres))
        return -1;

    WINE_TRACE("opening %s\n", wine_dbgstr_w(display_uri));

    if(scheme == URL_SCHEME_MAILTO)
        ret = open_mailto_url(display_uri);
    else
        /* let the browser decide how to handle the given url */
        ret = open_http_url(display_uri);

    SysFreeString(display_uri);
    return ret;
}
コード例 #2
0
static HRESULT WINAPI FtpProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl,
                                        IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
                                        DWORD grfPI, HANDLE_PTR dwReserved)
{
    FtpProtocol *This = PROTOCOL_THIS(iface);
    IUri *uri;
    HRESULT hres;

    static const WCHAR ftpW[] = {'f','t','p',':'};

    TRACE("(%p)->(%s %p %p %08x %lx)\n", This, debugstr_w(szUrl), pOIProtSink,
          pOIBindInfo, grfPI, dwReserved);

    if(strncmpW(szUrl, ftpW, sizeof(ftpW)/sizeof(WCHAR)))
        return MK_E_SYNTAX;

    hres = CreateUri(szUrl, 0, 0, &uri);
    if(FAILED(hres))
        return hres;

    hres = protocol_start(&This->base, PROTOCOL(This), uri, pOIProtSink, pOIBindInfo);

    IUri_Release(uri);
    return hres;
}
コード例 #3
0
ファイル: bsc.c プロジェクト: Moteesh/reactos
HRESULT create_uri(const WCHAR *url, IUri **uri)
{
    WCHAR fileUrl[INTERNET_MAX_URL_LENGTH];

    TRACE("%s\n", debugstr_w(url));

    if (!PathIsURLW(url))
    {
        WCHAR fullpath[MAX_PATH];
        DWORD needed = ARRAY_SIZE(fileUrl);

        if (!PathSearchAndQualifyW(url, fullpath, ARRAY_SIZE(fullpath)))
        {
            WARN("can't find path\n");
            return E_FAIL;
        }

        if (FAILED(UrlCreateFromPathW(fullpath, fileUrl, &needed, 0)))
        {
            ERR("can't create url from path\n");
            return E_FAIL;
        }
        url = fileUrl;
    }

    return CreateUri(url, Uri_CREATE_ALLOW_RELATIVE | Uri_CREATE_ALLOW_IMPLICIT_FILE_SCHEME, 0, uri);
}
コード例 #4
0
ファイル: axinstall.c プロジェクト: Kelimion/wine
/***********************************************************************
 *           AsyncInstallDistributionUnit (URLMON.@)
 */
HRESULT WINAPI AsyncInstallDistributionUnit(const WCHAR *szDistUnit, const WCHAR *szTYPE, const WCHAR *szExt,
        DWORD dwFileVersionMS, DWORD dwFileVersionLS, const WCHAR *szURL, IBindCtx *pbc, void *pvReserved, DWORD flags)
{
    install_ctx_t *ctx;
    HRESULT hres;

    TRACE("(%s %s %s %x %x %s %p %p %x)\n", debugstr_w(szDistUnit), debugstr_w(szTYPE), debugstr_w(szExt),
          dwFileVersionMS, dwFileVersionLS, debugstr_w(szURL), pbc, pvReserved, flags);

    if(szDistUnit || szTYPE || szExt)
        FIXME("Unsupported arguments\n");

    ctx = heap_alloc_zero(sizeof(*ctx));
    if(!ctx)
        return E_OUTOFMEMORY;

    hres = CreateUri(szURL, 0, 0, &ctx->uri);
    if(FAILED(hres)) {
        heap_free(ctx);
        return E_OUTOFMEMORY;
    }

    ctx->callback = bsc_from_bctx(pbc);

    hres = download_to_cache(ctx->uri, distunit_on_stop, ctx, ctx->callback);
    if(hres == MK_S_ASYNCHRONOUS)
        ctx->release_on_stop = TRUE;
    else
        release_install_ctx(ctx);

    return hres;
}
コード例 #5
0
ファイル: MessageBuilder.c プロジェクト: yjjfirst/x-sip
struct Header *BuildResponseContactHeader(MESSAGE *request)
{
    CONTACT_HEADER *c = CreateContactHeader();
    URI *uri = CreateUri(URI_SCHEME_SIP, "88001", GetLocalIpAddr(), LOCAL_PORT);

    ContactHeaderSetUri(c, uri);

    return (struct Header *)c;
}
コード例 #6
0
ファイル: sec_mgr.c プロジェクト: dvdhoo/wine
/********************************************************************
 *      CoInternetGetSecurityUrlEx (URLMON.@)
 */
HRESULT WINAPI CoInternetGetSecurityUrlEx(IUri *pUri, IUri **ppSecUri, PSUACTION psuAction, DWORD_PTR dwReserved)
{
    URL_SCHEME scheme_type;
    BSTR secure_uri;
    WCHAR *ret_url;
    HRESULT hres;

    TRACE("(%p,%p,%u,%u)\n", pUri, ppSecUri, psuAction, (DWORD)dwReserved);

    if(!pUri || !ppSecUri)
        return E_INVALIDARG;

    hres = IUri_GetDisplayUri(pUri, &secure_uri);
    if(FAILED(hres))
        return hres;

    hres = parse_security_url(secure_uri, psuAction, &ret_url);
    SysFreeString(secure_uri);
    if(FAILED(hres))
        return hres;

    hres = CreateUri(ret_url, Uri_CREATE_ALLOW_IMPLICIT_WILDCARD_SCHEME, 0, ppSecUri);
    if(FAILED(hres)) {
        CoTaskMemFree(ret_url);
        return hres;
    }

    /* File URIs have to hierarchical. */
    hres = IUri_GetScheme(pUri, (DWORD*)&scheme_type);
    if(SUCCEEDED(hres) && scheme_type == URL_SCHEME_FILE) {
        const WCHAR *tmp = ret_url;

        /* Check and see if a "//" is after the scheme name. */
        tmp += sizeof(fileW)/sizeof(WCHAR);
        if(*tmp != '/' || *(tmp+1) != '/')
            hres = E_INVALIDARG;
    }

    if(SUCCEEDED(hres))
        hres = CreateUri(ret_url, Uri_CREATE_ALLOW_IMPLICIT_WILDCARD_SCHEME, 0, ppSecUri);
    CoTaskMemFree(ret_url);
    return hres;
}
コード例 #7
0
ファイル: MessageBuilder.c プロジェクト: yjjfirst/x-sip
struct Header *BuildRequestContactHeader(MESSAGE *message, struct Dialog *dialog)
{
    struct UserAgent *ua = DialogGetUserAgent(dialog);
    URI *uri = CreateUri(URI_SCHEME_SIP, UaGetUserName(ua), GetLocalIpAddr(), 0);
    UriAddParameter(uri, "line", "6c451db26592505");
    CONTACT_HEADER *contact = CreateContactHeader();

    ContactHeaderSetUri(contact, uri);
    return  (struct Header *)contact;
}
コード例 #8
0
ファイル: persist.c プロジェクト: RareHare/reactos
void set_current_mon(HTMLOuterWindow *This, IMoniker *mon, DWORD flags)
{
    IUriContainer *uri_container;
    IUri *uri = NULL;
    HRESULT hres;

    if(This->mon) {
        if(This->doc_obj && !(flags & (BINDING_REPLACE|BINDING_REFRESH)))
            notify_travellog_update(This->doc_obj);
        IMoniker_Release(This->mon);
        This->mon = NULL;
    }

    This->load_flags = flags;
    if(!mon)
        return;

    IMoniker_AddRef(mon);
    This->mon = mon;

    hres = IMoniker_QueryInterface(mon, &IID_IUriContainer, (void**)&uri_container);
    if(SUCCEEDED(hres)) {
        hres = IUriContainer_GetIUri(uri_container, &uri);
        IUriContainer_Release(uri_container);
        if(hres != S_OK) {
            WARN("GetIUri failed: %08x\n", hres);
            uri = NULL;
        }
    }

    if(!uri) {
        WCHAR *url;

        hres = IMoniker_GetDisplayName(mon, NULL, NULL, &url);
        if(SUCCEEDED(hres)) {
            hres = CreateUri(url, 0, 0, &uri);
            if(FAILED(hres)) {
                WARN("CrateUri failed: %08x\n", hres);
                set_current_uri(This, NULL);
                This->url = SysAllocString(url);
                CoTaskMemFree(url);
                return;
            }
            CoTaskMemFree(url);
        }else {
            WARN("GetDisplayName failed: %08x\n", hres);
        }
    }

    set_current_uri(This, uri);
    if(uri)
        IUri_Release(uri);
    set_script_mode(This, use_gecko_script(This) ? SCRIPTMODE_GECKO : SCRIPTMODE_ACTIVESCRIPT);
}
コード例 #9
0
ファイル: persist.c プロジェクト: RareHare/reactos
static HRESULT WINAPI PersistHistory_LoadHistory(IPersistHistory *iface, IStream *pStream, IBindCtx *pbc)
{
    HTMLDocument *This = impl_from_IPersistHistory(iface);
    ULONG str_len, read;
    WCHAR *uri_str;
    IUri *uri;
    HRESULT hres;

    TRACE("(%p)->(%p %p)\n", This, pStream, pbc);

    if(!This->window) {
        FIXME("No current window\n");
        return E_UNEXPECTED;
    }

    if(pbc)
        FIXME("pbc not supported\n");

    if(This->doc_obj->client) {
        IOleCommandTarget *cmdtrg = NULL;

        hres = IOleClientSite_QueryInterface(This->doc_obj->client, &IID_IOleCommandTarget,
                (void**)&cmdtrg);
        if(SUCCEEDED(hres)) {
            IOleCommandTarget_Exec(cmdtrg, &CGID_ShellDocView, 138, 0, NULL, NULL);
            IOleCommandTarget_Release(cmdtrg);
        }
    }

    hres = IStream_Read(pStream, &str_len, sizeof(str_len), &read);
    if(FAILED(hres))
        return hres;
    if(read != sizeof(str_len))
        return E_FAIL;

    uri_str = heap_alloc((str_len+1)*sizeof(WCHAR));
    if(!uri_str)
        return E_OUTOFMEMORY;

    hres = IStream_Read(pStream, uri_str, str_len*sizeof(WCHAR), &read);
    if(SUCCEEDED(hres) && read != str_len*sizeof(WCHAR))
        hres = E_FAIL;
    if(SUCCEEDED(hres)) {
        uri_str[str_len] = 0;
        hres = CreateUri(uri_str, 0, 0, &uri);
    }
    heap_free(uri_str);
    if(FAILED(hres))
        return hres;

    hres = load_uri(This->window, uri, BINDING_FROMHIST);
    IUri_Release(uri);
    return hres;
}
コード例 #10
0
ファイル: Dialog.c プロジェクト: yjjfirst/x-sip
URI *DialogSetRemoteUri(struct Dialog *dialog, char *to)
{
    struct UserAgent *ua = DialogGetUserAgent(dialog);
    struct Account *account = UaGetAccount(ua);    

    if (dialog->remoteUri != NULL) return NULL;
    
    URI *uri = CreateUri(URI_SCHEME_SIP, to, AccountGetProxyAddr(account), 0);
    dialog->remoteUri = uri;

    return uri;
}
コード例 #11
0
ファイル: umon.c プロジェクト: Moteesh/reactos
static HRESULT WINAPI URLMoniker_Load(IMoniker* iface,IStream* pStm)
{
    URLMoniker *This = impl_from_IMoniker(iface);
    WCHAR *new_uri_str;
    IUri *new_uri;
    BSTR new_url;
    ULONG size;
    ULONG got;
    HRESULT hres;

    TRACE("(%p,%p)\n",This,pStm);

    if(!pStm)
        return E_INVALIDARG;

    /*
     * NOTE
     *  Writes a ULONG containing length of unicode string, followed
     *  by that many unicode characters
     */
    hres = IStream_Read(pStm, &size, sizeof(ULONG), &got);
    if(FAILED(hres))
        return hres;
    if(got != sizeof(ULONG))
        return E_FAIL;

    new_uri_str = heap_alloc(size+sizeof(WCHAR));
    if(!new_uri_str)
        return E_OUTOFMEMORY;

    hres = IStream_Read(pStm, new_uri_str, size, NULL);
    new_uri_str[size/sizeof(WCHAR)] = 0;
    if(SUCCEEDED(hres))
        hres = CreateUri(new_uri_str, 0, 0, &new_uri);
    heap_free(new_uri_str);
    if(FAILED(hres))
        return hres;

    hres = IUri_GetDisplayUri(new_uri, &new_url);
    if(FAILED(hres)) {
        IUri_Release(new_uri);
        return hres;
    }

    SysFreeString(This->URLName);
    if(This->uri)
        IUri_Release(This->uri);

    This->uri = new_uri;
    This->URLName = new_url;
    return S_OK;
}
コード例 #12
0
ファイル: MessageBuilder.c プロジェクト: yjjfirst/x-sip
struct Header *BuildRequestViaHeader(MESSAGE *message, struct Dialog *dialog)
{
    URI *uri = CreateUri("", "", GetLocalIpAddr(), LOCAL_PORT);
    VIA_HEADER *via = CreateViaHeader(uri);    
    struct Parameters *ps = ViaHeaderGetParameters(via);
    char branch[32];

    AddParameter(ps, "rport", "");
    GenerateBranch(branch);
    AddParameter(ps, VIA_BRANCH_PARAMETER_NAME, branch); 

    return (struct Header *)via;
}
コード例 #13
0
ファイル: MessageBuilder.c プロジェクト: yjjfirst/x-sip
struct RequestLine *BuildRequestLine(struct Dialog *dialog, SIP_METHOD method)
{
    struct UserAgent *ua = DialogGetUserAgent(dialog);
    URI *uri ;
    URI *remoteUri = UriDup(DialogGetRemoteUri(dialog));

    if (remoteUri == NULL) {
        uri = CreateUri(URI_SCHEME_SIP, NULL, UaGetProxy(ua), 0);
    } else {
        uri = remoteUri;
    }
    
    return  CreateRequestLine(method, uri);
}
コード例 #14
0
ファイル: umon.c プロジェクト: Moteesh/reactos
/***********************************************************************
 *           CreateURLMonikerEx (URLMON.@)
 *
 * Create a url moniker.
 *
 * PARAMS
 *    pmkContext [I] Context
 *    szURL      [I] Url to create the moniker for
 *    ppmk       [O] Destination for created moniker.
 *    dwFlags    [I] Flags.
 *
 * RETURNS
 *    Success: S_OK. ppmk contains the created IMoniker object.
 *    Failure: MK_E_SYNTAX if szURL is not a valid url, or
 *             E_OUTOFMEMORY if memory allocation fails.
 */
HRESULT WINAPI CreateURLMonikerEx(IMoniker *pmkContext, LPCWSTR szURL, IMoniker **ppmk, DWORD dwFlags)
{
    IUri *uri, *base_uri = NULL;
    URLMoniker *obj;
    HRESULT hres;

    TRACE("(%p, %s, %p, %08x)\n", pmkContext, debugstr_w(szURL), ppmk, dwFlags);

    if (ppmk)
        *ppmk = NULL;

    if (!szURL || !ppmk)
        return E_INVALIDARG;

    if(dwFlags >= ARRAY_SIZE(create_flags_map)) {
        FIXME("Unsupported flags %x\n", dwFlags);
        return E_INVALIDARG;
    }

    if(pmkContext) {
        IUriContainer *uri_container;

        hres = IMoniker_QueryInterface(pmkContext, &IID_IUriContainer, (void**)&uri_container);
        if(SUCCEEDED(hres)) {
            hres = IUriContainer_GetIUri(uri_container, &base_uri);
            IUriContainer_Release(uri_container);
            if(FAILED(hres))
                return hres;
        }
    }

    if(base_uri) {
        hres = CoInternetCombineUrlEx(base_uri, szURL, combine_flags_map[dwFlags], &uri, 0);
        IUri_Release(base_uri);
    }else {
        hres = CreateUri(szURL, Uri_CREATE_ALLOW_RELATIVE|Uri_CREATE_ALLOW_IMPLICIT_FILE_SCHEME|create_flags_map[dwFlags], 0, &uri);
    }
    if(FAILED(hres))
        return hres;

    hres = create_moniker(uri, &obj);
    IUri_Release(uri);
    if(FAILED(hres))
	return hres;

    *ppmk = &obj->IMoniker_iface;
    return S_OK;
}
コード例 #15
0
ファイル: MessageBuilder.c プロジェクト: yjjfirst/x-sip
struct Header *BuildRequestToHeader(MESSAGE *message, struct Dialog *dialog)
{
    struct UserAgent *ua = DialogGetUserAgent(dialog);
    URI *uri;
    URI *remoteUri = DialogGetRemoteUri(dialog);

    if (remoteUri != NULL)
        uri = UriDup(remoteUri);
    else
        uri = CreateUri(URI_SCHEME_SIP, "", UaGetProxy(ua), 0);

    CONTACT_HEADER *to = CreateToHeader();
    ContactHeaderSetUri(to, uri);

    return (struct Header *)to;
}
コード例 #16
0
ファイル: MessageBuilder.c プロジェクト: yjjfirst/x-sip
struct Header *BuildRequestFromHeader(MESSAGE *message, struct Dialog *dialog)
{
    struct UserAgent *ua = DialogGetUserAgent(dialog);
    URI *uri = CreateUri(URI_SCHEME_SIP, UaGetUserName(ua), UaGetProxy(ua), 0);
    CONTACT_HEADER *from = CreateFromHeader();
    struct Parameters *ps = ContactHeaderGetParameters(from);
    char tag[MAX_TAG_LENGTH +1] = {0};

    if (strlen(DialogGetLocalTag(dialog)) == 0){
        GenerateTag(tag);
        DialogSetLocalTag(dialog, tag);
    } else {
        strcpy(tag, DialogGetLocalTag(dialog));
    }

    AddParameter(ps, HEADER_PARAMETER_NAME_TAG, tag);
    ContactHeaderSetUri(from, uri);
    
    return (struct Header *)from;
}
コード例 #17
0
ファイル: gopher.c プロジェクト: mikekap/wine
static HRESULT WINAPI GopherProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl,
        IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
        DWORD grfPI, HANDLE_PTR dwReserved)
{
    GopherProtocol *This = PROTOCOL_THIS(iface);
    IUri *uri;
    HRESULT hres;

    TRACE("(%p)->(%s %p %p %08x %lx)\n", This, debugstr_w(szUrl), pOIProtSink,
          pOIBindInfo, grfPI, dwReserved);

    hres = CreateUri(szUrl, 0, 0, &uri);
    if(FAILED(hres))
        return hres;

    hres = protocol_start(&This->base, PROTOCOL(This), uri, pOIProtSink, pOIBindInfo);

    IUri_Release(uri);
    return hres;
}
コード例 #18
0
ファイル: ftp.c プロジェクト: AlexSteel/wine
static HRESULT WINAPI FtpProtocol_Start(IInternetProtocolEx *iface, LPCWSTR szUrl,
        IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
        DWORD grfPI, HANDLE_PTR dwReserved)
{
    FtpProtocol *This = impl_from_IInternetProtocolEx(iface);
    IUri *uri;
    HRESULT hres;

    TRACE("(%p)->(%s %p %p %08x %lx)\n", This, debugstr_w(szUrl), pOIProtSink,
          pOIBindInfo, grfPI, dwReserved);

    hres = CreateUri(szUrl, 0, 0, &uri);
    if(FAILED(hres))
        return hres;

    hres = IInternetProtocolEx_StartEx(&This->IInternetProtocolEx_iface, uri, pOIProtSink,
            pOIBindInfo, grfPI, (HANDLE*)dwReserved);

    IUri_Release(uri);
    return hres;
}
コード例 #19
0
ファイル: persist.c プロジェクト: RareHare/reactos
HRESULT create_relative_uri(HTMLOuterWindow *window, const WCHAR *rel_uri, IUri **uri)
{
    return window->uri
        ? CoInternetCombineUrlEx(window->uri, rel_uri, URL_ESCAPE_SPACES_ONLY|URL_DONT_ESCAPE_EXTRA_INFO, uri, 0)
        : CreateUri(rel_uri, 0, 0, uri);
}
コード例 #20
0
ファイル: persist.c プロジェクト: GeonHun/wine
HRESULT create_uri(const WCHAR *uri_str, DWORD flags, IUri **uri)
{
    return CreateUri(uri_str, flags | Uri_CREATE_ALLOW_IMPLICIT_FILE_SCHEME, 0, uri);
}
コード例 #21
0
// This method demonstrates how you can add custom objects to the signature,
// and also sign the custom objects.
HRESULT
AddCustomObjectsToSign(
    IOpcSigningOptions* signingOptions
    )
{
    IOpcSignatureCustomObjectSet * customObjectSet = NULL;
    IOpcSignatureReferenceSet * customReferenceSet = NULL;
    IUri * referenceUri1 = NULL;
    IUri * referenceUri2 = NULL;

    UINT32 count = 0;

    // Custom objects allow applications to add extra information to the signature.
    // One possible usage may be adding trustable timestamp to the signature.
    // Note that the signing time provided by OPC digital signature spec is from the
    // clock of local machine where the signature is created. So it is not a trustable
    // time since the clock may be inaccurate or the user may have changed the time locally.  
    //
    // Here we use a fake timestamp as an example to show how you can use custom object. 
    // In real world you need to get a trustable timestamp from a timestamp server.
    //
    // To better understand this sample, you should open and view the signature XML stored in
    // the signature part in the signed package. The default file extension of the signature
    // part is .psdsxs.

    // Example of constructing a fully signed custom object. The entire
    // object XML markup will be signed because we will reference the Id of the
    // object element. 
    //
    // Note that it is important to include namespace declaration in the XML markup. 
    // Otherwise it is not a valid XML snippet that can be interpreted.
    UINT8 customObject1[] = 
        "<Object Id=\"idMyCustomObject_Timestamp1\" xmlns=\"http://www.w3.org/2000/09/xmldsig#\" xmlns:x=\"http://www.example.com/MusicBundle\">"
            "<x:Comment>This is a fake timestamp.</x:Comment>"
            "<x:EncodedTime>ABCDEFGHIJK</x:EncodedTime>"
        "</Object>";

    // Example of custructing a partially signed custom object. 
    UINT8 customObject2[] = 
        "<Object xmlns=\"http://www.w3.org/2000/09/xmldsig#\">"
            // The <TimeStamp> element XML markup will be signed, because we will 
            // reference its Id.
            "<TimeStamp Id=\"idMyCustomObject_Timestamp2\" xmlns=\"http://www.example.com/MusicBundle\">"
                "<Comment>This is a fake timestamp.</Comment>"
                "<EncodedTime>ABCDEFGHIJK</EncodedTime>"
            "</TimeStamp>"
            // Outside of the <TimeStamp> element is the unsigned portion of this custom
            // object. Updates (changes, addition or deletion) can be made in that portion
            // without breaking the signature.
            "<Extension xmlns=\"http://www.example.com/MusicBundle\">"
                "<Comment>Unsigned portion of XML. Can be updated without breaking the signature.</Comment>"
            "</Extension>"
        "</Object>";


    // Get the custom object set from signing options. We will add custom objects to
    // it so those custom objects will be created in the signature XML after Sign() is called.
    HRESULT hr = signingOptions->GetCustomObjectSet(&customObjectSet);
    
    // Create and add the custom object into the custom object set.
    if (SUCCEEDED(hr))
    {
        // Number of bytes of the custom object. Note that we need to minus 1 because the 
        // buffer has the last byte as string terminator ('\0').
        count = sizeof(customObject1)/sizeof(customObject1[0]) - 1;

        hr = customObjectSet->Create(customObject1, count, NULL);
    }
   
    // Create and add the custom object into the custom object set.
    if (SUCCEEDED(hr))
    {
        // Number of bytes of the custom object. Note that we need to minus 1 because the 
        // buffer has the last byte as string terminator ('\0').
        count = sizeof(customObject2)/sizeof(customObject2[0]) - 1;
     
        hr = customObjectSet->Create(customObject2, count, NULL);
    }

    // Adding custom objects into the custom object set will make them appear
    // in the signature xml. However, unless you also add references to them,
    // they will not be signed.
    //
    // Add reference to the custom objects so they will be signed.
    if (SUCCEEDED(hr))
    {
        hr = signingOptions->GetCustomReferenceSet(&customReferenceSet);
    }

    // Create reference to the first custom object. Note that the reference Uri is
    // constructed as "#" + the Id value of the element you want to sign. Here
    // "#idMyCustomObject_Timestamp1" refers to the first custom object. Its entire
    // XML markup will be signed.
    if (SUCCEEDED(hr))
    {
        hr = CreateUri(L"#idMyCustomObject_Timestamp1", Uri_CREATE_ALLOW_RELATIVE, 0, &referenceUri1);
    }

    if (SUCCEEDED(hr))
    {
        hr = customReferenceSet->Create(
                referenceUri1, 
                NULL,   // Id. No Id for the reference element
                L"http://www.w3.org/2000/09/xmldsig#Object", // Type
                NULL,   // Digest method. Use default digest method, which will be set by IOpcSigningOptions::SetDefaultDigestMethod()
                OPC_CANONICALIZATION_C14N,   // Use C14N to canonicalize the referenced XML markup before signing
                NULL    // no need to get the output signature reference object
                );
    }

    // Create reference to the element we want to sign in the second custom object. 
    // Note that the reference Uri is constructed as "#" + the Id value of the element 
    // you want to sign. Here "#idMyCustomObject_Timestamp2" refers to the <TimeStamp>
    // element inside of the second custom object. Only the <TimeStamp> XML markup, including
    // its nested elements will be signed.
    if (SUCCEEDED(hr))
    {
        hr = CreateUri(
                L"#idMyCustomObject_Timestamp2",
                Uri_CREATE_ALLOW_RELATIVE,
                0,
                &referenceUri2
                );
    }

    if (SUCCEEDED(hr))
    {
        hr = customReferenceSet->Create(
                referenceUri2, 
                NULL,   // Id. No Id for the reference element
                L"http://www.example.com/MusicBundle#TimestampObject", // Type, user defined type
                NULL,   // Digest method. Use default digest method, which will be set by IOpcSigningOptions::SetDefaultDigestMethod()
                OPC_CANONICALIZATION_C14N,   // Use C14N to canonicalize the referenced XML markup before signing
                NULL    // no need to get the output signature reference object
                );
    }

    // Release resources
    if (customObjectSet)
    {
        customObjectSet->Release();
        customObjectSet = NULL;
    }

    if (customReferenceSet)
    {
        customReferenceSet->Release();
        customReferenceSet = NULL;
    }

    if (referenceUri1)
    {
        referenceUri1->Release();
        referenceUri1 = NULL;
    }

    if (referenceUri2)
    {
        referenceUri2->Release();
        referenceUri2 = NULL;
    }

    return hr;
}