|
|
// nntpdrv.idl : IDL source for nntpdrv.dll //
// This file will be processed by the MIDL tool to // produce the type library (nntpdrv.tlb) and marshalling code.
import "oaidl.idl"; import "ocidl.idl";
// // -------------- Interfaces implemented by the Server -------------- //
interface INntpServer; interface INNTPPropertyBag; interface INewsTreeIterator; interface INewsTree; interface INntpComplete; interface INntpDriver; interface INntpDriverSearch; interface INntpSearchResults;
// // Server access request bits // cpp_quote("#define NNTP_ACCESS_READ 0x0001") cpp_quote("#define NNTP_ACCESS_POST 0x0002") cpp_quote("#define NNTP_ACCESS_CREATE_SUBFOLDER 0x0004") cpp_quote("#define NNTP_ACCESS_REMOVE_SUBFOLDER 0x0008") cpp_quote("#define NNTP_ACCESS_REMOVE_FOLDER 0x0010") cpp_quote("#define NNTP_ACCESS_REMOVE 0x0020") cpp_quote("#define NNTP_ACCESS_EDIT_FOLDER 0x0040") cpp_quote("#define NNTP_ACCESS_EDIT 0x0080")
// // Connect flag bits // cpp_quote("#define NNTP_CONNECT_UPGRADE 0x0001")
// // Server mode, driver can inquire about server mode to determine' // what he should do during DecorateNewsTree // cpp_quote("#define NNTP_SERVER_NORMAL 0x0001") cpp_quote("#define NNTP_SERVER_STANDARD_REBUILD 0x0002") cpp_quote("#define NNTP_SERVER_CLEAN_REBUILD 0x0003")
typedef struct { BYTE cLen; BYTE pbStoreId[256]; } STOREID;
typedef DWORD GROUPID;
// // This interface exposes server functionality // [ object, uuid(c7bae7b4-dee3-11d1-94cf-00c04fa379f1), helpstring("INntpDriver Interface"), ] interface INntpServer : IUnknown {
// // find the primary groupid/articleid for an article given the secondary // groupid/articleid // // arguments: // pgroupSecondary - the property bag for the secondary crosspost // artidSecondary - the article ID for the secondary crosspost // ppgroupPrimary - gets filled in with the property bag for the primary // crosspost. the caller should Release() this when // they are done with it. // fStorePrimary - if TRUE then return the primary article for the store // that owns pgroupSecondary // partidPrimary - the article id for the primary crosspost // // returns (through completion object): // S_OK - found primary // S_FALSE - the values given were the primary // or an error code // [local] void FindPrimaryArticle([in] INNTPPropertyBag *pGroupSecondary, [in] DWORD artidSecondary, [out] INNTPPropertyBag **ppgroupPrimary, [out] DWORD *partidPrimary, [in] BOOL fStorePrimary, [in] INntpComplete *pCompletion, [in] INntpComplete *pProtocolComplete );
// // Create the entries in the hash tables for a new article. // [local] void CreatePostEntries([in] CHAR *pszMessageId, [in] DWORD iHeaderLength, [in] STOREID *pStoreId, [in] BYTE cGroups, [in] INNTPPropertyBag **rgpGroups, [in,out] DWORD *rgArticleIds, [in] BOOL fAllocArtId, [in] INntpComplete *pCompletion);
// // Create the entries in the hash tables for a new article. // [local] void DeleteArticle([in] CHAR *pszMessageId, [in] INntpComplete *pCompletion);
// // This tells the driver what rebuild mode the server is in // The returned value should be NNTP_SERVER_NORMAL, NNTP_SERVER // _STANDARD_REBUILD or NNTP_SERVER_CLEAN_REBUILD // [local] DWORD QueryServerMode();
// // Tells whether should skip empty dir when rebuild // [local] BOOL SkipNonLeafDirWhenRebuild();
// // Should I continue the rebuild ? Anybody has cancelled the rebuild ? // [local] BOOL ShouldContinueRebuild();
// // Is this message id in the server ( article table ) ? // [local] BOOL MessageIdExist( CHAR *szMessageId );
// // Set rebuild last error // [local] void SetRebuildLastError( DWORD err );
// // Obtain article number for each newsgroups. // [local] void AllocArticleNumber([in] BYTE cGroups, [in] INNTPPropertyBag **rgpGroups, [in,out] DWORD *rgArticleIds, [in] INntpComplete *pCompletion);
// // Return whether this is a Slave server, and the pickup dir // [local] BOOL IsSlaveServer( [out] WCHAR* pwszPickupDir, [out] LPVOID lpvContext);
};
// // this property bag is used to represent data in the newsgroups // [ object, uuid(f5ad0d78-af9f-11d1-862e-00c04fb960ea) ] interface INNTPPropertyBag : IUnknown { // // put a BLOB property into the table. this is also used for string // properties // [local] HRESULT PutBLOB( [in] DWORD dwID, [in] DWORD cbValue, [in,size_is(cbValue)] BYTE *pbValue);
// // get a BLOB property from the table. this is also used for string // properties // [local] HRESULT GetBLOB( [in] DWORD dwID, [in] BYTE *pbValue, [in,out] DWORD *pcbValue);
// // put a dword property into the table // [local] HRESULT PutDWord( [in] DWORD dwID, [in] DWORD dwValue);
// // get a dword property from the table // [local] HRESULT GetDWord( [in] DWORD dwID, [out] DWORD *pdwValue);
// // put an interface pointer into the table // // interfaces can only be used with properties that are runtime only. // [local] HRESULT PutInterface( [in] DWORD dwID, [in] IUnknown *punkValue);
// // get an interface pointer from the table // [local] HRESULT GetInterface( [in] DWORD dwID, [out] IUnknown **ppunkValue);
// // put a bool to the table // [local] HRESULT PutBool( DWORD dwID, BOOL fValue );
// // get a bool from the table // HRESULT GetBool( DWORD dwID, BOOL *pfValue);
// // remove a property from the property bag // [local] HRESULT RemoveProperty( [in] DWORD dwID); };
[ object, uuid(53f10148-afa8-11d1-862e-00c04fb960ea) ] interface INewsTreeIterator : IUnknown { // // are we at the front or back of the list? returns S_OK if we are // at the beginning or end, and S_FALSE otherwise. // [local] BOOL IsBegin(); [local] BOOL IsEnd();
// // go to the next or previousgroup // [local] void Next(); [local] void Prev();
// // get this group // [local] HRESULT Current( [out] INNTPPropertyBag **ppGroup, INntpComplete *pProtocolComplete ); };
[ object, uuid(9d2de8dc-afc4-11d1-862e-00c04fb960ea) ] interface INewsTree : IUnknown { // // given a group ID find the matching group // [local] HRESULT FindGroupByID( [in] DWORD dwGroupID, [out] INNTPPropertyBag **ppNewsgroupProps, [in] INntpComplete *pProtocolComplete );
// // given a group name find the matching group. if the group doesn't // exist and fCreateIfNotExist is set then a new group will be created. // the new group won't be available until CommitGroup() is called. // if the group is Release'd before CommitGroup was called then it // won't be added. // [local] HRESULT FindOrCreateGroupByName( [in] LPSTR pszGroupName, [in] BOOL fCreateIfNotExist, [out] INNTPPropertyBag **ppNewsgroupProps, [in] INntpComplete *pProtocolComplete, [in] GROUPID groupid, [in] BOOL fSetGroupId );
// // add a new group to the newstree // [local] HRESULT CommitGroup( [in] INNTPPropertyBag *pNewsgroupProps );
// // remove an entry // [local] HRESULT RemoveGroupByID( [in] DWORD dwGroupID); [local] HRESULT RemoveGroupByName( [in] LPSTR pszGroupName, [in] LPVOID lpContext);
// // enumerate across the list of keys. // [local] HRESULT GetIterator( [out] INewsTreeIterator **punkIterator // BUGBUG -- need to add filtering options );
// // this function will be used by drivers to make sure that they // are adding newsgroups that they properly own. // HRESULT LookupVRoot([in] LPSTR pszGroup, [out] INntpDriver **ppDriver);
// // Get a pointer to the owning server object // [local] HRESULT GetNntpServer( [out] INntpServer **ppNntpServer ); };
// // IIS side completion object interface // [ object, uuid(5EFC52FC-EADF-11d1-9212-00C04FA322A5), helpstring("INntpComplete Interface"), ] interface INntpComplete : IUnknown { // This is the base interface for all IIS side completion // objects. The base interface has only one interface // method: SetResult. This method may be overwritten by // derived class methods to carry out different implementation // for different completions. [local] void SetResult( [in] HRESULT hr );
[local] void ReleaseBag( INNTPPropertyBag *pPropBag ); };
// // -------------- Interfaces implemented by the Driver -------------- //
// // Driver implementaion interface that implements actual // driver functionality. // Returned by INntpDriverPrepare after successfully connected // to Exchange store. // [ object, uuid(ADD1050F-99C5-11D1-9128-00C04FC30A64), helpstring("INntpDriver Interface"), ] interface INntpDriver : IUnknown { typedef DWORD ARTICLEID;
/////////////////////////////////////////////////////////////////////////// // ***** initialize, terminate, config methods: ///////////////////////////////////////////////////////////////////////////
// Purpose: // Initialize the driver // Parameters: // pszVRootPath - virtual root path this driver interface maps to // ie. Nntpsvc/1/root/alt // pLookup - a pointer to the server's ILookup interface // pNewsTree - a pointer to the server's INewsTree interface // pdwNDS - Return status of current NNTP driver after Initialize() // Comments: // o Register change notification (ie directory pickup) // o Initialize Epoxy (once per Exchange store type) // o Detect if the other side of NNTP DLL is running (Exchange only) // o Initialize other global objects/interfaces (such as IMAIL, Async lib, etc) // o strVRootPath to obtain directory path (FS) or store name (Exchange) from VRoot // o Ilookup and InewsTree services are for notification operations on the store // as well as expiration. // o From metabase retrieve expiration policy // o Setup expiration // o WHAT OTHER PARAMETERS NEEDED/TASKS PERFORMED HERE - POSSIBLY: // o May setup metabase change notification to pickup expiration policy changes [local] HRESULT Initialize( [in] LPCWSTR pszVRootPath, [in] LPCSTR pszGroupPrefix, [in] IUnknown *punkMetabase, [in] INntpServer *pServer, [in] INewsTree *pINewsTree, [in] LPVOID lpvContext, [out] DWORD *pdwNDS, [in] HANDLE hToken );
// Purpose: // Detach the driver from protocol and cleanup // Parameters: // None // Comments: // o Un-register change notification. // o Un-initialize Epoxy, if last driver interface pointer to Terminate() // o Terminate expiration // o Other tasks? HRESULT Terminate( [out] DWORD *pdwNDS );
// Purpose: // Get the status of current NNTP driver // Parameters: // pdwNDS - NNTP_DRIVER_STATUS code // Comments: // o Used to get status of current NNTP driver, include: // STORE_UP, STORE_DOWN, EPOXY_ERROR, etc HRESULT GetDriverStatus( [out] DWORD *pdwNDS );
/////////////////////////////////////////////////////////////////////////// // ***** store change notification process method ///////////////////////////////////////////////////////////////////////////
// Purpose: // Handle change notification from the store // Parameters: // punkSOCChangeList - List of changes originated from store // Comment // o Serve as change notification process function dispatcher // o Owns a list of changes coming from the store HRESULT StoreChangeNotify( [in] IUnknown *punkSOCChangeList );
/////////////////////////////////////////////////////////////////////////// // ***** article posting methods: ///////////////////////////////////////////////////////////////////////////
// Purpose: // Commit the post // Parameters: // See separate spec from awetmore // Returned error code from completion object: // S_OK - Success // HRESULT_FROM_WIN32( ERROR_FILE_NOT_FOUND ) - Group Access Check Failed because file ( directory ) doesn't exist // HRESULT_FROM_WIN32( ERROR_PATH_NOT_FOUND ) - Group doesn't physically exist ( during CreateFile ) // HRESULT_FROM_WIN32( ERROR_FILE_EXISTS) - The article with the same article id physically exists ( during CreateFile ) // HRESULT_FROM_WIN32( ERROR_ACCESS_DENIED ) - Access Denied // Other - Other fatal errors that might cause UnsafeClose(); // Note: // This also applies to AllocMessage. Since we have no access to IMailMsg // IDL file, it's doc'd here [local] void CommitPost( [in] IUnknown *punkMessage, // IMsg pointer [in] STOREID *pStoreId, [in] STOREID *rgOtherStoreIDs, [in] HANDLE hToken, [in] INntpComplete *pICompletion, [in] BOOL fAnonymous );
/////////////////////////////////////////////////////////////////////////// // ***** article retrieval, delete methods (ARTICLE, BODY, HEAD, etc): ///////////////////////////////////////////////////////////////////////////
// Purpose: // Gets an article from the store // Parameters: // pNewsGroup - The INewsGroup where article is posted to // artId - Article ID for this article // StoreId - STOREID for this article // It contains FID/MID for Exchange store, but nothing for FS. // hFile - File handle for the article // Comment: // o FS uses pNewsGroup and artId to retrieve articles, no need for StoreId // o Exchange needs StoreId to give a pair of FID/MID // o If no FID/MID is found, get group properties from pNewsGroup and try // to retrieve article by article number. // o Return an hFile - NEED TO COMEUP WITH AN ASYNC MODEL. // Return value from completion object: // o S_OK - Succeeded // o HRESULT_FROM_WIN32( ERROR_FILE_NOT_FOUND ) - Article doesn't exist // o HRESULT_FROM_WIN32( ERROR_PATH_NOT_FOUND ) - Group doesn't exist // o E_ACCESSDENIED - Access denied // o OTHER: Fatal server error [local] void GetArticle( [in] INNTPPropertyBag *pPrimaryGroup, [in] INNTPPropertyBag *pCurrentGroup, [in] ARTICLEID PrimaryArtId, [in] ARTICLEID CurrentArtId, [in] STOREID StoreId, [in] HANDLE hToken, [out] void **pvFileHandleContext, [in] INntpComplete *pICompletion, [in] BOOL fAnonymous ); // Purpose: // This is called when the protocol needs to cancel an article // Parameters: // pGroupBag - Group property bag // cArticles - Number of articles to delete // rgidArt - Array of article id's to delete ( used by exdriver ) // rgidStore - Array of store id's to delete ( used by fsdriver ) // hToken - Client's access token // piFailed - To return the index into article array of the first // failed article // pICompletion - Completion object // Return value in completion object: // S_OK - Succeeded // S_FASLE - Succeeded but protocol has asked to delete too many // but the driver can not take them all, see pdwLastSuccess // for the last successfully deleted article // NNTP_E_PARTIAL_COMPLETE - No error, but not all messages are deleted // deletion partly failed in store // Otherwise, Failed [local] void DeleteArticle( [in] INNTPPropertyBag *pGroupBag, [in] DWORD cArticles, [in] ARTICLEID rgidArt[], [in] STOREID rgidStore[], [in] HANDLE hToken, [out] DWORD *pdwLastSuccess, [in] INntpComplete *pICompletion, [in] BOOL fAnonymous );
/////////////////////////////////////////////////////////////////////////// // ***** XOVER, XHDR retrieval methods: ///////////////////////////////////////////////////////////////////////////
// Purpose: // Gets the XOVER information for a range of articles // Parameters: // pNewsGroup - The NewsGroup object to get XOVER data from // idMinArticle - the first article to get information for // idMaxArticle - the last article to get information for // idNextArticle - The next article id that you should start from, if you // want // pszHeader - contains a string of header to be retrieved. // ie. "Subject", "From", For Xover, may use "@Xover", where // any string started with "@" is special. // pBuffer - where to put the information (ISSUE: what type is this? // stream or char *) // cbin - size of pBuffer // cbout - total count bytes of returned XOVER data // Return value from completion object: // S_OK - Succeeded perfectly // S_FALSE - Succeeded, but: // 1. If *idNextArticle > idMaxArticle - no article found // 2. If *idNextArticle <= idMaxArticle - Buffer too small, // though some entries have been filled // HRESULT_FROM_WIN32( ERROR_INSUFFICIENT_BUFFER ) // - Buffer too small, even first article can not be filled // Other - Other fatal error [local] void GetXover( [in] INNTPPropertyBag *pGroupPropBag, [in] ARTICLEID idMinArticle, [in] ARTICLEID idMaxArticle, [out] ARTICLEID *idNextArticle, [out] CHAR* pBuffer, [in] DWORD cbin, [out] DWORD *cbout, [in] HANDLE hToken, [in] INntpComplete *pICompletion, [in] BOOL fAnonymous );
[local] HRESULT GetXoverCacheDirectory( [in] INNTPPropertyBag* pGroupPropBag, [out] CHAR* pBuffer, [in] DWORD cbIn, [out] DWORD *pcbOut, [out] BOOL* fFlatDir ) ; // Get XHdr information from the driver - similar to GetXover [local] void GetXhdr( [in] INNTPPropertyBag *pGroupPropBag, [in] ARTICLEID idMinArticle, [in] ARTICLEID idMaxArticle, [out] ARTICLEID *idNextArticle, [in] CHAR* pszHeader, [out] CHAR* pBuffer, [in] DWORD cbin, [out] DWORD *cbOut, [in] HANDLE hToken, [in] INntpComplete *pICompletion, [in] BOOL fAnonymous );
/////////////////////////////////////////////////////////////////////////// // ***** Store rebuild related methods: ///////////////////////////////////////////////////////////////////////////
// Purpose: // Rebuild a news group: pick up every message, parse out its groups/ // articleid's and use INntpServer's post interface to insert xover/ // article entries. It updates group properties such as article counts, // high/low watermarks too [local] void RebuildGroup( [in] INNTPPropertyBag *pPropBag, [in] HANDLE hToken, [in] INntpComplete *pIComplete );
/////////////////////////////////////////////////////////////////////////// // ***** Newsgroup manipulation methods: ///////////////////////////////////////////////////////////////////////////
// Purpose: // Get properties from a group. // Parameters: // pNewsGroup - Property bag for the news group object // cProperties - Number of properties to get // rgidProperties - Array of properties to get [local] void DecorateNewsGroupObject( [in] INNTPPropertyBag *pNewsGroup, [in] DWORD cProperties, [in] DWORD *rgidProperties, [in] INntpComplete *pICompletion );
// Purpose: // Check if client has desired access to this group // Parameters: // pNewsGroup - Property bag to the news group // hToken - The client's access token // dwDesiredAccess - Access rights that the client desires // pICompletion - Pointer to completion object // Return value from completion object: // S_OK - Client has access // E_ACCESSDENIED - Access denied [local] void CheckGroupAccess( [in] INNTPPropertyBag *pNewsGroup, [in] HANDLE hToken, [in] DWORD dwDesiredAccess, [in] INntpComplete *pICompletion );
// Purpose: // Set Newsgroup properties into store // Parameters: // pNewsGroup - The news group property bag // cProperties - Number of properties to set // rgidProperties - Array of properties to set // pICompletion - Completion object // Return values: [local] void SetGroupProperties( [in] INNTPPropertyBag *pNewsGroup, [in] DWORD cProperties, [in] DWORD *rgidProperties, [in] HANDLE hToken, [in] INntpComplete *pICompletion, [in] BOOL fAnonymous );
// Purpose: // Decorate entire INewsTree object by going to the store and get // all the necessary properties. // Parameters: // punkNewsTree - INewsTree to be decorated // hToken - hToken for the user // dwSessionKey - TCP session key // lpvCompletionObj - Completion object in protocol to handle completion // pdwNDS - NNTP driver status [local] void DecorateNewsTreeObject( [in] HANDLE hToken, [in] INntpComplete *pICompletion );
// Purpose: // Create a new group in the store (newgroup) // Parameters: // pszGroupName - the group to create // Comment: // o Lookup virtual root to construct full path name using pszGroupName // o Create the directory structure with full path name [local] void CreateGroup( [in] INNTPPropertyBag* pGroupBag, [in] HANDLE hToken, [in] INntpComplete* pICompletion, [in] BOOL fAnonymous );
// Purpose: // Remove a group from the store (rmgroup). This should include a file // scan operation in the store to delete all articles within the group. // This may be done the same way as MCIS 2.0, when article cleanup is // handled by expiration thread. Groups to be removed is queued up. // Parameters: // pNewsGroup - Newsgroup to be removed. [local] void RemoveGroup( [in] INNTPPropertyBag *pGroupBag, [in] HANDLE hToken, [in] INntpComplete *pICompletion, [in] BOOL fAnonymous ); };
// // Driver interface to establish connection to Exchange store // [ object, uuid(D61569A0-D3F9-11d1-A58C-00C04FA375BA), helpstring("INntpDriverPrepare Interface"), ] interface INntpDriverPrepare : IUnknown { // Purpose: // Initialize driver specific data structure, ie Epoxy connection, etc. // Parameters: // pszVRootPath - virtual root path this driver interface maps to // ie. Nntpsvc/1/root/alt // pLookup - a pointer to the server's ILookup interface // pNewsTree - a pointer to the server's INewsTree interface // pCompletion - a pointer to the server's ICompletion interface // Comments: // o This function is async and returns to the caller without blocking. // o A seperate thread is spawned out to do any blocking operations. [local] void Connect( [in] LPCWSTR pszVRootPath, [in] LPCSTR pszGroupPrefix, [in] IUnknown *punkMetabase, [in] INntpServer* pIServer, [in] INewsTree* pINewsTree, [out] INntpDriver** ppIGoodDriver, [in] INntpComplete* pICompletion, [in] HANDLE hToken, [in] DWORD dwFlag );
// Purpose: // Cancel the pending Connect request // Parameters: // None // Comments: // o Cancel any outstanding connection requests // o Other tasks? [local] HRESULT CancelConnect();
};
[ object, uuid(9E2D8DE8-6926-11d2-9F03-00C04F8EF2F1), helpstring("INntpDriverSearch Interface") ] interface INntpDriverSearch : IUnknown {
[local] void MakeSearchQuery ( [in] CHAR *pszSearchString, [in] INNTPPropertyBag *pGroupBag, [in] BOOL bDeepQuery, [in] WCHAR *pwszColumns, [in] WCHAR *pwszSortOrder, [in] LCID LocaleID, [in] DWORD cMaxRows, [in] HANDLE hToken, [in] BOOL fAnonymous, [in] INntpComplete *pICompletion, [out] INntpSearchResults **pINntpSearch, [in] LPVOID lpvContext);
[local] void MakeXpatQuery ( [in] CHAR *pszSearchString, [in] INNTPPropertyBag *pGroupBag, [in] BOOL bDeepQuery, [in] WCHAR *pwszColumns, [in] WCHAR *pwszSortOrder, [in] LCID LocaleID, [in] DWORD cMaxRows, [in] HANDLE hToken, [in] BOOL fAnonymous, [in] INntpComplete *pICompletion, [out] INntpSearchResults **pINntpSearch, [out] DWORD *pLowArticleID, [out] DWORD *pHighArticleID, [in] LPVOID lpvContext);
[local] BOOL UsesSameSearchDatabase( [in] INntpDriverSearch *pDriver, [in] LPVOID lpvContext );
[local] void GetDriverInfo( [out] GUID *pDriverGUID, [out] void **ppvDriverInfo, [in] LPVOID lpvContext ); };
[ object, uuid(b72a754e-746c-11d2-9f04-00c04f8ef2f1), helpstring("INntpSearch Interface") ] interface INntpSearchResults : IUnknown {
[local] void GetResults ( [in,out] DWORD *pcResults, [out] BOOL *pfMore, [out] WCHAR **pGroupName, [out] DWORD *pdwArticleID, [in] INntpComplete *pICompletion, [in] HANDLE hToken, [in] BOOL fAnonymous, [in] LPVOID lpvContext); };
[ uuid(ADD104FE-99C5-11D1-9128-00C04FC30A64), version(1.0), helpstring("inntpdrv 1.0 Type Library") ] library INNTPDRVLib { importlib("stdole2.tlb");
[ uuid(ADD10510-99C5-11D1-9128-00C04FC30A64), helpstring("NntpDriverPrepare Class") ] coclass NntpDriverPrepare { [default] interface INntpDriverPrepare; };
};
|