\n
Microsoft Invisible Computing

IUnknown Interface

The IUnknown interface provides methods to obtain and manage pointers to interface objects. Every COM object must support the IUnknown interface and all interfaces are derived from it.

C type for interface pointer:

Extended by INameSpace INameRanges IHeap IContinuation IHeapFactory IModule IProcess IThread IProgram IEndpointFactory IWebProtocolFactory ITokenizerFactory IWsDiscoveryUtil ICimFactory ISensor IFile IDevice INetDriver IBusDriver IEndpoint1 IEndpoint IBuffer IBufWin IBaseRtl IDeviceConstructor IFrameBuffer IUsbSlaveDriver IUsbSlaveController IUsbMasterController IUsbHub IUsbDriver IProtoSW IVmView ISoapFactory IConvert ISaxParser ISaxHandler ISoapSerializer IListener IHttpConnector IHttpProcess ITokenizer IWsReservation IWsFlow IWsAddressing ICIM_Base ICIM_ManagedSystemElement ICIM_NumericSensor XXX_Config ICIM_Account ICIM_Service IWsTransfer IDssp IWsManagement IWsManId IWsManConfig IWsEnumeration IWsEventing IWsDiscovery IKeyExchange soap12 IWsMetadataExchange IWsDeviceProfile IWsScripting ITrustPolicy ISampling IStatistics IReservationBuilder ITaskBuilder IPlanner IInstigator IWsTargetService IEnum ICimTransaction ICimResource ICypher ICypherConstructor ICLR ICRuntime ISampleCalculator IRecorder ISntpClient IRobot ITablet IPong ITest ISampleTest ICLRSample IGlove ICIM_Schema ICIM_Catalog IWsManagementListener ICIM_IPMI ICIM_RecordLog IRobotGameController IServiceTutorial1

Implemented by CUnknown DefCob SoapFactory ConverterFactory HttpFactory TokenizerFactory WsRes WsAddressing WsMan Dssp WsDiscovery SAMPLECalculator Marionette tabletServiceImpl testserviceImpl SensorDemo Statistics Tzk CimFactory CimSampleFactory CEndpointFactory base64CypherConstructor Topolino CContinuation TcpServer HttpNSContent HttpProcessNS HttpProcessFile HttpProcessSoap HttpConnector Tokenizer TokenizerFile BufWin WsDiscoEnum CimResource CimEnum CEndpoint CBuffer EndPair base64Cypher DefCob SoapFactory ConverterFactory HttpFactory TokenizerFactory WsRes WsAddressing WsMan Dssp WsDiscovery SAMPLECalculator Marionette tabletServiceImpl testserviceImpl SensorDemo Statistics Tzk CimFactory CimSampleFactory CEndpointFactory base64CypherConstructor Topolino

Methods: QueryInterface AddRef Release

Constants: SCODE MMLite error SCODE MMLite success SCODE Ole32 SCODE Win32 SCODE

Structs: IID

Types: TIME PTIME

Methods

QueryInterface

Determines which interfaces an object supports and returns a valid pointer to an interface.

AddRef

Increments the reference count of the object.

Release

Decrements the reference count of an object. When the count goes to zero, the object is destroyed.

Constants

SCODE

Generic success codes

MMLite error SCODE

MMLite specific error codes

MMLite success SCODE

MMLite specific success codes

Ole32 SCODE

OLE derived error codes

Win32 SCODE

Win32 derived error codes

Structs

IID

A globally unique identifier for interface type checking and casting.

Types

typedef INT64 TIME;

The representation of time is the same as in Windows' FILETIME, namely a 64-bit value with a time unit of 100-nanoseconds. The beginning of time is January 1, 1601 GMT. A positive value for this signed integer is interpreted as an absolute epoch, a specific point in time. For instance the value 1 means 100 nanoseconds from the start of time. A negative value represents a relative epoch, one that is computed by adding the negated 64-bit value to the CurrentTime at the point of use. For instance the value -1 means 100 nanoseconds from now, whenever now is actually computed. Look up SleepUntil and the fields of a TIME_CONSTRAINT for some practical examples. The use of relative time is encouraged in programming because it avoids the common error of specifying CurrentTime()+delta. In the presence of multiple threads this can lead to occasional misbehaviours if the thread is descheduled between the computation of the given, future epoch and the use of the resulting epoch, which might then happen to actually be in the past.

typedef TIME * PTIME;

A pointer to a TIME value.

IUnknown.QueryInterface Method

Determines which interfaces an object supports and returns a valid pointer to an interface.

