void NotifyObjectListeners (ASID idCell, ASID idObject) { // If we get here, our cache of information for the specified object // has just been updated. Check for listeners who may be interested // in changes to this object. // if (l.pListeners) { for (LPENUM pEnum = l.pListenersKeyObject->FindFirst (&idObject); pEnum; pEnum = pEnum->FindNext()) { LPLISTENER pl = (LPLISTENER)( pEnum->GetObject() ); if (pl->idCell != idCell) continue; if (!IsWindow (pl->hNotify)) { l.pListeners->Remove (pl); Delete (pl); continue; } PostMessage (pl->hNotify, WM_ASC_NOTIFY_OBJECT, (WPARAM)0, (LPARAM)idObject); } } }
void SERVER::SendDeleteNotifications (void) { LPENUM pEnum; for (pEnum = m_lAggregates->FindFirst(); pEnum; pEnum = pEnum->FindNext()) { LPAGGREGATE lpAggregate = (LPAGGREGATE)(pEnum->GetObject()); lpAggregate->SendDeleteNotifications (); } for (pEnum = m_lServices->FindFirst(); pEnum; pEnum = pEnum->FindNext()) { LPSERVICE lpService = (LPSERVICE)(pEnum->GetObject()); lpService->SendDeleteNotifications(); } NOTIFYCALLBACK::SendNotificationToAll (evtDestroy, GetIdentifier()); }
void SERVER::FreeServices (void) { for (LPENUM pEnum = m_lServices->FindLast(); pEnum; pEnum = pEnum->FindPrevious()) { LPSERVICE lpService = (LPSERVICE)(pEnum->GetObject()); m_lServices->Remove (lpService); Delete (lpService); } }
void SERVER::FreeAggregates (void) { for (LPENUM pEnum = m_lAggregates->FindLast(); pEnum; pEnum = pEnum->FindPrevious()) { LPAGGREGATE lpAggregate = (LPAGGREGATE)(pEnum->GetObject()); m_lAggregates->Remove (lpAggregate); Delete (lpAggregate); } }
void ClearObjectNotifications (HWND hNotify) { asc_Enter(); if (l.pListeners) { for (LPENUM pEnum = l.pListeners->FindFirst(); pEnum; pEnum = pEnum->FindNext()) { LPLISTENER pl = (LPLISTENER)( pEnum->GetObject() ); if (pl->hNotify == hNotify) { l.pListeners->Remove (pl); Delete (pl); } } } asc_Leave(); }
void TestForNotifications (UINT_PTR idClient, ASID idCell, ASID idObject) { if (l.pListeners) { // First we'll zip through our list of listeners and // build an ASIDLIST reflecting the objects in this cell // for which we're listening. // LPASIDLIST pAsidList = NULL; for (LPENUM pEnum = l.pListeners->FindFirst(); pEnum; pEnum = pEnum->FindNext()) { LPLISTENER pl = (LPLISTENER)( pEnum->GetObject() ); if (pl->idCell != idCell) continue; if (idObject && (pl->idObject != idObject)) continue; if (!pAsidList) { if (!asc_AsidListCreate (&pAsidList)) break; } if (!asc_AsidListAddEntry (&pAsidList, pl->idObject, 0)) break; } // Then we'll call one of our cache routines, which in turn will tell // the admin server what version of the properties we have for each // of these objects; if any have newer properties available, we'll // get them back--and that will cause us to send out notifications to // our listeners. // if (pAsidList) { ULONG status; (void)RefreshCachedProperties (idClient, idCell, pAsidList, GET_ALL_DATA, &status); } } }
LPIDENT FILESET::GetIdentifier (void) { if (m_lpiThis == NULL) { TCHAR szCell[ cchNAME ]; TCHAR szServer[ cchNAME ]; TCHAR szAggregate[ cchNAME ]; m_lpiAggregate->GetCellName (szCell); m_lpiAggregate->GetLongServerName (szServer); m_lpiAggregate->GetAggregateName (szAggregate); // Finding the identifier for a fileset is a little tricky, because // (a) a fileset identifier's unique "key" includes the fileset's // aggregate, and (b) filesets can move around in the cell. // // We'll search through our list of IDENTs and see if we can find // an old IDENT object that refers to this fileset; if we can't find // one, we'll create a new one. To make sure we have an accurate match, // we'll require that the IDENT we find match all of the following // criteria: // 1- The identifier must point to a fileset // 2- The identifier must have the same fileset ID as this FILESET // 3- The identifier's cRef must be zero (i.e., there should // not be another FILESET object out there which thinks *it* // uses that IDENT) // 4- The identifier must (obviously) point to the cell in which // this FILESET object resides // 5- If this is a fileset replica, the IDENT must be on the same // aggregate as this fileset // // Note that the IDENT class maintains its list of IDENTs in a // HASHLIST that a key placed on volume IDs. We'll use that key // to speed up our search enormously. // BOOL fRequireSameAggregate = ProbablyReplica(); for (LPENUM pEnum = IDENT::x_lkFilesetID->FindFirst (&m_idVolume); pEnum; pEnum = pEnum->FindNext()) { // Only volumes which match this fileset ID will get here. // LPIDENT lpiFind = (LPIDENT)( pEnum->GetObject() ); if (lpiFind->m_iType != itFILESET) continue; if (lpiFind->m_cRef != 0) continue; if (lstrcmpi (szCell, lpiFind->m_szCell)) continue; if (fRequireSameAggregate) { if (lstrcmpi (szServer, lpiFind->m_szServer)) continue; if (lstrcmpi (szAggregate, lpiFind->m_szAggregate)) continue; } // Found a match! Update the IDENT's name and location, // to ensure it jives with reality... for instance, if // a fileset has been moved, we'll need to fix the // server and aggregate names. Since this affects one // of the keys in the IDENT class's hashlist, update that list. // Delete (pEnum); m_lpiThis = lpiFind; lstrcpy (m_lpiThis->m_szServer, szServer); lstrcpy (m_lpiThis->m_szAggregate, szAggregate); lstrcpy (m_lpiThis->m_szFileset, m_szName); m_lpiThis->Update(); break; } if (m_lpiThis == NULL) m_lpiThis = New2 (IDENT,(this)); // Create a new IDENT if necessary. m_lpiThis->m_cRef ++; } return m_lpiThis; }
void Display_OnEndTask_UpdMachines (LPTASKPACKET ptp) { HWND hDlg = GetTabChild (GetDlgItem (g.hMain, IDC_TAB)); HWND hList = GetDlgItem (hDlg, IDC_MACHINES_LIST); if (IsWindow (hList) && !lstrcmpi (TASKDATA(ptp)->szPattern, g.szPatternMachines)) { FastList_Begin (hList); // Update the title above the list to indicate what we're showing // TCHAR szCell[ cchRESOURCE ]; asc_CellNameGet_Fast (g.idClient, g.idCell, szCell); LPTSTR pszTitle = FormatString ((TASKDATA(ptp)->szPattern[0]) ? IDS_MACHINES_PATTERN : IDS_MACHINES_ALL, TEXT("%s"), szCell); SetDlgItemText (hDlg, IDC_MACHINES_TITLE, pszTitle); FreeString (pszTitle); // For faster access, we'll want to use a hashlist to deal with // the items in our ASIDLIST (right now it's just a flat array). // This lets us remove duplicates--which is no big deal because // there shouldn't be any anyway--but more importantly it lets // us instantly determine if a particular ASID is in the list // (the asc_AsidListTest function is O(n), and we need O(1)). // LPHASHLIST pAsidList = New (HASHLIST); if (TASKDATA(ptp)->pAsidList) { for (size_t iAsid = 0; iAsid < TASKDATA(ptp)->pAsidList->cEntries; ++iAsid) pAsidList->AddUnique ((PVOID)(TASKDATA(ptp)->pAsidList->aEntries[ iAsid ].idObject)); } // Delete any items which are currently in the FastList but // which aren't in our AsidList. // HLISTITEM hItemNext; for (HLISTITEM hItem = FastList_FindFirst (hList); hItem; hItem = hItemNext) { hItemNext = FastList_FindNext (hList, hItem); ASID idObject = (ASID)FastList_GetItemParam (hList, hItem); if (!pAsidList->fIsInList ((PVOID)idObject)) FastList_RemoveItem (hList, hItem); } // Add items for any entries which are in our AsidList but aren't // currently in the FastList. // DWORD dwStyle = GetWindowLong (hList, GWL_STYLE); for (LPENUM pEnum = pAsidList->FindFirst(); pEnum; pEnum = pEnum->FindNext()) { ASID idObject = (ASID)( pEnum->GetObject() ); HLISTITEM hItem; if ((hItem = FastList_FindItem (hList, (LPARAM)idObject)) == NULL) { FASTLISTADDITEM ai; memset (&ai, 0x00, sizeof(ai)); Display_GetImageIcons (dwStyle, gr.ivMch, idObject, imageSERVER, IMAGE_NOIMAGE, &ai.iFirstImage, &ai.iSecondImage); ai.lParam = (LPARAM)idObject; hItem = FastList_AddItem (hList, &ai); } } Delete (pAsidList); FastList_End (hList); } Display_StopWorking(); }
void AfsAdmSvr_CallbackManager (void) { AfsAdmSvr_Enter(); if ((++l.cManagers) == 1) { l.heCallback = CreateEvent (NULL, TRUE, FALSE, TEXT("AfsAdmSvr_CallbackManager Event")); l.pListCallbacks = New (HASHLIST); } AfsAdmSvr_Leave(); for (;;) { WaitForSingleObjectEx (l.heCallback, INFINITE, FALSE); if (l.fStopManagers) break; // We must ensure that we don't block the server's operations because // a callback doesn't go through; since other operations may need // access to the l.pListCallbacks structure in order to queue new // callbacks, we can't leave it locked by issuing callbacks while // enumerating it. Instead we'll copy the list into a local copy, // clear it, and enumerate that local copy--other threads can then // continue to add new requests to l.pListCallbacks. // AfsAdmSvr_Enter(); LPHASHLIST pList = New (HASHLIST); LPENUM pEnum; for (pEnum = l.pListCallbacks->FindFirst(); pEnum; pEnum = pEnum->FindNext()) { LPCALLBACKDATA pData = (LPCALLBACKDATA)( pEnum->GetObject() ); pList->Add (pData); l.pListCallbacks->Remove (pData); } ResetEvent (l.heCallback); AfsAdmSvr_Leave(); // Now enumerate that copied list, and issue callbacks for each item. // for (pEnum = pList->FindFirst(); pEnum; pEnum = pEnum->FindNext()) { LPCALLBACKDATA pData = (LPCALLBACKDATA)( pEnum->GetObject() ); try { switch (pData->Type) { case cbtACTION: AfsAdmSvrCallback_Action (pData->pAction, pData->fFinished); break; } } catch(...) { ; } pList->Remove (pData); AfsAdmSvr_FreeCallbackData (pData); } Delete (pList); } AfsAdmSvr_Enter(); if ((--l.cManagers) == 0) { Delete (l.pListCallbacks); l.pListCallbacks = NULL; CloseHandle (l.heCallback); l.heCallback = NULL; } AfsAdmSvr_Leave(); }
BOOL SERVER::RefreshServices (BOOL fNotify, ULONG *pStatus) { BOOL rc = TRUE; DWORD status = 0; if (m_fServicesOutOfDate) { m_fServicesOutOfDate = FALSE; if (fIsMonitored()) { if (fNotify) NOTIFYCALLBACK::SendNotificationToAll (evtRefreshServicesBegin, GetIdentifier()); // First thing is to forget about what services we think we have now. // LPENUM pEnum; for (pEnum = m_lServices->FindLast(); pEnum; pEnum = pEnum->FindPrevious()) { LPSERVICE lpService = (LPSERVICE)(pEnum->GetObject()); lpService->SendDeleteNotifications(); m_lServices->Remove (lpService); Delete (lpService); } // Next, the harder part: look through the server to find a list // of services. // PVOID hCell; PVOID hBOS; if ((hBOS = OpenBosObject (&hCell, &status)) == NULL) rc = FALSE; else { WORKERPACKET wpBegin; wpBegin.wpBosProcessNameGetBegin.hServer = hBOS; if (!Worker_DoTask (wtaskBosProcessNameGetBegin, &wpBegin, &status)) rc = FALSE; else { LPSERVICE lpService = New2 (SERVICE,(this, TEXT("BOS"))); m_lServices->Add (lpService); NOTIFYCALLBACK::SendNotificationToAll (evtCreate, lpService->GetIdentifier()); for (;;) { TCHAR szServiceName[ cchNAME ]; WORKERPACKET wpNext; wpNext.wpBosProcessNameGetNext.hEnum = wpBegin.wpBosProcessNameGetBegin.hEnum; wpNext.wpBosProcessNameGetNext.pszService = szServiceName; if (!Worker_DoTask (wtaskBosProcessNameGetNext, &wpNext, &status)) { if (status == ADMITERATORDONE) status = 0; else rc = FALSE; break; } lpService = New2 (SERVICE,(this, wpNext.wpBosProcessNameGetNext.pszService)); m_lServices->Add (lpService); NOTIFYCALLBACK::SendNotificationToAll (evtCreate, lpService->GetIdentifier()); } WORKERPACKET wpDone; wpDone.wpBosProcessNameGetDone.hEnum = wpBegin.wpBosProcessNameGetBegin.hEnum; Worker_DoTask (wtaskBosProcessNameGetDone, &wpDone); } CloseBosObject(); } if (fNotify) NOTIFYCALLBACK::SendNotificationToAll (evtRefreshServicesEnd, GetIdentifier(), ((rc) ? 0 : status)); } } if (pStatus && !rc) *pStatus = status; return TRUE; }
BOOL SERVER::RefreshAggregates (BOOL fNotify, ULONG *pStatus) { BOOL rc = TRUE; DWORD status = 0; if (m_fAggregatesOutOfDate) { m_fAggregatesOutOfDate = FALSE; if (fIsMonitored()) { if (fNotify) NOTIFYCALLBACK::SendNotificationToAll (evtRefreshAggregatesBegin, GetIdentifier()); // First thing is to forget about what aggregates we think we have // now. // LPENUM pEnum; for (pEnum = m_lAggregates->FindLast(); pEnum; pEnum = pEnum->FindPrevious()) { LPAGGREGATE lpAggregate = (LPAGGREGATE)(pEnum->GetObject()); lpAggregate->SendDeleteNotifications(); m_lAggregates->Remove (lpAggregate); Delete (lpAggregate); } // Next, the harder part: look through the server to find a list // of aggregates. // PVOID hCell; PVOID hVOS; if ((hVOS = OpenVosObject (&hCell, &status)) == NULL) rc = FALSE; else { WORKERPACKET wpBegin; wpBegin.wpVosPartitionGetBegin.hCell = hCell; wpBegin.wpVosPartitionGetBegin.hServer = hVOS; if (!Worker_DoTask (wtaskVosPartitionGetBegin, &wpBegin, &status)) rc = FALSE; else { for (;;) { WORKERPACKET wpNext; wpNext.wpVosPartitionGetNext.hEnum = wpBegin.wpVosPartitionGetBegin.hEnum; if (!Worker_DoTask (wtaskVosPartitionGetNext, &wpNext, &status)) { if (status == ADMITERATORDONE) status = 0; else rc = FALSE; break; } vos_partitionEntry_p pData = &wpNext.wpVosPartitionGetNext.Data; LPTSTR pszName = AnsiToString (pData->name); LPTSTR pszDevice = AnsiToString (pData->deviceName); LPAGGREGATE lpAggregate = New2 (AGGREGATE,(this, pszName, pszDevice)); lpAggregate->m_as.dwID = lpAggregate->GetID(); FreeString (pszDevice, pData->deviceName); FreeString (pszName, pData->name); lpAggregate->m_wGhost |= GHOST_HAS_SERVER_ENTRY; lpAggregate->m_as.ckStorageTotal = pData->totalSpace; lpAggregate->m_as.ckStorageFree = pData->totalFreeSpace; m_lAggregates->Add (lpAggregate); NOTIFYCALLBACK::SendNotificationToAll (evtCreate, lpAggregate->GetIdentifier()); } WORKERPACKET wpDone; wpDone.wpVosPartitionGetDone.hEnum = wpBegin.wpVosPartitionGetBegin.hEnum; Worker_DoTask (wtaskVosPartitionGetDone, &wpDone); } CloseVosObject(); } if (fNotify) NOTIFYCALLBACK::SendNotificationToAll (evtRefreshAggregatesEnd, GetIdentifier(), ((rc) ? 0 : status)); } } if (pStatus && !rc) *pStatus = status; return TRUE; }