mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1089 lines
19 KiB
1089 lines
19 KiB
/*++
|
|
|
|
Copyright (c) 1992 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
protocol.hxx
|
|
|
|
Abstract:
|
|
|
|
This module deals with objects that make up the server and group
|
|
entry items. This includes creatation/destruction and searching
|
|
of the entries.
|
|
|
|
Author:
|
|
|
|
Steven Zeck (stevez) 07/01/90
|
|
|
|
--*/
|
|
|
|
#ifndef _PROTOCOL_
|
|
#define _PROTOCOL_
|
|
|
|
class QUERY_SERVER;
|
|
class ENTRY_BASE_NODE;
|
|
class ENTRY_BASE_ITEM;
|
|
class ENTRY_SERVER_ITEM;
|
|
class ENTRY_SERVER_NODE;
|
|
class ENTRY_GROUP_ITEM;
|
|
class ENTRY_GROUP_NODE;
|
|
|
|
DYN_ARRAY_TYPE(UUID_ARRAY, NS_UUID, LONG)
|
|
|
|
|
|
// The following enumeration is the the type of entry the object is.
|
|
|
|
typedef enum {
|
|
|
|
ServerEntryType = 1,
|
|
GroupEntryType,
|
|
ProfileEntryType,
|
|
AnyEntryType,
|
|
LastEntryType
|
|
} TYPE_ENTRY_NODE ;
|
|
|
|
|
|
// The following are the type of base member entry the object is.
|
|
|
|
typedef enum {
|
|
LocalItemType = 1, // local item
|
|
CacheItemType, // cached item, ie - remote
|
|
DeleteItemType, // delayed delete due
|
|
LastItemType // end marker
|
|
|
|
} TYPE_ENTRY_ITEM;
|
|
|
|
|
|
// The follwing is the return values by MatchItem virtual functions.
|
|
|
|
typedef enum {
|
|
NoMatch, // Item didn't match
|
|
ItemMatch, // This item matched
|
|
SubItemMatch, // or a subitem under this object matched
|
|
}MATCH_RETURN;
|
|
|
|
|
|
|
|
// The following is the format for a query on the net with mailslots.
|
|
|
|
typedef struct {
|
|
|
|
NS_SYNTAX_ID Interface; // inteface that we are looking for
|
|
NS_UUID Object; // Object that we are interested in
|
|
UICHAR WkstaName[DOMAIN_MAX]; // buffer for machine name
|
|
UICHAR EntryName[ENTRY_MAX]; // buffer for entry name
|
|
|
|
} QueryPacket;
|
|
|
|
|
|
|
|
/*++
|
|
|
|
Class Definition:
|
|
|
|
ENTRY_KEY
|
|
|
|
Abstract:
|
|
|
|
This is the EntryName object. It is the name of the entries in
|
|
the in memory object data base.
|
|
|
|
--*/
|
|
|
|
class ENTRY_KEY {
|
|
|
|
private:
|
|
UNICODE_ARRAY EntryName; // and the string value of the entry
|
|
|
|
public:
|
|
|
|
ENTRY_KEY(
|
|
IN PUZ Name,
|
|
IN PUZ DomainName,
|
|
OUT STATUS *Status
|
|
);
|
|
|
|
ENTRY_KEY(
|
|
IN PUZ Name,
|
|
IN int fAllowGlobal,
|
|
OUT STATUS *Status
|
|
);
|
|
|
|
// Construct a new object by copying an existing one.
|
|
|
|
ENTRY_KEY(
|
|
IN ENTRY_KEY *KeyNew,
|
|
OUT STATUS *Status
|
|
)
|
|
{
|
|
EntryName = KeyNew->EntryName.Dup();
|
|
|
|
*Status = (!KeyNew->EntryName.pCur() || EntryName.pCur())?
|
|
NSI_S_OK: NSI_S_OUT_OF_MEMORY;
|
|
}
|
|
|
|
|
|
ACCESSOR(UNICODE_ARRAY, EntryName);
|
|
|
|
// Free the allocated objects referenced.
|
|
|
|
void
|
|
Free(
|
|
)
|
|
{
|
|
EntryName.Free();
|
|
}
|
|
|
|
// Set the value of the EntryName
|
|
|
|
void
|
|
SetEntryName(
|
|
IN UNICODE_ARRAY &New,
|
|
OUT UNICODE_ARRAY &Previous
|
|
)
|
|
{
|
|
Previous = EntryName;
|
|
EntryName = New;
|
|
}
|
|
|
|
int
|
|
Equal(
|
|
UNICODE_ARRAY& Entry1
|
|
);
|
|
|
|
// Compare two objects for identity
|
|
|
|
int
|
|
Equal (
|
|
IN ENTRY_KEY &Entry1
|
|
)
|
|
{
|
|
return(Equal(Entry1.EntryName));
|
|
}
|
|
|
|
// Determine if an entry name is empty.
|
|
|
|
int
|
|
IsNil(
|
|
)
|
|
{
|
|
return(EntryName.cCur() == 0);
|
|
}
|
|
|
|
// Return a Copy of the entry name.
|
|
|
|
UICHAR *
|
|
CopyName(
|
|
)
|
|
{
|
|
return((UICHAR *)NewCopy(EntryName.pCur(), (int) EntryName.Size()));
|
|
}
|
|
|
|
// Return the size to marshall this object.
|
|
|
|
int
|
|
MarshallSize(
|
|
)
|
|
{
|
|
return(sizeof(ENTRY_KEY) + EntryName.Size());
|
|
}
|
|
|
|
char *
|
|
Marshall(
|
|
OUT char *Buffer
|
|
);
|
|
|
|
PUZ
|
|
MakeLocalName(
|
|
OUT PUZ Buffer,
|
|
OUT PUZ DomainBuffer,
|
|
IN PUZ DefDomain
|
|
);
|
|
|
|
friend char *
|
|
KeyEntryUnMarshall(
|
|
OUT ENTRY_KEY **Key,
|
|
IN UICHAR * Domain,
|
|
IN char *Buffer,
|
|
OUT STATUS *Status
|
|
);
|
|
|
|
friend ostream& operator << (ostream&, ENTRY_KEY&);
|
|
};
|
|
|
|
|
|
|
|
/*++
|
|
|
|
Class Definition:
|
|
|
|
QUERY_REF_ITEM
|
|
|
|
Abstract:
|
|
|
|
This linked list is how replies are stored. Each found EntryItem
|
|
is referenced by a pointer to the base case for EntryItems.
|
|
|
|
--*/
|
|
|
|
NEW_LINK_LIST(QUERY_REF,
|
|
|
|
ENTRY_BASE_ITEM *EntryItem; /* Reference to matched item */
|
|
|
|
QUERY_REF_ITEM (
|
|
IN ENTRY_BASE_ITEM *EntryItemNew
|
|
)
|
|
{
|
|
EntryItem = EntryItemNew;
|
|
}
|
|
|
|
QUERY_REF_ITEM *
|
|
Free(
|
|
IN OUT QUERY_REF_LIST &ML
|
|
);
|
|
|
|
friend ostream& operator << (ostream&, QUERY_REF_ITEM&);
|
|
friend class QUERY;
|
|
)
|
|
|
|
|
|
|
|
/*++
|
|
|
|
Class Definition:
|
|
|
|
QUERY
|
|
|
|
Abstract:
|
|
|
|
Base class for a query into the object data base. It contains the
|
|
specification for the query and the resulting replay.
|
|
|
|
--*/
|
|
|
|
class QUERY {
|
|
|
|
protected:
|
|
QUERY_REF_LIST ReplyList; // List which gets the reply from the query.
|
|
ENTRY_KEY Entry; // The entry, that we are searching on.
|
|
TYPE_ENTRY_NODE Type; // Type of entry we are interested in.
|
|
long ExpirationTime; // Cut off point for cached entries.
|
|
long Scope; // Flags which limit query.
|
|
int RecursionCount; // Keeps track of the recursion in searchs.
|
|
|
|
public:
|
|
QUERY(
|
|
IN TYPE_ENTRY_NODE TypeNew,
|
|
IN ENTRY_KEY *KeyNew,
|
|
IN long ScopeNew,
|
|
OUT STATUS *Status
|
|
) :
|
|
Entry(KeyNew, Status)
|
|
{
|
|
Type = TypeNew;
|
|
ExpirationTime = maxCacheAge;
|
|
Scope = ScopeNew;
|
|
RecursionCount = 0;
|
|
}
|
|
|
|
~QUERY() {
|
|
Entry.Free();
|
|
}
|
|
|
|
ENTRY_BASE_ITEM *
|
|
NextReply(
|
|
);
|
|
|
|
QUERY_REF_ITEM *
|
|
First(
|
|
)
|
|
{
|
|
return(ReplyList.First());
|
|
}
|
|
|
|
void FreeReply(
|
|
IN QUERY_REF_ITEM * Item
|
|
)
|
|
{
|
|
Item->Free(ReplyList);
|
|
}
|
|
|
|
ACCESSOR(long, ExpirationTime);
|
|
|
|
STATUS
|
|
Search(
|
|
);
|
|
|
|
STATUS
|
|
SearchEntry(
|
|
IN ENTRY_SERVER_NODE * &ENTRY_SERVER
|
|
);
|
|
|
|
virtual STATUS
|
|
QueryNet(
|
|
);
|
|
|
|
STATUS BroadCast(
|
|
IN QueryPacket& NetRequest,
|
|
IN ENTRY_KEY &Entry
|
|
);
|
|
|
|
virtual STATUS
|
|
GetUpdatesFromMasterLocator(
|
|
);
|
|
|
|
|
|
char * DetectMasterLocator(
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
/*++
|
|
|
|
Class Definition:
|
|
|
|
QUERY_SERVER
|
|
|
|
Abstract:
|
|
|
|
Dervived class when searching only for a server entry object.
|
|
|
|
--*/
|
|
|
|
class QUERY_SERVER: public QUERY {
|
|
|
|
private:
|
|
|
|
// The following optional members are used to filter the search.
|
|
|
|
NS_SYNTAX_ID Interface; // Interface of interest.
|
|
NS_SYNTAX_ID TransferSyntax; // Stub transfer syntax of interest.
|
|
NS_UUID Object; // Object of interest
|
|
|
|
public:
|
|
|
|
QUERY_SERVER(
|
|
IN ENTRY_KEY *KeyNew,
|
|
IN NS_SYNTAX_ID *InterfaceNew,
|
|
IN NS_SYNTAX_ID * TransferSyntaxNew,
|
|
IN NS_UUID *ObjectNew,
|
|
IN long ScopeNew,
|
|
OUT STATUS *Status
|
|
) : QUERY (ServerEntryType, KeyNew, ScopeNew, Status)
|
|
{
|
|
|
|
Interface = *InterfaceNew;
|
|
TransferSyntax = *TransferSyntaxNew;
|
|
Object = *ObjectNew;
|
|
}
|
|
|
|
ACCESSOR(NS_UUID, Object);
|
|
|
|
virtual STATUS
|
|
QueryNet(
|
|
);
|
|
|
|
virtual STATUS
|
|
GetUpdatesFromMasterLocator(
|
|
);
|
|
|
|
|
|
friend class ENTRY_SERVER_ITEM;
|
|
};
|
|
|
|
|
|
|
|
/*++
|
|
|
|
Class Definition:
|
|
|
|
QUERY_GROUP
|
|
|
|
Abstract:
|
|
|
|
Dervived class when searching only for a group entry object.
|
|
|
|
|
|
--*/
|
|
class QUERY_GROUP: public QUERY {
|
|
|
|
private:
|
|
|
|
public:
|
|
|
|
QUERY_GROUP(
|
|
IN ENTRY_KEY *KeyNew,
|
|
IN long ScopeNew,
|
|
OUT STATUS *Status
|
|
) : QUERY (GroupEntryType, KeyNew, ScopeNew, Status)
|
|
{
|
|
|
|
}
|
|
|
|
virtual STATUS
|
|
QueryNet(
|
|
);
|
|
|
|
virtual STATUS
|
|
GetUpdatesFromMasterLocator(
|
|
);
|
|
|
|
|
|
friend class ENTRY_GROUP_ITEM;
|
|
};
|
|
|
|
|
|
|
|
/*++
|
|
|
|
Class Definition:
|
|
|
|
ENTRY_BASE_ITEM
|
|
|
|
Abstract:
|
|
|
|
Each type of entry object has a linked list of these objects. These items
|
|
make up the member objects that belong to the entry. This is the
|
|
base class for all member objects of a EntryNode (see next class).
|
|
|
|
--*/
|
|
|
|
NEW_LINK_LIST(ENTRY_BASE,
|
|
|
|
protected:
|
|
|
|
TYPE_ENTRY_ITEM Type; /* type of list item */
|
|
ENTRY_BASE_NODE *EntryNode; /* reference to which node I'm in */
|
|
ULONG Time; /* time arrived for cached PS */
|
|
ULONG UseCount; /* number of references to object */
|
|
|
|
public:
|
|
ENTRY_BASE_ITEM(
|
|
IN TYPE_ENTRY_ITEM TypeNew
|
|
)
|
|
{
|
|
Type = TypeNew;
|
|
Time = CurrentTime();
|
|
EntryNode = NIL;
|
|
UseCount = 1;
|
|
}
|
|
|
|
ACCESSOR(ENTRY_BASE_NODE *, EntryNode)
|
|
|
|
// See if a this object is a queried type.
|
|
|
|
BOOL
|
|
IsType(
|
|
IN TYPE_ENTRY_ITEM qType
|
|
)
|
|
{
|
|
return(qType == Type);
|
|
}
|
|
|
|
// Determine if a cached entry is stale and should be discarded.
|
|
|
|
BOOL
|
|
IsStaleEntry(
|
|
IN long Age
|
|
)
|
|
{
|
|
return(Type == CacheItemType && CurrentTime() > Time+Age);
|
|
}
|
|
|
|
// Threads must Reserve and Release an node item to use it.
|
|
|
|
void
|
|
MultiThreadReserve(
|
|
)
|
|
{
|
|
UseCount++;
|
|
}
|
|
|
|
void
|
|
MultiThreadRelease(
|
|
)
|
|
{
|
|
UseCount--;
|
|
if (Type == DeleteItemType && UseCount == 0)
|
|
delete this;
|
|
}
|
|
|
|
|
|
virtual
|
|
~ENTRY_BASE_ITEM(
|
|
);
|
|
|
|
virtual MATCH_RETURN
|
|
MatchItem(
|
|
IN QUERY *SearchSpec
|
|
);
|
|
|
|
virtual int
|
|
Marshall(
|
|
OUT PB Buffer,
|
|
IN OUT long UNALIGNED *cbBuffer
|
|
);
|
|
|
|
virtual ostream&
|
|
Format(
|
|
IN OUT ostream&
|
|
);
|
|
|
|
friend ostream& operator << (ostream&, ENTRY_BASE_ITEM&);
|
|
)
|
|
|
|
|
|
|
|
/*++
|
|
|
|
Class Definition:
|
|
|
|
ENTRY_BASE_NODE
|
|
|
|
Abstract:
|
|
|
|
This is the base class for all entry objects. It contains the name
|
|
of the entry and the type. All ENTRY_BASE_ITEM are belong to one
|
|
of this objects. This object is the one keep in the dictionary
|
|
for fast access.
|
|
|
|
--*/
|
|
|
|
class ENTRY_BASE_NODE {
|
|
|
|
protected:
|
|
ENTRY_KEY Entry; // The entry name, must be first member.
|
|
TYPE_ENTRY_NODE Type; // Type of entry object.
|
|
ENTRY_BASE_LIST ItemList; // List of member objects of this node.
|
|
|
|
public:
|
|
|
|
unsigned long LastUpdateTime;
|
|
|
|
ENTRY_BASE_NODE(
|
|
IN TYPE_ENTRY_NODE TypeNew,
|
|
IN ENTRY_KEY *KeyNew,
|
|
OUT STATUS *Status
|
|
):
|
|
Entry (KeyNew, Status)
|
|
{
|
|
Type = TypeNew;
|
|
LastUpdateTime = 0;
|
|
}
|
|
|
|
ACCESSOR(ENTRY_KEY, Entry)
|
|
ACCESSOR(ENTRY_BASE_LIST, ItemList)
|
|
|
|
// See if a this object is a queried type.
|
|
|
|
BOOL
|
|
IsType(
|
|
IN TYPE_ENTRY_NODE qType
|
|
)
|
|
{
|
|
return(qType == Type);
|
|
}
|
|
|
|
virtual void DeleteAllObjects()
|
|
{
|
|
//do nothing - just keep compiler happy
|
|
}
|
|
friend int ENTRY_BASE_NODECompare(ENTRY_KEY &E1, ENTRY_BASE_NODE &E2);
|
|
friend ENTRY_KEY& ENTRY_BASE_NODEMyKey(ENTRY_BASE_NODE &E1);
|
|
friend ostream& operator << (ostream&, ENTRY_BASE_NODE&);
|
|
};
|
|
|
|
|
|
|
|
/*++
|
|
|
|
Class Definition:
|
|
|
|
ENTRY_SERVER_NODE
|
|
|
|
Abstract:
|
|
|
|
The is a server entry node. This class addes the object vector
|
|
which all members of a server entry share.
|
|
|
|
--*/
|
|
|
|
class ENTRY_SERVER_NODE:public ENTRY_BASE_NODE {
|
|
|
|
private:
|
|
UUID_ARRAY ObjectDA; // Commaon object vector.
|
|
|
|
public:
|
|
ENTRY_SERVER_NODE(
|
|
IN ENTRY_KEY *KeyNew,
|
|
OUT STATUS *Status
|
|
): ENTRY_BASE_NODE (ServerEntryType, KeyNew, Status)
|
|
{
|
|
|
|
}
|
|
|
|
ACCESSOR(UUID_ARRAY, ObjectDA)
|
|
|
|
STATUS
|
|
MergeObjects(
|
|
IN UUID_ARRAY *NewObject
|
|
);
|
|
|
|
int
|
|
DeleteObject(
|
|
IN NS_UUID *Objects
|
|
);
|
|
|
|
virtual void DeleteAllObjects(
|
|
);
|
|
|
|
int
|
|
SearchObject(
|
|
IN NS_UUID *Object
|
|
);
|
|
|
|
ENTRY_SERVER_ITEM *
|
|
First(
|
|
)
|
|
{
|
|
return((ENTRY_SERVER_ITEM * ) TheItemList().First());
|
|
}
|
|
|
|
friend ostream& operator << (ostream&, ENTRY_SERVER_NODE&);
|
|
friend class ENTRY_SERVER_ITEM;
|
|
};
|
|
|
|
|
|
|
|
/*++
|
|
|
|
Class Definition:
|
|
|
|
ENTRY_SERVER_ITEM
|
|
|
|
Abstract:
|
|
|
|
This instance of a sever entry member object. It adds members which
|
|
describe the interface the the binding.
|
|
|
|
--*/
|
|
|
|
class ENTRY_SERVER_ITEM: public ENTRY_BASE_ITEM {
|
|
|
|
private:
|
|
|
|
NS_SYNTAX_ID Interface; // The interface of the member.
|
|
NS_SYNTAX_ID TransferSyntax; // The stub transfer syntax of the member.
|
|
UNICODE_ARRAY StringBinding; // DCE string binding.
|
|
|
|
public:
|
|
|
|
ASSERT_CLASS;
|
|
|
|
ENTRY_SERVER_ITEM (
|
|
IN TYPE_ENTRY_ITEM TypeNew,
|
|
IN NS_SYNTAX_ID *InterfaceNew,
|
|
IN NS_SYNTAX_ID * Transfer,
|
|
IN PUZ StringBinding,
|
|
OUT STATUS *Status);
|
|
|
|
virtual
|
|
~ENTRY_SERVER_ITEM(
|
|
);
|
|
|
|
int
|
|
Compare(
|
|
IN ENTRY_SERVER_ITEM * ServerItem
|
|
);
|
|
|
|
// Memeber access/update functions
|
|
|
|
NS_UUID &
|
|
TheInterfaceGID(
|
|
)
|
|
{
|
|
return(Interface.ThesyntaxGID());
|
|
}
|
|
ENTRY_KEY &
|
|
TheEntry(
|
|
)
|
|
{
|
|
return(EntryNode->TheEntry());
|
|
}
|
|
UUID_ARRAY &
|
|
TheObjectDA(
|
|
)
|
|
{
|
|
return(((ENTRY_SERVER_NODE *)EntryNode)->TheObjectDA());
|
|
}
|
|
|
|
ACCESSOR(NS_SYNTAX_ID, Interface);
|
|
ACCESSOR(NS_SYNTAX_ID, TransferSyntax);
|
|
ACCESSOR(UNICODE_ARRAY, StringBinding);
|
|
|
|
virtual MATCH_RETURN
|
|
MatchItem(
|
|
IN QUERY *SearchSpec
|
|
);
|
|
|
|
virtual int
|
|
Marshall(
|
|
OUT PB Buffer,
|
|
IN OUT long UNALIGNED *cbBuffer
|
|
);
|
|
|
|
virtual ostream&
|
|
Format(
|
|
ostream&
|
|
);
|
|
|
|
ENTRY_SERVER_ITEM *
|
|
Next(
|
|
)
|
|
{
|
|
return((ENTRY_SERVER_ITEM * ) ENTRY_BASE_ITEM::Next());
|
|
}
|
|
|
|
friend ostream& operator << (ostream&, QUERY_REF_ITEM&);
|
|
friend ostream& operator << (ostream&, ENTRY_SERVER_ITEM&);
|
|
};
|
|
|
|
STATUS
|
|
InsertServerEntry(
|
|
IN ENTRY_KEY *Entry,
|
|
IN ENTRY_SERVER_ITEM *ServerItem,
|
|
IN UUID_ARRAY * ObjectDA
|
|
);
|
|
|
|
|
|
/*++
|
|
|
|
Class Definition:
|
|
|
|
ENTRY_GROUP_NODE
|
|
|
|
Abstract:
|
|
|
|
This is a group entry node. No additional data members are added.
|
|
|
|
--*/
|
|
|
|
class ENTRY_GROUP_NODE:public ENTRY_BASE_NODE {
|
|
|
|
private:
|
|
|
|
public:
|
|
ENTRY_GROUP_NODE(
|
|
IN ENTRY_KEY *KeyNew,
|
|
OUT STATUS *Status
|
|
): ENTRY_BASE_NODE (GroupEntryType, KeyNew, Status)
|
|
|
|
{
|
|
|
|
|
|
}
|
|
|
|
ENTRY_GROUP_ITEM *
|
|
First(
|
|
)
|
|
{
|
|
return((ENTRY_GROUP_ITEM * ) TheItemList().First());
|
|
}
|
|
|
|
friend ostream& operator << (ostream&, ENTRY_GROUP_NODE&);
|
|
friend class EnteryGroupItem;
|
|
};
|
|
|
|
/*++
|
|
|
|
Class Definition:
|
|
|
|
ENTRY_GROUP_ITEM
|
|
|
|
Abstract:
|
|
|
|
This is a group entry member item. Group are simply a list of entry
|
|
names that reference other entry objects. The links are symbolic
|
|
references, not pointer values.
|
|
|
|
--*/
|
|
|
|
class ENTRY_GROUP_ITEM: public ENTRY_BASE_ITEM {
|
|
|
|
private:
|
|
|
|
UNICODE_ARRAY Member; // Entry Name of the member.
|
|
|
|
public:
|
|
|
|
ASSERT_CLASS;
|
|
|
|
ENTRY_GROUP_ITEM (
|
|
IN TYPE_ENTRY_ITEM TypeNew,
|
|
IN PUZ MemberBinding,
|
|
OUT STATUS *Status
|
|
);
|
|
|
|
virtual ~ENTRY_GROUP_ITEM(
|
|
);
|
|
|
|
// Compare this item with an other group member.
|
|
|
|
int
|
|
Compare (
|
|
IN ENTRY_GROUP_ITEM * GroupItem
|
|
)
|
|
{
|
|
return (CmpUZ(Member.pCur(), GroupItem->Member.pCur()));
|
|
}
|
|
|
|
// Compare this item with a unicode string for identity.
|
|
|
|
int
|
|
Compare (
|
|
IN PUZ Name
|
|
)
|
|
{
|
|
return (CmpUZ(Member.pCur(), Name));
|
|
}
|
|
|
|
ACCESSOR(UNICODE_ARRAY, Member);
|
|
|
|
virtual MATCH_RETURN
|
|
MatchItem(
|
|
IN OUT QUERY *SearchSpec
|
|
);
|
|
|
|
virtual int
|
|
Marshall(
|
|
OUT PB Buffer,
|
|
IN OUT long UNALIGNED *cbBuffer
|
|
);
|
|
|
|
virtual ostream&
|
|
Format(
|
|
IN OUT ostream&
|
|
);
|
|
|
|
ENTRY_GROUP_ITEM *
|
|
Next(
|
|
)
|
|
{
|
|
return((ENTRY_GROUP_ITEM * ) ENTRY_BASE_ITEM::Next());
|
|
}
|
|
|
|
friend ostream& operator << (ostream&, ENTRY_GROUP_ITEM&);
|
|
};
|
|
|
|
STATUS
|
|
InsertGroupEntry(
|
|
IN ENTRY_KEY *Entry,
|
|
IN ENTRY_GROUP_ITEM *GroupItem
|
|
);
|
|
|
|
|
|
|
|
/*++
|
|
|
|
Class Definition:
|
|
|
|
REPLY_BASE_ITEM
|
|
|
|
Abstract:
|
|
|
|
All replies are kept in a LinkList. There is a base reply type
|
|
which is used to derive several different kinds of replies in progress.
|
|
Each derived REPLY_BASE must implement the virtual functions Free and Discard.
|
|
|
|
--*/
|
|
|
|
/* State of the Query in a lookup operation. */
|
|
|
|
typedef enum {
|
|
InitialQuery, /* First query has been made */
|
|
FinialQuery, /* Finial query made, no more allowed */
|
|
ReRunQuery /* Rerun the query */
|
|
}REPLY_STATE;
|
|
|
|
NEW_LINK_LIST(REPLY_BASE,
|
|
|
|
protected:
|
|
|
|
long pidOwner; /* owner of the resource */
|
|
QUERY * aQuery; /* QUERY for lookup */
|
|
REPLY_STATE QueryMade; /* QUERY has been made */
|
|
|
|
public:
|
|
REPLY_BASE_ITEM();
|
|
~REPLY_BASE_ITEM();
|
|
|
|
BOOL
|
|
AssertHandle(
|
|
);
|
|
|
|
/* Set the cache discard age for a query. */
|
|
|
|
void SetExpiration(
|
|
IN unsigned long Time
|
|
)
|
|
{
|
|
aQuery->TheExpirationTime() = Time;
|
|
|
|
/* If the "Next" operation hasn't been called, rerun the query. */
|
|
|
|
if (QueryMade == InitialQuery) {
|
|
FreeQueryResult();
|
|
QueryMade = ReRunQuery;
|
|
}
|
|
}
|
|
|
|
|
|
/* Get the next item in the query reply. */
|
|
|
|
ENTRY_BASE_ITEM *
|
|
NextBaseItem(
|
|
)
|
|
{
|
|
return(aQuery->NextReply());
|
|
}
|
|
|
|
STATUS
|
|
PerformQueryIfNeeded(
|
|
BOOL fFirstTime
|
|
);
|
|
|
|
void
|
|
FreeQueryResult(
|
|
);
|
|
|
|
virtual BOOL
|
|
Discard(
|
|
IN ENTRY_BASE_ITEM *BaseItem
|
|
);
|
|
|
|
virtual BOOL
|
|
UpdateObject(
|
|
IN ENTRY_SERVER_NODE *Entry,
|
|
IN int Index
|
|
);
|
|
)
|
|
|
|
extern REPLY_BASE_LIST RPRoot; // Global list of replies from this root.
|
|
|
|
inline
|
|
REPLY_BASE_ITEM::REPLY_BASE_ITEM(
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Construct a base REPLY_BASE_ITEM object. Link this object into the
|
|
global list of replies.
|
|
|
|
--*/
|
|
|
|
{
|
|
QueryMade = InitialQuery;
|
|
aQuery = NIL;
|
|
pidOwner = (long) this;
|
|
RPRoot.Append(this);
|
|
}
|
|
|
|
|
|
/*++
|
|
|
|
Class Definition:
|
|
|
|
REPLY_SERVER_ITEM
|
|
|
|
Abstract:
|
|
|
|
This a reply object for a server entry based query. It contains
|
|
additional state to interate through the replies formain the
|
|
cross product of the reply list and object vector.
|
|
|
|
--*/
|
|
|
|
NEW_LINK_LIST_CLASS(REPLY_SERVER, REPLY_BASE,
|
|
|
|
private:
|
|
unsigned int VectorSize; /* Vector size to return */
|
|
unsigned int fAllObjects; /* Include all objects in response */
|
|
UUID_ARRAY_ITER ObjectCur; /* Iterator for current object */
|
|
|
|
public:
|
|
REPLY_SERVER_ITEM(
|
|
IN QUERY_SERVER * aQueryNew,
|
|
IN BOOL fAllObjectsNew = FALSE,
|
|
IN int VectorSizeNew = 0
|
|
)
|
|
{
|
|
aQuery = aQueryNew; /* BUGBUG glock c++: base should require this */
|
|
VectorSize = VectorSizeNew;
|
|
fAllObjects = fAllObjectsNew;
|
|
}
|
|
|
|
STATUS
|
|
PerformQueryIfNeeded(
|
|
BOOL fFirstTime
|
|
);
|
|
|
|
ENTRY_SERVER_ITEM *
|
|
NextBindingAndObject(
|
|
OUT NS_UUID ** Object
|
|
);
|
|
|
|
BOOL
|
|
NextObject(
|
|
OUT NS_UUID ** Object
|
|
)
|
|
{
|
|
return((!ObjectCur)? FALSE:
|
|
(*Object = &*ObjectCur, ++ObjectCur, TRUE));
|
|
}
|
|
|
|
ACCESSOR(unsigned int, VectorSize);
|
|
|
|
virtual BOOL
|
|
Discard(
|
|
IN ENTRY_BASE_ITEM *BaseItem
|
|
);
|
|
|
|
virtual BOOL
|
|
UpdateObject(
|
|
IN ENTRY_SERVER_NODE *Entry,
|
|
IN int Index
|
|
);
|
|
)
|
|
|
|
|
|
|
|
/*++
|
|
|
|
Class Definition:
|
|
|
|
REPLY_GROUP_ITEM
|
|
|
|
Abstract:
|
|
|
|
This a reply object for a group entry based query. Only group
|
|
items will be in the reply list.
|
|
|
|
--*/
|
|
|
|
NEW_LINK_LIST_CLASS(REPLY_GROUP, REPLY_BASE,
|
|
|
|
public:
|
|
REPLY_GROUP_ITEM(
|
|
IN QUERY_GROUP * aQueryNew
|
|
)
|
|
{
|
|
aQuery = aQueryNew; /* BUGBUG glock c++: base should require this */
|
|
}
|
|
|
|
)
|
|
|
|
#endif // _PROTOCOL_
|