#include "precomp.h" typedef struct _SERVICE_CACHE_ENTRY SERVICE_CACHE_ENTRY, *PSERVICE_CACHE_ENTRY; struct _SERVICE_CACHE_ENTRY { PIPX_SERVICE svc; PSERVICE_CACHE_ENTRY next; }; #define NUM_SERVICE_CACHES 2 #define CACHE_VALID_TIME 1800000000i64 PSERVICE_CACHE_ENTRY ServiceCache[NUM_SERVICE_CACHES][48]; LONGLONG ServiceCacheTimeStamp[NUM_SERVICE_CACHES] = { -CACHE_VALID_TIME, -CACHE_VALID_TIME}; USHORT ServiceCacheType[NUM_SERVICE_CACHES]; INT LastServiceCache = 0; DWORD GetNextServiceSorted ( USHORT type, PUCHAR name, PIPX_SERVICE *pSvp ) { INT idx = strlen (name); LONGLONG CurTime; PIPX_SERVICE Svp; IPX_MIB_GET_INPUT_DATA MibGetInputData; DWORD rc; ULONG SvSize; INT i,j; MibGetInputData.TableId = IPX_SERV_TABLE; GetSystemTimeAsFileTime ((LPFILETIME)&CurTime); while (TRUE) { j = LastServiceCache; while (CurTime-ServiceCacheTimeStamp[j]<=CACHE_VALID_TIME) { INT j1; if (type==ServiceCacheType[j]) { for (i=idx; isvc->Server.Name)>=0)) cur = cur->next; if (cur!=NULL) { *pSvp = cur->svc; return NO_ERROR; } } MibGetInputData.MibIndex.ServicesTableIndex.ServiceType = type; memset (MibGetInputData.MibIndex.ServicesTableIndex.ServiceName, 0xFF, sizeof (MibGetInputData.MibIndex.ServicesTableIndex.ServiceName)-1); MibGetInputData.MibIndex.ServicesTableIndex.ServiceName[ sizeof (MibGetInputData.MibIndex.ServicesTableIndex.ServiceName)-1] = 0; rc = MprAdminMIBEntryGetNext(g_MibServerHandle, PID_IPX, IPX_PROTOCOL_BASE, &MibGetInputData, sizeof(IPX_MIB_GET_INPUT_DATA), &Svp, &SvSize); if (rc==NO_ERROR) { j = LastServiceCache; type = Svp->Server.Type; name = (PUCHAR)"\0"; idx = 0; MprAdminMIBBufferFree (Svp); continue; } else return rc; } j1=(j+1)%NUM_SERVICE_CACHES; if (j1!=LastServiceCache) j = j1; else break; } MibGetInputData.MibIndex.ServicesTableIndex.ServiceType = type; MibGetInputData.MibIndex.ServicesTableIndex.ServiceName[0] = 1; MibGetInputData.MibIndex.ServicesTableIndex.ServiceName[1] = 0; rc = MprAdminMIBEntryGet(g_MibServerHandle, PID_IPX, IPX_PROTOCOL_BASE, &MibGetInputData, sizeof(IPX_MIB_GET_INPUT_DATA), &Svp, &SvSize); if (rc!=NO_ERROR) rc = MprAdminMIBEntryGetNext(g_MibServerHandle, PID_IPX, IPX_PROTOCOL_BASE, &MibGetInputData, sizeof(IPX_MIB_GET_INPUT_DATA), &Svp, &SvSize); if (rc!=NO_ERROR) return rc; do { for (i=0; isvc); ServiceCache[j][i] = cur->next; free (cur); } } ServiceCacheTimeStamp[j] = CurTime-CACHE_VALID_TIME; j = (j+1)%NUM_SERVICE_CACHES; if (j==LastServiceCache) break; } while (CurTime-ServiceCacheTimeStamp[j]>CACHE_VALID_TIME); j = (j+(NUM_SERVICE_CACHES-1))%NUM_SERVICE_CACHES; MibGetInputData.MibIndex.ServicesTableIndex.ServiceType = Svp->Server.Type; do { PSERVICE_CACHE_ENTRY cur; cur = (PSERVICE_CACHE_ENTRY)malloc (sizeof (SERVICE_CACHE_ENTRY)); if (cur!=NULL) { i = strlen ((PCHAR)Svp->Server.Name); cur->svc = Svp; cur->next = ServiceCache[j][i]; ServiceCache[j][i] = cur; } else { MprAdminMIBBufferFree (Svp); return ERROR_NOT_ENOUGH_MEMORY; } strcpy ( (PCHAR)MibGetInputData.MibIndex.ServicesTableIndex.ServiceName, (PCHAR)Svp->Server.Name); rc = MprAdminMIBEntryGetNext(g_MibServerHandle, PID_IPX, IPX_PROTOCOL_BASE, &MibGetInputData, sizeof(IPX_MIB_GET_INPUT_DATA), &Svp, &SvSize); } while ((rc==NO_ERROR) && (Svp->Server.Type==MibGetInputData.MibIndex.ServicesTableIndex.ServiceType)); if (rc==NO_ERROR) MprAdminMIBBufferFree (Svp); Svp = NULL; for (i=0; inext; cur->next = ServiceCache[j][i]; ServiceCache[j][i] = cur; } if ((typesvc; } GetSystemTimeAsFileTime ((LPFILETIME)&CurTime); ServiceCacheTimeStamp[j] = CurTime; ServiceCacheType[j] = MibGetInputData.MibIndex.ServicesTableIndex.ServiceType; LastServiceCache = j; if (Svp!=NULL) { *pSvp = Svp; return NO_ERROR; } } }