#include #include #include #include "wrapper.h" #include "ddestrs.h" #ifdef WIN16 #include #endif extern BOOL fServer; extern BOOL fClient; extern INT iAvailFormats[]; extern BOOL UpdateCount(HWND,INT,INT); extern LPSTR pszNetName; extern HANDLE hmemNet; BOOL IsTopicNameFromNetDde(LPSTR,LPSTR); BOOL FixForNetDdeStartup(HWND,LPSTR); BOOL FixForStressPercentage(HWND,LPSTR); BOOL SetStress(HWND,LONG); /***************************************************************************\ * * InitArgsError * \***************************************************************************/ VOID InitArgsError(HWND hwnd, unsigned at) { /* This function informs the user of an error. */ static char *mpatszError[] = { "DdeStrs.Exe -- Invalid command line\r\nTry DdeStrs -5% for standard run or DdeStrs -? for help", "DdeStrs.Exe -- Invalid number, possibly missing option value", "DdeStrs.Exe -- Invalid log level", "DdeStrs.Exe -- Invalid number of test to execute", "DdeStrs.Exe -- Invalid starting test number" }; MessageBox(NULL,mpatszError[at],"Error:DdeStrs",MB_OK|MB_ICONEXCLAMATION); } /***************************************************************************\ * * SysTime - This routine is intended to hide the differences between * the 16 bit time routines and win 32. All time queries * come through this point. * \***************************************************************************/ VOID SysTime( LPSYSTEMTIME lpst ) { #ifdef WIN32 GetSystemTime( lpst ); #else time_t t; struct tm ttmm; struct tm far *ptm=&ttmm; t=time(&t); ptm=localtime(&t); lpst->wYear =ptm->tm_year; lpst->wMonth =ptm->tm_mon; lpst->wDayOfWeek =ptm->tm_wday; lpst->wDay =ptm->tm_yday; lpst->wHour =ptm->tm_hour; lpst->wMinute =ptm->tm_min; lpst->wSecond =ptm->tm_sec; lpst->wMilliseconds =0; #endif } /************************** Private Function ****************************\ * * ParseCommandLine - This routine controls parsing the command line and * initializing command line settings. * \**************************************************************************/ BOOL ParseCommandLine( HWND hwnd, LPSTR lpcmd ) { SYSTEMTIME t; LPSYSTEMTIME lptime=&t; LONG lflags=0L; INT i,nThrd,num,nFmts; BOOL fSelect=FALSE; #ifdef WIN32 LPCRITICAL_SECTION lpcs; HANDLE hmem; #endif // Defaults SetWindowLong(hwnd,OFFSET_FLAGS,FLAG_AUTO); SetWindowLong(hwnd,OFFSET_RUNTIME,_1WEEKEND); SetWindowLong(hwnd,OFFSET_STRESS,5L); SetWindowLong(hwnd,OFFSET_DELAY,(100-GetWindowLong(hwnd,OFFSET_STRESS))*DELAY_METRIC); SetWindowLong(hwnd,OFFSET_TIME_ELAPSED,0L); SetWindowLong(hwnd,OFFSET_THRDCOUNT,1L); SetWindowLong(hwnd,OFFSET_CRITICALSECT,0L); if(!get_cmd_arg(hwnd,lpcmd)) return FALSE; // We need to make a change at this point for the // default client/server settings. If at this point // fClient==fServer==FALSE then we want to turn on // both of these as the default. if(!fClient && !fServer) { fClient=TRUE; fServer=TRUE; } // We need to check to see if specific formats where // specified. If not then select all of them. nFmts=0; for(i=0;iwSecond); SetWindowLong(hwnd,OFFSET_STARTTIME_MIN,lptime->wMinute); SetWindowLong(hwnd,OFFSET_STARTTIME_HOUR,lptime->wHour); SetWindowLong(hwnd,OFFSET_STARTTIME_DAY,lptime->wDay); SetWindowLong(hwnd,OFFSET_LAST_MIN,lptime->wMinute); SetWindowLong(hwnd,OFFSET_LAST_HOUR,lptime->wHour); SetWindowLong(hwnd,OFFSET_TIME_ELAPSED,0L); #ifdef WIN32 /* Setup our critical section if in multi-thread mode */ lflags=GetWindowLong(hwnd,OFFSET_FLAGS); if(lflags&FLAG_MULTTHREAD) { hmem=GetMemHandle(sizeof(CRITICAL_SECTION)); lpcs=GlobalLock(hmem); InitializeCriticalSection(lpcs); GlobalUnlock(hmem); SetWindowLong(hwnd,OFFSET_CRITICALSECT,(LONG)hmem); } #endif return TRUE; } /***************************************************************************\ * * SetupArgv - This is a conversion routine to go from the window worlds * command line format to the more standard argv, argc * format. The routine get_cmd_arg was setup for the * argv/argc format. * \***************************************************************************/ int SetupArgv( char *argv[], char *buff, LPSTR cmdline ) { int i=1; while( *cmdline != '\0' ) { argv[i] = &buff[0]; while ( *cmdline != ' ' && *cmdline != '\0') *buff++ = *cmdline++; *buff++='\0'; while(*cmdline == ' ') cmdline++; i++; } return i; } /***************************************************************************\ * * get_cmd_arg - This routine parses a argv\argc formatted command * line and stores away the values. * \***************************************************************************/ BOOL PASCAL get_cmd_arg( HWND hwnd, LPSTR cmdline ) { /* This function parses the command line for valid options. TRUE is returned if all of the options are valid; otherwise, FALSE is returned. */ char *pch; int iarg; unsigned at = AT_SWITCH; unsigned num; int argc; char *argv[10]; char buff[200]; LONG lflags=0L; #ifdef WIN32 int nThrd; #endif FixForStressPercentage(hwnd,cmdline); FixForNetDdeStartup(hwnd,cmdline); argc = SetupArgv( argv, buff, cmdline ); /* Iterate over the arguments in the command line. */ iarg=1; while(iarg0 && num<=NUM_FORMATS) { iAvailFormats[num-1]=1; } break; case AT_STRESS: SetStress(hwnd,num); break; case AT_DELAY: SetWindowLong(hwnd,OFFSET_DELAY,num); lflags=GetWindowLong(hwnd,OFFSET_FLAGS); SetWindowLong(hwnd,OFFSET_FLAGS,FLAGON(lflags,FLAG_USRDELAY)); break; case AT_TIME: SetWindowLong(hwnd,OFFSET_RUNTIME,num); break; case AT_THRD: #ifdef WIN32 if(num>THREADLIMIT) num=THREADLIMIT; // One is not really Mult-thread, shutoff the thread // code and run in normal form. if(num==1) { lflags=GetWindowLong(hwnd,OFFSET_FLAGS); lflags=FLAGOFF(lflags,FLAG_MULTTHREAD); lflags=FLAGON(lflags,FLAG_USRTHRDCOUNT); SetWindowLong(hwnd,OFFSET_FLAGS,lflags); SetWindowLong(hwnd,OFFSET_THRDCOUNT,num); } else { SetWindowLong(hwnd,OFFSET_THRDCOUNT,num); lflags=GetWindowLong(hwnd,OFFSET_FLAGS); SetWindowLong(hwnd,OFFSET_FLAGS,FLAGON(lflags,FLAG_USRTHRDCOUNT)); } #endif break; default: InitArgsError(hwnd,0); return FALSE; break; } //switch (inside) /* The next argument should be a switch. */ at = AT_SWITCH; break; } // switch (outside) NextArg:; iarg++; } // While loop /* Are we still looking for a filename or number? */ if (at != AT_SWITCH) { /* Tell the user about the filename or number not found. */ InitArgsError(hwnd,0); return FALSE; } return TRUE; } // end get_cmd_args /***************************************************************************\ * * SetStress * \***************************************************************************/ BOOL SetStress(HWND hwnd, LONG num) { LONG lflags; #ifdef WIN32 LONG l; #endif INT n; lflags=GetWindowLong(hwnd,OFFSET_FLAGS); SetWindowLong(hwnd,OFFSET_STRESS,num); #ifdef WIN32 if(!(lflags&FLAG_USRTHRDCOUNT)) { l=S2L(DIV(num,20)+1); if(num>9 && num<20) l++; if(l>5) l=5; if(l<1) l=1; SetWindowLong(hwnd,OFFSET_THRDCOUNT,l); if(l>1) { lflags=GetWindowLong(hwnd,OFFSET_FLAGS); SetWindowLong(hwnd,OFFSET_FLAGS,FLAGON(lflags,FLAG_MULTTHREAD)); } } #endif if(!(lflags&FLAG_USRDELAY)) { n=(int)(100-num)*DELAY_METRIC; SetWindowLong(hwnd,OFFSET_DELAY,n); // since dde messages have highest priority we don't // want to swamp the system. Always have some // minimal delay. if(n<10) { SetWindowLong(hwnd,OFFSET_DELAY,10); lflags=GetWindowLong(hwnd,OFFSET_FLAGS); SetWindowLong(hwnd,OFFSET_FLAGS,FLAGOFF(lflags,FLAG_DELAYON)); } } return TRUE; } /******************************************************************\ * TStrLen * 11/20/88 * * Finds the length of a string \******************************************************************/ INT TStrLen( LPSTR pStr ) { INT len = 0; while( *pStr++!='\0' ) len++; return( len ); } /******************************************************************\ * TStrCat * 7/16/92 * * Appends source string to destination string. Source string and * destination string must be zero terminated! \******************************************************************/ LPSTR TStrCat( LPSTR dest, LPSTR source) { LPSTR start_source; LPSTR start_dest; INT i=0; /* If we have a NULL pointer set destination to NULL and continue */ if (!dest || !source) { MessageBox(NULL,"TStrCat - NULL ptr for dest or source string!","Error : WmStress",MB_ICONEXCLAMATION); return NULL; } start_dest = dest; start_source = source; while (*dest++!='\0' && i++<=MAX_TITLE_LENGTH) ; TStrCpy(dest,source); source = start_source; dest = start_dest; return( start_dest ); } /*************************** Private Function ******************************\ * * TStrCmp * * Compares two NULL terminated strings ( returns TRUE if equal ) * \***************************************************************************/ BOOL TStrCmp(LPSTR s, LPSTR t) { // Valid pointer? if ( !s && !t ) return TRUE; // If either is NULL then they should if ( (!s&&t)||(s&&!t) ) // both be NULL. Otherwise error. return FALSE; for (; *s == *t; s++, t++) // Compare strings if (*s=='\0') return TRUE; if ((*s-*t)== 0) return TRUE; else return FALSE; } /******************************************************************\ * TStrCpy * 11/20/88 * * Copies a string from source to destination \******************************************************************/ LPSTR TStrCpy( LPSTR dest, LPSTR source) { LPSTR start_source; LPSTR start_dest; INT i; /* If we have a NULL pointer set destination to NULL and continue */ if(!source) { dest=NULL; return NULL; } if (!dest) { MessageBox(NULL,"TStrCpy - NULL ptr for dest!","Error:WmStress",MB_ICONEXCLAMATION); return NULL; } start_dest = dest; start_source = source; i=0; while (*dest++ = *source++){ i++; } source = start_source; dest = start_dest; return( start_dest ); } /***************************************************************************\ * * FixForStressPercentage - This is a fix for the command line -5%. The * origional get_cmd_args() did not handle this * case. This routine handles string modifications * to the command line parse will be correct. * \***************************************************************************/ BOOL FixForStressPercentage(HWND hwnd, LPSTR lpszStart ) { CHAR ac[6]; INT i; LPSTR lpsz,lpszdash; BOOL bLastTime; lpsz =lpszStart; lpszdash =NULL; ac[0]='x'; while(*lpsz!='\0') { if( *lpsz=='-') lpszdash=lpsz; if( *lpsz=='%') { if(lpszdash==NULL) return FALSE; else lpsz=(LPSTR)(lpszdash+1); // Basically what we do hear is replace the '%' by an 'x' // and shift characters...(-60% becomes -x60). i=0; bLastTime=FALSE; while(!bLastTime) { ac[i+1]=*lpsz; if(*lpsz=='%') bLastTime=TRUE; *lpsz=ac[i]; lpsz++; i++; } } // if lpsz++; } // while return TRUE; hwnd; } // FixForStressPercentage /***************************************************************************\ * * FixForNetDdeStartup - This is a fix for the command line "Test". The * origional get_cmd_args() did not handle this * case. This routine modifies the string from * "Test" to "-s". * * The reason for this change is to make ddestrs.exe * netdde aware for the startup situation. When * netdde starts up the application is passed the topic * name (in this case Test) to the application on the * command line. * * NOTE!!! The below code relies on TOPIC="Test". If this has changed then * update FixForNetDdeStartup() and IsTopicNameFromNetDde(). * \***************************************************************************/ BOOL FixForNetDdeStartup( HWND hwnd, LPSTR lpszStart ) { INT i; LPSTR lpsz; lpsz =lpszStart; i=1; while(*lpsz!='\0') { // Important. I am relying on lpsz being the same // exiting IsTopicNameFromNetDde as it was going in!!! if(IsTopicNameFromNetDde(lpsz,TOPIC)) { // We have one last check before we make the change. lpsz-2 // must not be '-' or '/' and lpsz must not be 'n' or 'N'. // Are we at the 3rd char or later? We can't make this // final check unless we have previous character to see. if(i>=3) { if( *(lpsz-1)!='n' && *(lpsz-1)!='N' && *(lpsz-2)!='-' && *(lpsz-2)!='/' ) { *lpsz='-'; *(lpsz+1)='s'; // change "Test" to "-s " *(lpsz+2)=' '; *(lpsz+3)=' '; } // if check for -,n,N,/ } // if i>=3 else { *lpsz='-'; *(lpsz+1)='s'; // change "Test" to "-s " *(lpsz+2)=' '; *(lpsz+3)=' '; } } // IsTopicName... lpsz++; i++; // We use this to keep charater position. } // while return TRUE; hwnd; } // FixForNetDdeStartup /***************************************************************************\ * * IsTopicNameFromNetDde * \***************************************************************************/ BOOL IsTopicNameFromNetDde(LPSTR lpsz, LPSTR lpszTopic ) { LPSTR lpstr; // Check to see that string is >=4 characters not including NULL // terminator. lpstr=lpsz; if(TStrLen(lpstr)wHour)) { // Calc update minutes for the wrap case. lrt=(((_1HOUR-lrtPMin)+lptime->wMinute)+lrt); // We need to check for multiple hours since last // update. if(lrtPHour>lptime->wHour) { // In case clock does not rap at 12:00. if(lptime->wHour>12) ll=lptime->wHour-12; else ll=lptime->wHour; l=(12-lrtPHour)+ll; } else l=lptime->wHour-lrtPHour; if(l>1) { lrt=lrt+((l-1)*_1HOUR); } } else lrt=((lptime->wMinute-lrtPMin)+lrt); SetWindowLong(hwnd,OFFSET_LAST_MIN,(LONG)lptime->wMinute); SetWindowLong(hwnd,OFFSET_LAST_HOUR,(LONG)lptime->wHour); SetWindowLong(hwnd,OFFSET_TIME_ELAPSED,lrt); if(lptime->wMinute!=LOWORD(lrtPMin)) UpdateCount(hwnd,OFFSET_TIME_ELAPSED,PNT); // if elapsed time > runtime time has expired. if(lrt>=lrtime) return TRUE; else return FALSE; } // If we are already shutting down no need to trigger other WM_CLOSE // messages. else return FALSE; } /*---------------------------------------------------------------------------*\ | ASCII TO INTEGER | This routine converts an ascii string to a decimal integer. | | created: 12-Oct-90 | history: 12-Oct-90 created. | \*---------------------------------------------------------------------------*/ int APIENTRY latoi(LPSTR lpString) { int nInt,nSign; if(*lpString == '-') { nSign = -1; lpString++; } else { if(*lpString == '+') lpString++; nSign = 1; } nInt = 0; while(*lpString) nInt = (nInt*10) + (*lpString++ - 48); return(nInt * nSign); } /*****************************************************************************\ | INTEGER TO ASCI | This routine converts an decimal integer to an ascii string. | | created: 29-Jul-91 | history: 29-Jul-91 created. | \*****************************************************************************/ LPSTR FAR PASCAL itola(INT i, LPSTR lpsz) { LPSTR lpsz_start; INT irange=1; INT id=0; lpsz_start=lpsz; // Keep track of the beginning of the // string. while (id=DIV(i,irange)>0) irange=irange*10; irange=DIV(irange,10); if(i==0) { // If i==0 set string and we *lpsz='0'; // will skip loop lpsz++; } while (irange>0) { id=DIV(i,irange); // Calculate character *lpsz=(CHAR)(id+48); lpsz++; i=i-(irange*id); // Adjust values for next time irange=DIV(irange,10); // through the loop. } *lpsz='\0'; // Null terminate the string return lpsz_start; }