Replacing the Issuance License in the Compound File
After you have the new signed issuance license, you replace the old one with it in the compound file.
To replace an existing issuance license, navigate to the stream that is holding the issuance license in the compound file (\006Primary), and overwrite the stream.
To overwrite the stream, set the size of the stream to zero (pStream->SetSize(0)) and rewrite the stream.
This will not clear the existing data from the stream, but because you are overwriting the stream with a header that lists the size of the issuance license, your application should only read the data size specified by the new header. Any remaining information after this will be ignored.
The following C++ example shows how to do this.
// PaddingLength is a custom function in Cdoclib.cpp that returns the
// number of padding bytes required to bring a submitted number up to
// a submitted block size.
// The VERSIONSTAMP structure is defined in Cdoclib.cpp.
// Error handling macro used in the function.
#define CHECK_STG_ERROR(api, hresult) if(FAILED(hresult)) \
{ \
printf("Error (%s): %S [%d]\n", api, StorageError(hresult), hresult);\
goto e_Exit; \
}
CDOCLIB_API HRESULT __stdcall UpdatePublishingLicense(
WCHAR* wcsRmhFilePath,
WCHAR* wcsEditedLicense)
{
// Storages and streams.
IStorage *pStorage = NULL;
IStorage *pDataSpaceStorage = NULL;
IStorage *pTransformInfoStorage = NULL;
IStorage *pDRMTransformStorage = NULL;
IStream *pStream = NULL;
HRESULT hResult = NULL;
ULONG bytesWritten = 0;
LPSTR szRightsLabel = NULL;
BYTE *drm_transform = NULL;
LPWSTR ClassID =
L"{C73DFACD-061F-43B0-8B64-0C620D2A8B50}";
LPWSTR FeatureIdentifier =
L"Microsoft.Metadata.DRMTransform";
LPWSTR wszSignedIL = wcsEditedLicense;
int IndexOfFeatureIdentifierLength = 88;
int TheNumberOne = 1;
int ClassIDLength =
(int)wcslen(ClassID)*sizeof(WCHAR);
int FeatureIdentifierLength =
(int)wcslen(FeatureIdentifier)*sizeof(WCHAR);
int TheNumberFour = 4;
short TheNumberZero = 0;
// Insert special characters into storage/stream names.
short char_nine = 9;
short char_six = 6;
memcpy(StorageName_DataSpaces, &char_six, 2);
memcpy(StorageName_DRMTransform, &char_nine, 2);
memcpy(StreamName_DRMDataSpace, &char_nine, 2);
memcpy(StreamName_Primary, &char_six, 2);
// Structure needed for the transform header.
VERSIONSTAMP version;
version.ReaderVersionMajor = 1;
version.ReaderVersionMinor = 0;
version.UpdaterVersionMajor = 1;
version.UpdaterVersionMinor = 0;
version.WriterVersionMajor = 1;
version.WriterVersionMinor = 0;
// Specifies the new stream size.
ULARGE_INTEGER ui = {0,0};
// Open the output compound file.
hResult = StgOpenStorageEx(
wcsRmhFilePath, // File name
STGM_READWRITE| // File access
STGM_SHARE_EXCLUSIVE,
STGFMT_STORAGE, // Compound file
0, // Required
NULL, // Required
0, // Required
IID_IStorage, // IStorage IID
(void **)&pStorage); // IStorage pointer
CHECK_STG_ERROR("StgOpenStorageEx", hResult);
// Now navigate down to \006Primary stream, where
// the issuance license is stored.
// \006DataSpaces->TransformInfo->\009DRMTransform->\006Primary.
// \006DataSpaces storage.
memcpy(StorageName_DataSpaces, &char_six, 2);
hResult = pStorage->OpenStorage(
StorageName_DataSpaces,
NULL,
STGM_READWRITE|STGM_SHARE_EXCLUSIVE,
NULL,
0,
&pDataSpaceStorage);
CHECK_STG_ERROR("OpenStorage", hResult);
// TransformInfo storage.
hResult = pDataSpaceStorage->OpenStorage(
StorageName_TransformInfo,
NULL,
STGM_READWRITE | STGM_SHARE_EXCLUSIVE,
NULL,
0,
&pTransformInfoStorage);
CHECK_STG_ERROR("OpenStorage[TransformInfo]", hResult);
// \009DRMTransform storage.
memcpy(StorageName_DRMTransform, &char_nine, 2);
hResult = pTransformInfoStorage->OpenStorage(
StorageName_DRMTransform,
NULL,
STGM_READWRITE|STGM_SHARE_EXCLUSIVE,
NULL,
0,
&pDRMTransformStorage);
CHECK_STG_ERROR("OpenStorage[DRMTransform]:", hResult);
// \006Primary stream.
hResult = pDRMTransformStorage->OpenStream(
StreamName_Primary,
NULL,
STGM_READWRITE|STGM_SHARE_EXCLUSIVE,
0,
&pStream);
CHECK_STG_ERROR("OpenStream[StreamName_Primary]:", hResult);
// Remove existing issuance license.
hResult = pStream->SetSize(ui);
CHECK_STG_ERROR("SetSize:", hResult);
// Allocate new buffer to hold new issuance license.
szRightsLabel = (CHAR *)HeapAlloc(
GetProcessHeap(),
0,
wcslen(wszSignedIL)+1);
if ( NULL == szRightsLabel )
{
printf("Error (%s): E_OUTOFMEMORY\n", "HeapAlloc");
goto e_Exit;
}
// Copy new issuance license into buffer.
StringCchPrintf(szRightsLabel,
wcslen(wszSignedIL)+1,
"%S",
wszSignedIL);
// Calculate size of new buffer needed to hold new
// stream and allocate memory.
int RightsLabelLength = (int)strlen(szRightsLabel);
int TransformLength = 38 + ClassIDLength +
FeatureIdentifierLength +
RightsLabelLength +
PaddingLength(RightsLabelLength,
sizeof(DWORD));
drm_transform = (BYTE *)HeapAlloc(
GetProcessHeap(),
0,
TransformLength);
if ( NULL == drm_transform )
{
printf("Error (%s): E_OUTOFMEMORY\n", "HeapAlloc");
goto e_Exit;
}
ZeroMemory(drm_transform, TransformLength);
// Copy headers and new issuance license into buffer.
memcpy(drm_transform+0, &IndexOfFeatureIdentifierLength, 4);
memcpy(drm_transform+4, &TheNumberOne, 4);
memcpy(drm_transform+8, &ClassIDLength, 4);
memcpy(drm_transform+12, ClassID, ClassIDLength);
memcpy(drm_transform+12+ClassIDLength,
&FeatureIdentifierLength,
4);
memcpy(drm_transform+16+ClassIDLength,
FeatureIdentifier,
FeatureIdentifierLength);
memcpy(drm_transform+16+ClassIDLength+FeatureIdentifierLength,
&TheNumberZero, 2);
memcpy(drm_transform+18+ClassIDLength+FeatureIdentifierLength,
&version, 12);
memcpy(drm_transform+30+ClassIDLength+FeatureIdentifierLength,
&TheNumberFour, 4);
memcpy(drm_transform+34+ClassIDLength+FeatureIdentifierLength,
&RightsLabelLength, 4);
memcpy(drm_transform+38+ClassIDLength+FeatureIdentifierLength,
szRightsLabel, RightsLabelLength);
//Write buffer to stream.
hResult = pStream->Write(
(void *)drm_transform,
TransformLength,
&bytesWritten);
CHECK_STG_ERROR("IStream::Write", hResult);
// Commit changes to root storage.
pStorage->Commit(STGC_DEFAULT);
e_Exit:
// Clean up.
if (pStorage != NULL)
pStorage->Release();
if (pDataSpaceStorage != NULL)
pDataSpaceStorage->Release();
if (pTransformInfoStorage != NULL)
pTransformInfoStorage->Release();
if (pDRMTransformStorage != NULL)
pDRMTransformStorage->Release();
if (pStream != NULL)
pStream->Release();
if (drm_transform != NULL)
HeapFree(GetProcessHeap(), NULL, drm_transform);
if (szRightsLabel != NULL)
HeapFree(GetProcessHeap(), NULL, szRightsLabel);
return hResult;
}
See Also
Send comments about this topic to Microsoft
Build date: 3/13/2008