183 lines
4.9 KiB
C
183 lines
4.9 KiB
C
|
#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; i<sizeof (ServiceCache[0])/sizeof (ServiceCache[0][0]); i++) {
|
||
|
PSERVICE_CACHE_ENTRY cur=ServiceCache[j][i];
|
||
|
while ((cur!=NULL) && (idx==i) && (strcmp (name,cur->svc->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; i<sizeof (ServiceCache[0])/sizeof (ServiceCache[0][0]); i++) {
|
||
|
PSERVICE_CACHE_ENTRY cur;
|
||
|
while (ServiceCache[j][i]!=NULL) {
|
||
|
cur = ServiceCache[j][i];
|
||
|
MprAdminMIBBufferFree (cur->svc);
|
||
|
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; i<sizeof (ServiceCache[0])/sizeof (ServiceCache[0][0]); i++) {
|
||
|
PSERVICE_CACHE_ENTRY cur,prev=ServiceCache[j][i];
|
||
|
ServiceCache[j][i] = NULL;
|
||
|
while (prev!=NULL) {
|
||
|
cur = prev;
|
||
|
prev = cur->next;
|
||
|
cur->next = ServiceCache[j][i];
|
||
|
ServiceCache[j][i] = cur;
|
||
|
}
|
||
|
if ((type<MibGetInputData.MibIndex.ServicesTableIndex.ServiceType)
|
||
|
&& (Svp==NULL) && (ServiceCache[j][i]!=NULL))
|
||
|
Svp = ServiceCache[j][i]->svc;
|
||
|
}
|
||
|
|
||
|
GetSystemTimeAsFileTime ((LPFILETIME)&CurTime);
|
||
|
ServiceCacheTimeStamp[j] = CurTime;
|
||
|
ServiceCacheType[j] = MibGetInputData.MibIndex.ServicesTableIndex.ServiceType;
|
||
|
LastServiceCache = j;
|
||
|
|
||
|
if (Svp!=NULL) {
|
||
|
*pSvp = Svp;
|
||
|
return NO_ERROR;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|