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.

182 lines
5.1 KiB

  1. #include "precomp.h"
  2. typedef struct _SERVICE_CACHE_ENTRY SERVICE_CACHE_ENTRY, *PSERVICE_CACHE_ENTRY;
  3. struct _SERVICE_CACHE_ENTRY {
  4. PIPX_SERVICE svc;
  5. PSERVICE_CACHE_ENTRY next;
  6. };
  7. #define NUM_SERVICE_CACHES 2
  8. #define CACHE_VALID_TIME 1800000000i64
  9. PSERVICE_CACHE_ENTRY ServiceCache[NUM_SERVICE_CACHES][48];
  10. LONGLONG ServiceCacheTimeStamp[NUM_SERVICE_CACHES] = {
  11. -CACHE_VALID_TIME,
  12. -CACHE_VALID_TIME};
  13. USHORT ServiceCacheType[NUM_SERVICE_CACHES];
  14. INT LastServiceCache = 0;
  15. DWORD
  16. GetNextServiceSorted (
  17. USHORT type,
  18. PUCHAR name,
  19. PIPX_SERVICE *pSvp
  20. ) {
  21. INT idx = strlen (name);
  22. LONGLONG CurTime;
  23. PIPX_SERVICE Svp;
  24. IPX_MIB_GET_INPUT_DATA MibGetInputData;
  25. DWORD rc;
  26. ULONG SvSize;
  27. INT i,j;
  28. MibGetInputData.TableId = IPX_SERV_TABLE;
  29. GetSystemTimeAsFileTime ((LPFILETIME)&CurTime);
  30. while (TRUE) {
  31. j = LastServiceCache;
  32. while (CurTime-ServiceCacheTimeStamp[j]<=CACHE_VALID_TIME) {
  33. INT j1;
  34. if (type==ServiceCacheType[j]) {
  35. for (i=idx; i<sizeof (ServiceCache[0])/sizeof (ServiceCache[0][0]); i++) {
  36. PSERVICE_CACHE_ENTRY cur=ServiceCache[j][i];
  37. while ((cur!=NULL) && (idx==i) && (strcmp (name,cur->svc->Server.Name)>=0))
  38. cur = cur->next;
  39. if (cur!=NULL) {
  40. *pSvp = cur->svc;
  41. return NO_ERROR;
  42. }
  43. }
  44. MibGetInputData.MibIndex.ServicesTableIndex.ServiceType = type;
  45. memset (MibGetInputData.MibIndex.ServicesTableIndex.ServiceName,
  46. 0xFF,
  47. sizeof (MibGetInputData.MibIndex.ServicesTableIndex.ServiceName)-1);
  48. MibGetInputData.MibIndex.ServicesTableIndex.ServiceName[
  49. sizeof (MibGetInputData.MibIndex.ServicesTableIndex.ServiceName)-1] = 0;
  50. rc = MprAdminMIBEntryGetNext(g_MibServerHandle,
  51. PID_IPX,
  52. IPX_PROTOCOL_BASE,
  53. &MibGetInputData,
  54. sizeof(IPX_MIB_GET_INPUT_DATA),
  55. &Svp,
  56. &SvSize);
  57. if (rc==NO_ERROR) {
  58. j = LastServiceCache;
  59. type = Svp->Server.Type;
  60. name = (PUCHAR)"\0";
  61. idx = 0;
  62. MprAdminMIBBufferFree (Svp);
  63. continue;
  64. }
  65. else
  66. return rc;
  67. }
  68. j1=(j+1)%NUM_SERVICE_CACHES;
  69. if (j1!=LastServiceCache)
  70. j = j1;
  71. else
  72. break;
  73. }
  74. MibGetInputData.MibIndex.ServicesTableIndex.ServiceType = type;
  75. MibGetInputData.MibIndex.ServicesTableIndex.ServiceName[0] = 1;
  76. MibGetInputData.MibIndex.ServicesTableIndex.ServiceName[1] = 0;
  77. rc = MprAdminMIBEntryGet(g_MibServerHandle,
  78. PID_IPX,
  79. IPX_PROTOCOL_BASE,
  80. &MibGetInputData,
  81. sizeof(IPX_MIB_GET_INPUT_DATA),
  82. &Svp,
  83. &SvSize);
  84. if (rc!=NO_ERROR)
  85. rc = MprAdminMIBEntryGetNext(g_MibServerHandle,
  86. PID_IPX,
  87. IPX_PROTOCOL_BASE,
  88. &MibGetInputData,
  89. sizeof(IPX_MIB_GET_INPUT_DATA),
  90. &Svp,
  91. &SvSize);
  92. if (rc!=NO_ERROR)
  93. return rc;
  94. do {
  95. for (i=0; i<sizeof (ServiceCache[0])/sizeof (ServiceCache[0][0]); i++) {
  96. PSERVICE_CACHE_ENTRY cur;
  97. while (ServiceCache[j][i]!=NULL) {
  98. cur = ServiceCache[j][i];
  99. MprAdminMIBBufferFree (cur->svc);
  100. ServiceCache[j][i] = cur->next;
  101. free (cur);
  102. }
  103. }
  104. ServiceCacheTimeStamp[j] = CurTime-CACHE_VALID_TIME;
  105. j = (j+1)%NUM_SERVICE_CACHES;
  106. if (j==LastServiceCache)
  107. break;
  108. }
  109. while (CurTime-ServiceCacheTimeStamp[j]>CACHE_VALID_TIME);
  110. j = (j+(NUM_SERVICE_CACHES-1))%NUM_SERVICE_CACHES;
  111. MibGetInputData.MibIndex.ServicesTableIndex.ServiceType = Svp->Server.Type;
  112. do {
  113. PSERVICE_CACHE_ENTRY cur;
  114. cur = (PSERVICE_CACHE_ENTRY)malloc (sizeof (SERVICE_CACHE_ENTRY));
  115. if (cur!=NULL) {
  116. i = strlen ((PCHAR)Svp->Server.Name);
  117. cur->svc = Svp;
  118. cur->next = ServiceCache[j][i];
  119. ServiceCache[j][i] = cur;
  120. }
  121. else {
  122. MprAdminMIBBufferFree (Svp);
  123. return ERROR_NOT_ENOUGH_MEMORY;
  124. }
  125. strcpy (
  126. (PCHAR)MibGetInputData.MibIndex.ServicesTableIndex.ServiceName,
  127. (PCHAR)Svp->Server.Name);
  128. rc = MprAdminMIBEntryGetNext(g_MibServerHandle,
  129. PID_IPX,
  130. IPX_PROTOCOL_BASE,
  131. &MibGetInputData,
  132. sizeof(IPX_MIB_GET_INPUT_DATA),
  133. &Svp,
  134. &SvSize);
  135. }
  136. while ((rc==NO_ERROR)
  137. && (Svp->Server.Type==MibGetInputData.MibIndex.ServicesTableIndex.ServiceType));
  138. if (rc==NO_ERROR)
  139. MprAdminMIBBufferFree (Svp);
  140. Svp = NULL;
  141. for (i=0; i<sizeof (ServiceCache[0])/sizeof (ServiceCache[0][0]); i++) {
  142. PSERVICE_CACHE_ENTRY cur,prev=ServiceCache[j][i];
  143. ServiceCache[j][i] = NULL;
  144. while (prev!=NULL) {
  145. cur = prev;
  146. prev = cur->next;
  147. cur->next = ServiceCache[j][i];
  148. ServiceCache[j][i] = cur;
  149. }
  150. if ((type<MibGetInputData.MibIndex.ServicesTableIndex.ServiceType)
  151. && (Svp==NULL) && (ServiceCache[j][i]!=NULL))
  152. Svp = ServiceCache[j][i]->svc;
  153. }
  154. GetSystemTimeAsFileTime ((LPFILETIME)&CurTime);
  155. ServiceCacheTimeStamp[j] = CurTime;
  156. ServiceCacheType[j] = MibGetInputData.MibIndex.ServicesTableIndex.ServiceType;
  157. LastServiceCache = j;
  158. if (Svp!=NULL) {
  159. *pSvp = Svp;
  160. return NO_ERROR;
  161. }
  162. }
  163. }