#ifndef _RESMONP_H #define _RESMONP_H /*++ Copyright (c) 1995-1997 Microsoft Corporation Module Name: resmonp.h Abstract: Private header file for the Resource Monitor component Author: John Vert (jvert) 30-Nov-1995 Revision History: Sivaprasad Padisetty (sivapad) 06-18-1997 Added the COM support --*/ #include "windows.h" #include "cluster.h" #include "rm_rpc.h" #include "monmsg.h" #ifdef COMRES #define COBJMACROS #include "comres.h" #endif #define LOG_CURRENT_MODULE LOG_MODULE_RESMON // // internal module identifiers. Not used with ClRtl logging code. Used to // track lock acquisitions. // #define RESMON_MODULE_EVNTLIST 1 #define RESMON_MODULE_NOTIFY 2 #define RESMON_MODULE_POLLER 3 #define RESMON_MODULE_PROPERTY 4 #define RESMON_MODULE_RESLIST 5 #define RESMON_MODULE_RESMON 6 #define RESMON_MODULE_RMAPI 7 // // Define the maximum number of resources handled per thread. // (This value must be smaller than MAXIMUM_WAIT_OBJECTS-1!) // #define MAX_RESOURCES_PER_THREAD 27 #define MAX_HANDLES_PER_THREAD (MAX_RESOURCES_PER_THREAD+1) // // Define the maximum number of threads. // (This value can be up to MAXIMUM_WAIT_OBJECTS, however the first two // entries are taken by events, so in fact we have 2 less threads available). // #define MAX_THREADS (MAXIMUM_WAIT_OBJECTS) // // Define structure and flags used for each resource entry // #define RESOURCE_SIGNATURE 'crsR' extern RESUTIL_PROPERTY_ITEM RmpResourceCommonProperties[]; extern RESUTIL_PROPERTY_ITEM RmpResourceTypeCommonProperties[]; typedef struct _POLL_EVENT_LIST; typedef struct _POLL_EVENT_LIST *PPOLL_EVENT_LIST; // // Lock Info for debugging lock acquires/releases // typedef struct _LOCK_INFO { DWORD Module: 6; DWORD ThreadId: 11; DWORD LineNumber: 15; } LOCK_INFO, *PLOCK_INFO; // // Entry points // #define RESDLL_ENTRY_CLOSE 0x00000001 #define RESDLL_ENTRY_TERMINATE 0x00000002 // // Flags // #define RESOURCE_INSERTED 1 typedef struct _RESOURCE { ULONG Signature; // 'Rsrc' ULONG Flags; LIST_ENTRY ListEntry; // for linking onto monitoring list LPWSTR DllName; LPWSTR ResourceType; LPWSTR ResourceId; LPWSTR ResourceName; DWORD LooksAlivePollInterval; DWORD IsAlivePollInterval; HINSTANCE Dll; // handle to resource's DLL RESID Id; HANDLE EventHandle; // async error notification handle HANDLE OnlineEvent; #ifdef COMRES #define RESMON_TYPE_DLL 1 #define RESMON_TYPE_COM 2 // TODO define this as a union IClusterResource *pClusterResource ; IClusterResControl *pClusterResControl ; IClusterQuorumResource *pClusterQuorumResource ; DWORD dwType ; // Type of resource whether it is DLL or a COMResources POPEN_ROUTINE pOpen; PCLOSE_ROUTINE pClose; PONLINE_ROUTINE pOnline; POFFLINE_ROUTINE pOffline; PTERMINATE_ROUTINE pTerminate; PIS_ALIVE_ROUTINE pIsAlive; PLOOKS_ALIVE_ROUTINE pLooksAlive; PARBITRATE_ROUTINE pArbitrate; PRELEASE_ROUTINE pRelease; PRESOURCE_CONTROL_ROUTINE pResourceControl; PRESOURCE_TYPE_CONTROL_ROUTINE pResourceTypeControl; #else POPEN_ROUTINE Open; PCLOSE_ROUTINE Close; PONLINE_ROUTINE Online; POFFLINE_ROUTINE Offline; PTERMINATE_ROUTINE Terminate; PIS_ALIVE_ROUTINE IsAlive; PLOOKS_ALIVE_ROUTINE LooksAlive; PARBITRATE_ROUTINE Arbitrate; PRELEASE_ROUTINE Release; PRESOURCE_CONTROL_ROUTINE ResourceControl; PRESOURCE_TYPE_CONTROL_ROUTINE ResourceTypeControl; #endif CLUSTER_RESOURCE_STATE State; ULONG IsAliveCount; ULONG IsAliveRollover; RM_NOTIFY_KEY NotifyKey; PPOLL_EVENT_LIST EventList; HANDLE TimerEvent; // Timer event for offline completion. DWORD PendingTimeout; DWORD CheckPoint; // Online pending checkpoint BOOL IsArbitrated; DWORD dwEntryPoint; // Number indicating which resdll entry point is called. BOOL fArbLock; // Variable used for synchronizing arbitrate with close and rundown } RESOURCE, *PRESOURCE; #ifdef COMRES extern DWORD tidActiveXWorker ; // ThreadID for the COM worker thread #define WM_RES_CREATE WM_USER+1 #define WM_RES_OPEN WM_USER+2 #define WM_RES_CLOSE WM_USER+3 #define WM_RES_ONLINE WM_USER+4 #define WM_RES_OFFLINE WM_USER+5 #define WM_RES_TERMINATE WM_USER+6 #define WM_RES_ISALIVE WM_USER+7 #define WM_RES_LOOKSALIVE WM_USER+8 #define WM_RES_ARBITRATE WM_USER+9 #define WM_RES_RELEASE WM_USER+10 #define WM_RES_EXITTHREAD WM_USER+11 #define WM_RES_FREE WM_USER+12 #define WM_RES_RESOURCECONTROL WM_USER+11 #define WM_RES_RESOURCETYPECONTROL WM_USER+12 DWORD WINAPI ActiveXWorkerThread (LPVOID pThreadInfo) ; // // Used in RmpAcquireSpinLock // #define RESMON_MAX_SLOCK_RETRIES 400 typedef struct { PRESOURCE Resource ; LPVOID Data1 ; // For ResourceKey in Open & EvenHandle in Online DWORD status ; // This is the Com Status indicating if the function is actually called. LONG Ret ; // Actual Return Value of the functions like IsAlive, LooksAlive etc. } COMWORKERTHREADPARAM, *PCOMWORKERTHREADPARAM ; DWORD PostWorkerMessage (DWORD tid, UINT msg, PCOMWORKERTHREADPARAM pData) ; RESID Resmon_Open ( IN PRESOURCE Resource, IN HKEY ResourceKey ); VOID Resmon_Close ( IN PRESOURCE Resource ); DWORD Resmon_Online ( IN PRESOURCE Resource, IN OUT LPHANDLE EventHandle ); DWORD Resmon_Offline ( IN PRESOURCE Resource ); VOID Resmon_Terminate ( IN PRESOURCE Resource ); BOOL Resmon_LooksAlive ( IN PRESOURCE Resource ); BOOL Resmon_IsAlive ( IN PRESOURCE Resource ); DWORD Resmon_Arbitrate ( IN PRESOURCE Resource, IN PQUORUM_RESOURCE_LOST LostQuorumResource ) ; DWORD Resmon_Release ( IN PRESOURCE Resource ) ; DWORD Resmon_ResourceControl ( IN PRESOURCE Resource, IN DWORD ControlCode, IN PVOID InBuffer, IN DWORD InBufferSize, OUT PVOID OutBuffer, IN DWORD OutBufferSize, OUT LPDWORD BytesReturned ) ; #define RESMON_OPEN(Resource, ResKey) Resmon_Open(Resource, ResKey) #define RESMON_CLOSE(Resource) Resmon_Close(Resource) #define RESMON_ONLINE(Resource, EventHandle) Resmon_Online(Resource, EventHandle) #define RESMON_OFFLINE(Resource) Resmon_Offline(Resource) #define RESMON_TERMINATE(Resource) Resmon_Terminate(Resource) #define RESMON_ISALIVE(Resource) Resmon_IsAlive(Resource) #define RESMON_LOOKSALIVE(Resource) Resmon_LooksAlive(Resource) #define RESMON_ARBITRATE(Resource, RmpLostQuorumResource) \ Resmon_Arbitrate (Resource, RmpLostQuorumResource) #define RESMON_RELEASE(Resource) \ Resmon_Release (Resource) #define RESMON_RESOURCECONTROL(Resource, ControlCode, InBuffer, InBufferSize, OutBuffer, OutBufferSize, BytesReturned) \ Resmon_ResourceControl (Resource, ControlCode, InBuffer, InBufferSize, OutBuffer, OutBufferSize, BytesReturned) #endif // COMRES typedef struct _RESDLL_FNINFO{ HINSTANCE hDll; PCLRES_FUNCTION_TABLE pResFnTable; }RESDLL_FNINFO, *PRESDLL_FNINFO; #ifdef COMRES typedef struct _RESDLL_INTERFACES{ IClusterResource *pClusterResource ; IClusterResControl *pClusterResControl ; IClusterQuorumResource *pClusterQuorumResource ; }RESDLL_INTERFACES, *PRESDLL_INTERFACES; #endif typedef struct _MONITOR_BUCKET { LIST_ENTRY BucketList; // For chaining buckets together. LIST_ENTRY ResourceList; // List of resources in this bucket DWORDLONG DueTime; // Next time that these resources should be polled DWORDLONG Period; // Periodic interval of this bucket. } MONITOR_BUCKET, *PMONITOR_BUCKET; // // The Poll Event List structure. // typedef struct _POLL_EVENT_LIST { LIST_ENTRY Next; // Next event list LIST_ENTRY BucketListHead; // Bucket Listhead for this list/thread DWORD NumberOfBuckets; // Number of entries on this bucket list DWORD NumberOfResources; // Number of resources on this event list CRITICAL_SECTION ListLock; // Critical section to add/remove events LOCK_INFO PPrevPrevListLock; LOCK_INFO PrevPrevListLock; LOCK_INFO PrevListLock; LOCK_INFO LastListLock; LOCK_INFO LastListUnlock; LOCK_INFO PrevListUnlock; LOCK_INFO PrevPrevListUnlock; LOCK_INFO PPrevPrevListUnlock; HANDLE ListNotify; // List change notification HANDLE ThreadHandle; // Handle of thread processing this list DWORD EventCount; // Number of events/resources in lists HANDLE Handle[MAX_HANDLES_PER_THREAD]; // Array of handles to wait for PRESOURCE Resource[MAX_HANDLES_PER_THREAD]; // Resources that match handles PRESOURCE LockOwnerResource; // Resource that owns the eventlist lock DWORD MonitorState; // Resdll entry point called. } POLL_EVENT_LIST, *PPOLL_EVENT_LIST; #define POLL_GRANULARITY (10) // 10ms #define PENDING_TIMEOUT (3*1000*60) // 3 minutes for pending requests to finish // // Private helper macros and functions // VOID RmpSetEventListLockOwner( IN PRESOURCE pResource, IN DWORD dwMonitorState ); #define RmpAlloc(size) LocalAlloc(LMEM_FIXED, (size)) #define RmpFree(size) LocalFree((size)) #define RmpSetMonitorState(state, resource) \ EnterCriticalSection(&RmpMonitorStateLock); \ GetSystemTimeAsFileTime((PFILETIME)&RmpSharedState->LastUpdate); \ RmpSharedState->State = (state); \ RmpSharedState->ActiveResource = (HANDLE)(resource); \ LeaveCriticalSection(&RmpMonitorStateLock); \ RmpSetEventListLockOwner( resource, state ) #define AcquireListLock() \ EnterCriticalSection( &RmpListLock ); \ RmpListPPrevPrevLock = RmpListPrevPrevLock; \ RmpListPrevPrevLock = RmpListPrevLock; \ RmpListPrevLock = RmpListLastLock; \ RmpListLastLock.Module = RESMON_MODULE; \ RmpListLastLock.ThreadId = GetCurrentThreadId(); \ RmpListLastLock.LineNumber = __LINE__ #define ReleaseListLock() \ RmpListPPrevPrevUnlock = RmpListPrevPrevUnlock; \ RmpListPrevPrevUnlock = RmpListPrevUnlock; \ RmpListPrevUnlock = RmpListLastUnlock; \ RmpListLastUnlock.Module = RESMON_MODULE; \ RmpListLastUnlock.ThreadId = GetCurrentThreadId(); \ RmpListLastUnlock.LineNumber = __LINE__; \ LeaveCriticalSection( &RmpListLock ) #define AcquireEventListLock( EventList ) \ EnterCriticalSection( &(EventList)->ListLock ); \ (EventList)->PPrevPrevListLock = (EventList)->PrevPrevListLock; \ (EventList)->PrevPrevListLock = (EventList)->PrevListLock; \ (EventList)->PrevListLock = (EventList)->LastListLock; \ (EventList)->LastListLock.Module = RESMON_MODULE; \ (EventList)->LastListLock.ThreadId = GetCurrentThreadId(); \ (EventList)->LastListLock.LineNumber = __LINE__ #define ReleaseEventListLock( EventList ) \ (EventList)->PPrevPrevListUnlock = (EventList)->PrevPrevListUnlock; \ (EventList)->PrevPrevListUnlock = (EventList)->PrevListUnlock; \ (EventList)->PrevListUnlock = (EventList)->LastListUnlock; \ (EventList)->LastListUnlock.Module = RESMON_MODULE; \ (EventList)->LastListUnlock.ThreadId = GetCurrentThreadId(); \ (EventList)->LastListUnlock.LineNumber = __LINE__; \ (EventList)->LockOwnerResource = NULL; \ (EventList)->MonitorState = RmonIdle; \ LeaveCriticalSection( &(EventList)->ListLock ) // // Data global to Resource Monitor // extern CRITICAL_SECTION RmpListLock; extern LOCK_INFO RmpListPPrevPrevLock; extern LOCK_INFO RmpListPrevPrevLock; extern LOCK_INFO RmpListPrevLock; extern LOCK_INFO RmpListLastLock; extern LOCK_INFO RmpListLastUnlock; extern LOCK_INFO RmpListPrevUnlock; extern LOCK_INFO RmpListPrevPrevUnlock; extern LOCK_INFO RmpListPPrevPrevUnlock; extern CRITICAL_SECTION RmpMonitorStateLock; extern PMONITOR_STATE RmpSharedState; extern CL_QUEUE RmpNotifyQueue; extern HKEY RmpResourcesKey; extern HKEY RmpResTypesKey; extern HCLUSTER RmpHCluster; extern BOOL RmpShutdown; extern LIST_ENTRY RmpEventListHead; extern HANDLE RmpWaitArray[]; extern HANDLE RmpRewaitEvent; extern HANDLE RmpClusterProcess; extern DWORD RmpNumberOfThreads; extern BOOL RmpDebugger; // // Interfaces for manipulating the resource lists // VOID RmpRundownResources( VOID ); DWORD RmpInsertResourceList( IN PRESOURCE Resource, IN OPTIONAL PPOLL_EVENT_LIST pPollEventList ); VOID RmpRemoveResourceList( IN PRESOURCE Resource ); DWORD RmpOfflineResource( IN RESID ResourceId, IN BOOL Shutdown, OUT DWORD *pdwState ); DWORD RmpSetResourceStatus( IN RESOURCE_HANDLE ResourceHandle, IN PRESOURCE_STATUS ResourceStatus ); VOID RmpLogEvent( IN RESOURCE_HANDLE ResourceHandle, IN LOG_LEVEL LogLevel, IN LPCWSTR FormatString, ... ); VOID RmpLostQuorumResource( IN RESOURCE_HANDLE ResourceHandle ); // // Interfaces for interfacing with the poller thread // DWORD RmpPollerThread( IN LPVOID lpParameter ); VOID RmpSignalPoller( IN PPOLL_EVENT_LIST EventList ); PVOID RmpCreateEventList( VOID ); DWORD RmpAddPollEvent( IN PPOLL_EVENT_LIST EventList, IN HANDLE EventHandle, IN PRESOURCE Resource ); DWORD RmpRemovePollEvent( IN HANDLE EventHandle ); DWORD RmpResourceEventSignaled( IN PPOLL_EVENT_LIST EventList, IN DWORD EventIndex ); // // Notification interfaces // typedef enum _NOTIFY_REASON { NotifyResourceStateChange, NotifyResourceResuscitate, NotifyShutdown } NOTIFY_REASON; VOID RmpPostNotify( IN PRESOURCE Resource, IN NOTIFY_REASON Reason ); DWORD RmpTimerThread( IN LPVOID Context ); DWORD RmpResourceEnumCommonProperties( OUT PVOID OutBuffer, IN DWORD OutBufferSize, OUT LPDWORD BytesReturned, OUT LPDWORD Required ); DWORD RmpResourceGetCommonProperties( IN PRESOURCE Resource, IN BOOL ReadOnly, OUT PVOID OutBuffer, IN DWORD OutBufferSize, OUT LPDWORD BytesReturned, OUT LPDWORD Required ); DWORD RmpResourceValidateCommonProperties( IN PRESOURCE Resource, IN PVOID InBuffer, IN DWORD InBufferSize ); DWORD RmpResourceSetCommonProperties( IN PRESOURCE Resource, IN PVOID InBuffer, IN DWORD InBufferSize ); DWORD RmpResourceEnumPrivateProperties( IN PRESOURCE Resource, OUT PVOID OutBuffer, IN DWORD OutBufferSize, OUT LPDWORD BytesReturned, OUT LPDWORD Required ); DWORD RmpResourceGetPrivateProperties( IN PRESOURCE Resource, OUT PVOID OutBuffer, IN DWORD OutBufferSize, OUT LPDWORD BytesReturned, OUT LPDWORD Required ); DWORD RmpResourceValidatePrivateProperties( IN PRESOURCE Resource, IN PVOID InBuffer, IN DWORD InBufferSize ); DWORD RmpResourceSetPrivateProperties( IN PRESOURCE Resource, IN PVOID InBuffer, IN DWORD InBufferSize ); DWORD RmpResourceGetFlags( IN PRESOURCE Resource, OUT PVOID OutBuffer, IN DWORD OutBufferSize, OUT LPDWORD BytesReturned, OUT LPDWORD Required ); DWORD RmpResourceTypeEnumCommonProperties( IN LPCWSTR ResourceTypeName, OUT PVOID OutBuffer, IN DWORD OutBufferSize, OUT LPDWORD BytesReturned, OUT LPDWORD Required ); DWORD RmpResourceTypeGetCommonProperties( IN LPCWSTR ResourceTypeName, IN BOOL ReadOnly, OUT PVOID OutBuffer, IN DWORD OutBufferSize, OUT LPDWORD BytesReturned, OUT LPDWORD Required ); DWORD RmpResourceTypeValidateCommonProperties( IN LPCWSTR ResourceTypeName, IN PVOID InBuffer, IN DWORD InBufferSize ); DWORD RmpResourceTypeSetCommonProperties( IN LPCWSTR ResourceTypeName, IN PVOID InBuffer, IN DWORD InBufferSize ); DWORD RmpResourceTypeEnumPrivateProperties( IN LPCWSTR ResourceTypeName, OUT PVOID OutBuffer, IN DWORD OutBufferSize, OUT LPDWORD BytesReturned, OUT LPDWORD Required ); DWORD RmpResourceTypeGetPrivateProperties( IN LPCWSTR ResourceTypeName, OUT PVOID OutBuffer, IN DWORD OutBufferSize, OUT LPDWORD BytesReturned, OUT LPDWORD Required ); DWORD RmpResourceTypeValidatePrivateProperties( IN LPCWSTR ResourceTypeName, IN PVOID InBuffer, IN DWORD InBufferSize ); DWORD RmpResourceTypeSetPrivateProperties( IN LPCWSTR ResourceTypeName, IN PVOID InBuffer, IN DWORD InBufferSize ); DWORD RmpResourceTypeGetFlags( IN LPCWSTR ResourceTypeName, OUT PVOID OutBuffer, IN DWORD OutBufferSize, OUT LPDWORD BytesReturned, OUT LPDWORD Required ); #ifdef COMRES DWORD RmpLoadResType( IN LPCWSTR lpszResourceTypeName, IN LPCWSTR lpszDllName, OUT PRESDLL_FNINFO pResDllFnInfo, OUT PRESDLL_INTERFACES pResDllInterfaces, OUT LPDWORD pdwCharacteristics ); DWORD RmpLoadComResType( IN LPCWSTR lpszDllName, OUT PRESDLL_INTERFACES pResDllInterfaces, OUT LPDWORD pdwCharacteristics ); #else DWORD RmpLoadResType( IN LPCWSTR lpszResourceTypeName, IN LPCWSTR lpszDllName, OUT PRESDLL_FNINFO pResDllFnInfo, OUT LPDWORD pdwCharacteristics ); #endif VOID GenerateExceptionReport( IN PEXCEPTION_POINTERS pExceptionInfo ); VOID DumpCriticalSection( IN PCRITICAL_SECTION CriticalSection ); BOOL RmpAcquireSpinLock( IN PRESOURCE pResource, IN BOOL fSpin ); VOID RmpReleaseSpinLock( IN PRESOURCE pResource ); #endif //_RESMONP_h