SCODE QueryInterface( 
    /*in,this*/ PIUNKNOWN iThis,
    /*in*/ REFIID iid,
    /*out*/ void** ppObject)
iid

Specifies the interface ID of the desired interface.

ppObject

Contains the address of a pointer to the object whose interface is being queried. Upon successful return, the method fills it with a pointer to the newly created object. If, and only if, the query is successful, a valid pointer to an interface is returned.

This method provides the necessary verification that an object implements a given interface. The Iid parameter guarantees that the interface methods are implemented with the proper type signature. Different interfaces on the same object are desirable for implementing strict relationships between objects, backward-compatible changes, and security purposes.

An object can implement an interface directly, or it can delegate this task to a separate object. Therefore, there are no guarantees that the object returned by this method will be the same as its parameter. Assume the object is different on each call, even for the same interface. Moreover, if the object is implemented in a different address space (possibly on some remote machine), the remote method invocation mechanism will always return a different interface pointer (for example to a proxy object) for each separate interface. It is an error to directly type-cast interface pointers without passing though IUnknown.QueryInterface first.

If an interface derives (in the C++ sense) from any other interfaces, it has access to all the methods in those interfaces.

Example QueryInterface Usage: C++ Version

/* Pointer and reference to the current process. */
PIPROCESS pPrc = CurrentProcess();
PIMODULE pModule;
SCODE StatusCode;

/* Get the module that corresponds to our process. */
StatusCode = pPrc->QueryInterface(IID_IModule, (void **) &pModule);
if (FAILED(StatusCode)) {
    _tprintf(_TEXT("QueryInterface failed, sc =  %08x\n"), StatusCode);
    return 1;
}
_tprintf(_TEXT("Process is %08x, module is %08x.\n"),
         (ADDRESS) pPrc, (ADDRESS) pModule);
pModule->Release();
return 0;

Example QueryInterface Usage: C Version

/* Pointer and reference to the current process. */
PIPROCESS pPrc = CurrentProcess();
PIMODULE pModule;
SCODE StatusCode;

/* Get the module that corresponds to our process. */
StatusCode = pPrc->v->QueryInterface(pPrc, &IID_IModule, (void **) &pModule);
if (FAILED(StatusCode)) {
    _tprintf(_TEXT("QueryInterface failed, sc =  %08x\n"), StatusCode);
    return 1;
}
_tprintf(_TEXT("Process is %08x, module is %08x.\n"),
         (ADDRESS) pPrc, (ADDRESS) pModule);
pModule->v->Release(pModule);
return 0;

See also IUnknown.AddRef INameSpace.Bind

C++

SCODE IUnknown::QueryInterface( 
    /*in*/ REFIID iid,
    /*out*/ void** ppObject)

IUnknown.AddRef Method

Increments the reference count of the object.

UINT AddRef( 
    /*in,this*/ PIUNKNOWN iThis)

This method and IUnknown.Release work together to determine whether an object is in use. As long as one of its interfaces is referenced by another object, the object should continue to exist. The main purpose of reference counting is for storage-management purposes such as garbage collection.

This method reveals how many references exist at some point in time, but note that another thread can change the reference count immediately.

This method is especially useful when an object depends on some other object. An arbitrary hierarchy of objects can be reference counted by invoking IUnknown.AddRef or IUnknown.Release on the top object, which in turn invokes the method call on the nested object.

The same object can implement different interfaces. Each interface can be separately reference counted, if desired, by using different AddRef or Release method calls.

The use of the AtomicInc function in the implementation of the method is highly recommended. The ++ operator in C/C++ is not safe in the presence of multiple threads.

Example AddRef

/* Pointer and reference to the current process. */
/* We want to force this process to stay around even after its last
 * thread is gone, presumably because some persistent object has
 * been registered in the namespace.
 */
pPrc->AddRef();
ThreadExit();

See also AtomicInc IUnknown.QueryInterface IUnknown.Release

C++

UINT IUnknown::AddRef( void )

IUnknown.Release Method

Decrements the reference count of an object. When the count goes to zero, the object is destroyed.

UINT Release( 
    /*in,this*/ PIUNKNOWN iThis)

Decrements the reference count of an object, should be called each time a pointer to an object is no longer needed. When all references to the object are gone, the object is destroyed. Failure to invoke this method leads to memory leaks. Calling this method inappropriately can cause the premature destruction of objects, which in turn leads to failures that are very difficult to detect. The developer must ensure the function is called exactly once for each time AddRef or QueryInterface is called, or unpredictable system failures will occur. Note that these failures often occur in unrelated components. This is analogous to using IHeap.Free on a non-object.

