386 lines
7.7 KiB
C++
386 lines
7.7 KiB
C++
|
/*++
|
|||
|
|
|||
|
Copyright (C) Microsoft Corporation, 1991 - 1999
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
rpcobj.cxx
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
The implementation of the object dictionary lives in this file;
|
|||
|
it is used to map from an object uuid to a type uuid. From there
|
|||
|
we need to map to a manager entry point vector.
|
|||
|
|
|||
|
Author:
|
|||
|
|
|||
|
Michael Montague (mikemon) 14-Nov-1991
|
|||
|
|
|||
|
Revision History:
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
#include <precomp.hxx>
|
|||
|
#include <rpcobj.hxx>
|
|||
|
|
|||
|
static RPC_OBJECT_INQ_FN PAPI * ObjectTypeInquiryFn = 0;
|
|||
|
|
|||
|
|
|||
|
class OBJECT_ENTRY
|
|||
|
/*++
|
|||
|
|
|||
|
Class Description:
|
|||
|
|
|||
|
Each of the entries in the object dictionary consist of one of these
|
|||
|
objects.
|
|||
|
|
|||
|
Fields:
|
|||
|
|
|||
|
ObjectUuid - Contains the object uuid of this entry.
|
|||
|
|
|||
|
TypeUuid - Contains the type uuid of the object uuid in this entry.
|
|||
|
|
|||
|
DictionaryKey - Contains the key in the dictionary for this object
|
|||
|
entry. I made this a public instance variable for two reasons:
|
|||
|
(1) I was just going to defined a writer and a reader for
|
|||
|
it (routines to set and get the value).
|
|||
|
(2) This class is private to a source file, so it is very
|
|||
|
obvious the scope of usage.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
private:
|
|||
|
|
|||
|
RPC_UUID ObjectUuid;
|
|||
|
RPC_UUID TypeUuid;
|
|||
|
|
|||
|
public:
|
|||
|
|
|||
|
unsigned int DictionaryKey;
|
|||
|
|
|||
|
OBJECT_ENTRY (
|
|||
|
IN RPC_UUID PAPI * ObjectUuid,
|
|||
|
IN RPC_UUID PAPI * TypeUuid
|
|||
|
);
|
|||
|
|
|||
|
int
|
|||
|
MatchObjectUuid (
|
|||
|
IN RPC_UUID PAPI * ObjectUuid
|
|||
|
);
|
|||
|
|
|||
|
void
|
|||
|
CopyToTypeUuid (
|
|||
|
OUT RPC_UUID PAPI * TypeUuid
|
|||
|
);
|
|||
|
};
|
|||
|
|
|||
|
|
|||
|
OBJECT_ENTRY::OBJECT_ENTRY (
|
|||
|
IN RPC_UUID PAPI * ObjectUuid,
|
|||
|
IN RPC_UUID PAPI * TypeUuid
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine is used to construct an entry in the object dictionary.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
ObjectUuid - Supplies the uuid to use to initialize the object uuid
|
|||
|
in this entry.
|
|||
|
|
|||
|
TypeUuid - Supplies the uuid to use to initialize the type uuid in
|
|||
|
this entry.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
ALLOCATE_THIS(OBJECT_ENTRY);
|
|||
|
|
|||
|
this->ObjectUuid.CopyUuid(ObjectUuid);
|
|||
|
this->TypeUuid.CopyUuid(TypeUuid);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
inline int
|
|||
|
OBJECT_ENTRY::MatchObjectUuid (
|
|||
|
IN RPC_UUID PAPI * ObjectUuid
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This method compares the supplied object uuid against the object
|
|||
|
uuid contained in this object entry.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
ObjectUuid - Supplies the object uuid.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Zero will be returned if the supplied object uuid is the same as the
|
|||
|
object uuid contained in this.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
return(this->ObjectUuid.MatchUuid(ObjectUuid));
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
inline void
|
|||
|
OBJECT_ENTRY::CopyToTypeUuid (
|
|||
|
OUT RPC_UUID PAPI * TypeUuid
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
We copy the type uuid for this object entry into the supplied type
|
|||
|
uuid.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
TypeUuid - Returns a copy of the type uuid in this object entry.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
TypeUuid->CopyUuid(&(this->TypeUuid));
|
|||
|
}
|
|||
|
|
|||
|
NEW_SDICT(OBJECT_ENTRY);
|
|||
|
|
|||
|
OBJECT_ENTRY_DICT * ObjectDictionary;
|
|||
|
|
|||
|
|
|||
|
OBJECT_ENTRY *
|
|||
|
FindObject (
|
|||
|
IN RPC_UUID PAPI * ObjectUuid
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine is used to find the object entry in the object dictionary
|
|||
|
having the specified object uuid.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
ObjectUuid - Supplies the object uuid which we wish to find.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
The object entry having the supplied object uuid will be returned if
|
|||
|
it can be found, otherwise, zero will be returned.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
OBJECT_ENTRY * ObjectEntry;
|
|||
|
DictionaryCursor cursor;
|
|||
|
|
|||
|
ObjectDictionary->Reset(cursor);
|
|||
|
while ((ObjectEntry = ObjectDictionary->Next(cursor)) != 0)
|
|||
|
{
|
|||
|
if (ObjectEntry->MatchObjectUuid(ObjectUuid) == 0)
|
|||
|
return(ObjectEntry);
|
|||
|
}
|
|||
|
|
|||
|
return(0);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
RPC_STATUS
|
|||
|
ObjectInqType (
|
|||
|
IN RPC_UUID PAPI * ObjUuid,
|
|||
|
OUT RPC_UUID PAPI * TypeUuid
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
We search in the dictionary for the specified object UUID; if it
|
|||
|
is found, we return its type UUID.
|
|||
|
|
|||
|
Parameters:
|
|||
|
|
|||
|
ObjUuid - Supplies the object UUID for which we are trying to
|
|||
|
find the type UUID.
|
|||
|
|
|||
|
TypeUuid - Returns the type UUID of the object UUID, presuming
|
|||
|
that the object UUID is found.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
RPC_S_OK - The operation completed successfully; the object uuid
|
|||
|
is registered with the runtime or the object inquiry function
|
|||
|
knows the object uuid.
|
|||
|
|
|||
|
RPC_S_OBJECT_NOT_FOUND - The specified object uuid has not been
|
|||
|
registered with the runtime and the object inquiry function
|
|||
|
does not know about the object uuid.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
RPC_STATUS Status;
|
|||
|
OBJECT_ENTRY * ObjectEntry;
|
|||
|
|
|||
|
if ( ObjUuid == NULL
|
|||
|
|| ObjUuid->IsNullUuid())
|
|||
|
{
|
|||
|
TypeUuid->SetToNullUuid();
|
|||
|
return(RPC_S_OK);
|
|||
|
}
|
|||
|
|
|||
|
RequestGlobalMutex();
|
|||
|
ObjectEntry = FindObject(ObjUuid);
|
|||
|
if (ObjectEntry == 0)
|
|||
|
{
|
|||
|
if (ObjectTypeInquiryFn == 0)
|
|||
|
{
|
|||
|
ClearGlobalMutex();
|
|||
|
TypeUuid->SetToNullUuid();
|
|||
|
return(RPC_S_OBJECT_NOT_FOUND);
|
|||
|
}
|
|||
|
ClearGlobalMutex();
|
|||
|
(*ObjectTypeInquiryFn)((UUID PAPI *) ObjUuid, (UUID PAPI *) TypeUuid,
|
|||
|
&Status);
|
|||
|
return(Status);
|
|||
|
}
|
|||
|
|
|||
|
ObjectEntry->CopyToTypeUuid(TypeUuid);
|
|||
|
ClearGlobalMutex();
|
|||
|
return(RPC_S_OK);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
RPC_STATUS
|
|||
|
ObjectSetInqFn (
|
|||
|
IN RPC_OBJECT_INQ_FN PAPI * InquiryFn
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
With just two lines of code, the comment for this routine is
|
|||
|
already longer than the routine.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
InquiryFn - Supplies a function to be used when the type of an
|
|||
|
unknown object is inquired.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
RPC_S_OK - This is always returned by the second line of code.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
ObjectTypeInquiryFn = InquiryFn;
|
|||
|
|
|||
|
return(RPC_S_OK);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
RPC_STATUS
|
|||
|
ObjectSetType (
|
|||
|
IN RPC_UUID PAPI * ObjUuid,
|
|||
|
IN RPC_UUID PAPI * TypeUuid OPTIONAL
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine is used to associate a type UUID with an object UUID.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
ObjUuid - Supplies the object UUID.
|
|||
|
|
|||
|
TypeUuid - Supplies the type UUID to associate with the object
|
|||
|
UUID.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
RPC_S_OK - The type UUID was successfully associated with the
|
|||
|
object UUID.
|
|||
|
|
|||
|
RPC_S_ALREADY_REGISTERED - The object uuid specified has already
|
|||
|
been registered with the runtime.
|
|||
|
|
|||
|
RPC_S_OUT_OF_MEMORY - There is insufficient memory available to
|
|||
|
associate the object UUID with the type UUID.
|
|||
|
|
|||
|
RPC_S_INVALID_OBJECT - The object uuid specified is the nil uuid.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
OBJECT_ENTRY * ObjectEntry;
|
|||
|
|
|||
|
if ( ObjUuid->IsNullUuid() != 0 )
|
|||
|
{
|
|||
|
return(RPC_S_INVALID_OBJECT);
|
|||
|
}
|
|||
|
|
|||
|
RequestGlobalMutex();
|
|||
|
ObjectEntry = FindObject(ObjUuid);
|
|||
|
if ( (ARGUMENT_PRESENT(TypeUuid) == 0)
|
|||
|
|| (TypeUuid->IsNullUuid() != 0))
|
|||
|
{
|
|||
|
if (ObjectEntry != 0)
|
|||
|
{
|
|||
|
ObjectDictionary->Delete(ObjectEntry->DictionaryKey);
|
|||
|
ClearGlobalMutex();
|
|||
|
return(RPC_S_OK);
|
|||
|
}
|
|||
|
ClearGlobalMutex();
|
|||
|
return(RPC_S_OK);
|
|||
|
}
|
|||
|
|
|||
|
if (ObjectEntry != 0)
|
|||
|
{
|
|||
|
ClearGlobalMutex();
|
|||
|
return(RPC_S_ALREADY_REGISTERED);
|
|||
|
}
|
|||
|
|
|||
|
ObjectEntry = new OBJECT_ENTRY(ObjUuid,TypeUuid);
|
|||
|
if (ObjectEntry == 0)
|
|||
|
{
|
|||
|
ClearGlobalMutex();
|
|||
|
return(RPC_S_OUT_OF_MEMORY);
|
|||
|
}
|
|||
|
|
|||
|
ObjectEntry->DictionaryKey = ObjectDictionary->Insert(ObjectEntry);
|
|||
|
if (ObjectEntry->DictionaryKey == -1)
|
|||
|
{
|
|||
|
ClearGlobalMutex();
|
|||
|
delete ObjectEntry;
|
|||
|
return(RPC_S_OUT_OF_MEMORY);
|
|||
|
}
|
|||
|
|
|||
|
ClearGlobalMutex();
|
|||
|
return(RPC_S_OK);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
int
|
|||
|
InitializeObjectDictionary (
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
At DLL initialization time, this routine will get called.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Zero will be returned if initialization completes successfully;
|
|||
|
otherwise, non-zero will be returned.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
ObjectDictionary = new OBJECT_ENTRY_DICT;
|
|||
|
if (ObjectDictionary == 0)
|
|||
|
return(1);
|
|||
|
return(0);
|
|||
|
}
|