//\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
// "SHLPropsHnd" SHELL PROPERTIES HANDLE OPERATIONS:
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// NativeLib DLL (for DotNetHelpers) | C+- (SysRoutine) | Author: Sergei Y.Kitáev
#include "Precompiled.h"
#include "SharedIncludes.h"
#include "partition\SHLProps.h"
//==================================================================================================

bool SHLPropsHnd::Initialize() $null_on_failure $needs_finalize nl_last_error
{
   $CLEAR_INSTANCE();

   HRESULT hResult;
   if ( FAILED( hResult = ::CoCreateInstance(
      CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
      IID_IShellLink, ($PPVoid)&PSLInterface )))
      return CantObtainInterface($, L"IShellLink", hResult );

   if ( FAILED( hResult = PSLInterface -> QueryInterface(
        IID_IPersistFile, ($PPVoid)&PPersistFileInterface )))
   {
      Finalize();
      return CantObtainInterface($, L"IPersistFile", hResult );
   }

   if ( FAILED( hResult = PSLInterface->QueryInterface(
        IID_IShellLinkDataList, ($PPVoid)&PSLDataListInterface )))
   {
      Finalize();
      return CantObtainInterface($, L"IShellLinkDataList", hResult );
   }

   return true;
}

void SHLPropsHnd::Finalize()
{
   if ( FinalizerAccessed )
      return;
   FinalizerAccessed = true;
   $COM_RESET_RELEASE( PSLDataListInterface );
   $COM_RESET_RELEASE( PPersistFileInterface );
   $COM_RESET_RELEASE( PSLInterface );
}

//--------------------------------------------------------------------------------------------------

bool SHLPropsHnd::CantObtainInterface($A, PCWSTR interfaceName, HRESULT hResult ) $ret_false
                                                                                  nl_last_error
{
   $VERIFY_POINTER_ARG( interfaceName );
   return NLFailure::SetCOMErrorFmt($ci, hResult, $TEXT(
      L"Can not obtain COM-interface “%s”.",
      L"Не удаётся получить COM-интерфейс “%s”." ),
      interfaceName );
}

//==================================================================================================

bool SHLPropsHnd::SaveProperties($OA, PCWSTR filePath,
                                      const NLShellLinkSpecialProps* specialPropsPtr $optional )
                                      const nl_last_error
{
   $ASSERT( !FinalizerAccessed );
   $VERIFY_POINTER_ARG( filePath );
   $VERIFY_POINTER_ARG( specialPropsPtr );

   HRESULT hResult;
   if ( FAILED( hResult = PPersistFileInterface -> Save( filePath, TRUE ) ) ||
        FAILED( hResult = PPersistFileInterface -> SaveCompleted( NULL ) ))
      return NL_FAIL_COM( hResult );
   SHELL_LINK_DATA_FLAGS dataFlags;
   if ( FAILED( hResult = PSLDataListInterface -> GetFlags( (PDWORD)&dataFlags ) ) )
      return NL_FAIL_COM( hResult );
   if ( specialPropsPtr )
      if ( specialPropsPtr->RunAsAdministrator )
         dataFlags |= SLDF_RUNAS_USER;
      else
         dataFlags &= ~SLDF_RUNAS_USER;
   if ( FAILED( hResult = PSLDataListInterface -> SetFlags( dataFlags ) ) ||
        FAILED( hResult = PPersistFileInterface -> Save( NULL, TRUE ) ) ||
        FAILED( hResult = PPersistFileInterface -> SaveCompleted( NULL ) ))
      return NL_FAIL_COM( hResult );

   return NL_SUCCEED();
}

//==================================================================================================
