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