This method and IUnknown.AddRef work together to determine whether an object is in use or not. See the discussion for IUnknown.AddRef for more information. Note that IUnknown.Queryinterface calls AddRef upon success.

When the reference count goes to zero, the object is no longer available to any thread. No further methods can invoke this object again. If the object was allocated dynamically, a memory leak will occur unless the memory is freed. If the object holds references to any other objects, these objects should be released as well. Otherwise, they are not recoverable.

If the reference count is non-zero after decrementing, there are threads that will possibly invoke methods on this object. The implementation of this method should never destroy the object if there are outstanding references.

The use of the AtomicDec function in the implementation of the method is strongly recommended. The -- operator in C/C++ is not safe in the presence of multiple threads.

Example Release

/* MyClass implements only IUnknown. */
struct MyClass : IUnknown {
    SCODE MCT QueryInterface(REFIID riid, void **ppvObject);
    UINT MCT AddRef(void);
    UINT MCT Release(void);
private:
    UINT RefCount;
};

UINT MCT MyClass::Release(void)
{
    UINT Refs = AtomicDec(&RefCount);
    /* Last reference? */
    if(Refs == 0) {
        _tprintf(_T("Object %x is released.\n"), (ADDRESS) this);
        delete this;
    }
    return Refs;
}

See also AtomicDec IUnknown.QueryInterface IUnknown.AddRef

C++

UINT IUnknown::Release( void )

SCODE Constant

Generic success codes

S_OK 0x0

Generic all OK success used by all methods that return SCODEs.

S_FALSE 0x1

Generic secondary success, indicates last entry or similar.

MMLite error SCODE Constant

MMLite specific error codes

E_UNEXPECTED_ERROR 0x80060000

Object is in a state where the operation is not allowed.

E_OBJECT_NOT_INITIALIZED 0x80060001

Object is in a state where it is unable to service method call.

E_TIMED_OUT 0x80060003

Operation timed out and was not completed. In many cases this is intentional behavior and does not indicate any kind of failure.

E_ALREADY_RESERVED 0x8006000d

Memory region was already reserved. A region cannot be reserved twice.

E_NOT_RESERVED 0x8006000e

Memory region was not reserved. It must be reserved before mappings can be mapped to it.

E_ALREADY_COMMITTED 0x8006000f

A memory region already had a mapping and/or physical pages.

E_NOT_COMMITTED 0x80060010

Operation required a mapping but there was none.

E_TOO_MANY_CONTIGUOUS 0x80060012

The image has too many sections.

E_RESTART 0x80060014

Operation could not be completed atomically and must be restarted.

E_END_OF_DATA 0x80060015

Parser reached maximum content size.

E_PARSE_ERROR 0x80060016

Data format error.

E_SCHEMA_CHECK 0x80060017

Data format error.

E_WOULD_BLOCK 0x80060018

The method is done for now but ought to be restarted in the future.

E_OBJECT_BUSY 0x80060019

The method can't proceed since a resource needed is currently in use but this ought to be restarted in the future.

E_PARSING_ERROR 0x80060020

Invalid input encountered

E_ERROR_RESPONSE_RECEIVED 0x80060021

Invalid input encountered

E_AUTHORIZATION_REQUIRED 0x80060022

The client authorization is lacking (e.g. HTTP 401).

E_NAME_NOT_FOUND E_PATH_NOT_FOUND

The name referred to did not exist in namespace.

E_OBJECT_NOT_FOUND E_ENTRY_NOT_FOUND

Lookup failed.

E_INVALID_METHOD E_INVALID_ORDINAL

Protocol error. Message referred to method not in schema.

MMLite success SCODE Constant

MMLite specific success codes

S_OUTATIME 0x60004

The previous constraint overran its estimate.

S_ALREADY_EXISTS 0x600b7

Entry already existed but was overwritten.

S_BUFFER_TOO_SMALL 0x6007a

The buffer provided was too small. This means usually the size of an out parameter of a method call. Nevertheless the call was completed and the return value was filled in up to the size.

S_NAME_SEARCH_INCOMPLETE 0x6007b

A symbolic link was encountered in the middle of a name resolution when NAME_SPACE_NOFOLLOW was set.

S_NO_RESPONSE 0x6007c

The application already sent a response or will send a response so the server should not do it.

S_MUST_REPLY 0x6007d

