A: The terms "safe for scripting" and "safe for initializing" represent a second level of security, called Object Safety, which goes beyond the basic code signature. When you sign your code using Authenticode, you're certifying, among other things, that your code is not specifically designed to be harmful, and that the object can be downloaded and instantiated safely.
When you download a control in an HTML page, it's possible for the page to contain property values for your control. It's also possible for the HTML page to contain JavaScript or VBScript, which will set properties on the control or call its methods. If you've defined methods or properties of your control that could potentially be (mis)used to cause damage to a client computer, you need to make sure to protect the client's computer from the hazard.
A control marked "safe for scripting" means the object can be automated safely via OLE automation, regardless of the script that is used to automate the object. A control marked "safe for initializing" means that the object's properties or data can safely be restored from any persistent store.
These concepts are further defined in Microsoft's ActiveSDK web site, at http://www.microsoft.com/intdev/inetsdk/docs/inet1273.htm and http://www.microsoft.com/intdev/inetsdk/docs/inet1274.htm
Install the appropriate registry keys for your control. You can do this by replacing the factory creation code (at the bottom of your control's implementation unit) with a call that creates a special factory with the object safety registry entries. Basically this means replacing the code that says "TActiveXControlFactory.Create" with "TSafeActiveXControlFactory.Create", and USEing the following unit.
unit SafeFactory;
interface
uses ComObj, ActiveX, AXCtrls;
const
CATID_SafeForScripting: TGUID = '{7DD95801-9882-11CF-9FA9-00AA006C42C4}';
CATID_SafeForInitializing: TGUID =
'{7DD95802-9882-11CF-9FA9-00AA006C42C4}';
type
TSafeActiveFormFactory = class( TActiveFormFactory )
procedure UpdateRegistry( Register: Boolean ); override;
end;
TSafeActiveXControlFactory = class( TActiveXControlFactory )
procedure UpdateRegistry( Register: Boolean ); override;
end;
implementation
procedure AddSafetyKeys( const ClassID: TGUID );
var
ClassKey: string;
begin
ClassKey := 'CLSID\' + GUIDToString( ClassID );
CreateRegKey( ClassKey + '\Implemented Categories','','');
CreateRegKey( ClassKey + '\Implemented Categories\'+GUIDToString(
CATID_SafeForScripting ),'','');
CreateRegKey( ClassKey + '\Implemented Categories\'+GUIDToString(
CATID_SafeForInitializing ),'','');
end;
procedure RemoveSafetyKeys( const ClassID: TGUID );
var
ClassKey: string;
begin
ClassKey := 'CLSID\' + GUIDToString( ClassID );
DeleteRegKey( ClassKey + '\Implemented Categories\'+GUIDToString(
CATID_SafeForInitializing ));
DeleteRegKey( ClassKey + '\Implemented Categories\'+GUIDToString(
CATID_SafeForScripting ));
DeleteRegKey( ClassKey + '\Implemented Categories');
end;
{TSafeActiveFormFactory}
procedure TSafeActiveFormFactory.UpdateRegistry( Register: Boolean );
begin
if Register then
begin
AddSafetyKeys( ClassID );
inherited UpdateRegistry( Register );
end
else
begin
RemoveSafetyKeys( ClassID );
inherited UpdateRegistry( Register );
end;
end;
{TSafeActiveXControlFactory}
procedure TSafeActiveXControlFactory.UpdateRegistry( Register: Boolean );
begin
if Register then
begin
AddSafetyKeys( ClassID );
inherited UpdateRegistry( Register );
end
else
begin
RemoveSafetyKeys( ClassID );
inherited UpdateRegistry( Register );
end;
end;
end.
Implementing the IObjectSafety interface allows your control to expose unsafe methods or properties when running in a container that doesn't require safety. In a container that requires safety, like Internet Explorer, the container will use IObjectSafety to ask your control to switch into safe mode, and to disable all unsafe methods and properties.