win95-initial-port-20010430
[openafs.git] / src / WINNT / afsadmsvr / TaAfsAdmSvrCommon.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/TaAfsAdmSvr.h>
16
17
18 /*
19  * DEFINITIONS ________________________________________________________________
20  *
21  */
22
23 #define cREALLOC_ASIDLIST     64
24
25 #define cREALLOC_OBJPROPLIST  32
26
27 #define cREALLOC_ACTIONLIST    8
28
29
30 /*
31  * REALLOC ____________________________________________________________________
32  *
33  * This thing, RPC_REALLOC, is a specialized version of the REALLOC() code that
34  * you'll find in most libraries. It's intended to deal with structures that
35  * look like this:
36  *
37  * typedef struct {
38  *    DWORD dwGarbage1;
39  *    size_t cElements;     <- The interesting bit
40  *    DWORD dwGarbage2;
41  *    MYTYPE aElements[1];  <- <- <- The really interesting bit
42  * } MYSTRUCT;
43  *
44  * Remember that since the array is growable, it must be the last element
45  * in the structure. This thing's called RPC_REALLOC because these growable
46  * arrays are well-suited for transferring via rpc--just make the aElements
47  * line in your .IDL file look like:
48  *
49  *    [size_is(cElements) length_is(cElements)] MYTYPE aElements[*];
50  *
51  * As an example of its use, say we want to fill in element 15:
52  *
53  *    void FillInElement15 (MYSTRUCT *pStruct, MYTYPE *pNewData)
54  *    {
55  *       int iElement = 15;
56  *       if (RPC_REALLOC (MYSTRUCT, pStruct, aElements, cElements, 1+iElement, cREALLOC_MYSTRUCT))
57  *       {
58  *          memcpy (&pStruct->aElements[ iElement ], pNewData, sizeof(MYTYPE));
59  *       }
60  *    }
61  *
62  * As always, the "cREALLOC_MYSTRUCT" can be any positive value; it specifies
63  * the granularity with which the the array will be over-allocated. Note that
64  * unlike the normal REALLOC() routine, the {aElements} and {cElements}
65  * parameters are presumed to be members of the specified pointer-to-structure.
66  * If {*pStruct} is NULL upon entry, it will be allocated and zero-filled.
67  *
68  */
69
70 #define OFFSETOF(_type,_a) (size_t)&(((_type *)0)->_a)
71 #define RPC_REALLOC(_type,_str,_a,_c,_r,_ci) AfsAdmSvr_ReallocFunction ((PVOID*)&(_str), OFFSETOF(_type,_a), OFFSETOF(_type,_c), sizeof((_str)->_a[0]), (size_t)_r, (size_t)_ci, 0x00)
72
73 BOOL AfsAdmSvr_ReallocFunction (PVOID *ppStructure, size_t cbHeader, size_t iposCount, size_t cbElement, size_t cReq, size_t cInc, BYTE chFill)
74 {
75    // Use cInc to over-estimate how much space is really required; that
76    // way, allocating space for one element actually allocates space for
77    // many--so that next time we get here, we won't have to do any work.
78    //
79    if (cInc)
80       cReq = cInc * ( (cReq + cInc - 1) / cInc );
81    cReq = max (cReq, 1);
82
83    // See how much space is allocated now. If we have no structure to start
84    // with, obviously we have no array elements either.
85    //
86    size_t cNow = 0;
87    if (*ppStructure)
88       cNow = *(size_t *)( ((PBYTE)(*ppStructure)) + iposCount );
89
90    if (cNow < cReq)
91       {
92       // Hmmm... there wasn't enough space. Allocate a new structure.
93       //
94       size_t cbAlloc = cbHeader + cbElement * cReq;
95       PVOID pNewStructure;
96       if ((pNewStructure = Allocate (cbAlloc)) == NULL)
97          return FALSE;
98
99       memset (pNewStructure, 0x00, cbHeader);
100       memset ((PBYTE)pNewStructure + cbHeader, chFill, cbAlloc - cbHeader);
101       if (*ppStructure)
102          memcpy (pNewStructure, *ppStructure, cbHeader);
103
104       *(size_t *)( ((PBYTE)pNewStructure) + iposCount ) = cReq;
105
106       // Transfer any information from the old structure's elements
107       //
108       if (cNow)
109          memcpy ((PBYTE)pNewStructure + cbHeader, ((PBYTE)(*ppStructure)) + cbHeader, cNow * cbElement);
110
111       // If there was one, free the old structure
112       //
113       if (*ppStructure)
114          Free (*ppStructure);
115       *ppStructure = pNewStructure;
116       }
117
118    return TRUE;
119 }
120
121
122 /*
123  * ROUTINES ___________________________________________________________________
124  *
125  */
126
127       // ASIDLIST - Managed type for lists of cell objects
128       //
129 LPASIDLIST AfsAdmSvr_CreateAsidList (void)
130 {
131    LPASIDLIST pList = NULL;
132    if (!RPC_REALLOC (ASIDLIST, pList, aEntries, cEntriesAllocated, 0, cREALLOC_ASIDLIST))
133       return NULL;
134    return pList;
135 }
136
137 LPASIDLIST AfsAdmSvr_CopyAsidList (LPASIDLIST pListSource)
138 {
139    LPASIDLIST pList = NULL;
140    if (!RPC_REALLOC (ASIDLIST, pList, aEntries, cEntriesAllocated, pListSource->cEntries, cREALLOC_ASIDLIST))
141       return NULL;
142    if (pList->cEntriesAllocated)
143       memcpy (pList->aEntries, pListSource->aEntries, sizeof(pList->aEntries[0]) * pList->cEntriesAllocated);
144    pList->cEntries = pListSource->cEntries;
145    return pList;
146 }
147
148 BOOL AfsAdmSvr_AddToAsidList (LPASIDLIST *ppList, ASID idObject, LPARAM lp)
149 {
150    if (!ppList || !*ppList)
151       return FALSE;
152
153    if (!RPC_REALLOC (ASIDLIST, *ppList, aEntries, cEntriesAllocated, (*ppList)->cEntries +1, cREALLOC_ASIDLIST))
154       return FALSE;
155
156    (*ppList)->aEntries[ (*ppList)->cEntries ].idObject = idObject;
157    (*ppList)->aEntries[ (*ppList)->cEntries ].lParam = lp;
158    (*ppList)->cEntries ++;
159    return TRUE;
160 }
161
162 BOOL AfsAdmSvr_RemoveFromAsidList (LPASIDLIST *ppList, ASID idObject)
163 {
164    if (!ppList || !(*ppList) || !(*ppList)->cEntries)
165       return FALSE;
166
167    BOOL fFound = FALSE;
168    for (ULONG iEntry = 0; iEntry < (*ppList)->cEntries; )
169       {
170       if ((*ppList)->aEntries[ iEntry ].idObject != idObject)
171          iEntry ++;
172       else if ((fFound = AfsAdmSvr_RemoveFromAsidListByIndex (ppList, iEntry)) == FALSE)
173          break;
174       }
175
176    return fFound;
177 }
178
179
180 BOOL AfsAdmSvr_RemoveFromAsidListByIndex (LPASIDLIST *ppList, size_t iIndex)
181 {
182    if (iIndex >= (*ppList)->cEntries)
183       return FALSE;
184
185    if (iIndex < (*ppList)->cEntries -1)
186       memcpy (&(*ppList)->aEntries[ iIndex ], &(*ppList)->aEntries[ (*ppList)->cEntries-1 ], sizeof((*ppList)->aEntries[0]));
187    (*ppList)->cEntries --;
188    return TRUE;
189 }
190
191
192 BOOL AfsAdmSvr_SetAsidListParam (LPASIDLIST *ppList, ASID idObject, LPARAM lp)
193 {
194    BOOL fFound = FALSE;
195    for (ULONG iEntry = 0; iEntry < (*ppList)->cEntries; ++iEntry)
196       {
197       if ((*ppList)->aEntries[ iEntry ].idObject == idObject)
198          {
199          (*ppList)->aEntries[ iEntry ].lParam = lp;
200          fFound = TRUE;
201          }
202       }
203    return fFound;
204 }
205
206
207 BOOL AfsAdmSvr_SetAsidListParamByIndex (LPASIDLIST *ppList, size_t iIndex, LPARAM lp)
208 {
209    if (iIndex >= (*ppList)->cEntries)
210       return FALSE;
211
212    (*ppList)->aEntries[ iIndex ].lParam = lp;
213    return TRUE;
214 }
215
216
217 BOOL AfsAdmSvr_IsInAsidList (LPASIDLIST *ppList, ASID idObject, LPARAM *pParam)
218 {
219    if (!ppList || !(*ppList) || !(*ppList)->cEntries)
220       return FALSE;
221
222    for (ULONG iEntry = 0; iEntry < (*ppList)->cEntries; ++iEntry)
223       {
224       if ((*ppList)->aEntries[ iEntry ].idObject == idObject)
225          {
226          if (pParam)
227             *pParam = (*ppList)->aEntries[ iEntry ].lParam;
228          return TRUE;
229          }
230       }
231
232    return FALSE;
233 }
234
235
236 void AfsAdmSvr_FreeAsidList (LPASIDLIST *ppList)
237 {
238    if (ppList && *ppList)
239       {
240       Free (*ppList);
241       (*ppList) = 0;
242       }
243 }
244
245
246       // ASOBJPROPLIST - Managed type for lists of cell objects
247       //
248 LPASOBJPROPLIST AfsAdmSvr_CreateObjPropList (void)
249 {
250    LPASOBJPROPLIST pList = NULL;
251    if (!RPC_REALLOC (ASOBJPROPLIST, pList, aEntries, cEntriesAllocated, 0, cREALLOC_OBJPROPLIST))
252       return NULL;
253    return pList;
254 }
255
256 LPASOBJPROPLIST AfsAdmSvr_CopyObjPropList (LPASOBJPROPLIST pListSource)
257 {
258    LPASOBJPROPLIST pList = NULL;
259    if (!RPC_REALLOC (ASOBJPROPLIST, pList, aEntries, cEntriesAllocated, pListSource->cEntries, cREALLOC_OBJPROPLIST))
260       return NULL;
261    if (pList->cEntriesAllocated)
262       memcpy (pList->aEntries, pListSource->aEntries, sizeof(pList->aEntries[0]) * pList->cEntriesAllocated);
263    pList->cEntries = pListSource->cEntries;
264    return pList;
265 }
266
267 BOOL AfsAdmSvr_AddToObjPropList (LPASOBJPROPLIST *ppList, LPASOBJPROP pProperties, LPARAM lp)
268 {
269    if (!ppList || !*ppList)
270       return FALSE;
271
272    if (!RPC_REALLOC (ASOBJPROPLIST, *ppList, aEntries, cEntriesAllocated, (*ppList)->cEntries +1, cREALLOC_OBJPROPLIST))
273       return NULL;
274
275    memcpy (&(*ppList)->aEntries[ (*ppList)->cEntries ].ObjectProperties, pProperties, sizeof(ASOBJPROP));
276    (*ppList)->aEntries[ (*ppList)->cEntries ].lParam = lp;
277    (*ppList)->cEntries ++;
278    return TRUE;
279 }
280
281 BOOL AfsAdmSvr_RemoveFromObjPropList (LPASOBJPROPLIST *ppList, ASID idObject)
282 {
283    if (!ppList || !(*ppList) || !(*ppList)->cEntries)
284       return FALSE;
285
286    BOOL fFound = FALSE;
287    for (ULONG iEntry = 0; iEntry < (*ppList)->cEntries; )
288       {
289       if ((*ppList)->aEntries[ iEntry ].ObjectProperties.idObject != idObject)
290          iEntry ++;
291       else
292          {
293          fFound = TRUE;
294          if (iEntry < (*ppList)->cEntries -1)
295             memcpy (&(*ppList)->aEntries[ iEntry ], &(*ppList)->aEntries[ (*ppList)->cEntries-1 ], sizeof((*ppList)->aEntries[0]));
296          (*ppList)->cEntries --;
297          }
298       }
299
300    return fFound;
301 }
302
303 BOOL AfsAdmSvr_IsInObjPropList (LPASOBJPROPLIST *ppList, ASID idObject, LPASOBJPROP pProperties, LPARAM *pParam)
304 {
305    if (!ppList || !(*ppList) || !(*ppList)->cEntries)
306       return FALSE;
307
308    for (ULONG iEntry = 0; iEntry < (*ppList)->cEntries; ++iEntry)
309       {
310       if ((*ppList)->aEntries[ iEntry ].ObjectProperties.idObject == idObject)
311          {
312          if (pProperties)
313             memcpy (pProperties, &(*ppList)->aEntries[ iEntry ].ObjectProperties, sizeof(ASOBJPROP));
314          if (pParam)
315             *pParam = (*ppList)->aEntries[ iEntry ].lParam;
316          return TRUE;
317          }
318       }
319
320    return FALSE;
321 }
322
323 void AfsAdmSvr_FreeObjPropList (LPASOBJPROPLIST *ppList)
324 {
325    if (ppList && *ppList)
326       {
327       Free (*ppList);
328       (*ppList) = 0;
329       }
330 }
331
332
333       // ASACTIONLIST - Managed type for lists of cell objects
334       //
335 LPASACTIONLIST AfsAdmSvr_CreateActionList (void)
336 {
337    LPASACTIONLIST pList = NULL;
338    if (!RPC_REALLOC (ASACTIONLIST, pList, aEntries, cEntriesAllocated, 0, cREALLOC_ACTIONLIST))
339       return NULL;
340    return pList;
341 }
342
343 LPASACTIONLIST AfsAdmSvr_CopyActionList (LPASACTIONLIST pListSource)
344 {
345    LPASACTIONLIST pList = NULL;
346    if (!RPC_REALLOC (ASACTIONLIST, pList, aEntries, cEntriesAllocated, pListSource->cEntries, cREALLOC_ACTIONLIST))
347       return NULL;
348    if (pList->cEntriesAllocated)
349       memcpy (pList->aEntries, pListSource->aEntries, sizeof(pList->aEntries[0]) * pList->cEntriesAllocated);
350    pList->cEntries = pListSource->cEntries;
351    return pList;
352 }
353
354 BOOL AfsAdmSvr_AddToActionList (LPASACTIONLIST *ppList, LPASACTION pAction)
355 {
356    if (!ppList || !*ppList)
357       return FALSE;
358
359    if (!RPC_REALLOC (ASACTIONLIST, *ppList, aEntries, cEntriesAllocated, (*ppList)->cEntries +1, cREALLOC_OBJPROPLIST))
360       return NULL;
361
362    memcpy (&(*ppList)->aEntries[ (*ppList)->cEntries ].Action, pAction, sizeof(ASACTION));
363    (*ppList)->cEntries ++;
364    return TRUE;
365 }
366
367 BOOL AfsAdmSvr_RemoveFromActionList (LPASACTIONLIST *ppList, DWORD idAction)
368 {
369    if (!ppList || !(*ppList) || !(*ppList)->cEntries)
370       return FALSE;
371
372    BOOL fFound = FALSE;
373    for (ULONG iEntry = 0; iEntry < (*ppList)->cEntries; )
374       {
375       if ((*ppList)->aEntries[ iEntry ].Action.idAction != idAction)
376          iEntry ++;
377       else
378          {
379          fFound = TRUE;
380          if (iEntry < (*ppList)->cEntries -1)
381             memcpy (&(*ppList)->aEntries[ iEntry ], &(*ppList)->aEntries[ (*ppList)->cEntries-1 ], sizeof((*ppList)->aEntries[0]));
382          (*ppList)->cEntries --;
383          }
384       }
385
386    return fFound;
387 }
388
389 BOOL AfsAdmSvr_IsInActionList (LPASACTIONLIST *ppList, DWORD idAction, LPASACTION pAction)
390 {
391    if (!ppList || !(*ppList) || !(*ppList)->cEntries)
392       return FALSE;
393
394    for (ULONG iEntry = 0; iEntry < (*ppList)->cEntries; ++iEntry)
395       {
396       if ((*ppList)->aEntries[ iEntry ].Action.idAction == idAction)
397          {
398          if (pAction)
399             memcpy (pAction, &(*ppList)->aEntries[ iEntry ].Action, sizeof(ASACTION));
400          return TRUE;
401          }
402       }
403
404    return FALSE;
405 }
406
407 void AfsAdmSvr_FreeActionList (LPASACTIONLIST *ppList)
408 {
409    if (ppList && *ppList)
410       {
411       Free (*ppList);
412       (*ppList) = 0;
413       }
414 }
415