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