patch-from-shadow-to-jaltman-bkbox-20031120
[openafs.git] / src / WINNT / afsclass / c_ident.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 extern "C" {
11 #include <afs/param.h>
12 #include <afs/stds.h>
13 }
14
15 #include <WINNT/afsclass.h>
16 #include "internal.h"
17
18
19 /*
20  * VARIABLES __________________________________________________________________
21  *
22  */
23
24 LPHASHLIST IDENT::x_lIdents = NULL;
25 LPHASHLISTKEY IDENT::x_lkTypeServer = NULL;
26 LPHASHLISTKEY IDENT::x_lkFilesetID = NULL;
27 LPHASHLISTKEY IDENT::x_lkFilesetName = NULL;
28 LPHASHLISTKEY IDENT::x_lkAccountName = NULL;
29
30
31
32 /*
33  * CONSTRUCTION AND LIST MANAGEMENT ___________________________________________
34  *
35  */
36
37 void IDENT::InitClass (void)
38 {
39    if (x_lIdents == NULL)
40       {
41       x_lIdents = New (HASHLIST);
42       x_lkTypeServer = x_lIdents->CreateKey ("Type and Server", IDENT::KeyTypeServer_Compare, IDENT::KeyTypeServer_HashObject, IDENT::KeyTypeServer_HashData);
43       x_lkFilesetID = x_lIdents->CreateKey ("Fileset ID", IDENT::KeyFilesetID_Compare, IDENT::KeyFilesetID_HashObject, IDENT::KeyFilesetID_HashData);
44       x_lkFilesetName = x_lIdents->CreateKey ("Fileset Name", IDENT::KeyFilesetName_Compare, IDENT::KeyFilesetName_HashObject, IDENT::KeyFilesetName_HashData);
45       x_lkAccountName = x_lIdents->CreateKey ("Account Name", IDENT::KeyAccountName_Compare, IDENT::KeyAccountName_HashObject, IDENT::KeyAccountName_HashData);
46       }
47 }
48
49 void IDENT::InitIdent (void)
50 {
51    InitClass();
52    m_iType = itUNUSED;
53    m_szCell[0] = TEXT('\0');
54    m_szServer[0] = TEXT('\0');
55    m_szService[0] = TEXT('\0');
56    m_szAggregate[0] = TEXT('\0');
57    m_szFileset[0] = TEXT('\0');
58    m_szAccount[0] = TEXT('\0');
59    m_szInstance[0] = TEXT('\0');
60    memset (&m_vidFileset, 0x00, sizeof(m_vidFileset));
61    m_pUser = NULL;
62    m_cRef = 0;
63 }
64
65 IDENT::~IDENT (void)
66 {
67    x_lIdents->Remove (this);
68    InitIdent();
69 }
70
71 void IDENT::RemoveIdentsInCell (LPIDENT lpiCell)
72 {
73    InitClass();
74    for (LPENUM pEnum = x_lIdents->FindFirst(); pEnum; pEnum = pEnum->FindNext())
75       {
76       LPIDENT lpi = (LPIDENT)( pEnum->GetObject() );
77
78       if (!lstrcmpi (lpi->m_szCell, lpiCell->m_szCell))
79          Delete (lpi);
80       }
81 }
82
83 void IDENT::Update (void)
84 {
85    x_lIdents->Update (this);
86 }
87
88
89 /*
90  * ENUMERATION ________________________________________________________________
91  *
92  */
93
94 LPIDENT IDENT::FindFirst (HENUM *phEnum)
95 {
96    InitClass();
97
98    if ((*phEnum = x_lIdents->FindFirst()) == NULL)
99       return NULL;
100
101    return (LPIDENT)( (*phEnum)->GetObject() );
102 }
103
104
105 LPIDENT IDENT::FindFirst (HENUM *phEnum, VOLUMEID *pvidFileset)
106 {
107    InitClass();
108
109    if ((*phEnum = x_lkFilesetID->FindFirst(pvidFileset)) == NULL)
110       return NULL;
111
112    LPIDENT lpiFound;
113    while ((lpiFound = (LPIDENT)((*phEnum)->GetObject())) != NULL)
114       {
115       if (lpiFound->m_iType == itFILESET)
116          return lpiFound;
117
118       if ((*phEnum = (*phEnum)->FindNext()) == NULL)
119          break;
120       }
121
122    return NULL;
123 }
124
125 LPIDENT IDENT::FindNext (HENUM *phEnum)
126 {
127    if (*phEnum == NULL)
128       return NULL;
129
130    for (;;)
131       {
132       if ((*phEnum = (*phEnum)->FindNext()) == NULL)
133          break;
134
135       LPIDENT lpiFound;
136       if ((lpiFound = (LPIDENT)((*phEnum)->GetObject())) == NULL)
137          break;
138
139       if (lpiFound->m_iType == itFILESET)
140          return lpiFound;
141       }
142
143    return NULL;
144 }
145
146 void IDENT::FindClose (HENUM *phEnum)
147 {
148    if (*phEnum != NULL)
149       {
150       Delete (*phEnum);
151       (*phEnum) = NULL;
152       }
153 }
154
155
156 /*
157  * CELL IDENT _________________________________________________________________
158  *
159  */
160
161 IDENT::IDENT (LPCELL lpCell)
162 {
163    InitIdent();
164
165    if (ASSERT( lpCell != NULL ))
166       {
167       m_iType = itCELL;
168       lpCell->GetName (m_szCell);
169       x_lIdents->Add (this);
170       }
171 }
172
173 BOOL IDENT::fIsCell (void)
174 {
175    return (m_iType == itCELL) ? TRUE : FALSE;
176 }
177
178 LPCELL IDENT::OpenCell (ULONG *pStatus)
179 {
180    if (!ASSERT( m_iType != itUNUSED ))
181       return NULL;
182
183    return CELL::ReopenCell (m_szCell, pStatus);
184 }
185
186 LPIDENT IDENT::GetCell (void)
187 {
188    if (!ASSERT( m_iType != itUNUSED ))
189       return NULL;
190    if (m_iType == itCELL)
191       return this;
192
193    return FindIdent (itCELL, m_szCell, NULL, NULL, NULL, NULL, NULL);
194 }
195
196 void IDENT::GetCellName (LPTSTR pszName)
197 {
198    if (!ASSERT( m_iType != itUNUSED ))
199       {
200       *pszName = 0;
201       return;
202       }
203
204    lstrcpy (pszName, m_szCell);
205 }
206
207
208 /*
209  * USER IDENT _________________________________________________________________
210  *
211  */
212
213 IDENT::IDENT (LPUSER lpUser)
214 {
215    InitIdent();
216
217    if (ASSERT( lpUser != NULL ))
218       {
219       m_iType = itUSER;
220       lstrcpy (m_szCell, lpUser->m_lpiCell->m_szCell);
221       lpUser->GetName (m_szAccount, m_szInstance);
222       x_lIdents->Add (this);
223       }
224 }
225
226 BOOL IDENT::fIsUser (void)
227 {
228    return (m_iType == itUSER) ? TRUE : FALSE;
229 }
230
231 LPUSER IDENT::OpenUser (ULONG *pStatus)
232 {
233    LPUSER lpUser = NULL;
234
235    if (!ASSERT( m_iType == itUSER ))
236       return NULL;
237
238    LPCELL lpCell;
239    if ((lpCell = CELL::ReopenCell (m_szCell, pStatus)) != NULL)
240       {
241       lpUser = lpCell->OpenUser (m_szAccount, m_szInstance, pStatus);
242       lpCell->Close();
243       }
244
245    return lpUser;
246 }
247
248 LPIDENT IDENT::GetUser (void)
249 {
250    if (!ASSERT( m_iType == itUSER ))
251       return NULL;
252    return this;
253 }
254
255
256 void IDENT::GetUserName (LPTSTR pszName, LPTSTR pszInstance)
257 {
258    if (!ASSERT( m_iType == itUSER ))
259       {
260       *pszName = 0;
261       if (pszInstance)
262          *pszInstance = 0;
263       return;
264       }
265
266    lstrcpy (pszName, m_szAccount);
267    if (pszInstance)
268       lstrcpy (pszInstance, m_szInstance);
269 }
270
271
272 void IDENT::GetFullUserName (LPTSTR pszFullName)
273 {
274    if (!ASSERT( m_iType == itUSER ))
275       {
276       *pszFullName = 0;
277       return;
278       }
279
280    AfsClass_GenFullUserName (pszFullName, m_szAccount, m_szInstance);
281 }
282
283
284 /*
285  * GROUP IDENT ________________________________________________________________
286  *
287  */
288
289 IDENT::IDENT (LPPTSGROUP lpGroup)
290 {
291    InitIdent();
292
293    if (ASSERT( lpGroup != NULL ))
294       {
295       m_iType = itGROUP;
296       lstrcpy (m_szCell, lpGroup->m_lpiCell->m_szCell);
297       lpGroup->GetName (m_szAccount);
298       x_lIdents->Add (this);
299       }
300 }
301
302 BOOL IDENT::fIsGroup (void)
303 {
304    return (m_iType == itGROUP) ? TRUE : FALSE;
305 }
306
307 LPPTSGROUP IDENT::OpenGroup (ULONG *pStatus)
308 {
309    LPPTSGROUP lpGroup = NULL;
310
311    if (!ASSERT( m_iType == itGROUP ))
312       return NULL;
313
314    LPCELL lpCell;
315    if ((lpCell = CELL::ReopenCell (m_szCell, pStatus)) != NULL)
316       {
317       lpGroup = lpCell->OpenGroup (m_szAccount, pStatus);
318       lpCell->Close();
319       }
320
321    return lpGroup;
322 }
323
324 LPIDENT IDENT::GetGroup (void)
325 {
326    if (!ASSERT( m_iType == itGROUP ))
327       return NULL;
328    return this;
329 }
330
331
332 void IDENT::GetGroupName (LPTSTR pszName)
333 {
334    if (!ASSERT( m_iType == itGROUP ))
335       {
336       *pszName = 0;
337       return;
338       }
339
340    lstrcpy (pszName, m_szAccount);
341 }
342
343
344 /*
345  * SERVER IDENT _______________________________________________________________
346  *
347  */
348
349 IDENT::IDENT (LPSERVER lpServer)
350 {
351    InitIdent();
352
353    if (ASSERT( lpServer != NULL ))
354       {
355       m_iType = itSERVER;
356       lstrcpy (m_szCell, lpServer->m_lpiCell->m_szCell);
357       lpServer->GetLongName (m_szServer);
358       x_lIdents->Add (this);
359       }
360 }
361
362 BOOL IDENT::fIsServer (void)
363 {
364    return (m_iType == itSERVER) ? TRUE : FALSE;
365 }
366
367 LPSERVER IDENT::OpenServer (ULONG *pStatus)
368 {
369    LPSERVER lpServer = NULL;
370
371    if (!ASSERT( m_iType != itUNUSED && m_iType != itCELL ))
372       return NULL;
373
374    LPCELL lpCell;
375    if ((lpCell = CELL::ReopenCell (m_szCell, pStatus)) != NULL)
376       {
377       lpServer = lpCell->OpenServer (m_szServer, pStatus);
378       lpCell->Close();
379       }
380
381    return lpServer;
382 }
383
384 LPIDENT IDENT::GetServer (void)
385 {
386    if (!ASSERT( m_iType != itUNUSED && m_iType != itCELL ))
387       return NULL;
388    if (m_iType == itSERVER)
389       return this;
390
391    return FindIdent (itSERVER, m_szCell, m_szServer, NULL, NULL, NULL, NULL);
392 }
393
394 void IDENT::GetLongServerName (LPTSTR pszName)
395 {
396    if (!ASSERT( m_iType != itUNUSED && m_iType != itCELL ))
397       {
398       *pszName = 0;
399       return;
400       }
401
402    lstrcpy (pszName, m_szServer);
403 }
404
405 void IDENT::GetShortServerName (LPTSTR pszName)
406 {
407    if (!ASSERT( m_iType != itUNUSED && m_iType != itCELL ))
408       {
409       *pszName = 0;
410       return;
411       }
412
413    SERVER::ShortenName (pszName, m_szServer, TRUE);
414 }
415
416 void IDENT::GetServerName (LPTSTR pszName)
417 {
418    if (!ASSERT( m_iType != itUNUSED && m_iType != itCELL ))
419       {
420       *pszName = 0;
421       return;
422       }
423
424    SERVER::ShortenName (pszName, m_szServer);
425 }
426
427
428 /*
429  * SERVICE IDENT ______________________________________________________________
430  *
431  */
432
433 IDENT::IDENT (LPSERVICE lpService)
434 {
435    InitIdent();
436
437    if (ASSERT( lpService != NULL ))
438       {
439       LPSERVER lpServer;
440       if ((lpServer = lpService->OpenServer()) != NULL)
441          {
442          m_iType = itSERVICE;
443          lstrcpy (m_szCell, lpServer->m_lpiCell->m_szCell);
444          lpServer->GetLongName (m_szServer);
445          lpService->GetName (m_szService);
446          x_lIdents->Add (this);
447          lpServer->Close();
448          }
449       }
450 }
451
452 BOOL IDENT::fIsService (void)
453 {
454    return (m_iType == itSERVICE) ? TRUE : FALSE;
455 }
456
457 LPSERVICE IDENT::OpenService (ULONG *pStatus)
458 {
459    LPSERVICE lpService = NULL;
460
461    if (!ASSERT( fIsService() ))
462       return NULL;
463
464    LPCELL lpCell;
465    if ((lpCell = CELL::ReopenCell (m_szCell, pStatus)) != NULL)
466       {
467       LPSERVER lpServer;
468       if ((lpServer = lpCell->OpenServer (m_szServer, pStatus)) != NULL)
469          {
470          lpService = lpServer->OpenService (m_szService, pStatus);
471          lpServer->Close();
472          }
473       lpCell->Close();
474       }
475
476    return lpService;
477 }
478
479 LPIDENT IDENT::GetService (void)
480 {
481    if (!ASSERT( fIsService() ))
482       return NULL;
483    return this;
484 }
485
486 void IDENT::GetServiceName (LPTSTR pszName)
487 {
488    if (!ASSERT( fIsService() ))
489       {
490       *pszName = 0;
491       return;
492       }
493
494    lstrcpy (pszName, m_szService);
495 }
496
497
498 /*
499  * AGGREGATE IDENT ____________________________________________________________
500  *
501  */
502
503 IDENT::IDENT (LPAGGREGATE lpAggregate)
504 {
505    InitIdent();
506
507    if (ASSERT( lpAggregate != NULL ))
508       {
509       LPSERVER lpServer;
510       if ((lpServer = lpAggregate->OpenServer()) != NULL)
511          {
512          m_iType = itAGGREGATE;
513          lstrcpy (m_szCell, lpServer->m_lpiCell->m_szCell);
514          lpServer->GetLongName (m_szServer);
515          lpAggregate->GetName (m_szAggregate);
516          x_lIdents->Add (this);
517          lpServer->Close();
518          }
519       }
520 }
521
522 BOOL IDENT::fIsAggregate (void)
523 {
524    return (m_iType == itAGGREGATE) ? TRUE : FALSE;
525 }
526
527 LPAGGREGATE IDENT::OpenAggregate (ULONG *pStatus)
528 {
529    LPAGGREGATE lpAggregate = NULL;
530
531    if (!ASSERT( fIsAggregate() || fIsFileset() ))
532       return NULL;
533
534    LPCELL lpCell;
535    if ((lpCell = CELL::ReopenCell (m_szCell, pStatus)) != NULL)
536       {
537       LPSERVER lpServer;
538       if ((lpServer = lpCell->OpenServer (m_szServer, pStatus)) != NULL)
539          {
540          lpAggregate = lpServer->OpenAggregate (m_szAggregate, pStatus);
541          lpServer->Close();
542          }
543       lpCell->Close();
544       }
545
546    return lpAggregate;
547 }
548
549 LPIDENT IDENT::GetAggregate (void)
550 {
551    if (!ASSERT( fIsAggregate() || fIsFileset() ))
552       return NULL;
553    if (m_iType == itAGGREGATE)
554       return this;
555
556    return FindIdent (itAGGREGATE, m_szCell, m_szServer, NULL, m_szAggregate, NULL, NULL);
557 }
558
559 void IDENT::GetAggregateName (LPTSTR pszName)
560 {
561    if (!ASSERT( fIsAggregate() || fIsFileset() ))
562       {
563       *pszName = 0;
564       return;
565       }
566
567    lstrcpy (pszName, m_szAggregate);
568 }
569
570
571 /*
572  * FILESET IDENT ______________________________________________________________
573  *
574  */
575
576 IDENT::IDENT (LPFILESET lpFileset)
577 {
578    InitIdent();
579
580    if (ASSERT( lpFileset != NULL ))
581       {
582       LPAGGREGATE lpAggregate;
583       if ((lpAggregate = lpFileset->OpenAggregate()) != NULL)
584          {
585          LPSERVER lpServer;
586          if ((lpServer = lpAggregate->OpenServer()) != NULL)
587             {
588             m_iType = itFILESET;
589             lstrcpy (m_szCell, lpServer->m_lpiCell->m_szCell);
590             lpServer->GetLongName (m_szServer);
591             lpAggregate->GetName (m_szAggregate);
592             lpFileset->GetName (m_szFileset);
593             lpFileset->GetID (&m_vidFileset);
594             x_lIdents->Add (this);
595             lpServer->Close();
596             }
597          lpAggregate->Close();
598          }
599       }
600 }
601
602 BOOL IDENT::fIsFileset (void)
603 {
604    return (m_iType == itFILESET) ? TRUE : FALSE;
605 }
606
607 LPFILESET IDENT::OpenFileset (ULONG *pStatus)
608 {
609    LPFILESET lpFileset = NULL;
610
611    if (!ASSERT( fIsFileset() ))
612       return NULL;
613
614    LPCELL lpCell;
615    if ((lpCell = CELL::ReopenCell (m_szCell, pStatus)) != NULL)
616       {
617       LPSERVER lpServer;
618       if ((lpServer = lpCell->OpenServer (m_szServer, pStatus)) != NULL)
619          {
620          LPAGGREGATE lpAggregate;
621          if ((lpAggregate = lpServer->OpenAggregate (m_szAggregate, pStatus)) != NULL)
622             {
623             lpFileset = lpAggregate->OpenFileset (&m_vidFileset, pStatus);
624             lpAggregate->Close();
625             }
626          lpServer->Close();
627          }
628       lpCell->Close();
629       }
630
631    return lpFileset;
632 }
633
634 LPIDENT IDENT::GetFileset (void)
635 {
636    if (!ASSERT( fIsFileset() ))
637       return NULL;
638    return this;
639 }
640
641 void IDENT::GetFilesetName (LPTSTR pszName)
642 {
643    if (!ASSERT( fIsFileset() ))
644       {
645       *pszName = 0;
646       return;
647       }
648
649    lstrcpy (pszName, m_szFileset);
650 }
651
652 void IDENT::GetFilesetID (VOLUMEID *pvidFileset)
653 {
654    if (!ASSERT( fIsFileset() ))
655       {
656       memset (pvidFileset, 0x00, sizeof(VOLUMEID));
657       return;
658       }
659
660    memcpy (pvidFileset, &m_vidFileset, sizeof(VOLUMEID));
661 }
662
663
664 /*
665  * NON- TYPE-SPECIFIC ROUTINES ________________________________________________
666  *
667  */
668
669 IDENTTYPE IDENT::GetType (void)
670 {
671    return m_iType;
672 }
673
674 PVOID IDENT::GetUserParam (void)
675 {
676    return m_pUser;
677 }
678
679 void IDENT::SetUserParam (PVOID pUser)
680 {
681    m_pUser = pUser;
682 }
683
684 size_t IDENT::GetRefCount (void)
685 {
686    return m_cRef;
687 }
688
689
690 /*
691  * HASH KEYS __________________________________________________________________
692  *
693  * A list of all IDENT objects is maintained using a HashList, which has two
694  * index keys: one on [type+servername], and another on [filesetid].
695  *
696  */
697
698 typedef struct
699    {
700    IDENTTYPE iType;
701    LPCTSTR pszServer;
702    } KeyTypeServer;
703
704 BOOL CALLBACK IDENT::KeyTypeServer_Compare (LPHASHLISTKEY pKey, PVOID pObject, PVOID pData)
705 {
706    if (((LPIDENT)pObject)->m_iType != ((KeyTypeServer*)pData)->iType)
707       return FALSE;
708    if (lstrcmp (((LPIDENT)pObject)->m_szServer, ((KeyTypeServer*)pData)->pszServer))
709       return FALSE;
710    return TRUE;
711 }
712
713 HASHVALUE CALLBACK IDENT::KeyTypeServer_HashObject (LPHASHLISTKEY pKey, PVOID pObject)
714 {
715    KeyTypeServer kts;
716    kts.iType = ((LPIDENT)pObject)->m_iType;
717    kts.pszServer = ((LPIDENT)pObject)->m_szServer;
718    return IDENT::KeyTypeServer_HashData (pKey, &kts);
719 }
720
721 HASHVALUE CALLBACK IDENT::KeyTypeServer_HashData (LPHASHLISTKEY pKey, PVOID pData)
722 {
723    return (HashString( ((KeyTypeServer*)pData)->pszServer ) + ((KeyTypeServer*)pData)->iType);
724 }
725
726
727 BOOL CALLBACK IDENT::KeyFilesetID_Compare (LPHASHLISTKEY pKey, PVOID pObject, PVOID pData)
728 {
729    return !memcmp (&((LPIDENT)pObject)->m_vidFileset, (VOLUMEID*)pData, sizeof(VOLUMEID));
730 }
731
732 HASHVALUE CALLBACK IDENT::KeyFilesetID_HashObject (LPHASHLISTKEY pKey, PVOID pObject)
733 {
734    return IDENT::KeyFilesetID_HashData (pKey, &((LPIDENT)pObject)->m_vidFileset);
735 }
736
737 HASHVALUE CALLBACK IDENT::KeyFilesetID_HashData (LPHASHLISTKEY pKey, PVOID pData)
738 {
739    return (HASHVALUE)(*((VOLUMEID*)pData));
740 }
741
742
743 BOOL CALLBACK IDENT::KeyFilesetName_Compare (LPHASHLISTKEY pKey, PVOID pObject, PVOID pData)
744 {
745    return !lstrcmpi (((LPIDENT)pObject)->m_szFileset, (LPTSTR)pData);
746 }
747
748 HASHVALUE CALLBACK IDENT::KeyFilesetName_HashObject (LPHASHLISTKEY pKey, PVOID pObject)
749 {
750    return IDENT::KeyFilesetName_HashData (pKey, &((LPIDENT)pObject)->m_szFileset);
751 }
752
753 HASHVALUE CALLBACK IDENT::KeyFilesetName_HashData (LPHASHLISTKEY pKey, PVOID pData)
754 {
755    return HashString ((LPTSTR)pData);
756 }
757
758
759 BOOL CALLBACK IDENT::KeyAccountName_Compare (LPHASHLISTKEY pKey, PVOID pObject, PVOID pData)
760 {
761    return !lstrcmpi (((LPIDENT)pObject)->m_szAccount, (LPTSTR)pData);
762 }
763
764 HASHVALUE CALLBACK IDENT::KeyAccountName_HashObject (LPHASHLISTKEY pKey, PVOID pObject)
765 {
766    return IDENT::KeyAccountName_HashData (pKey, &((LPIDENT)pObject)->m_szAccount);
767 }
768
769 HASHVALUE CALLBACK IDENT::KeyAccountName_HashData (LPHASHLISTKEY pKey, PVOID pData)
770 {
771    return HashString ((LPTSTR)pData);
772 }
773
774
775 /*
776  * SEARCHING __________________________________________________________________
777  *
778  */
779
780 LPIDENT IDENT::FindIdent (LPCELL lpCell)
781 {
782    TCHAR szCell[ cchNAME ];
783    lpCell->GetName (szCell);
784    return FindIdent (itCELL, szCell, NULL, NULL, NULL, NULL, NULL);
785 }
786
787 LPIDENT IDENT::FindIdent (LPUSER lpUser)
788 {
789    TCHAR szCell[ cchNAME ];
790    TCHAR szAccount[ cchNAME ];
791    TCHAR szInstance[ cchNAME ];
792    lpUser->m_lpiCell->GetCellName (szCell);
793    lpUser->GetName (szAccount, szInstance);
794    return FindIdent (itUSER, szCell, szAccount, szInstance);
795 }
796
797 LPIDENT IDENT::FindIdent (LPPTSGROUP lpGroup)
798 {
799    TCHAR szCell[ cchNAME ];
800    TCHAR szAccount[ cchNAME ];
801    lpGroup->m_lpiCell->GetCellName (szCell);
802    lpGroup->GetName (szAccount);
803    return FindIdent (itGROUP, szCell, szAccount, NULL);
804 }
805
806 LPIDENT IDENT::FindIdent (LPSERVER lpServer)
807 {
808    TCHAR szCell[ cchNAME ];
809    TCHAR szServer[ cchNAME ];
810    lpServer->m_lpiCell->GetCellName (szCell);
811    lpServer->GetLongName (szServer);
812    return FindIdent (itSERVER, szCell, szServer, NULL, NULL, NULL, NULL);
813 }
814
815 LPIDENT IDENT::FindIdent (LPSERVICE lpService)
816 {
817    LPIDENT lpi = NULL;
818
819    LPSERVER lpServer;
820    if ((lpServer = lpService->OpenServer()) != NULL)
821       {
822       TCHAR szCell[ cchNAME ];
823       TCHAR szServer[ cchNAME ];
824       TCHAR szService[ cchNAME ];
825       lpServer->m_lpiCell->GetCellName (szCell);
826       lpServer->GetLongName (szServer);
827       lpService->GetName (szService);
828
829       lpi = FindIdent (itSERVICE, szCell, szServer, szService, NULL, NULL, NULL);
830
831       lpServer->Close();
832       }
833
834    return lpi;
835 }
836
837 LPIDENT IDENT::FindIdent (LPAGGREGATE lpAggregate)
838 {
839    LPIDENT lpi = NULL;
840
841    LPSERVER lpServer;
842    if ((lpServer = lpAggregate->OpenServer()) != NULL)
843       {
844       TCHAR szCell[ cchNAME ];
845       TCHAR szServer[ cchNAME ];
846       TCHAR szAggregate[ cchNAME ];
847       lpServer->m_lpiCell->GetCellName (szCell);
848       lpServer->GetLongName (szServer);
849       lpAggregate->GetName (szAggregate);
850
851       lpi = FindIdent (itAGGREGATE, szCell, szServer, NULL, szAggregate, NULL, NULL);
852
853       lpServer->Close();
854       }
855
856    return lpi;
857 }
858
859 LPIDENT IDENT::FindIdent (LPFILESET lpFileset)
860 {
861    LPIDENT lpi = NULL;
862
863    LPAGGREGATE lpAggregate;
864    if ((lpAggregate = lpFileset->OpenAggregate()) != NULL)
865       {
866       LPSERVER lpServer;
867       if ((lpServer = lpAggregate->OpenServer()) != NULL)
868          {
869          TCHAR szCell[ cchNAME ];
870          TCHAR szServer[ cchNAME ];
871          TCHAR szAggregate[ cchNAME ];
872          VOLUMEID vidFileset;
873          lpServer->m_lpiCell->GetCellName (szCell);
874          lpServer->GetLongName (szServer);
875          lpAggregate->GetName (szAggregate);
876          lpFileset->GetID (&vidFileset);
877
878          lpi = FindIdent (itFILESET, szCell, szServer, NULL, szAggregate, NULL, &vidFileset);
879
880          lpServer->Close();
881          }
882
883       lpAggregate->Close();
884       }
885
886    return lpi;
887 }
888
889 LPIDENT IDENT::FindIdent (LPFILESET lpFileset, VOLUMEID *pvid)
890 {
891    TCHAR szCell[ cchNAME ];
892    lpFileset->m_lpiCell->GetCellName (szCell);
893
894    // since all read-only replicas of a fileset share the same ID,
895    // you can't use this routine to search for one.  BUT, you can
896    // use it to look up a read-write or backup regardless of the
897    // aggregate on which it sits, because there should be only one.
898    // When FindIdent() realizes we didn't supply an aggregate to
899    // match against, it will just skip comparing aggregates and
900    // return the first IDENT it finds which matches the given ID.
901    //
902    return FindIdent (itFILESET, szCell, NULL, NULL, NULL, NULL, pvid);
903 }
904
905
906 LPIDENT IDENT::FindServer (LPIDENT lpiCell, LPTSTR pszServer)
907 {
908    TCHAR szCell[ cchNAME ];
909    lpiCell->GetCellName (szCell);
910
911    return FindIdent (itSERVER, szCell, pszServer, NULL, NULL, NULL, NULL);
912 }
913
914
915 LPIDENT IDENT::FindAggregate (LPIDENT lpiServer, LPTSTR pszAggregate)
916 {
917    TCHAR szCell[ cchNAME ];
918    TCHAR szServer[ cchNAME ];
919    lpiServer->GetCellName (szCell);
920    lpiServer->GetLongServerName (szServer);
921
922    return FindIdent (itAGGREGATE, szCell, szServer, NULL, pszAggregate, NULL, NULL);
923 }
924
925
926 LPIDENT IDENT::FindFileset (LPIDENT lpiParent, LPTSTR pszFileset)
927 {
928    TCHAR szCell[ cchNAME ];
929    TCHAR szServer[ cchNAME ];
930    TCHAR szAggregate[ cchNAME ];
931
932    LPTSTR pszServer = NULL;
933    LPTSTR pszAggregate = NULL;
934
935    lpiParent->GetCellName (szCell);
936
937    if (!lpiParent->fIsCell())
938       {
939       pszServer = szServer;
940       lpiParent->GetLongServerName (szServer);
941       }
942
943    if (lpiParent->fIsAggregate())
944       {
945       pszAggregate = szAggregate;
946       lpiParent->GetAggregateName (szAggregate);
947       }
948
949    return FindIdent (itFILESET, szCell, pszServer, NULL, pszAggregate, pszFileset, NULL);
950 }
951
952
953 LPIDENT IDENT::FindFileset (LPIDENT lpiParent, VOLUMEID *pvidFileset)
954 {
955    TCHAR szCell[ cchNAME ];
956    TCHAR szServer[ cchNAME ];
957    TCHAR szAggregate[ cchNAME ];
958
959    LPTSTR pszServer = NULL;
960    LPTSTR pszAggregate = NULL;
961
962    lpiParent->GetCellName (szCell);
963
964    if (!lpiParent->fIsCell())
965       {
966       pszServer = szServer;
967       lpiParent->GetLongServerName (szServer);
968       }
969
970    if (lpiParent->fIsAggregate())
971       {
972       pszAggregate = szAggregate;
973       lpiParent->GetAggregateName (szAggregate);
974       }
975
976    return FindIdent (itFILESET, szCell, pszServer, NULL, pszAggregate, NULL, pvidFileset);
977 }
978
979
980 LPIDENT IDENT::FindUser (LPIDENT lpiCell, LPTSTR pszPrincipal, LPTSTR pszInstance)
981 {
982    return FindIdent (itUSER, lpiCell->m_szCell, pszPrincipal, pszInstance);
983 }
984
985
986 LPIDENT IDENT::FindGroup (LPIDENT lpiCell, LPTSTR pszGroup)
987 {
988    return FindIdent (itGROUP, lpiCell->m_szCell, pszGroup, NULL);
989 }
990
991
992 LPIDENT IDENT::FindIdent (IDENTTYPE iType, LPTSTR pszCell, LPTSTR pszAccount, LPTSTR pszInstance)
993 {
994    for (LPENUM pEnum = x_lkAccountName->FindFirst (pszAccount); pEnum; pEnum = pEnum->FindNext())
995       {
996       LPIDENT lpiFound = (LPIDENT)( pEnum->GetObject() );
997       if (lpiFound->m_iType != iType)
998          continue;
999       if (lstrcmpi (pszCell, lpiFound->m_szCell))
1000          continue;
1001       if (pszInstance && lstrcmpi (pszInstance, lpiFound->m_szInstance))
1002          continue;
1003       Delete (pEnum);
1004       return lpiFound;
1005       }
1006    return NULL;
1007 }
1008
1009 LPIDENT IDENT::FindIdent (IDENTTYPE iType, LPTSTR pszCell, LPTSTR pszServer, LPTSTR pszService, LPTSTR pszAggregate, LPTSTR pszFileset, VOLUMEID *pvidFileset)
1010 {
1011    InitClass();
1012
1013    // Since all IDENTs are maintained in a hashlist, we have several
1014    // possible techniques for finding any given IDENT. For this particular
1015    // hashlist, we have two keys: by type and server, and by volume ID.
1016    // If possible we want to use the latter; otherwise, use the former.
1017    //
1018    if ((iType == itFILESET) && (pvidFileset))
1019       {
1020       for (LPENUM pEnum = x_lkFilesetID->FindFirst (pvidFileset); pEnum; pEnum = pEnum->FindNext())
1021          {
1022          // Only volumes which match this fileset ID will get here.
1023          //
1024          LPIDENT lpi = (LPIDENT)( pEnum->GetObject() );
1025
1026          if (lpi->m_iType != itFILESET)
1027             continue;
1028          if (pszCell && lstrcmpi (lpi->m_szCell, pszCell))
1029             continue;
1030          if (pszServer && lstrcmpi (lpi->m_szServer, pszServer))
1031             continue;
1032          if (pszAggregate && lstrcmpi (lpi->m_szAggregate, pszAggregate))
1033             continue;
1034
1035          Delete (pEnum);
1036          return lpi;
1037          }
1038       }
1039    else if ((!pszServer) && (iType != itCELL))
1040       {
1041       LPTSTR pszFilesetSearch = (pszFileset) ? pszFileset : TEXT("");
1042
1043       for (LPENUM pEnum = x_lkFilesetName->FindFirst (pszFilesetSearch); pEnum; pEnum = pEnum->FindNext())
1044          {
1045          // Only idents which match this fileset name will get here.
1046          //
1047          LPIDENT lpi = (LPIDENT)( pEnum->GetObject() );
1048
1049          if (iType != lpi->m_iType)
1050             continue;
1051          if (pszCell && lstrcmpi (lpi->m_szCell, pszCell))
1052             continue;
1053          if ((iType == itSERVICE) && lstrcmpi (lpi->m_szService, pszService))
1054             continue;
1055          if ((iType == itAGGREGATE) && pszAggregate && lstrcmpi (lpi->m_szAggregate, pszAggregate))
1056             continue;
1057
1058          Delete (pEnum);
1059          return lpi;
1060          }
1061       }
1062    else // Look up the IDENT based on its type and (optional) server name
1063       {
1064       KeyTypeServer kts;
1065       kts.iType = iType;
1066       kts.pszServer = (pszServer) ? pszServer : TEXT("");
1067
1068       for (LPENUM pEnum = x_lkTypeServer->FindFirst (&kts); pEnum; pEnum = pEnum->FindNext())
1069          {
1070          // Only idents which match this type and server name will get here.
1071          //
1072          LPIDENT lpi = (LPIDENT)( pEnum->GetObject() );
1073
1074          if (pszCell && lstrcmpi (lpi->m_szCell, pszCell))
1075             continue;
1076          if ((iType == itSERVICE) && lstrcmpi (lpi->m_szService, pszService))
1077             continue;
1078          if ((iType == itAGGREGATE) && pszAggregate && lstrcmpi (lpi->m_szAggregate, pszAggregate))
1079             continue;
1080          if ((iType == itFILESET) && pszFileset && lstrcmpi (lpi->m_szFileset, pszFileset))
1081             continue;
1082
1083          Delete (pEnum);
1084          return lpi;
1085          }
1086       }
1087
1088    return NULL;
1089 }
1090