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.

990 lines
24 KiB

  1. #include <windows.h>
  2. #include <port1632.h>
  3. #include <ddeml.h>
  4. #include "wrapper.h"
  5. #include "ddestrs.h"
  6. #ifdef WIN16
  7. #include <time.h>
  8. #endif
  9. extern BOOL fServer;
  10. extern BOOL fClient;
  11. extern INT iAvailFormats[];
  12. extern BOOL UpdateCount(HWND,INT,INT);
  13. extern LPSTR pszNetName;
  14. extern HANDLE hmemNet;
  15. BOOL IsTopicNameFromNetDde(LPSTR,LPSTR);
  16. BOOL FixForNetDdeStartup(HWND,LPSTR);
  17. BOOL FixForStressPercentage(HWND,LPSTR);
  18. BOOL SetStress(HWND,LONG);
  19. /***************************************************************************\
  20. *
  21. * InitArgsError
  22. *
  23. \***************************************************************************/
  24. VOID InitArgsError(HWND hwnd, unsigned at)
  25. {
  26. /* This function informs the user of an error. */
  27. static char *mpatszError[] = {
  28. "DdeStrs.Exe -- Invalid command line\r\nTry DdeStrs -5% for standard run or DdeStrs -? for help",
  29. "DdeStrs.Exe -- Invalid number, possibly missing option value",
  30. "DdeStrs.Exe -- Invalid log level",
  31. "DdeStrs.Exe -- Invalid number of test to execute",
  32. "DdeStrs.Exe -- Invalid starting test number"
  33. };
  34. MessageBox(NULL,mpatszError[at],"Error:DdeStrs",MB_OK|MB_ICONEXCLAMATION);
  35. }
  36. /***************************************************************************\
  37. *
  38. * SysTime - This routine is intended to hide the differences between
  39. * the 16 bit time routines and win 32. All time queries
  40. * come through this point.
  41. *
  42. \***************************************************************************/
  43. VOID SysTime( LPSYSTEMTIME lpst ) {
  44. #ifdef WIN32
  45. GetSystemTime( lpst );
  46. #else
  47. time_t t;
  48. struct tm ttmm;
  49. struct tm far *ptm=&ttmm;
  50. t=time(&t);
  51. ptm=localtime(&t);
  52. lpst->wYear =ptm->tm_year;
  53. lpst->wMonth =ptm->tm_mon;
  54. lpst->wDayOfWeek =ptm->tm_wday;
  55. lpst->wDay =ptm->tm_yday;
  56. lpst->wHour =ptm->tm_hour;
  57. lpst->wMinute =ptm->tm_min;
  58. lpst->wSecond =ptm->tm_sec;
  59. lpst->wMilliseconds =0;
  60. #endif
  61. }
  62. /************************** Private Function ****************************\
  63. *
  64. * ParseCommandLine - This routine controls parsing the command line and
  65. * initializing command line settings.
  66. *
  67. \**************************************************************************/
  68. BOOL ParseCommandLine( HWND hwnd, LPSTR lpcmd ) {
  69. SYSTEMTIME t;
  70. LPSYSTEMTIME lptime=&t;
  71. LONG lflags=0L;
  72. INT i,nThrd,num,nFmts;
  73. BOOL fSelect=FALSE;
  74. #ifdef WIN32
  75. LPCRITICAL_SECTION lpcs;
  76. HANDLE hmem;
  77. #endif
  78. // Defaults
  79. SetWindowLong(hwnd,OFFSET_FLAGS,FLAG_AUTO);
  80. SetWindowLong(hwnd,OFFSET_RUNTIME,_1WEEKEND);
  81. SetWindowLong(hwnd,OFFSET_STRESS,5L);
  82. SetWindowLong(hwnd,OFFSET_DELAY,(100-GetWindowLong(hwnd,OFFSET_STRESS))*DELAY_METRIC);
  83. SetWindowLong(hwnd,OFFSET_TIME_ELAPSED,0L);
  84. SetWindowLong(hwnd,OFFSET_THRDCOUNT,1L);
  85. SetWindowLong(hwnd,OFFSET_CRITICALSECT,0L);
  86. if(!get_cmd_arg(hwnd,lpcmd))
  87. return FALSE;
  88. // We need to make a change at this point for the
  89. // default client/server settings. If at this point
  90. // fClient==fServer==FALSE then we want to turn on
  91. // both of these as the default.
  92. if(!fClient && !fServer) {
  93. fClient=TRUE;
  94. fServer=TRUE;
  95. }
  96. // We need to check to see if specific formats where
  97. // specified. If not then select all of them.
  98. nFmts=0;
  99. for(i=0;i<NUM_FORMATS;i++)
  100. if(iAvailFormats[i]) {
  101. nFmts=nFmts++;
  102. fSelect=TRUE;
  103. }
  104. if(!fSelect) {
  105. for(i=0;i<NUM_FORMATS;i++) iAvailFormats[i]=1;
  106. nFmts=NUM_FORMATS;
  107. }
  108. // We have now read all of the command line. Make needed adjustment
  109. // to the delay as needed by addtional threads.
  110. // This adjustment code works with the routine SetStress. It
  111. // does not simply recalculate values. A change to SetStress will
  112. // cause changes in the final value.
  113. lflags=GetWindowLong(hwnd,OFFSET_FLAGS);
  114. if(!(lflags&FLAG_USRDELAY)) {
  115. num=(INT)GetWindowLong(hwnd,OFFSET_DELAY);
  116. nThrd=(INT)GetWindowLong(hwnd,OFFSET_THRDCOUNT);
  117. // 200 is the base value for basic overhead.
  118. num=(200)+(num*(nThrd*nThrd)*nFmts);
  119. SetWindowLong(hwnd,OFFSET_DELAY,num);
  120. }
  121. SetWindowLong(hwnd,OFFSET_BASE_DELAY,GetWindowLong(hwnd,OFFSET_DELAY));
  122. // We need to know the starting time to calculate
  123. // time to quit test.
  124. SysTime(lptime);
  125. SetWindowLong(hwnd,OFFSET_STARTTIME_SEC,lptime->wSecond);
  126. SetWindowLong(hwnd,OFFSET_STARTTIME_MIN,lptime->wMinute);
  127. SetWindowLong(hwnd,OFFSET_STARTTIME_HOUR,lptime->wHour);
  128. SetWindowLong(hwnd,OFFSET_STARTTIME_DAY,lptime->wDay);
  129. SetWindowLong(hwnd,OFFSET_LAST_MIN,lptime->wMinute);
  130. SetWindowLong(hwnd,OFFSET_LAST_HOUR,lptime->wHour);
  131. SetWindowLong(hwnd,OFFSET_TIME_ELAPSED,0L);
  132. #ifdef WIN32
  133. /* Setup our critical section if in multi-thread mode */
  134. lflags=GetWindowLong(hwnd,OFFSET_FLAGS);
  135. if(lflags&FLAG_MULTTHREAD) {
  136. hmem=GetMemHandle(sizeof(CRITICAL_SECTION));
  137. lpcs=GlobalLock(hmem);
  138. InitializeCriticalSection(lpcs);
  139. GlobalUnlock(hmem);
  140. SetWindowLong(hwnd,OFFSET_CRITICALSECT,(LONG)hmem);
  141. }
  142. #endif
  143. return TRUE;
  144. }
  145. /***************************************************************************\
  146. *
  147. * SetupArgv - This is a conversion routine to go from the window worlds
  148. * command line format to the more standard argv, argc
  149. * format. The routine get_cmd_arg was setup for the
  150. * argv/argc format.
  151. *
  152. \***************************************************************************/
  153. int SetupArgv( char *argv[], char *buff, LPSTR cmdline )
  154. {
  155. int i=1;
  156. while( *cmdline != '\0' ) {
  157. argv[i] = &buff[0];
  158. while ( *cmdline != ' ' && *cmdline != '\0')
  159. *buff++ = *cmdline++;
  160. *buff++='\0';
  161. while(*cmdline == ' ') cmdline++;
  162. i++;
  163. }
  164. return i;
  165. }
  166. /***************************************************************************\
  167. *
  168. * get_cmd_arg - This routine parses a argv\argc formatted command
  169. * line and stores away the values.
  170. *
  171. \***************************************************************************/
  172. BOOL PASCAL get_cmd_arg( HWND hwnd, LPSTR cmdline ) {
  173. /* This function parses the command line for valid options. TRUE is
  174. returned if all of the options are valid; otherwise, FALSE is returned. */
  175. char *pch;
  176. int iarg;
  177. unsigned at = AT_SWITCH;
  178. unsigned num;
  179. int argc;
  180. char *argv[10];
  181. char buff[200];
  182. LONG lflags=0L;
  183. #ifdef WIN32
  184. int nThrd;
  185. #endif
  186. FixForStressPercentage(hwnd,cmdline);
  187. FixForNetDdeStartup(hwnd,cmdline);
  188. argc = SetupArgv( argv, buff, cmdline );
  189. /* Iterate over the arguments in the command line. */
  190. iarg=1;
  191. while(iarg<argc && argv[iarg]!='\0') {
  192. /* Get the next argument. */
  193. pch = argv[iarg];
  194. /* Process the argument depending upon the arguement
  195. * type we are looking for.
  196. */
  197. switch (at) {
  198. case AT_SWITCH:
  199. /* All options begin with a switch character. */
  200. if (*pch != '-' && *pch != '/') {
  201. InitArgsError(hwnd,0);
  202. return FALSE;
  203. }
  204. /* Skip over the switch character. */
  205. pch++;
  206. /* Look for an option character. */
  207. do {
  208. switch (*pch) {
  209. case 'a':
  210. /* Run the test in the background */
  211. lflags=GetWindowLong(hwnd,OFFSET_FLAGS);
  212. SetWindowLong(hwnd,OFFSET_FLAGS,FLAGON(lflags,FLAG_APPOWNED));
  213. break;
  214. case 'p':
  215. /* Run the test in the background */
  216. lflags=GetWindowLong(hwnd,OFFSET_FLAGS);
  217. SetWindowLong(hwnd,OFFSET_FLAGS,FLAGON(lflags,FLAG_PAUSE_BUTTON|FLAG_PAUSE));
  218. break;
  219. case '?':
  220. /* Give brief help. For more detailed information see ddestrs.txt in source directory */
  221. MessageBox(NULL,"DdeStrs Options...\r\n-#% stress\r\n-e# delay\r\n-t# run time\r\n-d debug\r\n-a appowned\r\n-s server\r\n-c client\r\n-f# format\r\n-nNAME netdde\r\n-i# threads\r\n-p pause\r\n\nSee DdeStrs.Txt","DdeStrs Help",MB_OK);
  222. return FALSE;
  223. break;
  224. case 'b':
  225. /* Run the test in the background */
  226. lflags=GetWindowLong(hwnd,OFFSET_FLAGS);
  227. SetWindowLong(hwnd,OFFSET_FLAGS,FLAGON(lflags,FLAG_BACKGROUND));
  228. break;
  229. case 'l':
  230. /* Set the name of the log file. */
  231. if (*(++pch) == '\0') {
  232. /* The next argument should be a filename. */
  233. at = AT_FILE;
  234. goto NextArg;
  235. }
  236. case 'c':
  237. /* This is a client */
  238. fClient = TRUE;
  239. break;
  240. case 's':
  241. /* This is a server */
  242. fServer = TRUE;
  243. break;
  244. case 'i':
  245. /* The next argument should be the number of threads (w32 only) The
  246. range for this = [1...5] */
  247. #ifdef WIN32
  248. lflags=GetWindowLong(hwnd,OFFSET_FLAGS);
  249. SetWindowLong(hwnd,OFFSET_FLAGS,FLAGON(lflags,FLAG_MULTTHREAD));
  250. #endif
  251. at = AT_THRD;
  252. goto ParseNumber;
  253. case 'x':
  254. /* The next argument should be the stress level. */
  255. at = AT_STRESS;
  256. goto ParseNumber;
  257. case 'e':
  258. /* The next argument is the delay in milliseconds */
  259. lflags=GetWindowLong(hwnd,OFFSET_FLAGS);
  260. SetWindowLong(hwnd,OFFSET_FLAGS,FLAGON(lflags,FLAG_USRDELAY));
  261. at = AT_DELAY;
  262. goto ParseNumber;
  263. case 'd':
  264. /* The next argument is whether we are in debug mode */
  265. lflags=GetWindowLong(hwnd,OFFSET_FLAGS);
  266. SetWindowLong(hwnd,OFFSET_FLAGS,FLAGON(lflags,FLAG_DEBUG));
  267. break;
  268. case 'n':
  269. /* Process the network name */
  270. pch++;
  271. while( *pch==' ' ||
  272. *pch=='\\') pch++;
  273. pszNetName=GetMem(MAX_TITLE_LENGTH,&hmemNet);
  274. pszNetName=TStrCpy(pszNetName,pch);
  275. lflags=GetWindowLong(hwnd,OFFSET_FLAGS);
  276. SetWindowLong(hwnd,OFFSET_FLAGS,FLAGON(lflags,FLAG_NET));
  277. while(*pch!='\0') {
  278. pch++;
  279. }
  280. pch--;
  281. break;
  282. case 'f':
  283. at = AT_FORMAT;
  284. goto ParseNumber;
  285. case 't':
  286. lflags=GetWindowLong(hwnd,OFFSET_FLAGS);
  287. SetWindowLong(hwnd,OFFSET_FLAGS,FLAGON(lflags,FLAG_TIME));
  288. /* The next argument is the time (in minutes)
  289. to run the test. */
  290. at = AT_TIME;
  291. goto ParseNumber;
  292. default:
  293. InitArgsError(hwnd,0);
  294. return FALSE;
  295. } // switch
  296. } while (*(++pch) != '\0'); // do-while loop
  297. break;
  298. case AT_FILE:
  299. /* The next argument should be a switch. */
  300. at = AT_SWITCH;
  301. break;
  302. ParseNumber:
  303. /* Does this arg have the number? */
  304. if (*(++pch) == '\0') goto NextArg;
  305. case AT_STRESS:
  306. case AT_DELAY:
  307. case AT_TIME:
  308. case AT_WND:
  309. case AT_MSG:
  310. case AT_THRD:
  311. /* Set the number of tests to run. */
  312. if ((num = latoi(pch))==0) {
  313. /* Indicate that an invalid number has been specified. */
  314. if(at!=AT_DELAY) {
  315. InitArgsError(hwnd,0);
  316. return FALSE;
  317. }
  318. }
  319. switch (at) {
  320. case AT_FORMAT:
  321. if (num>0 && num<=NUM_FORMATS) {
  322. iAvailFormats[num-1]=1;
  323. }
  324. break;
  325. case AT_STRESS:
  326. SetStress(hwnd,num);
  327. break;
  328. case AT_DELAY:
  329. SetWindowLong(hwnd,OFFSET_DELAY,num);
  330. lflags=GetWindowLong(hwnd,OFFSET_FLAGS);
  331. SetWindowLong(hwnd,OFFSET_FLAGS,FLAGON(lflags,FLAG_USRDELAY));
  332. break;
  333. case AT_TIME:
  334. SetWindowLong(hwnd,OFFSET_RUNTIME,num);
  335. break;
  336. case AT_THRD:
  337. #ifdef WIN32
  338. if(num>THREADLIMIT) num=THREADLIMIT;
  339. // One is not really Mult-thread, shutoff the thread
  340. // code and run in normal form.
  341. if(num==1)
  342. {
  343. lflags=GetWindowLong(hwnd,OFFSET_FLAGS);
  344. lflags=FLAGOFF(lflags,FLAG_MULTTHREAD);
  345. lflags=FLAGON(lflags,FLAG_USRTHRDCOUNT);
  346. SetWindowLong(hwnd,OFFSET_FLAGS,lflags);
  347. SetWindowLong(hwnd,OFFSET_THRDCOUNT,num);
  348. }
  349. else {
  350. SetWindowLong(hwnd,OFFSET_THRDCOUNT,num);
  351. lflags=GetWindowLong(hwnd,OFFSET_FLAGS);
  352. SetWindowLong(hwnd,OFFSET_FLAGS,FLAGON(lflags,FLAG_USRTHRDCOUNT));
  353. }
  354. #endif
  355. break;
  356. default:
  357. InitArgsError(hwnd,0);
  358. return FALSE;
  359. break;
  360. } //switch (inside)
  361. /* The next argument should be a switch. */
  362. at = AT_SWITCH;
  363. break;
  364. } // switch (outside)
  365. NextArg:;
  366. iarg++;
  367. } // While loop
  368. /* Are we still looking for a filename or number? */
  369. if (at != AT_SWITCH) {
  370. /* Tell the user about the filename or number not found. */
  371. InitArgsError(hwnd,0);
  372. return FALSE;
  373. }
  374. return TRUE;
  375. } // end get_cmd_args
  376. /***************************************************************************\
  377. *
  378. * SetStress
  379. *
  380. \***************************************************************************/
  381. BOOL SetStress(HWND hwnd, LONG num) {
  382. LONG lflags;
  383. #ifdef WIN32
  384. LONG l;
  385. #endif
  386. INT n;
  387. lflags=GetWindowLong(hwnd,OFFSET_FLAGS);
  388. SetWindowLong(hwnd,OFFSET_STRESS,num);
  389. #ifdef WIN32
  390. if(!(lflags&FLAG_USRTHRDCOUNT)) {
  391. l=S2L(DIV(num,20)+1);
  392. if(num>9 && num<20) l++;
  393. if(l>5) l=5;
  394. if(l<1) l=1;
  395. SetWindowLong(hwnd,OFFSET_THRDCOUNT,l);
  396. if(l>1) {
  397. lflags=GetWindowLong(hwnd,OFFSET_FLAGS);
  398. SetWindowLong(hwnd,OFFSET_FLAGS,FLAGON(lflags,FLAG_MULTTHREAD));
  399. }
  400. }
  401. #endif
  402. if(!(lflags&FLAG_USRDELAY)) {
  403. n=(int)(100-num)*DELAY_METRIC;
  404. SetWindowLong(hwnd,OFFSET_DELAY,n);
  405. // since dde messages have highest priority we don't
  406. // want to swamp the system. Always have some
  407. // minimal delay.
  408. if(n<10) {
  409. SetWindowLong(hwnd,OFFSET_DELAY,10);
  410. lflags=GetWindowLong(hwnd,OFFSET_FLAGS);
  411. SetWindowLong(hwnd,OFFSET_FLAGS,FLAGOFF(lflags,FLAG_DELAYON));
  412. }
  413. }
  414. return TRUE;
  415. }
  416. /******************************************************************\
  417. * TStrLen
  418. * 11/20/88
  419. *
  420. * Finds the length of a string
  421. \******************************************************************/
  422. INT TStrLen( LPSTR pStr )
  423. {
  424. INT len = 0;
  425. while( *pStr++!='\0' ) len++;
  426. return( len );
  427. }
  428. /******************************************************************\
  429. * TStrCat
  430. * 7/16/92
  431. *
  432. * Appends source string to destination string. Source string and
  433. * destination string must be zero terminated!
  434. \******************************************************************/
  435. LPSTR TStrCat( LPSTR dest, LPSTR source)
  436. {
  437. LPSTR start_source;
  438. LPSTR start_dest;
  439. INT i=0;
  440. /* If we have a NULL pointer set destination to NULL and
  441. continue */
  442. if (!dest || !source) {
  443. MessageBox(NULL,"TStrCat - NULL ptr for dest or source string!","Error : WmStress",MB_ICONEXCLAMATION);
  444. return NULL;
  445. }
  446. start_dest = dest;
  447. start_source = source;
  448. while (*dest++!='\0' && i++<=MAX_TITLE_LENGTH)
  449. ;
  450. TStrCpy(dest,source);
  451. source = start_source;
  452. dest = start_dest;
  453. return( start_dest );
  454. }
  455. /*************************** Private Function ******************************\
  456. *
  457. * TStrCmp
  458. *
  459. * Compares two NULL terminated strings ( returns TRUE if equal )
  460. *
  461. \***************************************************************************/
  462. BOOL TStrCmp(LPSTR s, LPSTR t)
  463. {
  464. // Valid pointer?
  465. if ( !s && !t ) return TRUE; // If either is NULL then they should
  466. if ( (!s&&t)||(s&&!t) ) // both be NULL. Otherwise error.
  467. return FALSE;
  468. for (; *s == *t; s++, t++) // Compare strings
  469. if (*s=='\0')
  470. return TRUE;
  471. if ((*s-*t)== 0) return TRUE;
  472. else return FALSE;
  473. }
  474. /******************************************************************\
  475. * TStrCpy
  476. * 11/20/88
  477. *
  478. * Copies a string from source to destination
  479. \******************************************************************/
  480. LPSTR TStrCpy( LPSTR dest, LPSTR source)
  481. {
  482. LPSTR start_source;
  483. LPSTR start_dest;
  484. INT i;
  485. /* If we have a NULL pointer set destination to NULL and
  486. continue */
  487. if(!source) {
  488. dest=NULL;
  489. return NULL;
  490. }
  491. if (!dest) {
  492. MessageBox(NULL,"TStrCpy - NULL ptr for dest!","Error:WmStress",MB_ICONEXCLAMATION);
  493. return NULL;
  494. }
  495. start_dest = dest;
  496. start_source = source;
  497. i=0;
  498. while (*dest++ = *source++){
  499. i++;
  500. }
  501. source = start_source;
  502. dest = start_dest;
  503. return( start_dest );
  504. }
  505. /***************************************************************************\
  506. *
  507. * FixForStressPercentage - This is a fix for the command line -5%. The
  508. * origional get_cmd_args() did not handle this
  509. * case. This routine handles string modifications
  510. * to the command line parse will be correct.
  511. *
  512. \***************************************************************************/
  513. BOOL FixForStressPercentage(HWND hwnd, LPSTR lpszStart )
  514. {
  515. CHAR ac[6];
  516. INT i;
  517. LPSTR lpsz,lpszdash;
  518. BOOL bLastTime;
  519. lpsz =lpszStart;
  520. lpszdash =NULL;
  521. ac[0]='x';
  522. while(*lpsz!='\0') {
  523. if( *lpsz=='-') lpszdash=lpsz;
  524. if( *lpsz=='%') {
  525. if(lpszdash==NULL) return FALSE;
  526. else lpsz=(LPSTR)(lpszdash+1);
  527. // Basically what we do hear is replace the '%' by an 'x'
  528. // and shift characters...(-60% becomes -x60).
  529. i=0;
  530. bLastTime=FALSE;
  531. while(!bLastTime) {
  532. ac[i+1]=*lpsz;
  533. if(*lpsz=='%') bLastTime=TRUE;
  534. *lpsz=ac[i];
  535. lpsz++;
  536. i++;
  537. }
  538. } // if
  539. lpsz++;
  540. } // while
  541. return TRUE;
  542. hwnd;
  543. } // FixForStressPercentage
  544. /***************************************************************************\
  545. *
  546. * FixForNetDdeStartup - This is a fix for the command line "Test". The
  547. * origional get_cmd_args() did not handle this
  548. * case. This routine modifies the string from
  549. * "Test" to "-s".
  550. *
  551. * The reason for this change is to make ddestrs.exe
  552. * netdde aware for the startup situation. When
  553. * netdde starts up the application is passed the topic
  554. * name (in this case Test) to the application on the
  555. * command line.
  556. *
  557. * NOTE!!! The below code relies on TOPIC="Test". If this has changed then
  558. * update FixForNetDdeStartup() and IsTopicNameFromNetDde().
  559. *
  560. \***************************************************************************/
  561. BOOL FixForNetDdeStartup( HWND hwnd, LPSTR lpszStart )
  562. {
  563. INT i;
  564. LPSTR lpsz;
  565. lpsz =lpszStart;
  566. i=1;
  567. while(*lpsz!='\0') {
  568. // Important. I am relying on lpsz being the same
  569. // exiting IsTopicNameFromNetDde as it was going in!!!
  570. if(IsTopicNameFromNetDde(lpsz,TOPIC)) {
  571. // We have one last check before we make the change. lpsz-2
  572. // must not be '-' or '/' and lpsz must not be 'n' or 'N'.
  573. // Are we at the 3rd char or later? We can't make this
  574. // final check unless we have previous character to see.
  575. if(i>=3) {
  576. if( *(lpsz-1)!='n' &&
  577. *(lpsz-1)!='N' &&
  578. *(lpsz-2)!='-' &&
  579. *(lpsz-2)!='/' )
  580. {
  581. *lpsz='-';
  582. *(lpsz+1)='s'; // change "Test" to "-s "
  583. *(lpsz+2)=' ';
  584. *(lpsz+3)=' ';
  585. } // if check for -,n,N,/
  586. } // if i>=3
  587. else {
  588. *lpsz='-';
  589. *(lpsz+1)='s'; // change "Test" to "-s "
  590. *(lpsz+2)=' ';
  591. *(lpsz+3)=' ';
  592. }
  593. } // IsTopicName...
  594. lpsz++;
  595. i++; // We use this to keep charater position.
  596. } // while
  597. return TRUE;
  598. hwnd;
  599. } // FixForNetDdeStartup
  600. /***************************************************************************\
  601. *
  602. * IsTopicNameFromNetDde
  603. *
  604. \***************************************************************************/
  605. BOOL IsTopicNameFromNetDde(LPSTR lpsz, LPSTR lpszTopic )
  606. {
  607. LPSTR lpstr;
  608. // Check to see that string is >=4 characters not including NULL
  609. // terminator.
  610. lpstr=lpsz;
  611. if(TStrLen(lpstr)<TStrLen(lpszTopic)) return FALSE;
  612. // Is our topic string present.
  613. if(*lpsz!='T' && *lpsz!='t') {
  614. return FALSE;
  615. }
  616. if(*(lpsz+1)!='e' && *(lpsz+1)!='E') {
  617. return FALSE;
  618. }
  619. if(*(lpsz+2)!='s' && *(lpsz+2)!='S') {
  620. return FALSE;
  621. }
  622. if(*(lpsz+3)!='t' && *(lpsz+3)!='T') {
  623. return FALSE;
  624. }
  625. if(*(lpsz+4)!=' ' && *(lpsz+4)!='\0') {
  626. return FALSE;
  627. }
  628. return TRUE;
  629. } // IsTopicNameFromNetDde
  630. /************************** Private Function ****************************\
  631. *
  632. * IsTimeExpired - This routine is called periodically to check if its
  633. * time to quit.
  634. *
  635. \**************************************************************************/
  636. BOOL IsTimeExpired( HWND hwnd ) {
  637. LONG lrtime, lrtPMin, lrtPHour, lrt, l, ll;
  638. SYSTEMTIME t;
  639. LPSYSTEMTIME lptime=&t;
  640. LONG lflags=0L;
  641. lflags=GetWindowLong(hwnd,OFFSET_FLAGS);
  642. if(!(lflags&FLAG_STOP)) {
  643. // This is how long we should run. In minutes
  644. lrtime =GetWindowLong(hwnd,OFFSET_RUNTIME);
  645. // This is how long we have run. In minutes.
  646. lrt =GetWindowLong(hwnd,OFFSET_TIME_ELAPSED);
  647. l=lrt;
  648. // Time at last check.
  649. lrtPMin =GetWindowLong(hwnd,OFFSET_LAST_MIN);
  650. lrtPHour=GetWindowLong(hwnd,OFFSET_LAST_HOUR);
  651. SysTime(lptime);
  652. if(lrtPHour!=(LONG)(lptime->wHour)) {
  653. // Calc update minutes for the wrap case.
  654. lrt=(((_1HOUR-lrtPMin)+lptime->wMinute)+lrt);
  655. // We need to check for multiple hours since last
  656. // update.
  657. if(lrtPHour>lptime->wHour) {
  658. // In case clock does not rap at 12:00.
  659. if(lptime->wHour>12) ll=lptime->wHour-12;
  660. else ll=lptime->wHour;
  661. l=(12-lrtPHour)+ll;
  662. }
  663. else l=lptime->wHour-lrtPHour;
  664. if(l>1) {
  665. lrt=lrt+((l-1)*_1HOUR);
  666. }
  667. }
  668. else lrt=((lptime->wMinute-lrtPMin)+lrt);
  669. SetWindowLong(hwnd,OFFSET_LAST_MIN,(LONG)lptime->wMinute);
  670. SetWindowLong(hwnd,OFFSET_LAST_HOUR,(LONG)lptime->wHour);
  671. SetWindowLong(hwnd,OFFSET_TIME_ELAPSED,lrt);
  672. if(lptime->wMinute!=LOWORD(lrtPMin))
  673. UpdateCount(hwnd,OFFSET_TIME_ELAPSED,PNT);
  674. // if elapsed time > runtime time has expired.
  675. if(lrt>=lrtime)
  676. return TRUE;
  677. else return FALSE;
  678. }
  679. // If we are already shutting down no need to trigger other WM_CLOSE
  680. // messages.
  681. else return FALSE;
  682. }
  683. /*---------------------------------------------------------------------------*\
  684. | ASCII TO INTEGER
  685. | This routine converts an ascii string to a decimal integer.
  686. |
  687. | created: 12-Oct-90
  688. | history: 12-Oct-90 <chriswil> created.
  689. |
  690. \*---------------------------------------------------------------------------*/
  691. int APIENTRY latoi(LPSTR lpString)
  692. {
  693. int nInt,nSign;
  694. if(*lpString == '-')
  695. {
  696. nSign = -1;
  697. lpString++;
  698. }
  699. else
  700. {
  701. if(*lpString == '+')
  702. lpString++;
  703. nSign = 1;
  704. }
  705. nInt = 0;
  706. while(*lpString)
  707. nInt = (nInt*10) + (*lpString++ - 48);
  708. return(nInt * nSign);
  709. }
  710. /*****************************************************************************\
  711. | INTEGER TO ASCI
  712. | This routine converts an decimal integer to an ascii string.
  713. |
  714. | created: 29-Jul-91
  715. | history: 29-Jul-91 <johnsp> created.
  716. |
  717. \*****************************************************************************/
  718. LPSTR FAR PASCAL itola(INT i, LPSTR lpsz)
  719. {
  720. LPSTR lpsz_start;
  721. INT irange=1;
  722. INT id=0;
  723. lpsz_start=lpsz; // Keep track of the beginning of the
  724. // string.
  725. while (id=DIV(i,irange)>0)
  726. irange=irange*10;
  727. irange=DIV(irange,10);
  728. if(i==0) { // If i==0 set string and we
  729. *lpsz='0'; // will skip loop
  730. lpsz++;
  731. }
  732. while (irange>0) {
  733. id=DIV(i,irange); // Calculate character
  734. *lpsz=(CHAR)(id+48);
  735. lpsz++;
  736. i=i-(irange*id); // Adjust values for next time
  737. irange=DIV(irange,10); // through the loop.
  738. }
  739. *lpsz='\0'; // Null terminate the string
  740. return lpsz_start;
  741. }