The application has generated a response and it should be forwarded to the server. Used by intermediaries that can handle data in either directions.

S_NO_MORE_ENTRIES S_FALSE

Last entry in namespace.

Ole32 SCODE Constant

OLE derived error codes

E_NOT_IMPLEMENTED 0x80040001

The method is not implementation by the server.

Same as E_NOTIMPL in Ole.

E_NO_INTERFACE 0x80040002

The server does not support the given interface. In other words the Interface ID given to QueryInterface was not recognized.

Same as E_NOINTERFACE in Ole.

E_FAIL 0x80040005

Generic catch-all failure.

Win32 SCODE Constant

Win32 derived error codes

E_FILE_NOT_FOUND 0x80070002

Specified name is not present in namespace.

E_PATH_NOT_FOUND 0x80070003

The name referred to did not exist in namespace.

E_ACCESS_DENIED 0x80070005

Access was denied. For example a write to a read-only file.

E_INVALID_HANDLE 0x80070006

Operation could not be completed because a required object was not available.

E_NOT_ENOUGH_MEMORY 0x80070008

Resource shortage.

E_WRITE_PROTECT 0x80070013

Disk was read-only.

E_BAD_UNIT 0x80070014

Disk error.

E_NOT_READY 0x80070015

Disk error.

E_CRC 0x80070017

Disk error.

E_DMA_FAILURE 0x80070018

Driver error.

E_SEEK 0x80070019

Disk error.

E_SECTOR_NOT_FOUND 0x8007001b

Disk error.

E_OUT_OF_STRUCTURES 0x80070054

Allocation from fixed size pool failed. Resource shortage.

E_INVALID_PARAMETER 0x80070057

A method argument had a value not allowed in call.

E_NULL_PARAMETER 0x80070058

A method argument had a value not allowed in call.

E_BUFFER_TOO_SMALL 0x8007007a

The buffer provided was too small. This means usually the size of an out parameter of a method call. The call could not be completed and the out parameters were not updated.

E_MOD_NOT_FOUND 0x8007007e

Module not found.

E_PROC_NOT_FOUND 0x8007007f

Method not found. DLL import was not found in export table.

E_INVALID_ORDINAL 0x800700b6

Method number out of range. DLL entry was not exported.

E_ALREADY_EXISTS 0x800700b7

Entry could not be created because it was already present.

E_INVALID_EXE_SIGNATURE 0x800700bf

Image could not be loaded for execution.

E_EXE_MARKED_INVALID 0x800700c0

E_BAD_EXE_FORMAT 0x800700c1

Image could not be loaded for execution.

E_LOCKED 0x800700d4

E_INCOMPATIBLE_VERSION 0x800700d8

An object's version is incompatible with another object, like between the loader and an executable image.

E_INVALID_ADDRESS 0x800701e7

Pointer argument was not within range.

E_IO_PENDING 0x800703e5

I/O in progress.

E_NOACCESS 0x800703e6

E_MEDIA_CHANGED 0x80070456

Disk error.

E_NO_MEDIA_IN_DRIVE 0x80070458

Disk error.

E_DLL_INIT_FAILED 0x8007045a

Image load failed.

E_FLOPPY_ID_MARK_NOT_FOUND 0x80070462

Disk error.

E_FLOPPY_WRONG_CYLINDER 0x80070463

Disk error.

E_FLOPPY_UNKNOWN_ERROR 0x80070464

Disk error.

E_FLOPPY_BAD_REGISTERS 0x80070465

Disk error.

E_DISK_RECALIBRATE_FAILED 0x80070466

Disk error.

E_DISK_OPERATION_FAILED 0x80070467

Disk error.

E_DISK_RESET_FAILED 0x80070468

Disk error.

E_INTERNAL_ERROR 0x8007054f

Should not happen.

E_ENTRY_NOT_FOUND 0x800706e1

Name was not found in namespace.

E_UNRECOGNIZED_MEDIA 0x800706f9

Disk error.

E_SIG_NOT_FOUND 0x80070715

E_DEVICE_IN_USE 0x80070964

Driver error. Exclusive access.

E_HTTP_ERROR 0x80070965

Driver error. Exclusive access.

IID Structure

A globally unique identifier for interface type checking and casting.

See also QueryInterface

Fields
Data1
C/C++ type: UINT32
Data2
C/C++ type: UINT16
Data3
C/C++ type: UINT16
Data4
C/C++ type: UINT8 [8]

©2006 Microsoft Corporation. All rights reserved. Terms of Use Privacy Statement Accessibility End User License Agreement