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