//\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
//
// CommonHelpers satellite library | Author: Sergei Y.Kitáev
//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#include "Precompiled.h"
#include "SharedIncludes.h"

static const int strbuff_initial_capacity = 64;

#define $INSTALL_TRANCATABLE_PROPERTY_GET( _PropertyName_ ) \
   String^ SysHelpers_ShellLinkProperties::_PropertyName_::get() \
   { \
      HDisposableSZ dsz( strbuff_initial_capacity ); \
      try \
      { \
         $LOOP \
         { \
            dsz.LastCharInBuffer = 1; \
            HRESULT hResult = PSLInterface -> Get##_PropertyName_( %dsz, dsz.Capacity ); \
            if ( FAILED( hResult ) ) \
               throw HCOMError::CreateOpFailedException( hResult ); \
            if ( dsz.LastCharInBuffer ) \
               return %dsz; \
            dsz.TwiceEnlargeCapacity(); \
         } \
      } \
      catch (HOperationFailedException^ e) \
      { \
         throw CreateOpFailedException_CantExtractSLProperty( \
            $STRINGIZE( _PropertyName_ ), e->Message ); \
      } \
      return dsz.ToString(); \
   }

namespace CommonHelpers {
//==================================================================================================

$INSTALL_TRANCATABLE_PROPERTY_GET( Arguments )

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

String^ SysHelpers_ShellLinkProperties::Description::get()
{
   Char szValue[ INFOTIPSIZE ];
   HRESULT hResult = PSLInterface -> GetDescription( $ARRAY_N_COUNT_OF(szValue) );
   if ( FAILED( hResult ) )
      throw CreateOpFailedException_CantExtractSLProperty( "Description", hResult );
   return gcnew String( szValue );
}

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

UInt16 SysHelpers_ShellLinkProperties::Hotkey::get()
{
   UInt16 value;
   HRESULT hResult = PSLInterface -> GetHotkey( &value );
   if ( FAILED( hResult ) )
      throw CreateOpFailedException_CantExtractSLProperty( "Hotkey", hResult );
   return value;
}

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

String^ SysHelpers_ShellLinkProperties::GetIconLocation([HOut] int% index)
{
   Char szPath[ INFOTIPSIZE ]; int idx;
   HRESULT hResult = PSLInterface -> GetIconLocation( $ARRAY_N_COUNT_OF(szPath), &idx );
   if ( FAILED( hResult ) )
      throw CreateOpFailedException_CantExtractSLProperty( "IconLocation", hResult );
   index = idx; return gcnew String( szPath );
}

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

String^ SysHelpers_ShellLinkProperties::Path::get()
{
   Char szValue[ MAX_PATH ];
   HRESULT hResult = PSLInterface -> GetPath( $ARRAY_N_COUNT_OF(szValue), NULL, SLGP_RAWPATH );
   if ( FAILED( hResult ) )
      throw CreateOpFailedException_CantExtractSLProperty( "Path", hResult );
   return gcnew String( szValue );
}

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

String^ SysHelpers_ShellLinkProperties::DisplayName::get()
{
   PIDLIST_ABSOLUTE
      pIDList = NULL;
   IShellFolder
      *pDesktopFolder = NULL;
   STRRET
      strRet = {};
   try
   {
      HRESULT hResult = PSLInterface -> GetIDList( &pIDList );
      if ( FAILED( hResult ) )
         throw CreateOpFailedException_CantExtractSLProperty( "IDList", hResult );
      if ( hResult == S_FALSE )
         return "";
      if ( FAILED( hResult = ::SHGetDesktopFolder( &pDesktopFolder ) ) )
         throw HCOMError::CreateOpFailedException( hResult );
      if ( FAILED( hResult = pDesktopFolder -> GetDisplayNameOf(
           pIDList, SHGDN_FORPARSING, &strRet ) ) )
         throw CreateOpFailedException_CantExtractSLProperty( "IDList",
            HShellLinkProperties::Verbose::CAN_NOT_OBTAIN_DISPLAYNAME_VALUE__0,
            HCOMError::HRToMessage( hResult ) );
      return gcnew String( strRet.pOleStr );
   }
   finally
   {
      HTCOMInterface::Release( pDesktopFolder );
      HUnsafeCOM::FreeTaskMemory( pIDList, strRet.pOleStr );
   }
}

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

Int32 SysHelpers_ShellLinkProperties::ShowCmd::get()
{
   Int32 value;
   HRESULT hResult = PSLInterface -> GetShowCmd( &value );
   if ( FAILED( hResult ) )
      throw CreateOpFailedException_CantExtractSLProperty( "ShowCmd", hResult );
   return value;
}

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

$INSTALL_TRANCATABLE_PROPERTY_GET( WorkingDirectory )

//==================================================================================================
} // CommonHelpers
