#include <stdio.h>
#import <msxml5.dll>
using namespace MSXML2;
#define DSIGNS "xmlns:ds='http://www.w3.org/2000/09/xmldsig#'"
IXMLDOMDocument3Ptr xmldoc = NULL;
IXMLDigitalSignaturePtr xmldsig = NULL;
VARIANT_BOOL objectsAreInitialized = VARIANT_FALSE;
VARIANT_BOOL loadSignature(_bstr_t sigFile)
{
   if (!objectsAreInitialized) {
      printf("Must initialize objects before loading signature.\n");
      return VARIANT_FALSE;
   }
   if (xmldoc->load(sigFile) == VARIANT_FALSE) {
      printf("Can't load %s\n", (LPCSTR)sigFile);
      return VARIANT_FALSE;
   }
   printf("\nInput signature template:\n\n%s\n", (LPCSTR)xmldoc->xml);
   xmldoc->setProperty("SelectionNamespaces", DSIGNS);
   // Set the signature property to a <ds:Signature> DOM node.
   xmldsig->signature = xmldoc->selectSingleNode(".//ds:Signature");
   if (xmldsig->signature == NULL) {
      printf("Failed to set the signature property.\n");
      return VARIANT_FALSE;
   }
   return VARIANT_TRUE;
}
VARIANT_BOOL signWithKey(long CspType, _bstr_t keyContainer)
{
   if (!objectsAreInitialized) {
      printf("Must initialize object for signing.\n");
      return VARIANT_FALSE;
   }
   // Get the value of the signature property, and see if 
      // it has been set.
   if (xmldsig->signature == NULL) {
      printf("Must set signature template before signing.\n");
      return VARIANT_FALSE;
   }
   IXMLDSigKeyPtr dsigKey = xmldsig->createKeyFromCSP(CspType, "", keyContainer,0);
   if (dsigKey == NULL) {
      printf("Failed to create key from CSP\n");
      return VARIANT_FALSE;
   }
   IXMLDSigKeyPtr signedKey = xmldsig->sign(dsigKey, KEYVALUE);
   if (signedKey != NULL) {
      printf("\nThe data referenced in the signature template ");
      printf("was signed successfully.\nResultant signature:\n\n");
      printf("%s\n",(LPCSTR)xmldoc->xml);
   }
   else {
      printf("Signing failed.\n");
      if (dsigKey) dsigKey.Release();
      return VARIANT_FALSE;
   }
   if (dsigKey) dsigKey.Release();
   if (signedKey) signedKey.Release();
   return VARIANT_TRUE;
}
VARIANT_BOOL initObjects()
{
   if (FAILED(xmldsig.CreateInstance(__uuidof(MXDigitalSignature50)) )) {
      printf("Installation of msxml5 is required to run this app.\n");
      return VARIANT_FALSE;
   }
   if (FAILED(xmldoc.CreateInstance(__uuidof(DOMDocument50)) )) {
      printf("Installation of msxml5 is required to run this app.\n");
      return VARIANT_FALSE;
   }
   xmldoc->async = VARIANT_FALSE;
   xmldoc->validateOnParse = VARIANT_FALSE;
   xmldoc->preserveWhiteSpace = VARIANT_TRUE;
   objectsAreInitialized = VARIANT_TRUE;
   return VARIANT_TRUE;
}
void cleanObjects()
{
   if (xmldoc) xmldoc.Release();
   if (xmldsig) xmldsig.Release();
}
void main() 
{
   if ( CoInitialize(NULL) == E_FAIL) {
      printf("can't initialize COM Lib\n");
      exit(-1);
   }
   if (!initObjects()) {
      cleanObjects();
      exit(-1);
   }
   if(VARIANT_TRUE == loadSignature(
      "signature_template.rsa.xml")) 
   {
      if (VARIANT_TRUE != signWithKey(
            // Change this key container name to your own if necessary.
            PROV_RSA_FULL, "MyRSAFullKeys")) 
      {
         printf("exit with failure.\n");
      }
   }
   cleanObjects();
   CoUninitialize();
}
Try It!