/*
 * Copyright (C) 2005 CorVu Corporation
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

import "unknwn.idl";

cpp_quote("#define INTERFACESAFE_FOR_UNTRUSTED_CALLER 1")
cpp_quote("#define INTERFACESAFE_FOR_UNTRUSTED_DATA 2")
cpp_quote("#define INTERFACE_USES_DISPEX 4")
cpp_quote("#define INTERFACE_USES_SECURITY_MANAGER 8")

cpp_quote("DEFINE_GUID(CATID_SafeForScripting, 0x7dd95801,0x9882,0x11cf,0x9f,0xa9,0x00,0xaa,0x00,0x6c,0x42,0xc4);")
cpp_quote("DEFINE_GUID(CATID_SafeForInitializing, 0x7dd95802,0x9882,0x11cf,0x9f,0xa9,0x00,0xaa,0x00,0x6c,0x42,0xc4);")

[
    object,
    uuid(cb5bdc81-93c1-11cf-8f20-00805f2cd064),
    pointer_default(unique)
]
interface IObjectSafety : IUnknown
{
    HRESULT GetInterfaceSafetyOptions([in] REFIID riid,
    				      [out] DWORD *pdwSupportedOptions,
				      [out] DWORD *pdwEnabledOptions);

    HRESULT SetInterfaceSafetyOptions([in] REFIID riid,
    				      [in] DWORD dwOptionSetMask,
				      [in] DWORD dwEnabledOptions);
}
