2025-11-28 00:35:46 +09:00

1109 lines
30 KiB
C++

/*=====================================================================
File: PublishingACL.cpp
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.
Copyright (C) Microsoft Corporation. All rights reserved.
=====================================================================*/
//
// This sample shows how to create an issuance license. See the
// comments at the beginning of wmain() for a more detailed description.
// Note: To retrieve an object's DACL, you must be the object's owner or
// have READ_CONTROL access to the object. To run this sample, you must
// have READ_CONTROL on the path you provide on the command line.
//
#define _WIN32_DCOM
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0500
#endif
#include <wtypes.h>
#include <strsafe.h>
#include <stdio.h>
#include <windows.h>
#include <sddl.h>
#include <ctype.h>
#include <Wbemidl.h>
#include <comdef.h>
#include <objbase.h>
#include <oleauto.h>
#include <comutil.h>
#include "msdrm.h"
#include "msdrmdefs.h"
#include "msdrmerror.h"
#pragma comment( lib, "wbemuuid.lib" )
//
// Time to wait for "downloads" to complete
//
static const DWORD DW_WAIT_TIME_SECONDS = 60 * 1000;
//
// Length of a GUID string
//
static const UINT GUID_STRING_LENGTH = 128;
//
// Define the two rights that are used in this sample
//
#define EDIT_RIGHT L"EDIT"
#define VIEW_RIGHT L"VIEW"
//
// Define the file to save the template into
//
#define TEMPLATE_FILE L".\\ILTemplate.xml"
//
// Define the known domains to exclude from the issuance license
//
#define NT_AUTHORITY L"NT AUTHORITY"
#define BUILTIN L"BUILTIN"
//
// Print the correct usage of this application
//
void
PrintUsage()
{
wprintf( L"Usage:\n" );
wprintf( L"\n PublishingACL -P Path\n" );
wprintf( L" -P: Path to the directory to use for the "\
L"issuance license's rights.\n" );
wprintf( L" example: c:\\myDir\n" );
}
//
// Parse the values passed in through the command line
//
HRESULT
ParseCommandLine(
int argc,
__in_ecount( argc )WCHAR **argv,
__deref_out PWCHAR *pwszPath
)
{
HRESULT hr = S_OK;
size_t uiPathLength = 0;
//
// Check input parameters.
//
if ( ( 3 != argc ) )
{
return E_INVALIDARG;
}
for( int i = 1; SUCCEEDED( hr ) && i < argc - 1; i ++ )
{
if ( ( '-' != argv[ i ][ 0 ] ) && ( '/' != argv[ i ][ 0 ] ) )
{
hr = E_INVALIDARG;
break;
}
else if ( ( '-' == argv[ i + 1 ][ 0 ] ) ||
( '/' == argv[ i + 1 ][ 0 ] ) )
{
hr = E_INVALIDARG;
break;
}
//
// Path to directory for publishing license rights
//
if ( 'P' == toupper( argv[ i ][ 1 ] ) )
{
//
// Retrieve the length of the path
//
hr = StringCchLengthW( argv[ i + 1 ],
STRSAFE_MAX_CCH,
&uiPathLength
);
if ( FAILED( hr ) )
{
wprintf( L"StringCchLengthW failed. hr = 0x%x\n", hr );
break;
}
//
// Allocate memory for the path
//
*pwszPath = new WCHAR[ uiPathLength + 1 ];
if ( NULL == *pwszPath )
{
wprintf( L"Failed to allocate memory for pwszPath\n" );
hr = E_OUTOFMEMORY;
break;
}
//
// Copy the URL into the pwszPath buffer
//
hr = StringCchCopyW( ( wchar_t* )*pwszPath,
uiPathLength + 1,
argv[ i + 1 ]
);
if ( FAILED( hr ) )
{
wprintf( L"StringCchCopyW failed. hr = 0x%x\n", hr );
break;
}
i++;
}
else
{
hr = E_INVALIDARG;
break;
}
}
if ( NULL == pwszPath )
{
wprintf( L"A path is required.\n" );
hr = E_INVALIDARG;
}
return hr;
}
//
// Write the template string to a unicode file
//
HRESULT
WriteTemplateToUnicodeFile(
__in LPCWSTR szFileName,
__in PWSTR wszTemplateString
)
{
HRESULT hr = E_FAIL;
HANDLE hFile = INVALID_HANDLE_VALUE;
size_t cchTemplate = 0;
DWORD dwBytesWritten = 0;
//
// Validate the parameters
//
if ( ( NULL == szFileName ) ||
( FAILED( StringCchLengthW( ( LPCWSTR )szFileName, MAX_PATH, NULL ) ) ) ||
( NULL == wszTemplateString ) )
{
hr = E_INVALIDARG;
goto e_Exit;
}
hr = StringCchLengthW( wszTemplateString, STRSAFE_MAX_CCH, &cchTemplate );
if ( FAILED( hr ) )
{
wprintf( L"\nStringCchLengthW failed. hr = 0x%x\n", hr );
goto e_Exit;
}
//
// Create a handle to the file to write to
//
hFile = CreateFileW( szFileName,
GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
0,
NULL
);
if ( INVALID_HANDLE_VALUE == hFile )
{
hr = HRESULT_FROM_WIN32( GetLastError() );
wprintf( L"\nCreateFileW failed. hr = 0x%x\n", hr );
goto e_Exit;
}
//
// Write the template string to the file
//
if ( !WriteFile( hFile,
wszTemplateString,
( DWORD )( sizeof( wchar_t ) * cchTemplate),
&dwBytesWritten,
NULL
) )
{
hr = HRESULT_FROM_WIN32( GetLastError() );
wprintf( L"\nWriteFile failed. hr = 0x%x\n", hr );
goto e_Exit;
}
e_Exit:
if ( ( NULL != hFile ) && ( INVALID_HANDLE_VALUE != hFile ) )
{
CloseHandle( hFile );
}
return hr;
}
//
// Determine if the machine the sample is running on is a domain controller
//
bool
IsDomainController()
{
HRESULT hr;
bool result = false;
IWbemLocator *pLocator = NULL;
IWbemServices *pSvc = NULL;
IEnumWbemClassObject *pEnumerator = NULL;
IWbemClassObject *pclsObj = NULL;
ULONG uReturn = 0;
VARIANT vtProp;
//
// Initialize COM
//
hr = CoInitializeEx( 0, COINIT_MULTITHREADED );
if ( FAILED( hr ) )
{
wprintf( L"CoInitializeEx failed. hr = 0x%x\n", hr );
result = false;
goto e_Exit;
}
//
// Set general COM security levels.
// NOTE: If you are using Windows 2000, you need to specify the default
// authentication credentials for a user by using a
// SOLE_AUTHENTICATION_LIST structure in the pAuthList parameter
//
hr = CoInitializeSecurity( NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT,
RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL );
if ( FAILED( hr ) )
{
wprintf( L"CoInitializeSecurity failed. hr = 0x%x\n", hr );
result = false;
goto e_Exit;
}
//
// Obtain the initial locator to WMI
//
hr = CoCreateInstance( CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER,
IID_IWbemLocator, ( LPVOID* )&pLocator );
if ( FAILED( hr ) )
{
wprintf( L"CoCreateInstance failed. hr = 0x%x\n", hr );
result = false;
goto e_Exit;
}
//
// Connect to WMI through the IWbemLocator::ConnectServer method
//
// Connect to the root\cimv2 namespace with the current user and obtain
// pointer pSvc to make IWbemServices calls.
//
if ( NULL == pLocator )
{
wprintf( L"pLocator was NULL\n" );
goto e_Exit;
}
hr = pLocator->ConnectServer( _bstr_t( L"ROOT\\CIMV2" ), NULL, NULL, 0,
NULL, 0, 0, &pSvc );
if ( FAILED( hr ) )
{
wprintf( L"ConnectServer failed. hr = 0x%x\n", hr );
result = false;
goto e_Exit;
}
//
// Set security levels on the proxy
//
hr = CoSetProxyBlanket( pSvc, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL,
RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE,
NULL, EOAC_NONE );
if ( FAILED( hr ) )
{
wprintf( L"CoSetProxyBlanket failed. hr = 0x%x\n", hr );
result = false;
goto e_Exit;
}
//
// Use the IWbemServices pointer to make requests of WMI
//
hr = pSvc->ExecQuery( _bstr_t( L"WQL" ),
_bstr_t( L"SELECT * FROM Win32_ComputerSystem" ),
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
NULL,
&pEnumerator
);
if ( FAILED( hr ) )
{
wprintf( L"ExecQuery failed. hr = 0x%x\n", hr );
result = false;
goto e_Exit;
}
//
// Use the data from the query to determine if the machine
// is a domain controller
//
while ( pEnumerator )
{
hr = pEnumerator->Next( WBEM_INFINITE, 1, &pclsObj, &uReturn );
if ( FAILED( hr ) )
{
wprintf( L"Next failed. hr = 0x%x\n", hr );
result = false;
goto e_Exit;
}
if ( 0 == uReturn )
{
break;
}
VariantInit( &vtProp );
//
// Get the value of the DomainRole property
//
hr = pclsObj->Get( L"DomainRole", 0, &vtProp, 0, 0);
if ( FAILED( hr ) )
{
wprintf( L"Get failed. hr = 0x%x\n", hr );
result = false;
goto e_Exit;
}
if ( ( vtProp.lVal == 4 ) || ( vtProp.lVal == 5 ) )
{
result = true;
}
}
e_Exit:
VariantClear( &vtProp );
if ( pSvc )
{
pSvc->Release();
}
if ( pLocator )
{
pLocator->Release();
}
CoUninitialize();
return result;
}
//
// This sample will perform the following actions:
// 1. Create an unsigned issuance license from scratch
// 2. Determine what the ACLs are on the directory
// passed in as the command line argument
// 3. For each ACL:
// (a) Get the user name for the ACL
// (b) Determine if the user should be added to the issuance
// license
// (c) Get the SID in the form of a string
// (d) Get the right name for the ACL
// (e) Create a user based on the ACL
// (f) Create a right based on the ACL
// (g) Add the user and right to the unsigned issuance license
// 4. Set the metadata in the issuance license
// 5. Generate a template from the issuance license
// 6. Clean up and free memory
//
int __cdecl
wmain(
int argc,
__in_ecount( argc )WCHAR **argv
)
{
HRESULT hr = E_FAIL;
int iDaclPresent, iDaclDefault, iMask;
int count = 0;
size_t uiRightLength = 0;
DWORD dwSize;
DWORD pdwNameLength = 0;
DWORD pdwDomainLength = 0;
DWORD dwMachNameLength = 0;
PWCHAR wszTemplate = NULL;
PWCHAR wszRight = NULL;
PWCHAR wszPath = NULL;
PWCHAR wszSid = NULL;
PWCHAR wszName = NULL;
PWCHAR wszDomain = NULL;
PWCHAR wszMachineName = NULL;
ACL *pDacl = NULL;
ACL_SIZE_INFORMATION asi;
SID_NAME_USE sidNameUse;
SECURITY_DESCRIPTOR *pSD = NULL;
ACCESS_ALLOWED_ACE *pAccessAllowed = NULL;
SID *pSid = NULL;
void *pAce = NULL;
SYSTEMTIME stTimeFrom, stTimeUntil;
DRMPUBHANDLE hIssuanceLicense = NULL;
DRMPUBHANDLE hUser = NULL;
DRMPUBHANDLE hRight = NULL;
UINT uiTemplateLength = 0;
GUID guid;
PWSTR wszGUID = NULL;
UINT uiGUIDLength;
WCHAR *p = NULL;
if ( FAILED ( ParseCommandLine( argc, argv, &wszPath ) ) )
{
PrintUsage();
goto e_Exit;
}
wprintf( L"\nRunning sample PublishingACL...\n" );
//
// Get the system time for the starting and ending validity times
// in the unsigned issuance license
//
GetSystemTime( &stTimeFrom );
GetSystemTime( &stTimeUntil );
FILETIME ft = { 0 };
SystemTimeToFileTime(&stTimeUntil, &ft);
ULARGE_INTEGER u = { 0 };
memcpy(&u, &ft, sizeof(u));
u.QuadPart += 90 * 24 * 60 * 60 * 10000000LLU; // 90 days
memcpy(&ft, &u, sizeof(ft));
FileTimeToSystemTime(&ft, &stTimeUntil);
//
// 1. Create an unsigned issuance license from scratch
//
hr = DRMCreateIssuanceLicense( &stTimeFrom,
&stTimeUntil,
NULL,
NULL,
NULL,
NULL,
NULL,
&hIssuanceLicense
);
if ( FAILED( hr ) )
{
wprintf( L"\nDRMCreateIssuanceLicense failed. hr = 0x%x\n", hr );
goto e_Exit;
}
//
// 2. Determine what the ACLs are on the directory passed in as
// the command line argument
//
// Get the DACL information from the path from the command line argument.
//
if ( GetFileSecurityW( wszPath,
DACL_SECURITY_INFORMATION,
NULL,
NULL,
&dwSize
) )
{
wprintf( L"GetFileSecurityW should not have returned true\n" );
goto e_Exit;
}
if ( ERROR_INSUFFICIENT_BUFFER != GetLastError() )
{
wprintf( L"GetFileSecurityW failed. Error: %d\n", GetLastError() );
goto e_Exit;
}
pSD = ( SECURITY_DESCRIPTOR* )new BYTE[ dwSize ];
if ( NULL == pSD )
{
hr = E_OUTOFMEMORY;
wprintf( L"Failed to allocate memory for the "\
L"SECURITY_DESCRIPTOR: hr = 0x%x\n", hr );
goto e_Exit;
}
if ( !GetFileSecurityW( wszPath,
DACL_SECURITY_INFORMATION,
pSD,
dwSize,
&dwSize ) )
{
wprintf( L"GetFileSecurityW failed. Error: %d\n", GetLastError() );
goto e_Exit;
}
//
// Get the Dacl from the SECURITY_DESCRIPTOR
//
if ( !GetSecurityDescriptorDacl( pSD,
&iDaclPresent,
&pDacl,
&iDaclDefault ) )
{
wprintf( L"GetSecurityDescriptorDacl failed. "\
L"Error: %d\n", GetLastError() );
goto e_Exit;
}
//
// If there was no Dacl present, then fail since no user/right
// information will be put into the issuance license
//
if ( !iDaclPresent )
{
wprintf( L"There was no DACL present in the security descriptor\n" );
hr = E_FAIL;
goto e_Exit;
}
//
// Get Acl information from the Dacl
//
if ( !GetAclInformation( pDacl,
( void* ) &asi,
sizeof( asi ),
AclSizeInformation ) )
{
wprintf( L"GetAclInformation failed. Error: %d\n", GetLastError() );
goto e_Exit;
}
//
// Get the machine name
//
if ( !GetComputerNameExW( ComputerNamePhysicalDnsHostname,
NULL,
&dwMachNameLength
) )
{
if ( ERROR_MORE_DATA != GetLastError() )
{
wprintf( L"GetComputerNameExW failed. "\
L"Error = %d\n", GetLastError() );
goto e_Exit;
}
wszMachineName = new WCHAR[ dwMachNameLength ];
if ( NULL == *wszMachineName )
{
wprintf( L"Failed to allocate memory for the machine name.\n" );
goto e_Exit;
}
}
if ( !GetComputerNameExW( ComputerNamePhysicalDnsHostname,
wszMachineName,
&dwMachNameLength
) )
{
wprintf( L"GetComputerNameExW failed. "\
L"Error = %d\n", GetLastError() );
goto e_Exit;
}
//
// Make the machine name all upper case
//
for ( p = wszMachineName; p < wszMachineName + dwMachNameLength; p++ )
{
if ( iswlower( *p ) )
{
*p = towupper( *p );
}
}
//
// 3. For each ACL:
//
//
// Parse each Acl and create the appropriate user and
// right for the issuance license
//
for ( int i = 0; i < ( int )asi.AceCount; i++ )
{
pdwDomainLength = pdwNameLength = 0;
pAccessAllowed = NULL;
pSid = NULL;
pAce = NULL;
uiRightLength = 0;
iMask = 0;
if ( !GetAce( pDacl, i, &pAce ) )
{
wprintf( L"GetAce failed. Error: %d\n", GetLastError() );
goto e_Exit;
}
if ( !pAce )
{
wprintf( L"Invalid ACE. Continuing...\n" );
continue;
}
//
// If the Ace was an ACCESS_ALLOWED_ACE_TYPE
//
if ( ( ( ACCESS_ALLOWED_ACE* )pAce )->Header.AceType ==
ACCESS_ALLOWED_ACE_TYPE )
{
pAccessAllowed = ( ACCESS_ALLOWED_ACE* )pAce;
pSid = ( SID* ) &pAccessAllowed->SidStart;
iMask = pAccessAllowed->Mask;
//
// Verify that we have a valid SID
//
if ( IsValidSid( pSid ) )
{
count++;
//
// 3(a). Get the user name for the ACL
//
//
// Lookup the account name and domain associated with the SID
//
if ( LookupAccountSidW( 0,
pSid,
( wchar_t* )wszName,
&pdwNameLength,
( wchar_t* )wszDomain,
&pdwDomainLength,
&sidNameUse ) )
{
wprintf( L"LookupAccountSidW passed when it "\
L"should have failed." );
goto e_Exit;
}
if ( ERROR_INSUFFICIENT_BUFFER != GetLastError() )
{
if ( ERROR_NONE_MAPPED == GetLastError() )
{
//
// Skip this SID since it cannot be resolved
//
continue;
}
wprintf( L"LookUpAccountSidW failed. "\
L"Error: %d\n", GetLastError() );
goto e_Exit;
}
wszName = new WCHAR[ pdwNameLength ];
wszDomain = new WCHAR[ pdwDomainLength ];
if ( NULL == wszName || NULL == wszDomain )
{
wprintf( L"Memory allocation failed for wszName "\
L"or wszDomain\n" );
goto e_Exit;
}
if ( !LookupAccountSidW( 0,
pSid,
( wchar_t* )wszName,
&pdwNameLength,
( wchar_t* )wszDomain,
&pdwDomainLength,
&sidNameUse ) )
{
wprintf( L"LookupAccountSidW failed. "\
L"Error: %d\n", GetLastError() );
goto e_Exit;
}
//
// 3(b) Determine if the user should be added to the issuance
// license. If the SID is not a SID we want to put into
// the issuance license, then clean up memory and
// continue through the for loop
//
if ( ( wcscmp( ( wchar_t* )wszDomain, NT_AUTHORITY ) == 0 ) ||
( wcscmp( ( wchar_t* )wszDomain, BUILTIN ) == 0 ) ||
( wcscmp( ( wchar_t* )wszDomain, L"" ) == 0 ) ||
( wcscmp( ( wchar_t* )wszDomain, L"NT SERVICE" ) == 0 ) ||
( ( !IsDomainController() &&
wcscmp( ( wchar_t* )wszDomain, ( wchar_t* )wszMachineName ) == 0 ) ) )
{
if ( NULL != wszName )
{
delete [] wszName;
wszName = NULL;
}
if ( NULL != wszDomain )
{
delete [] wszDomain;
wszDomain = NULL;
}
continue;
}
//
// 3(c). Get the SID in the form of a string
//
if ( !ConvertSidToStringSidW( pSid, &wszSid ) )
{
wprintf( L"ConvertSidToStringSidW failed. "\
L"Error: %d\n", GetLastError() );
goto e_Exit;
}
//
// 3(d). Get the right name for the ACL
//
//
// If the access allowed is a "write" access, then that will
// be considered an EDIT_RIGHT for the purposes of this sample
//
if ( iMask & FILE_SHARE_WRITE )
{
hr = StringCchLengthW( EDIT_RIGHT,
STRSAFE_MAX_CCH,
&uiRightLength );
if ( FAILED( hr ) )
{
wprintf( L"StringCchLengthW failed. "\
L"hr = 0x%x\n", hr );
goto e_Exit;
}
//
// Allocate memory for the right
//
wszRight = new WCHAR[ uiRightLength + 1 ];
if ( NULL == wszRight )
{
wprintf( L"Failed to allocate memory for "\
L"wszRight.\n" );
hr = E_OUTOFMEMORY;
goto e_Exit;
}
hr = StringCchCopyW( ( wchar_t* )wszRight,
uiRightLength + 1,
EDIT_RIGHT );
if ( FAILED( hr ) )
{
wprintf( L"StringCchCopyW failed. hr = 0x%x\n", hr );
break;
}
}
//
// If the access allowed is a "read" access, then that will be
// considered a VIEW_RIGHT for the purposes of this sample
//
else if ( iMask & FILE_SHARE_READ )
{
hr = StringCchLengthW( VIEW_RIGHT,
STRSAFE_MAX_CCH,
&uiRightLength );
if ( FAILED( hr ) )
{
wprintf( L"StringCchLengthW failed. "\
L"hr = 0x%x\n", hr );
goto e_Exit;
}
//
// Allocate memory for the right
//
wszRight = new WCHAR[ uiRightLength + 1 ];
if ( NULL == wszRight )
{
wprintf( L"Failed to allocate memory "\
L"for wszRight.\n" );
hr = E_OUTOFMEMORY;
goto e_Exit;
}
hr = StringCchCopyW( ( wchar_t* )wszRight,
uiRightLength + 1,
VIEW_RIGHT );
if ( FAILED( hr ) )
{
wprintf( L"StringCchCopyW failed. hr = 0x%x\n", hr );
break;
}
}
else
{
wprintf( L"An unknown right was encountered. "\
L"Continuing...\n" );
if ( NULL != wszName )
{
delete [] wszName;
wszName = NULL;
}
if ( NULL != wszDomain )
{
delete [] wszDomain;
wszDomain = NULL;
}
continue;
}
}
}
//
// 3(e). Create a user based on the ACL
//
hr = DRMCreateUser( wszName, wszSid, L"Windows", &hUser );
if ( FAILED( hr ) )
{
wprintf( L"\nDRMCreateUser failed. hr = 0x%x\n", hr );
goto e_Exit;
}
//
// 3(f). Create a right based on the ACL
//
hr = DRMCreateRight( wszRight,
&stTimeFrom,
&stTimeUntil,
NULL,
NULL,
NULL,
&hRight );
if ( FAILED( hr ) )
{
wprintf( L"\nDRMCreateRight failed. hr = 0x%x\n", hr );
goto e_Exit;
}
//
// 3(g). Add the user and right to the unsigned issuance license
//
hr = DRMAddRightWithUser( hIssuanceLicense, hRight, hUser );
if ( FAILED( hr ) )
{
wprintf( L"\nDRMAddRightWithUser failed. hr = 0x%x\n", hr );
goto e_Exit;
}
//
// Clean up the memory and variables before
// continuing through the loop
//
if ( NULL != wszName )
{
delete [] wszName;
wszName = NULL;
}
if ( NULL != wszDomain )
{
delete [] wszDomain;
wszDomain = NULL;
}
if ( NULL != wszRight )
{
delete [] wszRight;
wszRight = NULL;
}
if ( NULL != wszSid )
{
LocalFree( wszSid );
wszSid = NULL;
}
if ( NULL != hUser )
{
hr = DRMClosePubHandle( hUser );
if ( FAILED( hr ) )
{
wprintf( L"DRMClosePubHandle failed while closing hUser. "\
L"hr = 0x%x\n", hr );
hr = E_FAIL;
}
hUser = NULL;
}
if ( NULL != hRight )
{
hr = DRMClosePubHandle( hRight );
if ( FAILED( hr ) )
{
wprintf( L"DRMClosePubHandle failed while closing hRight. "\
L"hr = 0x%x\n", hr );
hr = E_FAIL;
}
hRight = NULL;
}
}
//
// Create a GUID to use as a unique content ID
// in the issuance license
//
hr = CoCreateGuid( &guid );
if ( FAILED( hr ) )
{
wprintf( L"CoCreateGuid failed. hr = 0x%x\n", hr );
goto e_Exit;
}
wszGUID = new WCHAR[ GUID_STRING_LENGTH ];
if ( NULL == wszGUID )
{
wprintf( L"Failed to allocate memory for wszGUID\n" );
goto e_Exit;
}
uiGUIDLength = StringFromGUID2( guid, wszGUID, GUID_STRING_LENGTH );
if ( 0 == uiGUIDLength )
{
wprintf( L"StringFromGUID2 failed.\n" );
hr = E_FAIL;
goto e_Exit;
}
//
// 4. Set the metadata in the issuance license
//
hr = DRMSetMetaData( hIssuanceLicense,
wszGUID,
L"MS-GUID",
NULL,
NULL,
NULL,
NULL
);
if ( FAILED( hr ) )
{
wprintf( L"DRMSetMetaData failed. hr = 0x%x\n", hr );
goto e_Exit;
}
//
// If there were no valid SIDs, then fail since no users/rights will be
// added to the issuance license
//
if ( 0 == count )
{
wprintf( L"No valid SIDs were found for the provided directory.\n" );
hr = E_FAIL;
goto e_Exit;
}
//
// 5. Generate a template from the issuance license
//
hr = DRMGetIssuanceLicenseTemplate( hIssuanceLicense,
&uiTemplateLength,
NULL
);
if ( FAILED( hr ) )
{
wprintf( L"\nDRMGetIssuanceLicenseTemplate failed. hr = 0x%x\n", hr );
goto e_Exit;
}
wszTemplate = new WCHAR[ uiTemplateLength ];
if ( NULL == wszTemplate )
{
wprintf( L"\nMemory allocation failed for the template.\n" );
hr = E_OUTOFMEMORY;
goto e_Exit;
}
hr = DRMGetIssuanceLicenseTemplate( hIssuanceLicense,
&uiTemplateLength,
wszTemplate
);
if ( FAILED( hr ) )
{
wprintf( L"\nDRMGetIssuanceLicenseTemplate failed. hr = 0x%x\n", hr );
goto e_Exit;
}
//
// Write the template to a file
//
hr = WriteTemplateToUnicodeFile( TEMPLATE_FILE, wszTemplate );
if ( FAILED( hr ) )
{
wprintf( L"WriteTemplateToUnicodeFile failed. hr = 0x%x\n", hr );
goto e_Exit;
}
wprintf( L"PublishingACL succeeded.\n" );
e_Exit:
//
// 6. Clean up and free memory
//
if ( NULL != pSD )
{
delete [] pSD;
}
if ( NULL != wszName )
{
delete [] wszName;
}
if ( NULL != wszDomain )
{
delete [] wszDomain;
}
if ( NULL != wszRight )
{
delete [] wszRight;
}
if ( NULL != wszSid )
{
LocalFree( wszSid );
wszSid = NULL;
}
if ( NULL != wszPath )
{
delete [] wszPath;
}
if ( NULL != wszMachineName )
{
delete [] wszMachineName;
}
if ( NULL != wszTemplate )
{
delete [] wszTemplate;
}
if ( NULL != hIssuanceLicense )
{
hr = DRMClosePubHandle( hIssuanceLicense );
if ( FAILED( hr ) )
{
wprintf( L"DRMClosePubHandle failed while closing "\
L"hIssuanceLicense. hr = 0x%x\n", hr );
hr = E_FAIL;
}
}
if ( NULL != hUser )
{
hr = DRMClosePubHandle( hUser );
if ( FAILED( hr ) )
{
wprintf( L"DRMClosePubHandle failed while closing hUser. "\
L"hr = 0x%x\n", hr );
hr = E_FAIL;
}
}
if ( NULL != hRight )
{
hr = DRMClosePubHandle( hRight );
if ( FAILED( hr ) )
{
wprintf( L"DRMClosePubHandle failed while closing hRight. "\
L"hr = 0x%x\n", hr );
hr = E_FAIL;
}
}
if ( FAILED( hr ) )
{
wprintf( L"\nPublishingACL failed. hr = 0x%x\n", hr );
}
return hr;
}