i'm not very good on c++ and i got to develop a dll for our lotus domino server.
the problem i have is, when the dll is called about 1000 times the http-task of the domino server crashes whith following error message on the server console:
"MemAlloc: OUT OF PRIVATE HANDLES! -- pid 000004F4 Handles used so far 16953, Maximum handles = 10495"
here's the code of my dll
i think that my mistake is, that i use goto's when an error appears and i don't free the memory.
--------------------------
----------
----------
----------
----------
----------
----------
----------
----------
--------
#include <stdlib.h>
#include <stdio.h>
// Lotus C API for Domino and Notes Header files.
#include <global.h>
#include <editods.h>
#include <osmem.h>
#include <schgtw.h>
#include <textlist.h>
#include <lapiplat.h>
// Header file.
#include "busytime2.h"
/*************************
**********
**********
**********
**********
*******
DLL Main
**************************
**********
**********
**********
**********
*******/
BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved){
switch (ul_reason_for_call){
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
/*************************
**********
**********
**********
**********
********
Initializing Notes
**************************
**********
**********
**********
**********
*******/
BUSYTIME_DLL_API int Start_Notes (char *exepath, char *inipath) {
STATUS sError;
char *argv[2];
//Umschlüsseln der Parameter
argv[0] = exepath;
argv[1] = inipath;
//Notesinitialisierung
sError = NotesInitExtended(2, argv);
// Errorhandling
if (sError != NOERROR) {
LAPI_RETURN(2);
} else {
LAPI_RETURN(0);
}
}
/*************************
**********
**********
**********
**********
********
Wrapper function to exit from Domino and Notes.
**************************
**********
**********
**********
**********
*******/
BUSYTIME_DLL_API void Stop_Notes (void) {
NotesTerm();
}
/*************************
**********
**********
**********
**********
********
Write Busytimes to File
**************************
**********
**********
**********
**********
*******/
BUSYTIME_DLL_API int BusyTimeToFile (char *szUser, char *startTime, char *endTime, char *fname) {
//Declarations
char *theSchedList;
int retcode=0;
int laenge=0;
int i;
int anzuser=0;
int anzschedules=0;
char szMyUser[256]="";
char *tmpUser=szUser;
char *tmpStartTime;
char *tmpEndTime;
int zaehler=0;
//Filepointers
FILE *fz;
//
VOID *list_ptr;
WORD list_size;
DWORD retdwSize;
//Notestypes
STATUS sError = NOERROR; //typedef WORD STATUS;
UNID apptUnid; //#define UNID UNIVERSALNOTEID
HCNTNR schListCntnr = NULLHANDLE; //typedef HANDLE HCNTNR; [ void LNPUBLIC SchContainer_Free(HCNTNR hCntnr); ]
HCNTNROBJ schedObj; //typedef DWORD HCNTNROBJ;
HCNTNROBJ nextSchedObj;
HCNTNROBJ hMoreObj = NULLCNTNROBJ;
TIMEDATE_PAIR interval; //typedef struct {TIMEDATE Lower;TIMEDATE Upper;} TIMEDATE_PAIR;
TIMEDATE_PAIR pInterval;
SCHEDULE *nextSchedule; //typedef struct {DWORD reserved[8]; DBID dbReplicaID; TIMEDATE_PAIR Interval; DWORD dwErrGateway; STATUS error; WORD wReserved; WORD wOwnerNameSize; } SCHEDULE;
SCHEDULE *pSchedule;
HANDLE list_handle; //typedef unsigned int HANDLE; [ OSMemAlloc / OSMemFree ]
HANDLE rethSchedList;
//try to open file
if ((fz=fopen(fname,"w"))==NU
LL) {
retcode=1;
goto done;
} else {
sError = ListAllocate (0, 0, FALSE, &list_handle, &list_ptr, &list_size);
if (sError != NOERROR)
goto NError;
i=0;
while (*tmpUser!='\0') {
if (i>=256) {
retcode=2;
goto done;
}
if(*tmpUser!=',') {
szMyUser[i++]=*tmpUser;
} else {
szMyUser[i++]='\0';
anzuser++;
sError = ListAddEntry(list_handle, FALSE, &list_size, (WORD) anzuser, szMyUser, (WORD) strlen(szMyUser));
if (sError != NOERROR)
goto NError;
i=0;
}
tmpUser++;
}
//add last user
szMyUser[i]='\0';
anzuser++;
sError = ListAddEntry(list_handle, FALSE, &list_size, (WORD) anzuser, szMyUser, (WORD) strlen(szMyUser));
if (sError != NOERROR)
goto NError;
//Convert Start and Endtime to Notesdatetime
tmpStartTime = startTime;
tmpEndTime = endTime;
sError = ConvertTextToTIMEDATE(NULL
, NULL, &tmpStartTime, (WORD) strlen(startTime), &interval.Lower);
if (sError != NOERROR)
goto NError;
sError = ConvertTextToTIMEDATE(NULL
, NULL, &tmpEndTime, (WORD) strlen(endTime), &interval.Upper);
if (sError != NOERROR)
goto NError;
//Get Schedules
OSUnlockObject(list_handle
);
list_ptr = OSLockObject(list_handle);
sError = SchRetrieve(&apptUnid, NULL, SCHRQST_FORCEREMOTE|SCHRQS
T_EACHPERS
ON,&interv
al,(LIST *)list_ptr, &schListCntnr, NULL, NULL, NULL);
if (sError != NOERROR)
goto NError;
// going through the schedules
while (sError == NOERROR) {
zaehler++;
//beginn
if (anzschedules==0) {
// first schedule
sError = SchContainer_GetFirstSched
ule(schLis
tCntnr, &schedObj, &pSchedule);
if (sError != NOERROR)
goto NError;
memcpy (szMyUser,pSchedule + 1 ,pSchedule->wOwnerNameSize
);
}else {
// next schedule
sError = SchContainer_GetNextSchedu
le(schList
Cntnr, schedObj, &nextSchedObj, &nextSchedule);
if (sError != NOERROR)
goto NError;
schedObj=nextSchedObj;
memcpy (szMyUser,nextSchedule + 1 ,nextSchedule->wOwnerNameS
ize);
}
//* extract the list
sError = Schedule_ExtractSchedList(
schListCntnr, schedObj, &pInterval, (unsigned long *) &retdwSize, &rethSchedList, &hMoreObj);
if (sError == NOERROR) {
anzschedules++;
fprintf(fz,"#\n");
fprintf(fz,"%s\n",szMyUser
);
theSchedList=(char *)OSLockObject(rethSchedLi
st);
// ... und in ein Stringarray hinzufügen
DumpTextSchedEntryListToFi
le(theSche
dList,fz);
OSUnlockObject(rethSchedLi
st);
} else if (sError==1002 && zaehler<anzuser) {
sError=NO_ERROR;
}else {
goto NError;
}
}
//* Free all handles
//OSUnlockObject(theSchedL
ist);
//OSMemFree(theSchedList);
OSUnlockObject(list_handle
);
OSMemFree(list_handle);
OSUnlockObject(rethSchedLi
st);
OSMemFree(rethSchedList);
Schedule_Free(schListCntnr
,schedObj)
;
SchContainer_Free(schListC
ntnr);
}
NError:
retcode=0;
if (sError!=NO_ERROR && sError!=1006 && sError!=1002) {
retcode=2;
} else if (anzuser!=anzschedules) {
retcode=1;
}
done:
fclose(fz);
LAPI_RETURN(retcode);
}
/*************************
**********
**********
**********
**********
*******
FUNCTION: DumpTextSchedEntryListToFi
le
**************************
**********
**********
**********
**********
*******/
void LNPUBLIC DumpTextSchedEntryListToFi
le(char *pSchedList, FILE *fz) {
//Declaration
int num=0;
int i=0;
char szLowerTD[MAXALPHATIMEDATE
+1];
char szUpperTD[MAXALPHATIMEDATE
+1];
//Notesdatatypes
SCHED_LIST SchedList; //typedef struct { DWORD NumEntries; WORD wApplicationID; WORD Spare; } SCHED_LIST;
SCHED_ENTRY SchedEntry; //typedef struct { UNID Unid; TIMEDATE_PAIR Interval; BYTE Attr; BYTE UserAttr; BYTE spare[2];} SCHED_ENTRY;
memcpy( (char*)&SchedList, pSchedList, sizeof(SCHED_LIST) );
pSchedList += sizeof(SCHED_LIST);
num = SchedList.NumEntries;
//fprintf(fz,"next\n");
for (i=0;i<num;i++) {
memcpy((char *)&SchedEntry, pSchedList, sizeof(SCHED_ENTRY) );
//Check if busy
if (SCHED_ATTR_AVAILABLE(Sche
dEntry.Att
r)==FALSE)
{
GetTDString( &(SchedEntry).Interval.Low
er, szLowerTD );
GetTDString( &(SchedEntry).Interval.Upp
er, szUpperTD );
fprintf(fz,"%s-%s\n",szLow
erTD,szUpp
erTD);
}
pSchedList += sizeof(SCHED_ENTRY);
}
}
/*************************
**********
**********
**********
**********
*******
FUNCTION: GetTDString
**************************
**********
**********
**********
**********
*******/
void LNPUBLIC GetTDString( TIMEDATE * ptdModified, char * szTimedate )
{
WORD wLen;
ConvertTIMEDATEToText( NULL, NULL, ptdModified, szTimedate, MAXALPHATIMEDATE, &wLen );
szTimedate[wLen] = '\0';
return;
}
--------------------------
----------
----------
----------
----------
----------
----------
----------
----------
--------
Start Free Trial