Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

258 lines
6.8 KiB

  1. /* Copyright (C) Boris Nikolaus, Germany, 1996-1997. All rights reserved. */
  2. /* Copyright (C) Microsoft Corporation, 1997-1998. All rights reserved. */
  3. #include "precomp.h"
  4. /* --- NamedObjIdValue --- */
  5. /* constructor of NamedObjIdValue_t */
  6. NamedObjIdValue_t *NewNamedObjIdValue(NamedObjIdValue_e type)
  7. {
  8. NamedObjIdValue_t *ret;
  9. ret = (NamedObjIdValue_t *)malloc(sizeof(NamedObjIdValue_t));
  10. ret->Type = type;
  11. ret->Next = NULL;
  12. ret->Name = NULL;
  13. ret->Number = 0xffffffff;
  14. return ret;
  15. }
  16. /* copy constructor of NamedObjIdValue_t */
  17. NamedObjIdValue_t *DupNamedObjIdValue(NamedObjIdValue_t *src)
  18. {
  19. NamedObjIdValue_t *ret;
  20. if (!src)
  21. return NULL;
  22. ret = (NamedObjIdValue_t *)malloc(sizeof(NamedObjIdValue_t));
  23. *ret = *src;
  24. return ret;
  25. }
  26. /* --- AssignedObjIds --- */
  27. /* constructor of AssignedObjId_t */
  28. AssignedObjId_t *NewAssignedObjId()
  29. {
  30. AssignedObjId_t *ret;
  31. ret = (AssignedObjId_t *)malloc(sizeof(AssignedObjId_t));
  32. ret->Next = NULL;
  33. ret->Child = NULL;
  34. ret->Names = NULL;
  35. ret->Number = 0;
  36. return ret;
  37. }
  38. /* copy constructor of AssignedObjId_t */
  39. AssignedObjId_t *DupAssignedObjId(AssignedObjId_t *src)
  40. {
  41. AssignedObjId_t *ret;
  42. if (!src)
  43. return NULL;
  44. ret = (AssignedObjId_t *)malloc(sizeof(AssignedObjId_t));
  45. *ret = *src;
  46. return ret;
  47. }
  48. /* find an AssignedObjId_t by number in a list of AssignedObjId_t's */
  49. static AssignedObjId_t *FindAssignedObjIdByNumber(AssignedObjId_t *aoi, objectnumber_t number)
  50. {
  51. for (; aoi; aoi = aoi->Next) {
  52. if (aoi->Number == number)
  53. return aoi;
  54. }
  55. return NULL;
  56. }
  57. /* find an AssignedObjId_t by name in a list of AssignedObjId_t's */
  58. static AssignedObjId_t *FindAssignedObjIdByName(AssignedObjId_t *aoi, char *name)
  59. {
  60. String_t *names;
  61. for (; aoi; aoi = aoi->Next) {
  62. for (names = aoi->Names; names; names = names->Next) {
  63. if (!strcmp(names->String, name))
  64. return aoi;
  65. }
  66. }
  67. return NULL;
  68. }
  69. /* convert a NamedObjIdValue into an object identifier value */
  70. /* search for one NamedObjIdValue in AssignedObjIds; */
  71. /* returns -1 for bad NamedObjIdValue (names defined to different values), */
  72. /* returns 0 for unknown NamedObjIdValue (will probably be resolved in */
  73. /* the next pass), */
  74. /* returns 1 for success; */
  75. /* on success: */
  76. /* number contains the objectnumber, */
  77. /* aoi contains a duplicate of the AssignedObjIds for the found */
  78. /* NamedObjIdValue */
  79. static int GetObjectIdentifierNumber(AssignedObjId_t **aoi, NamedObjIdValue_t *val, objectnumber_t *number)
  80. {
  81. AssignedObjId_t *a, *a2;
  82. switch (val->Type) {
  83. case eNamedObjIdValue_NameForm:
  84. /* name form: search the assigned objid by name and return 0 if not */
  85. /* found */
  86. a2 = FindAssignedObjIdByName(*aoi, val->Name);
  87. if (!a2)
  88. return 0;
  89. /* otherwise create a duplicate */
  90. a = DupAssignedObjId(a2);
  91. a->Next = *aoi;
  92. *aoi = a;
  93. break;
  94. case eNamedObjIdValue_NumberForm:
  95. /* number form: search the assigned objid by number and create */
  96. /* a new one/a duplicate */
  97. a2 = FindAssignedObjIdByNumber(*aoi, val->Number);
  98. if (!a2) {
  99. a = NewAssignedObjId();
  100. a->Number = val->Number;
  101. a->Next = *aoi;
  102. *aoi = a;
  103. } else {
  104. a = DupAssignedObjId(a2);
  105. a->Next = *aoi;
  106. *aoi = a;
  107. }
  108. break;
  109. case eNamedObjIdValue_NameAndNumberForm:
  110. /* name and number form: search the assigned objid by name and by */
  111. /* number */
  112. a = FindAssignedObjIdByName(*aoi, val->Name);
  113. a2 = FindAssignedObjIdByNumber(*aoi, val->Number);
  114. /* successful but different results are errorneous */
  115. if (a && a != a2)
  116. return -1;
  117. if (!a && !a2) {
  118. /* found none, then create it */
  119. a = NewAssignedObjId();
  120. a->Number = val->Number;
  121. a->Names = NewString();
  122. a->Names->String = val->Name;
  123. a->Next = *aoi;
  124. *aoi = a;
  125. } else if (!a) {
  126. /* found only by number, then duplicate it and add the name */
  127. a = DupAssignedObjId(a2);
  128. a->Names = NewString();
  129. a->Names->String = val->Name;
  130. a->Names->Next = a2->Names;
  131. a->Next = *aoi;
  132. *aoi = a;
  133. } else {
  134. /* found only by name, then duplicate it */
  135. a = DupAssignedObjId(a2);
  136. a->Next = *aoi;
  137. *aoi = a;
  138. }
  139. break;
  140. }
  141. *number = a->Number;
  142. return 1;
  143. }
  144. /*
  145. * create a value out of NamedObjIdValues
  146. * returns -1 for bad NamedObjIdValue (names defined to different values),
  147. * returns 0 for unknown NamedObjIdValue (will probably be resolved next pass),
  148. * returns 1 for success;
  149. */
  150. int GetAssignedObjectIdentifier(AssignedObjId_t **aoi, Value_t *parent, NamedObjIdValueList_t named, Value_t **val)
  151. {
  152. Value_t *v;
  153. int parentl;
  154. int l;
  155. NamedObjIdValue_t *n;
  156. objectnumber_t *on;
  157. /* get length of object identifier */
  158. parentl = (parent ? parent->U.ObjectIdentifier.Value.length : 0);
  159. for (l = parentl, n = named; n; n = n->Next)
  160. {
  161. Value_t *pValue;
  162. pValue = (n->Type == eNamedObjIdValue_NameForm) ?
  163. GetDefinedOIDValue(n->Name) : NULL;
  164. if (pValue)
  165. {
  166. ASSERT(pValue->Type->Type == eType_ObjectIdentifier);
  167. l += pValue->U.ObjectIdentifier.Value.length;
  168. }
  169. else
  170. {
  171. l++;
  172. }
  173. }
  174. /* create the object identifier value */
  175. v = NewValue(NULL, Builtin_Type_ObjectIdentifier);
  176. v->U.ObjectIdentifier.Value.length = l;
  177. v->U.ObjectIdentifier.Value.value = on =
  178. (objectnumber_t *)malloc(l * sizeof(objectnumber_t));
  179. /* get the numbers of the parent object identifier and walk in the object */
  180. /* identifier tree */
  181. n = NewNamedObjIdValue(eNamedObjIdValue_NumberForm);
  182. for (l = 0; l < parentl; l++) {
  183. n->Number = parent->U.ObjectIdentifier.Value.value[l];
  184. switch (GetObjectIdentifierNumber(aoi, n, on + l)) {
  185. case -1:
  186. return -1;
  187. case 0:
  188. return 0;
  189. default:
  190. aoi = &(*aoi)->Child;
  191. break;
  192. }
  193. }
  194. /* get the numers from the namedobjidvaluelist */
  195. for (n = named; n; n = n->Next)
  196. {
  197. Value_t *pValue;
  198. pValue = (n->Type == eNamedObjIdValue_NameForm) ?
  199. GetDefinedOIDValue(n->Name) : NULL;
  200. if (pValue)
  201. {
  202. memcpy(on + l, pValue->U.ObjectIdentifier.Value.value,
  203. pValue->U.ObjectIdentifier.Value.length * sizeof(objectnumber_t));
  204. l += pValue->U.ObjectIdentifier.Value.length;
  205. }
  206. else
  207. {
  208. switch (GetObjectIdentifierNumber(aoi, n, on + l))
  209. {
  210. case -1:
  211. return -1;
  212. case 0:
  213. return 0;
  214. default:
  215. aoi = &(*aoi)->Child;
  216. break;
  217. }
  218. l++;
  219. }
  220. }
  221. *val = v;
  222. return 1;
  223. }