Windows: Platform specific MIDL output
[openafs.git] / src / WINNT / afsadmsvr / TaAfsAdmSvrProperties.cpp
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  *
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 #include <winsock2.h>
11 #include <ws2tcpip.h>
12
13 extern "C" {
14 #include <afsconfig.h>
15 #include <afs/param.h>
16 #include <afs/stds.h>
17 #include <roken.h>
18 }
19
20 #include "TaAfsAdmSvrInternal.h"
21
22
23 /*
24  * VARIABLES __________________________________________________________________
25  *
26  */
27
28 typedef struct
29    {
30    ASID idCell;
31    DWORD timeLastRefresh;
32    DWORD cminRefreshRate;
33    HANDLE hThread;
34    } REFRESHTHREAD, *LPREFRESHTHREAD;
35
36 static struct
37    {
38    REFRESHTHREAD *aRefreshThreads;
39    size_t cRefreshThreads;
40    CRITICAL_SECTION *pcsRefreshThreads;
41    } l;
42
43
44 /*
45  * AUTO-REFRESH _______________________________________________________________
46  *
47  */
48
49 DWORD WINAPI AfsAdmSvr_AutoRefreshThread (PVOID lp)
50 {
51    ASID idCell = (ASID)lp;
52    for (;;)
53       {
54       EnterCriticalSection (l.pcsRefreshThreads);
55
56       BOOL fFound = FALSE;
57       DWORD cminRefreshRate;
58       DWORD timeLastRefresh;
59       for (size_t iThread = 0; (!fFound) && (iThread < l.cRefreshThreads); ++iThread)
60          {
61          LPREFRESHTHREAD pThread = &l.aRefreshThreads[ iThread ];
62          if (pThread->idCell == idCell)
63             {
64             fFound = TRUE;
65             cminRefreshRate = pThread->cminRefreshRate;
66             timeLastRefresh = pThread->timeLastRefresh;
67             }
68          }
69
70       LeaveCriticalSection (l.pcsRefreshThreads);
71
72       if (!fFound)
73          break;
74
75       DWORD timeNextRefresh = timeLastRefresh + cminRefreshRate;
76       if ((cminRefreshRate) && ((!timeLastRefresh) || (AfsAdmSvr_GetCurrentTime() >= timeNextRefresh)))
77          {
78          Print (dlDETAIL, TEXT("Auto-refresh: %lu minutes elapsed; refreshing cell 0x%08lX"), cminRefreshRate, idCell);
79
80          LPCELL lpCell;
81          if ((lpCell = ((LPIDENT)idCell)->OpenCell()) != NULL)
82             {
83             lpCell->Invalidate();
84
85             ULONG status;
86             if (!lpCell->RefreshAll (&status))
87                Print (dlERROR, TEXT("Auto-refresh: RefreshCell failed; error 0x%08lX"), status);
88             else
89                Print (dlSTANDARD, TEXT("Auto-refresh of cell 0x%08lX successful"), idCell);
90             lpCell->Close();
91             }
92          }
93
94       Sleep (60L * 1000L); // sleep for one minute
95       }
96
97    return 0;
98 }
99
100
101 void AfsAdmSvr_PrepCellRefresh (void)
102 {
103    if (!l.pcsRefreshThreads)
104       {
105       l.pcsRefreshThreads = New (CRITICAL_SECTION);
106       InitializeCriticalSection (l.pcsRefreshThreads);
107       }
108 }
109
110
111 void AfsAdmSvr_SetCellRefreshRate (ASID idCell, ULONG cminRefreshRate)
112 {
113    AfsAdmSvr_PrepCellRefresh();
114    EnterCriticalSection (l.pcsRefreshThreads);
115
116    size_t iThread;
117    for (iThread = 0; iThread < l.cRefreshThreads; ++iThread)
118       {
119       LPREFRESHTHREAD pThread = &l.aRefreshThreads[ iThread ];
120       if (pThread->idCell == idCell)
121          {
122          pThread->cminRefreshRate = cminRefreshRate;
123          break;
124          }
125       }
126    if (iThread == l.cRefreshThreads)
127       {
128       for (iThread = 0; iThread < l.cRefreshThreads; ++iThread)
129          {
130          LPREFRESHTHREAD pThread = &l.aRefreshThreads[ iThread ];
131          if (pThread->idCell == 0)
132             break;
133          }
134       if (REALLOC (l.aRefreshThreads, l.cRefreshThreads, 1+iThread, 1))
135          {
136          DWORD idThread;
137
138          LPREFRESHTHREAD pThread = &l.aRefreshThreads[ iThread ];
139          pThread->idCell = idCell;
140          pThread->timeLastRefresh = AfsAdmSvr_GetCurrentTime();
141          pThread->cminRefreshRate = cminRefreshRate;
142          pThread->hThread = CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE)AfsAdmSvr_AutoRefreshThread, (LPVOID)idCell, 0, &idThread);
143          }
144       }
145
146    LeaveCriticalSection (l.pcsRefreshThreads);
147 }
148
149
150 void AfsAdmSvr_StopCellRefreshThread (ASID idCell)
151 {
152    AfsAdmSvr_PrepCellRefresh();
153    EnterCriticalSection (l.pcsRefreshThreads);
154
155    for (size_t iThread = 0; iThread < l.cRefreshThreads; ++iThread)
156       {
157       LPREFRESHTHREAD pThread = &l.aRefreshThreads[ iThread ];
158       if (pThread->idCell == idCell)
159          pThread->idCell = 0;
160       }
161
162    LeaveCriticalSection (l.pcsRefreshThreads);
163 }
164
165
166 void AfsAdmSvr_MarkRefreshThread (ASID idCell)
167 {
168    AfsAdmSvr_PrepCellRefresh();
169    EnterCriticalSection (l.pcsRefreshThreads);
170
171    for (size_t iThread = 0; iThread < l.cRefreshThreads; ++iThread)
172       {
173       LPREFRESHTHREAD pThread = &l.aRefreshThreads[ iThread ];
174       if (pThread->idCell == idCell)
175          pThread->timeLastRefresh = AfsAdmSvr_GetCurrentTime();
176       }
177
178    LeaveCriticalSection (l.pcsRefreshThreads);
179 }
180
181
182 /*
183  * OBJECT PROPERTIES __________________________________________________________
184  *
185  */
186
187 void AfsAdmSvr_ObtainRudimentaryProperties (LPASOBJPROP pProperties)
188 {
189    LPIDENT lpi = (LPIDENT)(pProperties->idObject);
190
191    switch (GetAsidType (pProperties->idObject))
192       {
193       case itCELL:
194          pProperties->Type = TYPE_CELL;
195          lpi->GetCellName (pProperties->szName);
196          break;
197
198       case itSERVER:
199          pProperties->Type = TYPE_SERVER;
200          pProperties->idParentCell = (ASID)( lpi->GetCell() );
201          lpi->GetServerName (pProperties->szName);
202          break;
203
204       case itSERVICE:
205          pProperties->Type = TYPE_SERVICE;
206          pProperties->idParentCell = (ASID)( lpi->GetCell() );
207          pProperties->idParentServer = (ASID)( lpi->GetServer() );
208          lpi->GetServiceName (pProperties->szName);
209          break;
210
211       case itAGGREGATE:
212          pProperties->Type = TYPE_PARTITION;
213          pProperties->idParentCell = (ASID)( lpi->GetCell() );
214          pProperties->idParentServer = (ASID)( lpi->GetServer() );
215          lpi->GetAggregateName (pProperties->szName);
216          break;
217
218       case itFILESET:
219          pProperties->Type = TYPE_VOLUME;
220          pProperties->idParentCell = (ASID)( lpi->GetCell() );
221          pProperties->idParentServer = (ASID)( lpi->GetServer() );
222          pProperties->idParentPartition = (ASID)( lpi->GetAggregate() );
223          lpi->GetFilesetName (pProperties->szName);
224          break;
225
226       case itUSER:
227          pProperties->Type = TYPE_USER;
228          pProperties->idParentCell = (ASID)( lpi->GetCell() );
229          lpi->GetUserName (pProperties->szName);
230          break;
231
232       case itGROUP:
233          pProperties->Type = TYPE_GROUP;
234          pProperties->idParentCell = (ASID)( lpi->GetCell() );
235          lpi->GetGroupName (pProperties->szName);
236          break;
237
238       default:
239          pProperties->verProperties = verPROP_NO_OBJECT;
240          return;
241       }
242
243    if (pProperties->verProperties == verPROP_NO_OBJECT)
244       pProperties->verProperties = verPROP_RUDIMENTARY;
245 }
246
247
248 BOOL AfsAdmSvr_ObtainFullProperties (LPASOBJPROP pProperties, ULONG *pStatus)
249 {
250    BOOL rc = TRUE;
251    ULONG status = 0;
252
253    AfsAdmSvr_ObtainRudimentaryProperties (pProperties);
254
255    if (pProperties->verProperties != verPROP_NO_OBJECT)
256       {
257       LPIDENT lpi = (LPIDENT)(pProperties->idObject);
258
259       switch (GetAsidType (pProperties->idObject))
260          {
261          case itCELL:
262             PTSPROPERTIES PtsProperties;
263             if ((rc = AfsClass_GetPtsProperties (lpi, &PtsProperties, &status)) == TRUE)
264                {
265                pProperties->u.CellProperties.idUserMax = (DWORD)PtsProperties.idUserMax;
266                pProperties->u.CellProperties.idGroupMax = (DWORD)PtsProperties.idGroupMax;
267                }
268             break;
269
270          case itSERVER:
271             LPSERVER lpServer;
272             if ((lpServer = lpi->OpenServer (&status)) == NULL)
273                rc = FALSE;
274             else
275                {
276                SERVERSTATUS ss;
277                if (!lpServer->GetStatus (&ss, TRUE, &status))
278                   rc = FALSE;
279                else
280                   {
281                   pProperties->u.ServerProperties.nAddresses = 0;
282                   for (size_t ii = 0; ii < ss.nAddresses; ++ii)
283                      {
284                      if (!ss.aAddresses[ii].sin_addr.s_addr)
285                         continue;
286                      if (pProperties->u.ServerProperties.nAddresses < ASOBJPROP_SERVER_MAXADDRESS)
287                         {
288                         pProperties->u.ServerProperties.aAddresses[ pProperties->u.ServerProperties.nAddresses ] = ntohl(ss.aAddresses[ii].sin_addr.s_addr);
289                         pProperties->u.ServerProperties.nAddresses ++;
290                         }
291                      }
292                   }
293                lpServer->Close();
294                }
295             break;
296
297          case itSERVICE:
298             LPSERVICE lpService;
299             if ((lpService = lpi->OpenService (&status)) == NULL)
300                rc = FALSE;
301             else
302                {
303                SERVICESTATUS ss;
304                if (!lpService->GetStatus (&ss, TRUE, &status))
305                   rc = FALSE;
306                else
307                   {
308                   pProperties->u.ServiceProperties.ServiceType = ss.type;
309                   pProperties->u.ServiceProperties.ServiceState = ss.state;
310                   lstrcpy (pProperties->u.ServiceProperties.szAuxStatus, ss.szAuxStatus);
311                   lstrcpy (pProperties->u.ServiceProperties.szParams, ss.szParams);
312                   lstrcpy (pProperties->u.ServiceProperties.szNotifier, ss.szNotifier);
313                   memcpy (&pProperties->u.ServiceProperties.timeLastStart, &ss.timeLastStart, sizeof(SYSTEMTIME));
314                   memcpy (&pProperties->u.ServiceProperties.timeLastStop, &ss.timeLastStop, sizeof(SYSTEMTIME));
315                   memcpy (&pProperties->u.ServiceProperties.timeLastFail, &ss.timeLastFail, sizeof(SYSTEMTIME));
316                   pProperties->u.ServiceProperties.nStarts = ss.nStarts;
317                   pProperties->u.ServiceProperties.dwErrLast = ss.dwErrLast;
318                   pProperties->u.ServiceProperties.dwSigLast = ss.dwSigLast;
319                   }
320                lpService->Close();
321                }
322             break;
323
324          case itAGGREGATE:
325             LPAGGREGATE lpAggregate;
326             if ((lpAggregate = lpi->OpenAggregate(&status)) == NULL)
327                rc = FALSE;
328             else
329                {
330                AGGREGATESTATUS as;
331                if (!lpAggregate->GetStatus (&as, TRUE, &status))
332                   rc = FALSE;
333                else
334                   {
335                   pProperties->u.PartitionProperties.dwID = as.dwID;
336                   pProperties->u.PartitionProperties.ckStorageTotal = as.ckStorageTotal;
337                   pProperties->u.PartitionProperties.ckStorageFree = as.ckStorageFree;
338                   pProperties->u.PartitionProperties.ckStorageAllocated = as.ckStorageAllocated;
339                   }
340                lpAggregate->Close();
341                }
342             break;
343
344          case itFILESET:
345             LPFILESET lpFileset;
346             if ((lpFileset = lpi->OpenFileset(&status)) == NULL)
347                rc = FALSE;
348             else
349                {
350                FILESETSTATUS fs;
351                if (!lpFileset->GetStatus (&fs, TRUE, &status))
352                   rc = FALSE;
353                else
354                   {
355                   pProperties->u.VolumeProperties.id = fs.id;
356                   pProperties->u.VolumeProperties.idReadWrite = fs.idReadWrite;
357                   pProperties->u.VolumeProperties.idReplica = fs.idReplica;
358                   pProperties->u.VolumeProperties.idClone = fs.idClone;
359                   memcpy (&pProperties->u.VolumeProperties.timeCreation, &fs.timeCreation, sizeof(SYSTEMTIME));
360                   memcpy (&pProperties->u.VolumeProperties.timeLastUpdate, &fs.timeLastUpdate, sizeof(SYSTEMTIME));
361                   memcpy (&pProperties->u.VolumeProperties.timeLastAccess, &fs.timeLastAccess, sizeof(SYSTEMTIME));
362                   memcpy (&pProperties->u.VolumeProperties.timeLastBackup, &fs.timeLastBackup, sizeof(SYSTEMTIME));
363                   memcpy (&pProperties->u.VolumeProperties.timeCopyCreation, &fs.timeCopyCreation, sizeof(SYSTEMTIME));
364                   pProperties->u.VolumeProperties.nFiles = fs.nFiles;
365                   pProperties->u.VolumeProperties.ckQuota = (UINT_PTR)fs.ckQuota;
366                   pProperties->u.VolumeProperties.ckUsed = (UINT_PTR)fs.ckUsed;
367                   pProperties->u.VolumeProperties.FilesetType = fs.Type;
368                   pProperties->u.VolumeProperties.FilesetState = fs.State;
369                   }
370                lpFileset->Close();
371                }
372             break;
373
374          case itUSER:
375             LPUSER lpUser;
376             if ((lpUser = lpi->OpenUser (&status)) == NULL)
377                rc = FALSE;
378             else
379                {
380                USERSTATUS us;
381                if (!lpUser->GetStatus (&us, TRUE, &status))
382                   rc = FALSE;
383                else
384                   {
385                   lpUser->GetName (NULL, pProperties->u.UserProperties.szInstance);
386
387                   if ((pProperties->u.UserProperties.fHaveKasInfo = us.fHaveKasInfo) == TRUE)
388                      {
389                      pProperties->u.UserProperties.KASINFO.fIsAdmin = us.KASINFO.fIsAdmin;
390                      pProperties->u.UserProperties.KASINFO.fCanGetTickets = us.KASINFO.fCanGetTickets;
391                      pProperties->u.UserProperties.KASINFO.fEncrypt = us.KASINFO.fEncrypt;
392                      pProperties->u.UserProperties.KASINFO.fCanChangePassword = us.KASINFO.fCanChangePassword;
393                      pProperties->u.UserProperties.KASINFO.fCanReusePasswords = us.KASINFO.fCanReusePasswords;
394                      memcpy (&pProperties->u.UserProperties.KASINFO.timeExpires, &us.KASINFO.timeExpires, sizeof(SYSTEMTIME));
395                      memcpy (&pProperties->u.UserProperties.KASINFO.timeLastPwChange, &us.KASINFO.timeLastPwChange, sizeof(SYSTEMTIME));
396                      memcpy (&pProperties->u.UserProperties.KASINFO.timeLastMod, &us.KASINFO.timeLastMod, sizeof(SYSTEMTIME));
397                      pProperties->u.UserProperties.KASINFO.szUserLastMod[0] = TEXT('\0');
398                      pProperties->u.UserProperties.KASINFO.csecTicketLifetime = us.KASINFO.csecTicketLifetime;
399                      pProperties->u.UserProperties.KASINFO.keyVersion = us.KASINFO.keyVersion;
400                      memcpy (&pProperties->u.UserProperties.KASINFO.keyData, us.KASINFO.key.key, ENCRYPTIONKEYLENGTH);
401                      pProperties->u.UserProperties.KASINFO.dwKeyChecksum = us.KASINFO.dwKeyChecksum;
402                      pProperties->u.UserProperties.KASINFO.cdayPwExpire = us.KASINFO.cdayPwExpire;
403                      pProperties->u.UserProperties.KASINFO.cFailLogin = us.KASINFO.cFailLogin;
404                      pProperties->u.UserProperties.KASINFO.csecFailLoginLock = us.KASINFO.csecFailLoginLock;
405                      if (us.KASINFO.lpiLastMod)
406                         us.KASINFO.lpiLastMod->GetUserName (pProperties->u.UserProperties.KASINFO.szUserLastMod);
407                      }
408                   if ((pProperties->u.UserProperties.fHavePtsInfo = us.fHavePtsInfo) == TRUE)
409                      {
410                      pProperties->u.UserProperties.PTSINFO.cgroupCreationQuota = us.PTSINFO.cgroupCreationQuota;
411                      pProperties->u.UserProperties.PTSINFO.cgroupMember = us.PTSINFO.cgroupMember;
412                      pProperties->u.UserProperties.PTSINFO.uidName = us.PTSINFO.uidName;
413                      pProperties->u.UserProperties.PTSINFO.uidOwner = us.PTSINFO.uidOwner;
414                      pProperties->u.UserProperties.PTSINFO.uidCreator = us.PTSINFO.uidCreator;
415                      lstrcpy (pProperties->u.UserProperties.PTSINFO.szOwner, us.PTSINFO.szOwner);
416                      lstrcpy (pProperties->u.UserProperties.PTSINFO.szCreator, us.PTSINFO.szCreator);
417                      pProperties->u.UserProperties.PTSINFO.aaListStatus = us.PTSINFO.aaListStatus;
418                      pProperties->u.UserProperties.PTSINFO.aaGroupsOwned = us.PTSINFO.aaGroupsOwned;
419                      pProperties->u.UserProperties.PTSINFO.aaMembership = us.PTSINFO.aaMembership;
420                      }
421                   }
422                lpUser->Close();
423                }
424             break;
425
426          case itGROUP:
427             lpi->GetGroupName (pProperties->szName);
428
429             LPPTSGROUP lpGroup;
430             if ((lpGroup = lpi->OpenGroup (&status)) == NULL)
431                rc = FALSE;
432             else
433                {
434                PTSGROUPSTATUS gs;
435                if (!lpGroup->GetStatus (&gs, TRUE, &status))
436                   rc = FALSE;
437                else
438                   {
439                   pProperties->u.GroupProperties.nMembers = gs.nMembers;
440                   pProperties->u.GroupProperties.uidName = gs.uidName;
441                   pProperties->u.GroupProperties.uidOwner = gs.uidOwner;
442                   pProperties->u.GroupProperties.uidCreator = gs.uidCreator;
443                   pProperties->u.GroupProperties.aaListStatus = gs.aaListStatus;
444                   pProperties->u.GroupProperties.aaListGroupsOwned = gs.aaListGroupsOwned;
445                   pProperties->u.GroupProperties.aaListMembers = gs.aaListMembers;
446                   pProperties->u.GroupProperties.aaAddMember = gs.aaAddMember;
447                   pProperties->u.GroupProperties.aaDeleteMember = gs.aaDeleteMember;
448                   lstrcpy (pProperties->u.GroupProperties.szOwner, gs.szOwner);
449                   lstrcpy (pProperties->u.GroupProperties.szCreator, gs.szCreator);
450                   }
451                lpGroup->Close();
452                }
453             break;
454          }
455       }
456
457    if (rc && (pProperties->verProperties < verPROP_FIRST_SCAN))
458       pProperties->verProperties = verPROP_FIRST_SCAN;
459
460    if (!rc)
461       pProperties->verProperties = verPROP_NO_OBJECT;
462
463    if (!rc && pStatus)
464       *pStatus = status;
465    return rc;
466 }
467
468
469 BOOL AfsAdmSvr_PropertiesDiffer (LPASOBJPROP pProp1, LPASOBJPROP pProp2)
470 {
471    if (pProp1->idObject != pProp2->idObject)
472       return TRUE;
473    if (pProp1->Type != pProp2->Type)
474       return TRUE;
475    if (pProp1->idParentCell != pProp2->idParentCell)
476       return TRUE;
477    if (pProp1->idParentServer != pProp2->idParentServer)
478       return TRUE;
479    if (pProp1->idParentPartition != pProp2->idParentPartition)
480       return TRUE;
481    if (lstrcmp (pProp1->szName, pProp2->szName))
482       return TRUE;
483    if (memcmp (&pProp1->u, &pProp2->u, sizeof(pProp1->u)))
484       return TRUE;
485
486    return FALSE;
487 }
488
489
490 void AfsAdmSvr_TestProperties (ASID idObject)
491 {
492    LPASOBJPROP pProperties;
493    if ((pProperties = (LPASOBJPROP)((LPIDENT)idObject)->GetUserParam()) == NULL)
494       return;
495
496    if (pProperties->verProperties >= verPROP_FIRST_SCAN)
497       {
498       ASOBJPROP NewProperties;
499       memcpy (&NewProperties, pProperties, sizeof(ASOBJPROP));
500       memset (&NewProperties.u, 0x00, sizeof(NewProperties.u));
501
502       if (AfsAdmSvr_ObtainFullProperties (&NewProperties))
503          {
504          if (AfsAdmSvr_PropertiesDiffer (&NewProperties, pProperties))
505             {
506             LPIDENT lpi = (LPIDENT)(pProperties->idObject);
507
508             LPASOBJPROP pStoredProp;
509             if ((pStoredProp = (LPASOBJPROP)(lpi->GetUserParam())) != NULL)
510                {
511                pStoredProp->idParentCell = NewProperties.idParentCell;
512                pStoredProp->idParentServer = NewProperties.idParentServer;
513                pStoredProp->idParentPartition = NewProperties.idParentPartition;
514                lstrcpy (pStoredProp->szName, NewProperties.szName);
515                memcpy (&pStoredProp->u, &NewProperties.u, sizeof(NewProperties.u));
516                pStoredProp->verProperties ++;
517                }
518             }
519          }
520       }
521 }
522
523
524 BOOL CALLBACK AfsAdmSvr_NotifyCallback (NOTIFYEVENT evt, PNOTIFYPARAMS pParams)
525 {
526    switch (evt)
527       {
528       case evtCreate:
529          LPIDENT lpiCreate;
530          if ((lpiCreate = pParams->lpi1) != NULL)
531             {
532             if ((lpiCreate->GetUserParam()) == NULL)
533                {
534                LPASOBJPROP pProperties = New (ASOBJPROP);
535                memset (pProperties, 0x00, sizeof(ASOBJPROP));
536                pProperties->idObject = (ASID)lpiCreate;
537                AfsAdmSvr_ObtainRudimentaryProperties (pProperties);
538                lpiCreate->SetUserParam(pProperties);
539                }
540
541             AfsAdmSvr_TestProperties ((ASID)lpiCreate);
542             }
543          break;
544
545       case evtDestroy:
546          if (GetAsidType ((ASID)pParams->lpi1) == itCELL)
547             AfsAdmSvr_StopCellRefreshThread ((ASID)(pParams->lpi1));
548          break;
549
550       case evtRefreshAllBegin:
551          AfsAdmSvr_Action_StartRefresh ((ASID)(pParams->lpi1));
552          break;
553
554       case evtRefreshAllEnd:
555          AfsAdmSvr_Action_StopRefresh ((ASID)(pParams->lpi1));
556          break;
557
558       case evtRefreshStatusEnd:
559          AfsAdmSvr_TestProperties ((ASID)(pParams->lpi1));
560          break;
561       }
562
563    return TRUE;
564 }
565
566
567 LPASOBJPROP AfsAdmSvr_GetCurrentProperties (ASID idObject, ULONG *pStatus)
568 {
569    switch (GetAsidType (idObject))
570       {
571       case itCELL:
572          LPCELL lpCell;
573          if ((lpCell = ((LPIDENT)idObject)->OpenCell (pStatus)) == NULL)
574             return NULL;
575          lpCell->Close();
576          break;
577
578       case itSERVER:
579          LPSERVER lpServer;
580          if ((lpServer = ((LPIDENT)idObject)->OpenServer (pStatus)) == NULL)
581             return NULL;
582          lpServer->Close();
583          break;
584
585       case itSERVICE:
586          LPSERVICE lpService;
587          if ((lpService = ((LPIDENT)idObject)->OpenService (pStatus)) == NULL)
588             return NULL;
589          lpService->Close();
590          break;
591
592       case itAGGREGATE:
593          LPAGGREGATE lpAggregate;
594          if ((lpAggregate = ((LPIDENT)idObject)->OpenAggregate (pStatus)) == NULL)
595             return NULL;
596          lpAggregate->Close();
597          break;
598
599       case itFILESET:
600          LPFILESET lpFileset;
601          if ((lpFileset = ((LPIDENT)idObject)->OpenFileset (pStatus)) == NULL)
602             return NULL;
603          lpFileset->Close();
604          break;
605
606       case itUSER:
607          LPUSER lpUser;
608          if ((lpUser = ((LPIDENT)idObject)->OpenUser (pStatus)) == NULL)
609             return NULL;
610          lpUser->Close();
611          break;
612
613       case itGROUP:
614          LPPTSGROUP lpGroup;
615          if ((lpGroup = ((LPIDENT)idObject)->OpenGroup (pStatus)) == NULL)
616             return NULL;
617          lpGroup->Close();
618          break;
619
620       default:
621          return (LPASOBJPROP)NULL_(ERROR_INVALID_PARAMETER,pStatus);
622       }
623
624    LPASOBJPROP pCurrentProperties;
625    if ((pCurrentProperties = (LPASOBJPROP)((LPIDENT)idObject)->GetUserParam()) == NULL)
626       {
627       return (LPASOBJPROP)NULL_(ERROR_NOT_ENOUGH_MEMORY,pStatus);
628       }
629
630    return pCurrentProperties;
631 }
632
633
634 BOOL AfsAdmSvr_InvalidateObjectProperties (ASID idObject, ULONG *pStatus)
635 {
636    switch (GetAsidType (idObject))
637       {
638       case itCELL:
639          LPCELL lpCell;
640          if ((lpCell = ((LPIDENT)idObject)->OpenCell (pStatus)) == NULL)
641             return FALSE;
642          lpCell->Invalidate();
643          lpCell->Close();
644          break;
645
646       case itSERVER:
647          LPSERVER lpServer;
648          if ((lpServer = ((LPIDENT)idObject)->OpenServer (pStatus)) == NULL)
649             return FALSE;
650          lpServer->Invalidate();
651          lpServer->Close();
652          break;
653
654       case itSERVICE:
655          LPSERVICE lpService;
656          if ((lpService = ((LPIDENT)idObject)->OpenService (pStatus)) == NULL)
657             return FALSE;
658          lpService->Invalidate();
659          lpService->Close();
660          break;
661
662       case itAGGREGATE:
663          LPAGGREGATE lpAggregate;
664          if ((lpAggregate = ((LPIDENT)idObject)->OpenAggregate (pStatus)) == NULL)
665             return FALSE;
666          lpAggregate->Invalidate();
667          lpAggregate->Close();
668          break;
669
670       case itFILESET:
671          LPFILESET lpFileset;
672          if ((lpFileset = ((LPIDENT)idObject)->OpenFileset (pStatus)) == NULL)
673             return FALSE;
674          lpFileset->Invalidate();
675          lpFileset->Close();
676          break;
677
678       case itUSER:
679          LPUSER lpUser;
680          if ((lpUser = ((LPIDENT)idObject)->OpenUser (pStatus)) == NULL)
681             return FALSE;
682          lpUser->Invalidate();
683          lpUser->Close();
684          break;
685
686       case itGROUP:
687          LPPTSGROUP lpGroup;
688          if ((lpGroup = ((LPIDENT)idObject)->OpenGroup (pStatus)) == NULL)
689             return FALSE;
690          lpGroup->Invalidate();
691          lpGroup->Close();
692          break;
693
694       default:
695          return FALSE_(ERROR_INVALID_PARAMETER,pStatus);
696       }
697
698    return TRUE;
699 }
700