Creating a Compound File and Adding Protected Content

[The AD RMS SDK leveraging functionality exposed by the client in Msdrm.dll is available for use in Windows Server 2008, Windows Vista, Windows Server 2008 R2, Windows 7, Windows Server 2012, and Windows 8. It may be altered or unavailable in subsequent versions. Instead, use Active Directory Rights Management Services SDK 2.1, which leverages functionality exposed by the client in Msipc.dll.]

After you have encrypted content, saved it in a file, and obtained a signed issuance license, you can create a compound file container. The Active Directory Rights Management Add-on for Internet Explorer interprets the rights specified in the issuance license and allows permitted users to access the protected content.

It does not matter whether you first add the encrypted content or the signed issuance license to the compound file. The following example creates a compound file and adds the encrypted content first. The issuance license is added later. For more information, see Adding an Issuance License to the Compound File.

Streams and storage objects hold header and data information in linear, binary form. Much of the following code that creates and adds information to a compound file is devoted to compiling long arrays of data in a specific order and copying that information into the header in specific locations.

HRESULT AddEncryptedContent(
                              DWORD  cbUnpublishedFileLen,
                              BYTE*  pbEncryptedContent,
                              DWORD  cbEncryptedContent
   HRESULT hResult = S_OK;
   ULARGE_INTEGER ContentSize;
   DWORD bytesWritten = 0;

   // Insert ASCII characters into storage/stream names.
   short char_nine=9;

   // Storage and stream objects.
   IStorage *pStorage = NULL;
   IStream  *pStream = NULL;

   // Create the compound file.
   hResult = StgCreateStorageEx( 
              wszRmhFilePath,         // Compound file name
              STGFMT_STORAGE,         // Compound file
              0,                      // Required
              NULL,                   // Required
              0,                      // Required
              IID_IStorage,           // IStorage
              (void **)&pStorage);    // IStorage pointer

   // Create a \009DRMViewerContent stream object 
   // to hold the content.
   hResult = pStorage->CreateStream( 
               StreamName_DRMViewerContent, // Name
               STGM_READWRITE | 
                  STGM_SHARE_EXCLUSIVE,     // Access
               0,                           // Required
               0,                           // Required
               &pStream);                   // IStream pointer

   // Write the file to stream, starting with file 
   // size as a 64-bit UINT.
   ContentSize.QuadPart = cbUnpublishedFileLen; 
   hResult = pStream->Write(&ContentSize,
   hResult = pStream->Write(pbEncryptedContent, 

   // Save data.

   // Clean up.
   if (pStream != NULL)
   if (pStorage != NULL)

   return hResult;

Related topics

Adding an Issuance License to the Compound File
Adding a Use License to the Compound File
Publishing Content
Understanding Compound Files