Creating a Compound File and Adding Content

After you have encrypted the file and obtained a signed issuance license, you must create a metafile to hold the file and all associated licenses in very specific locations. A compound file is such a metafile. Both the encrypted file and the license are packaged inside a compound file, which can associate files and licenses. The Active Directory Rights Management Add-on for Internet Explorer associates the license with the file and interprets the license's rights appropriately, allowing permitted users to access the protected files.

It does not matter whether you add your encrypted content or your signed issuance license first to the new compound file. The following example creates a compound file and adds encrypted content first. The issuance license will be added later, as shown in Adding the Issuance License to the Compound File.

Streams and storage objects hold header and data information in linear, binary form, in a very specific format. A great deal of the 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.

The following C++ example comes from the Cdoclib.cpp file.

HRESULT AddEncryptedContent(
                              WCHAR*wszRmhFilePath,
                              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;
   memcpy(StreamName_DRMViewerContent,&char_nine,2);

   // Storages and streams.
   IStorage *pStorage = NULL;
   IStream  *pStream = NULL;

   // Create the compound file.
   hResult = StgCreateStorageEx( 
              wszRmhFilePath,         // Compound file name
              STGM_READWRITE|
                STGM_SHARE_EXCLUSIVE|
                  STGM_CREATE, 
              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; // 64-bit UINT.
   hResult = pStream->Write(&ContentSize,
                            8,
                            &bytesWritten);
   hResult = pStream->Write(pbEncryptedContent, 
                            cbEncryptedContent, 
                            &bytesWritten);

   // Save data.
   pStorage->Commit(STGC_DEFAULT);

e_Exit:
   // Clean up.
   if (pStream != NULL)
      pStream->Release();
   if (pStorage != NULL)
      pStorage->Release();

   return hResult;
}

See Also

Building a Protected Document Library

Send comments about this topic to Microsoft

Build date: 3/13/2008