75% found this document useful (4 votes)
664 views2,063 pages

Com PDF

This document provides an overview of the Component Object Model (COM) including COM fundamentals, processes and threading, COM clients and servers, interfaces, registration, security, error handling, monikers, and events in COM. It covers topics such as interfaces, memory management, out-of-process servers, persistence, class and type libraries, COM activation, marshaling, and more.

Uploaded by

imran hameer
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
75% found this document useful (4 votes)
664 views2,063 pages

Com PDF

This document provides an overview of the Component Object Model (COM) including COM fundamentals, processes and threading, COM clients and servers, interfaces, registration, security, error handling, monikers, and events in COM. It covers topics such as interfaces, memory management, out-of-process servers, persistence, class and type libraries, COM activation, marshaling, and more.

Uploaded by

imran hameer
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 2063

Contents

Component Object Model (COM)


COM Fundamentals
Guide
What's New in COM
Changes to COM in Windows 7
Changes to COM in Windows Vista
The Component Object Model
COM Technical Overview
COM Objects and Interfaces
Interfaces and Interface Implementations
Interface Pointers and Interfaces
IUnknown and Interface Inheritance
Using and Implementing IUnknown
QueryInterface: Navigating in an Object
Rules for Implementing QueryInterface
Managing Object Lifetimes Through Reference Counting
Reusing Objects
Containment/Delegation
Aggregation
The COM Library
Managing Memory Allocation
The OLE Memory Allocator
Memory Management Rules
Debugging Memory Allocations
Processes, Threads, and Apartments
Choosing the Threading Model
Single-Threaded Apartments
Multithreaded Apartments
Single-Threaded and Multithreaded Communication
In-Process Server Threading Issues
Accessing Interfaces Across Apartments
Creating the Global Interface Table
When to Use the Global Interface Table
COM Clients and Servers
Getting a Pointer to an Object
Creating an Object Through a Class Object
COM Class Objects and CLSIDs
Locating a Remote Object
Instance Creation Helper Functions
COM Server Responsibilities
Implementing IClassFactory
Licensing and IClassFactory2
Registering COM Servers
Out-of-Process Server Implementation Helpers
GUID Creation and Optimizations
Persistent Object State
Persistent Object Interfaces
Initializing Persistent Objects
Providing Class Information
Inter-Object Communication
Marshaling Details
Proxy
Stub
Channel
Microsoft RPC
Making and Processing Asynchronous Calls
Making an Asynchronous Call
Client Security During an Asynchronous Call
Impersonation and Asynchronous Calls
Canceling an Asynchronous Call
Canceling Method Calls
Call Synchronization
Defining COM Interfaces
Interface Marshaling
Anatomy of an IDL File
MIDL Compilation
MIDL Compiler Options
Loading and Registering a Type Library
Building and Registering a Proxy DLL
Interface Design Rules
Designing Remotable Interfaces
Using a COM Interface
Registering COM Applications
Registry Hierarchy
Classes and Servers
Classifying Components
Using OleView
Registering Components
Checking Registration
Unknown User Types
COM Registry Keys
Security in COM
Determining Your Security Needs
COM Security Defaults
Activation Security
Security Values
Authentication Level
Delegation and Impersonation
Application Identity
Software Restriction Policy
Reference Tracking
Setting Security for COM Applications
Modifying the Security Defaults for a Computer
Setting Process-Wide Security
Setting Security at the Interface Proxy Level
Enabling COM Security Using DCOMCNFG
Turning Off Security
Turning Off Activation Security
Turning Off Call Security
Server-Side Security
Security Blanket Negotiation
COM and Security Packages
NTLMSSP
Kerberos v5 Protocol
Schannel
Snego
DCOM Security Enhancements in Windows XP Service Pack 2 and Windows
Server 2003 Service Pack 1
Access Control Lists for COM
The COM Elevation Moniker
Error Handling in COM
Structure of COM Error Codes
Codes in FACILITY_ITF
Using Macros for Error Handling
COM Error Handling in Java and Visual Basic
Returning Error Information
Retrieving Error Information
Error Handling Strategies
Handling Unknown Errors
COM Handlers
The OLE Handler
The Lightweight Client-Side Handler
Implementing and Activating a Handler with No Extra Server Data
Implementing and Activating a Handler with Extra Data Supplied by Server
Delegation of QueryInterface
DLL Surrogates
DLL Server Requirements
Surrogate Sharing
Registering the DLL Server for Surrogate Activation
Using the System-Supplied Surrogate
Writing a Custom Surrogate
Monikers
Moniker Clients
Moniker Providers
OLE Moniker Implementations
File Monikers
Composite Monikers
Item Monikers
Anti-Monikers
Pointer Monikers
Class Monikers
Asynchronous Monikers
URL Monikers
Events in COM and Connectable Objects
Architecture of Connectable Objects
Connectable Object Interfaces
Using IConnectionPointContainer
Using IConnectionPoint
Using IProvideClassInfo
Component Categories Manager Implementation
Categorizing by Component Capabilities
Categorizing by Container Capabilities
The Component Categories Manager
Default Classes and Associations
Defining Component Categories
Associating Icons with a Category
Reference
Constants
Access Flags
Authentication Level Constants
Authentication Service Constants
Authorization Constants
COM Error Codes
COM Error Codes (Generic)
COM Error Codes (XACT, SCHED, OLE)
COM Error Codes (STG, RPC)
COM Error Codes (Security and Setup)
COM Error Codes (COMADMIN, FILTER, GRAPHICS)
COM Error Codes (TPM, PLA, FVE)
COM Error Codes (FWP, WS, NDIS, HyperV)
COM Error Codes (VOLMGR, BCD, VHD, SDIAG)
COM Error Codes (WPN, MBN, P2P, Bluetooth)
COM Error Codes (UI, Audio, DirectX, Codec)
Impersonation Level Constants
Enumerations
CWMO_FLAGS
APTTYPE
APTTYPEQUALIFIER
BIND_FLAGS
BINDSPEED
CALLFRAME_COPY
CALLFRAME_FREE
CALLFRAME_NULL
CALLFRAME_WALK
CALLTYPE
CLSCTX
CO_MARSHALING_CONTEXT_ATTRIBUTES
COINIT
COMSD
COWAIT_FLAGS
EOC_ChangeType
EOLE_AUTHENTICATION_CAPABILITIES
EXTCONN
GLOBALOPT_PROPERTIES
GLOBALOPT_UNMARSHALING_POLICY_VALUES
MKRREDUCE
MKSYS
MSHCTX
MSHLFLAGS
PENDINGMSG
PENDINGTYPE
RECORD_READING_POLICY
REGCLS
SERVERCALL
THDTYPE
TYSPEC
Interfaces
IAccessibilityDockingService
GetAvailableSize method
DockWindow method
UndockWindow method
IAccessibilityDockingServiceCallback
Undocked method
IAccessControl
GetAllAccessRights Method
GrantAccessRights Method
IsAccessAllowed Method
RevokeAccessRights Method
SetAccessRights Method
SetOwner Method
IAgileObject
IBindCtx
EnumObjectParam Method
GetBindOptions Method
GetObjectParam Method
GetRunningObjectTable Method
RegisterObjectBound Method
RegisterObjectParam Method
ReleaseBoundObjects Method
RevokeObjectBound Method
RevokeObjectParam Method
SetBindOptions Method
IBlockingLock
Lock Method
Unlock Method
ICallFactory
CreateCall Method
ICallFrame
Copy Method
Free Method
FreeParam Method
GetIIDAndMethod Method
GetInfo Method
GetMarshalSizeMax Method
GetNames Method
GetParam Method
GetParamInfo Method
GetReturnValue Method
GetStackLocation Method
Invoke Method
Marshal Method
ReleaseMarshalData Method
SetParam Method
SetReturnValue Method
SetStackLocation Method
Unmarshal Method
WalkFrame Method
ICallFrameEvents
OnCall Method
ICallFrameWalker
OnWalkInterface Method
ICallIndirect
CallIndirect Method
GetIID Method
GetMethodInfo Method
GetStackSize Method
ICallInterceptor
GetRegisteredSink Method
RegisterSink Method
ICallUnmarshal
ReleaseMarshalData Method
Unmarshal Method
ICancelMethodCalls
Cancel Method
TestCancel Method
ICatInformation
EnumCategories Method
EnumClassesOfCategories Method
EnumImplCategoriesOfClass Method
EnumReqCategoriesOfClass Method
GetCategoryDesc Method
IsClassOfCategories Method
ICatRegister
RegisterCategories Method
RegisterClassImplCategories Method
RegisterClassReqCategories Method
UnRegisterCategories Method
UnRegisterClassImplCategories Method
UnRegisterClassReqCategories Method
IClassActivator
GetClassObject Method
IClassFactory
CreateInstance Method
LockServer Method
IClassFactory2
CreateInstanceLic Method
GetLicInfo Method
RequestLicKey Method
IClientSecurity
CopyProxy Method
QueryBlanket Method
SetBlanket Method
IComThreadingInfo
GetCurrentApartmentType Method
GetCurrentLogicalThreadId Method
GetCurrentThreadType Method
SetCurrentLogicalThreadId Method
IConnectionPoint
Advise Method
EnumConnections Method
GetConnectionInterface Method
GetConnectionPointContainer Method
Unadvise Method
IConnectionPointContainer
EnumConnectionPoints Method
FindConnectionPoint Method
IContext
EnumContextProps Method
GetProperty Method
RemoveProperty Method
SetProperty Method
IContextCallback
ContextCallback Method
IContinueCallback
FContinue Method
FContinuePrinting Method
IEnumCATEGORYINFO
Clone Method
Next Method
Reset Method
Skip Method
IEnumConnectionPoints
Clone Method
Next Method
Reset Method
Skip Method
IEnumConnections
Clone Method
Next Method
Reset Method
Skip Method
IEnumContextProps
Clone Method
Count Method
Next Method
Reset Method
Skip Method
IEnumGUID
Clone Method
Next Method
Reset Method
Skip Method
IEnumString
Clone Method
Next Method
Reset Method
Skip Method
IEnumUnknown
Clone Method
Next Method
Reset Method
Skip Method
IEventProperty
Name Property
Value Property
IEventPublisher
Description Property
GetDefaultProperty Method
GetDefaultPropertyCollection Method
OwnerSID Property
PublisherID Property
PublisherName Property
PublisherType Property
PutDefaultProperty Method
RemoveDefaultProperty Method
IExternalConnection
AddConnection Method
ReleaseConnection Method
IFastRundown
IFileBasedLogInit
InitNew Method
IForegroundTransfer
AllowForegroundTransfer Method
IGlobalInterfaceTable
GetInterfaceFromGlobal Method
RegisterInterfaceInGlobal Method
RevokeInterfaceFromGlobal Method
IGlobalOptions
Query Method
Set Method
IInitializeSpy
PostInitialize Method
PostUninitialize Method
PreInitialize Method
PreUninitialize Method
IInternalUnknown
QueryInternalInterface Method
ILog
AppendRecord Method
Force Method
GetLogLimits Method
ReadRecord Method
ReadRecordPrefix Method
SetAccessPolicyHint Method
TruncatePrefix Method
IMalloc
Alloc Method
DidAlloc Method
Free Method
GetSize Method
HeapMinimize Method
Realloc Method
IMallocSpy
PostAlloc Method
PostDidAlloc Method
PostFree Method
PostGetSize Method
PostHeapMinimize Method
PostRealloc Method
PreAlloc Method
PreDidAlloc Method
PreFree Method
PreGetSize Method
PreHeapMinimize Method
PreRealloc Method
IMarshal
DisconnectObject Method
GetMarshalSizeMax Method
GetUnmarshalClass Method
MarshalInterface Method
ReleaseMarshalData Method
UnmarshalInterface Method
IMarshalingStream
GetMarshalingContextAttribute method
IMessageDispatcher
PumpMessages method
IMessageFilter
HandleInComingCall Method
MessagePending Method
RetryRejectedCall Method
IMoniker
BindToObject Method
BindToStorage Method
CommonPrefixWith Method
ComposeWith Method
Enum Method
GetDisplayName Method
GetTimeOfLastChange Method
Hash Method
Inverse Method
IsEqual Method
IsRunning Method
IsSystemMoniker Method
ParseDisplayName Method
Reduce Method
RelativePathTo Method
IMultiQI
QueryMultipleInterfaces Method
INoMarshal
IObjContext
IOleItemContainer
GetObject Method
GetObjectStorage Method
IsRunning Method
IOrpcDebugNotify
ClientGetBufferSize Method
ClientFillBuffer Method
ClientNotify Method
ServerNotify Method
ServerGetBufferSize Method
ServerFillBuffer Method
IParseDisplayName
ParseDisplayName Method
IPersist
GetClassID Method
IPersistFile
GetCurFile Method
IsDirty Method
Load Method
Save Method
SaveCompleted Method
IPersistStorage
HandsOffStorage Method
InitNew Method
IsDirty Method
Load Method
Save Method
SaveCompleted Method
IPersistStream
GetSizeMax Method
IsDirty Method
Load Method
Save Method
IPersistStreamInit
GetSizeMax Method
InitNew Method
IsDirty Method
Load Method
Save Method
IPipeByte
Pull Method
Push Method
IPipeDouble
Pull Method
Push Method
IPipeLong
Pull Method
Push Method
IProcessInitControl
ResetInitializerTimeout Method
IProcessLock
AddRefOnProcess Method
ReleaseRefOnProcess Method
IProgressNotify
OnProgress Method
IProvideClassInfo
GetClassInfo Method
IProvideClassInfo2
GetGUID Method
IProvideMultipleClassInfo
GetInfoOfIndex Method
GetMultiTypeInfoCount Method
IPSFactoryBuffer
CreateProxy Method
CreateStub Method
IROTData
GetComparisonData Method
IRpcChannelBuffer
FreeBuffer Method
GetBuffer Method
GetDestCtx Method
IsConnected Method
SendReceive Method
IRpcOptions
Query Method
Set Method
IRpcProxyBuffer
Connect Method
Disconnect Method
IRpcStubBuffer
Connect Method
CountRefs Method
DebugServerQueryInterface Method
DebugServerRelease Method
Disconnect Method
Invoke Method
IsIIDSupported Method
IRunnableObject
GetRunningClass Method
IsRunning Method
LockRunning Method
Run Method
SetContainedObject Method
IRunningObjectTable
EnumRunning Method
GetObject Method
GetTimeOfLastChange Method
IsRunning Method
NoteChangeTime Method
Register Method
Revoke Method
IServerSecurity
ImpersonateClient Method
IsImpersonating Method
QueryBlanket Method
RevertToSelf Method
IStdMarshalInfo
GetClassForHandler Method
ISurrogate
FreeSurrogate Method
LoadDllServer Method
ISurrogateService
ApplicationFree Method
ApplicationLaunch Method
CatalogRefresh Method
Init Method
ProcessShutdown Method
ISynchronize
Reset Method
Signal Method
Wait Method
ISynchronizeContainer
AddSynchronize Method
WaitMultiple Method
ISynchronizeEvent
SetEventHandle Method
ISynchronizeHandle
GetHandle Method
IUnknown
AddRef Method
QueryInterface Method
Release Method
Macros
FAILED
HRESULT_CODE
HRESULT_FACILITY
HRESULT_FROM_NT
HRESULT_FROM_WIN32
HRESULT_SEVERITY
IS_ERROR
MAKE_HRESULT
MAKE_SCODE
OLESTR
SCODE_CODE
SCODE_FACILITY
SCODE_SEVERITY
SUCCEEDED
Registry Entries
HKEY_LOCAL_MACHINE_SOFTWARE\Classes
AppID Key
CLSID Key
<file_extension> Key
FileType Key
Interface Key
<ProgID> Key
<version-independent ProgID> Key
HKEY_LOCAL_MACHINE_SOFTWARE\Microsoft\Ole
ActivationFailureLoggingLevel
CallFailureLoggingLevel
DCOMSCMRemoteCallFlags
DefaultAccessPermission
DefaultLaunchPermission
DoNotAddAllApplicationPackagesToRestrictions
EnableDCOM
InvalidSecurityDescriptorLoggingLevel
LegacyAuthenticationLevel
LegacyImpersonationLevel
LegacySecureReferences
MachineAccessRestriction
MachineLaunchRestriction
NONREDIST
SRPActivateAsActivatorChecks
SRPRunningObjectChecks
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion
DebugObjectRPCEnabled
Structures
ACTRL_ACCESS
ACTRL_ACCESS_ENTRY
ACTRL_ACCESS_ENTRY_LIST
ACTRL_PROPERTY_ENTRY
BIND_OPTS
BIND_OPTS2
BIND_OPTS3
CALLFRAME_MARSHALCONTEXT
CALLFRAMEINFO
CALLFRAMEPARAMINFO
CATEGORYINFO
COAUTHIDENTITY
COAUTHINFO
CONNECTDATA
COSERVERINFO
CSPLATFORM
INTERFACEINFO
MULTI_QI
ORPC_DBG_ALL
ORPC_DBG_BUFFER
ORPC_INIT_ARGS
QUERYCONTEXT
RPCOLEMESSAGE
SOLE_AUTHENTICATION_INFO
SOLE_AUTHENTICATION_LIST
SOLE_AUTHENTICATION_SERVICE
SOleTlsData
Functions
BindMoniker
CLSIDFromProgID
CLSIDFromProgIDEx
CLSIDFromString
CoAddRefServerProcess
CoAllowSetForegroundWindow
CoAllowUnmarshalerCLSID
CoCancelCall
CoCopyProxy
CoCreateFreeThreadedMarshaler
CoCreateGuid
CoCreateInstance
CoCreateInstanceEx
CoCreateInstanceFromApp
CoDecrementMTAUsage
CoDisableCallCancellation
CoDisconnectContext
CoDisconnectObject
CoDosDateTimeToFileTime
CoEnableCallCancellation
CoFileTimeNow
CoFileTimeToDosDateTime
CoFreeAllLibraries
CoFreeLibrary
CoFreeUnusedLibraries
CoFreeUnusedLibrariesEx
CoGetApartmentType
CoGetCallContext
CoGetCallerTID
CoGetCancelObject
CoGetClassObject
CoGetContextToken
CoGetCurrentLogicalThreadId
CoGetCurrentProcess
CoGetInstanceFromFile
CoGetInstanceFromIStorage
CoGetInterceptor
CoGetInterfaceAndReleaseStream
CoGetMalloc
CoGetMarshalSizeMax
CoGetObject
CoGetObjectContext
CoGetPSClsid
CoGetStandardMarshal
CoGetStdMarshalEx
CoGetSystemSecurityPermissions
CoGetTreatAsClass
CoHandlePriorityEventsFromMessagePump
CoImpersonateClient
CoIncrementMTAUsage
CoInitialize
CoInitializeEx
CoInitializeSecurity
CoInstall
CoInvalidateRemoteMachineBindings
CoIsHandlerConnected
CoIsOle1Class
CoLoadLibrary
CoLockObjectExternal
CoMarshalHresult
CoMarshalInterface
CoMarshalInterThreadInterfaceInStream
CoQueryAuthenticationServices
CoQueryClientBlanket
CoQueryProxyBlanket
CoRegisterActivationFilter
CoRegisterChannelHook
CoRegisterClassObject
CoRegisterInitializeSpy
CoRegisterMallocSpy
CoRegisterMessageFilter
CoRegisterPSClsid
CoRegisterSurrogate
CoReleaseMarshalData
CoReleaseServerProcess
CoResumeClassObjects
CoRevertToSelf
CoRevokeClassObject
CoRevokeInitializeSpy
CoRevokeMallocSpy
CoSetCancelObject
CoSetMessageDispatcher
CoSetProxyBlanket
CoSuspendClassObjects
CoSwitchCallContext
CoTaskMemAlloc
CoTaskMemFree
CoTaskMemRealloc
CoTestCancel
CoTreatAsClass
CoUninitialize
CoUnmarshalHresult
CoUnmarshalInterface
CoWaitForMultipleHandles
CoWaitForMultipleObjects
CreateAntiMoniker
CreateAsyncBindCtx
CreateBindCtx
CreateClassMoniker
CreateFileMoniker
CreateGenericComposite
CreateItemMoniker
CreateObjrefMoniker
CreatePointerMoniker
LPFNCANUNLOADNOW
DllDebugObjectRPCHook
DllGetClassObject
DllRegisterServer
DllUnregisterServer
GetClassFile
GetRunningObjectTable
IIDFromString
Initialize
IsAccelerator
IsEqualCLSID
IsEqualGUID
IsEqualIID
MkParseDisplayName
MonikerCommonPrefixWith
MonikerRelativePathTo
OleBuildVersion
OleDoAutoConvert
OleGetAutoConvert
OleGetIconOfClass
OleGetIconOfFile
OleIconToCursor
OleRegGetMiscStatus
OleRegGetUserType
OleSetAutoConvert
ProgIDFromCLSID
StringFromCLSID
StringFromGUID2
StringFromIID
OLE and Data Transfer
Guide
Guide
Compound Documents
Containers and Servers
Linking and Embedding
Linked Objects
Embedded Objects
Object Handlers
The Default Handler and Custom Handlers
In-Process Servers
Advantages
Disadvantages
Linked Objects and Monikers
Notifications
Types of Notifications
How Notifications Work
Compound Document Interfaces
Object States
Entering the Loaded State
Entering the Running State
Entering the Passive State
Implementing In-Place Activation
Creating Linked and Embedded Objects from Existing Data
View Caching
Data Transfer
Data Transfer Interfaces
Data Formats and Transfer Media
The FORMATETC Structure
The STGMEDIUM Structure
Drag and Drop
Drag Source Responsibilities
Data Notification
Reference
Constants
DROPEFFECT Constants
Enumerations
ACTIVATEFLAGS
ADVF
DATADIR
DISCARDCACHE
DOCMISC
DVASPECT
DVASPECT2
DVASPECTINFOFLAG
DVEXTENTMODE
HITRESULT
OLECLOSE
OLECMDEXECOPT
OLECMDF
OLECMDID
OLECMDID_WINDOWSTATE_FLAG
OLECMDTEXTF
OLECONTF
OLEDCFLAGS
OLEGETMONIKER
OLELINKBIND
OLEMISC
OLERENDER
OLEUIPASTEFLAG
OLEUPDATE
OLEVERBATTRIB
OLEWHICHMK
TYMED
UASFLAGS
USERCLASSTYPE
VIEWSTATUS
Functions
CreateDataAdviseHolder
CreateDataCache
CreateFormatEnumerator
CreateOleAdviseHolder
DoDragDrop
OleCreate
OleCreateDefaultHandler
OleCreateEmbeddingHelper
OleCreateEx
OleCreateFontIndirect
OleCreateFromData
OleCreateFromDataEx
OleCreateFromFile
OleCreateFromFileEx
OleCreateLink
OleCreateLinkEx
OleCreateLinkFromData
OleCreateLinkFromDataEx
OleCreateLinkToFile
OleCreateLinkToFileEx
OleCreateMenuDescriptor
OleCreatePictureIndirect
OleCreateStaticFromData
OleDestroyMenuDescriptor
OleDraw
OleDuplicateData
OleFlushClipboard
OleGetClipboard
OleGetClipboardWithEnterpriseInfo
OleInitialize
OleIsCurrentClipboard
OleIsRunning
OleLoad
OleLoadFromStream
OleLoadPicture
OleLoadPictureEx
OleLockRunning
OleMetafilePictFromIconAndLabel
OleNoteObjectVisible
OleQueryCreateFromData
OleQueryLinkFromData
OleRegEnumFormatEtc
OleRegEnumVerbs
OleRun
OleSave
OleSaveToStream
OleSetClipboard
OleSetContainedObject
OleSetMenuDescriptor
OleTranslateAccelerator
OleUIAddVerbMenu
OleUIBusy
OleUICanConvertOrActivateAs
OleUIChangeIcon
OleUIChangeSource
OleUIConvert
OleUIEditLinks
OleUIInsertObject
OleUIObjectProperties
OleUIPasteSpecial
OleUIPromptUser
OleUIUpdateLinks
OleUninitialize
RegisterDragDrop
ReleaseStgMedium
RevokeDragDrop
Interfaces
IAdviseSink
OnClose Method
OnDataChange Method
OnRename Method
OnSave Method
OnViewChange Method
IAdviseSink2
OnLinkSrcChange Method
IAdviseSinkEx
OnViewStatusChange Method
IDataAdviseHolder
Advise Method
EnumAdvise Method
SendOnDataChange Method
Unadvise Method
IDataObject
DAdvise Method
DUnadvise Method
EnumDAdvise Method
EnumFormatEtc Method
GetCanonicalFormatEtc Method
GetData Method
GetDataHere Method
QueryGetData Method
SetData Method
IDropSource
GiveFeedback Method
QueryContinueDrag Method
IDropSourceNotify
DragEnterTarget Method
DragLeaveTarget Method
IDropTarget
DragEnter Method
DragLeave Method
DragOver Method
Drop Method
IEnterpriseDropTarget
SetDropSourceEnterpriseId method
IsEvaluatingEdpPolicy method
IEnumFORMATETC
Clone Method
Next Method
Reset Method
Skip Method
IEnumMoniker
Clone Method
Next Method
Reset Method
Skip Method
IEnumOleDocumentViews
Clone Method
Next Method
Reset Method
Skip Method
IEnumOleUndoUnits
Clone Method
Next Method
Reset Method
Skip Method
IEnumOLEVERB
Clone Method
Next Method
Reset Method
Skip Method
IEnumSTATDATA
Clone Method
Next Method
Reset Method
Skip Method
IObjectWithSite
GetSite Method
SetSite Method
IOleAdviseHolder
Advise Method
EnumAdvise Method
SendOnClose Method
SendOnRename Method
SendOnSave Method
Unadvise Method
IOleCache
Cache Method
EnumCache Method
InitCache Method
SetData Method
Uncache Method
IOleCache2
DiscardCache Method
UpdateCache Method
IOleCacheControl
OnRun Method
OnStop Method
IOleClientSite
GetContainer Method
GetMoniker Method
OnShowWindow Method
RequestNewObjectLayout Method
SaveObject Method
ShowObject Method
IOleCommandTarget
Exec Method
QueryStatus Method
IOleContainer
EnumObjects Method
LockContainer Method
IOleDocument
CreateView Method
EnumViews Method
GetDocMiscStatus Method
IOleDocumentSite
ActivateMe Method
IOleDocumentView
ApplyViewState Method
Clone Method
CloseView Method
GetDocument Method
GetInPlaceSite Method
GetRect Method
Open Method
SaveViewState Method
SetInPlaceSite Method
SetRect Method
SetRectComplex Method
Show Method
UIActivate Method
IOleInPlaceActiveObject
EnableModeless Method
OnDocWindowActivate Method
OnFrameWindowActivate Method
ResizeBorder Method
TranslateAccelerator Method
IOleInPlaceFrame
EnableModeless Method
InsertMenus Method
RemoveMenus Method
SetMenu Method
SetStatusText Method
TranslateAccelerator Method
IOleInPlaceObject
InPlaceDeactivate Method
ReactivateAndUndo Method
SetObjectRects Method
UIDeactivate Method
IOleInPlaceObjectWindowless
GetDropTarget Method
OnWindowMessage Method
IOleInPlaceSite
CanInPlaceActivate Method
DeactivateAndUndo Method
DiscardUndoState Method
GetWindowContext Method
OnInPlaceActivate Method
OnInPlaceDeactivate Method
OnPosRectChange Method
OnUIActivate Method
OnUIDeactivate Method
Scroll Method
IOleInPlaceSiteEx
OnInPlaceActivateEx Method
OnInPlaceDeactivateEx Method
RequestUIActivate Method
IOleInPlaceSiteWindowless
AdjustRect Method
CanWindowlessActivate Method
GetCapture Method
GetDC Method
GetFocus Method
InvalidateRect Method
InvalidateRgn Method
OnDefWindowMessage Method
ReleaseDC Method
ScrollRect Method
SetCapture Method
SetFocus Method
IOleInPlaceUIWindow
GetBorder Method
RequestBorderSpace Method
SetActiveObject Method
SetBorderSpace Method
IOleLink
BindIfRunning Method
BindToSource Method
GetBoundSource Method
GetSourceDisplayName Method
GetSourceMoniker Method
GetUpdateOptions Method
SetSourceDisplayName Method
SetSourceMoniker Method
SetUpdateOptions Method
UnbindSource Method
Update Method
IOleObject
Advise Method
Close Method
DoVerb Method
EnumAdvise Method
EnumVerbs Method
GetClientSite Method
GetClipboardData Method
GetExtent Method
GetMiscStatus Method
GetMoniker Method
GetUserClassID Method
GetUserType Method
InitFromData Method
IsUpToDate Method
SetClientSite Method
SetColorScheme Method
SetExtent Method
SetHostNames Method
SetMoniker Method
Unadvise Method
Update Method
IOleParentUndoUnit
Add Method
Close Method
FindUnit Method
GetParentState Method
Open Method
IOleUILinkContainer
CancelLink Method
GetLinkSource Method
GetLinkUpdateOptions Method
GetNextLink Method
OpenLinkSource Method
SetLinkSource Method
SetLinkUpdateOptions Method
UpdateLink Method
IOleUILinkInfo
GetLastUpdate Method
IOleUIObjInfo
ConvertObject Method
GetConvertInfo Method
GetObjectInfo Method
GetViewInfo Method
SetViewInfo Method
IOleUndoManager
Add Method
Close Method
DiscardFrom Method
Enable Method
EnumRedoable Method
EnumUndoable Method
GetLastRedoDescription Method
GetLastUndoDescription Method
GetOpenParentState Method
Open Method
RedoTo Method
UndoTo Method
IOleUndoUnit
Do Method
GetDescription Method
GetUnitType Method
OnNextAdd Method
IOleWindow
ContextSensitiveHelp Method
GetWindow Method
IViewObject
Draw Method
Freeze Method
GetAdvise Method
GetColorSet Method
SetAdvise Method
Unfreeze Method
IViewObject2
GetExtent Method
IViewObjectEx
GetNaturalExtent Method
GetRect Method
GetViewStatus Method
QueryHitPoint Method
QueryHitRect Method
Structures
DVASPECTINFO
DVEXTENTINFO
DVTARGETDEVICE
FORMATETC
OBJECTDESCRIPTOR
OLECMD
OLECMDTEXT
OLEINPLACEFRAMEINFO
OLEMENUGROUPWIDTHS
OLEUIBUSY
OLEUICHANGEICON
OLEUICHANGESOURCE
OLEUICONVERT
OLEUIEDITLINKS
OLEUIGNRLPROPS
OLEUIINSERTOBJECT
OLEUILINKPROPS
OLEUIOBJECTPROPS
OLEUIPASTEENTRY
OLEUIPASTESPECIAL
OLEUIVIEWPROPS
OLEVERB
POINTF
STATDATA
STGMEDIUM
Controls and Property Pages
Guide
ActiveX Controls
ActiveX Controls Architecture
ActiveX Controls Interfaces
Properties and Methods
Control Properties
Control Methods
Control Events
Visual Representation
Keyboard Handling for Controls
Persistence
Registration and Licensing
ActiveX Controls Registry Information
Property Pages and Property Sheets
Property Sheets and Property Pages
Data Binding through IPropertyNotifySink
ActiveX Control and Control Container Guidelines
Overview of Control and Control Container Guidelines
Controls
Self Registration for Controls
What Support for an Interface Means
Persistence Interfaces
Optional Methods in Control Interfaces
Class Factory Options
Exposing Properties through IDispatch
Exposing Methods through IDispatch
Events in Controls
Property Pages
Ambient Properties for Controls
Using the Container's Functionality
Containers
Required Interfaces
Optional Methods
Miscellaneous Status Bits Support
Keyboard Handling in Controls
Storage Interfaces
Ambient Properties
Extended Properties, Events and Methods
Message Reflection
Automatic Clipping
Degrading Gracefully in the Absence of an Interface
Component Categories
Component Categories and How they Work
Simple Frame Site Containment
Simple Data Binding
Advanced Data Binding
Visual Basic Private Interfaces
Internet-Aware Objects
Windowless Controls
Categorizing DCOM Proxies and Stubs
General Guidelines
Overloading IPropertyNotifySink
Container-Specific Private Interfaces
Multi-Threaded Issues
Event Freezing
Container Controls
WS_GROUP and WS_TABSTOP Flags in Controls
Multiple Controls in One DLL
The IOleContainer::EnumObjects Method
Enhanced Metafiles
Licensing
Dual Interfaces
IPropertyBag and IPersistPropertyBag
Event Coordinate Translation
Standard DISPIDS
Databinding
Reference
Constants
PICTYPE Constants
Enumerations
GUIDKIND
PICTUREATTRIBUTES
POINTERINACTIVE
QACONTAINERFLAGS
Functions
OleCreatePropertyFrame
OleCreatePropertyFrameIndirect
OleLoadPicturePath
OleTranslateColor
Interfaces
IFont
AddRefHfont Method
Clone Method
get_Bold Method
get_Charset Method
get_hFont Method
get_Italic Method
get_Name Method
get_Size Method
get_Strikethrough Method
get_Underline Method
get_Weight Method
IsEqual Method
put_Bold Method
put_Charset Method
put_Italic Method
put_Name Method
put_Size Method
put_Strikethrough Method
put_Underline Method
put_Weight Method
QueryTextMetrics Method
ReleaseHfont Method
SetHdc Method
SetRatio Method
IFontDisp
IOleControl
FreezeEvents Method
GetControlInfo Method
OnAmbientPropertyChange Method
OnMnemonic Method
IOleControlSite
GetExtendedControl Method
LockInPlaceActive Method
OnControlInfoChanged Method
OnFocus Method
ShowPropertyFrame Method
TransformCoords Method
TranslateAccelerator Method
IPerPropertyBrowsing
GetDisplayString Method
GetPredefinedStrings Method
GetPredefinedValue Method
MapPropertyToPage Method
IPicture
get_Attributes Method
get_CurDC Method
get_Handle Method
get_Height Method
get_hPal Method
get_KeepOriginalFormat Method
get_Type Method
get_Width Method
PictureChanged Method
put_KeepOriginalFormat Method
Render Method
SaveAsFile Method
SelectPicture Method
set_hPal Method
IPictureDisp
IPointerInactive
GetActivationPolicy Method
OnInactiveMouseMove Method
OnInactiveSetCursor Method
IPrint
GetPageInfo Method
Print Method
SetInitialPageNum Method
IPropertyNotifySink
OnChanged Method
OnRequestEdit Method
IPropertyPage
Activate Method
Apply Method
Deactivate Method
GetPageInfo Method
Help Method
IsPageDirty Method
Move Method
SetObjects Method
SetPageSite Method
Show Method
TranslateAccelerator Method
IPropertyPage2
EditProperty Method
IPropertyPageSite
GetLocaleID Method
GetPageContainer Method
OnStatusChange Method
TranslateAccelerator Method
IQuickActivate
GetContentExtent Method
QuickActivate Method
SetContentExtent Method
ISimpleFrameSite
PostMessageFilter Method
PreMessageFilter Method
ISpecifyPropertyPages
GetPages Method
Structures
CADWORD
CALPOLESTR
CAUUID
CONTROLINFO
FONTDESC
LICINFO
OCPFIPARAMS
PAGERANGE
PAGESET
PICTDESC
PROPPAGEINFO
QACONTAINER
QACONTROL
COM Language Translations
Syntax Differences
Data Type Conversions
IDL Files
Translating COM Object Syntax for Programming Languages
Type Library Viewers and Conversion Tools
How Developer Tools Use Type Libraries
Translating to C++
Translating to C++ from Visual Basic
Translating to C++ from Java
Adding an ActiveX Control to a Visual C++ Project
MIDL Compiler
MkTypLib Command-Line Tool
OLE-COM Object Viewer
Translating to Visual Basic
Translating to Visual Basic from C++
Translating to Visual Basic from Java
Adding a Component to a Visual Basic Project
Adding a Reference to a Visual Basic Project
Visual Basic Object Browser
Translating to Java
Translating to Java from C++
Translating to Java from Visual Basic
JActiveX Command-Line Tool
Java Type Library Wizard
JavaTLB Command-Line Tool
Scripting with COM Objects
Embedding COM Objects in Web Pages
Using COM Objects in Active Server Pages
Using COM Objects in Windows Script Host
Scripting COM Objects in Custom Applications
Translating to VBScript
Translating to VBScript from JScript
Translating to VBScript from JavaScript
Translating to JScript
Translating to JScript from VBScript
Translating to JScript from JavaScript
Translating to JavaScript
Translating to JavaScript from VBScript
Translating to JavaScript from JScript
COM Glossary
Component Object Model (COM)
1/7/2020 • 2 minutes to read • Edit Online

Purpose
COM is a platform-independent, distributed, object-oriented system for creating binary software components that
can interact. COM is the foundation technology for Microsoft's OLE (compound documents) and ActiveX
(Internet-enabled components) technologies.

Where applicable
COM objects can be created with a variety of programming languages. Object-oriented languages, such as C++,
provide programming mechanisms that simplify the implementation of COM objects. These objects can be within
a single process, in other processes, even on remote computers.

Run-time requirements
For information on which operating systems are required to use a particular interface or function, see the
Requirements section of the documentation for the interface or function.

In this section
TOPIC DESCRIPTION

COM Fundamentals Describes the fundamental concepts and programming


reference.

OLE and Data Transfer Describes compound documents and data transfer.

Controls and Property Pages Describes ActiveX controls and property pages.

COM Language Translations Describes the differences between programming languages


and describe how to translate COM object syntax from one
language to another.

Related documentation
TOPIC DESCRIPTION

COM Fundamentals Describes the fundamental concepts and programming


reference.

OLE and Data Transfer Describes compound documents and data transfer.

Controls and Property Pages Describes ActiveX controls and property pages.

COM Language Translations Describes the differences between programming languages


and describe how to translate COM object syntax from one
language to another.
Related topics
TOPIC DESCRIPTION

Component Object Model (COM) COM is a platform-independent, distributed, object-oriented


system for creating binary software components that can
interact. COM is the foundation technology for Microsoft's
OLE (compound documents) and ActiveX (Internet-enabled
components) technologies.

Automation Automation enables software packages to expose their unique


features to scripting tools and other applications. Automation
uses the Component Object Model (COM), but may be
implemented independently from other OLE features, such as
in-place activation.

Microsoft Interface Definition Language (MIDL) The Microsoft Interface Definition Language (MIDL) defines
interfaces between client and server programs. Microsoft
includes the MIDL compiler with the Platform Software
Development Kit (SDK) to enable developers to create the
interface definition language (IDL) files and application
configuration files (ACF) required for remote procedure call
(RPC) interfaces and COM/DCOM interfaces. MIDL also
supports the generation of type libraries for OLE Automation.

Structured Storage Structured Storage provides file and data persistence in COM
by handling a single file as a structured collection of objects
known as storages and streams.

COM+ COM+ is an evolution of Microsoft Component Object Model


(COM) and Microsoft Transaction Server (MTS). COM+ builds
on and extends applications written using COM, MTS, and
other COM-based technologies.
COM Fundamentals
1/7/2020 • 2 minutes to read • Edit Online

The COM Fundamentals documentation is divided into the following sections:


Guide
Reference

Related topics
C
o
m
p
o
n
e
n
t
O
b
j
e
c
t
M
o
d
e
l
(
C
O
M
)

C
o
n
t
r
o
l
s
a
n
d
P
r
o
p
e
r
t
y
P
a
g
e
s

O
L
E
a
n
d
D
a
t
a
T
r
a
n
s
f
e
r
Guide
1/7/2020 • 2 minutes to read • Edit Online

This guide introduces the Microsoft Component Object Model (COM ).


What's New in COM
The Component Object Model
Processes, Threads, and Apartments
COM Clients and Servers
Making and Processing Asynchronous Calls
Defining COM Interfaces
Registering COM Applications
Security in COM
Error Handling in COM
COM Handlers
DLL Surrogates
Monikers
Events in COM and Connectable Objects
Component Categories Manager Implementation

Related topics
R
e
f
e
r
e
n
c
e
What's New in COM
1/7/2020 • 2 minutes to read • Edit Online

The following topics describe recent changes to COM:


Changes to COM in Windows 7
Changes to COM in Windows Vista
Changes to COM in Windows 7
1/7/2020 • 2 minutes to read • Edit Online

The following additions were made to the COM API in Windows 7:


CoGetApartmentType
The following APIs have changed in Windows 7:
IGlobalOptions

Related topics
C
h
a
n
g
e
s
t
o
C
O
M
i
n
W
i
n
d
o
w
s
V
i
s
t
a
Changes to COM in Windows Vista
1/7/2020 • 2 minutes to read • Edit Online

The following changes were made to COM in Windows Vista:


The COM elevation moniker allows applications that are running under a limited user account (LUA) to activate
COM classes with elevated functionality. For more information, please see The COM Elevation Moniker.
When you install an application that makes COM calls on a Windows Vista computer, and you plan to run the
application as an administrator, you must install the application per-machine, rather than per-user, or it will not
function properly.

Related topics
C
h
a
n
g
e
s
t
o
C
O
M
i
n
W
i
n
d
o
w
s
7
The Component Object Model
1/7/2020 • 2 minutes to read • Edit Online

The Microsoft Component Object Model (COM ) is a platform-independent, distributed, object-oriented system
for creating binary software components that can interact. COM is the foundation technology for Microsoft's OLE
(compound documents), ActiveX (Internet-enabled components), as well as others.
To understand COM (and therefore all COM -based technologies), it is crucial to understand that it is not an
object-oriented language but a standard. Nor does COM specify how an application should be structured;
language, structure, and implementation details are left to the application developer. Rather, COM specifies an
object model and programming requirements that enable COM objects (also called COM components, or
sometimes simply objects) to interact with other objects. These objects can be within a single process, in other
processes, and can even be on remote computers. They can be written in different languages, and they may be
structurally quite dissimilar, which is why COM is referred to as a binary standard; a standard that applies after a
program has been translated to binary machine code.
The only language requirement for COM is that code is generated in a language that can create structures of
pointers and, either explicitly or implicitly, call functions through pointers. Object-oriented languages such as C++
and Smalltalk provide programming mechanisms that simplify the implementation of COM objects, but
languages such as C, Java, and VBScript can be used to create and use COM objects.
COM defines the essential nature of a COM object. In general, a software object is made up of a set of data and
the functions that manipulate the data. A COM object is one in which access to an object's data is achieved
exclusively through one or more sets of related functions. These function sets are called interfaces, and the
functions of an interface are called methods. Further, COM requires that the only way to gain access to the
methods of an interface is through a pointer to the interface.
Besides specifying the basic binary object standard, COM defines certain basic interfaces that provide functions
common to all COM -based technologies, and it provides a small number of functions that all components require.
COM also defines how objects work together over a distributed environment and has added security features to
help provide system and component integrity.
The following topics in this section describe basic COM issues related to designing COM objects:
COM Objects and Interfaces
Using and Implementing IUnknown
Reusing Objects
The COM Library
Managing Memory Allocation
COM Technical Overview
1/29/2020 • 21 minutes to read • Edit Online

This topic provides an overview of the Microsoft Component Object Model (COM ):
Introduction to COM
Objects and Interfaces
Interface implementation
The IUnknown Interface
The Client/Server Model
Service Control Manager
Reusability
Storage and Stream Objects
Data Transfer
Remoting
Security
Related topics

Introduction to COM
The Microsoft Component Object Model (COM ) defines a binary interoperability standard for creating reusable
software libraries that interact at run time. You can use COM libraries without the requirement of compiling them
into your application. COM is the foundation for a number of Microsoft products and technologies, such as
Windows Media Player and Windows Server.
COM defines a binary standard that applies to many operating systems and hardware platforms. For network
computing, COM defines a standard wire format and protocol for interaction among objects that run on different
hardware platforms. COM is independent of implementation language, which means that you can create COM
libraries by using different programming languages, such as C++ and those in the .NET Framework.
The COM specification provides all of the fundamental concepts that enable cross-platform software reuse:
A binary standard for function calls between components.
A provision for strongly-typed groupings of functions into interfaces.
A base interface that provides polymorphism, feature discovery, and object lifetime tracking.
A mechanism that uniquely identifies components and their interfaces.
A component loader that creates component instances from a deployment.
COM has a number of parts that work together to enable the creation of applications that are built from reusable
components:
A host system that provides a run-time environment that conforms to the COM specification.
Interfaces that define feature contracts, and components that implement interfaces.
Servers that provide components to the system, and clients that use the features provided by components.
A registry that tracks where components are deployed on local and remote hosts.
A Service Control Manager that locates components on local and remote hosts and connects servers to clients.
A structured storage protocol that defines how to navigate the contents of files on the host's file system.
Enabling code re-use across hosts and platforms is central to COM. A reusable interface implementation is named
a component, a component object, or a COM object. A component implements one or more COM interfaces.
You define a custom COM library by designing the interfaces that your library implements. Consumers of your
library can discover and use its features without any knowledge of your library's deployment and implementation
details.

Objects and Interfaces


A COM object exposes its features through an interface, which is a collection of member functions. A COM
interface defines the expected behavior and responsibilities of a component, and it specifies a strongly-typed
contract that provides a small set of related operations. All communication among COM components occurs
through interfaces, and all services offered by a component are exposed through its interface. A caller can access
only the interface member functions. Internal state is unavailable to a caller unless it is exposed in the interface.
Interfaces are strongly typed. Every interface has its own unique interface identifier, named an IID, which eliminates
collisions that could occur with human-readable names. The IID is a globally unique identifier (GUID ), which is the
same as the Universally Unique ID (UUID ) defined by the Open Software Foundation (OSF ) Distributed
Computing Environment (DCE ). When you create a new interface, you must create a new identifier for that
interface. When a caller uses an interface, it must use the unique identifier. This explicit identification improves
robustness by eliminating naming conflicts that would result in run-time failure.
When you define a new interface, you can create an interface definition by using the interface definition language
(IDL ). From this interface definition, the Microsoft IDL compiler generates header files for use by applications using
the interface, and source code to handle remote procedure calls. The IDL supplied by Microsoft is based on simple
extensions to DCE IDL, an industry standard for Remote Procedure Call (RPC )-based distributed computing. IDL is
a tool for the convenience of the interface designer and is not central to COM interoperability. With IDL, you do not
need to create header files manually for each programming environment. For more information, see Defining
COM Interfaces.
Inheritance is used sparingly in COM interfaces. COM supports interface inheritance only to reuse a contract
associated with a base interface. COM does not support selective inheritance; therefore, if one interface inherits
from another, it includes all of the functions that the base interface defines. In addition, interfaces use only single
inheritance, instead of multiple inheritance, to obtain functions from a base interface.

Interface implementation
You cannot create an instance of a COM interface by itself. Instead, you create an instance of a class that
implements the interface. In C++, a COM interface is modeled as an abstract base class, which means that the
interface is a C++ class that contains only pure virtual member functions. A C++ library implements COM objects
by inheriting the member function signatures from one or more interfaces, overriding each member function, and
providing an implementation for each function.
You can use any programming language that supports the concept of function pointers to implement a COM
interface. For example, in C, an interface is a structure containing a pointer to a table of function pointers, one for
each method in the interface.
When you implement an interface, your class must provide an implementation for every function in the interface. If
the class has no work to do in an interface function, the implementation may be a single return statement.
A COM class is identified by using a unique 128-bit Class ID (CLSID ) that associates a class with a particular
deployment in the file system, which for Windows is a DLL or EXE. A CLSID is a GUID, which means that no other
class has the same CLSID. The use of unique class identifiers prevents name collisions among classes. For example,
two different vendors can write a class named CStack, but both classes have a unique CLSID, so any possibility of a
collision is avoided.
You obtain a new CLSID by using the CoCreateGuid function or by using a COM authoring tool, such as Visual
Studio, that calls this function internally.

The IUnknown Interface


All COM interfaces inherit from the IUnknown interface. The IUnknown interface contains the fundamental
COM operations for polymorphism and instance lifetime management. The IUnknown interface has three
member functions, named QueryInterface, AddRef, and Release. All COM objects are required to implement the
IUnknown interface.
The QueryInterface member function provides polymorphism for COM. Call QueryInterface to determine at
run time whether a COM object supports a particular interface. The COM object returns an interface pointer in the
ppvObject``out parameter if it implements the requested interface, otherwise it returns NULL . The
QueryInterface member function enables navigation among all of the interfaces that a COM object supports.
The lifetime of a COM object instance is controlled by its reference count. The IUnknown member functions
AddRef and Release control the count. AddRef increments the count and Release decrements the count. When
the reference count reaches zero, the Release member function may free the instance, because no callers are using
it.

The Client/Server Model


A COM class implements a number of COM interfaces. The implementation consists of binaries that run when a
caller interacts with an instance of the COM class. COM enables using a class in different applications, including
applications written without knowledge of a particular class. On a Windows platform, classes exist either in a
dynamic-linked library (DLL ) or in another application (EXE ).
On its host system, COM maintains a registration database of all the CLSIDs for the COM objects installed on the
system. The registration database is a mapping between each CLSID and the location of the DLL or EXE that
houses the corresponding class. COM queries this database whenever a caller wants to create an instance of a
COM class. The caller needs to know only the CLSID to request a new instance of the class.
The interaction between a COM object and its callers is modeled as a client/server relationship. The client is the
caller that requests a COM object from the system, and the server is the module that houses COM objects that
provides services to clients.
A COM client is any caller that passes a CLSID to the system to request an instance of a COM object. The simplest
way to create an instance is to call the COM function, CoCreateInstance.
The CoCreateInstance function creates one instance of the specified CLSID and returns an interface pointer of
the type requested by the client. The client is responsible for managing the lifetime of the instance by calling its
Release function when the client has finished using it. To create multiple objects based on a single CLSID, call the
CoGetClassObject function. To connect to an object that is already created and running, call the GetActiveObject
function.
A COM server provides a COM implementation to the system. A server associates a CLSID with a COM class,
houses the implementation of the class, implements a class factory for creating instances of the class, and provides
for unloading the server.

NOTE
A COM server is not the same as the COM object that it provides to the system.

To enable creating a COM object, a COM server must provide an implementation of the IClassFactory interface.
Clients can call the CreateInstance method to request a new instance of a COM object, but usually such requests
are encapsulated in the CoCreateInstance function.
You can deploy a COM server either as a shared library that is loaded into the client's process at run time (DLL on
Windows platforms) or as an executable module (EXE on Windows platforms). For more information, see
Registering COM Applications.

Service Control Manager


The Service Control Manager (SCM ) handles the client request for an instance of a COM object. The following list
shows the sequence of events:
A client requests an interface pointer to a COM object from the COM Library by calling a function such as
CoCreateInstance with the CLSID of the COM object.
The COM Library queries the SCM to find the server that corresponds with the requested CLSID.
The SCM locates the server and requests the creation of the COM object from the class factory that is provided
by the server.
If successful, the COM Library returns an interface pointer to the client.
After the COM system connects a server object to a client, the client and object communicate directly. There is no
added overhead from calling through an intermediary run time.
When you register a COM server with the host system, you can specify different ways for the server to be
activated. The following list shows the three ways that the SCM can activate a COM server:
In-process: The SCM returns the file path of the DLL that contains the object server implementation. The COM
Library loads the DLL and queries it for its class factory interface pointer.
Local: The SCM starts the local executable which registers a class factory on startup, and its interface pointer is
available to the system and clients.
Remote: The local SCM acquires a class factory interface pointer from the SCM that is running on a remote
computer.
When a client requests a COM object, the COM Library contacts the SCM on the local host. The SCM locates the
appropriate COM server, which may be local or remote, and the server returns an interface pointer to the server's
class factory. When the class factory is available, the COM Library or the client can use the class factory to create
the requested object. For more information, see Implementing IClassFactory.

Reusability
COM supports black-box reusability, which means that the implementation details of a reusable component are
not exposed to clients. To achieve black-box reusability, COM supports two mechanisms through which one object
may reuse another. The two forms of reuse are named containment and aggregation. By convention, the object
being reused is named the inner object, and the object that is making use of the inner object is named the outer
object.
In containment, the outer object behaves as a client of the inner object. The outer object is a logical container for
the inner object, and when the outer object uses the services of the inner object, the outer object delegates
implementation to the inner object's interfaces. This means that the outer object is implemented in terms of the
inner object's services. The outer object may not support the same interfaces as the inner object, and the outer
object may use an inner object's interface to help with implementing parts of a different interface on the outer
object.
In aggregation, the outer object exposes interfaces from the inner object as if they were implemented on the outer
object. This is useful when the outer object would always delegate every call on one of its interfaces to the same
interface of the inner object. Aggregation is a convenience that enables the outer object to avoid extra
implementation overhead.
For more information, see Reusing Objects.

Storage and Stream Objects


COM objects save state to a file by using structured storage, which is a form of persistent storage that enables
navigation of a file's contents by using file system semantics. Treating a file's contents in this manner enables
features such as incremental access, transactions, and sharing among processes.
The COM persistent storage specification provides for two types of storage elements: storage objects and stream
objects. These objects are implemented by the COM Library, and user applications rarely implement these storage
elements. Storage objects implement the IStorage interface, and stream objects implement the IStream interface.
A stream object contains data and is conceptually similar to a single file in a file system. Each stream has access
rights and a single seek pointer. Through the IStream interface, you can read, write, seek, and perform other
operations on the stream's underlying data. A stream is named by using a text string. It can contain any internal
structure, because it is a flat stream of bytes. In addition, the functions in the IStream interface are similar to
standard file-handle based functions, such as those in the ANSI C run-time library.
A storage object is conceptually similar to a directory in a file system. Each storage can contain any number of sub-
storage objects and any number of streams. Each storage has its own access rights. Through the IStorage
interface, you can perform operations such as enumerating, moving, copying, renaming, creating, and deleting
elements. A storage object does not store application-defined data, but it stores implicitly the names of the
elements (storages and streams) that it contains.
Storage and stream objects are sharable among processes when they are implemented according to the COM
specification on a host platform. This enables objects that are running in-process or out-of-process to have equal
incremental access to their file storage. Because COM is loaded into each process separately, it uses operating-
system supported shared memory mechanisms to communicate the state of opened elements and their access
modes between processes.
Every storage and stream object in a structured file has a name to identify it. The name is a string that follows a
particular convention. For more information, see Storage Object Naming Conventions. The name is passed to
IStorage functions to specify which element in the storage to operate on. Names of root storage objects are the
same as file names in the underlying file system, and these names must follow the file system's conventions and
restrictions. Strings passed to storage-related functions which name files are passed through to the file system
without interpretation or changes.
Names of elements that are contained within storage objects are managed by the implementation of the particular
storage object in question. All implementations of storage objects must support element names that are 32
characters in length, and some implementations may support longer names. Names are stored with case
preserved, but they are compared as case-insensitive. Applications that define storage element names must choose
names that work in either situation.
You access every element in a structured storage file by using functions and interfaces that are implemented by
COM. This means that other applications can browse the file by navigating with the IStorage interface functions
that provide directory-like services. Also, other applications can use the file's data, without having to run the
application that wrote the file. When a COM application accesses the structured storage files of another application,
standard Windows access rights apply, and the application must have sufficient privileges.
A COM object can read and write itself to persistent storage. A client queries for one of the persistence-related
interfaces on the COM object, depending on the context of the operation. COM objects can implement any
combination of the following interfaces:
IPersistStorage: The COM object reads and writes its persistent state to a storage object. The client provides
the object with an IStorage pointer through this interface. This is the only persistence interface that includes
semantics for incremental access.
IPersistStream: The COM object reads and writes its persistent state to a stream object. The client provides the
object with an IStream pointer through this interface.
IPersistFile: The COM object reads and writes its persistent state directly to a file on the underlying system.
This interface does not involve IStorage or IStream unless the underlying file is accessed through these
interfaces, but the IPersistFile interface has no semantics for storages and streams. The client provides the
object with a file name and calls the Save or Load functions.

Data Transfer
Structured storage provides the basis for data exchange between COM objects and processes, which is named
uniform data transfer. Before COM was implemented in OLE 2, data transfer on Windows was specified by
transfer protocols, such as the clipboard and drag-drop protocols. Each transfer protocol had its own set of
functions that bound the protocol to the query, and specific code was required to handle each different protocol
and exchange procedure. Uniform data transfer represents all data transfers by using the IDataObject interface,
which separates common data exchange operations from the transfer protocol.
The IDataObject interface encapsulates the standard get and set operations on data, queries and enumerations,
and notifications that detect when data changes in an object. Uniform data transfer enables rich descriptions of
data formats, as well as the use of different storage media for the data transfer.
During uniform data transfer, all protocols exchange a pointer to an IDataObject interface. The server is the
source of the data and implements one data object, which is usable in any data exchange protocol. The client
consumes the data and requests data from a data object when it receives an IDataObject pointer from any
protocol. After the pointer exchange has occurred, both sides handle data exchange in a uniform fashion, through
the IDataObject interface.
COM defines two data structures that enable uniform data transfer. The FORMATETC structure represents a
generalized clipboard format, and the STGMEDIUM structure represents the transfer medium as a memory
handle.
The client creates a FORMATETC structure to indicate the type of data that it requests from a data source, and it is
used by the data source to describe what formats it provides. The client queries a data source for its available
formats by requesting its IEnumFORMATETC interface. For more information, see The FORMATETC Structure.
The client creates a STGMEDIUM structure and passes it to the GetData method, and the data object returns the
data in the provided STGMEDIUM structure.
The STGMEDIUM structure enables both clients and data sources to choose the most efficient exchange medium.
For example, if the data to be exchanged is very large, the data source can indicate a disk-based medium as its
preferred format, instead of main memory. This flexibility enables efficient data exchanges that can be as fast as
passing a pointer to an IStorage or an IStream. For more information, see The STGMEDIUM Structure.
A client of a data source may require notification when the data changes. COM handles data-change notifications
by using an advise sink object, which implements the IAdviseSink interface. The advise sink object and the
IAdviseSink interface are implemented by the client, which passes an IAdviseSink pointer to the data source.
When the data source detects a change in the underlying data, it calls an IAdviseSink method to notify the client.
For more information, see Data Notification.

Remoting
COM enables remote and distributed computation. Interface remoting enables a member function to return an
interface pointer to a COM object that is in a different process or on a different host computer. The infrastructure
that performs the interface remoting is transparent to both the client and the object server. Neither the client nor
the server need one another's deployment details to communicate through a remoted interface. A client calls
member functions on the same interface to communicate with a COM object that is in-process, out-of-process on
the local host, or on a remote computer. Local and remote calls on the same interface are indistinguishable to the
client.
To communicate with a COM object, a client always calls an in-process implementation. If the COM object is in-
process, the call is direct. If the COM object is out-of-process or remote, COM provides a proxy implementation
that forwards the call to the object by using the Remote Procedure Call (RPC ) protocol.
A COM object always receives calls from a client through an in-process implementation. If the caller is in-process,
the call is direct. If the caller is out-of-process or remote, COM provides a stub implementation that receives the
remote procedure call from the proxy in the client process.
Marshaling is the procedure for packaging the call stack for transmission from proxy to stub. Unmarshaling is the
unpackaging that occurs at the receiving end. Return values are marshaled and unmarshaled from the stub to the
proxy. This kind of communication is also referred to as sending a call over the wire.
Each different data type has rules for marshaling. Interface pointers also have a marshaling protocol, which is
encapsulated in the CoMarshalInterface function. In most cases, standard interface marshaling, which is
provided by the system, is sufficient, but a COM object optionally may implement custom interface marshaling to
control the creation of remote object proxies to itself. For more information, see Inter-Object Communication.

Security
COM provides two forms of application security. One is activation security, which specifies how new objects are
created, how clients connect to new and existing objects, and how certain public services, such as the Class Table
and the Running Object Table are secured. The other is call security, which specifies how security operates in an
established connection between a client to a COM object.
Activation security is applied automatically by the Service Control Manager (SCM ). When the SCM receives a
request to retrieve a COM object, it checks the request against security information that is stored in the registry.
SCM implementations usually offer registry-driven configuration for administering deployed classes and for
specific user accounts on the host. For more information, see Activation Security.
Call security is applied automatically or is enforced by the application. If the application provides setup information,
COM performs the necessary checks to secure the application.
The automatic mechanism checks security for the process, but not for individual objects or methods. If an
application requires more fine-grained security, COM provides functions that applications may use do their own
security checking.
The automatic and custom mechanisms can be used together, so an application may ask COM to perform
automatic security checking and then perform its own.
COM call security services are divided into the following categories:
General functions that are called by both clients and servers, which enable the automatic security mechanism to
be initialized and automatic authentication services to be registered. The general call security APIs are the
CoInitializeSecurity and CoQueryAuthenticationServices functions.
Interfaces on client proxies, which enable the client to control the security on calls to individual interfaces. The
IClientSecurity interface and the CoQueryProxyBlanket, CoSetProxyBlanket, and CoCopyProxy
functions provide call security on a remote object.
Server-side functions and call-context interfaces, which enable the server to retrieve security information about
a call and to impersonate the caller. The IServerSecurity interface and the CoGetCallContext,
CoImpersonateClient, and CoRevertToSelf functions provide server-side call security.
Often, the client queries the COM object for the IClientSecurity interface, which is implemented locally by the
remoting layer. The client uses this interface to control the security of individual interface proxies on the COM
object before making a call on one of the interfaces.
When a call arrives at the server, the server may call the CoGetCallContext function to retrieve an
IServerSecurity interface, which allows the server to check the client's authentication and to impersonate the
client, if necessary. The IServerSecurity object is valid for the duration of the call.
Call the CoInitializeSecurity function to initialize the security layer and set the specified values as the security
default. If a process does not call CoInitializeSecurity, COM calls it automatically the first time an interface is
marshaled or unmarshaled, registering the system default security. The CoInitializeSecurity function allows the
client to establish default call security for the process, which avoids the use of IClientSecurity on individual
proxies. The CoInitializeSecurity function enables a server to register automatic authentication services for the
process. For more information, see Setting Process-Wide Security with CoInitializeSecurity.

Related topics
C
O
M
C
l
i
e
n
t
s
a
n
d
S
e
r
v
e
r
s

D
e
f
i
n
i
n
g
C
O
M
I
n
t
e
r
f
a
c
e
s

R
e
g
i
s
t
e
r
i
n
g
C
O
M
A
p
p
l
i
c
a
t
i
o
n
s

S
e
c
u
r
i
t
y
i
n
C
O
M

P
r
o
c
e
s
s
e
s
,
T
h
r
e
a
d
s
,
a
n
d
A
p
a
r
t
m
e
n
t
s
COM Objects and Interfaces
1/7/2020 • 2 minutes to read • Edit Online

COM is a technology that allows objects to interact across process and computer boundaries as easily as within a
single process. COM enables this by specifying that the only way to manipulate the data associated with an object
is through an interface on the object. When this term is used in this documentation, it refers to an implementation
in code of a COM binary-compliant interface that is associated with an object.
COM uses the word interface in a sense different from that typically used in Visual C++ programming. A C++
interface refers to all of the functions that a class supports and that clients of an object can call to interact with it. A
COM interface refers to a predefined group of related functions that a COM class implements, but a specific
interface does not necessarily represent all the functions that the class supports.
Referring to an object implementing an interface means that the object uses code that implements each method of
the interface and provides COM binary-compliant pointers to those functions to the COM library. COM then
makes those functions available to any client who asks for a pointer to the interface, whether the client is inside or
outside of the process that implements those functions.
For more information, see the following topics:
Interfaces and Interface Implementations
Interface Pointers and Interfaces
IUnknown and Interface Inheritance

Related topics
I
n
t
e
r
f
a
c
e
s
Interfaces and Interface Implementations
1/7/2020 • 2 minutes to read • Edit Online

COM makes a fundamental distinction between interface definitions and their implementations.
An interface is actually a contract that consists of a group of related function prototypes whose usage is defined
but whose implementation is not. These function prototypes are equivalent to pure virtual base classes in C++
programming. An interface definition specifies the interface's member functions, called methods, their return types,
the number and types of their parameters, and what they must do. There is no implementation associated with an
interface.
An interface implementation is the code a programmer supplies to carry out the actions specified in an interface
definition. Implementations of many of the interfaces a programmer can use in an object-based application are
included in the COM libraries. However, programmers are free to ignore these implementations and write their
own. An interface implementation is to be associated with an object when an instance of that object is created, and
the implementation provides the services that the object offers.
For example, a hypothetical interface named IStack might define two methods, named Push and Pop, specifying
that successive calls to the Pop method return, in reverse order, values previously passed to the Push method. This
interface definition would not specify how the functions are to be implemented in code. In implementing the
interface, one programmer might implement the stack as an array and implement the Push and Pop methods in
such a way as to access that array, while another programmer might use a linked list and would implement the
methods accordingly. Regardless of a particular implementation of the Push and Pop methods, the in-memory
representation of a pointer to an IStack interface, and therefore its use by a client, is completely determined by the
interface definition.
Simple objects support only a single interface. More complicated objects, such as embeddable objects, typically
support several interfaces. Clients have access to a COM object only through a pointer to one of its interfaces,
which, in turn, allows the client to call any of the methods that make up that interface. These methods determine
how a client can use the object's data.
Interfaces define a contract between an object and its clients. The contract specifies the methods that must be
associated with each interface and what the behavior of each of the methods must be in terms of input and output.
The contract generally does not define how to implement the methods in an interface. Another important aspect of
the contract is that if an object supports an interface, it must support all of that interface's methods in some way.
Not all of the methods in an implementation need to do something—if an object does not support the function
implied by a method, its implementation may be a simple return or perhaps the return of a meaningful error
message—but the methods must exist.

Related topics
C
O
M
O
b
j
e
c
t
s
a
n
d
I
n
t
e
r
f
a
c
e
s
Interface Pointers and Interfaces
1/7/2020 • 2 minutes to read • Edit Online

An instance of an interface implementation is actually a pointer to an array of pointers to methods - that is, a
function table that refers to an implementation of all of the methods specified in the interface. Objects with
multiple interfaces can provide pointers to more than one function table. Any code that has a pointer through
which it can access the array can call the methods in that interface.
Speaking precisely about this multiple indirection is inconvenient, so instead, the pointer to the interface function
table that another object must have to call its methods is called simply an interface pointer. You can manually
create function tables in a C application or almost automatically by using Visual C++ (or other object-oriented
languages that support COM ).
With appropriate compiler support (which is inherent in C and C++), a client can call an interface method through
its name, not its position in the array. Because an interface is a type, the compiler, given the names of methods, can
check the types of parameters and return values of each interface method call. In contrast, if a client uses a
position-based calling scheme, such type-checking is not available, even in C or C++.
Each interface is an immutable contract of a functional group of methods. You reference an interface at run time
with a globally unique interface identifier (IID ). This IID, which is a specific instance of a globally unique identifier
(GUID ) supported by COM, allows a client to ask an object precisely whether it supports the semantics of the
interface, without unnecessary overhead and without the confusion that could arise in a system from having
multiple versions of the same interface with the same name.
To summarize, it is important to understand what a COM interface is, and is not:
A COM interface is not the same as a C++ class. The pure virtual definition carries no implementation. If you
are a C++ programmer, you can define your implementation of an interface as a class, but this falls under the
heading of implementation details, which COM does not specify. An instance of an object that implements an
interface must be created for the interface actually to exist. Furthermore, different object classes may implement
an interface differently yet be used interchangeably in binary form, as long as the behavior conforms to the
interface definition.
A COM interface is not an object. It is simply a related group of functions and is the binary standard through
which clients and objects communicate. As long as it can provide pointers to interface methods, the object can
be implemented in any language with any internal state representation.
COM interfaces are strongly typed. Every interface has its own interface identifier (a GUID ), which eliminates
the possibility of duplication that could occur with any other naming scheme.
COM interfaces are immutable. You cannot define a new version of an old interface and give it the same
identifier. Adding or removing methods of an interface or changing semantics creates a new interface, not a new
version of an old interface. Therefore, a new interface cannot conflict with an old interface. However, objects can
support multiple interfaces simultaneously and can expose interfaces that are successive revisions of an
interface, with different identifiers. Thus, each interface is a separate contract, and systemwide objects need not
be concerned about whether the version of the interface they are calling is the one they expect. The interface ID
(IID ) defines the interface contract explicitly and uniquely.

Related topics
C
O
M
O
b
j
e
c
t
s
a
n
d
I
n
t
e
r
f
a
c
e
s
IUnknown and Interface Inheritance
1/29/2020 • 2 minutes to read • Edit Online

Inheritance in COM does not mean code reuse. Because no implementations are associated with interfaces,
interface inheritance does not mean code inheritance. It means only that the contract associated with an interface is
inherited in a C++ pure-virtual base-class fashion and modified — either by adding new methods or by further
qualifying the allowed usage of methods. There is no selective inheritance in COM. If one interface inherits from
another, it includes all the methods that the other interface defines.
Inheritance is used sparingly in the predefined COM interfaces. All predefined interfaces (and any custom
interfaces you define) inherit their definitions from the important interface IUnknown, which contains three vital
methods: QueryInterface, AddRef, and Release. All COM objects must implement the IUnknown interface
because it provides the means, using QueryInterface, to move freely between the different interfaces that an
object supports as well as the means to manage its lifetime by using AddRef and Release.
In creating an object that supports aggregation, you would need to implement one set of IUnknown functions for
all interfaces as well as a stand-alone IUnknown interface. In any case, any object implementor will implement
IUnknown methods. See the section Using and Implementing IUnknown for more information.
While there are a few interfaces that inherit their definitions from a second interface in addition to IUnknown, the
majority simply inherit the IUnknown interface methods. This makes most interfaces relatively compact and easy
to encapsulate.

Related topics
C
O
M
O
b
j
e
c
t
s
a
n
d
I
n
t
e
r
f
a
c
e
s
Using and Implementing IUnknown
1/7/2020 • 2 minutes to read • Edit Online

COM provides a rich set of standards for implementing and using objects and for inter-object communication. The
topics in this section describe basic information relating to implementing objects. For information about how
clients and servers interact, see COM Clients and Servers. For more information about threading models and their
implementation and use, see Processes, Threads, and Apartments.
For details on using and implementing IUnknown, see the following topics:
QueryInterface: Navigating in an Object
Rules for Implementing QueryInterface
Managing Object Lifetimes Through Reference Counting
QueryInterface: Navigating in an Object
1/29/2020 • 3 minutes to read • Edit Online

After you have an initial pointer to an interface on an object, COM has a very simple mechanism to find out
whether the object supports another specific interface and, if so, to get a pointer to it. (For information about
getting an initial pointer to an interface on an object, see Getting a Pointer to an Object.) This mechanism is the
QueryInterface method of the IUnknown interface. If the object supports the requested interface, the method
must return a pointer to that interface. This permits an object to navigate freely through the interfaces that an
object supports. QueryInterface separates the request "Do you support a given contract?" from the high-
performance use of that contract once negotiations have been successful.
When a client initially gains access to an object, that client will receive, at a minimum, an IUnknown interface
pointer (the most fundamental interface) through which it can control the lifetime of the object—by telling the
object when it is done using the object—and invoke QueryInterface. The client is programmed to ask each object
it manages to perform some operations, but the IUnknown interface has no functions for those operations.
Instead, those operations are expressed through other interfaces. The client is thus programmed to negotiate with
objects for those interfaces. Specifically, the client will call QueryInterface to ask an object for an interface
through which the client may invoke the desired operations.
Because the object implements QueryInterface, it has the ability to accept or reject the request. If the object
accepts the client's request, QueryInterface returns a new pointer to the requested interface to the client. Through
that interface pointer, the client has access to the methods of that interface. If, on the other hand, the object rejects
the client's request, QueryInterface returns a null pointer—an error—and the client has no pointer through which
to call the desired functions. In this case, the client must deal gracefully with that possibility. For example, suppose
a client has a pointer to interface A on an object and asks for interfaces B and C. Suppose also that the object
supports interface B but does not support interface C. The result is that the object returns a pointer to B and
reports that C is not supported.
A key point is that when an object rejects a call to QueryInterface, it is impossible for the client to ask the object
to perform the operations expressed through the requested interface. A client must have an interface pointer to
invoke methods in that interface. If the object refuses to provide the requested pointer, the client must be prepared
to do without, either by not doing whatever it had intended to do with that object or by attempting to fall back on
another, perhaps less powerful, interface. This feature of COM functionality works well in comparison with other
object-oriented systems in which you cannot know whether a function will work until you call that function, and
even then, handling failure is uncertain. QueryInterface provides a reliable and consistent way to know whether
an object supports an interface before attempting to call its methods.
The QueryInterface method also provides a robust and reliable way for an object to indicate that it does not
support a given contract. That is, if in a call to QueryInterface one asks an "old" object whether it supports a
"new" interface (one, for example, that was invented after the old object had been shipped), the old object will
reliably, without causing a crash, answer "no." The technology that supports this is the algorithm by which IIDs are
allocated. While this may seem like a small point, it is extremely important to the overall architecture of the system,
and the ability to inquire of legacy elements about new functionality is, surprisingly, a feature not present in most
other object architectures.

Related topics
U
s
i
n
g
a
n
d
I
m
p
l
e
m
e
n
t
i
n
g
I
U
n
k
n
o
w
n
Rules for Implementing QueryInterface
1/29/2020 • 2 minutes to read • Edit Online

There are three main rules that govern implementing the IUnknown::QueryInterface method on a COM object:
Objects must have identity.
The set of interfaces on an object instance must be static.
It must be possible to query successfully for any interface on an object from any other interface.

Objects Must Have Identity


For any given object instance, a call to QueryInterface with IID_IUnknown must always return the same physical
pointer value. This allows you to call QueryInterface on any two interfaces and compare the results to determine
whether they point to the same instance of an object.

The Set of Interfaces on an Object Instance Must Be Static


The set of interfaces accessible on an object through QueryInterface must be static, not dynamic. Specifically, if
QueryInterface returns S_OK for a given IID once, it must never return E_NOINTERFACE on subsequent calls on
the same object; and if QueryInterface returns E_NOINTERFACE for a given IID, subsequent calls for the same
IID on the same object must never return S_OK.

It Must Be Possible to Query Successfully for Any Interface on an


Object from Any Other Interface
That is, given the following code:

IA * pA = (some function returning an IA *);


IB * pB = NULL;
HRESULT hr;
hr = pA->QueryInterface(IID_IB, &pB);

the following rules apply:


If you have a pointer to an interface on an object, a call like the following to QueryInterface for that same
interface must succeed:

pA->QueryInterface(IID_IA, ...)

If a call to QueryInterface for a second interface pointer succeeds, a call to QueryInterface from that
pointer for the first interface must also succeed. If pB was successfully obtained, the following must also
succeed:

pB->QueryInterface(IID_IA, ...)

Any interface must be able to query for any other interface on an object. If pB was successfully obtained and
you successfully query for a third interface (IC ) using that pointer, you must also be able to query
successfully for IC using the first pointer, pA. In this case, the following sequence must succeed:

IC * pC = NULL;
hr = pB->QueryInterface(IID_IC, &pC);
pA->QueryInterface(IID_IC, ...)

Interface implementations must maintain a counter of outstanding pointer references to all the interfaces on a
given object. You should use an unsigned integer for the counter.
If a client needs to know that resources have been freed, it must use a method in some interface on the object with
higher-level semantics before calling IUnknown::Release.

Related topics
U
s
i
n
g
a
n
d
I
m
p
l
e
m
e
n
t
i
n
g
I
U
n
k
n
o
w
n
Managing Object Lifetimes Through Reference
Counting
1/7/2020 • 3 minutes to read • Edit Online

In traditional object systems, the life cycle of objects—that is, the issues surrounding the creation and deletion of
objects—is handled implicitly by the language (or the language run time) or explicitly by application programmers.
In an evolving, decentrally constructed system made up of reused components, it is no longer true that any client,
or even any programmer, always "knows" how to deal with a component's lifetime. For a client with the right
security privileges, it is still relatively easy to create objects through a simple request, but object deletion is another
matter entirely. It is not necessarily clear when an object is no longer needed and should be deleted. (Readers
familiar with garbage-collected programming environments, such as Java, may disagree; however, Java objects do
not span machine or even process boundaries, and therefore the garbage collection is restricted to objects living
within a single-process space. In addition, Java forces the use of a single programming language.) Even when the
original client is done with the object, it cannot simply shut the object down, because some other client or clients
might still have a reference to it.
One way to ensure that an object is no longer needed is to depend entirely on an underlying communication
channel to inform the system when all connections to a cross-process or cross-channel object have disappeared.
However, schemes that use this method are unacceptable for several reasons. One problem is that it could require
a major difference between the cross-process/cross-network programming model and the single-process
programming model. In the cross-process/cross-network programming model, the communication system would
provide the hooks necessary for object lifetime management, while in the single-process programming model,
objects are directly connected without any intervening communications channel. Another problem is that this
scheme could also result in a layer of system-provided software that would interfere with component performance
in the in-process case. Furthermore, a mechanism based on explicit monitoring would not tend to scale toward
many thousands or millions of objects.
COM offers a scalable and distributed approach to this set of problems. Clients tell an object when they are using
it and when they are done, and objects delete themselves when they are no longer needed. This approach
mandates that all objects count references to themselves. Programming languages such as Java, which inherently
have their own lifetime management schemes, such as garbage collection, can use COM's reference counting to
implement and use COM objects internally, allowing the programmer to avoid dealing with it.
Just as an application must free memory it has allocated once that memory is no longer in use, a client of an object
is responsible for freeing its references to the object when that object is no longer needed. In an object-oriented
system, the client can do this only by giving the object an instruction to free itself.
It is important that an object be deallocated when it is no longer being used. The difficulty lies in determining
when it is appropriate to deallocate an object. This is easy with automatic variables (those allocated on the stack)—
they cannot be used outside the block in which they're declared, so the compiler deallocates them when the end of
the block is reached. For COM objects, which are dynamically allocated, it is up to the clients of an object to decide
when they no longer need to use the object—especially local or remote objects that might be in use by multiple
clients at the same time. The object must wait until all clients are finished with it before freeing itself. Because COM
objects are manipulated through interface pointers and can be used by objects in different processes or on other
machines, the system cannot keep track of an object's clients.
COM's method of determining when it is appropriate to deallocate an object is manual reference counting. Each
object maintains a reference count that tracks how many clients are connected to it—that is, how many pointers
exist to any of its interfaces in any client.
For more information, see the following topics:
Implementing Reference Counting
Rules for Managing Reference Counts

Related topics
U
s
i
n
g
a
n
d
I
m
p
l
e
m
e
n
t
i
n
g
I
U
n
k
n
o
w
n
Implementing Reference Counting
1/29/2020 • 2 minutes to read • Edit Online

Reference counting requires work on the part of both the implementor of a class and the clients who use objects of
that class. When you implement a class, you must implement the AddRef and Release methods as part of the
IUnknown interface. These two methods have the following simple implementations:
AddRef increments the object's internal reference count.
Release first decrements the object's internal reference count, and then it checks whether the reference count
has fallen to zero. If it has, that means no one is using the object any longer, so the Release function deallocates
the object.
A common implementation approach for most objects is to have only one implementation of these methods (along
with QueryInterface), which is shared between all interfaces, and therefore a reference count that applies to the
entire object. However, from a client's perspective, reference counting is strictly and clearly a per-interface-pointer
notion, and therefore objects that take advantage of this capability by dynamically constructing, destroying, loading,
or unloading portions of their functionality based on the currently extant interface pointers may be implemented.
These are colloquially called tear-off interfaces.
Whenever a client calls a method (or API function), such as QueryInterface, that returns a new interface pointer,
the method being called is responsible for incrementing the reference count through the returned pointer. For
example, when a client first creates an object, it receives an interface pointer to an object that, from the client's point
of view, has a reference count of one. If the client then calls AddRef on the interface pointer, the reference count
becomes two. The client must call Release twice on the interface pointer to drop all of its references to the object.
An example of how reference counts are strictly per-interface-pointer occurs when a client calls QueryInterface
on the first pointer for either a new interface or the same interface. In either of these cases, the client is required to
call Release once for each pointer. COM does not require that an object return the same pointer when asked for
the same interface multiple times. (The only exception to this is a query to IUnknown, which identifies an object to
COM.) This allows the object implementation to manage resources efficiently.
Thread-safety is also an important issue in implementing AddRef and Release. For more information, see
Processes, Threads, and Apartments.

Related topics
M
a
n
a
g
i
n
g
O
b
j
e
c
t
L
i
f
e
t
i
m
e
s
T
h
r
o
u
g
h
R
e
f
e
r
e
n
c
e
C
o
u
n
t
i
n
g
Rules for Managing Reference Counts
1/29/2020 • 4 minutes to read • Edit Online

Using a reference count to manage an object's lifetime allows multiple clients to obtain and release access to a
single object without having to coordinate with one another in managing the object's lifetime. As long as the client
object conforms to certain rules of use, the object, in effect, provides this management. These rules specify how to
manage references between objects. (COM does not specify internal implementations of objects, although these
rules are a reasonable starting point for a policy within an object.)
Conceptually, interface pointers can be thought of as residing within pointer variables that include all the internal
computation state that holds an interface pointer. This would include variables in memory locations, in internal
processor registers, and both programmer-generated and compiler-generated variables. Assignment to or
initialization of a pointer variable involves creating a new copy of an already existing pointer. Where there was one
copy of the pointer in some variable (the value used in the assignment/initialization), there are now two. An
assignment to a pointer variable destroys the pointer copy presently in the variable, as does the destruction of the
variable itself. (That is, the scope in which the variable is found, such as the stack frame, is destroyed.)
From a COM client's perspective, reference counting is always done for each interface. Clients should never
assume that an object uses the same counter for all interfaces.
The default case is that AddRef must be called for every new copy of an interface pointer and Release must be
called for every destruction of an interface pointer, except where the following rules permit otherwise:
In-out parameters to functions. The caller must call AddRef on the parameter because it will be released
(with a call to Release) in the implementing code when the out value is stored on top of it.
Fetching a global variable. When creating a local copy of an interface pointer from an existing copy of the
pointer in a global variable, you must call AddRef on the local copy because another function might destroy the
copy in the global variable while the local copy is still valid.
New pointers synthesized out of "thin air." A function that synthesizes an interface pointer using special
internal knowledge rather than obtaining it from some other source must call AddRef initially on the newly
synthesized pointer. Important examples of such routines include instance creation routines, implementations of
QueryInterface, and so on.
Retrieving a copy of an internally stored pointer. When a function retrieves a copy of a pointer that is
stored internally by the object called, that object's code must call AddRef on the pointer before the function
returns. Once the pointer has been retrieved, the originating object has no other way of determining how its
lifetime relates to that of the internally stored copy of the pointer.
The only exceptions to the default case require that the managing code know the relationships of the lifetimes of
two or more copies of a pointer to the same interface on an object and simply ensure that the object is not
destroyed by allowing its reference count to go to zero. There are generally two cases, as follows:
When one copy of a pointer already exists and a second is created subsequently and then is destroyed while the
first copy still exists, calls to AddRef and Releasefor the second copy can be omitted.
When one copy of a pointer exists and a second is created and then the first is destroyed before the second, the
calls to AddReffor the second copy and to Release for the first copy can be omitted.
The following are specific examples of these situations, the first two being especially common:
In parameters to functions. The lifetime of the copy of an interface pointer passed as a parameter to a
function is nested in that of the pointer used to initialize the value, so there is no need for a separate reference
count on the parameter.
Out parameters from functions, including return values. To set the out parameter, the function must have
a stable copy of the interface pointer. On return, the caller is responsible for releasing the pointer. Therefore, the
out parameter does not need a separate reference count.
Local variables. A method implementation has control of the lifetimes of each of the pointer variables
allocated on the stack frame and can use this to determine how to omit redundant AddRef/Release pairs.
Backpointers. Some data structures contain two objects, each with a pointer to the other. If the lifetime of the
first object is known to contain the lifetime of the second, it is not necessary to have a reference count on the
second object's pointer to the first object. Often, avoiding this cycle is important in maintaining the appropriate
deallocation behavior. However, uncounted pointers should be used with extreme caution because the portion
of the operating system that handles remote processing has no way of knowing about this relationship.
Therefore, in almost all cases, having the backpointer see a second, "friend" object of the first pointer (thus
avoiding the circularity) is the preferred solution. COM's connectable objects architecture, for example, uses this
approach.
When implementing or using reference-counted objects, it may be useful to apply artificial reference counts, which
guarantee object stability during processing of a function. In implementing a method of an interface, you might call
functions that have a chance of decrementing your reference count to an object, causing a premature release of the
object and failure of the implementation. A robust way to avoid this is to insert a call to AddRef at the beginning
of the method implementation and pair it with a call to Release just before the method returns.
In some situations, the return values of AddRef and Release may be unstable and should not be relied upon; they
should be used only for debugging or diagnostic purposes.

Related topics
M
a
n
a
g
i
n
g
O
b
j
e
c
t
L
i
f
e
t
i
m
e
s
T
h
r
o
u
g
h
R
e
f
e
r
e
n
c
e
C
o
u
n
t
i
n
g
Reusing Objects
1/7/2020 • 2 minutes to read • Edit Online

An important goal of any object model is to enable object authors to reuse and extend objects provided by others
as pieces of their own implementations. One way to do this in Microsoft Visual C++ and other languages is by
using implementation inheritance, which allows an object to inherit ("subclass") some of its functions from another
object while overriding other functions.
The problem for systemwide object interaction using traditional implementation inheritance is that the contract
(the interface) between objects in an implementation hierarchy is not clearly defined. In fact, it is implicit and
ambiguous. When the parent or child object changes its implementation, the behavior of related components
might become undefined or unstably implemented. In any single application, where the implementation can be
managed by a single engineering team that updates all of the components at the same time, this is not always a
major concern. In an environment where the components of one team are built through black-box reuse of other
components built by other teams, this type of instability jeopardizes reuse. Additionally, implementation
inheritance usually works only within process boundaries. This makes traditional implementation inheritance
impractical for large, evolving systems composed of software components built by many engineering teams.
The key to building reusable components is to be able to treat the object as a black box. This means that the piece
of code attempting to reuse another object knows nothing, and needs to know nothing, about the internal
structure or implementation of the component being used. In other words, the code attempting to reuse a
component depends on the behavior of the object and not its exact implementation.
To achieve black-box reusability, COM adopts other established reusability mechanisms such as
containment/delegation and aggregation.

NOTE
For convenience, the object being reused is called the inner object and the object making use of that inner object is the outer
object.

It is important to remember in both these mechanisms how the outer object appears to its clients. As far as the
clients are concerned, both objects implement any interfaces to which the client can get a pointer. The client treats
the outer object as a black box and therefore does not care, nor does it need to care, about the internal structure of
the outer object—the client cares only about behavior.
For more information, see the following topics:
Containment/Delegation
Aggregation
Containment/Delegation
1/7/2020 • 2 minutes to read • Edit Online

The most common mechanism for object reuse in COM is containment/delegation. This type of reuse is a familiar
concept found in most object-oriented languages and systems. The outer object, which needs to make use of the
inner object, acts as an object client to the inner object. The outer object "contains" the inner object, and when the
outer object requires the services of the inner object, the outer object explicitly delegates implementation to the
inner object's methods. That is, the outer object uses the inner object's services to implement itself.
It is not necessary for the outer and inner objects to support the same interfaces, although it certainly is
reasonable to contain an object that implements an interface that the outer object does not and implement the
methods of the outer object simply as calls to the corresponding methods in the inner object. When the complexity
of the outer and inner objects differs greatly, however, the outer object may implement some of the methods of its
interfaces by delegating calls to interface methods implemented in the inner object.
It is simple to implement containment for an outer object. The outer object creates the inner objects it needs to use
as any other client would. This is nothing new —the process is like a C++ object that itself contains a C++ string
object that it uses to perform certain string functions, even if the outer object is not considered a string object in its
own right. Then, using its pointer to the inner object, a call to a method in the outer object generates a call to an
inner object method.

Related topics
A
g
g
r
e
g
a
t
i
o
n
Aggregation
1/29/2020 • 4 minutes to read • Edit Online

Aggregation is the object reuse mechanism in which the outer object exposes interfaces from the inner object as if
they were implemented on the outer object itself. This is useful when the outer object delegates every call to one
of its interfaces to the same interface in the inner object. Aggregation is available as a convenience to avoid extra
implementation overhead in the outer object in this case. Aggregation is actually a specialized case of
containment/delegation.
Aggregation is almost as simple to implement as containment is, except for the three IUnknown functions:
QueryInterface, AddRef, and Release. The catch is that from the client's perspective, any IUnknown function
on the outer object must affect the outer object. That is, AddRef and Release affect the outer object and
QueryInterface exposes all the interfaces available on the outer object. However, if the outer object simply
exposes an inner object's interface as its own, that inner object's IUnknown members called through that
interface will behave differently than those IUnknown members on the outer object's interfaces, an absolute
violation of the rules and properties governing IUnknown.
The solution is that aggregation requires an explicit implementation of IUnknown on the inner object and
delegation of the IUnknown methods of any other interface to the outer object's IUnknown methods.

Creating Aggregable Objects


Creating objects that can be aggregated is optional; however, it is simple to do and provides significant benefits.
The following rules apply to creating an aggregable object:
The aggregable (or inner) object's implementation of QueryInterface, AddRef, and Release for its
IUnknown interface controls the inner object's reference count, and this implementation must not delegate to
the outer object's unknown (the controlling IUnknown).
The aggregable (or inner) object's implementation of QueryInterface, AddRef, and Release for its other
interfaces must delegate to the controlling IUnknown and must not directly affect the inner object's reference
count.
The inner IUnknown must implement QueryInterface only for the inner object.
The aggregable object must not call AddRef when holding a reference to the controlling IUnknown pointer.
When the object is created, if any interface other than IUnknown is requested, the creation must fail with
E_NOINTERFACE.
The following code fragment illustrates a correct implementation of an aggregable object by using the nested
class method of implementing interfaces:

// CSomeObject is an aggregable object that implements


// IUnknown and ISomeInterface
class CSomeObject : public IUnknown
{
private:
DWORD m_cRef; // Object reference count
IUnknown* m_pUnkOuter; // Controlling IUnknown, no AddRef

// Nested class to implement the ISomeInterface interface


class CImpSomeInterface : public ISomeInterface
{
friend class CSomeObject ;
private:
DWORD m_cRef; // Interface ref-count, for debugging
IUnknown* m_pUnkOuter; // Controlling IUnknown
IUnknown* m_pUnkOuter; // Controlling IUnknown
public:
CImpSomeInterface() { m_cRef = 0; };
~ CImpSomeInterface(void) {};

// IUnknown members delegate to the outer unknown


// IUnknown members do not control lifetime of object
STDMETHODIMP QueryInterface(REFIID riid, void** ppv)
{ return m_pUnkOuter->QueryInterface(riid,ppv); };

STDMETHODIMP_(DWORD) AddRef(void)
{ return m_pUnkOuter->AddRef(); };

STDMETHODIMP_(DWORD) Release(void)
{ return m_pUnkOuter->Release(); };

// ISomeInterface members
STDMETHODIMP SomeMethod(void)
{ return S_OK; };
} ;
CImpSomeInterface m_ImpSomeInterface ;
public:
CSomeObject(IUnknown * pUnkOuter)
{
m_cRef=0;
// No AddRef necessary if non-NULL as we're aggregated.
m_pUnkOuter=pUnkOuter;
m_ImpSomeInterface.m_pUnkOuter=pUnkOuter;
} ;
~CSomeObject(void) {} ;

// Static member function for creating new instances (don't use


// new directly). Protects against outer objects asking for
// interfaces other than Iunknown.
static HRESULT Create(IUnknown* pUnkOuter, REFIID riid, void **ppv)
{
CSomeObject* pObj;
if (pUnkOuter != NULL && riid != IID_IUnknown)
return CLASS_E_NOAGGREGATION;
pObj = new CSomeObject(pUnkOuter);
if (pObj == NULL)
return E_OUTOFMEMORY;
// Set up the right unknown for delegation (the non-
// aggregation case)
if (pUnkOuter == NULL)
{
pObj->m_pUnkOuter = (IUnknown*)pObj ;
pObj->m_ImpSomeInterface.m_pUnkOuter = (IUnknown*)pObj;
}
HRESULT hr;
if (FAILED(hr = pObj->QueryInterface(riid, (void**)ppv)))
delete pObj ;
return hr;
}

// Inner IUnknown members, non-delegating


// Inner QueryInterface only controls inner object
STDMETHODIMP QueryInterface(REFIID riid, void** ppv)
{
*ppv=NULL;
if (riid == IID_IUnknown)
*ppv=this;
if (riid == IID_ISomeInterface)
*ppv=&m_ImpSomeInterface;
if (NULL==*ppv)
return ResultFromScode(E_NOINTERFACE);
((IUnknown*)*ppv)->AddRef();
return NOERROR;
} ;
STDMETHODIMP_(DWORD) AddRef(void)
{ return ++m_cRef; };
STDMETHODIMP_(DWORD) Release(void)
{
if (--m_cRef != 0)
return m_cRef;
delete this;
return 0;
};
};

Aggregating Objects
When developing an aggregable object, the following rules apply:
When creating the inner object, the outer object must explicitly ask for its IUnknown.
The outer object must protect its implementation of Release from reentrancy with an artificial reference
count around its destruction code.
The outer object must call its controlling IUnknown Release method if it queries for a pointer to any of
the inner object's interfaces. To free this pointer, the outer object calls its controlling IUnknown AddRef
method, followed by Release on the inner object's pointer.

// Obtaining inner object interface pointer


pUnkInner->QueryInterface(IID_ISomeInterface, &pISomeInterface);
pUnkOuter->Release();

// Releasing inner object interface pointer


pUnkOuter->AddRef();
pISomeInterface->Release();

The outer object must not blindly delegate a query for any unrecognized interface to the inner object,
unless that behavior is specifically the intention of the outer object.

Related topics
C
o
n
t
a
i
n
m
e
n
t
/
D
e
l
e
g
a
t
i
o
n
The COM Library
1/7/2020 • 2 minutes to read • Edit Online

Any process that uses COM must both initialize and uninitialize the COM library. In addition to being a
specification, COM also implements some important services in this library. Provided as a set of DLLs and EXEs
(primarily Ole32.dll and Rpcss.exe) in Microsoft Windows, the COM library includes the following:
A small number of fundamental functions that facilitate the creation of COM applications, both client and
server. For clients, COM supplies basic functions for creating objects. For servers, COM supplies the means
of exposing their objects.
Implementation-locator services through which COM determines, from a unique class identifier (CLSID ),
which server implements that class and where that server is located. This service includes support for a
level of indirection, usually a system registry, between the identity of an object class and the packaging of
the implementation so that clients are independent of the packaging, which can change in the future.
Transparent remote procedure calls when an object is running in a local or remote server.
A standard mechanism to allow an application to control how memory is allocated within its process,
particularly memory that needs to be passed between cooperating objects so that it can be freed properly.
To use basic COM services, all COM threads of execution in clients and out-of-process servers must call either the
CoInitialize or the CoInitializeEx function before calling any other COM function except memory allocation
calls. CoInitializeEx replaces the other function, adding a parameter that allows you to specify the threading
model of the thread—either apartment-threaded or free-threaded. A call to CoInitialize simply sets the
threading model to apartment-threaded.
OLE compound document applications call the OleInitialize function, which calls CoInitializeEx and also does
some initialization required for compound documents. Therefore, threads that call OleInitialize cannot be free-
threaded. For information on threading in clients and servers, see Processes, Threads, and Apartments.
In-process servers do not call the initialization functions because they are being loaded into a process that has
already done so. As a result, in-process servers must set their threading model in the registry under the
InprocServer32 key. For detailed information on threading issues in in-process servers, see In-Process Server
Threading Issues.
It is also important to uninitialize the library. For each call to CoInitialize or CoInitializeEx, there must be a
corresponding call to CoUninitialize. For each call to OleInitialize, there must be a corresponding call to
OleUninitialize.
In-process servers can assume that the process they are being loaded into has already performed these steps.

Related topics
T
h
e
C
o
m
p
o
n
e
n
t
O
b
j
e
c
t
M
o
d
e
l
Managing Memory Allocation
1/7/2020 • 2 minutes to read • Edit Online

In COM, many, if not most, interface methods are called by code written by one programming organization and
implemented by code written by another. Many of the parameters and return values of these functions are of types
that can be passed around by value. Sometimes, however, it is necessary to pass data structures for which this is
not the case, so it is necessary for both caller and called to have a compatible allocation and de-allocation policy.
COM defines a universal convention for memory allocation, because it is more reasonable than defining case-by-
case rules and so that the COM remote procedure call implementation can correctly manage memory.
The methods of a COM interface always provide memory management of pointers to the interface by calling the
AddRef and Release functions found in the IUnknown interface, from which all other COM interfaces derive.
(See Rules for Managing Reference Counts for more information.)
This section describes only how to allocate memory for parameters that are not passed by value — not pointers to
interfaces, but more mundane things like strings, pointers to structures, and so forth.
For more information, see the following topics:
The OLE Memory Allocator
Memory Management Rules
Debugging Memory Allocations
The OLE Memory Allocator
1/7/2020 • 2 minutes to read • Edit Online

The COM library provides an implementation of a memory allocator that is thread-safe. (That is, it cannot cause
problems in multithreaded situations.) Whenever ownership of an allocated chunk of memory is passed through a
COM interface or between a client and the COM library, you must use this COM allocator to allocate the memory.
Allocation internal to an object can use any allocation scheme desired, but the COM memory allocator is a handy,
efficient, and thread-safe allocator.
A call to the API function CoGetMalloc provides a pointer to the OLE allocator, which is an implementation of the
IMalloc interface. However, it is more efficient to call the helper functions CoTaskMemAlloc,
CoTaskMemRealloc, and CoTaskMemFree, which wrap getting a pointer to the task memory allocator, calling
the corresponding IMalloc method, and then releasing the pointer to the allocator.

Related topics
M
a
n
a
g
i
n
g
M
e
m
o
r
y
A
l
l
o
c
a
t
i
o
n

T
h
e
C
O
M
L
i
b
r
a
r
y
Memory Management Rules
1/7/2020 • 2 minutes to read • Edit Online

The lifetime of pointers to interfaces is always managed through the AddRef and Release methods on every
COM interface. For more information, see Rules for Managing Reference Counts.
For all other parameters, it is important to adhere to certain rules for managing memory. The following rules apply
to all parameters of interface methods—including the return value—that are not passed by value:
In-parameters must be allocated and freed by the caller.
Out-parameters must be allocated by the one called; they are freed by the caller using the standard COM task
memory allocator. See The OLE Memory Allocator for more information.
In/out-parameters are initially allocated by the caller, and then freed and reallocated by the one called, if
necessary. As is true for out parameters, the caller is responsible for freeing the final returned value. The
standard COM memory allocator must be used.
In the latter two cases, where one piece of code allocates the memory and a different piece of code frees it, using
the COM allocator ensures that the two pieces of code are using the same allocation methods.
Another area that needs special attention is the treatment of out and in-out parameters in failure conditions. If a
function returns a failure code, the caller typically has no way to clean up the out or in-out parameters. This leads
to the following additional rules:
In case of an error condition, parameters must always be reliably set to a value that will be cleaned up without
any action by the caller.
All out pointer parameters must explicitly be set to NULL. These are usually passed in a pointer-to-pointer
parameter but can also be passed as members of a structure that the caller allocates and the called code fills.
The most straightforward way to ensure this is (in part) to set these values to NULL on function entry. This rule
is important because it promotes more robust application interoperability.
Under error conditions, all in-out parameters must either be left alone by the code called (thus remaining at the
value to which they were initialized by the caller) or be explicitly set, as in the out parameter error return case.
Remember that these memory management conventions for COM applications apply only across public interfaces
and APIs—there is no requirement at all that memory allocation strictly internal to a COM application need be
done using these mechanisms.
COM internally uses Remote Procedure Calls (RPC ) to communicate between clients and servers. For more
information about managing memory in RPC server stubs, see the Server-stub Memory Management topic.

Related topics
M
a
n
a
g
i
n
g
M
e
m
o
r
y
A
l
l
o
c
a
t
i
o
n
Debugging Memory Allocations
1/7/2020 • 2 minutes to read • Edit Online

COM provides the IMallocSpy interface for developers to use to debug their memory allocations. For each
method in IMalloc, there are two methods in IMallocSpy, a "pre" method and a "post" method. After a developer
implements it and publishes it to the system, the system calls the IMallocSpy "pre" method just before the
corresponding IMalloc method, effectively allowing the debug code to "spy" on the allocation operation, and calls
the "post" method to release the spy.
For example, when COM detects that the next call is a call to IMalloc::Alloc, it calls IMallocSpy::PreAlloc,
executing whatever debug operations the developer wants during the Alloc execution, and then, when the Alloc
call returns, calls IMallocSpy::PostAlloc to release the spy and return control to the code.

Related topics
M
a
n
a
g
i
n
g
M
e
m
o
r
y
A
l
l
o
c
a
t
i
o
n
Processes, Threads, and Apartments
1/7/2020 • 5 minutes to read • Edit Online

A process is a collection of virtual memory space, code, data, and system resources. A thread is code that is to be
serially executed within a process. A processor executes threads, not processes, so each application has at least
one process, and a process always has at least one thread of execution, known as the primary thread. A process
can have multiple threads in addition to the primary thread.
Processes communicate with one another through messages, using Microsoft's Remote Procedure Call (RPC )
technology to pass information to one another. There is no difference to the caller between a call coming from a
process on a remote machine and a call coming from another process on the same machine.
When a thread begins to execute, it continues until it is killed or until it is interrupted by a thread with higher
priority (by a user action or the kernel's thread scheduler). Each thread can run separate sections of code, or
multiple threads can execute the same section of code. Threads executing the same block of code maintain
separate stacks. Each thread in a process shares that process's global variables and resources.
The thread scheduler determines when and how often to execute a thread, according to a combination of the
process's priority class attribute and the thread's base priority. You set a process's priority class attribute by
calling the SetPriorityClass function , and you set a thread's base priority with a call to SetThreadPriority.
Multithreaded applications must avoid two threading problems: deadlocks and races. A deadlock occurs when
each thread is waiting for the other to do something. The COM call control helps prevent deadlocks in calls
between objects. A race condition occurs when one thread finishes before another on which it depends, causing
the former to use an uninitialized value because the latter has not yet supplied a valid one. COM supplies some
functions specifically designed to help avoid race conditions in out-of-process servers. (See Out-of-Process
Server Implementation Helpers.)

The Apartment and the COM Threading Architecture


While COM supports the single-thread-per-process model prevalent before the introduction of multiple threads
of execution, you can write code to take advantage of multiple threads, resulting in more efficient applications, by
allowing one thread to be executed while another thread waits for some time-consuming operation to complete.

NOTE
Using multiple threads is not a guarantee of better performance. In fact, because thread factoring is a difficult problem,
using multiple threads often causes performance problems. The key is to use multiple threads only if you are very sure of
what you are doing.

In general, the simplest way to view the COM threading architecture is to think of all the COM objects in the
process as divided into groups called apartments. A COM object lives in exactly one apartment, in the sense that
its methods can legally be directly called only by a thread that belongs to that apartment. Any other thread that
wants to call the object must go through a proxy.
There are two types of apartments: single-threaded apartments, and multithreaded apartments.
Single-threaded apartments consist of exactly one thread, so all COM objects that live in a single-threaded
apartment can receive method calls only from the one thread that belongs to that apartment. All method calls
to a COM object in a single-threaded apartment are synchronized with the windows message queue for the
single-threaded apartment's thread. A process with a single thread of execution is simply a special case of this
model.
Multithreaded apartments consist of one or more threads, so all COM objects that live in an multithreaded
apartment can receive method calls directly from any of the threads that belong to the multithreaded
apartment. Threads in a multithreaded apartment use a model called free-threading. Calls to COM objects in
a multithreaded apartment are synchronized by the objects themselves.

NOTE
For a description of communication between single-threaded apartments and multithreaded apartments within the same
process, see Single-Threaded and Multithreaded Communication.

A process can have zero or more single-threaded apartments and zero or one multithreaded apartment.
In a process, the main apartment is the first to be initialized. In a single-threaded process, this is the only
apartment. Call parameters are marshaled between apartments, and COM handles the synchronization through
messaging. If you designate multiple threads in a process to be free-threaded, all free threads reside in a single
apartment, parameters are passed directly to any thread in the apartment, and you must handle all
synchronization. In a process with both free-threading and apartment threading, all free threads reside in a
single apartment and all other apartments are single-threaded apartments. A process that does COM work is a
collection of apartments with, at most, one multithreaded apartment but any number of single-threaded
apartments.
The threading models in COM provide the mechanism for clients and servers that use different threading
architectures to work together. Calls among objects with different threading models in different processes are
naturally supported. From the perspective of the calling object, all calls to objects outside a process behave
identically, no matter how the object being called is threaded. Likewise, from the perspective of the object being
called, arriving calls behave identically, regardless of the threading model of the caller.
Interaction between a client and an out-of-process object is straightforward, even when they use different
threading models because the client and object are in different processes. COM, interposed between the client
and the server, can provide the code for the threading models to interoperate, using standard marshaling and
RPC. For example, if a single-threaded object is called simultaneously by multiple free-threaded clients, the calls
will be synchronized by COM by placing corresponding window messages in the server's message queue. The
object's apartment will receive one call each time it retrieves and dispatches messages. However, some care
must be taken to ensure that in-process servers interact properly with their clients. (See In-Process Server
Threading Issues.)
The most important issue in programming with a multithreaded model is to make your code thread-safe so that
messages intended for a particular thread go only to that thread and access to threads is protected.
For more information, see the following topics:
Choosing the Threading Model
Single-Threaded Apartments
Multithreaded Apartments
Single-Threaded and Multithreaded Communication
In-Process Server Threading Issues
Accessing Interfaces Across Apartments
Choosing the Threading Model
1/7/2020 • 2 minutes to read • Edit Online

Choosing the threading model for an object depends on the object's function. An object that does extensive I/O
might support free-threading to provide maximum response to clients by allowing interface calls during I/O
latency. On the other hand, an object that interacts with the user might support apartment threading to
synchronize incoming COM calls with its window operations.
It is easier to support apartment threading in single-threaded apartments because COM provides synchronization
on a per-call basis. Supporting free-threading is more difficult because the object must implement
synchronization; however, response to clients may be better because synchronization can be implemented for
smaller sections of code.

Related topics
A
c
c
e
s
s
i
n
g
I
n
t
e
r
f
a
c
e
s
A
c
r
o
s
s
A
p
a
r
t
m
e
n
t
s

M
u
l
t
i
t
h
r
e
a
d
e
d
A
p
a
r
t
m
e
n
t
s

I
n
-
P
r
o
c
e
s
s
S
e
r
v
e
r
T
h
r
e
a
d
i
n
g
I
s
s
u
e
s

P
r
o
c
e
s
s
e
s
,
T
h
r
e
a
d
s
,
a
n
d
A
p
a
r
t
m
e
n
t
s

S
i
n
g
l
e
-
T
h
r
e
a
d
e
d
a
n
d
M
u
l
t
i
t
h
r
e
a
d
e
d
C
o
m
m
u
n
i
c
a
t
i
o
n

S
i
n
g
l
e
-
T
h
r
e
a
d
e
d
A
p
a
r
t
m
e
n
t
s
Single-Threaded Apartments
1/7/2020 • 5 minutes to read • Edit Online

Using single-threaded apartments (the apartment model process) offers a message-based paradigm for dealing
with multiple objects running concurrently. It enables you to write more efficient code by allowing a thread, while
it waits for some time-consuming operation to complete, to allow another thread to be executed.
Each thread in a process that is initialized as an apartment model process, and that retrieves and dispatches
window messages, is a single-threaded apartment thread. Each thread lives within its own apartment. Within an
apartment, interface pointers can be passed without marshaling, and therefore, all objects in one single-threaded
apartment thread communicate directly.
A logical grouping of related objects that all execute on the same thread, and therefore must have synchronous
execution, could live on the same single-threaded apartment thread. However, an apartment model object cannot
reside on more than one thread. Calls to objects in other processes must be made within the context of the
owning process, so distributed COM switches threads for you automatically when you call on a proxy.
The interprocess and interthread models are similar. When it is necessary to pass an interface pointer to an object
in another apartment (on another thread) within the same process, you use the same marshaling model that
objects in different processes use to pass pointers across process boundaries. By getting a pointer to the standard
marshaling object, you can marshal interface pointers across thread boundaries (between apartments) in the
same way you do between processes. (Interface pointers must be marshaled when passed between apartments.)
Rules for single-threaded apartments are simple, but it is important to follow them carefully:
Every object should live on only one thread (within a single-threaded apartment).
Initialize the COM library for each thread.
Marshal all pointers to objects when passing them between apartments.
Each single-threaded apartment must have a message loop to handle calls from other processes and
apartments within the same process. Single-threaded apartments without objects (client only) also need a
message loop to dispatch the broadcast messages that some applications use.
DLL -based or in-process objects do not call the COM initialization functions; instead, they register their
threading model with the ThreadingModel named-value under the InprocServer32 key in the registry.
Apartment-aware objects must also write DLL entry points carefully. There are special considerations that
apply to threading in-process servers. For more information, see In-Process Server Threading Issues.
While multiple objects can live on a single thread, no apartment model object can live on more than one thread.
Each thread of a client process or out-of-process server must call CoInitialize, or call CoInitializeEx and specify
COINIT_APARTMENTTHREADED for the dwCoInit parameter. The main apartment is the thread that calls
CoInitializeEx first. For information on in-process servers, see In-Process Server Threading Issues.
All calls to an object must be made on its thread (within its apartment). It is forbidden to call an object directly
from another thread; using objects in this free-threaded manner could cause problems for applications. The
implication of this rule is that all pointers to objects must be marshaled when passed between apartments. COM
provides the following two functions for this purpose:
CoMarshalInterThreadInterfaceInStream marshals an interface into a stream object that is returned to the
caller.
CoGetInterfaceAndReleaseStream unmarshals an interface pointer from a stream object and releases it.
These functions wrap calls to CoMarshalInterface and CoUnmarshalInterface functions, which require the
use of the MSHCTX_INPROC flag.
In general, the marshaling is accomplished automatically by COM. For example, when passing an interface
pointer as a parameter in a method call on a proxy to an object in another apartment, or when calling
CoCreateInstance, COM does the marshaling automatically. However, in some special cases, where the
application writer is passing interface pointers between apartments without using the normal COM mechanisms,
the writer must handle the marshaling manually.
If one apartment (Apartment 1) in a process has an interface pointer and another apartment (Apartment 2)
requires its use, Apartment 1 must call CoMarshalInterThreadInterfaceInStream to marshal the interface. The
stream that is created by this function is thread-safe and must be stored in a variable that is accessible by
Apartment 2. Apartment 2 must pass this stream to CoGetInterfaceAndReleaseStream to unmarshal the
interface and will get back a pointer to a proxy through which it can access the interface. The main apartment
must remain alive until the client has completed all COM work (because some in-process objects are loaded in
the main apartment, as described in In-Process Server Threading Issues). After one object has been passed
between threads in this manner, it is very easy to pass interface pointers as parameters. That way, distributed
COM does the marshaling and thread switching for the application.
To handle calls from other processes and apartments within the same process, each single-threaded apartment
must have a message loop. This means that the thread's work function must have a
GetMessage/DispatchMessage loop. If other synchronization primitives are being used to communicate between
threads, the MsgWaitForMultipleObjects function can be used to wait both for messages and for thread
synchronization events. The documentation for this function has an example of this sort of combination loop.
COM creates a hidden window using the Windows class "OleMainThreadWndClass" in each single-threaded
apartment. A call to an object is received as a window message to this hidden window. When the object's
apartment retrieves and dispatches the message, the hidden window will receive it. The window procedure will
then call the corresponding interface method of the object.
When multiple clients call an object, the calls are queued in the message queue and the object will receive a call
each time its apartment retrieves and dispatches messages. Because the calls are synchronized by COM and the
calls are always delivered by the thread that belongs to the object's apartment, the object's interface
implementations need not provide synchronization. Single-threaded apartments can implement IMessageFilter
to permit them to cancel calls or receive window messages when necessary.
The object can be reentered if one of its interface method implementations retrieves and dispatches messages or
makes an ORPC call to another thread, thereby causing another call to be delivered to the object (by the same
apartment). OLE does not prevent reentrancy on the same thread, but it can help provide thread safety. This is
identical to the way in which a window procedure can be reentered if it retrieves and dispatches messages while
processing a message. However, calling an out-of-process single-threaded apartment server that calls another
single-threaded apartment server will allow the first server to be reentered.

Related topics
A
c
c
e
s
s
i
n
g
I
n
t
e
r
f
a
c
e
s
A
c
r
o
s
s
A
p
a
r
t
m
e
n
t
s

C
h
o
o
s
i
n
g
t
h
e
T
h
r
e
a
d
i
n
g
M
o
d
e
l
M
u
l
t
i
t
h
r
e
a
d
e
d
A
p
a
r
t
m
e
n
t
s

I
n
-
P
r
o
c
e
s
s
S
e
r
v
e
r
T
h
r
e
a
d
i
n
g
I
s
s
u
e
s

P
r
o
c
e
s
s
e
s
,
T
h
r
e
a
d
s
,
a
n
d
A
p
a
r
t
m
e
n
t
s

S
i
n
g
l
e
-
T
h
r
e
a
d
e
d
a
n
d
M
u
l
t
i
t
h
r
e
a
d
e
d
C
o
m
m
u
n
i
c
a
t
i
o
n
Multithreaded Apartments
1/7/2020 • 4 minutes to read • Edit Online

In a multithreaded apartment model, all the threads in the process that have been initialized as free-threaded
reside in a single apartment. Therefore, there is no need to marshal between threads. The threads need not
retrieve and dispatch messages because COM does not use window messages in this model.
Calls to methods of objects in the multithreaded apartment can be run on any thread in the apartment. There is
no serialization of calls; many calls may occur to the same method or to the same object simultaneously. Objects
created in the multithreaded apartment must be able to handle calls on their methods from other threads at any
time.
Because calls to objects are not serialized in any way, multithreaded object concurrency offers the highest
performance and takes the best advantage of multiprocessor hardware for cross-thread, cross-process, and cross-
machine calling. This means, however, that the code for objects must provide synchronization in their interface
implementations, typically through the use of synchronization primitives such as event objects, critical sections,
mutexes, or semaphores, which are described later in this section. In addition, because the object doesn't control
the lifetime of the threads that are accessing it, no thread-specific state may be stored in the object (in thread local
storage).
Following are some important considerations regarding synchronization for multithreaded apartments:
COM provides call synchronization for single-threaded apartments only.
Multithreaded apartments do not receive calls while making calls (on the same thread).
Multithreaded apartments cannot make input-synchronized calls.
Asynchronous calls are converted to synchronous calls in multithreaded apartments.
The message filter is not called for any thread in a multithreaded apartment.
To initialize a thread as free-threaded, call CoInitializeEx, specifying COINIT_MULTITHREADED. For
information on in-process server threading, see In-Process Server Threading Issues.
Multiple clients can simultaneously call, from different threads, an object that supports free-threading. In free-
threaded out-of-process servers, COM, through the RPC subsystem, creates a pool of threads in the server
process and a client call (or multiple client calls) can be delivered by any of these threads at any time. An out-of-
process server must also implement synchronization in its class factory. Free-threaded, in-process objects can
receive direct calls from multiple threads of the client.
The client can do COM work in multiple threads. All threads belong to the same multithreaded apartment.
Interface pointers are passed directly from thread to thread within a multithreaded apartment, so interface
pointers are not marshaled between its threads. Message filters (implementations of IMessageFilter) are not
used in multithreaded apartments. The client thread will suspend when it makes a COM call to out-of-apartment
objects and will resume when the call returns. Calls between processes are still handled by RPC.
Threads initialized with the free-threaded model must implement their own synchronization. As mentioned earlier
in this section, Windows enables this implementation through the following synchronization primitives:
Event objects provide a way of signaling one or more threads that an event has occurred. Any thread within a
process can create an event object. A handle to the event is returned by the event-creating function,
CreateEvent. Once an event object has been created, threads with a handle to the object can wait on it before
continuing execution.
Critical sections are used for a section of code that requires exclusive access to some set of shared data before
it can be executed and that is used only by the threads within a single process. A critical section is like a
turnstile through which only one thread at a time may pass, working as follows:
To ensure that no more than one thread at a time accesses shared data, a process's primary thread
allocates a global CRITICAL_SECTION data structure and initializes its members. A thread entering a
critical section calls the EnterCriticalSection function and modifies the data structure's members.
A thread attempting to enter a critical section calls EnterCriticalSection which checks to see whether
the CRITICAL_SECTION data structure has been modified. If so, another thread is currently in the
critical section and the subsequent thread is put to sleep. A thread leaving a critical section calls
LeaveCriticalSection, which resets the data structure. When a thread leaves a critical section, the
system wakes one of the sleeping threads, which then enters the critical section.
Mutexes performs the same function as a critical section, except that the mutex is accessible to threads running
in different processes. Owning a mutex object is like having the floor in a debate. A process creates a mutex
object by calling the CreateMutex function, which returns a handle. The first thread requesting a mutex object
obtains ownership of it. When the thread has finished with the mutex, ownership passes to other threads on a
first-come, first-served basis.
Semaphores are used to maintain a reference count on some available resource. A thread creates a semaphore
for a resource by calling the CreateSemaphore function and passing a pointer to the resource, an initial
resource count, and the maximum resource count. This function returns a handle. A thread requesting a
resource passes its semaphore handle in a call to the WaitForSingleObject function. The semaphore object
polls the resource to determine whether it is available. If so, the semaphore decrements the resource count
and wakes the waiting thread. If the count is zero, the thread remains asleep until another thread releases a
resource, causing the semaphore to increment the count to one.

Related topics
A
c
c
e
s
s
i
n
g
I
n
t
e
r
f
a
c
e
s
A
c
r
o
s
s
A
p
a
r
t
m
e
n
t
s

C
h
o
o
s
i
n
g
t
h
e
T
h
r
e
a
d
i
n
g
M
o
d
e
l

I
n
-
P
r
o
c
e
s
s
S
e
r
v
e
r
T
h
r
e
a
d
i
n
g
I
s
s
u
e
s

P
r
o
c
e
s
s
e
s
,
T
h
r
e
a
d
s
,
a
n
d
A
p
a
r
t
m
e
n
t
s

S
i
n
g
l
e
-
T
h
r
e
a
d
e
d
a
n
d
M
u
l
t
i
t
h
r
e
a
d
e
d
C
o
m
m
u
n
i
c
a
t
i
o
n

S
i
n
g
l
e
-
T
h
r
e
a
d
e
d
A
p
a
r
t
m
e
n
t
s
Single-Threaded and Multithreaded Communication
1/7/2020 • 2 minutes to read • Edit Online

A client or server that supports both single-threaded and multithreaded apartments will have one multithreaded
apartment, containing all threads initialized as free-threaded, and one or more single-threaded apartments.
Interface pointers must be marshaled between apartments but can be used without marshaling within an
apartment. Calls to objects in a single-threaded apartment will be synchronized by COM. Calls to objects in the
multithreaded apartment will not be synchronized by COM.
All of the information on single-threaded apartments applies to the threads marked as apartment model, and all
of the information on multithreaded apartments applies to all of the threads marked as free-threaded. Apartment
threading rules apply to inter-apartment communication, requiring that interface pointers be marshaled between
apartments with calls to CoMarshalInterThreadInterfaceInStream and CoGetInterfaceAndReleaseStream,
as described in Single-Threaded Apartments.

NOTE
Some special considerations apply when dealing with in-process servers. For more information, see In-Process Server
Threading Issues.

Related topics
A
c
c
e
s
s
i
n
g
I
n
t
e
r
f
a
c
e
s
A
c
r
o
s
s
A
p
a
r
t
m
e
n
t
s

C
h
o
o
s
i
n
g
t
h
e
T
h
r
e
a
d
i
n
g
M
o
d
e
l

M
u
l
t
i
t
h
r
e
a
d
e
d
A
p
a
r
t
m
e
n
t
s

I
n
-
P
r
o
c
e
s
s
S
e
r
v
e
r
T
h
r
e
a
d
i
n
g
I
s
s
u
e
s

P
r
o
c
e
s
s
e
s
,
T
h
r
e
a
d
s
,
a
n
d
A
p
a
r
t
m
e
n
t
s

S
i
n
g
l
e
-
T
h
r
e
a
d
e
d
A
p
a
r
t
m
e
n
t
s
In-Process Server Threading Issues
1/7/2020 • 5 minutes to read • Edit Online

An in-process server does not call CoInitialize, CoInitializeEx, or OleInitialize to mark its threading model.
For thread-aware DLL -based or in-process objects, you need to set the threading model in the registry. The
default model when you do not specify a threading model is single-thread-per-process. To specify a model, you
add the ThreadingModel value to the InprocServer32 key in the registry.
DLLs that support instantiation of a class object must implement and export the functions DllGetClassObject
and DllCanUnloadNow. When a client wants an instance of the class the DLL supports, a call to
CoGetClassObject (either directly or through a call to CoCreateInstance) calls DllGetClassObject to get a
pointer to its class object when the object is implemented in a DLL. DllGetClassObject should therefore be
able to give away multiple class objects or a single thread-safe object (essentially just using
InterlockedIncrement/InterlockedDecrement on their internal reference counts).
As its name implies, DllCanUnloadNow is called to determine whether the DLL that implements it is in use,
enabling the caller to safely unload it if it is not. Calls to CoFreeUnusedLibraries from any thread always route
through the main apartment's thread to call DllCanUnloadNow.
Like other servers, in-process servers can be single-threaded, apartment-threaded, or free-threaded. These
servers can be used by any OLE client, regardless of the threading model used by that client.
All combinations of threading model interoperability are allowed between clients and in-process objects.
Interaction between a client and an in-process object that use different threading models is exactly like the
interaction between clients and out-of-process servers. For an in-process server, when the threading model of
the client and in-process server differ, COM must interpose itself between the client and the object.
When an in-process object that supports the single-threaded model is called simultaneously by multiple
threads of a client, COM cannot allow the client threads to directly access the object's interface—the object was
not designed for such access. Instead, COM must ensure that calls are synchronized and are made only by the
client thread that created the object. Therefore, COM creates the object in the client's main apartment and
requires all the other client apartments to access the object by using proxies.
When a free-threaded apartment (multithreaded apartment model) in a client creates an apartment-threaded
in-process server, COM spins up a single-threaded apartment model "host" thread in the client. This host thread
will create the object, and the interface pointer will be marshaled back to the client's free-threaded apartment.
Similarly, when a single-threaded apartment in an apartment-model client creates a free-threaded in-process
server, COM spins up a free-threaded host thread (multithreaded apartment on which the object will be created
and then marshaled back to the client single-threaded apartment).

NOTE
In general, if you design a custom interface on an in-process server, you should also provide the marshaling code for it so
that COM can marshal the interface between client apartments.

COM helps protect access to objects provided by a single-threaded DLL by requiring access from the same
client apartment in which they were created. In addition, all of the DLL entry points (like DllGetClassObject
and DllCanUnloadNow) and global data should always be accessed by the same apartment. COM creates
such objects in the main apartment of the client, giving the main apartment direct access to the object's
pointers. Calls from the other apartments use interthread marshaling to go from the proxy to the stub in the
main apartment and then to the object. This allows COM to synchronize calls to the object. Interthread calls are
slow, so it is recommended that these servers be rewritten to support multiple apartments.
Like a single-threaded in-process server, an object provided by an apartment model DLL must be accessed by
the same client apartment from which it was created. However, objects provided by this server can be created in
multiple apartments of the client, so the server must implement its entry points (like DllGetClassObject and
DllCanUnloadNow) for multithreaded use. For example, if two apartments of a client try to create two
instances of the in-process object simultaneously, DllGetClassObject can be called simultaneously by both
apartments. DllCanUnloadNow must be written so that the DLL does not unload while code is still executing
in the DLL.
If the DLL provides only one instance of the class factory to create all the objects, the class factory
implementation must also be designed for multithreaded use, because it will be accessed by multiple client
apartments. If the DLL creates a new instance of the class factory each time DllGetClassObject is called, the
class factory need not be thread-safe.
Objects created by the class factory need not be thread-safe. Once created by a thread, the object is always
accessed through that thread and all calls to the object are synchronized by COM. The apartment model
apartment of a client that creates this object will get a direct pointer to the object. Client apartments that are
different from the apartment in which the object was created must access the object through proxies. These
proxies are created when the client marshals the interface between its apartments.
When an in-process DLL ThreadingModel value is set to "Both", an object provided by this DLL can be
created and used directly (without a proxy) in single-threaded or multithreaded client apartments. However, it
can be used directly only within the apartment in which it was created. To give the object to any other
apartment, the object must be marshaled. The DLL object must implement its own synchronization and can be
accessed by multiple client apartments at the same time.
To speed performance for free-threaded access to in-process DLL objects, COM provides the
CoCreateFreeThreadedMarshaler function. This function creates a free-threaded marshaling object that can
be aggregated with an in-process server object. When a client apartment in the same process needs access to
an object in another apartment, aggregating the free-threaded marshaler provides the client with a direct
pointer to the server object, rather than to a proxy, when the client marshals the object's interface to a different
apartment. The client does not need to do any synchronization. This works only within the same
process—standard marshaling is used for a reference to the object that is sent to another process.
An object provided by an in-process DLL that supports only free threading is a free-threaded object. It
implements its own synchronization and can be accessed by multiple client threads at the same time. This
server does not marshal interfaces between threads, so this server can be created and used directly (without a
proxy) only by multithreaded apartments in a client. Single-threaded apartments that create it will access it
through a proxy.

Related topics
A
c
c
e
s
s
i
n
g
I
n
t
e
r
f
a
c
e
s
A
c
r
o
s
s
A
p
a
r
t
m
e
n
t
s

C
h
o
o
s
i
n
g
t
h
e
T
h
r
e
a
d
i
n
g
M
o
d
e
l
M
u
l
t
i
t
h
r
e
a
d
e
d
A
p
a
r
t
m
e
n
t
s

P
r
o
c
e
s
s
e
s
,
T
h
r
e
a
d
s
,
a
n
d
A
p
a
r
t
m
e
n
t
s

S
i
n
g
l
e
-
T
h
r
e
a
d
e
d
a
n
d
M
u
l
t
i
t
h
r
e
a
d
e
d
C
o
m
m
u
n
i
c
a
t
i
o
n

S
i
n
g
l
e
-
T
h
r
e
a
d
e
d
A
p
a
r
t
m
e
n
t
s
Accessing Interfaces Across Apartments
1/7/2020 • 2 minutes to read • Edit Online

COM provides a way for any apartment in a process to get access to an interface implemented on an object in
any other apartment in the process. This is done through the IGlobalInterfaceTable interface. This interface has
three methods, which allow you to do the following:
Register an interface as a global (processwide) interface.
Get a pointer to that interface from any other apartment through a cookie.
Revoke the global registration of an interface.
The IGlobalInterfaceTable interface is an efficient way for a process to store an interface pointer in a memory
location that can be accessed from multiple apartments within the process, such as process-wide variables and
agile objects (free-threaded, marshaled objects) containing interface pointers to other objects.
An agile object is unaware of the underlying COM infrastructure in which it runs; in other words, what apartment,
context, and thread it is executing on. The object may be holding on to interfaces that are specific to an apartment
or context. For this reason, calling these interfaces from wherever the agile component is executing might not
always work properly. The global interface table avoids this problem by guaranteeing that a valid proxy (or direct
pointer) to the object is used, based on where the agile object is executing.

NOTE
The global interface table is not portable across process or machine boundaries, so it cannot be used in place of the normal
parameter-passing mechanism.

For information about creating and using a global interface table, see the following topics:
Creating the Global Interface Table
When to Use the Global Interface Table

Related topics
C
h
o
o
s
i
n
g
t
h
e
T
h
r
e
a
d
i
n
g
M
o
d
e
l

M
u
l
t
i
t
h
r
e
a
d
e
d
A
p
a
r
t
m
e
n
t
s

I
n
-
P
r
o
c
e
s
s
S
e
r
v
e
r
T
h
r
e
a
d
i
n
g
I
s
s
u
e
s

P
r
o
c
e
s
s
e
s
,
T
h
r
e
a
d
s
,
a
n
d
A
p
a
r
t
m
e
n
t
s

S
i
n
g
l
e
-
T
h
r
e
a
d
e
d
a
n
d
M
u
l
t
i
t
h
r
e
a
d
e
d
C
o
m
m
u
n
i
c
a
t
i
o
n

S
i
n
g
l
e
-
T
h
r
e
a
d
e
d
A
p
a
r
t
m
e
n
t
s
Creating the Global Interface Table
1/7/2020 • 2 minutes to read • Edit Online

Use the following call to create the global interface table object and get a pointer to IGlobalInterfaceTable:

HRESULT hr;
hr = CoCreateInstance(CLSID_StdGlobalInterfaceTable,
NULL,
CLSCTX_INPROC_SERVER,
IID_IGlobalInterfaceTable,
(void **)&gpGIT);
if (hr != S_OK) {
exit(0); // Handle errors here.
}

NOTE
When creating the global interface table object using the preceding call, it is necessary to link to the library uuid.lib. This will
resolve the external symbols CLSID_StdGlobalInterfaceTable and IID_IGlobalInterfaceTable.

There is a single instance of the global interface table per process, so all calls to this function in a process return the
same instance.
After the call to the CoCreateInstance function, register the interface from the apartment in which it resides with
a call to the RegisterInterfaceInGlobal method. This method supplies a cookie that identifies the interface and its
location. An apartment seeking a pointer to this interface then calls the GetInterfaceFromGlobal method with
this cookie, and the implementation then supplies an interface pointer to the calling apartment. To revoke the
interface's global registration, any apartment can call the RevokeInterfaceFromGlobal method.
A simple example of using IGlobalInterfaceTable would be when you want to pass an interface pointer on an
object in a single-threaded apartment (STA) to a worker thread in another apartment. Rather than having to
marshal it into a stream and pass the stream to the worker thread as a thread parameter, IGlobalInterfaceTable
allows you simply to pass a cookie.
When you register the interface in the global interface table, you get a cookie that you can use instead of passing
the actual pointer (whenever you need to pass the pointer), either to a nonmethod parameter that is going to
another apartment (as a parameter to ThreadProc through CreateThread) or to in-process memory accessible
outside your apartment.
Care is required because using global interfaces places the extra burden on the programmer of managing
problems such as race conditions and mutual exclusion, which are associated with accessing global state from
multiple threads simultaneously.
COM provides a standard implementation of the IGlobalInterfaceTable interface. It is highly recommended that
you use this standard implementation because it provides complete thread-safe functionality.

Related topics
W
h
e
n
t
o
U
s
e
t
h
e
G
l
o
b
a
l
I
n
t
e
r
f
a
c
e
T
a
b
l
e
When to Use the Global Interface Table
1/7/2020 • 2 minutes to read • Edit Online

If you are unmarshaling an interface pointer multiple times between apartments in a process, you might use the
IGlobalInterfaceTable interface. With other techniques, you would have to remarshal each time.

NOTE
If the interface pointer is unmarshaled only once, you may want to use the CoMarshalInterThreadInterfaceInStream
function. It can also be used to pass an interface pointer from one thread to another thread in the same process.

The IGlobalInterfaceTable interface also makes another previously difficult problem simpler for the
programmer. This problem occurs when the following conditions apply:
An in-process agile object aggregates the free-threaded marshaler.
This same agile object also holds (as member variables) interface pointers to other objects that are not agile
and do not aggregate the free-threaded marshaler.
In this situation, if the outer object gets marshaled to another apartment and the application calls on it, and the
object tries to call on any of its member variable interface pointers that are not free-threaded or are proxies to
objects in other apartments, it might get incorrect results or the error RPC_E_WRONG_THREAD. This error
occurs because the inner interface is designed to be callable only from the apartment in which it was first stored in
the member variable.
To solve this problem, the outer object aggregating the free-threaded marshaler should call
IGlobalInterfaceTable::RegisterInterfaceInGlobal on the inner interface and store the resulting cookie in its
member variable, instead of storing the actual interface pointer. When the outer object wants to call on an inner
object's interface pointer, it should call IGlobalInterfaceTable::GetInterfaceFromGlobal, use the returned
interface pointer, and then release it. When the outer object goes away, it should call
IGlobalInterfaceTable::RevokeInterfaceFromGlobal to remove the interface from the global interface table.

Related topics
C
r
e
a
t
i
n
g
t
h
e
G
l
o
b
a
l
I
n
t
e
r
f
a
c
e
T
a
b
l
e
COM Clients and Servers
1/7/2020 • 2 minutes to read • Edit Online

A critical aspect of COM is how clients and servers interact. A COM client is whatever code or object gets a
pointer to a COM server and uses its services by calling the methods of its interfaces. A COM server is any object
that provides services to clients; these services are in the form of COM interface implementations that can be
called by any client that is able to get a pointer to one of the interfaces on the server object.
There are two main types of servers, in-process and out-of-process. In-process servers are implemented in a
dynamic linked library (DLL ), and out-of-process servers are implemented in an executable file (EXE ). Out-of-
process servers can reside either on the local computer or on a remote computer. In addition, COM provides a
mechanism that allows an in-process server (a DLL ) to run in a surrogate EXE process to gain the advantage of
being able to run the process on a remote computer. For more information, see DLL Surrogates.
The COM programming model and constructs have now been extended so that COM clients and servers can
work together across the network, not just within a given computer. This enables existing applications to interact
with new applications and with each other across networks with proper administration, and new applications can
be written to take advantage of networking features.
COM client applications do not need to be aware of how server objects are packaged, whether they are packaged
as in-process objects (in DLLs) or as local or remote objects (in EXEs). Distributed COM further allows objects to
be packaged as service applications, synchronizing COM with the rich administrative and system-integration
capabilities of Windows.

NOTE
Throughout this documentation the acronym COM is used in preference to DCOM. This is because DCOM is not
separate;it is just COM with a longer wire. In cases where what is being described is specifically a remote operation, the
term distributed COM is used.

COM is designed to make it possible to add the support for location transparency that extends across a network.
It allows applications written for single computers to run across a network and provides features that extend
these capabilities and add to the security necessary in a network. (For more information, see Security in COM.)
COM specifies a mechanism by which the class code can be used by many different applications.
For more information, see the following topics:
Getting a Pointer to an Object
Creating an Object Through a Class Object
COM Server Responsibilities
Persistent Object State
Providing Class Information
Inter-Object Communication

Related topics
C
a
l
l
S
y
n
c
h
r
o
n
i
z
a
t
i
o
n

S
e
c
u
r
i
t
y
i
n
C
O
M
Getting a Pointer to an Object
1/7/2020 • 2 minutes to read • Edit Online

Because COM does not have a strict class model, there are four ways that a client can instantiate or get a pointer to
an interface on an object:
Call a COM library function that creates an object of a predetermined type—that is, the function will return a
pointer to only one specific interface for a specific object class.
Call a COM library function that can create an object based on a class identifier (CLSID ) and that returns any
type of interface pointer requested.
Call a method of some interface that creates another object (or connects to an existing one) and returns an
interface pointer on that separate object.
Implement an object with an interface through which other objects pass their interface pointer to the client
directly.
For information on getting pointers to other interfaces on an object after you have the first one, see
QueryInterface: Navigating in an Object.

Creating an Object of a Predetermined Type


There are numerous COM functions, such as CoGetMalloc, that return pointers to specific interface
implementations. (CoGetMalloc retrieves a pointer to the standard COM memory allocator.) Most of these are
helper functions, and most of these functions are described in the reference sections of this documentation, under
the specific area they are related to, such as storage or data transfer.

Creating an Object Based on a CLSID


There are several functions that, given a CLSID, a client can call to create an object instance and get a pointer to it.
All of these functions are based on the function CoGetClassObject, which creates a class object and supplies a
pointer to an interface that allows you to create instances of that class. While there must be information that says
which system the server resides on, there is no need for that information to be contained in the client. The client
needs to know only the CLSID and never the absolute path of the server code. For more information, see Creating
an Object Through a Class Object.

Returning a Pointer to a Separate Object


Among the many interface methods that return a pointer to a separate object are several that create and return a
pointer to an enumerator object, which allows you to determine how many items of a given type an object
maintains. COM defines interfaces for enumerating a wide variety of items, such as strings, important structures,
monikers, and IUnknown interface pointers. The typical way to create an enumerator instance and get a pointer
to its interface is to call a method from another interface. For example, the IDataObject interface defines two
methods, EnumDAdvise and EnumFormatEtc, that return pointers to interfaces on two different enumeration
objects. There are many other examples in COM of methods that return pointers to objects, such as the OLE
compound document interface IOleObject::GetClientSite, which, when called on the embedded or linked object,
returns a pointer to the container object's implementation of IOleClientSite.

Implementing an Object Through Which to Pass an Interface Pointer


Directly to the Client
When two objects, such as an OLE compound document container and server, need bidirectional communication,
each implements an object containing an interface method through which it can pass an interface pointer to the
other object. The implementing object, which is also the client of the created object, can then call the method and
get the pointer that was passed.

Related topics
C
O
M
C
l
i
e
n
t
s
a
n
d
S
e
r
v
e
r
s

C
O
M
S
e
r
v
e
r
R
e
s
p
o
n
s
i
b
i
l
i
t
i
e
s
Creating an Object Through a Class Object
1/7/2020 • 2 minutes to read • Edit Online

With the increasing importance of computer networks, it has become necessary for clients and servers to interact
easily and efficiently, whether they reside on the same machine or across a network. Crucial to this is a client's
ability to launch a server, create an instance of the server's object, and have access to the methods of the interfaces
on the object.
COM provides extensions to this basic COM process that make it virtually seamless across a network. If a client is
able to identify the server through its CLSID, calling a few simple functions permit COM to do all the work of
locating and launching the server and activating the object. Subkeys in the registry allow remote servers to
register their location, so the client does not require that information. For applications that want to take advantage
of networking features, the COM object creation functions allow more flexibility and efficiency.
For more information, see the following topics:
COM Class Objects and CLSIDs
Locating a Remote Object
Instance Creation Helper Functions

Related topics
C
O
M
C
l
i
e
n
t
s
a
n
d
S
e
r
v
e
r
s
COM Class Objects and CLSIDs
1/7/2020 • 3 minutes to read • Edit Online

A COM server is implemented as a COM class. A COM class is an implementation of a group of interfaces in code
executed whenever you interact with a given object. There is an important distinction between a C++ class and a
COM class: In C++, a class is a type, while a COM class is simply a definition of the object and carries no type,
although a C++ programmer might implement it by using a C++ class. COM is designed to allow a class to be
used by different applications, including applications written without knowledge of that particular class's existence.
Therefore, class code for a given type of object exists either in a dynamic linked library (DLL ) or in another
executable application (EXE ).
Each COM class is identified by a CLSID, a unique 128-bit GUID, which the server must register. COM uses this
CLSID, at the request of a client, to associate specific data with the DLL or EXE containing the code that
implements the class, thus creating an instance of the object.
For clients and servers on the same computer, the CLSID of the server is all the client ever needs. On each
computer, COM maintains a database (it makes use of the system registry on Microsoft Windows and Macintosh
platforms) of all the CLSIDs for the servers installed on the system. This is a mapping between each CLSID and
the location of the DLL or EXE that houses the code for that CLSID. COM consults this database whenever a client
wants to create an instance of a COM class and use its services, so the client never needs to know the absolute
location of the code on the computer.
For distributed systems, COM provides registry entries that allow a remote server to register itself for use by a
client. While applications need know only a server's CLSID, because they can rely on the registry to locate the
server, COM allows clients to override registry entries and to specify server locations, to take full advantage of the
network. (See Locating a Remote Object.)
The basic way to create an instance of a class is through a COM class object. This is simply an intermediate object
that supports functions common to creating new instances of a given class. Most class objects used to create
objects from a CLSID support the IClassFactory interface, an interface that includes the important
CreateInstance method. You implement an IClassFactory interface for each class of object that you offer to be
instantiated. (For more information about implementing IClassFactory, see Implementing IClassFactory.)

NOTE
Servers that support some other custom class factory interface are not required to support IClassFactory specifically.
However, calls to activation functions other than CoGetClassObject (such as CoCreateInstanceEx) require that the server
support IClassFactory.

When a client wants to create an instance of the server's object, it uses the desired object's CLSID in a call to
CoGetClassObject. (This call can be either direct or implicit, through one of the object creation helper functions.)
This function locates the code associated with the CLSID, and creates a class object, and supplies a pointer to the
interface requested. (CoGetClassObject takes a riid param that specifies the client's desired interface pointer.)

NOTE
COM has just a few functions upon which many of the others are built. The most important of these is probably
CoGetClassObject, which underlies all of the instance creation functions.
With this pointer, the caller can create an instance of the object and retrieve a pointer to a requested interface on
the object. This is usually an initialization interface, used to activate the object (put it in the running state) so that
the client can do whatever work with the object that it wants to. Using COM's basic functions, the client must also
take care to release all object pointers.
Another mechanism for activating object instances is through the class moniker. Class monikers bind to the class
object of the class for which they are created. For more information, see Class Monikers.
COM provides several helper functions that reduce the work of creating object instances. These are described in
Instance Creation Helper Functions.

Related topics
C
r
e
a
t
i
n
g
a
n
O
b
j
e
c
t
T
h
r
o
u
g
h
a
C
l
a
s
s
O
b
j
e
c
t
Locating a Remote Object
1/7/2020 • 2 minutes to read • Edit Online

With the advent of COM for distributed systems, COM uses the basic model for object creation described in COM
Class Objects and CLSIDs and adds more than one way to locate an object that might reside on another system in
a network, without overburdening the client application.
COM has added registry keys that permit a server to register the name of the machine on which it resides or the
machine where an existing storage is located. Therefore, client applications need know only the CLSID of the
server.
However, for cases where it is desired, COM has replaced a previously reserved parameter of CoGetClassObject
with a COSERVERINFO structure, which allows a client to specify the location of a server. Another important
value in the CoGetClassObject function is the CLSCTX enumeration, which specifies whether the expected object
is to be run in-process, out-of-process local, or out-of-process remote. Taken together, these two values and the
values in the registry determine how and where the object is to be run.

NOTE
Instance creation calls, when they specify a server location, can override a registry setting. The algorithm COM uses for
doing this is described in the reference for the CLSCTX enumeration.

Remote activation depends on the security relationship between client and server. For more information, see
Security in COM.

Related topics
C
O
M
C
l
a
s
s
O
b
j
e
c
t
s
a
n
d
C
L
S
I
D
s

C
r
e
a
t
i
n
g
a
n
O
b
j
e
c
t
T
h
r
o
u
g
h
a
C
l
a
s
s
O
b
j
e
c
t
Instance Creation Helper Functions
1/7/2020 • 2 minutes to read • Edit Online

In previous releases of COM, the primary mechanism used to create an object instance was the
CoCreateInstance function. This function encapsulates the process of creating a class object, using that to create
a new instance and releasing the class object. Another function of this kind is the more specific OleCreate, the
OLE compound document helper that creates a class object and retrieves a pointer to a requested object.
To smooth the process of instance creation on distributed systems, COM has introduced four important new
instance creation mechanisms:
Class monikers and IClassActivator
CoCreateInstanceEx
CoGetInstanceFromFile
CoGetInstanceFromIStorage
A class moniker permits you to identify the class of an object and is typically used with another moniker, like a file
moniker, to indicate the location of the object. This permits you to bind to an object and specify the server that is to
be launched for that object. Class monikers may also be composed to the right of monikers supporting binding to
the IClassActivator interface. For more information, see Class Monikers.
CoCreateInstanceEx extends CoCreateInstance to make it possible to create a single uninitialized object
associated with the given CLSID on a specified remote machine. In addition, rather than requesting a single
interface and obtaining a single pointer to that interface, CoCreateInstanceEx makes it possible to query for
multiple interfaces and (if available) receive pointers to them in a single round-trip, thus permitting fewer round-
trips between machines. This can make remote object interaction much more efficient. To do this, the function uses
an array of MULTI_QI structures.
Creating an object through CoCreateInstanceEx still requires that the object be initialized through a call to one
of the initialization interfaces (such as IPersistStorage::Load). The helper functions CoGetInstanceFromFile
and CoGetInstanceFromIStorage encapsulate both the instance creation power of CoCreateInstanceEx and
the initialization, the former from a file and the latter from a storage.

Related topics
C
r
e
a
t
i
n
g
a
n
O
b
j
e
c
t
T
h
r
o
u
g
h
a
C
l
a
s
s
O
b
j
e
c
t
COM Server Responsibilities
1/7/2020 • 2 minutes to read • Edit Online

One of the most important ways for a client to get a pointer to an object is for the client to ask that a server be
launched and that an instance of the object provided by the server be created and activated. It is the responsibility
of the server to ensure that this happens properly. There are several important parts to this.
The server must implement code for a class object through an implementation of either the IClassFactory or
IClassFactory2 interface.
The server must register its CLSID in the system registry on the machine on which it resides and further, has the
option of publishing its machine location to other systems on a network to allow clients to call it without requiring
the client to know the server's location.
The server is primarily responsible for security; that is, for the most part, the server determines whether it will
provide a pointer to one of its objects to a client.
In-process servers should implement and export certain functions that allow the client process to instantiate
them.
The following topics detail the responsibilities of the COM server:
Implementing IClassFactory
Licensing and IClassFactory2
Registering COM Servers
Out-of-Process Server Implementation Helpers
GUID Creation and Optimizations

Related topics
C
O
M
C
l
i
e
n
t
s
a
n
d
S
e
r
v
e
r
s
Implementing IClassFactory
1/7/2020 • 2 minutes to read • Edit Online

When a client uses a CLSID to request the creation of an object instance, the first step is creation of a class object,
an intermediate object that contains an implementation of the methods of the IClassFactory interface. While
COM provides several instance creation functions, the first step in the implementation of these functions is the
creation of a class object.
As a result, all servers must implement the methods of the IClassFactory interface, which contains two methods:
CreateInstance. This method must create an uninitialized instance of the object and return a pointer to a
requested interface on the object.
LockServer. This method just increments the reference count on the class object to ensure that the server
stays in memory and does not shut down before the client is ready for it to do so.
To enable a server to be responsible for its own licensing, COM defines IClassFactory2, which inherits its
definition from IClassFactory. Thus, a server implementing IClassFactory2 must, by definition, implement the
methods of IClassFactory.
COM also provides helper functions for implementing out-of-process servers. For more information, see Out-of-
Process Server Implementation Helpers.

Related topics
C
O
M
S
e
r
v
e
r
R
e
s
p
o
n
s
i
b
i
l
i
t
i
e
s
L
i
c
e
n
s
i
n
g
a
n
d
I
C
l
a
s
s
F
a
c
t
o
r
y
2
Licensing and IClassFactory2
1/7/2020 • 3 minutes to read • Edit Online

The IClassFactory interface on a class object provides the basic object creation mechanism of COM. Using
IClassFactory, a server can control object creation on a machine basis. The implementation of the
IClassFactory::CreateInstance method can allow or disallow object creation based on the existence of a machine
license. A machine license is a piece of information separate from the application that exists on a machine to
indicate that the software was installed from a valid source, such as the vendor's installation disks. If the machine
license does not exist, the server can disallow object creation. Machine licensing prevents piracy in cases where a
user attempts to copy the software from one machine to another, because the license information is not copied
with the software and the machine that receives the copy is not licensed.
However, in a component software industry, vendors need a finer level of control over licensing. In addition to
machine license control, a vendor needs to allow some clients to create a component object while denying other
clients the same capability. This requires that the client application obtain a license key from the component while
the client application is still under development. The client application uses the license key at run time to create
objects on an unlicensed machine.
For example, if a vendor provides a library of controls to developers, the developer who purchases the library will
have a full machine license, allowing the objects to be created on the development machine. The developer can
then build a client application on the licensed machine incorporating one or more of the controls. When the
resulting client application is run on another machine, the controls used in the client application must be created
on the other machine even if that machine does not possess a machine license for the controls from the original
vendor.
The IClassFactory2 interface provides this level of control. To allow key-based licensing for any given component,
you implement IClassFactory2 on the class factory object for that component. IClassFactory2is derived from
IClassFactory, so by implementing IClassFactory2, the class factory object fulfills the basic COM requirements.
To incorporate a licensed component into your client application, use the following methods in IClassFactory2:
The GetLicInfo method fills a LICINFO structure with information describing the licensing behavior of the
class factory. For example, the class factory can provide license keys for run-time licensing if the
fRunTimeKeyAvail member is TRUE.
The RequestLicKey method provides a license key for the component. A machine license must be available
when the client calls this method.
The CreateInstanceLic method creates an instance of the licensed component if the license key parameter
(BSTRÂ bstrKey) is valid.

NOTE
In its type information, a component uses the attribute licensed to mark the coclass that supports licensing through
IClassFactory2.

First, you need a separate development tool that is also a client of the licensed component. The purpose of this tool
is to obtain the run-time license key and save it in your client application. This tool runs only on a machine that
possesses a machine license for the component. The tool calls the GetLicInfo and RequestLicKey methods to
obtain the run-time license key and then saves the license key in your client application. For example, the
development tool could create a header (.h) file containing the BSTR license key, and then you would include that
.h file in your client application.
To instantiate the component within your client application, first try to instantiate the object directly with
IClassFactory::CreateInstance. If CreateInstance succeeds, the second machine is licensed for the component
and objects can be created at will. If CreateInstancefails with the return code CLASS_E_NOTLICENSED, the only
way to create the object is to pass the run-time key to the CreateInstanceLic method. CreateInstanceLic verifies
the key and creates the object if the key is valid.
In this way, an application built with components (such as controls) can run on a machine that has no other license
—only the client application containing the run-time license is allowed to create the component objects in
question.
The IClassFactory2 interface supports flexibility in licensing schemes. For example, the server implementor can
encrypt license keys in the component for added security. Server implementers can also enable or disable levels of
functionality in their objects by providing different license keys for different functions. For example, one key might
allow a base level of functionality while another allows basic and advanced functionality, and so on.

Related topics
C
O
M
S
e
r
v
e
r
R
e
s
p
o
n
s
i
b
i
l
i
t
i
e
s
Registering COM Servers
1/7/2020 • 2 minutes to read • Edit Online

After you have defined a class in code (ensuring that it implements IClassFactory or IClassFactory2) and
assigned it a CLSID, you need to put information in the registry that will allow COM, on request of a client with
the CLSID, to create instances of its objects. This information tells the system, for a given CLSID, where the DLL
or EXE code for that class is located and how it is to be launched.
There is more than one way of registering a class in the registry. In addition, there are other ways of "registering"
a class with the system when it is running, so that the system is aware that a running object is currently in the
system.
See the following topics for more information about registering:
Registering a Class at Installation
Registering a Running EXE Server
Registering Objects in the ROT
Self-Registration
Installing as a Service Application

Related topics
C
O
M
S
e
r
v
e
r
R
e
s
p
o
n
s
i
b
i
l
i
t
i
e
s
Registering a Class at Installation
1/7/2020 • 2 minutes to read • Edit Online

If a class is intended to be available to clients at any time, as most applications are, you usually register it through
an installation and setup program. This means putting information about the application into the registry,
including how and where its objects are to be instantiated. This information must be registered for all CLSIDs.
Other information is optional. Tools such as Regsvr32 make it simple to write a setup program that registers
servers at installation.
If you are not relying on system defaults, there are two important keys in the registry: the CLSID and the AppID.
Among the important pieces of information under these keys is how the object is to be instantiated. Objects can be
designated as in-process, out-of-process local, or out-of-process remote.
Under the AppID key are several values that define information specific to that application. Among these are
RemoteServerName and ActivateAtStorage, both of which can be used to permit a client to create an object, with
the client having no built-in knowledge of the location of the server. (For more information about remote
instantiation, see Locating a Remote Object and Instance Creation Helper Functions.)
A server can also be installed as a service, or to run under a specific user account. For more information, see
Installing as a Service Application.
A server or ROT object that is not a service or running under a specific user account can be referred to as an
"activate as activator" server. For these servers, the security context and the window station/desktop of the client
must match the server's. A client attempting to connect to a remote server is considered to have a NULL window
station/desktop, so only the server security context is compared in this instance. (For more information about
SIDs, see Security in COM.) COM caches the window station/desktop of a process when the process first connects
to the distributed COM service. Therefore, COM clients and servers should not change their window station or
thread desktops of the process after calling CoInitialize or CoInitializeEx.
When a class is registered as in-process, a call to CoGetClassObject to create its class object is automatically
passed by COM to the DllGetClassObject function, which the class must implement to give the calling object a
pointer to its class object.
Classes implemented in executables can specify that COM should execute their process and wait for the process to
register their class object's IClassFactory interface through a call to the CoRegisterClassObject function.

Related topics
C
O
M
R
e
g
i
s
t
r
y
K
e
y
s

I
n
s
t
a
l
l
i
n
g
a
s
a
S
e
r
v
i
c
e
A
p
p
l
i
c
a
t
i
o
n

R
e
g
i
s
t
e
r
i
n
g
a
R
u
n
n
i
n
g
E
X
E
S
e
r
v
e
r

R
e
g
i
s
t
e
r
i
n
g
C
o
m
p
o
n
e
n
t
s

R
e
g
i
s
t
e
r
i
n
g
O
b
j
e
c
t
s
i
n
t
h
e
R
O
T

S
e
l
f
-
R
e
g
i
s
t
r
a
t
i
o
n
Registering a Running EXE Server
1/7/2020 • 2 minutes to read • Edit Online

When an executable (EXE ) server is launched, it should call CoRegisterClassObject, which registers the CLSID
for the server in what is called the class table (a different table than the running object table). When a server is
registered in the class table, it allows the service control manager (SCM ) to determine that it is not necessary to
launch the class again, because the server is already running. Only if the server is not listed in the class table will
the SCM check the registry for appropriate values and launch the server associated with the given CLSID.
You pass CoRegisterClassObject the CLSID for the class and a pointer to its IUnknown interface. Clients who
subsequently call CoGetClassObject with this CLSID will retrieve a pointer to their requested interface, as long
as security does not forbid it. (See Instance Creation Helper Functions for a description of several instance creation
and activation functions.)
The server for a class object should call CoRevokeClassObject to revoke the class object (remove its registration)
when all of the following are true:
There are no existing instances of the object definition.
There are no locks on the class object.
The application providing services to the class object is not under user control (not visible to the user on the
display).

Related topics
I
n
s
t
a
l
l
i
n
g
a
s
a
S
e
r
v
i
c
e
A
p
p
l
i
c
a
t
i
o
n

R
e
g
i
s
t
e
r
i
n
g
a
C
l
a
s
s
a
t
I
n
s
t
a
l
l
a
t
i
o
n

R
e
g
i
s
t
e
r
i
n
g
O
b
j
e
c
t
s
i
n
t
h
e
R
O
T

S
e
l
f
-
R
e
g
i
s
t
r
a
t
i
o
n
Registering Objects in the ROT
1/7/2020 • 2 minutes to read • Edit Online

Typically, when a client asks a server to create an object instance, the server typically creates a moniker for the
object and registers it in the running object table (ROT) through a call to IRunningObjectTable::Register.
When the server calls CreateFileMoniker to create a file moniker to be registered in the ROT, servers should
pass local file names that are drive-based, not in UNC format. This ensures that the moniker comparison data that
is generated by the ROT register call will match what is used while doing a ROT lookup on the part of a remote
client. This is because when the distributed COM service receives an activation request for a file local to the server
from a remote client, the file is converted to a local-drive-based path.

Related topics
I
n
s
t
a
l
l
i
n
g
a
s
a
S
e
r
v
i
c
e
A
p
p
l
i
c
a
t
i
o
n

R
e
g
i
s
t
e
r
i
n
g
a
C
l
a
s
s
a
t
I
n
s
t
a
l
l
a
t
i
o
n

R
e
g
i
s
t
e
r
i
n
g
a
R
u
n
n
i
n
g
E
X
E
S
e
r
v
e
r

S
e
l
f
-
R
e
g
i
s
t
r
a
t
i
o
n
Self-Registration
1/7/2020 • 2 minutes to read • Edit Online

As component software continues to grow as a market, there will be more and more instances where a user
obtains a new software component as a single DLL or EXE module, such as when downloading a new component
from an on-line service or receiving one from a friend on a floppy disk. In these cases, it is not practical to require
the user to go through a lengthy installation procedure or setup program. Besides the licensing issues, which are
handled through IClassFactory2, an installation procedure typically creates the necessary registry entries for a
component to run properly in the COM and OLE context.
Self-registration is the standard means through which a server module can package its own registry operations,
both registration and unregistration, into the module itself. When used with licensing handled through
IClassFactory2, a server can become an entirely self-contained module with no need for external installation
programs or .reg files.
Any self-registering module, DLL or EXE, should first include an "OleSelfRegister" string in the StringFileInfo
section of its version information resource, as shown here.

VS_VERSION_INFO VERSIONINFO

...

BEGIN
BLOCK "StringFileInfo"
BEGIN
#ifdef UNICODE
BLOCK "040904B0" // Lang=US English, CharSet=Unicode
#else
BLOCK "040904E4" // Lang=US English, CharSet=Windows Multilingual
#endif
BEGIN
...
VALUE "OLESelfRegister", "\0"
END

...

END

...

END

The existence of this data allows any interested party, such as an application that wishes to integrate this new
component, to determine whether the server supports self-registration without having to load the DLL or EXE
first.
If the server is packaged in a DLL module, the DLL must export the functions DllRegisterServer and
DllUnregisterServer. Any application that wishes to instruct the server to register itself (that is, all its CLSIDs
and type library IDs) can obtain a pointer to DllRegisterServer through the GetProcAddress function. Within
DllRegisterServer, the DLL creates all its necessary registry entries, storing the correct path to the DLL for all
InprocServer32 or InprocHandler32 entries.
When an application wishes to remove the component from the system, it should unregister that component by
calling DllUnregisterServer. Within this call, the server removes exactly those entries it previously created in
DllRegisterServer. The server should not blindly remove all entries for its classes because other software may
have stored additional entries, such as a TreatAs key.
If the server is packaged in an EXE module, the application wishing to register the server launches the EXE server
with the command-line argument /RegServer or -RegServer (case-insensitive). If the application wishes to
unregister the server, it launches the EXE with the command-line argument /UnregServer or -UnregServer. The
self-registering EXE detects these command-line arguments and invokes the same operations as a DLL would
within DllRegisterServerand DllUnregisterServer, respectively, registering its module path under
LocalServer32 instead of InprocServer32 or InprocHandler32.
The server must register the full path to the installation location of the DLL or EXE module for their respective
InprocServer32, InprocHandler32, and LocalServer32 keys in the registry. The module path is easily obtained
through the GetModuleFileName function.

Related topics
I
n
s
t
a
l
l
i
n
g
a
s
a
S
e
r
v
i
c
e
A
p
p
l
i
c
a
t
i
o
n

R
e
g
i
s
t
e
r
i
n
g
a
C
l
a
s
s
a
t
I
n
s
t
a
l
l
a
t
i
o
n

R
e
g
i
s
t
e
r
i
n
g
a
R
u
n
n
i
n
g
E
X
E
S
e
r
v
e
r

R
e
g
i
s
t
e
r
i
n
g
O
b
j
e
c
t
s
i
n
t
h
e
R
O
T
Installing as a Service Application
1/7/2020 • 2 minutes to read • Edit Online

In addition to running as a local server executable (EXE ), a COM object may also package itself to run as a service
application when activated by a local or remote client. Services support numerous useful and user
interface–integrated administrative features, including local and remote starting, stopping, pausing, and
restarting, as well as the ability to establish the server to run under a specific user account and window station.
An object written as a service is installed for use by COM by establishing a LocalService value under its AppID
key and performing a standard service installation.
Classes may also be configured to run under a specific user account when activated by a remote client without
being written as a service application. To do this, the class installs a user name and a password to be used when
the SCM launches its local server process.
When a class is configured in this fashion, calls to CoRegisterClassObject with this CLSID will fail unless the
process was launched by COM on behalf of an actual activation request. In other words, classes configured to run
as a particular user may not be registered under any other identity.
The user name is taken from the RunAs named-value under the class's APPID key. If the user name is "Interactive
User", the class code is run in the security context of the currently logged on user and is connected to the
interactive window station.
Otherwise, the password is retrieved from a hidden portion of the registry available only to administrators of the
machine and to the system. The user name and password are then used to create a logon session in which the
class code is run. When launched in this way, the class code runs with its own desktop and window -station and
does not share window handles, the clipboard, or other user interface elements with the interactive user or other
classes running in other user accounts.
A server registered either with LocalService or RunAs can register an object in the running object table to allow
any client to connect to it. To do so, the server's call to IRunningObjectTable::Register must set the
ROTFLAGS_ALLOWANYCLIENT flag. A server setting this bit must have its executable name in the AppID
section of the registry that refers to the AppID for the executable. An "activate as activator" server (not registered
as either LocalService or RunAs) may not register an object with this flag.

Related topics
R
e
g
i
s
t
e
r
i
n
g
a
C
l
a
s
s
a
t
I
n
s
t
a
l
l
a
t
i
o
n

R
e
g
i
s
t
e
r
i
n
g
a
R
u
n
n
i
n
g
E
X
E
S
e
r
v
e
r

R
e
g
i
s
t
e
r
i
n
g
O
b
j
e
c
t
s
i
n
t
h
e
R
O
T

S
e
l
f
-
R
e
g
i
s
t
r
a
t
i
o
n
Out-of-Process Server Implementation Helpers
1/7/2020 • 5 minutes to read • Edit Online

Four helper functions that can be called by out-of-process servers are available to simplify the job of writing
server code. COM clients and COM in-process servers typically would not call them. These functions are designed
to help prevent race conditions in server activation when the servers have multiple apartments or multiple class
objects. They can also, however, as easily be used for single-threaded and single class object servers. The functions
are as follows:
CoAddRefServerProcess
CoReleaseServerProcess
CoSuspendClassObjects
CoResumeClassObjects
To shut down properly, a COM server must keep track of how many object instances it has instantiated and how
many times its IClassFactory::LockServer method has been called. Only when both of these counts reach zero
can a server shut down. In single-threaded COM servers, the decision to shut down was coordinated with
incoming activation requests, which were serialized by the message queue. The server, upon receiving a release on
its final object instance and deciding to shut down, would revoke its class objects before any more activation
requests were dispatched. If an activation request did come in after this point, COM would recognize that the class
objects were revoked and would return an error to the Service Control Manager (SCM ), which would then cause a
new instance of the local server process to be run.
However, in an apartment model server, in which different class objects are registered on different apartments,
and in all free-threaded servers, this decision to shut down must be coordinated with activation requests across
multiple threads so that one thread of the server does not decide to shut down while another thread of the server
is busy handing out class objects or object instances. One classical but cumbersome approach to solving this is to
have the server, after it has revoked its class objects, recheck its instance count and stay alive until all instances
have been released.
To make it easier for server writers to handle these types of race conditions, COM provides two reference counting
functions:
CoAddRefServerProcess increments a global per-process reference count.
CoReleaseServerProcess decrements the global per-process reference count.
When the global per-process reference count reaches zero, COM automatically calls CoSuspendClassObjects,
which prevents any new activation requests from coming in. The server can then deregister its various class
objects from its various threads at leisure without worry that another activation request may come in. All new
activation requests are henceforth handled by the SCM launching a new instance of the local server process.
The simplest way for a local server application to make use of these functions is to call CoAddRefServerProcess
in the constructor for each of its instance objects and in each of its IClassFactory::LockServer methods when the
fLock parameter is TRUE. The server application should also call CoReleaseServerProcess in the destructor of
each of its instance objects and in each of its IClassFactory::LockServer methods when the fLock parameter is
FALSE.
Finally, the server application should pay attention to the return code from CoReleaseServerProcess, and if it
returns 0, the server application should initiate its cleanup, which, for a server with multiple threads, typically
means that it should signal its various threads to exit their message loops and call CoAddRefServerProcess and
CoReleaseServerProcess. If the server process lifetime management functions are used, they must be used in
both the object instances and the LockServer method; otherwise, the server application may be shut down
prematurely.
When a CoGetClassObject request is made, COM contacts the server, marshals the IClassFactory interface of
the class object, returns to the client process, unmarshals the IClassFactory interface, and returns this to the
client. At this point, clients typically call LockServer with TRUE to prevent the server process from shutting down.
However, there is a window of time between when the class object is marshaled and when the client calls
LockServer in which another client could connect to the same server, get an instance, and release that instance,
thus causing the server to shut down and leaving the first client high and dry with a disconnected IClassFactory
pointer. To prevent this race condition, COM adds an implicit call to LockServer with TRUE to the class object
when it marshals the IClassFactory interface and an implicit call to LockServer with FALSE when the client
releases the IClassFactory interface. Therefore, it is not necessary to remote LockServer calls back to the server,
and the proxy for LockServer simply returns S_OK without actually remoting the call.
There is another activation-related race condition during initialization of an out-of-process server process. A COM
server that registers multiple classes typically calls CoRegisterClassObject with REGCLS_LOCAL_SERVER for
each CLSID it supports. After it has done this for all classes, the server enters its message loop. For a single-
threaded COM server, all activation requests are blocked until the server enters the message loop. However, for an
apartment model server that registers different class objects in different apartments and for all free-threaded
servers, activation requests can arrive earlier than this. In the case of apartment model servers, activation requests
could arrive as soon as any one thread has entered its message loop. In the case of free-threaded servers, an
activation request could arrive as soon as the first class object is registered. Since an activation can happen this
early, it is also possible for the final release to occur (and therefore cause the server to begin shutting down)
before the rest of the server has had a chance to finish initializing.
To eliminate these race conditions and simplify the job of the server writer, any server that wants to register
multiple class objects with COM should call CoRegisterClassObject with REGCLS_LOCAL_SERVER |
REGCLS_SUSPENDED for each different CLSID the server supports. After all classes have been registered and
the server process is ready to accept incoming activation requests, the server should make one call to
CoResumeClassObjects. This function tells COM to inform the SCM about all the registered classes, and it
begins letting activation requests into the server process. Using these functions provides the following
advantages:
Only one call is made to the SCM, regardless of how many CLSIDs are registered, thus reducing the overall
registration time (and hence startup time of the server application).
If the server has multiple apartments and different CLSIDs are registered in different apartments, or if the
server is a free-threaded server, no activation requests will come in until the server calls
CoResumeClassObjects, giving the server a chance to register all of its CLSIDs and get properly set up
before having to deal with activation requests and possible shut down requests.

Related topics
C
O
M
S
e
r
v
e
r
R
e
s
p
o
n
s
i
b
i
l
i
t
i
e
s
GUID Creation and Optimizations
1/7/2020 • 2 minutes to read • Edit Online

Because a CLSID, like an interface identifier (IID ), is a GUID, no other class, no matter who writes it, has a duplicate
CLSID. Server implementers generally obtain CLSIDs through the CoCreateGuid function. This function is
guaranteed to produce unique CLSIDs, so server implementers across the world can independently develop and
deploy their software without fear of accidental collision with software written by others.
Using unique CLSIDs avoids the possibility of name collisions among classes because CLSIDs are in no way
connected to the names used in the underlying implementation. For example, two different vendors can write
classes called "StackClass," but each would have a unique CLSID and therefore could not be confused.
COM frequently must map GUIDs (IIDs and CLSIDs) to some arbitrarily large set of other values. As an
application developer, you can help speed up such searches, and thereby enhance system performance, by
generating the GUIDs for your application as a block of consecutive values.
The most efficient way to generate a block of consecutive GUIDs is to run the uuidgen utility using the -n and -x
switches, which generates a block of UUIDs, each of whose first DWORD value is incremented by one.
For example, if you were to type
uuidgen -n5 -x
the uuidgen utility would generate a block of UUIDs similar to the following:

12340001-4980-1920-6788-123456789012
12340002-4980-1920-6788-123456789012
12340003-4980-1920-6788-123456789012
12340004-4980-1920-6788-123456789012
12340005-4980-1920-6788-123456789012

One method for generating and tracking GUIDs for an entire project begins with generating a block of some
arbitrarily large number of UUIDs, say 500. For example, if you were to type
uuidgen -n500 -x > guids.txt
the utility would generate 500 consecutive UUIDs and write them to the specified text file. You could then check
this file into your source tree, providing a single repository for all GUIDs to be used in a project. As people require
GUIDs for their portions of the project, they can check out the file, take however many GUIDs they need, marking
them as taken and leaving a note about where in the code or "spec" they are using them.
In addition to improving system performance, generating blocks of consecutive GUIDs in this way has the
following benefits:
A central file containing all GUIDs for an application makes it easy to keep track of which GUIDs are for what
and which people are using them.
A block of consecutive GUIDs associated with a particular application helps developers and testers recognize
internal GUIDs during debugging and makes it easier to find them in the system registry because they are
stored sequentially.

Related topics
C
O
M
S
e
r
v
e
r
R
e
s
p
o
n
s
i
b
i
l
i
t
i
e
s
Persistent Object State
1/7/2020 • 2 minutes to read • Edit Online

Some COM objects can save their internal state when asked to do so by a client.
COM defines standards through which clients can request objects to be initialized, loaded, and saved to and from a
data store (for example, flat file, structured storage, or memory). It is the client's responsibility to manage the
location where the object's persistent data is stored but not the format of the data. COM objects that adhere to
these standards are called persistent objects.
For more information, see the following topics:
Persistent Object Interfaces
Initializing Persistent Objects

Related topics
C
O
M
C
l
i
e
n
t
s
a
n
d
S
e
r
v
e
r
s
Persistent Object Interfaces
1/7/2020 • 2 minutes to read • Edit Online

A persistent object implements one or more persistent object interfaces. Clients use persistent object interfaces to
tell those objects when and where to store their state. All persistent object interfaces are derived from IPersist, so
any object that implements any persistent object interface also implements IPersist.
The following persistent object interfaces are currently defined:
IPersistStream
IPersistStreamInit
IPersistStorage
IPersistFile
IPersistMoniker
IPersistMemory
IPersistPropertyBag
Implementers choose which persistent object interfaces an object supports depending on how the object is to be
used. By not supporting any persistent object interfaces, the implementer is effectively saying, "This object's state
cannot be persistently stored." By supporting one or more persistent object interfaces, the implementer is
effectively saying, "This object's state can be persistently stored in one or more data store mediums."
For example, the following table lists several object types that allow support for different persistent object
interfaces.

CATEGORY PERSISTENT OBJECT INTERFACES TYPICALLY SUPPORTED

Monikers IPersistStream

OLE embeddable objects IPersistStorage, IPersistFile

ActiveX controls IPersistStreamInit, IPersistStorage, IPersistMemory,


IPersistPropertyBag, IPersistMoniker

ActiveX document objects IPersistStorage, IPersistFile

Client implementers can also choose which persistent object interfaces the client can use. The interfaces a client
uses is usually determined by where the client can store its own data. A client that can store its data only in a flat
file will probably use only IPersistStreamInit, IPersistMoniker, and IPersistPropertyBag. (IPersistStreamInit
can replace IPersistStream in most applications, because it contains that definition and adds an initialization
method.) A client that can save its data to a structured storage file will, in addition, use IPersistStorage.

Related topics
I
n
i
t
i
a
l
i
z
i
n
g
P
e
r
s
i
s
t
e
n
t
O
b
j
e
c
t
s
Initializing Persistent Objects
1/7/2020 • 2 minutes to read • Edit Online

Several of the persistent object interfaces, IPersistStreamInit, IPersistStorage, IPersistMemory, and


IPersistPropertyBag, allow clients to initialize objects to a "fresh" or "default" state. This initial state is different
from that of a newly created object, which has no state.
Initializing an object's state, even to the default state, may be a compute-intensive or resource-intensive operation.
By separating creation from initialization, the initialization can be performed only when it is actually needed and
clients can avoid initializing objects to the default state only to immediately load previously stored data.

Related topics
P
e
r
s
i
s
t
e
n
t
O
b
j
e
c
t
I
n
t
e
r
f
a
c
e
s
Providing Class Information
1/7/2020 • 2 minutes to read • Edit Online

It is often useful for a client of an object to examine the object's type information. Given the object's CLSID, a client
can locate the object's type library using registry entries and then can scan the type library for the coclass entry in
the library matching the CLSID.
However, not all objects have a CLSID, although they still need to provide type information. In addition, it is
convenient for a client to have a way to simply ask an object for its type information instead of going through all
the tedium to extract the same information from registry entries. This capability is important when dealing with
outgoing interfaces on connectable objects. (See Using IProvideClassInfo for more information on how
connectable objects provide this capability.)
In these cases, a client can query the object for IProvideClassInfo or IProvideClassInfo2. If these interfaces
exist, the client calls the GetClassInfo method to get the type information for the interface.
By implementing IProvideClassInfo or IProvideClassInfo2, an object specifies that it can provide type
information for its entire class; that is, what it would describe in its coclass section of its type library, if it has one.
GetClassInfo returns an ITypeInfo pointer corresponding to the object's coclass information. Through this
ITypeInfo pointer, the client can examine all the object's incoming and outgoing interface definitions.
The object can also provide IProvideClassInfo2. The IProvideClassInfo2 interface is a simple extension to
IProvideClassInfo that makes it quick and easy to retrieve an object's outgoing interface identifiers for its default
event set. IProvideClassInfo2 is derived from IProvideClassInfo.

Related topics
C
O
M
C
l
i
e
n
t
s
a
n
d
S
e
r
v
e
r
s
Inter-Object Communication
1/7/2020 • 5 minutes to read • Edit Online

COM is designed to allow clients to communicate transparently with objects, regardless of where those objects
are running—in the same process, on the same computer, or on a different computer. This provides a single
programming model for all types of objects, and for both object clients and object servers.
From a client's point of view, all objects are accessed through interface pointers. A pointer must be in-process. In
fact, any call to an interface function always reaches some piece of in-process code first. If the object is in-process,
the call reaches it directly, with no intervening system-infrastructure code. If the object is out-of-process, the call
first reaches what is called a "proxy" object provided either by COM or by the object (if the implementor wishes).
The proxy packages call parameters (including any interface pointers) and generate the appropriate remote
procedure call (or other communication mechanism in the case of custom generated proxies) to the other process
or the other computer where the object implementation is located. This process of packaging pointers for
transmission across process boundaries is called marshaling.
From a server's point of view, all calls to an object's interface functions are made through a pointer to that
interface. Again, a pointer has context only in a single process, and the caller must always be some piece of in-
process code. If the object is in-process, the caller is the client itself. Otherwise, the caller is a "stub" object
provided either by COM or by the object itself. The stub receives the remote procedure call (or other
communication mechanism in the case of custom generated proxies) from the "proxy" in the client process,
unmarshals the parameters, and calls the appropriate interface on the server object. From the points of view of
both clients and servers, they always communicate directly with some other in-process code.
COM provides an implementation of marshaling, referred to as standard marshaling. This implementation works
very well for most objects and greatly reduces programming requirements, making the marshaling process
effectively transparent.
The clear separation of interface from implementation of COM's process transparency can, however, get in the
way in some situations. The design of an interface that focuses on its function from the client's point of view can
sometimes lead to design decisions that conflict with efficient implementation of that interface across a network.
In cases like this, what is needed is not pure process transparency but "process transparency, unless you need to
care." COM provides this capability by allowing an object implementor to support custom marshaling (also called
IMarshal marshaling). Standard marshaling is, in fact, an instance of custom marshaling; it is the default
implementation used when an object does not require custom marshaling.
You can implement custom marshaling to allow an object to take different actions when used from across a
network than it takes under local access—and it is completely transparent to the client. This architecture makes it
possible to design client/object interfaces without regard to network performance issues and then later to address
network performance issues without disrupting the established design.
COM does not specify how components are structured; it specifies how they interact. COM leaves the concern
about the internal structure of a component to programming languages and development environments.
Conversely, programming environments have no set standards for working with objects outside of the immediate
application. Microsoft Visual C++, for example, works extremely well for manipulating objects inside an
application but has no support for working with objects outside the application. Generally, all other programming
languages are the same in this regard. Therefore, to provide networkwide interoperability, COM, through
language-independent interfaces, picks up where programming languages leave off.
The double indirection of the vtbl structure means that the pointers in the table of function pointers do not need
to point directly to the real implementation in the real object. This is the heart of process transparency.
For in-process servers, where the object is loaded directly into the client process, the function pointers in the table
point directly to the actual implementation. In this case, a function call from the client to an interface method
directly transfers execution control to the method. However, this cannot work for local, let alone remote, objects
because pointers to memory cannot be shared between processes. Nevertheless, the client must be able to call
interface methods as if it were calling the actual implementation. Thus, the client uniformly transfers control to a
method in some object by making the call.
A client always calls interface methods in some in-process object. If the actual object is local or remote, the call is
made to a proxy object, which then makes a remote procedure call to the actual object.
So what method is actually executed? The answer is that whenever there is a call to an out-of-process interface,
each interface method is implemented by a proxy object. The proxy object is always an in-process object that acts
on behalf of the object being called. This proxy object knows that the actual object is running in a local or remote
server.
The proxy object packages up the function parameters in some data packets and generates an RPC call to the
local or remote object. That packet is picked up by a stub object in the server's process on the local or a remote
computer, which unpacks the parameters and makes the call to the real implementation of the method. When that
function returns, the stub packages up any out-parameters and the return value and sends it back to the proxy,
which unpacks them and returns them to the original client.
Thus, client and server always talk to each other as if everything was in-process. All calls from the client and all
calls to the server are, at some point, in-process. But because the vtbl structure allows some agent, like COM, to
intercept all function calls and all returns from functions, that agent can redirect those calls to an RPC call as
necessary. Although in-process calls are faster than out-of-process calls, the process differences are completely
transparent to the client and server.
For more information, see the following topics:
Marshaling Details
Proxy
Stub
Channel
Microsoft RPC

Related topics
C
O
M
C
l
i
e
n
t
s
a
n
d
S
e
r
v
e
r
s

I
n
t
e
r
f
a
c
e
M
a
r
s
h
a
l
i
n
g
Marshaling Details
1/7/2020 • 4 minutes to read • Edit Online

If you use standard marshaling, COM handles all of the details described here for you. However, there are those
few programmers who need these details and for those interested in the underlying information. Marshaling is the
process of packaging and unpackaging parameters so a remote procedure call can take place.
Different parameter types are marshaled in different ways. For example, marshaling an integer parameter involves
simply copying the value into the message buffer. (Although even in this simple case, there are issues such as byte
ordering to deal with in cross-computer calls.) Marshaling an array, however, is a more complex process. Array
members are copied in a specific order so that the other side can reconstruct the array exactly. When a pointer is
marshaled, the data that the pointer is pointing to is copied following rules and conventions for dealing with
nested pointers in structures. Unique functions exist to handle the marshaling of each parameter type.
With standard marshaling, the proxies and stubs are systemwide resources for the interface and they interact with
the channel through a standard protocol. Standard marshaling can be used both by standard COM -defined
interfaces and by custom interfaces, as follows:
In the case of most COM interfaces, the proxies and stubs for standard marshaling are in-process component
objects which are loaded from a systemwide DLL provided by COM in Ole32.dll.
In the case of custom interfaces, the proxies and stubs for standard marshaling are generated by the interface
designer, typically with MIDL. These proxies and stubs are statically configured in the registry, so any potential
client can use the custom interface across process boundaries. These proxies and stubs are loaded from a DLL
that is located via the system registry, using the interface ID (IID ) for the custom interface they marshal.
An alternative to using MIDL to generate proxies and stubs for custom interfaces, a type library can be
generated instead and the system provided, type-library–driven marshaling engine will marshal the interface.
As an alternative to standard marshaling, an interface (standard or custom) can use custom marshaling. With
custom marshaling, an object dynamically implements the proxies at run time for each interface that it supports.
For any given interface, the object can select COM -provided standard marshaling or custom marshaling. This
choice is made by the object on an interface-by-interface basis. Once the choice is made for a given interface, it
remains in effect during the object's lifetime. However, one interface on an object can use custom marshaling
while another uses standard marshaling.
Custom marshaling is inherently unique to the object that implements it. It uses proxies implemented by the
object and provided to the system on request at run time. Objects that implement custom marshaling must
implement the IMarshal interface, whereas objects that support standard marshaling do not.
If you decide to write a custom interface, you must provide marshaling support for it. Typically, you will provide a
standard marshaling DLL for the interface you design. You can create the proxy/stub code and the proxy/stub
DLL, or you can create a type library that COM will use to do data-driven marshaling (using the data in the type
library).
For a client to make a call to an interface method in an object in another process involves the cooperation of
several components. The standard proxy is a piece of interface-specific code that resides in the client's process
space and prepares the interface parameters for transmittal. It packages, or marshals, them in such a way that they
can be re-created and understood in the receiving process. The standard stub, also a piece of interface-specific
code, resides in the server's process space and reverses the work of the proxy. The stub unpackages, or
unmarshals, the sent parameters and forwards them to the object application. It also packages reply information
to send back to the client.
NOTE
Readers more familiar with RPC than COM may be used to seeing the terms client stub and server stub. These terms are
analogous to proxy and stub.

Components of Interprocess Communications


The following diagram shows the flow of communication between the components involved. On the client side of
the process boundary, the client's method call goes through the proxy and then onto the channel, which is part of
the COM library. The channel sends the buffer containing the marshaled parameters to the RPC run-time library,
which transmits it across the process boundary. The RPC run time and the COM libraries exist on both sides of the
process. The distinction between the channel and the RPC run time is a characteristic of this implementation and
is not part of the programming model or the conceptual model for COM client/server objects. COM servers see
only the proxy or stub and, indirectly, the channel. Future implementations may use different layers below the
channel or no layers.

Related topics
C
h
a
n
n
e
l

I
n
t
e
r
-
O
b
j
e
c
t
C
o
m
m
u
n
i
c
a
t
i
o
n

M
i
c
r
o
s
o
f
t
R
P
C

P
r
o
x
y

S
t
u
b
Proxy
1/7/2020 • 2 minutes to read • Edit Online

A proxy resides in the address space of the calling process and acts as a surrogate for the remote object. From the
perspective of the calling object, the proxy is the object. Typically, the proxy's role is to package the interface
parameters for calls to methods in its object interfaces. The proxy packages the parameters into a message buffer
and passes the buffer onto the channel, which handles the transport between processes. The proxy is implemented
as an aggregate, or composite, object. It contains a system-provided, manager piece called the proxy manager and
one or more interface-specific components called interface proxies. The number of interface proxies equals the
number of object interfaces that have been exposed to that particular client. To the client complying with the
component object model, the proxy appears to be the real object.

NOTE
With custom marshaling, the proxy can be implemented similarly or it can communicate directly with the object without
using a stub.

Each interface proxy is a component object that implements the marshaling code for one of the object's interfaces.
The proxy represents the object for which it provides marshaling code. Each proxy also implements the
IRpcProxyBuffer interface. Although the object interface represented by the proxy is public, the
IRpcProxyBuffer implementation is private and is used internally within the proxy. The proxy manager keeps
track of the interface proxies and also contains the public implementation of the controlling IUnknown interface
for the aggregate. Each interface proxy can exist in a separate DLL that is loaded when the interface it supports is
materialized to the client.

Structure of the Proxy


The following diagram shows the structure of a proxy that supports the standard marshaling of parameters
belonging to two interfaces: IA1 and IA2. Each interface proxy implements IRpcProxyBuffer for internal
communication between the aggregate pieces. When the proxy is ready to pass its marshaled parameters across
the process boundary, it calls methods in the IRpcChannelBuffer interface, which is implemented by the channel.
The channel in turn forwards the call to the RPC run-time library so that it can reach its destination in the object.

Related topics
C
h
a
n
n
e
l

I
n
t
e
r
-
O
b
j
e
c
t
C
o
m
m
u
n
i
c
a
t
i
o
n

M
a
r
s
h
a
l
i
n
g
D
e
t
a
i
l
s

M
i
c
r
o
s
o
f
t
R
P
C

S
t
u
b
Stub
1/7/2020 • 2 minutes to read • Edit Online

The stub, like the proxy, is made up of one or more interface pieces and a manager. Each interface stub provides
code to unmarshal the parameters and code that calls one of the object's supported interfaces. Each stub also
provides an interface for internal communication. The stub manager keeps track of the available interface stubs.
There are, however, the following differences between the stub and the proxy:
The most important difference is that the stub represents the client in the object's address space.
The stub is not implemented as an aggregate object because there is no requirement that the client be viewed
as a single unit; each piece in the stub is a separate component.
The interface stubs are private rather than public.
The interface stubs implement IRpcStubBuffer, not IRpcProxyBuffer.
Instead of packaging parameters to be marshaled, the stub unpackages them after they have been marshaled
and then packages the reply.

Structure of the Stub


The following diagram shows the structure of the stub. Each interface stub is connected to an interface on the
object. The channel dispatches incoming messages to the appropriate interface stub. All the components talk to
the channel through IRpcChannelBuffer, the interface that provides access to the RPC run-time library.

Related topics
C
h
a
n
n
e
l

I
n
t
e
r
-
O
b
j
e
c
t
C
o
m
m
u
n
i
c
a
t
i
o
n

M
a
r
s
h
a
l
i
n
g
D
e
t
a
i
l
s

M
i
c
r
o
s
o
f
t
R
P
C

P
r
o
x
y
Channel
1/7/2020 • 2 minutes to read • Edit Online

The channel has the responsibility of transmitting all messages between client and object across the process
boundary. The channel has been designed to work transparently with different channel types, is compatible with
OSF DCE standard RPC, and supports single and multithreaded applications.

Related topics
I
n
t
e
r
-
O
b
j
e
c
t
C
o
m
m
u
n
i
c
a
t
i
o
n

M
a
r
s
h
a
l
i
n
g
D
e
t
a
i
l
s

M
i
c
r
o
s
o
f
t
R
P
C

P
r
o
x
y

S
t
u
b
Microsoft RPC
1/7/2020 • 2 minutes to read • Edit Online

Microsoft RPC is a model for programming in a distributed computing environment. The goal of RPC is to
provide transparent communication so that the client appears to be directly communicating with the server.
Microsoft's implementation of RPC is compatible with the Open Software Foundation (OSF ) Distributed
Computing Environment (DCE ) RPC.
You can configure RPC to use one or more transports, one or more name services, and one or more security
servers. The interfaces to those providers are handled by RPC. Because Microsoft RPC is designed to work with
multiple providers, you can choose the providers that work best for your network. The transport is responsible for
transmitting the data across the network. The name service takes an object name, such as a moniker, and finds its
location on the network. The security server offers applications the option of denying access to specific users
and/or groups. See Interface Design Rules for more detailed information about application security.
In addition to the RPC run-time libraries, Microsoft RPC includes the Interface Definition Language (IDL ) and its
compiler. Although the IDL file is a standard part of RPC, Microsoft has enhanced it to extend its functionality to
support custom COM interfaces. The Microsoft Interface Definition Language (MIDL ) compiler uses the IDL file
that describes your custom interface to generate several files discussed in Building and Registering a Proxy DLL.

Related topics
C
h
a
n
n
e
l

I
n
t
e
r
-
O
b
j
e
c
t
C
o
m
m
u
n
i
c
a
t
i
o
n

M
a
r
s
h
a
l
i
n
g
D
e
t
a
i
l
s

P
r
o
x
y

S
t
u
b
Making and Processing Asynchronous Calls
1/7/2020 • 2 minutes to read • Edit Online

COM objects can support asynchronous calling. When a client makes an asynchronous call, control returns to the
client immediately. While the server processes the call, the client is free to do other work. When the client can no
longer proceed without the results of the call, it can get the results of the call at that time.
For example, a request for a large or complex recordset can be time-consuming. A client can request the recordset
by an asynchronous call and then do other work. When the recordset is available, the client can obtain it quickly
without blocking.
Clients do not make asynchronous calls directly on the server object. Instead, they obtain a call object that
implements an asynchronous version of a synchronous interface on the server object. The asynchronous interface
on the call object has a name of the form AsyncInterfaceName. For example, if a server object implements a
synchronous interface named IMyInterface, there will be a call object that implements an asynchronous interface
named AsyncIMyInterface.

NOTE
Asynchronous support is not available for IDispatch or for interfaces that inherit IDispatch.

Server objects that support asynchronous calls implement the ICallFactory interface. This interface exposes a
single method, CreateCall, which creates an instance of a specified call object. Clients can query for ICallFactory
to determine whether an object supports asynchronous calling.
For each method on a synchronous interface, the corresponding asynchronous interface implements two methods.
These methods attach the prefixes Begin_ and Finish_ to the name of the synchronous method. For example, if an
interface named ISimpleStream has a Read method, the AsyncISimpleStream interface will have a Begin_Read and
a Finish_Read method. To begin an asynchronous call, the client calls the Begin_ method.
When you implement a server object, you do not have to provide a call object for every interface the object
implements. If the server object implements the ICallFactory interface and uses standard marshaling, a
marshaled client can always obtain a proxy call object, even if there is no call object on the server side. This proxy
will marshal the Begin_ method as a synchronous call, the server will process the call synchronously, and the client
can obtain the out parameters by calling the Finish_ method.
Conversely, if a client makes a marshaled synchronous call on an interface for which there is a call object on the
server side, the server will always process the call asynchronously. This behavior will not be apparent to the client,
because the client will receive the same out parameters and the same return value it would have received from the
synchronous method.
In either case, the interaction between client and server is marshaled as if the call were synchronous: The output of
synchronous and asynchronous proxies is indistinguishable, as is the output of the corresponding stubs. This
behavior greatly simplifies the programming model both of clients and of servers. If a server object implements
ICallFactory, a marshaled client does not have to attempt to create a call object that may not be available — to the
client, a call object is always available.
When client and server are in the same apartment, the server object will process whichever call the client makes. If
a call object is not available, the client must explicitly obtain the synchronous interface and make a synchronous
call.
For more information, see the following topics:
Making an Asynchronous Call
Canceling an Asynchronous Call
Canceling Method Calls
Call Synchronization
Making an Asynchronous Call
1/29/2020 • 3 minutes to read • Edit Online

The procedure for making a synchronous call is straightforward: The client obtains an interface pointer on the
server object and calls methods through that pointer. Asynchronous calling involves a call object, so it involves a
few more steps.
For each method on a synchronous interface, the corresponding asynchronous interface implements two methods.
These methods attach the prefixes Begin_ and Finish_ to the name of the synchronous method. For example, if an
interface named ISimpleStream has a Read method, the AsyncISimpleStream interface will have a Begin_Read
and a Finish_Read method. To begin an asynchronous call, the client calls the Begin_ method.
To begin an asynchronous call
1. Query the server object for the ICallFactory interface. If QueryInterface returns E_NOINTERFACE, the
server object does not support asynchronous calling.
2. Call ICallFactory::CreateCall to create a call object corresponding to the interface you want, and then
release the pointer to ICallFactory.
3. If you did not request a pointer to the asynchronous interface from the call to CreateCall, query the call
object for the asynchronous interface.
4. Call the appropriate Begin_ method.
The server object is now processing the asynchronous call, and the client is free to do other work until it needs the
results of the call.
A call object can process only one asynchronous call at a time. If the same or a second client calls a Begin_ method
before a pending asynchronous call is finished, the Begin_ method will return RPC_E_CALL_PENDING.
If the client does not need the results of the Begin_ method, it can release the call object at the end of this
procedure. COM detects this condition and cleans up the call. The Finish_ method is not called, and the client does
not get any out parameters or a return value.
When the server object is ready to return from the Begin_ method, it signals the call object that it is done. When
the client is ready, it checks to see whether the call object has been signaled. If so, the client can complete the
asynchronous call.
The mechanism for this signaling and checking between client and server is the ISynchronize interface on the call
object. The call object normally implements this interface by aggregating a system-supplied synchronization
object. The synchronization object wraps an event handle, which the server signals just before returning from the
Begin_ method by calling ISynchronize::Signal.
To complete an asynchronous call
1. Query the call object for the ISynchronize interface.
2. Call ISynchronize::Wait.
3. If Wait returns RPC_E_TIMEOUT, the Begin_ method is not finished processing. The client can continue
with other work and call Wait again later. It cannot call the Finish_ method until Wait returns S_OK.
If Wait returns S_OK, the Begin_ method has returned. Call the appropriate Finish_ method.
The Finish_ method passes the client any out parameters. The behavior of the asynchronous methods, including
the return value of the Finish_ method, should match exactly that of the corresponding synchronous method.
The client can release the call object as soon as the Finish_ method returns, or it can hold a pointer to the call
object to make additional calls. In either case, the client is responsible for releasing the call object when the object
is no longer needed.
If you call a Finish_ method when no call is in progress, the method will return RPC_E_CALL_COMPLETE.

NOTE
If the client and server objects are in the same apartment, calls to ICallFactory::CreateCall are not guaranteed to succeed.
If the server object does not support asynchronous calling on a particular interface, the attempt to create a call object will
fail and the client must use the synchronous interface.

Related topics
C
a
n
c
e
l
i
n
g
a
n
A
s
y
n
c
h
r
o
n
o
u
s
C
a
l
l

C
l
i
e
n
t
S
e
c
u
r
i
t
y
D
u
r
i
n
g
a
n
A
s
y
n
c
h
r
o
n
o
u
s
C
a
l
l

I
m
p
e
r
s
o
n
a
t
i
o
n
a
n
d
A
s
y
n
c
h
r
o
n
o
u
s
C
a
l
l
s
Client Security During an Asynchronous Call
1/7/2020 • 2 minutes to read • Edit Online

The proxy manager created by MIDL for objects that use standard marshaling implements the IClientSecurity
interface. Clients can manage the security of marshaled calls by querying for IClientSecurity on the call object
and obtaining or changing security settings.

Related topics
M
a
k
i
n
g
a
n
A
s
y
n
c
h
r
o
n
o
u
s
C
a
l
l
Impersonation and Asynchronous Calls
1/7/2020 • 2 minutes to read • Edit Online

The server cannot impersonate the client after the server's call to ISynchronize::Signal completes, even if the
Begin_ method has not yet completed. For example, suppose a client calls the Begin_ method, the server processes
the call immediately, and the server calls Signal to indicate it is finished processing. Even if work remains to be
done in the Begin_ method, the server cannot impersonate the client after the call to Signal completes.
If the server impersonates the client before it calls Signal, the impersonation token will not be removed from the
thread until the server calls IServerSecurity::RevertToSelf or until the server's call to Begin_ returns, whichever
comes first.

Related topics
D
e
l
e
g
a
t
i
o
n
a
n
d
I
m
p
e
r
s
o
n
a
t
i
o
n

M
a
k
i
n
g
a
n
A
s
y
n
c
h
r
o
n
o
u
s
C
a
l
l
Canceling an Asynchronous Call
1/29/2020 • 2 minutes to read • Edit Online

A client can cancel an asynchronous call that is in progress if the call object implements the ICancelMethodCalls
interface. For objects that use standard marshaling, ICancelMethodCalls is always available for marshaled calls.
For objects that use custom marshaling or for calls to server objects within the same apartment, this functionality
is available only if the call object implements ICancelMethodCalls.
The client can cancel the call at any time, from when the Begin_ method is called until the Finish_ method returns.
If the client cancels the call before calling the Finish_ method, it must call the Finish_ method to clean up the state
of the call object. Until the client has done so, any calls to any Begin_ method on the call object will return
RPC_E_CALL_PENDING.
To cancel an asynchronous call
1. Query the call object for ICancelMethodCalls.
2. Call ICancelMethodCalls::Cancel, and then call Release to release the pointer obtained by the
QueryInterface call in step 1.
3. If the client has not called the Finish_ method already, call it now.
There is no guarantee that the server actually stopped execution of the call. If the client's further work depends on
some server state that the call may or may not have changed, the client should determine that state before
proceeding.

Related topics
M
a
k
i
n
g
a
n
A
s
y
n
c
h
r
o
n
o
u
s
C
a
l
l
Canceling Method Calls
1/7/2020 • 2 minutes to read • Edit Online

With the introduction of distributed and Web-based applications, some method calls can take an unacceptably long
time to return. The latency of the network connection may be high, the server machine may be serving many
clients, or the server component may be passing a large amount of data, such as a multimedia file. Users should be
able to cancel a request that is taking too long, and the application should be able to handle cancellation requests
and continue with its other work. In COM, you can use the IMessageFilter interface to cancel a pending call that
originates from a single-threaded apartment.
When a call is marshaled, the proxy creates a cancel object, which implements the ICancelMethodCalls interface.
The cancel object is associated with both the call and the thread on which the call is pending.
To cancel the pending call, the client passes a cancellation request through the cancel object, which handles the
details of notifying the server object that the call has been canceled. If the called method has not returned, the
server object, on detecting the cancellation request, cleans up any program resources it has allocated and notifies
its client, by returning an appropriate HRESULT value, that it canceled execution of the call. If the called method
has already returned, the cancel object notifies the client. In either case, the client thread is unblocked and can
continue processing.
How the server object responds to a cancellation request is at the discretion of the server implementer, but the
calling thread on the client will always be unblocked and will ignore whatever results the server tries to pass to it.
Cancel objects provide a means to request that a currently running method be canceled, but there is no guarantee
that the server object will stop processing the call. For example, the call may have already returned, or the server
object may not support cancel objects.
COM automatically provides a standard implementation of cancel objects for client objects and interfaces that use
standard marshaling. For objects and interfaces that use custom marshaling, you will need to implement your own
cancel object.
At this time, cancel objects handle only synchronous calls.

Related topics
C
a
n
c
e
l
i
n
g
a
n
A
s
y
n
c
h
r
o
n
o
u
s
C
a
l
l

C
o
G
e
t
C
a
n
c
e
l
O
b
j
e
c
t

C
o
S
e
t
C
a
n
c
e
l
O
b
j
e
c
t

C
o
T
e
s
t
C
a
n
c
e
l
Call Synchronization
1/7/2020 • 2 minutes to read • Edit Online

COM applications must be able to deal correctly with user input while processing one or more calls from COM or
the operating system. COM provides call synchronization for single-threaded apartments only. Multithreaded
apartments (containing free-threaded threads) do not receive calls while making calls (on the same thread).
Multithreaded apartments cannot make input synchronized calls. Asynchronous calls are converted to
synchronous calls in multithreaded apartments. The message filter is not called for any thread in a multithreaded
apartment. For more information about threading issues, see Processes, Threads, and Apartments.
COM calls between processes fall into three categories, as follows:

S
y
n
c
h
r
o
n
o
u
s
c
a
l
l
s

Most of the communication that takes place within COM is synchronous. When making synchronous calls,
the caller waits for the reply before continuing and can receive incoming messages while waiting. COM
enters a modal loop to wait for the reply, receiving and dispatching other messages in a controlled manner.

A
s
y
n
c
h
r
o
n
o
u
s
n
o
t
i
f
i
c
a
t
i
o
n
s

When sending asynchronous notifications, the caller does not wait for the reply. COM uses PostMessage or
high-level events to send asynchronous notifications, depending on the platform. COM defines five
asynchronous methods of IAdviseSink:
OnDataChange
OnViewChange
OnRename
OnSave
OnClose

NOTE
While COM is processing an asynchronous call, synchronous calls cannot be made. For example, a container
application's implementation of OnDataChange cannot contain a call to IPersistStorage::Save. These calls are the
only asynchronous calls supported by COM. There is no way to create a custom interface that is asynchronous at this
time.

I
n
p
u
t
-
s
y
n
c
h
r
o
n
i
z
e
d
c
a
l
l
s

When making input-synchronized calls, the object called must complete the call before yielding control. This
helps ensure that focus management works correctly and that data entered by the user is processed
appropriately. These calls are made by COM through the SendMessage function, without entering a modal
loop. While processing an input-synchronized call, the object called must not call any function or method
(including synchronous methods) that might yield control. The following methods are input synchronized
IOleWindow::GetWindow
IOleInPlaceActiveObject::OnFrameWindowActivate
IOleInPlaceActiveObject::OnDocWindowActivate
IOleInPlaceActiveObject::ResizeBorder
IOleInPlaceUIWindow::GetBorder
IOleInPlaceUIWindow::RequestBorderSpace
IOleInPlaceUIWindow::SetBorderSpace
IOleInPlaceFrame::SetMenu
IOleInPlaceFrame::SetStatusText
IOleInPlaceObject::SetObjectRects

To minimize problems that can arise from asynchronous message processing, the majority of COM method calls
are synchronous. With synchronous communication, there is no need for special code to dispatch and handle
incoming messages. When an application makes a synchronous method call, COM enters a modal wait loop that
handles the required replies and dispatches incoming messages to applications capable of processing them.
COM manages method calls by assigning an identifier called a logical thread ID. A new one is assigned when a
user selects a menu command or when the application initiates a new COM operation. Subsequent calls that relate
to the initial COM call are assigned the same logical thread ID as the initial call.
Defining COM Interfaces
1/7/2020 • 2 minutes to read • Edit Online

Microsoft defines many COM interfaces. In most cases, you can reuse these generic interfaces. However, some
applications have specific requirements that make it desirable or necessary to define your own object interfaces.
All COM interfaces must derive, directly or indirectly, from the IUnknown interface. Within that constraint, your
custom interface can support almost any method or parameter, including asynchronous methods. You can also
generate a type library for your custom interfaces so that clients can access information about your object's
methods at run time. After you define an interface, describe it in Microsoft Interface Definition Language (MIDL ),
compile and register it, you use it just like any generic interface. With distributed COM, interface methods are
available both to remote processes and to other processes on the same computer.
Finally, building COM interfaces requires a development environment that includes a C/C++ compiler and the
Midl.exe compiler.
The steps in creating a COM interface are as follows:
Decide how you want to provide marshaling support for your interface; either with type-library–driven
marshaling or with a proxy/stub DLL. Even in-process interfaces must be marshaled if they are to be used
across apartment boundaries. It is a good idea to build marshaling support into every COM interface, even if
you don't think you will need it. See Interface Marshaling for more information.
Describe the interface or interfaces in an interface definition (IDL ) file. In addition, you can specify certain local
aspects of your interface in an application configuration file (ACF ). If you are using type-library–driven
marshaling, add a library statement that references the interfaces for which you want to generate type
information.
Use the MIDL compiler to generate a type library file and header file, or C -language proxy/stub files, interface
identifier file, DLL data file and header file. See MIDL Compilation for more information.
Depending on the marshaling method you chose, write a module definition (DEF ) file, compile and link all the
MIDL -generated files into a single proxy DLL, and register the interface in the system registry, or register the
type library. See Loading and Registering a Type Library and Building and Registering a Proxy DLL for more
information.

Related topics
A
n
a
t
o
m
y
o
f
a
n
I
D
L
F
i
l
e

C
O
M
C
l
i
e
n
t
s
a
n
d
S
e
r
v
e
r
s

I
n
t
e
r
f
a
c
e
D
e
s
i
g
n
R
u
l
e
s

T
h
e
C
o
m
p
o
n
e
n
t
O
b
j
e
c
t
M
o
d
e
l
Interface Marshaling
1/7/2020 • 2 minutes to read • Edit Online

Unless you know beyond all doubt that your interface will never be used across apartment, thread, or process
boundaries, you need to decide how to provide marshaling support for your interfaces. There are three ways to
provide marshaling support:
Write your own proxy/stub code that calls the COM channel, which in turn calls the RPC run-time libraries.
Theoretically, it is possible to do this, but in practice it is almost impossible to do without a significant amount
of effort.
Describe your interfaces in an interface definition language (IDL ) file and use the MIDL compiler to generate a
proxy/stub DLL. This method provides the best performance and the most flexibility in terms of acceptable data
types. Using MIDL -generated proxy stubs, you can control not only memory management but even the
marshaling and unmarshaling of complex data types across different platforms.
Use MIDL to generate a type library that the system uses to provide marshaling support at run time. This is the
easiest way to implement marshaling support. All you have to do is generate a type library and register it. Your
interfaces must be Automation-compatible (either oleautomation or dual), which places some restrictions on
the kinds of data types you can use as method parameters. However, in most cases, the advantage of having
your interfaces accessible to programs written in other languages, such as Microsoft Visual Basic and Java,
outweighs the limitations on data types.

Related topics
I
n
t
e
r
-
O
b
j
e
c
t
C
o
m
m
u
n
i
c
a
t
i
o
n
Anatomy of an IDL File
1/7/2020 • 4 minutes to read • Edit Online

These example IDL files demonstrate the fundamental constructs of interface definition. Memory allocation,
custom marshaling, and asynchronous messaging are just a few of the features you can implement in a custom
COM interface. MIDL attributes are used to define COM interfaces. For more information about implementing
interfaces and type libraries, including a summary of MIDL attributes, see Interface Definitions and Type Libraries
in the MIDL Programmer's Guide and Reference. For a complete reference of all MIDL attributes, keywords, and
directives, see the MIDL Language Reference.

Example.idl
The following example IDL file defines two COM interfaces. From this IDL file, Midl.exe will generate proxy/stub
and marshaling code and header files. A line-by-line dissection follows the example.

//
// Example.idl
//
import "mydefs.h","unknwn.idl";
[
object,
uuid(a03d1420-b1ec-11d0-8c3a-00c04fc31d2f),
] interface IFace1 : IUnknown
{
HRESULT MethodA([in] short Bread, [out] BKFST * pBToast);
HRESULT MethodB([in, out] BKFST * pBPoptart);
};

[
object,
uuid(a03d1421-b1ec-11d0-8c3a-00c04fc31d2f),
pointer_default(unique)
] interface IFace2 : IUnknown
{
HRESULT MethodC([in] long Max,
[in, max_is(Max)] BkfstStuff[ ],
[out] long * pSize,
[out, size_is( , *pSize)] BKFST ** ppBKFST);
};

The IDL import statement is used here to bring in a header file, Mydefs.h, which contains user-defined types, and
Unknwn.idl, which contains the definition of IUnknown, from which IFace1 and IFace2 derive.
The object attribute identifies the interface as an object interface and tells the MIDL compiler to generate
proxy/stub code instead of RPC client and server stubs. Object interface methods must have a return type of
HRESULT, to allow the underlying RPC mechanism to report errors for calls that fail to complete due to network
problems.
The uuid attribute specifies the interface identifier (IID ). Each interface, class, and type library must be identified
with its own unique identifier. Use the utility Uuidgen.exe to generate a set of unique IDs for your interfaces and
other components.
The interface keyword defines the interface name. All object interfaces must derive, directly or indirectly, from
IUnknown.
The in directional parameter specifies a parameter that is set only by the caller. The out parameter specifies data
that is passed back to the caller. Using both directional attributes on one parameter specifies that the parameter is
used both to send data to the method and to pass data back to the caller.
The pointer_default attribute specifies the default pointer type (unique, ref, or ptr) for all pointers except for
those included in parameter lists. If no default type is specified, MIDL assumes that single pointers are unique.
However, when you have multiple levels of pointers, you must explicitly specify a default pointer type, even if you
want the default type to be unique.
In the preceding example, the array BkfstStuff[ ] is a conformant array, the size of which is determined at run time.
The max_is attribute specifies the variable that contains the maximum value for the array index.
The size_is attribute is also used to specify the size of an array or, as in the preceding example, multiple levels of
pointers. In the example, the call can be made without knowing in advance how much data will be returned.

Example2.idl
The following IDL example (which reuses the interfaces described in the previous IDL example) shows the various
ways to generate type library information for interfaces.
//
// Example2.idl
//

import "example.idl","oaidl.idl";

[
uuid(a03d1422-b1ec-11d0-8c3a-00c04fc31d2f),
helpstring("IFace3 interface"),
pointer_default(unique);
dual,
oleautomation
]
interface IFace3 : IDispatch
{
HRESULT MethodD([in] BSTR OrderIn,
[out, retval] * pTakeOut);
}; //end IFace3 def

[
uuid(a03d1423-b1ec-11d0-8c3a-00c04fc31d2f),
version(1.0),
helpstring("Example Type Library"),
] library ExampleLib
{
importlib("stdole32.tlb");
interface IFace3;
[
uuid(a03d1424-b1ec-11d0-8c3a-00c04fc31d2f),
helpstring("Breakfast Component Class")
] coclass BkfstComponent
{
[default]interface IFace1;
interfaceIFace2
}; //end coclass def

[
uuid(a03d1424-b1ec-11d0-8c3a-00c04fc31d2f),
helpstring("IFace4 interface"),
pointer_default(unique);
dual,
oleautomation
]
interface IFace4 : IDispatch
{
[propput] HRESULT MethodD([in] BSTR OrderIn);
[propget] HRESULT MethodE([out, retval] * pTakeOut);
}; //end IFace4 def

}; //end library def

The helpstring attribute is optional; you use it to briefly describe the object or to provide a status line. These help
strings are readable with an object browser such as the one provided with Microsoft Visual Basic.
The dual attribute on IFace3 creates an interface that is both a dispatch interface and a COM interface. Because it
is derived from IDispatch, a dual interface supports Automation, which is what the oleautomation attribute
specifies. IFace3 imports Oaidl.idl to get the definition of IDispatch.
The library statement defines the ExampleLib type library, which has its own uuid, helpstring, and version
attributes.
Within the type library definition, the importlib directive brings in a compiled type library. All type library
definitions should bring in the base type library defined in Stdole32.tlb.
This type library definition demonstrates three different ways to include interfaces in the type library. IFace3 is
included merely by referencing it within the library statement.
The coclass statement defines an entirely new component class, BkfstComponent, that includes two previously
defined interfaces, IFace1 and IFace2. The default attribute designates IFace1 as the default interface.
IFace4 is described within the library statement. The propput attribute on MethodD indicates that the method
performs a set action on a property of the same name. The propget attribute indicates that the method retrieves
information from a property of the same name as the method. The retval attribute in MethodD designates an
output parameter that contains the return value of the function.
MIDL Compilation
1/7/2020 • 2 minutes to read • Edit Online

Given an IDL file, such as Example2.idl, that defines one or more COM interfaces and a type library, the MIDL
compiler (Midl.exe) generates the files described in the following table as the default output.

FILENAME DESCRIPTION

Example2.h The header file, containing type definitions and function


declarations for all of the interfaces defined in the IDL file as
well as forward declarations for routines that the stubs call.

Example2_p.c The proxy/stub file, which includes the surrogate entry points
both for clients and for servers.

Example2_i.c The interface ID file, which defines the GUID for every
interface specified in the IDL file.

Example2.tlb A compound document file that contains information about


types and objects.

Dlldata.c Contains the data you need to create a proxy/stub DLL.

You use the header file and all of the .c files to create a proxy DLL that can support the interface when used both by
client applications and by object servers. You use the interface header file (Example2.h) and the interface ID
(Example2_i.c) file when creating the executable file for a client application that uses the interface. You can choose
to include the type library file as a resource in your EXE or DLL, or you can ship it as a separate file.

Related topics
F
i
l
e
s
G
e
n
e
r
a
t
e
d
f
o
r
a
C
O
M
I
n
t
e
r
f
a
c
e

M
I
D
L
C
o
m
p
i
l
e
r
O
p
t
i
o
n
s
MIDL Compiler Options
1/7/2020 • 2 minutes to read • Edit Online

You can use the following command-line options to override some of the default behavior of the MIDL compiler
and to choose optimizations appropriate for your application. For a complete listing of MIDL command-line
options, see the MIDL Command-Line Reference.

COMMAND LINE SWITCH DESCRIPTION

/acf Use to supply an explicit ACF filename. This switch also


enables the use of different interface names in the IDL and
ACF files.

/dlldata Specifies a filename for the generated DLL data file for a proxy
DLL. The default filename is Dlldata.c.

/env Directs MIDL to generate stubs or a type library for a target


environment.

/header, /h Specifies the name of the interface header file. The default
name is that of the IDL file with an .h extension.

/iid Specifies an interface identifier filename that overrides the


default interface identifier filename for a COM interface.

/lcid Provides full DBCS support so that you can use international
characters in your input files, filenames, and directory paths.

/no_format_opt By default, to reduce code size, MIDL eliminates duplicate


descriptors. This switch turns off this optimizing behavior.

/Oi, /Oic, /Oif Directs MIDL to use a fully interpreted marshaling method.
The /Oic and /Oicf switches provide additional performance
enhancements.

/out Specifies the directory to which the MIDL compiler writes


output files. The output directory can be specified with a drive
letter, an absolute pathname, or both. The default is that
MIDL writes the files to the current directory.

/proxy Specifies the name of the interface proxy file for a COM
interface. The default name is that of the IDL file plus "_p.c".

/tlb Specifies the name of the type library file. The default name is
that of the IDL file, with a .tlb extension.

Related topics
M
I
D
L
C
o
m
p
i
l
a
t
i
o
n
Loading and Registering a Type Library
1/7/2020 • 2 minutes to read • Edit Online

The Automation dynamic link library, Oleaut32.dll, provides several functions that you can call to load and register
a type library. Calling LoadTypeLibEx, as shown in the following example, both loads the library and creates the
registry entries.

Example
ITypeLib *pTypeLib;
HRESULT hr;
hr = LoadTypeLibEx("example.tlb", REGKIND_REGISTER, &pTypeLib);
if(SUCCEEDED(hr))
{
pTypeLib->Release();
} else {
exit(0); // Handle errors here.
}
Building and Registering a Proxy DLL
1/7/2020 • 2 minutes to read • Edit Online

If you chose proxy/stub marshaling for your application, the .c and .h files that MIDL generated must be compiled
and linked to create a proxy DLL, and that DLL must be entered into the system registry so that clients can locate
your interfaces. The MIDL -generated file Dlldata.c contains the necessary routines and other information to build
and register a proxy/stub DLL.
The first step in building the DLL is to write a module definition file for the linker, as shown in the following
example:

LIBRARY example.dll
DESCRIPTION 'generic proxy/stub DLL'
EXPORTS DllGetClassObject @1 PRIVATE
DllCanUnloadNow @2 PRIVATE
DllRegisterServer @4 PRIVATE
DllUnregisterServer @5 PRIVATE

Alternatively, you can specify these exported functions on the LINK command line of your makefile.
The exported functions are declared in Rpcproxy.h, which Dlldata.c includes, and default implementations are part
of the RPC run-time library. COM uses these functions to create a class factory, unload DLLs (after making sure
that no objects or locks exist), retrieve information about the proxy DLL, and to self-register and unregister the
proxy DLL. To take advantage of these predefined functions, you need to invoke the Cpreprocessor /D (or -D )
option when you compile the Dlldata.c and Example_p.c files, as shown in the following makefile:

example.h example.tlb example_p.c example_i.c dlldata.c : example.idl


midl example.idl
dlldata.obj : dlldata.c
CL /c /DWIN32 /DREGISTER_PROXY_DLL dlldata.c
example.obj : example_p.c
CL /c /DWIN32 /DREGISTER_PROXY_DLL example_p.c
iids.obj : example_i.c
PROXYSTUBOBJS = dlldata.obj example.obj iids.obj
PROXYSTUBLIBS = kernel32.lib rpcndr.lib rpcns4.lib rpcrt4.lib uuid.lib
proxy.dll : $(PROXYSTUBOBJX) example.def
link /dll /out:proxy.dll /def:example.def
$(PROXYSTUBOBJS) $(ORIXYSTUBLIBS)
regsvr32 /s proxy.dll

If you do not specify these preprocessor definitions at compile time, these functions are not automatically defined.
(That is, the macros in Rpcproxy.c expand to nothing.) You would have to have defined them explicitly in another
source file, whose module would also be included in the final linking and compilation on the C compiler command
line.
When REGISTER_PROXY_DLL is defined, Rpcproxy.h provides for additional conditional compilation control with
PROXY_CLSID=guid, PROXY_CLSID_IS=explicit value of guid, and ENTRY_PREFIX=prefix string. These macro
definitions are described in greater detail in C -Compiler Definitions for Proxy/Stubs in the MIDL Programmer's
Guide.

Manually Registering the Proxy DLL


If for some reason you cannot use the default proxy stub registration routines, you can manually register the DLL
by adding the following entries to the system registry, using Regedt32.exe.

HKEY_CLASSES_ROOT
Interface
iid
(Default) = ICustomInterfaceName
ProxyStubClsid32 = {clsid}

HKEY_CLASSES_ROOT
CLSID
clsid
(Default) = ICustomInterfaceName_PSFactory
InprocServer32 = proxstub.dll

Related topics
C
-
C
o
m
p
i
l
e
r
D
e
f
i
n
i
t
i
o
n
s
f
o
r
P
r
o
x
y
/
S
t
u
b
s
R
e
g
i
s
t
e
r
i
n
g
C
O
M
S
e
r
v
e
r
s

S
e
l
f
-
R
e
g
i
s
t
r
a
t
i
o
n
Interface Design Rules
1/7/2020 • 2 minutes to read • Edit Online

This section provides a short summary of interface design rules and guidelines. Some of these rules are specific to
the COM architecture, while others are restrictions imposed by the interface design language, MIDL. For details of
COM interface design, see Anatomy of an IDL File.
By definition, an object is not a COM object unless it implements either the IUnknown interface or an interface
that is derived from IUnknown. In addition, the following rules apply to all interfaces implemented on a COM
object:
They must have a unique interface identifier (IID ).
They must be immutable. Once they are created and published, no part of their definition may change.
All interface methods must return an HRESULT value so that the portions of the system that handle remote
processing can report RPC errors.
All string parameters in interface methods must be Unicode.
Your data types must be remotable. If you cannot convert a data type to a remotable type, you will have to
create your own marshaling and unmarshaling routines. Also, LPVOID, or void *, has no meaning on a remote
computer. Use a pointer to IUnknown, if necessary.

NOTE
The current implementation of MIDL does not handle function overloading or multiple inheritance.

Other Interface Design Considerations


Use pointers to data very carefully. To re-create the data in the address space of the process that is called, the RPC
run time must know the exact size of the data. If, for example, a CHAR * parameter points to a buffer of characters
rather than to a single character, the data cannot be correctly re-created. Use the syntax available with MIDL to
accurately describe the data structures represented by your type definitions.
Initialization is essential for pointers that are embedded in arrays and structures and passed across process
boundaries. Uninitialized pointers may work when passed to a program in the same process space, but proxies and
stubs assume that all pointers are initialized with valid addresses or are null.
Be careful when aliasing pointers (allowing pointers to point to the same piece of memory). If the aliasing is
intentional, these pointers should be declared aliased in the IDL file. Pointers declared as nonaliased should never
alias each other.
Pay attention to how you allocate and free memory. Remember that, unless you explicitly tell a COM object (by
using the allocate attribute) not to free a data structure that was created during an out-of-process call, that
structure will be destroyed when the call completes. Also, consider the potentially destructive overhead created by
inefficient allocation of data structures that now need to be marshaled and unmarshaled.
Finally, be careful when defining your HRESULT return values so that you don't create error codes that conflict
with COM -defined FACILITY_ITF codes (values between 0x0000 and 0x01FF are reserved) or that conflict with
other HRESULT values with the same value. Whenever possible, use the universal COM success and failure return
values, and use an out parameter, rather than an HRESULT, to return information specific to the function call.
For more information, see the following topics:
Designing Remotable Interfaces
Using a COM Interface

Related topics
I
n
t
e
r
f
a
c
e
D
e
f
i
n
i
t
i
o
n
s
a
n
d
T
y
p
e
L
i
b
r
a
r
i
e
s
Designing Remotable Interfaces
1/29/2020 • 2 minutes to read • Edit Online

With the advent of the distributed component object model, it is important that your custom interface be
remotable, even if you intend to use it in-process only.
MIDL is more than just a way to generate header files for your interfaces. It is a programming language for
remoting that allows you to use your interfaces across machine, process, and thread boundaries. This means that
you need to verify the behavior of your MIDL -defined interfaces under those conditions before you release your
program to customers. If you made a mistake in your IDL and the interface is not remoted correctly, it can be
difficult to remedy that mistake. Either you have to revise your interface with a new IID and leave the old one in for
backward compatibility or you have to convert every client and every server machine everywhere at the same
time.
Even if your interface will never be used out-of-process, it may be used cross-thread. The worst problem for an
unchecked IDL file can arise for in-process servers that do not support multiple single-threaded apartments ). A
server that does not specify a threading model is implicitly single-threaded. Everything marked single-threaded is
forced over to the thread that first called CoInitialize or CoInitializeEx. If some other thread was the one that
activated the object, all the interfaces on that single-threaded server must be remoted back to the activating thread,
which can result in a return of REGDB_E_IIDNOTREG in response to a call to QueryInterface). Unless you can
absolutely assert that your interface is both in-process and always going to be called on the same thread, you will
get remoted at some time.
Finally, as an interface designer, you need to consider how client applications will use your interface. Two things,
together, determine whether an interface will be efficient across process and machine boundaries: the frequency of
method calls across the interface boundary, and the amount of data to be transferred in a given method call.
Although COM makes cross-process and cross-network calls transparent to programs, it cannot make high-
frequency and high-bandwidth calls efficient across address spaces. In some cases, it is more appropriate to design
interfaces that will normally be implemented only as in-process servers while other interfaces are more
appropriate for remote use.
Using a COM Interface
1/7/2020 • 2 minutes to read • Edit Online

The client code is the user of the COM interface. To use any COM interface, custom or standard, a client must know
its IID. In the following example, the driver that calls CustomRpt passes it the name of the object that is converted
to a wide-character format. The object name is fed to CreateFileMoniker so that a file moniker can be created
and the client can bind to the running object. After the object is running, CustomRpt can access a pointer to either
an interface in the standard proxy/stub, such as IPersistFile, or to the custom interface, ICustomInterface.

void CustomRpt(char *pszObject)


{
HRESULT hr;
WCHAR wszObject[128];
WCHAR wszMsg[128] = {L"Your Message Here...\n"};
IMoniker *pmkObject = NULL;
IUnknown *pIUnk = NULL;
IPersistFile *pIPersistFile = NULL;
ICustomInterface *pICustomInterface = NULL;

// Create a wide-character version of the object's file name.


StringCchPrintf(wszObject, 128, L"%hs", pszObject);

// Get a file moniker for the object (a *.smp file).


hr = CreateFileMoniker(wszObject, &pmkObject);

if(FAILED(hr))
{
printf("Client: CreateFileMoniker for Object failed");
return;
}

// BindMoniker is equivalent to calling CreateBindCtx() followed by


// a call to BindToObject(). It has the net result of binding the
// interface (specified by the IID) to the moniker.

hr = BindMoniker(pmkObject, 0, IID_IUnknown, (void **)&pIUnk);


if (FAILED(hr))
{
printf("Client: BindMoniker failed (%x)\n", hr);
return;
}

// Try a couple QueryInterface calls into the object code; first a


// QueryInterface to IPersistFile...

hr = pIUnk->QueryInterface(IID_IPersistFile, (void **)&pIPersistFile);

if (FAILED(hr)) {
printf("Client: QueryInterface IPersistFile failed (%x)\n", hr);
pIUnk->Release();
return;
}

// Followed by a QueryInterface to ICustomInterface.


hr = pIUnk->QueryInterface(IID_ICustomInterface, (void **)&pICustomInterface);

if (FAILED(hr)) {
printf("Client: QueryInterface failed (%x)\n", hr);
pIUnk->Release();
pIPersistFile->Release();
return;
}

// CustomReport() is the object function that displays the time and


// date information on the object.
hr = pICustomInterface->CustomReport();

if (FAILED(hr))
{
printf("Client: pICustomInterface->CustomReport failed (%x)\n", hr);
pIUnk->Release();
pIPersistFile->Release();
return;
}

// Clean up resources by calling release on each of the interfaces.


pIPersistFile->Release();
pICustomInterface->Release();
pIUnk->Release();
return;
}
Registering COM Applications
1/7/2020 • 2 minutes to read • Edit Online

The registry is a system database that contains information about the configuration of system hardware and
software as well as about users of the system. Any Windows-based program can add information to the registry
and read information back from the registry. Clients search the registry for interesting components to use.
The registry maintains information about all the COM objects installed in the system. Whenever an application
creates an instance of a COM component, the registry is consulted to resolve either the CLSID or ProgID of the
component into the pathname of the server DLL or EXE that contains it. After determining the component's
server, Windows either loads the server into the process space of the client application (in-process components)
or starts the server in its own process space (local and remote servers). The server creates an instance of the
component and returns to the client a reference to one of the component's interfaces.
For more information about the Windows registry, see the following topics:
Registry Hierarchy
Classes and Servers
Classifying Components
Using OleView
Registering Components
Checking Registration
Unknown User Types
COM Registry Keys
Registry Hierarchy
1/7/2020 • 2 minutes to read • Edit Online

The registry is structured as a hierarchy of keys, subkeys, and named values or single default values. Subkeys can
have multiple subkeys and values. Keys are named by backslash-delimited strings. Each key in the registry can
have one or more values, which can contain strings, integral values, or binary data.

Related topics
R
e
g
i
s
t
e
r
i
n
g
C
O
M
A
p
p
l
i
c
a
t
i
o
n
s
Classes and Servers
1/7/2020 • 2 minutes to read • Edit Online

COM uses HKEY_CLASSES_ROOT for computer-wide settings but also allows per-user configuration of CLSIDS
for greater security and flexibility. COM first consults HKEY_CURRENT_USER\Software\Classes before looking
under HKEY_CLASSES_ROOT. COM keeps computer-wide information related to CLSIDs under
HKEY_CLASSES_ROOT\CLSID and keeps per-user class information under
HKEY_CURRENT_USER\Software\Classes\CLSID.
COM servers support self-registration. For an in-process server, this means that the DLL must export the
following functions:
DllRegisterServer
DllUnregisterServer
You must explicitly export these functions by using a module definition file, linker switches, or compiler directives.
The class store uses these functions to configure the local registry after downloading the file to the client machine.
In addition to class store, these functions are also used by other environments to install servers on host computers.

Related topics
R
e
g
i
s
t
e
r
i
n
g
C
O
M
A
p
p
l
i
c
a
t
i
o
n
s
Classifying Components
1/7/2020 • 2 minutes to read • Edit Online

While a client is able to browse through the list of CLSIDs in the registry and select a component to use, loading
each component in the registry and querying it for its supported interfaces is very time-consuming. To determine
whether a component supports the interfaces required before creating an instance of the component, a method to
classify components into categories was developed.
A component category is a set of interfaces that have been assigned a GUID named CATID. Components that
implement all of the interfaces in a component category register themselves as members of that component
category. Components that belong to a certain component category can then be selected from the registry. By
registering itself as a member of a component category, the component is guaranteeing that it supports all of the
member interfaces in the component category.
A component can be a member of many categories. It is not limited to supporting interfaces in a component
category. It can support any interface, in addition to those in a component category.
In contrast to the standard registration of components, in which developers must write code that manually
registers objects, component categories automates much of this work. The six methods of the ICatRegister
interface define component categories and register objects that implement or require them. The Component
Categories Manager object implements this interface. See ICatRegister and ICatInformation for additional
information on using component categories.

Related topics
R
e
g
i
s
t
e
r
i
n
g
C
O
M
A
p
p
l
i
c
a
t
i
o
n
s
Using OleView
1/7/2020 • 2 minutes to read • Edit Online

While the Registry Editor shows an unprocessed view of the registry and is helpful for learning the organization of
the registry, using the Registry Editor can be time-consuming.
OleView provides a higher-level view of the information contained in the registry. Rather than looking at a long list
of CLSIDs, OleView features tree controls with friendly names.

Related topics
R
e
g
i
s
t
e
r
i
n
g
C
O
M
A
p
p
l
i
c
a
t
i
o
n
s
Registering Components
1/7/2020 • 2 minutes to read • Edit Online

When the following types of applications are installed, installation information must be added to the registry,
usually through a setup program:
Server applications
Container/server applications
Container applications that allow linking to embedded objects
For all three instances, register COM library (DLL ) information and application-specific information.
The DLL registers the information for all its components by exporting DllRegisterServer and
DllUnregisterServer. Use the following functions to register and unregister a component:
RegOpenKeyEx
RegCreateKeyEx
RegSetValueEx
RegEnumKeyEx
RegDeleteKey
RegCloseKey

Related topics
R
e
g
i
s
t
e
r
i
n
g
C
O
M
A
p
p
l
i
c
a
t
i
o
n
s
Checking Registration
1/7/2020 • 2 minutes to read • Edit Online

Each time an application loads, it should check its registration to determine the following:
Whether the CLSIDs are present in the registry. If they are not present, the application should register as the
original setup.
Whether the application's CLSIDs are present in the register but have no OLE 2-related information in them. If
this is the case, the application should register as the original setup.
Whether the path containing server entries ( LocalServer and LocalServer32, InprocServer and InprocServer32,
and DefaultIcon) points to the location at which the application is currently installed. If the path does not,
rewrite the path entries to point to the current location.

Related topics
R
e
g
i
s
t
e
r
i
n
g
C
O
M
A
p
p
l
i
c
a
t
i
o
n
s
Unknown User Types
1/7/2020 • 2 minutes to read • Edit Online

You can ease product localization by adding the following registry key:
HKEY_LOCAL_MACHINES\SOFTWARE\Microsoft\OLE2\UnknownUserType = usertype
This key allows functions to return a specified string rather than a default value of "Unknown", enabling localizers
to specify a user type of a different language.
The COM default handler's implementation of IOleObject::GetUserType examines the registry by calling
OleRegGetUserType. If the object's class is not found in the registry, the user type from the object's IStorage
instance is returned. If the class is not found in the object's IStorage instance, the string "Unknown" is returned.

Related topics
R
e
g
i
s
t
e
r
i
n
g
C
O
M
A
p
p
l
i
c
a
t
i
o
n
s
COM Registry Keys
1/7/2020 • 2 minutes to read • Edit Online

The registry contains a wealth of information used by COM. The most important information is stored in the
following keys.

KEY DESCRIPTION

AppID Groups the configuration options (a set of named values) for


one or more distributed COM objects into one location in the
registry. Subkeys under this key are used to map an
application identifier (AppID) to a remote server name. To
simplify the management of common security and
configuration settings, distributed COM objects hosted by the
same executable are grouped into one AppID.

CLSID A class identifier (CLSID) is a globally unique identifier that


identifies a COM class object. If the server or container allows
linking to embedded objects, register a CLSID for each
supported class of objects. The CLSID key contains
information used by the default COM handler to return
information about a class when it is in the running state.
To obtain a CLSID for your application, use uuidgen.exe, found
in the \TOOLs directory of the COM Toolkit, or use
CoCreateGuid.

ProgID A programmatic identifier (ProgID) is a registry entry that can


be associated with a CLSID. The ProgID key maps a user-
friendly string to a CLSID. Like the CLSID, the ProgID identifies
a class, but with less precision. Use a ProgID in programming
situations where it is not possible to use a CLSID. ProgIDs
should not appear in the user interface. ProgIDs are not
guaranteed to be unique, so they can be used only where
name collisions do not occur.

VersionIndependentProgID Associates a ProgID with a CLSID. It is used to determine the


latest version of an object application. Like the ProgID, the
version-independent ProgID can be registered with a human-
readable name.
Applications must register a version-independent
programmatic identifier under the VersionIndependentProgID
key. The version-independent ProgID refers to the
application's class and does not change from version to
version, instead remaining constant across all versions. It is
used with macro languages and refers to the currently
installed version of the application's class. The version-
independent ProgID must correspond to the name of the
latest version of the object application.

file_extension Associates a file name extension with a ProgID.


Information contained in the file name extension key is used
by both the system and file monikers. GetClassFile uses the
file name extension key to supply the associated CLSID.
KEY DESCRIPTION

Interface Registers new interfaces by associating an interface name with


an interface identifier (IID). It maps IIDs to information specific
to an interface. The information is required mainly for using
interfaces across process boundaries.
When adding a new interface, the Interface key must be
completed for COM to register the new interface. There must
be one IID subkey for each new interface.

Ole Controls default launch and access permissions for distributed


COM objects as well as call-level security capabilities for
applications that do not call CoInitializeSecurity. Only
administrators have full access to this portion of the registry.
All other users have read-only access.

Related topics
R
e
g
i
s
t
e
r
i
n
g
C
O
M
A
p
p
l
i
c
a
t
i
o
n
s
Security in COM
1/7/2020 • 2 minutes to read • Edit Online

Security in COM is firmly based on the security provided by Windows and the underlying RPC security
mechanisms. COM security relies on authentication (the process of verifying a caller's identity) and
authorization (the process of determining whether a caller is authorized to do what it is asking to do). There
are two main types of security in COM: activation security and call security. Activation security determines
whether a client can launch a server at all. After a server has been launched, you can use call security to control
access to a server's objects.
In this security model, servers manage and help protect objects, clients get access to objects through servers,
and servers can attempt access while impersonating the client.
The system implements the Kerberos v5 authentication protocol and the Schannel security package. It also
includes features such as delegate-level impersonation, mutual authentication, the ability to set authentication
levels for an AppID in the registry, and cloaking. Using COM security, you can implement objects that can
perform privileged operations without compromising security.
Because there is a wide range of COM security features available, it is helpful to initially determine what kind of
security your application needs. For most applications, setting an acceptable level of security can be a painless
process, but you can also use COM security to support very complex security scenarios.
You can set security processwide, either by using Dcomcnfg.exe to set the registry or by calling
CoInitializeSecurity. Two primary interfaces, IClientSecurity and IServerSecurity (and associated helper
functions), allow you to set call-level security within your program.
To learn more about COM security, see the following topics:
Determining Your Security Needs
COM Security Defaults
Activation Security
Security Values
Setting Security for COM Applications
Enabling COM Security Using DCOMCNFG
Turning Off Security
Server-Side Security
Security Blanket Negotiation
COM and Security Packages
DCOM Security Enhancements in Windows XP Service Pack 2 and Windows Server 2003 Service Pack 1
Access Control Lists for COM
The COM Elevation Moniker
Determining Your Security Needs
1/7/2020 • 2 minutes to read • Edit Online

How you set up COM security for your application depends on what kind of security your application needs. There
are several common situations that determine what you should do.
If you decide to use the COM security defaults, you do not have to do anything—COM handles it all. For
information on what these default settings are, see COM Security Defaults.
You can also prevent any remote calls into your machine by disabling DCOM altogether (COM between remote
computers). For more information, see Setting System-Wide Security Using DCOMCNFG.
For legacy or new applications, you can set process-wide security in the registry. For more information, see Setting
Processwide Security Through the Registry.
You can also override default security settings for calls to certain interfaces in the process while setting default
security for the remainder of the process (to allow COM to handle the general cases). For more information, see
Setting Security at the Interface Proxy Level.
For complex security requirements, you can handle all security programmatically rather than allowing COM to
handle it for you. To do this, call CoInitializeSecurity to disable automatic authentication, and then control all the
security settings by setting security on a per-interface proxy basis. For more information, see Setting Processwide
Security with CoInitializeSecurity and Setting Security at the Interface Proxy Level.
In some scenarios, you might want to turn off security completely. You might decide that your application does not
need any security, or you might want to disable security during development time so that you can enable security
features individually. To learn how to disable COM security, see Turning Off Security.
Security in COM relies on authentication services administered by security packages. NTLMSSP works well for
many applications but does not provide the more robust security offered by other packages. Therefore, COM
supports the Schannel security package and the Kerberos v5 security protocol. For more details on using these
security packages, see COM and Security Packages.

Related topics
S
e
c
u
r
i
t
y
i
n
C
O
M
COM Security Defaults
1/7/2020 • 2 minutes to read • Edit Online

You can use the COM security defaults for your application rather than specifying your own security settings. In
that case, COM will initialize and manage security for you. You do not need to configure the registry or call any
security functions in your program.
However, if certain registry named values have been set or modified, the security defaults that COM uses will be
affected. The list below describes COM security default values and explains how some values are influenced by
registry settings.
Following are the default security values that COM uses:
The default security service provider is the one that is determined by COM to be the most compatible with the
environment. COM chooses either the Kerberos v5 protocol or NTLMSSP, with the Kerberos protocol being
the default choice. None of the protocols provided by Schannel are ever chosen as the default.
The system identifies a caller through user name and password and automatically creates an identification
token used by the security system.
If the LegacyAuthenticationLevel named value exists and if its value has been set, that value is used. Otherwise,
the authentication level is set at connect (RPC_C_AUTHN_LEVEL_CONNECT). This level means that at the first
call a client makes to the server, COM does an authentication check. If the client passes the check, no further
authentication is done. The AuthenticationLevel value can also be set under the AppID key.
If the LegacyImpersonationLevel named value exists and if its value has been set, that value is used. Otherwise,
the impersonation level is set to identify (RPC_C_IMP_LEVEL_IDENTIFY ). Impersonation rights are granted by
the client to the server. Identify level means that the server can obtain the client's identity. The server can
impersonate the client for access control list (ACL ) checking but cannot access system objects as the client. For
more information, see Impersonation Levels and Cloaking.
If the AccessPermission named value under AppID exists and has been set, that value is used. Otherwise, COM
checks for a DefaultAccessPermission entry. If present, that value is used. If this value is not present, COM
constructs an ACL that grants permissions to the server identity and the local system.
If the SRPTrustLevel named value under AppID exists and has been set, that value is used. Otherwise, the
Software Restriction Policy (SRP ) trust level is set to Disallowed (SAFER_LEVELID_DISALLOWED ), which
indicates that the application is run in a constrained environment and is disallowed from accessing any
security-sensitive user privileges of the user.

Related topics
S
e
c
u
r
i
t
y
i
n
C
O
M
Activation Security
1/7/2020 • 2 minutes to read • Edit Online

Activation security (also called launch security) helps control who can launch a server. Activation security is
automatically applied by the service control manager (SCM ) of a particular computer. Upon receipt of a request
from a client to activate an object (as described in Instance Creation Helper Functions), the SCM checks the
request against activation-security information stored within its registry. (Activation security is also checked for
same-computer activations.)
When determining the identity of the client, activation examines the cloaking flag set in the client's call to
CoInitializeSecurity. If the cloaking flag is set (for either dynamic or static cloaking), the thread token is used, if
present, to determine the identity of the client. If no cloaking is set, the process token is used instead of the thread
token.
For more information about activation security, see COAUTHINFO and COSERVERINFO.

Related topics
S
e
c
u
r
i
t
y
i
n
C
O
M
Security Values
1/7/2020 • 2 minutes to read • Edit Online

Several values affect security for COM applications, including authentication level, impersonation level, cloaking,
application identity, software restriction policy configuration, and reference tracking.
For more information, see the following topics:
Authentication Level describes how to help control the amount of protection for communication between COM
objects.
Delegation and Impersonation explains how cloaking affects the identity presented to the server during
impersonation and how the client grants the server the authority to act on its behalf.
Application Identity identifies and explains the identities your application can use.
Software Restriction Policy explains how to help protect your system from the dangers associated with running
unknown code.
Reference Tracking explains how you can ensure that objects are not released too early.

Related topics
S
e
c
u
r
i
t
y
i
n
C
O
M
Authentication Level
1/7/2020 • 2 minutes to read • Edit Online

The authentication level controls how much security a client or server wants from its SSP. The authentication level
is set by passing an appropriate RPC_C_AUTHN_LEVEL_xxx value to CoInitializeSecurity or
CoSetProxyBlanket through the dwAuthnLevel parameter. The authentication levels from the client and server
are compared during the handshake, and the higher level security protection setting is used for the connection.
The different authentication levels are described as follows, from lowest level security protection to highest:

N
o
n
e
(
R
P
C
_
C
_
A
U
T
H
N
_
L
E
V
E
L
_
N
O
N
E
)

No authentication is performed during the communication between client and server. All security settings are
ignored. This authentication level can be set only if the authentication service level is
RPC_C_AUTHN_NONE.

D
e
f
a
u
l
t
(
R
P
C
_
C
_
A
U
T
H
N
_
L
E
V
E
L
_
D
E
F
A
U
L
T
)

COM chooses the authentication level by using its normal security blanket negotiation. It will never choose
an authentication level of None.

C
o
n
n
e
c
t
(
R
P
C
_
C
_
A
U
T
H
N
_
L
E
V
E
L
_
C
O
N
N
E
C
T
)

The normal authentication handshake occurs between the client and server, and a session key is established
but that key is never used for communication between the client and server. All communication after the
handshake is nonsecure.

C
a
l
l
(
R
P
C
_
C
_
A
U
T
H
N
_
L
E
V
E
L
_
C
A
L
L
)

Only the headers of the beginning of each call are signed. The rest of the data exchanged between the client
and server is neither signed nor encrypted. Most SSPs do not support this authentication level and silently
promote it to Packet.

P
a
c
k
e
t
(
R
P
C
_
C
_
A
U
T
H
N
_
L
E
V
E
L
_
P
K
T
)

The header of each packet is signed but not encrypted. The packets themselves are not signed or encrypted.

P
a
c
k
e
t
I
n
t
e
g
r
i
t
y
(
R
P
C
_
C
_
A
U
T
H
N
_
L
E
V
E
L
_
P
K
T
_
I
N
T
E
G
R
I
T
Y
)

Each packet of data is signed in its entirety but is not encrypted. Because all of the data is signed by the
sender, the recipient can be certain that none of the data has been tampered with during transit.

P
a
c
k
e
t
P
r
i
v
a
c
y
(
R
P
C
_
C
_
A
U
T
H
N
_
L
E
V
E
L
_
P
K
T
_
P
R
I
V
A
C
Y
)

Each data packet is signed and encrypted. This helps protect the entire communication between the client
and server.

Related topics
A
u
t
h
e
n
t
i
c
a
t
i
o
n
L
e
v
e
l

L
e
g
a
c
y
A
u
t
h
e
n
t
i
c
a
t
i
o
n
L
e
v
e
l
Delegation and Impersonation
1/7/2020 • 2 minutes to read • Edit Online

In client/server scenarios, it is common for one server to call another server to accomplish some task on a client's
behalf. The situation where a server is given the authority to act on a client's behalf is called delegation.
From a security standpoint, two issues arise regarding delegation:
What should the server be allowed to do when acting on the client's behalf?
What identity is presented by the server when it calls other servers on behalf of a client?
To deal with these issues, COM provides the following functionality. The client can set an impersonation level that
determines to what extent the server will be able to act as the client. If the client grants enough authority to the
server, the server can impersonate (pretend to be) the client. When impersonating the client, the server is given
access to only those objects or resources that the client has permission to use. The server, acting as a client, can
also enable cloaking to mask its own identity and project the client's identity in calls to other COM components.

Consider the scenario illustrated by the preceding figure, where A and B are processes on a different machine
from C. Process A calls B, and B calls C. Client A sets the impersonation level. B sets the cloaking capability. If A
sets an impersonation level that permits impersonation, B can impersonate A when calling C on A's behalf. The
identity that is presented to process C will be either A's identity or B's identity, depending on whether cloaking
was enabled by B. If cloaking is enabled, the identity presented to process C will be that of A. If cloaking is not
enabled, B's identity will be presented to C.
For more information, see the following topics:
Impersonation
Impersonation Levels
Cloaking
Impersonation
1/7/2020 • 2 minutes to read • Edit Online

Impersonation is the ability of a thread to execute in a security context that is different from the context of the
process that owns the thread. When running in the client's security context, the server "is" the client, to some
degree. The server thread uses an access token representing the client's credentials to obtain access to the objects
to which the client has access.
The primary reason for impersonation is to cause access checks to be performed against the client's identity. Using
the client's identity for access checks can cause access to be either restricted or expanded, depending on what the
client has permission to do. For example, suppose a file server has files containing confidential information and
that each of these files is protected by an ACL. To help prevent a client from obtaining unauthorized access to
information in these files, the server can impersonate the client before accessing the files.

Access Tokens for Impersonation


Access tokens are objects that describe the security context of a process or thread. They provide information that
includes the identity of a user account and a subset of the privileges available to the user account. Every process
has a primary access token that describes the security context of the user account associated with the process. By
default, the system uses the primary token when a thread of the process interacts with a securable object. However,
when a thread impersonates a client, the impersonating thread has both a primary access token and an
impersonation token. The impersonation token represents the client's security context, and this access token is the
one that is used for access checks during impersonation. When impersonation is over, the thread reverts to using
only the primary access token.
You can use the OpenProcessToken function to get a handle to the primary token of a process. Use the
OpenThreadToken function to get a handle to the impersonation token of a thread.

Related topics
A
c
c
e
s
s
T
o
k
e
n
s

D
e
l
e
g
a
t
i
o
n
a
n
d
I
m
p
e
r
s
o
n
a
t
i
o
n
Impersonation Levels
1/7/2020 • 2 minutes to read • Edit Online

If impersonation succeeds, it means that the client has agreed to let the server be the client to some degree. The
varying degrees of impersonation are called impersonation levels, and they indicate how much authority is given
to the server when it is impersonating the client.
Currently, there are four impersonation levels: anonymous, identify, impersonate, and delegate. The following list
briefly describes each impersonation level:

a
n
o
n
y
m
o
u
s
(
R
P
C
_
C
_
I
M
P
_
L
E
V
E
L
_
A
N
O
N
Y
M
O
U
S
)

The client is anonymous to the server. The server process can impersonate the client, but the impersonation
token does not contain any information about the client. This level is only supported over the local
interprocess communication transport. All other transports silently promote this level to identify.

i
d
e
n
t
i
f
y
(
R
P
C
_
C
_
I
M
P
_
L
E
V
E
L
_
I
D
E
N
T
I
F
Y
)

The system default level. The server can obtain the client's identity, and the server can impersonate the
client to do ACL checks.

i
m
p
e
r
s
o
n
a
t
e
(
R
P
C
_
C
_
I
M
P
_
L
E
V
E
L
_
I
M
P
E
R
S
O
N
A
T
E
)

The server can impersonate the client's security context while acting on behalf of the client. The server can
access local resources as the client. If the server is local, it can access network resources as the client. If the
server is remote, it can access only resources that are on the same computer as the server.

d
e
l
e
g
a
t
e
(
R
P
C
_
C
_
I
M
P
_
L
E
V
E
L
_
D
E
L
E
G
A
T
E
)

The most powerful impersonation level. When this level is selected, the server (whether local or remote) can
impersonate the client's security context while acting on behalf of the client. During impersonation, the
client's credentials (both local and network) can be passed to any number of computers.
For impersonation to work at the delegate level, the following requirements must be met:
The client must set the impersonation level to RPC_C_IMP_LEVEL_DELEGATE.
The client account must not be marked "Account is sensitive and cannot be delegated" in the Active
Directory Service.
The server account must be marked with the "Trusted for delegation" attribute in the Active Directory
Service.
The computers hosting the client, the server, and any "downstream" servers must all be running in a
domain.

By choosing the impersonation level, the client tells the server how far it can go in impersonating the client. The
client sets the impersonation level on the proxy it uses to communicate with the server.

Setting the Impersonation Level


There are two ways to set the impersonation level:
The client can set it processwide, through a call to CoInitializeSecurity.
A client can set proxy-level security on an interface of a remote object through a call to
IClientSecurity::SetBlanket (or the helper function CoSetProxyBlanket).
You set the impersonation level by passing an appropriate RPC_C_IMP_LEVEL_xxx value to
CoInitializeSecurity or CoSetProxyBlanket through the dwImpLevel parameter.
Different authentication services support delegate-level impersonation to different extents. For instance,
NTLMSSP supports cross-thread and cross-process delegate-level impersonation, but not cross-computer. On
the other hand, the Kerberos protocol supports delegate-level impersonation across computer boundaries, while
Schannel does not support any impersonation at the delegate level. If you have a proxy at impersonate level and
you want to set the impersonation level to delegate, you should call SetBlanket using the default constants for
every parameter except the impersonation level. COM will choose NTLM locally and the Kerberos protocol
remotely (when the Kerberos protocol will work).

Related topics
D
e
l
e
g
a
t
i
o
n
a
n
d
I
m
p
e
r
s
o
n
a
t
i
o
n
Cloaking
1/7/2020 • 6 minutes to read • Edit Online

Cloaking is a COM security capability that determines what identity the client projects toward the server during
impersonation. When cloaking is set, the intermediate server masks its own identity and presents the client's
identity to the server that it calls on the client's behalf. Basically; the client identity that is seen by the server is the
identity associated with the proxy. The proxy's identity is determined by several factors, one of which is the type of
cloaking that is set (if any). Cloaking is not supported by the Schannel security provider.
The following topics provide more information about cloaking:
Types of Cloaking
How Cloaking Affects Client Identity
Setting Cloaking
Cloaking and Impersonation Levels
Cloaking Scenarios
Related topics

Types of Cloaking
There are two types of cloaking: static cloaking and dynamic cloaking:
With static cloaking (EOAC_STATIC_CLOAKING ), the server sees the thread token from the first call from a
client to the server. For the first call, if the proxy identity was previously set during a call to
CoSetProxyBlanket, that proxy identity is used. However, if the proxy identity was not previously set, the
thread token is used. If no thread token is present, the process token is used. For all future calls, the identity set
on the first call is used.
With dynamic cloaking (EOAC_DYNAMIC_CLOAKING ), on each call the current thread token (if there is a
thread token) is used to determine the client's identity. If there is no thread token, the process token is used.
This means that servers called on the client's behalf during impersonation see the identity of the COM client
that originated the call, which is generally the desired behavior. (Of course, for impersonation to succeed, the
client must have given the server authority to impersonate by setting an appropriate impersonation level. For
more information, see Impersonation Levels.) This type of cloaking is expensive.

How Cloaking Affects Client Identity


When an encrypted call is made and the server asks the client for its identity, it usually gets the identity tied to the
proxy. (Sometimes the authentication service performs a translation from the real identity, but generally the proxy
identity is the identity the server sees.) The proxy presents an identity to the server that depends on the type of
cloaking that is set and other factors.
To summarize, the identity of the client is a function of the cloaking flag set, the process token, the presence or
absence of a thread token, and whether the proxy identity has been previously set. The following table shows the
resulting proxy identity (client identity) when these factors vary.

PROXY IDENTITY PREVIOUSLY PROXY IDENTITY (CLIENT


CLOAKING FLAGS THREAD TOKEN PRESENCE SET IDENTITY)

Cloaking not set Don't care Don't care Process token or


authentication identity
PROXY IDENTITY PREVIOUSLY PROXY IDENTITY (CLIENT
CLOAKING FLAGS THREAD TOKEN PRESENCE SET IDENTITY)

EOAC_STATIC_CLOAKING Present No Thread token

EOAC_STATIC_CLOAKING Present Yes Current proxy identity

EOAC_STATIC_CLOAKING Not present No Process token

EOAC_STATIC_CLOAKING Not present Yes Current proxy identity

EOAC_DYNAMIC_CLOAKIN Present Don't care Thread token


G

EOAC_DYNAMIC_CLOAKIN Not present Don't care Process token


G

The following flowchart illustrates how the proxy identity is determined in different situations.

Setting Cloaking
Cloaking is set as a capability flag in a call to CoInitializeSecurity, which sets cloaking for the entire process. The
cloaking capability is then set until the client changes it through a call to IClientSecurity::SetBlanket (or to
CoSetProxyBlanket), which sets cloaking for the proxy.
By default, cloaking is not set. To set it, pass EOAC_STATIC_CLOAKING or EOAC_DYNAMIC_CLOAKING to the
pCapabilities parameter in CoInitializeSecurity or SetBlanket.
When static cloaking is enabled using CoInitializeSecurity, each proxy picks up a token (thread or process) the
first time you make a call on the proxy. When static cloaking is enabled using SetBlanket, the proxy picks up the
token on the thread at that time. If no thread token is available when SetBlanket is called, the process token is
used for the proxy's identity. Basically, SetBlanket fixes the identity of the proxy.
With dynamic cloaking, the proxy's identity is determined the same way regardless of whether dynamic cloaking
is set using CoInitializeSecurity or with SetBlanket. The current thread token is used if there is one; otherwise,
the process token is used.
If cloaking is set for the entire process through a call to CoInitializeSecurity and you want to make calls with the
process token, do not impersonate while making calls.

Cloaking and Impersonation Levels


As mentioned previously, the cloaking capability determines what identity is presented to a server during
impersonation. Cloaking provides a way for a server to project an identity other than its own to another server it
is calling on behalf of the client. The impersonation level indicates how much authority the client has given the
server.
Impersonation without cloaking works, but it may not be the best choice because, in some cases, the final server
needs to know the identity of the initial caller. This cannot be achieved without using cloaking because it is difficult
to ensure that only authorized clients can access a remote computer. When impersonation is used without
cloaking, the identity presented to a downstream server is that of the immediate calling process.
However, cloaking is not useful without impersonation. Cloaking makes sense only when the client has set an
impersonation level of impersonate or delegate. (With lower impersonation levels, the server cannot make
cloaked calls.) Whether cloaking is successful depends on the number of computer boundaries crossed and on the
impersonation level, which indicates how much authority the server has to act on behalf of the client.
In some situations, it makes sense for the server to set cloaking when the client sets the impersonation level to
RPC_C_IMP_LEVEL_IMPERSONATE. However, certain limitations are in effect. If the original client sets the
impersonation level to RPC_C_IMP_LEVEL_IMPERSONATE, the intermediate server (acting as a client on the
same computer) can cloak across only one computer boundary. This is because an impersonate-level
impersonation token can be passed across only one computer boundary. After the computer boundary has been
crossed, only local resources can be accessed. The identity presented to the server depends on the type of
cloaking that is set. If no cloaking is set, the identity presented to a server will be that of the process making the
immediate call.
To cloak over multiple computer boundaries, you must specify both an appropriate cloaking capability flag and
delegate-level impersonation. With this type of impersonation, both the local and network credentials of the client
are given to the server, so the impersonation token can cross any number of computer boundaries. Again, the
identity presented to the server depends on the type of cloaking that is set. If no cloaking is set with delegate-level
impersonation, the identity presented to a server is that of the process making the call.
For example, suppose Process A calls B, and B calls C. B has set cloaking and A has set the impersonation level to
impersonate. If A, B, and C are on the same computer, passing the impersonation token from A to B and then to C
will work. But if A and C are on the same computer, and B is not, passing the token will work between A and B,
but not from B to C. The call from B to C will fail because B cannot call C while cloaking. However, if A sets the
impersonation level to delegate, the token can be passed from B to C and the call may succeed.
Cloaking Scenarios
In the following illustration, Process A calls B, calls C, calls D when cloaking is not set. As a result, each
intermediate process sees the identity of the process that called it.

With static cloaking, the server sees the proxy identity that was set during the first call from the client to the
server. The following figure shows an example of the proxy identity being set during a call from B to C. On a
subsequent call, Process D sees B's identity when static cloaking is set by B and C.

With dynamic cloaking, the identity of the caller during impersonation is based on the current thread token, if
there is one. The following illustration shows the situation where B and C set dynamic cloaking and D sees the
identity of A, despite an earlier call from B to C.

Related topics
D
e
l
e
g
a
t
i
o
n
a
n
d
I
m
p
e
r
s
o
n
a
t
i
o
n
Application Identity
1/7/2020 • 2 minutes to read • Edit Online

An application's identity is the account that is used to run the application. The identity can be that of the user that
is currently logged on (the interactive user), the user that launched the server, a specified user, or a service. To learn
how to set application identity using Dcomcnfg.exe, see Setting Processwide Security Using DCOMCNFG.
The following topics describe each of the four types of application identity and explain the limitations of each type:
Interactive User
Launching User
Specified User
Service Identity
Interactive User
1/7/2020 • 2 minutes to read • Edit Online

The interactive user is the user that is currently logged on to the computer where the COM server is running. If
the identity is set to be the interactive user, all clients use the same instance of the server if the server registers its
class factory as multi-use. If no user is logged on, the server will not run. If the server has a graphical user
interface (GUI) that the client needs to see, you should use interactive user for the server's identity. However,
choosing this identity carries some security risks because the server runs under the identity of the logged on user
without the logged on user's knowledge or consent. In addition, a service application cannot display a user
interface. For more information, see Interactive Services.
If a COM server is configured to run as the interactive user, in a terminal services environment, the server will be
launched in the interactive session that matches the client's user identity. However, the client application can use
the session moniker to reference an object provided by the server in a session that does not match the client
identity. When this is used, the client application can specify any session, in which case the server will run as the
user who owns the session, not the launching user. The default access permissions in this scenario would not allow
the launching user to call methods on the server. However, the following security risks remain:
If the COM server exposes interfaces that are not controlled by COM, such as TCP ports, named pipes, LPC
ports, shared memory sections, and so on, these could be used by the launching user to influence the server.
COM objects configured to run as the interactive user should reduce this attack surface as much as possible.
COM objects are free to set their own access permissions. If the object sets access permissions, either in its
AppID registration or by calling CoInitializeSecurity, to allow the launching user access, the user would be
able to launch the server to run as another user, then access the object.

Related topics
A
p
p
l
i
c
a
t
i
o
n
I
d
e
n
t
i
t
y

L
a
u
n
c
h
i
n
g
U
s
e
r

S
e
r
v
i
c
e
I
d
e
n
t
i
t
y

S
p
e
c
i
f
i
e
d
U
s
e
r
Launching User
1/7/2020 • 2 minutes to read • Edit Online

This is the default setting for the application identity. When the launching user is chosen for the application's
identity, each client account gets a new instance of the server and each server gets its own window station.
Because of the separate server instances, launching user is the highest-level security protection identity setting.
However, there are finite limits on resource consumption. Also, any GUI the server displays will not be seen by the
client.
If the application has the identity of the launching user, it runs with an impersonation token. For more information
about impersonation and access tokens, see Impersonation Levels and Cloaking.

Related topics
A
p
p
l
i
c
a
t
i
o
n
I
d
e
n
t
i
t
y

I
n
t
e
r
a
c
t
i
v
e
U
s
e
r
S
e
r
v
i
c
e
I
d
e
n
t
i
t
y

S
p
e
c
i
f
i
e
d
U
s
e
r
Specified User
1/7/2020 • 2 minutes to read • Edit Online

Specifying a particular user (and the user's password) is the preferred identity for COM servers. The reason this
identity is preferred is that no one has to be logged on the machine where the server is running for the server to
run, and every client talks to the same instance of the server if the server registers its class factory as multi-use. If
the server has a GUI, you should not choose this identity; if you do, the user will not be able to see the user
interface.
This type of server has a primary token and can access remote resources where a server that has the launching-
user identity might not be able to. For more information about impersonation and access tokens, see
Impersonation Levels and Cloaking.
Running as a fixed user account is more secure than the interactive user identity because this identity can be
assigned to the application only by someone who has the specific user's password.

Related topics
A
p
p
l
i
c
a
t
i
o
n
I
d
e
n
t
i
t
y

I
n
t
e
r
a
c
t
i
v
e
U
s
e
r

L
a
u
n
c
h
i
n
g
U
s
e
r

S
e
r
v
i
c
e
I
d
e
n
t
i
t
y
Service Identity
1/7/2020 • 2 minutes to read • Edit Online

Choosing this identity causes the application to be run as a service. You can set service accounts by choosing the
Services option from the Control Panel. For more information, see Installing as a Service Application.

Related topics
A
p
p
l
i
c
a
t
i
o
n
I
d
e
n
t
i
t
y

I
n
t
e
r
a
c
t
i
v
e
U
s
e
r

L
a
u
n
c
h
i
n
g
U
s
e
r

S
p
e
c
i
f
i
e
d
U
s
e
r
Software Restriction Policy
1/7/2020 • 2 minutes to read • Edit Online

The software restriction policy (SRP ) settings were introduced with the release of Windows XP to help protect
systems from unknown and possibly dangerous code. The SRP provides a mechanism where only trusted code is
given unrestricted access to a user's privileges. Unknown code, which might contain viruses or code that conflicts
with currently installed programs, is allowed to run only in a constrained environment (often called a sandbox)
where it is disallowed from accessing any security-sensitive user privileges. Properly using the SRP can make your
business more agile because it provides a proactive framework for preventing problems, rather than a reactive
framework that relies on the costly alternative of restoring a system after a problem has occurred.
The SRP depends upon assigning trust levels to the code that can run on a system. Currently, two trust levels exist:
Unrestricted and Disallowed. Code that has an Unrestricted trust level is given unrestricted access to the user's
privileges, so this trust level should be applied only to fully trusted code. Code with a Disallowed trust level is
disallowed from accessing any security-sensitive user privileges and can run only in a sandbox so that Unrestricted
code cannot load the Disallowed code into its address space.
The SRP configuration of individual COM applications is done through the SRPTrustLevel value in the
application's AppID key in the registry. If the SRP trust level is not specified for a COM application, the default
value of Disallowed is used. A COM application that has an Unrestricted trust level has unrestricted access to the
user's privileges but can load only components with an Unrestricted trust level, while a Disallowed COM
application can load components with any trust level but cannot access any security-sensitive user privileges.
In addition to the SRP trust levels of individual COM applications, two other SRP properties determine how the
SRP is used for all COM applications. If SRPRunningObjectChecks is enabled, attempts to connect to running
objects will be checked for appropriate SRP trust levels. The running object cannot have a less stringent SRP trust
level than the client object. For example, the running object cannot have a Disallowed trust level if the client object
has an Unrestricted trust level.
The second property determines how the SRP handles activate-as-activator connections. If
SRPActivateAsActivatorChecks is enabled, the SRP trust level that is configured for the server object is compared
with the SRP trust level of the client object and the more stringent trust level will be used to run the server object.
If SRPActivateAsActivatorChecks is not enabled, the server object runs with the SRP trust level of the client
object, regardless of the SRP trust level with which it was configured. By default, both
SRPRunningObjectChecks and SRPActivateAsActivatorChecks are enabled.
Reference Tracking
1/7/2020 • 2 minutes to read • Edit Online

Reference tracking can prevent the unintentional or malicious early release of objects.
When you enable reference tracking, you are requesting that distributed AddRef and Release calls be
authenticated by COM. When reference tracking is enabled, COM keeps track of per-user reference counts so that
a user can call Release only on objects that the user previously called AddRef on. Although reference tracking can
decrease performance, it ensures that no matter how many times a given user calls Release, the objects and stubs
will still exist if someone else has a reference to them.
The client can set reference tracking for a process by passing the EOAC_SECURE_REFS capability flag in a call to
CoInitializeSecurity. You can also enable or disable reference tracking for all applications on a computer by
using Dcomcnfg.exe.
If reference tracking is enabled, IUnknown always uses default security settings. In this case, calls to
CoSetProxyBlanket on IUnknown will fail.
Setting Security for COM Applications
1/7/2020 • 2 minutes to read • Edit Online

There are several ways you can help control security for your applications. You can change a computer's default
security settings, which are used by all applications on the computer that do not supply their own security values.
You can set security for a particular process, either by using Dcomcnfg.exe or by calling CoInitializeSecurity.
You can also programmatically control security settings at the interface proxy level.
The following topics provide procedures that explain how to set security:
Modifying the Security Defaults for a Computer
Setting Process-Wide Security
Setting Security at the Interface Proxy Level

Related topics
S
e
c
u
r
i
t
y
i
n
C
O
M
Modifying the Security Defaults for a Computer
1/7/2020 • 2 minutes to read • Edit Online

It is not recommended that you change the system-wide security settings, because this will affect all COM server
applications that do not set their own process-wide security, and might prevent them from working properly. If you
are changing the system-wide security settings to affect the security settings for a particular COM application, then
you should instead change the process-wide security settings for that particular COM application. For more
information about setting process-wide security, see Setting Process-Wide Security.
Certain values in the registry determine security settings for applications that do not call CoInitializeSecurity.
You can modify these settings using Dcomcnfg.exe.
For more information, see the following topics:
Registry Values for System-Wide Security
Setting System-Wide Security Using DCOMCNFG

Related topics
S
e
t
t
i
n
g
P
r
o
c
e
s
s
-
w
i
d
e
S
e
c
u
r
i
t
y

S
e
t
t
i
n
g
S
e
c
u
r
i
t
y
f
o
r
C
O
M
A
p
p
l
i
c
a
t
i
o
n
s
Registry Values for System-Wide Security
1/7/2020 • 2 minutes to read • Edit Online

It is not recommended that you change the system-wide security settings, because this will affect all COM server
applications that do not set their own process-wide security, and might prevent them from working properly. If you
are changing the system-wide security settings to affect the security settings for a particular COM application, then
you should instead change the process-wide security settings for that particular COM application. For more
information about setting process-wide security, see Setting Process-Wide Security.
Certain values in the registry are used to determine security settings for applications that do not call
CoInitializeSecurity. You can use Dcomcnfg.exe to modify these default security settings for a computer. For
step-by-step procedures that describe how to use Dcomcnfg.exe for this purpose, see Setting System-Wide
Security Using DCOMCNFG.
Another way to change default system-wide settings is to manipulate registry values directly. However, only
administrators and the system have full access to the portion of the registry that contains the default system-wide
call-security settings. All other users have read-access only.
The named values that affect system-wide security defaults are as follows:
DefaultLaunchPermission
DefaultAccessPermission
LegacyAuthenticationLevel
LegacyImpersonationLevel
LegacySecureReferences
SRPRunningObjectChecks
SRPActivateAsActivatorChecks

Related topics
S
e
t
t
i
n
g
P
r
o
c
e
s
s
-
W
i
d
e
S
e
c
u
r
i
t
y
Setting System-Wide Security Using DCOMCNFG
1/7/2020 • 7 minutes to read • Edit Online

Changing the system-wide security settings will affect all COM server applications that do not set their own
process-wide security. This may prevent such applications from working properly. If you are changing the system-
wide security settings to affect the security settings for a particular COM application, then you should instead
change the process-wide security settings for that particular COM application. For more information about setting
process-wide security, see Setting Process-wide Security.
When you want all of the applications on one computer that do not provide their own security to share the same
default security settings, you would set security on a system-wide basis. Using Dcomcnfg.exe makes it easy to set
default values in the registry that apply to all applications on a computer.
It is important to understand that if the client or server explicitly calls CoInitializeSecurity to set process-wide
security, the default settings in the registry will be ignored and the parameters to CoInitializeSecurity will be
used instead for the security settings for the process. Also, if you use Dcomcnfg.exe to specify security settings for
a particular process, the default computer settings are overridden by the settings for the process.
When enabling system-wide security, you must set the authentication level to a value other than None and you
must set launch and access permissions. You have the option of setting the default impersonation level, and you
also can enable reference tracking. The following topics provide step-by-step procedures:
Setting System-Wide Default Authentication Level
Setting System-Wide Launch Permissions
Setting System-Wide Access Permissions
Setting System-Wide Impersonation Level
Setting System-Wide Reference Tracking
Enabling and Disabling DCOM
Related topics

Setting System-Wide Default Authentication Level


The authentication level is used to tell COM at what level you want the client to be authenticated. These levels
offer various levels of protection, from no protection to full encryption. To enable security for a computer, you need
to choose an authentication level other than None. You can choose such a setting, using Dcomcnfg.exe, by
completing the following steps.
To set the authentication level on a system -wide basis
1. Run Dcomcnfg.exe.
2. Choose the Default Properties tab.
3. From the Default Authentication Level list box, choose a value other than (None).
4. If you will be setting more properties for the computer, click the Apply button to apply the new
authentication level. Otherwise, click OK to apply the changes and exit Dcomcnfg.exe.

Setting System-Wide Launch Permissions


The launch permissions you set with Dcomcnfg.exe determine a list of users, each of which is explicitly granted or
denied permission to launch any server that does not provide its own launch-permission settings. When setting
launch permissions, you can add or remove one or more users or groups from this list. For each user that you add,
you must specify whether the user is being granted or denied launch permission.
To set launch permissions for a computer
1. On the Default Security property page in Dcomcnfg.exe, choose the Edit Default button in the Default
Launch Permissions area.
2. To remove users or groups, select the user or group you want to remove and choose the Remove button.
The selected user or group will no longer appear in the list box. When you have finished removing users
and groups, choose OK.
3. If you want to add a user or group, choose the Add button.
4. If you know the fully qualified user name you want to add, type it in the Add Names text box. If you do not
know the user name, see Setting Processwide Security Using DCOMCNFG to find it. When you have
located the user name, select the user or group from the Names list box and choose the Add button.
5. From the Type of Access list box, select the access type (either Allow Launch or Deny Launch). To add
other users that will also have the selected type of access, repeat step 4. When you have finished adding
users for the selected access type, choose the OK button.
6. To add users that will have a different type of access, repeat steps 4 and 5. Otherwise, choose OK to apply
the changes.

Setting System-Wide Access Permissions


Dcomcnfg.exe allows you to set access permissions to control the list of users who are granted or denied access to
the methods of those servers that do not provide their own access permissions. You can add users or groups to
the list, specifying whether access permission is being granted or denied. You can also remove users from the list.
When setting access permissions, you must ensure that SYSTEM is included in the list of users that are granted
access. If you have granted access permissions to Everyone, SYSTEM is included implicitly.
The process of setting access permissions for a computer is similar to setting launch permissions. The following
steps should be taken.
To set access permissions for a computer
1. On the Default Security property page in Dcomcnfg.exe, choose the Edit Default button in the Default
Access Permissions area.
2. To remove users or groups, select the user or group you want to remove and choose the Remove button.
The selected user or group will no longer appear in the list box. When you have finished removing user and
groups, choose OK.
3. If you want to add a user or a group, choose the Add button.
4. If you know the fully qualified user name you want to add, type it in the Add Names text box. If you do not
know the user name, see Setting Process-wide Security Using DCOMCNFG to find it. When you have
located the user name, select the user or group from the Names list box and choose the Add button.
5. From the Type of Access list box, select the access type (either Allow Access or Deny Access). To add
other users that will have the selected type of access, repeat step 4. When you have finished adding users
for the selected access type, choose the OK button.
6. To add users that will have a different type of access, repeat steps 4 and 5. Otherwise, choose OK to apply
the changes.

Setting System-Wide Impersonation Level


Setting System-Wide Impersonation Level
The impersonation level, set by the client, determines the amount of authority given to the server to act on the
client's behalf. For example, when the client has set its impersonation level to delegate, the server can access local
and remote resources as the client, and the server can cloak over multiple computer boundaries if the cloaking
capability is set. To help determine which impersonation level you should choose, see Impersonation Levels and
Cloaking.
Setting the default impersonation level for the whole computer tells COM what impersonation level to use when a
particular client on the computer does not specify an impersonation level programmatically by using
CoInitializeSecurity or CoSetProxyBlanket.
To set the impersonation level for a computer
1. With Dcomcnfg.exe running, choose the Default Properties tab.
2. From the Default Impersonation Level list box, choose the impersonation level you want.
3. If you will be setting more properties for the computer, choose the Apply button to apply the new
impersonation level. Otherwise, choose OK to apply the changes and exit Dcomcnfg.exe.

Setting System-Wide Reference Tracking


When you enable reference tracking, you are asking COM to do additional security checks and to keep track of
information that will keep objects from being released too early. Keep in mind that these additional checks are
expensive. For more information about reference tracking, see Reference Tracking. Use the following steps to
enable or disable reference tracking.
To set reference tracking for a computer
1. With Dcomcnfg.exe running, choose the Default Properties tab.
2. To enable (or disable) reference tracking, select (or clear) the Provide additional security for reference
tracking check box near the bottom of the page.
3. If you will be setting more properties for the computer, choose the Apply button to apply the new setting.
Otherwise, choose OK to apply the changes and exit Dcomcnfg.exe.

Enabling and Disabling DCOM


When a computer is part of a network, the DCOM wire protocol enables COM objects on that computer to
communicate with COM objects on other computers. You can disable DCOM for a particular computer, but doing
so will disable all communication between objects on that computer and objects on other computers.
Disabling DCOM on a computer has no effect on local COM objects. COM still looks for launch permissions that
you have specified. If no launch permissions have been specified, default launch permissions are used. Even if you
disable DCOM, if a user has physical access to the computer, they could launch a server on the computer unless
you set launch permissions not to allow it.

NOTE
If you disable DCOM on a remote computer, you will not be able to remotely access that computer afterward to re-enable
DCOM. To re-enable DCOM, you will need physical access to that computer.

To manually enable (or disable) DCOM for a computer


1. Run Dcomcnfg.exe.
2. Choose the Default Properties tab.
3. Select (or clear) the Enable Distributed COMÂ on this Computer check box.
4. If you will be setting more properties for the computer, click the Apply button to enable (or disable)
DCOM. Otherwise, click OK to apply the changes and exit Dcomcnfg.exe.

Related topics
S
e
t
t
i
n
g
P
r
o
c
e
s
s
-
w
i
d
e
S
e
c
u
r
i
t
y
Setting Process-Wide Security
1/7/2020 • 2 minutes to read • Edit Online

There are several ways to set process-wide security. The first way, using the Dcomcnfg.exe tool, is easiest
because it requires no programming. The second technique offers the programmer more control, and it
requires a call to CoInitializeSecurity. Another technique is to set process-wide security in the registry by
using the AppID key.
For more information about these techniques, see the following topics:
Setting Process-Wide Security Using DCOMCNFG
Setting Process-Wide Security with CoInitializeSecurity
Setting Process-Wide Security Through the Registry

Related topics
S
e
t
t
i
n
g
S
e
c
u
r
i
t
y
a
t
t
h
e
I
n
t
e
r
f
a
c
e
P
r
o
x
y
L
e
v
e
l

S
e
t
t
i
n
g
S
e
c
u
r
i
t
y
f
o
r
C
O
M
A
p
p
l
i
c
a
t
i
o
n
s
Setting Process-Wide Security Using DCOMCNFG
1/7/2020 • 7 minutes to read • Edit Online

You might want to enable security for a particular application if an application has security needs that are different
from those required by other applications on the computer. For instance, you might decide to use system-wide
settings for your applications that require a low level of security while setting a higher level of security for a
particular application.
However, security settings in the registry that apply to a particular application are sometimes not used. For
example, the process-wide settings that you set in the registry using Dcomcnfg.exe will be overridden if a client
calls CoSetProxyBlanket to set security for a particular interface proxy. Similarly, if a client or server (or both)
call CoInitializeSecurity to set security for a process, the settings in the registry will be ignored and the
parameters specified to CoInitializeSecurity will be used instead.
When enabling security for an application, several settings may need to be modified. These include authentication
level, location, launch permissions, access permissions, and identity. For step-by-step procedures, see the
following:
Setting the Authentication Level for an Application
Setting the Location for an Application
Setting Launch Permissions for an Application
Setting Access Permissions for an Application
Setting the Identity for an Application
Browsing the User Database
Dcomcnfg.exe and 64-bit Applications
Related topics

Setting the Authentication Level for an Application


To enable security for an application, you must set an authentication level other than None. The authentication
level tells COM how much authentication protection is required, and it can range from authenticating the client at
the first method call to encrypting parameter states fully.
To set an application's authentication level
1. On the Applications property page in Dcomcnfg.exe, select the application and click the Properties
button (or double-click the selected application).
2. On the General page, select an authentication level other than (None) from the Authentication Level list
box.
3. If you will be setting other properties for this application, choose the Apply button to apply the new
authentication level. Click OK if you are finished setting properties for this application and you wish to
apply the changes.

Setting the Location for an Application


The location you set for your application determines the computer on which the application will run. You can
choose to run your application on the computer where the data is located, on the computer you use to set the
location, or on a specified computer.
To set an application's location
1. With Dcomcnfg.exe running, select the application from the Applications page and choose the Properties
button (or double-click the selected application).
2. On the Location page, select one or more check boxes that correspond to locations where you want the
application to run. If you select more than one check box, COM uses the first one that applies. If
Dcomcnfg.exe is being run on the server computer, always select Run Application On This Computer.
3. If you will be setting other properties for this application, choose the Apply button to apply the new
location. Choose OK if you are finished setting properties for this application and you wish to apply the
changes.

Setting Launch Permissions for an Application


With Dcomcnfg.exe, you can set launch permissions to control the list of users who are granted or denied
permission to launch a particular server. You can add users or groups to the list, specifying whether access
permission is being granted or denied. You can also remove users from the list.
To set launch permissions for an application
1. With Dcomcnfg.exe running, select the application from the Applications page and choose the Properties
button (or double-click the selected application).
2. On the Security property page, select the Use custom launch permissions option button and choose the
Edit button in the same area.
3. To remove users or groups, select the user or group you want to remove and choose the Remove button.
The selected user or group will no longer appear in the list box. When you have finished removing user and
groups, choose OK.
4. If you want to add users or groups, choose the Add button.
5. If you know the fully qualified user name you want to add, type it in the Add Names text box. If you do not
know the user name, you can browse the user database to find it (see Browsing the User Database below ).
When you have located the user name, select the user or group from the Names list box and choose the
Add button.
6. From the Type of Access list box, select the access type (either Allow Launch or Deny Launch). To add
other users that will have the selected type of access, repeat step 5. When you have finished adding users
for the selected access type, choose the OK button.
7. To add users that will have a different type of access, repeat steps 5 and 6. Otherwise, choose OK to apply
the changes.

Setting Access Permissions for an Application


With Dcomcnfg.exe, you can manage the list of users who are granted or denied access to the methods of a
particular server by setting access permissions. You can add users or groups to the list, specifying whether access
permission is being granted or denied. You can also remove users from the list.
When setting access permissions, you must ensure that SYSTEM is included in the list of users that are granted
access. If you have granted access permissions to Everyone, SYSTEM is included implicitly.
The process of setting access permissions for an application is similar to setting launch permissions. The steps are
as follows.
To set access permissions for an application
1. With Dcomcnfg.exe running, select the application from the Applications page and choose the Properties
button (or double-click the selected application).
2. On the Security property page, select the Use custom access permissions option button and choose the
Edit button in the same area.
3. To remove users or groups, select the user or group you want to remove and choose the Remove button.
The selected user or group will no longer appear in the list box. When you have finished removing user and
groups, choose OK.
4. If you want to add a user or a group, choose the Add button.
5. If you know the fully qualified user name you want to add, type it in the Add Names text box. If you do not
know the user name, you can browse the user database to find it. When you have located the user name,
select the user or group from the Names list box and choose the Add button.
6. From the Type of Access list box, select the access type (either Allow Access or Deny Access). To add
other users that will have the selected type of access, repeat step 5. When you have finished adding users
for the selected access type, choose the OK button.
7. To add users that will have a different type of access, repeat steps 5 and 6. Otherwise, choose OK to apply
the changes.

Setting the Identity for an Application


An application's identity is the account that is used to run the application. The identity can be that of the user that
is currently logged on (the interactive user), the user account of the client process that launched the server, a
specified user, or a service. You can use Dcomcnfg.exe to choose one of these identities for the application. For
help with deciding which identity to set for your application, see Application Identity.
To set identity for an application
1. With Dcomcnfg.exe running, select the application from the Applications page and choose the Properties
button (or double-click the selected application).
2. On the Identity property page, select the option button for the identity you want. If you choose This User,
you must type in the user name, the password, and the confirmed password.
3. If you will be setting other properties for this application, choose the Apply button to apply the new
identity. Choose OK if you are finished setting properties for this application and you wish to apply the
changes.

Browsing the User Database


You would browse the user database in Dcomcnfg.exe when you need to find the fully qualified user name for a
particular user. For instance, you can browse the user database to locate a user that you want to add for access or
launch permissions.
To browse the user database
1. In the List Names From list box, select the domain containing the user or group you want to add.
2. To see the users that belong to the selected domain, choose the Show Users button.
3. To see the members of a particular group, select the group in the Names list box and choose the Show
Members button.
4. If you cannot locate the user or group you want to add, choose the Search button, which brings up the
Find Account dialog box. Select the domain you want to search (or select Search All), type the user name
you want to look for, and choose the Search button.

Dcomcnfg.exe and 64-bit Applications


On x64 operating systems from Windows XP to Windows Server 2008, the 64-bit version of DCOMCNFG.EXE
does not correctly configure 32-bit DCOM applications for remote activation. This behavior causes components
that are meant to be activated remotely instead being activated locally. This behavior does not occur in Windows 7
and Windows Server 2008 R2 and higher versions.
The workaround is to use the 32-bit version of DCOMCNFG. Run the 32-bit version of mmc.exe and load the 32-
bit version of the Component Services snap-in by using the following command line.
C:\WINDOWS\SysWOW64>mmc comexp.msc /32
The 32-bit version of Component Services correctly registers 32-bit DCOM applications for remote activation.

Related topics
S
e
t
t
i
n
g
P
r
o
c
e
s
s
-
W
i
d
e
S
e
c
u
r
i
t
y
Setting Process-Wide Security with
CoInitializeSecurity
1/7/2020 • 2 minutes to read • Edit Online

The CoInitializeSecurity function allows you to control complex security scenarios by setting security for an
application programmatically. This topic describes scenarios when you might use CoInitializeSecurity and
provides some details on how you use it.
There are several reasons why you might want to use CoInitializeSecurity to set process-wide security within
your program. For example, although you can set the authentication level and the access permissions for the
application using dcomcnfg.exe, the default impersonation level for the computer might not be the one you want
for your process. The only way to change this setting for your process is to call CoInitializeSecurity.
If you want to use the Schannel security provider, you must specify it as an authentication service in a call to
CoInitializeSecurity.
Another common scenario in which you might set process-wide security programmatically is when you would like
to set default security for the entire process but you have one or more objects within that process that expose
interfaces with special security requirements. In this case, you can call CoInitializeSecurity to set security for the
process, allowing COM to handle most of the security checks, and you can call other methods to set security for
the objects with special security needs. Calling these methods and functions is described in Setting Security at the
Interface Proxy Level.
If your application has very specialized security requirements, such as allowing certain groups access to different
objects depending on the time of day, you might want to handle all of your security programmatically, ensuring
that COM does no automatic checking for you at all. To do this, you must call CoInitializeSecurity, setting the
dwAuthnLevel parameter to none and the pVoid parameter to NULL. If you have your own security package you
would also need to register it in the pAuthnSvc parameter. Then you can handle all of your own security
programmatically through calls to the proxy-level interface and functions described in Setting Security at the
Interface Proxy Level.
CoInitializeSecurity offers a rich set of capabilities. If you call CoInitializeSecurity, the registry values are
ignored and the security initialization values you pass in to the call are used instead. Depending on the result you
want, the first parameter, pVoid, can point to three different types of values: a SECURITY_DESCRIPTOR , an
IAccessControl object, or a pointer to an AppID. In most cases, you will use Windows functions to create a
SECURITY_DESCRIPTOR that pVoid will point to.
However, pVoid can also point to an IAccessControl object.
To indicate to CoInitializeSecurity that you are passing an IAccessControl object to pVoid, you must pass the
EOAC_ACCESS_CONTROL value to the dwCapabilities parameter. Since CoInitializeSecurity caches the results
of access checks, the access control list must not be changed after calling CoInitializeSecurity.
Another type of value you can pass to the pVoid parameter is a pointer to a GUID, which is the AppID of your
application. If pVoid is a pointer to an AppID, you must specify EOAC_APPID in the pCapabilities parameter so
that the function knows what value to expect in pVoid. If pVoid points to an AppID, CoInitializeSecurity uses
only the registry for authentication values and ignores all other parameters to CoInitializeSecurity.

Related topics
S
e
t
t
i
n
g
P
r
o
c
e
s
s
-
W
i
d
e
S
e
c
u
r
i
t
y
Setting Process-Wide Security Through the Registry
1/7/2020 • 2 minutes to read • Edit Online

If you want to set security for an entire process, one solution is to set the security levels you want in the registry. If
your application cannot call CoInitializeSecurity or if you prefer not to use programmatic security, this might be
a good option. If you decide to set process-wide security using the registry, you should be aware that if you call
CoInitializeSecurity within your program COM will use the values in CoInitializeSecurity and ignore the
registry values.
There are two ways to set security in the registry for your application:
You can use Dcomcnfg.exe, which provides a simple user interface for modifying security values. All COM
servers can be configured using Dcomcnfg.exe. For more information, see Setting Process-Wide Security Using
DCOMCNFG. However, client applications do not normally appear in Dcomcnfg.exe unless the client creates a
GUID and enters it in the registry.
You can set security values under the AppID key for the application. The rest of this topic explains how to set
security in the registry using the AppID key.
An AppID is a GUID that represents a server process for one or more classes. Each class is associated with exactly
one AppID, and AppIDs can be assigned only to EXEs. DLLs do not get AppIDs unless they are running in a
surrogate, and then it is the surrogate process that has the AppID. If multiple DLLs are loaded into a surrogate,
each surrogate has only one AppID.
For some COM servers, the registration code generates an AppID and places entries in the registry that map the
AppID to the name of the executable. But some COM servers do not provide this functionality. However, if the
server's registration code adds an entry for HKCR\CLSID {ServerCLSID }\LocalServer32 when dcomcnfg.exe is
run, it will automatically add an AppID for the CLSID.
For a COM client that is not a server, this mapping is not created because the client is never registered. Therefore,
to set security using the AppID key, the client must create the necessary registry entries, either programmatically
by using the registry functions or by using regedit.
If you decide to set process-wide security in the registry under the AppID key, be aware that there are two named
values under the AppID key that you can set without having administrator permissions:
AccessPermission
AuthenticationLevel
The AuthenticationLevel and AccessPermission values are set independently and have separate default values.
If the AuthenticationLevel value is not present, the LegacyAuthenticationLevel value is used as the default.
Similarly, if the AccessPermission value is not present, the DefaultAccessPermission value is used as the default.
However, the AuthenticationLevel and the AccessPermission values are interrelated in the following ways:
If the AuthenticationLevel is none, the AccessPermission and DefaultAccessPermission values are
ignored for that application.
If the AuthenticationLevel is not present and the LegacyAuthenticationLevel is none, the
AccessPermission and DefaultAccessPermission values are ignored for that application.

Related topics
S
e
t
t
i
n
g
P
r
o
c
e
s
s
-
W
i
d
e
S
e
c
u
r
i
t
y
Setting Security at the Interface Proxy Level
1/7/2020 • 2 minutes to read • Edit Online

Sometimes the client needs fine-grained control over the security on calls to particular interfaces. For example,
security might be set at a low level for the process but calls to a particular interface might require a higher
authentication level, such as encryption. The methods of the IClientSecurity interface allow the client to change
the security settings associated with calls to a particular interface by controlling the security settings at the
interface-proxy level.
The client can query an existing object for IClientSecurity and then call the IClientSecurity::QueryBlanket
method to find out what the current security settings are for a particular interface proxy. The
IClientSecurity::SetBlanket method can be used to modify the security settings for an individual interface
proxy on the object before calling one of the interface's methods. The new settings apply to any future callers of
this particular interface. The IClientSecurity::CopyProxy method provides a way for the client to copy an
interface proxy so that subsequent calls to SetBlanket on the copy do not affect callers of the original proxy.
SetBlanket is commonly used to raise the authentication level for a particular interface proxy to a higher level of
security protection. However, in some situations, it might also be helpful to lower the authentication level for a
particular interface proxy. For instance, suppose the default authentication level for the process is some value
other than RPC_C_AUTHN_LEVEL_NONE and the client and server are in separate domains that do not trust
each other. In this case, calls to the server will fail unless the client calls SetBlanket to lower the authentication
level to RPC_C_AUTHN_LEVEL_NONE.
Clients using the default implementation of IClientSecurity provided by the proxy manager can call the
CoQueryProxyBlanket, CoSetProxyBlanket, and CoCopyProxy helper functions instead of calling
IClientSecurity methods directly. The helper functions simplify the code but are slightly less efficient than calling
the corresponding IClientSecurity methods directly.
The IClientSecurity interface is implemented locally for the client by the proxy manager. Some custom
marshaled objects might not support IClientSecurity.
IClientSecurity works with all supported authentication services (currently NTLMSSP, Schannel, and the
Kerberos v5 protocol).

Related topics
S
e
t
t
i
n
g
S
e
c
u
r
i
t
y
f
o
r
C
O
M
A
p
p
l
i
c
a
t
i
o
n
s
Enabling COM Security Using DCOMCNFG
1/7/2020 • 2 minutes to read • Edit Online

Dcomcnfg.exe provides a user interface for modifying certain settings in the registry. By using Dcomcnfg.exe, you
can enable security either on a computer-wide or a process-wide basis. You can enable security for a particular
computer so that when a process does not provide its own security settings, either programmatically or through
registry values, the values set by Dcomcnfg.exe will be used. Or you can use Dcomcnfg.exe to enable security for a
particular application only.
When enabling security, there are two primary tasks to accomplish:
Set an authentication level that is not None.
Set permissions, including both launch and access permissions.
The steps taken to accomplish these tasks depend on whether you are enabling security for the whole computer or
just for a particular application. Also, you may want to set other values for the computer or application.

NOTE
You must be an administrator to run Dcomcnfg.exe.

The following topics provide step-by-step procedures on how to set security with Dcomcnfg.exe:
Setting System-Wide Security Using DCOMCNFG
Setting Processwide Security Using DCOMCNFG

Related topics
S
e
c
u
r
i
t
y
i
n
C
O
M

T
u
r
n
i
n
g
O
f
f
S
e
c
u
r
i
t
y
Turning Off Security
1/7/2020 • 2 minutes to read • Edit Online

There are several reasons why you might decide to turn off the security that COM provides. When developing
applications, it might be helpful to turn security off initially to allow you to focus on other functionality within your
application. Then, you can add security features to your design when you are ready. To facilitate debugging, you
may want to turn off security and then add security features one at a time. Finally, some applications do not need
security and might run faster if no security checks are done.
The following topics provide step-by-step procedures:
Turning Off Activation Security
Turning Off Call Security

Related topics
E
n
a
b
l
i
n
g
C
O
M
S
e
c
u
r
i
t
y
U
s
i
n
g
D
C
O
M
C
N
F
G
S
e
c
u
r
i
t
y
i
n
C
O
M
Turning Off Activation Security
1/7/2020 • 2 minutes to read • Edit Online

Normally, activation uses default security settings. However, you can control activation security by specifying a
COAUTHINFO structure, which is a member of the COSERVERINFO structure that is passed to the activation
functions. If the client specifies an authentication level of RPC_C_AUTHN_LEVEL_NONE in the COAUTHINFO
structure, authentication is not attempted. Otherwise, secure activation is attempted, and if authentication fails,
activation fails.
If the client does not specify an explicit COAUTHINFO structure and instead sets the pointer to NULL, COM will
attempt to authenticate the client. If it cannot authenticate the client, COM checks the launch permission security
descriptor to see whether there is a NULL DACL or an ACL that allows access to Everyone. If this check succeeds,
the server is launched. Therefore, even if the client does not specify a COAUTHINFOstructure, unsecure activation
may take place when the server allows it.

NOTE
To allow unauthenticated network users to run a COM application, the application roles must include the Anonymous user.
Starting with Windows Server 2003, by default, the Anonymous user is not included in the Everyone group.

Why would a client want to turn off activation security explicitly even though unsecure activation will eventually
take place if the server allows it? Because explicitly turning off activation security increases performance when the
client does not want or need security checks.
The following things must be done to explicitly turn off activation security:
The client must specify an authentication level of RPC_C_AUTHN_LEVEL_NONE in the COAUTHINFO
structure that is a member of the COSERVERINFO structure supplied to the activation function.
The client must specify an impersonation level of RPC_C_IMP_LEVEL_IMPERSONATE in the COAUTHINFO
structure that is a member of the COSERVERINFO structure supplied to the activation function. If this value is
not passed, you will get RPC_S_SERVER_UNAVAILABLE.
The server must specify Everyone for Default Launch Permissions. The recommended way to perform this
task is to use Dcomcnfg.exe as follows:
1. Run Dcomcnfg.exe.
2. On the Applications page, select the application that represents the server. Click the Properties button
(or double-click the selected application).
3. On the Security property page, click the Use Custom Launch Permissions button.
4. Click the Edit button in the Launch Permissions area.
5. In the Registry Value Permissions dialog box, click the Add button.
6. Select the entry for Everyone in the list box.
7. In the Type of Access list box, choose Allow Launch.
8. Click the OK button.
NOTE
In Windows Server 2003, the authentication capability for the COM+ system application includes the value
EOAC_DISABLE_AAA. This value, which disables activate-as-activator (AAA) activations, is used in the CoInitializeSecurity
call when launching the system application. Setting the authentication capability to EOAC_DISABLE_AAA allows an
application that runs under a privileged account (such as LocalSystem) to help prevent its identity from being used to launch
untrusted components.

Related topics
T
u
r
n
i
n
g
O
f
f
C
a
l
l
S
e
c
u
r
i
t
y
Turning Off Call Security
1/7/2020 • 2 minutes to read • Edit Online

Call security determines whether a client has permission to call a server's methods. There are two ways to disable
call security: One involves using Dcomcnfg.exe to modify the registry, and the other requires calls to
CoInitializeSecurity.
Turning Off Call Security Using DCOMCNFG
Turning Off Call Security Programmatically
Related topics

Turning Off Call Security Using DCOMCNFG


Call security can most easily be turned off by using Dcomcnfg.exe to modify the registry. However, using
Dcomcnfg.exe to turn security off will work only if both the client and the server do not call CoInitializeSecurity.
This is because when CoInitializeSecurity is called, DCOM ignores the registry settings and uses the values
supplied to CoInitializeSecurity instead.
To turn off security with Dcomcnfg.exe, both the client and the server must set their Authentication Levels to None.
The following steps must be completed:
1. Run Dcomcnfg.exe.
2. On the Applications page, select the application that represents the server. Click the Properties button (or
double-click the selected application).
3. Click the General tab.
4. From the Default Authentication Level list box, select (None).
5. Click the Apply button to apply changes; however, changes are not applied to any running instances of the
application.
6. If the client appears on the list on the Applications page, repeat steps 2 through 5, choosing the client instead of
the server for step 2. Then click the OK button. If the client is not on the list, you can do one of the following
three things:
You can set the client's Authentication Level to None on a computer-wide basis by using Dcomcnfg.exe.
(See the warning and the procedure below.)
You can set the client's authentication level to None programmatically.
You can create an AppID key for the client to indicate an authentication level of None. (See Setting
Process-Wide Security Through the Registry.)
To set the Authentication Level to None on a computer-wide basis:

NOTE
Setting the computer-wide Authentication Level to None is extremely unsecure.

1. Run Dcomcnfg.exe.
2. Choose the Default Properties tab.
3. From the Default Authentication Level list box, choose (None).
4. Click the OK button.
Turning Off Call Security Programmatically
To turn call security off programmatically, both the client and the server must call CoInitializeSecurity, setting
the authentication level in the dwAuthnLevel parameter to RPC_C_AUTHN_LEVEL_NONE.

Related topics
T
u
r
n
i
n
g
O
f
f
A
c
t
i
v
a
t
i
o
n
S
e
c
u
r
i
t
y
Server-Side Security
1/7/2020 • 2 minutes to read • Edit Online

The server can retrieve security information about a caller or impersonate the caller by using the methods of
IServerSecurity. An implementation of IServerSecurity is supplied by COM on the context object for the current
call when standard marshaling is used. However, this interface may be absent for some custom-marshaled
interfaces.
When a call arrives at the server, the server can call CoGetCallContext to obtain a pointer to the IServerSecurity
interface. With this pointer, IServerSecurity methods can be called by the server to find out what the client's
authentication settings are and to impersonate the client, if needed. The IServerSecurity object is valid on any
thread in the apartment until the call represented by IServerSecurity completes. For more information about
impersonation, see Impersonation and Cloaking.
The following helper functions that rely on the call context object's IServerSecurity interface implementation are
also available:
CoQueryClientBlanket
CoImpersonateClient
CoRevertToSelf

Related topics
S
e
c
u
r
i
t
y
i
n
C
O
M
Security Blanket Negotiation
1/7/2020 • 2 minutes to read • Edit Online

A security blanket is a group of values that describe the security settings that apply to all proxies in a process or to
just a particular interface proxy. A security blanket comprises the following values:
Authentication service
Authorization service
Principal name
Authentication level
Impersonation level
Authentication identity
Capabilities
An access control list (ACL ) (servers only)
Security blanket negotiation is the process that COM uses to choose the security settings for a proxy when it is
created. This process involves comparing the server's security blanket with the client's security blanket and using
those values to create an appropriate default security blanket for the proxy. The following paragraphs explain
where the client's and the server's security blankets come from and describe how COM negotiates the security
blanket for the proxy using the client's and server's security blankets.
The client and the server can each call CoInitializeSecurity to specify their respective security blankets. If an
application doesn't call CoInitializeSecurity explicitly, COM calls it implicitly for the application, using
appropriate default values. For more information about these default values, see COM Security Defaults.
Some parameters to CoInitializeSecurity apply when the application is a server, and some apply when the
application is a client. When the application is acting as a server, these parameters are relevant: an ACL, a list of
authentication service/authorization service/principal name tuples, and an authentication level. A server's call to
CoInitializeSecurity, whether implicit or explicit, determines the server's security blanket, which remains fixed.
When the application is acting as a client, the following values passed to CoInitializeSecurity are relevant: an
authentication level, an impersonation level, the authentication identity, and capabilities. A client's implicit or
explicit call to CoInitializeSecurity indicates the security blanket that the client wants.
When a proxy is created, COM uses the values specified by the server's security blanket and the client's security
blanket to negotiate a default security blanket that is appropriate for the proxy. COM picks an authentication
service that works on both the client and server. The authorization service and principal name are chosen to work
with the authentication service. For the authentication level, COM chooses the higher of the authentication levels
specified by the client and the server. The impersonation level and the capabilities chosen by COM are the ones
specified by the client. The authentication identity is the one specified by the client for the chosen authentication
service.
Once the default security blanket has been computed, its values are assigned to the newly created proxy. The client
can override the security settings for the proxy by calling IClientSecurity::SetBlanket. The values specified to
SetBlanket are not negotiated; they are simply assigned to the specified proxy. However, if default parameters
(such as RPC_C_IMP_LEVEL_DEFAULT) are passed to SetBlanket, COM uses the previously described security
blanket negotiation algorithm to compute the default parameters.

Related topics
S
e
c
u
r
i
t
y
i
n
C
O
M
COM and Security Packages
1/7/2020 • 2 minutes to read • Edit Online

Windows supports NTLMSSP (LAN Manager Security Support Provider), the Kerberos v5 authentication
protocol, and the Schannel security package, which provides the PCT 1.0, SSL 2.0, SSL 3.0, and TLS 1.0 protocols.
Also supported is Snego, which checks for available security packages and selects the most appropriate one.
The following table shows the levels of authentication supported by the various security packages.

SERVER/CLIENT AUTHENTICATION SECURITY PACKAGE SUPPORT

Neither can get the name of the other. None

The client can authenticate the server, but not vice versa. Schannel

The client cannot discover the server, but the server can get NTLMSSP
the user ID of the client.

Mutual authentication: Both the client and server can know NTLMSSP (locally), Kerberos v5 protocol, and Schannel
the name of the other, if permission is granted.

For more information about these security packages, see the following topics in this section:
NTLMSSP
Kerberos v5 Protocol
Schannel
Snego

Related topics
S
e
c
u
r
i
t
y
i
n
C
O
M
NTLMSSP
1/7/2020 • 2 minutes to read • Edit Online

NTLMSSP, whose authentication service identifier is RPC_C_AUTHN_WINNT, is a security support provider that
is available on all versions of DCOM. It uses the NTLM protocol for authentication. NTLM never actually transmits
the user's password to the server during authentication. Therefore, the server cannot use the password during
impersonation to access network resources that the user would have access to. Only local resources can be
accessed.
NTLM works both locally and across computers. That is, if the client and server are on different computers, NTLM
can still make sure the client is who it claims to be.
With NTLM, the client's identity is represented by a domain name, user name, and a password or token. When a
server calls CoQueryClientBlanket, the client's domain name and user name are returned. However, when a
server calls CoImpersonateClient, the client's token is returned. If there is no trust relationship between client
and server and if the server has a local account with the same name and password as the client, that account will
be used to represent the client.
NTLM supports mutual authentication cross-thread and cross-process (locally only). If the client specifies the
principal name of the server in the form domain\user in a call to IClientSecurity::SetBlanket, the server's
identity must match that principal name or the call will fail. If the client specifies NULL, the server's identity will not
be checked.
NTLM additionally supports the delegate impersonation level cross-thread and cross-process (locally only).

Related topics
C
O
M
a
n
d
S
e
c
u
r
i
t
y
P
a
c
k
a
g
e
s
Kerberos v5 Protocol
1/7/2020 • 2 minutes to read • Edit Online

The Kerberos v5 authentication protocol has an authentication service identifier of


RPC_C_AUTHN_GSS_KERBEROS. The Kerberos protocol defines how clients interact with a network
authentication service and was standardized by the Internet Engineering Task Force (IETF ) in September 1993, in
document RFC 1510. Clients obtain tickets from the Kerberos Key Distribution Center (KDC ), and they present
these tickets to servers when connections are established. Kerberos tickets represent the client's network
credentials.
Like NTLM, the Kerberos protocol uses the domain name, user name, and password to represent the client's
identity. The initial Kerberos ticket obtained from the KDC when the user logs on is based on an encrypted hash of
the user's password. This initial ticket is cached. When the user tries to connect to a server, the Kerberos protocol
checks the ticket cache for a valid ticket for that server. If one is not available, the initial ticket for the user is sent to
the KDC along with a request for a ticket for the specified server. That session ticket is added to the cache, and it
can be used to connect to the same server until the ticket expires.
When a server calls CoQueryClientBlanket using the Kerberos protocol, the client's domain name and user
name are returned. When a server calls CoImpersonateClient, the client's token is returned. These behaviors are
the same as when using NTLM.
The Kerberos protocol works across computer boundaries. The client and server computers must both be in
domains, and those domains must have a trust relationship.
The Kerberos protocol requires mutual authentication and supports it remotely. The client must specify the
principal name of the server, and the server's identity must match that principal name exactly. If the client specifies
NULL for the server's principal name or if the principal name doesn't match the server, the call will fail.
With the Kerberos protocol, the impersonation levels identify, impersonate, and delegate can be used. When a
server calls CoImpersonateClient, the token returned is valid off the computer for some time period between 5
minutes and 8 hours. After this time, it can be used on the server computer only. If a server is "run as activator" and
the activation is done with the Kerberos protocol, the server's token will expire between 5 minutes and 8 hours
after activation.
The Kerberos v5 authentication protocol implemented by Windows supports cloaking.

Related topics
C
O
M
a
n
d
S
e
c
u
r
i
t
y
P
a
c
k
a
g
e
s
Schannel
1/7/2020 • 11 minutes to read • Edit Online

The Secure Channel (Schannel) security package, whose authentication service identifier is
RPC_C_AUTHN_GSS_SCHANNEL, supports the following public-key based protocols: SSL (Secure Sockets
Layer) versions 2.0 and 3.0, Transport Layer Security (TLS ) 1.0, and Private Communication Technology (PCT) 1.0.
TLS 1.0 is a standardized, slightly modified version of SSL 3.0 that was issued by the Internet Engineering Task
Force (IETF ) in January 1999, in document RFC 2246. Because TLS has been standardized, developers are
encouraged to use TLS rather than SSL. PCT is included for backward compatibility only and should not be used
for new development. When the Schannel security package is used, DCOM automatically negotiates the best
protocol, depending on the client and server capabilities.
The following topics briefly describe the TLS protocol and how it works with DCOM.
When to Use TLS
Brief Overview of How TLS Works
X.509 Certificates
Client Certificates
Using TLS in COM
How a Server Sets the Security Blanket
How a Client Sets the Security Blanket
How a Client Changes the Security Blanket
Example: Client Changes the Security Blanket
Related topics

NOTE
All the information about the TLS protocol in these sections also applies to the SSL and PCT protocols.

When to Use TLS


TLS is the only security option available when servers need to prove their identity to anonymous clients. This is
particularly important for websites that want to participate in e-commerce because it helps protect the
transmission of sensitive information such as credit card numbers. TLS assures that the e-commerce customers
can be certain of whom they are doing business with because they are given proof of the server's identity. It also
gives the e-commerce server the efficiency of not having to concern itself with authenticating the identity of each
of its customers.
TLS requires that all servers prove their identity to clients. Additionally, TLS provides the option of having clients
prove their identity to servers. This mutual authentication can be useful in restricting the access of certain
webpages in a large corporate intranet.
TLS supports the strongest authentication levels and offers an open architecture that permits encryption strength
to increase over time to keep up with technological innovation. TLS is the best choice for environments where the
highest level of security is desired for the data in transit.

Brief Overview of How TLS Works


TLS is built upon a public key infrastructure (PKI), which uses public/private key pairs for enabling data encryption
and establishing data integrity, and uses X.509 certificates for authentication.
Many security protocols, such as the Kerberos v5 protocol, depend on a single key to both encrypt and decrypt
data. Such protocols therefore depend on the secure exchange of encryption keys; in the Kerberos protocol, this is
done through tickets obtained from the Key Distribution Center (KDC ). This requires that everyone using the
Kerberos protocol be registered with the KDC, which would be an impractical limitation for an e-commerce web
server that is intended to attract millions of customers from around the world. TLS therefore relies upon a PKI,
which uses two keys for data encryption—when one key of the pair encrypts the data, only the other key of the
pair can decrypt it. The principle benefit of this design is that encryption can be performed without requiring the
secure exchange of encryption keys.
A PKI uses a technique where one of the keys is kept private and is available only to the principal to whom it is
registered, while the other key is made public for anyone to access. If someone wants to send a private message to
the owner of a key pair, the message can be encrypted with the public key and only the private key can be used to
decrypt the message.
Key pairs are also used to verify the integrity of the data being sent. To do this, the owner of the key pair can attach
a digital signature to the data before sending it. Creating a digital signature involves calculating a hash of the data
and encrypting the hash with the private key. Anyone who uses the public key to decrypt the digital signature is
assured that the digital signature must have come only from the person who owns the private key. Additionally,
the recipient can calculate a hash of the data using the same algorithm as the sender, and if the calculated hash
matches the one sent in the digital signature, the recipient can be certain that the data was not modified after it
was digitally signed.
One disadvantage of using a PKI for high-volume data encryption is its relatively slow performance. Because of
the intensive mathematics involved, encryption and decryption of data using an asymmetric cipher that depends
on a key pair can be up to 1,000 times slower than encryption and decryption using a symmetric cipher that
depends only on a single key. TLS therefore uses a PKI only for generating digital signatures and for negotiating
the session-specific single key that will be used by both the client and the server for bulk data encryption and
decryption. TLS supports a wide variety of single-key symmetric ciphers, and additional ciphers may be added in
the future.
For more information about the TLS handshake protocol, see TLS Handshake Protocol.
For more details regarding the cryptography behind the TLS protocol, see Cryptography Essentials.

X.509 Certificates
A critical issue that must be handled by a PKI is the ability to trust the authenticity of the public key that is being
used. When you use a public key issued to a company that you want to do business with, you want to be certain
that the key actually belongs to the company rather than to a thief who wants to discover your credit card number.
To guarantee the identity of a principal holding a key pair, the principal is issued an X.509 certificate by a
certification authority (CA). This certificate contains information that identifies the principal, contains the principal's
public key, and is digitally signed by the CA. This digital signature indicates that the CA believes that the public key
contained in the certificate truly belongs to the principal identified by the certificate.
And how do you trust the CA? Because the CA itself holds an X.509 certificate that has been signed by a higher-
level CA. This chain of certificate signatures continues until it reaches a root CA, which is a CA that signs its own
certificates. If you trust the integrity of the root CA of a certificate, you should be able to trust the authenticity of
the certificate itself. Therefore, picking root CAs that you are willing to trust is an important duty for a system
administrator.
Client Certificates
When security transport-layer protocols first emerged, their primary purpose was to guarantee that a client was
connecting to an authentic server and help protect the privacy of data while in transit. However, SSL 3.0 and TLS
1.0 also include support for the transmission of a client's certificate during the protocol's handshake. This optional
feature enables the mutual authentication of the client and server.
The decision of whether to use a client certificate should be made in the context of the application. Client
certificates are unnecessary if the primary requirement is authenticating the server. However, if client
authentication is essential, a client's certificate can be used rather than relying on custom authentication within the
application. Using client certificates is preferable over custom authentication because it gives users a single sign-
on scenario.

Using TLS in COM


TLS supports only the impersonate (RPC_C_IMP_LEVEL_IMPERSONATE ) level of impersonation. If COM
negotiates TLS as the authentication service on a proxy, COM will set the impersonation level to impersonate
regardless of the process default. For impersonation to work properly in TLS, the client must provide an X.509
certificate to the server and the server must have that certificate mapped to a particular user account on the server.
For more information, see the Step-by-Step Guide to Mapping Certificates to User Accounts.
TLS does not support cloaking. If a cloaking flag and TLS are specified in a CoInitializeSecurity or a
IClientSecurity::SetBlanket call, E_INVALIDARG will be returned.
TLS does not work with the authentication level set to None. The handshake between the client and server
examines the authentication level set by each and chooses the higher security setting for the connection.
The security parameters for TLS can be set by calling CoInitializeSecurity and CoSetProxyBlanket. The
following sections describe the nuances involved in making those calls.
How a Server Sets the Security Blanket
If a server wants to use TLS, it must specify Schannel (RPC_C_AUTHN_GSS_SCHANNEL ) as an authentication
service in the asAuthSvc parameter of CoInitializeSecurity. To prevent clients from connecting to the server by
using a less secure authentication service, the server should specify only Schannel as an authentication service
when it calls CoInitializeSecurity. The server cannot change the security blanket after it has called
CoInitializeSecurity.
To use TLS, the following parameters should be specified when a server calls CoInitializeSecurity:
pVoid should be either a pointer to an IAccessControl object or a pointer to a SECURITY_DESCRIPTOR. It
should not be NULL or a pointer to an AppID.
cAuthSvc cannot be 0 or -1. COM servers never chooses Schannel when cAuthSvcis -1.
asAuthSvc must specify Schannel as a possible authentication service. This is done by setting the following
SOLE_AUTHENTICATION_SERVICE parameters for the Schannel member of the
SOLE_AUTHENTICATION_LIST:
dwAuthnSvc must be RPC_C_AUTHN_GSS_SCHANNEL.
dwAuthzSvc should be RPC_C_AUTHZ_NONE. Currently, it is ignored.
pPrincipalName must be a pointer to a CERT_CONTEXT, cast as a pointer to OLECHAR, which
represents the server's X.509 certificate.
dwAuthnLevel indicates the minimum authentication level that will be accepted from clients for a successful
connection. It cannot be RPC_C_AUTHN_LEVEL_NONE.
dwCapabilities should not have the EOAC_APPID flag set. The EOAC_ACCESS_CONTROL flag should be set if
pVoid points to an IAccessControl object; it should not be set if pVoid points to a SECURITY_DESCRIPTOR.
For other flags that may be set, see CoInitializeSecurity.
For more information about using CoInitializeSecurity, see Setting Processwide Security with
CoInitializeSecurity.
How a Client Sets the Security Blanket
If a client wants to use TLS, it must specify Schannel (RPC_C_AUTHN_GSS_SCHANNEL ) in its list of
authentication services in the pAuthList parameter of CoInitializeSecurity. If Schannel is not specified as a
possible authentication service when CoInitializeSecurity is called, a later call to CoSetProxyBlanket (or
IClientSecurity::SetBlanket) will fail if it tries to specify Schannel as the authentication service.
The following parameters should be specified when a client calls CoInitializeSecurity:
dwAuthnLevel specifies the default authentication level that the client wants to use. It cannot be
RPC_C_AUTHN_LEVEL_NONE.
dwImpLevel must be RPC_C_IMP_LEVEL_IMPERSONATE.
pAuthList must have the following SOLE_AUTHENTICATION_INFO parameters as a member of the list:
dwAuthnSvc must be RPC_C_AUTHN_GSS_SCHANNEL.
dwAuthzSvc must be RPC_C_AUTHZ_NONE.
pAuthInfo is a pointer to a CERT_CONTEXT, cast as a pointer to void, which represents the client's
X.509 certificate. If the client does not have a certificate or does not wish to present its certificate to the
server, pAuthInfo must be NULL and an anonymous connection will be attempted with the server.
dwCapabilities is a set of flags that indicate additional client capabilities. See CoInitializeSecurity for
information about which flags should be set.
For more information about using CoInitializeSecurity, see Setting Processwide Security with
CoInitializeSecurity.
How a Client Changes the Security Blanket
If a client wants to use TLS but change the security blanket after calling CoInitializeSecurity, it must call either
CoSetProxyBlanket or IClientSecurity::SetBlanket with parameters similar to those used in the call to
CoInitializeSecurity, with the following differences:
pServerPrincName indicates the principal name of the server, in either msstd or fullsic format. For information
on these formats, see Principal Names. If the client has the server's X.509 certificate, it can find the principal
name by calling RpcCertGeneratePrincipalName.
pAuthInfo is a pointer to a CERT_CONTEXT, cast as a pointer to RPC_AUTH_IDENTITY_HANDLE, which
represents the client's X.509 certificate. If the client does not have a certificate or does not wish to present its
certificate to the server, pAuthInfo must be NULL and an anonymous connection will be attempted with the
server.
dwCapabilities consists of flags that indicate additional client capabilities. Only four flags can be used to change
security blanket settings: EOAC_DEFAULT, EOAC_MUTUAL_AUTH, EOAC_ANY_AUTHORITY (this flag is
deprecated), and EOAC_MAKE_FULLSIC. For more information, see CoSetProxyBlanket.
For more information about using CoSetProxyBlanket, see Setting Security at the Interface Proxy Level.
Example: Client Changes the Security Blanket
The following example demonstrates how a client can change the security blanket to accommodate a request from
the server for the client to provide its X.509 certificate. Error handling code is omitted for brevity.

void ClientChangesSecurity ()
{
HCRYPTPROV provider = 0;
HCERTSTORE cert_store = NULL;
PCCERT_CONTEXT client_cert = NULL;
PCCERT_CONTEXT server_cert = NULL;
WCHAR *server_princ_name = NULL;
ISecret *pSecret = NULL;
MULTI_QI server_instance;
COSERVERINFO server_machine;
SOLE_AUTHENTICATION_LIST auth_list;
SOLE_AUTHENTICATION_INFO auth_info[1];

// Specify all the authentication info.


// The client is willing to connect using SChannel,
// with no client certificate.
auth_list.cAuthInfo = 1;
auth_list.aAuthInfo = auth_info;
auth_info[0].dwAuthnSvc = RPC_C_AUTHN_GSS_SCHANNEL;
auth_info[0].dwAuthzSvc = RPC_C_AUTHZ_NONE;
auth_info[0].pAuthInfo = NULL; // No certificate

// Initialize client security with no client certificate.


CoInitializeSecurity( NULL, -1, NULL, NULL,
RPC_C_AUTHN_LEVEL_PKT,
RPC_C_IMP_LEVEL_IMPERSONATE, &auth_list,
EOAC_NONE, NULL );

// Specify info for the proxy.


server_instance = {&IID_ISecret, NULL, S_OK};
server_machine = {0, L"ServerMachineName", NULL, 0};

// Create a proxy.
CoCreateInstanceEx( CLSID_Secret, NULL, CLSCTX_REMOTE_SERVER,
&server_machine, 1, &server_instance);
pSecret = (ISecret *) server_instance.pItf;

//** The client obtained the server's certificate during the handshake.
//** The server requests a certificate from the client.

// Get the default certificate provider.


CryptAcquireContext( &provider, NULL, NULL, PROV_RSA_SCHANNEL, 0 );

// Open the certificate store.


cert_store = CertOpenSystemStore( provider, L"my" );

// Find the client's certificate.


client_cert =
CertFindCertificateInStore( cert_store,
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
0,
CERT_FIND_SUBJECT_STR,
L"ClientName", // Use the principal name
NULL );

// Find the fullsic principal name of the server.


RpcCertGeneratePrincipalName( server_cert, RPC_C_FULL_CERT_CHAIN,
&server_princ_name );

// Change the client's security:


// Increase the authentication level and attach a certificate.
CoSetProxyBlanket( pSecret, RPC_C_AUTHN_GSS_SCHANNEL,
RPC_C_AUTHZ_NONE,
server_princ_name, RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
RPC_C_IMP_LEVEL_IMPERSONATE,
(RPC_AUTH_IDENTITY_HANDLE *) client_cert,
EOAC_NONE );

cleanup:
if (server_princ_name != NULL)
RpcStringFree( &server_princ_name );
if (client_cert != NULL)
CertFreeCertificateContext(client_cert);
if (server_cert != NULL)
CertFreeCertificateContext(server_cert);
if (cert_store != NULL)
CertCloseStore( cert_store, CERT_CLOSE_STORE_CHECK_FLAG );
if (provider != 0 )
CryptReleaseContext( provider, 0 );
if (pSecret != NULL)
pSecret->Release();
CoUninitialize();
}

Related topics
C
O
M
a
n
d
S
e
c
u
r
i
t
y
P
a
c
k
a
g
e
s
Snego
1/7/2020 • 2 minutes to read • Edit Online

Snego, whose authentication service identifier is RPC_C_AUTHN_GSS_NEGOTIATE, does not actually provide
authentication services itself. Instead, it takes a list of authentication services and negotiates a service that will work
between the client and server. The authentication parameters are not used by Snego but are passed to the chosen
authentication service, which does the actual authentication. Snego was standardized by the Internet Engineering
Task Force (IETF ) in December 1998, in document RFC 2478.
Snego is useful when you don't know what authentication services the remote computer can provide.
To use Snego, both the client and the server must specify Snego as the authentication service. The server specifies
RPC_C_AUTHN_GSS_NEGOTIATE as the dwAuthnSvc member of one of the
SOLE_AUTHENTICATION_SERVICE structures in the asAuthSvc array parameter that is passed to
CoInitializeSecurity. The client can specify Snego by calling CoSetProxyBlanket and passing
RPC_C_AUTHN_GSS_NEGOTIATE as the dwAuthnSvc parameter. The client should also provide a list of possible
authentication services for Snego through the PackageList member of the SEC_WINNT_AUTH_IDENTITY_EX
structure that is passed to the pAuthInfo parameter in the call to CoSetProxyBlanket. If pAuthInfo is NULL,
Snego composes a list of authentication services from the security packages installed on the computer. Then
Snego sends the list of authentication services to the server, compares the list to the server's available
authentication services, and picks an authentication service to use for the connection.

NOTE
Schannel cannot be on the list of authentication services that Snego uses.

Clients can also specify Snego when they call CoInitializeSecurity. The dwAuthnSvc and pAuthInfo parameters
of CoSetProxyBlanket become members of a SOLE_AUTHENTICATION_INFO structure that is passed to
CoInitializeSecurity through its pAuthList parameter. The details of the values of those members are the same as
described in the preceding paragraph.
If Snego is used, calls to CoQueryProxyBlanket or CoQueryClientBlanket will return Snego as the
authentication service, rather than the actual authentication service that Snego picked for establishing the
connection.

Related topics
C
O
M
a
n
d
S
e
c
u
r
i
t
y
P
a
c
k
a
g
e
s
DCOM Security Enhancements in Windows XP
Service Pack 2 and Windows Server 2003 Service
Pack 1
1/7/2020 • 17 minutes to read • Edit Online

Windows Server XP Service Pack 2 (SP2) and Windows Server 2003 Service Pack 1 (SP1) introduce enhanced
default security settings for the Distributed Component Object Model (DCOM ). Specifically, they introduce more
granular rights that enable an administrator to have independent control over local and remote permissions for
launching, activating, and accessing COM servers.

What does DCOM do?


The Microsoft Component Object Model (COM ) is a platform-independent, distributed, object-oriented system for
creating binary software components that can interact. The Distributed Component Object Model (DCOM ) allows
applications to be distributed across locations that make the most sense to you and to the application. The DCOM
wire protocol transparently provides support for reliable, secure, and efficient communication between COM
components.

Who does this feature apply to?


If you use COM only for in-process COM components, this feature does not apply to you.
This feature applies to you if you have a COM server application that meets one of the following criteria:
The access permission for the application is less stringent than the launch permission, which is necessary to run
the application.
The application is usually activated by a remote COM client without using an administrative account.
The application is meant to be used only locally. This means you can restrict your COM server application so it
is not remotely accessible.

What new functionality is added to this feature in Windows XP Service


Pack 2 and Windows Server 2003 Service Pack 1?
Computer-wide restrictions
A change has been made in COM to provide computer-wide access controls that govern access to all call,
activation, or launch requests on the computer. The simplest way to think about these access controls is as an
additional AccessCheck call that is done against a computer-wide access control list (ACL ) on each call, activation,
or launch of any COM server on the computer. If the AccessCheck fails, the call, activation, or launch request is
denied. This is in addition to any AccessCheck that is run against the server-specific ACLs. In effect, it provides a
minimum authorization standard that must be passed to access any COM server on the computer. There is a
computer-wide ACL for launch permissions to cover activate and launch rights, and a computer-wide ACL for
access permissions to cover call rights. These can be configured through the Component Services Microsoft
Management Console (MMC ).
These computer-wide ACLs provide a way to override weak security settings specified by a specific application
through CoInitializeSecurity or application-specific security settings. This provides a minimum security standard
that must be passed, regardless of the settings of the specific server.
These ACLs are checked when the interfaces exposed by RPCSS are accessed. This provides a method to control
access to this system service.
These ACLs provide a centralized location where an administrator can set general authorization policy that applies
to all COM servers on the computer.

NOTE
Changing the computer-wide security settings will affect all COM server applications, and might prevent them from working
properly. If there are COM server applications that have restrictions that are less stringent than the computer-wide
restrictions, reducing the computer-wide restrictions might expose these applications to unwanted access. Conversely, if you
increase the computer-wide restrictions, some COM server applications might no longer be accessible by calling applications.

By default, Windows XP SP2 computer restriction settings are:

PERMISSION ADMINISTRATOR EVERYONE ANONYMOUS

Launch Local Launch Local Launch


Local Activation Local Activation
Remote Launch
Remote Activation

Access Local Access Local Access


Remote Access

By default, Windows Server 2003 SP 1 computer restriction settings are as follows.

DISTRIBUTED COM
USERS (BUILT IN
PERMISSION ADMINISTRATOR GROUP) EVERYONE ANONYMOUS

Launch Local Launch Local Launch Local Launch N/A


Local Activation Local Activation Local Activation
Remote Launch Remote Launch
Remote Activation Remote Activation

Access N/A Local Access Local Access Local Access


Remote Access Remote Access Remote Access

NOTE
Distributed COM Users is a new built-in group included with Windows Server 2003 SP1 to expedite the process of adding
users to the DCOM computer restriction settings. This group is part of the ACL used by the MachineAccessRestriction and
MachineLaunchRestriction settings, so removing users from this group will affect those settings.

Why is this change important? What threats does it help mitigate?


Many COM applications include some security-specific code (for example, calling CoInitializeSecurity), but use
weak settings, often allowing unauthenticated access to the process. There is currently no way for an administrator
to override these settings to force stronger security in earlier versions of Windows.
COM infrastructure includes the RPCSS, a system service that runs during system startup and always runs after
that. It manages activation of COM objects and the running object table and provides helper services to DCOM
remoting. It exposes RPC interfaces that can be called remotely. Because some COM servers allow
unauthenticated remote access, these interfaces can be called by anyone, including unauthenticated users. As a
result, RPCSS can be attacked by malicious users on remote, unauthenticated computers.
In earlier versions of Windows, there was no way for an administrator to understand the exposure level of the
COM servers on a computer. An administrator got an idea of the exposure level by systematically checking the
configured security settings for all the registered COM applications on the computer, but, given that there are
about 150 COM servers in a default installation of Windows, that task was daunting. There was no way to view the
settings for a server that incorporates security in the software, short of reviewing the source code for that software.
DCOM computer-wide restrictions mitigate these three problems. It also gives an administrator the capability to
disable incoming DCOM activation, launch, and calls.
What works differently?
By default, the Everyone group is granted local launch, local activation, and local access call permissions. This
enables all local scenarios to work without modification to the software or the operating system.
By default, in Windows XP SP2, the Everyone group is granted remote access call permissions. In Windows Server
2003 SP1, the Everyone and Anonymous groups are granted remote access permissions. This enables most COM
client scenarios, including the common case where a COM client passes a local reference to a remote server, in
effect turning the client into a server. In Windows XP SP2, this might disable scenarios that require
unauthenticated remote access calls.
Also by default, only members of the Administrators group are granted remote activation and launch permissions.
This disables remote activations by non-administrators to installed COM servers.
How do I resolve these issues?
If you implement a COM server and expect to support remote activation by a non-administrative COM client, then
you should consider whether the risk associated with enabling this process is acceptable or if you should modify
your implementation to not require remote activation by a non-administrative COM client or remote
unauthenticated calls.
If the risk is acceptable and you want to enable remote activation by a non-administrative COM client or remote
unauthenticated calls, you must change the default configuration for this feature.

NOTE
Changing the computer-wide security settings will affect all COM server applications, and might prevent them from working
properly. If there are COM server applications that have restrictions that are less stringent than the computer-wide
restrictions, reducing the computer-wide restrictions may expose these applications to unwanted access. Conversely, if you
increase the computer-wide restrictions, some COM server applications might no longer be accessible by calling applications.

You can change the configuration settings using either the Component Services Microsoft Management Console
(MMC ) or the Windows registry.
If you use the Component Services MMC snap-in, these settings can be configured on the COM Security tab of
the Properties dialog box for the computer you are managing. The Access Permissions area has been modified
to enable you to set computer-wide limits in addition to the standard default settings for COM servers.
Additionally, you can provide separate ACL settings for local and remote access under both limits and defaults.
In the Launch and Activation Permissions area, you can control the local and remote permissions as well as the
computer-wide limits and the defaults. You can specify both local and remote activation and launch permissions
independently.
Alternatively, you can configure these ACL settings using the registry.
These ACLs are stored in the registry at the following locations:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Ole\MachineAccessRestriction=ACL
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Ole\MachineLaunchRestriction=ACL

These are named values of type REG_BINARY that contain data that describe the ACL of the principals that can
access any COM class or COM object on the computer. The access rights in the ACL are:

COM_RIGHTS_EXECUTE 1
COM_RIGHTS_EXECUTE_LOCAL 2
COM_RIGHTS_EXECUTE_REMOTE 4
COM_RIGHTS_ACTIVATE_LOCAL 8
COM_RIGHTS_ACTIVATE_REMOTE 16

These ACLs can be created using normal security functions.

NOTE
To provide backward compatibility, an ACL can exist in the format used before Windows XP SP2 and Windows Server 2003
SP1, which uses only the access right COM_RIGHTS_EXECUTE, or it can exist in the new format used in Windows XP SP2 and
Windows Server 2003 SP1, which uses COM_RIGHTS_EXECUTE together with a combination of
COM_RIGHTS_EXECUTE_LOCAL, COM_RIGHTS_EXECUTE_REMOTE, COM_RIGHTS_ACTIVATE_LOCAL, and
COM_RIGHTS_ACTIVATE_REMOTE. Note that COM_RIGHTS_EXECUTE> must always be present; the absence of this right
generates an invalid security descriptor. Also note that you must not mix the old format and the new format within a single
ACL; either all access control entries (ACEs) must grant only the COM_RIGHTS_EXECUTE access right, or they all must grant
COM_RIGHTS_EXECUTE together with a combination of COM_RIGHTS_EXECUTE_LOCAL, COM_RIGHTS_EXECUTE_REMOTE,
COM_RIGHTS_ACTIVATE_LOCAL, and COM_RIGHTS_ACTIVATE_REMOTE.

NOTE
Only users with Administrator rights can modify these settings.

What existing functionality is changing in Windows XP Service Pack 2


and Windows Server 2003 Service Pack 1?
RPCSS runs as a network service
RPCSS is a key service for the RPC Endpoint Mapper and DCOM infrastructure. This service ran as Local System
in previous versions of Windows. To reduce the attack surface of Windows and provide defense in depth, the
RPCSS service functionality was split into two services. The RPCSS service with all the original functionality that
did not require Local System privileges now runs under the Network Service account. A new DCOMLaunch
service that includes functionality that requires Local System privileges runs under the Local System account.
Why is this change important?
This change reduces the attack surface and provides defense in depth for the RPCSS service because an elevation
of privilege in the RPCSS service is now limited to the Network Service privilege.
What works differently?
This change should be transparent to users because the combination of the RPCSS and DCOMLaunch services is
equivalent to the previous RPCSS service provided in prior versions of Windows.
More specific COM permissions
COM server applications have two types of permissions: launch permissions and access permissions. Launch
permissions control authorization to start a COM server during COM activation if the server is not already
running. These permissions are defined as security descriptors that are specified in registry settings. Access
permissions control authorization to call a running COM server. These permissions are defined as security
descriptors provided to the COM infrastructure through the CoInitializeSecurity API, or using registry settings.
Both launch and access permissions allow or deny access based on principals, and make no distinction as to
whether the caller is local to the server or remote.
The first change distinguishes the COM access rights, based on distance. The two distances that are defined are
Local and Remote. A Local COM message arrives by way of the Local Remote Procedure Call (LRPC ) protocol,
while a Remote COM message arrives by way of a remote procedure call (RPC ) host protocol like transmission
control protocol (TCP ).
COM activation is the act of getting a COM interface proxy on a client by calling CoCreateInstance or one of its
variants. As a side effect of this activation process, sometimes a COM server must be started to fulfill the client's
request. A launch permissions ACL asserts who is allowed to start a COM server. An access permissions ACL
asserts who is allowed to activate a COM object or call that object once the COM server is already running.
The second change is that the call and activation rights are separated to reflect to two distinct operations and to
move the activation right from the access permission ACL to the launch permission ACL. Because activation and
launching are both related to acquiring an interface pointer, activation and launch access rights logically belong
together in one ACL. And because you always specify launch permissions through configuration (as compared to
access permissions, which are often specified programmatically), putting the activation rights in the launch
permission ACL provides the administrator with control over activation.
The launch permission access control entries (ACEs) are broken into four access rights:
Local Launch (LL )
Remote Launch (RL )
Local Activate (LA)
Remote Activate (RA)
The access permission security descriptor is split into two access rights:
Local Access Calls (LC )
Remote Access Calls (RC )
This allows the administrator to apply very specific security configurations. For example, you can configure a COM
server so that it accepts local access calls from everyone, while only accepting remote access calls from
Administrators. These distinctions can be specified through changes to the COM permissions security descriptors.
Why is this change important? What threats does it help mitigate?
Earlier versions of the COM server application have no way to restrict an application so that it can only be used
locally without exposing the application on the network by way of DCOM. When a user has access to a COM
server application, they have access for both local and remote use.
A COM server application might expose itself to unauthenticated users to implement a COM callback scenario. In
this scenario, the application must also expose its activation to unauthenticated users, which might not be
desirable.
Precise COM permissions give flexibility to the administrator to control a computer's COM permission policy.
These permissions enable security for the described scenarios.
What works differently? Are there any dependencies?
To provide backward compatibility, existing COM security descriptors are interpreted to allow or deny both local
and remote access simultaneously. That is, an access control entry (ACE ) either allows both local and remote, or
denies both local and remote.
There are no backward-compatibility issues for call or launch rights. There is, however, an activation rights
compatibility issue. If, in the existing security descriptors for a COM server, the configured launch permissions are
more restrictive than the access permissions and are more restrictive than what is minimally required for client
activation scenarios, then the launch permissions ACL must be modified to give the authorized clients the
appropriate activation permissions.
For COM applications that use the default security settings, there are no compatibility issues. For applications that
are dynamically started using COM activation, most have no compatibility issues, because the launch permissions
must already include anyone who is able to activate an object. Otherwise, such applications generate activation
failures even before applying Windows XP SP2 or Windows Server 2003 SP1, when callers without launch
permission try to activate an object and the COM server is not already running.
The applications of most concern for compatibility issues are COM applications that are already started by some
other mechanism, such as Windows Explorer, or Service Control Manager. You can also start these applications by
a previous COM activation, which overrides the default access and launch permissions and specifies launch
permissions that are more restrictive than the call permissions. For more details about addressing this
compatibility issue, see "How do I resolve these issues?" in the next section.
If a system that is upgraded to Windows XP SP2 or Windows Server 2003 SP1 is rolled back to an earlier state,
any ACE that was edited to allow local access, remote access, or both, is interpreted to allow both local and remote
access. Any ACE that was edited to deny local access, remote access, or both, is interpreted to deny both local and
remote access. Whenever you uninstall a service pack, you should ensure that no newly set ACEs cause
applications to stop working.
How do I resolve these issues?
If you implement a COM server and you override the default security settings, confirm that the application-specific
launch permissions ACL grants activation permission to appropriate users. If it does not, you must change your
application-specific launch permission ACL to give appropriate users activation rights so applications and
Windows components that use DCOM do not fail. These application-specific launch permissions are stored in the
registry.
The COM ACLs can be created or modified using normal security functions.

What settings are added or changed in Windows XP Service Pack 2?


Cau t i on

Improper use of these settings can cause applications and Windows components that use DCOM to fail.
In the following table, these abbreviations are used:
LL - Local Launch
LA - Local Activation
RL - Remote Launch
RA - Remote Activation
LC - Local Access Calls
RC - Remote Access Calls
ACL - Access Control List

PREVIOUS DEFAULT
SETTING NAME LOCATION VALUE DEFAULT VALUE POSSIBLE VALUES
PREVIOUS DEFAULT
SETTING NAME LOCATION VALUE DEFAULT VALUE POSSIBLE VALUES

MachineLaunchRest HKEY_LOCAL_MACH Everyone - LL, LA, RL, Administrator: LL, LA, ACL
riction INE\SOFTWARE\ RA RL, RA
Microsoft\Ole Anonymous -
LL, LA, RL, RA
(This is a new registry
key. Based on existing
behavior, these are
the effective values.)

MachineAccessRestr HKEY_LOCAL_MACH Everyone - LC, RC Everyone: LC, RC ACL


iction INE\SOFTWARE\ Anonymous - LC, RC Anonymous: LC
Microsoft\Ole (This is a new registry
key. Based on existing
behavior, these are
the effective values.)

CallFailureLoggingL HKEY_LOCAL_MACH Not applicable. This registry key is 1 - Always log event
evel INE\SOFTWARE\ not present; however, log failures during a
Microsoft\Ole a missing key or value call in the COM
is interpreted as 2. Server process.
This event is not 2 - Never log event
logged by default. If log failures during a
you change this value call in the call server
to 1 to start logging process.
this information to
help you troubleshoot
an issue, be sure to
monitor the size of
your event log,
because this is an
event that can
generate a large
number of entries.

InvalidSecurityDesc HKEY_LOCAL_MACH Not applicable. This registry key is 1 - Always log event
riptorLoggingLevel INE\SOFTWARE\ not present; however, log failures when the
Microsoft\Ole a missing key or value COM infrastructure
is interpreted as 1. finds an invalid
This event is logged security descriptor.
by default. It should 2 - Never log event
rarely occur. log failures when the
COM infrastructure
finds an invalid
security descriptor.

DCOM:Machine (Group Policy object) Not applicable. Not defined Access control list in
Launch Restrictions in Computer SDDL format.
Security Descriptor Configuration Existence of this policy
Definition Language \Windows overrides values in
(SDDL) Syntax Settings\Local Policies MachineLaunchRestric
\Security Options tion, previously.

DCOM:Machine (Group Policy object) Not applicable. Not defined Access control list in
Access Restrictions in Computer SDDL format.
Security Descriptor Configuration Existence of this policy
Definition Language \Windows Settings overrides values in
(SDDL) Syntax \Local Policies MachineAccessRestric
\Security Options tion, previously.
What settings are added or changed in Windows Server 2003 Service
Pack 1?
NOTE
Improper use of these settings can cause applications and Windows components that use DCOM to fail.

In the following table, these abbreviations are used:


LL - Local Launch
LA - Local Activation
RL - Remote Launch
RA - Remote Activation
LC - Local Access Calls
RC - Remote Access Calls
ACL - Access Control List

PREVIOUS DEFAULT
SETTING NAME LOCATION VALUE DEFAULT VALUE POSSIBLE VALUES

MachineLaunchRest HKEY_LOCAL_MACH Everyone: LL, LA, RL, Administrator: LL, LA, ACL
riction INE\SOFTWARE\ RA RL, RA
Microsoft\Ole Anonymous: LL, LA, Everyone: LL, LA
RL, RA Distributed COM
(This is a new registry users: LL, LA, RL, RA
key. Based on existing
behavior, these would
be the effective
values.)

MachineAccessRestr HKEY_LOCAL_MACH Everyone: LC, RC Everyone: LC, RC ACL


iction INE\SOFTWARE\ Anonymous: LC, RC Anonymous: LC, RC
Microsoft\Ole (This is a new registry
key. Based on existing
behavior, these would
be the effective
values.)
PREVIOUS DEFAULT
SETTING NAME LOCATION VALUE DEFAULT VALUE POSSIBLE VALUES

CallFailureLoggingL HKEY_LOCAL_MACH Not applicable. This registry key is 1 - Always log event
evel INE\SOFTWARE\ not present; however, log failures when the
Microsoft\Ole a missing key or value COM infrastructure
is interpreted as 2. finds an invalid
This event is not security descriptor.
logged by default. If 2 - Never log event
you change this value log failures when the
to 1 to start logging COM infrastructure
this information to finds an invalid
help you troubleshoot security descriptor.
an issue, be sure to
monitor the size of
your event log,
because this is an
event that can
generate a large
number of entries.

InvalidSecurityDesc HKEY_LOCAL_MACH Not applicable. This registry key is 1 - Always log event
riptorLoggingLevel INE\SOFTWARE\ not present; however, log failures when
Microsoft\Ole a missing key or value COM infrastructure
is interpreted as 1. finds an invalid
This event is logged security descriptor.
by default. It should 2 - Never log event
rarely occur. log failures when
COM infrastructure
finds an invalid
security descriptor.

DCOM:Machine (Group Policy object) Not applicable. Not defined. Access control list in
Launch Restrictions in Computer SDDL format.
Security Descriptor Configuration Existence of this policy
Definition Language \Windows Settings overrides values in
(SDDL) Syntax \Local Policies MachineLaunchRestric
\Security Options tion, previously.

DCOM:Machine (Group Policy object) Not applicable. Not defined. Access control list in
Access Restrictions in Computer SDDL format.
Security Descriptor Configuration Existence of this policy
Definition Language \Windows Settings overrides values in
(SDDL) Syntax \Local Policies MachineAccessRestric
\Security Options tion, previously.

Related topics
S
e
c
u
r
i
t
y
i
n
C
O
M
Access Control Lists for COM
1/7/2020 • 2 minutes to read • Edit Online

Windows Server XP Service Pack 2 (SP 2) and Windows Server 2003 Service Pack 1 (SP 1) introduce security
enhancements for the Distributed Component Object Model (DCOM ). One of these enhancements is more specific
access rights for use in access control lists (ACLs). The access rights are:

COM_RIGHTS_EXECUTE 1
COM_RIGHTS_EXECUTE_LOCAL 2
COM_RIGHTS_EXECUTE_REMOTE 4
COM_RIGHTS_ACTIVATE_LOCAL 8
COM_RIGHTS_ACTIVATE_REMOTE 16

To provide backward compatibility, an ACL may exist in the format used before Windows XP SP 2 and Windows
Server 2003 SP 1, which uses only the access right COM_RIGHTS_EXECUTE, or it may exist in the new format
used in Windows XP SP 2 and Windows Server 2003 SP 1, which uses COM_RIGHTS_EXECUTE together with a
combination of COM_RIGHTS_EXECUTE_LOCAL, COM_RIGHTS_EXECUTE_REMOTE,
COM_RIGHTS_ACTIVATE_LOCAL, and COM_RIGHTS_ACTIVATE_REMOTE.

NOTE
COM_RIGHTS_EXECUTE must always be present; the absence of this right generates an invalid security descriptor.

You must not mix the old format and the new format within a single ACL; either all access control entries (ACEs)
must grant only the COM_RIGHTS_EXECUTE access right, or they all must grant COM_RIGHTS_EXECUTE
together with a combination of COM_RIGHTS_EXECUTE_LOCAL, COM_RIGHTS_EXECUTE_REMOTE,
COM_RIGHTS_ACTIVATE_LOCAL, and COM_RIGHTS_ACTIVATE_REMOTE.
The following is an example of an incorrectly formatted ACL:
Revision 1
Sbz1 0
Control 0x8004
SE_DACL_PRESENT
SE_SELF_RELATIVE
Owner: S-1-5-21-1597522630-148096252-1166023319-500 (no name mapped)
Group: S-1-5-21-1597522630-148096252-1166023319-500 (no name mapped)
DACL:
AclRevision 2
Sbz1 0
AclSize 128
AceCount 4
Sbz2 0
Ace[0]
AceType 0: ACCESS_ALLOWED_ACE_TYPE
AceFlags 0
AceSize 36
AccessMask 0x1
S-1-5-21-1597522630-148096252-1166023319-500 (no name mapped)
Ace[1]
AceType 0: ACCESS_ALLOWED_ACE_TYPE
AceFlags 0
AceSize 20
AccessMask 0xb
S-1-5-18 (Well Known Group: NT AUTHORITY\SYSTEM)
Ace[2]
AceType 0: ACCESS_ALLOWED_ACE_TYPE
AceFlags 0
AceSize 20
AccessMask 0x9
S-1-5-11 (Well Known Group: NT AUTHORITY\Authenticated Users)
SACL:
(null)

Note that the first access control entry (ACE ) grants COM_RIGHTS_EXECUTE (0x1) only, while the second ACE
grants COM_RIGHTS_EXECUTE, COM_RIGHTS_EXECUTE_LOCAL, and COM_RIGHTS_ACTIVATE_LOCAL (0xb),
and the third grants COM_RIGHTS_EXECUTE and COM_RIGHTS_ACTIVATE_LOCAL (0x9).
To correct this, the first ACE should be changed to grant COM_RIGHTS_EXECUTE in combination with one of the
other four access rights, or else the second and third ACEs should be changed to grant only
COM_RIGHTS_EXECUTE.

Related topics
D
C
O
M
S
e
c
u
r
i
t
y
E
n
h
a
n
c
e
m
e
n
t
s
i
n
W
i
n
d
o
w
s
X
P
S
e
r
v
i
c
e
P
a
c
k
2
a
n
d
W
i
n
d
o
w
s
S
e
r
v
e
r
2
0
0
3
S
e
r
v
i
c
e
P
a
c
k
1

S
e
c
u
r
i
t
y
i
n
C
O
M
The COM Elevation Moniker
1/7/2020 • 8 minutes to read • Edit Online

The COM elevation moniker allows applications that are running under user account control (UAC ) to activate
COM classes with elevated privileges. For more information, see Focus on Least Privilege.

When to Use the Elevation Moniker


The elevation moniker is used to activate a COM class to accomplish a specific and limited function that requires
elevated privileges, such as changing the system date and time.
Elevation requires participation from both a COM class and its client. The COM class must be configured to
support elevation by annotating its registry entry, as described in the Requirements section. The COM client must
request elevation by using the elevation moniker.
The elevation moniker is not intended to provide application compatibility. For example, if you want to run a legacy
COM application such as WinWord as an elevated server, you should configure the COM client executable to
require elevation, rather than activating the legacy application's class with the elevation moniker. When the
elevated COM client calls CoCreateInstance using the legacy application's CLSID, the client's elevated state will
flow to the server process.
Not all COM functionality is compatible with elevation. The functionality that will not work includes:
Elevation does not flow from a client to a remote COM server. If a client activates a remote COM server with
the elevation moniker, the server will not be elevated, even if it supports elevation.
If an elevated COM class uses impersonation during a COM call, it might lose its elevated privileges during the
impersonation.
If an elevated COM server registers a class in the running object table (ROT), the class will not be available to
non-elevated clients.
A process elevated by using the UAC mechanism does not load per-user classes during COM activations. For
COM applications, this means that the application's COM classes must be installed in the
HKEY_LOCAL_MACHINE registry hive if the application is to be used both by non-privileged and privileged
accounts. The application's COM classes need only be installed in the HKEY_USERS hive if the application is
never used by privileged accounts.
Drag and drop is not allowed from non-elevated to elevated applications.

Requirements
In order to use the elevation moniker to activate a COM class, the class must be configured to run as the launching
user or the 'Activate as Activator' application identity. If the class is configured to run under any other identity, the
activation returns the error CO_E_RUNAS_VALUE_MUST_BE_AAA.
The class must also be annotated with a "friendly" display name that is multilingual user interface (MUI)
compatible. This requires the following registry entry:

HKEY_LOCAL_MACHINE\Software\Classes\CLSID
{CLSID}
LocalizedString = displayName

If this entry is missing, the activation returns the error CO_E_MISSING_DISPLAYNAME. If the MUI file is missing,
the error code from the RegLoadMUIStringW function is returned.
Optionally, to specify an application icon to be displayed by the UAC user interface, add the following registry key:

HKEY_LOCAL_MACHINE\Software\Classes\CLSID
{CLSID}
Elevation
IconReference = applicationIcon

IconReference uses the same format as LocalizedString:


@pathtobinary,-resourcenumber
In addition, the COM component must be signed for the icon to be displayed.
The COM class must also be annotated as LUA-Enabled. This requires the following registry entry:

HKEY_LOCAL_MACHINE\Software\Classes\CLSID
{CLSID}
Elevation
Enabled = 1

If this entry is missing, then the activation returns the error CO_E_ELEVATION_DISABLED.
Note that these entries must exist in the HKEY_LOCAL_MACHINE hive, not the HKEY_CURRENT_USER or
HKEY_USERS hive. This prevents users from elevating COM classes that they did not also have the privileges to
register.

The Elevation Moniker and the Elevation UI


If the client is already elevated, using the elevation moniker will not cause the Elevation UI to display.

How to Use the Elevation Moniker


The elevation moniker is a standard COM moniker, similar to the session, partition, or queue monikers. It directs
an activation request to a specified server with the specified elevation level. The CLSID to be activated appears in
the moniker string.
The elevation moniker supports the following Run level tokens:
1. Administrator
2. Highest
The syntax for this is as follows:

Elevation:Administrator!new:{guid}
Elevation:Highest!new:{guid}

The preceding syntax uses the "new" moniker to return an instance of the COM class specified by guid. Note that
the "new" moniker internally uses the IClassFactory interface to obtain a class object and then calls
IClassFactory::CreateInstance on it.
The elevation moniker can also be used to get a class object, which implements IClassFactory. The caller then
calls CreateInstance to get an object instance. The syntax for this is as follows:

Elevation:Administrator!clsid:{guid}
Sample code
The following code example shows how to use the elevation moniker. It assumes that you have already initialized
COM on the current thread.

HRESULT CoCreateInstanceAsAdmin(HWND hwnd, REFCLSID rclsid, REFIID riid, __out void ** ppv)
{
BIND_OPTS3 bo;
WCHAR wszCLSID[50];
WCHAR wszMonikerName[300];

StringFromGUID2(rclsid, wszCLSID, sizeof(wszCLSID)/sizeof(wszCLSID[0]));


HRESULT hr = StringCchPrintf(wszMonikerName, sizeof(wszMonikerName)/sizeof(wszMonikerName[0]),
L"Elevation:Administrator!new:%s", wszCLSID);
if (FAILED(hr))
return hr;
memset(&bo, 0, sizeof(bo));
bo.cbStruct = sizeof(bo);
bo.hwnd = hwnd;
bo.dwClassContext = CLSCTX_LOCAL_SERVER;
return CoGetObject(wszMonikerName, &bo, riid, ppv);
}

BIND_OPTS3 is new in Windows Vista. It is derived from BIND_OPTS2.


The only addition is an HWND field, hwnd. This handle represents a window that becomes the owner of the
Elevation UI, if applicable.
If hwnd is NULL, COM will call GetActiveWindow to find a window handle associated with the current thread.
This case might occur if the client is a script, which cannot fill in a BIND_OPTS3 structure. In this case, COM will
try to use the window associated with the script thread.

Over-The-Shoulder (OTS) Elevation


Over-the-shoulder (OTS ) elevation refers to the scenario in which a client runs a COM server with an
administrator's credentials rather than his or her own. (The term "over the shoulder" means that the administrator
is watching over the client's shoulder as the client runs the server.)
This scenario might cause a problem for COM calls into the server, because the server might not call
CoInitializeSecurity either explicitly (that is, programmatically) or implicitly (that is, declaratively, using the
registry). For such servers, COM computes a security descriptor that allows only SELF, SYSTEM, and
Builtin\Administrators to makes COM calls into the server. This arrangement will not work in OTS scenarios.
Instead, the server must call CoInitializeSecurity, either explicitly or implicitly, and specify an ACL that includes
the INTERACTIVE group SID and SYSTEM.
The following code example shows how to create a security descriptor (SD ) with the INTERACTIVE group SID.
BOOL GetAccessPermissionsForLUAServer(SECURITY_DESCRIPTOR **ppSD)
{
// Local call permissions to IU, SY
LPWSTR lpszSDDL = L"O:BAG:BAD:(A;;0x3;;;IU)(A;;0x3;;;SY)";
SECURITY_DESCRIPTOR *pSD;
*ppSD = NULL;

if (ConvertStringSecurityDescriptorToSecurityDescriptorW(lpszSDDL, SDDL_REVISION_1, (PSECURITY_DESCRIPTOR


*)&pSD, NULL))
{
*ppSD = pSD;
return TRUE;
}

return FALSE;
}

The following code example shows how to call CoInitializeSecurity implicitly with the SD from the previous
code example:

// hKey is the HKCR\AppID\{GUID} key


BOOL SetAccessPermissions(HKEY hkey, PSECURITY_DESCRIPTOR pSD)
{
BOOL bResult = FALSE;
DWORD dwLen = GetSecurityDescriptorLength(pSD);
LONG lResult;
lResult = RegSetValueExA(hkey,
"AccessPermission",
0,
REG_BINARY,
(BYTE*)pSD,
dwLen);
if (lResult != ERROR_SUCCESS) goto done;
bResult = TRUE;
done:
return bResult;
}

The following code example shows how to call CoInitializeSecurity explicitly with the above SD:
// Absolute SD values
PSECURITY_DESCRIPTOR pAbsSD = NULL;
DWORD AbsSdSize = 0;
PACL pAbsAcl = NULL;
DWORD AbsAclSize = 0;
PACL pAbsSacl = NULL;
DWORD AbsSaclSize = 0;
PSID pAbsOwner = NULL;
DWORD AbsOwnerSize = 0;
PSID pAbsGroup = NULL;
DWORD AbsGroupSize = 0;

MakeAbsoluteSD (
pSD,
pAbsSD,
&AbsSdSize,
pAbsAcl,
&AbsAclSize,
pAbsSacl,
&AbsSaclSize,
pAbsOwner,
&AbsOwnerSize,
pAbsGroup,
&AbsGroupSize
);

if (ERROR_INSUFFICIENT_BUFFER == GetLastError())
{
pAbsSD = (PSECURITY_DESCRIPTOR)LocalAlloc(LMEM_FIXED, AbsSdSize);
pAbsAcl = (PACL)LocalAlloc(LMEM_FIXED, AbsAclSize);
pAbsSacl = (PACL)LocalAlloc(LMEM_FIXED, AbsSaclSize);
pAbsOwner = (PSID)LocalAlloc(LMEM_FIXED, AbsOwnerSize);
pAbsGroup = (PSID)LocalAlloc(LMEM_FIXED, AbsGroupSize);

if ( ! (pAbsSD && pAbsAcl && pAbsSacl && pAbsOwner && pAbsGroup))


{
hr = E_OUTOFMEMORY;
goto Cleanup;
}
if ( ! MakeAbsoluteSD(
pSD,
pAbsSD,
&AbsSdSize,
pAbsAcl,
&AbsAclSize,
pAbsSacl,
&AbsSaclSize,
pAbsOwner,
&AbsOwnerSize,
pAbsGroup,
&AbsGroupSize
))
{
hr = HRESULT_FROM_WIN32(GetLastError());
goto Cleanup;
}
}
else
{
hr = HRESULT_FROM_WIN32(GetLastError());
goto Cleanup;
}

// Call CoinitilizeSecurity.
COM Permissions and Mandatory Access Labels
Windows Vista introduces the notion of mandatory access labels in security descriptors. The label dictates whether
clients can get execute access to a COM object. The label is specified in the system access control list (SACL )
portion of the security descriptor. In Windows Vista, COM supports the
SYSTEM_MANDATORY_LABEL_NO_EXECUTE_UP label. SACLs in the COM permissions are ignored on
operating systems prior to Windows Vista.
As of Windows Vista, dcomcnfg.exe does not support changing the integrity level (IL ) in COM permissions. It must
be set programmatically.
The following code example shows how to create a COM security descriptor with a label that allows
launch/activation requests from all LOW IL clients. Note that the labels are valid for Launch/Activation and Call
permissions. Thus, it is possible to write a COM server that disallows launch, activation or calls from clients with a
certain IL. For more information about integrity levels, see the section "Understanding Windows Vista's Integrity
Mechanism" in Understanding and Working in Protected Mode Internet Explorer.

BOOL GetLaunchActPermissionsWithIL (SECURITY_DESCRIPTOR **ppSD)


{
// Allow World Local Launch/Activation permissions. Label the SD for LOW IL Execute UP
LPWSTR lpszSDDL = L"O:BAG:BAD:(A;;0xb;;;WD)S:(ML;;NX;;;LW)";
if (ConvertStringSecurityDescriptorToSecurityDescriptorW(lpszSDDL, SDDL_REVISION_1, (PSECURITY_DESCRIPTOR
*)&pSD, NULL))
{
*ppSD = pSD;
return TRUE;
}
}

BOOL SetLaunchActPermissions(HKEY hkey, PSECURITY_DESCRIPTOR pSD)


{

BOOL bResult = FALSE;


DWORD dwLen = GetSecurityDescriptorLength(pSD);
LONG lResult;
lResult = RegSetValueExA(hkey,
"LaunchPermission",
0,
REG_BINARY,
(BYTE*)pSD,
dwLen);
if (lResult != ERROR_SUCCESS) goto done;
bResult = TRUE;
done:
return bResult;
};

CoCreateInstance and Integrity Levels


The behavior of CoCreateInstance has changed in Windows Vista, to prevent Low IL clients from binding to
COM servers by default. The server must explicitly allow such bindings by specifying the SACL. The changes to
CoCreateInstance are as follows:
1. When launching a COM server process, the IL in the server process token is set to the client or server token IL,
whichever is lower.
2. By default, COM will prevent Low IL clients from binding to running instances of any COM servers. To allow
the bind, a COM server's Launch/Activation security descriptor must contain a SACL that specifies the Low IL
label (see the previous section for the sample code to create such a security descriptor).
Elevated Servers and ROT Registrations
If a COM server wishes to register in the running object table (ROT) and allow any client to access the registration,
it must use the ROTFLAGS_ALLOWANYCLIENT flag. An "Activate As Activator" COM server cannot specify
ROTFLAGS_ALLOWANYCLIENT because the DCOM service control manager (DCOMSCM ) enforces a spoof
check against this flag. Therefore, in Windows Vista, COM adds support for a new registry entry that allows the
server to stipulate that its ROT registrations be made available to any client:

HKEY_LOCAL_MACHINE\Software\Classes\AppID
{APPID}
ROTFlags

The only valid value for this REG_DWORD entry is:

ROTREGFLAGS_ALLOWANYCLIENT 0x1

The entry must exist in the HKEY_LOCAL_MACHINE hive.


This entry provides an "Activate As Activator" server with the same functionality that
ROTFLAGS_ALLOWANYCLIENT provides for a RunAs server.

Related topics
S
e
c
u
r
i
t
y
i
n
C
O
M

U
n
d
e
r
s
t
a
n
d
i
n
g
a
n
d
W
o
r
k
i
n
g
i
n
P
r
o
t
e
c
t
e
d
M
o
d
e
I
n
t
e
r
n
e
t
E
x
p
l
o
r
e
r
Error Handling in COM
1/7/2020 • 2 minutes to read • Edit Online

Almost all COM functions and interface methods return a value of the type HRESULT. The HRESULT (for result
handle) is a way of returning success, warning, and error values. HRESULTs are really not handles to anything;
they are only values with several fields encoded in the value. As per the COM specification, a result of zero
indicates success and a nonzero result indicates failure.
At the source code level, all error values consist of three parts, separated by underscores. The first part is the
prefix that identifies the facility associated with the error, the second part is E for error, and the third part is a string
that describes the actual condition. For example, STG_E_MEDIUMFULL is returned when there is no space left
on a hard disk. The STG prefix indicates the storage facility, the E indicates that the status code represents an error,
and the MEDIUMFULL provides specific information about the error. Many of the values that you might want to
return from an interface method or function are defined in Winerror.h.
For more information about error handling, see the following sections:
Structure of COM Error Codes
Codes in FACILITY_ITF
Using Macros for Error Handling
COM Error Handling in Java and Visual Basic
Error Handling Strategies
Handling Unknown Errors

Related topics
C
O
M
E
r
r
o
r
C
o
d
e
s
Structure of COM Error Codes
1/7/2020 • 2 minutes to read • Edit Online

The following illustration shows the format of an HRESULT (or SCODE ); the numbers indicate bit positions:

The high-order bit in the HRESULT or SCODE indicates whether the return value represents success or failure. If
set to 0, SEVERITY_SUCCESS, the value indicates success. If set to 1, SEVERITY_ERROR, it indicates failure.
The R, C, N, and r bits are reserved.
The facility field indicates the system service responsible for the error. Microsoft allocates new facility codes as they
become necessary. Most SCODEs and HRESULT values set the facility field to FACILITY_ITF, indicating an
interface method error.
Common facility fields are described in the following table.

FACILITY FIELD VALUE DESCRIPTION

FACILITY_DISPATCH 2 For late-binding IDispatch interface


errors.

FACILITY_ITF 4 For most status codes returned from


interface methods. The actual meaning
of the error is defined by the interface.
That is, two HRESULTs with exactly the
same 32-bit value returned from two
different interfaces might have different
meanings.

FACILITY_NULL 0 For broadly applicable common status


codes such as S_OK.

FACILITY_RPC 1 For status codes returned from remote


procedure calls.

FACILITY_STORAGE 3 For status codes returned from


IStorage or IStream method calls
relating to structured storage. Status
codes whose code (lower 16 bits) value
is in the range of MS-DOS error codes
(that is, less than 256) have the same
meaning as the corresponding MS-DOS
error.

FACILITY_WIN32 7 Used to provide a means of handling


error codes from functions in the
Windows API as an HRESULT. Error
codes in 16-bit OLE that duplicated
system error codes have also been
changed to FACILITY_WIN32.
FACILITY FIELD VALUE DESCRIPTION

FACILITY_WINDOWS 8 Used for additional error codes from


Microsoft-defined interfaces.

The code field is a unique number that is assigned to represent the error or warning.
By convention, HRESULT values generally have names in the following format: Facility_Severity_Reason.
Facility is either the facility name or some other distinguishing identifier; Severity is a single letter, S or E, that
indicates whether the function call succeeded (S ) or produced an error (E ); and Reason is an identifier that
describes the meaning of the code. For example, the status code STG_E_FILENOTFOUND indicates a storage-
related error has occurred; specifically, a requested file does not exist. Status codes from FACILITY_NULL omit the
Facility_ prefix.
Error codes are defined within the context of an interface implementation. Once defined, success codes cannot be
changed or new success codes added. However, new failure codes can be written. Microsoft reserves the right to
define new failure codes (but not success codes) for the interfaces described in FACILITY_ITF or in new facilities.

Related topics
E
r
r
o
r
H
a
n
d
l
i
n
g
i
n
C
O
M

W
i
n
d
o
w
s
P
r
o
t
o
c
o
l
s
:
H
R
E
S
U
L
T
Codes in FACILITY_ITF
1/7/2020 • 2 minutes to read • Edit Online

HRESULTs with facilities such as FACILITY_NULL and FACILITY_RPC have universal meaning because they are
defined at a single source: Microsoft. However, HRESULTs in FACILITY_ITF are determined by the function or
interface method from which they are returned. This means that the same 32-bit value in FACILITY_ITF returned
from two different interface methods might have different meanings.
The reason HRESULTs in FACILITY_ITF can have different meanings in different interfaces is that HRESULTs are
kept to an efficient data type size of 32 bits. Unfortunately, 32 bits is not large enough for the development of an
error code allocation system that avoids conflicting codes allocated by different programmers at different times in
different places (unlike the handling of interface identifiers and CLSIDs). As a result, the 32-bit HRESULT is
structured such that Microsoft can define several universal error codes, while allowing other programmers to
define new error codes without fear of conflict. The status code convention is as follows:
Status codes in facilities other than FACILITY_ITF can be defined only by Microsoft.
Status codes in facility FACILITY_ITF are defined solely by the developer of the interface or function that returns
the status code. To avoid conflicting error codes, whoever defines the interface is responsible for coordinating
and publishing the FACILITY_ITF status codes associated with that interface.
All the COM -defined FACILITY_ITF codes have a code value in the range of 0x0000-0x01FF. While it is legal to use
any codes in FACILITY_ITF, it is recommended that only code values in the range of 0x0200-0xFFFF be used. This
recommendation is made as a means of reducing confusion with any COM -defined errors.
It is also recommended that developers define new functions and interfaces to return error codes as defined by
COM and in facilities other than FACILITY_ITF. In particular, interfaces that have any chance of being remoted
using RPC in the future should define the FACILITY_RPC codes as legal. E_UNEXPECTED is a specific error code
that most developers will want to make universally legal.

Related topics
E
r
r
o
r
H
a
n
d
l
i
n
g
i
n
C
O
M
Using Macros for Error Handling
1/7/2020 • 2 minutes to read • Edit Online

COM defines a number of macros that make it easier to work with HRESULT values.
The error handling macros are described in the following table.

MACRO DESCRIPTION

MAKE_HRESULT Returns an HRESULT given the severity bit, facility code, and
error code that comprise the HRESULT.
[!Note]
Calling MAKE_HRESULT for S_OK verification carries a
performance penalty. You should not routinely use
MAKE_HRESULT for successful results.

MAKE_SCODE Returns an SCODE given the severity bit, facility code, and
error code that comprise the SCODE.

HRESULT_CODE Extracts the error code portion of the HRESULT.

HRESULT_FACILITY Extracts the facility code of the HRESULT.

HRESULT_SEVERITY Extracts the severity bit of the HRESULT.

SCODE_CODE Extracts the error code portion of the SCODE.

SCODE_FACILITY Extracts the facility code of the SCODE.

SCODE_SEVERITY Extracts the severity field of the SCODE.

SUCCEEDED Tests the severity bit of the SCODE or HRESULT; returns


TRUE if the severity is zero and FALSE if it is one.

FAILED Tests the severity bit of the SCODE or HRESULT; returns


TRUE if the severity is one and FALSE if it is zero.

IS_ERROR Provides a generic test for errors on any status value.

HRESULT_FROM_WIN32 Maps a system error code to an HRESULT value.

HRESULT_FROM_NT Maps an NT status value to an HRESULT value.

Related topics
E
r
r
o
r
H
a
n
d
l
i
n
g
i
n
C
O
M
COM Error Handling in Java and Visual Basic
1/7/2020 • 2 minutes to read • Edit Online

There are three interfaces and three functions that can be used in COM to provide error handling when
programming in Java or Microsoft Visual Basic. In Java and Visual Basic, the method call does not return an
HRESULT as the return value. Instead, these languages use the COM interfaces and functions to obtain HRESULT
values and to handle errors or exceptions. (Exceptions are events beyond the program's control, such as file
problems or invalid parameters.)
The three interfaces that provide support for HRESULTs are listed and described briefly in the following table.

ICreateErrorInfo Sets error information.

IErrorInfo Returns information from an error object.

ISupportErrorInfo Identifies the object as supporting the IErrorInfo interface.

The three functions that provide support for HRESULTs are listed and described briefly in the following table.

CreateErrorInfo Creates an instance of a generic error object.

GetErrorInfo Obtains the error information pointer set by the previous call
to SetErrorInfo in the current logical thread.

SetErrorInfo Sets the error information object for the current thread of
execution.

Related topics
E
r
r
o
r
H
a
n
d
l
i
n
g
i
n
C
O
M
Returning Error Information
1/7/2020 • 2 minutes to read • Edit Online

Using the COM error-handling interfaces and functions, you can return error information by performing the
following the steps:
1. Implement the ISupportErrorInfo interface.
2. To create an instance of the generic error object, call the CreateErrorInfo function.
3. To set its contents, use the ICreateErrorInfo methods.
4. To associate the error object with the current logical thread, call the SetErrorInfo function.
The error handling interfaces create and manage an error object, which provides information about the error. The
error object is not the same as the object that encountered the error. It is a separate object associated with the
current thread of execution.
Retrieving Error Information
1/29/2020 • 2 minutes to read • Edit Online

Using the COM error-handling interfaces and functions, you can retrieve error information as follows:
1. Check whether the returned value represents an error that the object is prepared to handle.
2. Call QueryInterface to get a pointer to the ISupportErrorInfo interface. Then call
ISupportErrorInfo::InterfaceSupportsErrorInfo to verify that the error was raised by the object that
returned it and that the error object pertains to the current error and not to a previous call.
3. To get a pointer to the error object, call the GetErrorInfo function.
4. To retrieve information from the error object, use the IErrorInfo methods.
If the object is not prepared to handle the error but needs to propagate the error information further down the call
chain, it should simply pass the return value to its caller. Because the GetErrorInfo function clears the error
information and passes ownership of the error object to the caller, the function should be called only by the object
that handles the error.
Error Handling Strategies
1/29/2020 • 2 minutes to read • Edit Online

Because interface methods are virtual, it is not possible for a caller to know the full set of values that may be
returned from any one call. One implementation of a method may return five values; another may return eight.
The documentation lists common values that may be returned for each method; these are the values that you must
check for and handle in your code because they have special meanings. Other values may be returned, but because
they are not meaningful, you do not need to write special code to handle them. A simple check for zero or nonzero
is adequate.

HRESULT Values
The return value of COM functions and methods is an HRESULT. The values of some HRESULTs have been
changed in COM to eliminate all duplication and overlapping with the system error codes. Those that duplicate
system error codes have been changed to FACILITY_WIN32, and those that overlap remain in FACILITY_NULL.
Common HRESULT values and their values are listed in the following table.

HRESULT VALUE DESCRIPTION

E_ABORT 0x80004004 The operation was aborted because of


an unspecified error.

E_ACCESSDENIED 0x80070005 A general access-denied error.

E_FAIL 0x80004005 An unspecified failure has occurred.

E_HANDLE 0x80070006 An invalid handle was used.

E_INVALIDARG 0x80070057 One or more arguments are invalid.

E_NOINTERFACE 0x80004002 The QueryInterface method did not


recognize the requested interface. The
interface is not supported.

E_NOTIMPL 0x80004001 The method is not implemented.

E_OUTOFMEMORY 0x8007000E The method failed to allocate necessary


memory.

E_PENDING 0x8000000A The data necessary to complete the


operation is not yet available.

E_POINTER 0x80004003 An invalid pointer was used.

E_UNEXPECTED 0x8000FFFF A catastrophic failure has occurred.

S_FALSE 0x00000001 The method succeeded and returned


the boolean value FALSE.
HRESULT VALUE DESCRIPTION

S_OK 0x00000000 The method succeeded. If a boolean


return value is expected, the returned
value is TRUE.

Network Errors
If the first four digits of the error code are 8007, this indicates a system or network error. You can use the net
command to decode these types of errors. To decode the error, first convert the last four digits of the hexadecimal
error code to decimal. Then, at the command prompt, type the following, where decimal code is replaced with the
return value you want to decode:
net helpmsg <decimal_code>
The net command returns a description of the error. For example, if COM returns the error 8007054B, convert the
054B to decimal (1355). Then type the following:
net helpmsg 1355
The net command returns the error description: "The specified domain did not exist".

Related topics
E
r
r
o
r
H
a
n
d
l
i
n
g
i
n
C
O
M
Handling Unknown Errors
1/7/2020 • 2 minutes to read • Edit Online

It is legal to return a status code only from the implementation of an interface method sanctioned as legally
returnable. Failure to observe this rule invites the possibility of conflict between returned error-code values and
those sanctioned by the application. Pay particular attention to this potential problem when propagating error
codes from functions that are called internally.
Applications that call interfaces should treat any unknown returned error code (as opposed to a success code) as
synonymous with E_UNEXPECTED. This practice of handling unknown error codes is required by clients of the
COM -defined interfaces and functions. Because typical programming practice is to handle a few specific error
codes in detail and treat the rest generically, this requirement of handling unexpected or unknown error codes is
easily met.
It is important to handle all possible errors when calling an interface method. Failure to do so could cause your
application to crash, to corrupt data, or to become vulnerable to security exploits. The following code sample shows
the recommended way of handling unknown errors:

HRESULT hr;
hr = xxMethod();

switch (GetScode(hr))
{
case NOERROR:
// Method returned success.
break;

case x1:
// Handle error x1 here.
break;

case x2:
// Handle error x2 here.
break;

case E_UNEXPECTED:
default:
// Handle unexpected errors here.
break;
}

The following error check is often used with those routines that do not return anything special (other than S_OK or
some unexpected error):

if (xxMethod() == NOERROR)
{
// Handle success here.
}
else
{
// Handle failure here.
}
Related topics
E
r
r
o
r
H
a
n
d
l
i
n
g
i
n
C
O
M
COM Handlers
1/7/2020 • 2 minutes to read • Edit Online

The purpose of COM handlers is to provide some "smart" code in the client address space that can optimize calls
between a client and server. Handlers can override some interfaces while delegating others directly to the server
(through the proxy).
There are two types of COM handlers:
The OLE handler is a heavyweight DLL that provides important services for linking and embedding. It is usually
created before the server is launched and is initialized so that the server is activated when the embedded object
enters the running state.
The lightweight client-side handler can be created for any purpose, can be very small, and cannot be created
before the server.
The OLE Handler
1/7/2020 • 2 minutes to read • Edit Online

An OLE handler is a DLL containing several interacting components used for linking and embedding. To avoid the
expense of constant interprocess communication between a container and its server, the handler is loaded into the
container's process space to act on behalf of a server as a sort of surrogate process. The OLE handler manages
container requests that do not require the attention of the server application, such as requests for drawing. When a
container requests something that the object handler cannot provide, the handler communicates with the server
application using the COM out-of-process communication mechanism.
The OLE handler components include remoting pieces to manage communication between the handler and its
server, a cache for storing an object's data (along with information on how that data should be formatted and
displayed), and a controlling object that coordinates the activities of the DLL's other components. In addition, if an
object is a link, the DLL also includes a linking component, or linked object, which keeps track of the name and
location of the link source.
OLE provides a default handler that most applications use for linking and embedding. If the default does not
match the requirements of your server, you can either completely replace the default handler or use parts of the
functionality it provides where appropriate. In the latter case, the application handler is implemented as an
aggregate object composed of a new control object and the default handler. Combination application/default
handlers are also known as in-process handlers. The remoting handler is used for objects that are not assigned a
CLSID in the system registry or that have no specified handler. All that is required from a handler for these types
of objects is that they pass information across the process boundary. To create a new instance of the default
handler, call OleCreateDefaultHandler. For some special circumstances, call OleCreateEmbeddingHelper.
When you create an instance of a handler for one class, you cannot use it for another. When used for a compound
document, the OLE handler implements the container-side data structures when objects of a particular class are
accessed remotely.
OLE defined the default handler for clients of compound document local servers. The default handler implemented
a number of interfaces that the typical server did not. When OLE subsequently allowed in-process servers for
compound documents, they had to create an embedding helper that implemented these extra interfaces so that
clients could seamlessly work with them.
Framework designers that define and implement a client-side handler should consider this issue in their design
and should provide an equivalent in-process helper for the same reasons. Even if the designers currently don't
implement interfaces on the handler that the servers don't expose, they may want to define a helper now so that
they can add them in the future. Alternatively, one could implement the extra interfaces on the server object itself.

Related topics
T
h
e
L
i
g
h
t
w
e
i
g
h
t
C
l
i
e
n
t
-
S
i
d
e
H
a
n
d
l
e
r
The Lightweight Client-Side Handler
1/29/2020 • 2 minutes to read • Edit Online

Lightweight client-side handlers allow you to create general client-side handlers of any size, to help you do any
kind of standard task. As handlers, these are usable by more than one client. They differ from OLE handlers in that
they cannot be created before the server is launched, and their lifetime is tied to that of the proxy manager,
preventing a possible race condition in which the handler could otherwise be prematurely released.
The proxy manager is the system-created object that implements the IMarshal interface. If you use standard
marshaling, the system creates it for you when you call CoGetStandardMarshal (or CoGetStdMarshalEx, for
creating an aggregated marshaler for lightweight handlers) and also implements the IClientSecurity and
IMultiQI interfaces on the object. On the server side, there is a corresponding system object that also implements
IMarshal. These objects handle marshaling for you transparently.
There are two general types of these handlers that you may want to implement:
A handler that performs a service that requires no extra data from the server
A handler that uses extra data from the server
Some potential uses of the extra data in the stream supplied by the server are as follows:
Static data from server. Regardless of the particular interface being marshaled, the server writes the same data
into the stream.
Per-interface data from server. Depending on which particular interface is being marshaled, the server may
write different data into the stream.
Per-interface helpers. Per-interface COM components aggregated into the client handler and delegating to the
standard proxy. For example, to improve network performance, a COM component for IStream could do
client-side caching of data, read-ahead, write-behind, op-locking, and so forth.
Network version of an interface. The network version of the interface is different from the interface exposed by
the client and server application code. It is possible, for example, to multiplex exposed interfaces IA and IB over
the same network interface INetAB, the way the embedding server handler does. For example, one could
convert a data transfer interface into a network interface that uses pipes for efficient data transfer.
Down-level clients may not have the capability of unmarshaling interfaces that have custom handlers, for two
reasons: First, they may not understand the CLSID used in the custom marshaled packet when the server handler
is aggregated and the object wants a handler. Second, the handler code may not even run on the client side if it
requires new functionality from COM to create the aggregated standard marshaler and to do remote
QueryInterface calls.

Related topics
T
h
e
O
L
E
H
a
n
d
l
e
r
Implementing and Activating a Handler with No Extra
Server Data
1/7/2020 • 2 minutes to read • Edit Online

To create an instance of your handler, if it is one that gets no extra server data, the server must implement
IStdMarshalInfo but not IMarshal. IStdMarshalInfo has one method, GetClassForHandler, which retrieves the
CLSID of the object handler to be used in the destination process. COM calls this when it calls
CoMarshalInterface for you and activates the handler on the client side.
Next, both the server and handler implementations must call the CoGetStdMarshalEx function. This function
creates a standard marshaler on each side (called a proxy manager on the client side and a stub manager on the
server side).
The server calls CoGetStdMarshalEx, passing in the flag SMEXF_SERVER. This creates a server-side standard
marshaler (stub manager). The server-side structure is shown in the following illustration:

Server-Side Structure
The handler calls CoGetStdMarshalEx, passing in the flag SMEXF_HANDLER. This creates a client-side standard
marshaler (proxy manager) and aggregates it with the handler on the client side. The lifetime of both are managed
by the controlling identity object (implementing IUnknown) that the system implements when the handler calls
CoGetStdMarshalEx. The client-side structure is shown in the following illustration.

Client-Side Structure
As shown in the preceding illustration, the handler is actually sandwiched between the proxy manager and the
identity/controlling unknown. This gives the system control over the lifetime of the object while giving the handler
control over the exposed interfaces. The dashed line between the Identity and Proxy Manager indicates that the two
share tight integration through internal private interfaces.
When COM calls CoUnmarshalInterface for the client, it creates the handler instance, aggregating it with the
Identity. The handler will create the standard marshaler (through the call to CoGetStdMarshalEx, passing in the
controlling unknown it received when it was created). The handler does not implement IMarshal but just returns
IMarshal from the standard marshaler. Even if the handler does implement IMarshal, it will not get called during
an unmarshal.
If two threads simultaneously unmarshal the same object for the first time, it is possible for two handlers to get
created temporarily. One will subsequently be released.

Related topics
T
h
e
L
i
g
h
t
w
e
i
g
h
t
C
l
i
e
n
t
-
S
i
d
e
H
a
n
d
l
e
r
Implementing and Activating a Handler with Extra
Data Supplied by Server
1/7/2020 • 2 minutes to read • Edit Online

If the server wants to include some extra data in the packet for the handler to use, the server must implement both
the IMarshal and the IStdMarshalInfo interfaces. The server must aggregate the standard marshaler and must
delegate the first part of the marshaling to the aggregated standard marshaler, including
IMarshal::GetUnmarshalClass, and must add its own data size to the size returned by the standard marshaler's
IMarshal::GetMarshalSizeMax. The standard marshaler calls IStdMarshalInfo::GetClassForHandler to get the
CLSID of the handler to be created. After the standard marshaler has done its marshaling, the server then writes its
own extra data into the stream. The resulting structures, with extra data in the stream, are shown in the following
illustration:

Server-Side Structures with Extra Data in Stream


This allows the call from COM to CoUnmarshalInterface on the client side the ability to skip over any unread
data and leave the stream in the appropriate position following all the marshaled interface data if the handler
cannot be created.

Client-Side Structures with Extra Data in Stream


As in the case where there is no extra server data in the stream, the client-side COM call to
CoUnmarshalInterface will create the identity and handler. The handler must implement IMarshal and must
delegate the IMarshal calls to the aggregated standard marshaler first and then marshal or unmarshal any extra
data that the server provided. The handler's UnmarshalInterface will be called for every unmarshal, regardless of
whether it has unmarshaled the interface before or not. In this case, the server does not call CoGetStdMarshalEx
but the handler must. The resulting client-side structure is shown in the following illustration.
Related topics
T
h
e
L
i
g
h
t
w
e
i
g
h
t
C
l
i
e
n
t
-
S
i
d
e
H
a
n
d
l
e
r
Delegation of QueryInterface
1/7/2020 • 2 minutes to read • Edit Online

Handlers that require access to some of the internal interfaces on the proxy manager have to go through the
IInternalUnknown interface. This prevents handlers from blindly delegating and exposing the aggregatee's
internal interfaces outside of the aggregate. These interfaces include IClientSecurity and IMultiQI. If the handler
wants to expose IClientSecurity or IMultiQI, it should implement them itself.
In the case of IClientSecurity, if the client tries to set the security on an interface that the handler has exposed, the
handler should set the security on the underlying network interface proxy.
In the case of IMultiQI, the handler should fill in the interfaces it knows about and then forward the call to the
proxy manager to get the rest of the interfaces filled in.

Related topics
T
h
e
L
i
g
h
t
w
e
i
g
h
t
C
l
i
e
n
t
-
S
i
d
e
H
a
n
d
l
e
r
DLL Surrogates
1/7/2020 • 2 minutes to read • Edit Online

COM makes it possible to create DLL servers that can be loaded into a surrogate EXE process. This combines the
ease of writing DLL servers with the benefits of executable implementation. Development tools like Microsoft
Visual Studio facilitate the writing of DLL servers, but a DLL server in itself has limits. Running the DLL server in
a surrogate process offers several possible benefits:
Fault isolation and the ability to service multiple clients simultaneously.
In a distributed environment, a DLL server implementation could be used to service remote clients.
It could permit clients to help protect themselves from untrusted server code while allowing them access to the
services the DLL server provides.
Running a DLL server in a surrogate provides the DLL with the surrogate's security.
COM provides a default surrogate process, or you can write a custom surrogate if you have special needs.
The following topics provide more information on DLL surrogates:
DLL Server Requirements
Using the System-Supplied Surrogate
Writing a Custom Surrogate
DLL Server Requirements
1/7/2020 • 2 minutes to read • Edit Online

While most DLLs can run in a surrogate, some DLLs cannot.


The DLL must be well-behaved if you want to use the system-supplied surrogate. For example, a DLL that calls
methods that register callbacks from the client would try to invoke those callbacks as if the function pointers it
received were for instructions in its address space, which is not the case. Similarly, a DLL that uses a global
variable that it expects the client to access would not work. In general, parameters that cannot be properly
marshaled will prevent the DLL server from running outside the client process. In many cases, you can write a
custom surrogate specifically designed to compensate for "bad" behavior. (For more information, see Writing a
Custom Surrogate.)
If the DLL server uses custom interfaces, you would have to ensure that marshaling code is available for those
interfaces. For example, you could build and register a proxy DLL or provide and register a type library that would
allow the server to function correctly while running in a surrogate.
DLL servers will be loaded only into a surrogate process running in the proper security context. The security
context for the DLL server surrogate is determined in the same way as for EXE servers. The DLL server surrogate
runs in the same security context as the client, unless a RunAs value, which determines the security context, is set
in the AppID registry section for the server.

Related topics
D
L
L
S
u
r
r
o
g
a
t
e
s
Surrogate Sharing
1/7/2020 • 2 minutes to read • Edit Online

DLL servers will share a surrogate if they have matching security identities and share the same AppID value.
DLL servers are loaded, by default, into their own surrogate process. To load other DLL servers into an existing
surrogate so that it supports more than one DLL server, there are two requirements:
The DLL servers must have the same AppID value.
The security context of the DLL servers must be the same.
If two DLL servers are to be launched under different security identities, they must be in different surrogates,
whether their AppIDs match.
Following is an example of administering surrogate sharing with AppIDs:

AppID
{12345678-0000-0000-0000-abcdabcdabcd}
@DllSurrogate REG_SZ
CLSID
{12345678-0000-0000-0000-000000000001}
@AppId REG_SZ {12345678-0000-0000-0000-abcdabcdabcd}
InProcServer32
@ REG_SZ c:\myapp\comp1.dll
{12345678-0000-0000-0000-000000000002}
@AppId REG_SZ {12345678-0000-0000-0000-abcdabcdabcd}
InProcServer32
@ REG_SZ c:\myapp\comp2.dll

The two CLSIDs for DLL components comp1.dll and comp2.dll have been configured to share an AppID. The
AppID key specifies that the DLL server can be loaded in a surrogate by specifying the DllSurrogate value. In this
example, the DllSurrogate value is an empty string, indicating that the default system implementation of the DLL
surrogate should be used.

Related topics
D
L
L
S
e
r
v
e
r
R
e
q
u
i
r
e
m
e
n
t
s

R
e
g
i
s
t
e
r
i
n
g
t
h
e
D
L
L
S
e
r
v
e
r
f
o
r
S
u
r
r
o
g
a
t
e
A
c
t
i
v
a
t
i
o
n
Registering the DLL Server for Surrogate Activation
1/7/2020 • 2 minutes to read • Edit Online

A DLL server will be loaded into a surrogate process under the following conditions:
There must be an AppID value specified under the CLSID key in the registry, and a corresponding AppID key.
In an activation call, the CLSCTX_LOCAL_SERVER bit is set and the CLSID key does not specify
LocalServer32, LocalServer, or LocalService. If other CLSCTX bits are set, the processing algorithmfor the in-
process, local, or remote execution flags is followed.
The CLSID key contains the InprocServer32 subkey.
The proxy/stub DLL specified in the InprocServer32 key exists.
The DllSurrogate value exists under the AppID key.
If there is a LocalServer, LocalServer32, or LocalService, indicating the existence of an EXE, the EXE server or
service will always be launched in preference to loading a DLL server into a surrogate process.
The DllSurrogate named-value must be specified for surrogate activation to occur. Activation refers to calls to any
of the following activation functions:
CoGetClassObject
CoCreateInstanceEx
CoGetInstanceFromFile
CoGetInstanceFromIStorage
IMoniker::BindToObject
To launch an instance of the system-supplied surrogate, set the value of DllSurrogate either to an empty string or
to NULL. To specify the launch of a custom surrogate, set the value to the path of the surrogate.
If both RemoteServerName and DllSurrogate are specified for the same AppID, the RemoteServerName value
is ignored and the DllSurrogate value causes an activation on the local computer. For remote surrogate activation,
specify RemoteServerName but not DllSurrogate on the client, and specify DllSurrogate on the server.
A DLL server that is designed to always run alone in its own surrogate process is best configured with an AppID
equal its CLSID. Under AppID, simply specify a DllSurrogate named-value with an empty string value.
It is best to configure a DLL server that is designed to run alone in its own surrogate process and to service
multiple clients across a network with a RunAs value specified under the AppID registry key. Whether the RunAs
specifies "Interactive User" or a specific user identity depends upon the user interface, security, and other server
requirements. When a RunAs value is specified, only one instance of the server is loaded to service all of the
clients, regardless of the identity of the client. On the other hand, do not configure the server with RunAs if the
intention is to have one instance of the DLL server running in surrogate to service each remote client identity.

Related topics
D
L
L
S
e
r
v
e
r
R
e
q
u
i
r
e
m
e
n
t
s

S
u
r
r
o
g
a
t
e
S
h
a
r
i
n
g
Using the System-Supplied Surrogate
1/7/2020 • 2 minutes to read • Edit Online

To use the system-supplied surrogate for your DLL server, register the DLL specifying an empty string or NULL
for the DllSurrogate value in the registry. When an activation request for a DLL server so designated comes to
COM, COM launches the default surrogate process and the requested DLL (by specifying the CLSID on the launch
command line internally) at the same time to avoid a separate call. (For information on running more than one
DLL server in a surrogate process, see Surrogate Sharing.)
The default implementation of the surrogate process is a mixed-threading model style pseudo-COM server. When
multiple DLL servers are loaded into a single surrogate process, this process ensures that each DLL server is
instantiated using the threading model specified in the registry for that server. All loaded free-threaded servers will
live together in the multithreaded apartment, while each apartment-threaded server will reside in a single-
threaded apartment. If a DLL server supports both threading models, COM will choose multithreading.
This surrogate process is written so that COM handles both the unloading of DLL servers and the terminating of
the surrogate process.
The system-provided surrogate will work very well for most developers, as well as being very easy to use.
However, those developers with special considerations may decide that a custom surrogate is necessary. For more
information, see Writing a Custom Surrogate.

Related topics
D
L
L
S
u
r
r
o
g
a
t
e
s
Writing a Custom Surrogate
1/7/2020 • 3 minutes to read • Edit Online

While the system-supplied surrogate will be more than adequate for most situations, there are some cases where
writing a custom surrogate could be worthwhile. Following are some examples:
A custom surrogate could provide some optimizations or semantics not present in the system surrogate.
If an in-process DLL contains code that depends on being in the same process as the client, the DLL server will
not function correctly if it is running in the system surrogate. A custom surrogate could be tailored to a specific
DLL to deal with this.
The system surrogate supports a mixed-threading model so that it can load both free and apartment model
DLLs. A custom surrogate might be tailored to load only apartment DLLs for reasons of efficiency or to accept
a command-line argument for the type of DLL it is allowed to load.
A custom surrogate could take extra command-line parameters that the system surrogate does not.
The system surrogate calls CoInitializeSecurity and tells it to use any existing security settings found under
the AppID key in the registry. A custom surrogate could use another security context.
Interfaces that aren't remotable (such as those for recent OCXs) will not work with the system surrogate. A
custom surrogate could wrap the DLL's interfaces with its own implementation and use proxy/stub DLLs with
a remotable IDL definition that would allow the interface to be remoted.
The main surrogate thread should typically perform the following setup steps:
1. Call CoInitializeEx to initialize the thread and set the threading model.
2. If you want the DLL servers that are to run in the server to be able to use the security settings in the AppID
registry key, call CoInitializeSecurity with the EOAC_APPID capability. Otherwise, legacy security settings
will be used.
3. Call CoRegisterSurrogate to register the surrogate interface to COM.
4. Call ISurrogate::LoadDllServer for the requested CLSID.
5. Put main thread in a loop to call CoFreeUnusedLibraries periodically.
6. When COM calls ISurrogate::FreeSurrogate, revoke all class factories and exit.
A surrogate process must implement the ISurrogate interface. This interface should be registered when a new
surrogate is started and after calling CoInitializeEx. As indicated in the preceding steps, the ISurrogate interface
has two methods that COM calls: LoadDllServer, to dynamically load new DLL servers into existing surrogates;
and FreeSurrogate, to free the surrogate.
The implementation of LoadDllServer, which COM calls with a load request, must first create a class factory
object that supports IUnknown, IClassFactory, and IMarshal, and then call CoRegisterClassObject to register
the object as the class factory for the requested CLSID.
The class factory registered by the surrogate process is not the actual class factory implemented by the DLL
server but is a generic class factory implemented by the surrogate process that supports IClassFactory and
IMarshal. Because it is the surrogate's class factory, rather than that of the DLL server that is being registered, the
surrogate's class factory will need to use the real class factory to create an instance of the object for the registered
CLSID. The surrogate's IClassFactory::CreateInstance should look something like the following example:
STDMETHODIMP CSurrogateFactory::CreateInstance(
IUnknown* pUnkOuter,
REFIID iid,
void** ppv)
{
void* pcf;
HRESULT hr;

hr = CoGetClassObject(clsid, CLSCTX_INPROC_SERVER, NULL, IID_IClassFactory, &pcf);


if ( FAILED(hr) )
return hr;
hr = ((IClassFactory*)pcf)->CreateInstance(pUnkOuter, iid, ppv);
((IClassFactory*)pcf)->Release();
return hr;
}

The surrogate's class factory must also support IMarshal because a call to CoGetClassObject can request any
interface from the registered class factory, not just IClassFactory. Further, since the generic class factory supports
only IUnknown and IClassFactory, requests for other interfaces must be directed to the real object. Thus, there
should be a MarshalInterface method which should be similar to the following:

STDMETHODIMP CSurrogateFactory::MarshalInterface(
IStream *pStm,
REFIID riid, void *pv,
WORD dwDestContext,
void *pvDestContext,
DWORD mshlflags )
{
void * pCF = NULL;
HRESULT hr;

hr = CoGetClassObject(clsid, CLSCTX_INPROC_SERVER, NULL, riid, &pCF);


if ( FAILED(hr) )
return hr;
hr = CoMarshalInterface(pStm, riid, (IUnknown*)pCF, dwDestContext, pvDestContext, mshlflags);
((IUnknown*)pCF)->Release();
return S_OK;

The surrogate that houses a DLL server must publish the DLL server's class object(s) with a call to
CoRegisterClassObject. All class factories for DLL surrogates should be registered as REGCLS_SURROGATE.
REGCLS_SINGLUSE and REGCLS_MULTIPLEUSE should not be used for DLL servers loaded into surrogates.
Following these guidelines for creating a surrogate process when it is necessary to do so should ensure proper
behavior.

Related topics
D
L
L
S
u
r
r
o
g
a
t
e
s
Monikers
1/7/2020 • 2 minutes to read • Edit Online

A moniker in COM is not only a way to identify an object—a moniker is also implemented as an object. This object
provides services allowing a component to obtain a pointer to the object identified by the moniker. This process is
referred to as binding.
Monikers are objects that implement the IMoniker interface and are generally implemented in DLLs as
component objects. There are two ways of viewing the use of monikers: as a moniker client, a component that uses
a moniker to get a pointer to another object; and as a moniker provider, a component that supplies monikers
identifying its objects to moniker clients.
OLE uses monikers to connect to and activate objects, whether they are in the same machine or across a network.
A very important use is for network connections. They are also used to identify, connect to, and run OLE
compound document link objects. In this case, the link source acts as the moniker provider and the container
holding the link object acts as the moniker client.
For more information, see the following topics:
Moniker Clients
Moniker Providers
OLE Moniker Implementations

Related topics
T
h
e
C
o
m
p
o
n
e
n
t
O
b
j
e
c
t
M
o
d
e
l
Moniker Clients
1/7/2020 • 2 minutes to read • Edit Online

Moniker clients must start by getting a moniker, and there are several ways for a moniker client to get a moniker.
For example, in OLE compound documents, when the end user creates a linked item (either using Insert Object
dialog, the clipboard, or drag-and drop), a moniker is embedded as part of the linked item. In that case, the
programmer has minimal contact with monikers. Programmatically, if you have an interface pointer to an object
that implements the IMoniker interface, you can use that to get a moniker, and there are methods on other
interfaces that are defined to return monikers.
There are different kinds of monikers, which are used to identify different kinds of objects, but to a moniker client,
all monikers look the same. A moniker client simply calls IMoniker::BindToObject on a moniker and gets an
interface pointer to the object that the moniker identifies. Whether the moniker identifies an object as large as an
entire spreadsheet or as small as a single cell within a spreadsheet, calling BindToObject will return a pointer to
that object. If the object is already running, BindToObject will find it in memory. If the object is stored passively
on disk, BindToObject will locate a server for that object, run the server, and have the server bring the object into
the running state. All the details of the binding process are hidden from the moniker client. Thus, for a moniker
client, using the moniker is very simple.

Related topics
M
o
n
i
k
e
r
P
r
o
v
i
d
e
r
s

O
L
E
M
o
n
i
k
e
r
I
m
p
l
e
m
e
n
t
a
t
i
o
n
s
Moniker Providers
1/7/2020 • 2 minutes to read • Edit Online

In general, a component should be a moniker provider when it allows access to one of its objects, while still
controlling the object's storage. If a component is going to hand out monikers that identify its objects, it must be
capable of performing the following tasks:
On request, create a moniker that identifies an object.
Enable the moniker to be bound when a client calls IMoniker::BindToObject on it.
A moniker provider must create a moniker of an appropriate moniker class to identify an object. The moniker class
refers to a specific implementation of the IMoniker interface that defines the type of moniker created. While you
can implement IMoniker to create a new moniker class, it is frequently unnecessary because OLE provides
implementations of several different moniker classes, each with its own CLSID. See OLE Moniker
Implementations for descriptions of moniker classes that OLE provides.

Related topics
M
o
n
i
k
e
r
C
l
i
e
n
t
s

O
L
E
M
o
n
i
k
e
r
I
m
p
l
e
m
e
n
t
a
t
i
o
n
s
OLE Moniker Implementations
1/7/2020 • 2 minutes to read • Edit Online

OLE provides implementations of several monikers for different situations, as described in the following topics:
File Monikers
Composite Monikers
Item Monikers
Anti-Monikers
Pointer Monikers
Class Monikers
Asynchronous Monikers
URL Monikers
The file, composite, and item monikers are the most frequently used monikers, because they can be used to make
nearly any object in any location. Anti-moniker and pointer monikers are primarily used inside OLE but have
some application in implementing custom monikers.

Related topics
M
o
n
i
k
e
r
C
l
i
e
n
t
s

M
o
n
i
k
e
r
P
r
o
v
i
d
e
r
s
File Monikers
1/7/2020 • 2 minutes to read • Edit Online

File monikers are the simplest moniker class. File monikers can be used to identify any object that is stored in its
own file. A file moniker acts as a wrapper for the path name the native file system assigns to the file. Calling
IMoniker::BindToObject for this moniker would cause this object to be activated and then would return an
interface pointer to the object. The source of the object named by the moniker must provide an implementation of
the IPersistFile interface to support binding a file moniker. File monikers can represent either a complete or a
relative path.
For example, the file moniker for a spreadsheet object stored as the file C:\Work\MySheet.xls would contain
information equivalent to that path name. The moniker would not necessarily consist of the same string, however.
The string is just its display name, a representation of the moniker's contents that is meaningful to an end user.
The display name, which is available through the IMoniker::GetDisplayName method, is used only when
displaying a moniker to an end user. This method gets the display name for any of the moniker classes. Internally,
the moniker may store the same information in a format that is more efficient for performing moniker operations
but isn't meaningful to users. Then, when this same object is bound through a call to the BindToObject method,
the object would be activated, probably by loading the file into the spreadsheet.
OLE offers moniker providers the helper function CreateFileMoniker that creates a file moniker object and
returns its pointer to the provider.

Related topics
A
n
t
i
-
M
o
n
i
k
e
r
s

C
l
a
s
s
M
o
n
i
k
e
r
s

C
o
m
p
o
s
i
t
e
M
o
n
i
k
e
r
s

I
t
e
m
M
o
n
i
k
e
r
s

P
o
i
n
t
e
r
M
o
n
i
k
e
r
s
Composite Monikers
1/7/2020 • 2 minutes to read • Edit Online

One of the most useful features of monikers is that you can concatenate or compose monikers together. A
composite moniker is a moniker that is a composition of other monikers and can determine the relation between
the parts. This lets you assemble the complete path to an object given two or more monikers that are the
equivalent of partial paths. You can compose monikers of the same class (such as two file monikers) or of different
classes (such as a file moniker and an item moniker). If you were to write your own moniker class, you could also
compose your monikers with file or item monikers. The basic advantage of a composite is that it gives you one
piece of code to implement every possible moniker that is a combination of simpler monikers. That significantly
reduces the need for specific custom moniker classes.
Because monikers of different classes can be composed with one another, monikers provide the ability to join
multiple namespaces. The file system defines a common namespace for objects stored as files because all
applications understand a file system path name. Similarly, a container object also defines a private namespace for
the objects that it contains because no container understands the names generated by another container.
Monikers allow these namespaces to be joined because file monikers and item monikers can be composed. A
moniker client can search the namespace for all objects using a single mechanism. The client simply calls
IMoniker::BindToObject on the moniker, and the moniker code handles the rest. A call to
IMoniker::GetDisplayName on a composite creates a name using the concatenation of all the individual
monikers' display names.
Furthermore, because you can write your own moniker class, moniker composition allows you to add customized
extensions to the namespace for objects.
Sometimes two monikers of specific classes can be combined in a special way. For example, a file moniker
representing an incomplete path and another file moniker representing a relative path can be combined to form a
single file moniker representing the complete path. For example, the file monikers "c:\work\art" could be
composed with the relative file moniker "..\backup\myfile.doc" to equal "c:\work\backup\myfile.doc". This is an
example of nongeneric composition.
Generic composition, on the other hand, permits the connection of any two monikers, no matter what their classes.
For example, you could compose an item moniker onto a file moniker, although not, of course, the other way
around.
Because a nongeneric composition depends on the class of the monikers involved, its details are defined by the
implementation of a particular moniker class. You can define new types of nongeneric compositions if you write a
new moniker class. By contrast, generic compositions are defined by OLE. Monikers created as a result of generic
composition are called generic composite monikers.
These three classes, file monikers, item monikers, and generic composite monikers, all work together, and they are
the most commonly used classes of monikers.
Moniker clients should call IMoniker::ComposeWith to create a composite on moniker with another. The
moniker it is called on internally decides whether it can do a generic or nongeneric composition. If the moniker
implementation determines that a generic composition is usable, OLE provides the CreateGenericComposite
function to facilitate this.

Related topics
A
n
t
i
-
M
o
n
i
k
e
r
s

C
l
a
s
s
M
o
n
i
k
e
r
s

F
i
l
e
M
o
n
i
k
e
r
s

I
t
e
m
M
o
n
i
k
e
r
s
P
o
i
n
t
e
r
M
o
n
i
k
e
r
s
Item Monikers
1/7/2020 • 2 minutes to read • Edit Online

Another OLE -implemented moniker class is the item moniker, which can be used to identify an object contained
in another object. One type of contained object is an OLE object embedded in a compound document. A
compound document could identify the embedded objects it contains by assigning each one an arbitrary name,
such as "embedobj1," "embedobj2," and so forth. Another type of contained object is a user selection in a
document, such as a range of cells in a spreadsheet or a range of characters in a text document. An object that
consists of a selection is called a pseudo -object because it isn't treated as a distinct object until a user marks the
selection. A spreadsheet might identify a cell range using a name such as "1A:7F," while a word processing
document might identify a range of characters using the name of a bookmark.
An item moniker is useful primarily when concatenated, or composed, with another moniker, one that identifies
the container. An item moniker is usually created and then composed onto (for example) a file moniker to create
the equivalent of a complete path to the object. For example, you can compose the file moniker
"c:\work\report.doc" (which identifies the container object) with the item moniker "embedobj1" (which identifies
an object within the container) to form the moniker "c:\work\report.doc\embedobj1," which uniquely identifies a
particular object within a particular file. You can also concatenate additional item monikers to identify deeply
nested objects. For example, if "embedobj1" is the name of a spreadsheet object, to identify a certain range of cells
in that spreadsheet object you could append another item moniker to create a moniker that would be the
equivalent of "c:\work\report.doc\embedobj1\1A:7F."
When combined with a file moniker, an item moniker forms a complete path. Item monikers thus extend the
notion of path names beyond the file system, defining path names to identify individual objects, not just files.
There is a significant difference between an item moniker and a file moniker. The path contained in a file moniker
is meaningful to anyone who understands the file system, while the partial path contained in an item moniker is
meaningful only to a particular container. Everyone knows what "c:\work\report.doc" refers to, but only one
particular container object knows what "1A:7F" refers to. One container cannot interpret an item moniker created
by another application; the only container that knows which object is referred to by an item moniker is the
container that assigned the item moniker to the object in the first place. For this reason, the source of the object
named by the combination of a file and item moniker must not only implement IPersistFile, to facilitate binding
the file moniker, but also IOleItemContainer to facilitate resolving the name of the item moniker into the
appropriate object, in the context of a file.
The advantage of monikers is that someone using a moniker to locate an object doesn't need to understand the
name contained within the item moniker, as long as the item moniker is part of a composite. Generally, it would
not make sense for an item moniker to exist on its own. Instead, you would compose an item moniker onto a file
moniker. You would then call IMoniker::BindToObject on the composite, which binds the individual monikers
within it, interpreting the names.
To create an item moniker object and return its pointer to the moniker provider, OLE provides the helper function
CreateItemMoniker. This function creates an item moniker object and returns its pointer to the provider.

Related topics
A
n
t
i
-
M
o
n
i
k
e
r
s

C
l
a
s
s
M
o
n
i
k
e
r
s

C
o
m
p
o
s
i
t
e
M
o
n
i
k
e
r
s

F
i
l
e
M
o
n
i
k
e
r
s

P
o
i
n
t
e
r
M
o
n
i
k
e
r
s
Anti-Monikers
1/7/2020 • 2 minutes to read • Edit Online

OLE provides an implementation of a special type of moniker called an anti-moniker. You use this moniker in the
creation of new moniker classes. You use it as the inverse of the moniker that it is composed onto, effectively
canceling that moniker, in much the same way that the ".." operator moves up a directory level in a file system
command.
It is necessary to have an anti-moniker available, because once a composite moniker is created, it is not possible
to delete parts of the moniker if, for example, an object moves. Instead, you use an anti-moniker to remove one or
more entries from a composite moniker.
Anti-monikers are a moniker class explicitly intended for use as an inverse. COM defines the named
CreateAntiMoniker function, which returns an anti-moniker. You generally use this function to implement the
IMoniker::Inverse method.
An anti-moniker is only an inverse for those types of monikers that are implemented to treat anti-monikers as an
inverse. For example, if you want to remove the last piece of a composite moniker, you should not create an anti-
moniker and compose it to the end of the composite. You cannot be sure that the last piece of the composite
considers an anti-moniker to be its inverse. Instead, you should call IMoniker::Enum on the composite moniker,
specifying FALSE as the first parameter. This creates an enumerator that returns the component monikers in
reverse order. Use the enumerator to retrieve the last piece of the composite, and call Inverse on that moniker.
The moniker returned by Inverse is what you need to remove the last piece of the composite.

Related topics
C
l
a
s
s
M
o
n
i
k
e
r
s

C
o
m
p
o
s
i
t
e
M
o
n
i
k
e
r
s

F
i
l
e
M
o
n
i
k
e
r
s

I
t
e
m
M
o
n
i
k
e
r
s

P
o
i
n
t
e
r
M
o
n
i
k
e
r
s
Pointer Monikers
1/29/2020 • 2 minutes to read • Edit Online

A pointer moniker identifies an object that can exist only in the active or running state. This differs from other
classes of monikers, which identify objects that can exist in either the passive or the active state.
Suppose, for example, an application has an object that has no persistent representation. Normally, if a client of
your application needs access to that object, you could simply pass the client a pointer to the object. However,
suppose your client is expecting a moniker. The object cannot be identified with a file moniker, because it isn't
stored in a file, nor with an item moniker, because it isn't contained in another object.
Instead, your application can create a pointer moniker, which is a moniker that simply contains a pointer internally,
and pass that to the client. The client can treat this moniker like any other. However, when the client calls
IMoniker::BindToObject on the pointer moniker, the moniker code does not check the running object table
(ROT) or load anything from storage. Instead, the moniker code simply calls QueryInterface on the pointer
stored inside the moniker.
Pointer monikers allow objects that exist only in the active or running state to participate in moniker operations
and be used by moniker clients. One important difference between pointer monikers and other classes of
monikers is that pointer monikers cannot be saved to persistent storage. If you do, calling the IMoniker::Save
method returns an error. This means that pointer monikers are useful only in specialized situations. You can use
the CreatePointerMoniker function if you need to use a pointer moniker.

Related topics
A
n
t
i
-
M
o
n
i
k
e
r
s

C
l
a
s
s
M
o
n
i
k
e
r
s

C
o
m
p
o
s
i
t
e
M
o
n
i
k
e
r
s

F
i
l
e
M
o
n
i
k
e
r
s

I
t
e
m
M
o
n
i
k
e
r
s
Class Monikers
1/7/2020 • 2 minutes to read • Edit Online

Although classes are typically identified directly with CLSIDs to functions such as CoCreateInstance or
CoGetClassObject, classes may also now be identified with a moniker called a class moniker. Class monikers
bind to the class object of the class for which they are created.
The ability to identify classes with a moniker supports useful operations that are otherwise unwieldy. For
example, file monikers traditionally supported rich binding only to the class associated with the class of file they
referred to; a moniker to an Excel file would bind to an instance of an Excel object, and a moniker to a GIF image
would bind to an instance of the currently registered GIF handler. A class moniker allows you to indicate the class
you want to use to manipulate a file through composition with a file moniker. A class moniker for a 3D charting
class composed with a moniker to an Excel file yields a moniker that binds to an instance of the 3D charting
object and initializes the object with the contents of the Excel file.
Class monikers are therefore most useful in composition with other types of monikers, such as file monikers or
item monikers.
Class monikers may also be composed to the right of monikers supporting binding to the IClassActivator
interface. When composed in this manner, IClassActivator simply gives access to the class object and instances
of the class through IClassActivator::GetClassObject. Class monikers may be identified through
IMoniker::IsSystemMoniker, which returns MKSYS_CLASSMONIKER in pdwMksys.
Programmers typically create class monikers using the CreateClassMoniker function or through
MkParseDisplayName. (See IMoniker::ParseDisplayName for details.)

Related topics
A
n
t
i
-
M
o
n
i
k
e
r
s

C
o
m
p
o
s
i
t
e
M
o
n
i
k
e
r
s

F
i
l
e
M
o
n
i
k
e
r
s

I
t
e
m
M
o
n
i
k
e
r
s

P
o
i
n
t
e
r
M
o
n
i
k
e
r
s
Asynchronous Monikers
1/7/2020 • 2 minutes to read • Edit Online

The OLE moniker architecture provides a consistent, extensible programming model for working with Internet
objects, providing methods for parsing names, representing Universal Resource Locators (URLs) as printable
names, and locating and binding to the objects represented by URL strings. (Also see URL Monikers.) Standard
OLE monikers (notably, item, file, and pointer monikers), however, are inappropriate for the Internet because they
are synchronous, returning a pointer to an object or its storage only at such time as all data is available.
Depending on the amount of data to be downloaded, binding synchronously can tie up the client's user interface
for prolonged periods.
The Internet requires new approaches to application design. Applications should be able to perform all expensive
network operations asynchronously to avoid stalling the user interface. An application should be able to trigger an
operation and receive notification on full or partial completion. At that point, the application should have the
choice either of proceeding with the next step of the operation or providing additional information as needed. As a
download proceeds, an application should also be able to provide users with progress information and the
opportunity to cancel the operation at any time.
Asynchronous monikers provide these capabilities, as well as various levels of asynchronous binding behavior,
while providing backward compatibility for applications that are either unaware of or do not require asynchronous
behavior. Another OLE technology, asynchronous storage, works with asynchronous monikers to provide
asynchronous downloading of an Internet object's persistent state. The asynchronous moniker triggers the bind
operation and sets up the necessary components, including storage and stream objects, byte-array objects, and
notification sinks. Once the components are connected, the moniker gets out of the way and the rest of the bind is
executed mainly between the components implementing the asynchronous storage components and the object.
For more information, see the following topics:
Asynchronous and Synchronous Monikers
Asynchronous and Synchronous Binding
Asynchronous and Synchronous Storage
Data-Pull Model and Data-Push Model

Related topics
U
R
L
M
o
n
i
k
e
r
s
Asynchronous and Synchronous Monikers
1/7/2020 • 2 minutes to read • Edit Online

A client of a standard, synchronous OLE moniker typically creates and holds a reference to the moniker, as well as
the bind-context to be used during binding. The components involved in using traditional monikers are shown in
the following diagram.

Clients typically create standard monikers by calling functions such as CreateFileMoniker, CreateItemMoniker,
or CreatePointerMoniker or, because they are can be saved to persistent storage, through OleSaveToStream
and OleLoadFromStream. Monikers may also be obtained from a container object by calling the
IBindHost::CreateMoniker method. Clients create bind contexts by calling the CreateBindCtx function and then
pass the bind context to the moniker with calls to IMoniker::BindToStorage or IMoniker::BindToObject.
As shown in the following diagram, a client of an asynchronous moniker also creates and holds a reference to the
moniker and bind context to be used during binding.

To get asynchronous behavior, the client implements the IBindStatusCallback interface on a bind-status-callback
object and calls either the RegisterBindStatusCallback function or the CreateAsyncBindCtx function to register
this interface with the bind context. The moniker passes a pointer to its IBinding interface in a call to the
IBindStatusCallback::OnStartBinding method. The client tells the asynchronous moniker how it wants to bind
on return from the moniker's call to IBindStatusCallback::GetBindInfo method.

Related topics
A
s
y
n
c
h
r
o
n
o
u
s
M
o
n
i
k
e
r
s
Asynchronous and Synchronous Binding
1/7/2020 • 2 minutes to read • Edit Online

The client may check to see whether the moniker is asynchronous by calling the IsAsyncMoniker function. If the
client returns the BINDF_ASYNCHRONOUS flag, rather than returning an object pointer or a storage pointer from
subsequent calls to IMoniker::BindToStorage or IMoniker::BindToObject, the moniker returns
MK_S_ASYNCHRONOUS in place of the object pointer and NULL in place of the storage pointer. In response, the
client should wait to receive the requested object or storage during implementation of
IBindStatusCallback::OnDataAvailable and IBindStatusCallBack::OnObjectAvailable.
The callback object also receives progress notification through IBindStatusCallback::OnProgress, data
availability notification through OnDataAvailable, and various other notifications from the moniker about the
status of the binding operation.
If the client does not return the BINDF_ASYNCHRONOUS flag from the moniker's call to
IBindStatusCallback::GetBindInfo, the bind operation will proceed synchronously and the desired object or
storage will be returned from subsequent calls to BindToObject or BindToStorage. Similarly, if the client desires
synchronous operation and does not wish to receive any progress notifications or callbacks, it can request an
asynchronous moniker to behave synchronously by not implementing IBindStatusCallback. In such cases, the
asynchronous moniker will behave like a standard synchronous moniker.

Related topics
A
s
y
n
c
h
r
o
n
o
u
s
M
o
n
i
k
e
r
s
Asynchronous and Synchronous Storage
1/7/2020 • 2 minutes to read • Edit Online

Asynchronous monikers may also return an Asynchronous Storage object in the


IBindStatusCallback::OnDataAvailable notification. This storage object may allow access to some of the object's
persistent data while the binding is still in progress. A client can choose between two modes for the storage:
blocking and nonblocking.
In blocking mode, which is compatible with current implementations of storage objects, if data is unavailable, the
call blocks until data arrives. In nonblocking mode, rather than blocking the call, the storage object returns a new
error E_PENDING when data is unavailable. A client aware of asynchronous binding and storage notes this error
and waits for further notifications (OnDataAvailable) to retry the operation. A client can choose between a
synchronous (blocking) and asynchronous (nonblocking) storage by choosing whether to set the
BINDF_ASYNCSTORAGE flag in the grfBINDF value returned to IBindStatusCallback::GetBindInfo.

Related topics
A
s
y
n
c
h
r
o
n
o
u
s
M
o
n
i
k
e
r
s
Data-Pull Model and Data-Push Model
1/7/2020 • 2 minutes to read • Edit Online

A client of an asynchronous moniker can choose between a data-pull and data-push model for driving an
asynchronous IMoniker::BindToStorage operation and receiving asynchronous notifications. In the data-pull
model, the client drives the bind operation and the moniker provides data to the client only as it is read. In other
words, after the first call to IBindStatusCallback::OnDataAvailable, the moniker does not provide any data to
the client unless the client has consumed all of the data that is already available.
Because data is downloaded only as it is requested, clients that choose the data-pull model must make sure to read
this data in a timely manner. In the case of Internet downloads with URL monikers, the bind operation may fail if a
client waits too long before requesting more data.
In the data-push model, the moniker drives the asynchronous bind operation and continuously notifies the client
whenever new data is available. The client may choose whether to read the data at any point during the bind
operation, but the moniker will drive the bind operation to completion regardless.
Also, you need to remember to follow the COM rules for memory allocation when using asynchronous monikers,
specifically the following:
Whenever a COM interface or function call returns a buffer (string or other) to its client, the client is responsible
for freeing the memory by calling CoTaskMemFree.
Whenever a COM interface or function requires a buffer from its client, the client must allocate that buffer using
CoTaskMemAlloc and the callee must free it.
Be sure to follow these rules when allocating strings or buffers that are passed to asynchronous monikers, and
remember to free memory returned by asynchronous monikers. See Managing Memory Allocation and related
topics for complete details.

Related topics
A
s
y
n
c
h
r
o
n
o
u
s
M
o
n
i
k
e
r
s
URL Monikers
1/7/2020 • 2 minutes to read • Edit Online

The OLE moniker architecture provides a convenient programming model for working with URLs. The moniker
architecture supports extensible and complete name parsing through the MkParseDisplayName function and
the IParseDisplayName and IMoniker interfaces, as well as printable names through the
IMoniker::GetDisplayName method. The IMoniker interface is the way you actually use URLs you encounter,
and building components that fit into the moniker architecture is the way to actually extend URL namespaces in
practice.
A system-provided moniker class, the URL moniker, provides a framework for building and using certain URLs.
Because URLs frequently see resources across high-latency networks, the URL moniker supports asynchronous
as well as synchronous binding. The URL moniker does not currently support asynchronous storage.
The following diagram shows the components involved in using URL monikers. All these components should be
familiar. (See Asynchronous Monikers.)

Like all moniker clients, a user of URL Monikers typically creates and holds a reference to the moniker as well as
to the bind context to be used during binding (IMoniker::BindToStorage or IMoniker::BindToObject). To
support asynchronous binding, the client can implement a bind-status-callback object, which implements the
IBindStatusCallback interface, and register it with the bind context using the RegisterBindStatusCallback
function. This object will receive the transport's IBinding interface during calls to
IBindStatusCallback::OnStartBinding.
The URL Moniker identifies the protocol being used by parsing the URL prefix and then retrieves the IBinding
interface from the transport layer. The client uses IBinding to support pausing, cancellation, and prioritization of
the binding operation. The callback object also receives progress notification through
IBindStatusCallback::OnProgress, data availability notification through
IBindStatusCallback::OnDataAvailable, and various, other transport-layer notifications about the status of the
binding. The URL moniker or specific transport layers may also request extended information from the client
through IBindStatusCallback::QueryInterface, allowing the client to provide protocol-specific information that
will affect the bind operation.
For more information, see the following topics:
Callback Synchronization
Media-Type Negotiation
URL Moniker Functions

Related topics
A
s
y
n
c
h
r
o
n
o
u
s
M
o
n
i
k
e
r
s

A
b
o
u
t
U
R
L
M
o
n
i
k
e
r
s
Callback Synchronization
1/7/2020 • 2 minutes to read • Edit Online

The asynchronous WinInet API (used for the most common protocols) leaves the synchronization of the callback
mechanism and the calling application as an exercise for the client. This is intentional because it allows the greatest
degree of flexibility. The default protocols and the URL moniker implementation perform this synchronization and
guarantee that single-threaded and apartment-threaded applications never have to deal with free-thread-style
contention. That is, the client's IEnumFORMATETC and IBindStatusCallback interfaces are called only on their
proper threads. This feature is transparent to the user of the URL mMoniker as long each thread that calls
IMoniker::BindToStorage and IMoniker::BindToObject has a message queue.
The asynchronous moniker specification requires more precise control over the prioritization and management of
downloads than is allowed for by either WinSock or WinInet. Accordingly, a URL moniker manages all the
downloads for any given caller's thread, using (as part of its synchronization) a priority scheme based on the
IBinding specification.

Related topics
U
R
L
M
o
n
i
k
e
r
s
Media-Type Negotiation
1/7/2020 • 2 minutes to read • Edit Online

Many application-layer Internet protocols are based on the exchange of messages in a simple, flexible format called
Multipurpose Internet Mail Extensions (MIME ). Although MIME originated as a standard for exchanging electronic
mail messages, it is used today by a wide variety of applications to specify mutually understood data formats as
MIME, or media, types. The process is called media -type negotiation.
Media types are simple strings that denote a type and subtype (such as "text/plain" or "text/HTML"). They are used
to label data or qualify a request. A Web browser, for example, as part of an HTTP request-for-data or request-for-
info, specifies that it is requesting "image/gif" or "image/jpeg" Media Types, to which a web server responds by
returning the appropriate media type and, if the call was a request-for-data, the data itself in the requested format.
Media-type negotiation is often similar to how existing desktop applications negotiate with the system clipboard to
determine which data format to paste when a user chooses Edit/Paste or queries for formats when receiving an
IDataObject pointer during a drag-and-drop operation. The subtle difference in HTTP media-type negotiation is
that the client does not know ahead of time which formats the server has available. Therefore, the client specifies
up-front the media types it supports, in order of greatest fidelity, and the server responds with the best available
format.
URL monikers support media-type negotiation as a way for Internet clients and servers to agree upon formats to
be used when downloading data in BindToStorage operations. To support media-type negotiation, a client
implements the IEnumFORMATETC interface and calls the RegisterFormatEnumerator function to register it
with the bind context. The format enumerator lists the formats the client can accept. A URL moniker translates
these formats into media types when binding to HTTP URLs.
The possible media types requested by the client are represented to URL monikers through FORMATETC
structures available from the IEnumFORMATETC enumerator registered by the caller on the bind context: Each
FORMATETC specifies a clipboard format identifying the media type. For example, the following code fragment
specifies that the media type is PostScript.

FORMATETC fmtetc;
fmtetc.cfFormat = RegisterClipboardFormat(CF_MIME_POSTSCRIPT);
. . .

A client can set the clipboard format to the special media type CF_NULL to indicate that the default media type of
the resource pointed to by the URL should be retrieved. This format is usually the last one in which the client is
interested. When no enumerator is registered with the bind context, a URL moniker works as if an enumerator
containing a single FORMATETC with cfFormat=CF_NULL is available, automatically downloading the default
media-type.
Whatever media type is to be used, the client is notified of the choice by means of the pformatetc argument on its
IBindStatusCallback::OnDataAvailable method. The callback occurs within the context of the client's call to
BindToStorage.

NOTE
If received content is of an unrecognized media-type, the client automatically calls RegisterMediaTypes to register the new
type.
Related topics
U
R
L
M
o
n
i
k
e
r
s
URL Moniker Functions
1/7/2020 • 2 minutes to read • Edit Online

URL moniker functions insulate developers from the complexities of creating, managing, and using URL monikers.
These functions are as follows:
CreateURLMoniker
IsValidURL
RegisterMediaTypes
CreateFormatEnumerator
RegisterFormatEnumerator
RevokeFormatEnumerator
RegisterMediaTypeClass
FindMediaTypeClass
GetClassFileOrMime
UrlMkSetSessionOption
Your familiarity with these functions can be as follows:
Be familiar with CreateURLMoniker and IsValidURL if you will be using URL monikers in stand-alone
applications. If you are authoring an ActiveX control, you should use IBindHost::CreateMoniker instead of
CreateURLMoniker.
Be familiar with RegisterMediaTypes, CreateFormatEnumerator, RegisterFormatEnumerator, and
RevokeFormatEnumerator if you will be performing any MIME negotiation with URL monikers.
Be familiar with RegisterMediaTypeClass, FindMediaTypeClass, GetClassFileOrMime, and
UrlMkSetSessionOption only if you have significant experience both with URL monikers and with COM.

Related topics
U
R
L
M
o
n
i
k
e
r
s
Events in COM and Connectable Objects
1/29/2020 • 2 minutes to read • Edit Online

When a program detects something that has happened, it can notify its clients. For example, if a stock ticker
program detects a change in the price of a stock, it can notify all clients of the change. This notification process is
referred to as firing an event.
With COM, server objects can use COM events to fire events without any information about what objects will be
notified. Objects can also use connectable objects to maintain detailed information about clients who have
requested notifications.
COM connectable objects provide outgoing interfaces to their clients in addition to their incoming interfaces. As a
result, objects and their clients can engage in bidirectional communication. Incoming interfaces are implemented
on an object and receive calls from external clients of an object, while outgoing interfaces are implemented on the
client's sink and receive calls from the object. The object defines an interface it would like to use, and the client
implements it.
An object defines its incoming interfaces and provides implementations of these interfaces. Incoming interfaces
are available to clients through the object's IUnknown::QueryInterface method. Clients call the methods of an
incoming interface on the object, and the object performs desired actions on behalf of the client.
Outgoing interfaces are also defined by an object, but the client provides the implementations of the outgoing
interfaces on a sink object that the client creates. The object then calls methods of the outgoing interface on the
sink object to notify the client of changes in the object, to trigger events in the client, to request something from
the client, or, in fact, for any purpose the object creator comes up with.
An example of an outgoing interface is an IButtonSink interface defined by a push button control to notify its
clients of its events. For example, the button object calls IButtonSink::OnClick on the client's sink object when the
user clicks the button on the screen. The button control defines the outgoing interface. For a client of the button to
handle the event, the client must implement that outgoing interface on a sink object and then connect that sink to
the button control. Then, when events occur in the button, the button will call the sink, at which time the client can
execute whatever action it wishes to assign to that button click.
Connectable objects provide a general mechanism for object-to-client communication. Any object that wishes to
expose events or notifications of any kind can use this technology. In addition to the general connectable object
technology, COM provides many special purpose sink and site interfaces used by objects to notify clients of
specific events of interest to the client. For example, IAdviseSink may be used by objects to notify clients of data
and view changes in the object.
For more information, see the following topics:
Architecture of Connectable Objects
Connectable Object Interfaces
Architecture of Connectable Objects
1/29/2020 • 3 minutes to read • Edit Online

The connectable object is only one piece of the overall architecture of connectable objects. This technology
includes the following elements:
Connectable object. Implements the IConnectionPointContainer interface; creates at least one connection
point object; defines an outgoing interface for the client.
Client. Queries the object for IConnectionPointContainer to determine whether the object is connectable;
creates a sink object to implement the outgoing interface defined by the connectable object.
Sink object. Implements the outgoing interface; used to establish a connection to the connectable object.
Connection point object. Implements the IConnectionPoint interface and manages connection with the
client's sink.
The relationships between client, connectable object, a connection point, and a sink are illustrated in the following
diagram:

Before the connection point object calls methods in the sink interface in step 3 in the preceding diagram, it must
QueryInterface for the specific interface required, even if the pointer was already passed in the step 2 call to the
Advise method.
Two enumerator objects are also involved in this architecture though not shown in the illustration. One is created
by a method in IConnectionPointContainer to enumerate the connection points within the connectable object.
The other is created by a method in IConnectionPoint to enumerate the connections currently established to that
connection point. One connection point can support multiple connected sink interfaces, and it should iterate
through the list of connections each time it makes a method call on that interface. This process is known as
multicasting.
When working with connectable objects, it is important to understand that the connectable object, each connection
point, each sink, and all enumerators are separate objects with separate IUnknown implementations, separate
reference counts, and separate lifetimes. A client using these objects is always responsible for releasing all
reference counts it owns.

NOTE
A connectable object can support more than one client and can support multiple sinks within a client. Likewise, a sink can be
connected to more than one connectable object.
The steps for establishing a connection between a client and a connectable object are as follows:
1. The client queries for IConnectionPointContainer on the object to determine whether the object is
connectable. If this call is successful, the client holds a pointer to the IConnectionPointContainer interface on
the connectable object and the connectable object reference counter has been incremented. Otherwise, the
object is not connectable and does not support outgoing interfaces.
2. If the object is connectable, the client next tries to obtain a pointer to the IConnectionPoint interface on a
connection point within the connectable object. There are two methods for obtaining this pointer, both in
IConnectionPointContainer::FindConnectionPoint and in
IConnectionPointContainer::EnumConnectionPoints. There are a few additional steps needed if
EnumConnectionPoints is used. (See Using IConnectionPointContainer for more information.) If successful,
the connectable object and the client both support the same outgoing interface. The connectable object defines
it and calls it, and the client implements it. The client can then communicate through the connection point
within the connectable object.
3. The client then calls Advise on the connection point to establish a connection between its sink interface and the
object's connection point. After this call, the object's connection point holds a pointer to the outgoing interface
on the sink.
4. The code inside Advise calls QueryInterface on the interface pointer that is passed in, asking for the specific
interface identifier to which it connects.
5. The object calls methods on the sink's interface as needed, using the pointer held by its connection point.
6. The client calls Unadvise to terminate the connection. Then the client calls IConnectionPoint::Release to free
its hold on the connection point and, therefore, the main connectable object also. The client must also call
IConnectionPointContainer::Release to free its hold on the main connectable object.

Related topics
C
o
n
n
e
c
t
a
b
l
e
O
b
j
e
c
t
I
n
t
e
r
f
a
c
e
s
Connectable Object Interfaces
1/7/2020 • 2 minutes to read • Edit Online

Support for connectable objects requires support for four interfaces:


IConnectionPointContainer on the connectable object
IConnectionPoint on the connection point object
IEnumConnectionPoints on an enumerator object
IEnumConnections on an enumerator object
The latter two are defined as standard enumerators for the types IConnectionPoint * and CONNECTDATA.
Additionally, the connectable object can optionally support IProvideClassInfo and IProvideClassInfo2 to
provide enough information to a client so that the client can provide support for the outgoing interface at run
time.
Finally, the client must provide a sink object that implements the outgoing interface, which is a custom COM
interface defined by the connectable object.
For more information, see the following topics:
Using IConnectionPointContainer
Using IConnectionPoint
Using IProvideClassInfo

Related topics
A
r
c
h
i
t
e
c
t
u
r
e
o
f
C
o
n
n
e
c
t
a
b
l
e
O
b
j
e
c
t
s
Using IConnectionPointContainer
1/29/2020 • 2 minutes to read • Edit Online

A connectable object implements IConnectionPointContainer (and exposes it through QueryInterface) to


indicate the existence of outgoing interfaces. For each outgoing interface, the connectable object manages a
connection point sub-object, which itself implements IConnectionPoint. The connectable object therefore
contains the connection points, hence the naming of IConnectionPointContainer and IConnectionPoint.
Through IConnectionPointContainer, a client can perform two operations. First, if the client already has the IID
for an outgoing interface that it supports, it can locate the corresponding connection point for the IID using
IConnectionPointContainer::FindConnectionPoint. The client cannot query for the connection point directly
because of the container/contained relationship between the connectable object and its contained connection
points. Basically, FindConnectionPoint is the QueryInterface for outgoing interfaces when the IID is known to
the client.
Second, the client can enumerate all connection points within the connectable object through
IConnectionPointContainer::EnumConnectionPoints. This method returns an IEnumConnectionPoints
interface pointer for a separate enumerator object. Through IEnumConnectionPoints::Next, the client can
obtain IConnectionPoint interface pointers to each connection point.
After the client obtains the IConnectionPoint interface, it must call
IConnectionPoint::GetConnectionInterface to determine the IID of the outgoing interface supported by each
connection point. If the client already supports that outgoing interface, it can establish a connection. Otherwise, it
may still be able to support the outgoing interface by using information from the connectable object's type library
to provide support at run time. This technique requires that the connectable object support the
IProvideClassInfo interface. (See Using IProvideClassInfo.)
Because the enumerator is a separate object, the client must call IEnumConnectionPoints::Release when the
enumerator is no longer needed. In addition, each connection point is an object with a separate reference count
from the containing connectable object. Therefore, the client must also call IConnectionPoint::Release for each
connection point accessed either through the enumerator or through FindConnectionPoint.

Related topics
C
o
n
n
e
c
t
a
b
l
e
O
b
j
e
c
t
I
n
t
e
r
f
a
c
e
s
Using IConnectionPoint
1/7/2020 • 2 minutes to read • Edit Online

When the client has a pointer to a connection point, it can perform the following operations as expressed through
IConnectionPoint:
First, IConnectionPoint::GetConnectionInterface retrieves the outgoing interface IID supported by the
connection point. When used in conjunction with IEnumConnectionPoints, this method allows the client to
examine the IIDs of all outgoing interfaces supported on the connectable object.
Second, a client can navigate from the connection point back to the connectable object's
IConnectionPointContainer interface through the IConnectionPoint::GetConnectionPointContainer
method.
Third, the most interesting methods for the client are IConnectionPoint::Advise and
IConnectionPoint::Unadvise. When a client wishes to connect its own sink object to the connectable object,
the client passes the sink's IUnknown pointer (or any other interface pointer on the same object) to Advise.
The connection point queries the sink for the specific outgoing interface that is expected. If that interface is
available on the sink, the connection point then stores the interface pointer. From this point until Unadvise is
called, the connectable object will make calls to the sink through this interface when events occur. To disconnect
the sink from the connection point, the client passes a key returned from Advise to the Unadvise method.
Unadvise must call Release on the sink interface.
Finally, a client can ask a connection point to enumerate all the connections to it that exist through
IConnectionPoint::EnumConnections. This method creates an enumerator object (with a separate reference
count) returning an IEnumConnections pointer to it. The client must call Release when the enumerator is no
longer needed. Additionally, the enumerator returns a series of CONNECTDATA structures, one for each
connection. Each structure describes one connection using the IUnknown pointer of the sink as well as the
connection key originally returned from Advise. When done with these sink interface pointers, the client must
call Release on each pointer returned in a CONNECTDATA structure.

Related topics
C
o
n
n
e
c
t
a
b
l
e
O
b
j
e
c
t
I
n
t
e
r
f
a
c
e
s
Using IProvideClassInfo
1/7/2020 • 2 minutes to read • Edit Online

A connectable object can offer the IProvideClassInfo and IProvideClassInfo2 interfaces so that its clients can
easily examine its type information. This capability is important when dealing with outgoing interfaces, which, by
definition, are defined by an object but implemented by a client on its own sink object. In some cases, an outgoing
interface is known at compile time to both the connectable object and the sink object; such is the case with
IPropertyNotifySink.
In other cases, however, only the connectable object knows its outgoing interface definitions at compile time. In
these cases, the client must obtain the type information for the outgoing interface so that it can dynamically
provide a sink supporting the right entry points, as follows:
1. The client enumerates the connection points and then, to obtain the IIDs of outgoing interfaces supported by
the connectable object, calls IConnectionPoint::GetConnectionInterface for each connection point.
2. The client queries the connectable object for one of the IProvideClassInfo interfaces.
3. The client calls methods in the IProvideClassInfo interfaces to get the type information for the outgoing
interface.
4. The client creates a sink object supporting the outgoing interface.
5. The process continues, and the client calls IConnectionPoint::Advise to connect its sink to the connection
point.
In the type information, the attribute source marks an interface or dispinterface listed under a coclass as an
outgoing interface. Those listed without this attribute are considered incoming interfaces.

Related topics
C
o
n
n
e
c
t
a
b
l
e
O
b
j
e
c
t
I
n
t
e
r
f
a
c
e
s

P
r
o
v
i
d
i
n
g
C
l
a
s
s
I
n
f
o
r
m
a
t
i
o
n
Component Categories Manager Implementation
1/7/2020 • 2 minutes to read • Edit Online

As the number of available components grows, it becomes increasingly difficult to manage these components. In
terms of the interfaces they expose as well as the tasks they perform, many components offer similar functionality.
It is often necessary to enumerate the components that can be used in a certain context. Examples of this are the
Insert Object dialog box used in OLE compound documents and the Insert Control dialog box used in OLE
controls. These dialog boxes list all components that fulfill (or claim to fulfill) the interface contracts for compound
documents or controls. These existing categories (OLE document, OLE control) do not imply an exact interface
signature. OLE documents have to expose a certain set of core interfaces (for example, IOleObject or
IPersistStorage) but can also expose additional interfaces such as IOleLink.
In the past, components have been tagged by adding a human-readable name ("Insertable", "Control", and so on)
as a subkey to the HKEY_CLASSES_ROOT\CLSID\{...} registry key corresponding to the component. This works
well for a central definition of categories but risks name collisions when many independent parties define new
categories. As in other areas of COM, the solution to providing an extensible namespace lies in the use of globally
unique identifiers (GUIDs). Instead of using a human-readable name, a unique number (CATID ) is assigned to each
category.
Another limitation with the existing categorization is that it is limited to expressing the capabilities of the
component itself. Many components require certain capabilities from the containers. When such a component is
inserted into a container, the insertion can fail or behave unexpectedly, even though the component fulfills the
contracts implied by one of its categories. To enumerate the components that can be used successfully in certain
situations, the capabilities of both the component and the container must be considered.
Because of these considerations, the following changes were made to the existing categorization:
Categories are indicated by using CATIDs that are globally unique identifiers.
Under the Components subkey of the HKEY_CLASSES_ROOT\CLSID registry key, two separate subkeys,
"Implemented Categories" and "Required Categories", were developed. These subkeys contain the lists of
CATIDs that are provided by the component or that the container of the component must provide.
To ease managing the component categories, categories are listed in a central place in the registry:
HKEY_CLASSES_ROOT\Component Categories. This key lists the installed categories both with their CATID
and with localized, human-readable names.
For more information, see the following topics:
Categorizing by Component Capabilities
Categorizing by Container Capabilities
The Component Categories Manager
Default Classes and Associations
Defining Component Categories
Associating Icons with a Category
Categorizing by Component Capabilities
1/7/2020 • 2 minutes to read • Edit Online

Component categories can be used to display a subset of all of the installed components. Each component
category is identified by a GUID, referred to as a Category ID (CATID ). Each CATID has a list of locale-tagged,
human-readable names associated with it. A listing of the CATIDs and the human-readable names is stored in a
well-known location in the registry.
For example, all components that implement the functionality for OLE document embedding can be classified
within a component category. In the past, these objects would have been identified by the "Insertable" key in the
registry. To use component categories instead, the following information would be added to the registry:

HKEY_CLASSES_ROOT\Component Categories\{40FC6ED3-2438-11cf-A3DB-080036F12502}
(Default) = ""
409 = "Embeddable Objects"

Each class that implements the functionality corresponding to a component category lists the category ID for that
category within the CLSID key in the registry. Because a single component can support a wide range of
functionality, components can belong to multiple component categories. For example, a particular OLE control
might support all of the functionality required to participate as OLE document embedding, Microsoft Visual Basic
data binding, and Internet functionality. Such a control would have the following information stored in its CLSID
key in the registry:

;The CLSID for "My Super OLE Control" is {12345678-ABCD-4321-0101-00000000000C}HKEY_CLASSES_ROOT\CLSID\


{12345678-ABCD-4321-0101-00000000000C}\Implemented Categories
;The CATID for "Insertable" is {40FC6ED3-2438-11cf-A3DB-080036F12502} HKEY_CLASSES_ROOT\CLSID\{12345678-ABCD-
4321-0101-00000000000C}Implemented Categories\{40FC6ED3-2438-11cf-A3DB-080036F12502}
;The CATID for "Control" is {40FC6ED4-2438-11cf-A3DB-080036F12502} HKEY_CLASSES_ROOT\CLSID\{12345678-ABCD-
4321-0101-00000000000C}Implemented Categories\{40FC6ED4-2438-11cf-A3DB-080036F12502}
;The CATID for an internet aware control is {...CATID_InternetAware...} HKEY_CLASSES_ROOT\CLSID\{12345678-
ABCD-4321-0101-00000000000C}Implemented Categories\{...CATID_InternetAware...}

With this information, a container can enumerate the controls installed on a system and display only those
controls that support the functionality required by the container. The use of component categories provides a way
to categorize components by the implemented functionality of the component.

Related topics
A
s
s
o
c
i
a
t
i
n
g
I
c
o
n
s
w
i
t
h
a
C
a
t
e
g
o
r
y

C
a
t
e
g
o
r
i
z
i
n
g
b
y
C
o
n
t
a
i
n
e
r
C
a
p
a
b
i
l
i
t
i
e
s

D
e
f
a
u
l
t
C
l
a
s
s
e
s
a
n
d
A
s
s
o
c
i
a
t
i
o
n
s

D
e
f
i
n
i
n
g
C
o
m
p
o
n
e
n
t
C
a
t
e
g
o
r
i
e
s

T
h
e
C
o
m
p
o
n
e
n
t
C
a
t
e
g
o
r
i
e
s
M
a
n
a
g
e
r
Categorizing by Container Capabilities
1/7/2020 • 2 minutes to read • Edit Online

Components often require certain functionality from the container and will not work with a container that does
not provide the support. The user interface should filter out components that require functionality the container
does not support. To accomplish this, components can be categorized by the required container functionality.
An example of components that require functionality from the container and do not work in containers that do not
support that functionality are simple frame OLE controls. Categorizing by container capabilities is accomplished
by an additional registry key within the component's CLSID key:

;The CLSID for "Simple Frame Control" is {123456FF-ABCD-4321-0101-00000000000C}HKEY_CASSES_ROOT\CLSID\


{12346FF-ABCD-4321-0101-00000000000C}\Implemented Categories
;The CATID for "Control" is {40FC6ED4-2438-11cf-A3DB-080036F12502} HKEY_CLASSES_ROOT\CLSID\{123456FF-ABCD-
4321-0101-00000000000C}Implemented Categories\{40FC6ED4-2438-11cf-A3DB-080036F12502}
;The CATID for simple frame controls is {...CATID_SimpleFrameControl...} HKEY_CLASSES_ROOT\CLSID\{123456FF-
ABCD-4321-0101-00000000000C}Implemented Categories\{...CATID_SimpleFrameControl...}
HKEY_CLASSES_ROOT\CLSID\{123456FF-ABCD-4321-0101-00000000000C}Required Categories\
{...CATID_SimpleFrameControl...}

As shown in this example, a component can belong to component categories that indicate supported functionality
as well as to component categories that indicate required functionality.
In the following example, the button control is a generic OLE control that supports no additional functionality. It
will work in any OLE control container.

HKEY_CLASSES_ROOT\CLSID\{...CLSID_Button...}\Implemented Categories
HKEY_CLASSES_ROOT\CLSID\{...CLSID_Button...}\Implemented Categories\{...CATID_Control...}

Compare the preceding example with the next example in which the MyDBControl can use Visual Basic data
binding if the container supports it. However, it has been defined so that it will work in containers that do not
support Visual Basic data binding (perhaps by a different database API):

HKEY_CLASSES_ROOT\CLSID\{...CLSID_MyDBControl...}\Implemented Categories
HKEY_CLASSES_ROOT\CLSID\{...CLSID_MyDBControl...}\Implemented Categories\{...CATID_Control...}
HKEY_CLASSES_ROOT\CLSID\{...CLSID_MyDBControl...}\Implemented Categories\{...CATID_VBDatabound...}

The GroupBox control is a simple frame control. It relies on the container implementing the ISimpleFrameSite
interface and will work correctly only in such containers:

HKEY_CLASSES_ROOT\CLSID\{...CLSID_GroupBox...}\Implemented Categories
HKEY_CLASSES_ROOT\CLSID\{...CLSID_GroupBox...}\Implemented Categories\{...CATID_Control...}
HKEY_CLASSES_ROOT\CLSID\{...CLSID_GroupBox...}\Implemented Categories\{...CATID_SimpleFrame...}
HKEY_CLASSES_ROOT\CLSID\{...CLSID_GroupBox...}\Required Categories\{...CATID_SimpleFrame...}

A container that supports Visual Basic data bound controls but does not support simple frame controls would
specify CATID_Control and CATID_VBDatabound to the insert control user interface. The list of controls displayed
to the user would contain the CLSID_Button and CLSID_MyDBControl. CLSID_GroupBox would not be
displayed.

Related topics
A
s
s
o
c
i
a
t
i
n
g
I
c
o
n
s
w
i
t
h
a
C
a
t
e
g
o
r
y

C
a
t
e
g
o
r
i
z
i
n
g
b
y
C
o
m
p
o
n
e
n
t
C
a
p
a
b
i
l
i
t
i
e
s

D
e
f
a
u
l
t
C
l
a
s
s
e
s
a
n
d
A
s
s
o
c
i
a
t
i
o
n
s

D
e
f
i
n
i
n
g
C
o
m
p
o
n
e
n
t
C
a
t
e
g
o
r
i
e
s

T
h
e
C
o
m
p
o
n
e
n
t
C
a
t
e
g
o
r
i
e
s
M
a
n
a
g
e
r
The Component Categories Manager
1/7/2020 • 2 minutes to read • Edit Online

To facilitate the handling of component categories and to guarantee consistency of the registry, the system
provides the Component Categories Manager, a COM object with a CLSID of
CLSID_StdComponentCategoriesMgr. This COM object provides the following interfaces:
ICatInformation
ICatRegister
ICatInformation provides methods for obtaining information about the categories implemented or required by
a certain class and provides information about the categories registered on a given machine.
ICatRegister provides methods for registering and unregistering component category information in the
registry. This includes both the human-readable names of categories and the categories implemented or required
by a given component or class.

Related topics
A
s
s
o
c
i
a
t
i
n
g
I
c
o
n
s
w
i
t
h
a
C
a
t
e
g
o
r
y

C
a
t
e
g
o
r
i
z
i
n
g
b
y
C
o
m
p
o
n
e
n
t
C
a
p
a
b
i
l
i
t
i
e
s

C
a
t
e
g
o
r
i
z
i
n
g
b
y
C
o
n
t
a
i
n
e
r
C
a
p
a
b
i
l
i
t
i
e
s

D
e
f
a
u
l
t
C
l
a
s
s
e
s
a
n
d
A
s
s
o
c
i
a
t
i
o
n
s

D
e
f
i
n
i
n
g
C
o
m
p
o
n
e
n
t
C
a
t
e
g
o
r
i
e
s
Default Classes and Associations
1/7/2020 • 2 minutes to read • Edit Online

For certain categories, a single class can be associated as the default class. The default class is selected whenever
that particular category of object is required. While this may not be useful for all component categories,
establishing a default class can be helpful when a particular class must be loaded from a list of possible classes
without user intervention. Administrators define which class can be used by manipulating the registry.
To associate a default class with a category, introduce a CLSID key with the same CLSID as the CATID of the
component category chosen as the default. Then add a TreatAs key to this key, using the value for the CLSID of
the default class for the category. To use the default class for a component category, use CoCreateInstance or
CoGetClassObject, specifying the CATID for the CLSID parameter. This automatically redirects to the CLSID
established as the default for this category. The registry entry is as follows:

HKEY_CLASSES_ROOT\CLSID
{catid}
TreatAs
= default clsid

During installation, a component can check for the existence of any default class keys for its categories and
present the user with options for overriding the current settings.

Related topics
A
s
s
o
c
i
a
t
i
n
g
I
c
o
n
s
w
i
t
h
a
C
a
t
e
g
o
r
y

C
a
t
e
g
o
r
i
z
i
n
g
b
y
C
o
m
p
o
n
e
n
t
C
a
p
a
b
i
l
i
t
i
e
s

C
a
t
e
g
o
r
i
z
i
n
g
b
y
C
o
n
t
a
i
n
e
r
C
a
p
a
b
i
l
i
t
i
e
s

D
e
f
i
n
i
n
g
C
o
m
p
o
n
e
n
t
C
a
t
e
g
o
r
i
e
s
T
h
e
C
o
m
p
o
n
e
n
t
C
a
t
e
g
o
r
i
e
s
M
a
n
a
g
e
r
Defining Component Categories
1/7/2020 • 2 minutes to read • Edit Online

The author of a component category definition creates a unique GUID (the CATID ) that is published along with
the definition. Other parties know the definition of this type and can make use of its supported classes
accordingly. Like the method signature of an interface, a category's semantics should not be modified after being
installed. It is better to maintain backward compatibility of the category by introducing a new category identifier
with revised semantics.
Because interface identifiers (IID ) and component category identifiers (CATID ) exist in different namespaces, it
seems as if it would be possible to use the same GUID for both an IID and a CATID. However, since IIDs are often
used for the CLSID of the interface's proxy/stub server, there is the potential for conflict. Therefore, do not use the
same GUID for an IID and CATID.

Related topics
A
s
s
o
c
i
a
t
i
n
g
I
c
o
n
s
w
i
t
h
a
C
a
t
e
g
o
r
y

C
a
t
e
g
o
r
i
z
i
n
g
b
y
C
o
m
p
o
n
e
n
t
C
a
p
a
b
i
l
i
t
i
e
s

C
a
t
e
g
o
r
i
z
i
n
g
b
y
C
o
n
t
a
i
n
e
r
C
a
p
a
b
i
l
i
t
i
e
s

D
e
f
a
u
l
t
C
l
a
s
s
e
s
a
n
d
A
s
s
o
c
i
a
t
i
o
n
s

T
h
e
C
o
m
p
o
n
e
n
t
C
a
t
e
g
o
r
i
e
s
M
a
n
a
g
e
r
Associating Icons with a Category
1/7/2020 • 2 minutes to read • Edit Online

Building a user interface that allows the user to select component categories within a category requires the ability
to display a meaningful image for a particular category. To associate an icon with a component category, create a
key for the category's CATID and populate that key with a DefaultIcon subkey. The registry entry is as follows:

HKEY_CLASSES_ROOT\CLSID\{...catid...}\DefaultIcon = "c:\hello\icons.dll,1"

The filename referenced by the DefaultIcon key can be either an EXE or a DLL file (resource-only DLL ).
To associate a small 16x16 "toolbox bitmap" with a component category, create a key in
HKEY_CLASSES_ROOT\CLSID for the category's CATID and populate that key with a ToolBoxBitmap32
subkey, as shown in the following example:

HKEY_CLASSES_ROOT\CLSID\{...catid...}\ToolBoxBitmap32 = "c:\goodbye\mycomponent.dll,42"

The filename referenced by the ToolBoxBitmap32 key can also be an EXE or DLL file (resource-only DLL ).

Related topics
C
a
t
e
g
o
r
i
z
i
n
g
b
y
C
o
m
p
o
n
e
n
t
C
a
p
a
b
i
l
i
t
i
e
s

C
a
t
e
g
o
r
i
z
i
n
g
b
y
C
o
n
t
a
i
n
e
r
C
a
p
a
b
i
l
i
t
i
e
s

D
e
f
a
u
l
t
C
l
a
s
s
e
s
a
n
d
A
s
s
o
c
i
a
t
i
o
n
s

D
e
f
i
n
i
n
g
C
o
m
p
o
n
e
n
t
C
a
t
e
g
o
r
i
e
s
I
C
a
t
I
n
f
o
r
m
a
t
i
o
n

I
C
a
t
R
e
g
i
s
t
e
r

T
h
e
C
o
m
p
o
n
e
n
t
C
a
t
e
g
o
r
i
e
s
M
a
n
a
g
e
r
Reference
1/7/2020 • 2 minutes to read • Edit Online

The following programming elements are provided by COM:


Constants
Enumerations
Functions
Interfaces
Macros
Registry Entries
Structures
Constants
1/7/2020 • 2 minutes to read • Edit Online

The following constants are provided by COM:


Access Flags
Authentication Level Constants
Authentication Service Constants
Authorization Constants
COM Error Codes
Impersonation Level Constants
Access Flags
1/7/2020 • 2 minutes to read • Edit Online

These values indicate whether an entry in the access list describes rights that are allowed or denied.

CONSTANT/VALUE DESCRIPTION

Indicates an access-allowed entry.


ACT
RL_
ACC
ESS
_AL
LO
WE
D
0x0
000
000
0

Indicates an access-denied entry.


ACT
RL_
ACC
ESS
_DE
NIE
D
0x1
000
000
0

Requirements

Minimum supported client Windows 2000 Professional [desktop apps only]

Minimum supported server Windows 2000 Server [desktop apps only]

Header
Acc
Ctrl.
h

See also
A
C
T
R
L
_
A
C
C
E
S
S
_
E
N
T
R
Y
Authentication Level Constants
1/7/2020 • 2 minutes to read • Edit Online

These values specify an authentication level, which indicates the amount of authentication provided to help protect
the integrity of the data. Each level includes the protection provided by the previous levels.

CONSTANT/VALUE DESCRIPTION

Tells DCOM to choose the authentication level using its


RPC normal security blanket negotiation algorithm. For more
_C_ information, see Security Blanket Negotiation.
AUT
HN_
LEV
EL_
DEF
AUL
T
0

Performs no authentication.
RPC
_C_
AUT
HN_
LEV
EL_
NO
NE
1

Authenticates the credentials of the client only when the client


RPC establishes a relationship with the server. Datagram transports
_C_ always use RPC_AUTHN_LEVEL_PKT instead.
AUT
HN_
LEV
EL_
CO
NN
ECT
2

Authenticates only at the beginning of each remote procedure


RPC call when the server receives the request. Datagram
_C_ transports use RPC_C_AUTHN_LEVEL_PKT instead.
AUT
HN_
LEV
EL_
CAL
L
3
CONSTANT/VALUE DESCRIPTION

Authenticates that all data received is from the expected client.


RPC
_C_
AUT
HN_
LEV
EL_
PKT
4

Authenticates and verifies that none of the data transferred


RPC between client and server has been modified.
_C_
AUT
HN_
LEV
EL_
PKT
_IN
TEG
RIT
Y
5

Authenticates all previous levels and encrypts the argument


RPC value of each remote procedure call.
_C_
AUT
HN_
LEV
EL_
PKT
_PRI
VAC
Y
6

Requirements

Minimum supported client Windows 2000 Professional [desktop apps only]

Minimum supported server Windows 2000 Server [desktop apps only]

Header
Rpc
dce.
h
Authentication Service Constants
1/7/2020 • 2 minutes to read • Edit Online

Defines authentication services by identifying the security package that provides the service, such as NTLMSSP,
Kerberos, or Schannel.

CONSTANT/VALUE DESCRIPTION

No authentication.
RPC
_C_
AUT
HN_
NO
NE
0

DCE private key authentication.


RPC
_C_
AUT
HN_
DCE
_PRI
VAT
E
1

DCE public key authentication.


RPC
_C_
AUT
HN_
DCE
_PU
BLI
C
2

DEC public key authentication. Reserved for future use.


RPC
_C_
AUT
HN_
DEC
_PU
BLI
C
4
CONSTANT/VALUE DESCRIPTION

Snego security support provider.


RPC
_C_
AUT
HN_
GSS
_NE
GO
TIA
TE
9

NTLMSSP
RPC
_C_
AUT
HN_
WI
NN
T
10

Schannel security support provider. This authentication service


RPC supports SSL 2.0, SSL 3.0, TLS, and PCT.
_C_
AUT
HN_
GSS
_SC
HA
NN
EL
14

Kerberos security support provider.


RPC
_C_
AUT
HN_
GSS
_KE
RBE
ROS
16

DPA security support provider.


RPC
_C_
AUT
HN_
DP
A
17
CONSTANT/VALUE DESCRIPTION

MSN security support provider.


RPC
_C_
AUT
HN_
MS
N
18

Kernel security support provider.


RPC
_C_
AUT
HN_
KER
NEL
20

Digest security support provider.


RPC
_C_
AUT
HN_
DIG
EST
21

NEGO extender security support provider.


RPC
_C_
AUT
HN_
NEG
O_E
XTE
NDE
R
30

PKU2U security support provider.


RPC
_C_
AUT
HN_
PKU
2U
31

MQ security support provider.


RPC
_C_
AUT
HN_
MQ
100
CONSTANT/VALUE DESCRIPTION

The system default authentication service. When this value is


RPC specified, COM uses its normal security blanket negotiation
_C_ algorithm to pick an authentication service. For more
AUT information, see Security Blanket Negotiation.
HN_
DEF
AUL
T
0xFF
FFFF
FFL

Remarks
These constants are used in the SOLE_AUTHENTICATION_SERVICE and the
SOLE_AUTHENTICATION_INFO structures. The SOLE_AUTHENTICATION_SERVICE structure is passed by
the server to the CoInitializeSecurity function and can be retrieved by the CoQueryAuthenticationServices
function. A pointer to a SOLE_AUTHENTICATION_INFO structure is passed by the client to
CoInitializeSecurity. For more information on the security packages identified by these values, such as
NTLMSSP and Kerberos, see COM and Security Packages.

Requirements

Minimum supported client Windows 2000 Professional [desktop apps only]

Minimum supported server Windows 2000 Server [desktop apps only]

Header
Rpc
Dce.
h

See also
C
o
I
n
i
t
i
a
l
i
z
e
S
e
c
u
r
i
t
y

C
o
Q
u
e
r
y
A
u
t
h
e
n
t
i
c
a
t
i
o
n
S
e
r
v
i
c
e
s

I
C
l
i
e
n
t
S
e
c
u
r
i
t
y

S
O
L
E
_
A
U
T
H
E
N
T
I
C
A
T
I
O
N
_
I
N
F
O

S
O
L
E
_
A
U
T
H
E
N
T
I
C
A
T
I
O
N
_
S
E
R
V
I
C
E
Authorization Constants
1/7/2020 • 2 minutes to read • Edit Online

Defines what the server authorizes.

CONSTANT/VALUE DESCRIPTION

The server performs no authorization. Currently,


RPC RPC_C_AUTHN_WINNT, RPC_C_AUTHN_GSS_SCHANNEL, and
_C_ RPC_C_AUTHN_GSS_KERBEROS all use only
AUT RPC_C_AUTHZ_NONE.
HZ_
NO
NE
0

The server performs authorization based on the client's


RPC principal name.
_C_
AUT
HZ_
NA
ME
1

The server performs authorization checking using the client's


RPC DCE privilege attribute certificate (PAC) information, which is
_C_ sent to the server with each remote procedure call made
AUT using the binding handle. Generally, access is checked against
HZ_ DCE access control lists (ACLs).
DCE
2

DCOM can choose the authorization level using its normal


RPC security blanket negotiation algorithm. For more information,
_C_ see Security Blanket Negotiation.
AUT
HZ_
DEF
AUL
T
0xfff
fffff

Remarks
These constants are used by methods of the IClientSecurity interface. They are used in the
SOLE_AUTHENTICATION_SERVICE structure, which is retrieved by the CoQueryAuthenticationServices
function. They are also used in the SOLE_AUTHENTICATION_INFO structure, which in turn is a member of the
SOLE_AUTHENTICATION_LIST structure. This structure, which is a list of authentication services, the
authorization services they perform, and the authentication information for each service, is passed to the
CoInitializeSecurity function and the IClientSecurity::SetBlanket method.
Requirements

Minimum supported client Windows 2000 Professional [desktop apps only]

Minimum supported server Windows 2000 Server [desktop apps only]

Header
Rpc
Dce.
h

See also
C
o
I
n
i
t
i
a
l
i
z
e
S
e
c
u
r
i
t
y

C
o
Q
u
e
r
y
A
u
t
h
e
n
t
i
c
a
t
i
o
n
S
e
r
v
i
c
e
s

I
C
l
i
e
n
t
S
e
c
u
r
i
t
y

S
O
L
E
_
A
U
T
H
E
N
T
I
C
A
T
I
O
N
_
I
N
F
O

S
O
L
E
_
A
U
T
H
E
N
T
I
C
A
T
I
O
N
_
S
E
R
V
I
C
E
COM Error Codes
1/7/2020 • 2 minutes to read • Edit Online

The following topics provide lists of error codes used by COM -based APIs. These values are defined in the
Winerror.h header file.
COM Error Codes (Generic)
COM Error Codes (XACT, SCHED, OLE )
COM Error Codes (STG, RPC )
COM Error Codes (Security and Setup)
COM Error Codes (COMADMIN, FILTER, GRAPHICS )
COM Error Codes (TPM, PLA, FVE )
COM Error Codes (FWP, WS, NDIS, HyperV )
COM Error Codes (VOLMGR, BCD, VHD, SDIAG)
COM Error Codes (WPN, MBN, P2P, Bluetooth)
COM Error Codes (UI, Audio, DirectX, Codec)
If you are experiencing difficulty with an application you are installing or running, contact customer support for
the software that is displaying the error message. To obtain support for a Microsoft product, go to
https://support.microsoft.com.
COM Error Codes (Generic)
1/7/2020 • 9 minutes to read • Edit Online

The following table provides a list of error codes used by COM -based APIs.
If you are experiencing difficulty with an application you are installing or running, contact customer support for the
software that is displaying the error message. To obtain support for a Microsoft product, go to
https://support.microsoft.com.

CONSTANT/VALUE DESCRIPTION

Catastrophic failure
E_U
NEX
PEC
TED
0x8
000
FFFF

Not implemented
E_N
OTI
MP
L
0x8
000
400
1

Ran out of memory


E_O
UT
OF
ME
MO
RY
0x8
007
000
E

One or more arguments are invalid


E_IN
VAL
IDA
RG
0x8
007
005
7
CONSTANT/VALUE DESCRIPTION

No such interface supported


E_N
OIN
TER
FAC
E
0x8
000
400
2

Invalid pointer
E_P
OIN
TER
0x8
000
400
3

Invalid handle
E_H
AN
DLE
0x8
007
000
6

Operation aborted
E_A
BO
RT
0x8
000
400
4

Unspecified error
E_F
AIL
0x8
000
400
5

General access denied error


E_A
CCE
SSD
ENI
ED
0x8
007
000
5
CONSTANT/VALUE DESCRIPTION

The data necessary to complete this operation is not yet


E_P available.
END
ING
0x8
000
000
A

The operation attempted to access data outside the valid


E_B range
OU
ND
S
0x8
000
000
B

A concurrent or interleaved operation changed the state of


E_C the object, invalidating this operation.
HA
NGE
D_S
TAT
E
0x8
000
000
C

An illegal state change was requested.


E_IL
LEG
AL_
STA
TE_
CH
AN
GE
0x8
000
000
D

A method was called at an unexpected time.


E_IL
LEG
AL_
MET
HO
D_C
ALL
0x8
000
000
E
CONSTANT/VALUE DESCRIPTION

Typename or Namespace was not found in metadata file.


RO_
E_M
ETA
DAT
A_N
AM
E_N
OT_
FOU
ND
0x8
000
000
F

Name is an existing namespace rather than a typename.


RO_
E_M
ETA
DAT
A_N
AM
E_IS
_NA
MES
PAC
E
0x8
000
001
0

Typename has an invalid format.


RO_
E_M
ETA
DAT
A_I
NV
ALI
D_T
YPE
_FO
RM
AT
0x8
000
001
1
CONSTANT/VALUE DESCRIPTION

Metadata file is invalid or corrupted.


RO_
E_IN
VAL
ID_
MET
AD
ATA
_FIL
E
0x8
000
001
2

The object has been closed.


RO_
E_C
LOS
ED
0x8
000
001
3

Only one thread may access the object during a write


RO_ operation.
E_E
XCL
USI
VE_
WRI
TE
0x8
000
001
4

Operation is prohibited during change notification.


RO_
E_C
HA
NGE
_NO
TIFI
CAT
ION
_IN_
PR
OG
RES
S
0x8
000
001
5
CONSTANT/VALUE DESCRIPTION

The text associated with this error code could not be found.
RO_
E_E
RR
OR_
STR
ING
_NO
T_F
OU
ND
0x8
000
001
6

String not null terminated.


E_S
TRI
NG_
NO
T_N
ULL
_TE
RMI
NA
TED
0x8
000
001
7

A delegate was assigned when not allowed.


E_IL
LEG
AL_
DEL
EGA
TE_
ASS
IGN
ME
NT
0x8
000
001
8
CONSTANT/VALUE DESCRIPTION

An async operation was not properly started.


E_A
SYN
C_O
PER
ATI
ON_
NO
T_S
TAR
TED
0x8
000
001
9

The application is exiting and cannot service this request.


E_A
PPL
ICA
TIO
N_E
XITI
NG
0x8
000
001
A

The application view is exiting and cannot service this request.


E_A
PPL
ICA
TIO
N_V
IEW
_EXI
TIN
G
0x8
000
001
B

The object must support the IAgileObject interface.


RO_
E_M
UST
_BE_
AGI
LE
0x8
000
001
C
CONSTANT/VALUE DESCRIPTION

Activating a single-threaded class from MTA is not supported.


RO_
E_U
NS
UPP
ORT
ED_
FRO
M_
MT
A
0x8
000
001
D

The object has been committed.


RO_
E_C
OM
MIT
TED
0x8
000
001
E

Thread local storage failure


CO_
E_IN
IT_T
LS
0x8
000
400
6

Get shared memory allocator failure


CO_
E_IN
IT_S
HA
RED
_AL
LOC
AT
OR
0x8
000
400
7
CONSTANT/VALUE DESCRIPTION

Get memory allocator failure


CO_
E_IN
IT_
ME
MO
RY_
ALL
OC
AT
OR
0x8
000
400
8

Unable to initialize class cache


CO_
E_IN
IT_C
LAS
S_C
AC
HE
0x8
000
400
9

Unable to initialize RPC services


CO_
E_IN
IT_R
PC_
CH
AN
NEL
0x8
000
400
A

Cannot set thread local storage channel control


CO_
E_IN
IT_T
LS_
SET
_CH
AN
NEL
_CO
NTR
OL
0x8
000
400
B
CONSTANT/VALUE DESCRIPTION

Could not allocate thread local storage channel control


CO_
E_IN
IT_T
LS_
CH
AN
NEL
_CO
NTR
OL
0x8
000
400
C

The user supplied memory allocator is unacceptable


CO_
E_IN
IT_U
NA
CCE
PTE
D_U
SER
_AL
LOC
AT
OR
0x8
000
400
D

The OLE service mutex already exists


CO_
E_IN
IT_S
CM_
MU
TEX
_EXI
STS
0x8
000
400
E
CONSTANT/VALUE DESCRIPTION

The OLE service file mapping already exists


CO_
E_IN
IT_S
CM_
FILE
_M
APP
ING
_EXI
STS
0x8
000
400
F

Unable to map view of file for OLE service


CO_
E_IN
IT_S
CM_
MA
P_VI
EW_
OF_
FILE
0x8
000
401
0

Failure attempting to launch OLE service


CO_
E_IN
IT_S
CM_
EXE
C_F
AIL
URE
0x8
000
401
1
CONSTANT/VALUE DESCRIPTION

There was an attempt to call CoInitialize a second time while


CO_ single threaded
E_IN
IT_
ON
LY_
SIN
GLE
_TH
REA
DED
0x8
000
401
2

A Remote activation was necessary but was not allowed


CO_
E_C
AN
T_R
EM
OTE
0x8
000
401
3

A Remote activation was necessary but the server name


CO_ provided was invalid
E_B
AD_
SER
VER
_NA
ME
0x8
000
401
4

The class is configured to run as a security id different from


CO_ the caller
E_W
RO
NG_
SER
VER
_IDE
NTI
TY
0x8
000
401
5
CONSTANT/VALUE DESCRIPTION

Use of Ole1 services requiring DDE windows is disabled


CO_
E_O
LE1
DDE
_DIS
ABL
ED
0x8
000
401
6

A RunAs specification must be \ or simply .


CO_
E_R
UN
AS_
SYN
TAX
0x8
000
401
7

The server process could not be started. The pathname may


CO_ be incorrect.
E_C
REA
TEP
RO
CES
S_F
AIL
URE
0x8
000
401
8

The server process could not be started as the configured


CO_ identity. The pathname may be incorrect or unavailable.
E_R
UN
AS_
CRE
ATE
PR
OCE
SS_
FAIL
URE
0x8
000
401
9
CONSTANT/VALUE DESCRIPTION

The server process could not be started because the


CO_ configured identity is incorrect. Check the user name and
E_R password.
UN
AS_
LOG
ON_
FAIL
URE
0x8
000
401
A

The client is not allowed to launch this server.


CO_
E_L
AU
NC
H_P
ER
MS
SIO
N_D
ENI
ED
0x8
000
401
B

The service providing this server could not be started.


CO_
E_S
TAR
T_S
ERV
ICE_
FAIL
URE
0x8
000
401
C
CONSTANT/VALUE DESCRIPTION

This computer was unable to communicate with the computer


CO_ providing the server.
E_R
EM
OTE
_CO
MM
UNI
CAT
ION
_FAI
LUR
E
0x8
000
401
D

The server did not respond after being launched.


CO_
E_SE
RVE
R_S
TAR
T_TI
ME
OU
T
0x8
000
401
E

The registration information for this server is inconsistent or


CO_ incomplete.
E_C
LSR
EG_I
NC
ON
SIST
ENT
0x8
000
401
F
CONSTANT/VALUE DESCRIPTION

The registration information for this interface is inconsistent or


CO_ incomplete.
E_II
DRE
G_I
NC
ON
SIST
ENT
0x8
000
402
0

The operation attempted is not supported.


CO_
E_N
OT_
SUP
PO
RTE
D
0x8
000
402
1

A dll must be loaded.


CO_
E_R
ELO
AD_
DLL
0x8
000
402
2

A Microsoft Software Installer error was encountered.


CO_
E_M
SI_E
RR
OR
0x8
000
402
3
CONSTANT/VALUE DESCRIPTION

The specified activation could not occur in the client context as


CO_ specified.
E_A
TTE
MP
T_T
O_C
REA
TE_
OU
TSI
DE_
CLIE
NT_
CO
NTE
XT
0x8
000
402
4

Activations on the server are paused.


CO_
E_SE
RVE
R_P
AUS
ED
0x8
000
402
5

Activations on the server are not paused.


CO_
E_SE
RVE
R_N
OT_
PA
USE
D
0x8
000
402
6
CONSTANT/VALUE DESCRIPTION

The component or application containing the component has


CO_ been disabled.
E_C
LAS
S_DI
SAB
LED
0x8
000
402
7

The common language runtime is not available


CO_
E_C
LRN
OT
AV
AIL
ABL
E
0x8
000
402
8

The thread-pool rejected the submitted asynchronous work.


CO_
E_A
SYN
C_
WO
RK_
REJ
ECT
ED
0x8
000
402
9

The server started, but did not finish initializing in a timely


CO_ fashion.
E_SE
RVE
R_I
NIT
_TI
ME
OU
T
0x8
000
402
A
CONSTANT/VALUE DESCRIPTION

Unable to complete the call since there is no COM+ security


CO_ context inside IObjectControl.Activate.
E_N
O_S
ECC
TX_I
N_A
CTI
VAT
E
0x8
000
402
B

The provided tracker configuration is invalid


CO_
E_T
RAC
KER
_CO
NFI
G
0x8
000
403
0

The provided thread pool configuration is invalid


CO_
E_T
HRE
AD
PO
OL_
CO
NFI
G
0x8
000
403
1

The provided side-by-side configuration is invalid


CO_
E_S
XS_
CO
NFI
G
0x8
000
403
2
CONSTANT/VALUE DESCRIPTION

The server principal name (SPN) obtained during security


CO_ negotiation is malformed.
E_M
ALF
OR
ME
D_S
PN
0x8
000
403
3

Invalid OLEVERB structure


OLE
_E_
OLE
VER
B
0x8
004
000
0

Invalid advise flags


OLE
_E_
AD
VF
0x8
004
000
1

Can't enumerate any more, because the associated data is


OLE missing
_E_E
NU
M_
NO
MO
RE
0x8
004
000
2
CONSTANT/VALUE DESCRIPTION

This implementation doesn't take advises


OLE
_E_
AD
VISE
NO
TSU
PP
ORT
ED
0x8
004
000
3

There is no connection for this connection ID


OLE
_E_
NO
CO
NN
ECTI
ON
0x8
004
000
4

Need to run the object to perform this operation


OLE
_E_
NO
TRU
NNI
NG
0x8
004
000
5

There is no cache to operate on


OLE
_E_
NO
CAC
HE
0x8
004
000
6
CONSTANT/VALUE DESCRIPTION

Uninitialized object
OLE
_E_B
LAN
K
0x8
004
000
7

Linked object's source class has changed


OLE
_E_C
LAS
SDI
FF
0x8
004
000
8

Not able to get the moniker of the object


OLE
_E_C
AN
T_G
ETM
ONI
KER
0x8
004
000
9

Not able to bind to the source


OLE
_E_C
AN
T_BI
ND
TOS
OU
RCE
0x8
004
000
A

Object is static; operation not allowed


OLE
_E_S
TAT
IC
0x8
004
000
B
CONSTANT/VALUE DESCRIPTION

User canceled out of save dialog


OLE
_E_P
RO
MP
TSA
VEC
AN
CEL
LED
0x8
004
000
C

Invalid rectangle
OLE
_E_I
NV
ALI
DRE
CT
0x8
004
000
D

compobj.dll is too old for the ole2.dll initialized


OLE
_E_
WR
ON
GC
OM
PO
BJ
0x8
004
000
E

Invalid window handle


OLE
_E_I
NV
ALI
DH
WN
D
0x8
004
000
F
CONSTANT/VALUE DESCRIPTION

Object is not in any of the inplace active states


OLE
_E_
NO
T_I
NPL
ACE
ACT
IVE
0x8
004
001
0

Not able to convert object


OLE
_E_C
AN
TCO
NVE
RT
0x8
004
001
1

Not able to perform the operation because object is not given


OLE storage yet
_E_
NO
STO
RA
GE
0x8
004
001
2

Invalid FORMATETC structure


DV_
E_F
OR
MA
TET
C
0x8
004
006
4
CONSTANT/VALUE DESCRIPTION

Invalid DVTARGETDEVICE structure


DV_
E_D
VTA
RGE
TDE
VIC
E
0x8
004
006
5

Invalid STDGMEDIUM structure


DV_
E_S
TG
ME
DIU
M
0x8
004
006
6

Invalid STATDATA structure


DV_
E_S
TAT
DAT
A
0x8
004
006
7

Invalid lindex
DV_
E_LI
NDE
X
0x8
004
006
8

Invalid tymed
DV_
E_T
YM
ED
0x8
004
006
9
CONSTANT/VALUE DESCRIPTION

Invalid clipboard format


DV_
E_C
LIPF
OR
MA
T
0x8
004
006
A

Invalid aspect(s)
DV_
E_D
VAS
PEC
T
0x8
004
006
B

tdSize parameter of the DVTARGETDEVICE structure is invalid


DV_
E_D
VTA
RGE
TDE
VIC
E_SI
ZE
0x8
004
006
C

Object doesn't support IViewObject interface


DV_
E_N
OIVI
EW
OBJ
ECT
0x8
004
006
D
CONSTANT/VALUE DESCRIPTION

Trying to revoke a drop target that has not been registered


DR
AG
DR
OP_
E_N
OTR
EGI
STE
RED
0x8
004
010
0

This window has already been registered as a drop target


DR
AG
DR
OP_
E_A
LRE
AD
YRE
GIS
TER
ED
0x8
004
010
1

Invalid window handle


DR
AG
DR
OP_
E_IN
VAL
IDH
WN
D
0x8
004
010
2
CONSTANT/VALUE DESCRIPTION

Class does not support aggregation (or class object is remote)


CLA
SS_
E_N
OA
GG
REG
ATI
ON
0x8
004
011
0

ClassFactory cannot supply requested class


CLA
SS_
E_C
LAS
SN
OT
AV
AIL
ABL
E
0x8
004
011
1

Class is not licensed for use


CLA
SS_
E_N
OTL
ICE
NSE
D
0x8
004
011
2

Error drawing view


VIE
W_E
_DR
AW
0x8
004
014
0
CONSTANT/VALUE DESCRIPTION

Could not read key from registry


REG
DB_
E_R
EAD
REG
DB
0x8
004
015
0

Could not write key to registry


REG
DB_
E_W
RITE
REG
DB
0x8
004
015
1

Could not find the key in the registry


REG
DB_
E_K
EY
MIS
SIN
G
0x8
004
015
2

Invalid value for registry


REG
DB_
E_IN
VAL
IDV
ALU
E
0x8
004
015
3
CONSTANT/VALUE DESCRIPTION

Class not registered


REG
DB_
E_C
LAS
SN
OTR
EG
0x8
004
015
4

Interface not registered


REG
DB_
E_II
DN
OTR
EG
0x8
004
015
5

Threading model entry is not valid


REG
DB_
E_B
ADT
HRE
ADI
NG
MO
DEL
0x8
004
015
6

CATID does not exist


CAT
_E_C
ATI
DN
OEX
IST
0x8
004
016
0
CONSTANT/VALUE DESCRIPTION

Description not found


CAT
_E_
NO
DES
CRI
PTI
ON
0x8
004
016
1

No package in the software installation data in the Active


CS_ Directory meets this criteria.
E_P
ACK
AGE
_NO
TFO
UN
D
0x8
004
016
4

Deleting this will break the referential integrity of the software


CS_ installation data in the Active Directory.
E_N
OT_
DEL
ETA
BLE
0x8
004
016
5

The CLSID was not found in the software installation data in


CS_ the Active Directory.
E_C
LAS
S_N
OTF
OU
ND
0x8
004
016
6
CONSTANT/VALUE DESCRIPTION

The software installation data in the Active Directory is


CS_ corrupt.
E_IN
VAL
ID_
VER
SIO
N
0x8
004
016
7

There is no software installation data in the Active Directory.


CS_
E_N
O_C
LAS
SST
ORE
0x8
004
016
8

There is no software installation data object in the Active


CS_ Directory.
E_O
BJE
CT_
NO
TFO
UN
D
0x8
004
016
9

The software installation data object in the Active Directory


CS_ already exists.
E_O
BJE
CT_
ALR
EAD
Y_E
XIS
TS
0x8
004
016
A
CONSTANT/VALUE DESCRIPTION

The path to the software installation data in the Active


CS_ Directory is not correct.
E_IN
VAL
ID_
PAT
H
0x8
004
016
B

A network error interrupted the operation.


CS_
E_N
ET
WO
RK_
ERR
OR
0x8
004
016
C

The size of this object exceeds the maximum size set by the
CS_ Administrator.
E_A
DMI
N_LI
MIT
_EX
CEE
DED
0x8
004
016
D

The schema for the software installation data in the Active


CS_ Directory does not match the required schema.
E_S
CHE
MA
_MI
SM
ATC
H
0x8
004
016
E
CONSTANT/VALUE DESCRIPTION

An error occurred in the software installation data in the


CS_ Active Directory.
E_IN
TER
NAL
_ER
RO
R
0x8
004
016
F

Cache not updated


CAC
HE_
E_N
OC
AC
HE_
UP
DAT
ED
0x8
004
017
0

No verbs for OLE object


OLE
OBJ
_E_
NO
VER
BS
0x8
004
018
0

Invalid verb for OLE object


OLE
OBJ
_E_I
NV
ALI
DVE
RB
0x8
004
018
1
CONSTANT/VALUE DESCRIPTION

Undo is not available


INP
LAC
E_E_
NO
TU
ND
OA
BLE
0x8
004
01A
0

Space for tools is not available


INP
LAC
E_E_
NO
TO
OLS
PAC
E
0x8
004
01A
1

OLESTREAM Get method failed


CO
NVE
RT1
0_E_
OLE
STR
EA
M_
GET
0x8
004
01C
0

OLESTREAM Put method failed


CO
NVE
RT1
0_E_
OLE
STR
EA
M_P
UT
0x8
004
01C
1
CONSTANT/VALUE DESCRIPTION

Contents of the OLESTREAM not in correct format


CO
NVE
RT1
0_E_
OLE
STR
EA
M_F
MT
0x8
004
01C
2

There was an error in a Windows GDI call while converting the


CO bitmap to a DIB
NVE
RT1
0_E_
OLE
STR
EA
M_B
ITM
AP_
TO_
DIB
0x8
004
01C
3

Contents of the IStorage not in correct format


CO
NVE
RT1
0_E_
STG
_FM
T
0x8
004
01C
4
CONSTANT/VALUE DESCRIPTION

Contents of IStorage is missing one of the standard streams


CO
NVE
RT1
0_E_
STG
_NO
_ST
D_S
TRE
AM
0x8
004
01C
5

There was an error in a Windows GDI call while converting the


CO DIB to a bitmap.
NVE
RT1
0_E_
STG
_DI
B_T
O_B
ITM
AP
0x8
004
01C
6

OpenClipboard Failed
CLI
PBR
D_E
_CA
NT_
OPE
N
0x8
004
01D
0

EmptyClipboard Failed
CLI
PBR
D_E
_CA
NT_
EM
PTY
0x8
004
01D
1
CONSTANT/VALUE DESCRIPTION

SetClipboard Failed
CLI
PBR
D_E
_CA
NT_
SET
0x8
004
01D
2

Data on clipboard is invalid


CLI
PBR
D_E
_BA
D_D
ATA
0x8
004
01D
3

CloseClipboard Failed
CLI
PBR
D_E
_CA
NT_
CLO
SE
0x8
004
01D
4

Moniker needs to be connected manually


MK_
E_C
ON
NEC
TM
AN
UAL
LY
0x8
004
01E
0
CONSTANT/VALUE DESCRIPTION

Operation exceeded deadline


MK_
E_E
XCE
EDE
DDE
ADL
INE
0x8
004
01E
1

Moniker needs to be generic


MK_
E_N
EED
GEN
ERI
C
0x8
004
01E
2

Operation unavailable
MK_
E_U
NA
VAI
LAB
LE
0x8
004
01E
3

Invalid syntax
MK_
E_S
YNT
AX
0x8
004
01E
4

No object for moniker


MK_
E_N
OO
BJE
CT
0x8
004
01E
5
CONSTANT/VALUE DESCRIPTION

Bad extension for file


MK_
E_IN
VAL
IDE
XTE
NSI
ON
0x8
004
01E
6

Intermediate operation failed


MK_
E_IN
TER
ME
DIA
TEI
NTE
RFA
CEN
OTS
UPP
ORT
ED
0x8
004
01E
7

Moniker is not bindable


MK_
E_N
OTB
IND
ABL
E
0x8
004
01E
8

Moniker is not bound


MK_
E_N
OTB
OU
ND
0x8
004
01E
9
CONSTANT/VALUE DESCRIPTION

Moniker cannot open file


MK_
E_C
AN
TOP
ENF
ILE
0x8
004
01E
A

User input required for operation to succeed


MK_
E_M
UST
BOT
HER
USE
R
0x8
004
01E
B

Moniker class has no inverse


MK_
E_N
OIN
VER
SE
0x8
004
01E
C

Moniker does not refer to storage


MK_
E_N
OST
OR
AGE
0x8
004
01E
D

No common prefix
MK_
E_N
OP
REFI
X
0x8
004
01E
E
CONSTANT/VALUE DESCRIPTION

Moniker could not be enumerated


MK_
E_E
NU
ME
RAT
ION
_FAI
LED
0x8
004
01E
F

CoInitialize has not been called.


CO_
E_N
OTI
NITI
ALI
ZED
0x8
004
01F
0

CoInitialize has already been called.


CO_
E_A
LRE
AD
YINI
TIA
LIZE
D
0x8
004
01F
1

Class of object cannot be determined


CO_
E_C
AN
TDE
TER
MIN
ECL
ASS
0x8
004
01F
2
CONSTANT/VALUE DESCRIPTION

Invalid class string


CO_
E_C
LAS
SST
RIN
G
0x8
004
01F
3

Invalid interface string


CO_
E_II
DST
RIN
G
0x8
004
01F
4

Application not found


CO_
E_A
PP
NO
TFO
UN
D
0x8
004
01F
5

Application cannot be run more than once


CO_
E_A
PPS
ING
LEU
SE
0x8
004
01F
6
CONSTANT/VALUE DESCRIPTION

Some error in application program


CO_
E_E
RR
ORI
NA
PP
0x8
004
01F
7

DLL for class not found


CO_
E_D
LLN
OTF
OU
ND
0x8
004
01F
8

Error in the DLL


CO_
E_E
RR
ORI
NDL
L
0x8
004
01F
9

Wrong operating system or operating system version for the


CO_ application
E_W
RO
NG
OSF
OR
APP
0x8
004
01F
A
CONSTANT/VALUE DESCRIPTION

Object is not registered


CO_
E_O
BJN
OTR
EG
0x8
004
01F
B

Object is already registered


CO_
E_O
BJIS
REG
0x8
004
01F
C

Object is not connected to server


CO_
E_O
BJN
OTC
ON
NEC
TED
0x8
004
01F
D

Application was launched but it didn't register a class factory


CO_
E_A
PPD
IDN
TRE
G
0x8
004
01F
E

Object has been released


CO_
E_R
ELE
ASE
D
0x8
004
01F
F
CONSTANT/VALUE DESCRIPTION

An event was able to invoke some but not all of the


EVE subscribers
NT_
S_S
OM
E_S
UBS
CRI
BER
S_F
AILE
D
0x0
004
020
0

An event was unable to invoke any of the subscribers


EVE
NT_
E_A
LL_S
UBS
CRI
BER
S_F
AILE
D
0x8
004
020
1

An event was delivered but there were no subscribers


EVE
NT_
S_N
OS
UBS
CRI
BER
S
0x0
004
020
2
CONSTANT/VALUE DESCRIPTION

A syntax error occurred trying to evaluate a query string


EVE
NT_
E_Q
UER
YSY
NT
AX
0x8
004
020
3

An invalid field name was used in a query string


EVE
NT_
E_Q
UER
YFIE
LD
0x8
004
020
4

An unexpected exception was raised


EVE
NT_
E_IN
TER
NAL
EXC
EPTI
ON
0x8
004
020
5

An unexpected internal error was detected


EVE
NT_
E_IN
TER
NAL
ERR
OR
0x8
004
020
6
CONSTANT/VALUE DESCRIPTION

The owner SID on a per-user subscription doesn't exist


EVE
NT_
E_IN
VAL
ID_
PER
_US
ER_
SID
0x8
004
020
7

A user-supplied component or subscriber raised an exception


EVE
NT_
E_U
SER
_EX
CEP
TIO
N
0x8
004
020
8

An interface has too many methods to fire events from


EVE
NT_
E_T
OO_
MA
NY_
MET
HO
DS
0x8
004
020
9

A subscription cannot be stored unless its event class already


EVE exists
NT_
E_M
ISSI
NG_
EVE
NTC
LAS
S
0x8
004
020
A
CONSTANT/VALUE DESCRIPTION

Not all the objects requested could be removed


EVE
NT_
E_N
OT_
ALL
_RE
MO
VED
0x8
004
020
B

COM+ is required for this operation, but is not installed


EVE
NT_
E_C
OM
PLU
S_N
OT_
INS
TAL
LED
0x8
004
020
C

Cannot modify or delete an object that was not added using


EVE the COM+ Admin SDK
NT_
E_C
AN
T_M
ODI
FY_
OR_
DEL
ETE_
UN
CO
NFI
GU
RED
_OB
JEC
T
0x8
004
020
D
CONSTANT/VALUE DESCRIPTION

Cannot modify or delete an object that was added using the


EVE COM+ Admin SDK
NT_
E_C
AN
T_M
ODI
FY_
OR_
DEL
ETE_
CO
NFI
GU
RED
_OB
JEC
T
0x8
004
020
E

The event class for this subscription is in an invalid partition


EVE
NT_
E_IN
VAL
ID_E
VEN
T_C
LAS
S_P
ART
ITIO
N
0x8
004
020
F

The owner of the PerUser subscription is not logged on to the


EVE system specified
NT_
E_P
ER_
USE
R_SI
D_N
OT_
LOG
GED
_ON
0x8
004
021
0
Requirements

Header
Win
erro
r.h

See also
C
O
M
E
r
r
o
r
C
o
d
e
s
COM Error Codes (XACT, SCHED, OLE)
1/7/2020 • 12 minutes to read • Edit Online

The following table provides a list of error codes used by COM -based APIs.
If you are experiencing difficulty with an application you are installing or running, contact customer support for the
software that is displaying the error message. To obtain support for a Microsoft product, go to
https://support.microsoft.com.

CONSTANT/VALUE DESCRIPTION

Another single phase resource manager has already been


XAC enlisted in this transaction.
T_E_
ALR
EAD
YOT
HER
SIN
GLE
PH
ASE
0x8
004
D00
0

A retaining commit or abort is not supported


XAC
T_E_
CA
NTR
ETA
IN
0x8
004
D00
1

The transaction failed to commit for an unknown reason. The


XAC transaction was aborted.
T_E_
CO
MM
ITF
AILE
D
0x8
004
D00
2
CONSTANT/VALUE DESCRIPTION

Cannot call commit on this transaction object because the


XAC calling application did not initiate the transaction.
T_E_
CO
MM
ITP
REV
ENT
ED
0x8
004
D00
3

Instead of committing, the resource heuristically aborted.


XAC
T_E_
HEU
RIS
TIC
AB
ORT
0x8
004
D00
4

Instead of aborting, the resource heuristically committed.


XAC
T_E_
HEU
RIS
TIC
CO
MM
IT
0x8
004
D00
5

Some of the states of the resource were committed while


XAC others were aborted, likely because of heuristic decisions.
T_E_
HEU
RIS
TIC
DA
MA
GE
0x8
004
D00
6
CONSTANT/VALUE DESCRIPTION

Some of the states of the resource may have been committed


XAC while others may have been aborted, likely because of
T_E_ heuristic decisions.
HEU
RIS
TIC
DA
NGE
R
0x8
004
D00
7

The requested isolation level is not valid or supported.


XAC
T_E_
ISO
LAT
ION
LEV
EL
0x8
004
D00
8

The transaction manager doesn't support an asynchronous


XAC operation for this method.
T_E_
NO
ASY
NC
0x8
004
D00
9

Unable to enlist in the transaction.


XAC
T_E_
NO
ENL
IST
0x8
004
D00
A
CONSTANT/VALUE DESCRIPTION

The requested semantics of retention of isolation across


XAC retaining commit and abort boundaries cannot be supported
T_E_ by this transaction implementation, or isoFlags was not equal
NOI to zero.
SOR
ETA
IN
0x8
004
D00
B

There is no resource presently associated with this enlistment


XAC
T_E_
NO
RES
OU
RCE
0x8
004
D00
C

The transaction failed to commit due to the failure of


XAC optimistic concurrency control in at least one of the resource
T_E_ managers.
NO
TCU
RRE
NT
0x8
004
D00
D

The transaction has already been implicitly or explicitly


XAC committed or aborted
T_E_
NO
TRA
NS
ACT
ION
0x8
004
D00
E
CONSTANT/VALUE DESCRIPTION

An invalid combination of flags was specified


XAC
T_E_
NO
TSU
PP
ORT
ED
0x8
004
D00
F

The resource manager id is not associated with this


XAC transaction or the transaction manager.
T_E_
UN
KN
OW
NR
MG
RID
0x8
004
D01
0

This method was called in the wrong state


XAC
T_E_
WR
ON
GST
ATE
0x8
004
D01
1

The indicated unit of work does not match the unit of work
XAC expected by the resource manager.
T_E_
WR
ON
GU
OW
0x8
004
D01
2
CONSTANT/VALUE DESCRIPTION

An enlistment in a transaction already exists.


XAC
T_E_
XTI
ON
EXIS
TS
0x8
004
D01
3

An import object for the transaction could not be found.


XAC
T_E_
NOI
MP
ORT
OBJ
ECT
0x8
004
D01
4

The transaction cookie is invalid.


XAC
T_E_
INV
ALI
DC
OO
KIE
0x8
004
D01
5

The transaction status is in doubt. A communication failure


XAC occurred, or a transaction manager or resource manager has
T_E_ failed
IND
OU
BT
0x8
004
D01
6
CONSTANT/VALUE DESCRIPTION

A time-out was specified, but time-outs are not supported.


XAC
T_E_
NO
TIM
EOU
T
0x8
004
D01
7

The requested operation is already in progress for the


XAC transaction.
T_E_
ALR
EAD
YIN
PR
OG
RES
S
0x8
004
D01
8

The transaction has already been aborted.


XAC
T_E_
AB
ORT
ED
0x8
004
D01
9

The Transaction Manager returned a log full error.


XAC
T_E_
LOG
FUL
L
0x8
004
D01
A
CONSTANT/VALUE DESCRIPTION

The Transaction Manager is not available.


XAC
T_E_
TM
NO
TAV
AIL
ABL
E
0x8
004
D01
B

A connection with the transaction manager was lost.


XAC
T_E_
CO
NN
ECTI
ON_
DO
WN
0x8
004
D01
C

A request to establish a connection with the transaction


XAC manager was denied.
T_E_
CO
NN
ECTI
ON_
DEN
IED
0x8
004
D01
D

Resource manager reenlistment to determine transaction


XAC status timed out.
T_E_
REE
NLI
STTI
ME
OU
T
0x8
004
D01
E
CONSTANT/VALUE DESCRIPTION

This transaction manager failed to establish a connection with


XAC another TIP transaction manager.
T_E_
TIP_
CO
NN
ECT
_FAI
LED
0x8
004
D01
F

This transaction manager encountered a protocol error with


XAC another TIP transaction manager.
T_E_
TIP_
PR
OT
OC
OL_
ERR
OR
0x8
004
D02
0

This transaction manager could not propagate a transaction


XAC from another TIP transaction manager.
T_E_
TIP_
PUL
L_F
AILE
D
0x8
004
D02
1

The Transaction Manager on the destination machine is not


XAC available.
T_E_
DES
T_T
MN
OT
AV
AIL
ABL
E
0x8
004
D02
2
CONSTANT/VALUE DESCRIPTION

The Transaction Manager has disabled its support for TIP.


XAC
T_E_
TIP_
DIS
ABL
ED
0x8
004
D02
3

The transaction manager has disabled its support for


XAC remote/network transactions.
T_E_
NET
WO
RK_
TX_
DIS
ABL
ED
0x8
004
D02
4

The partner transaction manager has disabled its support for


XAC remote/network transactions.
T_E_
PAR
TNE
R_N
ET
WO
RK_
TX_
DIS
ABL
ED
0x8
004
D02
5

The transaction manager has disabled its support for XA


XAC transactions.
T_E_
XA_
TX_
DIS
ABL
ED
0x8
004
D02
6
CONSTANT/VALUE DESCRIPTION

MSDTC was unable to read its configuration information.


XAC
T_E_
UN
ABL
E_T
O_R
EAD
_DT
C_C
ON
FIG
0x8
004
D02
7

MSDTC was unable to load the dtc proxy dll.


XAC
T_E_
UN
ABL
E_T
O_L
OA
D_D
TC_
PR
OX
Y
0x8
004
D02
8

The local transaction has aborted.


XAC
T_E_
AB
ORT
ING
0x8
004
D02
9
CONSTANT/VALUE DESCRIPTION

The MSDTC transaction manager was unable to push the


XAC transaction to the destination transaction manager due to
T_E_ communication problems. Possible causes are: a firewall is
PUS present and it doesn't have an exception for the MSDTC
H_C process, the two machines cannot find each other by their
OM NetBIOS names, or the support for network transactions is
M_F not enabled for one of the two transaction managers.
AIL
URE
0x8
004
D02
A

The MSDTC transaction manager was unable to pull the


XAC transaction from the source transaction manager due to
T_E_ communication problems. Possible causes are: a firewall is
PUL present and it doesn't have an exception for the MSDTC
L_C process, the two machines cannot find each other by their
OM NetBIOS names, or the support for network transactions is
M_F not enabled for one of the two transaction managers.
AIL
URE
0x8
004
D02
B

The MSDTC transaction manager has disabled its support for


XAC SNA LU 6.2 transactions.
T_E_
LU_
TX_
DIS
ABL
ED
0x8
004
D02
C

XACT_E_CLERKNOTFOUND
XAC
T_E_
CLE
RK
NO
TFO
UN
D
0x8
004
D08
0
CONSTANT/VALUE DESCRIPTION

XACT_E_CLERKEXISTS
XAC
T_E_
CLE
RKE
XIS
TS
0x8
004
D08
1

XACT_E_RECOVERYINPROGRESS
XAC
T_E_
REC
OVE
RYI
NP
RO
GRE
SS
0x8
004
D08
2

XACT_E_TRANSACTIONCLOSED
XAC
T_E_
TRA
NS
ACT
ION
CLO
SED
0x8
004
D08
3

XACT_E_INVALIDLSN
XAC
T_E_
INV
ALI
DLS
N
0x8
004
D08
4
CONSTANT/VALUE DESCRIPTION

XACT_E_REPLAYREQUEST
XAC
T_E_
REP
LAY
REQ
UES
T
0x8
004
D08
5

An asynchronous operation was specified. The operation has


XAC begun, but its outcome is not known yet.
T_S_
ASY
NC
0x0
004
D00
0

XACT_S_DEFECT
XAC
T_S_
DEF
ECT
0x0
004
D00
1

The method call succeeded because the transaction was read-


XAC only.
T_S_
REA
DO
NLY
0x0
004
D00
2

The transaction was successfully aborted. However, this is a


XAC coordinated transaction, and some number of enlisted
T_S_ resources were aborted outright because they could not
SO support abort-retaining semantics
ME
NO
RET
AIN
0x0
004
D00
3
CONSTANT/VALUE DESCRIPTION

No changes were made during this call, but the sink wants
XAC another chance to look if any other sinks make further
T_S_ changes.
OKI
NF
OR
M
0x0
004
D00
4

The sink is content and wishes the transaction to proceed.


XAC Changes were made to one or more resources during this call.
T_S_
MA
DEC
HA
NGE
SCO
NTE
NT
0x0
004
D00
5

The sink is for the moment and wishes the transaction to


XAC proceed, but if other changes are made following this return
T_S_ by other event sinks then this sink wants another chance to
MA look
DEC
HA
NGE
SIN
FOR
M
0x0
004
D00
6

The transaction was successfully aborted. However, the abort


XAC was non-retaining.
T_S_
ALL
NO
RET
AIN
0x0
004
D00
7
CONSTANT/VALUE DESCRIPTION

An abort operation was already in progress.


XAC
T_S_
AB
ORT
ING
0x0
004
D00
8

The resource manager has performed a single-phase commit


XAC of the transaction.
T_S_
SIN
GLE
PH
ASE
0x0
004
D00
9

The local transaction has not aborted.


XAC
T_S_
LOC
ALL
Y_O
K
0x0
004
D00
A

The resource manager has requested to be the coordinator


XAC (last resource manager) for the transaction.
T_S_
LAS
TRE
SO
URC
EM
AN
AGE
R
0x0
004
D01
0
CONSTANT/VALUE DESCRIPTION

The root transaction wanted to commit, but transaction


CO aborted
NTE
XT_
E_A
BO
RTE
D
0x8
004
E00
2

You made a method call on a COM+ component that has a


CO transaction that has already aborted or in the process of
NTE aborting.
XT_
E_A
BO
RTI
NG
0x8
004
E00
3

There is no MTS object context


CO
NTE
XT_
E_N
OC
ON
TEX
T
0x8
004
E00
4

The component is configured to use synchronization and this


CO method call would cause a deadlock to occur.
NTE
XT_
E_W
OUL
D_D
EAD
LOC
K
0x8
004
E00
5
CONSTANT/VALUE DESCRIPTION

The component is configured to use synchronization and a


CO thread has timed out waiting to enter the context.
NTE
XT_
E_S
YN
CH_
TIM
EOU
T
0x8
004
E00
6

You made a method call on a COM+ component that has a


CO transaction that has already committed or aborted.
NTE
XT_
E_O
LDR
EF
0x8
004
E00
7

The specified role was not configured for the application


CO
NTE
XT_
E_R
OLE
NO
TFO
UN
D
0x8
004
E00
C

COM+ was unable to talk to the Microsoft Distributed


CO Transaction Coordinator
NTE
XT_
E_T
MN
OT
AV
AIL
ABL
E
0x8
004
E00
F
CONSTANT/VALUE DESCRIPTION

An unexpected error occurred during COM+ Activation.


CO_
E_A
CTI
VAT
ION
FAIL
ED
0x8
004
E02
1

COM+ Activation failed. Check the event log for more


CO_ information
E_A
CTI
VAT
ION
FAIL
ED_
EVE
NTL
OG
GED
0x8
004
E02
2

COM+ Activation failed due to a catalog or configuration


CO_ error.
E_A
CTI
VAT
ION
FAIL
ED_
CAT
ALO
GER
RO
R
0x8
004
E02
3
CONSTANT/VALUE DESCRIPTION

COM+ activation failed because the activation could not be


CO_ completed in the specified amount of time.
E_A
CTI
VAT
ION
FAIL
ED_
TIM
EOU
T
0x8
004
E02
4

COM+ Activation failed because an initialization function


CO_ failed. Check the event log for more information.
E_IN
ITIA
LIZ
ATI
ON
FAIL
ED
0x8
004
E02
5

The requested operation requires that JIT be in the current


CO context and it is not
NTE
XT_
E_N
OJI
T
0x8
004
E02
6

The requested operation requires that the current context


CO have a Transaction, and it does not
NTE
XT_
E_N
OTR
AN
SAC
TIO
N
0x8
004
E02
7
CONSTANT/VALUE DESCRIPTION

The components threading model has changed after install


CO_ into a COM+ Application. Please re-install component.
E_T
HRE
ADI
NG
MO
DEL
_CH
AN
GED
0x8
004
E02
8

IIS intrinsics not available. Start your work with IIS.


CO_
E_N
OIIS
INT
RIN
SIC
S
0x8
004
E02
9

An attempt to write a cookie failed.


CO_
E_N
OC
OO
KIES
0x8
004
E02
A

An attempt to use a database generated a database specific


CO_ error.
E_D
BER
RO
R
0x8
004
E02
B
CONSTANT/VALUE DESCRIPTION

The COM+ component you created must use object pooling


CO_ to work.
E_N
OTP
OO
LED
0x8
004
E02
C

The COM+ component you created must use object


CO_ construction to work correctly.
E_N
OTC
ON
STR
UCT
ED
0x8
004
E02
D

The COM+ component requires synchronization, and it is not


CO_ configured for it.
E_N
OSY
NC
HR
ONI
ZAT
ION
0x8
004
E02
E

The TxIsolation Level property for the COM+ component


CO_ being created is stronger than the TxIsolationLevel for the
E_IS "root" component for the transaction. The creation failed.
OLE
VEL
MIS
MA
TCH
0x8
004
E02
F
CONSTANT/VALUE DESCRIPTION

The component attempted to make a cross-context call


CO_ between invocations of EnterTransactionScopeand
E_C ExitTransactionScope. This is not allowed. Cross-context calls
ALL cannot be made while inside of a transaction scope.
_OU
T_O
F_T
X_S
CO
PE_
NO
T_A
LLO
WE
D
0x8
004
E03
0

The component made a call to EnterTransactionScope, but did


CO_ not make a corresponding call to ExitTransactionScope before
E_E returning.
XIT_
TRA
NS
ACT
ION
_SC
OPE
_NO
T_C
ALL
ED
0x8
004
E03
1

Use the registry database to provide the requested


OLE information
_S_
USE
REG
0x0
004
000
0

Success, but static


OLE
_S_S
TAT
IC
0x0
004
000
1
CONSTANT/VALUE DESCRIPTION

Macintosh clipboard format


OLE
_S_
MA
C_C
LIPF
OR
MA
T
0x0
004
000
2

Successful drop took place


DR
AG
DR
OP_
S_D
RO
P
0x0
004
010
0

Drag-drop operation canceled


DR
AG
DR
OP_
S_C
AN
CEL
0x0
004
010
1

Use the default cursor


DR
AG
DR
OP_
S_U
SED
EFA
ULT
CUR
SOR
S
0x0
004
010
2
CONSTANT/VALUE DESCRIPTION

Data has same FORMATETC


DAT
A_S
_SA
MEF
OR
MA
TET
C
0x0
004
013
0

View is already frozen


VIE
W_S
_AL
REA
DY_
FRO
ZEN
0x0
004
014
0

FORMATETC not supported


CAC
HE_
S_F
OR
MA
TET
C_N
OTS
UPP
ORT
ED
0x0
004
017
0

Same cache
CAC
HE_
S_S
AM
ECA
CHE
0x0
004
017
1
CONSTANT/VALUE DESCRIPTION

Some cache(s) not updated


CAC
HE_
S_S
OM
ECA
CHE
S_N
OT
UP
DAT
ED
0x0
004
017
2

Invalid verb for OLE object


OLE
OBJ
_S_I
NV
ALI
DVE
RB
0x0
004
018
0

Verb number is valid but verb cannot be done now


OLE
OBJ
_S_
CA
NN
OT_
DO
VER
B_N
OW
0x0
004
018
1
CONSTANT/VALUE DESCRIPTION

Invalid window handle passed


OLE
OBJ
_S_I
NV
ALI
DH
WN
D
0x0
004
018
2

Message is too long; some of it had to be truncated before


INP displaying
LAC
E_S_
TRU
NC
ATE
D
0x0
004
01A
0

Unable to convert OLESTREAM to IStorage


CO
NVE
RT1
0_S_
NO_
PRE
SEN
TAT
ION
0x0
004
01C
0

Moniker reduced to itself


MK_
S_R
EDU
CED
_TO
_SEL
F
0x0
004
01E
2
CONSTANT/VALUE DESCRIPTION

Common prefix is this moniker


MK_
S_M
E
0x0
004
01E
4

Common prefix is input moniker


MK_
S_H
IM
0x0
004
01E
5

Common prefix is both monikers


MK_
S_U
S
0x0
004
01E
6

Moniker is already registered in running object table


MK_
S_M
ONI
KER
ALR
EAD
YRE
GIS
TER
ED
0x0
004
01E
7

The task is ready to run at its next scheduled time.


SCH
ED_
S_T
ASK
_RE
AD
Y
0x0
004
130
0
CONSTANT/VALUE DESCRIPTION

The task is currently running.


SCH
ED_
S_T
ASK
_RU
NNI
NG
0x0
004
130
1

The task will not run at the scheduled times because it has
SCH been disabled.
ED_
S_T
ASK
_DIS
ABL
ED
0x0
004
130
2

The task has not yet run.


SCH
ED_
S_T
ASK
_HA
S_N
OT_
RU
N
0x0
004
130
3

There are no more runs scheduled for this task.


SCH
ED_
S_T
ASK
_NO
_M
ORE
_RU
NS
0x0
004
130
4
CONSTANT/VALUE DESCRIPTION

One or more of the properties that are needed to run this


SCH task on a schedule have not been set.
ED_
S_T
ASK
_NO
T_S
CHE
DUL
ED
0x0
004
130
5

The last run of the task was terminated by the user.


SCH
ED_
S_T
ASK
_TE
RMI
NA
TED
0x0
004
130
6

Either the task has no triggers or the existing triggers are


SCH disabled or not set.
ED_
S_T
ASK
_NO
_VA
LID_
TRI
GGE
RS
0x0
004
130
7

Event triggers don't have set run times.


SCH
ED_
S_E
VEN
T_T
RIG
GER
0x0
004
130
8
CONSTANT/VALUE DESCRIPTION

Trigger not found.


SCH
ED_
E_T
RIG
GER
_NO
T_F
OU
ND
0x8
004
130
9

One or more of the properties that are needed to run this


SCH task have not been set.
ED_
E_T
ASK
_NO
T_R
EAD
Y
0x8
004
130
A

There is no running instance of the task.


SCH
ED_
E_T
ASK
_NO
T_R
UN
NIN
G
0x8
004
130
B
CONSTANT/VALUE DESCRIPTION

The Task Scheduler Service is not installed on this computer.


SCH
ED_
E_SE
RVI
CE_
NO
T_I
NST
ALL
ED
0x8
004
130
C

The task object could not be opened.


SCH
ED_
E_C
AN
NO
T_O
PEN
_TA
SK
0x8
004
130
D

The object is either an invalid task object or is not a task


SCH object.
ED_
E_IN
VAL
ID_T
ASK
0x8
004
130
E
CONSTANT/VALUE DESCRIPTION

No account information could be found in the Task Scheduler


SCH security database for the task indicated.
ED_
E_A
CC
OU
NT_
INF
OR
MA
TIO
N_N
OT_
SET
0x8
004
130
F

Unable to establish existence of the account specified.


SCH
ED_
E_A
CC
OU
NT_
NA
ME_
NO
T_F
OU
ND
0x8
004
131
0

Corruption was detected in the Task Scheduler security


SCH database; the database has been reset.
ED_
E_A
CC
OU
NT_
DB
ASE
_CO
RRU
PT
0x8
004
131
1
CONSTANT/VALUE DESCRIPTION

Task Scheduler security services are not available.


SCH
ED_
E_N
O_S
ECU
RIT
Y_S
ERV
ICES
0x8
004
131
2

The task object version is either unsupported or invalid.


SCH
ED_
E_U
NK
NO
WN
_OB
JEC
T_V
ERSI
ON
0x8
004
131
3

The task has been configured with an unsupported


SCH combination of account settings and run time options.
ED_
E_U
NS
UPP
ORT
ED_
ACC
OU
NT_
OPT
ION
0x8
004
131
4
CONSTANT/VALUE DESCRIPTION

The Task Scheduler Service is not running.


SCH
ED_
E_SE
RVI
CE_
NO
T_R
UN
NIN
G
0x8
004
131
5

The task XML contains an unexpected node.


SCH
ED_
E_U
NEX
PEC
TED
NO
DE
0x8
004
131
6

The task XML contains an element or attribute from an


SCH unexpected namespace.
ED_
E_N
AM
ESP
ACE
0x8
004
131
7

The task XML contains a value which is incorrectly formatted


SCH or out of range.
ED_
E_IN
VAL
IDV
ALU
E
0x8
004
131
8
CONSTANT/VALUE DESCRIPTION

The task XML is missing a required element or attribute.


SCH
ED_
E_M
ISSI
NG
NO
DE
0x8
004
131
9

The task XML is malformed.


SCH
ED_
E_M
ALF
OR
ME
DX
ML
0x8
004
131
A

The task is registered, but not all specified triggers will start
SCH the task.
ED_
S_S
OM
E_T
RIG
GER
S_F
AILE
D
0x0
004
131
B

The task is registered, but may fail to start. Batch logon


SCH privilege needs to be enabled for the task principal.
ED_
S_B
ATC
H_L
OG
ON_
PR
OBL
EM
0x0
004
131
C
CONSTANT/VALUE DESCRIPTION

The task XML contains too many nodes of the same type.
SCH
ED_
E_T
OO_
MA
NY_
NO
DES
0x8
004
131
D

The task cannot be started after the trigger's end boundary.


SCH
ED_
E_P
AST
_EN
D_B
OU
ND
ARY
0x8
004
131
E

An instance of this task is already running.


SCH
ED_
E_A
LRE
AD
Y_R
UN
NIN
G
0x8
004
131
F

The task will not run because the user is not logged on.
SCH
ED_
E_U
SER
_NO
T_L
OG
GED
_ON
0x8
004
132
0
CONSTANT/VALUE DESCRIPTION

The task image is corrupt or has been tampered with.


SCH
ED_
E_IN
VAL
ID_T
ASK
_HA
SH
0x8
004
132
1

The Task Scheduler service is not available.


SCH
ED_
E_SE
RVI
CE_
NO
T_A
VAI
LAB
LE
0x8
004
132
2

The Task Scheduler service is too busy to handle your request.


SCH Please try again later.
ED_
E_SE
RVI
CE_
TO
O_B
USY
0x8
004
132
3

The Task Scheduler service attempted to run the task, but the
SCH task did not run due to one of the constraints in the task
ED_ definition.
E_T
ASK
_AT
TEM
PTE
D
0x8
004
132
4
CONSTANT/VALUE DESCRIPTION

The Task Scheduler service has asked the task to run.


SCH
ED_
S_T
ASK
_QU
EUE
D
0x0
004
132
5

The task is disabled.


SCH
ED_
E_T
ASK
_DIS
ABL
ED
0x8
004
132
6

The task has properties that are not compatible with previous
SCH versions of Windows.
ED_
E_T
ASK
_NO
T_V
1_C
OM
PAT
0x8
004
132
7

The task settings do not allow the task to start on demand.


SCH
ED_
E_S
TAR
T_O
N_D
EM
AN
D
0x8
004
132
8
CONSTANT/VALUE DESCRIPTION

The combination of properties that task is using is not


SCH compatible with the scheduling engine.
ED_
E_T
ASK
_NO
T_U
BP
M_C
OM
PAT
0x8
004
132
9

Attempt to create a class object failed


CO_
E_C
LAS
S_C
REA
TE_F
AILE
D
0x8
008
000
1

OLE service could not bind object


CO_
E_S
CM_
ERR
OR
0x8
008
000
2

RPC communication failed with OLE service


CO_
E_S
CM_
RPC
_FAI
LUR
E
0x8
008
000
3
CONSTANT/VALUE DESCRIPTION

Bad path to object


CO_
E_B
AD_
PAT
H
0x8
008
000
4

Server execution failed


CO_
E_SE
RVE
R_E
XEC
_FAI
LUR
E
0x8
008
000
5

OLE service could not communicate with the object server


CO_
E_O
BJS
RV_
RPC
_FAI
LUR
E
0x8
008
000
6

Moniker path could not be normalized


MK_
E_N
O_N
OR
MA
LIZE
D
0x8
008
000
7
CONSTANT/VALUE DESCRIPTION

Object server is stopping when OLE service contacts it


CO_
E_SE
RVE
R_S
TOP
PIN
G
0x8
008
000
8

An invalid root block pointer was specified


ME
M_E
_IN
VAL
ID_
RO
OT
0x8
008
000
9

An allocation chain contained an invalid link pointer


ME
M_E
_IN
VAL
ID_L
INK
0x8
008
001
0

The requested allocation size was too large


ME
M_E
_IN
VAL
ID_S
IZE
0x8
008
001
1
CONSTANT/VALUE DESCRIPTION

Not all the requested interfaces were available


CO_
S_N
OT
ALLI
NTE
RFA
CES
0x0
008
001
2

The specified machine name was not found in the cache.


CO_
S_M
AC
HIN
ENA
ME
NO
TFO
UN
D
0x0
008
001
3

The activation requires a display name to be present under


CO_ the CLSID key.
E_M
ISSI
NG_
DIS
PLA
YN
AM
E
0x8
008
001
5
CONSTANT/VALUE DESCRIPTION

The activation requires that the RunAs value for the


CO_ application is Activate As Activator.
E_R
UN
AS_
VAL
UE_
MU
ST_
BE_
AA
A
0x8
008
001
6

The class is not configured to support Elevated activation.


CO_
E_EL
EVA
TIO
N_D
ISA
BLE
D
0x8
008
001
7

Unknown interface.
DIS
P_E_
UN
KN
OW
NIN
TER
FAC
E
0x8
002
000
1
CONSTANT/VALUE DESCRIPTION

Member not found.


DIS
P_E_
ME
MB
ERN
OTF
OU
ND
0x8
002
000
3

Parameter not found.


DIS
P_E_
PAR
AM
NO
TFO
UN
D
0x8
002
000
4

Type mismatch.
DIS
P_E_
TYP
EMI
SM
ATC
H
0x8
002
000
5

Unknown name.
DIS
P_E_
UN
KN
OW
NN
AM
E
0x8
002
000
6
CONSTANT/VALUE DESCRIPTION

No named arguments.
DIS
P_E_
NO
NA
ME
DA
RGS
0x8
002
000
7

Bad variable type.


DIS
P_E_
BA
DV
ART
YPE
0x8
002
000
8

Exception occurred.
DIS
P_E_
EXC
EPTI
ON
0x8
002
000
9

Out of present range.


DIS
P_E_
OVE
RFL
OW
0x8
002
000
A

Invalid index.
DIS
P_E_
BA
DIN
DEX
0x8
002
000
B
CONSTANT/VALUE DESCRIPTION

Unknown language.
DIS
P_E_
UN
KN
OW
NLC
ID
0x8
002
000
C

Memory is locked.
DIS
P_E_
ARR
AYI
SLO
CKE
D
0x8
002
000
D

Invalid number of parameters.


DIS
P_E_
BA
DP
AR
AM
CO
UN
T
0x8
002
000
E

Parameter not optional.


DIS
P_E_
PAR
AM
NO
TOP
TIO
NAL
0x8
002
000
F
CONSTANT/VALUE DESCRIPTION

Invalid callee.
DIS
P_E_
BA
DC
ALL
EE
0x8
002
001
0

Does not support a collection.


DIS
P_E_
NO
TAC
OLL
ECTI
ON
0x8
002
001
1

Division by zero.
DIS
P_E_
DIV
BYZ
ERO
0x8
002
001
2

Buffer too small


DIS
P_E_
BUF
FER
TO
OS
MA
LL
0x8
002
001
3
CONSTANT/VALUE DESCRIPTION

Buffer too small.


TYP
E_E_
BUF
FER
TO
OS
MA
LL
0x8
002
801
6

Field name not defined in the record.


TYP
E_E_
FIEL
DN
OTF
OU
ND
0x8
002
801
7

Old format or invalid type library.


TYP
E_E_
INV
DAT
ARE
AD
0x8
002
801
8

Old format or invalid type library.


TYP
E_E_
UN
SUP
FOR
MA
T
0x8
002
801
9
CONSTANT/VALUE DESCRIPTION

Error accessing the OLE registry.


TYP
E_E_
REG
IST
RYA
CCE
SS
0x8
002
801
C

Library not registered.


TYP
E_E_
LIB
NO
TRE
GIS
TER
ED
0x8
002
801
D

Bound to unknown type.


TYP
E_E_
UN
DEFI
NED
TYP
E
0x8
002
802
7

Qualified name disallowed.


TYP
E_E_
QU
ALIF
IED
NA
ME
DIS
ALL
OW
ED
0x8
002
802
8
CONSTANT/VALUE DESCRIPTION

Invalid forward reference, or reference to uncompiled type.


TYP
E_E_
INV
ALI
DST
ATE
0x8
002
802
9

Type mismatch.
TYP
E_E_
WR
ON
GTY
PEK
IND
0x8
002
802
A

Element not found.


TYP
E_E_
ELE
ME
NT
NO
TFO
UN
D
0x8
002
802
B

Ambiguous name.
TYP
E_E_
AM
BIG
UO
US
NA
ME
0x8
002
802
C
CONSTANT/VALUE DESCRIPTION

Name already exists in the library.


TYP
E_E_
NA
ME
CO
NFL
ICT
0x8
002
802
D

Unknown LCID.
TYP
E_E_
UN
KN
OW
NLC
ID
0x8
002
802
E

Function not defined in specified DLL.


TYP
E_E_
DLL
FUN
CTI
ON
NO
TFO
UN
D
0x8
002
802
F

Wrong module kind for the operation.


TYP
E_E_
BA
DM
OD
ULE
KIN
D
0x8
002
88B
D
CONSTANT/VALUE DESCRIPTION

Size may not exceed 64K.


TYP
E_E_
SIZE
TO
OBI
G
0x8
002
88C
5

Duplicate ID in inheritance hierarchy.


TYP
E_E_
DU
PLI
CAT
EID
0x8
002
88C
6

Incorrect inheritance depth in standard OLE hmember.


TYP
E_E_
INV
ALI
DID
0x8
002
88C
F

Type mismatch.
TYP
E_E_
TYP
EMI
SM
ATC
H
0x8
002
8CA
0
CONSTANT/VALUE DESCRIPTION

Invalid number of arguments.


TYP
E_E_
OU
TOF
BO
UN
DS
0x8
002
8CA
1

I/O Error.
TYP
E_E_
IOE
RR
OR
0x8
002
8CA
2

Error creating unique tmp file.


TYP
E_E_
CA
NTC
REA
TET
MP
FILE
0x8
002
8CA
3

Error loading type library/DLL.


TYP
E_E_
CA
NTL
OA
DLI
BRA
RY
0x8
002
9C4
A
CONSTANT/VALUE DESCRIPTION

Inconsistent property functions.


TYP
E_E_
INC
ON
SIST
ENT
PR
OPF
UN
CS
0x8
002
9C8
3

Circular dependency between types/modules.


TYP
E_E_
CIR
CUL
ART
YPE
0x8
002
9C8
4

Requirements

Header
Win
erro
r.h

See also
C
O
M
E
r
r
o
r
C
o
d
e
s
COM Error Codes (STG, RPC)
1/7/2020 • 8 minutes to read • Edit Online

The following table provides a list of error codes used by COM -based APIs.
If you are experiencing difficulty with an application you are installing or running, contact customer support for the
software that is displaying the error message. To obtain support for a Microsoft product, go to
https://support.microsoft.com.

CONSTANT/VALUE DESCRIPTION

Unable to perform requested operation.


STG
_E_I
NV
ALI
DFU
NCT
ION
0x8
003
000
1

could not be found.


STG
_E_F
ILE
NO
TFO
UN
D
0x8
003
000
2

The path %1 could not be found.


STG
_E_P
AT
HN
OTF
OU
ND
0x8
003
000
3
CONSTANT/VALUE DESCRIPTION

There are insufficient resources to open another file.


STG
_E_T
OO
MA
NY
OPE
NFI
LES
0x8
003
000
4

Access Denied.
STG
_E_
ACC
ESS
DEN
IED
0x8
003
000
5

Attempted an operation on an invalid object.


STG
_E_I
NV
ALI
DH
AN
DLE
0x8
003
000
6

There is insufficient memory available to complete operation.


STG
_E_I
NS
UFFI
CIE
NT
ME
MO
RY
0x8
003
000
8
CONSTANT/VALUE DESCRIPTION

Invalid pointer error.


STG
_E_I
NV
ALI
DP
OIN
TER
0x8
003
000
9

There are no more entries to return.


STG
_E_
NO
MO
REFI
LES
0x8
003
001
2

Disk is write-protected.
STG
_E_
DIS
KIS
WRI
TEP
ROT
ECT
ED
0x8
003
001
3

An error occurred during a seek operation.


STG
_E_S
EEK
ERR
OR
0x8
003
001
9
CONSTANT/VALUE DESCRIPTION

A disk error occurred during a write operation.


STG
_E_
WRI
TEF
AUL
T
0x8
003
001
D

A disk error occurred during a read operation.


STG
_E_R
EAD
FAU
LT
0x8
003
001
E

A share violation has occurred.


STG
_E_S
HA
REV
IOL
ATI
ON
0x8
003
002
0

A lock violation has occurred.


STG
_E_L
OC
KVI
OLA
TIO
N
0x8
003
002
1
CONSTANT/VALUE DESCRIPTION

already exists.
STG
_E_F
ILEA
LRE
AD
YEX
ISTS
0x8
003
005
0

Invalid parameter error.


STG
_E_I
NV
ALI
DP
AR
AM
ETE
R
0x8
003
005
7

There is insufficient disk space to complete operation.


STG
_E_
ME
DIU
MF
ULL
0x8
003
007
0

Illegal write of non-simple property to simple property set.


STG
_E_P
RO
PSE
TMI
SM
ATC
HED
0x8
003
00F
0
CONSTANT/VALUE DESCRIPTION

An API call exited abnormally.


STG
_E_
AB
NO
RM
ALA
PIE
XIT
0x8
003
00F
A

The file %1 is not a valid compound file.


STG
_E_I
NV
ALI
DHE
ADE
R
0x8
003
00F
B

The name %1 is not valid.


STG
_E_I
NV
ALI
DN
AM
E
0x8
003
00F
C

An unexpected error occurred.


STG
_E_
UN
KN
OW
N
0x8
003
00F
D
CONSTANT/VALUE DESCRIPTION

That function is not implemented.


STG
_E_
UNI
MP
LEM
ENT
EDF
UN
CTI
ON
0x8
003
00F
E

Invalid flag error.


STG
_E_I
NV
ALI
DFL
AG
0x8
003
00F
F

Attempted to use an object that is busy.


STG
_E_I
NU
SE
0x8
003
010
0

The storage has been changed since the last commit.


STG
_E_
NO
TCU
RRE
NT
0x8
003
010
1
CONSTANT/VALUE DESCRIPTION

Attempted to use an object that has ceased to exist.


STG
_E_R
EVE
RTE
D
0x8
003
010
2

Can't save.
STG
_E_C
AN
TSA
VE
0x8
003
010
3

The compound file %1 was produced with an incompatible


STG version of storage.
_E_
OLD
FOR
MA
T
0x8
003
010
4

The compound file %1 was produced with a newer version of


STG storage.
_E_
OLD
DLL
0x8
003
010
5

Share.exe or equivalent is required for operation.


STG
_E_S
HA
RER
EQU
IRE
D
0x8
003
010
6
CONSTANT/VALUE DESCRIPTION

Illegal operation called on non-file based storage.


STG
_E_
NO
TFIL
EBA
SED
STO
RA
GE
0x8
003
010
7

Illegal operation called on object with extant marshallings.


STG
_E_E
XTA
NT
MA
RSH
ALLI
NG
S
0x8
003
010
8

The docfile has been corrupted.


STG
_E_
DO
CFIL
ECO
RRU
PT
0x8
003
010
9

OLE32.DLL has been loaded at the wrong address.


STG
_E_B
AD
BAS
EAD
DRE
SS
0x8
003
011
0
CONSTANT/VALUE DESCRIPTION

The compound file is too large for the current implementation


STG
_E_
DO
CFIL
ETO
OLA
RGE
0x8
003
011
1

The compound file was not created with the STGM_SIMPLE


STG flag
_E_
NO
TSI
MP
LEF
OR
MA
T
0x8
003
011
2

The file download was aborted abnormally. The file is


STG incomplete.
_E_I
NC
OM
PLE
TE
0x8
003
020
1

The file download has been terminated.


STG
_E_T
ER
MIN
ATE
D
0x8
003
020
2
CONSTANT/VALUE DESCRIPTION

The underlying file was converted to compound file format.


STG
_S_
CO
NVE
RTE
D
0x0
003
020
0

The storage operation should block until more data is


STG available.
_S_
BLO
CK
0x0
003
020
1

The storage operation should retry immediately.


STG
_S_
RET
RY
NO
W
0x0
003
020
2

The notified event sink will not influence the storage


STG operation.
_S_
MO
NIT
ORI
NG
0x0
003
020
3
CONSTANT/VALUE DESCRIPTION

Multiple opens prevent consolidated. (commit succeeded).


STG
_S_
MU
LTIP
LEO
PEN
S
0x0
003
020
4

Consolidation of the storage file failed. (commit succeeded).


STG
_S_
CO
NS
OLI
DAT
ION
FAIL
ED
0x0
003
020
5

Consolidation of the storage file is inappropriate. (commit


STG succeeded).
_S_
CA
NN
OTC
ON
SOL
IDA
TE
0x0
003
020
6
CONSTANT/VALUE DESCRIPTION

Generic Copy Protection Error.


STG
_E_S
TAT
US_
CO
PY_
PR
OTE
CTI
ON_
FAIL
URE
0x8
003
030
5

Copy Protection Error - DVD CSS Authentication failed.


STG
_E_C
SS_
AUT
HE
NTI
CAT
ION
_FAI
LUR
E
0x8
003
030
6

Copy Protection Error - The given sector does not have a valid
STG CSS key.
_E_C
SS_
KEY
_NO
T_P
RES
ENT
0x8
003
030
7
CONSTANT/VALUE DESCRIPTION

Copy Protection Error - DVD session key not established.


STG
_E_C
SS_
KEY
_NO
T_E
STA
BLIS
HED
0x8
003
030
8

Copy Protection Error - The read failed because the sector is


STG encrypted.
_E_C
SS_
SCR
AM
BLE
D_S
ECT
OR
0x8
003
030
9

Copy Protection Error - The current DVD's region does not


STG correspond to the region setting of the drive.
_E_C
SS_
REG
ION
_MI
SM
ATC
H
0x8
003
030
A

Copy Protection Error - The drive's region setting may be


STG permanent or the number of user resets has been exhausted.
_E_R
ESE
TS_
EXH
AUS
TED
0x8
003
030
B
CONSTANT/VALUE DESCRIPTION

Call was rejected by callee.


RPC
_E_C
ALL
_REJ
ECT
ED
0x8
001
000
1

Call was canceled by the message filter.


RPC
_E_C
ALL
_CA
NCE
LED
0x8
001
000
2

The caller is dispatching an intertask SendMessage call and


RPC cannot call out via PostMessage.
_E_C
AN
TPO
ST_I
NSE
ND
CAL
L
0x8
001
000
3

The caller is dispatching an asynchronous call and cannot


RPC make an outgoing call on behalf of this call.
_E_C
AN
TCA
LLO
UT_I
NA
SYN
CCA
LL
0x8
001
000
4
CONSTANT/VALUE DESCRIPTION

It is illegal to call out while inside message filter.


RPC
_E_C
AN
TCA
LLO
UT_I
NEX
TER
NAL
CAL
L
0x8
001
000
5

The connection terminated or is in a bogus state and cannot


RPC be used any more. Other connections are still valid.
_E_C
ON
NEC
TIO
N_T
ER
MIN
ATE
D
0x8
001
000
6

The callee (server [not server application]) is not available and


RPC disappeared; all connections are invalid. The call may have
_E_S executed.
ERV
ER_
DIE
D
0x8
001
000
7

The caller (client) disappeared while the callee (server) was


RPC processing a call.
_E_C
LIE
NT_
DIE
D
0x8
001
000
8
CONSTANT/VALUE DESCRIPTION

The data packet with the marshalled parameter data is


RPC incorrect.
_E_I
NV
ALI
D_D
ATA
PAC
KET
0x8
001
000
9

The call was not transmitted properly; the message queue was
RPC full and was not emptied after yielding.
_E_C
AN
TTR
AN
SMI
T_C
ALL
0x8
001
000
A

The client (caller) cannot marshal the parameter data - low


RPC memory, etc.
_E_C
LIE
NT_
CA
NT
MA
RSH
AL_
DAT
A
0x8
001
000
B
CONSTANT/VALUE DESCRIPTION

The client (caller) cannot unmarshal the return data - low


RPC memory, etc.
_E_C
LIE
NT_
CA
NT
UN
MA
RSH
AL_
DAT
A
0x8
001
000
C

The server (callee) cannot marshal the return data - low


RPC memory, etc.
_E_S
ERV
ER_
CA
NT
MA
RSH
AL_
DAT
A
0x8
001
000
D

The server (callee) cannot unmarshal the parameter data - low


RPC memory, etc.
_E_S
ERV
ER_
CA
NT
UN
MA
RSH
AL_
DAT
A
0x8
001
000
E
CONSTANT/VALUE DESCRIPTION

Received data is invalid; could be server or client data.


RPC
_E_I
NV
ALI
D_D
ATA
0x8
001
000
F

A particular parameter is invalid and cannot be


RPC (un)marshalled.
_E_I
NV
ALI
D_P
AR
AM
ETE
R
0x8
001
001
0

There is no second outgoing call on same channel in DDE


RPC conversation.
_E_C
AN
TCA
LLO
UT_
AG
AIN
0x8
001
001
1

The callee (server [not server application]) is not available and


RPC disappeared; all connections are invalid. The call did not
_E_S execute.
ERV
ER_
DIE
D_D
NE
0x8
001
001
2
CONSTANT/VALUE DESCRIPTION

System call failed.


RPC
_E_S
YS_
CAL
L_F
AILE
D
0x8
001
010
0

Could not allocate some required resource (memory, events,


RPC ...)
_E_
OU
T_O
F_R
ESO
URC
ES
0x8
001
010
1

Attempted to make calls on more than one thread in single


RPC threaded mode.
_E_
ATT
EM
PTE
D_
MU
LTIT
HRE
AD
0x8
001
010
2

The requested interface is not registered on the server object.


RPC
_E_
NO
T_R
EGI
STE
RED
0x8
001
010
3
CONSTANT/VALUE DESCRIPTION

RPC could not call the server or could not return the results of
RPC calling the server.
_E_F
AUL
T
0x8
001
010
4

The server threw an exception.


RPC
_E_S
ERV
ERF
AUL
T
0x8
001
010
5

Cannot change thread mode after it is set.


RPC
_E_C
HA
NGE
D_
MO
DE
0x8
001
010
6

The method called does not exist on the server.


RPC
_E_I
NV
ALI
DM
ETH
OD
0x8
001
010
7
CONSTANT/VALUE DESCRIPTION

The object invoked has disconnected from its clients.


RPC
_E_
DIS
CO
NN
ECT
ED
0x8
001
010
8

The object invoked chose not to process the call now. Try
RPC again later.
_E_R
ETR
Y
0x8
001
010
9

The message filter indicated that the application is busy.


RPC
_E_S
ERV
ERC
ALL
_RE
TRY
LAT
ER
0x8
001
010
A

The message filter rejected the call.


RPC
_E_S
ERV
ERC
ALL
_REJ
ECT
ED
0x8
001
010
B
CONSTANT/VALUE DESCRIPTION

A call control interfaces was called with invalid data.


RPC
_E_I
NV
ALI
D_C
ALL
DAT
A
0x8
001
010
C

An outgoing call cannot be made since the application is


RPC dispatching an input-synchronous call.
_E_C
AN
TCA
LLO
UT_I
NIN
PUT
SYN
CCA
LL
0x8
001
010
D

The application called an interface that was marshalled for a


RPC different thread.
_E_
WR
ON
G_T
HRE
AD
0x8
001
010
E

CoInitialize has not been called on the current thread.


RPC
_E_T
HRE
AD_
NO
T_I
NIT
0x8
001
010
F
CONSTANT/VALUE DESCRIPTION

The version of OLE on the client and server machines does


RPC not match.
_E_V
ERSI
ON_
MIS
MA
TCH
0x8
001
011
0

OLE received a packet with an invalid header.


RPC
_E_I
NV
ALI
D_H
EAD
ER
0x8
001
011
1

OLE received a packet with an invalid extension.


RPC
_E_I
NV
ALI
D_E
XTE
NSI
ON
0x8
001
011
2

The requested object or interface does not exist.


RPC
_E_I
NV
ALI
D_I
PID
0x8
001
011
3
CONSTANT/VALUE DESCRIPTION

The requested object does not exist.


RPC
_E_I
NV
ALI
D_O
BJE
CT
0x8
001
011
4

OLE has sent a request and is waiting for a reply.


RPC
_S_
CAL
LPE
NDI
NG
0x8
001
011
5

OLE is waiting before retrying a request.


RPC
_S_
WAI
TO
NTI
ME
R
0x8
001
011
6

Call context cannot be accessed after call completed.


RPC
_E_C
ALL
_CO
MP
LET
E
0x8
001
011
7
CONSTANT/VALUE DESCRIPTION

Impersonate on unsecure calls is not supported.


RPC
_E_
UN
SEC
URE
_CA
LL
0x8
001
011
8

Security must be initialized before any interfaces are


RPC marshalled or unmarshalled. It cannot be changed once
_E_T initialized.
OO_
LAT
E
0x8
001
011
9

No security packages are installed on this machine or the user


RPC is not logged on or there are no compatible security packages
_E_ between the client and server.
NO_
GO
OD_
SEC
URI
TY_
PAC
KA
GES
0x8
001
011
A

Access is denied.
RPC
_E_
ACC
ESS
_DE
NIE
D
0x8
001
011
B
CONSTANT/VALUE DESCRIPTION

Remote calls are not allowed for this process.


RPC
_E_R
EM
OTE
_DIS
ABL
ED
0x8
001
011
C

The marshaled interface data packet (OBJREF) has an invalid or


RPC unknown format.
_E_I
NV
ALI
D_O
BJR
EF
0x8
001
011
D

No context is associated with this call. This happens for some


RPC custom marshalled calls and on the client side of the call.
_E_
NO_
CO
NTE
XT
0x8
001
011
E

This operation returned because the timeout period expired.


RPC
_E_T
IME
OU
T
0x8
001
011
F
CONSTANT/VALUE DESCRIPTION

There are no synchronize objects to wait on.


RPC
_E_
NO_
SYN
C
0x8
001
012
0

Full subject issuer chain SSL principal name expected from the
RPC server.
_E_F
ULL
SIC_
REQ
UIR
ED
0x8
001
012
1

Principal name is not a valid MSSTD name.


RPC
_E_I
NV
ALI
D_S
TD_
NA
ME
0x8
001
012
2

Unable to impersonate DCOM client


CO_
E_F
AILE
DT
OIM
PER
SO
NA
TE
0x8
001
012
3
CONSTANT/VALUE DESCRIPTION

Unable to obtain server's security context


CO_
E_F
AILE
DT
OGE
TSE
CCT
X
0x8
001
012
4

Unable to open the access token of the current thread


CO_
E_F
AILE
DT
OO
PEN
THR
EAD
TOK
EN
0x8
001
012
5

Unable to obtain user info from an access token


CO_
E_F
AILE
DT
OGE
TTO
KEN
INF
O
0x8
001
012
6
CONSTANT/VALUE DESCRIPTION

The client who called IAccessControl::IsAccessPermitted was


CO_ not the trustee provided to the method
E_T
RUS
TEE
DOE
SNT
MA
TCH
CLIE
NT
0x8
001
012
7

Unable to obtain the client's security blanket


CO_
E_F
AILE
DT
OQ
UER
YCL
IEN
TBL
AN
KET
0x8
001
012
8

Unable to set a discretionary ACL into a security descriptor


CO_
E_F
AILE
DT
OSE
TDA
CL
0x8
001
012
9

The system function, AccessCheck, returned false


CO_
E_A
CCE
SSC
HEC
KFA
ILED
0x8
001
012
A
CONSTANT/VALUE DESCRIPTION

Either NetAccessDel or NetAccessAdd returned an error code.


CO_
E_N
ETA
CCE
SSA
PIF
AILE
D
0x8
001
012
B

One of the trustee strings provided by the user did not


CO_ conform to the \ syntax and it was not the "*" string
E_W
RO
NG
TRU
STE
ENA
MES
YNT
AX
0x8
001
012
C

One of the security identifiers provided by the user was invalid


CO_
E_IN
VAL
IDSI
D
0x8
001
012
D

Unable to convert a wide character trustee string to a


CO_ multibyte trustee string
E_C
ON
VER
SIO
NFA
ILED
0x8
001
012
E
CONSTANT/VALUE DESCRIPTION

Unable to find a security identifier that corresponds to a


CO_ trustee string provided by the user
E_N
OM
ATC
HIN
GSI
DFO
UN
D
0x8
001
012
F

The system function, LookupAccountSID, failed


CO_
E_L
OO
KUP
ACC
SID
FAIL
ED
0x8
001
013
0

Unable to find a trustee name that corresponds to a security


CO_ identifier provided by the user
E_N
OM
ATC
HIN
GN
AM
EFO
UN
D
0x8
001
013
1
CONSTANT/VALUE DESCRIPTION

The system function, LookupAccountName, failed


CO_
E_L
OO
KUP
ACC
NA
MEF
AILE
D
0x8
001
013
2

Unable to set or reset a serialization handle


CO_
E_SE
TSE
RLH
NDL
FAIL
ED
0x8
001
013
3

Unable to obtain the Windows directory


CO_
E_F
AILE
DT
OGE
TWI
NDI
R
0x8
001
013
4

Path too long


CO_
E_P
AT
HT
OO
LO
NG
0x8
001
013
5
CONSTANT/VALUE DESCRIPTION

Unable to generate a uuid.


CO_
E_F
AILE
DT
OGE
NU
UID
0x8
001
013
6

Unable to create file


CO_
E_F
AILE
DT
OC
REA
TEFI
LE
0x8
001
013
7

Unable to close a serialization handle or a file handle.


CO_
E_F
AILE
DT
OCL
OSE
HA
NDL
E
0x8
001
013
8

The number of ACEs in an ACL exceeds the system limit.


CO_
E_E
XCE
EDS
YSA
CLLI
MIT
0x8
001
013
9
CONSTANT/VALUE DESCRIPTION

Not all the DENY_ACCESS ACEs are arranged in front of the


CO_ GRANT_ACCESS ACEs in the stream.
E_A
CESI
NW
RO
NG
OR
DER
0x8
001
013
A

The version of ACL format in the stream is not supported by


CO_ this implementation of IAccessControl
E_IN
CO
MP
ATI
BLE
STR
EA
MV
ERSI
ON
0x8
001
013
B

Unable to open the access token of the server process


CO_
E_F
AILE
DT
OO
PEN
PR
OCE
SST
OKE
N
0x8
001
013
C
CONSTANT/VALUE DESCRIPTION

Unable to decode the ACL in the stream provided by the user


CO_
E_D
ECO
DEF
AILE
D
0x8
001
013
D

The COM IAccessControl object is not initialized


CO_
E_A
CN
OTI
NITI
ALI
ZED
0x8
001
013
F

Call Cancellation is disabled


CO_
E_C
AN
CEL
_DIS
ABL
ED
0x8
001
014
0

An internal error occurred.


RPC
_E_
UNE
XPE
CTE
D
0x8
001
FFFF

Requirements

Header
Win
erro
r.h
See also
C
O
M
E
r
r
o
r
C
o
d
e
s
COM Error Codes (Security and Setup)
1/7/2020 • 32 minutes to read • Edit Online

The following table provides a list of error codes used by COM -based APIs.
If you are experiencing difficulty with an application you are installing or running, contact customer support for the
software that is displaying the error message. To obtain support for a Microsoft product, go to
https://support.microsoft.com.

CONSTANT/VALUE DESCRIPTION

The specified event is currently not being audited.


ERR
OR_
AU
DITI
NG_
DIS
ABL
ED
0xC
009
000
1

The SID filtering operation removed all SIDs.


ERR
OR_
ALL
_SID
S_FI
LTE
RED
0xC
009
000
2

Business rule scripts are disabled for the calling application.


ERR
OR_
BIZ
RUL
ES_
NO
T_E
NA
BLE
D
0xC
009
000
3
CONSTANT/VALUE DESCRIPTION

The packaging API has encountered an internal error.


APP
X_E_
PAC
KA
GIN
G_I
NTE
RN
AL
0x8
008
020
0

The file is not a valid package because its contents are


APP interleaved.
X_E_
INT
ERL
EAV
ING
_NO
T_A
LLO
WE
D
0x8
008
020
1

The file is not a valid package because it contains OPC


APP relationships.
X_E_
REL
ATI
ON
SHI
PS_
NO
T_A
LLO
WE
D
0x8
008
020
2
CONSTANT/VALUE DESCRIPTION

The file is not a valid package because it is missing a manifest


APP or block map, or missing a signature file when the code
X_E_ integrity file is present.
MIS
SIN
G_R
EQU
IRE
D_FI
LE
0x8
008
020
3

The package's manifest is invalid.


APP
X_E_
INV
ALI
D_
MA
NIF
EST
0x8
008
020
4

The package's block map is invalid.


APP
X_E_
INV
ALI
D_B
LOC
KM
AP
0x8
008
020
5

The package's content cannot be read because it is corrupt.


APP
X_E_
CO
RRU
PT_
CO
NTE
NT
0x8
008
020
6
CONSTANT/VALUE DESCRIPTION

The computed hash value of the block does not match the
APP one stored in the block map.
X_E_
BLO
CK_
HA
SH_
INV
ALI
D
0x8
008
020
7

The requested byte range is over 4GB when translated to byte


APP range of blocks.
X_E_
REQ
UES
TED
_RA
NGE
_TO
O_L
AR
GE
0x8
008
020
8

The SIP_SUBJECTINFO structure used to sign the package


APP didn't contain the required data.
X_E_
INV
ALI
D_SI
P_C
LIE
NT_
DAT
A
0x8
008
020
9
CONSTANT/VALUE DESCRIPTION

The app didn't start in the required time.


E_A
PPL
ICA
TIO
N_A
CTI
VAT
ION
_TI
ME
D_O
UT
0x8
027
025
A

The app didn't start.


E_A
PPL
ICA
TIO
N_A
CTI
VAT
ION
_EX
EC_
FAIL
URE
0x8
027
025
B

This app failed to launch because of an issue with its license.


E_A Please try again in a moment.
PPL
ICA
TIO
N_T
EM
PO
RAR
Y_LI
CEN
SE_E
RR
OR
0x8
027
025
C
CONSTANT/VALUE DESCRIPTION

Bad UID.
NTE
_BA
D_U
ID
0x8
009
000
1

Bad Hash.
NTE
_BA
D_H
AS
H
0x8
009
000
2

Bad Key.
NTE
_BA
D_K
EY
0x8
009
000
3

Bad Length.
NTE
_BA
D_L
EN
0x8
009
000
4

Bad Data.
NTE
_BA
D_D
ATA
0x8
009
000
5
CONSTANT/VALUE DESCRIPTION

Invalid Signature.
NTE
_BA
D_SI
GN
ATU
RE
0x8
009
000
6

Bad Version of provider.


NTE
_BA
D_V
ER
0x8
009
000
7

Invalid algorithm specified.


NTE
_BA
D_A
LGI
D
0x8
009
000
8

Invalid flags specified.


NTE
_BA
D_F
LAG
S
0x8
009
000
9

Invalid type specified.


NTE
_BA
D_T
YPE
0x8
009
000
A
CONSTANT/VALUE DESCRIPTION

Key not valid for use in specified state.


NTE
_BA
D_K
EY_
STA
TE
0x8
009
000
B

Hash not valid for use in specified state.


NTE
_BA
D_H
AS
H_S
TAT
E
0x8
009
000
C

Key does not exist.


NTE
_NO
_KE
Y
0x8
009
000
D

Insufficient memory available for the operation.


NTE
_NO
_ME
MO
RY
0x8
009
000
E

Object already exists.


NTE
_EXI
STS
0x8
009
000
F
CONSTANT/VALUE DESCRIPTION

Access denied.
NTE
_PE
RM
0x8
009
001
0

Object was not found.


NTE
_NO
T_F
OU
ND
0x8
009
001
1

Data already encrypted.


NTE
_DO
UBL
E_E
NC
RYP
T
0x8
009
001
2

Invalid provider specified.


NTE
_BA
D_P
RO
VID
ER
0x8
009
001
3

Invalid provider type specified.


NTE
_BA
D_P
RO
V_T
YPE
0x8
009
001
4
CONSTANT/VALUE DESCRIPTION

Provider's public key is invalid.


NTE
_BA
D_P
UBL
IC_K
EY
0x8
009
001
5

Keyset does not exist


NTE
_BA
D_K
EYS
ET
0x8
009
001
6

Provider type not defined.


NTE
_PR
OV_
TYP
E_N
OT_
DEF
0x8
009
001
7

Provider type as registered is invalid.


NTE
_PR
OV_
TYP
E_E
NTR
Y_B
AD
0x8
009
001
8
CONSTANT/VALUE DESCRIPTION

The keyset is not defined.


NTE
_KE
YSE
T_N
OT_
DEF
0x8
009
001
9

Keyset as registered is invalid.


NTE
_KE
YSE
T_E
NTR
Y_B
AD
0x8
009
001
A

Provider type does not match registered value.


NTE
_PR
OV_
TYP
E_N
O_
MA
TCH
0x8
009
001
B

The digital signature file is corrupt.


NTE
_SIG
NA
TUR
E_FI
LE_
BA
D
0x8
009
001
C
CONSTANT/VALUE DESCRIPTION

Provider DLL failed to initialize correctly.


NTE
_PR
OVI
DER
_DL
L_F
AIL
0x8
009
001
D

Provider DLL could not be found.


NTE
_PR
OV_
DLL
_NO
T_F
OU
ND
0x8
009
001
E

The Keyset parameter is invalid.


NTE
_BA
D_K
EYS
ET_
PAR
AM
0x8
009
001
F

An internal error occurred.


NTE
_FAI
L
0x8
009
002
0
CONSTANT/VALUE DESCRIPTION

A base error occurred.


NTE
_SY
S_E
RR
0x8
009
002
1

Provider could not perform the action since the context was
NTE acquired as silent.
_SIL
ENT
_CO
NTE
XT
0x8
009
002
2

The security token does not have storage space available for
NTE an additional container.
_TO
KEN
_KE
YSE
T_S
TOR
AGE
_FU
LL
0x8
009
002
3

The profile for the user is a temporary profile.


NTE
_TE
MP
OR
ARY
_PR
OFI
LE
0x8
009
002
4
CONSTANT/VALUE DESCRIPTION

The key parameters could not be set because the CSP uses
NTE fixed parameters.
_FIX
EDP
AR
AM
ETE
R
0x8
009
002
5

The supplied handle is invalid.


NTE
_IN
VAL
ID_
HA
NDL
E
0x8
009
002
6

The parameter is incorrect.


NTE
_IN
VAL
ID_
PAR
AM
ETE
R
0x8
009
002
7

The buffer supplied to a function was too small.


NTE
_BU
FFE
R_T
OO_
SM
ALL
0x8
009
002
8
CONSTANT/VALUE DESCRIPTION

The requested operation is not supported.


NTE
_NO
T_S
UPP
ORT
ED
0x8
009
002
9

No more data is available.


NTE
_NO
_M
ORE
_ITE
MS
0x8
009
002
A

The supplied buffers overlap incorrectly.


NTE
_BU
FFE
RS_
OVE
RLA
P
0x8
009
002
B

The specified data could not be decrypted.


NTE
_DE
CRY
PTI
ON_
FAIL
URE
0x8
009
002
C
CONSTANT/VALUE DESCRIPTION

An internal consistency check failed.


NTE
_IN
TER
NAL
_ER
RO
R
0x8
009
002
D

This operation requires input from the user.


NTE
_UI_
REQ
UIR
ED
0x8
009
002
E

The cryptographic provider does not support HMAC.


NTE
_H
MA
C_N
OT_
SUP
PO
RTE
D
0x8
009
002
F

The device that is required by this cryptographic provider is


NTE not ready for use.
_DE
VIC
E_N
OT_
REA
DY
0x8
009
003
0
CONSTANT/VALUE DESCRIPTION

The dictionary attack mitigation is triggered and the provided


NTE authorization was ignored by the provider.
_AU
THE
NTI
CAT
ION
_IG
NO
RED
0x8
009
003
1

The validation of the provided data failed the integrity or


NTE signature validation.
_VA
LID
ATI
ON_
FAIL
ED
0x8
009
003
2

Incorrect password.
NTE
_IN
CO
RRE
CT_
PAS
SW
OR
D
0x8
009
003
3

Encryption failed.
NTE
_EN
CRY
PTI
ON_
FAIL
URE
0x8
009
003
4
CONSTANT/VALUE DESCRIPTION

Not enough memory is available to complete this request


SEC
_E_I
NS
UFFI
CIE
NT_
ME
MO
RY
0x8
009
030
0

The handle specified is invalid


SEC
_E_I
NV
ALI
D_H
AN
DLE
0x8
009
030
1

The function requested is not supported


SEC
_E_
UN
SUP
PO
RTE
D_F
UN
CTI
ON
0x8
009
030
2

The specified target is unknown or unreachable


SEC
_E_T
AR
GET
_UN
KN
OW
N
0x8
009
030
3
CONSTANT/VALUE DESCRIPTION

The Local Security Authority cannot be contacted


SEC
_E_I
NTE
RN
AL_
ERR
OR
0x8
009
030
4

The requested security package does not exist


SEC
_E_S
ECP
KG_
NO
T_F
OU
ND
0x8
009
030
5

The caller is not the owner of the desired credentials


SEC
_E_
NO
T_O
WN
ER
0x8
009
030
6

The security package failed to initialize, and cannot be installed


SEC
_E_C
AN
NO
T_I
NST
ALL
0x8
009
030
7
CONSTANT/VALUE DESCRIPTION

The token supplied to the function is invalid


SEC
_E_I
NV
ALI
D_T
OKE
N
0x8
009
030
8

The security package is not able to marshal the logon buffer,


SEC so the logon attempt has failed
_E_C
AN
NO
T_P
ACK
0x8
009
030
9

The per-message Quality of Protection is not supported by


SEC the security package
_E_
QO
P_N
OT_
SUP
PO
RTE
D
0x8
009
030
A

The security context does not allow impersonation of the


SEC client
_E_
NO_
IMP
ERS
ON
ATI
ON
0x8
009
030
B
CONSTANT/VALUE DESCRIPTION

The logon attempt failed


SEC
_E_L
OG
ON_
DEN
IED
0x8
009
030
C

The credentials supplied to the package were not recognized


SEC
_E_
UN
KN
OW
N_C
RED
ENT
IAL
S
0x8
009
030
D

No credentials are available in the security package


SEC
_E_
NO_
CRE
DEN
TIA
LS
0x8
009
030
E

The message or signature supplied for verification has been


SEC altered
_E_
MES
SAG
E_A
LTE
RED
0x8
009
030
F
CONSTANT/VALUE DESCRIPTION

The message supplied for verification is out of sequence


SEC
_E_
OU
T_O
F_SE
QUE
NCE
0x8
009
031
0

No authority could be contacted for authentication.


SEC
_E_
NO_
AUT
HE
NTI
CAT
ING
_AU
TH
ORI
TY
0x8
009
031
1

The function completed successfully, but must be called again


SEC to complete the context
_I_C
ON
TIN
UE_
NEE
DED
0x0
009
031
2

The function completed successfully, but CompleteToken must


SEC be called
_I_C
OM
PLE
TE_
NEE
DED
0x0
009
031
3
CONSTANT/VALUE DESCRIPTION

The function completed successfully, but both CompleteToken


SEC and this function must be called to complete the context
_I_C
OM
PLE
TE_
AN
D_C
ON
TIN
UE
0x0
009
031
4

The logon was completed, but no network authority was


SEC available. The logon was made using locally known
_I_L information
OC
AL_
LOG
ON
0x0
009
031
5

The requested security package does not exist


SEC
_E_B
AD_
PKG
ID
0x8
009
031
6

The context has expired and can no longer be used.


SEC
_E_C
ON
TEX
T_E
XPI
RED
0x8
009
031
7
CONSTANT/VALUE DESCRIPTION

The context has expired and can no longer be used.


SEC
_I_C
ON
TEX
T_E
XPI
RED
0x0
009
031
7

The supplied message is incomplete. The signature was not


SEC verified.
_E_I
NC
OM
PLE
TE_
MES
SAG
E
0x8
009
031
8

The credentials supplied were not complete, and could not be


SEC verified. The context could not be initialized.
_E_I
NC
OM
PLE
TE_
CRE
DEN
TIA
LS
0x8
009
032
0

The buffers supplied to a function was too small.


SEC
_E_B
UFF
ER_
TO
O_S
MA
LL
0x8
009
032
1
CONSTANT/VALUE DESCRIPTION

The credentials supplied were not complete, and could not be


SEC verified. Additional information can be returned from the
_I_I context.
NC
OM
PLE
TE_
CRE
DEN
TIA
LS
0x0
009
032
0

The context data must be renegotiated with the peer.


SEC
_I_R
ENE
GO
TIA
TE
0x0
009
032
1

The target principal name is incorrect.


SEC
_E_
WR
ON
G_P
RIN
CIP
AL
0x8
009
032
2

There is no LSA mode context associated with this context.


SEC
_I_N
O_L
SA_
CO
NTE
XT
0x0
009
032
3
CONSTANT/VALUE DESCRIPTION

The clocks on the client and server machines are skewed.


SEC
_E_T
IME
_SK
EW
0x8
009
032
4

The certificate chain was issued by an authority that is not


SEC trusted.
_E_
UN
TRU
STE
D_R
OO
T
0x8
009
032
5

The message received was unexpected or badly formatted.


SEC
_E_I
LLE
GAL
_ME
SSA
GE
0x8
009
032
6

An unknown error occurred while processing the certificate.


SEC
_E_C
ERT
_UN
KN
OW
N
0x8
009
032
7
CONSTANT/VALUE DESCRIPTION

The received certificate has expired.


SEC
_E_C
ERT
_EX
PIR
ED
0x8
009
032
8

The specified data could not be encrypted.


SEC
_E_E
NC
RYP
T_F
AIL
URE
0x8
009
032
9

The specified data could not be decrypted.


SEC
_E_
DEC
RYP
T_F
AIL
URE
0x8
009
033
0

The client and server cannot communicate, because they do


SEC not possess a common algorithm.
_E_
ALG
ORI
TH
M_
MIS
MA
TCH
0x8
009
033
1
CONSTANT/VALUE DESCRIPTION

The security context could not be established due to a failure


SEC in the requested quality of service (e.g. mutual authentication
_E_S or delegation).
ECU
RIT
Y_Q
OS_
FAIL
ED
0x8
009
033
2

A security context was deleted before the context was


SEC completed. This is considered a logon failure.
_E_
UNF
INIS
HED
_CO
NTE
XT_
DEL
ETE
D
0x8
009
033
3

The client is trying to negotiate a context and the server


SEC requires user-to-user but didn't send a TGT reply.
_E_
NO_
TGT
_RE
PLY
0x8
009
033
4

Unable to accomplish the requested task because the local


SEC machine does not have any IP addresses.
_E_
NO_
IP_
AD
DRE
SSE
S
0x8
009
033
5
CONSTANT/VALUE DESCRIPTION

The supplied credential handle does not match the credential


SEC associated with the security context.
_E_
WR
ON
G_C
RED
ENT
IAL_
HA
NDL
E
0x8
009
033
6

The crypto system or checksum function is invalid because a


SEC required function is unavailable.
_E_C
RYP
TO_
SYS
TEM
_IN
VAL
ID
0x8
009
033
7

The number of maximum ticket referrals has been exceeded.


SEC
_E_
MA
X_R
EFE
RRA
LS_E
XCE
EDE
D
0x8
009
033
8
CONSTANT/VALUE DESCRIPTION

The local machine must be a Kerberos KDC (domain controller)


SEC and it is not.
_E_
MU
ST_
BE_
KDC
0x8
009
033
9

The other end of the security negotiation is requires strong


SEC crypto but it is not supported on the local machine.
_E_S
TRO
NG_
CRY
PTO
_NO
T_S
UPP
ORT
ED
0x8
009
033
A

The KDC reply contained more than one principal name.


SEC
_E_T
OO_
MA
NY_
PRI
NCI
PAL
S
0x8
009
033
B

Expected to find PA data for a hint of what etype to use, but it


SEC was not found.
_E_
NO_
PA_
DAT
A
0x8
009
033
C
CONSTANT/VALUE DESCRIPTION

The client certificate does not contain a valid UPN, or does not
SEC match the client name in the logon request. Please contact
_E_P your administrator.
KINI
T_N
AM
E_M
ISM
ATC
H
0x8
009
033
D

Smartcard logon is required and was not used.


SEC
_E_S
MA
RTC
AR
D_L
OG
ON_
REQ
UIR
ED
0x8
009
033
E

A system shutdown is in progress.


SEC
_E_S
HU
TD
OW
N_I
N_P
RO
GRE
SS
0x8
009
033
F
CONSTANT/VALUE DESCRIPTION

An invalid request was sent to the KDC.


SEC
_E_K
DC_
INV
ALI
D_R
EQU
EST
0x8
009
034
0

The KDC was unable to generate a referral for the service


SEC requested.
_E_K
DC_
UN
ABL
E_T
O_R
EFE
R
0x8
009
034
1

The encryption type requested is not supported by the KDC.


SEC
_E_K
DC_
UN
KN
OW
N_E
TYP
E
0x8
009
034
2
CONSTANT/VALUE DESCRIPTION

An unsupported preauthentication mechanism was presented


SEC to the Kerberos package.
_E_
UN
SUP
PO
RTE
D_P
REA
UT
H
0x8
009
034
3

The requested operation cannot be completed. The computer


SEC must be trusted for delegation and the current user account
_E_ must be configured to allow delegation.
DEL
EGA
TIO
N_R
EQU
IRE
D
0x8
009
034
5

Client's supplied SSPI channel bindings were incorrect.


SEC
_E_B
AD_
BIN
DIN
GS
0x8
009
034
6

The received certificate was mapped to multiple accounts.


SEC
_E_
MU
LTIP
LE_
ACC
OU
NTS
0x8
009
034
7
CONSTANT/VALUE DESCRIPTION

SEC_E_NO_KERB_KEY
SEC
_E_
NO_
KER
B_K
EY
0x8
009
034
8

The certificate is not valid for the requested usage.


SEC
_E_C
ERT
_W
RO
NG_
USA
GE
0x8
009
034
9

The system cannot contact a domain controller to service the


SEC authentication request. Please try again later.
_E_
DO
WN
GR
ADE
_DE
TEC
TED
0x8
009
035
0

The smartcard certificate used for authentication has been


SEC revoked. Please contact your system administrator. There may
_E_S be additional information in the event log.
MA
RTC
AR
D_C
ERT
_RE
VO
KED
0x8
009
035
1
CONSTANT/VALUE DESCRIPTION

An untrusted certificate authority was detected While


SEC processing the smartcard certificate used for authentication.
_E_I Please contact your system administrator.
SSU
ING
_CA
_UN
TRU
STE
D
0x8
009
035
2

The revocation status of the smartcard certificate used for


SEC authentication could not be determined. Please contact your
_E_R system administrator.
EVO
CAT
ION
_OF
FLI
NE_
C
0x8
009
035
3

The smartcard certificate used for authentication was not


SEC trusted. Please contact your system administrator.
_E_P
KINI
T_C
LIE
NT_
FAIL
URE
0x8
009
035
4
CONSTANT/VALUE DESCRIPTION

The smartcard certificate used for authentication has expired.


SEC Please contact your system administrator.
_E_S
MA
RTC
AR
D_C
ERT
_EX
PIR
ED
0x8
009
035
5

The Kerberos subsystem encountered an error. A service for


SEC user protocol request was made against a domain controller
_E_ which does not support service for user.
NO_
S4U
_PR
OT_
SUP
PO
RT
0x8
009
035
6

An attempt was made by this server to make a Kerberos


SEC constrained delegation request for a target outside of the
_E_C server's realm. This is not supported, and indicates a
ROS misconfiguration on this server's allowed to delegate to list.
SRE Please contact your administrator.
AL
M_
DEL
EGA
TIO
N_F
AIL
URE
0x8
009
035
7
CONSTANT/VALUE DESCRIPTION

The revocation status of the domain controller certificate used


SEC for smartcard authentication could not be determined. There
_E_R is additional information in the system event log. Please
EVO contact your system administrator.
CAT
ION
_OF
FLI
NE_
KDC
0x8
009
035
8

An untrusted certificate authority was detected while


SEC processing the domain controller certificate used for
_E_I authentication. There is additional information in the system
SSU event log. Please contact your system administrator.
ING
_CA
_UN
TRU
STE
D_K
DC
0x8
009
035
9

The domain controller certificate used for smartcard logon has


SEC expired. Please contact your system administrator with the
_E_K contents of your system event log.
DC_
CER
T_E
XPI
RED
0x8
009
035
A

The domain controller certificate used for smartcard logon has


SEC been revoked. Please contact your system administrator with
_E_K the contents of your system event log.
DC_
CER
T_R
EVO
KED
0x8
009
035
B
CONSTANT/VALUE DESCRIPTION

A signature operation must be performed before the user can


SEC authenticate.
_I_SI
GN
ATU
RE_
NEE
DED
0x0
009
035
C

One or more of the parameters passed to the function was


SEC invalid.
_E_I
NV
ALI
D_P
AR
AM
ETE
R
0x8
009
035
D

Client policy does not allow credential delegation to target


SEC server.
_E_
DEL
EGA
TIO
N_P
OLI
CY
0x8
009
035
E

Client policy does not allow credential delegation to target


SEC server with NLTM only authentication.
_E_P
OLI
CY_
NLT
M_
ON
LY
0x8
009
035
F
CONSTANT/VALUE DESCRIPTION

The recipient rejected the renegotiation request.


SEC
_I_N
O_R
ENE
GO
TIA
TIO
N
0x0
009
036
0

The required security context does not exist.


SEC
_E_
NO_
CO
NTE
XT
0x8
009
036
1

The PKU2U protocol encountered an error while attempting


SEC to utilize the associated certificates.
_E_P
KU2
U_C
ERT
_FAI
LUR
E
0x8
009
036
2

The identity of the server computer could not be verified.


SEC
_E_
MU
TUA
L_A
UT
H_F
AILE
D
0x8
009
036
3
CONSTANT/VALUE DESCRIPTION

The returned buffer is only a fragment of the message. More


SEC fragments need to be returned.
_I_
MES
SAG
E_F
RA
GM
ENT
0x0
009
036
4

Only https scheme is allowed.


SEC
_E_
ON
LY_
HTT
PS_
ALL
OW
ED
0x8
009
036
5

The function completed successfully, but must be called again


SEC to complete the context. Early start can be used.
_I_C
ON
TIN
UE_
NEE
DED
_ME
SSA
GE_
OK
0x8
009
036
6

An error occurred while performing an operation on a


CRY cryptographic message.
PT_
E_M
SG_
ERR
OR
0x8
009
100
1
CONSTANT/VALUE DESCRIPTION

Unknown cryptographic algorithm.


CRY
PT_
E_U
NK
NO
WN
_AL
GO
0x8
009
100
2

The object identifier is poorly formatted.


CRY
PT_
E_OI
D_F
OR
MA
T
0x8
009
100
3

Invalid cryptographic message type.


CRY
PT_
E_IN
VAL
ID_
MS
G_T
YPE
0x8
009
100
4

Unexpected cryptographic message encoding.


CRY
PT_
E_U
NEX
PEC
TED
_EN
CO
DIN
G
0x8
009
100
5
CONSTANT/VALUE DESCRIPTION

The cryptographic message does not contain an expected


CRY authenticated attribute.
PT_
E_A
UT
H_A
TTR
_MI
SSI
NG
0x8
009
100
6

The hash value is not correct.


CRY
PT_
E_H
AS
H_V
ALU
E
0x8
009
100
7

The index value is not valid.


CRY
PT_
E_IN
VAL
ID_I
NDE
X
0x8
009
100
8

The content of the cryptographic message has already been


CRY decrypted.
PT_
E_A
LRE
AD
Y_D
ECR
YPT
ED
0x8
009
100
9
CONSTANT/VALUE DESCRIPTION

The content of the cryptographic message has not been


CRY decrypted yet.
PT_
E_N
OT_
DEC
RYP
TED
0x8
009
100
A

The enveloped-data message does not contain the specified


CRY recipient.
PT_
E_R
ECI
PIE
NT_
NO
T_F
OU
ND
0x8
009
100
B

Invalid control type.


CRY
PT_
E_C
ON
TRO
L_T
YPE
0x8
009
100
C

Invalid issuer and/or serial number.


CRY
PT_
E_IS
SUE
R_S
ERI
ALN
UM
BER
0x8
009
100
D
CONSTANT/VALUE DESCRIPTION

Cannot find the original signer.


CRY
PT_
E_SI
GNE
R_N
OT_
FOU
ND
0x8
009
100
E

The cryptographic message does not contain all of the


CRY requested attributes.
PT_
E_A
TTR
IBU
TES
_MI
SSI
NG
0x8
009
100
F

The streamed cryptographic message is not ready to return


CRY data.
PT_
E_S
TRE
AM
_MS
G_N
OT_
REA
DY
0x8
009
101
0
CONSTANT/VALUE DESCRIPTION

The streamed cryptographic message requires more data to


CRY complete the decode operation.
PT_
E_S
TRE
AM
_IN
SUF
FICI
ENT
_DA
TA
0x8
009
101
1

The protected data needs to be re-protected.


CRY
PT_I
_NE
W_
PR
OTE
CTI
ON_
REQ
UIR
ED
0x0
009
101
2

The length specified for the output data was insufficient.


CRY
PT_
E_B
AD_
LEN
0x8
009
200
1

An error occurred during encode or decode operation.


CRY
PT_
E_B
AD_
ENC
ODE
0x8
009
200
2
CONSTANT/VALUE DESCRIPTION

An error occurred while reading or writing to a file.


CRY
PT_
E_FI
LE_E
RR
OR
0x8
009
200
3

Cannot find object or property.


CRY
PT_
E_N
OT_
FOU
ND
0x8
009
200
4

The object or property already exists.


CRY
PT_
E_E
XIS
TS
0x8
009
200
5

No provider was specified for the store or object.


CRY
PT_
E_N
O_P
RO
VID
ER
0x8
009
200
6
CONSTANT/VALUE DESCRIPTION

The specified certificate is self signed.


CRY
PT_
E_SE
LF_S
IGN
ED
0x8
009
200
7

The previous certificate or CRL context was deleted.


CRY
PT_
E_D
ELE
TED
_PR
EV
0x8
009
200
8

Cannot find the requested object.


CRY
PT_
E_N
O_
MA
TCH
0x8
009
200
9

The certificate does not have a property that references a


CRY private key.
PT_
E_U
NEX
PEC
TED
_MS
G_T
YPE
0x8
009
200
A
CONSTANT/VALUE DESCRIPTION

Cannot find the certificate and private key for decryption.


CRY
PT_
E_N
O_K
EY_
PR
OPE
RTY
0x8
009
200
B

Cannot find the certificate and private key to use for


CRY decryption.
PT_
E_N
O_D
ECR
YPT
_CE
RT
0x8
009
200
C

Not a cryptographic message or the cryptographic message is


CRY not formatted correctly.
PT_
E_B
AD_
MS
G
0x8
009
200
D

The signed cryptographic message does not have a signer for


CRY the specified signer index.
PT_
E_N
O_S
IGN
ER
0x8
009
200
E
CONSTANT/VALUE DESCRIPTION

Final closure is pending until additional frees or closes.


CRY
PT_
E_P
END
ING
_CL
OSE
0x8
009
200
F

The certificate is revoked.


CRY
PT_
E_R
EVO
KED
0x8
009
201
0

No Dll or exported function was found to verify revocation.


CRY
PT_
E_N
O_R
EVO
CAT
ION
_DL
L
0x8
009
201
1

The revocation function was unable to check revocation for


CRY the certificate.
PT_
E_N
O_R
EVO
CAT
ION
_CH
ECK
0x8
009
201
2
CONSTANT/VALUE DESCRIPTION

The revocation function was unable to check revocation


CRY because the revocation server was offline.
PT_
E_R
EVO
CAT
ION
_OF
FLI
NE
0x8
009
201
3

The certificate is not in the revocation server's database.


CRY
PT_
E_N
OT_
IN_
REV
OC
ATI
ON_
DAT
AB
ASE
0x8
009
201
4

The string contains a non-numeric character.


CRY
PT_
E_IN
VAL
ID_
NU
ME
RIC_
STR
ING
0x8
009
202
0
CONSTANT/VALUE DESCRIPTION

The string contains a non-printable character.


CRY
PT_
E_IN
VAL
ID_
PRI
NT
ABL
E_S
TRI
NG
0x8
009
202
1

The string contains a character not in the 7 bit ASCII character


CRY set.
PT_
E_IN
VAL
ID_I
A5_
STR
ING
0x8
009
202
2

The string contains an invalid X500 name attribute key, oid,


CRY value or delimiter.
PT_
E_IN
VAL
ID_
X50
0_S
TRI
NG
0x8
009
202
3
CONSTANT/VALUE DESCRIPTION

The dwValueType for the CERT_NAME_VALUE is not one of


CRY the character strings. Most likely it is either a
PT_ CERT_RDN_ENCODED_BLOB or CERT_RDN_OCTET_STRING.
E_N
OT_
CH
AR_
STR
ING
0x8
009
202
4

The Put operation cannot continue. The file needs to be


CRY resized. However, there is already a signature present. A
PT_ complete signing operation must be done.
E_FI
LER
ESIZ
ED
0x8
009
202
5

The cryptographic operation failed due to a local security


CRY option setting.
PT_
E_SE
CUR
ITY_
SET
TIN
GS
0x8
009
202
6

No DLL or exported function was found to verify subject


CRY usage.
PT_
E_N
O_V
ERIF
Y_U
SAG
E_D
LL
0x8
009
202
7
CONSTANT/VALUE DESCRIPTION

The called function was unable to do a usage check on the


CRY subject.
PT_
E_N
O_V
ERIF
Y_U
SAG
E_C
HEC
K
0x8
009
202
8

Since the server was offline, the called function was unable to
CRY complete the usage check.
PT_
E_V
ERIF
Y_U
SAG
E_O
FFLI
NE
0x8
009
202
9

The subject was not found in a Certificate Trust List (CTL).


CRY
PT_
E_N
OT_
IN_
CTL
0x8
009
202
A

None of the signers of the cryptographic message or


CRY certificate trust list is trusted.
PT_
E_N
O_T
RUS
TED
_SIG
NER
0x8
009
202
B
CONSTANT/VALUE DESCRIPTION

The public key's algorithm parameters are missing.


CRY
PT_
E_M
ISSI
NG_
PUB
KEY
_PA
RA
0x8
009
202
C

An object could not be located using the object locator


CRY infrastructure with the given name.
PT_
E_O
BJE
CT_
LOC
AT
OR_
NO
T_F
OU
ND
0x8
009
202
d

OSS Certificate encode/decode error code base See


CRY asn1code.h for a definition of the OSS runtime errors. The OSS
PT_ error values are offset by CRYPT_E_OSS_ERROR.
E_O
SS_
ERR
OR
0x8
009
300
0

OSS ASN.1 Error: Output Buffer is too small.


OSS
_M
ORE
_BU
F
0x8
009
300
1
CONSTANT/VALUE DESCRIPTION

OSS ASN.1 Error: Signed integer is encoded as a unsigned


OSS integer.
_NE
GAT
IVE_
UIN
TEG
ER
0x8
009
300
2

OSS ASN.1 Error: Unknown ASN.1 data type.


OSS
_PD
U_R
AN
GE
0x8
009
300
3

OSS ASN.1 Error: Output buffer is too small, the decoded data
OSS has been truncated.
_M
ORE
_IN
PUT
0x8
009
300
4

OSS ASN.1 Error: Invalid data.


OSS
_DA
TA_
ERR
OR
0x8
009
300
5

OSS ASN.1 Error: Invalid argument.


OSS
_BA
D_A
RG
0x8
009
300
6
CONSTANT/VALUE DESCRIPTION

OSS ASN.1 Error: Encode/Decode version mismatch.


OSS
_BA
D_V
ERSI
ON
0x8
009
300
7

OSS ASN.1 Error: Out of memory.


OSS
_OU
T_M
EM
OR
Y
0x8
009
300
8

OSS ASN.1 Error: Encode/Decode Error.


OSS
_PD
U_
MIS
MA
TCH
0x8
009
300
9

OSS ASN.1 Error: Internal Error.


OSS
_LI
MIT
ED
0x8
009
300
A

OSS ASN.1 Error: Invalid data.


OSS
_BA
D_P
TR
0x8
009
300
B
CONSTANT/VALUE DESCRIPTION

OSS ASN.1 Error: Invalid data.


OSS
_BA
D_TI
ME
0x8
009
300
C

OSS ASN.1 Error: Unsupported BER indefinite-length


OSS encoding.
_IN
DEFI
NIT
E_N
OT_
SUP
PO
RTE
D
0x8
009
300
D

OSS ASN.1 Error: Access violation.


OSS
_ME
M_E
RR
OR
0x8
009
300
E

OSS ASN.1 Error: Invalid data.


OSS
_BA
D_T
ABL
E
0x8
009
300
F
CONSTANT/VALUE DESCRIPTION

OSS ASN.1 Error: Invalid data.


OSS
_TO
O_L
ON
G
0x8
009
301
0

OSS ASN.1 Error: Invalid data.


OSS
_CO
NST
RAI
NT_
VIO
LAT
ED
0x8
009
301
1

OSS ASN.1 Error: Internal Error.


OSS
_FA
TAL
_ER
RO
R
0x8
009
301
2

OSS ASN.1 Error: Multi-threading conflict.


OSS
_AC
CES
S_S
ERI
ALI
ZAT
ION
_ER
RO
R
0x8
009
301
3
CONSTANT/VALUE DESCRIPTION

OSS ASN.1 Error: Invalid data.


OSS
_NU
LL_T
BL
0x8
009
301
4

OSS ASN.1 Error: Invalid data.


OSS
_NU
LL_F
CN
0x8
009
301
5

OSS ASN.1 Error: Invalid data.


OSS
_BA
D_E
NC
RUL
ES
0x8
009
301
6

OSS ASN.1 Error: Encode/Decode function not implemented.


OSS
_UN
AV
AIL_
ENC
RUL
ES
0x8
009
301
7
CONSTANT/VALUE DESCRIPTION

OSS ASN.1 Error: Trace file error.


OSS
_CA
NT_
OPE
N_T
RAC
E_W
IND
OW
0x8
009
301
8

OSS ASN.1 Error: Function not implemented.


OSS
_UN
IMP
LEM
ENT
ED
0x8
009
301
9

OSS ASN.1 Error: Program link error.


OSS
_OI
D_D
LL_
NO
T_LI
NKE
D
0x8
009
301
A

OSS ASN.1 Error: Trace file error.


OSS
_CA
NT_
OPE
N_T
RAC
E_FI
LE
0x8
009
301
B
CONSTANT/VALUE DESCRIPTION

OSS ASN.1 Error: Trace file error.


OSS
_TR
ACE
_FIL
E_A
LRE
AD
Y_O
PEN
0x8
009
301
C

OSS ASN.1 Error: Invalid data.


OSS
_TA
BLE
_MI
SM
ATC
H
0x8
009
301
D

OSS ASN.1 Error: Invalid data.


OSS
_TY
PE_
NO
T_S
UPP
ORT
ED
0x8
009
301
E

OSS ASN.1 Error: Program link error.


OSS
_RE
AL_
DLL
_NO
T_LI
NKE
D
0x8
009
301
F
CONSTANT/VALUE DESCRIPTION

OSS ASN.1 Error: Program link error.


OSS
_RE
AL_
CO
DE_
NO
T_LI
NKE
D
0x8
009
302
0

OSS ASN.1 Error: Program link error.


OSS
_OU
T_O
F_R
AN
GE
0x8
009
302
1

OSS ASN.1 Error: Program link error.


OSS
_CO
PIE
R_D
LL_
NO
T_LI
NKE
D
0x8
009
302
2

OSS ASN.1 Error: Program link error.


OSS
_CO
NST
RAI
NT_
DLL
_NO
T_LI
NKE
D
0x8
009
302
3
CONSTANT/VALUE DESCRIPTION

OSS ASN.1 Error: Program link error.


OSS
_CO
MP
AR
AT
OR_
DLL
_NO
T_LI
NKE
D
0x8
009
302
4

OSS ASN.1 Error: Program link error.


OSS
_CO
MP
AR
AT
OR_
CO
DE_
NO
T_LI
NKE
D
0x8
009
302
5

OSS ASN.1 Error: Program link error.


OSS
_ME
M_
MG
R_D
LL_
NO
T_LI
NKE
D
0x8
009
302
6
CONSTANT/VALUE DESCRIPTION

OSS ASN.1 Error: Program link error.


OSS
_PD
V_D
LL_
NO
T_LI
NKE
D
0x8
009
302
7

OSS ASN.1 Error: Program link error.


OSS
_PD
V_C
ODE
_NO
T_LI
NKE
D
0x8
009
302
8

OSS ASN.1 Error: Program link error.


OSS
_AP
I_DL
L_N
OT_
LIN
KED
0x8
009
302
9

OSS ASN.1 Error: Program link error.


OSS
_BE
RDE
R_D
LL_
NO
T_LI
NKE
D
0x8
009
302
A
CONSTANT/VALUE DESCRIPTION

OSS ASN.1 Error: Program link error.


OSS
_PE
R_D
LL_
NO
T_LI
NKE
D
0x8
009
302
B

OSS ASN.1 Error: Program link error.


OSS
_OP
EN_
TYP
E_E
RR
OR
0x8
009
302
C

OSS ASN.1 Error: System resource error.


OSS
_M
UTE
X_N
OT_
CRE
ATE
D
0x8
009
302
D

OSS ASN.1 Error: Trace file error.


OSS
_CA
NT_
CLO
SE_
TRA
CE_
FILE
0x8
009
302
E
CONSTANT/VALUE DESCRIPTION

ASN1 Certificate encode/decode error code base. The ASN1


CRY error values are offset by CRYPT_E_ASN1_ERROR.
PT_
E_A
SN1
_ER
RO
R
0x8
009
310
0

ASN1 internal encode or decode error.


CRY
PT_
E_A
SN1
_IN
TER
NAL
0x8
009
310
1

ASN1 unexpected end of data.


CRY
PT_
E_A
SN1
_EO
D
0x8
009
310
2

ASN1 corrupted data.


CRY
PT_
E_A
SN1
_CO
RRU
PT
0x8
009
310
3
CONSTANT/VALUE DESCRIPTION

ASN1 value too large.


CRY
PT_
E_A
SN1
_LA
RGE
0x8
009
310
4

ASN1 constraint violated.


CRY
PT_
E_A
SN1
_CO
NST
RAI
NT
0x8
009
310
5

ASN1 out of memory.


CRY
PT_
E_A
SN1
_ME
MO
RY
0x8
009
310
6

ASN1 buffer overflow.


CRY
PT_
E_A
SN1
_OV
ERF
LO
W
0x8
009
310
7
CONSTANT/VALUE DESCRIPTION

ASN1 function not supported for this PDU.


CRY
PT_
E_A
SN1
_BA
DP
DU
0x8
009
310
8

ASN1 bad arguments to function call.


CRY
PT_
E_A
SN1
_BA
DA
RGS
0x8
009
310
9

ASN1 bad real value.


CRY
PT_
E_A
SN1
_BA
DRE
AL
0x8
009
310
A

ASN1 bad tag value met.


CRY
PT_
E_A
SN1
_BA
DTA
G
0x8
009
310
B
CONSTANT/VALUE DESCRIPTION

ASN1 bad choice value.


CRY
PT_
E_A
SN1
_CH
OIC
E
0x8
009
310
C

ASN1 bad encoding rule.


CRY
PT_
E_A
SN1
_RU
LE
0x8
009
310
D

ASN1 bad unicode (UTF8).


CRY
PT_
E_A
SN1
_UT
F8
0x8
009
310
E

ASN1 bad PDU type.


CRY
PT_
E_A
SN1
_PD
U_T
YPE
0x8
009
313
3
CONSTANT/VALUE DESCRIPTION

ASN1 not yet implemented.


CRY
PT_
E_A
SN1
_NY
I
0x8
009
313
4

ASN1 skipped unknown extension(s).


CRY
PT_
E_A
SN1
_EX
TEN
DED
0x8
009
320
1

ASN1 end of data expected


CRY
PT_
E_A
SN1
_NO
EOD
0x8
009
320
2

The request subject name is invalid or too long.


CER
TSR
V_E_
BA
D_R
EQU
EST
SUB
JEC
T
0x8
009
400
1
CONSTANT/VALUE DESCRIPTION

The request does not exist.


CER
TSR
V_E_
NO_
REQ
UES
T
0x8
009
400
2

The request's current status does not allow this operation.


CER
TSR
V_E_
BA
D_R
EQU
EST
STA
TUS
0x8
009
400
3

The requested property value is empty.


CER
TSR
V_E_
PR
OPE
RTY
_EM
PTY
0x8
009
400
4

The certification authority's certificate contains invalid data.


CER
TSR
V_E_
INV
ALI
D_C
A_C
ERTI
FIC
ATE
0x8
009
400
5
CONSTANT/VALUE DESCRIPTION

Certificate service has been suspended for a database restore


CER operation.
TSR
V_E_
SER
VER
_SU
SPE
NDE
D
0x8
009
400
6

The certificate contains an encoded length that is potentially


CER incompatible with older enrollment software.
TSR
V_E_
ENC
ODI
NG_
LEN
GT
H
0x8
009
400
7

The operation is denied. The user has multiple roles assigned


CER and the certification authority is configured to enforce role
TSR separation.
V_E_
ROL
ECO
NFL
ICT
0x8
009
400
8

The operation is denied. It can only be performed by a


CER certificate manager that is allowed to manage certificates for
TSR the current requester.
V_E_
RES
TRI
CTE
DOF
FICE
R
0x8
009
400
9
CONSTANT/VALUE DESCRIPTION

Cannot archive private key. The certification authority is not


CER configured for key archival.
TSR
V_E_
KEY
_AR
CHI
VAL
_NO
T_C
ON
FIG
URE
D
0x8
009
400
A

Cannot archive private key. The certification authority could


CER not verify one or more key recovery certificates.
TSR
V_E_
NO_
VAL
ID_
KRA
0x8
009
400
B

The request is incorrectly formatted. The encrypted private


CER key must be in an unauthenticated attribute in an outermost
TSR signature.
V_E_
BA
D_R
EQU
EST
_KE
Y_A
RC
HIV
AL
0x8
009
400
C
CONSTANT/VALUE DESCRIPTION

At least one security principal must have the permission to


CER manage this CA.
TSR
V_E_
NO_
CA
AD
MIN
_DE
FIN
ED
0x8
009
400
D

The request contains an invalid renewal certificate attribute.


CER
TSR
V_E_
BA
D_R
ENE
WA
L_C
ERT
_AT
TRI
BUT
E
0x8
009
400
E

An attempt was made to open a Certification Authority


CER database session, but there are already too many active
TSR sessions. The server may need to be configured to allow
V_E_ additional sessions.
NO_
DB_
SES
SIO
NS
0x8
009
400
F
CONSTANT/VALUE DESCRIPTION

A memory reference caused a data alignment fault.


CER
TSR
V_E_
ALI
GN
ME
NT_
FAU
LT
0x8
009
401
0

The permissions on this certification authority do not allow


CER the current user to enroll for certificates.
TSR
V_E_
ENR
OLL
_DE
NIE
D
0x8
009
401
1

The permissions on the certificate template do not allow the


CER current user to enroll for this type of certificate.
TSR
V_E_
TEM
PLA
TE_
DEN
IED
0x8
009
401
2
CONSTANT/VALUE DESCRIPTION

The contacted domain controller cannot support signed LDAP


CER traffic. Update the domain controller or configure Certificate
TSR Services to use SSL for Active Directory access.
V_E_
DO
WN
LEV
EL_
DC_
SSL
_OR
_UP
GR
ADE
0x8
009
401
3

The request was denied by a certificate manager or CA


CER administrator.
TSR
V_E_
AD
MIN
_DE
NIE
D_R
EQU
EST
0x8
009
401
4

An enrollment policy server cannot be located.


CER
TSR
V_E_
NO_
POL
ICY_
SER
VER
0x8
009
401
5
CONSTANT/VALUE DESCRIPTION

The requested certificate template is not supported by this


CER CA.
TSR
V_E_
UN
SUP
PO
RTE
D_C
ERT
_TY
PE
0x8
009
480
0

The request contains no certificate template information.


CER
TSR
V_E_
NO_
CER
T_T
YPE
0x8
009
480
1

The request contains conflicting template information.


CER
TSR
V_E_
TEM
PLA
TE_
CO
NFL
ICT
0x8
009
480
2
CONSTANT/VALUE DESCRIPTION

The request is missing a required Subject Alternate name


CER extension.
TSR
V_E_
SUB
JEC
T_A
LT_
NA
ME_
REQ
UIR
ED
0x8
009
480
3

The request is missing a required private key for archival by


CER the server.
TSR
V_E_
ARC
HIV
ED_
KEY
_RE
QUI
RED
0x8
009
480
4

The request is missing a required SMIME capabilities


CER extension.
TSR
V_E_
SMI
ME_
REQ
UIR
ED
0x8
009
480
5
CONSTANT/VALUE DESCRIPTION

The request was made on behalf of a subject other than the


CER caller. The certificate template must be configured to require at
TSR least one signature to authorize the request.
V_E_
BA
D_R
ENE
WA
L_S
UBJ
ECT
0x8
009
480
6

The request template version is newer than the supported


CER template version.
TSR
V_E_
BA
D_T
EM
PLA
TE_
VER
SIO
N
0x8
009
480
7

The template is missing a required signature policy attribute.


CER
TSR
V_E_
TEM
PLA
TE_
POL
ICY_
REQ
UIR
ED
0x8
009
480
8
CONSTANT/VALUE DESCRIPTION

The request is missing required signature policy information.


CER
TSR
V_E_
SIG
NA
TUR
E_P
OLI
CY_
REQ
UIR
ED
0x8
009
480
9

The request is missing one or more required signatures.


CER
TSR
V_E_
SIG
NA
TUR
E_C
OU
NT
0x8
009
480
A

One or more signatures did not include the required


CER application or issuance policies. The request is missing one or
TSR more required valid signatures.
V_E_
SIG
NA
TUR
E_R
EJE
CTE
D
0x8
009
480
B
CONSTANT/VALUE DESCRIPTION

The request is missing one or more required signature


CER issuance policies.
TSR
V_E_
ISS
UA
NCE
_PO
LIC
Y_R
EQU
IRE
D
0x8
009
480
C

The UPN is unavailable and cannot be added to the Subject


CER Alternate name.
TSR
V_E_
SUB
JEC
T_U
PN_
REQ
UIR
ED
0x8
009
480
D

The Active Directory GUID is unavailable and cannot be added


CER to the Subject Alternate name.
TSR
V_E_
SUB
JEC
T_DI
REC
TOR
Y_G
UID
_RE
QUI
RED
0x8
009
480
E
CONSTANT/VALUE DESCRIPTION

The DNS name is unavailable and cannot be added to the


CER Subject Alternate name.
TSR
V_E_
SUB
JEC
T_D
NS_
REQ
UIR
ED
0x8
009
480
F

The request includes a private key for archival by the server,


CER but key archival is not enabled for the specified certificate
TSR template.
V_E_
ARC
HIV
ED_
KEY
_UN
EXP
ECT
ED
0x8
009
481
0

The public key does not meet the minimum size required by
CER the specified certificate template.
TSR
V_E_
KEY
_LE
NG
TH
0x8
009
481
1
CONSTANT/VALUE DESCRIPTION

The EMail name is unavailable and cannot be added to the


CER Subject or Subject Alternate name.
TSR
V_E_
SUB
JEC
T_E
MAI
L_R
EQU
IRE
D
0x8
009
481
2

One or more certificate templates to be enabled on this


CER certification authority could not be found.
TSR
V_E_
UN
KN
OW
N_C
ERT
_TY
PE
0x8
009
481
3

The certificate template renewal period is longer than the


CER certificate validity period. The template should be reconfigured
TSR or the CA certificate renewed.
V_E_
CER
T_T
YPE
_OV
ERL
AP
0x8
009
481
4
CONSTANT/VALUE DESCRIPTION

The certificate template requires too many RA signatures.


CER Only one RA signature is allowed.
TSR
V_E_
TO
O_
MA
NY_
SIG
NA
TUR
ES
0x8
009
481
5

The certificate template requires renewal with the same public


CER key, but the request uses a different public key.
TSR
V_E_
REN
EW
AL_
BA
D_P
UBL
IC_K
EY
0x8
009
481
6

The key is not exportable.


XEN
ROL
L_E_
KEY
_NO
T_E
XP
ORT
ABL
E
0x8
009
500
0
CONSTANT/VALUE DESCRIPTION

You cannot add the root CA certificate into your local store.
XEN
ROL
L_E_
CA
NN
OT_
AD
D_R
OO
T_C
ERT
0x8
009
500
1

The key archival hash attribute was not found in the response.
XEN
ROL
L_E_
RES
PO
NSE
_KA
_HA
SH_
NO
T_F
OU
ND
0x8
009
500
2

An unexpected key archival hash attribute was found in the


XEN response.
ROL
L_E_
RES
PO
NSE
_UN
EXP
ECT
ED_
KA_
HA
SH
0x8
009
500
3
CONSTANT/VALUE DESCRIPTION

There is a key archival hash mismatch between the request


XEN and the response.
ROL
L_E_
RES
PO
NSE
_KA
_HA
SH_
MIS
MA
TCH
0x8
009
500
4

Signing certificate cannot include SMIME extension.


XEN
ROL
L_E_
KEY
SPE
C_S
MI
ME_
MIS
MA
TCH
0x8
009
500
5

A system-level error occurred while verifying trust.


TRU
ST_
E_S
YST
EM_
ERR
OR
0x8
009
600
1
CONSTANT/VALUE DESCRIPTION

The certificate for the signer of the message is invalid or not


TRU found.
ST_
E_N
O_S
IGN
ER_
CER
T
0x8
009
600
2

One of the counter signatures was invalid.


TRU
ST_
E_C
OU
NTE
R_SI
GNE
R
0x8
009
600
3

The signature of the certificate cannot be verified.


TRU
ST_
E_C
ERT
_SIG
NA
TUR
E
0x8
009
600
4

The timestamp signature and/or certificate could not be


TRU verified or is malformed.
ST_
E_TI
ME_
STA
MP
0x8
009
600
5
CONSTANT/VALUE DESCRIPTION

The digital signature of the object did not verify.


TRU
ST_
E_B
AD_
DIG
EST
0x8
009
601
0

A certificate's basic constraint extension has not been


TRU observed.
ST_
E_B
ASI
C_C
ON
STR
AIN
TS
0x8
009
601
9

The certificate does not meet or contain the Authenticode(tm)


TRU financial extensions.
ST_
E_FI
NA
NCI
AL_
CRI
TERI
A
0x8
009
601
E

Tried to reference a part of the file outside the proper range.


MS
SIP
OTF
_E_
OU
TOF
ME
MR
AN
GE
0x8
009
700
1
CONSTANT/VALUE DESCRIPTION

Could not retrieve an object from the file.


MS
SIP
OTF
_E_C
AN
TGE
TOB
JEC
T
0x8
009
700
2

Could not find the head table in the file.


MS
SIP
OTF
_E_
NO
HEA
DTA
BLE
0x8
009
700
3

The magic number in the head table is incorrect.


MS
SIP
OTF
_E_B
AD_
MA
GIC
NU
MB
ER
0x8
009
700
4
CONSTANT/VALUE DESCRIPTION

The offset table has incorrect values.


MS
SIP
OTF
_E_B
AD_
OFF
SET
_TA
BLE
0x8
009
700
5

Duplicate table tags or tags out of alphabetical order.


MS
SIP
OTF
_E_T
ABL
E_T
AG
OR
DER
0x8
009
700
6

A table does not start on a long word boundary.


MS
SIP
OTF
_E_T
ABL
E_L
ON
GW
OR
D
0x8
009
700
7
CONSTANT/VALUE DESCRIPTION

First table does not appear after header information.


MS
SIP
OTF
_E_B
AD_
FIRS
T_T
ABL
E_P
LAC
EME
NT
0x8
009
700
8

Two or more tables overlap.


MS
SIP
OTF
_E_T
ABL
ES_
OVE
RLA
P
0x8
009
700
9

Too many pad bytes between tables or pad bytes are not 0.
MS
SIP
OTF
_E_T
ABL
E_P
AD
BYT
ES
0x8
009
700
A
CONSTANT/VALUE DESCRIPTION

File is too small to contain the last table.


MS
SIP
OTF
_E_F
ILET
OO
SM
ALL
0x8
009
700
B

A table checksum is incorrect.


MS
SIP
OTF
_E_T
ABL
E_C
HEC
KSU
M
0x8
009
700
C

The file checksum is incorrect.


MS
SIP
OTF
_E_F
ILE_
CHE
CKS
UM
0x8
009
700
D

The signature does not have the correct attributes for the
MS policy.
SIP
OTF
_E_F
AILE
D_P
OLI
CY
0x8
009
701
0
CONSTANT/VALUE DESCRIPTION

The file did not pass the hints check.


MS
SIP
OTF
_E_F
AILE
D_H
INT
S_C
HEC
K
0x8
009
701
1

The file is not an OpenType file.


MS
SIP
OTF
_E_
NO
T_O
PEN
TYP
E
0x8
009
701
2

Failed on a file operation (open, map, read, write).


MS
SIP
OTF
_E_F
ILE
0x8
009
701
3

A call to a CryptoAPI function failed.


MS
SIP
OTF
_E_C
RYP
T
0x8
009
701
4
CONSTANT/VALUE DESCRIPTION

There is a bad version number in the file.


MS
SIP
OTF
_E_B
AD
VER
SIO
N
0x8
009
701
5

The structure of the DSIG table is incorrect.


MS
SIP
OTF
_E_
DSI
G_S
TRU
CTU
RE
0x8
009
701
6

A check failed in a partially constant table.


MS
SIP
OTF
_E_P
CO
NST
_CH
ECK
0x8
009
701
7

Some kind of structural error.


MS
SIP
OTF
_E_S
TRU
CTU
RE
0x8
009
701
8
CONSTANT/VALUE DESCRIPTION

The requested credential requires confirmation.


ERR
OR_
CRE
D_R
EQU
IRES
_CO
NFI
RM
ATI
ON
0x8
009
701
9

Unknown trust provider.


TRU
ST_
E_P
RO
VID
ER_
UN
KN
OW
N
0x8
00B
000
1

The trust verification action specified is not supported by the


TRU specified trust provider.
ST_
E_A
CTI
ON_
UN
KN
OW
N
0x8
00B
000
2
CONSTANT/VALUE DESCRIPTION

The form specified for the subject is not one supported or


TRU known by the specified trust provider.
ST_
E_S
UBJ
ECT
_FO
RM_
UN
KN
OW
N
0x8
00B
000
3

The subject is not trusted for the specified action.


TRU
ST_
E_S
UBJ
ECT
_NO
T_T
RUS
TED
0x8
00B
000
4

Error due to problem in ASN.1 encoding process.


DIG
SIG_
E_E
NC
ODE
0x8
00B
000
5

Error due to problem in ASN.1 decoding process.


DIG
SIG_
E_D
ECO
DE
0x8
00B
000
6
CONSTANT/VALUE DESCRIPTION

Reading / writing Extensions where Attributes are appropriate,


DIG and visa versa.
SIG_
E_E
XTE
NSI
BILI
TY
0x8
00B
000
7

Unspecified cryptographic failure.


DIG
SIG_
E_C
RYP
TO
0x8
00B
000
8

The size of the data could not be determined.


PER
SIST
_E_S
IZE
DEFI
NIT
E
0x8
00B
000
9

The size of the indefinite-sized data could not be determined.


PER
SIST
_E_S
IZEI
NDE
FINI
TE
0x8
00B
000
A
CONSTANT/VALUE DESCRIPTION

This object does not read and write self-sizing data.


PER
SIST
_E_
NO
TSE
LFSI
ZIN
G
0x8
00B
000
B

No signature was present in the subject.


TRU
ST_
E_N
OSI
GN
ATU
RE
0x8
00B
010
0

A required certificate is not within its validity period when


CER verifying against the current system clock or the timestamp in
T_E_ the signed file.
EXP
IRE
D
0x8
00B
010
1

The validity periods of the certification chain do not nest


CER correctly.
T_E_
VAL
IDIT
YPE
RIO
DNE
STI
NG
0x8
00B
010
2
CONSTANT/VALUE DESCRIPTION

A certificate that can only be used as an end-entity is being


CER used as a CA or visa versa.
T_E_
ROL
E
0x8
00B
010
3

A path length constraint in the certification chain has been


CER violated.
T_E_
PAT
HLE
NC
ON
ST
0x8
00B
010
4

A certificate contains an unknown extension that is marked


CER 'critical'.
T_E_
CRI
TIC
AL
0x8
00B
010
5

A certificate being used for a purpose other than the ones


CER specified by its CA.
T_E_
PUR
POS
E
0x8
00B
010
6

A parent of a given certificate in fact did not issue that child


CER certificate.
T_E_
ISS
UER
CH
AIN
ING
0x8
00B
010
7
CONSTANT/VALUE DESCRIPTION

A certificate is missing or has an empty value for an important


CER field, such as a subject or issuer name.
T_E_
MA
LFO
RM
ED
0x8
00B
010
8

A certificate chain processed, but terminated in a root


CER certificate which is not trusted by the trust provider.
T_E_
UN
TRU
STE
DR
OO
T
0x8
00B
010
9

A certificate chain could not be built to a trusted root


CER authority.
T_E_
CH
AIN
ING
0x8
00B
010
A

Generic trust failure.


TRU
ST_
E_F
AIL
0x8
00B
010
B

A certificate was explicitly revoked by its issuer.


CER
T_E_
REV
OKE
D
0x8
00B
010
C
CONSTANT/VALUE DESCRIPTION

The certification path terminates with the test root which is


CER not trusted with the current policy settings.
T_E_
UN
TRU
STE
DTE
STR
OO
T
0x8
00B
010
D

The revocation process could not continue - the certificate(s)


CER could not be checked.
T_E_
REV
OC
ATI
ON_
FAIL
URE
0x8
00B
010
E

The certificate's CN name does not match the passed value.


CER
T_E_
CN_
NO_
MA
TCH
0x8
00B
010
F

The certificate is not valid for the requested usage.


CER
T_E_
WR
ON
G_U
SAG
E
0x8
00B
011
0
CONSTANT/VALUE DESCRIPTION

The certificate was explicitly marked as untrusted by the user.


TRU
ST_
E_E
XPL
ICIT
_DIS
TRU
ST
0x8
00B
011
1

A certification chain processed correctly, but one of the CA


CER certificates is not trusted by the policy provider.
T_E_
UN
TRU
STE
DC
A
0x8
00B
011
2

The certificate has invalid policy.


CER
T_E_
INV
ALI
D_P
OLI
CY
0x8
00B
011
3

The certificate has an invalid name. The name is not included


CER in the permitted list or is explicitly excluded.
T_E_
INV
ALI
D_N
AM
E
0x8
00B
011
4
CONSTANT/VALUE DESCRIPTION

A non-empty line was encountered in the INF before the start


SPA of a section.
PI_E
_EX
PEC
TED
_SE
CTI
ON_
NA
ME
0x8
00F
000
0

A section name marker in the INF is not complete, or does not


SPA exist on a line by itself.
PI_E
_BA
D_S
ECTI
ON_
NA
ME_
LIN
E
0x8
00F
000
1

An INF section was encountered whose name exceeds the


SPA maximum section name length.
PI_E
_SE
CTI
ON_
NA
ME_
TO
O_L
ON
G
0x8
00F
000
2
CONSTANT/VALUE DESCRIPTION

The syntax of the INF is invalid.


SPA
PI_E
_GE
NER
AL_
SYN
TAX
0x8
00F
000
3

The style of the INF is different than what was requested.


SPA
PI_E
_W
RO
NG_
INF_
STY
LE
0x8
00F
010
0

The required section was not found in the INF.


SPA
PI_E
_SE
CTI
ON_
NO
T_F
OU
ND
0x8
00F
010
1

The required line was not found in the INF.


SPA
PI_E
_LIN
E_N
OT_
FOU
ND
0x8
00F
010
2
CONSTANT/VALUE DESCRIPTION

The files affected by the installation of this file queue have not
SPA been backed up for uninstall.
PI_E
_NO
_BA
CKU
P
0x8
00F
010
3

The INF or the device information set or element does not


SPA have an associated install class.
PI_E
_NO
_AS
SOC
IAT
ED_
CLA
SS
0x8
00F
020
0

The INF or the device information set or element does not


SPA match the specified install class.
PI_E
_CL
ASS
_MI
SM
ATC
H
0x8
00F
020
1

An existing device was found that is a duplicate of the device


SPA being manually installed.
PI_E
_DU
PLI
CAT
E_F
OU
ND
0x8
00F
020
2
CONSTANT/VALUE DESCRIPTION

There is no driver selected for the device information set or


SPA element.
PI_E
_NO
_DR
IVE
R_S
ELE
CTE
D
0x8
00F
020
3

The requested device registry key does not exist.


SPA
PI_E
_KE
Y_D
OES
_NO
T_E
XIS
T
0x8
00F
020
4

The device instance name is invalid.


SPA
PI_E
_IN
VAL
ID_
DEV
INS
T_N
AM
E
0x8
00F
020
5

The install class is not present or is invalid.


SPA
PI_E
_IN
VAL
ID_
CLA
SS
0x8
00F
020
6
CONSTANT/VALUE DESCRIPTION

The device instance cannot be created because it already


SPA exists.
PI_E
_DE
VIN
ST_
ALR
EAD
Y_E
XIS
TS
0x8
00F
020
7

The operation cannot be performed on a device information


SPA element that has not been registered.
PI_E
_DE
VIN
FO_
NO
T_R
EGI
STE
RED
0x8
00F
020
8

The device property code is invalid.


SPA
PI_E
_IN
VAL
ID_
REG
_PR
OPE
RTY
0x8
00F
020
9

The INF from which a driver list is to be built does not exist.
SPA
PI_E
_NO
_INF
0x8
00F
020
A
CONSTANT/VALUE DESCRIPTION

The device instance does not exist in the hardware tree.


SPA
PI_E
_NO
_SU
CH_
DEV
INS
T
0x8
00F
020
B

The icon representing this install class cannot be loaded.


SPA
PI_E
_CA
NT_
LOA
D_C
LAS
S_IC
ON
0x8
00F
020
C

The class installer registry entry is invalid.


SPA
PI_E
_IN
VAL
ID_
CLA
SS_I
NST
ALL
ER
0x8
00F
020
D

The class installer has indicated that the default action should
SPA be performed for this installation request.
PI_E
_DI_
DO_
DEF
AUL
T
0x8
00F
020
E
CONSTANT/VALUE DESCRIPTION

The operation does not require any files to be copied.


SPA
PI_E
_DI_
NO
FILE
CO
PY
0x8
00F
020
F

The specified hardware profile does not exist.


SPA
PI_E
_IN
VAL
ID_
HW
PR
OFI
LE
0x8
00F
021
0

There is no device information element currently selected for


SPA this device information set.
PI_E
_NO
_DE
VIC
E_SE
LEC
TED
0x8
00F
021
1

The operation cannot be performed because the device


SPA information set is locked.
PI_E
_DE
VIN
FO_
LIST
_LO
CKE
D
0x8
00F
021
2
CONSTANT/VALUE DESCRIPTION

The operation cannot be performed because the device


SPA information element is locked.
PI_E
_DE
VIN
FO_
DAT
A_L
OC
KED
0x8
00F
021
3

The specified path does not contain any applicable device


SPA INFs.
PI_E
_DI_
BA
D_P
AT
H
0x8
00F
021
4

No class installer parameters have been set for the device


SPA information set or element.
PI_E
_NO
_CL
ASS
INS
TAL
L_P
AR
AM
S
0x8
00F
021
5

The operation cannot be performed because the file queue is


SPA locked.
PI_E
_FIL
EQU
EUE
_LO
CKE
D
0x8
00F
021
6
CONSTANT/VALUE DESCRIPTION

A service installation section in this INF is invalid.


SPA
PI_E
_BA
D_S
ERV
ICE_
INS
TAL
LSE
CT
0x8
00F
021
7

There is no class driver list for the device information element.


SPA
PI_E
_NO
_CL
ASS
_DR
IVE
R_LI
ST
0x8
00F
021
8

The installation failed because a function driver was not


SPA specified for this device instance.
PI_E
_NO
_AS
SOC
IAT
ED_
SER
VIC
E
0x8
00F
021
9
CONSTANT/VALUE DESCRIPTION

There is presently no default device interface designated for


SPA this interface class.
PI_E
_NO
_DE
FAU
LT_
DEV
ICE_
INT
ERF
ACE
0x8
00F
021
A

The operation cannot be performed because the device


SPA interface is currently active.
PI_E
_DE
VIC
E_IN
TER
FAC
E_A
CTI
VE
0x8
00F
021
B

The operation cannot be performed because the device


SPA interface has been removed from the system.
PI_E
_DE
VIC
E_IN
TER
FAC
E_R
EM
OVE
D
0x8
00F
021
C
CONSTANT/VALUE DESCRIPTION

An interface installation section in this INF is invalid.


SPA
PI_E
_BA
D_I
NTE
RFA
CE_I
NST
ALL
SEC
T
0x8
00F
021
D

This interface class does not exist in the system.


SPA
PI_E
_NO
_SU
CH_
INT
ERF
ACE
_CL
ASS
0x8
00F
021
E

The reference string supplied for this interface device is invalid.


SPA
PI_E
_IN
VAL
ID_
REF
ERE
NCE
_ST
RIN
G
0x8
00F
021
F
CONSTANT/VALUE DESCRIPTION

The specified machine name does not conform to UNC


SPA naming conventions.
PI_E
_IN
VAL
ID_
MA
CHI
NE
NA
ME
0x8
00F
022
0

A general remote communication error occurred.


SPA
PI_E
_RE
MO
TE_
CO
MM
_FAI
LUR
E
0x8
00F
022
1

The machine selected for remote communication is not


SPA available at this time.
PI_E
_M
AC
HIN
E_U
NA
VAI
LAB
LE
0x8
00F
022
2
CONSTANT/VALUE DESCRIPTION

The Plug and Play service is not available on the remote


SPA machine.
PI_E
_NO
_CO
NFI
GM
GR_
SER
VIC
ES
0x8
00F
022
3

The property page provider registry entry is invalid.


SPA
PI_E
_IN
VAL
ID_
PR
OP
PA
GE_
PR
OVI
DER
0x8
00F
022
4

The requested device interface is not present in the system.


SPA
PI_E
_NO
_SU
CH_
DEV
ICE_
INT
ERF
ACE
0x8
00F
022
5
CONSTANT/VALUE DESCRIPTION

The device's co-installer has additional work to perform after


SPA installation is complete.
PI_E
_DI_
POS
TPR
OCE
SSI
NG_
REQ
UIR
ED
0x8
00F
022
6

The device's co-installer is invalid.


SPA
PI_E
_IN
VAL
ID_
COI
NST
ALL
ER
0x8
00F
022
7

There are no compatible drivers for this device.


SPA
PI_E
_NO
_CO
MP
AT_
DRI
VER
S
0x8
00F
022
8
CONSTANT/VALUE DESCRIPTION

There is no icon that represents this device or device type.


SPA
PI_E
_NO
_DE
VIC
E_IC
ON
0x8
00F
022
9

A logical configuration specified in this INF is invalid.


SPA
PI_E
_IN
VAL
ID_I
NF_
LOG
CO
NFI
G
0x8
00F
022
A

The class installer has denied the request to install or upgrade


SPA this device.
PI_E
_DI_
DO
NT_
INS
TAL
L
0x8
00F
022
B

One of the filter drivers installed for this device is invalid.


SPA
PI_E
_IN
VAL
ID_F
ILTE
R_D
RIV
ER
0x8
00F
022
C
CONSTANT/VALUE DESCRIPTION

The driver selected for this device does not support this
SPA version of Windows.
PI_E
_NO
N_
WI
ND
OW
S_N
T_D
RIV
ER
0x8
00F
022
D

The driver selected for this device does not support Windows.
SPA
PI_E
_NO
N_
WI
ND
OW
S_D
RIV
ER
0x8
00F
022
E

The third-party INF does not contain digital signature


SPA information.
PI_E
_NO
_CA
TAL
OG_
FOR
_OE
M_I
NF
0x8
00F
022
F
CONSTANT/VALUE DESCRIPTION

An invalid attempt was made to use a device installation file


SPA queue for verification of digital signatures relative to other
PI_E platforms.
_DE
VIN
STA
LL_
QUE
UE_
NO
NN
ATI
VE
0x8
00F
023
0

The device cannot be disabled.


SPA
PI_E
_NO
T_DI
SAB
LEA
BLE
0x8
00F
023
1

The device could not be dynamically removed.


SPA
PI_E
_CA
NT_
RE
MO
VE_
DEV
INS
T
0x8
00F
023
2
CONSTANT/VALUE DESCRIPTION

Cannot copy to specified target.


SPA
PI_E
_IN
VAL
ID_T
AR
GET
0x8
00F
023
3

Driver is not intended for this platform.


SPA
PI_E
_DR
IVE
R_N
ON
NA
TIVE
0x8
00F
023
4

Operation not allowed in WOW64.


SPA
PI_E
_IN_
WO
W6
4
0x8
00F
023
5

The operation involving unsigned file copying was rolled back,


SPA so that a system restore point could be set.
PI_E
_SE
T_S
YST
EM_
RES
TOR
E_P
OIN
T
0x8
00F
023
6
CONSTANT/VALUE DESCRIPTION

An INF was copied into the Windows INF directory in an


SPA improper manner.
PI_E
_IN
CO
RRE
CTL
Y_C
OPI
ED_I
NF
0x8
00F
023
7

The Security Configuration Editor (SCE) APIs have been


SPA disabled on this Embedded product.
PI_E
_SC
E_DI
SAB
LED
0x8
00F
023
8

An unknown exception was encountered.


SPA
PI_E
_UN
KN
OW
N_E
XCE
PTI
ON
0x8
00F
023
9

A problem was encountered when accessing the Plug and Play


SPA registry database.
PI_E
_PN
P_R
EGI
STR
Y_E
RR
OR
0x8
00F
023
A
CONSTANT/VALUE DESCRIPTION

The requested operation is not supported for a remote


SPA machine.
PI_E
_RE
MO
TE_
REQ
UES
T_U
NS
UPP
ORT
ED
0x8
00F
023
B

The specified file is not an installed OEM INF.


SPA
PI_E
_NO
T_A
N_I
NST
ALL
ED_
OE
M_I
NF
0x8
00F
023
C

One or more devices are presently installed using the specified


SPA INF.
PI_E
_INF
_IN_
USE
_BY
_DE
VIC
ES
0x8
00F
023
D
CONSTANT/VALUE DESCRIPTION

The requested device install operation is obsolete.


SPA
PI_E
_DI_
FUN
CTI
ON_
OBS
OLE
TE
0x8
00F
023
E

A file could not be verified because it does not have an


SPA associated catalog signed via Authenticode(tm).
PI_E
_NO
_AU
THE
NTI
CO
DE_
CAT
ALO
G
0x8
00F
023
F

Authenticode(tm) signature verification is not supported for


SPA the specified INF.
PI_E
_AU
THE
NTI
CO
DE_
DIS
ALL
OW
ED
0x8
00F
024
0
CONSTANT/VALUE DESCRIPTION

The INF was signed with an Authenticode(tm) catalog from a


SPA trusted publisher.
PI_E
_AU
THE
NTI
CO
DE_
TRU
STE
D_P
UBL
ISH
ER
0x8
00F
024
1

The publisher of an Authenticode(tm) signed catalog has not


SPA yet been established as trusted.
PI_E
_AU
THE
NTI
CO
DE_
TRU
ST_
NO
T_E
STA
BLIS
HED
0x8
00F
024
2

The publisher of an Authenticode(tm) signed catalog was not


SPA established as trusted.
PI_E
_AU
THE
NTI
CO
DE_
PUB
LIS
HER
_NO
T_T
RUS
TED
0x8
00F
024
3
CONSTANT/VALUE DESCRIPTION

The software was tested for compliance with Windows Logo


SPA requirements on a different version of Windows, and may not
PI_E be compatible with this version.
_SIG
NA
TUR
E_O
SAT
TRI
BUT
E_M
ISM
ATC
H
0x8
00F
024
4

The file may only be validated by a catalog signed via


SPA Authenticode(tm).
PI_E
_ON
LY_
VAL
IDA
TE_
VIA
_AU
THE
NTI
CO
DE
0x8
00F
024
5

One of the installers for this device cannot perform the


SPA installation at this time.
PI_E
_DE
VIC
E_IN
STA
LLE
R_N
OT_
REA
DY
0x8
00F
024
6
CONSTANT/VALUE DESCRIPTION

A problem was encountered while attempting to add the


SPA driver to the store.
PI_E
_DR
IVE
R_S
TOR
E_A
DD_
FAIL
ED
0x8
00F
024
7

The installation of this device is forbidden by system policy.


SPA Contact your system administrator.
PI_E
_DE
VIC
E_IN
STA
LL_
BLO
CKE
D
0x8
00F
024
8

The installation of this driver is forbidden by system policy.


SPA Contact your system administrator.
PI_E
_DR
IVE
R_I
NST
ALL
_BL
OC
KED
0x8
00F
024
9
CONSTANT/VALUE DESCRIPTION

The specified INF is the wrong type for this operation.


SPA
PI_E
_W
RO
NG_
INF_
TYP
E
0x8
00F
024
A

The hash for the file is not present in the specified catalog file.
SPA The file is likely corrupt or the victim of tampering.
PI_E
_FIL
E_H
AS
H_N
OT_
IN_
CAT
ALO
G
0x8
00F
024
B

A problem was encountered while attempting to delete the


SPA driver from the store.
PI_E
_DR
IVE
R_S
TOR
E_D
ELE
TE_F
AILE
D
0x8
00F
024
C
CONSTANT/VALUE DESCRIPTION

An unrecoverable stack overflow was encountered.


SPA
PI_E
_UN
REC
OVE
RAB
LE_S
TAC
K_O
VER
FLO
W
0x8
00F
030
0

No installed components were detected.


SPA
PI_E
_ER
RO
R_N
OT_
INS
TAL
LED
0x8
00F
100
0

An internal consistency check failed.


SCA
RD_
F_IN
TER
NAL
_ER
RO
R
0x8
010
000
1

The action was canceled by an SCardCancel request.


SCA
RD_
E_C
AN
CEL
LED
0x8
010
000
2
CONSTANT/VALUE DESCRIPTION

The supplied handle was invalid.


SCA
RD_
E_IN
VAL
ID_
HA
NDL
E
0x8
010
000
3

One or more of the supplied parameters could not be


SCA properly interpreted.
RD_
E_IN
VAL
ID_
PAR
AM
ETE
R
0x8
010
000
4

Registry startup information is missing or invalid.


SCA
RD_
E_IN
VAL
ID_T
AR
GET
0x8
010
000
5

Not enough memory available to complete this command.


SCA
RD_
E_N
O_
ME
MO
RY
0x8
010
000
6
CONSTANT/VALUE DESCRIPTION

An internal consistency timer has expired.


SCA
RD_
F_W
AIT
ED_
TO
O_L
ON
G
0x8
010
000
7

The data buffer to receive returned data is too small for the
SCA returned data.
RD_
E_IN
SUF
FICI
ENT
_BU
FFE
R
0x8
010
000
8

The specified reader name is not recognized.


SCA
RD_
E_U
NK
NO
WN
_RE
ADE
R
0x8
010
000
9

The user-specified timeout value has expired.


SCA
RD_
E_TI
ME
OU
T
0x8
010
000
A
CONSTANT/VALUE DESCRIPTION

The smart card cannot be accessed because of other


SCA connections outstanding.
RD_
E_S
HA
RIN
G_V
IOL
ATI
ON
0x8
010
000
B

The operation requires a Smart Card, but no Smart Card is


SCA currently in the device.
RD_
E_N
O_S
MA
RTC
AR
D
0x8
010
000
C

The specified smart card name is not recognized.


SCA
RD_
E_U
NK
NO
WN
_CA
RD
0x8
010
000
D

The system could not dispose of the media in the requested


SCA manner.
RD_
E_C
AN
T_DI
SPO
SE
0x8
010
000
E
CONSTANT/VALUE DESCRIPTION

The requested protocols are incompatible with the protocol


SCA currently in use with the smart card.
RD_
E_P
ROT
O_
MIS
MA
TCH
0x8
010
000
F

The reader or smart card is not ready to accept commands.


SCA
RD_
E_N
OT_
REA
DY
0x8
010
001
0

One or more of the supplied parameters values could not be


SCA properly interpreted.
RD_
E_IN
VAL
ID_
VAL
UE
0x8
010
001
1

The action was canceled by the system, presumably to log off


SCA or shut down.
RD_
E_S
YST
EM_
CA
NCE
LLE
D
0x8
010
001
2
CONSTANT/VALUE DESCRIPTION

An internal communications error has been detected.


SCA
RD_
F_C
OM
M_E
RR
OR
0x8
010
001
3

An internal error has been detected, but the source is


SCA unknown.
RD_
F_U
NK
NO
WN
_ER
RO
R
0x8
010
001
4

An ATR obtained from the registry is not a valid ATR string.


SCA
RD_
E_IN
VAL
ID_
ATR
0x8
010
001
5

An attempt was made to end a non-existent transaction.


SCA
RD_
E_N
OT_
TRA
NS
ACT
ED
0x8
010
001
6
CONSTANT/VALUE DESCRIPTION

The specified reader is not currently available for use.


SCA
RD_
E_R
EAD
ER_
UN
AV
AIL
ABL
E
0x8
010
001
7

The operation has been aborted to allow the server


SCA application to exit.
RD_
P_S
HU
TD
OW
N
0x8
010
001
8

The PCI Receive buffer was too small.


SCA
RD_
E_P
CI_T
OO_
SM
ALL
0x8
010
001
9

The reader driver does not meet minimal requirements for


SCA support.
RD_
E_R
EAD
ER_
UN
SUP
PO
RTE
D
0x8
010
001
A
CONSTANT/VALUE DESCRIPTION

The reader driver did not produce a unique reader name.


SCA
RD_
E_D
UPL
ICA
TE_
REA
DER
0x8
010
001
B

The smart card does not meet minimal requirements for


SCA support.
RD_
E_C
AR
D_U
NS
UPP
ORT
ED
0x8
010
001
C

The Smart card resource manager is not running.


SCA
RD_
E_N
O_S
ERV
ICE
0x8
010
001
D

The Smart card resource manager has shut down.


SCA
RD_
E_SE
RVI
CE_
STO
PPE
D
0x8
010
001
E
CONSTANT/VALUE DESCRIPTION

An unexpected card error has occurred.


SCA
RD_
E_U
NEX
PEC
TED
0x8
010
001
F

No Primary Provider can be found for the smart card.


SCA
RD_
E_IC
C_I
NST
ALL
ATI
ON
0x8
010
002
0

The requested order of object creation is not supported.


SCA
RD_
E_IC
C_C
REA
TEO
RDE
R
0x8
010
002
1

This smart card does not support the requested feature.


SCA
RD_
E_U
NS
UPP
ORT
ED_
FEA
TUR
E
0x8
010
002
2
CONSTANT/VALUE DESCRIPTION

The identified directory does not exist in the smart card.


SCA
RD_
E_DI
R_N
OT_
FOU
ND
0x8
010
002
3

The identified file does not exist in the smart card.


SCA
RD_
E_FI
LE_
NO
T_F
OU
ND
0x8
010
002
4

The supplied path does not represent a smart card directory.


SCA
RD_
E_N
O_D
IR
0x8
010
002
5

The supplied path does not represent a smart card file.


SCA
RD_
E_N
O_FI
LE
0x8
010
002
6
CONSTANT/VALUE DESCRIPTION

Access is denied to this file.


SCA
RD_
E_N
O_A
CCE
SS
0x8
010
002
7

The smartcard does not have enough memory to store the


SCA information.
RD_
E_W
RITE
_TO
O_
MA
NY
0x8
010
002
8

There was an error trying to set the smart card file object
SCA pointer.
RD_
E_B
AD_
SEE
K
0x8
010
002
9

The supplied PIN is incorrect.


SCA
RD_
E_IN
VAL
ID_
CH
V
0x8
010
002
A
CONSTANT/VALUE DESCRIPTION

An unrecognized error code was returned from a layered


SCA component.
RD_
E_U
NK
NO
WN
_RE
S_M
NG
0x8
010
002
B

The requested certificate does not exist.


SCA
RD_
E_N
O_S
UC
H_C
ERTI
FIC
ATE
0x8
010
002
C

The requested certificate could not be obtained.


SCA
RD_
E_C
ERTI
FIC
ATE
_UN
AV
AIL
ABL
E
0x8
010
002
D
CONSTANT/VALUE DESCRIPTION

Cannot find a smart card reader.


SCA
RD_
E_N
O_R
EAD
ERS
_AV
AIL
ABL
E
0x8
010
002
E

A communications error with the smart card has been


SCA detected. Retry the operation.
RD_
E_C
OM
M_
DAT
A_L
OST
0x8
010
002
F

The requested key container does not exist on the smart card.
SCA
RD_
E_N
O_K
EY_
CO
NT
AIN
ER
0x8
010
003
0

The Smart card resource manager is too busy to complete this


SCA operation.
RD_
E_SE
RVE
R_T
OO_
BUS
Y
0x8
010
003
1
CONSTANT/VALUE DESCRIPTION

The smart card PIN cache has expired.


SCA
RD_
E_PI
N_C
AC
HE_
EXP
IRE
D
0x8
010
003
2

The smart card PIN cannot be cached.


SCA
RD_
E_N
O_P
IN_
CAC
HE
0x8
010
003
3

The smart card is read only and cannot be written to.


SCA
RD_
E_R
EAD
_ON
LY_
CAR
D
0x8
010
003
4

The reader cannot communicate with the smart card, due to


SCA ATR configuration conflicts.
RD_
W_
UN
SUP
PO
RTE
D_C
AR
D
0x8
010
006
5
CONSTANT/VALUE DESCRIPTION

The smart card is not responding to a reset.


SCA
RD_
W_
UN
RES
PO
NSI
VE_
CAR
D
0x8
010
006
6

Power has been removed from the smart card, so that further
SCA communication is not possible.
RD_
W_
UN
PO
WE
RED
_CA
RD
0x8
010
006
7

The smart card has been reset, so any shared state


SCA information is invalid.
RD_
W_
RES
ET_
CAR
D
0x8
010
006
8

The smart card has been removed, so that further


SCA communication is not possible.
RD_
W_
RE
MO
VED
_CA
RD
0x8
010
006
9
CONSTANT/VALUE DESCRIPTION

Access was denied because of a security violation.


SCA
RD_
W_S
ECU
RIT
Y_VI
OLA
TIO
N
0x8
010
006
A

The card cannot be accessed because the wrong PIN was


SCA presented.
RD_
W_
WR
ON
G_C
HV
0x8
010
006
B

The card cannot be accessed because the maximum number


SCA of PIN entry attempts has been reached.
RD_
W_
CH
V_B
LOC
KED
0x8
010
006
C

The end of the smart card file has been reached.


SCA
RD_
W_E
OF
0x8
010
006
D
CONSTANT/VALUE DESCRIPTION

The action was canceled by the user.


SCA
RD_
W_
CA
NCE
LLE
D_B
Y_U
SER
0x8
010
006
E

No PIN was presented to the smart card.


SCA
RD_
W_
CAR
D_N
OT_
AUT
HE
NTI
CAT
ED
0x8
010
006
F

The requested item could not be found in the cache.


SCA
RD_
W_
CAC
HE_I
TEM
_NO
T_F
OU
ND
0x8
010
007
0
CONSTANT/VALUE DESCRIPTION

The requested cache item is too old and was deleted from the
SCA cache.
RD_
W_
CAC
HE_I
TEM
_ST
ALE
0x8
010
007
1

The new cache item exceeds the maximum per-item size


SCA defined for the cache.
RD_
W_
CAC
HE_I
TEM
_TO
O_B
IG
0x8
010
007
2

Authentication target is invalid or not configured correctly.


ON
L_E_
INV
ALI
D_A
UT
HE
NTI
CAT
ION
_TA
RGE
T
0x8
A02
000
1
CONSTANT/VALUE DESCRIPTION

Your application cannot get the Online Id properties due to


ON the Terms of Use accepted by the user.
L_E_
ACC
ESS
_DE
NIE
D_B
Y_T
OU
0x8
A02
000
2

Requirements

Header
Win
erro
r.h

See also
C
O
M
E
r
r
o
r
C
o
d
e
s
COM Error Codes (COMADMIN, FILTER, GRAPHICS)
1/7/2020 • 25 minutes to read • Edit Online

The following table provides a list of error codes used by COM -based APIs.
If you are experiencing difficulty with an application you are installing or running, contact customer support for the
software that is displaying the error message. To obtain support for a Microsoft product, go to
https://support.microsoft.com.

CONSTANT/VALUE DESCRIPTION

Errors occurred accessing one or more objects - the ErrorInfo


CO collection may have more detail
MA
DMI
N_E
_OB
JEC
TER
RO
RS
0x8
011
040
1

One or more of the object's properties are missing or invalid


CO
MA
DMI
N_E
_OB
JEC
TIN
VAL
ID
0x8
011
040
2

The object was not found in the catalog


CO
MA
DMI
N_E
_KE
YMI
SSI
NG
0x8
011
040
3
CONSTANT/VALUE DESCRIPTION

The object is already registered


CO
MA
DMI
N_E
_AL
REA
DYI
NST
ALL
ED
0x8
011
040
4

Error occurred writing to the application file


CO
MA
DMI
N_E
_AP
P_FI
LE_
WRI
TEF
AIL
0x8
011
040
7

Error occurred reading the application file


CO
MA
DMI
N_E
_AP
P_FI
LE_
REA
DFA
IL
0x8
011
040
8
CONSTANT/VALUE DESCRIPTION

Invalid version number in application file


CO
MA
DMI
N_E
_AP
P_FI
LE_
VER
SIO
N
0x8
011
040
9

The file path is invalid


CO
MA
DMI
N_E
_BA
DP
AT
H
0x8
011
040
A

The application is already installed


CO
MA
DMI
N_E
_AP
PLI
CAT
ION
EXIS
TS
0x8
011
040
B
CONSTANT/VALUE DESCRIPTION

The role already exists


CO
MA
DMI
N_E
_RO
LEE
XIS
TS
0x8
011
040
C

An error occurred copying the file


CO
MA
DMI
N_E
_CA
NTC
OP
YFIL
E
0x8
011
040
D

One or more users are not valid


CO
MA
DMI
N_E
_NO
USE
R
0x8
011
040
F

One or more users in the application file are not valid


CO
MA
DMI
N_E
_IN
VAL
IDU
SERI
DS
0x8
011
041
0
CONSTANT/VALUE DESCRIPTION

The component's CLSID is missing or corrupt


CO
MA
DMI
N_E
_NO
REG
IST
RYC
LSI
D
0x8
011
041
1

The component's progID is missing or corrupt


CO
MA
DMI
N_E
_BA
DRE
GIS
TRY
PR
OGI
D
0x8
011
041
2

Unable to set required authentication level for update request


CO
MA
DMI
N_E
_AU
THE
NTI
CAT
ION
LEV
EL
0x8
011
041
3
CONSTANT/VALUE DESCRIPTION

The identity or password set on the application is not valid


CO
MA
DMI
N_E
_US
ERP
ASS
WD
NO
TVA
LID
0x8
011
041
4

Application file CLSIDs or IIDs do not match corresponding


CO DLLs
MA
DMI
N_E
_CL
SID
ORII
DMI
SM
ATC
H
0x8
011
041
8

Interface information is either missing or changed


CO
MA
DMI
N_E
_RE
MO
TEI
NTE
RFA
CE
0x8
011
041
9
CONSTANT/VALUE DESCRIPTION

DllRegisterServer failed on component install


CO
MA
DMI
N_E
_DL
LRE
GIS
TER
SER
VER
0x8
011
041
A

No server file share available


CO
MA
DMI
N_E
_NO
SER
VER
SH
ARE
0x8
011
041
B

DLL could not be loaded


CO
MA
DMI
N_E
_DL
LLO
ADF
AILE
D
0x8
011
041
D
CONSTANT/VALUE DESCRIPTION

The registered TypeLib ID is not valid


CO
MA
DMI
N_E
_BA
DRE
GIS
TRY
LIBI
D
0x8
011
041
E

Application install directory not found


CO
MA
DMI
N_E
_AP
PDI
RN
OTF
OU
ND
0x8
011
041
F

Errors occurred while in the component registrar


CO
MA
DMI
N_E
_RE
GIS
TRA
RFA
ILED
0x8
011
042
3
CONSTANT/VALUE DESCRIPTION

The file does not exist


CO
MA
DMI
N_E
_CO
MP
FILE
_DO
ESN
OTE
XIS
T
0x8
011
042
4

The DLL could not be loaded


CO
MA
DMI
N_E
_CO
MP
FILE
_LO
AD
DLL
FAIL
0x8
011
042
5

GetClassObject failed in the DLL


CO
MA
DMI
N_E
_CO
MP
FILE
_GE
TCL
ASS
OBJ
0x8
011
042
6
CONSTANT/VALUE DESCRIPTION

The DLL does not support the components listed in the


CO TypeLib
MA
DMI
N_E
_CO
MP
FILE
_CL
ASS
NO
TAV
AIL
0x8
011
042
7

The TypeLib could not be loaded


CO
MA
DMI
N_E
_CO
MP
FILE
_BA
DTL
B
0x8
011
042
8

The file does not contain components or component


CO information
MA
DMI
N_E
_CO
MP
FILE
_NO
TIN
STA
LLA
BLE
0x8
011
042
9
CONSTANT/VALUE DESCRIPTION

Changes to this object and its sub-objects have been disabled


CO
MA
DMI
N_E
_NO
TCH
AN
GEA
BLE
0x8
011
042
A

The delete function has been disabled for this object


CO
MA
DMI
N_E
_NO
TDE
LET
EAB
LE
0x8
011
042
B

The server catalog version is not supported


CO
MA
DMI
N_E
_SE
SSI
ON
0x8
011
042
C

The component move was disallowed, because the source or


CO destination application is either a system application or
MA currently locked against changes
DMI
N_E
_CO
MP_
MO
VE_
LOC
KED
0x8
011
042
D
CONSTANT/VALUE DESCRIPTION

The component move failed because the destination


CO application no longer exists
MA
DMI
N_E
_CO
MP_
MO
VE_
BA
D_D
EST
0x8
011
042
E

The system was unable to register the TypeLib


CO
MA
DMI
N_E
_RE
GIS
TER
TLB
0x8
011
043
0

This operation cannot be performed on the system application


CO
MA
DMI
N_E
_SY
STE
MA
PP
0x8
011
043
3
CONSTANT/VALUE DESCRIPTION

The component registrar referenced in this file is not available


CO
MA
DMI
N_E
_CO
MP
FILE
_NO
REG
IST
RAR
0x8
011
043
4

A component in the same DLL is already installed


CO
MA
DMI
N_E
_CO
REQ
CO
MPI
NST
ALL
ED
0x8
011
043
5

The service is not installed


CO
MA
DMI
N_E
_SE
RVI
CEN
OTI
NST
ALL
ED
0x8
011
043
6
CONSTANT/VALUE DESCRIPTION

One or more property settings are either invalid or in conflict


CO with each other
MA
DMI
N_E
_PR
OPE
RTY
SAV
EFAI
LED
0x8
011
043
7

The object you are attempting to add or rename already exists


CO
MA
DMI
N_E
_OB
JEC
TEXI
STS
0x8
011
043
8

The component already exists


CO
MA
DMI
N_E
_CO
MP
ON
ENT
EXIS
TS
0x8
011
043
9
CONSTANT/VALUE DESCRIPTION

The registration file is corrupt


CO
MA
DMI
N_E
_RE
GFIL
E_C
OR
RUP
T
0x8
011
043
B

The property value is too large


CO
MA
DMI
N_E
_PR
OPE
RTY
_OV
ERF
LO
W
0x8
011
043
C

Object was not found in registry


CO
MA
DMI
N_E
_NO
TIN
REG
IST
RY
0x8
011
043
E
CONSTANT/VALUE DESCRIPTION

This object is not poolable


CO
MA
DMI
N_E
_OB
JEC
TN
OTP
OO
LAB
LE
0x8
011
043
F

A CLSID with the same GUID as the new application ID is


CO already installed on this machine
MA
DMI
N_E
_AP
PLI
D_
MA
TCH
ES_
CLSI
D
0x8
011
044
6

A role assigned to a component, interface, or method did not


CO exist in the application
MA
DMI
N_E
_RO
LE_
DOE
S_N
OT_
EXIS
T
0x8
011
044
7
CONSTANT/VALUE DESCRIPTION

You must have components in an application in order to start


CO the application
MA
DMI
N_E
_ST
ART
_AP
P_N
EED
S_C
OM
PO
NE
NTS
0x8
011
044
8

This operation is not enabled on this platform


CO
MA
DMI
N_E
_RE
QUI
RES
_DIF
FER
ENT
_PL
ATF
OR
M
0x8
011
044
9

Application Proxy is not exportable


CO
MA
DMI
N_E
_CA
N_N
OT_
EXP
ORT
_AP
P_P
RO
XY
0x8
011
044
A
CONSTANT/VALUE DESCRIPTION

Failed to start application because it is either a library


CO application or an application proxy
MA
DMI
N_E
_CA
N_N
OT_
STA
RT_
APP
0x8
011
044
B

System application is not exportable


CO
MA
DMI
N_E
_CA
N_N
OT_
EXP
ORT
_SY
S_A
PP
0x8
011
044
C

Cannot subscribe to this component (the component may


CO have been imported)
MA
DMI
N_E
_CA
NT_
SUB
SCR
IBE_
TO_
CO
MP
ON
ENT
0x8
011
044
D
CONSTANT/VALUE DESCRIPTION

An event class cannot also be a subscriber component


CO
MA
DMI
N_E
_EV
ENT
CLA
SS_
CA
NT_
BE_
SUB
SCR
IBE
R
0x8
011
044
E

Library applications and application proxies are incompatible


CO
MA
DMI
N_E
_LIB
_AP
P_P
RO
XY_I
NC
OM
PAT
IBLE
0x8
011
044
F

This function is valid for the base partition only


CO
MA
DMI
N_E
_BA
SE_
PAR
TITI
ON_
ON
LY
0x8
011
045
0
CONSTANT/VALUE DESCRIPTION

You cannot start an application that has been disabled


CO
MA
DMI
N_E
_ST
ART
_AP
P_D
ISA
BLE
D
0x8
011
045
1

The specified partition name is already in use on this


CO computer
MA
DMI
N_E
_CA
T_D
UPL
ICA
TE_
PAR
TITI
ON_
NA
ME
0x8
011
045
7

The specified partition name is invalid. Check that the name


CO contains at least one visible character
MA
DMI
N_E
_CA
T_I
NV
ALI
D_P
ART
ITIO
N_N
AM
E
0x8
011
045
8
CONSTANT/VALUE DESCRIPTION

The partition cannot be deleted because it is the default


CO partition for one or more users
MA
DMI
N_E
_CA
T_P
ART
ITIO
N_I
N_U
SE
0x8
011
045
9

The partition cannot be exported, because one or more


CO components in the partition have the same file name
MA
DMI
N_E
_FIL
E_P
ART
ITIO
N_D
UPL
ICA
TE_F
ILES
0x8
011
045
A

Applications that contain one or more imported components


CO cannot be installed into a non-base partition
MA
DMI
N_E
_CA
T_I
MP
ORT
ED_
CO
MP
ON
ENT
S_N
OT_
ALL
OW
ED
0x8
011
045
B
CONSTANT/VALUE DESCRIPTION

The application name is not unique and cannot be resolved to


CO an application id
MA
DMI
N_E
_A
MBI
GU
OU
S_A
PPL
ICA
TIO
N_N
AM
E
0x8
011
045
C

The partition name is not unique and cannot be resolved to a


CO partition id
MA
DMI
N_E
_A
MBI
GU
OU
S_P
ART
ITIO
N_N
AM
E
0x8
011
045
D

The COM+ registry database has not been initialized


CO
MA
DMI
N_E
_RE
GD
B_N
OTI
NITI
ALI
ZED
0x8
011
047
2
CONSTANT/VALUE DESCRIPTION

The COM+ registry database is not open


CO
MA
DMI
N_E
_RE
GD
B_N
OT
OPE
N
0x8
011
047
3

The COM+ registry database detected a system error


CO
MA
DMI
N_E
_RE
GD
B_S
YST
EME
RR
0x8
011
047
4

The COM+ registry database is already running


CO
MA
DMI
N_E
_RE
GD
B_A
LRE
AD
YRU
NNI
NG
0x8
011
047
5
CONSTANT/VALUE DESCRIPTION

This version of the COM+ registry database cannot be


CO migrated
MA
DMI
N_E
_MI
G_V
ERSI
ON
NO
TSU
PP
ORT
ED
0x8
011
048
0

The schema version to be migrated could not be found in the


CO COM+ registry database
MA
DMI
N_E
_MI
G_S
CHE
MA
NO
TFO
UN
D
0x8
011
048
1

There was a type mismatch between binaries


CO
MA
DMI
N_E
_CA
T_BI
TNE
SS
MIS
MA
TCH
0x8
011
048
2
CONSTANT/VALUE DESCRIPTION

A binary of unknown or invalid type was provided


CO
MA
DMI
N_E
_CA
T_U
NA
CCE
PTA
BLE
BIT
NES
S
0x8
011
048
3

There was a type mismatch between a binary and an


CO application
MA
DMI
N_E
_CA
T_W
RO
NG
APP
BIT
NES
S
0x8
011
048
4

The application cannot be paused or resumed


CO
MA
DMI
N_E
_CA
T_P
AUS
E_R
ESU
ME_
NO
T_S
UPP
ORT
ED
0x8
011
048
5
CONSTANT/VALUE DESCRIPTION

The COM+ Catalog Server threw an exception during


CO execution
MA
DMI
N_E
_CA
T_S
ERV
ERF
AUL
T
0x8
011
048
6

Only COM+ Applications marked "queued" can be invoked


CO using the "queue" moniker
MQ
C_E_
APP
LIC
ATI
ON_
NO
T_Q
UEU
ED
0x8
011
060
0

At least one interface must be marked "queued" in order to


CO create a queued component instance with the "queue"
MQ moniker
C_E_
NO_
QUE
UEA
BLE
_IN
TER
FAC
ES
0x8
011
060
1
CONSTANT/VALUE DESCRIPTION

MSMQ is required for the requested operation and is not


CO installed
MQ
C_E_
QUE
UIN
G_S
ERV
ICE_
NO
T_A
VAI
LAB
LE
0x8
011
060
2

Unable to marshal an interface that does not support


CO IPersistStream
MQ
C_E_
NO_
IPE
RSI
STS
TRE
AM
0x8
011
060
3

The message is improperly formatted or was damaged in


CO transit
MQ
C_E_
BA
D_
MES
SAG
E
0x8
011
060
4
CONSTANT/VALUE DESCRIPTION

An unauthenticated message was received by an application


CO that accepts only authenticated messages
MQ
C_E_
UN
AUT
HE
NTI
CAT
ED
0x8
011
060
5

The message was requeued or moved by a user not in the


CO "QC Trusted User" role
MQ
C_E_
UN
TRU
STE
D_E
NQ
UEU
ER
0x8
011
060
6

Cannot create a duplicate resource of type Distributed


MS Transaction Coordinator
DTC
_E_
DU
PLI
CAT
E_R
ESO
URC
E
0x8
011
070
1
CONSTANT/VALUE DESCRIPTION

One of the objects being inserted or updated does not belong


CO to a valid parent collection
MA
DMI
N_E
_OB
JEC
T_P
ARE
NT_
MIS
SIN
G
0x8
011
080
8

One of the specified objects cannot be found


CO
MA
DMI
N_E
_OB
JEC
T_D
OES
_NO
T_E
XIS
T
0x8
011
080
9

The specified application is not currently running


CO
MA
DMI
N_E
_AP
P_N
OT_
RU
NNI
NG
0x8
011
080
A
CONSTANT/VALUE DESCRIPTION

The partition(s) specified are not valid.


CO
MA
DMI
N_E
_IN
VAL
ID_
PAR
TITI
ON
0x8
011
080
B

COM+ applications that run as NT service may not be pooled


CO or recycled
MA
DMI
N_E
_SV
CAP
P_N
OT_
PO
OLA
BLE
_OR
_RE
CYC
LAB
LE
0x8
011
080
D

One or more users are already assigned to a local partition


CO set.
MA
DMI
N_E
_US
ER_I
N_S
ET
0x8
011
080
E
CONSTANT/VALUE DESCRIPTION

Library applications may not be recycled.


CO
MA
DMI
N_E
_CA
NTR
ECY
CLE
LIB
RAR
YAP
PS
0x8
011
080
F

Applications running as NT services may not be recycled.


CO
MA
DMI
N_E
_CA
NTR
ECY
CLE
SER
VIC
EAP
PS
0x8
011
081
1

The process has already been recycled.


CO
MA
DMI
N_E
_PR
OCE
SSA
LRE
AD
YRE
CYC
LED
0x8
011
081
2
CONSTANT/VALUE DESCRIPTION

A paused process may not be recycled.


CO
MA
DMI
N_E
_PA
USE
DPR
OCE
SS
MA
YN
OTB
ERE
CYC
LED
0x8
011
081
3

Library applications may not be NT services.


CO
MA
DMI
N_E
_CA
NT
MA
KEI
NP
RO
CSE
RVI
CE
0x8
011
081
4

The ProgID provided to the copy operation is invalid. The


CO ProgID is in use by another registered CLSID.
MA
DMI
N_E
_PR
OGI
DIN
USE
BYC
LSI
D
0x8
011
081
5
CONSTANT/VALUE DESCRIPTION

The partition specified as default is not a member of the


CO partition set.
MA
DMI
N_E
_DE
FAU
LT_
PAR
TITI
ON_
NO
T_I
N_S
ET
0x8
011
081
6

A recycled process may not be paused.


CO
MA
DMI
N_E
_RE
CYC
LED
PR
OCE
SS
MA
YN
OTB
EPA
USE
D
0x8
011
081
7

Access to the specified partition is denied.


CO
MA
DMI
N_E
_PA
RTI
TIO
N_A
CCE
SSD
ENI
ED
0x8
011
081
8
CONSTANT/VALUE DESCRIPTION

Only Application Files (*.MSI files) can be installed into


CO partitions.
MA
DMI
N_E
_PA
RTI
TIO
N_
MSI
_ON
LY
0x8
011
081
9

Applications containing one or more legacy components may


CO not be exported to 1.0 format.
MA
DMI
N_E
_LE
GA
CYC
OM
PS_
NO
T_A
LLO
WE
D_I
N_1
_0_F
OR
MA
T
0x8
011
081
A
CONSTANT/VALUE DESCRIPTION

Legacy components may not exist in non-base partitions.


CO
MA
DMI
N_E
_LE
GA
CYC
OM
PS_
NO
T_A
LLO
WE
D_I
N_N
ON
BAS
E_P
ART
ITIO
NS
0x8
011
081
B

A component cannot be moved (or copied) from the System


CO Application, an application proxy or a non-changeable
MA application
DMI
N_E
_CO
MP_
MO
VE_
SO
URC
E
0x8
011
081
C

A component cannot be moved (or copied) to the System


CO Application, an application proxy or a non-changeable
MA application
DMI
N_E
_CO
MP_
MO
VE_
DES
T
0x8
011
081
D
CONSTANT/VALUE DESCRIPTION

A private component cannot be moved (or copied) to a library


CO application or to the base partition
MA
DMI
N_E
_CO
MP_
MO
VE_
PRI
VAT
E
0x8
011
081
E

The Base Application Partition exists in all partition sets and


CO cannot be removed.
MA
DMI
N_E
_BA
SEP
ART
ITIO
N_R
EQU
IRE
D_I
N_S
ET
0x8
011
081
F

Event Class components cannot be aliased.


CO
MA
DMI
N_E
_CA
NN
OT_
ALI
AS_
EVE
NTC
LAS
S
0x8
011
082
0
CONSTANT/VALUE DESCRIPTION

Access is denied because the component is private.


CO
MA
DMI
N_E
_PRI
VAT
E_A
CCE
SSD
ENI
ED
0x8
011
082
1

The specified SAFER level is invalid.


CO
MA
DMI
N_E
_SA
FERI
NV
ALI
D
0x8
011
082
2

The specified user cannot write to the system registry


CO
MA
DMI
N_E
_RE
GIS
TRY
_AC
CES
SDE
NIE
D
0x8
011
082
3
CONSTANT/VALUE DESCRIPTION

COM+ partitions are currently disabled.


CO
MA
DMI
N_E
_PA
RTI
TIO
NS_
DIS
ABL
ED
0x8
011
082
4

The IO was completed by a filter.


ERR
OR_
FLT_
IO_
CO
MP
LET
E
0x0
01F
000
1

A handler was not defined by the filter for this operation.


ERR
OR_
FLT_
NO_
HA
NDL
ER_
DEFI
NED
0x8
01F
000
1
CONSTANT/VALUE DESCRIPTION

A context is already defined for this object.


ERR
OR_
FLT_
CO
NTE
XT_
ALR
EAD
Y_D
EFI
NED
0x8
01F
000
2

Asynchronous requests are not valid for this operation.


ERR
OR_
FLT_
INV
ALI
D_A
SYN
CH
RO
NO
US_
REQ
UES
T
0x8
01F
000
3

Disallow the Fast IO path for this operation.


ERR
OR_
FLT_
DIS
ALL
OW
_FA
ST_I
O
0x8
01F
000
4
CONSTANT/VALUE DESCRIPTION

An invalid name request was made. The name requested


ERR cannot be retrieved at this time.
OR_
FLT_
INV
ALI
D_N
AM
E_R
EQU
EST
0x8
01F
000
5

Posting this operation to a worker thread for further


ERR processing is not safe at this time because it could lead to a
OR_ system deadlock.
FLT_
NO
T_S
AFE
_TO
_PO
ST_
OPE
RAT
ION
0x8
01F
000
6

The Filter Manager was not initialized when a filter tried to


ERR register. Make sure that the Filter Manager is getting loaded
OR_ as a driver.
FLT_
NO
T_I
NITI
ALI
ZED
0x8
01F
000
7
CONSTANT/VALUE DESCRIPTION

The filter is not ready for attachment to volumes because it


ERR has not finished initializing (FltStartFiltering has not been
OR_ called).
FLT_
FILT
ER_
NO
T_R
EAD
Y
0x8
01F
000
8

The filter must cleanup any operation specific context at this


ERR time because it is being removed from the system before the
OR_ operation is completed by the lower drivers.
FLT_
POS
T_O
PER
ATI
ON_
CLE
AN
UP
0x8
01F
000
9

The Filter Manager had an internal error from which it cannot


ERR recover, therefore the operation has been failed. This is usually
OR_ the result of a filter returning an invalid value from a pre-
FLT_ operation callback.
INT
ERN
AL_
ERR
OR
0x8
01F
000
A
CONSTANT/VALUE DESCRIPTION

The object specified for this action is in the process of being


ERR deleted, therefore the action requested cannot be completed
OR_ at this time.
FLT_
DEL
ETI
NG_
OBJ
ECT
0x8
01F
000
B

Non-paged pool must be used for this type of context.


ERR
OR_
FLT_
MU
ST_
BE_
NO
NP
AGE
D_P
OO
L
0x8
01F
000
C

A duplicate handler definition has been provided for an


ERR operation.
OR_
FLT_
DU
PLI
CAT
E_E
NTR
Y
0x8
01F
000
D
CONSTANT/VALUE DESCRIPTION

The callback data queue has been disabled.


ERR
OR_
FLT_
CBD
Q_D
ISA
BLE
D
0x8
01F
000
E

Do not attach the filter to the volume at this time.


ERR
OR_
FLT_
DO_
NO
T_A
TTA
CH
0x8
01F
000
F

Do not detach the filter from the volume at this time.


ERR
OR_
FLT_
DO_
NO
T_D
ETA
CH
0x8
01F
001
0
CONSTANT/VALUE DESCRIPTION

An instance already exists at this altitude on the volume


ERR specified.
OR_
FLT_
INS
TA
NCE
_AL
TIT
UDE
_CO
LLIS
ION
0x8
01F
001
1

An instance already exists with this name on the volume


ERR specified.
OR_
FLT_
INS
TA
NCE
_NA
ME_
COL
LISI
ON
0x8
01F
001
2

The system could not find the filter specified.


ERR
OR_
FLT_
FILT
ER_
NO
T_F
OU
ND
0x8
01F
001
3
CONSTANT/VALUE DESCRIPTION

The system could not find the volume specified.


ERR
OR_
FLT_
VOL
UM
E_N
OT_
FOU
ND
0x8
01F
001
4

The system could not find the instance specified.


ERR
OR_
FLT_
INS
TA
NCE
_NO
T_F
OU
ND
0x8
01F
001
5

No registered context allocation definition was found for the


ERR given request.
OR_
FLT_
CO
NTE
XT_
ALL
OC
ATI
ON_
NO
T_F
OU
ND
0x8
01F
001
6
CONSTANT/VALUE DESCRIPTION

An invalid parameter was specified during context registration.


ERR
OR_
FLT_
INV
ALI
D_C
ON
TEX
T_R
EGI
STR
ATI
ON
0x8
01F
001
7

The name requested was not found in Filter Manager's name


ERR cache and could not be retrieved from the file system.
OR_
FLT_
NA
ME_
CAC
HE_
MIS
S
0x8
01F
001
8

The requested device object does not exist for the given
ERR volume.
OR_
FLT_
NO_
DEV
ICE_
OBJ
ECT
0x8
01F
001
9
CONSTANT/VALUE DESCRIPTION

The specified volume is already mounted.


ERR
OR_
FLT_
VOL
UM
E_A
LRE
AD
Y_M
OU
NTE
D
0x8
01F
001
A

The specified Transaction Context is already enlisted in a


ERR transaction
OR_
FLT_
ALR
EAD
Y_E
NLI
STE
D
0x8
01F
001
B

The specified context is already attached to another object


ERR
OR_
FLT_
CO
NTE
XT_
ALR
EAD
Y_LI
NKE
D
0x8
01F
001
C
CONSTANT/VALUE DESCRIPTION

No waiter is present for the filter's reply to this message.


ERR
OR_
FLT_
NO_
WAI
TER
_FO
R_R
EPL
Y
0x8
01F
002
0

The filesystem database resource is in use. Registration cannot


ERR complete at this time.
OR_
FLT_
REG
IST
RAT
ION
_BU
SY
0x8
01F
002
3

Display Driver Stopped Responding} The %hs display driver


ERR has stopped working normally. Save your work and reboot the
OR_ system to restore full display functionality. The next time you
HU reboot the machine a dialog will be displayed giving you a
NG_ chance to report this failure to Microsoft.
DIS
PLA
Y_D
RIV
ER_
THR
EAD
0x8
026
000
1
CONSTANT/VALUE DESCRIPTION

Desktop composition is disabled} The operation could not be


DW completed because desktop composition is disabled.
M_E
_CO
MP
OSI
TIO
NDI
SAB
LED
0x8
026
300
1

Some desktop composition APIs are not supported while


DW remoting} The operation is not supported while running in a
M_E remote session.
_RE
MO
TIN
G_N
OT_
SUP
PO
RTE
D
0x8
026
300
2

No DWM redirection surface is available} The DWM was


DW unable to provide a redireciton surface to complete the
M_E DirectX present.
_NO
_RE
DIR
ECTI
ON_
SUR
FAC
E_A
VAI
LAB
LE
0x8
026
300
3
CONSTANT/VALUE DESCRIPTION

DWM is not queuing presents for the specified window} The


DW window specified is not currently using queued presents.
M_E
_NO
T_Q
UEU
ING
_PR
ESE
NTS
0x8
026
300
4

The adapter specified by the LUID is not found} DWM cannot


DW find the adapter specified by the LUID.
M_E
_AD
APT
ER_
NO
T_F
OU
ND
0x8
026
300
5

GDI redirection surface was returned} GDI redirection surface


DW of the top level window was returned.
M_S
_GD
I_RE
DIR
ECTI
ON_
SUR
FAC
E
0x0
026
300
5
CONSTANT/VALUE DESCRIPTION

Redirection surface can not be created. The size of the surface


DW is larger than what is supported on this machine} Redirection
M_E surface can not be created. The size of the surface is larger
_TE than what is supported on this machine.
XTU
RE_
TO
O_L
AR
GE
0x8
026
300
7

Monitor descriptor could not be obtained.


ERR
OR_
MO
NIT
OR_
NO_
DES
CRI
PTO
R
0x8
026
100
1

Format of the obtained monitor descriptor is not supported


ERR by this release.
OR_
MO
NIT
OR_
UN
KN
OW
N_D
ESC
RIP
TOR
_FO
RM
AT
0x8
026
100
2
CONSTANT/VALUE DESCRIPTION

Checksum of the obtained monitor descriptor is invalid.


ERR
OR_
MO
NIT
OR_
INV
ALI
D_D
ESC
RIP
TOR
_CH
ECK
SU
M
0xC
026
100
3

Monitor descriptor contains an invalid standard timing block.


ERR
OR_
MO
NIT
OR_
INV
ALI
D_S
TA
ND
AR
D_TI
MIN
G_B
LOC
K
0xC
026
100
4
CONSTANT/VALUE DESCRIPTION

WMI data block registration failed for one of the


ERR MSMonitorClass WMI subclasses.
OR_
MO
NIT
OR_
WM
I_D
ATA
BLO
CK_
REG
IST
RAT
ION
_FAI
LED
0xC
026
100
5

Provided monitor descriptor block is either corrupted or does


ERR not contain monitor's detailed serial number.
OR_
MO
NIT
OR_
INV
ALI
D_S
ERI
AL_
NU
MB
ER_
MO
ND
SC_
BLO
CK
0xC
026
100
6
CONSTANT/VALUE DESCRIPTION

Provided monitor descriptor block is either corrupted or does


ERR not contain monitor's user friendly name.
OR_
MO
NIT
OR_
INV
ALI
D_U
SER
_FRI
END
LY_
MO
ND
SC_
BLO
CK
0xC
026
100
7

There is no monitor descriptor data at the specified (offset,


ERR size) region.
OR_
MO
NIT
OR_
NO_
MO
RE_
DES
CRI
PTO
R_D
ATA
0xC
026
100
8
CONSTANT/VALUE DESCRIPTION

Monitor descriptor contains an invalid detailed timing block.


ERR
OR_
MO
NIT
OR_
INV
ALI
D_D
ETA
ILED
_TI
MIN
G_B
LOC
K
0xC
026
100
9

Monitor descriptor contains invalid manufacture date.


ERR
OR_
MO
NIT
OR_
INV
ALI
D_
MA
NUF
ACT
URE
_DA
TE
0xC
026
100
A
CONSTANT/VALUE DESCRIPTION

Exclusive mode ownership is needed to create unmanaged


ERR primary allocation.
OR_
GR
AP
HIC
S_N
OT_
EXC
LUS
IVE_
MO
DE_
OW
NER
0xC
026
200
0

The driver needs more DMA buffer space in order to complete


ERR the requested operation.
OR_
GR
AP
HIC
S_I
NS
UFFI
CIE
NT_
DM
A_B
UFF
ER
0xC
026
200
1

Specified display adapter handle is invalid.


ERR
OR_
GR
AP
HIC
S_I
NV
ALI
D_D
ISPL
AY_
AD
APT
ER
0xC
026
200
2
CONSTANT/VALUE DESCRIPTION

Specified display adapter and all of its state has been reset.
ERR
OR_
GR
AP
HIC
S_A
DA
PTE
R_
WA
S_R
ESE
T
0xC
026
200
3

The driver stack doesn't match the expected driver model.


ERR
OR_
GR
AP
HIC
S_I
NV
ALI
D_D
RIV
ER_
MO
DEL
0xC
026
200
4

Present happened but ended up in the changed desktop


ERR
OR_
GR
AP
HIC
S_P
RES
ENT
_M
ODE
_CH
AN
GED
0xC
026
200
5
CONSTANT/VALUE DESCRIPTION

Nothing to present due to desktop occlusion


ERR
OR_
GR
AP
HIC
S_P
RES
ENT
_OC
CLU
DED
0xC
026
200
6

Not able to present due to denial of desktop access


ERR
OR_
GR
AP
HIC
S_P
RES
ENT
_DE
NIE
D
0xC
026
200
7

Not able to present with color convertion


ERR
OR_
GR
AP
HIC
S_C
AN
NO
TCO
LOR
CO
NVE
RT
0xC
026
200
8
CONSTANT/VALUE DESCRIPTION

The kernel driver detected a version mismatch between it and


ERR the user mode driver.
OR_
GR
AP
HIC
S_D
RIV
ER_
MIS
MA
TCH
0xC
026
200
9

Specified buffer is not big enough to contain entire requested


ERR dataset. Partial data populated up to the size of the buffer.
OR_ Caller needs to provide buffer of size as specified in the
GR partially populated buffer's content (interface specific).
AP
HIC
S_P
ART
IAL_
DAT
A_P
OP
ULA
TED
0x4
026
200
A

Present redirection is disabled (desktop windowing


ERR management subsystem is off).
OR_
GR
AP
HIC
S_P
RES
ENT
_RE
DIR
ECTI
ON_
DIS
ABL
ED
0xC
026
200
B
CONSTANT/VALUE DESCRIPTION

Previous exclusive VidPn source owner has released its


ERR ownership
OR_
GR
AP
HIC
S_P
RES
ENT
_UN
OC
CLU
DED
0xC
026
200
C

Window DC is not available for presentation


ERR
OR_
GR
AP
HIC
S_W
IND
OW
DC_
NO
T_A
VAI
LAB
LE
0xC
026
200
D

Not enough video memory available to complete the


ERR operation.
OR_
GR
AP
HIC
S_N
O_V
IDE
O_
ME
MO
RY
0xC
026
210
0
CONSTANT/VALUE DESCRIPTION

Couldn't probe and lock the underlying memory of an


ERR allocation.
OR_
GR
AP
HIC
S_C
AN
T_L
OC
K_M
EM
OR
Y
0xC
026
210
1

The allocation is currently busy.


ERR
OR_
GR
AP
HIC
S_A
LLO
CAT
ION
_BU
SY
0xC
026
210
2

An object being referenced has reach the maximum reference


ERR count already and can't be reference further.
OR_
GR
AP
HIC
S_T
OO_
MA
NY_
REF
ERE
NCE
S
0xC
026
210
3
CONSTANT/VALUE DESCRIPTION

A problem couldn't be solved due to some currently existing


ERR condition. The problem should be tried again later.
OR_
GR
AP
HIC
S_T
RY_
AG
AIN
_LA
TER
0xC
026
210
4

A problem couldn't be solved due to some currently existing


ERR condition. The problem should be tried again immediately.
OR_
GR
AP
HIC
S_T
RY_
AG
AIN
_NO
W
0xC
026
210
5

The allocation is invalid.


ERR
OR_
GR
AP
HIC
S_A
LLO
CAT
ION
_IN
VAL
ID
0xC
026
210
6
CONSTANT/VALUE DESCRIPTION

No more unswizzling aperture are currently available.


ERR
OR_
GR
AP
HIC
S_U
NS
WIZ
ZLI
NG_
APE
RTU
RE_
UN
AV
AIL
ABL
E
0xC
026
210
7

The current allocation can't be unswizzled by an aperture.


ERR
OR_
GR
AP
HIC
S_U
NS
WIZ
ZLI
NG_
APE
RTU
RE_
UN
SUP
PO
RTE
D
0xC
026
210
8
CONSTANT/VALUE DESCRIPTION

The request failed because a pinned allocation can't be evicted.


ERR
OR_
GR
AP
HIC
S_C
AN
T_E
VIC
T_PI
NN
ED_
ALL
OC
ATI
ON
0xC
026
210
9

The allocation can't be used from its current segment location


ERR for the specified operation.
OR_
GR
AP
HIC
S_I
NV
ALI
D_A
LLO
CAT
ION
_US
AGE
0xC
026
211
0
CONSTANT/VALUE DESCRIPTION

A locked allocation can't be used in the current command


ERR buffer.
OR_
GR
AP
HIC
S_C
AN
T_R
END
ER_
LOC
KED
_AL
LOC
ATI
ON
0xC
026
211
1

The allocation being referenced has been closed permanently.


ERR
OR_
GR
AP
HIC
S_A
LLO
CAT
ION
_CL
OSE
D
0xC
026
211
2
CONSTANT/VALUE DESCRIPTION

An invalid allocation instance is being referenced.


ERR
OR_
GR
AP
HIC
S_I
NV
ALI
D_A
LLO
CAT
ION
_IN
STA
NCE
0xC
026
211
3

An invalid allocation handle is being referenced.


ERR
OR_
GR
AP
HIC
S_I
NV
ALI
D_A
LLO
CAT
ION
_HA
NDL
E
0xC
026
211
4
CONSTANT/VALUE DESCRIPTION

The allocation being referenced doesn't belong to the current


ERR device.
OR_
GR
AP
HIC
S_W
RO
NG_
ALL
OC
ATI
ON_
DEV
ICE
0xC
026
211
5

The specified allocation lost its content.


ERR
OR_
GR
AP
HIC
S_A
LLO
CAT
ION
_CO
NTE
NT_
LOS
T
0xC
026
211
6

GPU exception is detected on the given device. The device is


ERR not able to be scheduled.
OR_
GR
AP
HIC
S_G
PU_
EXC
EPTI
ON_
ON_
DEV
ICE
0xC
026
220
0
CONSTANT/VALUE DESCRIPTION

Skip preparation of allocations referenced by the DMA buffer.


ERR
OR_
GR
AP
HIC
S_S
KIP_
ALL
OC
ATI
ON_
PRE
PAR
ATI
ON
0x4
026
220
1

Specified VidPN topology is invalid.


ERR
OR_
GR
AP
HIC
S_I
NV
ALI
D_V
IDP
N_T
OP
OL
OG
Y
0xC
026
230
0
CONSTANT/VALUE DESCRIPTION

Specified VidPN topology is valid but is not supported by this


ERR model of the display adapter.
OR_
GR
AP
HIC
S_VI
DP
N_T
OP
OL
OG
Y_N
OT_
SUP
PO
RTE
D
0xC
026
230
1

Specified VidPN topology is valid but is not supported by the


ERR display adapter at this time, due to current allocation of its
OR_ resources.
GR
AP
HIC
S_VI
DP
N_T
OP
OL
OG
Y_C
URR
ENT
LY_
NO
T_S
UPP
ORT
ED
0xC
026
230
2
CONSTANT/VALUE DESCRIPTION

Specified VidPN handle is invalid.


ERR
OR_
GR
AP
HIC
S_I
NV
ALI
D_V
IDP
N
0xC
026
230
3

Specified video present source is invalid.


ERR
OR_
GR
AP
HIC
S_I
NV
ALI
D_V
IDE
O_P
RES
ENT
_SO
URC
E
0xC
026
230
4
CONSTANT/VALUE DESCRIPTION

Specified video present target is invalid.


ERR
OR_
GR
AP
HIC
S_I
NV
ALI
D_V
IDE
O_P
RES
ENT
_TA
RGE
T
0xC
026
230
5

Specified VidPN modality is not supported (e.g. at least two of


ERR the pinned modes are not cofunctional).
OR_
GR
AP
HIC
S_VI
DP
N_
MO
DAL
ITY_
NO
T_S
UPP
ORT
ED
0xC
026
230
6
CONSTANT/VALUE DESCRIPTION

No mode is pinned on the specified VidPN source/target.


ERR
OR_
GR
AP
HIC
S_M
ODE
_NO
T_PI
NN
ED
0x0
026
230
7

Specified VidPN source mode set is invalid.


ERR
OR_
GR
AP
HIC
S_I
NV
ALI
D_V
IDP
N_S
OU
RCE
MO
DES
ET
0xC
026
230
8
CONSTANT/VALUE DESCRIPTION

Specified VidPN target mode set is invalid.


ERR
OR_
GR
AP
HIC
S_I
NV
ALI
D_V
IDP
N_T
AR
GET
MO
DES
ET
0xC
026
230
9

Specified video signal frequency is invalid.


ERR
OR_
GR
AP
HIC
S_I
NV
ALI
D_F
REQ
UEN
CY
0xC
026
230
A

Specified video signal active region is invalid.


ERR
OR_
GR
AP
HIC
S_I
NV
ALI
D_A
CTI
VE_
REG
ION
0xC
026
230
B
CONSTANT/VALUE DESCRIPTION

Specified video signal total region is invalid.


ERR
OR_
GR
AP
HIC
S_I
NV
ALI
D_T
OT
AL_
REG
ION
0xC
026
230
C

Specified video present source mode is invalid.


ERR
OR_
GR
AP
HIC
S_I
NV
ALI
D_V
IDE
O_P
RES
ENT
_SO
URC
E_M
ODE
0xC
026
231
0
CONSTANT/VALUE DESCRIPTION

Specified video present target mode is invalid.


ERR
OR_
GR
AP
HIC
S_I
NV
ALI
D_V
IDE
O_P
RES
ENT
_TA
RGE
T_M
ODE
0xC
026
231
1

Pinned mode must remain in the set on VidPN's cofunctional


ERR modality enumeration.
OR_
GR
AP
HIC
S_PI
NN
ED_
MO
DE_
MU
ST_
RE
MAI
N_I
N_S
ET
0xC
026
231
2
CONSTANT/VALUE DESCRIPTION

Specified video present path is already in VidPN's topology.


ERR
OR_
GR
AP
HIC
S_P
AT
H_A
LRE
AD
Y_I
N_T
OP
OL
OG
Y
0xC
026
231
3

Specified mode is already in the mode set.


ERR
OR_
GR
AP
HIC
S_M
ODE
_AL
REA
DY_
IN_
MO
DES
ET
0xC
026
231
4
CONSTANT/VALUE DESCRIPTION

Specified video present source set is invalid.


ERR
OR_
GR
AP
HIC
S_I
NV
ALI
D_V
IDE
OP
RES
ENT
SO
URC
ESE
T
0xC
026
231
5

Specified video present target set is invalid.


ERR
OR_
GR
AP
HIC
S_I
NV
ALI
D_V
IDE
OP
RES
ENT
TAR
GET
SET
0xC
026
231
6
CONSTANT/VALUE DESCRIPTION

Specified video present source is already in the video present


ERR source set.
OR_
GR
AP
HIC
S_S
OU
RCE
_AL
REA
DY_
IN_
SET
0xC
026
231
7

Specified video present target is already in the video present


ERR target set.
OR_
GR
AP
HIC
S_T
AR
GET
_AL
REA
DY_
IN_
SET
0xC
026
231
8

Specified VidPN present path is invalid.


ERR
OR_
GR
AP
HIC
S_I
NV
ALI
D_V
IDP
N_P
RES
ENT
_PA
TH
0xC
026
231
9
CONSTANT/VALUE DESCRIPTION

Miniport has no recommendation for augmentation of the


ERR specified VidPN's topology.
OR_
GR
AP
HIC
S_N
O_R
ECO
MM
END
ED_
VID
PN_
TOP
OL
OG
Y
0xC
026
231
A

Specified monitor frequency range set is invalid.


ERR
OR_
GR
AP
HIC
S_I
NV
ALI
D_
MO
NIT
OR_
FRE
QUE
NC
YRA
NGE
SET
0xC
026
231
B
CONSTANT/VALUE DESCRIPTION

Specified monitor frequency range is invalid.


ERR
OR_
GR
AP
HIC
S_I
NV
ALI
D_
MO
NIT
OR_
FRE
QUE
NC
YRA
NGE
0xC
026
231
C

Specified frequency range is not in the specified monitor


ERR frequency range set.
OR_
GR
AP
HIC
S_F
REQ
UEN
CYR
AN
GE_
NO
T_I
N_S
ET
0xC
026
231
D
CONSTANT/VALUE DESCRIPTION

Specified mode set does not specify preference for one of its
ERR modes.
OR_
GR
AP
HIC
S_N
O_P
REF
ERR
ED_
MO
DE
0x0
026
231
E

Specified frequency range is already in the specified monitor


ERR frequency range set.
OR_
GR
AP
HIC
S_F
REQ
UEN
CYR
AN
GE_
ALR
EAD
Y_I
N_S
ET
0xC
026
231
F

Specified mode set is stale. Please reacquire the new mode set.
ERR
OR_
GR
AP
HIC
S_S
TAL
E_M
ODE
SET
0xC
026
232
0
CONSTANT/VALUE DESCRIPTION

Specified monitor source mode set is invalid.


ERR
OR_
GR
AP
HIC
S_I
NV
ALI
D_
MO
NIT
OR_
SO
URC
EM
ODE
SET
0xC
026
232
1

Specified monitor source mode is invalid.


ERR
OR_
GR
AP
HIC
S_I
NV
ALI
D_
MO
NIT
OR_
SO
URC
E_M
ODE
0xC
026
232
2
CONSTANT/VALUE DESCRIPTION

Miniport does not have any recommendation regarding the


ERR request to provide a functional VidPN given the current
OR_ display adapter configuration.
GR
AP
HIC
S_N
O_R
ECO
MM
END
ED_
FUN
CTI
ON
AL_
VID
PN
0xC
026
232
3

ID of the specified mode is already used by another mode in


ERR the set.
OR_
GR
AP
HIC
S_M
ODE
_ID_
MU
ST_
BE_
UNI
QUE
0xC
026
232
4
CONSTANT/VALUE DESCRIPTION

System failed to determine a mode that is supported by both


ERR the display adapter and the monitor connected to it.
OR_
GR
AP
HIC
S_E
MP
TY_
AD
APT
ER_
MO
NIT
OR_
MO
DE_
SUP
PO
RT_I
NTE
RSE
CTI
ON
0xC
026
232
5

Number of video present targets must be greater than or


ERR equal to the number of video present sources.
OR_
GR
AP
HIC
S_VI
DEO
_PR
ESE
NT_
TAR
GET
S_LE
SS_
TH
AN_
SO
URC
ES
0xC
026
232
6
CONSTANT/VALUE DESCRIPTION

Specified present path is not in VidPN's topology.


ERR
OR_
GR
AP
HIC
S_P
AT
H_N
OT_
IN_
TOP
OL
OG
Y
0xC
026
232
7

Display adapter must have at least one video present source.


ERR
OR_
GR
AP
HIC
S_A
DA
PTE
R_M
UST
_HA
VE_
AT_
LEA
ST_
ON
E_S
OU
RCE
0xC
026
232
8
CONSTANT/VALUE DESCRIPTION

Display adapter must have at least one video present target.


ERR
OR_
GR
AP
HIC
S_A
DA
PTE
R_M
UST
_HA
VE_
AT_
LEA
ST_
ON
E_T
AR
GET
0xC
026
232
9

Specified monitor descriptor set is invalid.


ERR
OR_
GR
AP
HIC
S_I
NV
ALI
D_
MO
NIT
OR
DES
CRI
PTO
RSE
T
0xC
026
232
A
CONSTANT/VALUE DESCRIPTION

Specified monitor descriptor is invalid.


ERR
OR_
GR
AP
HIC
S_I
NV
ALI
D_
MO
NIT
OR
DES
CRI
PTO
R
0xC
026
232
B

Specified descriptor is not in the specified monitor descriptor


ERR set.
OR_
GR
AP
HIC
S_M
ONI
TOR
DES
CRI
PTO
R_N
OT_
IN_
SET
0xC
026
232
C
CONSTANT/VALUE DESCRIPTION

Specified descriptor is already in the specified monitor


ERR descriptor set.
OR_
GR
AP
HIC
S_M
ONI
TOR
DES
CRI
PTO
R_A
LRE
AD
Y_I
N_S
ET
0xC
026
232
D

ID of the specified monitor descriptor is already used by


ERR another descriptor in the set.
OR_
GR
AP
HIC
S_M
ONI
TOR
DES
CRI
PTO
R_I
D_
MU
ST_
BE_
UNI
QUE
0xC
026
232
E
CONSTANT/VALUE DESCRIPTION

Specified video present target subset type is invalid.


ERR
OR_
GR
AP
HIC
S_I
NV
ALI
D_V
IDP
N_T
AR
GET
_SU
BSE
T_T
YPE
0xC
026
232
F

Two or more of the specified resources are not related to each


ERR other, as defined by the interface semantics.
OR_
GR
AP
HIC
S_R
ESO
URC
ES_
NO
T_R
ELA
TED
0xC
026
233
0
CONSTANT/VALUE DESCRIPTION

ID of the specified video present source is already used by


ERR another source in the set.
OR_
GR
AP
HIC
S_S
OU
RCE
_ID_
MU
ST_
BE_
UNI
QUE
0xC
026
233
1

ID of the specified video present target is already used by


ERR another target in the set.
OR_
GR
AP
HIC
S_T
AR
GET
_ID_
MU
ST_
BE_
UNI
QUE
0xC
026
233
2

Specified VidPN source cannot be used because there is no


ERR available VidPN target to connect it to.
OR_
GR
AP
HIC
S_N
O_A
VAI
LAB
LE_
VID
PN_
TAR
GET
0xC
026
233
3
CONSTANT/VALUE DESCRIPTION

Newly arrived monitor could not be associated with a display


ERR adapter.
OR_
GR
AP
HIC
S_M
ONI
TOR
_CO
ULD
_NO
T_B
E_A
SSO
CIA
TED
_WI
TH_
AD
APT
ER
0xC
026
233
4

Display adapter in question does not have an associated


ERR VidPN manager.
OR_
GR
AP
HIC
S_N
O_V
IDP
NM
GR
0xC
026
233
5

VidPN manager of the display adapter in question does not


ERR have an active VidPN.
OR_
GR
AP
HIC
S_N
O_A
CTI
VE_
VID
PN
0xC
026
233
6
CONSTANT/VALUE DESCRIPTION

Specified VidPN topology is stale. Please reacquire the new


ERR topology.
OR_
GR
AP
HIC
S_S
TAL
E_VI
DP
N_T
OP
OL
OG
Y
0xC
026
233
7

There is no monitor connected on the specified video present


ERR target.
OR_
GR
AP
HIC
S_M
ONI
TOR
_NO
T_C
ON
NEC
TED
0xC
026
233
8

Specified source is not part of the specified VidPN's topology.


ERR
OR_
GR
AP
HIC
S_S
OU
RCE
_NO
T_I
N_T
OP
OL
OG
Y
0xC
026
233
9
CONSTANT/VALUE DESCRIPTION

Specified primary surface size is invalid.


ERR
OR_
GR
AP
HIC
S_I
NV
ALI
D_P
RIM
ARY
SUR
FAC
E_SI
ZE
0xC
026
233
A

Specified visible region size is invalid.


ERR
OR_
GR
AP
HIC
S_I
NV
ALI
D_V
ISIB
LER
EGI
ON_
SIZE
0xC
026
233
B

Specified stride is invalid.


ERR
OR_
GR
AP
HIC
S_I
NV
ALI
D_S
TRI
DE
0xC
026
233
C
CONSTANT/VALUE DESCRIPTION

Specified pixel format is invalid.


ERR
OR_
GR
AP
HIC
S_I
NV
ALI
D_P
IXEL
FOR
MA
T
0xC
026
233
D

Specified color basis is invalid.


ERR
OR_
GR
AP
HIC
S_I
NV
ALI
D_C
OL
OR
BAS
IS
0xC
026
233
E

Specified pixel value access mode is invalid.


ERR
OR_
GR
AP
HIC
S_I
NV
ALI
D_P
IXEL
VAL
UEA
CCE
SS
MO
DE
0xC
026
233
F
CONSTANT/VALUE DESCRIPTION

Specified target is not part of the specified VidPN's topology.


ERR
OR_
GR
AP
HIC
S_T
AR
GET
_NO
T_I
N_T
OP
OL
OG
Y
0xC
026
234
0

Failed to acquire display mode management interface.


ERR
OR_
GR
AP
HIC
S_N
O_D
ISPL
AY_
MO
DE_
MA
NA
GE
ME
NT_
SUP
PO
RT
0xC
026
234
1
CONSTANT/VALUE DESCRIPTION

Specified VidPN source is already owned by a DMM client and


ERR cannot be used until that client releases it.
OR_
GR
AP
HIC
S_VI
DP
N_S
OU
RCE
_IN_
USE
0xC
026
234
2

Specified VidPN is active and cannot be accessed.


ERR
OR_
GR
AP
HIC
S_C
AN
T_A
CCE
SS_
ACT
IVE_
VID
PN
0xC
026
234
3
CONSTANT/VALUE DESCRIPTION

Specified VidPN present path importance ordinal is invalid.


ERR
OR_
GR
AP
HIC
S_I
NV
ALI
D_P
AT
H_I
MP
ORT
AN
CE_
OR
DIN
AL
0xC
026
234
4

Specified VidPN present path content geometry


ERR transformation is invalid.
OR_
GR
AP
HIC
S_I
NV
ALI
D_P
AT
H_C
ON
TEN
T_G
EO
MET
RY_
TRA
NSF
OR
MA
TIO
N
0xC
026
234
5
CONSTANT/VALUE DESCRIPTION

Specified content geometry transformation is not supported


ERR on the respective VidPN present path.
OR_
GR
AP
HIC
S_P
AT
H_C
ON
TEN
T_G
EO
MET
RY_
TRA
NSF
OR
MA
TIO
N_N
OT_
SUP
PO
RTE
D
0xC
026
234
6

Specified gamma ramp is invalid.


ERR
OR_
GR
AP
HIC
S_I
NV
ALI
D_G
AM
MA
_RA
MP
0xC
026
234
7
CONSTANT/VALUE DESCRIPTION

Specified gamma ramp is not supported on the respective


ERR VidPN present path.
OR_
GR
AP
HIC
S_G
AM
MA
_RA
MP_
NO
T_S
UPP
ORT
ED
0xC
026
234
8

Multi-sampling is not supported on the respective VidPN


ERR present path.
OR_
GR
AP
HIC
S_M
ULT
ISA
MP
LIN
G_N
OT_
SUP
PO
RTE
D
0xC
026
234
9
CONSTANT/VALUE DESCRIPTION

Specified mode is not in the specified mode set.


ERR
OR_
GR
AP
HIC
S_M
ODE
_NO
T_I
N_
MO
DES
ET
0xC
026
234
A

Specified data set (e.g. mode set, frequency range set,


ERR descriptor set, topology, etc.) is empty.
OR_
GR
AP
HIC
S_D
ATA
SET
_IS_
EM
PTY
0x0
026
234
B

Specified data set (e.g. mode set, frequency range set,


ERR descriptor set, topology, etc.) does not contain any more
OR_ elements.
GR
AP
HIC
S_N
O_
MO
RE_
ELE
ME
NTS
_IN_
DAT
ASE
T
0x0
026
234
C
CONSTANT/VALUE DESCRIPTION

Specified VidPN topology recommendation reason is invalid.


ERR
OR_
GR
AP
HIC
S_I
NV
ALI
D_V
IDP
N_T
OP
OL
OG
Y_R
ECO
MM
END
ATI
ON_
REA
SO
N
0xC
026
234
D

Specified VidPN present path content type is invalid.


ERR
OR_
GR
AP
HIC
S_I
NV
ALI
D_P
AT
H_C
ON
TEN
T_T
YPE
0xC
026
234
E
CONSTANT/VALUE DESCRIPTION

Specified VidPN present path copy protection type is invalid.


ERR
OR_
GR
AP
HIC
S_I
NV
ALI
D_C
OP
YPR
OTE
CTI
ON_
TYP
E
0xC
026
234
F

No more than one unassigned mode set can exist at any given
ERR time for a given VidPN source/target.
OR_
GR
AP
HIC
S_U
NA
SSI
GNE
D_
MO
DES
ET_
ALR
EAD
Y_E
XIS
TS
0xC
026
235
0
CONSTANT/VALUE DESCRIPTION

Specified content transformation is not pinned on the


ERR specified VidPN present path.
OR_
GR
AP
HIC
S_P
AT
H_C
ON
TEN
T_G
EO
MET
RY_
TRA
NSF
OR
MA
TIO
N_N
OT_
PIN
NED
0x0
026
235
1

Specified scanline ordering type is invalid.


ERR
OR_
GR
AP
HIC
S_I
NV
ALI
D_S
CA
NLI
NE_
OR
DER
ING
0xC
026
235
2
CONSTANT/VALUE DESCRIPTION

Topology changes are not allowed for the specified VidPN.


ERR
OR_
GR
AP
HIC
S_T
OP
OL
OG
Y_C
HA
NGE
S_N
OT_
ALL
OW
ED
0xC
026
235
3

All available importance ordinals are already used in specified


ERR topology.
OR_
GR
AP
HIC
S_N
O_A
VAI
LAB
LE_I
MP
ORT
AN
CE_
OR
DIN
ALS
0xC
026
235
4
CONSTANT/VALUE DESCRIPTION

Specified primary surface has a different private format


ERR attribute than the current primary surface
OR_
GR
AP
HIC
S_I
NC
OM
PAT
IBLE
_PRI
VAT
E_F
OR
MA
T
0xC
026
235
5

Specified mode pruning algorithm is invalid


ERR
OR_
GR
AP
HIC
S_I
NV
ALI
D_
MO
DE_
PRU
NIN
G_A
LGO
RIT
HM
0xC
026
235
6
CONSTANT/VALUE DESCRIPTION

Specified monitor capability origin is invalid.


ERR
OR_
GR
AP
HIC
S_I
NV
ALI
D_
MO
NIT
OR_
CAP
ABI
LITY
_OR
IGI
N
0xC
026
235
7

Specified monitor frequency range constraint is invalid.


ERR
OR_
GR
AP
HIC
S_I
NV
ALI
D_
MO
NIT
OR_
FRE
QUE
NC
YRA
NGE
_CO
NST
RAI
NT
0xC
026
235
8
CONSTANT/VALUE DESCRIPTION

Maximum supported number of present paths has been


ERR reached.
OR_
GR
AP
HIC
S_M
AX_
NU
M_P
AT
HS_
REA
CHE
D
0xC
026
235
9

Miniport requested that augmentation be canceled for the


ERR specified source of the specified VidPN's topology.
OR_
GR
AP
HIC
S_C
AN
CEL
_VI
DP
N_T
OP
OL
OG
Y_A
UG
ME
NT
ATI
ON
0xC
026
235
A
CONSTANT/VALUE DESCRIPTION

Specified client type was not recognized.


ERR
OR_
GR
AP
HIC
S_I
NV
ALI
D_C
LIE
NT_
TYP
E
0xC
026
235
B

Client VidPN is not set on this adapter (e.g. no user mode


ERR initiated mode changes took place on this adapter yet).
OR_
GR
AP
HIC
S_C
LIE
NTV
IDP
N_N
OT_
SET
0xC
026
235
C

Specified display adapter child device already has an external


ERR device connected to it.
OR_
GR
AP
HIC
S_S
PEC
IFIE
D_C
HIL
D_A
LRE
AD
Y_C
ON
NEC
TED
0xC
026
240
0
CONSTANT/VALUE DESCRIPTION

Specified display adapter child device does not support


ERR descriptor exposure.
OR_
GR
AP
HIC
S_C
HIL
D_D
ESC
RIP
TOR
_NO
T_S
UPP
ORT
ED
0xC
026
240
1

Child device presence was not reliably detected.


ERR
OR_
GR
AP
HIC
S_U
NK
NO
WN
_CH
ILD_
STA
TUS
0x4
026
242
F

The display adapter is not linked to any other adapters.


ERR
OR_
GR
AP
HIC
S_N
OT_
A_LI
NKE
D_A
DA
PTE
R
0xC
026
243
0
CONSTANT/VALUE DESCRIPTION

Lead adapter in a linked configuration was not enumerated


ERR yet.
OR_
GR
AP
HIC
S_LE
ADL
INK
_NO
T_E
NU
ME
RAT
ED
0xC
026
243
1

Some chain adapters in a linked configuration were not


ERR enumerated yet.
OR_
GR
AP
HIC
S_C
HAI
NLI
NKS
_NO
T_E
NU
ME
RAT
ED
0xC
026
243
2
CONSTANT/VALUE DESCRIPTION

The chain of linked adapters is not ready to start because of


ERR an unknown failure.
OR_
GR
AP
HIC
S_A
DA
PTE
R_C
HAI
N_N
OT_
REA
DY
0xC
026
243
3

An attempt was made to start a lead link display adapter


ERR when the chain links were not started yet.
OR_
GR
AP
HIC
S_C
HAI
NLI
NKS
_NO
T_S
TAR
TED
0xC
026
243
4

An attempt was made to power up a lead link display adapter


ERR when the chain links were powered down.
OR_
GR
AP
HIC
S_C
HAI
NLI
NKS
_NO
T_P
OW
ERE
D_O
N
0xC
026
243
5
CONSTANT/VALUE DESCRIPTION

The adapter link was found to be in an inconsistent state. Not


ERR all adapters are in an expected PNP/Power state.
OR_
GR
AP
HIC
S_I
NC
ON
SIST
ENT
_DE
VIC
E_LI
NK_
STA
TE
0xC
026
243
6

Starting the leadlink adapter has been deferred temporarily.


ERR
OR_
GR
AP
HIC
S_LE
ADL
INK
_ST
ART
_DE
FER
RED
0x4
026
243
7

The driver trying to start is not the same as the driver for the
ERR POSTed display adapter.
OR_
GR
AP
HIC
S_N
OT_
POS
T_D
EVI
CE_
DRI
VER
0xC
026
243
8
CONSTANT/VALUE DESCRIPTION

The display adapter is being polled for children too frequently


ERR at the same polling level.
OR_
GR
AP
HIC
S_P
OLL
ING
_TO
O_F
REQ
UEN
TLY
0x4
026
243
9

Starting the adapter has been deferred temporarily.


ERR
OR_
GR
AP
HIC
S_S
TAR
T_D
EFE
RRE
D
0x4
026
243
A

An operation is being attempted that requires the display


ERR adapter to be in a quiescent state.
OR_
GR
AP
HIC
S_A
DA
PTE
R_A
CCE
SS_
NO
T_E
XCL
UDE
D
0xC
026
243
B
CONSTANT/VALUE DESCRIPTION

The driver does not support OPM.


ERR
OR_
GR
AP
HIC
S_O
PM_
NO
T_S
UPP
ORT
ED
0xC
026
250
0

The driver does not support COPP.


ERR
OR_
GR
AP
HIC
S_C
OP
P_N
OT_
SUP
PO
RTE
D
0xC
026
250
1

The driver does not support UAB.


ERR
OR_
GR
AP
HIC
S_U
AB_
NO
T_S
UPP
ORT
ED
0xC
026
250
2
CONSTANT/VALUE DESCRIPTION

The specified encrypted parameters are invalid.


ERR
OR_
GR
AP
HIC
S_O
PM_
INV
ALI
D_E
NC
RYP
TED
_PA
RA
MET
ERS
0xC
026
250
3

The GDI display device passed to this function does not have
ERR any active video outputs.
OR_
GR
AP
HIC
S_O
PM_
NO_
VID
EO_
OU
TPU
TS_
EXIS
T
0xC
026
250
5
CONSTANT/VALUE DESCRIPTION

An internal error caused this operation to fail.


ERR
OR_
GR
AP
HIC
S_O
PM_
INT
ERN
AL_
ERR
OR
0xC
026
250
B

The function failed because the caller passed in an invalid


ERR OPM user mode handle.
OR_
GR
AP
HIC
S_O
PM_
INV
ALI
D_H
AN
DLE
0xC
026
250
C

A certificate could not be returned because the certificate


ERR buffer passed to the function was too small.
OR_
GR
AP
HIC
S_P
VP_I
NV
ALI
D_C
ERTI
FIC
ATE
_LE
NG
TH
0xC
026
250
E
CONSTANT/VALUE DESCRIPTION

A video output could not be created because the frame buffer


ERR is in spanning mode.
OR_
GR
AP
HIC
S_O
PM_
SPA
NNI
NG_
MO
DE_
ENA
BLE
D
0xC
026
250
F

A video output could not be created because the frame buffer


ERR is in theater mode.
OR_
GR
AP
HIC
S_O
PM_
THE
ATE
R_M
ODE
_EN
ABL
ED
0xC
026
251
0

The function failed because the display adapter's Hardware


ERR Functionality Scan failed to validate the graphics hardware.
OR_
GR
AP
HIC
S_P
VP_
HFS
_FAI
LED
0xC
026
251
1
CONSTANT/VALUE DESCRIPTION

The HDCP System Renewability Message passed to this


ERR function did not comply with section 5 of the HDCP 1.1
OR_ specification.
GR
AP
HIC
S_O
PM_
INV
ALI
D_S
RM
0xC
026
251
2

The video output cannot enable the High-bandwidth Digital


ERR Content Protection (HDCP) System because it does not
OR_ support HDCP.
GR
AP
HIC
S_O
PM_
OU
TPU
T_D
OES
_NO
T_S
UPP
ORT
_HD
CP
0xC
026
251
3
CONSTANT/VALUE DESCRIPTION

The video output cannot enable Analog Copy Protection


ERR (ACP) because it does not support ACP.
OR_
GR
AP
HIC
S_O
PM_
OU
TPU
T_D
OES
_NO
T_S
UPP
ORT
_AC
P
0xC
026
251
4

The video output cannot enable the Content Generation


ERR Management System Analog (CGMS-A) protection technology
OR_ because it does not support CGMS-A.
GR
AP
HIC
S_O
PM_
OU
TPU
T_D
OES
_NO
T_S
UPP
ORT
_CG
MS
A
0xC
026
251
5
CONSTANT/VALUE DESCRIPTION

The IOPMVideoOutput::GetInformation method cannot return


ERR the version of the SRM being used because the application
OR_ never successfully passed an SRM to the video output.
GR
AP
HIC
S_O
PM_
HD
CP_
SR
M_
NEV
ER_
SET
0xC
026
251
6

The IOPMVideoOutput::Configure method cannot enable the


ERR specified output protection technology because the output's
OR_ screen resolution is too high.
GR
AP
HIC
S_O
PM_
RES
OLU
TIO
N_T
OO_
HIG
H
0xC
026
251
7
CONSTANT/VALUE DESCRIPTION

The IOPMVideoOutput::Configure method cannot enable


ERR HDCP because the display adapter's HDCP hardware is already
OR_ being used by other physical outputs.
GR
AP
HIC
S_O
PM_
ALL
_HD
CP_
HA
RD
WA
RE_
ALR
EAD
Y_I
N_U
SE
0xC
026
251
8

The operating system asynchronously destroyed this OPM


ERR video output because the operating system's state changed.
OR_ This error typically occurs because the monitor PDO
GR associated with this video output was removed, the monitor
AP PDO associated with this video output was stopped, the video
HIC output's session became a non-console session or the video
S_O output's desktop became an inactive desktop.
PM_
VID
EO_
OU
TPU
T_N
O_L
ON
GER
_EXI
STS
0xC
026
251
A
CONSTANT/VALUE DESCRIPTION

The method failed because the session is changing its type. No


ERR IOPMVideoOutput methods can be called when a session is
OR_ changing its type. There are currently three types of sessions:
GR console, disconnected and remote.
AP
HIC
S_O
PM_
SES
SIO
N_T
YPE
_CH
AN
GE_I
N_P
RO
GRE
SS
0xC
026
251
B

Either the
ERR IOPMVideoOutput::COPPCompatibleGetInformation,
OR_ IOPMVideoOutput::GetInformation, or
GR IOPMVideoOutput::Configure method failed. This error is
AP returned when the caller tries to use a COPP specific
HIC command while the video output has OPM semantics only.
S_O
PM_
VID
EO_
OU
TPU
T_D
OES
_NO
T_H
AVE
_CO
PP_
SEM
AN
TIC
S
0xC
026
251
C
CONSTANT/VALUE DESCRIPTION

The IOPMVideoOutput::GetInformation and


ERR IOPMVideoOutput::COPPCompatibleGetInformation methods
OR_ return this error if the passed in sequence number is not the
GR expected sequence number or the passed in OMAC value is
AP invalid.
HIC
S_O
PM_
INV
ALI
D_I
NF
OR
MA
TIO
N_R
EQU
EST
0xC
026
251
D

The method failed because an unexpected error occurred


ERR inside of a display driver.
OR_
GR
AP
HIC
S_O
PM_
DRI
VER
_IN
TER
NAL
_ER
RO
R
0xC
026
251
E
CONSTANT/VALUE DESCRIPTION

Either the
ERR IOPMVideoOutput::COPPCompatibleGetInformation,
OR_ IOPMVideoOutput::GetInformation, or
GR IOPMVideoOutput::Configure method failed. This error is
AP returned when the caller tries to use an OPM specific
HIC command while the video output has COPP semantics only.
S_O
PM_
VID
EO_
OU
TPU
T_D
OES
_NO
T_H
AVE
_OP
M_S
EM
AN
TIC
S
0xC
026
251
F

The IOPMVideoOutput::COPPCompatibleGetInformation or
ERR IOPMVideoOutput::Configure method failed because the
OR_ display driver does not support the
GR OPM_GET_ACP_AND_CGMSA_SIGNALING and
AP OPM_SET_ACP_AND_CGMSA_SIGNALING GUIDs.
HIC
S_O
PM_
SIG
NAL
ING
_NO
T_S
UPP
ORT
ED
0xC
026
252
0
CONSTANT/VALUE DESCRIPTION

The IOPMVideoOutput::Configure function returns this error


ERR code if the passed in sequence number is not the expected
OR_ sequence number or the passed in OMAC value is invalid.
GR
AP
HIC
S_O
PM_
INV
ALI
D_C
ON
FIG
UR
ATI
ON_
REQ
UES
T
0xC
026
252
1

The monitor connected to the specified video output does not


ERR have an I2C bus.
OR_
GR
AP
HIC
S_I2
C_N
OT_
SUP
PO
RTE
D
0xC
026
258
0
CONSTANT/VALUE DESCRIPTION

No device on the I2C bus has the specified address.


ERR
OR_
GR
AP
HIC
S_I2
C_D
EVI
CE_
DOE
S_N
OT_
EXIS
T
0xC
026
258
1

An error occurred while transmitting data to the device on the


ERR I2C bus.
OR_
GR
AP
HIC
S_I2
C_E
RR
OR_
TRA
NS
MIT
TIN
G_D
ATA
0xC
026
258
2
CONSTANT/VALUE DESCRIPTION

An error occurred while receiving data from the device on the


ERR I2C bus.
OR_
GR
AP
HIC
S_I2
C_E
RR
OR_
REC
EIVI
NG_
DAT
A
0xC
026
258
3

The monitor does not support the specified VCP code.


ERR
OR_
GR
AP
HIC
S_D
DCC
I_VC
P_N
OT_
SUP
PO
RTE
D
0xC
026
258
4

The data received from the monitor is invalid.


ERR
OR_
GR
AP
HIC
S_D
DCC
I_IN
VAL
ID_
DAT
A
0xC
026
258
5
CONSTANT/VALUE DESCRIPTION

The function failed because a monitor returned an invalid


ERR Timing Status byte when the operating system used the
OR_ DDC/CI Get Timing Report & Timing Message command to
GR get a timing report from a monitor.
AP
HIC
S_D
DCC
I_M
ONI
TOR
_RE
TUR
NED
_IN
VAL
ID_T
IMI
NG_
STA
TUS
_BY
TE
0xC
026
258
6

The monitor returned a DDC/CI capabilities string which did


ERR not comply with the ACCESS.bus 3.0, DDC/CI 1.1, or MCCS 2
OR_ Revision 1 specification.
GR
AP
HIC
S_M
CA_
INV
ALI
D_C
AP
ABI
LITI
ES_
STR
ING
0xC
026
258
7
CONSTANT/VALUE DESCRIPTION

An internal Monitor Configuration API error occurred.


ERR
OR_
GR
AP
HIC
S_M
CA_
INT
ERN
AL_
ERR
OR
0xC
026
258
8

An operation failed because a DDC/CI message had an invalid


ERR value in its command field.
OR_
GR
AP
HIC
S_D
DCC
I_IN
VAL
ID_
MES
SAG
E_C
OM
MA
ND
0xC
026
258
9
CONSTANT/VALUE DESCRIPTION

An error occurred because the field length of a DDC/CI


ERR message contained an invalid value.
OR_
GR
AP
HIC
S_D
DCC
I_IN
VAL
ID_
MES
SAG
E_LE
NG
TH
0xC
026
258
A

An error occurred because the checksum field in a DDC/CI


ERR message did not match the message's computed checksum
OR_ value. This error implies that the data was corrupted while it
GR was being transmitted from a monitor to a computer.
AP
HIC
S_D
DCC
I_IN
VAL
ID_
MES
SAG
E_C
HEC
KSU
M
0xC
026
258
B
CONSTANT/VALUE DESCRIPTION

This function failed because an invalid monitor handle was


ERR passed to it.
OR_
GR
AP
HIC
S_I
NV
ALI
D_P
HYS
ICA
L_M
ONI
TOR
_HA
NDL
E
0xC
026
258
C

The operating system asynchronously destroyed the monitor


ERR which corresponds to this handle because the operating
OR_ system's state changed. This error typically occurs because the
GR monitor PDO associated with this handle was removed, the
AP monitor PDO associated with this handle was stopped, or a
HIC display mode change occurred. A display mode change occurs
S_M when windows sends a WM_DISPLAYCHANGE windows
ONI message to applications.
TOR
_NO
_LO
NGE
R_E
XIS
TS
0xC
026
258
D
CONSTANT/VALUE DESCRIPTION

A continuous VCP code's current value is greater than its


ERR maximum value. This error code indicates that a monitor
OR_ returned an invalid value.
GR
AP
HIC
S_D
DCC
I_C
URR
ENT
_CU
RRE
NT_
VAL
UE_
GRE
ATE
R_T
HA
N_
MA
XIM
UM
_VA
LUE
0xC
026
25D
8

The monitor's VCP Version (0xDF) VCP code returned an


ERR invalid version value.
OR_
GR
AP
HIC
S_M
CA_
INV
ALI
D_V
CP_
VER
SIO
N
0xC
026
25D
9
CONSTANT/VALUE DESCRIPTION

The monitor does not comply with the MCCS specification it


ERR claims to support.
OR_
GR
AP
HIC
S_M
CA_
MO
NIT
OR_
VIO
LAT
ES_
MC
CS_
SPE
CIFI
CAT
ION
0xC
026
25D
A

The MCCS version in a monitor's mccs_ver capability does not


ERR match the MCCS version the monitor reports when the VCP
OR_ Version (0xDF) VCP code is used.
GR
AP
HIC
S_M
CA_
MC
CS_
VER
SIO
N_
MIS
MA
TCH
0xC
026
25D
B
CONSTANT/VALUE DESCRIPTION

The Monitor Configuration API only works with monitors


ERR which support the MCCS 1.0 specification, MCCS 2.0
OR_ specification or the MCCS 2.0 Revision 1 specification.
GR
AP
HIC
S_M
CA_
UN
SUP
PO
RTE
D_
MC
CS_
VER
SIO
N
0xC
026
25D
C

The monitor returned an invalid monitor technology type.


ERR CRT, Plasma and LCD (TFT) are examples of monitor
OR_ technology types. This error implies that the monitor violated
GR the MCCS 2.0 or MCCS 2.0 Revision 1 specification.
AP
HIC
S_M
CA_
INV
ALI
D_T
ECH
NO
LOG
Y_T
YPE
_RE
TUR
NED
0xC
026
25D
E
CONSTANT/VALUE DESCRIPTION

SetMonitorColorTemperature()'s caller passed a color


ERR temperature to it which the current monitor did not support.
OR_ This error implies that the monitor violated the MCCS 2.0 or
GR MCCS 2.0 Revision 1 specification.
AP
HIC
S_M
CA_
UN
SUP
PO
RTE
D_C
OL
OR_
TEM
PER
ATU
RE
0xC
026
25D
F

This function can only be used if a program is running in the


ERR local console session. It cannot be used if the program is
OR_ running on a remote desktop session or on a terminal server
GR session.
AP
HIC
S_O
NLY
_CO
NS
OLE
_SE
SSI
ON_
SUP
PO
RTE
D
0xC
026
25E
0
CONSTANT/VALUE DESCRIPTION

This function cannot find an actual GDI display device which


ERR corresponds to the specified GDI display device name.
OR_
GR
AP
HIC
S_N
O_D
ISPL
AY_
DEV
ICE_
CO
RRE
SPO
ND
S_T
O_N
AM
E
0xC
026
25E
1

The function failed because the specified GDI display device


ERR was not attached to the Windows desktop.
OR_
GR
AP
HIC
S_DI
SPL
AY_
DEV
ICE_
NO
T_A
TTA
CHE
D_T
O_D
ESK
TOP
0xC
026
25E
2
CONSTANT/VALUE DESCRIPTION

This function does not support GDI mirroring display devices


ERR because GDI mirroring display devices do not have any
OR_ physical monitors associated with them.
GR
AP
HIC
S_M
IRR
ORI
NG_
DEV
ICES
_NO
T_S
UPP
ORT
ED
0xC
026
25E
3

The function failed because an invalid pointer parameter was


ERR passed to it. A pointer parameter is invalid if it is NULL, points
OR_ to an invalid address, points to a kernel mode address, or is
GR not correctly aligned.
AP
HIC
S_I
NV
ALI
D_P
OIN
TER
0xC
026
25E
4
CONSTANT/VALUE DESCRIPTION

The function failed because the specified GDI device did not
ERR have any monitors associated with it.
OR_
GR
AP
HIC
S_N
O_
MO
NIT
ORS
_CO
RRE
SPO
ND_
TO_
DIS
PLA
Y_D
EVI
CE
0xC
026
25E
5

An array passed to the function cannot hold all of the data


ERR that the function must copy into the array.
OR_
GR
AP
HIC
S_P
AR
AM
ETE
R_A
RRA
Y_T
OO_
SM
ALL
0xC
026
25E
6
CONSTANT/VALUE DESCRIPTION

An internal error caused an operation to fail.


ERR
OR_
GR
AP
HIC
S_I
NTE
RN
AL_
ERR
OR
0xC
026
25E
7

The function failed because the current session is changing its


ERR type. This function cannot be called when the current session
OR_ is changing its type. There are currently three types of
GR sessions: console, disconnected and remote.
AP
HIC
S_S
ESSI
ON_
TYP
E_C
HA
NGE
_IN_
PR
OG
RES
S
0xC
026
05E
8

Requirements

Header
Win
erro
r.h

See also
C
O
M
E
r
r
o
r
C
o
d
e
s
COM Error Codes (TPM, PLA, FVE)
1/7/2020 • 43 minutes to read • Edit Online

The following table provides a list of error codes used by COM -based APIs.
If you are experiencing difficulty with an application you are installing or running, contact customer support for the
software that is displaying the error message. To obtain support for a Microsoft product, go to
https://support.microsoft.com.

CONSTANT/VALUE DESCRIPTION

This is an error mask to convert TPM hardware errors to win


TP errors.
M_E
_ER
RO
R_M
ASK
0x8
028
000
0

Authentication failed.
TP
M_E
_AU
THF
AIL
0x8
028
000
1

The index to a PCR, DIR or other register is incorrect.


TP
M_E
_BA
DIN
DEX
0x8
028
000
2
CONSTANT/VALUE DESCRIPTION

One or more parameter is bad.


TP
M_E
_BA
D_P
AR
AM
ETE
R
0x8
028
000
3

An operation completed successfully but the auditing of that


TP operation failed.
M_E
_AU
DIT
FAIL
URE
0x8
028
000
4

The clear disable flag is set and all clear operations now
TP require physical access.
M_E
_CL
EAR
_DIS
ABL
ED
0x8
028
000
5

Activate the Trusted Platform Module (TPM).


TP
M_E
_DE
ACT
IVA
TED
0x8
028
000
6
CONSTANT/VALUE DESCRIPTION

Enable the Trusted Platform Module (TPM).


TP
M_E
_DIS
ABL
ED
0x8
028
000
7

The target command has been disabled.


TP
M_E
_DIS
ABL
ED_
CM
D
0x8
028
000
8

The operation failed.


TP
M_E
_FAI
L
0x8
028
000
9

The ordinal was unknown or inconsistent.


TP
M_E
_BA
D_O
RDI
NAL
0x8
028
000
A
CONSTANT/VALUE DESCRIPTION

The ability to install an owner is disabled.


TP
M_E
_IN
STA
LL_
DIS
ABL
ED
0x8
028
000
B

The key handle cannot be interpreted.


TP
M_E
_IN
VAL
ID_
KEY
HA
NDL
E
0x8
028
000
C

The key handle points to an invalid key.


TP
M_E
_KE
YN
OTF
OU
ND
0x8
028
000
D

Unacceptable encryption scheme.


TP
M_E
_IN
APP
RO
PRI
ATE
_EN
C
0x8
028
000
E
CONSTANT/VALUE DESCRIPTION

Migration authorization failed.


TP
M_E
_MI
GR
ATE
FAIL
0x8
028
000
F

PCR information could not be interpreted.


TP
M_E
_IN
VAL
ID_
PCR
_INF
O
0x8
028
001
0

No room to load key.


TP
M_E
_NO
SPA
CE
0x8
028
001
1

There is no Storage Root Key (SRK) set.


TP
M_E
_NO
SRK
0x8
028
001
2
CONSTANT/VALUE DESCRIPTION

An encrypted blob is invalid or was not created by this TPM.


TP
M_E
_NO
TSE
ALE
D_B
LOB
0x8
028
001
3

The Trusted Platform Module (TPM) already has an owner.


TP
M_E
_O
WN
ER_
SET
0x8
028
001
4

The TPM has insufficient internal resources to perform the


TP requested action.
M_E
_RE
SO
URC
ES
0x8
028
001
5

A random string was too short.


TP
M_E
_SH
ORT
RA
ND
OM
0x8
028
001
6
CONSTANT/VALUE DESCRIPTION

The TPM does not have the space to perform the operation.
TP
M_E
_SIZ
E
0x8
028
001
7

The named PCR value does not match the current PCR value.
TP
M_E
_W
RO
NG
PCR
VAL
0x8
028
001
8

The paramSize argument to the command has the incorrect


TP value .
M_E
_BA
D_P
AR
AM
_SIZ
E
0x8
028
001
9

There is no existing SHA-1 thread.


TP
M_E
_SH
A_T
HRE
AD
0x8
028
001
A
CONSTANT/VALUE DESCRIPTION

The calculation is unable to proceed because the existing SHA-


TP 1 thread has already encountered an error.
M_E
_SH
A_E
RR
OR
0x8
028
001
B

The TPM hardware device reported a failure during its internal


TP self test. Try restarting the computer to resolve the problem. If
M_E the problem continues, you might need to replace your TPM
_FAI hardware or motherboard.
LED
SEL
FTE
ST
0x8
028
001
C

The authorization for the second key in a 2 key function failed


TP authorization.
M_E
_AU
TH2
FAIL
0x8
028
001
D

The tag value sent to for a command is invalid.


TP
M_E
_BA
DTA
G
0x8
028
001
E

An IO error occurred transmitting information to the TPM.


TP
M_E
_IOE
RR
OR
0x8
028
001
F
CONSTANT/VALUE DESCRIPTION

The encryption process had a problem.


TP
M_E
_EN
CRY
PT_
ERR
OR
0x8
028
002
0

The decryption process did not complete.


TP
M_E
_DE
CRY
PT_
ERR
OR
0x8
028
002
1

An invalid handle was used.


TP
M_E
_IN
VAL
ID_
AUT
HH
AN
DLE
0x8
028
002
2

The TPM does not have an Endorsement Key (EK) installed.


TP
M_E
_NO
_EN
DO
RSE
ME
NT
0x8
028
002
3
CONSTANT/VALUE DESCRIPTION

The usage of a key is not allowed.


TP
M_E
_IN
VAL
ID_
KEY
USA
GE
0x8
028
002
4

The submitted entity type is not allowed.


TP
M_E
_W
RO
NG_
ENT
ITY
TYP
E
0x8
028
002
5

The command was received in the wrong sequence relative to


TP TPM_Init and a subsequent TPM_Startup.
M_E
_IN
VAL
ID_
POS
TINI
T
0x8
028
002
6

Signed data cannot include additional DER information.


TP
M_E
_IN
APP
RO
PRI
ATE
_SIG
0x8
028
002
7
CONSTANT/VALUE DESCRIPTION

The key properties in TPM_KEY_PARMs are not supported by


TP this TPM.
M_E
_BA
D_K
EY_
PR
OPE
RTY
0x8
028
002
8

The migration properties of this key are incorrect.


TP
M_E
_BA
D_
MIG
RAT
ION
0x8
028
002
9

The signature or encryption scheme for this key is incorrect or


TP not permitted in this situation.
M_E
_BA
D_S
CHE
ME
0x8
028
002
A

The size of the data (or blob) parameter is bad or inconsistent


TP with the referenced key.
M_E
_BA
D_D
ATA
SIZE
0x8
028
002
B
CONSTANT/VALUE DESCRIPTION

A mode parameter is bad, such as capArea or subCapArea for


TP TPM_GetCapability, phsicalPresence parameter for
M_E TPM_PhysicalPresence, or migrationType for
_BA TPM_CreateMigrationBlob.
D_
MO
DE
0x8
028
002
C

Either the physicalPresence or physicalPresenceLock bits have


TP the wrong value.
M_E
_BA
D_P
RES
ENC
E
0x8
028
002
D

The TPM cannot perform this version of the capability.


TP
M_E
_BA
D_V
ERSI
ON
0x8
028
002
E

The TPM does not allow for wrapped transport sessions.


TP
M_E
_NO
_W
RAP
_TR
AN
SPO
RT
0x8
028
002
F
CONSTANT/VALUE DESCRIPTION

TPM audit construction failed and the underlying command


TP was returning a failure code also.
M_E
_AU
DIT
FAIL
_UN
SUC
CES
SFU
L
0x8
028
003
0

TPM audit construction failed and the underlying command


TP was returning success.
M_E
_AU
DIT
FAIL
_SU
CCE
SSF
UL
0x8
028
003
1

Attempt to reset a PCR register that does not have the


TP resettable attribute.
M_E
_NO
TRE
SET
ABL
E
0x8
028
003
2

Attempt to reset a PCR register that requires locality and


TP locality modifier not part of command transport.
M_E
_NO
TLO
CAL
0x8
028
003
3
CONSTANT/VALUE DESCRIPTION

Make identity blob not properly typed.


TP
M_E
_BA
D_T
YPE
0x8
028
003
4

When saving context identified resource type does not match


TP actual resource.
M_E
_IN
VAL
ID_
RES
OU
RCE
0x8
028
003
5

The TPM is attempting to execute a command only available


TP when in FIPS mode.
M_E
_NO
TFIP
S
0x8
028
003
6

The command is attempting to use an invalid family ID.


TP
M_E
_IN
VAL
ID_F
AMI
LY
0x8
028
003
7
CONSTANT/VALUE DESCRIPTION

The permission to manipulate the NV storage is not available.


TP
M_E
_NO
_NV
_PE
RMI
SSI
ON
0x8
028
003
8

The operation requires a signed command.


TP
M_E
_RE
QUI
RES
_SIG
N
0x8
028
003
9

Wrong operation to load an NV key.


TP
M_E
_KE
Y_N
OTS
UPP
ORT
ED
0x8
028
003
A

NV_LoadKey blob requires both owner and blob authorization.


TP
M_E
_AU
TH_
CO
NFL
ICT
0x8
028
003
B
CONSTANT/VALUE DESCRIPTION

The NV area is locked and not writtable.


TP
M_E
_AR
EA_
LOC
KED
0x8
028
003
C

The locality is incorrect for the attempted operation.


TP
M_E
_BA
D_L
OC
ALI
TY
0x8
028
003
D

The NV area is read only and can't be written to.


TP
M_E
_RE
AD_
ON
LY
0x8
028
003
E

There is no protection on the write to the NV area.


TP
M_E
_PE
R_N
OW
RITE
0x8
028
003
F
CONSTANT/VALUE DESCRIPTION

The family count value does not match.


TP
M_E
_FA
MIL
YC
OU
NT
0x8
028
004
0

The NV area has already been written to.


TP
M_E
_W
RITE
_LO
CKE
D
0x8
028
004
1

The NV area attributes conflict.


TP
M_E
_BA
D_A
TTR
IBU
TES
0x8
028
004
2

The structure tag and version are invalid or inconsistent.


TP
M_E
_IN
VAL
ID_S
TRU
CTU
RE
0x8
028
004
3
CONSTANT/VALUE DESCRIPTION

The key is under control of the TPM Owner and can only be
TP evicted by the TPM Owner.
M_E
_KE
Y_O
WN
ER_
CO
NTR
OL
0x8
028
004
4

The counter handle is incorrect.


TP
M_E
_BA
D_C
OU
NTE
R
0x8
028
004
5

The write is not a complete write of the area.


TP
M_E
_NO
T_F
ULL
WRI
TE
0x8
028
004
6

The gap between saved context counts is too large.


TP
M_E
_CO
NTE
XT_
GA
P
0x8
028
004
7
CONSTANT/VALUE DESCRIPTION

The maximum number of NV writes without an owner has


TP been exceeded.
M_E
_M
AX
NV
WRI
TES
0x8
028
004
8

No operator AuthData value is set.


TP
M_E
_NO
OPE
RAT
OR
0x8
028
004
9

The resource pointed to by context is not loaded.


TP
M_E
_RE
SO
URC
EMI
SSI
NG
0x8
028
004
A

The delegate administration is locked.


TP
M_E
_DE
LEG
ATE
_LO
CK
0x8
028
004
B
CONSTANT/VALUE DESCRIPTION

Attempt to manage a family other than the delegated family.


TP
M_E
_DE
LEG
ATE
_FA
MIL
Y
0x8
028
004
C

Delegation table management not enabled.


TP
M_E
_DE
LEG
ATE
_AD
MIN
0x8
028
004
D

There was a command executed outside of an exclusive


TP transport session.
M_E
_TR
AN
SPO
RT_
NO
TEX
CLU
SIVE
0x8
028
004
E

Attempt to context save a owner evict controlled key.


TP
M_E
_O
WN
ER_
CO
NTR
OL
0x8
028
004
F
CONSTANT/VALUE DESCRIPTION

The DAA command has no resources availble to execute the


TP command.
M_E
_DA
A_R
ESO
URC
ES
0x8
028
005
0

The consistency check on DAA parameter inputData0 has


TP failed.
M_E
_DA
A_I
NP
UT_
DAT
A0
0x8
028
005
1

The consistency check on DAA parameter inputData1 has


TP failed.
M_E
_DA
A_I
NP
UT_
DAT
A1
0x8
028
005
2

The consistency check on DAA_issuerSettings has failed.


TP
M_E
_DA
A_IS
SUE
R_S
ETTI
NG
S
0x8
028
005
3
CONSTANT/VALUE DESCRIPTION

The consistency check on DAA_tpmSpecific has failed.


TP
M_E
_DA
A_T
PM_
SET
TIN
GS
0x8
028
005
4

The atomic process indicated by the submitted DAA command


TP is not the expected process.
M_E
_DA
A_S
TAG
E
0x8
028
005
5

The issuer's validity check has detected an inconsistency.


TP
M_E
_DA
A_IS
SUE
R_V
ALI
DIT
Y
0x8
028
005
6

The consistency check on w has failed.


TP
M_E
_DA
A_
WR
ON
G_
W
0x8
028
005
7
CONSTANT/VALUE DESCRIPTION

The handle is incorrect.


TP
M_E
_BA
D_H
AN
DLE
0x8
028
005
8

Delegation is not correct.


TP
M_E
_BA
D_D
ELE
GAT
E
0x8
028
005
9

The context blob is invalid.


TP
M_E
_BA
DC
ON
TEX
T
0x8
028
005
A

Too many contexts held by the TPM.


TP
M_E
_TO
OM
AN
YC
ON
TEX
TS
0x8
028
005
B
CONSTANT/VALUE DESCRIPTION

Migration authority signature validation failure.


TP
M_E
_M
A_TI
CKE
T_SI
GN
ATU
RE
0x8
028
005
C

Migration destination not authenticated.


TP
M_E
_M
A_D
ESTI
NA
TIO
N
0x8
028
005
D

Migration source incorrect.


TP
M_E
_M
A_S
OU
RCE
0x8
028
005
E

Incorrect migration authority.


TP
M_E
_M
A_A
UT
HO
RIT
Y
0x8
028
005
F
CONSTANT/VALUE DESCRIPTION

Attempt to revoke the EK and the EK is not revocable.


TP
M_E
_PE
RM
ANE
NTE
K
0x8
028
006
1

Bad signature of CMK ticket.


TP
M_E
_BA
D_SI
GN
ATU
RE
0x8
028
006
2

There is no room in the context list for additional contexts.


TP
M_E
_NO
CO
NTE
XTS
PAC
E
0x8
028
006
3

The command was blocked.


TP
M_E
_CO
MM
AN
D_B
LOC
KED
0x8
028
040
0
CONSTANT/VALUE DESCRIPTION

The specified handle was not found.


TP
M_E
_IN
VAL
ID_
HA
NDL
E
0x8
028
040
1

The TPM returned a duplicate handle and the command needs


TP to be resubmitted.
M_E
_DU
PLI
CAT
E_V
HA
NDL
E
0x8
028
040
2

The command within the transport was blocked.


TP
M_E
_EM
BED
DED
_CO
MM
AN
D_B
LOC
KED
0x8
028
040
3
CONSTANT/VALUE DESCRIPTION

The command within the transport is not supported.


TP
M_E
_EM
BED
DED
_CO
MM
AN
D_U
NS
UPP
ORT
ED
0x8
028
040
4

The TPM is too busy to respond to the command immediately,


TP but the command could be resubmitted at a later time.
M_E
_RE
TRY
0x8
028
080
0

SelfTestFull has not been run.


TP
M_E
_NE
EDS
_SEL
FTE
ST
0x8
028
080
1

The TPM is currently executing a full selftest.


TP
M_E
_DO
ING
_SEL
FTE
ST
0x8
028
080
2
CONSTANT/VALUE DESCRIPTION

The TPM is defending against dictionary attacks and is in a


TP time-out period.
M_E
_DE
FEN
D_L
OC
K_R
UN
NIN
G
0x8
028
080
3

TPM 2.0: Inconsistent attributes.


TP
M_2
0_E_
ATT
RIB
UTE
S
0x8
028
008
2

TPM 2.0: Hash algorithm not supported or not appropriate.


TP
M_2
0_E_
HA
SH
0x8
028
008
3

TPM 2.0: Value is out of range or is not correct for the context.
TP
M_2
0_E_
VAL
UE
0x8
028
008
4
CONSTANT/VALUE DESCRIPTION

TPM 2.0: Hierarchy is not enabled or is not correct for the use.
TP
M_2
0_E_
HIE
RAR
CH
Y
0x8
028
008
5

TPM 2.0: Key size is not supported.


TP
M_2
0_E_
KEY
_SIZ
E
0x8
028
008
6

TPM 2.0: Mask generation function not supported.


TP
M_2
0_E_
MG
F
0x8
028
008
7

TPM 2.0: Mode of operation not supported.


TP
M_2
0_E_
MO
DE
0x8
028
008
9

TPM 2.0: The type of the value is not appropriate for the use.
TP
M_2
0_E_
TYP
E
0x8
028
008
A
CONSTANT/VALUE DESCRIPTION

TPM 2.0: The Handle is not correct for the use.


TP
M_2
0_E_
HA
NDL
E
0x8
028
008
B

TPM 2.0: Unsupported key derivation function or function not


TP appropriate for use.
M_2
0_E_
KDF
0x8
028
008
C

TPM 2.0: Value was out of allowed range.


TP
M_2
0_E_
RA
NGE
0x8
028
008
D

TPM 2.0: The authorization HMAC check failed and DA


TP counter incremented.
M_2
0_E_
AUT
H_F
AIL
0x8
028
008
E

TPM 2.0: Invalid nonce size.


TP
M_2
0_E_
NO
NCE
0x8
028
008
F
CONSTANT/VALUE DESCRIPTION

TPM 2.0: Unsupported or incompatible scheme.


TP
M_2
0_E_
SCH
EME
0x8
028
009
2

TPM 2.0: Structure is wrong size..


TP
M_2
0_E_
SIZE
0x8
028
009
5

TPM_20_E_SYMMETRIC TPM 2.0: Unsupported symmetric algorithm or key size, or not


appropriate for instance.
0x8
028
009
6

TPM 2.0: Incorrect structure tag.


TP
M_2
0_E_
TAG
0x8
028
009
7

TPM 2.0: Union selector is incorrect.


TP
M_2
0_E_
SEL
ECT
OR
0x8
028
009
8
CONSTANT/VALUE DESCRIPTION

TPM 2.0: The TPM was unable to unmarshal a value because


>TP there were not enough octets in the input buffer.
M_2
0_E_
INS
UFFI
CIE
NT
0x8
028
009
A

TPM 2.0: The signature is not valid.


TP
M_2
0_E_
SIG
NA
TUR
E
0x8
028
009
B

TPM 2.0: Key fields are not compatible with the selected use.
TP
M_2
0_E_
KEY
0x8
028
008
7

TPM 2.0: A policy check failed.


TP
M_2
0_E_
POL
ICY_
FAIL
0x8
028
009
D
CONSTANT/VALUE DESCRIPTION

TPM 2.0: Integrity check failed.


TP
M_2
0_E_
INT
EGR
ITY
0x8
028
009
F

TPM 2.0: Invalid ticket.


TP
M_2
0_E_
TIC
KET
0x8
028
00A
0

TPM 2.0: Reserved bits not set to zero as required.


TP
M_2
0_E_
RES
ERV
ED_
BIT
S
0x8
028
00A
1

TPM 2.0: Authorization failure without DA implications.


TP
M_2
0_E_
BA
D_A
UT
H
0x8
028
00A
2
CONSTANT/VALUE DESCRIPTION

TPM 2.0: The policy has expired.


TP
M_2
0_E_
EXP
IRE
D
0x8
028
00A
3

TPM 2.0: The command code in the policy is not the


TP command code of the command or the command code in a
M_2 policy command references a command that is not
0_E_ implemented.
POL
ICY_
CC
0x8
028
00A
4

TPM 2.0: Public and sensitive portions of an object are not


TP cryptographically bound.
M_2
0_E_
BIN
DIN
G
0x8
028
00A
5

TPM 2.0: Curve not supported.


TP
M_2
0_E_
CUR
VE
0x8
028
00A
6
CONSTANT/VALUE DESCRIPTION

TPM 2.0: Point is not on the required curve.


TP
M_2
0_E_
ECC
_PO
INT
0x8
028
00A
7

TPM 2.0: TPM not initialized.


TP
M_2
0_E_
INIT
IALI
ZE
0x8
028
010
0

TPM 2.0: Commands not being accepted because of a TPM


TP failure.
M_2
0_E_
FAIL
URE
0x8
028
010
1

TPM 2.0: Improper use of a sequence handle.


TP
M_2
0_E_
SEQ
UEN
CE
0x8
028
010
3
CONSTANT/VALUE DESCRIPTION

TPM 2.0: TPM_RC_PRIVATE error.


TP
M_2
0_E_
PRI
VAT
E
0x8
028
001
0B

TPM 2.0: TPM_RC_HMAC.


TP
M_2
0_E_
HM
AC
0x8
028
011
9

TPM 2.0: TPM_RC_DISABLED.


TP
M_2
0_E_
DIS
ABL
ED
0x8
028
012
0

TPM 2.0: Command failed because audit sequence required


TP exclusivity.
M_2
0_E_
EXC
LUS
IVE
0x8
028
012
1
CONSTANT/VALUE DESCRIPTION

TPM 2.0: Unsupported ECC curve.


TP
M_2
0_E_
ECC
_CU
RVE
0x8
028
012
3

TPM 2.0: Authorization handle is not correct for command.


TP
M_2
0_E_
AUT
H_T
YPE
0x8
028
012
4

TPM 2.0: Command requires an authorization session for


TP handle and is not present.
M_2
0_E_
AUT
H_
MIS
SIN
G
0x8
028
012
5

TPM 2.0: Policy failure in Math Operation or an invalid


TP authPolicy value.
M_2
0_E_
POL
ICY
0x8
028
012
6
CONSTANT/VALUE DESCRIPTION

TPM 2.0: PCR check fail.


TP
M_2
0_E_
PCR
0x8
028
012
7

TPM 2.0: PCR have changed since checked.


TP
M_2
0_E_
PCR
_CH
AN
GED
0x8
028
012
8

TPM 2.0: The TPM is not in the right mode for upgrade.
TP
M_2
0_E_
UP
GR
ADE
0x8
028
012
D

TPM 2.0: Context ID counter is at maximum.


TP
M_2
0_E_
TO
O_
MA
NY_
CO
NTE
XTS
0x8
028
012
E
CONSTANT/VALUE DESCRIPTION

TPM 2.0: authValue or authPolicy is not available for selected


TP entity.
M_2
0_E_
AUT
H_U
NA
VAI
LAB
LE
0x8
028
012
F

TPM 2.0: A _TPM_Init and Startup(CLEAR) is required before


TP the TPM can resume operation.
M_2
0_E_
REB
OO
T
0x8
028
013
0

TPM 2.0: The protection algorithms (hash and symmetric) are


TP not reasonably balanced. The digest size of the hash must be
M_2 larger than the key size of the symmetric algorithm.
0_E_
UN
BAL
AN
CED
0x8
028
013
1

TPM 2.0: The TPM command's commandSize value is


TP inconsistent with contents of the command buffer; either the
M_2 size is not the same as the bytes loaded by the hardware
0_E_ interface layer or the value is not large enough to hold a
CO command header.
MM
AN
D_SI
ZE
0x8
028
014
2
CONSTANT/VALUE DESCRIPTION

TPM 2.0: Command code not supported.


TP
M_2
0_E_
CO
MM
AN
D_C
ODE
0x8
028
014
3

TPM 2.0: The value of authorizationSize is out of range or the


TP number of octets in the authorization Area is greater than
M_2 required.
0_E_
AUT
HSI
ZE
0x8
028
014
4

TPM 2.0: Use of an authorization session with a context


TP command or another command that cannot have an
M_2 authorization session.
0_E_
AUT
H_C
ON
TEX
T
0x8
028
014
5

TPM 2.0: NV offset+size is out of range.


TP
M_2
0_E_
NV_
RA
NGE
0x8
028
014
6
CONSTANT/VALUE DESCRIPTION

TPM 2.0: Requested allocation size is larger than allowed.


TP
M_2
0_E_
NV_
SIZE
0x8
028
014
7

TPM 2.0: NV access locked.


TP
M_2
0_E_
NV_
LOC
KED
0x8
028
014
8

TPM 2.0: NV access authorization fails in command actions


TP
M_2
0_E_
NV_
AUT
HO
RIZ
ATI
ON
0x8
028
014
9

TPM 2.0: An NV index is used before being initialized or the


TP state saved by TPM2_Shutdown(STATE) could not be restored.
M_2
0_E_
NV_
UNI
NITI
ALI
ZED
0x8
028
014
A
CONSTANT/VALUE DESCRIPTION

TPM 2.0: Insufficient space for NV allocation.


TP
M_2
0_E_
NV_
SPA
CE
0x8
028
014
B

TPM 2.0: NV index or persistent object already defined.


TP
M_2
0_E_
NV_
DEFI
NED
0x8
028
014
C

TPM 2.0: Context in TPM2_ContextLoad() is not valid.


TP
M_2
0_E_
BA
D_C
ON
TEX
T
0x8
028
015
0

TPM 2.0: chHash value already set or not correct for use.
TP
M_2
0_E_
CP
HA
SH
0x8
028
015
1
CONSTANT/VALUE DESCRIPTION

TPM 2.0: Handle for parent is not a valid parent.


TP
M_2
0_E_
PAR
ENT
0x8
028
015
2

TPM 2.0: Some function needs testing.


TP
M_2
0_E_
NEE
DS_
TES
T
0x8
028
015
3

TPM 2.0: returned when an internal function cannot process a


TP request due to an unspecified problem. This code is usually
M_2 related to invalid parameters that are not properly filtered by
0_E_ the input unmarshaling code.
NO_
RES
ULT
0x8
028
015
4

TPM 2.0: The sensitive area did not unmarshal correctly after
TP decryption - this code is used in lieu of the other
M_2 unmarshaling errors so that an attacker cannot determine
0_E_ where the unmarshaling error occurred.
SEN
SITI
VE
0x8
028
015
5
CONSTANT/VALUE DESCRIPTION

TPM 2.0: Gap for context ID is too large.


TP
M_2
0_E_
CO
NTE
XT_
GA
P
0x8
028
090
1

TPM 2.0: Out of memory for object contexts.


TP
M_2
0_E_
OBJ
ECT
_ME
MO
RY
0x8
028
090
2

TPM 2.0: Out of memory for session contexts.


TP
M_2
0_E_
SES
SIO
N_
ME
MO
RY
0x8
028
090
3

TPM 2.0: Out of shared object/session memory or need space


TP for internal operations.
M_2
0_E_
ME
MO
RY
0x8
028
090
4
CONSTANT/VALUE DESCRIPTION

TPM 2.0: Out of session handles - a session must be flushed


TP before a new session may be created.
M_2
0_E_
SES
SIO
N_H
AN
DLE
S
0x8
028
090
5

TPM 2.0: Out of object handles - the handle space for objects
TP is depleted and a reboot is required.
M_2
0_E_
OBJ
ECT
_HA
NDL
ES
0x8
028
090
6

TPM 2.0: Bad locality.


TP
M_2
0_E_
LOC
ALI
TY
0x8
028
090
7

TPM 2.0: The TPM has suspended operation on the command;


TP forward progress was made and the command may be retried.
M_2
0_E_
YIEL
DED
0x8
028
090
8
CONSTANT/VALUE DESCRIPTION

TPM 2.0: The command was canceled.


TP
M_2
0_E_
CA
NCE
LED
0x8
028
090
9

TPM 2.0: TPM is performing self-tests.


TP
M_2
0_E_
TES
TIN
G
0x8
028
090
A

TPM 2.0: The TPM is rate-limiting accesses to prevent wearout


TP of NV.
M_2
0_E_
NV_
RAT
E
0x8
028
092
0

TPM 2.0: Authorization for objects subject to DA protection


TP are not allowed at this time because the TPM is in DA lockout
M_2 mode.
0_E_
LOC
KO
UT
0x8
028
092
1
CONSTANT/VALUE DESCRIPTION

TPM 2.0: The TPM was not able to start the command.
TP
M_2
0_E_
RET
RY
0x8
028
092
2

TPM 2.0: the command may require writing of NV and NV is


TP not current accessible..
M_2
0_E_
NV_
UN
AV
AIL
ABL
E
0x8
028
092
3

An internal software error has been detected.


TBS
_E_I
NTE
RN
AL_
ERR
OR
0x8
028
400
1

One or more input parameters is bad.


TBS
_E_B
AD_
PAR
AM
ETE
R
0x8
028
400
2
CONSTANT/VALUE DESCRIPTION

A specified output pointer is bad.


TBS
_E_I
NV
ALI
D_O
UTP
UT_
POI
NTE
R
0x8
028
400
3

The specified context handle does not refer to a valid context.


TBS
_E_I
NV
ALI
D_C
ON
TEX
T
0x8
028
400
4

A specified output buffer is too small.


TBS
_E_I
NS
UFFI
CIE
NT_
BUF
FER
0x8
028
400
5

An error occurred while communicating with the TPM.


TBS
_E_I
OER
RO
R
0x8
028
400
6
CONSTANT/VALUE DESCRIPTION

One or more context parameters is invalid.


TBS
_E_I
NV
ALI
D_C
ON
TEX
T_P
AR
AM
0x8
028
400
7

The TBS service is not running and could not be started.


TBS
_E_S
ERV
ICE_
NO
T_R
UN
NIN
G
0x8
028
400
8

A new context could not be created because there are too


TBS many open contexts.
_E_T
OO_
MA
NY_
TBS
_CO
NTE
XTS
0x8
028
400
9
CONSTANT/VALUE DESCRIPTION

A new virtual resource could not be created because there are


TBS too many open virtual resources.
_E_T
OO_
MA
NY_
RES
OU
RCE
S
0x8
028
400
A

The TBS service has been started but is not yet running.
TBS
_E_S
ERV
ICE_
STA
RT_
PEN
DIN
G
0x8
028
400
B

The physical presence interface is not supported.


TBS
_E_P
PI_
NO
T_S
UPP
ORT
ED
0x8
028
400
C

The command was canceled.


TBS
_E_C
OM
MA
ND_
CA
NCE
LED
0x8
028
400
D
CONSTANT/VALUE DESCRIPTION

The input or output buffer is too large.


TBS
_E_B
UFF
ER_
TO
O_L
AR
GE
0x8
028
400
E

A compatible Trusted Platform Module (TPM) Security Device


TBS cannot be found on this computer.
_E_T
PM_
NO
T_F
OU
ND
0x8
028
400
F

The TBS service has been disabled.


TBS
_E_S
ERV
ICE_
DIS
ABL
ED
0x8
028
401
0

No TCG event log is available.


TBS
_E_
NO_
EVE
NT_
LOG
0x8
028
401
1
CONSTANT/VALUE DESCRIPTION

The caller does not have the appropriate rights to perform the
TBS requested operation.
_E_
ACC
ESS
_DE
NIE
D
0x8
028
401
2

The TPM provisioning action is not allowed by the specified


TBS flags. For provisioning to be successful, one of several actions
_E_P may be required. The TPM management console (tpm.msc)
RO action to make the TPM Ready may help. For further
VISI information, see the documentation for the Win32_Tpm WMI
ONI method 'Provision'. (The actions that may be required include
NG_ importing the TPM Owner Authorization value into the
NO system, calling the Win32_Tpm WMI method for provisioning
T_A the TPM and specifying TRUE for either 'ForceClear_Allowed'
LLO or 'PhysicalPresencePrompts_Allowed' (as indicated by the
WE value returned in the Additional Information), or enabling the
D TPM in the system BIOS.)
0x8
028
401
3

The Physical Presence Interface of this firmware does not


TBS support the requested method.
_E_P
PI_F
UN
CTI
ON_
UN
SUP
PO
RTE
D
0x8
028
401
4
CONSTANT/VALUE DESCRIPTION

The requested TPM OwnerAuth value was not found.


TBS
_E_
OW
NER
AUT
H_N
OT_
FOU
ND
0x8
028
401
5

The TPM provisioning did not complete. For more information


TBS on completing the provisioning, call the Win32_Tpm WMI
_E_P method for provisioning the TPM ('Provision') and check the
RO returned Information.
VISI
ONI
NG_
INC
OM
PLE
TE
0x8
028
401
6

The command buffer is not in the correct state.


TP
MA
PI_E
_IN
VAL
ID_S
TAT
E
0x8
029
010
0
CONSTANT/VALUE DESCRIPTION

The command buffer does not contain enough data to satisfy


TP the request.
MA
PI_E
_NO
T_E
NO
UG
H_D
ATA
0x8
029
010
1

The command buffer cannot contain any more data.


TP
MA
PI_E
_TO
O_
MU
CH_
DAT
A
0x8
029
010
2

One or more output parameters was NULL or invalid.


TP
MA
PI_E
_IN
VAL
ID_
OU
TPU
T_P
OIN
TER
0x8
029
010
3
CONSTANT/VALUE DESCRIPTION

One or more input parameters is invalid.


TP
MA
PI_E
_IN
VAL
ID_
PAR
AM
ETE
R
0x8
029
010
4

Not enough memory was available to satisfy the request.


TP
MA
PI_E
_OU
T_O
F_M
EM
OR
Y
0x8
029
010
5

The specified buffer was too small.


TP
MA
PI_E
_BU
FFE
R_T
OO_
SM
ALL
0x8
029
010
6
CONSTANT/VALUE DESCRIPTION

An internal error was detected.


TP
MA
PI_E
_IN
TER
NAL
_ER
RO
R
0x8
029
010
7

The caller does not have the appropriate rights to perform the
TP requested operation.
MA
PI_E
_AC
CES
S_D
ENI
ED
0x8
029
010
8

The specified authorization information was invalid.


TP
MA
PI_E
_AU
TH
ORI
ZAT
ION
_FAI
LED
0x8
029
010
9
CONSTANT/VALUE DESCRIPTION

The specified context handle was not valid.


TP
MA
PI_E
_IN
VAL
ID_
CO
NTE
XT_
HA
NDL
E
0x8
029
010
A

An error occurred while communicating with the TBS.


TP
MA
PI_E
_TB
S_C
OM
MU
NIC
ATI
ON_
ERR
OR
0x8
029
010
B

The TPM returned an unexpected result.


TP
MA
PI_E
_TP
M_C
OM
MA
ND_
ERR
OR
0x8
029
010
C
CONSTANT/VALUE DESCRIPTION

The message was too large for the encoding scheme.


TP
MA
PI_E
_ME
SSA
GE_
TO
O_L
AR
GE
0x8
029
010
D

The encoding in the blob was not recognized.


TP
MA
PI_E
_IN
VAL
ID_E
NC
ODI
NG
0x8
029
010
E

The key size is not valid.


TP
MA
PI_E
_IN
VAL
ID_
KEY
_SIZ
E
0x8
029
010
F
CONSTANT/VALUE DESCRIPTION

The encryption operation failed.


TP
MA
PI_E
_EN
CRY
PTI
ON_
FAIL
ED
0x8
029
011
0

The key parameters structure was not valid


TP
MA
PI_E
_IN
VAL
ID_
KEY
_PA
RA
MS
0x8
029
011
1

The requested supplied data does not appear to be a valid


TP migration authorization blob.
MA
PI_E
_IN
VAL
ID_
MIG
RAT
ION
_AU
TH
ORI
ZAT
ION
_BL
OB
0x8
029
011
2
CONSTANT/VALUE DESCRIPTION

The specified PCR index was invalid


TP
MA
PI_E
_IN
VAL
ID_
PCR
_IN
DEX
0x8
029
011
3

The data given does not appear to be a valid delegate blob.


TP
MA
PI_E
_IN
VAL
ID_
DEL
EGA
TE_
BLO
B
0x8
029
011
4

One or more of the specified context parameters was not


TP valid.
MA
PI_E
_IN
VAL
ID_
CO
NTE
XT_
PAR
AM
S
0x8
029
011
5
CONSTANT/VALUE DESCRIPTION

The data given does not appear to be a valid key blob


TP
MA
PI_E
_IN
VAL
ID_
KEY
_BL
OB
0x8
029
011
6

The specified PCR data was invalid.


TP
MA
PI_E
_IN
VAL
ID_
PCR
_DA
TA
0x8
029
011
7

The format of the owner auth data was invalid.


TP
MA
PI_E
_IN
VAL
ID_
OW
NER
_AU
TH
0x8
029
011
8
CONSTANT/VALUE DESCRIPTION

The random number generated did not pass FIPS RNG check.
TP
MA
PI_E
_FIP
S_R
NG_
CHE
CK_
FAIL
ED
0x8
029
011
9

The TCG Event Log does not contain any data.


TP
MA
PI_E
_EM
PTY
_TC
G_L
OG
0x8
029
011
A

An entry in the TCG Event Log was invalid.


TP
MA
PI_E
_IN
VAL
ID_T
CG_
LOG
_EN
TRY
0x8
029
011
B
CONSTANT/VALUE DESCRIPTION

A TCG Separator was not found.


TP
MA
PI_E
_TC
G_S
EPA
RAT
OR_
ABS
ENT
0x8
029
011
C

A digest value in a TCG Log entry did not match hashed data.
TP
MA
PI_E
_TC
G_I
NV
ALI
D_D
IGE
ST_
ENT
RY
0x8
029
011
D

The requested operation was blocked by current TPM policy.


TP Please contact your system administrator for assistance.
MA
PI_E
_PO
LIC
Y_D
ENI
ES_
OPE
RAT
ION
0x8
029
011
E
CONSTANT/VALUE DESCRIPTION

The specified buffer was too small.


TBS
IMP
_E_B
UFF
ER_
TO
O_S
MA
LL
0x8
029
020
0

The context could not be cleaned up.


TBS
IMP
_E_C
LEA
NU
P_F
AILE
D
0x8
029
020
1

The specified context handle is invalid.


TBS
IMP
_E_I
NV
ALI
D_C
ON
TEX
T_H
AN
DLE
0x8
029
020
2
CONSTANT/VALUE DESCRIPTION

An invalid context parameter was specified.


TBS
IMP
_E_I
NV
ALI
D_C
ON
TEX
T_P
AR
AM
0x8
029
020
3

An error occurred while communicating with the TPM


TBS
IMP
_E_T
PM_
ERR
OR
0x8
029
020
4

No entry with the specified key was found.


TBS
IMP
_E_
HA
SH_
BA
D_K
EY
0x8
029
020
5

The specified virtual handle matches a virtual handle already


TBS in use.
IMP
_E_
DU
PLI
CAT
E_V
HA
NDL
E
0x8
029
020
6
CONSTANT/VALUE DESCRIPTION

The pointer to the returned handle location was NULL or


TBS invalid
IMP
_E_I
NV
ALI
D_O
UTP
UT_
POI
NTE
R
0x8
029
020
7

One or more parameters is invalid


TBS
IMP
_E_I
NV
ALI
D_P
AR
AM
ETE
R
0x8
029
020
8

The RPC subsystem could not be initialized.


TBS
IMP
_E_R
PC_I
NIT
_FAI
LED
0x8
029
020
9
CONSTANT/VALUE DESCRIPTION

The TBS scheduler is not running.


TBS
IMP
_E_S
CHE
DUL
ER_
NO
T_R
UN
NIN
G
0x8
029
020
A

The command was canceled.


TBS
IMP
_E_C
OM
MA
ND_
CA
NCE
LED
0x8
029
020
B

There was not enough memory to fulfill the request


TBS
IMP
_E_
OU
T_O
F_M
EM
OR
Y
0x8
029
020
C
CONSTANT/VALUE DESCRIPTION

The specified list is empty, or the iteration has reached the end
TBS of the list.
IMP
_E_L
IST_
NO_
MO
RE_I
TEM
S
0x8
029
020
D

The specified item was not found in the list.


TBS
IMP
_E_L
IST_
NO
T_F
OU
ND
0x8
029
020
E

The TPM does not have enough space to load the requested
TBS resource.
IMP
_E_
NO
T_E
NO
UG
H_S
PAC
E
0x8
029
020
F
CONSTANT/VALUE DESCRIPTION

There are too many TPM contexts in use.


TBS
IMP
_E_
NO
T_E
NO
UG
H_T
PM_
CO
NTE
XTS
0x8
029
021
0

The TPM command failed.


TBS
IMP
_E_C
OM
MA
ND_
FAIL
ED
0x8
029
021
1

The TBS does not recognize the specified ordinal.


TBS
IMP
_E_
UN
KN
OW
N_O
RDI
NAL
0x8
029
021
2
CONSTANT/VALUE DESCRIPTION

The requested resource is no longer available.


TBS
IMP
_E_R
ESO
URC
E_E
XPI
RED
0x8
029
021
3

The resource type did not match.


TBS
IMP
_E_I
NV
ALI
D_R
ESO
URC
E
0x8
029
021
4

No resources can be unloaded.


TBS
IMP
_E_
NO
THI
NG_
TO_
UNL
OA
D
0x8
029
021
5

No new entries can be added to the hash table.


TBS
IMP
_E_
HA
SH_
TAB
LE_F
ULL
0x8
029
021
6
CONSTANT/VALUE DESCRIPTION

A new TBS context could not be created because there are too
TBS many open contexts.
IMP
_E_T
OO_
MA
NY_
TBS
_CO
NTE
XTS
0x8
029
021
7

A new virtual resource could not be created because there are


TBS too many open virtual resources.
IMP
_E_T
OO_
MA
NY_
RES
OU
RCE
S
0x8
029
021
8

The physical presence interface is not supported.


TBS
IMP
_E_P
PI_
NO
T_S
UPP
ORT
ED
0x8
029
021
9
CONSTANT/VALUE DESCRIPTION

TBS is not compatible with the version of TPM found on the


TBS system.
IMP
_E_T
PM_
INC
OM
PAT
IBLE
0x8
029
021
A

No TCG event log is available.


TBS
IMP
_E_
NO_
EVE
NT_
LOG
0x8
029
021
B

A general error was detected when attempting to acquire the


TP BIOS's response to a Physical Presence command.
M_E
_PPI
_AC
PI_F
AIL
URE
0x8
029
030
0

The user failed to confirm the TPM operation request.


TP
M_E
_PPI
_US
ER_
AB
ORT
0x8
029
030
1
CONSTANT/VALUE DESCRIPTION

The BIOS failure prevented the successful execution of the


TP requested TPM operation (e.g. invalid TPM operation request,
M_E BIOS communication error with the TPM).
_PPI
_BI
OS_
FAIL
URE
0x8
029
030
2

The BIOS does not support the physical presence interface.


TP
M_E
_PPI
_NO
T_S
UPP
ORT
ED
0x8
029
030
3

The Physical Presence command was blocked by current BIOS


TP settings. The system owner may be able to reconfigure the
M_E BIOS settings to allow the command.
_PPI
_BL
OC
KED
_IN_
BIO
S
0x8
029
030
4

This is an error mask to convert Platform Crypto Provider


TP errors to win errors.
M_E
_PC
P_E
RR
OR_
MA
SK
0x8
029
040
0
CONSTANT/VALUE DESCRIPTION

The Platform Crypto Device is currently not ready. It needs to


TP be fully provisioned to be operational.
M_E
_PC
P_D
EVI
CE_
NO
T_R
EAD
Y
0x8
029
040
1

The handle provided to the Platform Crypto Provider is invalid.


TP
M_E
_PC
P_I
NV
ALI
D_H
AN
DLE
0x8
029
040
2

A parameter provided to the Platform Crypto Provider is


TP invalid.
M_E
_PC
P_I
NV
ALI
D_P
AR
AM
ETE
R
0x8
029
040
3
CONSTANT/VALUE DESCRIPTION

A provided flag to the Platform Crypto Provider is not


TP supported.
M_E
_PC
P_F
LAG
_NO
T_S
UPP
ORT
ED
0x8
029
040
4

The requested operation is not supported by this Platform


TP Crypto Provider.
M_E
_PC
P_N
OT_
SUP
PO
RTE
D
0x8
029
040
5

The buffer is too small to contain all data. No information has


TP been written to the buffer.
M_E
_PC
P_B
UFF
ER_
TO
O_S
MA
LL
0x8
029
040
6
CONSTANT/VALUE DESCRIPTION

An unexpected internal error has occurred in the Platform


TP Crypto Provider.
M_E
_PC
P_I
NTE
RN
AL_
ERR
OR
0x8
029
040
7

The authorization to use a provider object has failed.


TP
M_E
_PC
P_A
UT
HE
NTI
CAT
ION
_FAI
LED
0x8
029
040
8

The Platform Crypto Device has ignored the authorization for


TP the provider object, to mitigate against a dictionary attack.
M_E
_PC
P_A
UT
HE
NTI
CAT
ION
_IG
NO
RED
0x8
029
040
9
CONSTANT/VALUE DESCRIPTION

The referenced policy was not found.


TP
M_E
_PC
P_P
OLI
CY_
NO
T_F
OU
ND
0x8
029
040
A

The referenced profile was not found.


TP
M_E
_PC
P_P
ROF
ILE_
NO
T_F
OU
ND
0x8
029
040
B

The validation was not successful.


TP
M_E
_PC
P_V
ALI
DAT
ION
_FAI
LED
0x8
029
040
C
CONSTANT/VALUE DESCRIPTION

An attempt was made to import or load a key under an


TP incorrect storage parent.
M_E
_PC
P_
WR
ON
G_P
ARE
NT
0x8
029
040
E

The TPM key is not loaded.


TP
M_E
_KE
Y_N
OT_
LOA
DED
0x8
029
040
F

The TPM key certification has not been generated.


TP
M_E
_NO
_KE
Y_C
ERTI
FIC
ATI
ON
0x8
029
041
0

The TPM key is not yet finalized.


TP
M_E
_KE
Y_N
OT_
FIN
ALI
ZED
0x8
029
041
1
CONSTANT/VALUE DESCRIPTION

The TPM attestation challenge is not set.


TP
M_E
_AT
TES
TAT
ION
_CH
ALL
ENG
E_N
OT_
SET
0x8
029
041
2

The TPM PCR info is not available.


TP
M_E
_NO
T_P
CR_
BO
UN
D
0x8
029
041
3

The TPM key is already finalized.


TP
M_E
_KE
Y_A
LRE
AD
Y_FI
NAL
IZE
D
0x8
029
041
4
CONSTANT/VALUE DESCRIPTION

The TPM key usage policy is not supported.


TP
M_E
_KE
Y_U
SAG
E_P
OLI
CY_
NO
T_S
UPP
ORT
ED
0x8
029
041
5

The TPM key usage policy is invalid.


TP
M_E
_KE
Y_U
SAG
E_P
OLI
CY_I
NV
ALI
D
0x8
029
041
6

There was a problem with the software key being imported


TP into the TPM.
M_E
_SO
FT_
KEY
_ER
RO
R
0x8
029
041
7
CONSTANT/VALUE DESCRIPTION

The TPM key is not authenticated.


TP
M_E
_KE
Y_N
OT_
AUT
HE
NTI
CAT
ED
0x8
029
041
8

The TPM key is not an AIK.


TP
M_E
_PC
P_K
EY_
NO
T_AI
K
0x8
029
041
9

The TPM key is not a signing key.


TP
M_E
_KE
Y_N
OT_
SIG
NIN
G_K
EY
0x8
029
041
A

The TPM is locked out.


TP
M_E
_LO
CKE
D_O
UT
0x8
029
041
B
CONSTANT/VALUE DESCRIPTION

The claim type requested is not supported.


TP
M_E
_CL
AIM
_TY
PE_
NO
T_S
UPP
ORT
ED
0x8
029
041
C

TPM version is not supported.


TP
M_E
_VE
RSI
ON_
NO
T_S
UPP
ORT
ED
0x8
029
041
D

The buffer lengths do not match.


TP
M_E
_BU
FFE
R_L
ENG
TH_
MIS
MA
TCH
0x8
029
041
E
CONSTANT/VALUE DESCRIPTION

The RSA key creation is blocked on this TPM due to known


TP security vulnerabilities.
M_E
_PC
P_IF
X_R
SA_
KEY
_CR
EAT
ION
_BL
OC
KED
0x8
029
041
F

A ticket required to use a key was not provided.


TP
M_E
_PC
P_TI
CKE
T_M
ISSI
NG
0x8
029
042
0

This key has a raw policy so the KSP can't authenticate against
TP it.
M_E
_PC
P_R
AW
_PO
LIC
Y_N
OT_
SUP
PO
RTE
D
0x8
029
042
1
CONSTANT/VALUE DESCRIPTION

The TPM key's handle was unexpectedly invalidated due to a


TP hardware or firmware issue.
M_E
_PC
P_K
EY_
HA
NDL
E_IN
VAL
IDA
TED
0x8
029
042
2

The requested salt size for signing with RSAPSS does not
TP match what the TPM uses.
M_E
_PC
P_U
NS
UPP
ORT
ED_
PSS
_SA
LT
0x4
029
042
3

Validation of the platform claim failed.


TP
M_E
_PC
P_P
LAT
FOR
M_C
LAI
M_
MA
Y_B
E_O
UTD
ATE
D
0x4
029
042
4
CONSTANT/VALUE DESCRIPTION

The requested platform claim is for a previous boot.


TP
M_E
_PC
P_P
LAT
FOR
M_C
LAI
M_
OU
TDA
TED
0x4
029
042
5

The platform claim is for a previous boot, and cannot be


TP created without reboot.
M_E
_PC
P_P
LAT
FOR
M_C
LAI
M_R
EBO
OT
0x4
029
042
6

TPM related network operations are blocked as Zero Exhaust


TP mode is enabled on client.
M_E
_EX
HA
UST
_EN
ABL
ED
0x8
029
050
0
CONSTANT/VALUE DESCRIPTION

TPM provisioning did not run to completion.


TP
M_E
_PR
OVI
SIO
NIN
G_I
NC
OM
PLE
TE
0x8
029
060
0

An invalid owner authorization value was specified.


TP
M_E
_IN
VAL
ID_
OW
NER
_AU
TH
0x8
029
060
1

TPM command returned too much data.


TP
M_E
_TO
O_
MU
CH_
DAT
A
0x8
029
060
2

Data Collector Set was not found.


PLA
_E_
DCS
_NO
T_F
OU
ND
0x8
030
000
2
CONSTANT/VALUE DESCRIPTION

The Data Collector Set or one of its dependencies is already in


PLA use.
_E_
DCS
_IN_
USE
0x8
030
00A
A

Unable to start Data Collector Set because there are too many
PLA folders.
_E_T
OO_
MA
NY_
FOL
DER
S
0x8
030
004
5

Not enough free disk space to start Data Collector Set.


PLA
_E_
NO_
MIN
_DIS
K
0x8
030
007
0

Data Collector Set already exists.


PLA
_E_
DCS
_AL
REA
DY_
EXIS
TS
0x8
030
00B
7
CONSTANT/VALUE DESCRIPTION

Property value will be ignored.


PLA
_S_
PR
OPE
RTY
_IG
NO
RED
0x0
030
010
0

Property value conflict.


PLA
_E_P
RO
PER
TY_
CO
NFL
ICT
0x8
030
010
1

The current configuration for this Data Collector Set requires


PLA that it contain exactly one Data Collector.
_E_
DCS
_SI
NGL
ETO
N_R
EQU
IRE
D
0x8
030
010
2

A user account is required in order to commit the current


PLA Data Collector Set properties.
_E_C
RED
ENT
IAL
S_R
EQU
IRE
D
0x8
030
010
3
CONSTANT/VALUE DESCRIPTION

Data Collector Set is not running.


PLA
_E_
DCS
_NO
T_R
UN
NIN
G
0x8
030
010
4

A conflict was detected in the list of include/exclude APIs. Do


PLA not specify the same API in both the include list and the
_E_C exclude list.
ON
FLIC
T_I
NCL
_EX
CL_
API
0x8
030
010
5

The executable path you have specified refers to a network


PLA share or UNC path.
_E_
NET
WO
RK_
EXE
_NO
T_V
ALI
D
0x8
030
010
6
CONSTANT/VALUE DESCRIPTION

The executable path you have specified is already configured


PLA for API tracing.
_E_E
XE_
ALR
EAD
Y_C
ON
FIG
URE
D
0x8
030
010
7

The executable path you have specified does not exist. Verify
PLA that the specified path is correct.
_E_E
XE_
PAT
H_N
OT_
VAL
ID
0x8
030
010
8

Data Collector already exists.


PLA
_E_
DC_
ALR
EAD
Y_E
XIS
TS
0x8
030
010
9
CONSTANT/VALUE DESCRIPTION

The wait for the Data Collector Set start notification has timed
PLA out.
_E_
DCS
_ST
ART
_W
AIT_
TIM
EOU
T
0x8
030
010
A

The wait for the Data Collector to start has timed out.
PLA
_E_
DC_
STA
RT_
WAI
T_TI
ME
OU
T
0x8
030
010
B

The wait for the report generation tool to finish has timed out.
PLA
_E_R
EPO
RT_
WAI
T_TI
ME
OU
T
0x8
030
010
C
CONSTANT/VALUE DESCRIPTION

Duplicate items are not allowed.


PLA
_E_
NO_
DU
PLI
CAT
ES
0x8
030
010
D

When specifying the executable that you want to trace, you


PLA must specify a full path to the executable and not just a
_E_E filename.
XE_
FUL
L_P
AT
H_R
EQU
IRE
D
0x8
030
010
E

The session name provided is invalid.


PLA
_E_I
NV
ALI
D_S
ESSI
ON_
NA
ME
0x8
030
010
F
CONSTANT/VALUE DESCRIPTION

The Event Log channel Microsoft-Windows-Diagnosis-


PLA PLA/Operational must be enabled to perform this operation.
_E_P
LA_
CH
AN
NEL
_NO
T_E
NA
BLE
D
0x8
030
011
0

The Event Log channel Microsoft-Windows-TaskScheduler


PLA must be enabled to perform this operation.
_E_T
ASK
SCH
ED_
CH
AN
NEL
_NO
T_E
NA
BLE
D
0x8
030
011
1

The execution of the Rules Manager failed.


PLA
_E_R
ULE
S_M
AN
AGE
R_F
AILE
D
0x8
030
011
2
CONSTANT/VALUE DESCRIPTION

An error occurred while attempting to compress or extract the


PLA data.
_E_C
AB
API
_FAI
LUR
E
0x8
030
011
3

This drive is locked by BitLocker Drive Encryption. You must


FVE unlock this drive from Control Panel.
_E_L
OC
KED
_VO
LU
ME
0x8
031
000
0

The drive is not encrypted.


FVE
_E_
NO
T_E
NC
RYP
TED
0x8
031
000
1

The BIOS did not correctly communicate with the Trusted


FVE Platform Module (TPM). Contact the computer manufacturer
_E_ for BIOS upgrade instructions.
NO_
TP
M_B
IOS
0x8
031
000
2
CONSTANT/VALUE DESCRIPTION

The BIOS did not correctly communicate with the master boot
FVE record (MBR). Contact the computer manufacturer for BIOS
_E_ upgrade instructions.
NO_
MB
R_M
ETRI
C
0x8
031
000
3

A required TPM measurement is missing. If there is a bootable


FVE CD or DVD in your computer, remove it, restart the computer,
_E_ and turn on BitLocker again. If the problem persists, ensure
NO_ the master boot record is up to date.
BO
OTS
ECT
OR_
MET
RIC
0x8
031
000
4

The boot sector of this drive is not compatible with BitLocker


FVE Drive Encryption. Use the Bootrec.exe tool in the Windows
_E_ Recovery Environment to update or repair the boot manager
NO_ (BOOTMGR).
BO
OT
MG
R_M
ETRI
C
0x8
031
000
5

The boot manager of this operating system is not compatible


FVE with BitLocker Drive Encryption. Use the Bootrec.exe tool in
_E_ the Windows Recovery Environment to update or repair the
WR boot manager (BOOTMGR).
ON
G_B
OO
TM
GR
0x8
031
000
6
CONSTANT/VALUE DESCRIPTION

At least one secure key protector is required for this operation


FVE to be performed.
_E_S
ECU
RE_
KEY
_RE
QUI
RED
0x8
031
000
7

BitLocker Drive Encryption is not enabled on this drive. Turn


FVE on BitLocker.
_E_
NO
T_A
CTI
VAT
ED
0x8
031
000
8

BitLocker Drive Encryption cannot perform requested action.


FVE This condition may occur when two requests are issued at the
_E_ same time. Wait a few moments and then try the action again.
ACT
ION
_NO
T_A
LLO
WE
D
0x8
031
000
9

The Active Directory Domain Services forest does not contain


FVE the required attributes and classes to host BitLocker Drive
_E_ Encryption or Trusted Platform Module information. Contact
AD_ your domain administrator to verify that any required
SCH BitLocker Active Directory schema extensions have been
EM installed.
A_N
OT_
INS
TAL
LED
0x8
031
000
A
CONSTANT/VALUE DESCRIPTION

The type of the data obtained from Active Directory was not
FVE expected. The BitLocker recovery information may be missing
_E_ or corrupted.
AD_
INV
ALI
D_D
ATA
TYP
E
0x8
031
000
B

The size of the data obtained from Active Directory was not
FVE expected. The BitLocker recovery information may be missing
_E_ or corrupted.
AD_
INV
ALI
D_D
ATA
SIZE
0x8
031
000
C

The attribute read from Active Directory does not contain any
FVE values. The BitLocker recovery information may be missing or
_E_ corrupted.
AD_
NO_
VAL
UES
0x8
031
000
D

The attribute was not set. Verify that you are logged on with a
FVE domain account that has the ability to write information to
_E_ Active Directory objects.
AD_
ATT
R_N
OT_
SET
0x8
031
000
E
CONSTANT/VALUE DESCRIPTION

The specified attribute cannot be found in Active Directory


FVE Domain Services. Contact your domain administrator to verify
_E_ that any required BitLocker Active Directory schema
AD_ extensions have been installed.
GUI
D_N
OT_
FOU
ND
0x8
031
000
F

The BitLocker metadata for the encrypted drive is not valid.


FVE You can attempt to repair the drive to restore access.
_E_B
AD_
INF
OR
MA
TIO
N
0x8
031
001
0

The drive cannot be encrypted because it does not have


FVE enough free space. Delete any unnecessary data on the drive
_E_T to create additional free space and then try again.
OO_
SM
ALL
0x8
031
001
1

The drive cannot be encrypted because it contains system


FVE boot information. Create a separate partition for use as the
_E_S system drive that contains the boot information and a second
YST partition for use as the operating system drive and then
EM_ encrypt the operating system drive.
VOL
UM
E
0x8
031
001
2
CONSTANT/VALUE DESCRIPTION

The drive cannot be encrypted because the file system is not


FVE supported.
_E_F
AILE
D_
WR
ON
G_F
S
0x8
031
001
3

The file system size is larger than the partition size in the
FVE partition table. This drive may be corrupt or may have been
_E_B tampered with. To use it with BitLocker, you must reformat
AD_ the partition.
PAR
TITI
ON_
SIZE
0x8
031
001
4

This drive cannot be encrypted.


FVE
_E_
NO
T_S
UPP
ORT
ED
0x8
031
001
5

The data is not valid.


FVE
_E_B
AD_
DAT
A
0x8
031
001
6
CONSTANT/VALUE DESCRIPTION

The data drive specified is not set to automatically unlock on


FVE the current computer and cannot be unlocked automatically.
_E_V
OLU
ME_
NO
T_B
OU
ND
0x8
031
001
7

You must initialize the Trusted Platform Module (TPM) before


FVE you can use BitLocker Drive Encryption.
_E_T
PM_
NO
T_O
WN
ED
0x8
031
001
8

The operation attempted cannot be performed on an


FVE operating system drive.
_E_
NO
T_D
ATA
_VO
LU
ME
0x8
031
001
9

The buffer supplied to a function was insufficient to contain


FVE the returned data. Increase the buffer size before running the
_E_ function again.
AD_
INS
UFFI
CIE
NT_
BUF
FER
0x8
031
001
A
CONSTANT/VALUE DESCRIPTION

A read operation failed while converting the drive. The drive


FVE was not converted. Please re-enable BitLocker.
_E_C
ON
V_R
EAD
0x8
031
001
B

A write operation failed while converting the drive. The drive


FVE was not converted. Please re-enable BitLocker.
_E_C
ON
V_
WRI
TE
0x8
031
001
C

One or more BitLocker key protectors are required. You


FVE cannot delete the last key on this drive.
_E_K
EY_
REQ
UIR
ED
0x8
031
001
D

Cluster configurations are not supported by BitLocker Drive


FVE Encryption.
_E_C
LUS
TERI
NG_
NO
T_S
UPP
ORT
ED
0x8
031
001
E
CONSTANT/VALUE DESCRIPTION

The drive specified is already configured to be automatically


FVE unlocked on the current computer.
_E_V
OLU
ME_
BO
UN
D_A
LRE
AD
Y
0x8
031
001
F

The operating system drive is not protected by BitLocker Drive


FVE Encryption.
_E_
OS_
NO
T_P
ROT
ECT
ED
0x8
031
002
0

BitLocker Drive Encryption has been suspended on this drive.


FVE All BitLocker key protectors configured for this drive are
_E_P effectively disabled, and the drive will be automatically
ROT unlocked using an unencrypted (clear) key.
ECTI
ON_
DIS
ABL
ED
0x8
031
002
1

The drive you are attempting to lock does not have any key
FVE protectors available for encryption because BitLocker
_E_R protection is currently suspended. Re-enable BitLocker to lock
ECO this drive.
VER
Y_K
EY_
REQ
UIR
ED
0x8
031
002
2
CONSTANT/VALUE DESCRIPTION

BitLocker cannot use the Trusted Platform Module (TPM) to


FVE protect a data drive. TPM protection can only be used with
_E_F the operating system drive.
ORE
IGN
_VO
LU
ME
0x8
031
002
3

The BitLocker metadata for the encrypted drive cannot be


FVE updated because it was locked for updating by another
_E_ process. Please try this process again.
OVE
RLA
PPE
D_U
PD
ATE
0x8
031
002
4

The authorization data for the storage root key (SRK) of the
FVE Trusted Platform Module (TPM) is not zero and is therefore
_E_T incompatible with BitLocker. Please initialize the TPM before
PM_ attempting to use it with BitLocker.
SRK
_AU
TH_
NO
T_Z
ERO
0x8
031
002
5

The drive encryption algorithm cannot be used on this sector


FVE size.
_E_F
AILE
D_S
ECT
OR_
SIZE
0x8
031
002
6
CONSTANT/VALUE DESCRIPTION

The drive cannot be unlocked with the key provided. Confirm


FVE that you have provided the correct key and try again.
_E_F
AILE
D_A
UT
HE
NTI
CAT
ION
0x8
031
002
7

The drive specified is not the operating system drive.


FVE
_E_
NO
T_O
S_V
OLU
ME
0x8
031
002
8

BitLocker Drive Encryption cannot be turned off on the


FVE operating system drive until the auto unlock feature has been
_E_ disabled for the fixed data drives and removable data drives
AUT associated with this computer.
OU
NL
OC
K_E
NA
BLE
D
0x8
031
002
9

The system partition boot sector does not perform Trusted


FVE Platform Module (TPM) measurements. Use the Bootrec.exe
_E_ tool in the Windows Recovery Environment to update or
WR repair the boot sector.
ON
G_B
OO
TSE
CTO
R
0x8
031
002
A
CONSTANT/VALUE DESCRIPTION

BitLocker Drive Encryption operating system drives must be


FVE formatted with the NTFS file system in order to be encrypted.
_E_ Convert the drive to NTFS, and then turn on BitLocker.
WR
ON
G_S
YST
EM_
FS
0x8
031
002
B

Group Policy settings require that a recovery password be


FVE specified before encrypting the drive.
_E_P
OLI
CY_
PAS
SW
OR
D_R
EQU
IRE
D
0x8
031
002
C

The drive encryption algorithm and key cannot be set on a


FVE previously encrypted drive. To encrypt this drive with
_E_C BitLocker Drive Encryption, remove the previous encryption
AN and then turn on BitLocker.
NO
T_S
ET_F
VEK
_EN
CRY
PTE
D
0x8
031
002
D
CONSTANT/VALUE DESCRIPTION

BitLocker Drive Encryption cannot encrypt the specified drive


FVE because an encryption key is not available. Add a key
_E_C protector to encrypt this drive.
AN
NO
T_E
NC
RYP
T_N
O_K
EY
0x8
031
002
E

BitLocker Drive Encryption detected bootable media (CD or


FVE DVD) in the computer. Remove the media and restart the
_E_B computer before configuring BitLocker.
OO
TAB
LE_
CD
DV
D
0x8
031
003
0

This key protector cannot be added. Only one key protector of


FVE this type is allowed for this drive.
_E_P
ROT
ECT
OR_
EXIS
TS
0x8
031
003
1

The recovery password file was not found because a relative


FVE path was specified. Recovery passwords must be saved to a
_E_R fully qualified path. Environment variables configured on the
ELA computer can be used in the path.
TIVE
_PA
TH
0x8
031
003
2
CONSTANT/VALUE DESCRIPTION

The specified key protector was not found on the drive. Try
FVE another key protector.
_E_P
ROT
ECT
OR_
NO
T_F
OU
ND
0x8
031
003
3

The recovery key provided is corrupt and cannot be used to


FVE access the drive. An alternative recovery method, such as
_E_I recovery password, a data recovery agent, or a backup
NV version of the recovery key must be used to recover access to
ALI the drive.
D_K
EY_
FOR
MA
T
0x8
031
003
4

The format of the recovery password provided is invalid.


FVE BitLocker recovery passwords are 48 digits. Verify that the
_E_I recovery password is in the correct format and then try again.
NV
ALI
D_P
ASS
WO
RD_
FOR
MA
T
0x8
031
003
5
CONSTANT/VALUE DESCRIPTION

The random number generator check test failed.


FVE
_E_F
IPS_
RN
G_C
HEC
K_F
AILE
D
0x8
031
003
6

The Group Policy setting requiring FIPS compliance prevents a


FVE local recovery password from being generated or used by
_E_F BitLocker Drive Encryption. When operating in FIPS-compliant
IPS_ mode, BitLocker recovery options can be either a recovery key
PRE stored on a USB drive or recovery through a data recovery
VEN agent.
TS_
REC
OVE
RY_
PAS
SW
OR
D
0x8
031
003
7

The Group Policy setting requiring FIPS compliance prevents


FVE the recovery password from being saved to Active Directory.
_E_F When operating in FIPS-compliant mode, BitLocker recovery
IPS_ options can be either a recovery key stored on a USB drive or
PRE recovery through a data recovery agent. Check your Group
VEN Policy settings configuration.
TS_
EXT
ERN
AL_
KEY
_EX
PO
RT
0x8
031
003
8
CONSTANT/VALUE DESCRIPTION

The drive must be fully decrypted to complete this operation.


FVE
_E_
NO
T_D
ECR
YPT
ED
0x8
031
003
9

The key protector specified cannot be used for this operation.


FVE
_E_I
NV
ALI
D_P
ROT
ECT
OR_
TYP
E
0x8
031
003
A

No key protectors exist on the drive to perform the hardware


FVE test.
_E_
NO_
PR
OTE
CTO
RS_
TO_
TES
T
0x8
031
003
B

The BitLocker startup key or recovery password cannot be


FVE found on the USB device. Verify that you have the correct USB
_E_K device, that the USB device is plugged into the computer on
EYFI an active USB port, restart the computer, and then try again.
LE_ If the problem persists, contact the computer manufacturer
NO for BIOS upgrade instructions.
T_F
OU
ND
0x8
031
003
C
CONSTANT/VALUE DESCRIPTION

The BitLocker startup key or recovery password file provided


FVE is corrupt or invalid. Verify that you have the correct startup
_E_K key or recovery password file and try again.
EYFI
LE_I
NV
ALI
D
0x8
031
003
D

The BitLocker encryption key cannot be obtained from the


FVE startup key or recovery password. Verify that you have the
_E_K correct startup key or recovery password and try again.
EYFI
LE_
NO_
VM
K
0x8
031
003
E

The Trusted Platform Module (TPM) is disabled. The TPM must


FVE be enabled, initialized, and have valid ownership before it can
_E_T be used with BitLocker Drive Encryption.
PM_
DIS
ABL
ED
0x8
031
003
F

The BitLocker configuration of the specified drive cannot be


FVE managed because this computer is currently operating in Safe
_E_ Mode. While in Safe Mode, BitLocker Drive Encryption can
NO only be used for recovery purposes.
T_A
LLO
WE
D_I
N_S
AFE
_M
ODE
0x8
031
004
0
CONSTANT/VALUE DESCRIPTION

The Trusted Platform Module (TPM) was not able to unlock


FVE the drive because the system boot information has changed
_E_T or a PIN was not provided correctly. Verify that the drive has
PM_ not been tampered with and that changes to the system boot
INV information were caused by a trusted source. After verifying
ALI that the drive is safe to access, use the BitLocker recovery
D_P console to unlock the drive and then suspend and resume
CR BitLocker to update system boot information that BitLocker
0x8 associates with this drive.
031
004
1

The BitLocker encryption key cannot be obtained from the


FVE Trusted Platform Module (TPM).
_E_T
PM_
NO_
VM
K
0x8
031
004
2

The BitLocker encryption key cannot be obtained from the


FVE Trusted Platform Module (TPM) and PIN.
_E_P
IN_I
NV
ALI
D
0x8
031
004
3

A boot application has changed since BitLocker Drive


FVE Encryption was enabled.
_E_
AUT
H_I
NV
ALI
D_A
PPL
ICA
TIO
N
0x8
031
004
4
CONSTANT/VALUE DESCRIPTION

The Boot Configuration Data (BCD) settings have changed


FVE since BitLocker Drive Encryption was enabled.
_E_
AUT
H_I
NV
ALI
D_C
ON
FIG
0x8
031
004
5

The Group Policy setting requiring FIPS compliance prohibits


FVE the use of unencrypted keys, which prevents BitLocker from
_E_F being suspended on this drive. Please contact your domain
IPS_ administrator for more information.
DIS
ABL
E_P
ROT
ECTI
ON_
NO
T_A
LLO
WE
D
0x8
031
004
6

This drive cannot be encrypted by BitLocker Drive Encryption


FVE because the file system does not extend to the end of the
_E_F drive. Repartition this drive and then try again.
S_N
OT_
EXT
END
ED
0x8
031
004
7
CONSTANT/VALUE DESCRIPTION

BitLocker Drive Encryption cannot be enabled on the


FVE operating system drive. Contact the computer manufacturer
_E_F for BIOS upgrade instructions.
IRM
WA
RE_
TYP
E_N
OT_
SUP
PO
RTE
D
0x8
031
004
8

This version of Windows does not include BitLocker Drive


FVE Encryption. To use BitLocker Drive Encryption, please upgrade
_E_ the operating system.
NO_
LICE
NSE
0x8
031
004
9

BitLocker Drive Encryption cannot be used because critical


FVE BitLocker system files are missing or corrupted. Use Windows
_E_ Startup Repair to restore these files to your computer.
NO
T_O
N_S
TAC
K
0x8
031
004
A

The drive cannot be locked when the drive is in use.


FVE
_E_F
S_M
OU
NTE
D
0x8
031
004
B
CONSTANT/VALUE DESCRIPTION

The access token associated with the current thread is not an


FVE impersonated token.
_E_T
OKE
N_N
OT_
IMP
ERS
ON
ATE
D
0x8
031
004
C

The BitLocker encryption key cannot be obtained. Verify that


FVE the Trusted Platform Module (TPM) is enabled and ownership
_E_ has been taken. If this computer does not have a TPM, verify
DRY that the USB drive is inserted and available.
_RU
N_F
AILE
D
0x8
031
004
D

You must restart your computer before continuing with


FVE BitLocker Drive Encryption.
_E_R
EBO
OT_
REQ
UIR
ED
0x8
031
004
E

Drive encryption cannot occur while boot debugging is


FVE enabled. Use the bcdedit command-line tool to turn off boot
_E_ debugging.
DEB
UG
GER
_EN
ABL
ED
0x8
031
004
F
CONSTANT/VALUE DESCRIPTION

No action was taken as BitLocker Drive Encryption is in raw


FVE access mode.
_E_R
AW
_AC
CES
S
0x8
031
005
0

BitLocker Drive Encryption cannot enter raw access mode for


FVE this drive because the drive is currently in use.
_E_R
AW
_BL
OC
KED
0x8
031
005
1

The path specified in the Boot Configuration Data (BCD) for a


FVE BitLocker Drive Encryption integrity-protected application is
_E_B incorrect. Please verify and correct your BCD settings and try
CD_ again.
APP
LIC
ATI
ON
S_P
AT
H_I
NC
OR
REC
T
0x8
031
005
2
CONSTANT/VALUE DESCRIPTION

BitLocker Drive Encryption can only be used for limited


FVE provisioning or recovery purposes when the computer is
_E_ running in pre-installation or recovery environments.
NO
T_A
LLO
WE
D_I
N_V
ERSI
ON
0x8
031
005
3

The auto-unlock master key was not available from the


FVE operating system drive.
_E_
NO_
AUT
OU
NL
OC
K_M
AST
ER_
KEY
0x8
031
005
4

The system firmware failed to enable clearing of system


FVE memory when the computer was restarted.
_E_
MO
R_F
AILE
D
0x8
031
005
5

The hidden drive cannot be encrypted.


FVE
_E_
HID
DEN
_VO
LU
ME
0x8
031
005
6
CONSTANT/VALUE DESCRIPTION

BitLocker encryption keys were ignored because the drive was


FVE in a transient state.
_E_T
RA
NSI
ENT
_ST
ATE
0x8
031
005
7

Public key based protectors are not allowed on this drive.


FVE
_E_P
UBK
EY_
NO
T_A
LLO
WE
D
0x8
031
005
8

BitLocker Drive Encryption is already performing an operation


FVE on this drive. Please complete all operations before continuing.
_E_V
OLU
ME_
HA
NDL
E_O
PEN
0x8
031
005
9

This version of Windows does not support this feature of


FVE BitLocker Drive Encryption. To use this feature, upgrade the
_E_ operating system.
NO_
FEA
TUR
E_LI
CEN
SE
0x8
031
005
A
CONSTANT/VALUE DESCRIPTION

The Group Policy settings for BitLocker startup options are in


FVE conflict and cannot be applied. Contact your system
_E_I administrator for more information.
NV
ALI
D_S
TAR
TUP
_OP
TIO
NS
0x8
031
005
B

Group policy settings do not permit the creation of a recovery


FVE password.
_E_P
OLI
CY_
REC
OVE
RY_
PAS
SW
OR
D_N
OT_
ALL
OW
ED
0x8
031
005
C

Group policy settings require the creation of a recovery


FVE password.
_E_P
OLI
CY_
REC
OVE
RY_
PAS
SW
OR
D_R
EQU
IRE
D
0x8
031
005
D
CONSTANT/VALUE DESCRIPTION

Group policy settings do not permit the creation of a recovery


FVE key.
_E_P
OLI
CY_
REC
OVE
RY_
KEY
_NO
T_A
LLO
WE
D
0x8
031
005
E

Group policy settings require the creation of a recovery key.


FVE
_E_P
OLI
CY_
REC
OVE
RY_
KEY
_RE
QUI
RED
0x8
031
005
F

Group policy settings do not permit the use of a PIN at


FVE startup. Please choose a different BitLocker startup option.
_E_P
OLI
CY_
STA
RTU
P_PI
N_N
OT_
ALL
OW
ED
0x8
031
006
0
CONSTANT/VALUE DESCRIPTION

Group policy settings require the use of a PIN at startup.


FVE Please choose this BitLocker startup option.
_E_P
OLI
CY_
STA
RTU
P_PI
N_R
EQU
IRE
D
0x8
031
006
1

Group policy settings do not permit the use of a startup key.


FVE Please choose a different BitLocker startup option.
_E_P
OLI
CY_
STA
RTU
P_K
EY_
NO
T_A
LLO
WE
D
0x8
031
006
2

Group policy settings require the use of a startup key. Please


FVE choose this BitLocker startup option.
_E_P
OLI
CY_
STA
RTU
P_K
EY_
REQ
UIR
ED
0x8
031
006
3
CONSTANT/VALUE DESCRIPTION

Group policy settings do not permit the use of a startup key


FVE and PIN. Please choose a different BitLocker startup option.
_E_P
OLI
CY_
STA
RTU
P_PI
N_K
EY_
NO
T_A
LLO
WE
D
0x8
031
006
4

Group policy settings require the use of a startup key and


FVE PIN. Please choose this BitLocker startup option.
_E_P
OLI
CY_
STA
RTU
P_PI
N_K
EY_
REQ
UIR
ED
0x8
031
006
5

Group policy does not permit the use of TPM-only at startup.


FVE Please choose a different BitLocker startup option.
_E_P
OLI
CY_
STA
RTU
P_T
PM_
NO
T_A
LLO
WE
D
0x8
031
006
6
CONSTANT/VALUE DESCRIPTION

Group policy settings require the use of TPM-only at startup.


FVE Please choose this BitLocker startup option.
_E_P
OLI
CY_
STA
RTU
P_T
PM_
REQ
UIR
ED
0x8
031
006
7

The PIN provided does not meet minimum or maximum


FVE length requirements.
_E_P
OLI
CY_I
NV
ALI
D_P
IN_L
ENG
TH
0x8
031
006
8

The key protector is not supported by the version of BitLocker


FVE Drive Encryption currently on the drive. Upgrade the drive to
_E_K add the key protector.
EY_
PR
OTE
CTO
R_N
OT_
SUP
PO
RTE
D
0x8
031
006
9
CONSTANT/VALUE DESCRIPTION

Group policy settings do not permit the creation of a


FVE password.
_E_P
OLI
CY_
PAS
SPH
RAS
E_N
OT_
ALL
OW
ED
0x8
031
006
A

Group policy settings require the creation of a password.


FVE
_E_P
OLI
CY_
PAS
SPH
RAS
E_R
EQU
IRE
D
0x8
031
006
B

The group policy setting requiring FIPS compliance prevented


FVE the password from being generated or used. Please contact
_E_F your domain administrator for more information.
IPS_
PRE
VEN
TS_
PAS
SPH
RAS
E
0x8
031
006
C
CONSTANT/VALUE DESCRIPTION

A password cannot be added to the operating system drive.


FVE
_E_
OS_
VOL
UM
E_P
ASS
PH
RAS
E_N
OT_
ALL
OW
ED
0x8
031
006
D

The BitLocker object identifier (OID) on the drive appears to


FVE be invalid or corrupt. Use manage-BDE to reset the OID on
_E_I this drive.
NV
ALI
D_B
ITL
OC
KER
_OI
D
0x8
031
006
E

The drive is too small to be protected using BitLocker Drive


FVE Encryption.
_E_V
OLU
ME_
TO
O_S
MA
LL
0x8
031
006
F
CONSTANT/VALUE DESCRIPTION

The selected discovery drive type is incompatible with the file


FVE system on the drive. BitLocker To Go discovery drives must be
_E_ created on FAT formatted drives.
DV_
NO
T_S
UPP
ORT
ED_
ON_
FS
0x8
031
007
0

The selected discovery drive type is not allowed by the


FVE computer's Group Policy settings. Verify that Group Policy
_E_ settings allow the creation of discovery drives for use with
DV_ BitLocker To Go.
NO
T_A
LLO
WE
D_B
Y_G
P
0x8
031
007
1

Group Policy settings do not permit user certificates such as


FVE smart cards to be used with BitLocker Drive Encryption.
_E_P
OLI
CY_
USE
R_C
ERTI
FIC
ATE
_NO
T_A
LLO
WE
D
0x8
031
007
2
CONSTANT/VALUE DESCRIPTION

Group Policy settings require that you have a valid user


FVE certificate, such as a smart card, to be used with BitLocker
_E_P Drive Encryption.
OLI
CY_
USE
R_C
ERTI
FIC
ATE
_RE
QUI
RED
0x8
031
007
3

Group Policy settings requires that you use a smart card-


FVE based key protector with BitLocker Drive Encryption.
_E_P
OLI
CY_
USE
R_C
ERT
_M
UST
_BE_
HW
0x8
031
007
4
CONSTANT/VALUE DESCRIPTION

Group Policy settings do not permit BitLocker-protected fixed


FVE data drives to be automatically unlocked.
_E_P
OLI
CY_
USE
R_C
ON
FIG
URE
_FD
V_A
UT
OU
NL
OC
K_N
OT_
ALL
OW
ED
0x8
031
007
5

Group Policy settings do not permit BitLocker-protected


FVE removable data drives to be automatically unlocked.
_E_P
OLI
CY_
USE
R_C
ON
FIG
URE
_RD
V_A
UT
OU
NL
OC
K_N
OT_
ALL
OW
ED
0x8
031
007
6
CONSTANT/VALUE DESCRIPTION

Group Policy settings do not permit you to configure


FVE BitLocker Drive Encryption on removable data drives.
_E_P
OLI
CY_
USE
R_C
ON
FIG
URE
_RD
V_N
OT_
ALL
OW
ED
0x8
031
007
7

Group Policy settings do not permit you to turn on BitLocker


FVE Drive Encryption on removable data drives. Please contact
_E_P your system administrator if you need to turn on BitLocker.
OLI
CY_
USE
R_E
NA
BLE
_RD
V_N
OT_
ALL
OW
ED
0x8
031
007
8
CONSTANT/VALUE DESCRIPTION

Group Policy settings do not permit turning off BitLocker


FVE Drive Encryption on removable data drives. Please contact
_E_P your system administrator if you need to turn off BitLocker.
OLI
CY_
USE
R_D
ISA
BLE
_RD
V_N
OT_
ALL
OW
ED
0x8
031
007
9

Your password does not meet minimum password length


FVE requirements. By default, passwords must be at least 8
_E_P characters in length. Check with your system administrator for
OLI the password length requirement in your organization.
CY_I
NV
ALI
D_P
ASS
PH
RAS
E_LE
NG
TH
0x8
031
008
0

Your password does not meet the complexity requirements


FVE set by your system administrator. Try adding upper and
_E_P lowercase characters, numbers, and symbols.
OLI
CY_
PAS
SPH
RAS
E_T
OO_
SIM
PLE
0x8
031
008
1
CONSTANT/VALUE DESCRIPTION

This drive cannot be encrypted because it is reserved for


FVE Windows System Recovery Options.
_E_R
ECO
VER
Y_P
ART
ITIO
N
0x8
031
008
2

BitLocker Drive Encryption cannot be applied to this drive


FVE because of conflicting Group Policy settings. BitLocker cannot
_E_P be configured to automatically unlock fixed data drives when
OLI user recovery options are disabled. If you want BitLocker-
CY_ protected fixed data drives to be automatically unlocked after
CO key validation has occurred, please ask your system
NFL administrator to resolve the settings conflict before enabling
ICT_ BitLocker.
FDV
_RK
_OF
F_A
UK_
ON
0x8
031
008
3

BitLocker Drive Encryption cannot be applied to this drive


FVE because of conflicting Group Policy settings. BitLocker cannot
_E_P be configured to automatically unlock removable data drives
OLI when user recovery option are disabled. If you want
CY_ BitLocker-protected removable data drives to be automatically
CO unlocked after key validation has occured, please ask your
NFL system administrator to resolve the settings conflict before
ICT_ enabling BitLocker.
RDV
_RK
_OF
F_A
UK_
ON
0x8
031
008
4
CONSTANT/VALUE DESCRIPTION

The Enhanced Key Usage (EKU) attribute of the specified


FVE certificate does not permit it to be used for BitLocker Drive
_E_ Encryption. BitLocker does not require that a certificate have
NO an EKU attribute, but if one is configured it must be set to an
N_B object identifier (OID) that matches the OID configured for
ITL BitLocker.
OC
KER
_OI
D
0x8
031
008
5

BitLocker Drive Encryption cannot be applied to this drive as


FVE currently configured because of Group Policy settings. The
_E_P certificate you provided for drive encryption is self-signed.
OLI Current Group Policy settings do not permit the use of self-
CY_ signed certificates. Obtain a new certificate from your
PR certification authority before attempting to enable BitLocker.
OHI
BIT
S_S
ELF
SIG
NED
0x8
031
008
6

BitLocker Encryption cannot be applied to this drive because


FVE of conflicting Group Policy settings. When write access to
_E_P drives not protected by BitLocker is denied, the use of a USB
OLI startup key cannot be required. Please have your system
CY_ administrator resolve these policy conflicts before attempting
CO to enable BitLocker.
NFL
ICT_
RO_
AN
D_S
TAR
TUP
_KE
Y_R
EQU
IRE
D
0x8
031
008
7
CONSTANT/VALUE DESCRIPTION

BitLocker Drive Encryption cannot be applied to this drive


FVE because there are conflicting Group Policy settings for
_E_C recovery options on operating system drives. Storing recovery
ON information to Active Directory Domain Services cannot be
V_R required when the generation of recovery passwords is not
ECO permitted. Please have your system administrator resolve
VER these policy conflicts before attempting to enable BitLocker.
Y_F
AILE
D
0x8
031
008
8

The requested virtualization size is too big.


FVE
_E_V
IRT
UAL
IZE
D_S
PAC
E_T
OO_
BIG
0x8
031
008
9

BitLocker Drive Encryption cannot be applied to this drive


FVE because there are conflicting Group Policy settings for
_E_P recovery options on operating system drives. Storing recovery
OLI information to Active Directory Domain Services cannot be
CY_ required when the generation of recovery passwords is not
CO permitted. Please have your system administrator resolve
NFL these policy conflicts before attempting to enable BitLocker.
ICT_
OSV
_RP
_OF
F_A
DB_
ON
0x8
031
009
0
CONSTANT/VALUE DESCRIPTION

BitLocker Drive Encryption cannot be applied to this drive


FVE because there are conflicting Group Policy settings for
_E_P recovery options on fixed data drives. Storing recovery
OLI information to Active Directory Domain Services cannot be
CY_ required when the generation of recovery passwords is not
CO permitted. Please have your system administrator resolve
NFL these policy conflicts before attempting to enable BitLocker.
ICT_
FDV
_RP
_OF
F_A
DB_
ON
0x8
031
009
1

BitLocker Drive Encryption cannot be applied to this drive


FVE because there are conflicting Group Policy settings for
_E_P recovery options on removable data drives. Storing recovery
OLI information to Active Directory Domain Services cannot be
CY_ required when the generation of recovery passwords is not
CO permitted. Please have your system administrator resolve
NFL these policy conflicts before attempting to enable BitLocker.
ICT_
RDV
_RP
_OF
F_A
DB_
ON
0x8
031
009
2

The Key Usage (KU) attribute of the specified certificate does


FVE not permit it to be used for BitLocker Drive Encryption.
_E_ BitLocker does not require that a certificate have a KU
NO attribute, but if one is configured it must be set to either Key
N_B Encipherment or Key Agreement.
ITL
OC
KER
_KU
0x8
031
009
3
CONSTANT/VALUE DESCRIPTION

The private key associated with the specified certificate cannot


FVE be authorized. The private key authorization was either not
_E_P provided or the provided authorization was invalid.
RIV
ATE
KEY
_AU
TH_
FAIL
ED
0x8
031
009
4

Removal of the data recovery agent certificate must be done


FVE using the Certificates snap-in.
_E_R
EM
OV
AL_
OF_
DR
A_F
AILE
D
0x8
031
009
5

This drive was encrypted using the version of BitLocker Drive


FVE Encryption included with Windows Vista and Windows Server
_E_ 2008 which does not support organizational identifiers. To
OPE specify organizational identifiers for this drive upgrade the
RAT drive encryption to the latest version using the "manage-bde
ION -upgrade" command.
_NO
T_S
UPP
ORT
ED_
ON_
VIS
TA_
VOL
UM
E
0x8
031
009
6
CONSTANT/VALUE DESCRIPTION

The drive cannot be locked because it is automatically


FVE unlocked on this computer. Remove the automatic unlock
_E_C protector to lock this drive.
AN
T_L
OC
K_A
UT
OU
NL
OC
K_E
NA
BLE
D_V
OLU
ME
0x8
031
009
7

The default Bitlocker Key Derivation Function SP800-56A for


FVE ECC smart cards is not supported by your smart card. The
_E_F Group Policy setting requiring FIPS-compliance prevents
IPS_ BitLocker from using any other key derivation function for
HA encryption. You have to use a FIPS compliant smart card in
SH_ FIPS restricted environments.
KDF
_NO
T_A
LLO
WE
D
0x8
031
009
8

The BitLocker encryption key could not be obtained from the


FVE Trusted Platform Module (TPM) and enhanced PIN. Try using a
_E_E PIN containing only numerals.
NH_
PIN
_IN
VAL
ID
0x8
031
009
9
CONSTANT/VALUE DESCRIPTION

The requested TPM PIN contains invalid characters.


FVE
_E_I
NV
ALI
D_P
IN_
CH
ARS
0x8
031
009
A

The management information stored on the drive contained


FVE an unknown type. If you are using an old version of Windows,
_E_I try accessing the drive from the latest version.
NV
ALI
D_D
ATU
M_T
YPE
0x8
031
009
B

The feature is only supported on EFI systems.


FVE
_E_E
FI_O
NLY
0x8
031
009
C

More than one Network Key Protector certificate has been


FVE found on the system.
_E_
MU
LTIP
LE_
NK
P_C
ERT
S
0x8
031
009
D
CONSTANT/VALUE DESCRIPTION

Removal of the Network Key Protector certificate must be


FVE done using the Certificates snap-in.
_E_R
EM
OV
AL_
OF_
NK
P_F
AILE
D
0x8
031
009
E

An invalid certificate has been found in the Network Key


FVE Protector certificate store.
_E_I
NV
ALI
D_N
KP_
CER
T
0x8
031
009
F

This drive isn't protected with a PIN.


FVE
_E_
NO_
EXIS
TIN
G_P
IN
0x8
031
00A
0
CONSTANT/VALUE DESCRIPTION

Please enter the correct current PIN.


FVE
_E_P
ROT
ECT
OR_
CH
AN
GE_
PIN
_MI
SM
ATC
H
0x8
031
00A
1

You must be logged on with an administrator account to


FVE change the PIN or password. Click the link to reset the PIN or
_E_P password as an administrator.
ROT
ECT
OR_
CH
AN
GE_
BY_
STD
_US
ER_
DIS
ALL
OW
ED
0x8
031
00A
2
CONSTANT/VALUE DESCRIPTION

BitLocker has disabled PIN and password changes after too


FVE many failed requests. Click the link to reset the PIN or
_E_P password as an administrator.
ROT
ECT
OR_
CH
AN
GE_
MA
X_PI
N_C
HA
NGE
_AT
TEM
PTS
_RE
AC
HED
0x8
031
00A
3

Your system administrator requires that passwords contain


FVE only printable ASCII characters. This includes unaccented
_E_P letters (A-Z, a-z), numbers (0-9), space, arithmetic signs,
OLI common punctuation, separators, and the following symbols:
CY_ #$&@^_~.
PAS
SPH
RAS
E_R
EQU
IRES
_AS
CII
0x8
031
00A
4
CONSTANT/VALUE DESCRIPTION

BitLocker Drive Encryption only supports used space only


FVE encryption on thin provisioned storage.
_E_F
ULL
_EN
CRY
PTI
ON_
NO
T_A
LLO
WE
D_O
N_T
P_S
TOR
AGE
0x8
031
00A
5

BitLocker Drive Encryption does not support wiping free space


FVE on thin provisioned storage.
_E_
WIP
E_N
OT_
ALL
OW
ED_
ON_
TP_
STO
RA
GE
0x8
031
00A
6
CONSTANT/VALUE DESCRIPTION

The required authentication key length is not supported by


FVE the drive.
_E_K
EY_
LEN
GT
H_N
OT_
SUP
PO
RTE
D_B
Y_E
DRI
VE
0x8
031
00A
7

This drive isn't protected with a password.


FVE
_E_
NO_
EXIS
TIN
G_P
ASS
PH
RAS
E
0x8
031
00A
8

Please enter the correct current password.


FVE
_E_P
ROT
ECT
OR_
CH
AN
GE_
PAS
SPH
RAS
E_M
ISM
ATC
H
0x8
031
00A
9
CONSTANT/VALUE DESCRIPTION

The password cannot exceed 256 characters.


FVE
_E_P
ASS
PH
RAS
E_T
OO_
LO
NG
0x8
031
00A
A

A password key protector cannot be added because a TPM


FVE protector exists on the drive.
_E_
NO_
PAS
SPH
RAS
E_W
ITH
_TP
M
0x8
031
00A
B

A TPM key protector cannot be added because a password


FVE protector exists on the drive.
_E_
NO_
TP
M_
WIT
H_P
ASS
PH
RAS
E
0x8
031
00A
C
CONSTANT/VALUE DESCRIPTION

This command can only be performed from the coordinator


FVE node for the specified CSV volume.
_E_
NO
T_A
LLO
WE
D_O
N_C
SV_
STA
CK
0x8
031
00A
D

This command cannot be performed on a volume when it is


FVE part of a cluster.
_E_
NO
T_A
LLO
WE
D_O
N_C
LUS
TER
0x8
031
00A
E

BitLocker did not revert to using BitLocker software


FVE encryption due to group policy configuration.
_E_E
DRI
VE_
NO_
FAIL
OVE
R_T
O_S
W
0x8
031
00A
F
CONSTANT/VALUE DESCRIPTION

The drive cannot be managed by BitLocker because the drive's


FVE hardware encryption feature is already in use.
_E_E
DRI
VE_
BA
ND_
IN_
USE
0x8
031
00B
0

Group Policy settings do not allow the use of hardware-based


FVE encryption.
_E_E
DRI
VE_
DIS
ALL
OW
ED_
BY_
GP
0x8
031
00B
1

The drive specified does not support hardware-based


FVE encryption.
_E_E
DRI
VE_I
NC
OM
PAT
IBLE
_VO
LU
ME
0x8
031
00B
2
CONSTANT/VALUE DESCRIPTION

BitLocker cannot be upgraded during disk encryption or


FVE decryption.
_E_
NO
T_A
LLO
WE
D_T
O_U
PGR
ADE
_W
HIL
E_C
ON
VER
TIN
G
0x8
031
00B
3

Discovery Volumes are not supported for volumes using


FVE hardware encryption.
_E_E
DRI
VE_
DV_
NO
T_S
UPP
ORT
ED
0x8
031
00B
4

No pre-boot keyboard detected. The user may not be able to


FVE provide required input to unlock the volume.
_E_
NO_
PRE
BO
OT_
KEY
BO
AR
D_D
ETE
CTE
D
0x8
031
00B
5
CONSTANT/VALUE DESCRIPTION

No pre-boot keyboard or Windows Recovery Environment


FVE detected. The user may not be able to provide required input
_E_ to unlock the volume.
NO_
PRE
BO
OT_
KEY
BO
AR
D_O
R_
WI
NRE
_DE
TEC
TED
0x8
031
00B
6

Group Policy settings require the creation of a startup PIN,


FVE but a pre-boot keyboard is not available on this device. The
_E_P user may not be able to provide required input to unlock the
OLI volume.
CY_
REQ
UIR
ES_
STA
RTU
P_PI
N_O
N_T
OU
CH_
DEV
ICE
0x8
031
00B
7
CONSTANT/VALUE DESCRIPTION

Group Policy settings require the creation of a recovery


FVE password, but neither a pre-boot keyboard nor Windows
_E_P Recovery Environment is available on this device. The user
OLI may not be able to provide required input to unlock the
CY_ volume.
REQ
UIR
ES_
REC
OVE
RY_
PAS
SW
OR
D_O
N_T
OU
CH_
DEV
ICE
0x8
031
00B
8

Wipe of free space is not currently taking place.


FVE
_E_
WIP
E_C
AN
CEL
_NO
T_A
PPL
ICA
BLE
0x8
031
00B
9

BitLocker cannot use Secure Boot for platform integrity


FVE because Secure Boot has been disabled.
_E_S
ECU
REB
OO
T_DI
SAB
LED
0x8
031
00B
A
CONSTANT/VALUE DESCRIPTION

BitLocker cannot use Secure Boot for platform integrity


FVE because the Secure Boot configuration does not meet the
_E_S requirements for BitLocker.
ECU
REB
OO
T_C
ON
FIG
UR
ATI
ON_
INV
ALI
D
0x8
031
00B
B

Your computer doesn't support BitLocker hardware-based


FVE encryption. Check with your computer manufacturer for
_E_E firmware updates.
DRI
VE_
DRY
_RU
N_F
AILE
D
0x8
031
00B
C

BitLocker cannot be enabled on the volume because it


FVE contains a Volume Shadow Copy. Remove all Volume Shadow
_E_S Copies before encrypting the volume.
HA
DO
W_
CO
PY_
PRE
SEN
T
0x8
031
00B
D
CONSTANT/VALUE DESCRIPTION

BitLocker Drive Encryption cannot be applied to this drive


FVE because the Group Policy setting for Enhanced Boot
_E_P Configuration Data contains invalid data. Please have your
OLI system administrator resolve this invalid configuration before
CY_I attempting to enable BitLocker.
NV
ALI
D_E
NH
AN
CED
_BC
D_S
ETTI
NG
S
0x8
031
00B
E

This PC's firmware is not capable of supporting hardware


FVE encryption.
_E_E
DRI
VE_I
NC
OM
PAT
IBLE
_FIR
MW
ARE
0x8
031
00B
F
CONSTANT/VALUE DESCRIPTION

BitLocker has disabled password changes after too many failed


FVE requests. Click the link to reset the password as an
_E_P administrator.
ROT
ECT
OR_
CH
AN
GE_
MA
X_P
ASS
PH
RAS
E_C
HA
NGE
_AT
TEM
PTS
_RE
AC
HED
0x8
031
00C
0

You must be logged on with an administrator account to


FVE change the password. Click the link to reset the password as
_E_P an administrator.
ASS
PH
RAS
E_P
ROT
ECT
OR_
CH
AN
GE_
BY_
STD
_US
ER_
DIS
ALL
OW
ED
0x8
031
00C
1
CONSTANT/VALUE DESCRIPTION

BitLocker cannot save the recovery password because the


FVE specified Microsoft account is Suspended.
_E_L
IVEI
D_A
CC
OU
NT_
SUS
PEN
DED
0x8
031
00C
2

BitLocker cannot save the recovery password because the


FVE specified MIcrosoft account is Blocked.
_E_L
IVEI
D_A
CC
OU
NT_
BLO
CKE
D
0x8
031
00C
3

This PC is not provisioned to support device encryption.


FVE Please enable BitLocker on all volumes to comply with device
_E_ encryption policy.
NO
T_P
RO
VISI
ON
ED_
ON_
ALL
_VO
LU
MES
0x8
031
00C
4
CONSTANT/VALUE DESCRIPTION

This PC cannot support device encryption because


FVE unencrypted fixed data volumes are present.
_E_
DE_
FIXE
D_D
ATA
_NO
T_S
UPP
ORT
ED
0x8
031
00C
5

This PC does not meet the hardware requirements to support


FVE device encryption.
_E_
DE_
HA
RD
WA
RE_
NO
T_C
OM
PLI
AN
T
0x8
031
00C
6

This PC cannot support device encryption because WinRE is


FVE not properly configured.
_E_
DE_
WI
NRE
_NO
T_C
ON
FIG
URE
D
0x8
031
00C
7
CONSTANT/VALUE DESCRIPTION

Protection is enabled on the volume but has been suspended.


FVE This is likely to have happened due to an update being applied
_E_ to your system. Please try again after a reboot.
DE_
PR
OTE
CTI
ON_
SUS
PEN
DED
0x8
031
00C
8

This PC is not provisioned to support device encryption.


FVE
_E_
DE_
OS_
VOL
UM
E_N
OT_
PR
OTE
CTE
D
0x8
031
00C
9

Device Lock has been triggered due to too many incorrect


FVE password attempts.
_E_
DE_
DEV
ICE_
LOC
KED
OU
T
0x8
031
00C
A
CONSTANT/VALUE DESCRIPTION

Protection has not been enabled on the volume. Enabling


FVE protection requires a connected account. If you already have a
_E_ connected account and are seeing this error, please refer to
DE_ the event log for more information.
PR
OTE
CTI
ON_
NO
T_Y
ET_E
NA
BLE
D
0x8
031
00C
B

Your PIN can only contain numbers from 0 to 9.


FVE
_E_I
NV
ALI
D_P
IN_
CH
ARS
_DE
TAI
LED
0x8
031
00C
C

BitLocker cannot use hardware replay protection because no


FVE counter is available on your PC.
_E_
DEV
ICE_
LOC
KO
UT_
CO
UN
TER
_UN
AV
AIL
ABL
E
0x8
031
00C
D
CONSTANT/VALUE DESCRIPTION

Device Lockout state validation failed due to counter


FVE mismatch.
_E_
DEV
ICEL
OC
KO
UT_
CO
UN
TER
_MI
SM
ATC
H
0x8
031
00C
E

The input buffer is too large.


FVE
_E_B
UFF
ER_
TO
O_L
AR
GE
0x8
031
00C
F

Requirements

Header
Win
erro
r.h

See also
C
O
M
E
r
r
o
r
C
o
d
e
s
COM Error Codes (FWP, WS, NDIS, HyperV)
1/7/2020 • 16 minutes to read • Edit Online

The following table provides a list of error codes used by COM -based APIs.
If you are experiencing difficulty with an application you are installing or running, contact customer support for the
software that is displaying the error message. To obtain support for a Microsoft product, go to
https://support.microsoft.com.

CONSTANT/VALUE DESCRIPTION

The callout does not exist.


FW
P_E_
CAL
LOU
T_N
OT_
FOU
ND
0x8
032
000
1

The filter condition does not exist.


FW
P_E_
CO
NDI
TIO
N_N
OT_
FOU
ND
0x8
032
000
2

The filter does not exist.


FW
P_E_
FILT
ER_
NO
T_F
OU
ND
0x8
032
000
3
CONSTANT/VALUE DESCRIPTION

The layer does not exist.


FW
P_E_
LAY
ER_
NO
T_F
OU
ND
0x8
032
000
4

The provider does not exist.


FW
P_E_
PR
OVI
DER
_NO
T_F
OU
ND
0x8
032
000
5

The provider context does not exist.


FW
P_E_
PR
OVI
DER
_CO
NTE
XT_
NO
T_F
OU
ND
0x8
032
000
6
CONSTANT/VALUE DESCRIPTION

The sublayer does not exist.


FW
P_E_
SUB
LAY
ER_
NO
T_F
OU
ND
0x8
032
000
7

The object does not exist.


FW
P_E_
NO
T_F
OU
ND
0x8
032
000
8

An object with that GUID or LUID already exists.


FW
P_E_
ALR
EAD
Y_E
XIS
TS
0x8
032
000
9

The object is referenced by other objects so cannot be deleted.


FW
P_E_
IN_
USE
0x8
032
000
A
CONSTANT/VALUE DESCRIPTION

The call is not allowed from within a dynamic session.


FW
P_E_
DY
NA
MIC
_SE
SSI
ON_
IN_
PR
OG
RES
S
0x8
032
000
B

The call was made from the wrong session so cannot be


FW completed.
P_E_
WR
ON
G_S
ESSI
ON
0x8
032
000
C

The call must be made from within an explicit transaction.


FW
P_E_
NO_
TXN
_IN_
PR
OG
RES
S
0x8
032
000
D
CONSTANT/VALUE DESCRIPTION

The call is not allowed from within an explicit transaction.


FW
P_E_
TXN
_IN_
PR
OG
RES
S
0x8
032
000
E

The explicit transaction has been forcibly canceled.


FW
P_E_
TXN
_AB
ORT
ED
0x8
032
000
F

The session has been canceled.


FW
P_E_
SES
SIO
N_A
BO
RTE
D
0x8
032
001
0

The call is not allowed from within a read-only transaction.


FW
P_E_
INC
OM
PAT
IBLE
_TX
N
0x8
032
001
1
CONSTANT/VALUE DESCRIPTION

The call timed out while waiting to acquire the transaction


FW lock.
P_E_
TIM
EOU
T
0x8
032
001
2

Collection of network diagnostic events is disabled.


FW
P_E_
NET
_EV
ENT
S_DI
SAB
LED
0x8
032
001
3

The operation is not supported by the specified layer.


FW
P_E_
INC
OM
PAT
IBLE
_LA
YER
0x8
032
001
4

The call is allowed for kernel-mode callers only.


FW
P_E_
KM_
CLIE
NTS
_ON
LY
0x8
032
001
5
CONSTANT/VALUE DESCRIPTION

The call tried to associate two objects with incompatible


FW lifetimes.
P_E_
LIFE
TIM
E_M
ISM
ATC
H
0x8
032
001
6

The object is built in so cannot be deleted.


FW
P_E_
BUI
LTI
N_O
BJE
CT
0x8
032
001
7

The maximum number of callouts has been reached.


FW
P_E_
TO
O_
MA
NY_
CAL
LOU
TS
0x8
032
001
8

A notification could not be delivered because a message


FW queue is at its maximum capacity.
P_E_
NO
TIFI
CAT
ION
_DR
OP
PED
0x8
032
001
9
CONSTANT/VALUE DESCRIPTION

The traffic parameters do not match those for the security


FW association context.
P_E_
TRA
FFIC
_MI
SM
ATC
H
0x8
032
001
A

The call is not allowed for the current security association


FW state.
P_E_
INC
OM
PAT
IBLE
_SA
_ST
ATE
0x8
032
001
B

A required pointer is null.


FW
P_E_
NUL
L_P
OIN
TER
0x8
032
001
C

An enumerator is not valid.


FW
P_E_
INV
ALI
D_E
NU
ME
RAT
OR
0x8
032
001
D
CONSTANT/VALUE DESCRIPTION

The flags field contains an invalid value.


FW
P_E_
INV
ALI
D_F
LAG
S
0x8
032
001
E

A network mask is not valid.


FW
P_E_
INV
ALI
D_N
ET_
MA
SK
0x8
032
001
F

An FWP_RANGE is not valid.


FW
P_E_
INV
ALI
D_R
AN
GE
0x8
032
002
0

The time interval is not valid.


FW
P_E_
INV
ALI
D_I
NTE
RVA
L
0x8
032
002
1
CONSTANT/VALUE DESCRIPTION

An array that must contain at least one element is zero length.


FW
P_E_
ZER
O_L
ENG
TH_
ARR
AY
0x8
032
002
2

The displayData.name field cannot be null.


FW
P_E_
NUL
L_DI
SPL
AY_
NA
ME
0x8
032
002
3

The action type is not one of the allowed action types for a
FW filter.
P_E_
INV
ALI
D_A
CTI
ON_
TYP
E
0x8
032
002
4

The filter weight is not valid.


FW
P_E_
INV
ALI
D_
WEI
GH
T
0x8
032
002
5
CONSTANT/VALUE DESCRIPTION

A filter condition contains a match type that is not compatible


FW with the operands.
P_E_
MA
TCH
_TY
PE_
MIS
MA
TCH
0x8
032
002
6

An FWP_VALUE or FWPM_CONDITION_VALUE is of the


FW wrong type.
P_E_
TYP
E_M
ISM
ATC
H
0x8
032
002
7

An integer value is outside the allowed range.


FW
P_E_
OU
T_O
F_B
OU
ND
S
0x8
032
002
8

A reserved field is nonzero.


FW
P_E_
RES
ERV
ED
0x8
032
002
9
CONSTANT/VALUE DESCRIPTION

A filter cannot contain multiple conditions operating on a


FW single field.
P_E_
DU
PLI
CAT
E_C
ON
DITI
ON
0x8
032
002
A

A policy cannot contain the same keying module more than


FW once.
P_E_
DU
PLI
CAT
E_K
EY
MO
D
0x8
032
002
B

The action type is not compatible with the layer.


FW
P_E_
ACT
ION
_IN
CO
MP
ATI
BLE
_WI
TH_
LAY
ER
0x8
032
002
C
CONSTANT/VALUE DESCRIPTION

The action type is not compatible with the sublayer.


FW
P_E_
ACT
ION
_IN
CO
MP
ATI
BLE
_WI
TH_
SUB
LAY
ER
0x8
032
002
D

The raw context or the provider context is not compatible with


FW the layer.
P_E_
CO
NTE
XT_I
NC
OM
PAT
IBLE
_WI
TH_
LAY
ER
0x8
032
002
E

The raw context or the provider context is not compatible with


FW the callout.
P_E_
CO
NTE
XT_I
NC
OM
PAT
IBLE
_WI
TH_
CAL
LOU
T
0x8
032
002
F
CONSTANT/VALUE DESCRIPTION

The authentication method is not compatible with the policy


FW type.
P_E_
INC
OM
PAT
IBLE
_AU
TH_
MET
HO
D
0x8
032
003
0

The Diffie-Hellman group is not compatible with the policy


FW type.
P_E_
INC
OM
PAT
IBLE
_DH
_GR
OU
P
0x8
032
003
1

An IKE policy cannot contain an Extended Mode policy.


FW
P_E_
EM_
NO
T_S
UPP
ORT
ED
0x8
032
003
2

The enumeration template or subscription will never match


FW any objects.
P_E_
NEV
ER_
MA
TCH
0x8
032
003
3
CONSTANT/VALUE DESCRIPTION

The provider context is of the wrong type.


FW
P_E_
PR
OVI
DER
_CO
NTE
XT_
MIS
MA
TCH
0x8
032
003
4

The parameter is incorrect.


FW
P_E_
INV
ALI
D_P
AR
AM
ETE
R
0x8
032
003
5

The maximum number of sublayers has been reached.


FW
P_E_
TO
O_
MA
NY_
SUB
LAY
ERS
0x8
032
003
6
CONSTANT/VALUE DESCRIPTION

The notification function for a callout returned an error.


FW
P_E_
CAL
LOU
T_N
OTI
FIC
ATI
ON_
FAIL
ED
0x8
032
003
7

The IPsec authentication transform is not valid.


FW
P_E_
INV
ALI
D_A
UT
H_T
RA
NSF
OR
M
0x8
032
003
8

The IPsec cipher transform is not valid.


FW
P_E_
INV
ALI
D_C
IPH
ER_
TRA
NSF
OR
M
0x8
032
003
9
CONSTANT/VALUE DESCRIPTION

The IPsec cipher transform is not compatible with the policy.


FW
P_E_
INC
OM
PAT
IBLE
_CIP
HER
_TR
AN
SFO
RM
0x8
032
003
A

The combination of IPsec transform types is not valid.


FW
P_E_
INV
ALI
D_T
RA
NSF
OR
M_C
OM
BIN
ATI
ON
0x8
032
003
B

A policy cannot contain the same auth method more than


FW once.
P_E_
DU
PLI
CAT
E_A
UT
H_
MET
HO
D
0x8
032
003
C
CONSTANT/VALUE DESCRIPTION

A tunnel endpoint configuration is invalid.


FW
P_E_
INV
ALI
D_T
UN
NEL
_EN
DP
OIN
T
0x8
032
003
D

The WFP MAC Layers are not ready.


FW
P_E_
L2_
DRI
VER
_NO
T_R
EAD
Y
0x8
032
003
E

A key manager capable of key dictation is already registered


FW
P_E_
KEY
_DI
CTA
TOR
_AL
REA
DY_
REG
ISTE
RED
0x8
032
003
F
CONSTANT/VALUE DESCRIPTION

A key manager dictated invalid keys


FW
P_E_
KEY
_DI
CTA
TIO
N_I
NV
ALI
D_K
EYI
NG_
MA
TERI
AL
0x8
032
004
0

The BFE IPsec Connection Tracking is disabled.


FW
P_E_
CO
NN
ECTI
ON
S_DI
SAB
LED
0x8
032
004
1

The DNS name is invalid.


FW
P_E_
INV
ALI
D_D
NS_
NA
ME
0x8
032
004
2
CONSTANT/VALUE DESCRIPTION

The engine option is still enabled due to other configuration


FW settings.
P_E_
STIL
L_O
N
0x8
032
004
3

The IKEEXT service is not running. This service only runs when
FW there is IPsec policy applied to the machine.
P_E_
IKEE
XT_
NO
T_R
UN
NIN
G
0x8
032
004
4

The packet should be dropped, no ICMP should be sent.


FW
P_E_
DR
OP_
NOI
CM
P
0x8
032
010
4

The function call is completing asynchronously.


WS_
S_A
SYN
C
0x0
03D
000
0

There are no more messages available on the channel.


WS_
S_E
ND
0x0
03D
000
1
CONSTANT/VALUE DESCRIPTION

The input data was not in the expected format or did not have
WS_ the expected value.
E_IN
VAL
ID_F
OR
MA
T
0x8
03D
000
0

The operation could not be completed because the object is in


WS_ a faulted state due to a previous error.
E_O
BJE
CT_
FAU
LTE
D
0x8
03D
000
1

The operation could not be completed because it would lead


WS_ to numeric overflow.
E_N
UM
ERI
C_O
VER
FLO
W
0x8
03D
000
2

The operation is not allowed due to the current state of the


WS_ object.
E_IN
VAL
ID_
OPE
RAT
ION
0x8
03D
000
3
CONSTANT/VALUE DESCRIPTION

The operation was aborted.


WS_
E_O
PER
ATI
ON_
AB
ORT
ED
0x8
03D
000
4

Access was denied by the remote endpoint.


WS_
E_E
ND
POI
NT_
ACC
ESS
_DE
NIE
D
0x8
03D
000
5

The operation did not complete within the time allotted.


WS_
E_O
PER
ATI
ON_
TIM
ED_
OU
T
0x8
03D
000
6
CONSTANT/VALUE DESCRIPTION

The operation was abandoned.


WS_
E_O
PER
ATI
ON_
AB
AN
DO
NED
0x8
03D
000
7

A quota was exceeded.


WS_
E_Q
UO
TA_
EXC
EED
ED
0x8
03D
000
8

The information was not available in the specified language.


WS_
E_N
O_T
RA
NSL
ATI
ON_
AV
AIL
ABL
E
0x8
03D
000
9
CONSTANT/VALUE DESCRIPTION

Security verification was not successful for the received data.


WS_
E_SE
CUR
ITY_
VER
IFIC
ATI
ON_
FAIL
URE
0x8
03D
000
A

The address is already being used.


WS_
E_A
DD
RES
S_I
N_U
SE
0x8
03D
000
B

The address is not valid for this context.


WS_
E_A
DD
RES
S_N
OT_
AV
AIL
ABL
E
0x8
03D
000
C
CONSTANT/VALUE DESCRIPTION

The remote endpoint does not exist or could not be located.


WS_
E_E
ND
POI
NT_
NO
T_F
OU
ND
0x8
03D
000
D

The remote endpoint is not currently in service at this


WS_ location.
E_E
ND
POI
NT_
NO
T_A
VAI
LAB
LE
0x8
03D
000
E

The remote endpoint could not process the request.


WS_
E_E
ND
POI
NT_
FAIL
URE
0x8
03D
000
F
CONSTANT/VALUE DESCRIPTION

The remote endpoint was not reachable.


WS_
E_E
ND
POI
NT_
UN
REA
CH
ABL
E
0x8
03D
001
0

The operation was not supported by the remote endpoint.


WS_
E_E
ND
POI
NT_
ACT
ION
_NO
T_S
UPP
ORT
ED
0x8
03D
001
1

The remote endpoint is unable to process the request due to


WS_ being overloaded.
E_E
ND
POI
NT_
TO
O_B
USY
0x8
03D
001
2
CONSTANT/VALUE DESCRIPTION

A message containing a fault was received from the remote


WS_ endpoint.
E_E
ND
POI
NT_
FAU
LT_
REC
EIVE
D
0x8
03D
001
3

The connection with the remote endpoint was terminated.


WS_
E_E
ND
POI
NT_
DIS
CO
NN
ECT
ED
0x8
03D
001
4

The HTTP proxy server could not process the request.


WS_
E_P
RO
XY_
FAIL
URE
0x8
03D
001
5

Access was denied by the HTTP proxy server.


WS_
E_P
RO
XY_
ACC
ESS
_DE
NIE
D
0x8
03D
001
6
CONSTANT/VALUE DESCRIPTION

The requested feature is not available on this platform.


WS_
E_N
OT_
SUP
PO
RTE
D
0x8
03D
001
7

The HTTP proxy server requires HTTP authentication scheme


WS_ 'basic'.
E_P
RO
XY_
REQ
UIR
ES_
BAS
IC_
AUT
H
0x8
03D
001
8

The HTTP proxy server requires HTTP authentication scheme


WS_ 'digest'.
E_P
RO
XY_
REQ
UIR
ES_
DIG
EST
_AU
TH
0x8
03D
001
9
CONSTANT/VALUE DESCRIPTION

The HTTP proxy server requires HTTP authentication scheme


WS_ 'NTLM'.
E_P
RO
XY_
REQ
UIR
ES_
NTL
M_
AUT
H
0x8
03D
001
A

The HTTP proxy server requires HTTP authentication scheme


WS_ 'negotiate'.
E_P
RO
XY_
REQ
UIR
ES_
NEG
OTI
ATE
_AU
TH
0x8
03D
001
B

The remote endpoint requires HTTP authentication scheme


WS_ 'basic'.
E_SE
RVE
R_R
EQU
IRES
_BA
SIC_
AUT
H
0x8
03D
001
C
CONSTANT/VALUE DESCRIPTION

The remote endpoint requires HTTP authentication scheme


WS_ 'digest'.
E_SE
RVE
R_R
EQU
IRES
_DI
GES
T_A
UT
H
0x8
03D
001
D

The remote endpoint requires HTTP authentication scheme


WS_ 'NTLM'.
E_SE
RVE
R_R
EQU
IRES
_NT
LM_
AUT
H
0x8
03D
001
E

The remote endpoint requires HTTP authentication scheme


WS_ 'negotiate'.
E_SE
RVE
R_R
EQU
IRES
_NE
GO
TIA
TE_
AUT
H
0x8
03D
001
F
CONSTANT/VALUE DESCRIPTION

The endpoint address URL is invalid.


WS_
E_IN
VAL
ID_E
ND
POI
NT_
URL
0x8
03D
002
0

Unrecognized error occurred in the Windows Web Services


WS_ framework.
E_O
THE
R
0x8
03D
002
1

A security token was rejected by the server because it has


WS_ expired.
E_SE
CUR
ITY_
TOK
EN_
EXP
IRE
D
0x8
03D
002
2

A security operation failed in the Windows Web Services


WS_ framework.
E_SE
CUR
ITY_
SYS
TEM
_FAI
LUR
E
0x8
03D
002
3
CONSTANT/VALUE DESCRIPTION

The binding to the network interface is being closed.


ERR
OR_
NDI
S_I
NTE
RFA
CE_
CLO
SIN
G
0x8
034
000
2

An invalid version was specified.


ERR
OR_
NDI
S_B
AD_
VER
SIO
N
0x8
034
000
4

An invalid characteristics table was used.


ERR
OR_
NDI
S_B
AD_
CH
AR
ACT
ERIS
TIC
S
0x8
034
000
5
CONSTANT/VALUE DESCRIPTION

Failed to find the network interface or network interface is not


ERR ready.
OR_
NDI
S_A
DA
PTE
R_N
OT_
FOU
ND
0x8
034
000
6

Failed to open the network interface.


ERR
OR_
NDI
S_O
PEN
_FAI
LED
0x8
034
000
7

Network interface has encountered an internal unrecoverable


ERR failure.
OR_
NDI
S_D
EVI
CE_
FAIL
ED
0x8
034
000
8

The multicast list on the network interface is full.


ERR
OR_
NDI
S_M
ULT
ICA
ST_
FUL
L
0x8
034
000
9
CONSTANT/VALUE DESCRIPTION

An attempt was made to add a duplicate multicast address to


ERR the list.
OR_
NDI
S_M
ULT
ICA
ST_
EXIS
TS
0x8
034
000
A

At attempt was made to remove a multicast address that was


ERR never added.
OR_
NDI
S_M
ULT
ICA
ST_
NO
T_F
OU
ND
0x8
034
000
B

Netowork interface aborted the request.


ERR
OR_
NDI
S_R
EQU
EST
_AB
ORT
ED
0x8
034
000
C
CONSTANT/VALUE DESCRIPTION

Network interface cannot process the request because it is


ERR being reset.
OR_
NDI
S_R
ESE
T_I
N_P
RO
GRE
SS
0x8
034
000
D

Netword interface does not support this request.


ERR
OR_
NDI
S_N
OT_
SUP
PO
RTE
D
0x8
034
00B
B

An attempt was made to send an invalid packet on a network


ERR interface.
OR_
NDI
S_I
NV
ALI
D_P
ACK
ET
0x8
034
000
F
CONSTANT/VALUE DESCRIPTION

Network interface is not ready to complete this operation.


ERR
OR_
NDI
S_A
DA
PTE
R_N
OT_
REA
DY
0x8
034
001
1

The length of the buffer submitted for this operation is not


ERR valid.
OR_
NDI
S_I
NV
ALI
D_L
ENG
TH
0x8
034
001
4

The data used for this operation is not valid.


ERR
OR_
NDI
S_I
NV
ALI
D_D
ATA
0x8
034
001
5
CONSTANT/VALUE DESCRIPTION

The length of buffer submitted for this operation is too small.


ERR
OR_
NDI
S_B
UFF
ER_
TO
O_S
HO
RT
0x8
034
001
6

Network interface does not support this OID (Object


ERR Identifier)
OR_
NDI
S_I
NV
ALI
D_O
ID
0x8
034
001
7

The network interface has been removed.


ERR
OR_
NDI
S_A
DA
PTE
R_R
EM
OVE
D
0x8
034
001
8
CONSTANT/VALUE DESCRIPTION

Network interface does not support this media type.


ERR
OR_
NDI
S_U
NS
UPP
ORT
ED_
ME
DIA
0x8
034
001
9

An attempt was made to remove a token ring group address


ERR that is in use by other components.
OR_
NDI
S_G
RO
UP_
AD
DRE
SS_I
N_U
SE
0x8
034
001
A

An attempt was made to map a file that cannot be found.


ERR
OR_
NDI
S_FI
LE_
NO
T_F
OU
ND
0x8
034
001
B
CONSTANT/VALUE DESCRIPTION

An error occurred while NDIS tried to map the file.


ERR
OR_
NDI
S_E
RR
OR_
REA
DIN
G_FI
LE
0x8
034
001
C

An attempt was made to map a file that is alreay mapped.


ERR
OR_
NDI
S_A
LRE
AD
Y_M
APP
ED
0x8
034
001
D

An attempt to allocate a hardware resource failed because the


ERR resource is used by another component.
OR_
NDI
S_R
ESO
URC
E_C
ON
FLIC
T
0x8
034
001
E
CONSTANT/VALUE DESCRIPTION

The I/O operation failed because network media is


ERR disconnected or wireless access point is out of range.
OR_
NDI
S_M
EDI
A_D
ISC
ON
NEC
TED
0x8
034
001
F

The network address used in the request is invalid.


ERR
OR_
NDI
S_I
NV
ALI
D_A
DD
RES
S
0x8
034
002
2

The specified request is not a valid operation for the target


ERR device.
OR_
NDI
S_I
NV
ALI
D_D
EVI
CE_
REQ
UES
T
0x8
034
001
0
CONSTANT/VALUE DESCRIPTION

The offload operation on the network interface has been


ERR paused.
OR_
NDI
S_P
AUS
ED
0x8
034
002
A

Network interface was not found.


ERR
OR_
NDI
S_I
NTE
RFA
CE_
NO
T_F
OU
ND
0x8
034
002
B

The revision number specified in the structure is not


ERR supported.
OR_
NDI
S_U
NS
UPP
ORT
ED_
REV
ISIO
N
0x8
034
002
C
CONSTANT/VALUE DESCRIPTION

The specified port does not exist on this network interface.


ERR
OR_
NDI
S_I
NV
ALI
D_P
ORT
0x8
034
002
D

The current state of the specified port on this network


ERR interface does not support the requested operation.
OR_
NDI
S_I
NV
ALI
D_P
ORT
_ST
ATE
0x8
034
002
E

The miniport adapter is in low power state.


ERR
OR_
NDI
S_L
OW
_PO
WE
R_S
TAT
E
0x8
034
002
F
CONSTANT/VALUE DESCRIPTION

This operation requires the miniport adapter to be


ERR reinitialized.
OR_
NDI
S_R
EINI
T_R
EQU
IRE
D
0x8
034
003
0

The wireless local area network interface is in auto


ERR configuration mode and doesn't support the requested
OR_ parameter change operation.
NDI
S_D
OT1
1_A
UT
O_C
ON
FIG_
ENA
BLE
D
0x8
034
200
0

The wireless local area network interface is busy and cannot


ERR perform the requested operation.
OR_
NDI
S_D
OT1
1_M
EDI
A_I
N_U
SE
0x8
034
200
1
CONSTANT/VALUE DESCRIPTION

The wireless local area network interface is powered down and


ERR doesn't support the requested operation.
OR_
NDI
S_D
OT1
1_P
OW
ER_
STA
TE_I
NV
ALI
D
0x8
034
200
2

The list of wake on LAN patterns is full.


ERR
OR_
NDI
S_P
M_
WO
L_P
ATT
ERN
_LIS
T_F
ULL
0x8
034
200
3

The list of low power protocol offloads is full.


ERR
OR_
NDI
S_P
M_P
ROT
OC
OL_
OFF
LOA
D_LI
ST_
FUL
L
0x8
034
200
4
CONSTANT/VALUE DESCRIPTION

The request will be completed later by NDIS status indication.


ERR
OR_
NDI
S_I
NDI
CAT
ION
_RE
QUI
RED
0x0
034
000
1

The TCP connection is not offloadable because of a local policy


ERR setting.
OR_
NDI
S_O
FFL
OA
D_P
OLI
CY
0xC
034
100
F

The TCP connection is not offloadable by the Chimney Offload


ERR target.
OR_
NDI
S_O
FFL
OA
D_C
ON
NEC
TIO
N_R
EJE
CTE
D
0xC
034
101
2
CONSTANT/VALUE DESCRIPTION

The IP Path object is not in an offloadable state.


ERR
OR_
NDI
S_O
FFL
OA
D_P
AT
H_R
EJE
CTE
D
0xC
034
101
3

The hypervisor does not support the operation because the


ERR specified hypercall code is not supported.
OR_
HV_
INV
ALI
D_H
YPE
RCA
LL_
CO
DE
0xC
035
000
2

The hypervisor does not support the operation because the


ERR encoding for the hypercall input register is not supported.
OR_
HV_
INV
ALI
D_H
YPE
RCA
LL_I
NP
UT
0xC
035
000
3
CONSTANT/VALUE DESCRIPTION

The hypervisor could not perform the operation because a


ERR parameter has an invalid alignment.
OR_
HV_
INV
ALI
D_A
LIG
NM
ENT
0xC
035
000
4

The hypervisor could not perform the operation because an


ERR invalid parameter was specified.
OR_
HV_
INV
ALI
D_P
AR
AM
ETE
R
0xC
035
000
5

Access to the specified object was denied.


ERR
OR_
HV_
ACC
ESS
_DE
NIE
D
0xC
035
000
6
CONSTANT/VALUE DESCRIPTION

The hypervisor could not perform the operation because the


ERR partition is entering or in an invalid state.
OR_
HV_
INV
ALI
D_P
ART
ITIO
N_S
TAT
E
0xC
035
000
7

The operation is not allowed in the current state.


ERR
OR_
HV_
OPE
RAT
ION
_DE
NIE
D
0xC
035
000
8

The hypervisor does not recognize the specified partition


ERR property.
OR_
HV_
UN
KN
OW
N_P
RO
PER
TY
0xC
035
000
9
CONSTANT/VALUE DESCRIPTION

The specified value of a partition property is out of range or


ERR violates an invariant.
OR_
HV_
PR
OPE
RTY
_VA
LUE
_OU
T_O
F_R
AN
GE
0xC
035
000
A

There is not enough memory in the hypervisor pool to


ERR complete the operation.
OR_
HV_
INS
UFFI
CIE
NT_
ME
MO
RY
0xC
035
000
B

The maximum partition depth has been exceeded for the


ERR partition hierarchy.
OR_
HV_
PAR
TITI
ON_
TO
O_D
EEP
0xC
035
000
C
CONSTANT/VALUE DESCRIPTION

A partition with the specified partition Id does not exist.


ERR
OR_
HV_
INV
ALI
D_P
ART
ITIO
N_I
D
0xC
035
000
D

The hypervisor could not perform the operation because the


ERR specified VP index is invalid.
OR_
HV_
INV
ALI
D_V
P_I
NDE
X
0xC
035
000
E

The hypervisor could not perform the operation because the


ERR specified port identifier is invalid.
OR_
HV_
INV
ALI
D_P
ORT
_ID
0xC
035
001
1
CONSTANT/VALUE DESCRIPTION

The hypervisor could not perform the operation because the


ERR specified connection identifier is invalid.
OR_
HV_
INV
ALI
D_C
ON
NEC
TIO
N_I
D
0xC
035
001
2

Not enough buffers were supplied to send a message.


ERR
OR_
HV_
INS
UFFI
CIE
NT_
BUF
FER
S
0xC
035
001
3

The previous virtual interrupt has not been acknowledged.


ERR
OR_
HV_
NO
T_A
CK
NO
WLE
DGE
D
0xC
035
001
4
CONSTANT/VALUE DESCRIPTION

The previous virtual interrupt has already been acknowledged.


ERR
OR_
HV_
ACK
NO
WLE
DGE
D
0xC
035
001
6

The indicated partition is not in a valid state for saving or


ERR restoring.
OR_
HV_
INV
ALI
D_S
AVE
_RE
STO
RE_
STA
TE
0xC
035
001
7

The hypervisor could not complete the operation because a


ERR required feature of the synthetic interrupt controller (SynIC)
OR_ was disabled.
HV_
INV
ALI
D_S
YNI
C_S
TAT
E
0xC
035
001
8
CONSTANT/VALUE DESCRIPTION

The hypervisor could not perform the operation because the


ERR object or value was either already in use or being used for a
OR_ purpose that would not permit completing the operation.
HV_
OBJ
ECT
_IN_
USE
0xC
035
001
9

The proximity domain information is invalid.


ERR
OR_
HV_
INV
ALI
D_P
RO
XIM
ITY_
DO
MAI
N_I
NF
O
0xC
035
001
A

An attempt to retrieve debugging data failed because none


ERR was available.
OR_
HV_
NO_
DAT
A
0xC
035
001
B

The physical connection being used for debugging has not


ERR recorded any receive activity since the last operation.
OR_
HV_
INA
CTI
VE
0xC
035
001
C
CONSTANT/VALUE DESCRIPTION

There are not enough resources to complete the operation.


ERR
OR_
HV_
NO_
RES
OU
RCE
S
0xC
035
001
D

A hypervisor feature is not available to the user.


ERR
OR_
HV_
FEA
TUR
E_U
NA
VAI
LAB
LE
0xC
035
001
E

The maximum number of domains supported by the platform


ERR I/O remapping hardware is currently in use. No domains are
OR_ available to assign this device to this partition.
HV_
INS
UFFI
CIE
NT_
DEV
ICE_
DO
MAI
NS
0xC
035
003
8
CONSTANT/VALUE DESCRIPTION

The hypervisor could not perform the operation because the


ERR specified LP index is invalid.
OR_
HV_
INV
ALI
D_L
P_I
NDE
X
0xC
035
004
1

No hypervisor is present on this system.


ERR
OR_
HV_
NO
T_P
RES
ENT
0xC
035
100
0

The handler for the virtualization infrastructure driver is


ERR already registered. Restarting the virtual machine may fix the
OR_ problem. If the problem persists, try restarting the physical
VID computer.
_DU
PLI
CAT
E_H
AN
DLE
R
0xC
037
000
1
CONSTANT/VALUE DESCRIPTION

The number of registered handlers for the virtualization


ERR infrastructure driver exceeded the maximum. Restarting the
OR_ virtual machine may fix the problem. If the problem persists,
VID try restarting the physical computer.
_TO
O_
MA
NY_
HA
NDL
ERS
0xC
037
000
2

The message queue for the virtualization infrastructure driver


ERR is full and cannot accept new messages. Restarting the virtual
OR_ machine may fix the problem. If the problem persists, try
VID restarting the physical computer.
_QU
EUE
_FU
LL
0xC
037
000
3

No handler exists to handle the message for the virtualization


ERR infrastructure driver. Restarting the virtual machine may fix the
OR_ problem. If the problem persists, try restarting the physical
VID computer.
_HA
NDL
ER_
NO
T_P
RES
ENT
0xC
037
000
4
CONSTANT/VALUE DESCRIPTION

The name of the partition or message queue for the


ERR virtualization infrastructure driver is invalid. Restarting the
OR_ virtual machine may fix the problem. If the problem persists,
VID try restarting the physical computer.
_IN
VAL
ID_
OBJ
ECT
_NA
ME
0xC
037
000
5

The partition name of the virtualization infrastructure driver


ERR exceeds the maximum.
OR_
VID
_PA
RTI
TIO
N_N
AM
E_T
OO_
LO
NG
0xC
037
000
6

The message queue name of the virtualization infrastructure


ERR driver exceeds the maximum.
OR_
VID
_ME
SSA
GE_
QUE
UE_
NA
ME_
TO
O_L
ON
G
0xC
037
000
7
CONSTANT/VALUE DESCRIPTION

Cannot create the partition for the virtualization infrastructure


ERR driver because another partition with the same name already
OR_ exists.
VID
_PA
RTI
TIO
N_A
LRE
AD
Y_E
XIS
TS
0xC
037
000
8

The virtualization infrastructure driver has encountered an


ERR error. The requested partition does not exist. Restarting the
OR_ virtual machine may fix the problem. If the problem persists,
VID try restarting the physical computer.
_PA
RTI
TIO
N_D
OES
_NO
T_E
XIS
T
0xC
037
000
9

The virtualization infrastructure driver has encountered an


ERR error. Could not find the requested partition. Restarting the
OR_ virtual machine may fix the problem. If the problem persists,
VID try restarting the physical computer.
_PA
RTI
TIO
N_N
AM
E_N
OT_
FOU
ND
0xC
037
000
A
CONSTANT/VALUE DESCRIPTION

A message queue with the same name already exists for the
ERR virtualization infrastructure driver.
OR_
VID
_ME
SSA
GE_
QUE
UE_
ALR
EAD
Y_E
XIS
TS
0xC
037
000
B

The memory block page for the virtualization infrastructure


ERR driver cannot be mapped because the page map limit has
OR_ been reached. Restarting the virtual machine may fix the
VID problem. If the problem persists, try restarting the physical
_EX computer.
CEE
DED
_MB
P_E
NTR
Y_M
AP_
LIMI
T
0xC
037
000
C

The memory block for the virtualization infrastructure driver is


ERR still being used and cannot be destroyed.
OR_
VID
_MB
_STI
LL_
REF
ERE
NCE
D
0xC
037
000
D
CONSTANT/VALUE DESCRIPTION

Cannot unlock the page array for the guest operating system
ERR memory address because it does not match a previous lock
OR_ request. Restarting the virtual machine may fix the problem. If
VID the problem persists, try restarting the physical computer.
_CH
ILD_
GP
A_P
AGE
_SE
T_C
OR
RUP
TED
0xC
037
000
E

The non-uniform memory access (NUMA) node settings do


ERR not match the system NUMA topology. In order to start the
OR_ virtual machine, you will need to modify the NUMA
VID configuration.
_IN
VAL
ID_
NU
MA
_SE
TTI
NG
S
0xC
037
000
F

The non-uniform memory access (NUMA) node index does


ERR not match a valid index in the system NUMA topology.
OR_
VID
_IN
VAL
ID_
NU
MA
_NO
DE_I
NDE
X
0xC
037
001
0
CONSTANT/VALUE DESCRIPTION

The memory block for the virtualization infrastructure driver is


ERR already associated with a message queue.
OR_
VID
_NO
TIFI
CAT
ION
_QU
EUE
_AL
REA
DY_
ASS
OCI
ATE
D
0xC
037
001
1

The handle is not a valid memory block handle for the


ERR virtualization infrastructure driver.
OR_
VID
_IN
VAL
ID_
ME
MO
RY_
BLO
CK_
HA
NDL
E
0xC
037
001
2

The request exceeded the memory block page limit for the
ERR virtualization infrastructure driver. Restarting the virtual
OR_ machine may fix the problem. If the problem persists, try
VID restarting the physical computer.
_PA
GE_
RA
NGE
_OV
ERF
LO
W
0xC
037
001
3
CONSTANT/VALUE DESCRIPTION

The handle is not a valid message queue handle for the


ERR virtualization infrastructure driver.
OR_
VID
_IN
VAL
ID_
MES
SAG
E_Q
UEU
E_H
AN
DLE
0xC
037
001
4

The handle is not a valid page range handle for the


ERR virtualization infrastructure driver.
OR_
VID
_IN
VAL
ID_
GP
A_R
AN
GE_
HA
NDL
E
0xC
037
001
5

Cannot install client notifications because no message queue


ERR for the virtualization infrastructure driver is associated with
OR_ the memory block.
VID
_NO
_ME
MO
RY_
BLO
CK_
NO
TIFI
CAT
ION
_QU
EUE
0xC
037
001
6
CONSTANT/VALUE DESCRIPTION

The request to lock or map a memory block page failed


ERR because the virtualization infrastructure driver memory block
OR_ limit has been reached. Restarting the virtual machine may fix
VID the problem. If the problem persists, try restarting the
_ME physical computer.
MO
RY_
BLO
CK_
LOC
K_C
OU
NT_
EXC
EED
ED
0xC
037
001
7

The handle is not a valid parent partition mapping handle for


ERR the virtualization infrastructure driver.
OR_
VID
_IN
VAL
ID_
PP
M_
HA
NDL
E
0xC
037
001
8

Notifications cannot be created on the memory block because


ERR it is use.
OR_
VID
_MB
PS_
ARE
_LO
CKE
D
0xC
037
001
9
CONSTANT/VALUE DESCRIPTION

The message queue for the virtualization infrastructure driver


ERR has been closed. Restarting the virtual machine may fix the
OR_ problem. If the problem persists, try restarting the physical
VID computer.
_ME
SSA
GE_
QUE
UE_
CLO
SED
0xC
037
001
A

Cannot add a virtual processor to the partition because the


ERR maximum has been reached.
OR_
VID
_VIR
TUA
L_P
RO
CES
SOR
_LI
MIT
_EX
CEE
DED
0xC
037
001
B

Cannot stop the virtual processor immediately because of a


ERR pending intercept.
OR_
VID
_ST
OP_
PEN
DIN
G
0xC
037
001
C
CONSTANT/VALUE DESCRIPTION

Invalid state for the virtual processor. Restarting the virtual


ERR machine may fix the problem. If the problem persists, try
OR_ restarting the physical computer.
VID
_IN
VAL
ID_
PR
OCE
SSO
R_S
TAT
E
0xC
037
001
D

The maximum number of kernel mode clients for the


ERR virtualization infrastructure driver has been reached.
OR_ Restarting the virtual machine may fix the problem. If the
VID problem persists, try restarting the physical computer.
_EX
CEE
DED
_KM
_CO
NTE
XT_
CO
UN
T_LI
MIT
0xC
037
001
E

This kernel mode interface for the virtualization infrastructure


ERR driver has already been initialized. Restarting the virtual
OR_ machine may fix the problem. If the problem persists, try
VID restarting the physical computer.
_KM
_IN
TER
FAC
E_A
LRE
AD
Y_I
NITI
ALI
ZED
0xC
037
001
F
CONSTANT/VALUE DESCRIPTION

Cannot set or reset the memory block property more than


ERR once for the virtualization infrastructure driver. Restarting the
OR_ virtual machine may fix the problem. If the problem persists,
VID try restarting the physical computer.
_MB
_PR
OPE
RTY
_AL
REA
DY_
SET
_RE
SET
0xC
037
002
0

The memory mapped I/O for this page range no longer exists.
ERR Restarting the virtual machine may fix the problem. If the
OR_ problem persists, try restarting the physical computer.
VID
_M
MIO
_RA
NGE
_DE
STR
OYE
D
0xC
037
002
1

The lock or unlock request uses an invalid guest operating


ERR system memory address. Restarting the virtual machine may
OR_ fix the problem. If the problem persists, try restarting the
VID physical computer.
_IN
VAL
ID_
CHI
LD_
GP
A_P
AGE
_SE
T
0xC
037
002
2
CONSTANT/VALUE DESCRIPTION

Cannot destroy or reuse the reserve page set for the


ERR virtualization infrastructure driver because it is in use.
OR_ Restarting the virtual machine may fix the problem. If the
VID problem persists, try restarting the physical computer.
_RE
SER
VE_
PA
GE_
SET
_IS_
BEI
NG_
USE
D
0xC
037
002
3

The reserve page set for the virtualization infrastructure driver


ERR is too small to use in the lock request. Restarting the virtual
OR_ machine may fix the problem. If the problem persists, try
VID restarting the physical computer.
_RE
SER
VE_
PA
GE_
SET
_TO
O_S
MA
LL
0xC
037
002
4
CONSTANT/VALUE DESCRIPTION

Cannot lock or map the memory block page for the


ERR virtualization infrastructure driver because it has already been
OR_ locked using a reserve page set page. Restarting the virtual
VID machine may fix the problem. If the problem persists, try
_MB restarting the physical computer.
P_A
LRE
AD
Y_L
OC
KED
_USI
NG_
RES
ERV
ED_
PA
GE
0xC
037
002
5

Cannot create the memory block for the virtualization


ERR infrastructure driver because the requested number of pages
OR_ exceeded the limit. Restarting the virtual machine may fix the
VID problem. If the problem persists, try restarting the physical
_MB computer.
P_C
OU
NT_
EXC
EED
ED_
LIMI
T
0xC
037
002
6

Cannot restore this virtual machine because the saved state


ERR data cannot be read. Delete the saved state data and then try
OR_ to start the virtual machine.
VID
_SA
VED
_ST
ATE
_CO
RRU
PT
0xC
037
002
7
CONSTANT/VALUE DESCRIPTION

Cannot restore this virtual machine because an item read


ERR from the saved state data is not recognized. Delete the saved
OR_ state data and then try to start the virtual machine.
VID
_SA
VED
_ST
ATE
_UN
REC
OG
NIZ
ED_I
TEM
0xC
037
002
8

Cannot restore this virtual machine to the saved state


ERR because of hypervisor incompatibility. Delete the saved state
OR_ data and then try to start the virtual machine.
VID
_SA
VED
_ST
ATE
_IN
CO
MP
ATI
BLE
0xC
037
002
9

A virtual machine is running with its memory allocated across


ERR multiple NUMA nodes. This does not indicate a problem
OR_ unless the performance of your virtual machine is unusually
VID slow. If you are experiencing performance problems, you may
_RE need to modify the NUMA configuration.
MO
TE_
NO
DE_
PAR
ENT
_GP
A_P
AGE
S_U
SED
0x8
037
000
1
Requirements

Header
Win
erro
r.h

See also
C
O
M
E
r
r
o
r
C
o
d
e
s
COM Error Codes (VOLMGR, BCD, VHD, SDIAG)
1/7/2020 • 10 minutes to read • Edit Online

The following table provides a list of error codes used by COM -based APIs.
If you are experiencing difficulty with an application you are installing or running, contact customer support for the
software that is displaying the error message. To obtain support for a Microsoft product, go to
https://support.microsoft.com.

CONSTANT/VALUE DESCRIPTION

The regeneration operation was not able to copy all data from
ERR the active plexes due to bad sectors.
OR_
VOL
MG
R_I
NC
OM
PLE
TE_
REG
ENE
RAT
ION
0x8
038
000
1

One or more disks were not fully migrated to the target pack.
ERR They may or may not require reimport after fixing the
OR_ hardware problems.
VOL
MG
R_I
NC
OM
PLE
TE_
DIS
K_M
IGR
ATI
ON
0x8
038
000
2
CONSTANT/VALUE DESCRIPTION

The configuration database is full.


ERR
OR_
VOL
MG
R_D
ATA
BAS
E_F
ULL
0xC
038
000
1

The configuration data on the disk is corrupted.


ERR
OR_
VOL
MG
R_D
ISK_
CO
NFI
GU
RAT
ION
_CO
RRU
PTE
D
0xC
038
000
2

The configuration on the disk is not insync with the in-


ERR memory configuration.
OR_
VOL
MG
R_D
ISK_
CO
NFI
GU
RAT
ION
_NO
T_I
N_S
YN
C
0xC
038
000
3
CONSTANT/VALUE DESCRIPTION

A majority of disks failed to be updated with the new


ERR configuration.
OR_
VOL
MG
R_P
ACK
_CO
NFI
G_U
PD
ATE
_FAI
LED
0xC
038
000
4

The disk contains non-simple volumes.


ERR
OR_
VOL
MG
R_D
ISK_
CO
NT
AIN
S_N
ON_
SIM
PLE
_VO
LU
ME
0xC
038
000
5

The same disk was specified more than once in the migration
ERR list.
OR_
VOL
MG
R_D
ISK_
DU
PLI
CAT
E
0xC
038
000
6
CONSTANT/VALUE DESCRIPTION

The disk is already dynamic.


ERR
OR_
VOL
MG
R_D
ISK_
DY
NA
MIC
0xC
038
000
7

The specified disk id is invalid. There are no disks with the


ERR specified disk id.
OR_
VOL
MG
R_D
ISK_
ID_I
NV
ALI
D
0xC
038
000
8

The specified disk is an invalid disk. Operation cannot


ERR complete on an invalid disk.
OR_
VOL
MG
R_D
ISK_
INV
ALI
D
0xC
038
000
9
CONSTANT/VALUE DESCRIPTION

The specified disk(s) cannot be removed since it is the last


ERR remaining voter.
OR_
VOL
MG
R_D
ISK_
LAS
T_V
OTE
R
0xC
038
000
A

The specified disk has an invalid disk layout.


ERR
OR_
VOL
MG
R_D
ISK_
LAY
OU
T_I
NV
ALI
D
0xC
038
000
B

The disk layout contains non-basic partitions which appear


ERR after basic paritions. This is an invalid disk layout.
OR_
VOL
MG
R_D
ISK_
LAY
OU
T_N
ON_
BAS
IC_B
ET
WEE
N_B
ASI
C_P
ART
ITIO
NS
0xC
038
000
C
CONSTANT/VALUE DESCRIPTION

The disk layout contains partitions which are not cylinder


ERR aligned.
OR_
VOL
MG
R_D
ISK_
LAY
OU
T_N
OT_
CYL
IND
ER_
ALI
GNE
D
0xC
038
000
D

The disk layout contains partitions which are samller than the
ERR minimum size.
OR_
VOL
MG
R_D
ISK_
LAY
OU
T_P
ART
ITIO
NS_
TO
O_S
MA
LL
0xC
038
000
E
CONSTANT/VALUE DESCRIPTION

The disk layout contains primary partitions in between logical


ERR drives. This is an invalid disk layout.
OR_
VOL
MG
R_D
ISK_
LAY
OU
T_P
RIM
ARY
_BE
TW
EEN
_LO
GIC
AL_
PAR
TITI
ON
S
0xC
038
000
F

The disk layout contains more than the maximum number of


ERR supported partitions.
OR_
VOL
MG
R_D
ISK_
LAY
OU
T_T
OO_
MA
NY_
PAR
TITI
ON
S
0xC
038
001
0
CONSTANT/VALUE DESCRIPTION

The specified disk is missing. The operation cannot complete


ERR on a missing disk.
OR_
VOL
MG
R_D
ISK_
MIS
SIN
G
0xC
038
001
1

The specified disk is not empty.


ERR
OR_
VOL
MG
R_D
ISK_
NO
T_E
MP
TY
0xC
038
001
2

There is not enough usable space for this operation.


ERR
OR_
VOL
MG
R_D
ISK_
NO
T_E
NO
UG
H_S
PAC
E
0xC
038
001
3
CONSTANT/VALUE DESCRIPTION

The force revectoring of bad sectors failed.


ERR
OR_
VOL
MG
R_D
ISK_
REV
ECT
ORI
NG_
FAIL
ED
0xC
038
001
4

The specified disk has an invalid sector size.


ERR
OR_
VOL
MG
R_D
ISK_
SEC
TOR
_SIZ
E_IN
VAL
ID
0xC
038
001
5

The specified disk set contains volumes which exist on disks


ERR outside of the set.
OR_
VOL
MG
R_D
ISK_
SET
_NO
T_C
ON
TAI
NED
0xC
038
001
6
CONSTANT/VALUE DESCRIPTION

A disk in the volume layout provides extents to more than


ERR one member of a plex.
OR_
VOL
MG
R_D
ISK_
USE
D_B
Y_M
ULT
IPLE
_ME
MB
ERS
0xC
038
001
7

A disk in the volume layout provides extents to more than


ERR one plex.
OR_
VOL
MG
R_D
ISK_
USE
D_B
Y_M
ULT
IPLE
_PL
EXE
S
0xC
038
001
8

Dynamic disks are not supported on this system.


ERR
OR_
VOL
MG
R_D
YN
AMI
C_D
ISK_
NO
T_S
UPP
ORT
ED
0xC
038
001
9
CONSTANT/VALUE DESCRIPTION

The specified extent is already used by other volumes.


ERR
OR_
VOL
MG
R_E
XTE
NT_
ALR
EAD
Y_U
SED
0xC
038
001
A

The specified volume is retained and can only be extended


ERR into a contiguous extent. The specified extent to grow the
OR_ volume is not contiguous with the specified volume.
VOL
MG
R_E
XTE
NT_
NO
T_C
ON
TIG
UO
US
0xC
038
001
B

The specified volume extent is not within the public region of


ERR the disk.
OR_
VOL
MG
R_E
XTE
NT_
NO
T_I
N_P
UBL
IC_R
EGI
ON
0xC
038
001
C
CONSTANT/VALUE DESCRIPTION

The specified volume extent is not sector aligned.


ERR
OR_
VOL
MG
R_E
XTE
NT_
NO
T_S
ECT
OR_
ALI
GNE
D
0xC
038
001
D

The specified parition overlaps an EBR (the first track of an


ERR extended partition on a MBR disks).
OR_
VOL
MG
R_E
XTE
NT_
OVE
RLA
PS_
EBR
_PA
RTI
TIO
N
0xC
038
001
E
CONSTANT/VALUE DESCRIPTION

The specified extent lengths cannot be used to construct a


ERR volume with specified length.
OR_
VOL
MG
R_E
XTE
NT_
VOL
UM
E_LE
NG
THS
_DO
_NO
T_M
ATC
H
0xC
038
001
F

The system does not support fault tolerant volumes.


ERR
OR_
VOL
MG
R_F
AUL
T_T
OLE
RA
NT_
NO
T_S
UPP
ORT
ED
0xC
038
002
0
CONSTANT/VALUE DESCRIPTION

The specified interleave length is invalid.


ERR
OR_
VOL
MG
R_I
NTE
RLE
AVE
_LE
NG
TH_
INV
ALI
D
0xC
038
002
1

There is already a maximum number of registered users.


ERR
OR_
VOL
MG
R_M
AXI
MU
M_R
EGI
STE
RED
_US
ERS
0xC
038
002
2

The specified member is already in-sync with the other active


ERR members. It does not need to be regenerated.
OR_
VOL
MG
R_M
EM
BER
_IN_
SYN
C
0xC
038
002
3
CONSTANT/VALUE DESCRIPTION

The same member index was specified more than once.


ERR
OR_
VOL
MG
R_M
EM
BER
_IN
DEX
_DU
PLI
CAT
E
0xC
038
002
4

The specified member index is greater or equal than the


ERR number of members in the volume plex.
OR_
VOL
MG
R_M
EM
BER
_IN
DEX
_IN
VAL
ID
0xC
038
002
5

The specified member is missing. It cannot be regenerated.


ERR
OR_
VOL
MG
R_M
EM
BER
_MI
SSI
NG
0xC
038
002
6
CONSTANT/VALUE DESCRIPTION

The specified member is not detached. Cannot replace a


ERR member which is not detached.
OR_
VOL
MG
R_M
EM
BER
_NO
T_D
ETA
CHE
D
0xC
038
002
7

The specified member is already regenerating.


ERR
OR_
VOL
MG
R_M
EM
BER
_RE
GEN
ERA
TIN
G
0xC
038
002
8

All disks belonging to the pack failed.


ERR
OR_
VOL
MG
R_A
LL_
DIS
KS_
FAIL
ED
0xC
038
002
9
CONSTANT/VALUE DESCRIPTION

There are currently no registered users for notifications. The


ERR task number is irrelevant unless there are registered users.
OR_
VOL
MG
R_N
O_R
EGI
STE
RED
_US
ERS
0xC
038
002
A

The specified notification user does not exist. Failed to


ERR unregister user for notifications.
OR_
VOL
MG
R_N
O_S
UC
H_U
SER
0xC
038
002
B

The notifications have been reset. Notifications for the current


ERR user are invalid. Unregister and re-register for notifications.
OR_
VOL
MG
R_N
OTI
FIC
ATI
ON_
RES
ET
0xC
038
002
C
CONSTANT/VALUE DESCRIPTION

The specified number of members is invalid.


ERR
OR_
VOL
MG
R_N
UM
BER
_OF
_ME
MB
ERS
_IN
VAL
ID
0xC
038
002
D

The specified number of plexes is invalid.


ERR
OR_
VOL
MG
R_N
UM
BER
_OF
_PL
EXE
S_I
NV
ALI
D
0xC
038
002
E

The specified source and target packs are identical.


ERR
OR_
VOL
MG
R_P
ACK
_DU
PLI
CAT
E
0xC
038
002
F
CONSTANT/VALUE DESCRIPTION

The specified pack id is invalid. There are no packs with the


ERR specified pack id.
OR_
VOL
MG
R_P
ACK
_ID_
INV
ALI
D
0xC
038
003
0

The specified pack is the invalid pack. The operation cannot


ERR complete with the invalid pack.
OR_
VOL
MG
R_P
ACK
_IN
VAL
ID
0xC
038
003
1

The specified pack name is invalid.


ERR
OR_
VOL
MG
R_P
ACK
_NA
ME_
INV
ALI
D
0xC
038
003
2
CONSTANT/VALUE DESCRIPTION

The specified pack is offline.


ERR
OR_
VOL
MG
R_P
ACK
_OF
FLI
NE
0xC
038
003
3

The specified pack already has a quorum of healthy disks.


ERR
OR_
VOL
MG
R_P
ACK
_HA
S_Q
UO
RU
M
0xC
038
003
4

The pack does not have a quorum of healthy disks.


ERR
OR_
VOL
MG
R_P
ACK
_WI
TH
OU
T_Q
UO
RU
M
0xC
038
003
5
CONSTANT/VALUE DESCRIPTION

The specified disk has an unsupported partition style. Only


ERR MBR and GPT partition styles are supported.
OR_
VOL
MG
R_P
ART
ITIO
N_S
TYL
E_IN
VAL
ID
0xC
038
003
6

Failed to update the disk's partition layout.


ERR
OR_
VOL
MG
R_P
ART
ITIO
N_U
PD
ATE
_FAI
LED
0xC
038
003
7

The specified plex is already in-sync with the other active


ERR plexes. It does not need to be regenerated.
OR_
VOL
MG
R_P
LEX
_IN_
SYN
C
0xC
038
003
8
CONSTANT/VALUE DESCRIPTION

The same plex index was specified more than once.


ERR
OR_
VOL
MG
R_P
LEX
_IN
DEX
_DU
PLI
CAT
E
0xC
038
003
9

The specified plex index is greater or equal than the number of


ERR plexes in the volume.
OR_
VOL
MG
R_P
LEX
_IN
DEX
_IN
VAL
ID
0xC
038
003
A

The specified plex is the last active plex in the volume. The plex
ERR cannot be removed or else the volume will go offline.
OR_
VOL
MG
R_P
LEX
_LA
ST_
ACT
IVE
0xC
038
003
B
CONSTANT/VALUE DESCRIPTION

The specified plex is missing.


ERR
OR_
VOL
MG
R_P
LEX
_MI
SSI
NG
0xC
038
003
C

The specified plex is currently regenerating.


ERR
OR_
VOL
MG
R_P
LEX
_RE
GEN
ERA
TIN
G
0xC
038
003
D

The specified plex type is invalid.


ERR
OR_
VOL
MG
R_P
LEX
_TY
PE_I
NV
ALI
D
0xC
038
003
E
CONSTANT/VALUE DESCRIPTION

The operation is only supported on RAID-5 plexes.


ERR
OR_
VOL
MG
R_P
LEX
_NO
T_R
AID
5
0xC
038
003
F

The operation is only supported on simple plexes.


ERR
OR_
VOL
MG
R_P
LEX
_NO
T_SI
MP
LE
0xC
038
004
0

The Size fields in the VM_VOLUME_LAYOUT input structure


ERR are incorrectly set.
OR_
VOL
MG
R_S
TRU
CTU
RE_
SIZE
_IN
VAL
ID
0xC
038
004
1
CONSTANT/VALUE DESCRIPTION

There is already a pending request for notifications. Wait for


ERR the existing request to return before requesting for more
OR_ notifications.
VOL
MG
R_T
OO_
MA
NY_
NO
TIFI
CAT
ION
_RE
QUE
STS
0xC
038
004
2

There is currently a transaction in process.


ERR
OR_
VOL
MG
R_T
RA
NS
ACT
ION
_IN_
PR
OG
RES
S
0xC
038
004
3
CONSTANT/VALUE DESCRIPTION

An unexpected layout change occurred outside of the volume


ERR manager.
OR_
VOL
MG
R_U
NEX
PEC
TED
_DIS
K_L
AY
OU
T_C
HA
NGE
0xC
038
004
4

The specified volume contains a missing disk.


ERR
OR_
VOL
MG
R_V
OLU
ME_
CO
NT
AIN
S_M
ISSI
NG_
DIS
K
0xC
038
004
5

The specified volume id is invalid. There are no volumes with


ERR the specified volume id.
OR_
VOL
MG
R_V
OLU
ME_
ID_I
NV
ALI
D
0xC
038
004
6
CONSTANT/VALUE DESCRIPTION

The specified volume length is invalid.


ERR
OR_
VOL
MG
R_V
OLU
ME_
LEN
GT
H_I
NV
ALI
D
0xC
038
004
7

The specified size for the volume is not a multiple of the sector
ERR size.
OR_
VOL
MG
R_V
OLU
ME_
LEN
GT
H_N
OT_
SEC
TOR
_SIZ
E_M
ULT
IPLE
0xC
038
004
8

The operation is only supported on mirrored volumes.


ERR
OR_
VOL
MG
R_V
OLU
ME_
NO
T_M
IRR
ORE
D
0xC
038
004
9
CONSTANT/VALUE DESCRIPTION

The specified volume does not have a retain partition.


ERR
OR_
VOL
MG
R_V
OLU
ME_
NO
T_R
ETA
INE
D
0xC
038
004
A

The specified volume is offline.


ERR
OR_
VOL
MG
R_V
OLU
ME_
OFF
LIN
E
0xC
038
004
B

The specified volume already has a retain partition.


ERR
OR_
VOL
MG
R_V
OLU
ME_
RET
AIN
ED
0xC
038
004
C
CONSTANT/VALUE DESCRIPTION

The specified number of extents is invalid.


ERR
OR_
VOL
MG
R_N
UM
BER
_OF
_EX
TEN
TS_I
NV
ALI
D
0xC
038
004
D

All disks participating to the volume must have the same


ERR sector size.
OR_
VOL
MG
R_D
IFFE
REN
T_S
ECT
OR_
SIZE
0xC
038
004
E

The boot disk experienced failures.


ERR
OR_
VOL
MG
R_B
AD_
BO
OT_
DIS
K
0xC
038
004
F
CONSTANT/VALUE DESCRIPTION

The configuration of the pack is offline.


ERR
OR_
VOL
MG
R_P
ACK
_CO
NFI
G_O
FFLI
NE
0xC
038
005
0

The configuration of the pack is online.


ERR
OR_
VOL
MG
R_P
ACK
_CO
NFI
G_O
NLI
NE
0xC
038
005
1

The specified pack is not the primary pack.


ERR
OR_
VOL
MG
R_N
OT_
PRI
MA
RY_
PAC
K
0xC
038
005
2
CONSTANT/VALUE DESCRIPTION

All disks failed to be updated with the new content of the log.
ERR
OR_
VOL
MG
R_P
ACK
_LO
G_U
PD
ATE
_FAI
LED
0xC
038
005
3

The specified number of disks in a plex is invalid.


ERR
OR_
VOL
MG
R_N
UM
BER
_OF
_DIS
KS_I
N_P
LEX
_IN
VAL
ID
0xC
038
005
4
CONSTANT/VALUE DESCRIPTION

The specified number of disks in a plex member is invalid.


ERR
OR_
VOL
MG
R_N
UM
BER
_OF
_DIS
KS_I
N_
ME
MB
ER_I
NV
ALI
D
0xC
038
005
5

The operation is not supported on mirrored volumes.


ERR
OR_
VOL
MG
R_V
OLU
ME_
MIR
RO
RED
0xC
038
005
6

The operation is only supported on simple and spanned


ERR plexes.
OR_
VOL
MG
R_P
LEX
_NO
T_SI
MP
LE_S
PA
NN
ED
0xC
038
005
7
CONSTANT/VALUE DESCRIPTION

The pack has no valid log copies.


ERR
OR_
VOL
MG
R_N
O_V
ALI
D_L
OG_
CO
PIES
0xC
038
005
8

A primary pack is already present.


ERR
OR_
VOL
MG
R_P
RIM
ARY
_PA
CK_
PRE
SEN
T
0xC
038
005
9

The specified number of disks is invalid.


ERR
OR_
VOL
MG
R_N
UM
BER
_OF
_DIS
KS_I
NV
ALI
D
0xC
038
005
A
CONSTANT/VALUE DESCRIPTION

The system does not support mirrored volumes.


ERR
OR_
VOL
MG
R_M
IRR
OR_
NO
T_S
UPP
ORT
ED
0xC
038
005
B

The system does not support RAID-5 volumes.


ERR
OR_
VOL
MG
R_R
AID
5_N
OT_
SUP
PO
RTE
D
0xC
038
005
C

Some BCD entries were not imported correctly from the BCD
ERR store.
OR_
BCD
_NO
T_A
LL_E
NTR
IES_
IMP
ORT
ED
0x8
039
000
1
CONSTANT/VALUE DESCRIPTION

Entries enumerated have exceeded the allowed threshold.


ERR
OR_
BCD
_TO
O_
MA
NY_
ELE
ME
NTS
0xC
039
000
2

Some BCD entries were not synchronized correctly with the


ERR firmware.
OR_
BCD
_NO
T_A
LL_E
NTR
IES_
SYN
CH
RO
NIZ
ED
0x8
039
000
3

The virtual hard disk is corrupted. The virtual hard disk drive
ERR footer is missing.
OR_
VH
D_D
RIV
E_F
OO
TER
_MI
SSI
NG
0xC
03A
000
1
CONSTANT/VALUE DESCRIPTION

The virtual hard disk is corrupted. The virtual hard disk drive
ERR footer checksum does not match the on-disk checksum.
OR_
VH
D_D
RIV
E_F
OO
TER
_CH
ECK
SU
M_
MIS
MA
TCH
0xC
03A
000
2

The virtual hard disk is corrupted. The virtual hard disk drive
ERR footer in the virtual hard disk is corrupted.
OR_
VH
D_D
RIV
E_F
OO
TER
_CO
RRU
PT
0xC
03A
000
3

The system does not recognize the file format of this virtual
ERR hard disk.
OR_
VH
D_F
OR
MA
T_U
NK
NO
WN
0xC
03A
000
4
CONSTANT/VALUE DESCRIPTION

The version does not support this version of the file format.
ERR
OR_
VH
D_F
OR
MA
T_U
NS
UPP
ORT
ED_
VER
SIO
N
0xC
03A
000
5

The virtual hard disk is corrupted. The sparse header


ERR checksum does not match the on-disk checksum.
OR_
VH
D_S
PAR
SE_
HEA
DER
_CH
ECK
SU
M_
MIS
MA
TCH
0xC
03A
000
6
CONSTANT/VALUE DESCRIPTION

The system does not support this version of the virtual hard
ERR disk.This version of the sparse header is not supported.
OR_
VH
D_S
PAR
SE_
HEA
DER
_UN
SUP
PO
RTE
D_V
ERSI
ON
0xC
03A
000
7

The virtual hard disk is corrupted. The sparse header in the


ERR virtual hard disk is corrupt.
OR_
VH
D_S
PAR
SE_
HEA
DER
_CO
RRU
PT
0xC
03A
000
8

Failed to write to the virtual hard disk failed because the


ERR system failed to allocate a new block in the virtual hard disk.
OR_
VH
D_B
LOC
K_A
LLO
CAT
ION
_FAI
LUR
E
0xC
03A
000
9
CONSTANT/VALUE DESCRIPTION

The virtual hard disk is corrupted. The block allocation table in


ERR the virtual hard disk is corrupt.
OR_
VH
D_B
LOC
K_A
LLO
CAT
ION
_TA
BLE
_CO
RRU
PT
0xC
03A
000
A

The system does not support this version of the virtual hard
ERR disk. The block size is invalid.
OR_
VH
D_I
NV
ALI
D_B
LOC
K_SI
ZE
0xC
03A
000
B

The virtual hard disk is corrupted. The block bitmap does not
ERR match with the block data present in the virtual hard disk.
OR_
VH
D_B
ITM
AP_
MIS
MA
TCH
0xC
03A
000
C
CONSTANT/VALUE DESCRIPTION

The chain of virtual hard disks is broken. The system cannot


ERR locate the parent virtual hard disk for the differencing disk.
OR_
VH
D_P
ARE
NT_
VH
D_N
OT_
FOU
ND
0xC
03A
000
D

The chain of virtual hard disks is corrupted. There is a


ERR mismatch in the identifiers of the parent virtual hard disk and
OR_ differencing disk.
VH
D_C
HIL
D_P
ARE
NT_
ID_
MIS
MA
TCH
0xC
03A
000
E

The chain of virtual hard disks is corrupted. The time stamp of


ERR the parent virtual hard disk does not match the time stamp of
OR_ the differencing disk.
VH
D_C
HIL
D_P
ARE
NT_
TIM
EST
AM
P_M
ISM
ATC
H
0xC
03A
000
F
CONSTANT/VALUE DESCRIPTION

Failed to read the metadata of the virtual hard disk.


ERR
OR_
VH
D_
MET
AD
ATA
_RE
AD_
FAIL
URE
0xC
03A
001
0

Failed to write to the metadata of the virtual hard disk.


ERR
OR_
VH
D_
MET
AD
ATA
_W
RITE
_FAI
LUR
E
0xC
03A
001
1

The size of the virtual hard disk is not valid.


ERR
OR_
VH
D_I
NV
ALI
D_SI
ZE
0xC
03A
001
2
CONSTANT/VALUE DESCRIPTION

The file size of this virtual hard disk is not valid.


ERR
OR_
VH
D_I
NV
ALI
D_FI
LE_S
IZE
0xC
03A
001
3

A virtual disk support provider for the specified file was not
ERR found.
OR_
VIR
TDI
SK_
PR
OVI
DER
_NO
T_F
OU
ND
0xC
03A
001
4

The specified disk is not a virtual disk.


ERR
OR_
VIR
TDI
SK_
NO
T_VI
RTU
AL_
DIS
K
0xC
03A
001
5
CONSTANT/VALUE DESCRIPTION

The chain of virtual hard disks is inaccessible. The process has


ERR not been granted access rights to the parent virtual hard disk
OR_ for the differencing disk.
VH
D_P
ARE
NT_
VH
D_A
CCE
SS_
DEN
IED
0xC
03A
001
6

The chain of virtual hard disks is corrupted. There is a


ERR mismatch in the virtual sizes of the parent virtual hard disk
OR_ and differencing disk.
VH
D_C
HIL
D_P
ARE
NT_
SIZE
_MI
SM
ATC
H
0xC
03A
001
7

The chain of virtual hard disks is corrupted. A differencing disk


ERR is indicated in its own parent chain.
OR_
VH
D_D
IFFE
REN
CIN
G_C
HAI
N_C
YCL
E_D
ETE
CTE
D
0xC
03A
001
8
CONSTANT/VALUE DESCRIPTION

The chain of virtual hard disks is inaccessible. There was an


ERR error opening a virtual hard disk further up the chain.
OR_
VH
D_D
IFFE
REN
CIN
G_C
HAI
N_E
RR
OR_
IN_
PAR
ENT
0xC
03A
001
9

The requested operation could not be completed due to a


ERR virtual disk system limitation. On NTFS, virtual hard disk files
OR_ must be uncompressed and unencrypted. On ReFS, virtual
VIR hard disk files must not have the integrity bit set.
TUA
L_DI
SK_
LIMI
TAT
ION
0xC
03A
001
A

The requested operation cannot be performed on a virtual


ERR disk of this type.
OR_
VH
D_I
NV
ALI
D_T
YPE
0xC
03A
001
B
CONSTANT/VALUE DESCRIPTION

The requested operation cannot be performed on the virtual


ERR disk in its current state.
OR_
VH
D_I
NV
ALI
D_S
TAT
E
0xC
03A
001
C

The sector size of the physical disk on which the virtual disk
ERR resides is not supported.
OR_
VIR
TDI
SK_
UN
SUP
PO
RTE
D_D
ISK_
SEC
TOR
_SIZ
E
0xC
03A
001
D

The disk is already owned by a different owner.


ERR
OR_
VIR
TDI
SK_
DIS
K_A
LRE
AD
Y_O
WN
ED
0xC
03A
001
E
CONSTANT/VALUE DESCRIPTION

The disk must be offline or read-only.


ERR
OR_
VIR
TDI
SK_
DIS
K_O
NLI
NE_
AN
D_
WRI
TAB
LE
0xC
03A
001
F

Change Tracking is not initialized for this Virtual Disk.


ERR
OR_
CTL
OG_
TRA
CKI
NG_
NO
T_I
NITI
ALI
ZED
0xC
03A
002
0

Size of change tracking file exceeded the maximum size limit


ERR
OR_
CTL
OG_
LOG
FILE
_SIZ
E_E
XCE
EDE
D_
MA
XSI
ZE
0xC
03A
002
1
CONSTANT/VALUE DESCRIPTION

VHD file is changed due to compaction, expansion or offline


ERR patching
OR_
CTL
OG_
VH
D_C
HA
NGE
D_O
FFLI
NE
0xC
03A
002
2

Change Tracking for the virtual disk is not in a valid state to


ERR perform this request. Change tracking could be discontinued
OR_ or already in the requested state.
CTL
OG_
INV
ALI
D_T
RAC
KIN
G_S
TAT
E
0xC
03A
002
3

Change Tracking file for the virtual disk is not in a valid state.
ERR
OR_
CTL
OG_
INC
ON
SIST
AN
T_T
RAC
KIN
G_FI
LE
0xC
03A
002
4
CONSTANT/VALUE DESCRIPTION

The requested resize operation could not be completed


ERR because it might truncate user data residing on the virtual
OR_ disk.
VH
D_R
ESIZ
E_W
OUL
D_T
RU
NC
ATE
_DA
TA
0xC
03A
002
5

The requested operation could not be completed because the


ERR virtual disk's minimum safe size could not be determined. This
OR_ may be due to a missing or corrupt partition table.
VH
D_C
OUL
D_N
OT_
CO
MP
UTE
_MI
NIM
UM
_VIR
TUA
L_SI
ZE
0xC
03A
002
6
CONSTANT/VALUE DESCRIPTION

The requested operation could not be completed because the


ERR virtual disk's size cannot be safely reduced further.
OR_
VH
D_A
LRE
AD
Y_A
T_O
R_B
ELO
W_
MIN
IMU
M_V
IRT
UAL
_SIZ
E
0xC
03A
002
7

There is not enough space in the virtual disk file for the
ERR provided metadata item.
OR_
VH
D_
MET
AD
ATA
_FU
LL
0xC
03A
002
8

The virtualization storage subsystem has generated an error.


ERR
OR_
QUE
RY_
STO
RA
GE_
ERR
OR
0x8
03A
000
1
CONSTANT/VALUE DESCRIPTION

The operation was canceled.


SDI
AG_
E_C
AN
CEL
LED
0x8
03C
010
0

An error occurred when running a PowerShell script.


SDI
AG_
E_S
CRI
PT
0x8
03C
010
1

An error occurred when interacting with PowerShell runtime.


SDI
AG_
E_P
OW
ERS
HEL
L
0x8
03C
010
2

An error occurred in the Scripted Diagnostic Managed Host.


SDI
AG_
E_M
AN
AGE
DH
OST
0x8
03C
010
3
CONSTANT/VALUE DESCRIPTION

The troubleshooting pack does not contain a required verifier


SDI to complete the verification.
AG_
E_N
OVE
RIFI
ER
0x8
03C
010
4

The troubleshooting pack cannot be executed on this system.


SDI
AG_
S_C
AN
NO
TRU
N
0x0
03C
010
5

Scripted diagnostics is disabled by group policy.


SDI
AG_
E_DI
SAB
LED
0x8
03C
010
6

Trust validation of the diagnostic package failed.


SDI
AG_
E_T
RUS
T
0x8
03C
010
7
CONSTANT/VALUE DESCRIPTION

The troubleshooting pack cannot be executed on this system.


SDI
AG_
E_C
AN
NO
TRU
N
0x8
03C
010
8

This version of the troubleshooting pack is not supported.


SDI
AG_
E_V
ERSI
ON
0x8
03C
010
9

A required resource cannot be loaded.


SDI
AG_
E_R
ESO
URC
E
0x8
03C
010
A

The troubleshooting pack reported information for a root


SDI cause without adding the root cause.
AG_
E_R
OO
TCA
USE
0x8
03C
010
B

Requirements

Header
Win
erro
r.h
See also
C
O
M
E
r
r
o
r
C
o
d
e
s
COM Error Codes (WPN, MBN, P2P, Bluetooth)
1/7/2020 • 6 minutes to read • Edit Online

The following table provides a list of error codes used by COM -based APIs.
If you are experiencing difficulty with an application you are installing or running, contact customer support for the
software that is displaying the error message. To obtain support for a Microsoft product, go to
https://support.microsoft.com.

W
P 0
N x
_ 8
E 0
_ 3
C E
H 0
A 1
N 0
N 0
E T
L h
_ e
C n
L o
O t
S i
E f
D i
c
a
t
i
o
n
c
h
a
n
n
e
l
h
a
s
a
l
r
e
a
d
y
b
e
e
n
c
l
o
s
e
d
.

W
P 0
N x
_ 8
E 0
_ 3
C E
H 0
A 1
N 0
N 1
E T
L h
_ e
R n
E o
Q t
U i
E f
S i
T c
_ a
N t
O i
T o
_ n
C c
O h
M a
P n
L n
E e
T l
E r
e
q
u
e
s
t
d
i
d
n
o
t
c
o
m
p
l
e
t
e
s
u
c
c
e
s
s
f
u
l
l
y
.

W
P 0
N x
_ 8
E 0
_ 3
I E
N 0
V 1
A 0
L 2
I T
D h
_ e
A a
P p
P p
l
i
c
a
t
i
o
n
i
d
e
n
t
i
f
i
e
r
p
r
o
v
i
d
e
d
i
s
i
n
v
a
l
i
d
.

W
P 0
N x
_ 8
E 0
_ 3
O E
U 0
T 1
S 0
T 3
A A
N n
D o
I t
N i
G
_ f
C i
H c
A a
N t
N i
E o
L n
_ c
R h
E a
Q n
U n
E e
S l
T r
e
q
u
e
s
t
f
o
r
t
h
e
p
r
o
v
i
d
e
d
a
p
p
l
i
c
a
t
i
o
n
i
d
e
n
t
i
f
i
e
r
i
s
i
n
p
r
o
g
r
e
s
s
.

W
P 0
N x
_ 8
E 0
_ 3
D E
U 0
P 1
L 0
I 4
C T
A h
T e
E c
_ h
C a
H n
A n
N e
N l
E i
L d
e
n
t
i
f
i
e
r
i
s
a
l
r
e
a
d
y
t
i
e
d
t
o
a
n
o
t
h
e
r
a
p
p
l
i
c
a
t
i
o
n
e
n
d
p
o
i
n
t
.

W
P 0
N x
_ 8
E 0
_ 3
P E
L 0
A 1
T 0
F 5
O
R T
M h
_ e
U n
N o
A t
V i
A f
I i
L c
A a
B t
L i
E o
n
p
l
a
t
f
o
r
m
i
s
u
n
a
v
a
i
l
a
b
l
e
.

W
P 0
N x
_ 8
E 0
_ 3
N E
O 0
T 1
I 0
F 6
I T
C h
A e
T n
I o
O t
N i
_ f
P i
O c
S a
T t
E i
D o
n
h
a
s
a
l
r
e
a
d
y
b
e
e
n
p
o
s
t
e
d
.

W
P 0
N x
_ 8
E 0
_ 3
N E
O 0
T 1
I 0
F 7
I T
C h
A e
T n
I
O o
N t
_ i
H f
I i
D c
D a
E t
N i
o
n
h
a
s
a
l
r
e
a
d
y
b
e
e
n
h
i
d
d
e
n
.

W
P 0
N x
_ 8
E 0
_ 3
N E
O 0
T 1
I 0
F 8
I T
C h
A e
T n
I o
O t
N i
_
N f
O i
T c
_ a
P t
O i
S o
T n
E c
D a
n
n
o
t
b
e
h
i
d
d
e
n
u
n
t
i
l
i
t
h
a
s
b
e
e
n
s
h
o
w
n
.

W
P 0
N x
_ 8
E 0
_ 3
C E
L 0
O 1
U 0
D 9
_
D C
I l
S o
A u
B d
L n
E o
D t
i
f
i
c
a
t
i
o
n
s
h
a
v
e
b
e
e
n
t
u
r
n
e
d
o
f
f.

W
P 0
N x
_ 8
E 0
_ 3
C E
L 0
O 1
U 1
D 0
_ T
I h
N e
C a
A p
P p
A l
B i
L c
E a
t
i
o
n
d
o
e
s
n
o
t
h
a
v
e
t
h
e
c
l
o
u
d
n
o
t
i
f
i
c
a
t
i
o
n
c
a
p
a
b
i
l
i
t
y
.

W
P 0
N x
_ 8
E 0
_ 3
N E
O 0
T 1
I 1
F 1
I S
C e
A t
T t
I i
O n
N g
_ s
D p
I r
S e
A v
B e
L n
E t
D t
h
e
n
o
t
i
f
i
c
a
t
i
o
n
f
r
o
m
b
e
i
n
g
d
e
l
i
v
e
r
e
d
.

W
P 0
N x
_ 8
E 0
_ 3
N E
O 0
T 1
I 1
F 2
I A
C p
A p
T l
I i
O c
N a
_ t
I i
N o
C n
A c
P a
A p
B a
L b
E i
l
i
t
i
e
s
p
r
e
v
e
n
t
t
h
e
n
o
t
i
f
i
c
a
t
i
o
n
f
r
o
m
b
e
i
n
g
d
e
l
i
v
e
r
e
d
.

W
P 0
N x
_ 8
E 0
_ 3
I E
N 0
T 1
E 1
R 3
N T
E h
T
_ e
I a
N p
C p
A l
P i
A c
B a
L t
E i
o
n
d
o
e
s
n
o
t
h
a
v
e
t
h
e
i
n
t
e
r
n
e
t
a
c
c
e
s
s
c
a
p
a
b
i
l
i
t
y
.
W 0
P x
N 8
_ 0
E 3
_ E
N 0
O 1
T 1
I 4
F
I S
C e
A t
T t
I i
O n
N g
_ s
T p
Y r
P e
E v
_ e
D n
I t
S t
A h
B e
L n
E o
D t
i
f
i
c
a
t
i
o
n
t
y
p
e
f
r
o
m
b
e
i
n
g
d
e
l
i
v
e
r
e
d
.

W
P 0
N x
_ 8
E 0
_ 3
N E
O 0
T 1
I 1
F 5
I T
C h
A e
T s
I i
O z
N e
_ o
S f
I t
Z h
E e
n
o
t
i
f
i
c
a
t
i
o
n
c
o
n
t
e
n
t
i
s
t
o
o
l
a
r
g
e
.

W
P 0
N x
_ 8
E 0
_ 3
T E
A 0
G 1
_ 1
S 6
I T
Z h
E e
s
i
z
e
o
f
t
h
e
n
o
t
i
f
i
c
a
t
i
o
n
t
a
g
i
s
t
o
o
l
a
r
g
e
.

W
P 0
N x
_ 8
E 0
_ 3
A E
C 0
C 1
E 1
S 7
S T
_ h
D e
E n
N o
I t
E i
D f
i
c
a
t
i
o
n
p
l
a
t
f
o
r
m
d
o
e
s
n
'
t
h
a
v
e
a
p
p
r
o
p
r
i
a
t
e
p
r
i
v
i
l
e
g
e
o
n
r
e
s
o
u
r
c
e
s
.

W
P 0
N x
_ 8
E 0
_ 3
D E
U 0
P 1
L 1
I 8
C
A T
T h
E e
_ n
R o
E t
G i
I f
S i
T c
R a
A t
T i
I o
O n
N p
l
a
t
f
o
r
m
f
o
u
n
d
a
p
p
l
i
c
a
t
i
o
n
i
s
a
l
r
e
a
d
y
r
e
g
i
s
t
e
r
e
d
.

W
P 0
N x
_ 8
E 0
_ 3
O E
U 0
T 2
_ 0
O 0
F T
_ h
S e
E n
S o
S t
I i
O f
N i
c
a
t
i
o
n
p
l
a
t
f
o
r
m
h
a
s
r
u
n
o
u
t
o
f
p
r
e
s
e
n
t
a
t
i
o
n
l
a
y
e
r
s
e
s
s
i
o
n
s
.

W
P 0
N x
_ 8
E 0
_ 3
P E
O 0
W 2
E 0
R 1
_ T
S h
A e
V n
E o
t
i
f
i
c
a
t
i
o
n
p
l
a
t
f
o
r
m
r
e
j
e
c
t
s
i
m
a
g
e
d
o
w
n
l
o
a
d
r
e
q
u
e
s
t
d
u
e
t
o
s
y
s
t
e
m
i
n
p
o
w
e
r
s
a
v
e
m
o
d
e
.

W
P 0
N x
_ 8
E 0
_ 3
I E
M 0
A 2
G 0
E 2
_ T
N h
O e
T n
_ o
F t
O i
U f
N i
D c
_ a
I t
N i
_ o
C n
A p
C l
H a
E t
f
o
r
m
d
o
e
s
n
'
t
h
a
v
e
t
h
e
r
e
q
u
e
s
t
e
d
i
m
a
g
e
i
n
i
t
s
c
a
c
h
e
.

W
P 0
N x
_ 8
E 0
_ 3
A E
L 0
L 2
_ 0
U 3
R
L T
_ h
N e
O n
T o
_ t
C i
O f
M i
P c
L a
E t
T i
E o
D n
p
l
a
t
f
o
r
m
c
a
n
n
o
t
c
o
m
p
l
e
t
e
a
l
l
o
f
r
e
q
u
e
s
t
e
d
i
m
a
g
e
.

W
P 0
N x
_ 8
E 0
_ 3
I E
N 0
V 2
A 0
L 4
I A
D c
_ l
C o
L u
O d
U i
D m
_ a
I g
M e
A d
G o
E w
n
l
o
a
d
e
d
f
r
o
m
t
h
e
n
o
t
i
f
i
c
a
t
i
o
n
p
l
a
t
f
o
r
m
i
s
i
n
v
a
l
i
d
.

W
P 0
N x
_ 8
E 0
_ 3
N E
O 0
T 2
I 0
F 5
I N
C o
A t
T i
I f
O i
N c
_ a
I t
D i
_ o
M n
A I
T d
C p
H
E r
D o
v
i
d
e
d
a
s
f
i
l
t
e
r
i
s
m
a
t
c
h
e
d
w
i
t
h
w
h
a
t
t
h
e
n
o
t
i
f
i
c
a
t
i
o
n
p
l
a
t
f
o
r
m
m
a
i
n
t
a
i
n
s
.

W
P 0
N x
_ 8
E 0
_ 3
C E
A 0
L 2
L 0
B 6
A N
C o
K t
_ i
A f
L i
R c
E a
A t
D i
Y o
_ n
R c
E a
G l
I l
S b
T a
E c
R k
E i
D n
t
e
r
f
a
c
e
i
s
a
l
r
e
a
d
y
r
e
g
i
s
t
e
r
e
d
.

W
P 0
N x
_ 8
E 0
_ 3
T E
O 0
A 2
S 0
T 7
_ T
N o
O a
T s
I t
F N
I o
C t
A i
T f
I i
O c
N a
_ t
D i
R o
O
P n
P w
E a
D s
d
r
o
p
p
e
d
w
i
t
h
o
u
t
b
e
i
n
g
d
i
s
p
l
a
y
e
d
t
o
t
h
e
u
s
e
r.

W
P 0
N x
_ 8
E 0
_ 3
S E
T 0
O 2
R 0
A 8
G
E T
_ h
L e
O n
C o
K t
E i
D f
i
c
a
t
i
o
n
p
l
a
t
f
o
r
m
d
o
e
s
n
o
t
h
a
v
e
t
h
e
p
r
o
p
e
r
p
r
i
v
i
l
e
g
e
s
t
o
c
o
m
p
l
e
t
e
t
h
e
r
e
q
u
e
s
t
.

E
_ 0
M x
B 8
N 0
_ 5
C 4
O 8
N 2
T 0
E 1
X C
T o
_ n
N t
O e
T x
_ t
A i
C s
T n
I o
V t
A a
T c
E t
D
i
v
a
t
e
d
.

E
_ 0
M x
B 8
N 0
_ 5
B 4
A 8
D 2
_ 0
S 2
I B
M a
d
S
I
M
i
s
i
n
s
e
r
t
e
d
.

E
_ 0
M x
B 8
N 0
_ 5
D 4
A 8
T 2
A 0
_ 3
C R
L e
A q
S u
S e
_ s
N t
O e
T d
_ d
A a
V t
A a
I c
L l
A a
B s
L s
E i
s
n
o
t
a
v
a
i
l
a
b
l
e
.

E
_ 0
M x
B 8
N 0
_ 5
I 4
N 8
V 2
A 0
L 4
I A
D c
_ c
A e
C s
C s
E p
S o
S i
_
S n
T t
R n
I a
N m
G e
(
A
P
N
)
o
r
A
c
c
e
s
s
s
t
r
i
n
g
i
s
i
n
c
o
r
r
e
c
t
.

E
_ 0
M x
B 8
N 0
_ 5
M 4
A 8
X 2
_ 0
A 5
C M
T a
I
V x
A a
T c
E t
D i
_ v
C a
O t
N e
T d
E c
X o
T n
S t
e
x
t
s
h
a
v
e
r
e
a
c
h
e
d
.

E
_ 0
M x
B 8
N 0
_ 5
P 4
A 8
C 2
K 0
E 6
T D
_ e
S v
V i
C c
_ e
D i
E s
T i
A
C n
H p
E a
D c
k
e
t
d
e
t
a
c
h
s
t
a
t
e
.

E
_ 0
M x
B 8
N 0
_ 5
P 4
R 8
O 2
V 0
I 7
D P
E r
R o
_ v
N i
O d
T e
_ r
V i
I s
S n
I o
B t
L v
E i
s
i
b
l
e
.

E
_ 0
M x
B 8
N 0
_ 5
R 4
A 8
D 2
I 0
O 8
_ R
P a
O d
W i
E o
R i
_ s
O p
F o
F w
e
r
e
d
o
f
f.

E
_ 0
M x
B 8
N 0
_ 5
S 4
E 8
R 2
V 0
I 9
C M
E B
_ N
N s
O u
T b
_ s
A c
C r
T i
I p
V t
A i
T o
E n
D i
s
n
o
t
a
c
t
i
v
a
t
e
d
.

E
_ 0
M x
B 8
N 0
_ 5
S 4
I 8
M 2
_ 0
N A
O S
T I
_ M
I i
N s
S n
E o
R t
T i
E n
D s
e
r
t
e
d
.
E 0
_ x
M 8
B 0
N 5
_ 4
V 8
O 2
I 0
C B
E
_ V
C o
A i
L c
L e
_ c
I a
N l
_ l
P i
R n
O p
G r
R o
E g
S r
S e
s
s
.

E
_ 0
M x
B 8
N 0
_ 5
I 4
N 8
V 2
A 0
L C
I V
D i
_ s
C i
A b
C l
H e
E p
r
o
v
i
d
e
r
c
a
c
h
e
i
s
i
n
v
a
l
i
d
.

E
_ 0
M x
B 8
N 0
_ 5
N 4
O 8
T 2
_ 0
R D
E D
G e
I v
S i
T c
E e
R i
E s
D n
o
t
r
e
g
i
s
t
e
r
e
d
.

E
_ 0
M x
B 8
N 0
_ 5
P 4
R 8
O 2
V 0
I E
D P
E r
R o
S v
_ i
N d
O e
T r
_ s
F n
O o
U t
N f
D o
u
n
d
.

E
_ 0
M x
B 8
N 0
_ 5
P 4
I 8
N 2
_ 0
N F
O P
T i
_ n
S i
U s
P n
P o
O t
R s
T u
E p
D p
o
r
t
e
d
.

E
_ 0
M x
B 8
N 0
_ 5
P 4
I 8
N 2
_ 1
R 0
E P
Q i
U n
I i
R s
E r
D e
q
u
i
r
e
d
.

E
_ 0
M x
B 8
N 0
_ 5
P 4
I 8
N 2
_ 1
D 1
I
S P
A I
B N
L i
E s
D d
i
s
a
b
l
e
d
.

E
_ 0
M x
B 8
N 0
_ 5
F 4
A 8
I 2
L 1
U 2
R G
E e
n
e
r
i
c
F
a
i
l
u
r
e
.

E
_ 0
M x
B 8
N 0
_ 5
I 4
8
N 2
V 1
A 8
L
I P
D r
_ o
P f
R i
O l
F e
I i
L s
E i
n
v
a
l
i
d
.

E
_ 0
M x
B 8
N 0
_ 5
D 4
E 8
F 2
A 1
U 9
L D
T e
_ f
P a
R u
O l
F t
I p
L r
E o
_ f
E i
X l
I e
S e
T x
i
s
t
.

E
_ 0
M x
B 8
N 0
_ 5
S 4
M 8
S 2
_ 2
E 0
N S
C M
O S
D e
I n
N c
G o
_ d
N i
O n
T g
_ i
S s
U n
P o
P t
O s
R u
T p
E p
D o
r
t
e
d
.

E
_ 0
M x
B 8
N 0
_ 5
S 4
M 8
S 2
_ 2
F 1
I
L S
T M
E S
R f
_ i
N l
O t
T e
_ r
S i
U s
P n
P o
O t
R s
T u
E p
D p
o
r
t
e
d
.

E
_ 0
M x
B 8
N 0
_ 5
S 4
M 8
S 2
_ 2
I 2
N I
V n
A v
L a
I l
D i
_ d
M S
E M
M S
O m
R e
Y m
_ o
I r
N y
D i
E n
X d
e
x
i
s
u
s
e
d
.

E
_ 0
M x
B 8
N 0
_ 5
S 4
M 8
S 2
_ 2
L 3
A S
N M
G S
_ l
N a
O n
T g
_ u
S a
U g
P e
P i
O s
R n
T o
E t
D s
u
p
p
o
r
t
e
d
.

E
_ 0
M x
B 8
N 0
_ 5
S 4
M 8
S 2
_ 2
M 4
E S
M M
O S
R m
Y e
_ m
F o
A r
I y
L f
U a
R i
E l
u
r
e
o
c
c
u
r
r
e
d
.

E
_ 0
M x
B 8
N 0
_ 5
S 4
M 8
S 2
_ 2
N 5
E S
T M
W S
O n
R e
K t
_ w
T o
I r
M k
E t
O i
U m
T e
o
u
t
h
a
p
p
e
n
e
d
.

E
_ 0
M x
B 8
N 0
_ 5
S 4
M 8
S 2
_ 2
U 6
N U
K n
N k
O n
W o
N w
_ n
S S
M M
S S
C C
_ a
A d
D d
D
R r
E e
S s
S s
i
s
u
s
e
d
.

E
_ 0
M x
B 8
N 0
_ 5
S 4
M 8
S 2
_ 2
F 7
O S
R M
M S
A f
T o
_ r
N m
O a
T t
_ i
S s
U n
P o
P t
O s
R u
T p
E p
D o
r
t
e
d
.

E
_ 0
M x
B 8
N 0
_ 5
S 4
M 8
S 2
_ 2
O 8
P
E S
R M
A S
T o
I p
O e
N r
_ a
N t
O i
T o
_ n
A i
L s
L n
O o
W t
E a
D l
l
o
w
e
d
.

E
_ 0
M x
B 8
N 0
_ 5
S 4
M 8
S 2
_ 2
M 9
E D
M e
O v
R i
Y c
_ e
F S
U M
L S
L m
e
m
o
r
y
i
s
f
u
l
l.

P
E 0
E x
R 8
_ 0
E 6
_ 3
I 0
P 0
V 0
6 1
_ T
N h
O e
T I
_ P
I v
N 6
S p
T r
A o
L t
L o
E c
D o
l
i
s
n
o
t
i
n
s
t
a
l
l
e
d
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
N 0
O 0
T 0
_ 2
I T
N h
I e
T c
I o
A m
L p
I o
Z n
E e
D n
t
h
a
s
n
o
t
b
e
e
n
i
n
i
t
i
a
l
i
z
e
d
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
C 0
A 0
N 0
N 3
O T
T h
_ e
S r
T e
A q
R u
T i
_ r
S e
E d
R s
V e
I r
C v
E i
c
e
c
a
n
o
t
b
e
s
t
a
r
t
e
d
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
N 0
O 0
T 0
_ 4
L
I T
C h
E e
N P
S 2
E P
D p
r
o
t
o
c
o
l
i
s
n
o
t
l
i
c
e
n
s
e
d
t
o
r
u
n
o
n
t
h
i
s
O
S
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
I 0
N 0
V 1
A 0
L
I T
D h
_ e
G g
R r
A a
P p
H h
h
a
n
d
l
e
i
s
i
n
v
a
l
i
d
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
D 0
B 0
N 1
A 1
M T
E h
_ e
C G
H R
A a
N p
G h
E i
D n
g
d
a
t
a
b
a
s
e
n
a
m
e
h
a
s
c
h
a
n
g
e
d
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
D 0
U 0
P 1
L 2
I A
C g
A r
T a
E p
_ h
G w
R i
A t
P h
H t
h
e
s
a
m
e
I
D
a
l
r
e
a
d
y
e
x
i
s
t
s
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
G 0
R 0
A 1
P 3
H T
_ h
N e
O g
T r
_ a
R p
E h
A i
D s
Y n
o
t
r
e
a
d
y
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
G 0
R 0
A 1
P 4
H T
_ h
S e
H g
U r
T a
T p
I h
N i
G s
_ s
D h
O u
W t
N t
i
n
g
d
o
w
n
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
G 0
R 0
A 1
P 5
H T
_ h
I e
N g
_ r
U a
S p
E h
i
s
s
t
i
l
l
i
n
u
s
e
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
I 0
N 0
V 1
A 6
L T
I h
D e
_ g
D r
A a
T p
A h
B d
A a
S t
E a
b
a
s
e
i
s
c
o
r
r
u
p
t
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
T 0
O 0
O 1
_ 7
M T
A o
N o
Y m
_ a
A n
T y
T a
R t
I t
B r
U i
T b
E u
S t
e
s
h
a
v
e
b
e
e
n
u
s
e
d
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
C 0
O 1
N 0
N 3
E
C T
T h
I e
O c
N o
_ n
N n
O e
T c
_ t
F i
O o
U n
N c
D a
n
n
o
t
b
e
f
o
u
n
d
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
C 0
O 1
N 0
N 6
E T
C h
T e
_ p
S e
E e
L r
F a
t
t
e
m
p
t
e
d
t
o
c
o
n
n
e
c
t
t
o
i
t
s
e
l
f.

P
E 0
E x
R 8
_ 0
E 6
_ 3
A 0
L 1
R 0
E 7
A T
D h
Y e
_ p
L e
I e
S r
T i
E s
N
I a
N l
G r
e
a
d
y
l
i
s
t
e
n
i
n
g
f
o
r
c
o
n
n
e
c
t
i
o
n
s
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
N 0
O 1
D 0
E 8
_ T
N h
O e
T n
_ o
F d
O e
U w
N
D a
s
n
o
t
f
o
u
n
d
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
C 0
O 1
N 0
N 9
E T
C h
T e
I C
O o
N n
_ n
F e
A c
I t
L i
E o
D n
a
t
t
e
m
p
t
f
a
i
l
e
d
.
P 0
E x
E 8
R 0
_ 6
E 3
_ 0
C 1
O 0
N A
N
E T
C h
T e
I p
O e
N e
_ r
N c
O o
T n
_ n
A e
U c
T t
H i
E o
N n
T c
I o
C u
A l
T d
E n
D o
t
b
e
a
u
t
h
e
n
t
i
c
a
t
e
d
.
P
E 0
E x
R 8
_ 0
E 6
_ 3
C 0
O 1
N 0
N B
E T
C h
T e
I c
O o
N n
_ n
R e
E c
F t
U i
S o
E n
D w
a
s
r
e
f
u
s
e
d
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
C 0
L 2
A 0
S 1
S T
I h
F e
I p
E e
R e
_ r
T n
O a
O m
_ e
L c
O l
N a
G s
s
i
f
i
e
r
i
s
t
o
o
l
o
n
g
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
T 0
O 2
O 0
_ 2
M T
A h
N e
Y m
_ a
I x
D i
E m
N u
T m
I n
T
I u
E m
S b
e
r
o
f
i
d
e
n
t
i
e
s
h
a
v
e
b
e
e
n
c
r
e
a
t
e
d
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
N 0
O 2
_ 0
K 3
E U
Y n
_ a
A b
C l
C e
E t
S o
S
a
c
c
e
s
s
a
k
e
y
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
G 0
R 2
O 0
U 4
P T
S h
_ e
E g
X r
I o
S u
T p
a
l
r
e
a
d
y
e
x
i
s
t
s
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
R 0
E 3
C 0
O 1
R
D T
_ h
N e
O r
T e
_ q
F u
O e
U s
N t
D e
d
r
e
c
o
r
d
c
o
u
l
d
n
o
t
b
e
f
o
u
n
d
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
D 0
A 3
T 0
A 2
B
A A
S c
E c
_ e
A s
C s
C t
E o
S t
S h
D e
E d
N a
I t
E a
D b
a
s
e
w
a
s
d
e
n
i
e
d
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
D 0
B 3
I 0
N 3
I T
T h
I e
A D
L a
I t
Z a
A b
T a
I s
O e
N c
_ o
F u
A l
I d
L n
E o
D t
b
e
i
n
i
t
i
a
l
i
z
e
d
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
M 0
A 3
X 0
_ 4
R T
E h
C e
O r
R e
D c
_ o
S r
I d
Z i
E s
_ t
E o
X o
C b
E
E i
D g
E .
D

P
E 0
E x
R 8
_ 0
E 6
_ 3
D 0
A 3
T 0
A 5
B T
A h
S e
E d
_ a
A t
L a
R b
E a
A s
D e
Y a
_ l
P r
R e
E a
S d
E y
N e
T x
i
s
t
s
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
D 0
A 3
0
T 6
A
B T
A h
S e
E d
_ a
N t
O a
T b
_ a
P s
R e
E c
S o
E u
N l
T d
n
o
t
b
e
f
o
u
n
d
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
I 0
D 4
E 0
N 1
T T
I h
T e
Y i
_ d
N e
O n
T t
_ i
F t
O y
U c
N o
D u
l
d
n
o
t
b
e
f
o
u
n
d
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
E 0
V 5
E 0
N 1
T T
_ h
H e
A e
N v
D e
L n
E t
_ h
N a
O n
T d
_ l
F e
O c
U o
N u
D l
d
n
o
t
b
e
f
o
u
n
d
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
I 0
N 6
V 0
A 1
L I
I n
D v
_ a
S l
E i
A d
R s
C e
H a
r
c
h
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
I 0
N 6
V 0
A 2
L T
I h
D e
_ s
A e
T a
T r
R c
I h
B a
U t
T t
E r
S i
b
u
t
e
s
a
r
e
i
n
v
a
l
i
d
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
I 0
N 7
V 0
I 1
T T
A h
T e
I i
O n
N v
_ i
N t
O i
T a
_ t
T i
R o
U n
S i
T
E s
D n
o
t
t
r
u
s
t
e
d
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
C 0
H 7
A 0
I 3
N T
_ h
T e
O c
O e
_ r
L t
O c
N h
G a
i
n
i
s
t
o
o
l
o
n
g
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
I 0
N 7
V 0
A 5
L
I T
D h
_ e
T t
I i
M m
E e
_ p
P e
E r
R i
I o
O d
D i
s
i
n
v
a
l
i
d
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
C 0
I 7
R 0
C 6
U A
L c
A i
R r
_ c
C u
H l
A a
I r
N c
_ e
D r
E t
T c
E h
C a
T i
E n
D w
a
s
d
e
t
e
c
t
e
d
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
C 0
E 8
R 0
T 1
_ T
S h
T e
O c
R e
E r
_ t
C s
O t
R o
R r
U e
P i
T s
E c
D o
r
r
u
p
t
e
d
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
N 1
O 0
_ 0
C 1
L T
O h
U e
D s
p
e
c
i
f
i
e
d
P
N
R
P
c
l
o
u
d
d
e
o
s
n
o
t
e
x
i
s
t
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
C 1
L 0
O 0
U 5
D T
_ h
N e
A c
M l
E o
_ u
A d
M n
B a
I m
G e
U i
O s
U a
S m
b
i
g
u
o
u
s
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
I 2
N 0
V 1
A 0
L T
I h
D e
_ r
R e
E c
C o
O r
R d
D i
s
i
n
v
l
a
i
d
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
N 2
O 0
T 2
_ 0
A N
U o
T t
H a
O u
R t
I h
Z o
E r
D i
z
e
d
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
P 2
A 0
S 2
S 1
W
O T
R h
D e
_ p
D a
O s
E s
S w
_ o
N r
O d
T d
_ o
M e
E s
E n
T o
_ t
P m
O e
L e
I t
C p
Y o
l
i
c
y
r
e
q
u
i
r
e
m
e
n
t
s
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
D 2
E 0
F 3
E 0
R
R T
E h
D e
_ r
V e
A c
L o
I r
D d
A v
T a
I l
O i
N d
a
t
i
o
n
h
a
s
b
e
e
n
d
e
f
e
r
e
d
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
I 2
N 0
V 4
A 0
L
I T
D h
_ e
G g
R r
O o
U u
P p
_ p
P r
R o
O p
P e
E r
R i
T e
I s
E a
S r
e
i
n
v
a
l
i
d
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
I 2
N 0
V 5
A 0
L T
I h
D e
_ p
P e
E e
E r
R n
_ a
N m
A e
M i
E s
i
n
v
a
l
i
d
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
I 2
N 0
V 6
A 0
L T
I h
D e
_ c
C l
L a
A s
S s
S i
I f
F i
I e
E r
R i
s
i
n
v
a
l
i
d
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
I 2
N 0
V 7
A 0
L
I T
D h
_ e
F f
R r
I i
E e
N n
D d
L l
Y y
_ n
N a
A m
M e
E i
s
i
n
v
a
l
i
d
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
I 2
N 0
V 7
A 1
L I
I n
D v
_ a
R l
O i
L d
E r
_ o
P l
R e
O p
P r
E o
R p
T e
Y r
t
y
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
I 2
N 0
V 7
A 2
L I
I n
D v
_ a
C l
L i
A d
S c
S l
I a
F s
I s
E i
R f
_ i
P e
R r
O p
P r
E o
R t
T o
Y p
e
r
y
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
I 2
N 0
V 8
A 0
L I
I n
D v
_ l
R a
E i
C d
O r
R e
D c
_ o
E r
X d
P e
I x
R p
A i
T r
I a
O t
N i
o
n
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
I 2
N 0
V 8
A 1
L I
I n
D v
_ l
C a
R i
E d
D c
E r
N e
T d
I e
A n
L t
_ i
I a
N l
F i
O n
f
o
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
I 2
N 0
V 8
A 2
L I
I n
D v
_ a
C l
R i
E d
D c
E r
N e
T d
I e
A n
L t
i
a
l.

P
E 0
E x
R 8
_ 0
E 6
_ 3
I 2
N 0
V 8
A 3
L
I I
D n
_ v
R a
E l
C i
O d
R r
D e
_ c
S o
I r
Z d
E s
i
z
e
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
U 2
N 0
S 9
U 0
P U
P n
O s
R u
T p
E p
D o
_ r
V t
E e
R
S d
I v
O e
N r
s
i
o
n
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
G 2
R 0
O 9
U 1
P T
_ h
N e
O g
T r
_ o
R u
E p
A i
D s
Y n
o
t
r
e
a
d
y
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
G 2
R 0
O 9
U 2
P
_ T
I h
N e
_ g
U r
S o
E u
p
i
s
s
t
i
l
l
i
n
u
s
e
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
I 2
N 0
V 9
A 3
L T
I h
D e
_ g
G r
R o
O u
U p
P i
s
i
n
v
a
l
i
d
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
N 2
O 0
_ 9
M 4
E N
M o
B m
E e
R m
S b
_ e
F r
O s
U w
N e
D r
e
f
o
u
n
d
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
N 2
O 0
_ 9
M 5
E T
M h
B e
E r
R e
_ a
C
O r
N e
N n
E o
C m
T e
I m
O b
N e
S r
c
o
n
n
e
c
t
i
o
n
s
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
U 2
N 0
A 9
B 6
L U
E n
_ a
T b
O l
_ e
L t
I o
S l
T i
E s
N t
e
n
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
I 2
D 0
E A
N 0
T
I T
T h
Y e
_ i
D d
E e
L n
E t
T i
E t
D y
d
o
e
s
n
o
t
e
x
i
s
t
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
S 2
E 0
R A
V 1
I T
C h
E e
_ s
N
O e
T r
_ v
A i
V c
A e
I i
L s
A n
B o
L t
E a
v
a
i
l
i
b
l
e
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
C 6
O 0
N 0
T 1
A T
C h
T e
_ c
N o
O n
T t
_ a
F c
O t
U c
N o
D u
l
d
n
o
t
b
e
f
o
u
n
d
.

P
E 0
E x
R 0
_ 0
S 6
_ 3
G 0
R 0
A 0
P 1
H T
_ h
D e
A g
T r
A a
_ p
C h
R d
E a
A t
T a
E w
D a
s
c
r
e
a
t
e
d
.

P
E 0
E x
R 0
_ 0
S 6
_ 3
N 0
O 0
_ 0
E 2
V
E T
N h
T e
_ r
D e
A i
T s
A n
o
t
m
o
r
e
e
v
e
n
t
d
a
t
a
.

P
E 0
E x
R 0
_ 0
S 6
_ 3
A 2
L 0
R 0
E 0
A T
D h
Y e
_ g
C r
O a
N p
N h
E i
C s
T a
E l
D r
e
a
d
y
c
o
n
n
e
c
t
.

P
E 0
E x
R 0
_ 0
S 6
_ 3
S 6
U 0
B 0
S 0
C T
R h
I e
P s
T u
I b
O s
N c
_ r
E i
X p
I t
S i
T o
S n
a
l
r
e
a
d
y
e
x
i
s
t
s
.

P
E 0
E x
R 0
_ 0
S 6
_ 3
N 0
O 0
_ 0
C 5
O N
N o
N c
E o
C n
T n
I e
V c
I t
T i
Y v
i
t
y
.

P
E 0
E x
R 0
_ 0
S 6
_ 3
A 0
L 0
R 0
E 6
A A
D l
Y r
_ e
A a
_ d
M y
E a
M m
B e
E m
R b
e
r.

P
E 0
E x
R 8
_ 0
E 6
_ 3
C 4
A 0
N 0
N 1
O T
T h
_ e
C p
O e
N e
V r
E n
R a
T m
_ e
P c
E o
E u
R l
_ d
N n
A o
M t
E b
e
c
o
n
v
e
r
t
e
d
t
o
a
D
N
S
p
n
r
p
n
a
m
e
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
I 4
N 0
V 0
A 2
L I
I n
D v
_ a
P l
E i
E d
R p
_ e
H e
O r
S h
T o
_ s
N t
A n
M a
E m
e
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
N 4
O 0
_ 0
M 3
O
R N
E o
m
o
r
e
d
a
t
a
c
o
u
l
d
b
e
f
o
u
n
d
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
P 4
N 0
R 0
P 5
_ T
D h
U e
P e
L x
I i
C s
A t
T i
E n
_ g
P p
E e
E e
R r
_ n
N a
A m
M e
E i
s
a
l
r
e
a
d
y
r
e
g
i
s
t
e
r
e
d
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
I 7
N 0
V 0
I 0
T T
E h
_ e
C a
A p
N p
C i
E n
L v
L i
E t
D
e
r
e
q
u
e
s
t
w
a
s
c
a
n
c
e
l
d
b
y
t
h
e
u
s
e
r.

P
E 0
E x
R 8
_ 0
E 6
_ 3
I 7
N 0
V 0
I 1
T N
E o
_ r
R e
E s
S p
P o
O s
N e
S o
E t
_ t
N
O h
T e
_ i
A n
V v
A i
I t
L e
A w
B a
L s
E r
e
c
e
i
v
e
d
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
N 7
O 0
T 0
_ 3
S U
I s
G e
N r
E i
D s
_ n
I o
N t
s
i
g
e
d
i
n
t
o
s
e
r
v
e
r
l
e
s
s
p
r
e
s
e
n
c
e
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
P 7
R 0
I 0
V 4
A T
C h
Y e
_ u
D s
E e
C r
L d
I e
N c
E l
D i
n
d
e
d
t
h
e
p
r
i
v
a
c
y
p
o
l
i
c
y
p
r
o
m
p
t
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
T 7
I 0
M 0
E 5
O A
U t
T i
m
e
o
u
t
o
c
c
u
r
e
d
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
I 7
N 0
V 0
A 7
L
I T
D h
_ e
A a
D d
D d
R r
E e
S s
S s
i
s
i
n
v
a
l
i
d
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
F 7
W 0
_ 0
E 8
X A
C r
E e
P q
T u
I i
O r
N e
_ d
D f
I i
S r
A e
B w
L a
E l
D l
e
x
c
e
p
t
i
o
n
i
s
d
i
s
a
b
l
e
d
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
F 7
W 0
_ 0
B 9
L T
O h
C e
K s
E e
D r
_ v
B i
Y c
_ e
P i
O s
L b
I l
C
Y o
c
k
b
y
a
f
i
r
e
w
a
l
l
p
o
l
i
c
y
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
F 7
W 0
_ 0
B A
L F
O i
C r
K e
E w
D a
_ l
B l
Y e
_ x
S c
H e
I p
E t
L i
D o
S n
_ s
U
P a
r
e
d
i
s
a
b
l
e
d
.

P
E 0
E x
R 8
_ 0
E 6
_ 3
F 7
W 0
_ 0
D B
E T
C h
L e
I u
N s
E e
D r
d
e
c
l
i
n
d
e
d
t
o
e
n
a
b
l
e
t
h
e
f
i
r
e
w
a
l
l
e
x
c
e
p
t
i
o
n
s
.

E
_ 0
B x
L 8
U 0
E 6
T 5
O 0
O 0
T 0
H 1
_ T
A h
T e
T a
_ t
I t
N r
V i
A b
L u
I t
D e
_ h
H a
A n
N d
D l
L e
E g
i
v
e
n
w
a
s
n
o
t
v
a
l
i
d
o
n
t
h
i
s
s
e
r
v
e
r.

E
_ 0
B x
L 8
U 0
E 6
T 5
O 0
O 0
T 0
H 2
_ T
A h
T e
T a
_ t
R t
E r
A i
D b
_ u
N t
O e
T c
_
P a
E n
R n
M o
I t
T b
T e
E r
D e
a
d
.

E
_ 0
B x
L 8
U 0
E 6
T 5
O 0
O 0
T 0
H 3
_ T
A h
T e
T a
_ t
W t
R r
I i
T b
E u
_ t
N e
O c
T a
_ n
P n
E o
R t
M b
I e
T w
T r
E i
D t
t
e
n
.

E
_ 0
B x
L 8
U 0
E 6
T 5
O 0
O 0
T 0
H 4
_ T
A h
T e
T a
_ t
I t
N r
V i
A b
L u
I t
D e
_ P
P D
D U
U w
a
s
i
n
v
a
l
i
d
.

E
_ 0
B x
L 8
U 0
E 6
T 5
O 0
O 0
T 0
H 5
_ T
A h
T e
T a
_ t
I t
N r
S i
U b
F u
F t
I e
C r
I e
E q
N u
T i
_ r
A e
U s
T a
H u
E t
N h
T e
I n
C t
A i
T c
I a
O t
N i
o
n
b
e
f
o
r
e
i
t
c
a
n
b
e
r
e
a
d
o
r
w
r
i
t
t
e
n
.

E
_ 0
B x
L 8
U 0
E 6
T 5
O 0
O 0
T 0
H 6
_ A
A t
T t
T r
_ i
R b
E u
Q t
U e
E s
S e
T r
_ v
N e
O r
T d
_ o
S e
U s
P n
P o
O t
R s
T u
E p
D p
o
r
t
t
h
e
r
e
q
u
e
s
t
r
e
c
e
i
v
e
d
f
r
o
m
t
h
e
c
l
i
e
n
t
.

E
_ 0
B x
L 8
U 0
E 6
T 5
O 0
O 0
T 0
H 7
_ O
A f
T f
T s
_ e
I t
N s
V p
A
L e
I c
D i
_ f
O i
F e
F d
S w
E a
T s
p
a
s
t
t
h
e
e
n
d
o
f
t
h
e
a
t
t
r
i
b
u
t
e
.

E
_ 0
B x
L 8
U 0
E 6
T 5
O 0
O 0
T 0
H 8
_ T
A h
T e
T a
_
I t
N t
S r
U i
F b
F u
I t
C e
I r
E e
N q
T u
_ i
A r
U e
T s
H a
O u
R t
I h
Z o
A r
T i
I z
O a
N t
i
o
n
b
e
f
o
r
e
i
t
c
a
n
b
e
r
e
a
d
o
r
w
r
i
t
t
e
n
.

E
_ 0
B x
L 8
U 0
E 6
T 5
O 0
O 0
T 0
H 9
_ T
A o
T o
T m
_ a
P n
R y
E p
P r
A e
R p
E a
_ r
Q e
U w
E r
U i
E t
_ e
F s
U h
L a
L v
e
b
e
e
n
q
u
e
u
e
d
.
E
_ 0
B x
L 8
U 0
E 6
T 5
O 0
O 0
T 0
H A
_ N
A o
T a
T t
_ t
A r
T i
T b
R u
I t
B e
U f
T o
E u
_ n
N d
O w
T i
_ t
F h
O i
U n
N t
D h
e
g
i
v
e
n
a
t
t
r
i
b
u
t
e
h
a
n
d
l
e
r
a
n
g
e
.

E
_ 0
B x
L 8
U 0
E 6
T 5
O 0
O 0
T 0
H B
_ T
A h
T e
T a
_ t
A t
T r
T i
R b
I u
B t
U e
T c
E a
_ n
N n
O o
T t
_ b
L e
O r
N e
G a
d
o
r
w
r
i
t
t
e
n
u
s
i
n
g
t
h
e
R
e
a
d
B
l
o
b
R
e
q
u
e
s
t
.

E
_ 0
B x
L 8
U 0
E 6
T 5
O 0
O 0
T 0
H C
_ T
A h
T e
T E
_ n
I c
N r
S y
U p
F t
F
I i
C o
I n
E K
N e
T y
_ S
E i
N z
C e
R u
Y s
P e
T d
I f
O o
N r
_ e
K n
E c
Y r
_ y
S p
I t
Z i
E n
g
t
h
i
s
l
i
n
k
i
s
i
n
s
u
f
f
i
c
i
e
n
t
.

E
_ 0
B x
L 8
U 0
E 6
T 5
O 0
O 0
T 0
H D
_
A T
T h
T e
_ a
I t
N t
V r
A i
L b
I u
D t
_ e
A v
T a
T l
R u
I e
B l
U e
T n
E g
_ t
V h
A i
L s
U i
E n
_ v
L a
E l
N i
G d
T f
H o
r
t
h
e
o
p
e
r
a
t
i
o
n
.

E
_ 0
B x
L 8
U 0
E 6
T 5
O 0
O 0
T 0
H E
_ T
A h
T e
T a
_ t
U t
N r
L i
I b
K u
E t
L e
Y r
e
q
u
e
s
t
t
h
a
t
w
a
s
r
e
q
u
e
s
t
e
d
h
a
s
e
n
c
o
u
n
t
e
r
e
d
a
n
e
r
r
o
r
t
h
a
t
w
a
s
u
n
l
i
k
e
l
y
,
a
n
d
t
h
e
r
e
f
o
r
e
c
o
u
l
d
n
o
t
b
e
c
o
m
p
l
e
t
e
d
a
s
r
e
q
u
e
s
t
e
d
.

E
_ 0
B x
L 8
U 0
E 6
T 5
O 0
O 0
T 0
H F
_ T
A h
T e
T a
_ t
I t
N r
S i
U
F b
F u
I t
C e
I r
E e
N q
T u
_ i
E r
N e
C s
R e
Y n
P c
T r
I y
O p
N t
i
o
n
b
e
f
o
r
e
i
t
c
a
n
b
e
r
e
a
d
o
r
w
r
i
t
t
e
n
.

E
_ 0
B x
L 8
U 0
E 6
T 5
O 0
O 0
T 1
H 0
_
A T
T h
T e
_ a
U t
N t
S r
U i
P b
P u
O t
R e
T t
E y
D p
_ e
G i
R s
O n
U o
P t
_ a
T s
Y u
P p
E p
o
r
t
e
d
g
r
o
u
p
i
n
g
a
t
t
r
i
b
u
t
e
a
s
d
e
f
i
n
e
d
b
y
a
h
i
g
h
e
r
l
a
y
e
r
s
p
e
c
i
f
i
c
a
t
i
o
n
.

E
_ 0
B x
L 8
U 0
E 6
T 5
O 0
O 0
T 1
H 1
_
A I
T n
T s
_ u
I f
N f
S i
U c
F i
F e
I n
C t
I R
E e
N s
T o
_ u
R r
E c
S e
O s
U t
R o
C c
E o
S m
p
l
e
t
e
t
h
e
r
e
q
u
e
s
t
.

E
_ 0
B x
L 8
U 0
E 6
T 5
O 1
O 0
T 0
H 0
_
A A
T n
T e
_ r
U r
N o
K r
N t
O h
W a
N t
_ l
E i
R e
R s
O i
R n
t
h
e
r
e
s
e
r
v
e
d
r
a
n
g
e
h
a
s
b
e
e
n
r
e
c
e
i
v
e
d
.

Requirements

Header
Win
erro
r.h

See also
C
O
M
E
r
r
o
r
C
o
d
e
s
COM Error Codes (UI, Audio, DirectX, Codec)
1/7/2020 • 11 minutes to read • Edit Online

The following table provides a list of error codes used by COM -based APIs.
If you are experiencing difficulty with an application you are installing or running, contact customer support for the
software that is displaying the error message. To obtain support for a Microsoft product, go to
https://support.microsoft.com.

U
I 0
_ x
E 8
_ 0
C 2
R A
E 0
A 0
T 0
E 1
_ T
F h
A e
I o
L b
E j
D e
c
t
c
o
u
l
d
n
o
t
b
e
c
r
e
a
t
e
d
.
U 0
I x
_ 8
E 0
_ 2
S A
H 0
U 0
T 0
D 2
O
W S
N h
_ u
C t
A d
L o
L w
E n
D w
a
s
a
l
r
e
a
d
y
c
a
l
l
e
d
o
n
t
h
i
s
o
b
j
e
c
t
o
r
t
h
e
o
b
j
e
c
t
t
h
a
t
o
w
n
s
i
t
.

U
I 0
_ x
E 8
_ 0
I 2
L A
L 0
E 0
G 0
A 3
L T
_ h
R i
E s
E m
N e
T t
R h
A o
N d
C c
Y a
n
n
o
t
b
e
c
a
l
l
e
d
d
u
r
i
n
g
t
h
i
s
t
y
p
e
o
f
c
a
l
l
b
a
c
k
.

U
I 0
_ x
E 8
_ 0
O 2
B A
J 0
E 0
C 0
T 4
_ T
S h
E i
A s
L o
E b
D j
e
c
t
h
a
s
b
e
e
n
s
e
a
l
e
d
,
s
o
t
h
i
s
c
h
a
n
g
e
i
s
n
o
l
o
n
g
e
r
a
l
l
o
w
e
d
.

U
I 0
_ x
E 8
_ 0
V 2
A A
L 0
U 0
E 0
_ 5
N
O T
T h
_ e
S r
E e
T q
u
e
s
t
e
d
v
a
l
u
e
w
a
s
n
e
v
e
r
s
e
t
.

U
I 0
_ x
E 8
_ 0
V 2
A A
L 0
U 0
E 0
_ 6
N T
O h
T e
_ r
D e
E q
T u
E e
R s
M t
I e
N d
E v
D a
l
u
e
c
a
n
n
o
t
b
e
d
e
t
e
r
m
i
n
e
d
.

U
I 0
_ x
E 8
_ 0
I 2
N A
V 0
A 0
L 0
I 7
D A
_ c
O a
U l
T l
P b
U a
T c
k
r
e
t
u
r
n
e
d
a
n
i
n
v
a
l
i
d
o
u
t
p
u
t
p
a
r
a
m
e
t
e
r.

U
I 0
_ x
E 8
_ 0
B 2
O A
O 0
L 0
E 0
A 8
N A
_ c
E a
X l
P l
E b
C a
T c
E k
D
r
e
t
u
r
n
e
d
a
s
u
c
c
e
s
s
c
o
d
e
o
t
h
e
r
t
h
a
n
S
_
O
K
o
r
S
_
F
A
L
S
E
.

U
I 0
_ x
E 8
_ 0
D 2
I A
F 0
F 0
E 0
R 9
E
N A
T p
_ a
O r
W a
N m
E e
R t
e
r
t
h
a
t
s
h
o
u
l
d
b
e
o
w
n
e
d
b
y
t
h
i
s
o
b
j
e
c
t
i
s
o
w
n
e
d
b
y
a
d
i
f
f
e
r
e
n
t
o
b
j
e
c
t
.

U
I 0
_ x
E 8
_ 0
A 2
M A
B 0
I 0
G 0
U A
O M
U o
S r
_ e
M t
A h
T a
C n
H o
n
e
i
t
e
m
m
a
t
c
h
e
d
t
h
e
s
e
a
r
c
h
c
r
i
t
e
r
i
a
.

U
I 0
_ x
E 8
_ 0
F 2
P A
_ 0
O 0
V 0
E B
R A
F f
L l
O o
W a
t
i
n
g
-
p
o
i
n
t
o
v
e
r
f
l
o
w
o
c
c
u
r
r
e
d
.

U
I 0
_ x
E 8
_ 0
W 2
R A
O 0
N 0
G 0
_ C
T T
H h
R i
E s
A m
D e
t
h
o
d
c
a
n
o
n
l
y
b
e
c
a
l
l
e
d
f
r
o
m
t
h
e
t
h
r
e
a
d
t
h
a
t
c
r
e
a
t
e
d
t
h
e
o
b
j
e
c
t
.

U
I 0
_ x
E 8
_ 0
S 2
T A
O 0
R 1
Y 0
B 1
O T
A h
R e
D s
_ t
A o
C r
T y
I
V b
E o
a
r
d
i
s
c
u
r
r
e
n
t
l
y
i
n
t
h
e
s
c
h
e
d
u
l
e
.

U
I 0
_ x
E 8
_ 0
S 2
T A
O 0
R 1
Y 0
B 2
O T
A h
R e
D s
_ t
N o
O r
T y
_ b
P
L o
A a
Y r
I d
N i
G s
n
o
t
p
l
a
y
i
n
g
.

U
I 0
_ x
E 8
_ 0
S 2
T A
A 0
R 1
T 0
_ 3
K T
E h
Y e
F s
R t
A a
M r
E t
_ k
A e
F y
T f
E r
R a
_ m
E e
N m
D i
g
h
t
o
c
c
u
r
a
f
t
e
r
t
h
e
e
n
d
k
e
y
f
r
a
m
e
.

U
I 0
_ x
E 8
_ 0
E 2
N A
D 0
_ 1
K 0
E 4
Y I
F t
R m
A i
M g
E h
_ t
N n
O o
T t
_ b
D e
E p
T o
E s
R
M s
I i
N b
E l
D e
t
o
d
e
t
e
r
m
i
n
e
t
h
e
e
n
d
k
e
y
f
r
a
m
e
t
i
m
e
w
h
e
n
t
h
e
s
t
a
r
t
k
e
y
f
r
a
m
e
i
s
r
e
a
c
h
e
d
.

U
I 0
_ x
E 8
_ 0
L 2
O A
O 0
P 1
S 0
_ 5
O T
V w
E o
R r
L e
A p
P e
a
t
e
d
p
o
r
t
i
o
n
s
o
f
a
s
t
o
r
y
b
o
a
r
d
m
i
g
h
t
o
v
e
r
l
a
p
.

U
I 0
_ x
E 8
_ 0
T 2
R A
A 0
N 1
S 0
I 6
T T
I h
O e
N t
_ r
A a
L n
R s
E i
A t
D i
Y o
_ n
U h
S a
E s
D a
l
r
e
a
d
y
b
e
e
n
a
d
d
e
d
t
o
a
s
t
o
r
y
b
o
a
r
d
.

U
I 0
_ x
E 8
_ 0
T 2
R A
A 0
N 1
S 0
I 7
T T
I h
O e
N t
_ r
N a
O n
T s
_ i
I t
N i
_ o
S n
T h
O
R a
Y s
B n
O o
A t
R b
D e
e
n
a
d
d
e
d
t
o
a
s
t
o
r
y
b
o
a
r
d
.

U
I 0
_ x
E 8
_ 0
T 2
R A
A 0
N 1
S 0
I 8
T T
I h
O e
N t
_ r
E a
C n
L s
I i
P t
S i
E
D o
n
m
i
g
h
t
e
c
l
i
p
s
e
t
h
e
b
e
g
i
n
n
i
n
g
o
f
a
n
o
t
h
e
r
t
r
a
n
s
i
t
i
o
n
i
n
t
h
e
s
t
o
r
y
b
o
a
r
d
.

U
I 0
_ x
E 8
_ 0
T 2
I A
M 0
E 1
_ 0
B 9
E T
F h
O e
R g
E i
_ v
L e
A n
S t
T i
_ m
U e
P i
D s
A e
T a
E r
l
i
e
r
t
h
a
n
t
h
e
t
i
m
e
p
a
s
s
e
d
t
o
t
h
e
l
a
s
t
u
p
d
a
t
e
.

U
I 0
_ x
E 8
_ 0
T 2
I A
M 0
E 1
R 0
_ A
C T
L h
I i
E s
N c
T l
_ i
A e
L n
R t
E i
A s
D a
Y l
_ r
C
O e
N a
N d
E y
C c
T o
E n
D n
e
c
t
e
d
t
o
a
t
i
m
e
r.

U
I 0
_ x
E 8
_ 0
I 2
N A
V 0
A 1
L 0
I B
D T
_ h
D e
I p
M a
E s
N s
S e
I d
O d
N i
m
e
n
s
i
o
n
i
s
i
n
v
a
l
i
d
o
r
d
o
e
s
n
o
t
m
a
t
c
h
t
h
e
o
b
j
e
c
t
'
s
d
i
m
e
n
s
i
o
n
.

U
I 0
_ x
E 8
_ 0
P 2
R A
I 0
M 1
I 0
T C
I
V T
E h
_ e
O a
U d
T d
_ e
O d
F p
_ r
B i
O m
U i
N t
D i
S v
e
b
e
g
i
n
s
a
t
o
r
b
e
y
o
n
d
t
h
e
d
u
r
a
t
i
o
n
o
f
t
h
e
i
n
t
e
r
p
o
l
a
t
o
r.

U
I 0
_ x
E 8
_ 0
W 2
I A
N 0
D 2
O 0
W 1
_ T
C h
L e
O o
S p
E e
D r
a
t
i
o
n
c
a
n
n
o
t
b
e
c
o
m
p
l
e
t
e
d
b
e
c
a
u
s
e
t
h
e
w
i
n
d
o
w
i
s
b
e
i
n
g
c
l
o
s
e
d
.

E
_ 0
A x
U 8
D 0
I 6
O 6
_ 0
E 0
N 0
G 1
I P
N o
E r
_ t
N C
O
D l
E s
_ c
N o
O u
T l
_ d
F n
O o
U t
N f
D i
n
d
a
n
a
u
d
i
o
e
n
g
i
n
e
n
o
d
e
e
x
p
o
s
e
d
b
y
a
m
i
n
i
p
o
r
t
d
r
i
v
e
r
c
l
a
i
m
i
n
g
s
u
p
p
o
r
t
f
o
r
I
M
i
n
i
p
o
r
t
A
u
d
i
o
E
n
g
i
n
e
N
o
d
e
.

D
X 0
G x
I 0
_ 8
S 7
T A
A 0
T 0
U 0
S 1
_
O T
C h
C e
L P
U r
D e
E s
D e
n
t
o
p
e
r
a
t
i
o
n
w
a
s
i
n
v
i
s
i
b
l
e
t
o
t
h
e
u
s
e
r.

D
X 0
G x
I 0
_ 8
S 7
T A
A 0
T 0
U 0
S 2
_
C T
L h
I e
P P
P r
E e
D s
e
n
t
o
p
e
r
a
t
i
o
n
w
a
s
p
a
r
t
i
a
l
l
y
i
n
v
i
s
i
b
l
e
t
o
t
h
e
u
s
e
r.

D
X 0
G x
I 0
_ 8
S 7
T A
A 0
T 0
U 0
S 4
_ T
N h
O e
_ d
R r
E i
D v
I e
R r
E i
C s
T r
I e
O q
N u
e
s
t
i
n
g
t
h
a
t
t
h
e
D
X
G
I
r
u
n
t
i
m
e
n
o
t
u
s
e
s
h
a
r
e
d
r
e
s
o
u
r
c
e
s
t
o
c
o
m
m
u
n
i
c
a
t
e
w
i
t
h
t
h
e
D
e
s
k
t
o
p
W
i
n
d
o
w
M
a
n
a
g
e
r.

D
X 0
G x
I 0
_ 8
S 7
T A
A 0
T 0
U 0
S 5
_ T
N h
O e
_ P
D r
E e
S s
K e
T n
O t
P o
_ p
A e
C r
C a
E t
S i
S o
n
w
a
s
n
o
t
v
i
s
i
b
l
e
b
e
c
a
u
s
e
t
h
e
W
i
n
d
o
w
s
s
e
s
s
i
o
n
h
a
s
s
w
i
t
c
h
e
d
t
o
a
n
o
t
h
e
r
d
e
s
k
t
o
p
(
f
o
r
e
x
a
m
p
l
e
,
c
t
r
l
-
a
l
t
-
d
e
l
)
.

D
X 0
G x
I 0
_ 8
S 7
T A
A 0
T 0
U 0
S 6
_ T
G h
R e
A P
P r
H e
I s
C
S e
_ n
V t
I o
D p
P e
N r
_ a
S t
O i
U o
R n
C w
E a
_ s
I n
N o
_ t
U v
S i
E s
i
b
l
e
b
e
c
a
u
s
e
t
h
e
t
a
r
g
e
t
m
o
n
i
t
o
r
w
a
s
b
e
i
n
g
u
s
e
d
f
o
r
s
o
m
e
o
t
h
e
r
p
u
r
p
o
s
e
.

D
X 0
G x
I 0
_ 8
S 7
T A
A 0
T 0
U 0
S 7
_ T
M h
O e
D P
E r
_ e
C s
H e
A n
N t
G o
E
D p
e
r
a
t
i
o
n
w
a
s
n
o
t
v
i
s
i
b
l
e
b
e
c
a
u
s
e
t
h
e
d
i
s
p
l
a
y
m
o
d
e
c
h
a
n
g
e
d
.
D
X
G
I
w
i
l
l
h
a
v
e
r
e
-
a
t
t
e
m
p
t
e
d
t
h
e
p
r
e
s
e
n
t
a
t
i
o
n
.

D
X 0
G x
I 0
_ 8
S 7
T A
A 0
T 0
U 0
S 8
_ T
M
O h
D e
E P
_ r
C e
H s
A e
N n
G t
E o
_ p
I e
N r
_ a
P t
R i
O o
G n
R w
E a
S s
S n
o
t
v
i
s
i
b
l
e
b
e
c
a
u
s
e
a
n
o
t
h
e
r
D
i
r
e
c
t
3
D
d
e
v
i
c
e
w
a
s
a
t
t
e
m
p
t
i
n
g
t
o
t
a
k
e
f
u
l
l
s
c
r
e
e
n
m
o
d
e
a
t
t
h
e
t
i
m
e
.

D
X 0
G x
I 8
_ 8
E 7
R A
R 0
O 0
R 0
_ 1
I
N T
V h
A e
L a
I p
D p
_ l
C i
A c
L a
L t
i
o
n
m
a
d
e
a
c
a
l
l
t
h
a
t
i
s
i
n
v
a
l
i
d
.
E
i
t
h
e
r
t
h
e
p
a
r
a
m
e
t
e
r
s
o
f
t
h
e
c
a
l
l
o
r
t
h
e
s
t
a
t
e
o
f
s
o
m
e
o
b
j
e
c
t
w
a
s
i
n
c
o
r
r
e
c
t
.
E
n
a
b
l
e
t
h
e
D
3
D
d
e
b
u
g
l
a
y
e
r
i
n
o
r
d
e
r
t
o
s
e
e
d
e
t
a
i
l
s
v
i
a
d
e
b
u
g
m
e
s
s
a
g
e
s
.

D
X 0
G x
I 8
_ 8
E 7
R A
R 0
O 0
R 0
_ 2
N T
O h
T e
_ o
F b
O j
U e
N c
D t
w
a
s
n
o
t
f
o
u
n
d
.
I
f
c
a
l
l
i
n
g
I
D
X
G
I
F
a
c
t
o
r
y
::
E
n
u
m
A
d
a
p
t
e
s
,
t
h
e
r
e
i
s
n
o
a
d
a
p
t
e
r
w
i
t
h
t
h
e
s
p
e
c
i
f
i
e
d
o
r
d
i
n
a
l.

D
X 0
G x
I 8
_ 8
E 7
R A
R 0
O 0
R 0
_ 3
M T
O h
R e
E c
_ a
D l
A l
T e
A r
d
i
d
n
o
t
s
u
p
p
l
y
a
s
u
f
f
i
c
i
e
n
t
l
y
l
a
r
g
e
b
u
f
f
e
r.

D
X 0
G x
I 8
_ 8
E 7
R A
R 0
O 0
R 0
_ 4
U T
N h
S e
U s
P p
P e
O c
R i
T f
E i
D e
d
d
e
v
i
c
e
i
n
t
e
r
f
a
c
e
o
r
f
e
a
t
u
r
e
l
e
v
e
l
i
s
n
o
t
s
u
p
p
o
r
t
e
d
o
n
t
h
i
s
s
y
s
t
e
m
.
D 0
X x
G 8
I 8
_ 7
E A
R 0
R 0
O 0
R 5
_
D T
E h
V e
I G
C P
E U
_ d
R e
E v
M i
O c
V e
E i
D n
s
t
a
n
c
e
h
a
s
b
e
e
n
s
u
s
p
e
n
d
e
d
.
U
s
e
G
e
t
D
e
v
i
c
e
R
e
m
o
v
e
d
R
e
a
s
o
n
t
o
d
e
t
e
r
m
i
n
e
t
h
e
a
p
p
r
o
p
r
i
a
t
e
a
c
t
i
o
n
.

D
X 0
G x
I 8
_ 8
E 7
R A
R 0
O 0
R 0
_ 6
D T
E h
V e
I G
C P
E U
_ w
H i
U l
N l
G n
o
t
r
e
s
p
o
n
d
t
o
m
o
r
e
c
o
m
m
a
n
d
s
,
m
o
s
t
l
i
k
e
l
y
b
e
c
a
u
s
e
o
f
a
n
i
n
v
a
l
i
d
c
o
m
m
a
n
d
p
a
s
s
e
d
b
y
t
h
e
c
a
l
l
i
n
g
a
p
p
l
i
c
a
t
i
o
n
.

D
X 0
G x
I 8
_ 8
E 7
R A
R 0
O 0
R 0
_ 7
D T
E h
V e
I G
C P
E U
_ w
R i
E l
S l
E n
T o
t
r
e
s
p
o
n
d
t
o
m
o
r
e
c
o
m
m
a
n
d
s
,
m
o
s
t
l
i
k
e
l
y
b
e
c
a
u
s
e
s
o
m
e
o
t
h
e
r
a
p
p
l
i
c
a
t
i
o
n
s
u
b
m
i
t
t
e
d
i
n
v
a
l
i
d
c
o
m
m
a
n
d
s
.
T
h
e
c
a
l
l
i
n
g
a
p
p
l
i
c
a
t
i
o
n
s
h
o
u
l
d
r
e
-
c
r
e
a
t
e
t
h
e
d
e
v
i
c
e
a
n
d
c
o
n
t
i
n
u
e
.

D
X 0
G x
I 8
_ 8
E 7
R A
R 0
O 0
R 0
_ A
W T
A h
S e
_ G
S P
T U
I w
L a
L s
_ b
D u
R s
A y
W a
I t
N t
G h
e
m
o
m
e
n
t
w
h
e
n
t
h
e
c
a
l
l
w
a
s
m
a
d
e
,
a
n
d
t
h
e
c
a
l
l
w
a
s
n
e
i
t
h
e
r
e
x
e
c
u
t
e
d
n
o
r
s
c
h
e
d
u
l
e
d
.

D
X 0
G x
I 8
_ 8
E 7
R A
R 0
O 0
R 0
_ B
F A
R n
A e
M v
E e
_ n
S t
T (
A s
T u
I c
S h
T a
I s
C p
S o
_ w
D e
I r
S c
J y
O c
I l
N e
T )
i
n
t
e
r
r
u
p
t
e
d
t
h
e
g
a
t
h
e
r
i
n
g
o
f
p
r
e
s
e
n
t
a
t
i
o
n
s
t
a
t
i
s
t
i
c
s
.
A
n
y
p
r
e
v
i
o
u
s
s
t
a
t
i
s
t
i
c
s
s
h
o
u
l
d
b
e
c
o
n
s
i
d
e
r
e
d
i
n
v
a
l
i
d
.

D
X 0
G x
I 8
_ 8
E 7
R A
R 0
O 0
R 0
_ C
G
R F
A u
P l
H l
I s
C c
S r
_ e
V e
I n
D m
P o
N d
_ e
S c
O o
U u
R l
C d
E n
_ o
I t
N b
_ e
U a
S c
E h
i
e
v
e
d
b
e
c
a
u
s
e
t
h
e
s
p
e
c
i
f
i
e
d
o
u
t
p
u
t
w
a
s
a
l
r
e
a
d
y
i
n
u
s
e
.

D
X 0
G x
I 8
_ 8
E 7
R A
R 0
O 0
R 2
_ 0
D A
R n
I i
V n
E t
R e
_ r
I n
N a
T l
E i
R s
N s
A u
L
_ e
E p
R r
R e
O v
R e
n
t
e
d
t
h
e
d
r
i
v
e
r
f
r
o
m
c
a
r
r
y
i
n
g
o
u
t
t
h
e
s
p
e
c
i
f
i
e
d
o
p
e
r
a
t
i
o
n
.
T
h
e
d
r
i
v
e
r
'
s
s
t
a
t
e
i
s
p
r
o
b
a
b
l
y
s
u
s
p
e
c
t
,
a
n
d
t
h
e
a
p
p
l
i
c
a
t
i
o
n
s
h
o
u
l
d
n
o
t
c
o
n
t
i
n
u
e
.

D
X 0
G x
I 8
_ 8
E 7
R A
R 0
O 0
R 2
_ 1
N A
O g
N l
E o
X b
C a
L l
U c
S o
I u
V n
E t
e
r
r
e
s
o
u
r
c
e
w
a
s
i
n
u
s
e
,
a
n
d
t
h
e
s
p
e
c
i
f
i
e
d
c
o
u
n
t
e
r
c
a
n
n
o
t
b
e
u
s
e
d
b
y
t
h
i
s
D
i
r
e
c
t
3
D
d
e
v
i
c
e
a
t
t
h
i
s
t
i
m
e
.

D
X 0
G x
I 8
_ 8
E 7
R A
R 0
O 0
R 2
_ 2
N A
O r
T e
_ s
C o
U u
R r
R c
E e
N i
T s
L n
Y o
_
A t
V a
A v
I a
L i
A l
B a
L b
E l
e
a
t
t
h
e
t
i
m
e
o
f
t
h
e
c
a
l
l,
b
u
t
m
a
y
b
e
c
o
m
e
a
v
a
i
l
a
b
l
e
l
a
t
e
r.

D
X 0
G x
I 8
_ 8
E 7
R A
R 0
O 0
R 2
_ 3
R T
E h
M e
O a
T p
E p
_ l
C i
L c
I a
E t
N i
T o
_ n
D '
I s
S r
C e
O m
N o
N t
E e
C d
T e
E v
D i
c
e
h
a
s
b
e
e
n
r
e
m
o
v
e
d
d
u
e
t
o
s
e
s
s
i
o
n
d
i
s
c
o
n
n
e
c
t
o
r
n
e
t
w
o
r
k
d
i
s
c
o
n
n
e
c
t
.
T
h
e
a
p
p
l
i
c
a
t
i
o
n
s
h
o
u
l
d
c
a
l
l
I
D
X
G
I
F
a
c
t
o
r
y
1
::
I
s
C
u
r
r
e
n
t
t
o
f
i
n
d
o
u
t
w
h
e
n
t
h
e
r
e
m
o
t
e
d
e
v
i
c
e
b
e
c
o
m
e
s
a
v
a
i
l
a
b
l
e
a
g
a
i
n
.

D
X 0
G x
I 8
_ 8
E 7
R A
R 0
O 0
R 2
_ 4
R T
E h
M e
O d
T e
E v
_ i
O c
U e
T h
O a
F s
M b
E e
M e
O n
R r
Y e
m
o
v
e
d
d
u
r
i
n
g
a
r
e
m
o
t
e
s
e
s
s
i
o
n
b
e
c
a
u
s
e
t
h
e
r
e
m
o
t
e
c
o
m
p
u
t
e
r
r
a
n
o
u
t
o
f
m
e
m
o
r
y
.

D
X 0
G x
I 8
_ 8
E 7
R A
R 0
O 0
R 2
_ 6
A T
C h
C e
E k
S e
S y
_ e
L d
O m
S
T u
t
e
x
w
a
s
a
b
a
n
d
o
n
e
d
.

D
X 0
G x
I 8
_ 8
E 7
R A
R 0
O 0
R 2
_ 7
W T
A h
I e
T t
_ i
T m
I e
M o
E u
O t
U v
T a
l
u
e
h
a
s
e
l
a
p
s
e
d
a
n
d
t
h
e
r
e
s
o
u
r
c
e
i
s
n
o
t
y
e
t
a
v
a
i
l
a
b
l
e
.

D
X 0
G x
I 8
_ 8
E 7
R A
R 0
O 0
R 2
_ 8
S T
E h
S e
S o
I
O u
N t
_ p
D u
I t
S d
C u
O p
N l
N i
E c
C a
T t
E i
D o
n
h
a
s
b
e
e
n
t
u
r
n
e
d
o
f
f
b
e
c
a
u
s
e
t
h
e
W
i
n
d
o
w
s
s
e
s
s
i
o
n
e
n
d
e
d
o
r
w
a
s
d
i
s
c
o
n
n
e
c
t
e
d
.
T
h
i
s
h
a
p
p
e
n
s
w
h
e
n
a
r
e
m
o
t
e
u
s
e
r
d
i
s
c
o
n
n
e
c
t
s
,
o
r
w
h
e
n
"
s
w
i
t
c
h
u
s
e
r
"
i
s
u
s
e
d
l
o
c
a
l
l
y
.

D
X 0
G x
I 8
_ 8
E 7
R A
R 0
O 0
R 2
_ 9
R
E T
S h
T e
R D
I X
C G
T I
_ o
T u
O t
_ u
O p
U u
T t
P (
U m
T o
_ n
S i
T t
A o
L r
E )
t
o
w
h
i
c
h
t
h
e
s
w
a
p
c
h
a
i
n
c
o
n
t
e
n
t
w
a
s
r
e
s
t
r
i
c
t
e
d
,
h
a
s
b
e
e
n
d
i
s
c
o
n
n
e
c
t
e
d
o
r
c
h
a
n
g
e
d
.

D
X 0
G x
I 8
_ 8
E 7
R A
R 0
O 0
R 2
_ A
C
A D
N X
N G
O I
T i
_ s
P u
R n
O a
T b
E l
C e
T t
_ o
C p
O r
N o
T v
E i
N d
T e
c
o
n
t
e
n
t
p
r
o
t
e
c
t
i
o
n
o
n
t
h
e
s
w
a
p
c
h
a
i
n
.
T
h
i
s
i
s
t
y
p
i
c
a
l
l
y
c
a
u
s
e
d
b
y
a
n
o
l
d
e
r
d
r
i
v
e
r,
o
r
b
y
t
h
e
a
p
p
l
i
c
a
t
i
o
n
u
s
i
n
g
a
s
w
a
p
c
h
a
i
n
t
h
a
t
i
s
i
n
c
o
m
p
a
t
i
b
l
e
w
i
t
h
c
o
n
t
e
n
t
p
r
o
t
e
c
t
i
o
n
.

D
X 0
G x
I 8
_ 8
E 7
R A
R 0
O 0
R 2
_ B
A T
C h
C e
E a
S p
S p
_ l
D i
E c
N a
I t
E i
D o
n
i
s
t
r
y
i
n
g
t
o
u
s
e
a
r
e
s
o
u
r
c
e
t
o
w
h
i
c
h
i
t
d
o
e
s
n
o
t
h
a
v
e
t
h
e
r
e
q
u
i
r
e
d
a
c
c
e
s
s
p
r
i
v
i
l
e
g
e
s
.
T
h
i
s
i
s
m
o
s
t
c
o
m
m
o
n
l
y
c
a
u
s
e
d
b
y
w
r
i
t
i
n
g
t
o
a
s
h
a
r
e
d
r
e
s
o
u
r
c
e
w
i
t
h
r
e
a
d
-
o
n
l
y
a
c
c
e
s
s
.

D
X 0
G x
I 0
_ 8
S 7
T A
A 0
T 0
U 0
S 9
_ T
U h
N e
O s
C w
C a
L p
U c
D h
E a
D i
n
h
a
s
b
e
c
o
m
e
u
n
o
c
c
l
u
d
e
d
.

D
X 0
G x
I 0
_ 8
S 7
T A
A 0
T 0
U 0
S A
_ T
D h
D e
A a
_ d
W a
A p
S t
_ e
S r
T d
I i
L d
L n
_ o
D t
R h
A a
W v
I e
N a
G c
c
e
s
s
t
o
t
h
e
r
e
q
u
i
r
e
d
r
e
s
o
u
r
c
e
s
t
o
c
o
m
p
l
e
t
e
t
h
e
D
e
s
k
t
o
p
D
u
p
l
i
c
a
t
i
o
n
P
r
e
s
e
n
t
(
)
c
a
l
l,
t
h
e
P
r
e
s
e
n
t
(
)
c
a
l
l
n
e
e
d
s
t
o
b
e
m
a
d
e
a
g
a
i
n
.

D
X 0
G x
I 8
_ 8
E 7
R A
R 0
O 0
R 2
_ 5
M A
O n
D o
E n
_ -
C g
H o
A i
N n
G g
E m
_ o
I d
N e
_ c
P h
R a
O n
G g
R e
E p
S r
S e
v
e
n
t
e
d
c
o
m
p
l
e
t
i
o
n
o
f
t
h
e
c
a
l
l.
T
h
e
c
a
l
l
m
a
y
s
u
c
c
e
e
d
i
f
a
t
t
e
m
p
t
e
d
l
a
t
e
r.

D
X 0
G x
I 8
_ 8
D 7
D B
I 0
_ 0
E 0
R 1
R
_ T
W h
A e
S G
S P
T U
I w
L a
L s
D b
R u
A s
W y
I w
N h
G e
n
t
h
e
o
p
e
r
a
t
i
o
n
w
a
s
r
e
q
u
e
s
t
e
d
.

D
X 0
G x
I 8
_ 8
D 7
D B
I 0
_ 0
E 0
R 2
R
_ T
U h
N e
S d
U r
P i
P v
O e
R r
T h
E a
D s
r
e
j
e
c
t
e
d
t
h
e
c
r
e
a
t
i
o
n
o
f
t
h
i
s
r
e
s
o
u
r
c
e
.

D
X 0
G x
I 8
_ 8
D 7
D B
I 0
_ 0
E 0
R 3
R T
_ h
N e
O G
N P
E U
X c
C o
L u
U n
S t
I e
V r
E w
a
s
i
n
u
s
e
b
y
a
n
o
t
h
e
r
p
r
o
c
e
s
s
o
r
d
3
d
d
e
v
i
c
e
w
h
e
n
a
p
p
l
i
c
a
t
i
o
n
r
e
q
u
e
s
t
e
d
a
c
c
e
s
s
t
o
i
t
.

D
3 0
D x
1 8
0 8
_ 7
E 9
R 0
R 0
O 0
R 1
_
T T
O h
O e
_ a
M p
A p
N l
Y i
_ c
U a
N t
I i
Q o
U n
E h
_ a
S s
T e
A x
T c
E e
_ e
O d
B e
J d
E t
C h
T e
S m
a
x
i
m
u
m
n
u
m
b
e
r
o
f
u
n
i
q
u
e
s
t
a
t
e
o
b
j
e
c
t
s
p
e
r
D
i
r
e
c
t
3
D
d
e
v
i
c
e
.
T
h
e
l
i
m
i
t
i
s
4
0
9
6
f
o
r
f
e
a
t
u
r
e
l
e
v
e
l
s
u
p
t
o
1
1
.
1
.

D
3 0
D x
1 8
0 8
_ 7
E 9
R 0
R 0
O 0
R 2
_ T
F h
I e
L s
E p
_ e
N c
O i
T f
_ i
F e
O d
U f
N i
D l
e
w
a
s
n
o
t
f
o
u
n
d
.

D
3 0
D x
1 8
1 8
_ 7
E C
R 0
R 0
O 0
R 1
_ T
T h
O e
O a
_ p
M p
A l
N i
Y c
_ a
U t
N i
I o
Q n
U h
E a
_ s
S e
T x
A c
T e
E e
_ d
O e
B d
J t
E h
C e
T m
S a
x
i
m
u
m
n
u
m
b
e
r
o
f
u
n
i
q
u
e
s
t
a
t
e
o
b
j
e
c
t
s
p
e
r
D
i
r
e
c
t
3
D
d
e
v
i
c
e
.
T
h
e
l
i
m
i
t
i
s
4
0
9
6
f
o
r
f
e
a
t
u
r
e
l
e
v
e
l
s
u
p
t
o
1
1
.
1
.

D
3 0
D x
1 8
1 8
_ 7
E C
R 0
R 0
O 0
R 2
_ T
F h
I e
L
E s
_ p
N e
O c
T i
_ f
F i
O e
U d
N f
D i
l
e
w
a
s
n
o
t
f
o
u
n
d
.

D
3 0
D x
1 8
1 8
_ 7
E C
R 0
R 0
O 0
R 3
_ T
T h
O e
O a
_ p
M p
A l
N i
Y c
_ a
U t
N i
I o
Q n
U
E h
_ a
V s
I e
E x
W c
_ e
O e
B d
J e
E d
C t
T h
S e
m
a
x
i
m
u
m
n
u
m
b
e
r
o
f
u
n
i
q
u
e
v
i
e
w
o
b
j
e
c
t
s
p
e
r
D
i
r
e
c
t
3
D
d
e
v
i
c
e
.
T
h
e
l
i
m
i
t
i
s
2
^
2
0
f
o
r
f
e
a
t
u
r
e
l
e
v
e
l
s
u
p
t
o
1
1
.
1
.
D 0
3 x
D 8
1 8
1 7
_ C
E 0
R 0
R 0
O 4
R
_ T
D h
E e
F a
E p
R p
R l
E i
D c
_ a
C t
O i
N o
T n
E '
X s
T f
_ i
M r
A s
P t
_ c
W a
I l
T l
H p
O e
U r
T c
_ o
I m
N m
I a
T n
I d
A l
L i
_ s
D t
I t
S o
C M
A a
R p
D o
n
a
d
e
f
e
r
r
e
d
c
o
n
t
e
x
t
d
i
d
n
o
t
u
s
e
D
3
D
1
1
_
M
A
P
_
W
R
I
T
E
_
D
I
S
C
A
R
D
.

D
2 0
D x
E 8
R 8
R 9
_ 9
W 0
R 0
O 0
N 1
G T
_ h
S e
T o
A b
T j
E e
c
t
w
a
s
n
o
t
i
n
t
h
e
c
o
r
r
e
c
t
s
t
a
t
e
t
o
p
r
o
c
e
s
s
t
h
e
m
e
t
h
o
d
.

D
2 0
D x
E 8
R 8
R 9
_ 9
N 0
O 0
T 0
_ 2
I T
N h
I e
T o
I b
A j
L e
I c
Z t
E h
D a
s
n
o
t
y
e
t
b
e
e
n
i
n
i
t
i
a
l
i
z
e
d
.

D
2 0
D x
E 8
R 8
R 9
_ 9
U 0
N 0
S 0
U 3
P T
P h
O e
R r
T e
E q
D u
_ e
O s
P t
E e
R d
A o
T p
I e
O r
N a
t
i
o
n
i
s
n
o
t
s
u
p
p
o
r
t
e
d
.

D
2 0
D x
E 8
R 8
R 9
_ 9
S 0
C 0
A 0
N 4
N T
E h
R e
_ g
F e
A o
I m
L e
E t
D r
y
s
c
a
n
n
e
r
f
a
i
l
e
d
t
o
p
r
o
c
e
s
s
t
h
e
d
a
t
a
.

D
2 0
D x
E 8
R 8
R 9
_ 9
S 0
C 0
R 0
E 5
E D
N i
_ r
A e
C c
C t
E 2
S D
S c
_ o
D u
E l
N d
I n
E o
D t
a
c
c
e
s
s
t
h
e
s
c
r
e
e
n
.

D
2 0
D x
E 8
R 8
R 9
_ 9
D 0
I 0
S 0
P 6
L A
A v
Y a
_ l
S i
T d
A d
T i
E s
_ p
I l
N a
V y
A s
L t
I a
D t
e
c
o
u
l
d
n
o
t
b
e
d
e
t
e
r
m
i
n
e
d
.

D
2 0
D x
E 8
R 8
R 9
_ 9
Z 0
E 0
R 0
O 7
_ T
V h
E e
C s
T u
O p
R p
l
i
e
d
v
e
c
t
o
r
i
s
z
e
r
o
.

D
2 0
D x
E 8
R 8
R 9
_ 9
I 0
N 0
T 0
E 8
R A
N n
A i
L n
_ t
E e
R r
R n
O a
R l
e
r
r
o
r
(
D
i
r
e
c
t
2
D
b
u
g
)
o
c
c
u
r
r
e
d
.
O
n
c
h
e
c
k
e
d
b
u
i
l
d
s
,
w
e
w
o
u
l
d
a
s
s
e
r
t
.
T
h
e
a
p
p
l
i
c
a
t
i
o
n
s
h
o
u
l
d
c
l
o
s
e
t
h
i
s
i
n
s
t
a
n
c
e
o
f
D
i
r
e
c
t
2
D
a
n
d
s
h
o
u
l
d
c
o
n
s
i
d
e
r
r
e
s
t
a
r
t
i
n
g
i
t
s
p
r
o
c
e
s
s
.

D
2 0
D x
E 8
R 8
R 9
_ 9
D 0
I 0
S 0
P 9
L
A T
Y h
_ e
F d
O i
R s
M p
A l
T a
_ y
N f
O o
T r
_ m
S a
U t
P D
P i
O r
R e
T c
E t
D 2
D
n
e
e
d
s
t
o
r
e
n
d
e
r
i
s
n
o
t
s
u
p
p
o
r
t
e
d
b
y
t
h
e
h
a
r
d
w
a
r
e
d
e
v
i
c
e
.

D
2 0
D x
E 8
R 8
R 9
_ 9
I 0
N 0
V 0
A A
L A
I c
D a
_ l
C l
A t
L o
L t
h
i
s
m
e
t
h
o
d
i
s
i
n
v
a
l
i
d
.

D
2 0
D x
E 8
R 8
R 9
_ 9
N 0
O 0
_ 0
H B
A N
R o
D h
W a
A r
R d
E w
_ a
D r
E e
V r
I e
C n
E d
e
r
i
n
g
d
e
v
i
c
e
i
s
a
v
a
i
l
a
b
l
e
f
o
r
t
h
i
s
o
p
e
r
a
t
i
o
n
.

D
2 0
D x
E 8
R 8
R 9
_ 9
R 0
E 0
C 0
R C
E T
A h
T e
E r
_ e
T h
A a
R s
G b
E e
T e
n
a
p
r
e
s
e
n
t
a
t
i
o
n
e
r
r
o
r
t
h
a
t
m
a
y
b
e
r
e
c
o
v
e
r
a
b
l
e
.
T
h
e
c
a
l
l
e
r
n
e
e
d
s
t
o
r
e
c
r
e
a
t
e
,
r
e
r
e
n
d
e
r
t
h
e
e
n
t
i
r
e
f
r
a
m
e
,
a
n
d
r
e
a
t
t
e
m
p
t
p
r
e
s
e
n
t
.

D
2 0
D x
E 8
R 8
R 9
_ 9
T 0
O 0
O 0
_ D
M S
A h
N a
Y d
_ e
S r
H c
A o
D n
E s
R t
_ r
E u
L c
E t
M i
E o
N n
T f
S a
i
l
e
d
b
e
c
a
u
s
e
i
t
w
a
s
t
o
o
c
o
m
p
l
e
x
.

D
2 0
D x
E 8
R 8
R 9
_ 9
S 0
H 0
A 0
D E
E S
R h
_ a
C d
O e
M r
P c
I o
L m
E p
_ i
F l
A a
I t
L i
E o
D n
f
a
i
l
e
d
.

D
2 0
D x
E 8
R 8
R 9
_ 9
M 0
A 0
X 0
_ F
T
E R
X e
T q
U u
R e
E s
_ t
S e
I d
Z D
E i
_ r
E e
X c
C t
E X
E s
D u
E r
D f
a
c
e
s
i
z
e
e
x
c
e
e
d
e
d
m
a
x
i
m
u
m
t
e
x
t
u
r
e
s
i
z
e
.

D
2 0
D x
E 8
R 8
R 9
_ 9
U 0
N 0
S 1
U 0
P T
P h
O e
R r
T e
E q
D u
_ e
V s
E t
R e
S d
I D
O i
N r
e
c
t
2
D
v
e
r
s
i
o
n
i
s
n
o
t
s
u
p
p
o
r
t
e
d
.

D
2 0
D x
E 8
R 8
R 9
_ 9
B 0
A 0
D 1
_ 1
N I
U n
M v
B a
E l
R i
d
n
u
m
b
e
r.

D
2 0
D x
E 8
R 8
R 9
_ 9
W 0
R 0
O 1
N 2
G
_ O
F b
A j
C e
T c
O t
R s
Y u
s
e
d
t
o
g
e
t
h
e
r
m
u
s
t
b
e
c
r
e
a
t
e
d
f
r
o
m
t
h
e
s
a
m
e
f
a
c
t
o
r
y
i
n
s
t
a
n
c
e
.

D
2 0
D x
E 8
R 8
R 9
_ 9
L 0
A 0
Y 1
E 3
R A
_ l
A a
L y
R e
E r
A r
D e
Y s
_ o
I u
N r
_ c
U e
S c
E a
n
o
n
l
y
b
e
i
n
u
s
e
o
n
c
e
a
t
a
n
y
p
o
i
n
t
i
n
t
i
m
e
.

D
2 0
D x
E 8
R 8
R 9
_ 9
P 0
O 0
P 1
_ 4
C T
A h
L e
L p
_ o
D p
I c
D a
_ l
N l
O d
T i
_ d
M n
A o
T t
C m
H a
_ t
P c
U
S h
H t
h
e
c
o
r
r
e
s
p
o
n
d
i
n
g
p
u
s
h
c
a
l
l.

D
2 0
D x
E 8
R 8
R 9
_ 9
W 0
R 0
O 1
N 5
G T
_ h
R e
E r
S e
O s
U o
R u
C r
E c
_ e
D w
O a
M s
A
I r
N e
a
l
i
z
e
d
o
n
t
h
e
w
r
o
n
g
r
e
n
d
e
r
t
a
r
g
e
t
.

D
2 0
D x
E 8
R 8
R 9
_ 9
P 0
U 0
S 1
H 6
_ T
P h
O e
P p
_ u
U s
N h
B a
A
L n
A d
N p
C o
E p
D c
a
l
l
s
w
e
r
e
u
n
b
a
l
a
n
c
e
d
.

D
2 0
D x
E 8
R 8
R 9
_ 9
R 0
E 0
N 1
D 7
E A
R t
_ t
T e
A m
R p
G t
E t
T o
_ c
H o
A p
S y
_ f
L
A r
Y o
E m
R a
_ r
O e
R n
_ d
C e
L r
I t
P a
R r
E g
C e
T t
w
h
i
l
e
a
l
a
y
e
r
o
r
c
l
i
p
r
e
c
t
i
s
a
p
p
l
i
e
d
.

D
2 0
D x
E 8
R 8
R 9
_ 9
I 0
N 0
C 1
O 8
M
P T
A h
T e
I b
B r
L u
E s
_ h
B t
R y
U p
S e
H s
_ a
T r
Y e
P i
E n
S c
o
m
p
a
t
i
b
l
e
f
o
r
t
h
e
c
a
l
l.

D
2 0
D x
E 8
R 8
R 9
_ 9
W 0
I 0
N 1
3 9
2
_ A
E n
R u
R n
O k
R n
o
w
n
w
i
n
3
2
f
a
i
l
u
r
e
o
c
c
u
r
r
e
d
.

D
2 0
D x
E 8
R 8
R 9
_ 9
T 0
A 0
R 1
G A
E T
T h
_ e
N r
O e
T n
_ d
G e
D r
I t
_ a
C r
O g
M e
P t
A i
T s
I n
B o
L t
E c
o
m
p
a
t
i
b
l
e
w
i
t
h
G
D
I
.

D
2 0
D x
E 8
R 8
R 9
_ 9
T 0
E 0
X 1
T B
_ A
E t
F e
F x
E
C t
T c
_ l
I i
S e
_ n
W t
R d
O r
N a
G w
_ i
T n
Y g
P e
E f
f
e
c
t
o
b
j
e
c
t
i
s
o
f
t
h
e
w
r
o
n
g
t
y
p
e
.

D
2 0
D x
E 8
R 8
R 9
_ 9
T 0
E 0
X 1
T C
_
R T
E h
N e
D a
E p
R p
E l
R i
_ c
N a
O t
T i
_ o
R n
E i
L s
E h
A o
S l
E d
D i
n
g
a
r
e
f
e
r
e
n
c
e
t
o
t
h
e
I
D
W
r
i
t
e
T
e
x
t
R
e
n
d
e
r
e
r
i
n
t
e
r
f
a
c
e
a
f
t
e
r
t
h
e
c
o
r
r
e
s
p
o
n
d
i
n
g
D
r
a
w
T
e
x
t
o
r
D
r
a
w
T
e
x
t
L
a
y
o
u
t
c
a
l
l
h
a
s
r
e
t
u
r
n
e
d
.
T
h
e
I
D
W
r
i
t
e
T
e
x
t
R
e
n
d
e
r
e
r
i
n
s
t
a
n
c
e
w
i
l
l
b
e
i
n
v
a
l
i
d
.

D
2 0
D x
E 8
R 8
R 9
_ 9
E 0
X 0
C 1
E D
E T
D h
S e
_ r
M e
A q
X u
_ e
B s
I t
T e
M d
A s
P i
_ z
S e
I i
Z s
E l
a
r
g
e
r
t
h
a
n
t
h
e
g
u
a
r
a
n
t
e
e
d
s
u
p
p
o
r
t
e
d
t
e
x
t
u
r
e
s
i
z
e
a
t
t
h
e
D
i
r
e
c
t
3
D
d
e
v
i
c
e
'
s
c
u
r
r
e
n
t
f
e
a
t
u
r
e
l
e
v
e
l.

D
2 0
D x
E 8
R 8
R 9
_ 9
I 0
N 0
V 1
A E
L T
I h
D e
_ r
G e
R w
A a
P s
H a
_ c
C
O o
N n
F f
I i
G g
U u
R r
A a
T t
I i
O o
N n
e
r
r
o
r
i
n
t
h
e
g
r
a
p
h
.

D
2 0
D x
E 8
R 8
R 9
_ 9
I 0
N 0
V 1
A F
L T
I h
D e
_ r
I e
N w
T a
E s
R a
N i
A n
L
_ t
G e
R r
A n
P a
H l
_ c
C o
O n
N f
F i
I g
G u
U r
R a
A t
T i
I o
O n
N e
r
r
o
r
i
n
t
h
e
g
r
a
p
h
.

D
2 0
D x
E 8
R 8
R 9
_ 9
C 0
Y 0
C 2
L 0
I T
C h
_ e
G r
R
A e
P w
H a
s
a
c
y
c
l
e
i
n
t
h
e
g
r
a
p
h
.

D
2 0
D x
E 8
R 8
R 9
_ 9
B 0
I 0
T 2
M 1
A C
P a
_ n
C n
A o
N t
N d
O r
T a
_ w
D w
R i
A t
W h
a
b
i
t
m
a
p
t
h
a
t
h
a
s
t
h
e
D
2
D
1
_
B
I
T
M
A
P
_
O
P
T
I
O
N
S
_
C
A
N
N
O
T
_
D
R
A
W
o
p
t
i
o
n
.
D 0
2 x
D 8
E 8
R 9
R 9
_ 0
O 0
U 2
T 2
S
T T
A h
N e
D o
I p
N e
G r
_ a
B t
I i
T o
M n
A c
P a
_ n
R n
E o
F t
E c
R o
E m
N p
C l
E e
S t
e
w
h
i
l
e
t
h
e
r
e
a
r
e
o
u
t
s
t
a
n
d
i
n
g
r
e
f
e
r
e
n
c
e
s
t
o
t
h
e
t
a
r
g
e
t
b
i
t
m
a
p
.

D
2 0
D x
E 8
R 8
R 9
_ 9
O 0
R 0
I 2
G 3
I T
N h
A
L e
_ o
T p
A e
R r
G a
E t
T i
_ o
N n
O f
T a
_ i
B l
O e
U d
N b
D e
c
a
u
s
e
t
h
e
o
r
i
g
i
n
a
l
t
a
r
g
e
t
i
s
n
o
t
c
u
r
r
e
n
t
l
y
b
o
u
n
d
a
s
a
t
a
r
g
e
t
.

D
2 0
D x
E 8
R 8
R 9
_ 9
I 0
N 0
V 2
A 4
L C
I a
D n
_ n
T o
A t
R s
G e
E t
T t
h
e
i
m
a
g
e
a
s
a
t
a
r
g
e
t
b
e
c
a
u
s
e
i
t
i
s
e
i
t
h
e
r
a
n
e
f
f
e
c
t
o
r
i
s
a
b
i
t
m
a
p
t
h
a
t
d
o
e
s
n
o
t
h
a
v
e
t
h
e
D
2
D
1
_
B
I
T
M
A
P
_
O
P
T
I
O
N
S
_
T
A
R
G
E
T
f
l
a
g
s
e
t
.

D
2 0
D x
E 8
R 8
R 9
_ 9
B 0
I 0
T 2
M 5
A C
P a
_ n
B n
O o
U t
N d
D r
_ a
A w
S w
_ i
T t
A h
R a
G b
E i
T t
m
a
p
t
h
a
t
i
s
c
u
r
r
e
n
t
l
y
b
o
u
n
d
a
s
t
h
e
t
a
r
g
e
t
b
i
t
m
a
p
.

D
2 0
D x
E 8
R 8
R 9
_ 9
I 0
N 0
S 2
U 6
F D
F 3
I D
C D
I e
E v
N i
T c
_ e
D d
E o
V e
I s
C n
E o
_ t
C h
A a
P v
A e
B s
I u
L f
I f
T i
I c
E i
S e
n
t
c
a
p
a
b
i
l
i
t
i
e
s
t
o
p
e
r
f
o
r
m
t
h
e
r
e
q
u
e
s
t
e
d
a
c
t
i
o
n
.

D
2 0
D x
E 8
R 8
R 9
_ 9
I 0
N 0
T 2
E 7
R T
M
E h
D e
I g
A r
T a
E p
_ h
T c
O o
O u
_ l
L d
A n
R o
G t
E b
e
r
e
n
d
e
r
e
d
w
i
t
h
t
h
e
c
o
n
t
e
x
t
'
s
c
u
r
r
e
n
t
t
i
l
i
n
g
s
e
t
t
i
n
g
s
.

D
2 0
D x
E 8
R 8
R 9
_ 9
E 0
F 0
F 2
E 8
C T
T h
_ e
I C
S L
_ S
N I
O D
T p
_ r
R o
E v
G i
I d
S e
T d
E t
R o
E U
D n
r
e
g
i
s
t
e
r
d
i
d
n
o
t
c
o
r
r
e
s
p
o
n
d
t
o
a
r
e
g
i
s
t
e
r
e
d
e
f
f
e
c
t
.

D
2 0
D x
E 8
R 8
R 9
_ 9
I 0
N 0
V 2
A 9
L T
I h
D e
_
P s
R p
O e
P c
E i
R f
T i
Y e
d
p
r
o
p
e
r
t
y
d
o
e
s
n
o
t
e
x
i
s
t
.

D
2 0
D x
E 8
R 8
R 9
_ 9
N 0
O 0
_ 2
S A
U T
B h
P e
R s
O p
P e
E c
R i
T f
I
E i
S e
d
s
u
b
-
p
r
o
p
e
r
t
y
d
o
e
s
n
o
t
e
x
i
s
t
.

D
2 0
D x
E 8
R 8
R 9
_ 9
P 0
R 0
I 2
N B
T A
_ d
J d
O P
B a
_ g
C e
L o
O r
S C
E l
D
o
s
e
c
a
l
l
e
d
a
f
t
e
r
p
r
i
n
t
j
o
b
i
s
a
l
r
e
a
d
y
c
l
o
s
e
d
.

D
2 0
D x
E 8
R 8
R 9
_ 9
P 0
R 0
I 2
N C
T E
_
F r
O r
R o
M r
A d
T u
_ r
N i
O n
T g
_ p
S r
U i
P n
P t
O c
R o
T n
E t
D r
o
l
c
r
e
a
t
i
o
n
.
I
n
d
i
c
a
t
e
s
t
h
a
t
n
o
n
e
o
f
t
h
e
p
a
c
k
a
g
e
t
a
r
g
e
t
t
y
p
e
s
(
r
e
p
r
e
s
e
n
t
i
n
g
p
r
i
n
t
e
r
f
o
r
m
a
t
s
)
a
r
e
s
u
p
p
o
r
t
e
d
b
y
D
i
r
e
c
t
2
D
p
r
i
n
t
c
o
n
t
r
o
l.

D
2 0
D x
E 8
R 8
R 9
_ 9
T 0
O 0
O 2
_ D
M A
A n
N e
Y f
_ f
T e
R c
A t
N a
S t
F
O t
R e
M m
_ p
I t
N e
P d
U t
T o
S u
s
e
a
t
r
a
n
s
f
o
r
m
w
i
t
h
t
o
o
m
a
n
y
i
n
p
u
t
s
.

D
W 0
R x
I 8
T 8
E 9
_ 8
E 5
_ 0
F 0
I 0
L I
E n
F d
O i
R c
M a
A t
T e
s
a
n
e
r
r
o
r
i
n
a
n
i
n
p
u
t
f
i
l
e
s
u
c
h
a
s
a
f
o
n
t
f
i
l
e
.

D
W 0
R x
I 8
T 8
9
E 8
_ 5
E 0
_ 0
U 1
N
E I
X n
P d
E i
C c
T a
E t
D e
s
a
n
e
r
r
o
r
o
r
i
g
i
n
a
t
i
n
g
i
n
D
i
r
e
c
t
W
r
i
t
e
c
o
d
e
,
w
h
i
c
h
i
s
n
o
t
e
x
p
e
c
t
e
d
t
o
o
c
c
u
r
b
u
t
i
s
s
a
f
e
t
o
r
e
c
o
v
e
r
f
r
o
m
.

D
W 0
R x
I 8
T 8
E 9
_ 8
E 5
_ 0
N 0
O 2
F
O I
N n
T d
i
c
a
t
e
s
t
h
e
s
p
e
c
i
f
i
e
d
f
o
n
t
d
o
e
s
n
o
t
e
x
i
s
t
.

D
W 0
R x
I 8
T 8
E 9
_ 8
E 5
_ 0
F 0
I 3
L
E A
N f
O o
T n
F t
O f
U i
N l
D e
c
o
u
l
d
n
o
t
b
e
o
p
e
n
e
d
b
e
c
a
u
s
e
t
h
e
f
i
l
e
,
d
i
r
e
c
t
o
r
y
,
n
e
t
w
o
r
k
l
o
c
a
t
i
o
n
,
d
r
i
v
e
,
o
r
o
t
h
e
r
s
t
o
r
a
g
e
l
o
c
a
t
i
o
n
d
o
e
s
n
o
t
e
x
i
s
t
o
r
i
s
u
n
a
v
a
i
l
a
b
l
e
.

D
W 0
R x
I 8
T 8
E 9
_ 8
E 5
_ 0
F 0
I 4
L A
E f
A o
C n
C t
E f
S i
S l
e
e
x
i
s
t
s
b
u
t
c
o
u
l
d
n
o
t
b
e
o
p
e
n
e
d
d
u
e
t
o
a
c
c
e
s
s
d
e
n
i
e
d
,
s
h
a
r
i
n
g
v
i
o
l
a
t
i
o
n
,
o
r
s
i
m
i
l
a
r
e
r
r
o
r.

D
W 0
R x
I 8
T 8
E 9
_ 8
E 5
_ 0
F 0
O 5
N A
T f
C o
O n
L t
L c
E o
C l
T l
I e
O c
N t
O i
B o
S n
O i
L s
E o
T b
E s
o
l
e
t
e
d
u
e
t
o
c
h
a
n
g
e
s
i
n
t
h
e
s
y
s
t
e
m
.

D
W 0
R x
I 8
T 8
E 9
_ 8
E 5
_ 0
A 0
L 6
R T
E h
A e
D g
Y i
R v
E e
G n
I i
S n
T t
E e
R
E r
D f
a
c
e
i
s
a
l
r
e
a
d
y
r
e
g
i
s
t
e
r
e
d
.

D
W 0
R x
I 8
T 8
E 9
_ 8
E 5
_ 0
C 0
A 7
C T
H h
E e
F f
O o
R n
M t
A c
T a
c
h
e
c
o
n
t
a
i
n
s
i
n
v
a
l
i
d
d
a
t
a
.

D
W 0
R x
I 8
T 8
E 9
_ 8
E 5
_ 0
C 0
A 8
C A
H f
E o
V n
E t
R c
S a
I c
O h
N e
f
i
l
e
c
o
r
r
e
s
p
o
n
d
s
t
o
a
d
i
f
f
e
r
e
n
t
v
e
r
s
i
o
n
o
f
D
i
r
e
c
t
W
r
i
t
e
.

D
W 0
R x
I 8
T 8
E 9
_ 8
E 5
_ 0
U 0
N 9
S T
U h
P
P e
O o
R p
T e
E r
D a
O t
P i
E o
R n
A i
T s
I n
O o
N t
s
u
p
p
o
r
t
e
d
f
o
r
t
h
i
s
t
y
p
e
o
f
f
o
n
t
.

W
I 0
N x
C 8
O 8
D 9
E 8
C 2
_ F
E 0
R 4
R
_ T
W h
R e
O c
N o
G d
S e
T c
A i
T s
E i
n
t
h
e
w
r
o
n
g
s
t
a
t
e
.

W
I 0
N x
C 8
O 8
D 9
E 8
C 2
_ F
E 0
R 5
R T
_ h
V e
A v
L a
U l
E u
O e
U i
T s
O o
F u
R t
A o
N f
G r
E a
n
g
e
.

W
I 0
N x
C 8
O 8
D 9
E 8
C 2
_ F
E 0
R 7
R T
_ h
U e
N i
K m
N a
O g
W e
N f
I o
M r
A m
G a
E t
F i
O s
R u
M n
A k
T n
o
w
n
.

W
I 0
N x
C 8
O 8
D 9
E 8
C 2
_ F
E 0
R B
R
_ T
U h
N e
S S
U D
P K
P v
O e
R r
T s
E i
D o
V n
E i
R s
S u
I n
O s
N u
p
p
o
r
t
e
d
.

W
I 0
N x
C 8
O 8
D 9
E 8
C 2
_ F
E 0
R C
R T
_ h
N e
O c
T o
I m
N p
I o
T n
I e
A n
L t
I i
Z s
E n
D o
t
i
n
i
t
i
a
l
i
z
e
d
.

W
I 0
N x
C 8
O 8
D 9
E 8
C 2
_ F
E 0
R D
R T
_ h
A e
L r
R e
E i
A s
D a
Y l
L r
O e
C a
K d
E y
D a
n
o
u
t
s
t
a
n
d
i
n
g
r
e
a
d
o
r
w
r
i
t
e
l
o
c
k
.

W
I 0
N x
C 8
O 8
D 9
E 8
C 2
_ F
E 4
R 0
R T
_ h
P e
R s
O p
P e
E c
R i
T f
Y i
N e
O
T d
F b
O i
U t
N m
D a
p
p
r
o
p
e
r
t
y
c
a
n
n
o
t
b
e
f
o
u
n
d
.

W
I 0
N x
C 8
O 8
D 9
E 8
C 2
_ F
E 4
R 1
R T
_ h
P e
R b
O i
P t
E m
R a
T p
Y c
N
O o
T d
S e
U c
P d
P o
O e
R s
T n
E o
D t
s
u
p
p
o
r
t
t
h
e
b
i
t
m
a
p
p
r
o
p
e
r
t
y
.

W
I 0
N x
C 8
O 8
D 9
E 8
C 2
_ F
E 4
R 2
R T
_ h
P e
R
O b
P i
E t
R m
T a
Y p
S p
I r
Z o
E p
e
r
t
y
s
i
z
e
i
s
i
n
v
a
l
i
d
.

W
I 0
N x
C 8
O 8
D 9
E 8
C 2
_ F
E 4
R 3
R A
_ n
C u
O n
D k
E n
C o
P w
R n
E e
S r
E
N r
T o
r
h
a
s
o
c
c
u
r
r
e
d
.

W
I 0
N x
C 8
O 8
D 9
E 8
C 2
_ F
E 4
R 4
R T
_ h
C e
O b
D i
E t
C m
N a
O p
T c
H o
U d
M e
B c
N d
A o
I e
L s
n
o
t
s
u
p
p
o
r
t
a
t
h
u
m
b
n
a
i
l.

W
I 0
N x
C 8
O 8
D 9
E 8
C 2
_ F
E 4
R 5
R T
_ h
P e
A b
L i
E t
T m
T a
E p
U p
N a
A l
V e
A t
I t
L e
A i
B s
L u
E n
a
v
a
i
l
a
b
l
e
.

W
I 0
N x
C 8
O 8
D 9
E 8
C 2
_ F
E 4
R 6
R T
_ o
C o
O m
D a
E n
C y
T s
O c
O a
M n
A l
N i
Y n
S e
C s
A w
N e
L r
I e
N r
E e
S q
u
e
s
t
e
d
.

W
I 0
N x
C 8
O 8
D 9
E 8
C 2
_ F
E 4
R 8
R
_ A
I n
N i
T n
E t
R e
N r
A n
L a
E l
R e
R r
O r
R o
r
o
c
c
u
r
r
e
d
.

W
I 0
N x
C 8
O 8
D 9
E 8
C 2
_ F
E 4
R 9
R T
_ h
S e
O b
U i
R t
C m
E a
R p
E b
C o
T u
D n
O d
E s
S d
N o
O n
T o
M t
A m
T a
C t
H c
D h
I t
M h
E e
N b
S i
I t
O m
N a
S p
d
i
m
e
n
s
i
o
n
s
.

W
I 0
N x
C 8
O 8
D 9
E 8
C 2
_ F
E 5
R 0
R T
_
C h
O e
M c
P o
O m
N p
E o
N n
T e
N n
O t
T c
F a
O n
U n
N o
D t
b
e
f
o
u
n
d
.

W
I 0
N x
C 8
O 8
D 9
E 8
C 2
_ F
E 5
R 1
R T
_ h
I e
M b
A i
G t
E m
S a
I p
Z s
E i
O z
U e
T i
O
F s
R o
A u
N t
G s
E i
d
e
t
h
e
v
a
l
i
d
r
a
n
g
e
.

W
I 0
N x
C 8
O 8
D 9
E 8
C 2
_ F
E 5
R 2
R T
_ h
T e
O r
O e
M i
U s
C t
H o
M o
E m
T u
A c
D h
A m
T e
A t
a
d
a
t
a
t
o
b
e
w
r
i
t
t
e
n
t
o
t
h
e
b
i
t
m
a
p
.

W
I 0
N x
C 8
O 8
D 9
E 8
C 2
_ F
E 6
R 0
R T
_ h
B e
A i
D m
I a
M g
A e
G i
E s
u
n
r
e
c
o
g
n
i
z
e
d
.

W
I 0
N x
C 8
O 8
D 9
E 8
C 2
_ F
E 6
R 1
R T
_ h
B e
A i
D m
H a
E g
A e
D h
E e
R a
d
e
r
i
s
u
n
r
e
c
o
g
n
i
z
e
d
.

W
I 0
N x
C 8
O 8
D 9
E 8
C 2
_ F
E 6
R 2
R T
_ h
F e
R b
A i
M t
E m
M a
I p
S f
S r
I a
N m
G e
i
s
m
i
s
s
i
n
g
.

W
I 0
N x
C 8
O 8
D 9
E 8
C 2
_ F
E 6
R 3
R T
_ h
B e
A i
D m
M a
E g
T e
A m
D e
A t
T a
A d
H a
E t
A a
D h
E e
R a
d
e
r
i
s
u
n
r
e
c
o
g
n
i
z
e
d
.

W
I 0
N x
C 8
O 8
D 9
E 8
C 2
_ F
E 7
R 0
R T
_ h
B e
A
D s
S t
T r
R e
E a
A m
M d
D a
A t
T a
A i
s
u
n
r
e
c
o
g
n
i
z
e
d
.

W
I 0
N x
C 8
O 8
D 9
E 8
C 2
_ F
E 7
R 1
R F
_ a
S i
T l
R e
E d
A t
M o
W w
R r
I i
T t
E e
t
o
t
h
e
s
t
r
e
a
m
.

W
I 0
N x
C 8
O 8
D 9
E 8
C 2
_ F
E 7
R 2
R F
_ a
S i
T l
R e
E d
A t
M o
R r
E e
A a
D d
f
r
o
m
t
h
e
s
t
r
e
a
m
.

W
I 0
N x
C 8
O 8
D 9
E 8
C 2
_ F
E 7
R 3
R
_ T
S h
T e
R s
E t
A r
M e
N a
O m
T i
A s
V n
A o
I t
L a
A v
B a
L i
E l
a
b
l
e
.

W
I 0
N x
C 8
O 8
D 9
E 8
C 2
_ F
E 8
R 0
R T
_ h
U e
N b
S
U i
P t
P m
O a
R p
T p
E i
D x
P e
I l
X f
E o
L r
F m
O a
R t
M i
A s
T u
n
s
u
p
p
o
r
t
e
d
.

W
I 0
N x
C 8
O 8
D 9
E 8
C 2
_ F
E 8
R 1
R T
_ h
U e
N o
S p
U e
P r
P a
O t
R
T i
E o
D n
O i
P s
E u
R n
A s
T u
I p
O p
N o
r
t
e
d
.

W
I 0
N x
C 8
O 8
D 9
E 8
C 2
_ F
E 8
R A
R T
_ h
I e
N c
V o
A m
L p
I o
D n
R e
E n
G t
I r
S e
T g
R i
A s
T t
I r
O a
N t
i
o
n
i
s
i
n
v
a
l
i
d
.

W
I 0
N x
C 8
O 8
D 9
E 8
C 2
_ F
E 8
R B
R T
_ h
C e
O c
M o
P m
O p
N o
E n
N e
T n
I t
N i
I n
T i
I t
A i
L a
I l
Z i
E z
F a
A t
I i
L o
U n
R h
E
a
s
f
a
i
l
e
d
.

W
I 0
N x
C 8
O 8
D 9
E 8
C 2
_ F
E 8
R C
R T
_ h
I e
N b
S u
U f
F f
F e
I r
C a
I l
E l
N o
T c
B a
U t
F e
F d
E i
R s
i
n
s
u
f
f
i
c
i
e
n
t
.

W
I 0
N x
C 8
O 8
D 9
E 8
C 2
_ F
E 8
R D
R D
_ u
D p
U l
P i
L c
I a
C t
A e
T m
E e
M t
E a
T d
A a
D t
A a
T i
A s
P p
R r
E e
S s
E e
N n
T t
.

W
I 0
N x
C 8
O 8
D 9
E 8
C 2
_ F
E 8
R E
R
_ T
P h
R e
O b
P i
E t
R m
T a
Y p
U p
N r
E o
X p
P e
E r
C t
T y
E t
D y
T p
Y e
P i
E s
u
n
e
x
p
e
c
t
e
d
.

W
I 0
N x
C 8
O 8
D 9
E 8
C 2
_ F
E 8
R F
R T
_ h
U e
N s
E i
X z
P e
E i
C s
T u
E n
D e
S x
I p
Z e
E c
t
e
d
.

W
I 0
N x
C 8
O 8
D 9
E 8
C 2
_ F
E 9
R 0
R T
_ h
I e
N p
V r
A o
L p
I e
D r
Q t
U y
E q
R u
Y e
R r
E y
Q i
U s
E i
S n
T v
a
l
i
d
.

W
I 0
N x
C 8
O 8
D 9
E 8
C 2
_ F
E 9
R 1
R T
_ h
U e
N m
E e
X t
P a
E d
C a
T t
E a
D t
M y
E p
T e
A i
D s
A u
T n
A e
T x
Y p
P e
E c
t
e
d
.

W
I 0
N x
C 8
O 8
D 9
E 8
C 2
_ F
E 9
R 2
R
_ T
R h
E e
Q s
U p
E e
S c
T i
O f
N i
L e
Y d
V b
A i
L t
I m
D a
A p
T p
M r
E o
T p
A e
D r
A t
T y
A i
R s
O o
O n
T l
y
v
a
l
i
d
a
t
r
o
o
t
l
e
v
e
l.

W
I 0
N x
C 8
O 8
D 9
E 8
C 2
_ F
E 9
R 3
R T
_ h
I e
N q
V u
A e
L r
I y
D s
Q t
U r
E i
R n
Y g
C c
H o
A n
R t
A a
C i
T n
E s
R a
n
i
n
v
a
l
i
d
c
h
a
r
a
c
t
e
r.

W
I 0
N x
C 8
O 8
D 9
E 8
C 2
_ F
E 9
R 4
R W
_ i
W n
I d
N o
3 w
2 s
E C
R o
R d
O e
R c
s
r
e
c
e
i
v
e
d
a
n
e
r
r
o
r
f
r
o
m
t
h
e
W
i
n
3
2
s
y
s
t
e
m
.

W
I 0
N x
C 8
O 8
D 9
E 8
C 2
_ F
E 9
R 5
R T
_ h
I e
N r
V e
A q
L u
I e
D s
P t
R e
O d
G l
R e
E v
S e
S l
I o
V f
E d
L e
E t
V a
E i
L l
i
s
n
o
t
p
r
e
s
e
n
t
.

Requirements

Header
Win
erro
r.h

See also
C
O
M
E
r
r
o
r
C
o
d
e
s
Impersonation Level Constants
1/7/2020 • 2 minutes to read • Edit Online

Specifies an impersonation level, which indicates the amount of authority given to the server when it is
impersonating the client.

CONSTANT/VALUE DESCRIPTION

DCOM can choose the impersonation level using its normal


RPC security blanket negotiation algorithm. For more information,
_C_I see Security Blanket Negotiation.
MP_
LEV
EL_
DEF
AUL
T
0

The client is anonymous to the server. The server process can


RPC impersonate the client, but the impersonation token will not
_C_I contain any information and cannot be used.
MP_
LEV
EL_
AN
ON
YM
OU
S
1

The server can obtain the client's identity. The server can
RPC impersonate the client for ACL checking, but it cannot access
_C_I system objects as the client.
MP_
LEV
EL_I
DEN
TIFY
2

The server process can impersonate the client's security


RPC context while acting on behalf of the client. This level of
_C_I impersonation can be used to access local resources such as
MP_ files. When impersonating at this level, the impersonation
LEV token can only be passed across one machine boundary. The
EL_I Schannel authentication service only supports this level of
MP impersonation.
ERS
ON
ATE
3
CONSTANT/VALUE DESCRIPTION

The server process can impersonate the client's security


RPC context while acting on behalf of the client. The server process
_C_I can also make outgoing calls to other servers while acting on
MP_ behalf of the client, using cloaking. The server may use the
LEV client's security context on other machines to access local and
EL_ remote resources as the client. When impersonating at this
DEL level, the impersonation token can be passed across any
EGA number of computer boundaries.
TE
4

Remarks
GetUserName will fail while impersonating at identify level. The workaround is to impersonate, call
OpenThreadToken, revert, call GetTokenInformation, and finally, call LookupAccountSid. Using
CoSetProxyBlanket, the client sets the impersonation level
Using CoSetProxyBlanket, the client sets the impersonation level and proxy identity that will be available when a
server calls CoImpersonateClient. The identity the server will see when impersonating takes place is described in
Cloaking. Note that when making a call while impersonating, the callee will normally receive the caller's process
token, not the caller's impersonation token. To receive the caller's impersonation token, the caller must enable
cloaking.

Requirements

Minimum supported client Windows 2000 Professional [desktop apps only]

Minimum supported server Windows 2000 Server [desktop apps only]

Header
Rpc
Dce.
h

See also
C
l
o
a
k
i
n
g
Enumerations
1/7/2020 • 2 minutes to read • Edit Online

The following enumerations are provided by COM:


APTTYPE
APTTYPEQUALIFIER
BIND_FLAGS
BINDSPEED
BSCO_OPTION
CALLFRAME_COPY
CALLFRAME_FREE
CALLFRAME_WALK
CALLTYPE
CLSCTX
CO_MARSHALING_CONTEXT_ATTRIBUTES
COINIT
COMSD
COWAIT_FLAGS
EOC_ChangeType
EOLE_AUTHENTICATION_CAPABILITIES
EXTCONN
GLOBALOPT_PROPERTIES
GLOBALOPT_UNMARSHALING_POLICY_VALUES
MKRREDUCE
MKSYS
MSHCTX
MSHLFLAGS
PENDINGMSG
PENDINGTYPE
RECORD_READING_POLICY
REGCLS
SERVERCALL
THDTYPE
TYSPEC
Interfaces
1/29/2020 • 8 minutes to read • Edit Online

The following interfaces are provided by COM.

INTERFACE DESCRIPTION

IAccessControl Enables the management of access to objects and properties


on the objects.

IAgileObject Marks an interface as agile across apartments.

IBindCtx Provides access to a bind context, which is an object that


stores information about a particular moniker binding
operation.

IBlockingLock Provides a semaphore that can be used to provide


temporarily exclusive access to a shared resource such as a
file.

ICallFactory Creates a call object for processing calls to the methods of an


asynchronous interface.

ICallFrame Enables manipulation of call frames such as stack frames. The


call frame is the body of information that a procedure must
save to allow it to properly return to its caller. A call frame may
exist on the stack or in registers. A stack frame maintains its
caller's context information on the stack.

ICallFrameEvents Delivers method call notifications.

ICallFrameWalker Walks a stack frame looking for interesting values.

ICallIndirect Invokes an object with an indirect reference to the invocations


arguments, rather than the traditional direct call.

ICallInterceptor Supports the registration and un-registering of event sinks


wishing to be notified of calls made directly on the interface.
In addition, this interface provides a means by which an
invocation can be carried out with an indirect reference to the
invocations arguments.

ICallUnmarshal Is used on the server (receiving) side of a remote invocation.


An appropriate instance of ICallUnmarshal can be used to
transform back into an call frame a method invocation
previously marshaled by a call to ICallFrame::Marshal on the
client (sending) side.

ICancelMethodCalls Manages cancellation requests on an outbound method call


and monitors the current state of that method call on the
server thread.
INTERFACE DESCRIPTION

ICatInformation Obtains information about the categories implemented or


required by a certain class, as well as information about the
categories registered on the specified computer.

ICatRegister Provides methods for registering and unregistering


component category information in the registry. This includes
both the human-readable names of categories and the
categories implemented/required by a given component or
class.

IClassActivator Specifies a method that retrieves a class object.

IClassFactory Enables a class of objects to be created.

IClassFactory2 Enables a class factory object, in any sort of object server, to


control object creation through licensing.

IClientSecurity Gives the client control over the security settings for each
individual interface proxy of an object.

IComThreadingInfo Enables you to obtain the following information about the


apartment and thread that the caller is executing in:
apartment type, thread type, and thread GUID. It also allows
you to specify a thread GUID.

IConnectionPoint Supports connection points for connectable objects.

IConnectionPointContainer Supports connection points for connectable objects.

IContext Supports setting COM+ context properties.

IContextCallback Provides a mechanism to execute a function inside a specific


COM+ object context.

IContinueCallback Provides a generic callback mechanism for interruptible


processes that should periodically ask an object whether to
continue.

IEnumCATID Enumerates category identifiers.

IEnumCLSID Enumerates class identifiers.

IEnumCATEGORYINFO Enumerates component categories registered in the system.

IEnumConnectionPoints Enumerates connection points.

IEnumConnections Enumerates the current connections for a connectable object.

IEnumContextProps Provides a mechanism for enumerating the context properties


associated with a COM+ object context.

IEnumGUID Enables clients to enumerate through a collection of class IDs


for COM classes.
INTERFACE DESCRIPTION

IEnumString Enumerate strings. LPWSTR is the type that indicates a


pointer to a zero-terminated string of wide, or Unicode,
characters.

IEnumUnknown Enumerates objects with the IUnknown interface. It can be


used to enumerate through the objects in a component
containing multiple objects.

IEventProperty Associates a named event property with its value.

IEventPublisher Registers, modifies, removes, and provides information about


an event publisher.

IExternalConnection Manages a server object's count of marshaled, or external,


connections. A server that maintains such a count can detect
when it has no external connections and shut itself down in an
orderly fashion.

IFastRundown Marks an interface as eligible for fast rundown behavior.

IFileBasedLogInit Initializes an instance of a file based implementation of ILog.

IForegroundTransfer Transfers the foreground window to the process hosting the


COM server.

IGlobalInterfaceTable Enables any apartment in a process to get access to an


interface implemented on an object in any other apartment in
the process.

IGlobalOptions Sets and queries certain global properties of the COM


runtime.

IInitializeSpy Performs initialization or cleanup when entering or exiting a


COM apartment.

IInternalUnknown Used exclusively in lightweight client-side handlers that


require access to some of the internal interfaces on the proxy.

ILog Provides generic low-level logging functionality.

IMalloc Allocates, frees, and manages memory.

IMallocSpy Enables application developers to monitor (spy on) memory


allocation, detect memory leaks, and simulate memory failure
in calls to IMalloc methods.

IMarshal Enables a COM object to define and manage the marshaling


of its interface pointers.

IMarshalingStream Provides additional information about the marshaling context


to custom-marshaled objects and unmarshalers.
INTERFACE DESCRIPTION

IMessageFilter Provides COM servers and applications with the ability to


selectively handle incoming and outgoing COM messages
while waiting for responses from synchronous calls. Filtering
messages helps to ensure that calls are handled in a manner
that improves performance and avoids deadlocks. COM
messages can be synchronous, asynchronous, or input-
synchronized; the majority of interface calls are synchronous.

IMoniker Enables you to use a moniker object, which contains


information that uniquely identifies a COM object. An object
that has a pointer to the moniker object's IMoniker interface
can locate, activate, and get access to the identified object
without having any other specific information on where the
object is actually located in a distributed system.

IMultiQI Enables a client to query an object proxy, or handler, for


multiple interfaces by using a single RPC call. By using this
interface, instead of relying on separate calls to
IUnknown::QueryInterface, clients can reduce the number
of RPC calls that have to cross thread, process, or machine
boundaries and, therefore, the amount of time required to
obtain the requested interface pointers.

IObjContext Performs various operations on contexts.

IOleItemContainer Used by item monikers when they are bound to the objects
they identify.

IOrpcDebugNotify Provides remote debugging functionality.

IParseDisplayName Parses a displayable name string to convert it into a moniker


for custom moniker implementations.

IPersist Provides the CLSID of an object that can be stored


persistently in the system. Allows the object to specify which
object handler to use in the client process, as it is used in the
default implementation of marshaling.

IPersistFile Enables an object to be loaded from or saved to a disk file,


rather than a storage object or stream.

IPersistStorage Enables a container application to pass a storage object to


one of its contained objects and to load and save the storage
object.

IPersistStream Enables the saving and loading of objects that use a simple
serial stream for their storage needs.

IPersistStreamInit A replacement for IPersistStream that adds an initialization


method.

IPipeByte Transfers data of the byte type (which is 8 bits wide).

IPipeDouble Transfers data of the double type (which is 64 bits wide).


INTERFACE DESCRIPTION

IPipeLong Transfers data of the long integer type (which is 32 bits wide).

IProcessInitControl Specifies the process initialization time-out interval.

IProcessLock Used by ISurrogateService to prevent the process from


terminating due to a time-out.

IProgressNotify Enables applications and other objects to receive notifications


of changes in the progress of a downloading operation.

IProvideClassInfo Provides access to the type information for an object's coclass


entry in its type library.

IProvideClassInfo2 An extension to IProvideClassInfo that makes is faster and


easier to retrieve an object's outgoing interface IID for its
default event set.

IProvideMultipleClassInfo An extension to IProvideClassInfo2 that makes it faster and


easier to retrieve type information from a component that
may have multiple coclasses that determine its behavior.

IPSFactoryBuffer Provides custom methods for the creation of COM object


proxies and stubs. This interface is not marshalable.

IROTData Implemented by monikers to enable the running object table


(ROT) to compare monikers against each other.

IRpcChannelBuffer Marshals data between a COM client proxy and a COM server
stub.

IRpcOptions Enables callers to set or query the values of various properties


that control how COM handles remote procedure calls (RPC).

IRpcProxyBuffer Controls the RPC proxy used to marshal data between COM
components.

IRpcStubBuffer Controls the RPC stub used to marshal data between COM
components.

IRunnableObject Enables a container to control the running of its embedded


objects. In the case of an object implemented with a local
server, calling the Run method launches the server's .EXE file.
In the case of an object implemented with an in-process
server, calling Run causes the object .DLL file to transition into
the running state.

IRunningObjectTable Manages access to the running object table (ROT), a globally


accessible look-up table on each workstation. A workstation's
ROT keeps track of those objects that can be identified by a
moniker and that are currently running on the workstation.
When a client tries to bind a moniker to an object, the
moniker checks the ROT to see if the object is already running;
this allows the moniker to bind to the current instance instead
of loading a new one.
INTERFACE DESCRIPTION

IServerSecurity Used by a server to help authenticate the client and to


manage impersonation of the client.

IStdMarshalInfo Retrieves the CLSID identifying the handler to be used in the


destination process during standard marshaling.

ISurrogate Used to dynamically load new DLL servers into an existing


surrogate and free the surrogate when it is no longer needed.

ISurrogateService Used to initialize, launch, and release a COM+ application. You


can also refresh the catalog and shut down the process.

ISynchronize Provides asynchronous communication between objects


about the occurrence of an event. Objects that implement
ISynchronize can receive indications that an event has
occurred, and they can respond to queries about the event. In
this way, clients can make sure that one request has been
processed before they submit a subsequent request that
depends on completion of the first one.

ISynchronizeContainer Manages a group of unsignaled synchronization objects.

ISynchronizeEvent Assigns an event handle to a synchronization object.

ISynchronizeHandle Retrieves a handle associated with a synchronization object.

IUnknown Enables clients to get pointers to other interfaces on a given


object through the QueryInterface method, and manage the
existence of the object through the AddRef and Release
methods. All other COM interfaces are inherited, directly or
indirectly, from IUnknown. Therefore, the three methods in
IUnknown are the first entries in the VTable for every
interface.
IAccessibilityDockingService::GetAvailableSize
method
1/7/2020 • 2 minutes to read • Edit Online

Gets the dimensions available for docking an accessibility window on a monitor.

Syntax
HRESULT GetAvailableSize(
[in] HMONITOR hMonitor,
[out] UINT *puMaxHeight,
[out] UINT *puFixedWidth
);

Parameters
h Specifies the monitor for which the available docking size will be retrieved.
M
o
n
i
t
o
r
[
i
n
]

p On success, set to the maximum height available for docking on the specified hMonitor, in pixels.
u
On failure, set to zero.
M
a
x
H
e
i
g
h
t
[
o
u
t
]

p
u
F
i
x
e
d
W
i
d
t
h
[
o
u
t
]

On success, set to the fixed width available for docking on the specified hMonitor, in pixels. Any window
docked to this hMonitor will be sized to this width.
On failure, set to zero.

Return value
RETURN CODE DESCRIPTION

Success.
S_O
K

The monitor specified by the monitor handle does not support


HRE docking.
SUL
T_F
RO
M_
WI
N32
(ER
RO
R_I
NV
ALI
D_
MO
NIT
OR_
HA
NDL
E)

If either puMaxHeight or puFixedWidth are null, an access violation will occur.

Remarks
Accessibility windows can only be docked to a monitor that has at least 768 vertical screen pixels. This API will not
allow such windows to be docked with a height that would cause Windows Store apps to have less than 768
vertical screen pixels.

Examples
IAccessibilityDockingService *pDockingService;
HRESULT hr = CoCreateInstance(CLSID_AccessibilityDockingService, CLSCTX_INPROV_SERVER, nullptr,
IID_PPV_ARGS(&pDockingService));
if (SUCCEEDED(hr))
{
UINT uMaxHeight;
UINT uFixedWidth;

HMONITOR hMonitor = MonitorFromWindow(_hwndMyApplication, MONITOR_DEFAULTTONULL);


if (hMonitor != nullptr)
{
hr = pDockingService->GetAvailableSize(hMonitor, &uMaxHeight, &uFixedWidth);
}
}

See also
I
A
c
c
e
s
s
i
b
i
l
i
t
y
D
o
c
k
i
n
g
S
e
r
v
i
c
e
IOrpcDebugNotify interface
1/7/2020 • 2 minutes to read • Edit Online

Provides remote debugging functionality.

When to implement
Implement this interface to enable remote debugging over RPC.

When to use
This interface should be used for in-process remote debugging when software exceptions should not be used
for the COM debugger notifications. It enables in-process debuggers to be notified by direct calls using these
methods.

Members
The IOrpcDebugNotify interface inherits from the IUnknown interface. IOrpcDebugNotify also has these
types of members:
Methods
Methods
The IOrpcDebugNotify interface has these methods.

METHOD DESCRIPTION

ClientFillBuffer Sends data from the client debugger to the server debugger.

ClientGetBufferSize Retrieves the RPC buffer size from the client-side debugger.

ClientNotify Informs the client of an outgoing debugger request to the


server.

ServerFillBuffer Sends data from the server debugger to the client debugger.

ServerGetBufferSize Retrieves the RPC buffer size from the server-side debugger.

ServerNotify Informs the server of an incoming debugger request from


the client.

Remarks
An import library containing the IOrpcDebugNotify interface is not included in the Microsoft Windows
Software Development Kit (SDK). An application can use the GetProcAddress and GetModuleHandle
functions to retrieve a function pointer to DllDebugObjectRPCHook from oleaut.dll and provide these
methods via the IOrpcDebugNotify interface.

Requirements
Minimum supported client Windows 2000 Professional [desktop apps only]

Minimum supported server Windows 2000 Server [desktop apps only]

Header
N/A

IDL
N/A

See also
I
U
n
k
n
o
w
n

O
R
P
C
_
D
B
G
_
A
L
L

O
R
P
C
_
D
B
G
_
B
U
F
F
E
R
O
R
P
C
_
I
N
I
T
_
A
R
G
S

D
l
l
D
e
b
u
g
O
b
j
e
c
t
R
P
C
H
o
o
k
IOrpcDebugNotify::ClientGetBufferSize method
1/7/2020 • 2 minutes to read • Edit Online

Retrieves the RPC buffer size from the client-side debugger.

NOTE
An import library containing the ClientGetBufferSize function is not included in the Microsoft Windows Software
Development Kit (SDK). An application can use the GetProcAddress and GetModuleHandle functions to retrieve a
function pointer to DllDebugObjectRPCHook from oleaut.dll and provide this function via the IOrpcDebugNotify
interface.

Syntax
void ClientGetBufferSize(
ORPC_DBG_ALL *lpOrpcDebugAll
);

Parameters
l
p
O
r
p
c
D
e
b
u
g
A
l
l

A pointer to a ORPC_DBG_ALL structure that contains notification specific information the COM RPC
system passes to the debugger.

Return value
This method does not return a value.

Requirements

Minimum supported client Windows 2000 Professional [desktop apps only]


Minimum supported server Windows 2000 Server [desktop apps only]

Header
N/A

IDL
N/A

See also
O
R
P
C
_
I
N
I
T
_
A
R
G
S

D
l
l
D
e
b
u
g
O
b
j
e
c
t
R
P
C
H
o
o
k

I
O
r
p
c
D
e
b
u
g
N
o
t
i
f
y
IOrpcDebugNotify::ClientFillBuffer method
1/7/2020 • 2 minutes to read • Edit Online

Sends data from the client debugger to the server debugger.

NOTE
An import library containing the ClientFillBuffer function is not included in the Microsoft Windows Software Development
Kit (SDK). An application can use the GetProcAddress and GetModuleHandle functions to retrieve a function pointer to
DllDebugObjectRPCHook from oleaut.dll and provide this function via the IOrpcDebugNotify interface.

Syntax
void ClientFillBuffer(
ORPC_DBG_ALL *lpOrpcDebugAll
);

Parameters
l
p
O
r
p
c
D
e
b
u
g
A
l
l

A pointer to a ORPC_DBG_ALL structure that contains notification specific information the COM RPC
system passes to the debugger.

Return value
This method does not return a value.

Requirements

Minimum supported client Windows 2000 Professional [desktop apps only]


Minimum supported server Windows 2000 Server [desktop apps only]

Header
N/A

IDL
N/A

See also
D
l
l
D
e
b
u
g
O
b
j
e
c
t
R
P
C
H
o
o
k

I
O
r
p
c
D
e
b
u
g
N
o
t
i
f
y
IOrpcDebugNotify::ClientNotify method
1/7/2020 • 2 minutes to read • Edit Online

Informs the client of an outgoing debugger request to the server.

NOTE
An import library containing the ClientNotify function is not included in the Microsoft Windows Software Development Kit
(SDK). An application can use the GetProcAddress and GetModuleHandle functions to retrieve a function pointer to
DllDebugObjectRPCHook from oleaut.dll and provide this function via the IOrpcDebugNotify interface.

Syntax
void ClientNotify(
ORPC_DBG_ALL *lpOrpcDebugAll
);

Parameters
l
p
O
r
p
c
D
e
b
u
g
A
l
l

A pointer to a ORPC_DBG_ALL structure that contains notification specific information the COM RPC
system passes to the debugger.

Return value
This method does not return a value.

Requirements

Minimum supported client Windows 2000 Professional [desktop apps only]


Minimum supported server Windows 2000 Server [desktop apps only]

Header
N/A

IDL
N/A

See also
O
R
P
C
_
I
N
I
T
_
A
R
G
S

D
l
l
D
e
b
u
g
O
b
j
e
c
t
R
P
C
H
o
o
k

I
O
r
p
c
D
e
b
u
g
N
o
t
i
f
y
IOrpcDebugNotify::ServerNotify method
1/7/2020 • 2 minutes to read • Edit Online

Informs the server of an incoming debugger request from the client.

NOTE
An import library containing the ServerNotify function is not included in the Microsoft Windows Software Development
Kit (SDK). An application can use the GetProcAddress and GetModuleHandle functions to retrieve a function pointer to
DllDebugObjectRPCHook from oleaut.dll and provide this function via the IOrpcDebugNotify interface.

Syntax
void ServerNotify(
ORPC_DBG_ALL *lpOrpcDebugAll
);

Parameters
l
p
O
r
p
c
D
e
b
u
g
A
l
l

A pointer to a ORPC_DBG_ALL structure that contains notification specific information the COM RPC
system passes to the debugger.

Return value
This method does not return a value.

Requirements

Minimum supported client Windows 2000 Professional [desktop apps only]


Minimum supported server Windows 2000 Server [desktop apps only]

Header
N/A

IDL
N/A

See also
O
R
P
C
_
I
N
I
T
_
A
R
G
S

D
l
l
D
e
b
u
g
O
b
j
e
c
t
R
P
C
H
o
o
k

I
O
r
p
c
D
e
b
u
g
N
o
t
i
f
y
IOrpcDebugNotify::ServerGetBufferSize method
1/7/2020 • 2 minutes to read • Edit Online

Retrieves the RPC buffer size from the server-side debugger.

NOTE
An import library containing the ServerGetBufferSize function is not included in the Microsoft Windows Software
Development Kit (SDK). An application can use the GetProcAddress and GetModuleHandle functions to retrieve a
function pointer to DllDebugObjectRPCHook from oleaut.dll and provide this function via the IOrpcDebugNotify
interface.

Syntax
void ServerGetBufferSize(
ORPC_DBG_ALL *lpOrpcDebugAll
);

Parameters
l
p
O
r
p
c
D
e
b
u
g
A
l
l

A pointer to a ORPC_DBG_ALL structure that contains notification specific information the COM RPC
system passes to the debugger.

Return value
This method does not return a value.

Requirements

Minimum supported client Windows 2000 Professional [desktop apps only]


Minimum supported server Windows 2000 Server [desktop apps only]

Header
N/A

IDL
N/A

See also
O
R
P
C
_
I
N
I
T
_
A
R
G
S

D
l
l
D
e
b
u
g
O
b
j
e
c
t
R
P
C
H
o
o
k

I
O
r
p
c
D
e
b
u
g
N
o
t
i
f
y
IOrpcDebugNotify::ServerFillBuffer method
1/7/2020 • 2 minutes to read • Edit Online

Sends data from the server debugger to the client debugger.

NOTE
An import library containing the ServerFillBuffer function is not included in the Microsoft Windows Software Development
Kit (SDK). An application can use the GetProcAddress and GetModuleHandle functions to retrieve a function pointer to
DllDebugObjectRPCHook from oleaut.dll and provide this function via the IOrpcDebugNotify interface.

Syntax
void ServerFillBuffer(
ORPC_DBG_ALL *lpOrpcDebugAll
);

Parameters
l
p
O
r
p
c
D
e
b
u
g
A
l
l

A pointer to a ORPC_DBG_ALL structure that contains notification specific information the COM RPC
system passes to the debugger.

Return value
This method does not return a value.

Requirements

Minimum supported client Windows 2000 Professional [desktop apps only]


Minimum supported server Windows 2000 Server [desktop apps only]

Header
N/A

IDL
N/A

See also
O
R
P
C
_
I
N
I
T
_
A
R
G
S

D
l
l
D
e
b
u
g
O
b
j
e
c
t
R
P
C
H
o
o
k

I
O
r
p
c
D
e
b
u
g
N
o
t
i
f
y
Macros
1/7/2020 • 2 minutes to read • Edit Online

The following macros are provided by COM:


FAILED
HRESULT_CODE
HRESULT_FACILITY
HRESULT_FROM_NT
HRESULT_FROM_WIN32
HRESULT_SEVERITY
IS_ERROR
MAKE_HRESULT
MAKE_SCODE
OLESTR
SCODE_CODE
SCODE_FACILITY
SCODE_SEVERITY
SUCCEEDED
Registry Entries
1/7/2020 • 2 minutes to read • Edit Online

Registry values in the following registry keys control aspects of the functionality of COM:
HKEY_LOCAL_MACHINE\SOFTWARE\Classes
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Ole
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion
As of Windows Server 2003, COM uses only the current process token to decide which registry hive to access, not
the thread token. If COM is not able to access the user profile registry hive, it will access the
HKEY_LOCAL_MACHINE\System hive.

Related topics
R
e
g
i
s
t
r
y
HKEY_LOCAL_MACHINE\SOFTWARE\Classes
1/7/2020 • 2 minutes to read • Edit Online

The subkeys and registry values associated with the HKEY_LOCAL_MACHINE\SOFTWARE\Classes key
contain information about an application that is needed to support COM functionality. This information includes
such topics as supported data formats, compatibility information, programmatic identifiers, DCOM, and controls.

SUBKEY DESCRIPTION

AppID Configuration options for COM-based applications.

CLSID Configuration options for COM classes.

<file_extension> Associates a file name extension with a ProgID.

FileType Used by GetClassFile to match patterns against various file


bytes in a non-compound file.

Interface Associates an interface name with an interface ID (IID).

Identifies a class. Note that the ProgID is not guaranteed to


be globally unique, unlike a CLSID.

Used to determine the latest version of an object application.


AppID Key
1/7/2020 • 3 minutes to read • Edit Online

Groups the configuration options for one or more DCOM objects into one centralized location in the registry.
DCOM objects hosted by the same executable are grouped into one AppID to simplify the management of
common security and configuration settings.

Registry Key
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\AppID\{AppID_GUID }

REGISTRY VALUE DESCRIPTION

AccessPermission Describes the Access Control List (ACL) of the principals that
can access instances of this class. This ACL is used only by
applications that do not call CoInitializeSecurity.

ActivateAtStorage Configures the client to instantiate objects on the same


computer as the persistent state they are using or from
which they are initialized.

AppID Identifies the AppID GUID that corresponds to the named


executable.

AppIDFlags Configures how a COM server that is configured to run as


the "Interactive User" will be launched or bound to by a
client in a non-default desktop.

AuthenticationLevel Sets the authentication level for applications that do not call
CoInitializeSecurity or for applications that call
CoInitializeSecurity and specify an AppID.

DllSurrogate Enables DLL servers to run in a surrogate process. If an


empty string is specified, the system-supplied surrogate is
used; otherwise, the value specifies the path of the
surrogate to be used.

DllSurrogateExecutable Enables DLL servers to run in a custom surrogate process, in


conjunction with the DllSurrogate registry value.

Endpoints Configures a COM application to use a specified TCP port


number for DCOM communications.

LaunchPermission Describes the Access Control List (ACL) of the principals that
can start new servers for this class.

LoadUserSettings Determines whether COM will load the user profile for COM
servers running as the launching user application identity.

LocalService Installs an object as a service application.


REGISTRY VALUE DESCRIPTION

PreferredServerBitness Sets the preferred architecture, 32-bit or 64-bit, for this


COM server.

RemoteServerName Configures the client to request the object be run at a


particular computer whenever an activation function is
called for which a COSERVERINFO structure is not specified.

ROTFlags Controls the registration of a COM server in the running


object table (ROT).

RunAs Configures a class to run under a specific user account when


activated by a remote client without being written as a
service application.

ServiceParameters Specifies the command-line parameters to be passed to an


object installed for use by COM through the LocalService
registry value.

SRPTrustLevel Sets the software restriction policy (SRP) trust level for
applications.

Remarks
AppIDs are mapped to executables and classes using two different mechanisms:
Using a 128-bit Globally Unique Identifier (GUID ) that identifies the AppID key. A class indicates its
corresponding AppID under the CLSID key in a named value "AppID". This mapping is used during
activation.
Using a named value that indicates an executable name (such as "MYOLDAPP.EXE"). This named value is of
type REG_SZ and contains the string representation of the AppID associated with the executable. This
mapping is used to obtain the default access permissions and authentication level.
The HKEY_LOCAL_MACHINE\SOFTWARE\Classes key corresponds to the HKEY_CLASSES_ROOT key,
which was retained for compatibility with earlier versions of COM.
For COM servers, the mapping is usually generated and written to the registry during the registration process
or when running dcomcnfg.exe. However, COM clients that want to set security using the AppID key must
create appropriate registry keys and specify the required mapping by calling the registry functions or using
Regedit.exe. Then values such as AccessPermission or AuthenticationLevel can be set for the client. For
example, suppose the name of your executable for your client process is "YourClient.exe" and you want to set
the authentication level to "None". You would use Guidgen.exe or Uuidgen.exe to create the GUID that is the
AppID for your executable. Then you would set values in the registry as shown in the following example, where
00000001 represents an authentication level of "None":

HKEY_LOCAL_MACHINE\SOFTWARE\Classes\AppID
{MyGuid}
AuthenticationLevel = 00000001
MyClient.exe
AppID = {MyGUID}
AccessPermission
1/7/2020 • 2 minutes to read • Edit Online

Describes the Access Control List (ACL ) of the principals that can access instances of this class. This ACL is used
only by applications that do not call CoInitializeSecurity.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\AppID
{AppID_GUID}
AccessPermission = ACL

Remarks
This is a REG_BINARY value. It contains data describing the Access Control List (ACL ) of the principals that can
access instances of this class. Upon receiving a request to connect to an existing object of this class, the ACL is
checked by the application being called while impersonating the caller. If the access-check fails, the connection is
disallowed. If this named value does not exist, the DefaultAccessPermission ACL is tested to determine whether
the connection is to be allowed.
For applications that do not call CoInitializeSecurity or do not use the IGlobalOptions interface to specify the
AppID, the executable of the application's binary must be mapped to the AppID of the application as described in
AppID. This is required so that COM can locate the AppID of the application.

Related topics
C
o
I
n
i
t
i
a
l
i
z
e
S
e
c
u
r
i
t
y

D
e
f
a
u
l
t
A
c
c
e
s
s
P
e
r
m
i
s
s
i
o
n

S
e
c
u
r
i
t
y
i
n
C
O
M
ActivateAtStorage
1/7/2020 • 2 minutes to read • Edit Online

Configures the client to instantiate objects on the same computer as the persistent state they are using or from
which they are initialized.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\AppID
{AppID_GUID}
ActivateAtStorage = value

Remarks
This is a REG_SZ value. Any value that begins with 'Y' or 'y' indicates that ActivateAtStorage should be used.
The ActivateAtStorage capability provides a transparent way to allow clients to locate running objects on the
same computer as the data that they use. This reduces network traffic because the object performs local file-system
calls instead of calls across the network.
When a value is set for ActivateAtStorage, this becomes the default behavior in calls to the
CoGetInstanceFromFile and CoGetInstanceFromIStorage functions, as well as to the file moniker
implementation of IMoniker::BindToObject. In all of these calls, specifying a COSERVERINFO structure
overrides the setting of ActivateAtStorage for the duration of the function call. The caller can pass
COSERVERINFO information to IMoniker::BindToObject through the BIND_OPTS2 structure.
The value set for ActivateAtStorage is also the default behavior when CLSCTX_REMOTE_SERVER is specified if
no registry information for the class is installed on the client's computer. Client applications written to take
advantage of ActivateAtStorage may therefore require less administration.

Related topics
C
L
S
C
T
X

C
o
G
e
t
I
n
s
t
a
n
c
e
F
r
o
m
F
i
l
e

C
o
G
e
t
I
n
s
t
a
n
c
e
F
r
o
m
I
S
t
o
r
a
g
e

C
O
S
E
R
V
E
R
I
N
F
O

I
M
o
n
i
k
e
r
:
:
B
i
n
d
T
o
O
b
j
e
c
t

R
e
g
i
s
t
e
r
i
n
g
C
O
M
S
e
r
v
e
r
s
AppID
1/7/2020 • 2 minutes to read • Edit Online

Identifies the AppID GUID that corresponds to the named executable.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\AppID
<Executable_name>
AppID = {AppID_GUID}

Remarks
This is a REG_SZ value.

Related topics
A
p
p
I
D
K
e
y
AppIDFlags
1/7/2020 • 4 minutes to read • Edit Online

A set of flags that control the activation behavior of a COM server.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\AppID
{AppID_GUID}
AppIDFlags = flags

Remarks
This is a REG_DWORD value.

FLAG VALUE CONSTANT

0x1 APPIDREGFLAGS_ACTIVATE_IUSERVER_INDESKTOP

0x2 APPIDREGFLAGS_SECURE_SERVER_PROCESS_SD_AND_BIND

0x4 APPIDREGFLAGS_ISSUE_ACTIVATION_RPC_AT_IDENTIFY

APPIDREGFLAGS_ACTIVATE_IUSERVER_INDESKTOP Description
If the APPIDREGFLAGS_ACTIVATE_IUSERVER_INDESKTOP flag is cleared in AppIDFlags or if AppIDFlags
is not present, the client in a terminal server session making an activation request for an Interactive User COM
server, will either bind to, or launch and bind to, the COM server in the "default" desktop of the "winsta0" window
station of the session in the activation request. For example, if the client is running "winsta0\desktop1" of session 3,
the activation request for session 3 will either bind to, or launch and bind to, the COM server in "winsta0\default"
of session 3, even if an instance of the COM server is already running in "winsta0\desktop1" of session 3.
If the APPIDREGFLAGS_ACTIVATE_IUSERVER_INDESKTOP flag is set in the AppIDFlags value, COM will
either bind to, or launch and bind to, the server process running in the client's desktop and the session in the
activation request. For example, if the client is running "winsta0\desktop1" in session 3, the activation request for
session 3 will either bind to, or launch and bind to, the COM server in "winsta0\desktop1" in session 3, even if an
instance of the COM server is already running in "winsta0\default" in session 3.
The client can use the session moniker to specify a session different than the client's session when it makes the
activation request.
The APPIDREGFLAGS_ACTIVATE_IUSERVER_INDESKTOP flag applies only to COM servers that are
configured to RunAs "Interactive User".
APPIDREGFLAGS_SECURE_SERVER_PROCESS_SD_AND_BIND Description
If the APPIDREGFLAGS_SECURE_SERVER_PROCESS_SD_AND_BIND flag is set in AppIDFlags, COM
servers that are configured to RunAs "Activator" will be launched with a process security descriptor that allows
PROCESS_ALL_ACCESS to the LogonID SID of the process token. In addition, the owner of the security descriptor
will be set to the LogonID SID of the process token.
If the APPIDREGFLAGS_SECURE_SERVER_PROCESS_SD_AND_BIND flag is set in AppIDFlags, COM
servers that are configured to RunAs "This User" will be launched with a process security descriptor that allows
PROCESS_ALL_ACCESS in the LogonID SID of the process token. In addition, the owner of the security descriptor
will be set to the LogonID SID of the process token. Further, the COM Service Control Manager (SCM ) modifies
the token of the COM server process as follows:
It adds an APPID SID to the token. It grants the APPID SID full access in the token default discretionary access
control list (DACL ). In Windows Vista and later versions of Windows, it grants the OwnerRights SID
READ_CONTROL permission in the token default DACL. In pre-Windows Vista versions of Windows, it sets the
token owner to the APPID SID.
The following security considerations must be taken into account when using the
APPIDREGFLAGS_SECURE_SERVER_PROCESS_SD_AND_BIND flag:
The APPIDREGFLAGS_SECURE_SERVER_PROCESS_SD_AND_BIND flag is meant to be set by COM
servers that are launched under one of the built-in service security contexts; either the NetworkService or the
LocalService accounts. If the servers impersonate privileged clients and if the
APPIDREGFLAGS_SECURE_SERVER_PROCESS_SD_AND_BIND flag is not set, malicious code running in
other processes with the same security context can elevate privilege by hijacking the impersonation tokens of
the privileged clients from the COM server process.
When the APPIDREGFLAGS_SECURE_SERVER_PROCESS_SD_AND_BIND flag is set, COM hardens the
security descriptor of the process object in the case of RunAs "Activator" COM servers. For such servers, the
COM client is expected to harden the token that it uses for the COM activation.
When the APPIDREGFLAGS_SECURE_SERVER_PROCESS_SD_AND_BIND flag is set, COM hardens the
security descriptor of the process object in the case of RunAs "This User" COM servers. It also hardens the
process token of the COM server since the COM SCM is the entity that creates the token.
The APPIDREGFLAGS_SECURE_SERVER_PROCESS_SD_AND_BIND flag is supported in Windows XP,
Windows Server 2003, Windows Vista, and Windows Server 2008 only when the MSRC8322 patch (security
bulletin MS09-012) is applied. It is natively supported in Windows 7 and later versions of Windows.
The APPIDREGFLAGS_SECURE_SERVER_PROCESS_SD_AND_BIND flag applies only to COM servers that
are configured to RunAs "Activator" or "This User". It does not apply to COM servers that are NT services.
APPIDREGFLAGS_ISSUE_ACTIVATION_RPC_AT_IDENTIFY Description
If the APPIDREGFLAGS_ISSUE_ACTIVATION_RPC_AT_IDENTIFY flag is set in AppIDFlags, the COM SCM
will issue object activation requests to the COM server process using an impersonation level of
RPC_C_IMP_LEVEL_IDENTIFY.
If the APPIDREGFLAGS_ISSUE_ACTIVATION_RPC_AT_IDENTIFY flag is not set, the COM SCM will issue
object activation requests to the COM server processes using an impersonation level of
RPC_C_IMP_LEVEL_IMPERSONATE.
The following security considerations must be taken into account when using the
APPIDREGFLAGS_ISSUE_ACTIVATION_RPC_AT_IDENTIFY flag:
The APPIDREGFLAGS_ISSUE_ACTIVATION_RPC_AT_IDENTIFY flag is meant to be used by COM servers
that do not perform work on behalf of clients in object activation requests. For such servers, having the COM
SCM issue object activation requests at RPC_C_IMP_LEVEL_IDENTIFY minimizes the chances of privileged
tokens with SE_IMPERSONATE_NAME level appearing in the process.
The APPIDREGFLAGS_ISSUE_ACTIVATION_RPC_AT_IDENTIFY flag is supported in Windows 7 and later
versions of Windows.

Related topics
D
e
s
k
t
o
p
s

I
m
p
e
r
s
o
n
a
t
i
o
n
L
e
v
e
l
s

I
n
t
e
r
a
c
t
i
v
e
U
s
e
r

S
e
s
s
i
o
n
M
o
n
i
k
e
r
s

W
i
n
d
o
w
S
t
a
t
i
o
n
s
AuthenticationLevel
1/7/2020 • 2 minutes to read • Edit Online

Sets the authentication level for applications that do not call CoInitializeSecurity or for applications that call
CoInitializeSecurity and specify an AppID.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\AppID
{AppID_GUID}
AuthenticationLevel = value

Remarks
This is a REG_DWORD value that is equivalent to the RPC_C_AUTHN_LEVEL constants.

VALUE CONSTANT

1 RPC_C_AUTHN_LEVEL_NONE

2 RPC_C_AUTHN_LEVEL_CONNECT

3 RPC_C_AUTHN_LEVEL_CALL

4 RPC_C_AUTHN_LEVEL_PKT

5 RPC_C_AUTHN_LEVEL_PKT_INTEGRITY

6 RPC_C_AUTHN_LEVEL_PKT_PRIVACY

The AuthenticationLevel value is similar to the LegacyAuthenticationLevel value. If the


AuthenticationLevel value is present, it is used instead of the LegacyAuthenticationLevel value for that
AppID.
If the AuthenticationLevel value is of the wrong type or out of range, CoInitializeSecurity fails, causing
interface marshaling to fail. This prevents the application from making any calls at all (cross-apartment, cross-
thread, cross-process, or cross-computer).
The AuthenticationLevel and AccessPermission values are independent. If one is not present, the default is
used. The following rules list the interaction between the AuthenticationLevel value and the AccessPermission
value:
If the AuthenticationLevel is NONE, the AccessPermission and DefaultAccessPermission values are
ignored (for that application).
If the AuthenticationLevel is not present and the LegacyAuthenticationLevel is NONE, the
AccessPermission and DefaultAccessPermission values are ignored (for that application).

Related topics
A
u
t
h
e
n
t
i
c
a
t
i
o
n
L
e
v
e
l
C
o
n
s
t
a
n
t
s

L
e
g
a
c
y
A
u
t
h
e
n
t
i
c
a
t
i
o
n
L
e
v
e
l

R
e
g
i
s
t
e
r
i
n
g
C
O
M
S
e
r
v
e
r
s

S
e
c
u
r
i
t
y
i
n
C
O
M
DllSurrogate
1/7/2020 • 2 minutes to read • Edit Online

Enables DLL servers to run in a surrogate process. If an empty string is specified, the system-supplied surrogate
is used; otherwise, the value specifies the path of the surrogate to be used.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\AppID
{AppID_GUID}
DllSurrogate = path

Remarks
This is a REG_SZ value that specifies that the class is a DLL that is to be activated in a surrogate process, and the
surrogate process to be used. To use the system-supplied generic surrogate process, set path to an empty string
or NULL. To specify another surrogate process, set path to the path of the surrogate. As in the specification of the
path of a server under the LocalServer32 key, a full path specification is not necessary. The surrogate must be
written to properly communicate with the DCOM service as described in Writing a Custom Surrogate.
The DllSurrogate value must be present for a DLL server to be activated in a surrogate. Activation refers to a call
to CoGetClassObject, CoCreateInstanceEx, CoCreateInstanceEx, CoGetInstanceFromFile,
CoGetInstanceFromIStorage, or IMoniker::BindToObject. Running DLLs in a surrogate process provides the
benefits of an executable implementation, including fault isolation, the ability to serve multiple clients
simultaneously, and allowing the server to provide services to remote clients in a distributed environment.

Related topics
C
o
R
e
g
i
s
t
e
r
S
u
r
r
o
g
a
t
e
D
L
L
S
u
r
r
o
g
a
t
e
s

D
l
l
S
u
r
r
o
g
a
t
e
E
x
e
c
u
t
a
b
l
e

I
S
u
r
r
o
g
a
t
e
DllSurrogateExecutable
1/7/2020 • 2 minutes to read • Edit Online

Enables DLL servers to run in a custom surrogate process, in conjunction with the DllSurrogate registry value. If
DllSurrogateExecutable is not specified, COM passes NULL as the value for the first parameter of the
CreateProcess function.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\AppID
{AppID_GUID}
DllSurrogateExecutable = file

Remarks
This value is of type REG_SZ. It works in conjunction with the DllSurrogate value to prevent any ambiguity when
using the CreateProcess function. DllSurrogate indicates whether a custom surrogate needs to be used, and this
information is passed as the first parameter for CreateProcess. Depending on the implementation of
CreateProcess, this information might be ambiguous. If DllSurrogateExecutable is specified, COM passes the
value as the first parameter of CreateProcess. If DllSurrogateExecutable is not specified, COM passes NULL as
the value for the first parameter of CreateProcess.

Related topics
C
o
R
e
g
i
s
t
e
r
S
u
r
r
o
g
a
t
e

D
L
L
S
u
r
r
o
g
a
t
e
s

D
l
l
S
u
r
r
o
g
a
t
e

I
S
u
r
r
o
g
a
t
e
Endpoints
1/7/2020 • 2 minutes to read • Edit Online

Configures a COM application to use a specified TCP port number for DCOM communications.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\AppID
{AppID_GUID}
Endpoints = ncacn_ip_tcp,0,port

Remarks
This is a REG_MULTI_SZ value.
The port value is a number between 1024 and 65535 that specifies the TCP port number that your COM
application will use for DCOM communications. If you do not specify this registry key, port numbers for DCOM
communications are dynamically assigned. In most scenarios, you might prefer to leave this registry key undefined
and allow DCOM to dynamically assign port numbers.
LaunchPermission
1/7/2020 • 2 minutes to read • Edit Online

Describes the Access Control List (ACL ) of the principals that can start new servers for this class. This value may
be added under any AppID key to limit activation by remote clients of specific classes.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\AppID
{AppID_GUID}
LaunchPermission = ACL

Remarks
This is a REG_BINARY value. Upon receiving a local or remote request to launch the server of this class, the ACL
described by this value is checked while impersonating the client, and its success either allows or disallows the
launching of the server. If this value does not exist, the DefaultLaunchPermission value is checked in the same
way to determine whether the class code can be launched.

Related topics
C
o
I
n
i
t
i
a
l
i
z
e
S
e
c
u
r
i
t
y

D
e
f
a
u
l
t
L
a
u
n
c
h
P
e
r
m
i
s
s
i
o
n

S
e
c
u
r
i
t
y
i
n
C
O
M
LoadUserSettings
1/7/2020 • 2 minutes to read • Edit Online

Determines whether COM will load the user profile for COM servers running as the launching user application
identity.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\AppID
{AppID_GUID}
LoadUserSettings = value

Remarks
This is a REG_DWORD value. If value is nonzero, COM loads the profile of the user account with which it launches
the COM server. If value is zero or not present, COM will not load the profile of the user account with which it
launches the COM server.
This setting is ignored if a RunAs entry is present.
LocalService
1/7/2020 • 2 minutes to read • Edit Online

Installs an object as a service application.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\AppID
{AppID_GUID}
LocalService = name

Remarks
In addition to running as a local server executable (EXE ), a COM object may also choose to package itself to run
as a service application when activated by a local or remote client. Services support numerous useful and UI-
integrated administrative features, including local and remote starting, stopping, pausing, and restarting, as well
as the ability to establish the server to run under a specific user account and window station.
An object written as a service is installed for use by COM by establishing a LocalService value and performing a
standard service installation. The LocalService value must be set to the service name, as configured in
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services, as the default REG_SZ value.
When LocalService is set, any string assigned to ServiceParameters is passed as a command-line argument to
the service as it is being launched.
The service configuration is preferred in many situations where the capabilities of the local and remote service
management APIs and user interface might be useful for the services that the object provides. For example,
leveraging the existing administrative framework of the service architecture should be an obvious choice if the
object is long-lived or readily supports concepts such as starting, stopping, resetting, or pausing.
Services can be dynamically configured and can be configured to run automatically when the machine boots, or to
be launched when requested by a client application.
If you are implementing classes as services, you should be aware of the following points:
This value is used in preference to the LocalServer32 key for local and remote activation requests—if
LocalService exists and refers to a valid service, the LocalServer32 key is ignored.
Currently, only a single instance of a service application may be running at a given time on a computer. COM
services must therefore register their class objects on launch using REGCLS_MULTIPLEUSE to support
multiple clients.
To launch and initialize properly, COM services configured to run automatically when a machine boots must
include RPCSS in their list of dependent services.

Related topics
R
e
g
i
s
t
e
r
i
n
g
C
O
M
S
e
r
v
e
r
s

S
e
r
v
i
c
e
P
a
r
a
m
e
t
e
r
s

S
e
r
v
i
c
e
s
PreferredServerBitness
1/7/2020 • 2 minutes to read • Edit Online

Sets the preferred architecture, 32-bit or 64-bit, for this COM server.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\AppID
{AppID_GUID}
PreferredServerBitness = value

Remarks
This is a REG_DWORD value that is available only on 64-bit versions of Windows.

VALUE DESCRIPTION

1 Match the server architecture to the client architecture. For


example, if the client is 32-bit, use a 32-bit version of the
server, if it is available. If not, the client's activation request will
fail.

2 Use a 32-bit version of the server. If one does not exist, the
client's activation request will fail.

3 Use a 64-bit version of the server. If one does not exist, the
client's activation request will fail.

If this value is not present, then:


If the computer that hosts the server is running Windows XP or Windows Server 2003 without SP1 or later
installed, then COM will prefer a 64-bit version of the server if available; otherwise it will activate a 32-bit
version of the server.
If the computer that hosts the server is running Windows Server 2003 with SP1 or later installed, then COM
will try to match the server architecture to the client architecture. In other words, for a 32-bit client, COM will
activate a 32-bit server if available; otherwise it will activate a 64-bit version of the server. For a 64-bit client,
COM will activate a 64-bit server if available; otherwise it will activate a 32-bit server.
The client can also specify its own architecture preference via the CLSCTX_ACTIVATE_32_BIT_SERVER and
CLSCTX_ACTIVATE_64_BIT_SERVER flags, and these will override the server's preference. For more information,
and a chart of possible interactions between client and server architecture preferences, see CLSCTX.

Related topics
C
L
S
C
T
X
RemoteServerName
1/7/2020 • 2 minutes to read • Edit Online

Configures the client to request the object be run at a particular computer whenever an activation function is
called for which a COSERVERINFO structure is not specified.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\AppID
{AppID_GUID}
RemoteServerName = name

Remarks
RemoteServerName allows simple configuration management of client applications; they may be written
without hard-coded server names and can be configured by modifying the RemoteServerName registry values
of the classes of objects they use.
As described in the documentation for the CLSCTX enumeration and the COSERVERINFO structure, one of the
parameters of the distributed COM activation is a pointer to a COSERVERINFO structure. When this value is not
NULL, the information in the COSERVERINFO structure overrides the setting of the RemoteServerName key
for the function call.

Related topics
R
e
g
i
s
t
e
r
i
n
g
C
O
M
S
e
r
v
e
r
s
ROTFlags
1/7/2020 • 2 minutes to read • Edit Online

Controls the registration of a COM server in the running object table (ROT).

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\AppID
{AppID_GUID}
ROTFlags = flags

Remarks
This is a REG_DWORD value.

FLAG VALUE CONSTANT

0x1 ROTREGFLAGS_ALLOWANYCLIENT

ROTREGFLAGS_ALLOWANYCLIENT Description
If a COM server wants to register in the ROT and allow any client to access the registration, it must use the
ROTFLAGS_ALLOWANYCLIENT flag. An "Activate As Activator" COM server cannot specify
ROTFLAGS_ALLOWANYCLIENT because the DCOM service control manager (DCOMSCM ) enforces a spoof
check against this flag. Therefore, in Windows Vista and later, COM adds support for the ROTFlags registry entry
that allows the server to stipulate that its ROT registrations be made available to any client.
The entry must exist in the HKEY_LOCAL_MACHINE hive. This entry provides an "Activate As Activator" server
with the same functionality that ROTFLAGS_ALLOWANYCLIENT provides for a RunAs server.

Related topics
A
p
p
I
D
K
e
y

R
e
g
i
s
t
e
r
i
n
g
C
O
M
S
e
r
v
e
r
s

S
e
c
u
r
i
t
y
i
n
C
O
M
RunAs
1/7/2020 • 2 minutes to read • Edit Online

Configures a class to run under a specific user account when activated by a remote client without being written as
a service application.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\AppID
{AppID_GUID}
RunAs = value

Remarks
The value specifies the user name and must be either of the form UserName, Domain**\**UserName or of the
string "Interactive User". You can also specify the strings "nt authority\localservice" (for Local Service) and "nt
authority\networkservice" (for Network Service). You can also specify the string "nt authority\system" when
{AppID_GUID} refers to a COM server that is already started or that has an entry in the class table. However, you
cannot use "nt authority\system" with a COM server that is not already started. The default password for "nt
authority\localservice", "nt authority\networkservice", and "nt authority\system" is "" (empty string).

NOTE
As of Windows Vista, an empty password is no longer required to configure the "nt authority\localservice", "nt
authority\networkservice" and "nt authority\system" RunAs settings.

Classes configured to run as a particular user may not be registered under any other identity, so calls to
CoRegisterClassObject with this CLSID fail unless the process was launched by COM on behalf of an actual
activation request.
The user-name is taken from the RunAs value under the class's AppID key. If the user name is "Interactive User",
the server is run in the identity of the user currently logged on and is connected to the interactive desktop.
Otherwise, the password is retrieved from a portion of the registry that is available only to administrators of the
computer and to the system. The user-name and password are then used to create a logon session in which the
server is run. When launched in this way, the user runs with its own desktop and window station and does not
share window -handles, the clipboard, or other UI elements with the interactive user or other user running in other
user accounts.
To establish a password for a RunAs class, you must use the DCOMCNFG administrative tool installed in the
system directory.
For RunAs identities used by DCOM servers, the user account specified in the value must have the rights to log
on as a batch job. This right can be added using Local Security Policy administrative tool. Go to Local Policies
and open User Rights Assignment. Select Log on as a batch job, and add the user account.
The RunAs value is not used for servers configured to be run as services. COM services that need to run under an
identity other than LocalSystem should set the appropriate user name and password using the services control
panel applet or the service controller functions. (For more information about these functions, see Services.)

NOTE
As of Microsoft Windows Server 2003, the class AppID is explicitly read from
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\AppID, which, unlike most registry keys, is not interchangeable with
HKEY_CLASSES_ROOT\AppID.

Related topics
R
e
g
i
s
t
e
r
i
n
g
C
O
M
S
e
r
v
e
r
s
ServiceParameters
1/7/2020 • 2 minutes to read • Edit Online

Specifies the command-line parameters to be passed to an object installed for use by COM through the
LocalService registry value.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\AppID
{AppID_GUID}
ServiceParameters = parameter

Remarks
This is a REG_SZ value. This string is passed to the service as a command-line argument as it is being launched.

Related topics
L
o
c
a
l
S
e
r
v
i
c
e

R
e
g
i
s
t
e
r
i
n
g
C
O
M
S
e
r
v
e
r
s
SRPTrustLevel
1/7/2020 • 2 minutes to read • Edit Online

Sets the software restriction policy (SRP ) trust level for applications.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\AppID
{AppID_GUID}
SRPTrustLevel = value

Remarks
This is a REG_DWORD value that is available starting with Windows XP.

VALUE DESCRIPTION

0x0 (SAFER_LEVELID_DISALLOWED) The application is disallowed from accessing and security-


sensitive user privileges.

0x40000 (SAFE_LEVELID_FULLYTRUSTED) The application has unrestricted access to the user's privileges.

If the SRPTrustLevel value does not exist, the default value of SAFER_LEVELID_DISALLOWED is used. If
SRPTrustLevel is of the wrong type or out of range, COM returns the error COMADMIN_E_SAFERINVALID. If
an activation of any sort fails because of SRP trust checks, COM returns the error CO_E_ACTIVATIONFAILED.

Related topics
S
e
c
u
r
i
t
y
i
n
C
O
M

S
R
P
A
c
t
i
v
a
t
e
A
s
A
c
t
i
v
a
t
o
r
C
h
e
c
k
s

S
R
P
R
u
n
n
i
n
g
O
b
j
e
c
t
C
h
e
c
k
s
CLSID Key
1/7/2020 • 2 minutes to read • Edit Online

A CLSID is a globally unique identifier that identifies a COM class object. If your server or container allows linking
to its embedded objects, you need to register a CLSID for each supported class of objects.

Registry Key
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{CLSID }

REGISTRY KEY DESCRIPTION

AppID Associates an AppID with a CLSID.

AutoConvertTo Specifies the automatic conversion of a given class of objects


to a new class of objects.

AutoTreatAs Automatically sets the CLSID for the TreatAs key to the
specified value.

AuxUserType Specifies an application's short display name and application


names.

Control Identifies an object as an ActiveX Control.

Conversion Used by the Convert dialog box to determine the formats an


application can read and write.

DataFormats Specifies the default and main data formats supported by an


application.

DefaultIcon Provides default icon information for iconic presentations of


objects.

InprocHandler Specifies whether an application uses a custom handler.

InprocHandler32 Specifies whether an application uses a custom handler.

InprocServer Specifies the path to the in-process server DLL.

InprocServer32 Registers a 32-bit in-process server and specifies the


threading model of the apartment the server can run in.

Insertable Indicates that objects of this class should appear in the Insert
Object dialog box list box when used by COM container
applications.

Interface An optional entry that specifies all interface IDs (IIDs)


supported by the associated class.

LocalServer Specifies the full path to a 16-bit local server application.


REGISTRY KEY DESCRIPTION

LocalServer32 Specifies the full path to a 32-bit local server application.

MiscStatus Specifies how to create and display an object.

ProgID Associates a ProgID with a CLSID.

ToolBoxBitmap32 Identifies the module name and resource ID for a 16 x 16


bitmap to use for the face of a toolbar or toolbox button.

TreatAs Specifies the CLSID of a class that can emulate the current
class.

Verb Specifies the verbs to be registered for an application.

Version Specifies the version number of the control.

VersionIndependentProgID Associates a ProgID with a CLSID. This value is used to


determine the latest version of an object application.

Remarks
The HKEY_LOCAL_MACHINE\SOFTWARE\Classes key corresponds to the HKEY_CLASSES_ROOT key,
which was retained for compatibility with earlier versions of COM.
The CLSID key contains information used by the default COM handler to return information about a class when it
is in the running state.
To obtain a CLSID for your application, you can use the Uuidgen.exe, or use the CoCreateGuid function.
The CLSID is a 128-bit number, in hex, within a pair of curly braces.

Related topics
C
o
C
r
e
a
t
e
G
u
i
d
AppID
1/7/2020 • 2 minutes to read • Edit Online

Associates an AppID with a CLSID.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID
{CLSID}
AppID = {AppID_GUID}

Remarks
This is a REG_SZ value.

Related topics
A
p
p
I
D
K
e
y
AutoConvertTo
1/7/2020 • 2 minutes to read • Edit Online

Specifies the automatic conversion of a given class of objects to a new class of objects.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID
{CLSID}
AutoConvertTo = value

Remarks
This is a REG_SZ value that specifies the class identifier of the object to which the given object or class of objects
should be converted.
This key is typically used to automatically convert files created by an older version of an application to a newer
version of the application.

Related topics
O
l
e
D
o
A
u
t
o
C
o
n
v
e
r
t

O
l
e
G
e
t
A
u
t
o
C
o
n
v
e
r
t

O
l
e
S
e
t
A
u
t
o
C
o
n
v
e
r
t
AutoTreatAs
1/7/2020 • 2 minutes to read • Edit Online

Automatically sets the CLSID for the TreatAs key to the specified value.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID
{CLSID}
AutoTreatAs = value

Remarks
This is a REG_SZ value that specifies the class identifier.

Related topics
C
o
T
r
e
a
t
A
s
C
l
a
s
s
AuxUserType
1/7/2020 • 2 minutes to read • Edit Online

Specifies an application's short display name and application names.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID
{CLSID}
AuxUserType
2 = ShortDisplayName
3 = ApplicationName

Remarks
The recommended maximum length for ShortDisplayName is 15 characters. This name is used in menus, including
pop-up menus.
ApplicationName should contain the actual name of the application (such as "Acme Draw 2.0"). This name is used
in the Results field of the Paste Special dialog box.

Related topics
I
O
l
e
O
b
j
e
c
t
:
:
G
e
t
U
s
e
r
T
y
p
e
Control
1/7/2020 • 2 minutes to read • Edit Online

Identifies an object as an ActiveX Control.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID
{CLSID}
Control

Remarks
This optional entry is used by containers to fill in dialog boxes. The container uses this subkey to determine
whether to include an object in a dialog box that displays ActiveX Controls. A control can omit this entry if it is
designed to work only with a specific container and therefore does is not intended to be inserted in other
containers.
Conversion
1/7/2020 • 2 minutes to read • Edit Online

Used by the Convert dialog box to determine the formats an application can read and write.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID
{CLSID}
Conversion
Readable
Main = rformat, ...
ReadWritable
Main = rwformat, ...

Remarks
Conversion information is used by the Convert dialog box to determine what formats an application can read and
write. A comma-delimited file format is indicated by a number if it is one of the Clipboard formats defined in
Windows.h. A string indicates the format is not one defined in Windows.h (private). In this case, the readable and
writable format is CF_OUTLINE (private).
The rformat value specifies the file format an application can read (convert from).
The rwformat value specifies the file format an application can read and write (activate as).
DataFormats
1/7/2020 • 2 minutes to read • Edit Online

Specifies the default and main data formats supported by an application.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID
{CLSID}
DataFormats
DefaultFile = file/format
GetSet
n = formats

Remarks
The file/format value specifies the default main file or object format for objects of this class.
The formats value specifies a list of formats for default implementations of EnumFormatEtc, where n is a zero-
based integer index. For example, n = format, aspect, medium, flag, where format is a clipboard format, aspect is
one or more members of DVASPECT, medium is one or more members of TYMED, and flag is one or more
members of DATADIR.

Related topics
I
D
a
t
a
O
b
j
e
c
t
:
:
E
n
u
m
F
o
r
m
a
t
E
t
c

I
D
a
t
a
O
b
j
e
c
t
:
:
G
e
t
D
a
t
a

I
D
a
t
a
O
b
j
e
c
t
:
:
S
e
t
D
a
t
a
DefaultIcon
1/7/2020 • 2 minutes to read • Edit Online

Provides default icon information for iconic presentations of objects.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID
{CLSID}
DefaultIcon = path, resourceID

Remarks
This is a REG_SZ value that specifies the full path to the executable name of the object application and the
resource index of the icon within the executable.
DefaultIcon identifies the icon to use when, for example, a control is minimized to an icon. This entry contains the
full path to the executable name of the server application and the resource index of the icon within the executable.
Applications can use the information provided by DefaultIcon to obtain an icon handle with ExtractIcon.
InprocHandler
1/7/2020 • 2 minutes to read • Edit Online

Specifies whether an application uses a custom handler.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID
{CLSID}
InprocHandler = handler.dll

Remarks
This is a REG_SZ value that specifies the custom handler used by the application. If a custom handler is not used,
the entry should be set to Ole32.dll.
If a container is searching the registry for a custom handler, the 16-bit version has priority with a 16-bit container
and the 32-bit version has priority with a 32-bit container.

Related topics
I
n
p
r
o
c
H
a
n
d
l
e
r
3
2
InprocHandler32
1/7/2020 • 2 minutes to read • Edit Online

Specifies whether an application uses a custom handler.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID
{CLSID}
InprocHandler32 = handler.dll

Remarks
This is a REG_SZ value that specifies the custom handler used by the application. If a custom handler is not used,
the entry should be set to Ole32.dll.
If a container is searching the registry for a custom handler, the 16-bit version has priority with a 16-bit container
and the 32-bit version has priority with a 32-bit container.

Related topics
I
n
p
r
o
c
H
a
n
d
l
e
r
InprocServer
1/7/2020 • 2 minutes to read • Edit Online

Specifies the path to the in-process server DLL.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID
{CLSID}
InprocServer
(Default) = path

Remarks
The InprocServer entry is relatively rare for insertable classes.
In-process servers are currently registered using the InprocServer registry entry. The 32-bit and 64-bit in-
process servers should use the InprocServer32 entry. If a container is searching the registry for an in-process
server, the 16-bit version has priority with a 16-bit container and 32-bit version has priority with a 32-bit container.

Related topics
I
n
p
r
o
c
S
e
r
v
e
r
3
2
InprocServer32
1/7/2020 • 2 minutes to read • Edit Online

Registers a 32-bit in-process server and specifies the threading model of the apartment the server can run in.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID
{CLSID}
InprocServer32
(Default) = path
ThreadingModel = value

Remarks
ThreadingModel is a REG_SZ value the specifies the threading model. The possible values are shown in the
following table.

VALUE DESCRIPTION

Apartment Single-threaded apartment

Both Single-threaded or multithreaded apartment

Free Multithreaded apartment

Neutral Neutral apartment

You must use the same value for every object provided by the in-process server.
If ThreadingModel is not present or is not set to a value, the server is loaded into the first apartment that was
initialized in the process. This apartment is sometimes referred to as the main single-threaded apartment (STA).
If the first STA in a process is initialized by COM, rather than by an explicit call to CoInitialize or
CoInitializeEx, it is called the host STA. For example, COM creates a host STA if an in-process server to be
loaded requires an STA but there is currently no STA in the process.
Whenever possible, the in-process server is loaded in the same apartment as the client that loads it. If the
threading model of the client apartment is not compatible with the model specified, the server is loaded as
indicated in the following table.

THREADING MODEL OF SERVER APARTMENT SERVER IS RUN IN

Main STA

Both Same apartment as client

Free Multithreaded apartment


THREADING MODEL OF SERVER APARTMENT SERVER IS RUN IN

Neutral Neutral apartment

If the threading model of the server is Apartment, the apartment the server is loaded in depends on the
apartment the client is running in, as indicated in the following table.

APARTMENT CLIENT IS RUN IN APARTMENT SERVER IS RUN IN

Multithreaded Host STA

Neutral (on STA thread) Same apartment as client

Neutral (on MTA thread) Host STA

COM can also create a host multithreaded apartment (MTA). If a client in a single-threaded apartment requests
an in-process server whose threading model is Free when there is no MTA in the process, COM creates a host
MTA and loads the server into it.
For a 32-bit in-process server, the InprocHandler32, InprocServer, InprocServer32, and Insertable keys
must be registered. The InprocServer entry is needed only for backward compatibility. If it is missing, the class
still works but it cannot be loaded in 16-bit applications.
If a container is searching the registry for an in-process server, the 16-bit version has priority with a 16-bit
container and the 32-bit version has priority with a 32-bit container.

Related topics
I
n
p
r
o
c
S
e
r
v
e
r
Insertable
1/7/2020 • 2 minutes to read • Edit Online

Indicates that objects of this class should appear in the Insert Object dialog box list box when used by COM
container applications.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID
{CLSID}
Insertable

Remarks
This key is a required entry for 32-bit COM applications whose objects can be inserted into existing 16-bit
applications. Existing 16-bit applications look in the registry for this key, which informs the application that the
server supports embeddings. If the Insertable key exists, 16-bit applications may also attempt to verify that the
server exists on the machine. 16-bit applications typically retrieve the value of the LocalServer key from the class
and check to see whether it is a valid file on the system. Therefore, for a 32-bit application to be insertable by a 16-
bit application, the 32-bit application should register the LocalServer subkey in addition to registering
LocalServer32.
Used with controls, this entry indicates that an object can act only as an in-place embedded object with no special
control features. Objects that have this key appear in the Insert Object dialog box for their container. When used
with controls, this entry also indicates the control has been tested with non-control containers. This entry is also
optional and can be omitted when a control is not designed to work with older containers that do not understand
controls.

NOTE
This key is not present for internal classes like the moniker classes.

Related topics
Interface
1/7/2020 • 2 minutes to read • Edit Online

An optional entry that specifies all interface IDs (IIDs) supported by the associated class.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID
{CLSID}
Interface
{IID1} = name1
{IID2} = name2
...

Remarks
If an interface name is not present in this list, the interface can never be supported by an instance of this class.

Related topics
I
n
t
e
r
f
a
c
e
K
e
y
LocalServer
1/7/2020 • 2 minutes to read • Edit Online

Specifies the full path to a 16-bit local server application.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID
{CLSID}
LocalServer = path

Remarks
This is a REG_SZ value that specifies the full path and can include any command-line arguments.
COM appends the "-Embedding" flag to the string, so the application that uses flags must parse the whole string
and check for the -Embedding flag.
To run a COM object server in a separate memory space, change the value of LocalServer as follows:
cmd /c start /separate path**.exe**

Related topics
L
o
c
a
l
S
e
r
v
e
r
3
2
LocalServer32
1/7/2020 • 2 minutes to read • Edit Online

Specifies the full path to a 32-bit local server application.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID
{CLSID}
LocalServer32
(Default) = path
ServerExecutable = path

Remarks
The ServerExecutable value, which is of type REG_SZ and is supported starting with Windows Server 2003,
works in conjunction with the LocalServer32 subkey to prevent any ambiguity when using the CreateProcess
function. LocalServer32 specifies the location of the COM server application to launch, and this information is
passed as the first parameter lpApplicationName for CreateProcess. Depending on the implementation of
CreateProcess, this information might be ambiguous. For this reason, if ServerExecutable is specified, COM
passes the ServerExecutable named value to the lpApplicationName parameter of CreateProcess. If
ServerExecutable is not specified, COM passes NULL as the value for the first parameter of CreateProcess.
To help provide system security, use quoted strings in the path to indicate where the executable filename ends
and the arguments begin. For example, instead of specifying the following path as the LocalServer32 entry:
"C:\Program Files\Company Files\Application.exe param1 param2"
specify the path using the following syntax:
"\"C:\Program Files\Company Files\Application.exe\" param1 param2"
COM appends the "-Embedding" flag to the string, so the application that uses flags needs to parse the whole
string and check for the -Embedding flag.
When COM starts a 32-bit local server, the server must register a class object within an elapsed time set by the
user. By default, the elapsed time value must be at least 5 minutes, in milliseconds, but cannot exceed the number
of milliseconds in 30 days. Applications typically should not set this value, which is in the
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\COM2\ServerStartElapsedTime entry.
The required entries for 32-bit local servers are InprocHandler32, LocalServer, LocalServer32, and
Insertable.
If a container is searching the registry for a local server, a 32-bit local server has priority over a 16-bit local
server.
If you are implementing classes as services, you should be aware that the LocalService named value is used in
preference to the LocalServer32 key for local and remote activation requests—if LocalService exists and
refers to a valid service, the LocalServer32 key is ignored.

Related topics
L
o
c
a
l
S
e
r
v
e
r

L
o
c
a
l
S
e
r
v
i
c
e
MiscStatus
1/7/2020 • 2 minutes to read • Edit Online

Specifies how to create and display an object.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID
{CLSID}
MiscStatus
(Default) = value
aspect = value

Remarks
For more information, see the OLEMISC enumeration and IOleObject::GetMiscStatus.
If no subkey that corresponds to a DVASPECT is found, the default value of MiscStatus is used.

Related topics
I
O
l
e
O
b
j
e
c
t
:
:
G
e
t
M
i
s
c
S
t
a
t
u
s
ProgID
1/7/2020 • 2 minutes to read • Edit Online

Associates a ProgID with a CLSID.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID
{CLSID}
ProgID = value

Remarks
Every insertable object class has a ProgID. For information on creating a ProgID, see the key.

Related topics
k
e
y

V
e
r
s
i
o
n
I
n
d
e
p
e
n
d
e
n
t
P
r
o
g
I
D
ToolBoxBitmap32
1/7/2020 • 2 minutes to read • Edit Online

Identifies the module name and resource ID for a 16 x 16 bitmap to use for the face of a toolbar or toolbox button.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID
{CLSID}
ToolBoxBitmap32 = filename, resourceID

Remarks
This is a REG_SZ value that specifies the module name and resource identifier for the bitmap.
The standard Windows icon size is too large to be used for this purpose. This requires control containers that have
a design mode in which one selects controls and places them on a form being designed.
TreatAs
1/7/2020 • 2 minutes to read • Edit Online

Specifies the CLSID of a class that can emulate the current class.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID
{CLSID}
TreatAs = {CLSID_TreatAs}

Remarks
This is a REG_SZ value.
Emulation is the ability of one application to open and edit an object of a different class, while retaining the
original format of the object. Resolution occurs on the local computer, so in remote activation case, resolution
occurs on the client computer using the CLSID specified by TreatAs.
DCOM looks at the local registry for TreatAs, even if you call the CoCreateInstance function and specify a
remote server. This means that if you have a TreatAs entry for Class1 to be treated as Class2 on your local
computer, but you call CoCreateInstance to create an instance of Class1 and you specify a remote server, DCOM
will try to create an instance of Class2 on the remote server, even if Class2 is not registered on the remote server,
which will cause the call to CoCreateInstance to fail.

Related topics
A
u
t
o
T
r
e
a
t
A
s

C
o
G
e
t
T
r
e
a
t
A
s
C
l
a
s
s

C
o
T
r
e
a
t
A
s
C
l
a
s
s
Verb
1/7/2020 • 2 minutes to read • Edit Online

Specifies the verbs to be registered for an application.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID
{CLSID}
Verb
1 = verb1
2 = verb2
3 = ...

Remarks
Each verb is a REG_SZ value of the form "name, menu_flag, verb_flag". Verbs must be numbered consecutively.
The name describes how the verb is appended by an AppendMenu function call. For example, "&Play".
The menu_flag value indicates how the verb should appear in the menu. All flags supported by AppendMenu are
supported, except for MF_BITMAP, MF_OWNERDRAW, and MF_POPUP.
The verb_flag value describes attributes of the verbs. Use one of the values from OLEVERBATTRIB, or 0.
For more information, see OLEVERB, IOleObject::DoVerb, and IOleObject::EnumVerbs.

Related topics
A
p
p
e
n
d
M
e
n
u

O
L
E
V
E
R
B

O
L
E
V
E
R
B
A
T
T
R
I
B
Version
1/7/2020 • 2 minutes to read • Edit Online

Specifies the version number of the control.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID
{CLSID}
Version = value

Remarks
This is a REG_SZ value.
The version number should match the version of the type library associated with the control.
VersionIndependentProgID
1/7/2020 • 2 minutes to read • Edit Online

Associates a ProgID with a CLSID. This value is used to determine the latest version of an object application.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID
{CLSID}
VersionIndependentProgID = Program.Component

Remarks
This is a REG_SZ value that specifies the latest version of the object application.
The version-independent ProgID is stored and maintained solely by application code. When given the version-
independent ProgID, the CLSIDFromProgID function returns the CLSID of the current version.
You can use CLSIDFromProgID and ProgIDFromCLSID to convert between these two representations.
<file_extension> Key
1/7/2020 • 2 minutes to read • Edit Online

Associates a file name extension with a ProgID.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Classes
.ext = ProgID

Remarks
The information contained in the file name extension key is used by both the Windows Explorer and file monikers.
GetClassFile uses the file name extension key to supply the associated CLSID.
The HKEY_LOCAL_MACHINE\SOFTWARE\Classes key corresponds to the HKEY_CLASSES_ROOT key,
which was retained for compatibility with earlier versions of COM.

Related topics
F
i
l
e
T
y
p
e

G
e
t
C
l
a
s
s
F
i
l
e
FileType Key
1/7/2020 • 2 minutes to read • Edit Online

Used by GetClassFile to match patterns against various file bytes in a non-compound file.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\FileType
{CLSID}
n = offset, cb, mask, value

o
f
f
s
e
t

Determines how far from the beginning or end of the file to begin the comparison. If the offset is a negative
value, the comparison begins from the end of the file minus the offset value. The offset value is a decimal
type unless preceded by "0x".

c
b

Represents the length in bytes from the beginning to the end of the file. Represents the byte range in the file.
The cb value is a decimal unless preceded by "0x".

m
a
s
k

A binary value used for masking, which is performed by using a logical AND operation, and the byte range
specified by offset and cb. If this value is omitted, the bytes are set to all ones. This value is always
hexadecimal.

v
a
l
u
e

Represents the pattern that must match for a file to be of this file type. The pattern is used to properly
identify a known file format from its contents, not by its extension.

Remarks
Entries are used by the GetClassFile function to match patterns against various file bytes in a non-compound file.
FileType has CLSID subkeys, each of which has a series of subkeys 0, 1, 2, 3. These values contain patterns that, if
one matches, yield the indicated CLSID. For example, a value of "0, 4, FFFFFFFF, ABCD1234" indicates that the
first 4 bytes must be ABCD1234, in that order. A value of "-4, 4, FEFEFEFE " indicates that the last four bytes in the
file must be FEFEFEFE. If either pattern matches, the CLSID is returned.
The HKEY_LOCAL_MACHINE\SOFTWARE\Classes key corresponds to the HKEY_CLASSES_ROOT key,
which was retained for compatibility with earlier versions of COM.

Related topics
<
f
i
l
e
_
e
x
t
e
n
s
i
o
n
>

G
e
t
C
l
a
s
s
F
i
l
e
Interface Key
1/7/2020 • 2 minutes to read • Edit Online

Registers new interfaces by associating an interface name with an interface ID (IID ). There must be one IID
subkey for each new interface.

Registry Key
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Interface\{IID }

REGISTRY VALUE DESCRIPTION

BaseInterface Identifies the interface from which the current interface is


derived.

NumMethods Contains the number of methods in the associated interface,


including methods from derived interfaces.

ProxyStubClsid Maps an IID to a CLSID in 16-bit proxy DLLs.

ProxyStubClsid32 Maps an IID to a CLSID in 32-bit proxy DLLs.

Remarks
The HKEY_LOCAL_MACHINE\SOFTWARE\Classes key corresponds to the HKEY_CLASSES_ROOT key,
which was retained for compatibility with earlier versions of COM.

Related topics
I
n
t
e
r
f
a
c
e
BaseInterface
1/7/2020 • 2 minutes to read • Edit Online

Identifies the interface from which the current interface is derived.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Interface
{IID}
BaseInterface = name

Remarks
This is a REG_SZ value.

Related topics
I
n
t
e
r
f
a
c
e
NumMethods
1/7/2020 • 2 minutes to read • Edit Online

Contains the number of methods in the associated interface, including methods from derived interfaces.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Interface
{IID}
NumMethods = value

Remarks
This is a REG_SZ value.

Related topics
I
n
t
e
r
f
a
c
e
ProxyStubClsid
1/7/2020 • 2 minutes to read • Edit Online

Maps an IID to a CLSID in 16-bit proxy DLLs.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Interface
{IID}
ProxyStubClsid = {CLSID}

Remarks
This is a REG_SZ value that specifies the CLSID for the IID.
If you add interfaces, you must use this entry to register them (16-bit systems) so that OLE can find the
appropriate remoting code to establish interprocess communication.

Related topics
I
n
t
e
r
f
a
c
e

P
r
o
x
y
S
t
u
b
C
l
s
i
d
3
2
ProxyStubClsid32
1/7/2020 • 2 minutes to read • Edit Online

Maps an IID to a CLSID in 32-bit proxy DLLs.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Interface
{IID}
ProxyStubClsid32 = {CLSID}

Remarks
This is a REG_SZ value that specifies the CLSID for the IID.
This is a required entry since the IID -to-CLSID mapping may be different for 16-bit and 32-bit interfaces. The IID -
to-CLSID mapping depends on the way the interface proxies are packaged into a set of proxy DLLs.
If you add interfaces, you must use this entry to register them (32-bit systems) so that OLE can find the
appropriate remoting code to establish interprocess communication.

Related topics
I
M
a
r
s
h
a
l

I
n
t
e
r
f
a
c
e

P
r
o
x
y
S
t
u
b
C
l
s
i
d
Key
1/7/2020 • 2 minutes to read • Edit Online

A programmatic identifier (ProgID ) is a registry entry that can be associated with a CLSID. Like the CLSID, the
ProgID identifies a class but with less precision because it is not guaranteed to be globally unique.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\{ProgID }

REGISTRY KEY DESCRIPTION

CLSID Associates a ProgID with a CLSID.

Insertable Indicates that this class is insertable in OLE 2 containers.

Protocol Indicates that this OLE 2 class is insertable in OLE 1


containers.

Shell Provides Windows 3.1 shell printing and File Open


information.

Remarks
You can use a ProgID in programming situations where it is not possible to use a CLSID. ProgIDs should not
appear in the user interface. ProgIDs are not guaranteed to be unique, so they can be used only where name
collisions are manageable.
The format of a ProgID is <Program>.<Component>.<Version>, separated by periods and with no spaces, as in
Word.Document.6. The ProgID must comply with the following requirements:
Have no more than 39 characters.
Contain no punctuation (including underscores) except one or more periods.
Not start with a digit.
Be different from the class name of any OLE 1 application, including the OLE 1 version of the same
application, if there is one.
Because the ProgID should not appear in the user interface, you can obtain a displayable name by calling
IOleObject::GetUserType. Also, see OleRegGetUserType.
The HKEY_LOCAL_MACHINE\SOFTWARE\Classes key corresponds to the HKEY_CLASSES_ROOT key,
which was retained for compatibility with earlier versions of COM.

Related topics
I
O
l
e
O
b
j
e
c
t
:
:
G
e
t
U
s
e
r
T
y
p
e

O
l
e
R
e
g
G
e
t
U
s
e
r
T
y
p
e
CLSID
1/7/2020 • 2 minutes to read • Edit Online

Associates a ProgID with a CLSID.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Classes
{ProgID}
CLSID = CLSID

Remarks
This is a REG_SZ value that specifies the object's CLSID.
Insertable
1/7/2020 • 2 minutes to read • Edit Online

Indicates that this class is insertable in OLE 2 containers.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Classes
{ProgID}
Insertable

Remarks
This is a required entry for objects that are insertable in OLE 2 containers.
Protocol
1/7/2020 • 2 minutes to read • Edit Online

Indicates that this OLE 2 class is insertable in OLE 1 containers.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Classes
{ProgID}
Protocol
StdFileEditing
Server = path
Verb
0 = verb1
1 = verb2
...

Remarks
The StdFileEditing entry specifies OLE 1 compatibility information. It should be present only if objects of this
class are insertable in OLE 1 containers.
Server specifies the full path to the OLE 2 server application and Verb specifies the verbs. Verb 0 is the primary
verb and additional verbs must be numbered consecutively.
Shell
1/7/2020 • 2 minutes to read • Edit Online

Provides Windows 3.1 shell printing and File Open information.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Classes
{ProgID}
Shell
Open
command = path %1
Print
command = path %1

Remarks
These entries should provide the path and file name of the application.
Key
1/7/2020 • 2 minutes to read • Edit Online

Associates a ProgID with a CLSID. This key is used to determine the latest version of an object application.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Classes
<version-independent ProgID>
CurVer = ProgID

Remarks
The HKEY_LOCAL_MACHINE\SOFTWARE\Classes key corresponds to the HKEY_CLASSES_ROOT key,
which was retained for compatibility with earlier versions of COM.
The format for <version-independent ProgID> is <program>.<component>, separated by periods, no spaces, and
no version number. The version-independent ProgID, like the ProgID, can be registered with a human-readable
name.
ProgID is the ProgID of the latest installed version of the class.
Applications must register a version-independent programmatic identifier under the version-independent ProgID
key. The version-independent ProgID refers to the application's class and does not change from version to version,
instead remaining constant across all versions—for example, Microsoft Word Document. It is used with macro
languages and refers to the currently installed version of the application's class. The version-independent ProgID
must correspond to the name of the latest version of the object application.
For example, the version-independent ProgID is used when a container application creates a chart or table with a
toolbar button. In this situation, the application can use the version-independent ProgID to determine the latest
version of the needed object application.
The version-independent ProgID is stored and maintained solely by application code. When given the version-
independent ProgID, the CLSIDFromProgID function returns the CLSID of the current version.
You can use CLSIDFromProgID and ProgIDFromCLSID to convert between these two representations.
You can use IOleObject::GetUserType or OleRegGetUserType to change the identifier to a displayable string.
If a custom handler is not used, the entry should be set to OLE32.DLL, as shown in the following example:

HKEY_CLASSES_ROOT\CLSID\{00000402-0000-0000-C000-000000000046}
InprocHandler = ole32.dll

Related topics
C
L
S
I
D
F
r
o
m
P
r
o
g
I
D

P
r
o
g
I
D
F
r
o
m
C
L
S
I
D

K
e
y
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Ole
1/7/2020 • 2 minutes to read • Edit Online

The registry values associated with the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Ole key control the
default launch and access permission settings and call-level security capabilities for COM -based applications that
do not call CoInitializeSecurity.
Only administrators, the object creator, and the system have full access to this portion of the registry. All other
users have read-only access.

REGISTRY VALUE DESCRIPTION

ActivationFailureLoggingLevel Sets the verbosity of event log entries about failed requests
for component launch and activation.

CallFailureLoggingLevel Sets the verbosity of event log entries about failed calls to
components.

DCOMSCMRemoteCallFlags Controls the behavior of calls from the local DCOM Service
Control Manager (DCOMSCM) to a remote DCOMSCM.

DefaultAccessPermission Defines default access permission list for the computer.

DefaultLaunchPermission Defines default launch ACL for the computer.

EnableDCOM Sets the global activation policy for the computer.

InvalidSecurityDescriptorLoggingLevel Sets the verbosity of event log entries about invalid security
descriptors for component launch and access permissions.

LegacyAuthenticationLevel Sets the default authentication level.

LegacyImpersonationLevel Sets the default impersonation level.

LegacySecureReferences Determines security level of AddRef/Release invocations.

MachineAccessRestriction Sets the computer-wide restriction policy for component


access.

MachineLaunchRestriction Sets the computer-wide restriction policy for component


launch and activation.

NonRedist Adds names to the list of files that should not be exported
when COM+ applications are packaged for installation on
other computers. Note that this is a subkey, not a value.

SRPActivateAsActivatorChecks Determines whether software restriction policy (SRP) trust


levels are used during ActivateAsActivator activations.
REGISTRY VALUE DESCRIPTION

SRPRunningObjectChecks Determines whether attempts to connect to running objects


are screened for compatible software restriction policy (SRP)
trust levels.
ActivationFailureLoggingLevel
1/7/2020 • 2 minutes to read • Edit Online

Sets the verbosity of event log entries about failed requests for component launch and activation.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Ole
ActivationFailureLoggingLevel = value

Remarks
This is a REG_DWORD value.

VALUE DESCRIPTION

0 Use discretionary logging. Log failures by default, but clients


can override this behavior by specifying
CLSCTX_NO_FAILURE_LOG in CoCreateInstanceEx. This is
the default value.

1 Always log all failures no matter what the client specified.

2 Never log any failures no matter what the client specified.

If you need an application to control event logging, it is recommended that you set this value to 0 and write the
client code to override it when needed. It is strongly recommended that you do not set the value to 2. If event
logging is disabled, it is more difficult to diagnose problems. For machine restrictions permission failures, where
COM does not have the CLSCTX bits, COM will treat a value of 0 as 1.

Related topics
S
e
t
t
i
n
g
S
e
c
u
r
i
t
y
f
o
r
C
O
M
A
p
p
l
i
c
a
t
i
o
n
s
CallFailureLoggingLevel
1/7/2020 • 2 minutes to read • Edit Online

Sets the verbosity of event log entries about failed calls to components.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Ole
CallFailureLoggingLevel = value

Remarks
This is a REG_DWORD value.

VALUE DESCRIPTION

1 Always log failures during a call in the COM Server process.

2 Never log failures during a call in the COM Server process.


This is the default value.

Related topics
S
e
t
t
i
n
g
S
e
c
u
r
i
t
y
f
o
r
C
O
M
A
p
p
l
i
c
a
t
i
o
n
s
DCOMSCMRemoteCallFlags
1/7/2020 • 2 minutes to read • Edit Online

Controls the behavior of calls from the local DCOM Service Control Manager (DCOMSCM ) to a remote
DCOMSCM.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Ole
DCOMSCMRemoteCallFlags = value

Remarks
This is a REG_DWORD value.

VALUE DESCRIPTION

0x1 DCOMSCM_ACTIVATION_USE_ALL_AUTHNSERVICES

0x2 DCOMSCM_ACTIVATION_DISALLOW_UNSECURE_CALL

0x4 DCOMSCM_RESOLVE_USE_ALL_AUTHNSERVICES

0x8 DCOMSCM_RESOLVE_DISALLOW_UNSECURE_CALL

0x10 DCOMSCM_PING_USE_MID_AUTHNSERVICE

DCOMSCM_ACTIVATION_USE_ALL_AUTHNSERVICES Description
When the client issues an activation request that uses the default security settings, the local DCOMSCM uses the
Negotiate authentication service when making the activation RPC call to the remote DCOMSCM. If the call fails,
the local DCOMSCM makes the activation RPC call using no security.
Windows Server 2003 and Windows XP/2000: If the activation RPC call that uses the Negotiate authentication
service fails, the local DCOMSCM makes the activation RPC call using Kerberos, NTLM, or other configured
security providers. If no security providers work, the local DCOMSCM makes the activation RPC call using no
security.
By setting this flag, the local DCOMSCM on Windows Vista or higher can be made to behave like pre-Vista
systems. It is not recommended to set this flag unless required for compatibility reasons.

DCOMSCM_ACTIVATION_DISALLOW_UNSECURE_CALL Description
If the DCOMSCM_ACTIVATION_DISALLOW_UNSECURE_CALL flag is set, the local DCOMSCM does not
make an unsecure activation RPC call. To enable clients to make activation requests with non-default security
settings, specify the COAUTHINFO structure when making the activation request. In this case, the
DCOMSCM_ACTIVATION_USE_ALL_AUTHNSERVICES and
DCOMSCM_ACTIVATION_DISALLOW_UNSECURE_CALL flags are ignored.
It is not recommended to set this flag unless all the clients and servers in the network are fully authenticated.

DCOMSCM_RESOLVE_USE_ALL_AUTHNSERVICES Description
When the client unmarshals an object reference, the local DCOMSCM uses the Negotiate authentication service
when making the OXID Resolution RPC call to the remote DCOMSCM. If the call fails, the local DCOMSCM
makes the OXID Resolution RPC call using no security.
Windows Server 2003 and Windows XP/2000: If the OXID Resolution RPC call using the Negotiate
authentication service fails, the local DCOMSCM makes the OXID Resolution RPC call by using Kerberos, NTLM,
or other configured security providers. If no security providers work, then the local DCOMSCM makes the OXID
Resolution RPC call using no security.
By setting this flag, the local DCOMSCM on Windows Vista or higher can be made to behave like pre-Vista
systems. It is not recommended to set this flag unless required for compatibility reasons.

DCOMSCM_RESOLVE_DISALLOW_UNSECURE_CALL Description
If the DCOMSCM_RESOLVE_DISALLOW_UNSECURE_CALL flag is set, the local DCOMSCM does not make
an unsecure OXID Resolution RPC call. In addition, the local DCOMSCM does not make an unsecure garbage
collection Ping RPC call. It is not recommended to set this flag unless all the clients and servers in the network are
fully authenticated.

DCOMSCM_PING_USE_MID_AUTHNSERVICE Description
The local DCOMSCM uses the Negotiate authentication service when making the garbage-collection Ping RPC
call to the remote DCOMSCM. If the call fails, the local DCOMSCM makes the garbage-collection Ping RPC call
using no security.
Windows Server 2003 and Windows XP/2000: If the garbage-collection Ping RPC call using the Negotiate
authentication service fails, the local DCOMSCM makes the garbage collection Ping RPC call by using Kerberos,
NTLM, and other configured security providers. If no security providers work, then the local DCOMSCM makes
the garbage collection Ping RPC call using no security.
By setting this flag, the local DCOMSCM on Windows Vista or above can be made to behave like pre-Vista
systems. It is not recommended to set the DCOMSCM_PING_USE_MID_AUTHNSERVICE flag unless required
for compatibility reasons.

Related topics
A
u
t
h
e
n
t
i
c
a
t
i
o
n
f
o
r
R
e
m
o
t
e
C
o
n
n
e
c
t
i
o
n
s

E
n
a
b
l
e
D
C
O
M

R
e
g
i
s
t
e
r
i
n
g
C
O
M
S
e
r
v
e
r
s

S
e
c
u
r
i
t
y
i
n
C
O
M
DefaultAccessPermission
1/7/2020 • 2 minutes to read • Edit Online

Sets the Access Control List (ACL ) of the principals that can access classes for which there is no
AccessPermission setting. This ACL is used only by applications that do not call CoInitializeSecurity and do
not have an AccessPermission value under their AppID key.
Cau t i on

It is not recommended that you change this value, because this will affect all COM server applications that do
not set their own process-wide security, and might prevent them from working properly. If you are changing this
value to affect the security settings for a particular COM application, then you should instead change the
process-wide security settings for that particular COM application. For more information on setting process-
wide security, see Setting Process-wide Security.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Ole
DefaultAccessPermission = ACL

Remarks
This is a REG_BINARY value.
The COM runtime in the server checks the ACL described by this value while impersonating the caller that is
attempting to connect to the object, and its success determines whether the access is allowed or disallowed. If
the access-check fails, the connection to the object is disallowed. If this named value does not exist, only the
server principal and local system are allowed to call the server.
By default, this value has no entries in it. Only the server principal and system are allowed to call the server.
This value provides a simple level of centralized administration of the default connection access to running
objects on a computer.

Related topics
A
c
c
e
s
s
P
e
r
m
i
s
s
i
o
n

R
e
g
i
s
t
e
r
i
n
g
C
O
M
S
e
r
v
e
r
s

S
e
t
t
i
n
g
P
r
o
c
e
s
s
-
w
i
d
e
S
e
c
u
r
i
t
y
DefaultLaunchPermission
1/7/2020 • 2 minutes to read • Edit Online

Defines the Access Control List (ACL ) of the principals that can launch classes that do not specify their own ACL
through the LaunchPermission registry value.
Cau t i on

It is not recommended that you change this value, because this will affect all COM server applications that do not
set their own process-wide security, and might prevent them from working properly. If you are changing this
value to affect the security settings for a particular COM application, then you should instead change the process-
wide security settings for that particular COM application. For more information on setting process-wide security,
see Setting Process-wide Security.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Ole
DefaultLaunchPermission = ACL

Remarks
This is a REG_BINARY value.
The default access permissions are as follows:
Administrators: allow launch
SYSTEM: allow launch
INTERACTIVE: allow launch
If the LaunchPermission value is set for a server, it takes precedence over the DefaultLaunchPermission
value. Upon receiving a local or remote request to launch a server whose AppID key has no LaunchPermission
value of its own, the ACL described by this value is checked while impersonating the client and its success either
allows or disallows the launching of the class code.
This value provides a simple level of centralized administration of the default launching access to otherwise
unadministered classes on a computer. For example, an administrator might use the DCOMCNFG tool to
configure the system to allow read-only access for Power Users. OLE would therefore restrict requests to launch
class code to members of the Power Users group. An administrator could subsequently configure launch
permissions for individual classes to grant the ability to launch class code to other groups or individual users as
needed.

Related topics
L
a
u
n
c
h
P
e
r
m
i
s
s
i
o
n

R
e
g
i
s
t
e
r
i
n
g
C
O
M
S
e
r
v
e
r
s

S
e
t
t
i
n
g
P
r
o
c
e
s
s
-
w
i
d
e
S
e
c
u
r
i
t
y
DoNotAddAllApplicationPackagesToRestrictions
1/7/2020 • 2 minutes to read • Edit Online

Determines whether RPCSS automatically appends an ALL_APPLICATION_PACKAGES SID to COM restrictions


by default.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Ole
DoNotAddAllApplicationPackagesToRestrictions = value

Remarks
This is a REG_DWORD value.

VALUE DESCRIPTION

0 Disables Windows Store apps upon migration from Windows 7


to Windows 8.

1 Does not add the ALL_APPLICATION_PACKAGES SID to COM


restrictions. This is the default.

Related topics
S
e
t
t
i
n
g
S
e
c
u
r
i
t
y
f
o
r
C
O
M
A
p
p
l
i
c
a
t
i
o
n
s
EnableDCOM
1/7/2020 • 2 minutes to read • Edit Online

Controls the global activation and call policies of the machine. Only administrators and the system have full access
to this portion of the registry. All other users have read-only access.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Ole
EnableDCOM = value

Remarks
This is a REG_SZ value.

VALUE DESCRIPTION

N (or n) No remote clients may launch servers or connect to objects


on this computer. Local clients cannot access remote DCOM
servers; all DCOM traffic is blocked. Local launching of class
code and connecting to objects are allowed on a per-class
basis according to the value and access permissions of the
class's LaunchPermission registry value and the global
DefaultLaunchPermission registry value.

Y (or y) Launching of servers and connecting to objects by remote


clients is allowed on a per-class basis according to the value
and access permissions of the class's LaunchPermission
registry value and the global DefaultLaunchPermission
registry value.

Related topics
D
e
f
a
u
l
t
L
a
u
n
c
h
P
e
r
m
i
s
s
i
o
n

L
a
u
n
c
h
P
e
r
m
i
s
s
i
o
n

S
e
c
u
r
i
t
y
i
n
C
O
M
InvalidSecurityDescriptorLoggingLevel
1/7/2020 • 2 minutes to read • Edit Online

Sets the verbosity of event log entries about invalid security descriptors for component launch and access
permissions.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Ole
InvalidSecurityDescriptorLoggingLevel = value

Remarks
This is a REG_DWORD value.

VALUE DESCRIPTION

1 Always log failures when COM finds an invalid security


descriptor. This is the default value.

2 Never log failures when COM finds an invalid security


descriptor. It is not recommended that you disable event
logging, as it can make it more difficult to diagnose problems.

If you set launch and access permission security descriptors (commonly called ACLs) directly, it is possible to
construct a security descriptor whose meaning cannot be interpreted unambiguously. COM makes an event log
entry when it encounters such an invalid security descriptor.
Note that ActivationFailureLoggingLevel and CallFailureLoggingLevel have no control over logging invalid
security descriptor errors. Use InvalidSecurityDescriptorLoggingLevel for full control over this functionality.

Related topics
S
e
t
t
i
n
g
S
e
c
u
r
i
t
y
f
o
r
C
O
M
A
p
p
l
i
c
a
t
i
o
n
s
LegacyAuthenticationLevel
1/7/2020 • 2 minutes to read • Edit Online

Sets the default authentication level for applications that do not call CoInitializeSecurity.
Cau t i on

It is not recommended that you change this value, because this will affect all COM server applications that do not
set their own process-wide security, and might prevent them from working properly. If you are changing this
value to affect the security settings for a particular COM application, then you should instead change the
process-wide security settings for that particular COM application. For more information on setting process-
wide security, see Setting Process-wide Security.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Ole
LegacyAuthenticationLevel = value

Remarks
This is a REG_WORD value that is equivalent to the RPC_C_AUTHN_LEVEL constants.

VALUE CONSTANT

1 RPC_C_AUTHN_LEVEL_NONE

2 RPC_C_AUTHN_LEVEL_CONNECT

3 RPC_C_AUTHN_LEVEL_CALL

4 RPC_C_AUTHN_LEVEL_PKT

5 RPC_C_AUTHN_LEVEL_PKT_INTEGRITY

6 RPC_C_AUTHN_LEVEL_PKT_PRIVACY

If this registry value is not present, the default authentication level established by the system is 2
(RPC_C_AUTHN_CONNECT).

Related topics
A
u
t
h
e
n
t
i
c
a
t
i
o
n
L
e
v
e
l

R
e
g
i
s
t
e
r
i
n
g
C
O
M
S
e
r
v
e
r
s

S
e
t
t
i
n
g
P
r
o
c
e
s
s
-
w
i
d
e
S
e
c
u
r
i
t
y
LegacyImpersonationLevel
1/7/2020 • 2 minutes to read • Edit Online

Sets the default level of impersonation for applications that do not call CoInitializeSecurity.
Cau t i on

It is not recommended that you change this value, because this will affect all COM server applications that do not
set their own process-wide security, and might prevent them from working properly. If you are changing this value
to affect the security settings for a particular COM application, then you should instead change the process-wide
security settings for that particular COM application. For more information on setting process-wide security, see
Setting Process-wide Security.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Ole
LegacyImpersonationLevel = value

Remarks
This is a REG_WORD value that is equivalent to the RPC_C_IMP_LEVEL constants.

VALUE CONSTANT

1 RPC_C_IMP_LEVEL_ANONYMOUS

2 RPC_C_IMP_LEVEL_IDENTIFY

3 RPC_C_IMP_LEVEL_IMPERSONATE

4 RPC_C_IMP_LEVEL_DELEGATE

If this registry value is not present, the default impersonation level established by the system is 2
(RPC_C_IMP_LEVEL_IDENTIFY ).

Related topics
R
e
g
i
s
t
e
r
i
n
g
C
O
M
S
e
r
v
e
r
s

S
e
t
t
i
n
g
P
r
o
c
e
s
s
-
w
i
d
e
S
e
c
u
r
i
t
y
LegacySecureReferences
1/7/2020 • 2 minutes to read • Edit Online

Determines whether AddRef/Release invocations are secured for applications that do not call
CoInitializeSecurity.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Ole
LegacySecureReferences = value

Remarks
This is a REG_SZ value. A value of 'Y' or 'y' indicate that AddRef and Release are secured. If this registry value is
not present or is set to a value other than 'Y' or 'y', AddRef and Release are not secured. Enabling secure
references slows remote calls.

Related topics
R
e
g
i
s
t
e
r
i
n
g
C
O
M
S
e
r
v
e
r
s

S
e
t
t
i
n
g
P
r
o
c
e
s
s
-
w
i
d
e
S
e
c
u
r
i
t
y
MachineAccessRestriction
1/7/2020 • 2 minutes to read • Edit Online

Sets the computer-wide restriction policy for component access.


Cau t i on

Changing this value will affect all COM server applications, and might prevent them from working properly. If
there are COM server applications that have restrictions that are less stringent than the computer-wide
restrictions, reducing the computer-wide restrictions may expose these applications to unwanted access.
Conversely, if you increase the computer-wide restrictions, some COM server applications might no longer be
accessible by calling applications.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Ole
MachineAccessRestriction = SECURITY_DESCRIPTOR

Remarks
This is a REG_BINARY value.
Principals not given permissions here cannot obtain them even if the permissions are granted by the
DefaultAccessPermission registry value or by the CoInitializeSecurity function.
By default, members of the Everyone group can obtain local and remote access permissions, and anonymous
users can obtain local access permissions.

Related topics
S
e
t
t
i
n
g
S
e
c
u
r
i
t
y
f
o
r
C
O
M
A
p
p
l
i
c
a
t
i
o
n
s
MachineLaunchRestriction
1/7/2020 • 2 minutes to read • Edit Online

Sets the computer-wide restriction policy for component launch and activation.
Cau t i on

Changing this value will affect all COM server applications, and might prevent them from working properly. If
there are COM server applications that have restrictions that are less stringent than the computer-wide
restrictions, reducing the computer-wide restrictions may expose these applications to unwanted access.
Conversely, if you increase the computer-wide restrictions, some COM server applications might no longer be
accessible by calling applications.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Ole
MachineLaunchRestriction = SECURITY_DESCRIPTOR

Remarks
This is a REG_BINARY value.
Principals not given permissions here cannot obtain them even if the permissions are granted by the
DefaultAccessPermission registry value or by the CoInitializeSecurity function.
By default, administrators may obtain local and remote launch and activation permissions, and members of the
Everyone group may obtain local activation and launch permissions.

Related topics
S
e
t
t
i
n
g
S
e
c
u
r
i
t
y
f
o
r
C
O
M
A
p
p
l
i
c
a
t
i
o
n
s
NONREDIST
1/7/2020 • 2 minutes to read • Edit Online

Adds names to the list of files that should not be exported when COM+ applications are packaged for installation
on other computers. Note that this is a subkey, not a value.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Ole
NONREDIST
name1
name2

Remarks
The files you add to the list are represented by name/value pairs stored under this key. In each name/value pair, the
name is the file name and the value is reserved.
SRPActivateAsActivatorChecks
1/7/2020 • 2 minutes to read • Edit Online

Determines whether software restriction policy (SRP ) trust levels are used during ActivateAsActivator activations.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Ole
SRPActivateAsActivatorChecks = value

Remarks
This is a REG_SZ value.
String values of {N, n, NO, No, no} indicate that the server object runs with the SRP trust level of the client object,
regardless of the SRP trust level with which it was configured. If this registry value is set to any other value or
does not exist, the SRP trust level that is configured for the server object is compared with the SRP trust level of
the client object and that the more stringent trust level is used to run the server object.

Related topics
S
R
P
T
r
u
s
t
L
e
v
e
l
SRPRunningObjectChecks
1/7/2020 • 2 minutes to read • Edit Online

Determines whether attempts to connect to running objects are screened for compatible software restriction
policy (SRP ) trust levels.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Ole
SRPRunningObjectChecks = value

Remarks
This is a REG_SZ value.
String values of {N, n, NO, No, no} indicate that attempts to connect to running objects are not screened for
compatible SRP trust levels. If this registry value is set to any other value or does not exist, the running object
cannot have a less stringent SRP trust level than the client object. For example, the running object cannot have a
Disallowed trust level if the client object has an Unrestricted trust level.

Related topics
S
R
P
T
r
u
s
t
L
e
v
e
l
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows
NT\CurrentVersion
1/7/2020 • 2 minutes to read • Edit Online

The subkeys and registry values associated with the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows


NT\CurrentVersion key contain information related to COM RPC debugging functionality.

SUBKEY DESCRIPTION

DebugObjectRPCEnabled Configuration options for COM RPC remote debugging.


DebugObjectRPCEnabled
1/7/2020 • 2 minutes to read • Edit Online

The DebugObjectRPCEnabled enables remote COM debugging over RPC. If this key is not defined on the
server, remote debugging is disabled.

Registry Key
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows
NT\CurrentVersion\DebugObjectRPCEnabled

REGISTRY KEY DESCRIPTION

AeDebug Stores debugger specific options.

Related topics
D
l
l
D
e
b
u
g
O
b
j
e
c
t
R
P
C
H
o
o
k

I
O
r
p
c
D
e
b
u
g
N
o
t
i
f
y

O
R
P
C
_
D
B
G
_
A
L
L
AeDebug
1/7/2020 • 2 minutes to read • Edit Online

The AeDebug defines remote debugging options for COM.

Registry Key
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows
NT\CurrentVersion\DebugObjectRPCEnabled\AeDebug

REGISTRY VALUE DESCRIPTION

Auto Determines if the debugger is launched automatically.

Debugger Stores the debugger name.

Related topics
D
l
l
D
e
b
u
g
O
b
j
e
c
t
R
P
C
H
o
o
k

I
O
r
p
c
D
e
b
u
g
N
o
t
i
f
y

O
R
P
C
_
D
B
G
_
A
L
L
Auto
1/7/2020 • 2 minutes to read • Edit Online

Determines if the debugger is automatically launched when a COM RPC notification is sent.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\DebugObjectRPCEnabled\AeDebug
Auto = value

Remarks
This is a REG_WORD value.

VALUE DESCRIPTION

1 Automatically launch debugger.

Related topics
D
l
l
D
e
b
u
g
O
b
j
e
c
t
R
P
C
H
o
o
k

I
O
r
p
c
D
e
b
u
g
N
o
t
i
f
y

O
R
P
C
_
D
B
G
_
A
L
L
Debugger
1/7/2020 • 2 minutes to read • Edit Online

Stores the name of the preferred debugger to use with remote COM debugging over RPC.

Registry Entry
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\DebugObjectRPCEnabled\AeDebug
Debugger = value

Remarks
This is a REG_SZ value.

Related topics
D
l
l
D
e
b
u
g
O
b
j
e
c
t
R
P
C
H
o
o
k

I
O
r
p
c
D
e
b
u
g
N
o
t
i
f
y

O
R
P
C
_
D
B
G
_
A
L
L
Structures
1/7/2020 • 2 minutes to read • Edit Online

The following structures are provided by COM:


ACTRL_ACCESS
ACTRL_ACCESS_ENTRY
ACTRL_ACCESS_ENTRY_LIST
ACTRL_PROPERTY_ENTRY
BIND_OPTS
BIND_OPTS2
BIND_OPTS3
CALLFRAME_MARSHALCONTEXT
CALLFRAMEINFO
CALLFRAMEPARAMINFO
CATEGORYINFO
COAUTHIDENTITY
COAUTHINFO
CONNECTDATA
COSERVERINFO
CSPLATFORM
INTERFACEINFO
MULTI_QI
ORPC_DBG_ALL
ORPC_DBG_BUFFER
ORPC_INIT_ARGS
QUERYCONTEXT
RPCOLEMESSAGE
SOLE_AUTHENTICATION_INFO
SOLE_AUTHENTICATION_LIST
SOLE_AUTHENTICATION_SERVICE
SOleTlsData
ORPC_DBG_ALL structure
1/7/2020 • 2 minutes to read • Edit Online

The ORPC_DBG_ALL structure is used to pass parameters to the methods of the IOrpcDebugNotify
interface.

NOTE
Each method of the IOrpcDebugNotify interface uses a different combination of the members below. If a member is not
indicated as used by a method, it is undefined when passed to that method.

Syntax
typedef struct ORPC_DBG_ALL {
BYTE *pSignature;
RPCOLEMESSAGE *pMessage;
const IID *refiid;
IRpcChannelBuffer *pChannel;
IUnknown *pUnkProxyMgr;
void *pInterface;
IUnknown *pUnkObject;
HRESULT hresult;
void *pvBuffer;
ULONG *cbBuffer;
ULONG *lpcbBuffer;
void *reserved;
} ORPC_DBG_ALL, *LPORPC_DBG_ALL;

Members
p
S
i
g
n
a
t
u
r
e

A pointer to a BYTE buffer that contains:


First four bytes: the ASCII characters "MARB" in increasing memory order.
Next 16 bytes: A GUID that identifies the notification being called. It contains one of the following:
1. ClientGetBufferSize: 9ED14F80-9673-101A-B07B -00DD01113F11
2. ClientFillBuffer:DA45F3E0-9673-101A-B07B -00DD01113F11
3. ClientNotify:4F60E540-9674-101A-B07B -00DD01113F11
4. ServerNotify:1084FA00-9674-101A-B07B -00DD01113F11
5. ServerGetBufferSize:22080240-9674-101A-B07B -00DD01113F11
6. ServerFillBuffer:2FC09500-9674-101A-B07B -00DD01113F11
Next four-bytes: Reserved for future use.

NOTE
Used by all methods of the IOrpcDebugNotify interface.

p
M
e
s
s
a
g
e

A pointer to an RPCOLEMESSAGE structure that contains RPC data marshalling information.

NOTE
Used by the ClientFillBuffer, ClientGetBufferSize, ClientNotify, ServerFillBuffer, ServerGetBufferSize, and
ServerNotify methods.

r
e
f
i
i
d

A pointer to the IID of the IOrpcDebugNotify interface.

NOTE
Used by the ClientFillBuffer, ClientGetBufferSize, ClientNotify, ServerFillBuffer, ServerGetBufferSize, and
ServerNotify methods.

p
C
h
a
n
n
e
l

A pointer to the IRpcChannelBuffer interface of the COM RPC channel implementation on the server.

NOTE
Used by the ServerFillBuffer, ServerGetBufferSize, and ServerNotify methods.
p
U
n
k
P
r
o
x
y
M
g
r

A pointer to the IUnknown interface of the object involved in this debugger invocation. May be NULL,
however, this reduces debugger functionality.

NOTE
Used by the ClientFillBuffer, ClientGetBufferSize, and ClientNotify methods.

p A pointer to the COM interface of the method that will be invoked by this RPC. Must not be NULL.
I
n NOTE
t Used by the ServerFillBuffer, ServerGetBufferSize, and ServerNotify methods.
e
r
f
a
c
e

p Must be NULL.
U
n NOTE
k Used by the ServerFillBuffer, ServerGetBufferSize, and ServerNotify methods.
O
b
j
e
c
t

h
r
e
s
u
l
t

This member's purpose changes for each of the notifications below:


ClientGetBufferSize: the number of bytes the client debugger will transmit to the server debugger. If
zero, no information need be transmitted.
ClientNotify: the HRESULT of the last RPC.
ServerGetBufferSize: the number of bytes the client debugger will transmit to the server debugger. If
zero, no information need be transmitted.

NOTE
Used by the ClientGetBufferSize, ClientNotify, and ServerGetBufferSize methods.

p
v
B
u
f
f
e
r

A pointer to an ORPC_DBG_BUFFER structure that contains the RPC marshalled debug information. Is
undefined if cbBuffer is zero.

NOTE
Used by the ClientFillBuffer, ClientNotify, ServerFillBuffer, and ServerNotify methods.

c The length, in bytes, of the data pointed to by pvBuffer.


b
B NOTE
u Used by the ClientFillBuffer, ClientNotify, ServerFillBuffer, and ServerNotify methods.
f
f
e
r

l
p
c
b
B
u
f
f
e
r

The number of bytes the client debugger will transmit to the server debugger. If zero, no information
need be transmitted. This value supersedes the value returned in hresult.

NOTE
Used by the ClientFillBuffer, ClientGetBufferSize methods.
r Reserved. Do not use.
e
s
e
r
v
e
d

Requirements

Minimum supported client Windows 2000 Professional [desktop apps only]

Minimum supported server Windows 2000 Server [desktop apps only]

Header
N/A

See also
O
R
P
C
_
D
B
G
_
B
U
F
F
E
R

O
R
P
C
_
I
N
I
T
_
A
R
G
S

D
l
l
D
e
b
u
g
O
b
j
e
c
t
R
P
C
H
o
o
k

I
O
r
p
c
D
e
b
u
g
N
o
t
i
f
y
ORPC_DBG_BUFFER structure
1/7/2020 • 2 minutes to read • Edit Online

The ORPC_DBG_BUFFER structure is the buffer format used to marshalled RPC data to the methods of the
IOrpcDebugNotify interface.

Syntax
typedef struct _ORPC_DBG_BUFFER {
DWORD alwaysOrSometimes;
BYTE verMajor;
BYTE verMinor;
DWORD cbRemaining;
GUID guidSemantic;
union {
BOOL fStopOnOtherSide;
USHORT wDebuggingOpCode;
USHORT cExtent;
BYTE padding[2];
struct {
ULONG cb;
GUID guidExtent;
BYTE *rgbData;
};
};
} ORPC_DBG_BUFFER, *PORPC_DBG_BUFFER;

Members
a A value that controls debugger spawning. alwaysOrSometimes can be one of the following values:
l
w VALUE MEANING
a
y If set, COM will always raise the client or server
OR notification on the receiver.
s PC_
O DEB
r UG_
AL
S WA
o YS
m 0x0
e 000
000
t 0
i
m
e
s
VALUE MEANING

If set, COM will only raise the client or server


OR notification on the receiver if COM debugging has
PC_ been enabled by calling DllDebugObjectRPCHook
DEB in that process with fTrace set to TRUE.
UG_
IF_H
OO
K_E
NA
BLE
D
0x0
000
000
1

v The major version number of the data format specification.


e
r
M
a
j
o
r

v The minor version number of the data format specification.


e
r
M
i
n
o
r

c The number of bytes, inclusive of cbRemaining, that follow in this structure.


b
R
e
m
a
i
n
i
n
g

g
u
i
d
S
e
m
a
n
t
i
c

A GUID that determines which members of the union are present below. guidSemantic can take one of the
following values:

VALUE MEANING

Determines if single stepping is to be performed by the


9CA debugger. Only the fStopOnOtherSide member of the
DE5 union is present below.
60-
8F4
3-
101
A-
B07
B-
00D
D01
113
F11

Determines if RPC marshalled data and debugging


D62 opcodes are passed to the receiver. All of the members of
AED the union are present below with the exception of
FA- fStopOnOtherSide.
57E
A-
11c
e-
A96
4-
00A
A00
6C3
706

f
S
t
o
p
O
n
O
t
h
e
r
S
i
d
e

If TRUE, single stepping is performed by the debugger and it should step out of the server and continue
execution once the other side is reached. Otherwise, single stepping is not performed and debugger
execution stops on the other side.

w
D
e
b
u
g
g
i
n
g
O
p
C
o
d
e

A value that allows for one of a series of operations to be specified. wDebuggingOpCode can take one of
the following values:

VALUE MEANING

No operation.
0x0
000

If set, single step semantics are identical to


0x0 fStopOnOtherSide when set to TRUE.
001

c Padding. Do not use.


E
x
t
e
n
t

p Padding. Do not use.


a
d
d
i
n
g

c The size, in bytes of the data in rgbData.


b
g A GUID that determines the type of data in rgbData. guidExtent can take one of the following values:
u
i VALUE MEANING
d
E rgbData is a marshalled interface pointer.
531
x 990
t 51-
e 57E
B-
n 11c
t e-
A96
4-
00A
A00
6C3
706

r
g
b
D
a
t
a

A BYTE buffer used to pass RPC marshalled COM data between the client and server debuggers. The
contents of rgbData are determined by the GUID in guidExtent.

GUIDEX TENT VALUE RGBDATA CONTENTS

53199051-57EB-11ce-A964-00AA006C3706 A marshalled interface pointer that results from calling


CoMarshalInterface. The marshalled pointer is converted
into its corresponding interface pointer using
CoUnmarshalInterface.

Remarks
This members of this structure have 1-byte alignment and are always transmitted in little-endian byte order.

Requirements

Minimum supported client Windows 2000 Professional [desktop apps only]

Minimum supported server Windows 2000 Server [desktop apps only]

Header
N/A

See also
O
R
P
C
_
D
B
G
_
A
L
L

O
R
P
C
_
I
N
I
T
_
A
R
G
S

D
l
l
D
e
b
u
g
O
b
j
e
c
t
R
P
C
H
o
o
k

I
O
r
p
c
D
e
b
u
g
N
o
t
i
f
y
ORPC_INIT_ARGS structure
1/7/2020 • 2 minutes to read • Edit Online

The ORPC_INIT_ARGS structure contains information used to initialize remote debugging using the
IOrpcDebugNotify interface.

Syntax
typedef struct ORPC_INIT_ARGS {
IOrpcDebugNotify *lpIntfOrpcDebug;
void *pvPSN;
DWORD *dwReserved1;
DWORD *dwReserved2;
} ORPC_INIT_ARGS, *LPORPC_INIT_ARGS;

Members
l
p
I
n
t
f
O
r
p
c
D
e
b
u
g

A pointer to the IOrpcDebugNotify interface for use by in-process debuggers. If the debugger is not in-
process or is a Macintosh system, this field must be NULL.

p
v
P
S
N

A pointer to the Macintosh process serial number of the debuggee's process. If the debuggee is not a
Macintosh system, this field must be NULL.

d Reserved. Must be 0.
w
R
e
s
e
r
v
e
d
1

d Reserved. Must be 0.
w
R
e
s
e
r
v
e
d
2

Requirements

Minimum supported client Windows 2000 Professional [desktop apps only]

Minimum supported server Windows 2000 Server [desktop apps only]

Header
N/A

See also
O
R
P
C
_
D
B
G
_
A
L
L

O
R
P
C
_
D
B
G
_
B
U
F
F
E
R

D
l
l
D
e
b
u
g
O
b
j
e
c
t
R
P
C
H
o
o
k

I
O
r
p
c
D
e
b
u
g
N
o
t
i
f
y
Functions
1/7/2020 • 10 minutes to read • Edit Online

The following functions are provided by COM.

FUNCTION DESCRIPTION

BindMoniker Locates an object by means of its moniker, activates the object


if it is inactive, and retrieves a pointer to the specified interface
on that object.

CLSIDFromProgID Looks up a CLSID in the registry, given a ProgID.

CLSIDFromProgIDEx Triggers automatic installation if the COMClassStore policy is


enabled.

CLSIDFromString Converts a string generated by the StringFromCLSID


function back into the original CLSID.

CoAddRefServerProcess Increments a global per-process reference count.

CoAllowSetForegroundWindow Enables the COM server process called to take focus away
from the client application by using the IForegroundTransfer
interface.

CoAllowUnmarshalerCLSID Adds an unmarshaler CLSID to the allowed list for the calling
process only.

CoCancelCall Requests cancellation of an outbound DCOM method call


pending on a specified thread.

CoCopyProxy Makes a private copy of the specified proxy.

CoCreateFreeThreadedMarshaler Creates an aggregatable object capable of context-dependent


marshaling.

CoCreateGuid Creates a GUID, a unique 128-bit integer used for CLSIDs and
interface identifiers.

CoCreateInstance Creates a single uninitialized object of the class associated with


a specified CLSID.

CoCreateInstanceEx Creates an instance of a specific class on a specific computer.

CoCreateInstanceFromApp Creates an instance of a specific class on a specific computer


from within an app container.

CoDisableCallCancellation Undoes the action of a call to CoEnableCallCancellation.


FUNCTION DESCRIPTION

CoDisconnectContext Disconnects all proxy connections that are being maintained


on behalf of all interface pointers that point to objects in the
current context.

CoDisconnectObject Disconnects all remote process connections being maintained


on behalf of all the interface pointers that point to a specified
object.

CoDosDateTimeToFileTime Converts the MS-DOS representation of the time and date to


a FILETIME structure used by Windows.

CoEnableCallCancellation Enables cancellation of synchronous calls on the calling thread.

CoFileTimeNow Returns the current time as a FILETIME structure.

CoFileTimeToDosDateTime Converts a FILETIME into MS-DOS date and time values.

CoFreeAllLibraries Frees all the DLLs that have been loaded with the
CoLoadLibrary function (called internally by
CoGetClassObject), regardless of whether they are currently
in use.

CoFreeLibrary Frees a library that, when loaded, was specified to be freed


explicitly.

CoFreeUnusedLibraries Unloads any DLLs that are no longer in use.

CoFreeUnusedLibrariesEx Unloads any DLLs that are no longer in use and whose unload
delay has expired.

CoGetApartmentType Queries the current apartment type and type qualifier.

CoGetCallContext Retrieves the context of the current call on the current thread.

CoGetCallerTID Returns a pointer to a DWORD that contains the apartment


ID of the caller's thread.

CoGetCancelObject Obtains a pointer to a call control interface, normally


ICancelMethodCalls, on the cancel object corresponding to
an outbound COM method call pending on the same or
another client thread.

CoGetClassObject Provides a pointer to an interface on a class object associated


with a specified CLSID.

CoGetContextToken Returns a pointer to an implementation of IObjContext for


the current context.

CoGetCurrentLogicalThreadId Returns the logical thread id of the current physical thread.

CoGetCurrentProcess Returns a value that is unique to the current thread.


CoGetCurrentProcess can be used to avoid thread ID reuse
problems.
FUNCTION DESCRIPTION

CoGetInstanceFromFile Creates a new object and initializes it from a file using


IPersistFile::Load.

CoGetInstanceFromIStorage Creates a new object and initializes it from a storage object


through an internal call to IPersistFile::Load.

CoGetInterceptor Instantiates the appropriate interceptor for the indicated


interface to be intercepted and returns the newly created
interceptor.

CoGetInterfaceAndReleaseStream Unmarshals a buffer containing an interface pointer and


releases the stream when an interface pointer has been
marshaled from another thread to the calling thread.

CoGetMalloc Retrieves a pointer to the default OLE task memory allocator


(which supports the system implementation of the IMalloc
interface) so applications can call its methods to manage
memory.

CoGetMarshalSizeMax Returns an upper bound on the number of bytes needed to


marshal the specified interface pointer to the specified object.

CoGetObject Converts a display name into a moniker that identifies the


object named, and then binds to the object identified by the
moniker.

CoGetObjectContext Returns the context for the current object.

CoGetPSClsid Returns the CLSID of the DLL that implements the proxy and
stub for the specified interface.

CoGetStandardMarshal Creates a default, or standard, marshaling object in either the


client process or the server process, depending on the caller,
and returns a pointer to that object's IMarshal
implementation.

CoGetStdMarshalEx Creates an aggregated standard marshaler for use with


lightweight client-side handlers.

CoGetSystemSecurityPermissions Returns the default values of the Security Descriptors of the


machine-wide launch and access permissions, as well as launch
and access limits.

CoGetTreatAsClass Returns the CLSID of an object that can emulate the specified
object.

CoHandlePriorityEventsFromMessagePump Provides an opportunity for short-running infrastructural


COM calls and other high-priority or short-running COM
work to be dispatched between messages.

CoImpersonateClient Enables the server to impersonate the client of the current call
for the duration of the call.

CoInitialize Initializes the COM library on the current thread and identifies
the concurrency model as single-thread apartment (STA).
FUNCTION DESCRIPTION

CoInitializeEx Initializes the COM library for use by the calling thread, sets
the thread's concurrency model, and creates a new apartment
for the thread if one is required.

CoInitializeSecurity Registers security and sets the default security values for the
process.

CoInstall Installs the requested COM server application.

CoInvalidateRemoteMachineBindings Tells the service control manager to flush any cached RPC
binding handles for the specified computer.

CoIsHandlerConnected Determines whether a remote object is connected to the


corresponding in-process object.

CoIsOle1Class Determines whether the specified CLSID represents an OLE 1


object.

CoLoadLibrary Loads a specific DLL into the caller's process.

CoLockObjectExternal Called either to lock an object to ensure that it stays in


memory, or to release such a lock.

CoMarshalHresult Marshals an HRESULT to the specified stream, from which it


can be unmarshaled using the CoUnmarshalHresult function.

CoMarshalInterface Writes into a stream the data required to initialize a proxy


object in some client process.

CoMarshalInterThreadInterfaceInStream Marshals an interface pointer from one thread to another


thread in the same process.

CoQueryAuthenticationServices Retrieves a list of the authentication services registered when


the process called CoInitializeSecurity.

CoQueryClientBlanket Called by the server to find out about the client that invoked
the method executing on the current thread.

CoRegisterActivationFilter Registers a process-wide filter to process activation requests.

CoRegisterChannelHook Registers a channel hook.

CoQueryProxyBlanket Retrieves the authentication information the client uses to


make calls on the specified proxy.

CoRegisterClassObject Registers an EXE class object with OLE so other applications


can connect to it.
FUNCTION DESCRIPTION

CoRegisterInitializeSpy Registers an implementation of the IInitializeSpy interface.


The IInitializeSpy interface is defied to allow developers to
perform initialization and cleanup on COM apartments.

CoRegisterMallocSpy Registers an implementation of the IMallocSpy interface,


thereafter requiring OLE to call its wrapper methods around
every call to the corresponding IMalloc method.

CoRegisterMessageFilter Registers with OLE the instance of an IMessageFilter


interface, which is to be used for handling concurrency issues
on the current thread.

CoRegisterPSClsid Enables a downloaded DLL to register its custom interfaces


within its running process so that the marshaling code will be
able to marshal those interfaces.

CoRegisterSurrogate Registers the surrogate process through its ISurrogate


interface pointer.

CoReleaseMarshalData Destroys a previously marshaled data packet.

CoReleaseServerProcess Decrements the global per-process reference count.

CoResumeClassObjects Called by a server that can register multiple class objects to


inform the SCM about all registered classes, and permits
activation requests for those class objects.

CoRevertToSelf Restores the authentication information on a thread of


execution.

CoRevokeClassObject Informs OLE that a class object, previously registered with the
CoRegisterClassObject function, is no longer available for
use.

CoRevokeInitializeSpy Revokes a registered implementation of the IInitializeSpy


interface.

CoRevokeMallocSpy Revokes a registered IMallocSpy object.

CoSetCancelObject Sets (registers) or resets (unregisters) a cancel object for use


during subsequent cancel operations on the current thread.

CoSetMessageDispatcher Registers or unregisters the per-thread message dispatcher


that is to be invoked when there are window messages
available to dispatch within COM wait APIs on an ASTA
thread.

CoSetProxyBlanket Sets the authentication information that will be used to make


calls on the specified proxy.

CoSuspendClassObjects Prevents any new activation requests from the SCM on all
class objects registered within the process.

CoSwitchCallContext Switches the call context object used by CoGetCallContext.


FUNCTION DESCRIPTION

CoTaskMemAlloc Allocates a block of task memory in the same way that


IMalloc::Alloc does.

CoTaskMemFree Frees a block of task memory previously allocated through a


call to the CoTaskMemAlloc or CoTaskMemRealloc
function.

CoTaskMemRealloc Changes the size of a previously allocated block of task


memory.

CoTestCancel Determines whether the call being executed on the server has
been canceled by the client.

CoTreatAsClass Establishes or removes an emulation, in which objects of one


class are treated as objects of a different class.

CoUninitialize Closes the COM library on the current thread, unloads all
DLLs loaded by the thread, frees any other resources that the
thread maintains, and forces all RPC connections on the
thread to close.

CoUnmarshalHresult Unmarshals an HRESULT type from the specified stream.

CoUnmarshalInterface Initializes a newly created proxy using data written into the
stream by a previous call to the CoMarshalInterface
function, and returns an interface pointer to that proxy.

CoWaitForMultipleHandles Waits for specified handles to be signaled or for a specified


timeout period to elapse.

CoWaitForMultipleObjects A replacement for CoWaitForMultipleHandles primarily


intended for use by Windows Store apps and components.
This replacement API hides the options for
CoWaitForMultipleHandles that are not supported in ASTA.

CreateAntiMoniker Creates and returns a new anti-moniker.

CreateAsyncBindCtx Creates an asynchronous bind context for use with


asynchronous monikers.

CreateBindCtx Returns a pointer to an implementation of IBindCtx (a bind


context object). This object stores information about a
particular moniker-binding operation.

CreateClassMoniker Creates a class moniker that refers to the specified class.

CreateFileMoniker Creates a file moniker based on the specified path.

CreateGenericComposite Performs a generic composition of two monikers and supplies


a pointer to the resulting composite moniker.

CreateItemMoniker Creates an item moniker that identifies an object within a


containing object (typically a compound document).
FUNCTION DESCRIPTION

CreateObjrefMoniker Creates an OBJREF moniker based on a pointer to an object.

CreatePointerMoniker Creates a pointer moniker based on a pointer to an object.

DllCanUnloadNow Determines whether the DLL that implements this function is


in use. If not, the caller can unload the DLL from memory.

DllDebugObjectRPCHook Exported by DLLs to enable remote debugging.

DllGetClassObject Retrieves the class object from a DLL object handler or object
application.

DllRegisterServer Instructs an in-process server to create its registry entries for


all classes supported in this server module.

DllUnregisterServer Instructs an in-process server to remove only those entries


created through DllRegisterServer.

GetClassFile Returns the CLSID associated with the specified filename.

GetRunningObjectTable Returns a pointer to the IRunningObjectTable interface on


the local running object table (ROT).

IIDFromString Converts a string generated by the StringFromIID function


back into the original interface identifier (IID).

Initialize Initializes a thread to use Windows Runtime APIs.

IsAccelerator Determines whether the specified keystroke maps to an


accelerator in the specified accelerator table.

IsEqualCLSID Determines whether two CLSIDs are equal.

IsEqualGUID Determines whether two GUIDs are equal.

IsEqualIID Determines whether two interface identifiers are equal.

MkParseDisplayName Converts a string into a moniker that identifies the object


named by the string.

MonikerCommonPrefixWith Creates a new moniker based on the common prefix that this
moniker (the one comprising the data of this moniker object)
shares with another moniker.

MonikerRelativePathTo Provides a moniker that, when composed onto the end of the
first specified moniker (or one with a similar structure), yields
the second specified moniker.

OleDoAutoConvert Automatically converts an object to a new class if automatic


conversion for that object class is set in the registry.
FUNCTION DESCRIPTION

OleGetAutoConvert Determines whether the registry is set for objects of a


specified CLSID to be automatically converted to another
CLSID, and if so, retrieves the new CLSID.

OleGetIconOfClass Returns a handle to a metafile containing an icon and a string


label for the specified CLSID.

OleGetIconOfFile Returns a handle to a metafile containing an icon and string


label for the specified file name.

OleIconToCursor Converts an icon to a cursor.

OleRegGetMiscStatus Returns miscellaneous information about the presentation and


behaviors supported by the specified CLSID from the registry.

OleRegGetUserType Gets the user type of the specified class from the registry.

OleSetAutoConvert Specifies a CLSID for automatic conversion to a different class


when an object of that class is loaded.

ProgIDFromCLSID Retrieves the ProgID for a given CLSID.

StringFromCLSID Converts a CLSID into a string of printable characters.


Different CLSIDs always convert to different strings.

StringFromGUID2 Converts a globally unique identifier (GUID) into a string of


printable characters.

StringFromIID Converts an interface identifier into a string of printable


characters.
DllDebugObjectRPCHook function
1/7/2020 • 2 minutes to read • Edit Online

Exported by COM DLLs to enable remote debugging.

Syntax
BOOL WINAPI DllDebugObjectRPCHook(
BOOL fTrace,
LPORPC_INIT_ARGS lpOrpcInitArgs
);

Parameters
f If TRUE, remote debugging is enabled. If FALSE, remote debugging is not enabled.
T
r
a
c
e

l A pointer to an ORPC_INIT_ARGS structure.


p
O
r
p
c
I
n
i
t
A
r
g
s

Return value
TRUE if successful, FALSE otherwise

Requirements

Minimum supported client Windows 2000 Professional [desktop apps only]

Minimum supported server Windows 2000 Server [desktop apps only]


Header
N/A

Library
Ole
32.li
b

DLL
Ole
32.d
ll

See also
O
R
P
C
_
D
B
G
_
A
L
L

O
R
P
C
_
D
B
G
_
B
U
F
F
E
R

O
R
P
C
_
I
N
I
T
_
A
R
G
S

I
O
r
p
c
D
e
b
u
g
N
o
t
i
f
y
OLE and Data Transfer
1/7/2020 • 2 minutes to read • Edit Online

The following sections describe compound documents, the mechanism provided by the Component Object Model
(COM ) to transfer data between applications, and the APIs that are used to create compound documents and
perform data transfer.
Guide
Reference

Related topics
C
o
m
p
o
n
e
n
t
O
b
j
e
c
t
M
o
d
e
l
(
C
O
M
)
Guide
1/7/2020 • 2 minutes to read • Edit Online

This guide describes compound documents and the COM data transfer mechanism.
Compound Documents
Data Transfer

Related topics
R
e
f
e
r
e
n
c
e
Compound Documents
1/7/2020 • 2 minutes to read • Edit Online

OLE compound documents enable users working within a single application to manipulate data written in
various formats and derived from multiple sources. For example, a user might insert into a word processing
document a graph created in a second application and a sound object created in a third application. Activating
the graph causes the second application to load its user interface, or at least that part containing tools necessary
to edit the object. Activating the sound object causes the third application to play it. In both cases, a user is able to
manipulate data from external sources from within the context of a single document.
OLE compound document technology rests on a foundation consisting of COM, structured storage, and uniform
data transfer. As summarized below, each of these core technologies plays a critical role in OLE compound
documents:

C
O
M

A compound document object is essentially a COM object that can be embedded in, or linked to, an
existing document. As a COM object, a compound document object exposes the IUnknown interface,
through which clients can obtain pointers to its other interfaces, including several, such as IOleObject,
IOleLink, and IViewObject2, that provide special features unique to compound document objects.

S
t
r
u
c
t
u
r
e
d
S
t
o
r
a
g
e

A compound document object must implement the IPersistStorage or, optionally, IPersistStream
interfaces to manage its own storage. A container used to create compound documents must supply the
IStorage interface, through which objects store and retrieve data. Containers almost always provide
instances of IStorage obtained from OLE's Compound Files implementation. Containers must also use an
object's IPersistStorage and/or IPersistStream interfaces.

U
n
i
f
o
r
m
D
a
t
a
T
r
a
n
s
f
e
r

Applications that support compound documents must implement IDataObject because embedded
objects and linked objects begin as data that has been transferred using special OLE clipboard formats,
rather than standard Microsoft Windows clipboard formats. In other words, formatting data as an
embedded or linked object is simply one more option provided by OLE's uniform data transfer model.

OLE's compound document technology benefits both software developers and users alike. Instead of feeling
obligated to cram every conceivable feature into a single application, software developers are now free, if they
like, to develop smaller, more focused applications that rely on other applications to supply additional features. In
cases where a software developer decides to provide an application with capabilities beyond its core features, the
developer can implement these additional services as separate DLLs, which are loaded into memory only when
their services are required. Users benefit from smaller, faster, more capable software that they can mix and match
as needed, manipulating all required components from within a single master document.
For more information, see the following topics:
Containers and Servers
Linking and Embedding
Object Handlers
In-Process Servers
Linked Objects and Monikers
Notifications
Compound Document Interfaces
Object States
Implementing In-Place Activation
Creating Linked and Embedded Objects from Existing Data
View Caching

Related topics
D
a
t
a
T
r
a
n
s
f
e
r

S
t
r
u
c
t
u
r
e
d
S
t
o
r
a
g
e
Containers and Servers
1/7/2020 • 2 minutes to read • Edit Online

Compound document applications are of two basic types: container applications and server applications. OLE
container applications provide users with the ability to create, edit, save, and retrieve compound documents. OLE
server applications provide users with the means to create documents and other data representations that can be
contained as either links or embeddings in container applications. An OLE application can be a container
application, a server application, or both.
OLE server applications also differ in whether they are implemented as in-process servers or local servers. An in-
process server is a dynamic link library (DLL ) that runs in the container application's process space. You can run an
in-process server only from within the container application.

NOTE
Future releases of OLE will enable linking and embedding across computer boundaries, so that a container application on one
computer will be able to use a compound document object provided by a remote server running on another computer. From
a container application's point of view, any OLE server application that runs in its own process space, whether on the same
computer or a remote computer, is an out-of-process server.

Related topics
C
o
m
p
o
u
n
d
D
o
c
u
m
e
n
t
s

I
n
-
P
r
o
c
e
s
s
S
e
r
v
e
r
s
Linking and Embedding
1/7/2020 • 2 minutes to read • Edit Online

Users can create two types of compound-document objects: linked or embedded. The difference between the two
types lies in how and where the object's source data is stored. Where the object resides affects, in turn, the object's
portability and methods of activation, how data updates are performed, and the size and structure of its container.
Linked Objects
Embedded Objects

Related topics
C
o
m
p
o
u
n
d
D
o
c
u
m
e
n
t
s
Linked Objects
1/7/2020 • 2 minutes to read • Edit Online

When a link to an object is inserted in a compound document, the source data, or link source, continues to reside
wherever it was initially created, usually in another document. The compound document contains only a reference,
or link, to the actual data stored at the link source, along with information about how to present that data to the
user.
Activating a link runs the link source's server application, which the user requires in order to edit or otherwise
manipulate the link data. Linking keeps the size of a compound document small. It is also useful when the data
source is maintained by someone else and must be shared among many users. If the person maintaining the link
source changes the data, the change is automatically updated in all documents containing a link to that data. In
addition to creating simple links, users can nest links and combine linked and embedded objects to create complex
documents.

Related topics
C
r
e
a
t
i
n
g
L
i
n
k
e
d
a
n
d
E
m
b
e
d
d
e
d
O
b
j
e
c
t
s
f
r
o
m
E
x
i
s
t
i
n
g
D
a
t
a

D
i
s
t
r
i
b
u
t
e
d
L
i
n
k
T
r
a
c
k
i
n
g
a
n
d
O
b
j
e
c
t
I
d
e
n
t
i
f
i
e
r
s

L
i
n
k
e
d
O
b
j
e
c
t
s
a
n
d
M
o
n
i
k
e
r
s
Embedded Objects
1/7/2020 • 2 minutes to read • Edit Online

An embedded object is physically stored in the compound document, along with all the information needed to
manage the object. In other words, the embedded object is actually a part of the compound document in which it
resides. This arrangement has a couple of disadvantages. First, a compound document containing embedded
objects will be larger than one containing the same objects as links. Second, changes made to the source of an
embedded object will not be automatically replicated in the embedded copy, and changes in the source will not be
reflected in the source, as they are with a link.
Still, for certain purposes, embedding offers several advantages over links. First, users can transfer compound
documents with embedded objects to other computers, or other locations on the same computer, without breaking
a link. Second, users can edit embedded objects without changing the content of the original. Sometimes, this
separation is precisely what is required. Third, embedded objects can be activated in place, meaning that the user
can edit or otherwise manipulate the object without having to work in a separate window from that of the object's
container. Instead, when the object is activated, the container application's user interface changes to expose those
tools that are necessary to manage or modify the object.

Related topics
C
r
e
a
t
i
n
g
L
i
n
k
e
d
a
n
d
E
m
b
e
d
d
e
d
O
b
j
e
c
t
s
f
r
o
m
E
x
i
s
t
i
n
g
D
a
t
a
Object Handlers
1/7/2020 • 2 minutes to read • Edit Online

If an OLE server application is a local server, meaning that it runs in its own process space, communication
between container and server must occur across process boundaries. Because this process is expensive, OLE relies
on a surrogate object loaded into the container's process space to act on behalf of a local server application. This
surrogate object, known as an object handler, services container requests that do not require the attention of the
server application, such as requests for drawing. When a container requests something that the object handler
cannot provide, the handler communicates with the server application using COM's out-of-process
communication mechanism.
An object handler is unique to an object class. When you create an instance of a handler for one class, you cannot
use it for another. When used for a compound document, the object handler implements the container-side data
structures when objects of a particular class are accessed remotely.
OLE provides a default object handler that local server applications can use. For applications that require special
behaviors, developers can implement a custom handler that either replaces the default handler or uses it to
provide certain default behaviors.
An object handler is a DLL containing several interacting components. These components include remoting pieces
to manage communication between the handler and its server application, a cache for storing an object's data,
along with information on how that data should be formatted and displayed, and a controlling object that
coordinates the activities of the DLL's other components. In addition, if an object is a link, the DLL also includes a
linking component, or linked object, which keeps track of the name and location of the link source.
The cache contains data and presentation information sufficient for the handler to display a loaded, but not
running, object in its container. OLE provides an implementation of the cache used by OLE's default object handler
and the link object. The cache stores data in formats needed by the object handler to satisfy container draw
requests. When an object's data changes, the object sends a notification to the cache so that an update can occur.
For more information on the cache, see View Caching.
For more information, see the following topic:
The Default Handler and Custom Handlers

Related topics
C
o
m
p
o
u
n
d
D
o
c
u
m
e
n
t
s
The Default Handler and Custom Handlers
1/7/2020 • 2 minutes to read • Edit Online

The default handler, an implementation provided by OLE, is used by most applications as the handler. An
application implements a custom handler when the default handler's capabilities are insufficient. A custom handler
can either completely replace the default handler or use parts of the functionality it provides where appropriate. In
the latter case, the application handler is implemented as an aggregate object composed of a new control object
and the default handler. Combination application/default handlers are also known as in-process handlers. The
remoting handler is used for objects that are not assigned a CLSID in the system registry or that have no specified
handler. All that is required from a handler for these types of objects is that they pass information across the
process boundary.

Related topics
O
b
j
e
c
t
H
a
n
d
l
e
r
s
In-Process Servers
1/7/2020 • 2 minutes to read • Edit Online

If you implement an OLE server application as an in-process server — a DLL running in the process space of the
container application — rather than as a local server — an EXE running in its own process space —
communication between container and server is simplified because communication between the two can take the
form of normal function calls. Remote procedure calls are not required because the two applications run in the
same process space. As you would expect, the objects that manage the marshaling of parameters are also
unnecessary, although they may be aggregated within the DLL without interfering with the communication
between container and server.
When an OLE server application is implemented as an in-process server, a separate object handler is not required
because the server itself lives in the client's process space. The main difference between an in-process server and
object handler is that the server is able to manage the object in a running state while the handler cannot. One
consequence of this difference is that a server must provide a user interface for manipulating the running object,
while a handler delegates this requirement to the object's server. In creating an in-process server, you can
aggregate on the OLE default handler, letting it handle basic chores, such as display, storage, and notifications
while you implement only those services that the handler either does not provide or does not implement in the
way you require.
For more information, see the following topics:
Advantages
Disadvantages

Related topics
C
o
m
p
o
u
n
d
D
o
c
u
m
e
n
t
s
Advantages
1/7/2020 • 2 minutes to read • Edit Online

The advantages of implementing your application as an in-process server are speed and combining some the
advantages of an object handler and a local server. In-process servers are faster than local servers for several
reasons. First, because they are smaller and run in the process space of the container application, they load more
quickly. Second, they are optimized to perform certain tasks. Third, communication between container and server
does not rely on remote procedure calls.

Related topics
D
i
s
a
d
v
a
n
t
a
g
e
s

I
n
-
P
r
o
c
e
s
s
S
e
r
v
e
r
s
Disadvantages
1/7/2020 • 2 minutes to read • Edit Online

In-process servers provide the speed and size advantage of an object handler with the editing capability of a local
server. So why would you ever choose to implement your OLE application as a local server rather than an in-
process server? There are several reasons:
Security. Only a local server has its address space isolated from that of the client. An in-process server shares
the address space and process context of the client and can therefore be less robust in the face of faults or
malicious programming.
Granularity. A local server can host multiple instances of its object across many different clients, sharing server
state between objects in multiple clients in ways that would be difficult or impossible if implemented as an in-
process server, which is simply a DLL loaded into each client.
Compatibility. If you choose to implement an in-process server, you relinquish compatibility with OLE 1, which
does not support such servers. This will not be a consideration for many developers, but if it is, then it is of
critical concern.
Inability to support links. An in-process server cannot serve as a link source. Since a DLL cannot run by itself, it
cannot create a file object to be linked to.
Despite these disadvantages, an in-process server can be an excellent choice for its speed and size — if it fits all
your other requirements.

Related topics
A
d
v
a
n
t
a
g
e
s

I
n
-
P
r
o
c
e
s
s
S
e
r
v
e
r
s
Linked Objects and Monikers
1/7/2020 • 2 minutes to read • Edit Online

Linked objects, like embedded objects, rely on an object handler to communicate with server applications. The
linked object itself, however, manages the naming and tracking of link sources. The linked object acts like an in-
process server. For example, when activated, a linked object locates and launches the OLE server application that is
the link source.
A linked object's handler is made up of two main components: the handler component and the linking component.
The handler component contains the controlling and remoting pieces and functions much like a handler for an
embedded object. The linking component has its own controller and cache and provides access to the object's
structured storage. The linking components controller supports source naming through the use of monikers, and
binding, the process of locating and running the link source. (For more information on monikers and binding, see
The Component Object Model.)
When a user initially creates a linked object or loads an existing one from storage, the container loads an instance
of the linking component into memory, along with the object handler. The linking component supplies interfaces
— most notably IOleLink— that identify the object as a link and enable it to manage the naming, tracking, and
updating of its link source.
By implementing the IOleLink interface, a linked object provides its container with functions that support linking.
Only linked objects implement IOleLink, and by querying for this interface a container can determine whether a
given object is embedded or linked. The most important function provided by IOleLink enables a container to
binding to the source of the linked object, that is, to activate the connection to the document that stores the linked
object's native data. IOleLink also defines functions for managing information about the linked object, such as
cached presentation data and the location of the link source.
When a compound document containing a linked object is saved, the link's data is saved with the link source, not
with the container. Only information about its name and location is saved along with the compound document.
This behavior is in contrast to that of an embedded object, whose data is stored along with that of its container.
Container applications can provide information about their embedded objects such that the latter, or portions
thereof, can act as link sources. By implementing support for linking to your container's embedded objects, you
make nested embeddings possible, relieving the user of having to track down the originals of every embedding
object to which a link is desired. For example, if a user wants to embed a Microsoft Excel worksheet in Microsoft
Word, and the worksheet contains a bitmap created in Paintbrush, the user can link to a copy of the bitmap
contained in the worksheet rather than the original.

Related topics
C
o
m
p
o
u
n
d
D
o
c
u
m
e
n
t
s

I
n
-
P
r
o
c
e
s
s
S
e
r
v
e
r
s

O
b
j
e
c
t
H
a
n
d
l
e
r
s
Notifications
1/7/2020 • 2 minutes to read • Edit Online

Notifications are callbacks generated by an object when it detects a change in its name, state, data, or presentation.
Containers and other clients require notifications to respond appropriately to these changes. A container registers
to receive notifications by setting up an advisory connection to an object of interest. Other interested clients can do
the same. The container also creates an advisory sink to receive the notifications. Using the connection established
by the container, an object experiencing a change notifies the advisory sink. Upon receiving a notification, the
container takes whatever action has been defined for the type of change that has occurred.
For more information, see the following topics:
Types of Notifications
How Notifications Work

Related topics
C
o
m
p
o
u
n
d
D
o
c
u
m
e
n
t
s
Types of Notifications
1/7/2020 • 2 minutes to read • Edit Online

Notifications fall into three groups: compound document, data, and view. An object sends compound document
notifications in response to being renamed, saved, closed or, in the case of a link, having its link source renamed. As
you would expect, objects send data notifications in response to changes in their data and send view notifications
in response to changes in their presentation. Container applications must register separately for each of these
notification types, but all can be handled by a single advisory sink.
All containers, the object handler, and the linked object register for compound document notifications. The typical
container also registers for view notifications. Data notifications are usually sent to both the linked object and
object handler. A special purpose container, such as one that renders the data itself, might benefit from receiving
data notifications instead of view notifications. For example, an embedded chart container with a link to a table can
register for data notifications. Because a change to the table affects the chart, the receipt of a data notification
would direct the container to get the new tabular data.

Related topics
N
o
t
i
f
i
c
a
t
i
o
n
s
How Notifications Work
1/7/2020 • 2 minutes to read • Edit Online

Notifications originate in the object application and flow to the container by way of the object handler. If the object
is a linked object, the linked object intercepts the notifications from the object handler and notifies the container
directly.
An object application must manage registration requests, keeping track of where to send which notifications and
sending those notifications when appropriate. OLE provides two component objects to simplify this task: the
OleAdviseHolder for compound document notifications and the DataAdviseHolder for data notifications.
Object applications determine the conditions that prompt the sending of each specific notification and the
frequency with which each notification should be sent. When it is appropriate for multiple notifications to be sent, it
does not matter which notification is sent first; they can be sent in any order.
The timing of notifications affects the performance and coordination between an object application and its
containers. Whereas notifications sent too frequently slow processing, notifications sent too infrequently result in
an out-of-sync container. Notification frequency can be compared with the rate at which an application repaints.
Therefore, using similar logic for the timing of notifications (as is used for repainting) is wise.

Related topics
C
r
e
a
t
e
D
a
t
a
A
d
v
i
s
e
H
o
l
d
e
r

C
r
e
a
t
e
O
l
e
A
d
v
i
s
e
H
o
l
d
e
r

N
o
t
i
f
i
c
a
t
i
o
n
s
Compound Document Interfaces
1/7/2020 • 2 minutes to read • Edit Online

The following tables list the interfaces implemented by OLE containers, OLE servers, and compound document
objects. The required interfaces must be implemented on the components for which they are listed. All other
features are optional. If you want to include a particular feature in your application, however, you must implement
the interfaces shown for that feature in the table below. All other interfaces are required only if you are including a
particular feature.
The following table lists required and optional behaviors for OLE containers and which interfaces you must
implement for each.

BEHAVIOR INTERFACES

Required behaviors IOleClientSite


IAdviseSink

Message filtering IMessageFilter

Linking none

Linking to embedded objects IOleItemContainer


IPersistFile
IClassFactory

In-place activation IOleInPlaceSite


IOleInPlaceFrame
IOleInPlaceObject

Drag and drop IDropSource


IDropTarget
IDataObject

The following table lists required and optional behaviors for OLE servers and their compound document objects
and which interfaces you must implement for each. The table distinguishes OLE servers and their objects in order
to clarify which component implements which interfaces. The table also notes the different requirements of objects
provided by out-of-process versus in-process servers.

FEATURE OLE SERVER OBJECT (OUT-OF-PROCESS) OBJECT (IN-PROCESS)

Required behaviors IClassFactory IOleObject IOleObject


IDataObject IDataObject
IPersistStorage IPersistStorage
IViewObject2
IOleCache2

Message filtering IMessageFilter

Linking IOleItemContainer IOleLink


IPersistFile IExternalConnection
FEATURE OLE SERVER OBJECT (OUT-OF-PROCESS) OBJECT (IN-PROCESS)

In-place activation IOleInPlaceObject IOleInPlaceObject


IOleInPlaceActiveObject IOleInPlaceActiveObject

Drag and drop IDropSource


IDropTarget
IDataObject

Related topics
C
o
m
p
o
u
n
d
D
o
c
u
m
e
n
t
s
Object States
1/7/2020 • 2 minutes to read • Edit Online

A compound object exists in one of three states: passive, loaded, or running. A compound-document object's state
describes the relationship between the object in its container and the application responsible for its creation. The
following table summarizes these states.

OBJECT STATE DESCRIPTION

Passive The compound-document object exists only in storage, either


on disk or in a database. In this state, the object is unavailable
for viewing or editing.

Loaded The object's data structures created by the object handler are
in the container's memory. The container has established
communication with the object handler and there is cached
presentation data available for rendering the object. Calls are
processed by the object handler. This state, because of its low
overhead, is used when a user is simply viewing or printing an
object.

Running The objects that control remoting have been created and the
OLE server application is running. The object's interfaces are
accessible, and the container can receive notification of
changes. In this state, an end user can edit or otherwise
manipulate the object.

For more information, see the following topics:


Entering the Loaded State
Entering the Running State
Entering the Passive State

Related topics
C
o
m
p
o
u
n
d
D
o
c
u
m
e
n
t
s
Entering the Loaded State
1/7/2020 • 2 minutes to read • Edit Online

When an object enters the loaded state, the in-memory structures representing the object are created so that
operations can be invoked on it. The object's handler or in-process server is loaded. This process, referred to as
instantiation, occurs when an object is loaded from persistent storage (a transition from the passive to the loaded
state) or when an object is being created for the first time.
Internally, instantiation is a two-phase process. An object of the appropriate class is created, after which a method
on that object is called to perform initialization and give access to the object's data. The initialization method is
defined in one of the object's supported interfaces. The particular initialization method called depends on the
context in which the object is being instantiated and the location of the initialization data.
Entering the Running State
1/7/2020 • 2 minutes to read • Edit Online

When an embedded object makes the transition to the running state, the object handler must locate and run the
server application in order to utilize the services that only the server provides. Embedded objects are placed in the
running state either explicitly through a request by the container, such as a need to draw a format not currently
cached, or implicitly by OLE in response to invoking some operation, such as when a user of the container double-
clicks the object.
When a linked object makes the transition into the running state, the process is known as binding. In the process of
binding, the object handler asks its stored moniker to locate the link's data, then runs the server application.
At first glance, binding a linked object appears to be no more complicated than running an embedded object.
However, the following points complicate the process:
A link can refer to an object, or a portion thereof, that is embedded in another container. This capability implies
a potential for nested embeddings. Resolving references to such a hierarchy requires recursively traversing a
composite moniker, beginning with the rightmost member.
When the link source is running, OLE binds to the running instance of the object rather than running another
instance. In the case of nested embedded objects, one of which is the link source, OLE must be able to bind to
an already running object at any point.
Running an object requires accessing the storage area for the object. When an embedded object is run, OLE
receives a pointer to the storage during the load process, which it passes on to the OLE server application. For
linked objects, however, there is no standard interface for accessing storage. The OLE server application may
use the file system interface or some other mechanism.
Entering the Passive State
1/7/2020 • 2 minutes to read • Edit Online

Object closure forces an embedded or linked object into the passive state. It is typically initiated from the OLE
server application's user interface, such as when the user selects the File Close command. In this case, the OLE
server application notifies the container, which releases its reference count on the object. When all references to the
object have been released, the object can be freed. When all objects have been freed, the OLE server application
can safely terminate.
A container application can also initiate object closure. To close an object, the container releases its reference count
after completing an optional save operation. You can design containers to release objects when they are
deactivating after an in-place activation session, allowing the user to click outside the object without losing the
active editing session.
Implementing In-Place Activation
1/7/2020 • 2 minutes to read • Edit Online

In-place activation enables a user to interact with an embedded object without leaving the container document.
When a user activates the object, a composite menu bar comprising elements from both the container application's
and server application's menu bars replaces the container's main menu bar. Commands and features from both
applications are thus available to the user, including context sensitive help for the active object. When a user begins
working with some non-object portion of the document, the object is deactivated, causing the container
document's original menu to replace the composite menu.
This capability originally went by the name of in-place editing. The name was changed because editing is only one
way for a user to interact with a running object. Sound clips, for example, can be listened to instead of editing.
Video clips can be viewed instead of editing. In-place activation is particularly apt in the case of video clips because
it allows them to run in place, without calling up a separate window. This could be critical if the video were to be
viewed, say, in conjunction with adjacent text data in the container document.
Implementing in-place activation is strictly optional for both container and server applications. OLE still supports
the model in which activating an object causes the server application to open a separate window. Linked objects
always open in a separate window to emphasize that they reside in a separate document.
In-place activation begins with the object in response to an IOleObject::DoVerb call from its container. This call
usually happens in response to a user double-clicking the object or selecting a command (verb) from the container
application's Edit menu.
The in-place window receives keyboard and mouse input while the embedded object is active. When a user selects
commands from the composite menu bar, the command and associated menu messages are sent to the container
or object application, depending on which owns the particular drop-down menu selected. Input by means of an
object's rulers, toolbars, or frame adornments go directly to the embedded object, which owns these windows.
An in-place-activated embedded object remains active until either the container deactivates it in response to user
input or the object voluntarily gives up the active state, as a video clip might do, for example. A user can deactivate
an object by clicking inside the container document but outside the object's in-place-activation window, or simply
by clicking another object. An in-place-activated object remains active, however, if the user clicks the container's
title bar, scroll bar or, in particular, menu bar.
You can implement an in-place-activation-object server either as an in-process server (DLL ) or a local server (EXE ).
In both cases, the composite menu bar contains items (typically drop-down menus) from both the server and
container processes. In the case of a in-process server, the in-place activation window is simply another child
window in the container's window hierarchy, receiving its input through the container application's message pump.
In the case of a local server, the in-place activation window belongs to the embedded object's server application
process, but its parent window belongs to the container. Input for the in-place-activation window appears in the
server's message queue and is dispatched by the server's message loop. The OLE libraries are responsible for
seeing to it that menu commands and messages are dispatched correctly.

Related topics
C
o
m
p
o
u
n
d
D
o
c
u
m
e
n
t
s
Creating Linked and Embedded Objects from
Existing Data
1/7/2020 • 2 minutes to read • Edit Online

A user typically assembles a compound document by using either the clipboard or drag and drop to copy a data
object from its server application to the user's container application. With applications that support OLE, the user
can initiate the transfer from either the server or the container. For example, the server can copy data to the
clipboard in the server application, then switch to the container application and choose Paste Special/Embedded
Object or an equivalent menu command to create a new embedded object from the selected data. Or, the user can
drag the data from one application to the other. The process is similar for creating a linked object.

NOTE
An application that functions as both OLE server and container can use a selection of its own data to create an embedded or
linked object at a new location within the same document.

Data transfer between OLE server and container applications is built on uniform data transfer, as described in
Data Transfer. OLE servers and object handlers implement IDataObject in order to make their data available for
transfers using either the clipboard or drag and drop. OLE objects support all the usual clipboard formats. In
addition, they support six clipboard formats that support the creation of linked and embedded objects from a
selected data object.
OLE clipboard formats describe data objects that, upon being dropped or pasted in OLE containers, are to become
embedded or linked compound-document objects. The data object presents these formats to container
applications in order of their fidelity as descriptions of the data. In other words, the object presents first the format
that best represents it, followed by the next best format, and so on. This intentional ordering encourages a
container application to use the best possible format.

Related topics
C
o
m
p
o
u
n
d
D
o
c
u
m
e
n
t
s

D
a
t
a
T
r
a
n
s
f
e
r
View Caching
1/7/2020 • 4 minutes to read • Edit Online

A container application must be able to obtain a presentation of an object for the purpose of displaying or printing
it for users when the document is open but the object's server application is not running or is not installed on the
user's machine. To assume, however, that the servers for all the objects that might conceivably be found in a
document are installed on every user's machine and can always run on demand is unrealistic. The default object
handler, which is available at all times, solves this dilemma by caching object presentations in the document's
storage and manipulating these presentations on any platform regardless of the availablility of the object server
on any particular installation of the container.
Containers can maintain drawing presentations for one or more specific target devices in addition to the one
required to maintain the object on screen. Moreover, if you port the object from one platform to another, OLE
automatically converts the object's data formats to ones supported on the new platform. For example, if you move
an object from Windows to the Macintosh, OLE will convert its metafile presentations to PICT formats.
In order to present an accurate representation of an embedded object to the user, the object's container application
initiates a dialog with the object handler, requesting data and drawing instructions. To be able to fulfill the
container's requests, the handler must implement the IDataObject, IViewObject2, and IOleCache interfaces.
IDataObject enables an OLE container application to get data from and send data to its embedded or linked
objects. When data changes in an object, this interface provides a way for the object to make its new data available
to its container and provides the container with a way to update the data in its copy of the object. (For a discussion
of data transfer in general, see Chapter 4, Data Transfer.)
The IViewObject2 interface is very much like the IDataObject interface except that it asks an object to draw
itself on a device context, such as a screen, printer, or metafile, rather than move or copy its data to memory or
some other transfer medium. The purpose of the interface is to enable an OLE container to obtain alternative
pictorial representations of its embedded objects, whose data it already has, thereby avoiding the overhead of
having to transfer entirely new instances of the same data objects simply to obtain new drawing instructions.
Instead, the IViewObject2interface enables the container to ask an object to provide a pictorial representation of
itself by drawing on a device context specified by the container.
When calling the IViewObject2 interface, a container application can also specify that the object draw itself on a
target device different than the one on which it will actually be rendered. This enables the container, as needed, to
generate different renderings from a single object. For example, the caller could ask the object to compose itself
for a printer even though the resulting drawing will be rendered on screen. The result, of course, would be a print-
preview of the object.
The IViewObject2interface also provides methods that enable containers to register for view -change
notifications. As with data and OLE advisories, a view advisory connection enables a container to update its
renderings of an object at its own convenience rather than in response to a call from the object. For example, if a
new version of an object's server application were to offer additional views of the same data, the object's default
handler would call each container's implementation of IAdviseSink::OnViewChange to let them know that the
new presentations were available. The container would retrieve this information from the advise sink only when
needed.
Because Windows device contexts have meaning only within a single process, you cannot pass IViewObject2
pointers across process boundaries. As a result, OLE local and remote servers have no need whatsoever to
implement the interface, which wouldn't work properly even if they did. Only object handlers and in-process
servers implement the IViewObject2interface. OLE provides a default implementation, which you can use in your
own OLE in-process servers and object handlers simply by aggregating the OLE default handler. Or you can write
your own implementation of IViewObject2.
An object implements the IOleCache interface in order to let the handler know what capabilities it should cache.
The object handler also owns the cache and ensures it is kept up to date. As the embedded object enters the
running state, the handler sets up appropriate advisory connections on the server object, with itself acting as the
sink. The IDataObject and IViewObject2interface implementations operate out of data cached on the client side.
The handler's implementation of IViewObject2is responsible for determining what data formats to cache in order
to satisfy client draw requests. The handler's implementation of IDataObject is responsible for getting data in
various formats, etc., between memory and the underlying IStorage instance of the embedded object. Custom
handlers can use these implementations by aggregating on the default handler.

NOTE
The IViewObject2 interface is a simple functional extension of IViewObject and should be implemented instead of the latter
interface, which is now obsolete. In addition to providing the IViewObject methods, the IViewObject2 interface provides a
single additional member, GetExtent, which enables a container application to get the size of an object's presentation from
the cache without first having to move the object into the running state with a call to IOleObject::GetExtent.

Related topics
C
o
m
p
o
u
n
d
D
o
c
u
m
e
n
t
s
Data Transfer
1/7/2020 • 2 minutes to read • Edit Online

The Component Object Model (COM ) provides a standard mechanism for transferring data between applications.
This mechanism is the data object, which is simply any COM object that implements the IDataObject interface.
Some data objects, such as a piece of text copied to the clipboard, have IDataObject as their sole interface.
Others, such as compound document objects, expose several interfaces, of which IDataObject is simply one.
Data objects are fundamental to the working of compound documents, although they also have widespread
application outside that OLE technology.
By exchanging pointers to a data object, providers and consumers of data can manage data transfers in a uniform
manner, regardless of the format of the data, the type of medium used to transfer the data, or the target device on
which it is to be rendered. You can include support in your application for basic clipboard transfers, drag and drop
transfers, and OLE compound document transfers with a single implementation of IDataObject. Having done
that, the amount of code required to accommodate the special semantics of each protocol is minimal.
For more information, see the following topics:
Data Transfer Interfaces
Data Formats and Transfer Media
Drag and Drop

Related topics
C
o
m
p
o
u
n
d
D
o
c
u
m
e
n
t
s
Data Transfer Interfaces
1/7/2020 • 2 minutes to read • Edit Online

The IDataObject interface provides consumers of data with methods for getting and setting an object's data,
determining which formats the object supports, and registering for and receiving notifications when data in the
object changes. When obtaining data, a caller can specify the format in which it wants to render the data. The
source of the data, however, determines the storage medium, which it returns in an out parameter provided by the
caller.
By itself, IDataObject supplies all the tools you need to implement Windows clipboard transfers or compound
document transfers in your applications. If you also want to support drag and drop transfers, you need to
implement the IDropSource and IDropTarget interfaces along with IDataObject.
The IDataObject interface combined with OLE clipboard APIs provide all the capabilities of the Windows
clipboard APIs. It is not generally necessary to use both clipboard APIs. Data suppliers that support either drag
and drop transfers or OLE compound documents must implement the IDataObject interface. If your application
supports only clipboard transfers now, but you intend to add drag and drop or compound documents in later
releases, you may want to implement IDataObject and the OLE clipboard APIs now in order to minimize the
amount of time spent recoding and debugging later. You may also want to implement IDataObject in order to
utilize transfer media other than global memory.
The following table summarizes which ones to use, depending on what types of data transfer you want to support:

TO SUPPORT USE

Compound documents IDataObject

Drag and drop transfers IDataObject, IDropSource, IDropTarget, DoDragDrop (or


the equivalent)

Clipboard transfers using global memory exclusively Clipboard API

Clipboard transfers using exchange mediums other than IDataObject


global memory.

Clipboard transfers now but drag and drop or compound IDataObject and the interfaces and function listed above for
documents later "Drag and drop transfers"

When a user initiates a data transfer operation, the source application creates an instance of IDataObject and
through it makes the data available in one or more formats. In a clipboard transfer, the application calls the
OleSetClipboard function to pass a data-object pointer to OLE. (OleSetClipboard also offers standard clipboard
data formats for both OLE version 1 and non-OLE applications.) In a drag and drop transfer, the application calls
the DoDragDrop function instead.
On the receiving side of the transfer, the destination receives the IDataObject pointer either as an argument to an
invocation of IDropTarget::Drop or by calling the OleSetClipboard function, depending on whether the transfer
is by means of drag and drop or the clipboard. Having obtained this pointer, the destination calls
IDataObject::EnumFormatEtc to learn what formats are available for retrieval and on what types of media they
can be obtained. Armed with this information, the receiving application requests the data with a call to
IDataObject::GetData.
Related topics
D
a
t
a
T
r
a
n
s
f
e
r
Data Formats and Transfer Media
1/7/2020 • 2 minutes to read • Edit Online

Most platforms, including Windows, define a standard protocol for transferring data between applications, based
on a set of functions called the clipboard. Applications using these functions can share data even if their native data
formats are wildly different. Generally, these clipboards have two significant shortcomings that COM has
overcome.
First, data descriptions use only a format identifier, such as the single 16-bit clipboard format identifier on
Windows, which means the clipboard can only describe the structure of its data, that is, the ordering of the bits. It
can report, "I have a bitmap" "or I have some text," but it cannot specify the target devices for which the data is
composed, which views or aspects of itself the data can provide, or which storage media are best suited for its
transfer. For example, it cannot report, "I have a string of text that is stored in global memory and formatted for
presentation either on screen or on a printer" or "I have a thumbnail sketch bitmap rendered for a 100 dpi dot-
matrix printer and stored as a disk file."
Second, all data transfers using the clipboard generally occur through global memory. Using global memory is
reasonably efficient for small amounts of data but horribly inefficient for large amounts, such as a 20 MB
multimedia object. Global memory is slow for a large data object, whose size requires considerable swapping to
virtual memory on disk. In cases where the data being exchanged is going to reside mostly on disk anyway,
forcing it through this virtual-memory bottleneck is highly inefficient. A better way would skip global memory
entirely and simply transfer the data directly to disk.
To alleviate these problems, COM provides two data structures: FORMATETC and STGMEDIUM. For more
information, see the following topics:
The FORMATETC Structure
The STGMEDIUM Structure

Related topics
D
a
t
a
T
r
a
n
s
f
e
r
The FORMATETC Structure
1/7/2020 • 2 minutes to read • Edit Online

The FORMATETC structure is a generalized clipboard format, enhanced to encompass a target device, an aspect or
view of the data, and a storage medium. A data consumer, such as an OLE container application, passes the
FORMATETC structure as an argument in calls to IDataObject to indicate the type of data it wants from a data
source, such as a compound document object. The source uses the FORMATETC structure to describe what
formats it can provide.
FORMATETC can describe virtually any data, including other objects such as monikers. A container can ask one of
its embedded objects to list its data formats by calling IDataObject::EnumFormatEtc, which returns an
enumerator object that implements the IEnumFORMATETC interface. Instead of replying merely that it has "text
and a bitmap," the object can provide a detailed description of the data, including the device (normally screen or
printer) for which it is rendered, the aspect to be presented to the user (full contents, thumbnail, icon, or formatted
for printing), and the storage medium containing the data (global memory, disk file, storage object, or stream). This
ability to tightly describe data will, in time, result in higher quality printer and screen output as well as more
efficiency in data browsing, where a thumbnail sketch is much faster to retrieve and display than a fully detailed
rendering.
The following table lists fields of the FORMATETC data structure and the information that they specify.

FIELD SPECIFIES

cfFormat The format in which the data is to be rendered, which can be a


standard clipboard format, a proprietary format, or an OLE
format. For more information on OLE formats, see Compound
Documents.

ptd A DVTARGETDEVICE structure, which contains enough


information about a Windows target device, such as a screen
or printer, so that a handle to its device context (hDC) can be
created using the CreateDC function.

dwAspect The aspect or view of the data to be rendered; can be the full
contents, a thumbnail sketch, an icon, or formatted for
printing.

lindex The part of the aspect that is of interest; for the present, the
value must be -1, indicating that the entire view is of interest.

tymed The data's storage medium, which can be global memory, disk
file, or an instance of one of COM's structured-storage
interfaces.

Related topics
D
a
t
a
F
o
r
m
a
t
s
a
n
d
T
r
a
n
s
f
e
r
M
e
d
i
a
The STGMEDIUM Structure
1/7/2020 • 2 minutes to read • Edit Online

Just as the FORMATETC structure is an enhancement of the Windows clipboard format identifier, so the
STGMEDIUM structure is an improvement of the global memory handle used to transfer the data. The
STGMEDIUM structure includes a member, tymed, which indicates the medium to be used, and a union
comprising pointers and a handle for getting whichever medium is specified in tymed.
The STGMEDIUM structure enables both data sources and consumers to choose the most efficient exchange
medium on a per-rendering basis. If the data is so large that it should be kept on disk, the data source can indicate
a disk-based medium in its preferred format, only using global memory as a backup if that's the only medium the
consumer understands. Being able to use the best medium for exchanges as the default improves overall
performance of data exchange between applications. For example, if some of the data to be transferred is already
on disk, the source application can move or copy it to a new destination, either in the same application or in some
other, without having first to load the data into global memory. At the receiving end, the consumer of the data does
not have to write it back to disk.

Related topics
D
a
t
a
F
o
r
m
a
t
s
a
n
d
T
r
a
n
s
f
e
r
M
e
d
i
a
Drag and Drop
1/7/2020 • 2 minutes to read • Edit Online

Drag and drop refers to data transfers in which a mouse or other pointing device is used to specify both the data
source and its destination. In a typical drag and drop operation, a user selects the object to be transferred by
moving the mouse pointer to it and holding down either the left button or some other button designated for this
purpose. While continuing to hold down the button, the user initiates the transfer by dragging the object to its
destination, which can be any OLE container. Drag and drop provides exactly the same functionality as the OLE
clipboard copy and paste but adds visual feedback and eliminates the need for menus. In fact, if an application
supports clipboard copy and paste, little extra is needed to support drag and drop.
During an OLE drag and drop operation, the following three separate pieces of code are used.

DRAG-AND-DROP CODE SOURCE IMPLEMENTATION AND USE

IDropSource interface Implemented by the object containing the dragged data,


referred to as the drag source.

IDropTarget interface Implemented by the object that is intended to accept the


drop, referred to as the drop target.

DoDragDrop function Implemented by OLE and used to initiate a drag and drop
operation. After the operation is in progress, it facilitates
communication between the drag source and the drop target.

The IDropSource and IDropTarget interfaces can be implemented in either a container or in an object
application. The role of drag source or drop target is not limited to any one type of OLE application.
The OLE function DoDragDrop implements a loop that tracks mouse and keyboard movement until such time as
the drag is canceled or a drop occurs. DoDragDrop is the key function in the drag and drop process, facilitating
communication between the drag source and drop target.
During a drag and drop operation, three types of feedback can be displayed to the user.

TYPE OF FEEDBACK DESCRIPTION

Source feedback Provided by the drag source, the source feedback indicates
the data is being dragged and does not change during the
course of the drag. Typically, the data is highlighted to signal it
has been selected.

Pointer feedback Provided by the drag source, the pointer feedback indicates
what happens if the mouse is released at any given moment.
Pointer feedback changes continually as the user moves the
mouse and/or presses a modifier key. For example, if the
pointer is moved into a window that cannot accept a drop, the
pointer changes to the "not allowed" symbol.

Target feedback Provided by the drop target, target feedback indicates where
the drop is to occur.

For more information, see Drag Source Responsibilities.


Related topics
D
a
t
a
T
r
a
n
s
f
e
r
Drag Source Responsibilities
1/7/2020 • 2 minutes to read • Edit Online

The drag source is responsible for the following tasks:


Providing a data-transfer object for the drop target that exposes the IDataObject and IDropSource interfaces.
Generating pointer and source feedback.
Determining when the drag operation has been canceled or a drop operation has occurred.
Performing any action on the original data caused by the drop operation, such as deleting the data or creating a
link to it.
The main task is creating a data-transfer object that exposes the IDataObject and IDropSource interfaces. The
drag source might or might not include a copy of the selected data. Including it is not mandatory, but doing so
helps protect against inadvertent changes and allows the Clipboard operations code to be identical to the drag and
drop code.
While a drag operation is in progress, the drag source is responsible for setting the mouse pointer and, if
appropriate, for providing additional source feedback to the user. The drag source cannot provide any feedback
that tracks the mouse position other than by actually setting the real pointer (see the SetCursor function). This rule
must be enforced to avoid conflicts with the feedback provided by the drop target. (A drag source can also be a
drop target. When dropping on itself, the source/target can, of course, provide target feedback to track the mouse
position. In this case, however, it is the drop target tracking the mouse, not the source.) Based on the feedback
offered by the drop target, the source sets an appropriate pointer.

Related topics
D
r
a
g
a
n
d
D
r
o
p
Data Notification
1/7/2020 • 2 minutes to read • Edit Online

Objects that consume data from an external source sometimes need to be informed when data in that source
changes. For example, a stock ticker tape viewer that relies on data in some spreadsheet needs to be notified when
that data changes so it can update its display. Similarly, a compound document needs information about data
changes in its embedded objects so that it can update its data caches. In cases such as this, where dynamic
updating of data is desirable, sources of data require some mechanism of notifying data consumers of changes as
they occur without obligating the consumers to drop everything in order to update their data. Ideally, having been
notified that a change has occurred in the data source, a consuming object can ask for an updated copy at its
leisure.
COM's mechanism for handling asynchronous notifications of this type is an object called an advise sink, which is
simply any COM object that implements an interface called IAdviseSink. Consumers of data implement the
IAdviseSink. They register to receive notifications by handing a pointer to the data object of interest.
The IAdviseSink interfaces exposes the following methods for receiving asynchronous notifications:

METHOD NOTIFIES THE ADVISE SINK THAT

OnDataChange The calling object's data has changed.

OnViewChange The instructions for drawing the calling object have changed.

OnRename The calling object's moniker has changed.

OnSave The calling object has been saved to persistent storage.

OnClose The calling object has been closed.

As the table indicates, the IAdviseSink interface exposes methods for notifying the advise sink of events other
than changes in the calling object's data. The calling object can also notify the sink when the way in which it draws
itself changes, or it is renamed, saved, or closed. These other notifications are used mainly or entirely in the context
of compound documents, although the notification mechanism is identical. For more information on compound-
document notifications, see "Compound Documents."
In order to take advantage of the advise sink, a data source must implement IDataObject::DAdvise,
IDataObject::DUnadvise, and IDataObject::EnumDAdvise. A data consumer calls the DAdvise mothod to
notify a data object that it wishes to be notified when the object's data changes. The consuming object calls the
DUnadvise method to tear down this connection. Any interested party can call the EnumDAdvise method to
learn the number of objects having an advisory connection with a data object.
When data changes at the source, the data object calls IAdviseSink::OnDataChange on all data consumers that
have registered to receive notifications. To keep track of advisory connections and manage the dispatch of
notifications, data sources rely on an object called a data advise holder. You can create your own data advise holder
by implementing the IDataAdviseHolder interface. Or, you can let COM do it for you by calling the helper
function CreateDataAdviseHolder.

Related topics
D
a
t
a
T
r
a
n
s
f
e
r
Reference
1/7/2020 • 2 minutes to read • Edit Online

The following programming elements are used to implement compound documents and perform data transfer
between applications.
Constants
Enumerations
Functions
Interfaces
Structures
Constants
1/7/2020 • 2 minutes to read • Edit Online

The following constants are used to implement compound documents and perform data transfer between
applications.
DROPEFFECT Constants
DROPEFFECT Constants
1/7/2020 • 2 minutes to read • Edit Online

Represents information about the effects of a drag-and-drop operation. The DoDragDrop function and many of
the methods in the IDropSource and IDropTarget use the values of this enumeration.

CONSTANT/VALUE DESCRIPTION

Drop target cannot accept the data.


DR
OPE
FFE
CT_
NO
NE
0

Drop results in a copy. The original data is untouched by the


DR drag source.
OPE
FFE
CT_
CO
PY
1

Drag source should remove the data.


DR
OPE
FFE
CT_
MO
VE
2

Drag source should create a link to the original data.


DR
OPE
FFE
CT_
LIN
K
4
CONSTANT/VALUE DESCRIPTION

Scrolling is about to start or is currently occurring in the


DR target. This value is used in addition to the other values.
OPE
FFE
CT_
SCR
OLL
0x8
000
000
0

Remarks
Your application should always mask values from the DROPEFFECT enumeration to ensure compatibility with
future implementations. Presently, only some of the positions in a DROPEFFECT value have meaning. In the
future, more interpretations for the bits will be added. Drag sources and drop targets should carefully mask these
values appropriately before comparing. They should never compare a DROPEFFECT against, say,
DROPEFFECT_COPY by doing the following:

if (dwDropEffect == DROPEFFECT_COPY)...

Instead, the application should always mask for the value or values being sought as using one of the following
techniques:

if (dwDropEffect & DROPEFFECT_COPY) == DROPEFFECT_COPY)...

if (dwDropEffect & DROPEFFECT_COPY)...

This allows for the definition of new drop effects, while preserving backward compatibility with existing code.

Requirements

Minimum supported client Windows 2000 Professional [desktop apps only]

Minimum supported server Windows 2000 Server [desktop apps only]

Header
OleI
dl.h

See also
D
o
D
r
a
g
D
r
o
p

I
D
r
o
p
S
o
u
r
c
e

I
D
r
o
p
T
a
r
g
e
t
Enumerations
1/7/2020 • 2 minutes to read • Edit Online

The following enumerations are used to implement compound documents and perform data transfer between
applications.
ACTIVATEFLAGS
ADVF
DATADIR
DISCARDCACHE
DOCMISC
DVASPECT
DVASPECT2
DVASPECTINFOFLAG
DVEXTENTMODE
HITRESULT
OLECLOSE
OLECMDEXECOPT
OLECMDF
OLECMDID
OLECMDID_WINDOWSTATE_FLAG
OLECMDTEXTF
OLECONTF
OLEDCFLAGS
OLEGETMONIKER
OLELINKBIND
OLEMISC
OLERENDER
OLEUIPASTEFLAG
OLEUPDATE
OLEVERBATTRIB
OLEWHICHMK
TYMED
UASFLAGS
USERCLASSTYPE
VIEWSTATUS
Functions
1/7/2020 • 2 minutes to read • Edit Online

The following functions are used to implement compound documents and perform data transfer between
applications.
CreateDataAdviseHolder
CreateDataCache
CreateFormatEnumerator
CreateOleAdviseHolder
DoDragDrop
OleCreate
OleCreateDefaultHandler
OleCreateEmbeddingHelper
OleCreateEx
OleCreateFontIndirect
OleCreateFromData
OleCreateFromDataEx
OleCreateFromFile
OleCreateFromFileEx
OleCreateLink
OleCreateLinkEx
OleCreateLinkFromData
OleCreateLinkFromDataEx
OleCreateLinkToFile
OleCreateLinkToFileEx
OleCreateMenuDescriptor
OleCreatePictureIndirect
OleCreateStaticFromData
OleDestroyMenuDescriptor
OleDraw
OleDuplicateData
OleFlushClipboard
OleGetClipboard
OleInitialize
OleIsCurrentClipboard
OleIsRunning
OleLoad
OleLoadFromStream
OleLoadPicture
OleLoadPictureEx
OleLockRunning
OleMetafilePictFromIconAndLabel
OleNoteObjectVisible
OleQueryCreateFromData
OleQueryLinkFromData
OleRegEnumFormatEtc
OleRegEnumVerbs
OleRun
OleSave
OleSaveToStream
OleSetClipboard
OleSetContainedObject
OleSetMenuDescriptor
OleTranslateAccelerator
OleUIAddVerbMenu
OleUIBusy
OleUICanConvertOrActivateAs
OleUIChangeIcon
OleUIChangeSource
OleUIConvert
OleUIEditLinks
OleUIInsertObject
OleUIObjectProperties
OleUIPasteSpecial
OleUIPromptUser
OleUIUpdateLinks
OleUninitialize
RegisterDragDrop
ReleaseStgMedium
RevokeDragDrop
Interfaces
1/7/2020 • 4 minutes to read • Edit Online

The following interfaces are used to implement compound documents and perform data transfer between
applications.

INTERFACE DESCRIPTION

IAdviseSink Enables containers and other objects to receive notifications of


data changes, view changes, and compound-document
changes occurring in objects of interest.

IAdviseSink2 An extension to IAdviseSink that adds a method to handle a


change in the moniker of a linked object.

IAdviseSinkEx An extension to IAdviseSink that adds the ability to notify


the sink of changes in an object's view status.

IDataAdviseHolder Creates and manages advisory connections between a data


object and one or more advise sinks.

IDataObject Enables data transfer and notification of changes in data.

IDropSource One of the interfaces you must implement to provide drag-


and-drop operations in your application.

IDropSourceNotify Receives notifications when a user drags the mouse into or


out of a potential drop target window.

IDropTarget One of the interfaces you must implement to provide drag-


and-drop operations in your application.

IEnterpriseDropTarget When implemented by the drop target application, this


interface gives the OLE drag and drop engine the ability to
determine whether the drop target application intends to
evaluate enterprise protection policy and gives the OLE drag
and drop engine a way to provide the enterprise ID of the
drop source application to the drop target application.

IEnumFORMATETC Enumerates the FORMATETC structures that define the


formats and media supported by a given data object.

IEnumMoniker Enumerates the monikers in a table of monikers.

IEnumOleDocumentViews Enumerates the views supported by a document object.

IEnumOleUndoUnits Enumerates the undo units on the undo or redo stack.

IEnumOLEVERB Enumerates the different verbs available for an object in order


of ascending verb number.
INTERFACE DESCRIPTION

IEnumSTATDATA Enumerates the advisory connection information for a data


object.

IObjectWithSite Provides a simple way to support communication between an


object and its site in the container.

IOleAdviseHolder Manages advisory connections and compound document


notifications in an object server.

IOleCache Provides control of the presentation data that is cached inside


of an object.

IOleCache2 Enables object clients to selectively update each cache that


was created with IOleCache::Cache.

IOleCacheControl Provides proper maintenance of caches.

IOleClientSite Provides an embedded object with information about the


location and extent of its display site, its moniker, its user
interface, and other resources provided by its container.

IOleCommandTarget Enables objects and their containers to dispatch commands to


each other.

IOleContainer Enumerates objects in a compound document or lock a


container in the running state.

IOleDocument Enables a document object to communicate to containers its


ability to create views of its data.

IOleDocumentSite Enables a document that has been implemented as a


document object to bypass the normal activation sequence for
in-place-active objects and to directly instruct its client site to
activate it as a document object.

IOleDocumentView Enables a container to communicate with each view supported


by a document object.

IOleInPlaceActiveObject Provides a direct channel of communication between an in-


place object and the associated application's outer-most frame
window and the document window within the application that
contains the embedded object.

IOleInPlaceFrame Controls the container's top-level frame window.

IOleInPlaceObject Manages the activation and deactivation of in-place objects,


and determines how much of the in-place object should be
visible.

IOleInPlaceObjectWindowless Enables a windowless object to process window messages and


participate in drag and drop operations.

IOleInPlaceSite Manages interaction between the container and the object's


in-place client site.
INTERFACE DESCRIPTION

IOleInPlaceSiteEx Provides an additional set of activation and deactivation


notification methods that enable an object to avoid
unnecessary flashing on the screen when the object is
activated and deactivated.

IOleInPlaceSiteWindowless Enables a windowless object to process window messages,


participate in drag and drop operations, and to perform
drawing operations.

IOleInPlaceUIWindow Negotiates border space on the document or frame window.

IOleLink Enables a linked object to provide its container with functions


pertaining to linking.

IOleObject Enables an embedded object to provide basic functionality to,


and communicates with, its container.

IOleParentUndoUnit Enables undo units to contain child undo units.

IOleUILinkContainer OLE common dialog boxes use this interface to manage the
properties of a container's links.

IOleUILinkInfo An extension to the IOleUILinkContainer interface that


enables containers to support the Link page of the Object
Properties dialog box.

IOleUIObjInfo Provides information used by the General and View pages of


the Object Properties dialog box , which display information
about the object's size, location, type, and name. It also allows
the object to be converted via the Convert dialog box.

IOleUndoManager Enables containers to implement multi-level undo and redo


operations for actions that occur within contained controls.

IOleUndoUnit The undo manager calls the methods in this interface to


perform undo actions and to get strings that can be displayed
in the user interface to describe the undo action.

IOleWindow Enables an application to obtain the handle to the various


windows that participate in in-place activation, and also to
enter and exit context-sensitive help mode.

IViewObject Enables an object to display itself directly without passing a


data object to the caller. In addition, this interface can create
and manage a connection with an advise sink so the caller can
be notified of changes in the view object.

IViewObject2 An extension to the IViewObject interface that returns the


size of the drawing for a given view of an object.

IViewObjectEx An extension to the IViewObject2 interface that provides


support for flicker-free drawing, hit testing, and control sizing.
Structures
1/7/2020 • 2 minutes to read • Edit Online

The following structures are used to implement compound documents and perform data transfer between
applications.
DVASPECTINFO
DVEXTENTINFO
DVTARGETDEVICE
FORMATETC
OBJECTDESCRIPTOR
OLECMD
OLECMDTEXT
OLEINPLACEFRAMEINFO
OLEMENUGROUPWIDTHS
OLEUIBUSY
OLEUICHANGEICON
OLEUICHANGESOURCE
OLEUICONVERT
OLEUIEDITLINKS
OLEUIGNRLPROPS
OLEUIINSERTOBJECT
OLEUILINKPROPS
OLEUIOBJECTPROPS
OLEUIPASTEENTRY
OLEUIPASTESPECIAL
OLEUIVIEWPROPS
OLEVERB
POINTF
STATDATA
STGMEDIUM
Controls and Property Pages
1/7/2020 • 2 minutes to read • Edit Online

The following sections describe ActiveX controls, standard property pages, and the APIs that are used to create
property pages:
Guide
Reference

Related topics
C
o
m
p
o
n
e
n
t
O
b
j
e
c
t
M
o
d
e
l
(
C
O
M
)
Guide
1/7/2020 • 2 minutes to read • Edit Online

This guide describes ActiveX controls, property pages, and property sheets.
ActiveX Controls
Property Pages and Property Sheets
ActiveX Control and Control Container Guidelines

Related topics
R
e
f
e
r
e
n
c
e
ActiveX Controls
1/7/2020 • 3 minutes to read • Edit Online

ActiveX controls technology rests on a foundation consisting of COM, connectable objects, compound
documents, property pages, OLE automation, object persistence, and system-provided font and picture objects.
As summarized below, each of these core technologies plays a role in controls.

C
O
M

A control is essentially a COM object that exposes the IUnknown interface, through which clients can
obtain pointers to its other interfaces. Controls can support licensing through IClassFactory2 and self-
registration. See The Component Object Model for more information on COM, licensing, and self-
registration.

C
o
n
n
e
c
t
a
b
l
e
o
b
j
e
c
t
s

Controls can support outgoing interfaces through connectable objects so that the control can communicate
with its client. For example, an outgoing interface can trigger an action in the client, can notify the client of
some change in the control, or can request permission from the client before the control takes some action.
See Events in COM and Connectable Objects for more information on how connectable objects work.

U
n
i
f
o
r
m
d
a
t
a
t
r
a
n
s
f
e
r

Controls can support being dragged and dropped within a container with help from their container. See
IOleInPlaceObjectWindowless::GetDropTarget for more information on drag and drop.

C
o
m
p
o
u
n
d
d
o
c
u
m
e
n
t
s

A control can be an in-place active object that can be embedded in a containing client. An end-user activates
the control to initiate an action in the container application. See Compound Documents for more
information on in-place activation and other compound document interfaces.

P
r
o
p
e
r
t
y
p
a
g
e
s

Controls can provide property pages so end users can view and change the control's properties. See
Property Pages and Property Sheets for more information on how property pages work.

O
L
E
a
u
t
o
m
a
t
i
o
n

Controls can provide programmability through OLE automation so clients can take advantage of the
control's features through a programming language supplied by the client. See the OLE Automation section
for more information on OLE automation.

P
e
r
s
i
s
t
e
n
t
s
t
o
r
a
g
e

A control can implement one or more of several persistence interfaces to support persistence of its state.
The control implementer must decide what kinds of persistence are most important and implement the
appropriate persistence interfaces. The client decides which interface it prefers to use. See The Component
Object Model for more information on all the persistence interfaces.

F
o
n
t
a
n
d
p
i
c
t
u
r
e
o
b
j
e
c
t
s

Controls can use these system provided objects to provide a visual representation of themselves within the
client. The font object implements several interfaces, including IFont and IFontDisp. A font object can be
created with OleCreateFontIndirect. The picture object also implements several interfaces, including
IPicture and IPictureDisp. A picture object can be created using OleCreatePictureIndirect and can
loaded from a stream with OleLoadPicture.

It is important to understand that these features can be used in any OLE object. One does not need to implement
a control in order to use these features. Also, the only required interface on a control is IUnknown. The control
optionally supports other interfaces based on the need to support the related features.
In addition to these features, the following interfaces and functions are specific to controls technology:
IOleControl, IOleControlSite, ISimpleFrameSite, and OleTranslateColor. Also specific to controls are a set
of standards for properties and methods that a control or a control container can support.

NOTE
The system library OleAut32.dll contains implementations of the functions ( OleCreatePropertyFrame,
OleCreatePropertyFrameIndirect, OleCreateFontIndirect, OleCreatePictureIndirect, OleLoadPicture, and
OleTranslateColor). In addition, OleAut32.dll contains the implementations of the standard font and picture objects, as
well as a type library for all the interfaces used with controls as well as the additional data structures and data types.

For more information, see the following topics:


ActiveX Controls Architecture
ActiveX Controls Interfaces
Properties and Methods
Control Events
Visual Representation
Keyboard Handling for Controls
Persistence
Registration and Licensing

Related topics
A
c
t
i
v
e
X
C
o
n
t
r
o
l
a
n
d
C
o
n
t
r
o
l
C
o
n
t
a
i
n
e
r
G
u
i
d
e
l
i
n
e
s
ActiveX Controls Architecture
1/7/2020 • 2 minutes to read • Edit Online

ActiveX controls technology builds on a foundation of many lower-level objects and interfaces in OLE. The exact
interfaces available on a control vary with its capabilities. This section takes a closer look at the capabilities a
control might provide.
ActiveX controls are used to provide the building blocks for creating user interfaces in applications. For example, a
button that initiates some action in the container application when it is clicked is a simple control. The following
aspects are involved in providing these user interface building blocks:
A control can be embedded within its container client to support some user interface activity within the client.
Thus, a control needs to provide a visual representation of itself when it is embedded within the container and
needs to provide a way to save its state, for example, its property values and its position within its container. The
client must support being a container with objects embedded in it.
By activating the control using a keyboard or mouse, the end user initiates some action in the client application.
Thus, a control must respond to keyboard activity and must be able to communicate with its client so it can
notify its container of its activities and trigger events in the client.
The client also typically provides a programming language through which the end user can initiate actions
provided by the control's properties and methods. Thus, a control must support automation and some set of
design-time versus run-time features as well.
As a result of its role in providing user interface building blocks, a control typically supports features in the
following areas using OLE technologies as indicated:

P
r
o
p
e
r
t
i
e
s
a
n
d
m
e
t
h
o
d
s

Like any OLE object, a control can provide much of its functionality through a set of incoming interfaces with
properties and methods. The container can supply additional ambient properties, and it can support
extending the control's properties through aggregation. These features rest on OLE automation, property
pages, connectable objects, and ActiveX control technologies.
E
v
e
n
t
s

In addition to providing properties and methods, an ActiveX control can also provide outgoing interfaces to
notify its client of events. The client must support handling of these events. These features use OLE
automation and connectable objects.

V
i
s
u
a
l
r
e
p
r
e
s
e
n
t
a
t
i
o
n

A control can support positioning and displaying itself within its container. The container positions the
control and determines its size. These features use compound document technology, including OLE drag and
drop technology.

K
e
y
b
o
a
r
d
h
a
n
d
l
i
n
g
A control can respond to keyboard accelerators so the end-user can initiate actions performed by the control.
The container manages keyboard activity for all its embedded controls. These features use control and
compound document technologies.

P
e
r
s
i
s
t
e
n
c
e

A control can save its state. The client manages the persistence of its embedded controls. These features use
structured storage and object persistence technologies.

R
e
g
i
s
t
r
a
t
i
o
n
a
n
d
l
i
c
e
n
s
i
n
g

A control typically supports self-registration and creates a set of registry entries when it is instantiated. A
control can also be licensed to help prevent unauthorized use.

Most of these features involve both the control and its client container.

Related topics
A
c
t
i
v
e
X
C
o
n
t
r
o
l
s
ActiveX Controls Interfaces
1/7/2020 • 2 minutes to read • Edit Online

In addition to other mechanisms for communicating between the control and its client, ActiveX controls technology
specifies the IOleControl and IOleControlSite interfaces for client-control communication. There is also the
ISimpleFrameSite interface for simple control containers.
These three interfaces are, however, specific to controls and are not generally useful outside the context of controls.
These interfaces are defined as follows.

interface IOleControl : IUnknown


{
HRESULT GetControlInfo([out] CONTROLINFO *pCI);
HRESULT OnMnemonic([in] LPMSG pMsg);
HRESULT OnAmbientPropertyChange([in] DISPID dispID);
HRESULT FreezeEvents([in] BOOL bFreeze);
}

interface IOleControlSite : IUnknown


{
HRESULT OnControlInfoChanged(void);
HRESULT LockInPlaceActive([in] BOOL fLock);
HRESULT GetExtendedControl([out] IDispatch **ppDisp);
HRESULT TransformCoords([in-out] POINTL *pptlHimetric, [in-out] POINTF *pptfContainer, [in] DWORD
dwFlags);
HRESULT TranslateAccelerator([in] LPMSG pMsg, [in] DWORD grfModifiers);
HRESULT OnFocus([in] BOOL fGotFocus);
HRESULT ShowPropertyFrame(void);
}

interface ISimpleFrameSite : IUnknown


{
HRESULT PreMessageFilter([in] HWND hWnd, [in] UINT msg, [in] WPARAM wp, [in] LPARAM lp,
[out] LRESULT *plResult, [out] DWORD *pdwCookie);
HRESULT PostMessageFilter([in] HWND hWnd, [in] UINT msg, [in] WPARAM wp, [in] LPARAM lp,
[out] LRESULT *plResult, [in] DWORD dwCookie);
}

Some controls, like a group box, are merely a simple container of other controls. In such cases, the simple control,
called a simple frame, doesn't have to implement all the container requirements. It can delegate most of the
interface calls from its contained controls to the container that manages the simple frame. Besides interface calls,
the simple frame also has to deal with Windows messages that potentially come from controls within it. For this
reason, a container supplies ISimpleFrameSite to allow such simple frame controls to pass messages up to the
container. PreMessageFilter processes the message first; PostMessageFilter is called after the simple frame has
processed the message itself.

Related topics
A
c
t
i
v
e
X
C
o
n
t
r
o
l
s
Properties and Methods
1/7/2020 • 2 minutes to read • Edit Online

Like any OLE object, a control provides much of its functionality through a set of incoming interfaces with
properties and methods.
A control exposes properties and methods through OLE automation so that containers can access them under the
control of a container-supplied programming language.
To support access to properties through a user interface, a control provides property pages, support for
OLEIVERB_PROPERTIES, per property browsing, and data binding through property change notfications.
Through property pages a control can display its properties, independent of its container, if necessary.
By supporting OLEIVERB_PROPERTIES, the Properties item is displayed on the container's menu. Then, the
end user can select the Properties item to view the control's property pages and modify the properties.
Per property browsing supports a container that can display the control's properties as part of a larger property
sheet that may include properties from several controls in the container.
Through property change notification, a control can notify a client that its properties have change, allowing the
client to take any necessary actions as a result.
For more information, see the following topics:
Control Properties
Control Methods

Related topics
A
c
t
i
v
e
X
C
o
n
t
r
o
l
s

P
r
o
p
e
r
t
y
P
a
g
e
s
a
n
d
P
r
o
p
e
r
t
y
S
h
e
e
t
s
Control Properties
1/7/2020 • 2 minutes to read • Edit Online

In addition to properties defined and implemented by the control itself, ActiveX controls technology also involves:

A
m
b
i
e
n
t
p
r
o
p
e
r
t
i
e
s

These are exposed by the container through a control client site to provide environmental values that apply
to all controls embedded in the container. For example, a container can provide a default background color
or a default font that the control can use. Ambient properties are exposed through IDispatch implemented
on a container's site object. The container calls the control's IOleControl::OnAmbientPropertyChange
method when any of its ambient properties change value. In response, a control may need to update its own
internal or visual state in response. The container indicates which ambient property changed with the
DISPID parameter or may pass DISPID_UNKNOWN to indicate that multiple ambient properties changed.

E
x
t
e
n
d
e
d
p
r
o
p
e
r
t
i
e
s
These are actually implemented by a container to wrap the controls it contains to provide container-
managed properties that appear as if they were native control properties. The container can aggregate the
control, adding the extended properties to supplement or override the control's properties. The aggregated
object is called an extended control. To the container, the extended control appears as the control itself and
extended properties appear to be exposed by the control. The container supports an extended control
through its client site method IOleControlSite::GetExtendedControl. The GetExtendedControl method
allows controls to navigate through the site to the extended control object provided for them by the
container, if the container supports this feature. A container can also choose to show property pages for its
extended controls in addition to those pages that a control would normally specify through
ISpecifyPropertyPages. Because of this, a control has to ask a container to show a property frame before
the control attempts to do so itself. The control calls IOleControlSite::ShowPropertyFrame to do this. If
the container implements this function then it shows the property frame itself; if the method returns an error
then the control can show the property frame.

For more information, see the following topics:


Standard Properties
Standard Font Object
Standard Picture Object

Related topics
C
o
n
t
r
o
l
M
e
t
h
o
d
s
Standard Properties
1/7/2020 • 3 minutes to read • Edit Online

OLE defines a set of standard DISPIDs for all three kinds of properties: control, ambient, and extended. The
following tables list these standards for control properties, ambient properties, and extended properties.

CONTROL PROPERTY TYPE DESCRIPTION

BackColor, ForeColor, FillColor, OLE_COLOR The control's color scheme


BorderColor

BackStyle, FillStyle, BorderStyle, short or long Bits that define a control's visual
BorderWidth, BorderVisible, DrawStyle, behavior, such as being solid or
DrawWidth transparent, having thick or thin
borders, line styles, and so forth.

Font IDispatch * The font used in the control, which is an


IDispatch pointer to a standard font
object. See Standard Font Object for
more information.

Caption, Text BSTR Strings containing the control's label


(the caption) or its textual contents (the
text). Note that the caption does not
necessarily name the control in the
container. See the extended Name
property in the following table.

Enabled BOOL Determines whether the control is


enabled or disabled. If disabled, the
control is probably grayed.

Window HWND The window handle of the control, if it


has one.

TabStop BOOL Determines whether this control is a tab


stop.

AMBIENT PROPERTY TYPE DESCRIPTION

BackColor, ForeColor OLE_COLOR Provides controls with the default


background and foreground colors. Use
by a control is optional.

Font IDispatch * A pointer to a standard font object that


defines the default font for the form.
Use by a control is optional. See
Standard Font Object for more
information.

LocaleID LCID The language used in the container. Use


by a control is recommended.
AMBIENT PROPERTY TYPE DESCRIPTION

UserMode BOOL Describes whether the container is in a


design mode (FALSE) or run-mode
(TRUE), which a control should use to
change its available functionality as
necessary.

UIDead BOOL Describes whether the container is in a


mode where controls should ignore
user input. This applies irrespective of
UserMode. A container might always
set UIDead to TRUE in design mode,
and may set it to TRUE when it has hit
a breakpoint or such during run mode.
A control must pay attention to this
property.

MessageReflect BOOL Specifies whether the container would


like to receive Windows messages such
as WM_CTLCOLOR, WM_DRAWITEM,
WM_PARENTNOTIFY, and so on as
events.

SupportsMnemonics BOOL Describes whether the container


processes mnemonics or not. A control
can do whatever it wants with this
information, such as not underline
characters it would normally use as a
mnemonic.

ShowGrabHandles, ShowHatching BOOL Describes whether a control should


show a hatch border or grab handles (in
the hatch border) when in-place active.
Controls must obey these properties,
giving the container ultimate control
over who actually draws these bits of
user interface. A control container may
want to draw its own instead of relying
on each control, in which case these
ambients will always be FALSE.

DisplayAsDefault BOOL The container will expose a TRUE for


this property through whatever site
contains what is marked as the default
button when the button control should
draw itself with a thicker default frame.

EX TENDED PROPERTY TYPE DESCRIPTION

Name BSTR The container's name for the control.

Visible BOOL The control's visibility.

Parent IDispatch * The dispinterface of the form containing


the control.
EX TENDED PROPERTY TYPE DESCRIPTION

Default, Cancel BOOL Indicates if this control is the default or


cancel button.

All of these standard properties have negative DISPID values, indicating their standard status.
Note that to avoid conflicts in the programmatic symbols for these DISPIDs, all ambient properties are given
symbols in the form DISPID_AMBIENT_property as in DISPID_AMBIENT_FORECOLOR. All other symbols use
DISPID_property as usual.
Some ambient properties, as well as control properties, involve colors. The OLE_COLOR type mentioned in the
previous tables can refer to a standard COLORREF type, an index to a palette, a palette-relative index, or a system
color index used with the GetSysColor function. The OleTranslateColor function converts an OLE_COLOR type
to a COLORREF type given a palette.

Related topics
C
o
n
t
r
o
l
P
r
o
p
e
r
t
i
e
s
Standard Font Object
1/7/2020 • 2 minutes to read • Edit Online

The standard ambient font property supplied by the container and the standard font property supplied by the
control both provide a standard font object. That is, these standard fonts supply an IDispatch pointer to a
standard font object.
The font object is a system-provided implementation of a set of interfaces on top of the underlying GDI font
support. A font object is created through the API function OleCreateFontIndirect given a FONTDESC structure.
The font object supports a number of read/write properties as well as custom methods through its interface IFont,
and supports the same set of properties (but not the methods) through a dispinterface IFontDisp. The
dispinterface is used for the font properties mentioned previously. The properties correspond to the GDI font
attributes that are described in the LOGFONT structure.
The font object also supports the outgoing interface IPropertyNotifySink so that a client can determine when
font properties change. Since the font object supports at least one outgoing interface, it also implements
IConnectionPointContainer and one connection point for IPropertyNotifySink for this purpose.
The font object provides an hFont property that is a Windows font handle that conforms to the other attributes
specified for the font. The font object delays realizing this font when possible, so consecutively setting two
properties on a font won't cause an intermediate font to be realized. In addition, as an optimization, the standard
font object maintains a cache of font handles. Two font objects in the same process that have identical properties
will return the same font handle. The font object can remove fonts from this cache at will, which introduces special
considerations for clients using this hFont property. See IFont::get_hFont for more details.
The font object also supports IPersistStream such that it can save and load itself from an instance of IStream.
Any other object that uses a font object internally would normally save and load the font as part of the object's
own persistence handling.
In addition, the font object supports IDataObject through which it provides a property set containing typed
values for each font property.

Related topics
C
o
n
t
r
o
l
P
r
o
p
e
r
t
i
e
s
Standard Picture Object
1/7/2020 • 2 minutes to read • Edit Online

The standard picture object provides a language-neutral abstraction for GDI images: bitmaps, icons, metafiles, and
enhanced metafiles. As with the standard font object, the system provides a standard implementation of this object.
Its primary interfaces are IPicture and IPictureDisp, the latter being derived from IDispatch to provide access to
the picture's properties through OLE automation. A picture object is created new with OleCreatePictureIndirect.
The picture object also supports the outgoing interface IPropertyNotifySink so that a client can determine when
picture properties change. Accordingly, the picture object also supports IConnectionPointContainer and one
connection point for IPropertyNotifySink.
The picture object also supports IPersistStream such that it can save and load itself from an instance of IStream.
An object that uses a picture object internally would normally save and load the picture as part of the object's own
persistence handling. The OleLoadPicture function simplifies the creation of a picture object based on stream
contents.

Related topics
C
o
n
t
r
o
l
P
r
o
p
e
r
t
i
e
s
Control Methods
1/7/2020 • 2 minutes to read • Edit Online

There are three standard methods that controls can support: Refresh, DoClick, and AboutBox. These standard
methods have negative DISPID values, indicating their standard status.

Related topics
C
o
n
t
r
o
l
P
r
o
p
e
r
t
i
e
s
Control Events
1/7/2020 • 2 minutes to read • Edit Online

In addition to providing properties and methods, a control also provides outgoing interfaces to notify its client of
events. The client must support handling of these events. See Events in COM and Connectable Objects for more
information on how connectable objects work.
A control can support different outgoing interfaces for different purposes. All outgoing interfaces are marked as
source interfaces in the control's type information, but only one is marked default to indicate that it is the primary
outgoing interface.
A container can support one or more of the outgoing interfaces defined by a control. The control should be
prepared to deal with containers that only provide support for some of their outgoing interfaces.
Controls support four kinds of events:
Request events. A control requests permission from its client to do something by calling a method in the
outgoing interface, thus triggering a request event. The client signals the control through a boolean, out-
parameter in the method that the control called. The client can thus prevent the control from performing the
action.
Before events. A control notifies its client hat it is going to do something by calling a method in the outgoing
interface, thus triggering a before event. The client does not have the opportunity to prevent the action, but it
can take any necessary steps given the action that is about to occur.
After events. A control notifies its client that it has just done something by calling a method in the outgoing
interface, thus triggering an after event. Again, the client cannot cancel this action, but it can take necessary
steps given the action that has occurred.
Do events. A control triggers a do event to allow its client to override the control's action and provide some
alternative or supplementary actions. Usually, the method that a control calls for a do event has a number of
parameters for negotiating with the client about the actions that will occur.
The following dispids are defined for standard events that controls can support: Click, DblClick, KeyDown,
KeyPress, KeyUp, MouseMove, MouseUp, and Error. All of these standard events have negative DISPID values,
indicating their standard status.
The IOleControl::FreezeEvents method, when called with TRUE, tells a control whether the container will bother
handling events from the control until FreezeEvents is again called with FALSE. During this time control cannot
depend on the container actually handling any events. If an event must be handled, the control should queue the
event in order to fire it when FreezeEvents is called with FALSE.

Related topics
A
c
t
i
v
e
X
C
o
n
t
r
o
l
s
Visual Representation
1/7/2020 • 2 minutes to read • Edit Online

A control supports positioning and displaying itself within its container through compound document technology
and OLE drag and drop technology that involves both the control and its container. The control must be able to
draw itself while the container manages the position of the control and its size.
Controls add to the basic functions provided by OLE documents. A control calls its client's
IOleClientSite::RequestNewObjectLayout method to tell its container that it wants to change its size. The client
calls the control's IOleObject::GetExtent to get the new size and calls IOleInPlaceObject::SetObjectRects to
set the control to its new size.
Controls that support only IPersistStream or IPersistStreamInit do not support caching through IOleCache2
because the cache requires support for IPersistStorage. However, these controls should provide a way for the
client to render the control through IDataObject::GetData so the client can optionally create and manage its own
cache of the presentation data for the control.
Controls use the HIMETRIC type for its coordinates. However, different containers can use different coordinate
systems. The container wants to receive coordinates in its own system, but the control does not necessarily know
what coordinates its container is using. To communicate successfully, the control needs a way to convert values to
its container's coordinates. The container provides a site object with the IOleControlSite::TransformCoords
method. The control calls this method on its container's client site first to convert its coordinates into the
appropriate coordinates for the container. Then, it can pass the converted coordinates to the container.
Controls can call IOleControlSite::LockInPlaceActive in the container's site object to prevent the container from
attempting to demote the control out of the in-place active state. Demoting the control in this way causes the
control to be deactivated and its window destroyed, so if the control must maintain its window for a known
duration it can call LockInPlaceActive to guarantee its state.

Related topics
A
c
t
i
v
e
X
C
o
n
t
r
o
l
s
Keyboard Handling for Controls
1/7/2020 • 2 minutes to read • Edit Online

A control responds to keyboard accelerators so the end-user can initiate actions performed by the control. The
container manages keyboard activity for all its embedded controls. With compound documents, keyboard
accelerators apply only to the currently active object. With controls, a mechanism has been added so that a control
can respond to its keyboard mnemonics even if it is not currently UI-active.
The IOleControl::GetControlInfo and IOleControl::OnMnemonic methods and the
IOleControlSite::OnControlInfoChanged method handle a control's keyboard mnemonics. A CONTROLINFO
structure describes a control's mnemonic accelerators, and the flags passed back with it through the
GetControlInfo method describe the controls behavior with the Enter and Esc keys. When a control changes its
mnemonics, it calls OnControlInfoChanged so the container can reload the structure if necessary.
When a control is UI active, it is also the control with the focus. As controls are activated and deactivated between
the in-place active and the UI active states, the control calls IOleControlSite::OnFocus to tell the container of
such changes.
In addition, when a control is UI active, it will have first chance to process any keystrokes. To give a container the
opportunity to process the keystroke before the control, the control calls IOleControlSite::TranslateAccelerator.
If the container does not handle the keystroke, the control then processes it.

Related topics
A
c
t
i
v
e
X
C
o
n
t
r
o
l
s
Persistence
1/7/2020 • 2 minutes to read • Edit Online

A control implements one or more of several persistence interfaces to support persistence of its state. For example,
the IPersistStreamInit interface supports stream-based persistence of the control's state. IPersistStreamInit is a
replacement for IPersistStream and adds an initialization method, InitNew. The other methods are the same in
both interfaces. IPersistStreamInit is not derived from IPersistStream; an object supports only one of the two
interfaces based on whether it requires the ability to initialize new instances of itself.
Other persistence interfaces that a control can offer include: IPersistStorage, IPersistMemory,
IPersistPropertyBag, IPersistMoniker. The control implementer must decide what kinds of persistence are most
important and implement the appropriate persistence interfaces. The control implementer also decides what to
save. For example, a control can save the current values of its properties or its location and size within its container.
The client decides which interface it prefers to use.
Before loading a control from its persistent state, a client can check the OLEMISC_SETCLIENTSITEFIRST flag to
determine if the control supports getting its client site and ambient properties before loading its persistent state.
This optimization can save time when instantiating a control since the control is then free to ignore its persistent
values rather than loading them only to have them overridden by ambient properties supplied by the client.
A control can also support saving and restoring its state in an OLE property set, a set of identifiers and values in a
specified format. This feature can be useful with containers such as Visual Basic, which saves its programs in a
textual form. A control that wants to support this feature implements IDataObject::GetData and
IDataObject::SetData to pass its property values to and from the container, respectively. It is the container's job
to convert this information to text and save it. The identifiers used by the control correspond to the control's
property names and the values. See the OLE CDK for the definition of this property set.

Related topics
A
c
t
i
v
e
X
C
o
n
t
r
o
l
s
Registration and Licensing
1/7/2020 • 2 minutes to read • Edit Online

A control is usually provided as an in-process server (.DLL ), although it can also be a local or remote server (.EXE ).
A control typically supports self-registration and creates a set of registry entries when it is instantiated. A control
can also be licensed to help prevent unauthorized use. See The Component Object Model for more information on
self registration and licensing.
For more information, see ActiveX Controls Registry Information.

Related topics
A
c
t
i
v
e
X
C
o
n
t
r
o
l
s

A
c
t
i
v
e
X
C
o
n
t
r
o
l
s
R
e
g
i
s
t
r
y
I
n
f
o
r
m
a
t
i
o
n
ActiveX Controls Registry Information
1/7/2020 • 2 minutes to read • Edit Online

There are a number of registry entries and flags that are used. Additionally, controls can support component
categories to classify the features they provide.
Registry keys related to controls are marked with an asterisk in the following tree:

HKEY_CLASSES_ROOT
CLSID
{control_CLSID}
ProgID = <identifier>
InprocServer32 = <filename>.dll
*DefaultIcon = <filename>.<ext>,resourceID
*ToolboxBitmap32 = <filename>.<ext>,resourceID
*Control
verb
*n = &Properties...
*MiscStatus = 0
TypeLib = {object_typelibID}
*Version = version_number

The DefaultIcon entry is used to identify an icon to be displayed when the control is minimized to an icon. The
ExtractIcon function is used to get the icon from the .DLL or .EXE file specified.
The ToolboxBitmap32 entry identifies the module name and resource identifier for a 16*15 bitmap to use for the
face of a toolbar or toolbox button. The standard Windows icon size is too large to be used for this purpose. This
entry specifically supports control containers that have a design mode in which one selects controls and places
them on a form being designed. For example, in Visual Basic, the control's icon is displayed in the Visual Basic
toolbox during design mode.
The Control entry marks an object as a control. This entry is often used by containers to fill in dialog boxes. The
container uses this sub-key to determine whether to include an object in a dialog box that displays controls.
The Insertable sub-key can also be used with controls, depending on whether the object can act only as an in-
place embedded object with no special control features. Objects marked with Insertable appear in the Insert
Object dialog box of their container. The Insertable entry generally means that the control has been tested with
non-control containers.
Both the Insertable and the Control sub-keys are optional. A control can omit the Insertable sub-key if it not
designed to work with older containers that do not understand controls. A control can omit the Control key if it is
only designed to work with a specific container and thus does not wish to be inserted in other containers.
Controls should have a Properties verb, OLEIVERB_PROPERTIES, along with any other verbs they support. The
Properties verb, as well as the standard verb OLEIVERB_PRIMARY, instructs the control to display its property
sheet. The Properties verb is displayed as the Properties item on the container's menu when the control is active.
This way, the control can display its own property page allowing some useful functionality to the end user, even if
the container does not handle controls.
A control defines the MiscStatus key to describe itself to potential containers. The bits take on the values from
OLEMISC, and controls add several values to this enumeration. See the OLEMISC enumeration values for more
information. The client can obtain this information by calling IOleObject::GetMiscStatus without having to
instantiate the control first.
Finally, Version describes the version of the control which should match the version of the type library associated
with this control.
Also in the type information for a control, the attribute control marks a coclass entry as describing a control.
Property Pages and Property Sheets
1/7/2020 • 2 minutes to read • Edit Online

OLE property pages enable an object to display its properties in a tabbed dialog box known as a property sheet.
An end user can then view and change the object's properties. An object can display its property pages
independent of its client, or the client can manage the display of property pages from a number of contained
objects in a single property sheet. Property pages also provide a means for notifying a client of changes in an
object's properties.
Any object that wants to provide a user interface for its changing properties can use this technology.
For more information, see the following topics:
Property Sheets and Property Pages
Data Binding through IPropertyNotifySink
Property Sheets and Property Pages
1/7/2020 • 5 minutes to read • Edit Online

An object's properties are exposed to clients the same as methods through either COM interfaces or the object's
IDispatch implementation, allowing properties to be changed by programs calling these methods. The OLE
technology of property pages provides the means to build a user interface for an object's properties according to
Windows user interface standards. Thus, the properties are exposed to end users. An object's property sheet is a
tabbed-dialog where each tab corresponds to a specific property page. The OLE model for working with property
pages consists of these features:
Each property page is managed by an in-process object that implements either IPropertyPage or
IPropertyPage2. Each page is identified with its own unique CLSID.
An object specifies its support for property pages by implementing ISpecifyPropertyPages. Through this
interface the caller can obtain a list of CLSIDs identifying the specific property pages that the object supports. If
the object specifies a property page CLSID, the object must be able to receive property changes from the
property page.
Any piece of code (client or object) that wants to display an object's property sheet passes the object's
IUnknown pointer (or an array if multiple objects are to be affected) along with an array of page CLSIDs to
OleCreatePropertyFrame or OleCreatePropertyFrameIndirect, which creates the tabbed-dialog box.
The property frame dialog instantiates a single instance of each property page, using CoCreateInstance on
each CLSID. The property frame obtains at least an IPropertyPage pointer for each page. In addition, the
frame creates a property page site object in itself for each page. Each site implements IPropertyPageSite and
this pointer is passed to each page. The page then communicates with the site through this interface pointer.
Each page is also made aware of the object or objects for which it has been invoked; that is, the property frame
passes the IUnknownpointers of the objects to each page. When instructed to apply changes to the objects,
each page queries for the appropriate interface pointer and passes new property values to the objects in
whatever way is desired. There are no stipulations on how such communication has to happen.
An object can also support per property browsing through the IPerPropertyBrowsing interface permitting the
object to specify which property should receive initial focus when the property page is displayed and to specify
strings and values that can be displayed by the client in its own user interface.
These features are illustrated in the following diagram:

These interfaces are defined as follows:


interface ISpecifyPropertyPages : IUnknown
{
HRESULT GetPages([out] CAUUID *pPages);
};

interface IPropertyPage : IUnknown


{
HRESULT SetPageSite([in] IPropertyPageSite *pPageSite);
HRESULT Activate([in] HWND hWndParent, [in] LPCRECT prc
, [in] BOOL bModal);
HRESULT Deactivate(void);
HRESULT GetPageInfo([out] PROPPAGEINFO *pPageInfo);
HRESULT SetObjects([in] ULONG cObjects
, [in, max_is(cObjects)] IUnknown **ppunk);
HRESULT Show([in] UINT nCmdShow);
HRESULT Move([in] LPCRECT prc);
HRESULT IsPageDirty(void);
HRESULT Apply(void);
HRESULT Help([in] LPCOLESTR pszHelpDir);
HRESULT TranslateAccelerator([in] LPMSG pMsg);
}

interface IPropertyPageSite : IUnknown


{
HRESULT OnStatusChange([in] DWORD dwFlags);
HRESULT GetLocaleID([out] LCID *pLocaleID);
HRESULT GetPageContainer([out] IUnknown **ppUnk);
HRESULT TranslateAccelerator([in] LPMSG pMsg);
}

The ISpecifyPropertyPages::GetPages method returns a counted array of UUID (GUID ) values each of which
describe the CLSID of a property page that the object would like displayed. Whoever invokes the property sheet
with OleCreatePropertyFrame or OleCreatePropertyFrameIndirect passes this array to the function. Note
that if the caller wishes to display property pages for multiple objects, it must only pass the intersection of the
CLSID lists of all the objects to these functions. In other words, the caller must only invoke property pages that are
common to all objects.
In addition, the caller passes the IUnknown pointers to the affected objects to the API functions as well. Both API
functions create a property frame dialog and instantiate a page site with IPropertyPageSite for each page it will
load. Through this interface a property page can:
Retrieve the current language used in the property sheet through GetLocaleID.
Ask the frame to process keystrokes through TranslateAccelerator.
Notify the frame of changes in the page through OnStatusChange.
Obtain an interface pointer for the frame itself through GetPageContainer, although there are no interfaces
defined for the frame at this time for this function always returns E_NOTIMPL.
The property frame instantiates each property page object and obtain each page's IPropertyPage interface.
Through this interface the frame informs the page of its page site (SetPageSite), retrieves page dimensions and
strings (GetPageInfo), passes the interface pointers to the affected objects (SetObjects), tells the page when to
create and destroy its controls (Activate and Deactivate), instructs the page to show or reposition itself (Show
and Move), instructs the page to apply its current values to the affected objects (Apply), checks on the page's dirty
status (IsPageDirty), invokes help (Help), and passes keystrokes to the page (TranslateAccelerator).
An object can also support per-property browsing, which provides:
1. A way (through IPerPropertyBrowsing and IPropertyPage2) to specify which property on which property
page should be given the initial focus when a property sheet is first displayed
2. A way (through IPerPropertyBrowsing) for the object to specify predefined values and corresponding
descriptive strings that could be displayed in a client's own user interface for properties.
An object can choose to support (2) without supporting (1), such as when the object has no property sheet.
The IPropertyPage2 and IPerPropertyBrowsing interfaces are defined as follows:

interface IPerPropertyBrowsing : IUnknown


{
HRESULT GetDisplayString([in] DISPID dispID, [out] BSTR *pbstr);
HRESULT MapPropertyToPage([in] DISPID dispID, [out] CLSID *pclsid);
HRESULT GetPredefinedStrings([in] DISPID dispID, [out] CALPOLESTR *pcaStringsOut, [out] CADWORD
*pcaCookiesOut);
HRESULT GetPredefinedValue([in] DISPID dispID, [in] DWORD dwCookie, [out] VARIANT *pvarOut);
}

interface IPropertyPage2 : IPropertyPage


{
HRESULT EditProperty([in] DISPID dispID);
}

To specify its support for such capabilities, the object implements IPerPropertyBrowsing. Through this interface,
the caller can request the information necessary to achieve the browsing, such as predefined strings
(GetPredefinedStrings) and values (GetPredefinedValue) as well as a display string for a given property
(GetDisplayString).
In addition, the client can obtain the CLSID of the property page that allows the user to edit a given property
identified with a DISPID (MapPropertyToPage). The client then instructs the property frame to activate that page
initially by passing the CLSID and the DISPID to OleCreatePropertyFrameIndirect. The frame activates that
page first and passes the DISPID to the page through IPropertyPage2::EditProperty. The page then sets the
focus to that property's editing field. In this way, a client can jump from a property name in its own user interface
to the property page that can manipulate that property.

Related topics
P
r
o
p
e
r
t
y
P
a
g
e
s
a
n
d
P
r
o
p
e
r
t
y
S
h
e
e
t
s
Data Binding through IPropertyNotifySink
1/7/2020 • 2 minutes to read • Edit Online

Objects that support properties, for example, through OLE Automation and the IDispatch interface, may want to
allow clients to be notified when certain properties change value. Such a property is called a bindable property
because the notifications allow a client to synchronize its own display of the object's current property values. In
addition, the same objects may wish to allow a client to control when certain properties are allowed to change.
Such properties are called request edit properties.
The IPropertyNotifySink is a standard notification interface that supports bindable and request-edit properties.
IPropertyNotifySink is supported from an object with properties as an outgoing interface. That is, the interface
itself is implemented by a client's sink object, and the client connects the sink to the supporting object through the
connection point mechanism described earlier. The IPropertyNotifySinkis defined as follows:

interface IPropertyNotifySink : IUnknown


{
HRESULT OnChanged([in] DISPID dispID);
HRESULT OnRequestEdit([in] DISPID dispID);
}

When an object wishes to notify its connected sinks that a bindable property identified with a given DISPID has
changed, it calls OnChanged. If an object changes multiple properties at once, it can pass DISPID_UNKNOWN to
OnChanged in which case a client refreshes its cache of all property values of interest.
When a request edit property is about to change, an object can ask the client whether it will allow that change to
occur. The object calls OnRequestEdit passing the DISPID of the property in question (or DISPID_UNKNOWN
to identify all properties). The client's sink returns S_OK to indicate that the change is allowed, or S_FALSE (or an
error) to indicate that change is not allowed. When an object calls OnRequestEdit, it is required to obey the
client's wishes by following the exact semantics of S_OK and S_FALSE return values.
Note that OnRequestEdit cannot be used for data validation because at the time of the call, the new value of the
property is not yet available. The notification can only be used to control a read-only state for a property.
Objects control which properties are bindable and request edit and mark such properties in the object's type
information. In the type information, the attribute bindable marks a property as supporting OnChanged. The
attribute requestedit marks a property as supporting OnRequestEdit.
One property can support both behaviors in which case OnRequestEdit is called first, and only if change is
allowed is OnChanged called.
The one exception to the behavior of such properties is that no notifications are sent as a result of an object's
initialization or loading procedures. At such times, it is assumed that all properties change and that all must be
allowed to change. Notifications to this interface are therefore only meaningful in the context of a fully
initialized/loaded object.
Two other attributes can be applied to properties in an object's type information. The defaultbind attribute marks a
bindable property as being the one that best represents the state of the object as a whole. The displaybind attribute
marks a bindable property as suitable for display in a client's own user interface.

Related topics
P
r
o
p
e
r
t
y
P
a
g
e
s
a
n
d
P
r
o
p
e
r
t
y
S
h
e
e
t
s
ActiveX Control and Control Container Guidelines
1/7/2020 • 2 minutes to read • Edit Online

The following topics provide guidelines for implementing ActiveX controls and containers that will interoperate
well with other controls and containers. This section defines the minimum set of interfaces, methods, and features
that are required of ActiveX controls and containers to accomplish seamless and useful interoperability.
Overview of Control and Control Container Guidelines
Controls
Containers
Component Categories
General Guidelines
Event Coordinate Translation
Standard DISPIDS
Databinding

Related topics
A
c
t
i
v
e
X
C
o
n
t
r
o
l
s
Overview of Control and Control Container
Guidelines
1/29/2020 • 3 minutes to read • Edit Online

An ActiveX control is essentially a simple OLE object that supports the IUnknown interface. It will usually support
more interfaces in order to offer functionality, but all additional interfaces may be viewed as optional and as such, a
control container should not rely on any additional interfaces being supported. By not specifying additional
interfaces that a control must support, a control may efficiently target a particular area of functionality without
having to support particular interfaces to qualify as a control. As always with OLE, whether in a control or a control
container, it should never be assumed that an interface is available and standard return-checking conventions
should always be followed. It is important for a control or control container to degrade gracefully and offer
alternative functionality if an interface required is not available.
An ActiveX control container must be able to host a minimal ActiveX control; it will also support a number of
additional interfaces as specified in Containers. There are a number of interfaces and methods that a container may
optionally support, which are grouped into functional areas known as component categories. A container may
support any combination of component categories, for example, a component category exists for databinding and
a container may or may not support the databinding functionality, depending on the market needs of the container.
If a control needs databinding support from a container to function, then it will enter this requirement in the
registry. This allows a control container to only offer for insertion those controls that it knows it can successfully
host. It is important to note that component categories are specified as part of OLE and are not specific to ActiveX
controls, the controls architecture uses component categories to identify areas of functionality that an OLE
component may support. Component categories are not cumulative or exclusive, so a control container can
support one category without necessarily supporting another.
It is important for controls that require optional features, or features specific to a certain container to be clearly
packaged and marketed with those requirements. Similarly containers that offer certain features or component
categories must be marketed and packaged as offering those levels of support when hosting ActiveX controls. It is
recommended that controls target and test with as many containers as possible and degrade gracefully to offer
less or alternative functionality if interfaces or methods are not available. In a situation where a control cannot
perform its designated job function without the support of a component category, that category should be entered
as a requirement in the registry in order to prevent the control being inserted in an inappropriate container.
These guidelines define those interfaces and methods that a control may expect a control container to support,
although as always a control should check the return values when using QueryInterface or other methods to
obtain pointers to these interfaces. A container should not expect a control to support anything more than the
IUnknown interface, and these guidelines identify what interfaces a control may support and what the presence of
a particular interface means.

Why the ActiveX Control and Control Container Guidelines Are


Important
ActiveX Controls have become the primary architecture for developing programmable software components for
use in a variety of different containers ranging from software development tools to end-user productivity tools. In
order for a control to operate well in a variety of containers, the control must be able to assume some minimum
level of functionality that it can rely on in all containers.
By following these guidelines, control and container developers make their controls and containers more reliable
and interoperable, and ultimately, better and more usable components for building component-based solutions.
What to Do When an Interface You Need Is Not Available
OLE programs should use QueryInterface to acquire interface pointers, and must check the return value. OLE
applications cannot safely assume that QueryInterface will succeed.
This requirement applies to all OLE applications. If the requested interface is not available (that is, QueryInterface
returns E_NOINTERFACE ), the control or container must degrade gracefully, even if that means that it cannot
perform its designated job function.

Related topics
A
c
t
i
v
e
X
C
o
n
t
r
o
l
a
n
d
C
o
n
t
r
o
l
C
o
n
t
a
i
n
e
r
G
u
i
d
e
l
i
n
e
s
Controls
1/29/2020 • 2 minutes to read • Edit Online

An ActiveX control is really just another term for OLE object or more specifically, COM object. In other words, a
control, at the very least, is some COM object that supports the IUnknown interface and is also self-registering.
Through IUnknown::QueryInterface a container can manage the lifetime of the control as well as dynamically
discover the full extent of a control's functionality based on the available interfaces. This allows a control to
implement as little functionality as it needs to, instead of supporting a large number of interfaces that actually
don't do anything. In short, this minimal requirement for nothing more than IUnknown allows any control to be
as lightweight as it can.
In short, other than IUnknown and self-registration, there are no other requirements for a control. There are,
however, conventions that should be followed about what the support of an interface means in terms of
functionality provided to the container by the control. This section then describes what it means for a control to
actually support an interface, as well as methods, properties, and events that a control should provide as a
baseline if it has occasion to support methods, properties, and events.
For more information, see the following topics:
Self Registration for Controls
What Support for an Interface Means
Persistence Interfaces
Optional Methods in Control Interfaces
Class Factory Options
Exposing Properties through IDispatch
Exposing Methods through IDispatch
Events in Controls
Property Pages
Ambient Properties for Controls
Using the Container's Functionality

Related topics
A
c
t
i
v
e
X
C
o
n
t
r
o
l
a
n
d
C
o
n
t
r
o
l
C
o
n
t
a
i
n
e
r
G
u
i
d
e
l
i
n
e
s
Self Registration for Controls
1/7/2020 • 2 minutes to read • Edit Online

ActiveX controls must support self-registration by implementing the DllRegisterServer and


DllUnregisterServer functions. ActiveX controls must register all of the standard registry entries for embeddable
objects and automation servers.
ActiveX controls must use the component categories API to register themselves as a control and register the
component categories that they require a host to support and any categories that the control implements, see
Component Categories.
ActiveX controls should also register the ToolBoxBitmap32 registry key, although this is not mandatory.
The Insertable component category should be registered only if the control is suitable for use as a compound
document object. It is important to note that a compound document object must support certain interfaces beyond
the minimum IUnknown required for an ActiveX control. Although an ActiveX control may qualify as a
compound document object, the control's documentation should clearly state what behavior to expect under these
circumstances.

Related topics
C
o
n
t
r
o
l
s
What Support for an Interface Means
1/7/2020 • 5 minutes to read • Edit Online

Besides the IUnknown interface, an ActiveX Control or COM Object for that matter expresses whatever optional
functionality it supports through additional interfaces. This is to say that no other interfaces are required above
IUnknown. To that end, the following table lists the interfaces that an ActiveX Control might support, and what it
means to support that interface.

INTERFACE COMMENTS/WHAT IT MEANS TO SUPPORT THE INTERFACE

IOleObject If the control requires communication with its client site for
anything other than events (see
IConnectionPointContainer), then IOleObject is a necessity.
When implementing this interface, the control must also
support the semantics of the following methods:
SetHostNames, Close, EnumVerbs, Update, IsUpToDate,
GetUserClassID, GetUserType, GetMiscStatus, and the
Advise, Unadvise, and EnumAdvise methods that work in
conjunction with a container's IAdviseSink implementation. A
control implementing IOleObject must be able to handle
IAdviseSink if the container provides one; a container may
not, in which case a control ensures, of course, that it does not
attempt to call a non-existent sink.

IOleInPlaceObject Expresses the control's ability to be in-place activated and


possibly UI activated. This interface means that the control has
a user interface of some kind that can be activated, and
IOleInPlaceActiveObject is supported as well. Required
methods are GetWindow, InPlaceDeactivate, UIDeactivate,
SetObjectRects, and ReactivateAndUndo. Support for this
interface requires support for IOleObject.

IOleInPlaceActiveObject An in-place capable object that supports IOleInPlaceObject


must also provide this interface as well, though the control
itself doesn't necessarily implement the interface directly.
INTERFACE COMMENTS/WHAT IT MEANS TO SUPPORT THE INTERFACE

IOleControl Expresses the control's ability and desire to deal with (a)
mnemonics (GetControlInfo, OnMnemonic methods), (b)
ambient properties (OnAmbientPropertyChange), and/or (c)
events that the control requires the container to handle
(FreezeEvents). Note that mnemonics are different than
accelerators that are handled through
IOleInPlaceActiveObject: mnemonics have associated UI
and are active even when the control is not UI active. A
control's support for mnemonics means that the control also
knows how to use the container's
IOleControlSite::OnControlInfoChanged method. Because
this requires the control to know the container's site, support
for mnemonics also means support for IOleObject. In
addition, knowledge of mnemonics requires in-place support
and thus IOleInPlaceObject.
If a control uses any container-ambient properties, then it
must also implement this interface to receive change
notifications, as following the semantics of changes is required.
Because ambient properties are only available through the
container site's IDispatch, ambient property support means
that the control supports IOleObject (to get the site) as well
as being able to generate IDispatch::Invoke calls.
The FreezeEvents method is necessary for controls that must
know when a container is not going to handle an event this is
the only way for control to know this condition. If
FreezeEvents is only necessary in isolation, such that other
IOleControl methods are not implemented, then
IOleControl can stand alone without IOleObject or
IOleInPlaceObject.

IDataObject Indicates that the control can supply at least (a) graphical
renderings of the control (CF_METAFILEPICT is the minimum if
the control has any visuals at all) and/or (b) property sets, if
the control has any properties to provide. The methods
GetData, QueryGetData, EnumFormatEtc, DAdvise,
DUnadvise, and EnumDAdvise are required. Support for
graphical formats other than CF_METAFILEPICT is optional.

IViewObject2 Indicates that the control has some interesting visuals when it
is not in-place active. If implemented, a control must support
the methods Draw, GetAdvise, SetAdvise, and GetExtent.

IDispatch Indicates that the control has either (a) custom methods, or
(b) custom properties that are both available via late-binding
through IDispatch::Invoke. This also requires that the control
provides type information through other IDispatch methods.
A control may support multiple IDispatch implementations
where only one is associated with IID_IDispatch the others
must have their own unique dispinterface identifiers.
A control is encouraged to supply dual interfaces for custom
method and property access, but this is optional if methods
and properties exist.
INTERFACE COMMENTS/WHAT IT MEANS TO SUPPORT THE INTERFACE

IConnectionPointContainer Indicates that a control supports at least one outgoing


interface, such as events or property change notifications. All
methods of this interface must be implemented if this
interface is available at all, including EnumConnectionPoints
which requires a separate object with
IEnumConnectionPoints.
Support for IConnectionPointContainer means that the
object also supports one or more related objects with
IConnectionPoint that are available through
IConnectionPointContainer methods. Each connection point
object itself must implement the full IConnectionPoint
interface, including EnumConnections, which requires another
enumerator object with the IEnumConnections interface.

IProvideClassInfo Indicates that the object can provide its own coclass type
IProvideClassInfo2 information directly through
IProvideClassInfo::GetClassInfo. If the control supports the
later variation IProvideClassInfo2, then it also indicates its
ability to provide its primary source IID through
IProvideClassInfo2::GetGUID. All methods of this interface
must be implemented.

ISpecifyPropertyPages Indicates that the control has property pages that it can
display such that a container can coordinate this control's
property pages with other control's pages when property
pages are to be shown for a multi-control selection. All
methods of this interface must be implemented when support
exists.

IPerPropertyBrowsing Indicates the control's ability to (a) provide a display string for
a property, (b) provide predefined strings and values for its
properties and/or (c) map a property dispID to a specific
property page. Support for this interface means that support
for properties through IDispatch as above is provided. If (c) is
supported, then it also means that the object's property
pages mapped through
IPerPropertyBrowsing::MapPropertyToPage themselves
implement IPropertyPage2 as opposed to the basic
IPropertyPage interface.

IPersistStream See Persistence Interfaces.


IPersistStreamInit
IPersistMemory
IPersistStorage
IPersistMoniker
IPersistPropertyBag

IOleCache Indicates support for container caching of control visuals. A


IOleCache2 control generally obtains caching support itself through the
OLE function CreateDataCache. Only controls with
meaningful static content should choose to do this (although
it is not required). If a control supports caching at all, it should
simply aggregate the data cache and expose both IOleCache
and IOleCache2 interfaces from the data cache. A control
implementing IOleObject must be able to handle
IAdviseSink if the container provides one; a container may
not, in which case a control ensures, of course, that it does not
attempt to call a non-existent sink.
INTERFACE COMMENTS/WHAT IT MEANS TO SUPPORT THE INTERFACE

IExternalConnection Indicates that the control supports external links to itself; that
is, the control is not marked with OLEMISC_CANTLINKINSIDE
and supports IOleObject::SetMoniker and
IOleObject::GetMoniker. A container will never query for
this interface itself nor call it directly as calls are generated
from inside OLE's remoting layer.

IRunnableObject Indicates that the control differentiates being loaded from


being running, as some in-process objects do.

Related topics
C
o
n
t
r
o
l
s
Persistence Interfaces
1/7/2020 • 2 minutes to read • Edit Online

Objects that have a persistent state of any kind must implement at least one IPersist* interface, and preferably
multiple interfaces, in order to provide the container with the most flexible choice of how it wishes to save a
control's state.
If a control has any persistent state whatsoever, it must, as a minimum, implement either IPersistStream or
IPersistStreamInit (the two are mutually exclusive and shouldn't be implemented together for the most part). The
latter is used when a control wishes to know when it is created new as opposed to reloaded from an existing
persistent state (IPersistStream does not have the created new capability). The existence of either interface
indicates that the control can save and load its persistent state into a stream, that is, an instance of IStream.
Beyond these two stream-based interfaces, the IPersist* interfaces listed in the following table can be optionally
provided in order to support persistence to locations other than an expandable IStream.
A set of component categories is identified to cover the support for persistency interfaces see Component
Categories.

INTERFACE USAGE

IPersistMemory The object can save and load its state into a fixed-length
sequential byte array (in memory).

IPersistStorage The object can save and load its state into an IStorage
instance. Controls that wish to be marked Insertable as other
compound document objects (for insertion into non-control
aware containers) must support this interface.

IPersistPropertyBag The object can save and load its state as individual properties
written to IPropertyBag which the container implements. This
is used for Save As Text functionality in some containers.

IPersistMoniker The object can save and load its state to a location named by
a moniker. The control calls IMoniker::BindToStorage to
retrieve the storage interface it requires, such as IStorage,
IStream, ILockBytes, IDataObject, etc.

While support for IPersistPropertyBag is optional, it is strongly recommended as an optimization for containers
with Save As Text features, such as Visual Basic.
With the exception of IPersistStream::GetSizeMax, IPersistStreamInit::GetSizeMax, and
IPersistMemory::GetSizeMax, all methods of each interface must be fully implemented.

Related topics
C
o
n
t
r
o
l
s
Optional Methods in Control Interfaces
1/7/2020 • 2 minutes to read • Edit Online

Implementing an interface doesn't necessarily mean implementing all methods of that interface to do anything
more than return E_NOTIMPL or S_OK as appropriate. The following table identifies the methods of the interfaces
listed in the What Support for an Interface Means topic that a control may implement in this manner. Any method
not listed here must be fully implemented if the interface is supported.

IOLECONTROL COMMENTS

GetControlInfo, OnMnemonic Mandatory for controls with mnemonics.

IOleControl::OnAmbientPropertyChange Mandatory for controls that use ambient properties.

IOleControl::FreezeEvents See Event Freezing

IOleObject

SetMoniker Mandatory if the control is not marked with


OLEMISC_CANTLINKINSIDE

GetMoniker Mandatory if the control is not marked with


OLEMISC_CANTLINKINSIDE

InitFromData Optional

GetClipboardData Optional

SetExtent Mandatory only for DVASPECT_CONTENT

GetExtent Mandatory only for DVASPECT_CONTENT

SetColorScheme Optional

DoVerb See note 1

IOleInPlaceObject

ContextSensitiveHelp Optional

ReactivateAndUndo Optional

IOleInPlaceActiveObject

ContextSensitiveHelp Optional

IViewObject2

Freeze Optional
IOLECONTROL COMMENTS

Unfreeze Optional

GetColorSet Optional

IPersistStream, IPersistStreamInit, IPersistMemory

GetSizeMax See note 2

1. A control with property pages must support IOleObject::DoVerb for the OLEIVERB_PROPERTIES and
OLEIVERB_PRIMARY verbs. A control that can be active must support DoVerb for the
OLEIVERB_INPLACEACTIVATE verb. A control that can be UI active must also support DoVerb for the
OLEIVERB_UIACTIVATE verb.
2. If a control supports IPersistStream or IPersistStreamInit and can return an accurate value, then it should do
so.

Related topics
C
o
n
t
r
o
l
s
Class Factory Options
1/7/2020 • 2 minutes to read • Edit Online

An ActiveX Control, by virtue of being a COM object, must have associated server code that supports control
creation through IClassFactory as a minimum.
It is optional, not required, that this class object also support IClassFactory2 for licensing management. Only
those vendors that are concerned about licensing need to support COM's licensing mechanism. In other words,
because IClassFactory2 is the only way to achieve COM -level licensing, this interface is required on the class
object for those controls that want to be licensed.

Related topics
C
o
n
t
r
o
l
s
Exposing Properties through IDispatch
1/7/2020 • 2 minutes to read • Edit Online

Although most controls do have properties, controls are not required to expose any properties and thus the
control does not require IDispatch. If the control does have properties, there are no requirements for which
properties a control must expose.

Related topics
C
o
n
t
r
o
l
s
Exposing Methods through IDispatch
1/7/2020 • 2 minutes to read • Edit Online

Although most controls do expose and support several methods, controls are not required to expose or support
any methods and thus the control does not require IDispatch. If the control does have any methods, there are no
requirements for which methods a control must expose.

Related topics
C
o
n
t
r
o
l
s
Events in Controls
1/7/2020 • 2 minutes to read • Edit Online

Although most controls do expose and fire several events, controls are not required to expose or fire any events
and thus the control does not require IConnectionPointContainer. If the control does have any events, there are
no requirements for which events a control must expose.

Related topics
C
o
n
t
r
o
l
s
Property Pages
1/7/2020 • 2 minutes to read • Edit Online

Support for property pages and per-property browsing is strongly recommended, but not required. If a control
does implement property pages, then those pages should conform to one of the standard sizes: 250x62 or
250x110 dialog units (DLUs).

Related topics
C
o
n
t
r
o
l
s
Ambient Properties for Controls
1/7/2020 • 2 minutes to read • Edit Online

If a control supports any ambient properties at all, it must at least respect the values of the following ambient
properties under the conditions stated in the following table using the standard dispids.

AMBIENT PROPERTY DISPID COMMENT/CONDITIONS FOR USE

LocaleID -705 If Locale is significant to the control, e.g.


for text output

UserMode -709 If the control behaves differently in user


(design) mode and run mode

UIDead -710 If the control reacts to UI events, then it


should honor this ambient property

ShowGrabHandles -711 If the control support in-place resizing


of itself

ShowHatching -712 If the control support in-place


activation and UI activation

DisplayAsDefault -713 Only if the control is marked


OLEMISC_ACTSLIKEBUTTON (which
means that support for keyboard
mnemonics is provided, thus
IOleControl::GetControlInfo and
IOleControl::OnMnemonic must be
implemented).

As described previously, use of ambients requires both IOleControl (for OnAmbientPropertyChange as a


minimum) as well as IOleObject (for SetClientSite and GetClientSite).
The OLEMISC_SETCLIENTSITEFIRST bit may not necessarily be supported by a container. In these
circumstances, a control must resort to default values for the ambient properties that it requires.

Related topics
C
o
n
t
r
o
l
s
Using the Container's Functionality
1/7/2020 • 2 minutes to read • Edit Online

The previous sections have described some of the necessary caller-side support that an ActiveX control must have
in order to access certain features of its container. The following table describes a control's usage of container-side
interfaces and when such usage would occur.

INTERFACE CONTAINER OBJECT USAGE

IOleClientSite Site Controls that implement IOleObject


call IOleClientSite methods as part of
the standard OLE embedding protocol,
specifically the methods SaveObject,
ShowObject, OnShowWindow (only if
a separate-window activation state is
supported),
RequestNewObjectLayout, and
GetContainer (if communication with
other controls is desired). The
GetMoniker method is only used when
the control can be linked to externally,
that is, the control is not marked with
OLEMISC_CANTLINKINSIDE.

IOleInPlaceSite Site Controls that have an in-place activate


and possibly a UI active state will call
IOleInPlaceSite methods (generally all
of them with the exception of
ContextSensitiveHelp) as part of the
standard OLE in-place activation
protocol.

IAdviseSink Site Control calls OnDataChange if the


control supports IDataObject,
OnViewChange if the control supports
IViewObject2, and OnClose, OnSave,
and OnRename if the control supports
IOleObject.

IOleControlSite Site If supported, control calls


OnControlInfoChanged when
mnemonics change, LockInPlaceActive
and TransformCoords if events are
fired (the latter method is only used if
coordinates are passed as event
arguments), OnFocus and
TranslateAccelerator if the control has
a UI active state, and
GetExtendedControl if the control
wants to look at extended-control
(container-owned) properties.

IDispatch (ambient properties) Site Used to access ambient properties.


INTERFACE CONTAINER OBJECT USAGE

IPropertyNotifySink Varies A control must generate OnChanged


and OnRequestEdit for any control
properties that are marked as
[bindable] and [request], respectively.

Other event sink interfaces Varies A control that has outgoing interfaces
other than IPropertyNotifySink will be
handed other interface pointers of the
correct IID to the control's
IConnectionPoint::Advise
implementations (which are usually
found in sub-objects of the control). A
control always knows how to call its
own event interfaces because the
control defines those interfaces.

IOleInPlaceFrame Frame Used when a control has an in-place UI


active state that requires frame-level
tools or menu items.

IOleInPlaceUIWindow Document Used only when a control has an in-


place UI active state that requires
document-level or pane-level UI tools.
This is rare.

Related topics
C
o
n
t
r
o
l
s
Containers
1/7/2020 • 2 minutes to read • Edit Online

An ActiveX Control container is an OLE container that supports the following additional features:
Embedded objects from in-process servers
In-place activation
OLEMISC_ACTIVATEWHENVISIBLE
Event handling
ActiveX Control Containers must provide support for all of these features.
For more information, see the following topics:
Required Interfaces
Optional Methods
Miscellaneous Status Bits Support
Keyboard Handling in Controls
Storage Interfaces
Ambient Properties
Extended Properties, Events and Methods
Message Reflection
Automatic Clipping
Degrading Gracefully in the Absence of an Interface

Related topics
A
c
t
i
v
e
X
C
o
n
t
r
o
l
a
n
d
C
o
n
t
r
o
l
C
o
n
t
a
i
n
e
r
G
u
i
d
e
l
i
n
e
s
Required Interfaces
1/7/2020 • 2 minutes to read • Edit Online

The table below lists the ActiveX Control Container interfaces, and denotes which interfaces are optional, and
which are mandatory and must be implemented by control containers.

INTERFACE REQUIRED? COMMENTS

IOleClientSite Yes

IAdviseSink No Only when the container desires (a)


data change notifications (controls with
IDataObject), (b) view change
notification (controls that are not active
and have IViewObject or
IViewObject2), and (c) other
notifications from controls acting as
standard embedded objects.

IOleInPlaceSite Yes

IOleControlSite Yes

IOleInPlaceFrame Yes

IOleContainer Yes See note 1

IDispatch for ambient properties Yes See note 2 and Ambient Properties for
Controls

Control Event Sets Yes See note 2

ISimpleFrameSite No ISimpleFrameSite and support for


nested simple frames is optional.

IPropertyNotifySink No Only needed for containers that (a)


have their own property editing UI
which would require updating whenever
a control changed a property itself or
(b) want to control [requestedit]
property changes and other such data-
binding features.

IErrorInfo Yes Mandatory if container supports dual


interfaces. See note 2.

IClassFactory2 No Support is strongly recommended.

1. IOleContainer is implemented on the document or form object (or appropriate analog) that holds the
container sites. Controls use IOleContainer to navigate to other controls in the same document or form.
2. Support for dual interfaces is not mandatory, but is strongly recommended. Writing ActiveX control containers
to take advantage of dual interfaces will afford better performance with controls that offer dual interface
support.
ActiveX control containers must support OLE Automation exceptions. If a control container supports dual
interfaces, then it must capture automation exceptions through IErrorInfo.

Related topics
C
o
n
t
a
i
n
e
r
s
Optional Methods
1/7/2020 • 2 minutes to read • Edit Online

An OLE component can implement an interface without implementing all the semantics of every method in the
interface, instead returning E_NOTIMPL or S_OK as appropriate. The following table describes those methods that
an ActiveX control container is not required to implement (i.e. the control container can return E_NOTIMPL ).
The table below describes optional methods; note that the method must still exist, but can simply return
E_NOTIMPL instead of implementing real semantics. Note that any method from a mandatory interface that is not
listed below must be considered mandatory and may not return E_NOTIMPL.

IOleClientSite
METHOD COMMENTS

SaveObject Necessary for persistence to be successfully supported.

GetMoniker Necessary only if the container supports linking to controls


within its own form or document.

IOleInPlaceSite
METHOD COMMENTS

ContextSensitiveHelp Optional

Scroll May return S_FALSE with no action.

DiscardUndoState Can return S_OK with no action.

DeactivateAndUndo Deactivation is mandatory; Undo is optional.

IOleControlSite
METHOD COMMENTS

GetExtendedControl Necessary for containers that support extended controls.

ShowPropertyFrame Necessary for containers that wish to include their own


property pages to handle extended control properties in
addition to those provided by a control.

TranslateAccelerator May return S_FALSE with no action.

LockInPlaceActive Optional

IDispatch (Ambient properties)


METHOD COMMENTS

GetTypeInfoCount Necessary for containers that support non-standard ambient


properties.

GetTypeInfo Necessary for containers that support non-standard ambient


properties.

GetIDsOfNames Necessary for containers that support non-standard ambient


properties.

IDispatch (Event sink)


METHOD COMMENTS

GetTypeInfoCount The control knows its own type information, so it has no need
to call this.

GetTypeInfo The control knows its own type information, so it has no need
to call this.

GetIDsOfNames The control knows its own type information, so it has no need
to call this.

IOleInPlaceFrame
METHOD COMMENTS

ContextSensitiveHelp

GetBorder Necessary for containers with toolbar UI (which is optional)

RequestBorderSpace Necessary for containers with toolbar UI (which is optional)

SetBorderSpace Necessary for containers with toolbar UI (which is optional)

InsertMenus Necessary for containers with menu UI (which is optional)

SetMenu Necessary for containers with menu UI (which is optional)

RemoveMenus Necessary for containers with menu UI (which is optional)

SetStatusText Necessary only for containers that have a status line

EnableModeless Optional

TranslateAccelerator Optional

IOleContainer
METHOD COMMENTS

ParseDisplayName Only if linking to controls or other embeddings in the


container is supported, as this is necessary for moniker
binding.

LockContainer As for ParseDisplayName

EnumObjects Returns all ActiveX controls through an enumerator with


IEnumUnknown, but not necessarily all objects (because
there's no guarantee that all objects are ActiveX controls; some
may be regular Windows controls).

Related topics
C
o
n
t
a
i
n
e
r
s
Miscellaneous Status Bits Support
1/7/2020 • 2 minutes to read • Edit Online

ActiveX Control Containers must recognize and support the following OLEMISC_ status bits.

STATUS BIT REQUIRED? COMMENTS

ACTIVATEWHENVISIBLE Yes

IGNOREACTIVATEWHENVISIBLE No Needed for inactive and windowless


control support. The
IGNOREACTIVATEWHENVISIBLE bit is
for containers hosting inactive and
windowless controls. The
IGNOREACTIVATEWHENVISIBLE bit is
introduced as part of the ActiveX
Controls 96 specification, see this
documentation for more details.

INSIDEOUT No Not generally used with ActiveX


Controls but rather with compound
document embeddings. Note this is
contrary to some SDK documentation
that says this bit must be set for the
ACTIVATEWHENVISIBLE bit to be set.

INVISIBLEATRUNTIME Yes Designates a control that should be


visible at design time, but invisible at
run time.

ALWAYSRUN Yes

ACTSLIKEBUTTON No Support is normally mandatory


although it is not necessary for
document style containers.

ACTSLIKELABEL No Support is normally mandatory


although it is not necessary for
document style containers.

NOUIACTIVATE Yes

ALIGNABLE No

SIMPLEFRAME No See Simple Frame Site Containment

SETCLIENTSITEFIRST No Support for this bit is recommended but


not mandatory.

IMEMODE No

Related topics
C
o
n
t
a
i
n
e
r
s
Keyboard Handling in Controls
1/7/2020 • 2 minutes to read • Edit Online

Keyboard handling support for the following functionality is strongly recommended, although it is recognized that
it is not applicable to all containers.
Support for OLEMISC_ACTSLIKELABEL and OLEMISC_ACTSLIKEBUTTON status bits.
Implementing the DisplayAsDefault ambient property (if it exists, it can return FALSE ).
Implementing tab handling, including tab order.
Some containers will use ActiveX controls in traditional compound document scenarios. For example, a
spreadsheet may allow a user to embed an ActiveX control into a worksheet. In such scenarios, the container
would do keyboard handling differently, because the keyboard interface should remain consistent with the user's
expectations of a spreadsheet. Documentation for such products should inform users of differences in control
handling in these different scenarios. Other containers should endeavor to honor the above functionality correctly,
including Mnemonic handling.

Related topics
C
o
n
t
a
i
n
e
r
s
Storage Interfaces
1/7/2020 • 2 minutes to read • Edit Online

Control containers must be able to support controls that implement IPersistStorage, IPersistStream, or
IPersistStreamInit. Optionally, a container can support any other persistence interfaces such as IPersistMemory,
IPersistPropertyBag, and IPersistMoniker for those controls that provide support.
Once an ActiveX control container has chosen and initialized a storage interface to use (IPersistStorage,
IPersistStream, IPersistStreamInit, etc), that storage interface will remain the primary storage interface for the
lifetime of the control, i.e. the control will remain in possession of the storage. This does not preclude the container
from saving to other storage interfaces.
ActiveX control containers do not need to support a save as text mechanism, thus using IPersistPropertyBag and
the associated container-side interface IPropertyBag are optional.

Related topics
C
o
n
t
a
i
n
e
r
s
Ambient Properties
1/7/2020 • 2 minutes to read • Edit Online

At a minimum, ActiveX Control containers must support the following ambient properties using the standard
dispids.

AMBIENT PROPERTY DISPID COMMENTS/CONDITIONS

LocaleID -705

UserMode -709 For containers that have different user


and run environments.

DisplayAsDefault -713 For those containers where a default


button is relevant.

Related topics
C
o
n
t
a
i
n
e
r
s
Extended Properties, Events and Methods
1/7/2020 • 2 minutes to read • Edit Online

ActiveX control containers are not required to support extended controls. However, if the control container does
support extended properties, then it must support the following minimal set:
Visible
Parent
Default
Cancel
Currently, extended properties, events, and methods do not have standard dispids.

Related topics
C
o
n
t
a
i
n
e
r
s
Message Reflection
1/7/2020 • 2 minutes to read • Edit Online

It is strongly recommended that an ActiveX control container supports message reflection. This will result in more
efficient operation for subclassed controls. If message reflection is supported, the MessageReflect ambient
property must be supported and have a value of TRUE. If a container does not implement message reflection,
then the OLE CDK creates two windows for every subclassed control, to provide message reflection on behalf on
the control container.

Related topics
C
o
n
t
a
i
n
e
r
s
Automatic Clipping
1/7/2020 • 2 minutes to read • Edit Online

It is strongly recommended that an ActiveX control container supports automatic clipping of its controls. This will
result in more efficient operation for most controls. If automatic clipping is supported, the AutoClip ambient
property must be supported and have a value of TRUE.
Automatic clipping is the ability of a container to ensure that a control's drawn output goes only to the container's
current clipping region. In a container that supports automatic clipping, a control can paint without regard to its
clipping region, because the container will automatically clip any painting that occurs outside the control's area. If a
container does not support automatic clipping, then CDK-generated controls will create an extra parent window if
a non-null clipping region is passed.

Related topics
C
o
n
t
a
i
n
e
r
s
Degrading Gracefully in the Absence of an Interface
1/29/2020 • 5 minutes to read • Edit Online

Because a control may not support any interface other than IUnknown, a container has to degrade gracefully
when it encounters the absence of any particular interface.
One might question the usefulness of a control with nothing more than IUnknown. But consider the advantages
that a control receives from a container's visual programming environment (such as VB ) when the container
recognizes the object as a control:
A button for the object appears in a toolbox.
One can create an object by dragging it from the toolbox onto a form.
One can give the object a name that is recognized in the visual programming environment.
The same name in (3) above can be used immediately in writing any other code for controls on the same form
(or even a different form).
The container can automatically provide code entry points for any events available from that object.
The container provides its own property browsing UI for any available properties.
When an object isn't recognized as a control, then it potentially loses all of these very powerful and beneficial
integration features. For example, in Visual Basic 4.0 it is very difficult to really integrate some random object that
is not a control in the complete sense, but may still have properties and events. Because Visual Basic 4's idea of a
control is very restrictive, the object does not gain any of the integration features above. But even a control with
IUnknown, where the mere lifetime of the control determines the existence of some resource, should be able to
gain the integration capabilities described above.
As current tools require a large set of control interfaces to gain any advantage, controls are generally led to over-
implementation, such that they contain more code than they really need. Controls that could be 7K might end up
being 25K, which is a big performance problem in areas such as the Internet. This has also led to the perception
that one can only implement a control with one tool like the CDK because of the complexity of implementing all
the interfaces, and this has implications when a large DLL like OC30.DLL is required for such a control, increasing
the working set. If not all interfaces are required, then this opens up many developers to writing very small and
light controls with straight OLE or with other tools as well, minimizing the overhead for each control.
This is why this appendix recognizes a control as any object with a CLSID and an IUnknown interface. Even with
nothing more than IUnknown, a container with a programming environment should be able to provide at least
features #3 and ) registry entry, it gains #1 and #2. If the object supplies IConnectionPointContainer (and
IProvideClassInfo generally) for some event set, it gains #5, and if it supports IDispatch for properties and
methods, it gains #6, as well as better code integration in the container.
In short, an object should be able to implement as little as IDispatch and one event set exposed through
IConnectionPointContainer to gain all of those visual features above.
With this in mind, the following table describes what a container might do in the absence of any possible interface.
Note that only those interfaces are listed that the container will directly obtain through QueryInterface. Other
interfaces, like IOleInPlaceActiveObject, are obtained through other means.

INTERFACE MEANING OF INTERFACE ABSENCE


INTERFACE MEANING OF INTERFACE ABSENCE

IViewObject2 The control has no visuals that it will draw itself, so has no
definite extents to provide. In run-time, the container simply
doesn't attempt to draw anything when this interface is
absent. In design time, the container must at least draw some
kind of default rectangle with a name in it for such a control,
so a user in a visual programming environment can select the
object and check out its properties, methods, and events that
exist. Handling the absence of IViewObject2 is critical for
good visual programming support.

IOleObject The control doesn't need the site whatsoever, nor does it take
part in any embedded object layout negotiation. Any
information (like control extents) that a container might expect
from this interface should be filled in with container-provided
defaults.

IOleInPlaceObject The control doesn't go in-place active (like a label) and thus
never attempts to activate in this manner. Its only activation
may be its property pages.

IOleControl Control has no mnemonics and no use of ambient properties,


and doesn't care if the container ignores events. In the
absence of this interface, the container just doesn't call its
methods.

IDataObject The control provides no property sets nor any visual


renderings that could be cached, so the container would
choose to cache some default presentation in the absence of
this interface (support for CF_METAFILEPICT, specifically) and
disable any property-set related functionality.

IDispatch The control has no custom properties or methods. The


container does not need to try to show any control properties
in this case, and should disallow any custom method calls that
the container doesn't recognize as belonging to its own
extended controls (that may support methods and
properties). As extended controls generally delegate certain
IDispatch calls to the control, an extended control should not
expect the control to have IDispatch at all.

IConnectionPointContainer The control has no events, so the container doesn't have to


think about handling any.

IProvideClassInfo The control either doesn't have type information or events, or


IProvideClassInfo2 the container needs to go into the control's type information
through the control's registry entries. The existence of this
interface is an optimization.

ISpecifyPropertyPages The control has no property pages, so if the container has any
UI that would invoke them, the container should disable that
UI.

IPerPropertyBrowsing The control has no display name itself, no predetermined


strings and values, and no property to page mapping. This
interface is nearly always used for generating container user
interface, so such UI elements would be disabled in the
absence of this interface.
INTERFACE MEANING OF INTERFACE ABSENCE

IPersist* The control has no persistent state to speak of, so the


container doesn't have to worry about saving any control-
specific data. The container will, of course, save its own
information about the control in its own form or document,
but the control itself has nothing to contribute to that
information.

IOleCache The object doesn't support caching. A container can still


IOleCache2 support caching by just creating a data cache itself using
CreateDataCache.

Related topics
C
o
n
t
a
i
n
e
r
s
Component Categories
1/7/2020 • 2 minutes to read • Edit Online

OLE's component categories enable a software component's abilities and requirements to be identified by entries
in the registry. In a scenario where a container may not want to or not be able to support an area of functionality,
such as databinding for example, the container will not want to host controls that require databinding in order to
perform their job function. Component categories allow areas of functionality such as databinding to be
identified, so that the control container can avoid those controls that state it to be a requirement. Component
categories are specified separately as part of OLE and are not specific to the ActiveX control architecture, the
specification for component categories includes APIs for manipulation of the component category registry keys.
For more information, see the following topics:
Component Categories and How they Work
Simple Frame Site Containment
Simple Data Binding
Advanced Data Binding
Visual Basic Private Interfaces
Internet-Aware Objects
Windowless Controls
Categorizing DCOM Proxies and Stubs

Related topics
A
c
t
i
v
e
X
C
o
n
t
r
o
l
a
n
d
C
o
n
t
r
o
l
C
o
n
t
a
i
n
e
r
G
u
i
d
e
l
i
n
e
s
Component Categories and How they Work
1/7/2020 • 3 minutes to read • Edit Online

Component categories identify those areas of functionality that a software component supports and requires, a
registry entry is used for each category or identified area of functionality. Each component category is identified by
a globally unique identifier (GUID ), when a control is installed it registers itself as a control in the system registry
using the component category ID for control, see Self Registration for Controls. Within the controls self
registration it will also register those component categories that it implements and those component categories
that it requires a container to support in order to successfully host the control.
When a control container is offering controls to the user to insert, it only allows the user to select and instantiate
those controls that will be able to function adequately in that environment. For example, if the control container
does not support databinding, then the container will not allow the user to select and instantiate those controls that
have an entry in the registry signifying that they require the databinding component category. A common dialog
for control insertion and APIs to handle the registry entries are available.
Component categories are not cumulative or exclusive, a control can require any mix of component categories to
function. A control that has no required entries for component categories may be expected to be capable of
functioning in any control container and not require any specific functionality of a control container to function.
The following component categories are identified here, where necessary more detailed specifications of the
categories may be available.
ISimpleFrameSite control containment.
Simple Databinding through the IPropertyNotifySink interface.
Advanced Databinding (as supported by the additional databinding interfaces of VB4.0).
Visual Basic private interfaces - IVBFormat, IVBGetControl
Internet aware controls.
Windowless controls.
This is not a definitive list of categories; further categories are likely to be defined in the future as new
requirements are identified. An up-to-date list of component categories is available from Microsoft; this list reflects
those component categories that have been identified by Microsoft and any others that about which vendors have
informed Microsoft.
It is important to remember that controls should attempt to work in as many environments as possible. If it is
possible, the control should degrade its functionality when placed in a container that does not support certain
interfaces. The purpose of component categories is to prevent a situation where the control is placed in an
environment that is unsuitable and the control cannot achieve its desired task. Generally, a control should degrade
gracefully when interfaces are not present, a control may choose to advise the user with a message box that some
functionality is not available or clearly document the functionality required of a control container for optimal
performance.
Note older controls and containers do not make use of component categories and instead rely on the control
keyword being present against the control in the registry. In order to be recognized by older containers controls
may wish to register the control keyword in the registry, control developers should check that the control can
successfully be hosted in such containers before doing this. Containers that use component categories may
successfully use them to host older controls as the components category DLL handles the mapping, a separate
category exists for older controls CATID_ControlV1 so that a container may optionally exclude them if necessary.
As component categories are identified by GUIDs it is possible for containers that offer particular specific
functionality to have their own category IDs, generated using a GUID generation tool. However this can possibly
undermine the advantage of interoperability of controls and containers so it is preferred that wherever possible
existing component categories be used. Vendors are encouraged to consult together when defining new
component categories to ensure that they meet the common requirements of the marketplace, and follow the spirit
of interoperability of ActiveX controls.

Related topics
C
o
m
p
o
n
e
n
t
C
a
t
e
g
o
r
i
e
s
Simple Frame Site Containment
1/7/2020 • 2 minutes to read • Edit Online

A container control is an ActiveX control that is capable of containing other controls. A group box that contains a
collection of radio buttons is an example of a container control. Container controls should set the
OLEMISC_SIMPLEFRAME status bit, and should call its container's ISimpleFrameSite implementation. An
ActiveX control container that supports container controls must implement ISimpleFrameSite.
CATID - {157083E0-2368-11cf-87B9-00AA006C8166} CATID_SimpleFrameControl

Related topics
C
o
m
p
o
n
e
n
t
C
a
t
e
g
o
r
i
e
s
Simple Data Binding
1/7/2020 • 2 minutes to read • Edit Online

The ActiveX controls architecture defines a data-binding mechanism, whereby an ActiveX control can specify that
one or more of its properties are bindable. In most cases, a data-bound control should not absolutely require data
binding, so that it could be inserted into a container that does not support data binding. Obviously, in such a
situation, the functionality of the control may be reduced.
CATID - {157083E1-2368-11cf-87B9-00AA006C8166} CATID_PropertyNotifyControl

Related topics
C
o
m
p
o
n
e
n
t
C
a
t
e
g
o
r
i
e
s
Advanced Data Binding
1/7/2020 • 2 minutes to read • Edit Online

There is a set of advanced data binding interfaces that allow a more complex databinding scenario to be supported.
This component category covers that area of functionality.
CATID - {157083E2-2368-11cf-87B9-00AA006C8166} CATID_VBDataBound

Related topics
C
o
m
p
o
n
e
n
t
C
a
t
e
g
o
r
i
e
s
Visual Basic Private Interfaces
1/7/2020 • 2 minutes to read • Edit Online

Two interfaces that are implemented by Visual Basic are identified here for component categories. It is not
expected that controls should require these categories because it is possible for controls to offer alternative
functionality when these are not available.
The IVBFormat interface allows controls to better integrate into the Visual Basic environment when formatting
data.
CATID - {02496840-3AC4-11cf-87B9-00AA006C8166} CATID_VBFormat
The IVBGetControl interface allows a control to enumerate other controls on the VB form.
CATID - {02496841-3AC4-11cf-87B9-00AA006C8166} CATID_VBGetControl
Two additional private interfaces, IGetVBAObject and IGetOleObject, are described here even though they do
not define component categories. Use of these four interfaces is not recommended because they are not supported
by containers other than Visual Basic.

Related topics
C
o
m
p
o
n
e
n
t
C
a
t
e
g
o
r
i
e
s
Internet-Aware Objects
1/7/2020 • 2 minutes to read • Edit Online

There are certain categories identified to cover the persistency interfaces; these have been identified as a result of
defining how controls function across the Internet. A container that does not support the full range of persistency
interfaces should ensure that it does not host a control that requires a combination of interfaces that it does not
support.
The following tables describe the meaning for various categories as both implemented and required categories.

REQUIRED CATEGORIES DESCRIPTION

CATID_PersistsToMoniker, CATID_PersistsToStreamInit, Each of these categories is mutually exclusive and only used
CATID_PersisitsToStream, CATID_PersistsToStorage, when an object supports only one persistence mechanism at
CATID_PersistsToMemory, CATID_PersistsToFile, all (hence the mutual exclusion). Containers that do not
CATID_PersistsToPropertyBag support the persistence mechanism described by one of these
categories should prevent themselves from creating any
objects of classes so marked.

CATID_RequiresDataPathHost The object requires the ability to save data to one or more
paths and requires container involvement, therefore requiring
container support for IBindHost.

IMPLEMENTED CATEGORIES DESCRIPTION

CATID_PersistsToMoniker, CATID_PersistsToStreamInit, Object supports the corresponding IPersist* mechanism for


CATID_PersistsToStream, CATID_PersistsToStorage, the category.
CATID_PersistsToMemory, CATID_PersistsToFile,
CATID_PersistsToPropertyBag

The following table provides the exact CATIDs assigned to each category:

CATEGORY CATID

CATID_RequiresDataPathHost 0de86a50-2baa-11cf-a229-00aa003d7352

CATID_PersistsToMoniker 0de86a51-2baa-11cf-a229-00aa003d7352

CATID_PersistsToStorage 0de86a52-2baa-11cf-a229-00aa003d7352

CATID_PersistsToStreamInit 0de86a53-2baa-11cf-a229-00aa003d7352

CATID_PersistsToStream 0de86a54-2baa-11cf-a229-00aa003d7352

CATID_PersistsToMemory 0de86a55-2baa-11cf-a229-00aa003d7352

CATID_PersistsToFile 0de86a56-2baa-11cf-a229-00aa003d7352

CATID_PersistsToPropertyBag 0de86a57-2baa-11cf-a229-00aa003d7352
Related topics
C
o
m
p
o
n
e
n
t
C
a
t
e
g
o
r
i
e
s
Windowless Controls
1/7/2020 • 2 minutes to read • Edit Online

The ActiveX Controls 96 specification includes a definition for windowless controls. Such controls do not operate
in their own window and require a container to offer a shared window into which the control may draw, see the
ActiveX SDK. Windowless controls are designed to be compatible with older control containers by creating their
own window in that situation, windowless control containers should host windowed controls in the traditional way
with no problem. It may however be useful for a container to distinguish those controls that can operate in a
windowless mode, so an appropriate component category is defined.
CATID - {1D06B600-3AE3-11cf-87B9-00AA006C8166} CATID_WindowlessObject

Related topics
C
o
m
p
o
n
e
n
t
C
a
t
e
g
o
r
i
e
s
Categorizing DCOM Proxies and Stubs
1/7/2020 • 2 minutes to read • Edit Online

DCOM marshals references to objects by constructing OBJREFs that contain CLSIDs. These CLSIDs are
vulnerable to security attacks because arbitrary DLLs can be loaded during marshaling. However, the
EOAC_NO_CUSTOM_MARSHAL flag can be specified when calling CoInitializeSecurity (see
EOLE_AUTHENTICATION_CAPABILITIES ). Setting this flag helps protect server security when using DCOM
because it reduces the chances of executing arbitrary DLLs. When this flag is set, the server allows the marshaling
only of CLSIDs that are implemented in ole32.dll, comadmin.dll, comsvcs.dll, or es.dll, or that implement the
CATID_MARSHALER category ID.
CATID_MARSHALER is a component category GUID that can be associated with a CLSID that is being custom
marshaled. The interfaces being custom marshaled with this CLSID are allowed when the
EOAC_NO_CUSTOM_MARSHAL is set via CoInitializeSecurity.

Related topics
C
o
m
p
o
n
e
n
t
C
a
t
e
g
o
r
i
e
s
General Guidelines
1/7/2020 • 2 minutes to read • Edit Online

The following topics describe various features, hints and tips for ActiveX Control and ActiveX Control container
developers to help maintain good interoperability between controls and control containers:
Overloading IPropertyNotifySink
Container-Specific Private Interfaces
Multi-Threaded Issues
Event Freezing
Container Controls
WS_GROUP and WS_TABSTOP Flags in Controls
Multiple Controls in One DLL
The IOleContainer::EnumObjects Method
Enhanced Metafiles
Licensing
Dual Interfaces
IPropertyBag and IPersistPropertyBag

Related topics
A
c
t
i
v
e
X
C
o
n
t
r
o
l
a
n
d
C
o
n
t
r
o
l
C
o
n
t
a
i
n
e
r
G
u
i
d
e
l
i
n
e
s
Overloading IPropertyNotifySink
1/7/2020 • 2 minutes to read • Edit Online

Many ActiveX control containers implement a modeless property browsing window. If a control's properties are
altered through the control's property pages, then the control's properties can get out of sync with the container's
view of those properties (the control is always right, of course). To ensure that it always has the current values for a
control's properties, an ActiveX control container can overload the IPropertyNotifySink interface (data binding)
and also use it to be notified that a control property has changed. This technique is optional and is not required of
ActiveX control containers or ActiveX controls.
Note that a control should use OnRequestEdit only for data binding; it is free to use OnChanged for either or
both purposes.
Container-Specific Private Interfaces
1/7/2020 • 2 minutes to read • Edit Online

Some containers provide container-specific private interfaces for additional functionality or improved
performance. Controls that rely on those container-specific interfaces should, if possible, work without those
container-specific interfaces present so that the control functions in different containers. For example, Visual Basic
implements private interfaces that provide string formatting functionality to controls. If a control makes use of
these private formatting interfaces, it should be able to run with default formatting support if these interfaces are
not available. If the control can function without the private interfaces, it should take appropriate action (such as
warn the user of reduced functionality) but continue to work. If this is not an option, a component category should
be registered as required so that only containers supporting this functionality can host these controls.
Multi-Threaded Issues
1/7/2020 • 2 minutes to read • Edit Online

OLE provides support for multithreaded applications, allowing applications to make OLE calls from multiple
threads. This multithreaded support is called the apartment model, it is important that all OLE components using
multiple threads follow this model. The apartment model requires that interface pointers are marshaled (using
CoMarshalInterface, and CoUnmarshalInterface) when passed between threads.

Related topics
P
r
o
c
e
s
s
e
s
,
T
h
r
e
a
d
s
,
a
n
d
A
p
a
r
t
m
e
n
t
s
Event Freezing
1/7/2020 • 2 minutes to read • Edit Online

A container can notify a control that it is not ready to respond to events by calling IOleControl::FreezeEvents
with TRUE. It can unfreeze the events by calling FreezeEvents with FALSE. When a container freezes events, it is
freezing event processing, not event receiving; that is, a container can still receive events while events are frozen. If
a container receives an event notification while its events are frozen, the container should ignore the event. No
other action is appropriate.
A control should take note of a container's call to FreezeEvents with TRUE if it is important to the control that an
event is not missed. While a container's event processing is frozen, a control should implement one of the
following techniques:
Fire the events in the full knowledge that the container will take no action.
Discard all events that the control would have fired.
Queue up all pending events and fire them after the container has called FreezeEvents with FALSE.
Queue up only relevant or important events and fire them after the container has called FreezeEvents with
FALSE.
Each technique is acceptable and appropriate in different circumstances. The control developer is responsible for
determining and implementing the appropriate technique for the control's functionality.
Container Controls
1/7/2020 • 2 minutes to read • Edit Online

As described above, container controls are ActiveX controls that visually contain other controls. The ActiveX
controls architecture specifies the ISimpleFrameSite interface to enable container controls. Containers may also
support container controls without supporting ISimpleFrameSite, although the behavior cannot be guaranteed.
For this reason, a component category exists for SimpleFrameSite controls where the full functionality of this
interface is required.
To support container controls without implementing ISimpleFrameSite, an ActiveX control container must:
Activate all controls at all times.
Reparent the contained controls to the hWnd of the containing control.
Remain the parent of the container control.
WS_GROUP and WS_TABSTOP Flags in Controls
1/7/2020 • 2 minutes to read • Edit Online

A control should not use the WS_GROUP and WS_TABSTOP flags internally; some containers rely on these flags
to manage keyboard handling.
Multiple Controls in One DLL
1/7/2020 • 2 minutes to read • Edit Online

A single .ocx DLL can container any number of ActiveX controls, thus simplifying the distribution and use of a set
of related controls.
If you ship multiple controls in a single DLL, be sure to include the vendor name in each control name in the
package. Including the vendors' names in each control name will enable users to easily identify controls within a
package. For example, if you ship a DLL that implements three controls, Con1, Con2, and Con3, then the control
names should be:
Your company name Con1 Control
Your company name Con2 Control
Your company name Con3 Control
The IOleContainer::EnumObjects Method
1/7/2020 • 2 minutes to read • Edit Online

This method is used to enumerate over all the OLE objects contained in a document or form, returning an interface
pointer for each OLE object. The container must return pointers to each OLE object that shares the same container.
Nested forms or nested controls must also be enumerated.
Some containers implement extender controls, which wrap non-ActiveX controls, and then return pointers to these
extender controls as a form is enumerated. This behavior enables ActiveX controls and ActiveX control containers
to integrate well with non-ActiveX controls, and is thus recommended, but not required.
Enhanced Metafiles
1/7/2020 • 2 minutes to read • Edit Online

Not surprisingly, enhanced metafiles provide more functionality than standard metafiles; using enhanced metafiles
generally simplifies rendering code. An enhanced metafile DC is used in exactly the same way as a standard
metafile DC. OLE supports enhanced metafiles, and includes backward compatibility with standard metafiles.
ActiveX control containers should use enhanced metafiles instead of standard metafiles.
Licensing
1/7/2020 • 2 minutes to read • Edit Online

In order to embed licensed controls successfully, ActiveX control containers must use IClassFactory2 instead of
IClassFactory. Several OLE creation and loading helper functions (OleLoad and CoCreateInstance) explicitly
call IClassFactory and not IClassFactory2, and therefore cannot be used to create or load licensed ActiveX
controls. ActiveX control containers should explicitly create and load ActiveX Controls using IClassFactory2.
Dual Interfaces
1/7/2020 • 2 minutes to read • Edit Online

OLE Automation enables an object to expose a set of methods in two ways: via the IDispatch interface, and
through direct OLE VTable binding. IDispatch is used by most tools available today, and offers support for late
binding to properties and methods.
VTable binding offers much higher performance because this method is called directly instead of through
IDispatch::Invoke. IDispatch offers late bound support, where direct VTable binding offers a significant
performance gain; both techniques are valuable and important in different scenarios. By labeling an interface as
[dual] in the type library, an OLE Automation interface can be used either via IDispatch, or it can be bound to
directly. Containers can thus choose the most appropriate technique. Support for dual interfaces is strongly
recommended for both controls and containers.
IPropertyBag and IPersistPropertyBag
1/7/2020 • 2 minutes to read • Edit Online

IPropertyBag and IPersistPropertyBag optimize save as text mechanisms, and therefore are recommended for
ActiveX Control containers that implement a save as text mechanism. IPropertyBag is implemented by a
container, and is roughly analogous to IStream. IPersistPropertyBag is implemented by controls, and is roughly
analogous to IPersistStream.
Event Coordinate Translation
1/7/2020 • 2 minutes to read • Edit Online

The 96 specification for controls requires that coordinates passed for events fired by the control change from being
HIMETRIC to being points based. This change brings the event passing of coordinates in line with properties and
methods and thus coordinate translation is no longer the responsibility of the container. This raises certain
compatibility issues where a control fires events using a coordinate base that it is not expecting, this should only be
an issue where a 96 control container is hosting an older pre-96 control as follows:
When an older pre-96 container hosts a 96 control the control will present the event coordinates as points, this
should not cause the container any problems as the container should recognize the parameter type.
When a 96 container hosts a pre-96 control the control will present the container with coordinates and expect
the container to any translation necessary. However the 96 container will be expecting a control to conform to
the 96 controls specification and present its coordinates as points. The control uses the TransformCoords
method on the IOleControlSite interface provided by the container in the same way as it does for properties
and methods to achieve this.
As a result the user of a 96 container hosting pre-96 controls will need to be aware that further translation of
coordinates may be necessary when events are fired.
Standard DISPIDS
1/7/2020 • 2 minutes to read • Edit Online

A number of standard dispids have been defined for the controls specification.

DISPID_MOUSEPOINTER
Property of type integer.

#define DISPID_MOUSEPOINTER -521

The Mousepointer property identifies standard mouse icons.

VALUE DESCRIPTION

0 (Default) Shape determined by the object.

1 Arrow

2 Cross (cross-hair pointer)

3 I Beam

4 Icon (small square within a square)

5 Size (four-pointed arrow pointing north, south, east, and west)

6 Size NE SW (double arrow pointing northeast and southwest)

7 Size N S (double arrow pointing north and south)

8 Size NW, SE

9 Size E W (double arrow pointing east and west)

10 Up Arrow

11 Hourglass (wait)

12 No Drop

13 Arrow and hourglass

14 Arrow and question mark

15 Size all

99 Custom icon specified by the MouseIcon property


DISPID_MOUSEICON
Property of type picture.

#define DISPID_MOUSEICON -522

DISPID_PICTURE
Property of type picture.

#define DISPID_PICTURE -523

DISPID_VALID
Used to determine if the control has valid data or not.
Property of type BOOL.

#define DISPID_VALID -524

DISPID_ AMBIENT_PALETTE
Used to allow the control to get the container's HPAL. If the container supplies an ambient palette then that is the
only palette that may be realized into the foreground. Controls that want to realize their own palettes must do so in
the background. If there is no ambient palette provided by the container, then the active control can realize its
palette in the foreground. Palette handling is further discussed in Palette Behavior for OLE Controls which is in the
ActiveX SDK.

#define DISPID_AMBIENT_PALETTE -726


Databinding
1/7/2020 • 2 minutes to read • Edit Online

A new databinding attribute has been added to allow properties distinguish between communicating changes only
when focus leaves the control or during all property change notifications.
The new attribute, known as ImmediateBind, enables controls to differentiate two different types of bindable
properties. One type of bindable property needs to notify every change to the database, for example with a check
box control where every change needs to be sent through to the underlying database even though the control has
not lost the focus. However controls such as a listbox only wish to have the change of a property notified to the
database when the control loses focus, as the user may have changed the highlighted selection with the arrow keys
before finding the desired setting, to have the change notification sent to the database every time that the user hit
the arrow key would be give unacceptable performance. The new immediate bind property allows individual
bindable properties on a form to have this behavior specified, when this bit is set all changes will be notified.
The new ImmediateBind bit maps through to the new VARFLAG_FIMMEDIATEBIND (0x80) and the
FUNCFLAG_FIMMEDIATEBIND (0x80) bits in the VARFLAGS and FUNCFLAGS enumerations for the ITypeInfo
interface allowing for the properties attributes to be inspected.
Reference
1/7/2020 • 2 minutes to read • Edit Online

The following programming elements are used to create standard COM objects and property pages.
Constants
Enumerations
Functions
Interfaces
Structures
Constants
1/7/2020 • 2 minutes to read • Edit Online

The following constants are used to create standard COM objects and property pages.
PICTYPE Constants
PICTYPE Constants
1/7/2020 • 2 minutes to read • Edit Online

Describe the type of a picture object as returned by IPicture::get_Type, as well as to describe the type of picture in
the picType member of the PICTDESC structure that is passed to OleCreatePictureIndirect.

CONSTANT/VALUE DESCRIPTION

The picture object is currently uninitialized. This value is only


PIC valid as a return value from IPicture::get_Type and is not
TYP valid with the PICTDESC structure.
E_U
NIN
ITIA
LIZE
D
(-1)

A new picture object is to be created without an initialized


PIC state. This value is valid only in the PICTDESC structure.
TYP
E_N
ON
E
0

The picture type is a bitmap. When this value occurs in the


PIC PICTDESC structure, it means that the bmp field of that
TYP structure contains the relevant initialization parameters.
E_BI
TM
AP
1

The picture type is a metafile. When this value occurs in the


PIC PICTDESC structure, it means that the wmf field of that
TYP structure contains the relevant initialization parameters.
E_M
ETA
FILE
2

The picture type is an icon. When this value occurs in the


PIC PICTDESC structure, it means that the icon field of that
TYP structure contains the relevant initialization parameters.
E_IC
ON
3
CONSTANT/VALUE DESCRIPTION

The picture type is an enhanced metafile. When this value


PIC occurs in the PICTDESC structure, it means that the emf field
TYP of that structure contains the relevant initialization
E_E parameters.
NH
MET
AFIL
E
4

Requirements

Minimum supported client Windows 2000 Professional [desktop apps only]

Minimum supported server Windows 2000 Server [desktop apps only]

Header
Ole
Ctl.h

See also
I
P
i
c
t
u
r
e
:
:
g
e
t
_
T
y
p
e

O
l
e
C
r
e
a
t
e
P
i
c
t
u
r
e
I
n
d
i
r
e
c
t

P
I
C
T
D
E
S
C
Enumerations
1/7/2020 • 2 minutes to read • Edit Online

The following enumerations are used to create standard COM objects and property pages.
GUIDKIND
KEYMODIFIERS
PICTUREATTRIBUTES
POINTERINACTIVE
QACONTAINERFLAGS
Functions
1/7/2020 • 2 minutes to read • Edit Online

The following functions are used to create standard COM objects and property pages.
OleCreatePropertyFrame
OleCreatePropertyFrameIndirect
OleLoadPicturePath
OleTranslateColor
Interfaces
1/7/2020 • 2 minutes to read • Edit Online

The following interfaces are used to create standard COM objects and property pages.

INTERFACE DESCRIPTION

IFont Provides a wrapper around a Windows font object.

IFontDisp Exposes a font object's properties through Automation. It


provides a subset of the IFont methods.

IOleControl Provides the features for supporting keyboard mnemonics,


ambient properties, and events in control objects.

IOleControlSite Provides the methods that enable a site object to manage


each embedded control within a container.

IPerPropertyBrowsing Retrieves the information in the property pages offered by an


object.

IPicture Manages a picture object and its properties. Picture objects


provide a language-neutral abstraction for bitmaps, icons, and
metafiles.

IPictureDisp Exposes the picture object's properties through Automation. It


provides a subset of the functionality available through
IPicture methods.

IPointerInactive Enables an object to remain inactive most of the time, yet still
participate in interaction with the mouse, including drag and
drop.

IPrint Enables compound documents in general and active


documents in particular to support programmatic printing.

IPropertyNotifySink Implemented by a sink object to receive notifications about


property changes from an object that supports
IPropertyNotifySink as an outgoing interface.

IPropertyPage Provides the main features of a property page object that


manages a particular page within a property sheet.

IPropertyPage2 An extension to IPropertyPage to support initial selection of


a property on a page.

IPropertyPageSite Provides the main features for a property page site object.

IQuickActivate Enables controls and containers to avoid performance


bottlenecks on loading controls. It combines the load-time or
initialization-time handshaking between the control and its
container into a single call.
INTERFACE DESCRIPTION

ISimpleFrameSite Provides simple frame controls that act as simple containers


for other nested controls.

ISpecifyPropertyPage Indicates that an object supports property pages.


Structures
1/7/2020 • 2 minutes to read • Edit Online

The following structures are used to create standard COM objects and property pages.
CADWORD
CALPOLESTR
CAUUID
CONTROLINFO
FONTDESC
LICINFO
OCPFIPARAMS
PAGERANGE
PAGESET
PICTDESC
PROPPAGEINFO
QACONTAINER
QACONTROL
COM Language Translations
1/7/2020 • 2 minutes to read • Edit Online

Components created using the Component Object Model (COM ) can be reused in applications written in any
programming language that supports COM. This is because COM is a binary standard and, as such, is language-
independent.
COM objects are documented in the most relevant programming language or languages. For example, objects that
are created for use in webpages are typically documented in the Microsoft Visual Basic development system,
whereas system-level objects are typically documented in C++. However, because COM is language-neutral, you
are not limited to using an object in the same language in which it is written or documented. For example, you can
write an application in JScript that uses a control created in C++ and documented in Visual Basic.
The following topics discuss the differences between programming languages and describe how to translate COM
object syntax from one language to another. Additional topics describe how to use COM objects in various
scripting languages and environments.
Syntax Differences
Data Type Conversions
IDL Files
Translating COM Object Syntax for Programming Languages
Scripting with COM Objects
The intent is to address the most common language translation issues that arise when using COM objects. The
techniques and principles described apply to any programming or scripting language that supports COM. Because
scripting languages and programming languages represent different programming paradigms, translation
between scripting languages and programming languages is not addressed.

Related topics
C
o
m
p
o
n
e
n
t
O
b
j
e
c
t
M
o
d
e
l
(
C
O
M
)
Syntax Differences
1/7/2020 • 2 minutes to read • Edit Online

The most apparent change as you move between programming languages is the change in syntax.
Consider the EnhEvents object's Add method, shown as it is declared in three different languages.

object.Add(Time As Double, Name As String) As Variant

HRESULT Add(
double Time,
BSTR Name,
VARIANT* pVal
);

public com.ms.com.Variant Add(


double Time,
java.lang.String Name
);

Although the syntax of each language expresses the method differently, the functionality is the same. In each
language, the Add method takes the parameters Time and Name and returns an EnhEvent object. In the C++
example, the method returns the object by using a third, output parameter, pVal.
Typically, the functionality of a COM object is the same across programming languages. Because of this,
documentation for a COM object is useful even if the object is documented in another programming language
than the one you are using. The descriptions of the object's functionality, parameters, and return values are, with
few exceptions, valid for all languages.
For information about how to convert the syntax of a COM object to another programming language, see
Translating COM Object Syntax for Programming Languages.
The syntax differences among the scripting languages JavaScript, JScript, and VBScript are less pronounced than
the syntax differences among the programming languages shown preceding. For example, consider the square
function as it is implemented in each of these three scripting languages:

Function square(x)
square = x*x
End Function

function square(x){ return x*x; }

function square(x){ return x*x; }

Notice that the scripting languages, unlike the programming languages, are weakly typed. In other words, you do
not have to specify the data type of a parameter or return value when you declare a function. Instead, the variables
are automatically cast to the appropriate data type. In the case of VBScript, all variables are of the same data type,
Variant.
The JavaScript and JScript syntax for square is the same. JScript is largely compatible with JavaScript. However,
JScript includes some objects not currently supported by JavaScript, such as ActiveXObject, Enumerator, Error,
Global, and VBArray. For more information about these objects, see the JScript Language Reference.
On the surface, JavaScript and JScript syntax resembles Java syntax. This similarity is only superficial. The Java
language was developed independently from both JavaScript and JScript and is not related to either.
VBScript, on the other hand, is a subset of the Visual Basic programming language. Because of this, VBScript
syntax is a subset of Visual Basic syntax and is often interchangeable with Visual Basic syntax.
For information on using COM objects in scripting languages, see Scripting with COM Objects.
Data Type Conversions
1/7/2020 • 2 minutes to read • Edit Online

Each programming language defines certain types and containers for data. Most of these data types, especially the
primitives, map easily to other programming languages. Some data types, however, have no equivalent in another
language and cannot be converted.
For specific information about data types not recognized by your programming language, see the following topics:
Translating to C++
Translating to Visual Basic
Translating to Java
The following table lists conversions between programming languages for common data types.

C++ VISUAL BASIC JAVA CONTAINS

signed char Not supported byte 1-byte signed integer


(VT_I1, [T])

unsigned char Byte Not supported 1-byte unsigned integer


(VT_UI1, [V][T][P][S])

unsigned char Character char 2-byte Unicode character


(VT_UI2, [T][P])

short Integer short 2-byte signed integer


(VT_I2, [V][T][P][S])

unsigned short Not supported Not supported 2-byte unsigned integer


(VT_UI2, [T][P])

int Long int 4-byte signed integer


(VT_I4, [V][T][P][S])

unsigned int Not supported Not supported 4-byte unsigned integer


(VT_UI4, [T][P])

__int64 Not supported long 8-byte signed integer


(VT_I8, [T][P])

unsigned __int64 Not supported Not supported 8-byte unsigned integer


(VT_UI8, [T][P])

float Single float 4-byte floating-point


number
(VT_R4, [V][T][P][S])

double Double double 8-byte floating-point


number
(VT_R8, [V][T][P][S])
C++ VISUAL BASIC JAVA CONTAINS

BSTR String java.lang.String Automation string


(VT_BSTR, [V][T][P][S])

BOOL Boolean boolean Boolean


(VT_BOOL, [V][T][P][S])

VARIANT Variant com.ms.com.Variant VARIANT FAR*


(VT_VARIANT, [V][T][P][S])

IUnknown object com.ms.com.IUnknown IDispatch interface pointer


(VT_DISPATCH, [V][T][P][S])

DATE Date com.ms.com.Variant Date


(VT_DATE, [V][T][P][S])

CURRENCY Currency com.ms.com.Variant Currency


(VT_CY, [V][T][P][S] or
VT_DECIMAL, [V][T][S])

For information about VARTYPE values and how to use them, see the topic IDispatch Data Types and Structures.
The data type conversions between scripting languages are simpler than those for programming languages.
JScript and JavaScript both support the same data types, and VBScript supports only a single data type, Variant.
Thus, all JScript and JavaScript data types become Variant types when converted to VBScript. When you convert
VBScript to JScript or JavaScript, the Variant types become numbers, strings, Boolean values, and so on.
IDL Files
1/7/2020 • 2 minutes to read • Edit Online

COM uses the Microsoft Interface Definition Language (MIDL ) to describe COM objects. MIDL is an extension of
the IDL for distributed computing environments defined by the Open Software Foundation, which was developed
to define interfaces for remote procedure calls in traditional client/server applications. MIDL includes most of the
attributes and statements of Object Definition Language (ODL ), the language originally used to generate type
libraries for OLE Automation.
In C++ and Java, a developer building a COM object creates an IDL file that the MIDL compiler then processes to
create a type library or header and proxy files, or both. A type library is a binary file that describes the COM object
or COM interfaces, or both. A type library is the compiled version of the IDL file. However, type libraries support
ODL semantics only. In particular, they cannot represent all the information from an IDL file related to IDL
attributes like [size_is]. You need to create and use proxy files for IDL files affected by information loss in the type
library.
In Visual Basic, a developer creating a COM object does not create an IDL file. Instead, Visual Basic gathers
information using class and project properties and directly creates the type library.
Translating COM Object Syntax for Programming
Languages
1/7/2020 • 2 minutes to read • Edit Online

To call a COM object from an application written in a programming language other than the one used to write the
COM object, you must first translate the object's syntax to your programming language. This can be done using
the following steps:
1. View the COM object's type library in your programming language's syntax. Doing this provides you with
descriptions of the object's classes, interfaces, methods, properties and events in the language syntax you
use.
Microsoft developer products provide several tools to assist you in viewing and converting type libraries.
For more information, see Type Library Viewers and Conversion Tools and How Developer Tools Use Type
Libraries.
Once you can view the object's type library in your preferred programming language, you can compare its
syntax to that in the documentation for the object. If the object is documented in a programming language
other than the one you are using, the data types and syntax may differ, but descriptions of parameters,
return values, and the object's functionality should be the same.
2. Take into account any special considerations for translating to your programming language.
Because each programming language defines concepts that may not have an equivalent in other languages,
some of an object's functionality may work differently in another language, or not be available at all. For
example, the Visual Basic programming language does not recognize C++ unsigned data types, such as
unsigned long. An application written in Visual Basic cannot use COM methods that accept or return
unsigned data type variables.
3. Add the COM object's compiled code to your project. The compiled code is typically contained in a .dll or
.ocx file. This step is necessary for the compiler to recognize the COM object's classes. After you add the
COM object, your application can use its classes and interfaces.
The following topics describe how to translate and use COM objects in a variety of programming languages:
Translating to C++
Translating to Visual Basic
Translating to Java
These topics describe conversion tools and processes provided by Microsoft developer products. For instructions
on how to program COM objects using development tools created by other companies, see those development
tools' documentation.
Type Library Viewers and Conversion Tools
1/7/2020 • 2 minutes to read • Edit Online

Type libraries contain the specification for one or more COM elements, including classes, interfaces, enumerations,
and more. These files are stored in a standard binary format. A type library can be a stand-alone file with the .tlb
file name extension, or it can be stored as a resource in an executable file, which can have an .ocx, .dll, or .exe file
name extension. The type library viewers and conversion tools described following read this format to gain
information about the COM elements in the library.
Before you can program an object in a particular programming language, you must be able to view its type library
in that language. Doing this provides you with the proper syntax for the classes, interfaces, methods, properties,
and events of the COM object.
Microsoft development products provide the following tools that you can use to generate, extract, and view type
library information.

C++
OLE -COM Object Viewer
MIDL compiler
MkTypLib

Visual Basic
Visual Basic Object Browser

Java
JActiveX
Java Type Library Wizard
JavaTLB
For an overview of how these tools interact with type libraries, see How Developer Tools Use Type Libraries.
How Developer Tools Use Type Libraries
1/7/2020 • 2 minutes to read • Edit Online

The following diagram illustrates how the various development tools interact with a COM object's type library.
Each type library exposes standard programmatic interfaces that tools can call to get information about the
elements described in that type library. In this diagram, GUID stands for globally unique identifier and RPC for
remote procedure call.

In the preceding diagram, the C++ conversion tools, such as the MIDL compiler and the wizards provided by the
Microsoft Visual C++ development system, generate header and stub files. You can add these files to your project
in order to use the COM object described by the type library.
Similarly, in Java the developer tools generate Java class and source files, which you can then import into your
application.
In Visual Basic, the scenario is somewhat simpler. You do not need to generate additional files. The Visual Basic
environment provides dialog boxes listing the COM objects currently installed on your computer. You select the
component you want to call from your application, and it is added to your project, either as a component or a
reference.
The OLE -COM viewer reads a type library, generates a temporary IDL file based on the type library, and displays
it to users. The OLE -COM viewer also displays the C++ syntax for the COM elements listed in the type library.
For more information about type libraries, see Type Libraries and the Object Description Language.
Translating to C++
1/7/2020 • 2 minutes to read • Edit Online

Visual C++ provides several tools to assist you in adding COM objects to your project. You can add an ActiveX
control to your project, use the MFC Class Wizard, or run the MIDL compiler on an IDL file.
If you are using a C++ development environment other than Visual C++, consult that product's documentation
for information on COM conversion tools.
Once you have added the COM object's include or stub files to your project, your application can use the COM
object's classes.
Visual C++ also provides the OLE -COM Object Viewer, which you can use to view compiled type library
information. The object viewer presents the COM classes in C++ syntax.
For more information, see the following topics:
Translating to C++ from Visual Basic
Translating to C++ from Java
Adding an ActiveX Control to a Visual C++ Project
MIDL Compiler
MkTypLib Command-Line Tool
OLE -COM Object Viewer

Related topics
T
r
a
n
s
l
a
t
i
n
g
t
o
J
a
v
a

T
r
a
n
s
l
a
t
i
n
g
t
o
V
i
s
u
a
l
B
a
s
i
c
Translating to C++ from Visual Basic
1/7/2020 • 2 minutes to read • Edit Online

Visual Basic handles pointers implicitly. In C++, your application is responsible for performing any necessary
pointer arithmetic.
By default, Visual Basic passes parameters by reference (as pointers). Parameters that are meant to be passed by
value only are specified by the keyword ByVal. For example, a ByVal Integer parameter in Visual Basic is
equivalent to a short parameter in C++, whereas a ByRef Integer parameter in Visual Basic is equivalent to a
short* parameter.
A parameter that is declared As String in Visual Basic is declared as a pointer to a BSTR in C++. Setting a string
pointer to NULL in C++ is equivalent to setting the string to the vbNullString constant in Visual Basic. Passing a
zero-length string ("") to a function designed to receive NULL does not work, because this passes a pointer to a
zero-length string instead of a zero pointer.
C++ and Visual Basic differ slightly in how they represent properties. In C++, properties are represented as a set
of accessor functions, one that sets the property value and one that retrieves the property value. In Visual Basic,
properties are represented as a single item that can be used to retrieve or set the property value.

Related topics
T
r
a
n
s
l
a
t
i
n
g
t
o
C
+
+
Translating to C++ from Java
1/7/2020 • 2 minutes to read • Edit Online

Java handles pointers and memory management implicitly. In C++, your application is responsible for allocating
and deallocating memory, and for performing any necessary pointer arithmetic.

Related topics
T
r
a
n
s
l
a
t
i
n
g
t
o
C
+
+
Adding an ActiveX Control to a Visual C++ Project
1/7/2020 • 2 minutes to read • Edit Online

The following procedure adds dispatch class and header files for an ActiveX control to a Visual C++ project.
To add an ActiveX control to a Visual C++ Project
1. On the Project menu, click Add to Project. A shortcut menu appears.
2. Click Components and Controls. The Components and Controls Gallery dialog box appears.
3. Click the component to add to your project. Visual C++ displays a dialog box from which you can select a
subset of the component's classes to add to your project.
4. Click to select the check boxes of the classes you want to add, and click OK.
Visual C++ generates dispatch class and header files for the component and adds them to your project.

Related topics
T
r
a
n
s
l
a
t
i
n
g
t
o
C
+
+
MIDL Compiler
1/7/2020 • 2 minutes to read • Edit Online

The MIDL compiler processes an IDL file to generate a type library and output files. The type of output files
generated by the MIDL compiler depends on the attributes specified in the IDL file's interface attribute list.
If the attribute list contains the [object] keyword, the MIDL compiler generates COM interface output files: an
interface proxy file, an interface header file, and a globally unique identifier (GUID ) file for the interface. If the IDL
file contains a library statement, MIDL generates a type library file with the .tlb file name extension. If there are
any interfaces in the IDL file that do not have the [object] keyword and are not enclosed in a library statement,
the MIDL compiler generates interface output files appropriate for remote procedure calls (RPCs): a client stub file,
a server stub file, and a header file. For more information, see the topics Interface Definitions and Type Libraries
and Generating a Type Library with MIDL.
To generate a type library and output files from an IDL file:
From the command prompt, run
midl filename
where filename is the name of the IDL file.
The MIDL compiler also supports several optional parameters. For a complete list, see "MIDL Command-Line
Reference" in the Visual C++ documentation, or run the following command line:
midl /?

Related topics
M
i
c
r
o
s
o
f
t
I
n
t
e
r
f
a
c
e
D
e
f
i
n
i
t
i
o
n
L
a
n
g
u
a
g
e

T
r
a
n
s
l
a
t
i
n
g
t
o
C
+
+
MkTypLib Command-Line Tool
1/7/2020 • 2 minutes to read • Edit Online

[The Mktyplib.exe tool is obsolete. Use the MIDL compiler instead. If you need backward compatibility with old
Automation programs, use the MIDL compiler with the /mktyplib203 option.]
MkTypLib is a command-line application that processes an IDL file to produce a type library. It can also be used to
generate a C or C++ header file.
To generate a type library from a ODL file:
From the command prompt, run the following command:
**mktyplib **filename
where filenameis the name of the ODL file.
MkTypLib also supports several optional parameters. For a complete list, run the following command line:
mktyplib /?
Because MkTypLib is an obsolete application, it cannot parse IDL files or files with interfaces defined outside of a
library statement. For more information, see Differences Between MIDL and MkTypLib.

Related topics
T
r
a
n
s
l
a
t
i
n
g
t
o
C
+
+
OLE-COM Object Viewer
1/7/2020 • 2 minutes to read • Edit Online

The OLE -COM object viewer, Oleview.exe, is an application supplied with Visual C++ that displays the COM
objects installed on your computer and the interfaces they support. You can use this object viewer to view type
libraries.
To view a COM object's type library:
1. On the object viewer File menu, click View TypeLib. An Open dialog box appears.
2. Specify the type library file you want to open, and click OK.
The object viewer displays the object's interfaces.
For more information, see Using the OLE/COM Object Viewer in the Visual C++ documentation.

Related topics
T
r
a
n
s
l
a
t
i
n
g
t
o
C
+
+
Translating to Visual Basic
1/7/2020 • 2 minutes to read • Edit Online

You can add a COM object to your Visual Basic project either as a reference or a component. Once the object is
added to your project, your application can access its classes and interfaces. You can then use the Visual Basic
Object Browser to view the object's type library information in Visual Basic syntax.
Typically, controls are added to a project as a components and noncontrols are added as references. When a
COM object is added as a component, it appears in the Visual Basic toolbox. New instances of that object are
created by dragging the object icon from the toolbox onto a Visual Basic form or other type of container. New
instances of COM objects added as references are created using the new keyword.
The distinction between using a class as a reference versus a component is subtle but important. When you add
an object as a reference, you can use only the type library that the control provides, or the "raw" type library.
If you add a control as a component, Visual Basic merges the extender properties and methods of the form in
which the control is embedded with the control's type library, thus providing a wrapped, extended version of the
type library. With this version of the type library, you can use extender properties such as Top and Left as if they
were part of the control, instead of the control's container.
Visual Basic does not currently support multiple type libraries built into a single .dll file. If you run into a DLL that
incorporates multiple type libraries, you should get stand-alone copies of the type libraries from the source that
supplied the object in order to use the object with Visual Basic.
For more information, see the following topics:
Translating to Visual Basic from C++
Translating to Visual Basic from Java
Adding a Component to a Visual Basic Project
Adding a Reference to a Visual Basic Project
Visual Basic Object Browser

Related topics
T
r
a
n
s
l
a
t
i
n
g
t
o
C
+
+
T
r
a
n
s
l
a
t
i
n
g
t
o
J
a
v
a
Translating to Visual Basic from C++
1/7/2020 • 2 minutes to read • Edit Online

Using the C++ programming language, developers can directly access the memory that stores a particular
variable. Memory pointers provide this direct access. In Visual Basic, pointers are handled for you. For example, a
parameter declared as a pointer to an int in C++ is equivalent to a parameter declared in Visual Basic as a
ByRef Integer.
A parameter that is declared As String in Visual Basic is declared as a pointer to a BSTR in C++. Setting a string
pointer to NULL in C++ is equivalent to setting the string to the vbNullString constant in Visual Basic. Passing in
a zero-length string ("") to a function designed to receive NULL does not work, as this passes a pointer to a zero-
length string instead of a zero pointer.
C++ supports data containers, namely structures and unions, that have no equivalent in early versions of Visual
Basic. For this reason, COM objects typically wrap information that usually is stored in structures and unions in
object classes. Some COM objects, however, may contain structures, causing portions of the object's methods or
functionality to be inaccessible to Visual Basic.
Some C++ data types are not supported in Visual Basic, for example unsigned types and HWND types. Methods
that accept or return these data types are not available in Visual Basic.
Visual Basic uses Automation-compatible data types as its internal data types. Thus, C++ data types that are
Automation-compatible are also compatible with Visual Basic. Data types that are not Automation-compatible may
not be able to be converted to Visual Basic.
The following table lists the data types are supported by Visual Basic and their VARTYPE equivalents. VARTYPE
is an enumeration that lists the Automation variant types.

VISUAL BASIC DATA TYPE VARTYPE EQUIVALENT

Integer 16 bit, signed, VT_I2

Long 32 bit, signed, VT_I4

Date VT_DATE

Currency VT_CY

Object *VT_DISPATCH

String VT_BSTR

Boolean VT_BOOL

Currency VT_DECIMAL

Single VT_R4

Double VT_R8

Decimal VT_DECIMAL
VISUAL BASIC DATA TYPE VARTYPE EQUIVALENT

Byte VT_DECIMAL

Variant VT_VARIANT

All parameters in Visual Basic, unless labeled with the keyword ByVal, are passed by reference (as pointers)
instead of by value.
C++ and Visual Basic differ slightly in how they represent properties. In C++, properties are represented as a set
of accessor functions, one that sets the property value and one that retrieves the property value. In Visual Basic,
properties are represented as a single item that can be used to retrieve or set the property value.

Related topics
T
r
a
n
s
l
a
t
i
n
g
t
o
V
i
s
u
a
l
B
a
s
i
c
Translating to Visual Basic from Java
1/7/2020 • 2 minutes to read • Edit Online

Visual Basic uses Automation-compatible data types as its internal data types. Thus, Java data types that are
Automation-compatible are also compatible with Visual Basic. Data types that are not Automation-compatible may
not be able to be converted to Visual Basic.
Java and Visual Basic differ slightly in how they represent properties. In Java, properties are represented as a set of
accessor functions, one that sets the property value and one that retrieves the property value. In Visual Basic,
properties are represented as a single item that can be used to retrieve or set the property value.

Related topics
T
r
a
n
s
l
a
t
i
n
g
t
o
V
i
s
u
a
l
B
a
s
i
c
Adding a Component to a Visual Basic Project
1/7/2020 • 2 minutes to read • Edit Online

The following procedure describes how to add a COM object as a component to a Visual Basic project. Your
application can then use the classes of that object.
Adding a control as a component exposes the Visual Basic extender properties and methods as if they were part of
the control. In contrast, when you add an object as a reference you can only use the type library provided by the
control, or the "raw" type library.
To insert a control into a Visual Basic project
1. On the Project menu, click Components.
2. Click to select the check box next to the component you want to add. If the component is not listed, locate the
.dll or .ocx file using Browse.
3. Click OK.
The component is now part of the project and appears in the object toolbar. Your application can create instances
of the control by dragging the control from the toolbar and dropping it onto a form or dialog box.

Related topics
A
d
d
i
n
g
a
R
e
f
e
r
e
n
c
e
t
o
a
V
i
s
u
a
l
B
a
s
i
c
P
r
o
j
e
c
t

T
r
a
n
s
l
a
t
i
n
g
t
o
V
i
s
u
a
l
B
a
s
i
c
Adding a Reference to a Visual Basic Project
1/7/2020 • 2 minutes to read • Edit Online

The following procedure describes how to add a reference to a COM object to a Visual Basic project. Your
application can then use the classes of that object.
When you add an object as a reference, you can only use the type library provided by the control, or the "raw" type
library. In contrast, adding a control as a component also exposes the Visual Basic extender properties and
methods as if they were part of the control.
To make a Visual Basic reference to a component
1. On the Project menu, click References.
2. Click to select the check box next to the component you want to add. If the component is not listed, locate the
.dll or .ocx file using Browse.
3. Click OK.
The component is now part of the project. Your application can create class instances using the New keyword.

Related topics
A
d
d
i
n
g
a
C
o
m
p
o
n
e
n
t
t
o
a
V
i
s
u
a
l
B
a
s
i
c
P
r
o
j
e
c
t

T
r
a
n
s
l
a
t
i
n
g
t
o
V
i
s
u
a
l
B
a
s
i
c
Visual Basic Object Browser
1/7/2020 • 2 minutes to read • Edit Online

After a COM object has been added to your project as a reference or component, you can use the Visual Basic
Object Browser to view type library information for that object in Visual Basic.
To view a COM object in the Object Browser:
On the View menu, click Object Browser.
The left side of the Object Browser window displays all of the classes of references and components added to the
current project. The right side contains the methods, properties, and events of those classes.
You can filter which COM object classes are displayed by selecting an object library from the library selection
drop-down list.
For more information, see Browsing ActiveX Component Type Libraries in the Visual Basic documentation.
In some cases, the Visual Basic Object Browser appears not to show a return type for a function or property. No
return type appears when the return type is the default type, Variant. If the description pane of the Object Browser
describes the element as a function or property and a return type is not shown, the return type statement is "As
Variant".

Related topics
T
r
a
n
s
l
a
t
i
n
g
t
o
V
i
s
u
a
l
B
a
s
i
c
Translating to Java
1/7/2020 • 2 minutes to read • Edit Online

The Microsoft Visual J++ development system for Java provides two tools that you can use to generate type
library information for a COM object in Java syntax, the Java Type Library Wizard and the JActiveX command-
line tool. Using either of these tools, you can generate Java class files for a COM object.
In Visual J++ version 6.0, the JActiveX tool replaces the JavaTLB command-line tool. For more information, see
the Visual J++ documentation.
If you are using a Java development environment other than Visual J++, consult that product's documentation
for information on COM conversion tools.
Once you have generated the class files for a component, you can add the component classes to your Java
application using the import statement.
You can then create and use the object's classes in your Java application. For more information about the Java
import statement, see a reference on the Java programming language.
For more information, see the following topics:
Translating to Java from C++
Translating to Java from Visual Basic
JActiveX Command-Line Tool
Java Type Library Wizard
JavaTLB Command-Line Tool

Related topics
T
r
a
n
s
l
a
t
i
n
g
t
o
C
+
+

T
r
a
n
s
l
a
t
i
n
g
t
o
V
i
s
u
a
l
B
a
s
i
c
Translating to Java from C++
1/7/2020 • 2 minutes to read • Edit Online

Using the C++ programming language, developers can directly access the memory that stores a particular
variable. Memory pointers provide this direct access. In Java, pointers are handled for you.
In Java, struct, union, and typedef composite data types are handled exclusively through the use of classes. For
example, the C++ VARIANT data type maps to com.ms.com.Variant in Java.
In C++, strings are an array of characters. In Java, strings are objects. Methods that act on strings treat the string
as a complete object.
COM methods return a value known as a HRESULT, which is a 32-bit error code. The Java support for Microsoft
Internet Explorer defines a class, com.ms.com.ComException, which wraps the HRESULT error code.
Java does not support unsigned data types except for char, which is a 16-bit unsigned integer. Methods that accept
or return other unsigned data types cannot be used from Java.
Java does not support multidimensional arrays. Methods that accept or return multidimensional arrays are not
available from Java.
Boolean values in Java cannot be cast to 0 and 1.

Related topics
T
r
a
n
s
l
a
t
i
n
g
t
o
J
a
v
a
Translating to Java from Visual Basic
1/7/2020 • 2 minutes to read • Edit Online

By default, Visual Basic passes parameters by reference. Parameters that are meant to be passed by value only are
specified by the keyword ByVal.
Java does not support multidimensional arrays. Methods that accept or return multidimensional arrays are not
available from Java.
Java and Visual Basic differ slightly in how they represent properties. In Java, properties are represented as a set of
accessor functions, one that sets the property value and one that retrieves the property value. In Visual Basic,
properties are represented as a single item that can be used to retrieve or set the property value.

Related topics
T
r
a
n
s
l
a
t
i
n
g
t
o
J
a
v
a
JActiveX Command-Line Tool
1/7/2020 • 2 minutes to read • Edit Online

The JActiveX command-line application is a component of Visual J++ 6.0. It reads the type library of a Microsoft
ActiveX control and generates the corresponding Java source files. You can then compile these source files and
import them into your Java application.
To generate Java source files for a COM object, from the command prompt, run:
jactivex filename
where filename is the name of the file that contains the type library. This file may have any of the following file
name extensions: .tlb, .olb, .ocx, .dll, or .exe.
For more information about the optional parameters you can set in JActiveX, see the Visual J++ documentation,
or type the following command line:
jactivex /?

WARNING
Do not use Visual J++ compilers prior to version 1.02.3920 to compile the files generated by JActiveX.exe. This is because
the generated source files must be compiled with a @com-aware compiler. Only Visual J++ compilers later than version
1.02.3920 are @com-aware.

Related topics
T
r
a
n
s
l
a
t
i
n
g
t
o
J
a
v
a
Java Type Library Wizard
1/7/2020 • 2 minutes to read • Edit Online

The Java Type Library Wizard is a component of Visual J++ 5.0. This wizard generates class files and Java type
library information for a COM object.
To generate Java class files and type library information
1. On the Tools menu, click Java Type Library Wizard. A list of the installed COM components appears.
2. Click to select the check boxes next to the items you want to convert.
3. Click OK. The type library wizard generates class files for the selected components. It prints the import
statement required to insert each component into a Java application or applet and a summary text file that
contains the Java type library information for the object.

Related topics
T
r
a
n
s
l
a
t
i
n
g
t
o
J
a
v
a
JavaTLB Command-Line Tool
1/7/2020 • 2 minutes to read • Edit Online

JavaTLB is a component of Visual J++ 5.0. JavaTLB is a command-line application that generates class files for a
COM object. Methods that contain data types that cannot be accurately and safely represented in Java are not
converted.
Unlike the Java Type Library Wizard, JavaTLB does not generate a summary file containing the Java type library
information.
To generate Java class files for a single COM object, from the command prompt run:
javatlb filename
where filenameis the name of the file that contains the type library. This file may have any of the following file
name extensions: .tlb, .olb, .ocx, .dll, or .exe.
To generate Java class files for multiple COM objects, from the command prompt run:
**javatlb @**TextFile
where TextFile is the name of a text file that contains a list of the files containing the COM object's type libraries.

NOTE
In Visual J++ 6.0, the JavaTLB command-line tool is replaced by the JActiveX tool. For more information, see the Visual J++
6.0 documentation.

Related topics
T
r
a
n
s
l
a
t
i
n
g
t
o
J
a
v
a
Scripting with COM Objects
1/7/2020 • 2 minutes to read • Edit Online

A scripting language is a programming language that is parsed at run time by a scripting engine, a component
that translates scripts written in that language into machine code. Each scripting engine translates a specific
scripting language. A scripting host is an application, such as a Web browser, that hosts a scripting engine to run
scripts. If your scripting host supports COM, you can write scripts that use COM objects. The following topics
describe scripting hosts that support COM objects, common scripting languages, and how to translate between
scripting languages.
A scripting language differs from a compiled language in that it is translated into machine code at run time. This
means that each time you run a script, the scripting engine first parses the code and then runs it. In contrast,
compiled languages, such as C++, are translated to machine code once, during compilation. When you run a
compiled application, the operating system simply runs the precompiled code.
Because a scripting engine must reparse a script each time it runs, scripting languages are typically slower and
less efficient than their precompiled counterparts. The advantage of scripts, however, is they are easy to write and
maintain. Scripting languages are usually simpler than precompiled languages, and when a script changes, it does
not need to be recompiled. For lightweight and rapidly changing applications, such as webpages, scripting
languages are ideal.
There are several host environments in which you can write scripts that use COM objects, as described following:
Embedding COM Objects in Web Pages
Using COM Objects in Active Server Pages
Using COM Objects in Windows Script Host
Scripting COM Objects in Custom Applications
In each of the host environments mentioned preceding, a scripting engine parses and runs the script. Because the
engine for each scripting language is a separate component, you can add a new scripting language to an
environment by adding a new engine.
The most commonly used scripting languages are:
Microsoft Visual Basic Scripting Edition (VBScript), a subset of Visual Basic.
JavaScript, the Netscape scripting language, formerly known as LiveScript.
Microsoft JScript development software, the Microsoft implementation of the ECMA 262 language
specification.
Microsoft provides scripting engines for JScript and VBScript. Other software companies provide ActiveX
scripting engines for languages such as PerlScript, PScript, Python, and others.
For more information see the ECMA 262 language specification.
Note that most scripting languages, such as VBScript and JScript, cannot access or modify files. This inability
prevents the script from altering data on client computers. COM objects, however, have no such limitations. Once
they are downloaded and installed on client computers, they can perform any standard application action. Thus,
users should only download and run ActiveX controls from trusted sources.
For information on translating between scripting languages, see the following topics:
Translating to VBScript
Translating to JScript
Translating to JavaScript
Embedding COM Objects in Web Pages
1/7/2020 • 2 minutes to read • Edit Online

You can use COM objects in webpages. To do this, first create an instance of that COM object. After an object
instance is created, you can use it in subsequent scripts on that webpage.
To create a COM object instance in a webpage, you can use an OBJECT tag. Alternatively, if your scripting
language provides a native way to create COM objects, you can create an object instance using script.
Note that embedding COM objects in webpages only works with browsers that support ActiveX and COM, for
example Internet Explorer.
The following example illustrates using the OBJECT tag to embed a COM object in a webpage:

<OBJECT
ID = vid
CLASSID = "clsid:31263EC0-2957-11CF-A1E5-00AA9EC79700"
BORDER = 0
VSPACE = 0
HSPACE = 0
ALIGN = TOP
HEIGHT = 100%
WIDTH = 100%
>
</OBJECT>

You can also create a COM object instance in script, if your scripting language provides a way to create COM
objects. For example, VBScript provides the CreateObject method and JScript provides the ActiveXObject object.
Creating objects in script is illustrated in the following examples.

<SCRIPT LANGUAGE = "VBScript">


Dim objXL
Set objXL = CreateObject("Excel.Application")
</SCRIPT>

<SCRIPT LANGUAGE = "JScript">


var objXL = new ActiveXObject("Excel.Application");
</SCRIPT>

In addition to the CreateObject method and the ActiveXObject object, both VBScript and JScript provide the
method GetObject, which returns an object instance.
After a COM object has been created, you can reference it in subsequent scripts by using the identifier specified in
the OBJECT tag's ID attribute. In the preceding example, this identifier was specified as "vid." Note that the script
that uses the COM object must appear after the OBJECT tag or script that creates the object instance; otherwise,
the object identifier is undefined. The following script uses the objXL object to display the version information for
Microsoft Excel.

<SCRIPT LANGUAGE = "VBScript">


Msgbox objXL.Version
</SCRIPT>
If you are writing scripts embedded in a webpage, the browser also exposes an object model that your scripts can
access. The model used by Internet Explorer conforms to the Document Object Model (DOM ) proposed by the
World Wide Web Consortium (W3C ).

Related topics
S
c
r
i
p
t
i
n
g
w
i
t
h
C
O
M
O
b
j
e
c
t
s
Using COM Objects in Active Server Pages
1/7/2020 • 2 minutes to read • Edit Online

You can script COM objects in Active Server Pages (ASP ) applications. To do so, you must first create an instance
of the object either by using the OBJECT tag or by calling the CreateObject method of the ASP Server object.
Once a COM object has been created, you can use it in subsequent scripts on the ASP page.
Using ASP, you can work with many different types of scripting engines, each of which supports a different
scripting language. ASP comes with VBScript and JScript scripting engines. You can also plug in scripting engines
developed by other companies to support languages such as PerlScript, PScript, Python, and others.
If you do not set the scripting language for an ASP page, VBScript is the default. To specify a scripting language
other than VBScript, include a line such as the following at the top of each ASP page:

<%@ LANGUAGE=JScript %>

To use a COM object in an ASP page, you must first create an instance of that object. You do this by using the
OBJECT tag and specifying the value "SERVER" for the RUNAT attribute, as shown in the following example. By
default, the OBJECT tag creates an instance of the object on the client. Setting the RUNAT attribute to SERVER
causes the object to be created on the server. The object must run on the server in order to be used by ASP.

<OBJECT
RUNAT=SERVER
ID=MyAds
CLASSID="Clsid:1621F7C0-60AC-11CF-9427-444553540000">
</OBJECT>

You can also create an instance of a COM object on an ASP page by calling the CreateObject method of the ASP
Server object. Using Server.CreateObject is slower than creating the object using an OBJECT tag, but it is slightly
more readable because it specifies the programmatic identifier instead of the class identifier of the COM object.
The Server object is exposed by ASP and does not need to be created. How to call Server.CreateObject is
illustrated in the following examples. The first example is VBScript:

<%
Set MyAds = Server.CreateObject("MSWC.AdRotator")
%>

The next example is JScript:

<%
var MyAds = Server.CreateObject("MSWC.AdRotator")
%>

Calling CreateObject is slower than using the OBJECT tag to create a COM object. In applications where
performance is critical, you should use the OBJECT tag.
After you have created an instance of the COM object, you can use it in scripts. Doing this is illustrated in the
VBScript example following, which sets the value of the COM object's Border property.

<% MyAds.Border = 0 %>

Related topics
S
c
r
i
p
t
i
n
g
w
i
t
h
C
O
M
O
b
j
e
c
t
s
Using COM Objects in Windows Script Host
1/7/2020 • 2 minutes to read • Edit Online

Microsoft Windows Script Host is a scripting utility you can use to run scripts within the base operating system.
You can use Windows Script Host to automate common tasks and to create powerful macros and logon scripts.
Windows Script Host comes with VBScript and JScript ActiveX scripting engines. Other software companies
provide ActiveX scripting engines for languages such as PerlScript, PScript, Python, and others.
To use a COM object in a script run by Windows Script Host, you must first create an instance of the object. After a
COM object has been created, you can then use it in scripts.
Windows Script Host consists of two applications. One runs scripts from the Windows desktop (WScript.exe); the
other runs scripts from the command prompt (CScript.exe).
To run a script from the desktop, simply double-click a script file. Script files are text files. By convention, VBScript
files have the extension .vbs and JScript files .js.
To run a script from the command prompt, run the Cscript.exe application with a command line such as the
following:
cscript c:\"sample scripts"\chart.vbs
where c:\"sample scripts"\chart.vbs is the path to the file containing the script.
You can print out a list of the parameters supported by Cscript.exe by entering the following command line:
call cscript //?
To use a COM object in a script run by Windows Script Host, you must first create an instance of the object. You
can do this by calling the CreateObject method (in VBScript) or the ActiveXObject object (in JScript). The following
example illustrates calling CreateObject using VBScript:

Dim objXL
Set objXL = CreateObject("Excel.Application")

The following example illustrates creating an ActiveXObject object using JScript:

var objXL = new ActiveXObject("Excel.Application");

After you have created an instance of the COM object, you can write script that uses the object, for example:

objXL.Visible = true;

In addition to the CreateObject method and ActiveXObject object, both VBScript and JScript provide the method
GetObject, which returns an object instance.

Related topics
S
c
r
i
p
t
i
n
g
w
i
t
h
C
O
M
O
b
j
e
c
t
s
Scripting COM Objects in Custom Applications
1/7/2020 • 2 minutes to read • Edit Online

Microsoft provides several environments for scripting COM objects: Active Server Pages, Windows Script Host,
and so on. Independent software vendors (ISVs) can also license Microsoft scripting engines for use in their
applications. For example, an ISV creating a word processor might want to add a macro language to the
application so users could automate simple tasks. By licensing a scripting engine, the ISV can use a language such
as VBScript or JScript as the application's macro language.
In addition to licensing VBScript and JScript scripting engines, ISVs can write their own ActiveX scripting engines.
These scripting engines can then be plugged into any host environment that supports the ActiveX scripting engine
standard. For example, an ISV might write a PerlScript scripting engine and install it on an ASP server, thus
enabling the ASP server to process PerlScript scripts.

Related topics
S
c
r
i
p
t
i
n
g
w
i
t
h
C
O
M
O
b
j
e
c
t
s
Translating to VBScript
1/7/2020 • 2 minutes to read • Edit Online

VBScript is a subset of the Microsoft Visual Basic for Applications language. Because VBScript is intended to be
safe for use in client-side applications such as webpages, it does not provide file input and output or direct access
to the underlying operating system. This prevents a Web-based script from deleting or altering files on your
computer. For a complete list of Visual Basic features that are not supported in VBScript, see the Visual Basic for
Applications documentation.
In addition to the language features provided by VBScript, the scripting host may also expose a VBScript object
model that your script can access. For example, Internet Explorer exposes an object model that enables scripts to
interact with and programmatically control the browser. For more information about working with such object
models, see the documentation on your scripting host.
The following topics describe issues you should consider when translating a script to VBScript from JavaScript or
JScript:
Translating to VBScript from JScript
Translating to VBScript from JavaScript

Related topics
T
r
a
n
s
l
a
t
i
n
g
t
o
J
a
v
a
S
c
r
i
p
t

T
r
a
n
s
l
a
t
i
n
g
t
o
J
S
c
r
i
p
t
Translating to VBScript from JScript
1/7/2020 • 2 minutes to read • Edit Online

In VBScript, the For...Each loop enumerates the members of a collection; in JScript, the for...in loop enumerates
the members of a JScript object or array. To enumerate a collection in JScript, use an Enumerator object.
JScript provides the Error object, which can be used to trap and handle errors. The Error object is analogous to the
VBScript Err object.
In JScript, there are several data types such as numbers, strings, Booleans, objects, and the null attribute. VBScript
only uses one data type, Variant, which can be subtyped to represent strings, numbers, Booleans, and so on.
In JScript, arrays can be expanded dynamically by setting a new value for the array's length property. In VBScript,
arrays cannot be enlarged; they must be redimensioned using the redim statement.
Both VBScript and JScript support functions. VBScript, however, also supports subroutines. Subroutines are
similar to functions but do not return a value.
JScript is case-sensitive. VBScript is not.
JScript is supported by a wide variety of Web browsers, including both Internet Explorer and Netscape Navigator.
Netscape Navigator does not support VBScript.
JScript arrays are not arrays of the variable type VARIANT SAFEARRAY. A JScript script must use a VBArray
object to access the VARIANT SAFEARRAYvariable. VBScript scripts can access VARIANT
SAFEARRAYvariables directly.

Related topics
T
r
a
n
s
l
a
t
i
n
g
t
o
V
B
S
c
r
i
p
t
Translating to VBScript from JavaScript
1/7/2020 • 2 minutes to read • Edit Online

In JavaScript, there are several data types, such as numbers, strings, Booleans, objects, and the null attribute.
VBScript only uses one data type, Variant, which can be subtyped to represent strings, numbers, Booleans, and so
on.
In JavaScript, arrays can be expanded dynamically by setting a new value for the array's length property. In
VBScript, arrays cannot be enlarged; they must be redimensioned using the redim statement.
Both VBScript and JavaScript support functions. VBScript, however, also supports subroutines. Subroutines are
similar to functions, except they do not return a value.
JavaScript is case-sensitive. VBScript is not.
JavaScript is supported by a wide variety of Web browsers, including both Internet Explorer and Netscape
Navigator. Netscape Navigator does not support VBScript.
VBScript supports error handling through its Err object. JavaScript does not currently provide a means of trapping
and handling errors.

Related topics
T
r
a
n
s
l
a
t
i
n
g
t
o
V
B
S
c
r
i
p
t
Translating to JScript
1/7/2020 • 2 minutes to read • Edit Online

JScript is the Microsoft implementation of the ECMA 262 language specification. It is supported by both Internet
Explorer and Netscape Navigator. JScript is the first scripting language to conform to the ECMA 262 standard.
JScript is supported by a wide range of Web browsers, including both Internet Explorer and Navigator.
In addition to the language features provided by JScript, the scripting host may also expose an object model that
your script can access. For example, Internet Explorer exposes an object model that enables scripts to interact with
and programmatically control the browser. For more information about working with such object models, see the
documentation for your scripting host.
For more information about JScript, see the JScript Language Reference. For more information see the ECMA
262 language specification.
The following topics describe issues you should consider when translating a script to JScript from JavaScript or
VBScript:
Translating to JScript from VBScript
Translating to JScript from JavaScript

Related topics
T
r
a
n
s
l
a
t
i
n
g
t
o
J
a
v
a
S
c
r
i
p
t

T
r
a
n
s
l
a
t
i
n
g
t
o
V
B
S
c
r
i
p
t
Translating to JScript from VBScript
1/7/2020 • 2 minutes to read • Edit Online

In VBScript, the For...Each loop enumerates the members of a collection; in JScript, the for...in loop enumerates
the members of a JScript object or array. To enumerate a collection in JScript, use an Enumerator object.
In JScript, there are several data types such as numbers, strings, Booleans, objects, and the null attribute. VBScript
only uses one data type, Variant, which can be subtyped to represent strings, numbers, Booleans, and so on.
In JScript, arrays can be expanded dynamically by setting a new value for the array's length property. In VBScript,
arrays cannot be enlarged; they must be redimensioned using the redim statement.
Both VBScript and JScript support functions. VBScript, however, also supports subroutines. Subroutines are
similar to functions but do not return a value.
JScript is case-sensitive. VBScript is not.
JScript is supported by both Internet Explorer and Netscape Navigator. Netscape Navigator does not support
VBScript.
JScript provides the Error object, which can be used to trap and handle errors. The Error object is analogous to the
VBScript Err object.
JScript arrays are not arrays of the variable type VARIANT SAFEARRAY. If your script receives a VARIANT
SAFEARRAY variable from a COM object or VBScript script, it must use a VBArray object to access the
VARIANT SAFEARRAY variable.

Related topics
T
r
a
n
s
l
a
t
i
n
g
t
o
J
S
c
r
i
p
t
Translating to JScript from JavaScript
1/7/2020 • 2 minutes to read • Edit Online

JScript is largely compatible with JavaScript. However, JScript version 5.0 includes some objects not currently
supported by JavaScript, such as ActiveXObject, Enumerator, Error, Global, and VBArray.
JScript 5.0 supports exception handling through try...catch statements. JavaScript does not currently provide an
error-handing mechanism.
When working with either JScript or JavaScript, there are some subtle differences between the object model
implementations supported by various Web browsers. To write script that runs on both Internet Explorer and
Netscape Navigator, limit the features used by your scripts to those specified in the World Wide Web Consortium
(W3C ) standard for HTML version 3.2. For more information about this standard, see HTML 3.2 Reference
Specification.

Related topics
T
r
a
n
s
l
a
t
i
n
g
t
o
J
S
c
r
i
p
t
Translating to JavaScript
1/7/2020 • 2 minutes to read • Edit Online

JavaScript is a scripting language that was created by Netscape. It was originally called LiveScript. Despite the
similarities in name and syntax, JavaScript is not related to the Java programming language. Java is a full-featured
programming language developed by Sun Microsystems, Inc.
JavaScript is supported by a wide range of Web browsers, including both Internet Explorer and Netscape
Navigator.
In addition to the language features provided by JavaScript, the scripting host may also expose an object model
that your script can access. For example, Internet Explorer exposes an object model that enables scripts to interact
with and programmatically control the browser. For more information about working with such object models, see
the documentation on your scripting host.
For more information about JavaScript, see a JavaScript reference.
The following topics describe issues you should consider when translating a script to JavaScript from VBScript or
JScript:
Translating to JavaScript from VBScript
Translating to JavaScript from JScript

Related topics
T
r
a
n
s
l
a
t
i
n
g
t
o
J
S
c
r
i
p
t

T
r
a
n
s
l
a
t
i
n
g
t
o
V
B
S
c
r
i
p
t
Translating to JavaScript from VBScript
1/7/2020 • 2 minutes to read • Edit Online

In JavaScript, there are several data types such as numbers, strings, Booleans, objects, and the null attribute.
VBScript only uses one data type, Variant, which can be subtyped to represent strings, numbers, Booleans, and so
on.
In JavaScript, arrays can be expanded dynamically by setting a new value for the array's length property. In
VBScript, arrays cannot be enlarged; they must be redimensioned using the redim statement.
Both VBScript and JavaScript support functions. VBScript, however, also supports subroutines. Subroutines are
similar to functions but do not return a value.
JavaScript is case-sensitive. VBScript is not.
JavaScript is supported by a wide variety of Web browsers, including both Internet Explorer and Netscape
Navigator. VBScript is only supported by Internet Explorer.
VBScript provides error handling support through its Err object. JavaScript does not currently provide a means of
trapping and handling errors.

Related topics
T
r
a
n
s
l
a
t
i
n
g
t
o
J
a
v
a
S
c
r
i
p
t
Translating to JavaScript from JScript
1/7/2020 • 2 minutes to read • Edit Online

JScript is largely compatible with JavaScript. However, JScript includes some objects not currently supported by
JavaScript, such as ActiveXObject, Enumerator, Error, Global, and VBArray.
JScript version 5.0 supports exception handling through try...catch statements. JavaScript does not currently
provide an error-handing mechanism.
When working with either JScript or JavaScript, there are some subtle differences between the object model
implementations supported by various Web browsers. To write script that runs on both Internet Explorer and
Netscape Navigator, limit the features used by your scripts to those specified in the World Wide Web Consortium
(W3C ) standard for HTML version 3.2.

Related topics
T
r
a
n
s
l
a
t
i
n
g
t
o
J
a
v
a
S
c
r
i
p
t
COM Glossary
1/7/2020 • 25 minutes to read • Edit Online

a The process of loading an object in memory, which puts it into the running state.
c
t
i
v
a
t
i
o
n

a A COM object that is in the running state and has a visible user interface.
c
t
i
v
e
s
t
a
t
e

a
b
s
o
l
u
t
e
m
o
n
i
k
e
r

A moniker that specifies the absolute location of an object. An absolute moniker is analogous to a full path.

a
d
v
i
s
o
r
y
h
o
l
d
e
r

A COM object that caches, manages, and sends notifications of changes to container applications' advisory
sinks.

a
d
v
i
s
o
r
y
s
i
n
k

A COM object that can receive notifications of changes in an embedded object or linked object because it
implements the IAdviseSink or IAdviseSink2 interface. Containers that need to be notified of changes in
objects implement an advisory sink. Notifications originate in the server, which uses an advisory holder
object to cache and manage notifications to containers.

a
g
g
r
e
g
a
t
e
o
b
j
e
c
t

A COM object that is made up of one or more other COM objects. One object in the aggregate is designated
the controlling object, which controls which interfaces in the aggregate are exposed and which are private.
This controlling object has a special implementation of IUnknown called the controlling IUnknown. All
objects in the aggregate must pass calls to IUnknown methods through the controlling IUnknown.

a
g
g
r
e
g
a
t
i
o
n

A composition technique for implementing COM objects. It allows you to build a new object by reusing one
or more existing objects' interface implementations. The aggregate object chooses which interfaces to expose
to clients, and the interfaces are exposed as if they were implemented by the aggregate object. Clients of the
aggregate object communicate only with the aggregate object.

a
m
b
i
e
n
t
p
r
o
p
e
r
t
y

A run-time property that is managed and exposed by the container. Typically, an ambient property represents
a characteristic of a form, such as background color, that needs to be communicated to a control so that the
control can assume the look and feel of its surrounding environment.

a
n
t
i
-
m
o
n
i
k
e
r

The inverse of a file, item, or pointer moniker. An anti-moniker is added to the end of a file, item, or pointer
moniker to nullify it. Anti-monikers are used in the construction of relative monikers.

a
r
t
i
f
i
c
i
a
l
r
e
f
e
r
e
n
c
e
c
o
u
n
t
i
n
g

A technique used to help protect an object before calling a function or method that could prematurely
destroy it. A program calls IUnknown::AddRef to increment the object's reference count before making the
call that could free the object. After the function returns, the program calls IUnknown::Release to decrement
the count.

a
s
y
n
c
h
r
o
n
o
u
s
b
i
n
d
i
n
g

A type of binding in which it is necessary for the process to occur asynchronously to avoid performance
degradation for the end user. Typically, asynchronous binding is used in distributed environments such as the
World Wide Web. OLE supports asynchronous moniker classes and callback mechanisms that allow the
process of locating and initializing an object in a distributed environment to occur while other operations are
being carried out.

a
s
y
n
c
h
r
o
n
o
u
s
c
a
l
l

A call to a function that is executed separately so that the caller can continue processing instructions without
waiting for the function to return.

a
s
y
n
c
h
r
o
n
o
u
s
m
o
n
i
k
e
r

A moniker that supports asynchronous binding. For example, instances of the system-supplied URL moniker
class are asynchronous monikers.

a
u
t
o
m
a
t
i
o
n

A way to manipulate an application's objects from outside the application. Automation is typically used to
create applications that expose objects to programming tools and macro languages, create and manipulate
one application's objects from another applications, or to create tools for accessing and manipulating objects.

b
i
n
d
c
o
n
t
e
x
t

A COM object that implements the IBindCtx interface. Bind contexts are used in moniker operations to hold
references to the objects activated when a moniker is bound. The bind context contains parameters that apply
to all operations during the binding of a generic composite moniker and provides the moniker
implementation with access to information about its environment.

b
i
n
d
i
n
g

Associating a name with its referent. Specifically, locating the object named by a moniker, putting it into its
running state if it isn't already, and returning an interface pointer to it. Objects can be bound at run time (also
called late binding or dynamic binding) or at compile time (also called static binding).

c
a
c
h
e

A (usually temporary) local store of information. In OLE, a cache contains information that defines the
presentation of a linked or embedded object when the container is opened.

c
a
c
h
e
i
n
i
t
i
a
l
i
z
a
t
i
o
n

Filling a linked or embedded object's cache with presentation data. The IOleCache interface provides
methods that a container can call to control the data that gets cached for linked or embedded objects.

c
l
a
s
s

The definition of an object in code. In C++, the class of an object is defined as a data type, but this is not the
case in other languages. Because OLE can be coded in any language, class is used to refer to the general
object definition.

c
l
a
s
s
f
a
c
t
o
r
y

A COM object that implements the IClassFactory interface and that creates one or more instances of an
object identified by a given class identifier(CLSID ).

c
l
a
s
s
i
d
e
n
t
i
f
i
e
r
(
C
L
S
I
D
)

A globally unique identifier (GUID ) associated with an OLE class object. If a class object will be used to create
more than one instance of an object, the associated server application should register its CLSID in the system
registry so that clients can locate and load the executable code associated with the object(s). Every OLE
server or container that allows linking to its embedded objects must register a CLSID for each supported
object definition.

c
l
a
s
s
o
b
j
e
c
t

In object-oriented programming, an object whose state is shared by all the objects in a class and whose
behavior acts on that classwide state data. In COM, class objects are called class factories, and typically have
no behavior except to create new instances of the class.

c A COM object that requests services from another object.


l
i
e
n
t

c
l
i
e
n
t
s
i
t
e

The display site for an embedded or linked object within a compound document. The client site is the
principal means by which an object requests services from its container.

C
L
S
I
D

A globally unique identifier (GUID ) associated with an OLE class object. If a class object will be used to create
more than one instance of an object, the associated server application should register its CLSID in the system
registry so that clients can locate and load the executable code associated with the object(s). Every OLE
server or container that allows linking to its embedded objects must register a CLSID for each supported
object definition.

c
o
m
m
i
t

To persistently save any changes made to a storage or stream object since it was opened or changes were last
saved.

c
o
m
p
o
n
e
n
t

An object that encapsulates both data and code, and provides a well-specified set of publicly available
services.

C
o
m
p
o
n
e
n
t
O
b
j
e
c
t
M
o
d
e
l
(
C
O
M
)

The OLE object-oriented programming model that defines how objects interact within a single process or
between processes. In COM, clients have access to an object through interfaces implemented on the object.

c
o
m
p
o
s
i
t
e
m
e
n
u
b
a
r

A shared menu bar composed of menu groups from both a container application and an in-place-activated
server application.

c
o
m
p
o
s
i
t
e
m
o
n
i
k
e
r

A moniker that consists of two or more monikers that are treated as a unit. A composite moniker can be non-
generic, meaning that its component monikers have special knowledge of each other, or generic, meaning
that its component monikers know nothing about each other except that they are monikers

c A document that includes linked or embedded objects, as well as its own native data.
o
m
p
o
u
n
d
d
o
c
u
m
e
n
t

c An OLE -provided Structured Storage implementation.


o
m
p
o
u
n
d
f
i
l
e

C
O
M
o
b
j
e
c
t

An object that conforms to the OLE Component Object Model (COM ). A COM object is an instance of an
object definition, which specifies the object's data and one or more implementations of interfaces on the
object. Clients interact with a COM object only through its interfaces.

c
o
n
n
e
c
t
a
b
l
e
o
b
j
e
c
t

A COM object that implements, at a minimum, the IConnectionPointContainer interface, for the
management of connection point objects. Connectable objects support communication from the server to the
client. A connectable object creates and manages one or more connection point subobjects, which receive
events from interfaces implemented on other objects and send them on to the client.

c
o
n
n
e
c
t
i
o
n
p
o
i
n
t
o
b
j
e
c
t

A COM object that is managed by a connectable object and that implements the IConnectionPoint
interface. One or more connection point objects can be created and managed by a connectable object. Each
connection point object manages incoming events from a specific interface on another object and sends
those events on to the client.

c
o
n
t
a
i
n
e
r
a
p
p
l
i
c
a
t
i
o
n

An application that supports compound documents. The container application provides storage for an
embedded or linked object, a site for its display, access to the display site, and an advisory sink for receiving
notifications of changes in the object.

c
o
n
t
a
i
n
m
e
n
t

A composition technique for implementing COM objects. It allows one object to reuse some or all of the
interface implementations of one or more other objects. The outer object acts as a client to the other objects,
delegating implementation when it wishes to use the services of one of the contained objects.

c
o
n
t
e
x
t

In COM+, a set of run-time properties associated with one or more COM objects that are used to provide
services for those objects.

c
o
n
t
r
o
l

An embeddable, reusable COM object that supports, at a minimum, the IOleControl interface. Controls are
typically associated with the user interface. They also support communication with a container and can be
reused by multiple clients, depending upon licensing criteria.

c An application that supports embedding of controls by implementing the IOleControlSite interface.


o
n
t
r
o
l
c
o
n
t
a
i
n
e
r

c
o
n
t
r
o
l
p
r
o
p
e
r
t
y

A run-time property that is exposed and managed by the control itself. For example, the font and text size
used by the control are control properties.

c
o
n
t
r
o
l
l
i
n
g
o
b
j
e
c
t

The object within an aggregate object that controls which interfaces within the aggregate object are exposed
and which are private. The IUnknown interface of the controlling object is called the controlling IUnknown.
Calls to IUnknown methods of other objects in the aggregate must be passed to the controlling IUnknown.

c
o
n
t
r
o
l
s
i
t
e

A structure implemented by a control container for managing the display and storage of a control. Within a
given container, each control has a corresponding control site.

d
a
t
a
t
r
a
n
s
f
e
r
o
b
j
e
c
t

An object that implements the IDataObject interface and contains data to be transferred from one object to
another through either the Clipboard or drag-and-drop operations.

d
e
f
a
u
l
t
o
b
j
e
c
t
h
a
n
d
l
e
r

A DLL provided with OLE that acts as a surrogate in the processing space of the container application for the
real object.
With the default object handler, it is possible to look at an object's stored data without actually activating the
object. The default object handler performs other tasks, such as rendering an object from its cached state
when the object is loaded into memory.

d
e
p
e
n
d
e
n
t
o
b
j
e
c
t

A COM object that is typically initialized by another object (the host object). Although the dependent object's
lifetime may only make sense during the lifetime of the host object, the host object does not function as the
controlling IUnknown for the dependent object. In contrast, an object is an aggregated object when its
lifetime (by means of its reference count) is completely controlled by the managing object.

d
i
r
e
c
t
a
c
c
e
s
s
m
o
d
e

One of two access modes in which a storage object can be opened. In direct mode, all changes are
immediately committed to the root storage object.

d
o
c
u
m
e
n
t
o
b
j
e
c
t

An OLE document that can display one or more in-place activated views of its data within a native or foreign
frame, such as a browser, while retaining full control over its user interface. In addition to implementing the
usual OLE document and in-place activation interfaces, a document object must implement IOleDocument,
and each of its views (in the form of a document view object) must implement IOleDocumentView.

d
o
c
u
m
e
n
t
o
b
j
e
c
t
c
o
n
t
a
i
n
e
r

A container application capable of displaying one or more views of one or more document objects and of
managing all contained document objects within a file. Each document object is associated with a document
site, and each document site contains one or more document view sites corresponding to the views
supported by the document object. A document object container also includes a container frame, which
handles menu and toolbar negotiation and the enumeration of contained objects.

d A server application capable of providing document objects.


o
c
u
m
e
n
t
o
b
j
e
c
t
s
e
r
v
e
r

d
o
c
u
m
e
n
t
s
i
t
e

A client site implemented by a document object container for managing the display and storage of a
document object. Each document object in a container has a corresponding document site.

d
o
c
u
m
e
n
t
s
i
t
e
o
b
j
e
c
t

A COM object that implements the IOleDocumentSite interface, in addition to the usual client-site
interfaces (such as IOleClientSite).
d
o
c
u
m
e
n
t
v
i
e
w

A particular presentation of a document's data. A single document object can have one or more views, but a
single document view can belong to one and only one document object.

d
o
c
u
m
e
n
t
v
i
e
w
o
b
j
e
c
t

A COM object that implements the IOleDocumentView interface and corresponds to a particular
document view. An object with multiple document views aggregates a separate document view object for
each view.

d
o
c
u
m
e
n
t
v
i
e
w
s
i
t
e

An object aggregated by a document site object for managing the display space for a particular view of a
document object. Within a given document site, each document view has a corresponding document view
site.

d
o
c
u
m
e
n
t
v
i
e
w
s
i
t
e
o
b
j
e
c
t

A COM object that is aggregated in a document site object and implements the IOleInPlaceSite interface
and, optionally, the IContinueCallback interface.

d
r
a
g
a
n
d
d
r
o
p

An operation in which the end user uses the mouse or other pointing device to move data to another location
in the same window or another window.

e
m
b
e
d
To insert an object into a compound document in such a way as to preserve the data formats native to that
object, and to enable it to be edited from within its container using tools exposed by its server.

e
m
b
e
d
d
e
d
o
b
j
e
c
t

An object whose data is stored in a compound document, but the object runs in the process space of its
server. The default object handler provides a surrogate in the processing space of the container application
for the real object.

e
x
t
e
n
d
e
d
p
r
o
p
e
r
t
y

A run-time property, such as a control's position and size, that a user would assume to be exposed by the
control but is exposed and managed by the container.

f
i
l
e
m
o
n
i
k
e
r
A moniker based on a path in the file system. File monikers can be used to identify objects that are saved in
their own files. A file moniker is a COM object that supports the system-provided implementation of the
IMoniker interface for the file moniker class.

f
o
n
t
o
b
j
e
c
t

A COM object that provides access to Graphics Device Interface (GDI) fonts by implementing the IFont
interface.

f A GUID that identifies a persistent property set. Also referred to as FMTID.


o
r
m
a
t
i
d
e
n
t
i
f
i
e
r

f
r
a
m
e

The part of a container application responsible for negotiating menus, accelerator keys, toolbars, and other
shared user-interface elements with an embedded COM object or a document object.

f
r
a
m
e
o
b
j
e
c
t

A COM object that implements the IOleInPlaceFrame interface and, optionally, the IOleCommandTarget
interface.

g
e
n
e
r
i
c
c
o
m
p
o
s
i
t
e
m
o
n
i
k
e
r

A sequenced collection of monikers, starting with a file moniker to provide the document-level path and
continuing with one or more item monikers that, taken as a whole, uniquely identifies an object.

h
e
l
p
e
r
f
u
n
c
t
i
o
n

A function that encapsulates calls to other functions and interface methods publicly available in the OLE SDK.
Helper functions are a convenient way to call frequently used sequences of function and method calls that
accomplish common tasks.

h
o
s
t
o
b
j
e
c
t

A COM object that forms a hierarchical relationship with one or more other COM objects, known as the
dependent objects. Typically, the host object instantiates the dependent objects, and their existence only
makes sense within the lifetime of the host object. However, the host object does not act as the controlling
IUnknown for the dependent objects, nor does it directly delegate to the interface implementations of those
objects.

H
R
E
S
U
L
T

An opaque result handle defined to be zero for a successful return from a function and nonzero if error or
status information is returned.

h
y
p
e
r
l
i
n
k
o
b
j
e
c
t

A COM object that implements, at a minimum, the IHlink interface and acts as a link to an object at another
location (the target). A hyperlink is made up of four parts: a moniker that identifies the target's location; a
string for the location within the target; a friendly, or displayable, name for the target; and a string that can
contain additional parameters.

h
y
p
e
r
l
i
n
k
b
r
o
w
s
e
c
o
n
t
e
x
t

A COM object that implements the IHlinkBrowseContext interface and maintains the hyperlink navigation
stack. The browse context object manages the hyperlink frame window and hyperlink target object's window.

h
y
p
e
r
l
i
n
k
c
o
n
t
a
i
n
e
r

A container application that supports hyperlinks by implementing the IHlinkSite interface and, if the
container's objects can be targets of other hyperlinks, the IHlinkTarget interface.

h
y
p
e
r
l
i
n
k
f
r
a
m
e
o
b
j
e
c
t

A COM object that implements the IHlinkFrame interface and controls the top-level navigation and display
of hyperlinks for the frame's container and the hyperlink target's server.

h
y
p
e
r
l
i
n
k
s
i
t
e
o
b
j
e
c
t

A COM object that implements the IHlinkSite interface and supplies either the moniker or interface
identifier of its hyperlink container. One hyperlink site can serve multiple hyperlinks.

h
y
p
e
r
l
i
n
k
t
a
r
g
e
t
o
b
j
e
c
t

A COM object that implements the IHlinkTarget interface and supplies its moniker, friendly name, and other
information that other hyperlink objects will use to navigate to it.

i
n
p
a
r
a
m
e
t
e
r

A parameter that is allocated, set, and freed by the caller of a function or interface method. An in parameter is
not modified by the called function.

i
n
/
o
u
t
p
a
r
a
m
e
t
e
r

A parameter that is initially allocated by the caller of a function or interface method, and set, freed, and
reallocated, if necessary, by the process that is called.

i
n
-
p
l
a
c
e
a
c
t
i
v
a
t
i
o
n

Editing an embedded object within the window of its container, using tools provided by the server. Linked
objects do not support in-place activation; they are always edited in the window of the server.

i A server implemented as a DLL that runs in the process space of the client.
n
-
p
r
o
c
e
s
s
s
e
r
v
e
r

i An object for which memory is allocated or which is persistent.


n
s
t
a
n
c
e

i
n
t
e
r
f
a
c
e

A group of semantically related functions that provide access to a COM object. Each OLE interface defines a
contract that allows objects to interact according to the Component Object Model (COM ). While OLE
provides many interface implementations, most interfaces can also be implemented by developers designing
OLE applications.

i
n
t
e
r
f
a
c
e
i
d
e
n
t
i
f
i
e
r
(
I
I
D
)

A globally unique identifier (GUID ) associated with an interface. Some functions take IIDs as parameters to
allow the caller to specify which interface pointer should be returned.

i
t
e
m
m
o
n
i
k
e
r

A moniker based on a string that identifies an object in a container. Item monikers can identify objects smaller
than a file, including embedded objects in a compound document, or a pseudo-object (like a range of cells in
a spreadsheet).

l
i
c
e
n
s
i
n
g

A feature of COM that provides control over object creation. Licensed objects can be created only by clients
that are authorized to use them. Licensing is implemented in COM through the IClassFactory2 interface and
by support for a license key that can be passed at run time.

l
i
n
k
o
b
j
e
c
t

A COM object that is created when a linked COM object is created or loaded. The link object is provided by
OLE and implements the IOleLink interface.

l
i
n
k
e
d
o
b
j
e
c
t

A COM object whose source data physically resides where it was initially created. Only a moniker that
represents the source data and the appropriate presentation data are kept with the compound document.
Changes made to the link source are automatically reflected in the linked object.

l
i
n
k
s
o
u
r
c
e

The data that is the source of a linked object. A link source may be a file or a portion of a file, such as a
selected range of cells within a file (also called a pseudo object).

l
o
a
d
e
d
s
t
a
t
e

The state of an object after its data structures have been loaded into memory and are accessible to the client
process.

l
o
c
a
l
s
e
r
v
e
r

An out-of-process server implemented as an .EXE application running on the same computer as its client
application.

l
o
c
k

A pointer held to-and possibly, a reference count incremented on-a running object. OLE defines two types of
locks that can be held on an object: strong and weak. To implement a strong lock, a server must maintain
both a pointer and a reference count, so that the object will remain "locked" in memory at least until the
server calls IUnknown::Release. To implement a weak lock, the server maintains only a pointer to the
object, so that the object can be destroyed by another process.

m Packaging and sending interface method calls across thread or process boundaries.
a
r
s
h
a
l
i
n
g

m An extension of MIME that allows data format negotiation between a client and an object.
e
d
i
a
t
y
p
e

M An extension of MIME that allows data format negotiation between a client and an object.
I
M
E
c
o
n
t
e
n
t
t
y
p
e

M
u
l
t
i
p
u
r
p
o
s
e
I
n
t
e
r
n
e
t
M
a
i
l
E
x
t
e
n
s
i
o
n
(
M
I
M
E
)

An Internet protocol originally developed to allow exchange of electronic mail messages with rich content
across heterogeneous network, computer, and email environments. In practice, MIME has also been adopted
and extended by non-mail applications.

m
o
n
i
k
e
r

An object that implements the IMoniker interface. A moniker acts as a name that uniquely identifies a COM
object. In the same way that a path identifies a file in the file system, a moniker identifies a COM object in the
directory namespace.

m
o
n
i
k
e
r
c
l
a
s
s

An implementation of the IMoniker interface. System-supplied moniker classes include file monikers, item
monikers, generic composite monikers, anti-monikers, pointer monikers, and URL monikers.

m
o
n
i
k
e
r
c
l
i
e
n
t

An application that uses monikers to acquire interface pointers to objects managed by another application.

m
o
n
i
k
e
r
p
r
o
v
i
d
e
r

An application that makes available monikers that identify the objects it manages, so that the objects are
accessible to other applications.

n
a
m
e
s
p
a
c
e
e
x
t
e
n
s
i
o
n

An in-process COM object that implements IShellFolder, IPersistFolder, and IShellView, which are
sometimes referred to as the namespace extension interfaces. A namespace extension is used either to extend
the shell's namespace or to create a separate namespace. Primary users are the Windows Explorer and
common file dialog boxes.

n The data used by an OLE server application when editing an embedded object.
a
t
i
v
e
d
a
t
a

o
b
j
e
c
t

In OLE, a programming structure encapsulating both data and functionality that are defined and allocated as
a single unit and for which the only public access is through the programming structure's interfaces. A COM
object must support, at a minimum, the IUnknown interface, which maintains the object's existence while it
is being used and provides access to the object's other interfaces.

o
b
j
e
c
t
s
t
a
t
e

The relationship between a compound document object in its container and the application responsible for
the object's creation: active, passive, loaded, or running. Passive objects are stored on disk or in a database,
and the object is not selected or active. In the loaded state, the object's data structures have been loaded into
memory, but they are not available for operations such as editing. Running objects are both loaded and
available for all operations. Active objects are running objects that have a visible user interface.

o
b
j
e
c
t
t
y
p
e
n
a
m
e

A unique identification string that is stored as part of the information available for an object in the
registration database.

O
L
E

Microsoft's object-based technology for sharing information and services across process and computer
boundaries.

o
u
t
-
o
f
-
p
r
o
c
e
s
s
s
e
r
v
e
r

A server, implemented as an .EXE application, which runs outside the process of its client, either on the same
computer or a remote computer.

o An out parameter is allocated by the function being called, and freed by caller.
u
t
p
a
r
a
m
e
t
e
r

p The state of a COM object when it is stored (on disk or in a database). The object is not selected or active.
a
s
s
i
v
e
s
t
a
t
e

p
e
r
s
i
s
t
e
n
t
p
r
o
p
e
r
t
y

Information that can be stored persistently as part of a storage object such as a file or directory. Persistent
properties are grouped into property sets, which can be displayed and edited.
A persistent property is different from the run-time properties of objects created with OLE Controls and
Automation technologies, which can be used to affect system behavior. The PROPVARIANT structure
defines all valid types of persistent properties, whereas the VARIANT structure defines all valid types of run-
time properties.

p
e
r
s
i
s
t
e
n
t
s
t
o
r
a
g
e

Storage of a file or object in a medium such as a file system or database so that the object and its data persist
when the file is closed and then re-opened at a later time.

p A COM object that provides access to GDI images by implementing the IPicture interface.
i
c
t
u
r
e
o
b
j
e
c
t

p
o
i
n
t
e
r
m
o
n
i
k
e
r

A moniker that maps an interface pointer to an object in memory. Whereas most monikers identify objects
that can be persistently stored, pointer monikers identify objects that cannot. They allow such objects to
participate in a moniker binding operation.

p The data used by a container to display embedded or linked objects.


r
e
s
e
n
t
a
t
i
o
n
d
a
t
a

p
r
i
m
a
r
y
v
e
r
b

The action associated with the most common or preferred operation users perform on an object. The primary
verb is always defined as verb zero in the system registration database. An object's primary verb is executed
by double-clicking on the object.

p
r
o
p
e
r
t
y

Information that is associated with an object. In OLE, properties fall into two categories: run-time properties
and persistent properties. Run-time properties are typically associated with control objects or their
containers. For example, background color is a run-time property set by a control's container. Persistent
properties are associated with stored objects.

p
r
o
p
e
r
t
y
f
r
a
m
e

The user interface mechanism that displays one or more property pages for a control. The OLE Controls run-
time system provides a standard implementation of a property frame that can be accessed by using the
OleCreatePropertyFrame helper function.

p A four-byte signed integer that identifies a persistent property within a property set.
r
o
p
e
r
t
y
i
d
e
n
t
i
f
i
e
r

p
r
o
p
e
r
t
y
p
a
g
e

A COM object with its own CLSID that is part of a user interface, implemented by a control, and allows the
control's properties to be viewed and set. Property page objects implement the IPropertyPage interface.

p
r
o
p
e
r
t
y
p
a
g
e
s
i
t
e

The location within a property frame where a property page is displayed. The property frame implements the
IPropertyPageSite interface, which contains methods to manage the sites of each of the property pages
supplied by a control.

p
r
o
p
e
r
t
y
s
e
t

A logically related group of properties that is associated with a persistently stored object. To create, open,
delete, or enumerate one or more property sets, implement the IPropertySetStorage interface. If you are
using compound files, you can use OLE's implementation of this interface rather than implementing your
own.

p
r
o
p
e
r
t
y
s
e
t
s
t
o
r
a
g
e

A COM storage object that holds a property set. A property set storage is a dependent object associated with
and managed by a storage object.

p A set of property pages for one or more objects.


r
o
p
e
r
t
y
s
h
e
e
t

p
r
o
x
y

An interface-specific object that packages parameters for that interface in preparation for a remote method
call. A proxy runs in the address space of the sender and communicates with a corresponding stub in the
receiver's address space.

p In standard marshaling, a proxy that manages all the interface proxies for a single object.
r
o
x
y
m
a
n
a
g
e
r

p
s
e
u
d
o
o
b
j
e
c
t

A portion of a document or embedded object, such as a range of cells in a spreadsheet, that can be the source
for a COM object.

r
e
f
e
r
e
n
c
e
c
o
u
n
t
i
n
g

Keeping a count of each interface pointer held on an object to ensure that the object is not destroyed before
all references to it are released.

r
e
l
a
t
i
v
e
m
o
n
i
k
e
r

A moniker that specifies the location of an object relative to the location of another object. A relative moniker
is analogous to a relative path, such as ..\backup\report.old.

r
e
m
o
t
e
s
e
r
v
e
r

A server application, implemented as an EXE, running on a different computer from the client application
using it.

r
e
v
e
r
t

To discard any changes made to an object since the last time the changes were committed or the object's
storage was opened.

r
o
o
t
s
t
o
r
a
g
e
o
b
j
e
c
t

The outermost storage object in a document. A root storage object can contain other nested storage and
stream objects. For example, a compound document is saved on disk as a series of storage and stream
objects within a root storage object.

r
u
n
n
i
n
g
s
t
a
t
e

The state of a COM object when its server application is running and it is possible to access its interfaces and
receive notification of changes.

r
u
n
n
i
n
g
o
b
j
e
c
t
t
a
b
l
e
(
R
O
T
)

A globally accessible table on each computer that keeps track of all COM objects in the running state that can
be identified by a moniker. Moniker providers register an object in the table, which increments the object's
reference count. Before the object can be destroyed, its moniker must be released from the table.

r
u
n
-
t
i
m
e
p
r
o
p
e
r
t
y

Discrete state information associated with a control object or its container. There are three types of run-time
properties: ambient properties, control properties, and extended properties.

s The process by which a server can perform its own registry operations.
e
l
f
-
r
e
g
i
s
t
r
a
t
i
o
n

s
e
r
v
e
r
a
p
p
l
i
c
a
t
i
o
n

An application that can create COM objects. Container applications can then embed or link to these objects.

s
t
a
t
i
c
o
b
j
e
c
t

An object that contains only a presentation, with no native data. A container can treat a static object as though
it were a linked or embedded object, except that it is not possible to edit a static object.
A static object can result, for example, from the breaking of a link on a linked object-that is, the server
application is unavailable, or the user doesn't want the linked object to be updated anymore.

s
t
o
r
a
g
e
o
b
j
e
c
t

A COM object that implements the IStorage interface. A storage object contains nested storage objects or
stream objects, resulting in the equivalent of a directory/file structure within a single file.

s
t
r
e
a
m
o
b
j
e
c
t

A COM object that implements the IStream interface. A stream object is analogous to a file in a directory/file
system.

S OLE's technology for storing compound files in native file systems.


t
r
u
c
t
u
r
e
d
S
t
o
r
a
g
e

s
t
u
b

When a function's or interface method's parameters are marshaled across a process boundary, the stub is an
interface-specific object that unpackages the marshaled parameters and calls the required method. The stub
runs in the receiver's address space and communicates with a corresponding proxy in the sender's address
space.

s Manages all of the interface stubs for a single object.


t
u
b
m
a
n
a
g
e
r

s
y
n
c
h
r
o
n
o
u
s
c
a
l
l

A function call that does not allow further instructions in the calling process to be executed until the function
returns.

s
y
s
t
e
m
r
e
g
i
s
t
r
y

A system-wide repository of information supported by Windows, which contains information about the
system and its applications, including OLE clients and servers.

t
r
a
n
s
a
c
t
e
d
a
c
c
e
s
s
m
o
d
e

One of two access modes in which a storage object can be opened. When opened in transacted mode,
changes are stored in buffers until the root storage object commits its changes.

t
y
p
e
i
n
f
o
r
m
a
t
i
o
n

Information about an object's class provided by a type library. To provide type information, a COM object
implements the IProvideClassInfo interface.

u
n
i
f
o
r
m
d
a
t
a
t
r
a
n
s
f
e
r

A model for transferring data through the clipboard, drag and drop, or Automation. Objects conforming to
this model implement the IDataObject interface. This model replaces DDE (dynamic data exchange).

u Unpacking parameters that have been sent to a proxy across process boundaries.
n
m
a
r
s
h
a
l
i
n
g

u
n
i
v
e
r
s
a
l
r
e
s
o
u
r
c
e
l
o
c
a
t
o
r
(
U
R
L
)

The identifier used by the World Wide Web for the names and locations of objects on the Internet. OLE
provides a moniker class, URL moniker, whose implementation can be used to bind a client to objects
identified by a URL.

U
R
L
m
o
n
i
k
e
r

A moniker based on a universal resource locator (URL ). A client can use URL monikers to bind to objects that
reside on the Internet. The system-supplied URL moniker class supports both synchronous and
asynchronous binding.

You might also like