Primec.c
上传用户:bjlvip
上传日期:2010-02-08
资源大小:744k
文件大小:19k
源码类别:

Windows编程

开发平台:

Visual C++

  1. #include <STDIO.H>
  2. #include <LIMITS.H>
  3. #include <WINDOWS.H>
  4. #include "directio.h"
  5. #include "Serverprime.h"
  6. /* If we found a prime then return PRIME, otherwise return NOT_PRIME */
  7. #define PRIME           1
  8. #define NOT_PRIME       0
  9. /* Coordinates for displaying numbers to be tested */
  10. #define TESTING_X1      3
  11. #define TESTING_Y1      3
  12. #define TESTING_X2     23
  13. #define TESTING_Y2     18
  14. /* Coordinates for displaying prime numbers */
  15. #define PRIME_X1       30
  16. #define PRIME_Y1        3
  17. #define PRIME_X2       50
  18. #define PRIME_Y2       18
  19. #define ERROR_EXIT      2
  20. #define SUCCESS_EXIT    0
  21. #define STRING_LENGTH 256
  22. /* Delay time in microseconds */
  23. #define WAIT          350
  24. #define WAIT_DISPLAY 2000
  25. /* Colors used in this application */
  26. #define WHITE_ON_BLUE FOREGROUND_WHITE|FOREGROUND_INTENSITY|BACKGROUND_BLUE
  27. #define WHITE_ON_CYAN FOREGROUND_WHITE|FOREGROUND_INTENSITY|BACKGROUND_CYAN
  28. #define RED_ON_BLUE   FOREGROUND_RED|FOREGROUND_INTENSITY|BACKGROUND_BLUE
  29. #define RED_ON_CYAN   FOREGROUND_RED|FOREGROUND_INTENSITY|BACKGROUND_CYAN
  30. #define CYAN_ON_CYAN  FOREGROUND_CYAN|BACKGROUND_CYAN
  31. #define BLUE_ON_CYAN  FOREGROUND_BLUE|FOREGROUND_INTENSITY|BACKGROUND_CYAN
  32. /* Max number of threads for this application */
  33. #define MAX_THREADS      15
  34. #define COMP_NAME_LENGTH 7
  35. int NumThreads;
  36. /* Prototypes of functions used in this application */
  37. unsigned char IsPrime(unsigned long TestNumber);
  38. extern char ServerStatus(char);
  39. extern void thread_local(void);
  40. extern void thread_remote(int count);
  41. extern void Usage(void);
  42. extern void InitializeApplication(void);
  43. extern void NotifyServer(char);
  44. extern void thread_client(void);
  45. char IsActiveServer[MAX_THREADS];
  46. DWORD  lpIDThreadClient;
  47. HANDLE hthread_client;
  48. /* Critical Section for choosing next available number for testing */
  49. CRITICAL_SECTION GlobalCriticalSection;
  50. /* Storage for Computer Name */
  51. char computer_name_buffer[MAX_COMPUTERNAME_LENGTH];
  52. /* Unique number returned by the server */
  53. unsigned long PrimeServerHandle[MAX_THREADS];
  54. /*
  55. NextNumber    - Next available number to test
  56. StartTime     - Time that we start to compute primes
  57. CurrTime      - Current Computer time
  58. NoPrimeLocal  - Number of primes computed locally
  59. NoPrimeRemote - Number of primes computed on the remote computer
  60. StartNumber   - The starting number for testing primes
  61. */
  62. unsigned long NextNumber = 1, StartTime, CurrTime, NoPrimeLocal,
  63.    NoPrimeRemoteT, StartNumber = 1;
  64. handle_t BindingHandle[MAX_THREADS];
  65. unsigned long NoPrimeRemote[MAX_THREADS];
  66. PCONTEXT_HANDLE_TYPE phContext[MAX_THREADS];
  67. int ipszNetAdd = 0;
  68. RPC_NS_HANDLE ImportContext;
  69. unsigned char pszRemoteName[MAX_THREADS][MAX_COMPUTERNAME_LENGTH];
  70. #define REMOTE_TRY 100
  71. unsigned char Notry[MAX_THREADS];
  72. void main(int argc, char **argv)
  73.    {
  74.    RPC_STATUS status; /* returned by RPC API function */
  75.    unsigned char *pszUuid                          = NULL;
  76.    unsigned char *pszProtocolSequence              = "ncacn_np";
  77.    unsigned char *pszNetworkAddress[MAX_THREADS]   = { NULL };
  78.    unsigned char *pszEndpoint[MAX_THREADS]         =
  79.       {
  80.       "\pipe\prime", "\pipe\prime", "\pipe\prime", "\pipe\prime",
  81.       "\pipe\prime", "\pipe\prime", "\pipe\prime", "\pipe\prime",
  82.       "\pipe\prime"
  83.       };
  84.    unsigned char *pszOptions                       = NULL;
  85.    unsigned char *pszStringBinding[MAX_THREADS]    = { NULL };
  86.    DWORD  Max_ComputerName_Length = MAX_COMPUTERNAME_LENGTH;
  87.    DWORD  lpIDThread[MAX_THREADS];
  88.    HANDLE hthread_remote[MAX_THREADS];
  89.    int count;
  90.    /* Allow the user to override settings with command line switches */
  91.    for(count = 1; count < argc; count++)
  92.       {
  93.       if((*argv[count] == '-') || (*argv[count] == '/'))
  94.          {
  95.          switch(tolower(*(argv[count]+1)))
  96.             {
  97.             case 'p': /* protocol sequence */
  98.                pszProtocolSequence = argv[++count];
  99.                break;
  100.             case 'n': /* network address */
  101.                {
  102.                char tokensep[] = " t,;", *token;
  103.                token = strtok(argv[++count], tokensep);
  104.                while(token != NULL)
  105.                   {
  106.                   pszNetworkAddress[ipszNetAdd] = token;
  107.                   token = strtok(NULL, tokensep);
  108.                   strcpy(pszRemoteName[ipszNetAdd],
  109.                      strupr(&pszNetworkAddress[ipszNetAdd][2]));
  110.                   pszRemoteName[ipszNetAdd][COMP_NAME_LENGTH] = 0;
  111.                   ipszNetAdd++;
  112.                   }
  113.                }
  114.                break;
  115.             case 'e':
  116.                {
  117.                char tokensep[] = " t,;", *token;
  118.                token =strtok(argv[++count], tokensep);
  119.                while(token != NULL)
  120.                   {
  121.                   pszEndpoint[ipszNetAdd] = token;
  122.                   token = strtok(NULL, tokensep);
  123.                   ipszNetAdd++;
  124.                   }
  125.                }
  126.                break;
  127.             case 'o':
  128.                pszOptions = argv[++count];
  129.                break;
  130.             case 'f': /* first number */
  131.                NextNumber = StartNumber = atol(argv[++count]);
  132.                break;
  133.             case 't': /* number of threads */
  134.                NumThreads = atoi(argv[++count]);
  135.                if(NumThreads > MAX_THREADS)
  136.                   NumThreads = MAX_THREADS;
  137.                break;
  138.             case 'h':
  139.             case '?':
  140.             default:
  141.                Usage();
  142.             }
  143.          }
  144.       else
  145.          Usage();
  146.       }
  147.    if(pszNetworkAddress)
  148.       {
  149.       int i;
  150.       /*
  151.       Use a convenience function to concatenate the elements of
  152.       the string binding into the proper sequence
  153.       */
  154.       for(i = 0; i < ipszNetAdd; i++)
  155.          {
  156.          status = RpcStringBindingCompose(
  157.             pszUuid,
  158.             pszProtocolSequence,
  159.             pszNetworkAddress[i],
  160.             pszEndpoint[i],
  161.             pszOptions,
  162.             &pszStringBinding[i]);
  163.          if(status)
  164.             exit(ERROR_EXIT);
  165.          }
  166.       /* Set the binding handle that will be used to bind to the server */
  167.       for(i = 0; i < ipszNetAdd; i++)
  168.          {
  169.          status = RpcBindingFromStringBinding(pszStringBinding[i],
  170.             &BindingHandle[i]);
  171.          if(status)
  172.             exit(ERROR_EXIT);
  173.          }
  174.       }
  175.    GetComputerName(computer_name_buffer, &Max_ComputerName_Length);
  176.    InitializeCriticalSection(&GlobalCriticalSection);
  177.       {
  178.       char i;
  179.       for(i = 0; i < ipszNetAdd; i++)
  180.          ServerStatus(i);
  181.       }
  182.    for(count = 1; count <= ipszNetAdd ; count++)
  183.        hthread_remote[count-1] = CreateThread(NULL, 0,
  184.           (LPTHREAD_START_ROUTINE)thread_remote, (LPVOID)count, 0,
  185.           &lpIDThread[count-1]);
  186.    InitializeApplication();
  187.    hthread_client = CreateThread(NULL, 0,
  188.       (LPTHREAD_START_ROUTINE)thread_client, NULL,
  189.       CREATE_SUSPENDED, &lpIDThreadClient);
  190.    SetThreadPriority(hthread_client, THREAD_PRIORITY_NORMAL);
  191.    ResumeThread(hthread_client);
  192.    thread_local();
  193.    DeleteCriticalSection(&GlobalCriticalSection);
  194.    /*
  195.    The calls to the remote procedures are complete
  196.    Free the string and the binding handle
  197.    */
  198.    /* remote calls done - unbind */
  199.    if(pszNetworkAddress)
  200.       {
  201.       int i;
  202.       for(i = 0; i < ipszNetAdd; i++)
  203.          {
  204.          status = RpcStringFree(&pszStringBinding[i]);
  205.          if(status)
  206.             exit(ERROR_EXIT);
  207.          }
  208.       }
  209.    exit(SUCCESS_EXIT);
  210.    }
  211. void thread_local(void)
  212.    {
  213.    unsigned long temp;
  214.    char Buffer[STRING_LENGTH];
  215.    int loop;
  216.    SMALL_RECT psrctScrollRectTesting, psrctScrollRectPrime;
  217.    COORD coordDestOriginTesting, coordDestOriginPrime;
  218.    CHAR_INFO pchiFill;
  219.    WORD Color[TESTING_X2-TESTING_X1-3], Normal[TESTING_X2-TESTING_X1-3];
  220.    COORD ComputTestCoord;
  221.    COORD ComputPrimeCoord;
  222.    DWORD dummy;
  223.    COORD PrimeCoord;
  224.    psrctScrollRectTesting.Left   = TESTING_X1+1;
  225.    psrctScrollRectTesting.Top    = TESTING_Y1+2;
  226.    psrctScrollRectTesting.Right  = TESTING_X2-1;
  227.    psrctScrollRectTesting.Bottom = TESTING_Y2-1;
  228.    coordDestOriginTesting.X = TESTING_X1+1;
  229.    coordDestOriginTesting.Y = TESTING_Y1+1;
  230.    psrctScrollRectPrime.Left   = PRIME_X1+1;
  231.    psrctScrollRectPrime.Top    = PRIME_Y1+2;
  232.    psrctScrollRectPrime.Right  = PRIME_X2-1;
  233.    psrctScrollRectPrime.Bottom = PRIME_Y2-1;
  234.    coordDestOriginPrime.X = PRIME_X1+1;
  235.    coordDestOriginPrime.Y = PRIME_Y1+1;
  236.    pchiFill.Char.AsciiChar = (char)32;
  237.    pchiFill.Attributes = WHITE_ON_BLUE;
  238.    ComputTestCoord.X  = TESTING_X2-7;
  239.    ComputTestCoord.Y  = TESTING_Y2-1;
  240.    ComputPrimeCoord.X = PRIME_X2-7;
  241.    ComputPrimeCoord.Y = PRIME_Y2-1;
  242.    for(loop = 0; loop < TESTING_X2-TESTING_X1-3; loop++)
  243.       {
  244.       Color[loop]  = RED_ON_BLUE;
  245.       Normal[loop] = WHITE_ON_BLUE;
  246.       }
  247.    while(1)
  248.       {
  249.       EnterCriticalSection(&GlobalCriticalSection);
  250.       if((temp = ++NextNumber) >= ULONG_MAX)
  251.          break;
  252.       LeaveCriticalSection(&GlobalCriticalSection);
  253.       EnterCriticalSection(&GlobalCriticalSection);
  254.       ScrollConsoleScreenBuffer(hStdOut, &psrctScrollRectTesting, NULL,
  255.          coordDestOriginTesting, &pchiFill);
  256.       sprintf(Buffer, "%d", temp - 1);
  257.       mxyputs((unsigned char)TESTING_X1+2, (unsigned char)(TESTING_Y2-1),
  258.          Buffer, WHITE_ON_BLUE);
  259.       WriteConsoleOutputAttribute(hStdOut, Normal, 7, ComputTestCoord,
  260.          &dummy);
  261.       mxyputs((unsigned char)(TESTING_X2-7), (unsigned char)TESTING_Y2-1,
  262.          "LOCAL ", WHITE_ON_BLUE);
  263.       LeaveCriticalSection(&GlobalCriticalSection);
  264.       if(IsPrime(temp - 1) != 0)
  265.          {
  266.          PrimeCoord.X = PRIME_X1 + 2;
  267.          PrimeCoord.Y = PRIME_Y2 - 1;
  268.          EnterCriticalSection(&GlobalCriticalSection);
  269.          ScrollConsoleScreenBuffer(hStdOut, &psrctScrollRectPrime, NULL,
  270.             coordDestOriginPrime, &pchiFill);
  271.          sprintf(Buffer, "%-17d", temp - 1);
  272.          mxyputs((unsigned char)(PRIME_X1+2), (unsigned char)PRIME_Y2-1,
  273.             Buffer, WHITE_ON_BLUE);
  274.          WriteConsoleOutputAttribute(hStdOut, Normal, 7, ComputPrimeCoord,
  275.             &dummy);
  276.          mxyputs((unsigned char)(PRIME_X2-7), (unsigned char)PRIME_Y2-1,
  277.             "LOCAL ", WHITE_ON_BLUE);
  278.          LeaveCriticalSection(&GlobalCriticalSection);
  279.          NoPrimeLocal++;
  280.          }
  281.       }
  282.    }
  283. void thread_remote(int count)
  284.    {
  285.    unsigned long temp;
  286.    char Buffer[STRING_LENGTH];
  287.    int loop;
  288.    SMALL_RECT psrctScrollRectTesting, psrctScrollRectPrime;
  289.    COORD coordDestOriginTesting, coordDestOriginPrime;
  290.    CHAR_INFO pchiFill;
  291.    WORD Color[TESTING_X2-TESTING_X1-3], Normal[TESTING_X2-TESTING_X1-3];
  292.    COORD ComputTestCoord;
  293.    COORD ComputPrimeCoord;
  294.    DWORD dummy;
  295.    COORD PrimeCoord;
  296.    psrctScrollRectTesting.Left   = TESTING_X1+1;
  297.    psrctScrollRectTesting.Top    = TESTING_Y1+2;
  298.    psrctScrollRectTesting.Right  = TESTING_X2-1;
  299.    psrctScrollRectTesting.Bottom = TESTING_Y2-1;
  300.    coordDestOriginTesting.X = TESTING_X1+1;
  301.    coordDestOriginTesting.Y = TESTING_Y1+1;
  302.    psrctScrollRectPrime.Left   = PRIME_X1+1;
  303.    psrctScrollRectPrime.Top    = PRIME_Y1+2;
  304.    psrctScrollRectPrime.Right  = PRIME_X2-1;
  305.    psrctScrollRectPrime.Bottom = PRIME_Y2-1;
  306.    coordDestOriginPrime.X = PRIME_X1+1;
  307.    coordDestOriginPrime.Y = PRIME_Y1+1;
  308.    pchiFill.Char.AsciiChar = (char)32;
  309.    pchiFill.Attributes = WHITE_ON_BLUE;
  310.    ComputTestCoord.X  = TESTING_X2-7;
  311.    ComputTestCoord.Y  = TESTING_Y2-1;
  312.    ComputPrimeCoord.X = PRIME_X2-7;
  313.    ComputPrimeCoord.Y = PRIME_Y2-1;
  314.    for(loop = 0; loop < TESTING_X2-TESTING_X1-3; loop++)
  315.       {
  316.       Color[loop]  = RED_ON_BLUE;
  317.       Normal[loop] = WHITE_ON_BLUE;
  318.       }
  319.    while(1)
  320.       {
  321.       if(!IsActiveServer[count-1])
  322.          {
  323.          if(Notry[count-1]++ > REMOTE_TRY)
  324.             {  
  325.             Notry[count - 1] = 0;
  326.             EnterCriticalSection(&GlobalCriticalSection);
  327.              ServerStatus((char)(count - 1));
  328.             LeaveCriticalSection(&GlobalCriticalSection);
  329.             }
  330.          else        
  331.             continue;
  332.          }   
  333.       if(!IsActiveServer[count-1])
  334.          continue;       
  335. /* To make sure that we won't test the same number twice */
  336.       EnterCriticalSection(&GlobalCriticalSection);
  337.       if((temp = ++NextNumber) >= ULONG_MAX)
  338.          break;
  339.       LeaveCriticalSection(&GlobalCriticalSection);
  340.       EnterCriticalSection(&GlobalCriticalSection);
  341.       ScrollConsoleScreenBuffer(hStdOut, &psrctScrollRectTesting, NULL,
  342.          coordDestOriginTesting, &pchiFill);
  343.       sprintf(Buffer, " %-17d", temp - 1);
  344.       mxyputs((unsigned char)TESTING_X1+1, (unsigned char)(TESTING_Y2-1),
  345.          Buffer, RED_ON_BLUE);
  346.       WriteConsoleOutputAttribute(hStdOut, Color, 7, ComputTestCoord,
  347.          &dummy);
  348.       mxyputs((unsigned char)(TESTING_X2-7), (unsigned char)TESTING_Y2-1,
  349.          pszRemoteName[count-1], RED_ON_BLUE);
  350.       LeaveCriticalSection(&GlobalCriticalSection);
  351.       RpcTryExcept
  352.          {
  353.          if(RemoteIsPrime(BindingHandle[count-1], PrimeServerHandle[count-1],
  354.             temp - 1) != 0)
  355.             {
  356.             EnterCriticalSection(&GlobalCriticalSection);
  357.             PrimeCoord.X = TESTING_X1 + 2;
  358.             LeaveCriticalSection(&GlobalCriticalSection);
  359.             PrimeCoord.X = PRIME_X1 + 2;
  360.             PrimeCoord.Y = PRIME_Y2 - 1;
  361.             EnterCriticalSection(&GlobalCriticalSection);
  362.             ScrollConsoleScreenBuffer(hStdOut, &psrctScrollRectPrime, NULL,
  363.                coordDestOriginPrime, &pchiFill);
  364.             sprintf(Buffer, " %-17d", temp - 1);
  365.             mxyputs((unsigned char)(PRIME_X1+1), (unsigned char)PRIME_Y2-1,
  366.                Buffer, RED_ON_BLUE);
  367.             WriteConsoleOutputAttribute(hStdOut, Color, 7, ComputPrimeCoord,
  368.                &dummy);
  369.             mxyputs((unsigned char)(PRIME_X2-7), (unsigned char)PRIME_Y2-1,
  370.                pszRemoteName[count-1], RED_ON_BLUE);
  371.             LeaveCriticalSection(&GlobalCriticalSection);
  372.                NoPrimeRemote[count-1]++;
  373.             NoPrimeRemoteT++;
  374.             }
  375.          }
  376.       RpcExcept(1)
  377.          {
  378.          /* if exceptions occurs */
  379.          EnterCriticalSection(&GlobalCriticalSection);
  380.          ServerStatus((char)(count - 1));
  381.          LeaveCriticalSection(&GlobalCriticalSection);
  382.          }
  383.       RpcEndExcept
  384.       }
  385.    }
  386. /* Tests for prime number on the local computer */
  387. unsigned char IsPrime(unsigned long TestNumber)
  388.    {
  389.    unsigned long count;
  390.    unsigned long HalfNumber = TestNumber / 2 + 1;
  391.    for(count = 2; count < HalfNumber; count++)
  392.       if(TestNumber % count == 0)
  393.          return NOT_PRIME;
  394.    return PRIME;
  395.    }
  396. /* Displays command line options */
  397. void Usage(void)
  398.    {
  399.    printf("nDistributed client/server prime number example.nn");
  400.    printf("Usage: PRIMEn");
  401.    printf(" -p protocol_sequencen");
  402.    printf(" -n network_addressn");
  403.    printf(" -e endpointn");
  404.    printf(" -o optionsn");
  405.    printf(" -f first numbern");
  406.    exit(1);
  407.    }
  408. /* Screen Initialization and colors and title lines */
  409. void InitializeApplication(void)
  410.    {
  411.    set_vid_mem();
  412.    clearscreen(BACKGROUND_CYAN);
  413.    StartTime = GetTickCount();
  414.    box(0, 0, 79, 24, DOUBLE);
  415.    mxyputs(37, 0, " PRIMEC ", WHITE_ON_CYAN);
  416.    mxyputs(TESTING_X1, 2, "Testing...", WHITE_ON_CYAN);
  417.    box(TESTING_X1, TESTING_Y1, TESTING_X2, TESTING_Y2, SINGLE);
  418.    mxyputs(PRIME_X1, 2, "Prime!",WHITE_ON_CYAN);
  419.    box(PRIME_X1, PRIME_Y1, PRIME_X2, PRIME_Y2, SINGLE);
  420.    mxyputs(32, 23, "Press Esc to exit", WHITE_ON_CYAN);
  421.    }
  422. /*
  423.    Check the Server status if it is of line, then try to connect, return
  424.    server status
  425. */
  426. char ServerStatus(char iserver)
  427.    {
  428.    char value = FALSE;
  429.    RpcTryExcept
  430.       {
  431.       PrimeServerHandle[iserver] = InitializePrimeServer(
  432.          BindingHandle[iserver], &phContext[iserver], computer_name_buffer);
  433.       IsActiveServer[iserver] = TRUE;
  434.       }      
  435.    RpcExcept(1)
  436.       {
  437.       value = TRUE;
  438.       IsActiveServer[iserver] = FALSE;
  439.       }
  440.    RpcEndExcept
  441.    return value;
  442.    }
  443. /* Let the Server know that we are about to exit */
  444. void NotifyServer(char iserver)
  445.    {
  446.    RpcTryExcept
  447.       {
  448.       TerminatePrimeServer(BindingHandle[iserver],
  449.          PrimeServerHandle[iserver]);
  450.       }
  451.    RpcExcept(1)
  452.       {
  453.       return;
  454.       }
  455.    RpcEndExcept
  456.    }
  457. void thread_client()
  458.    {
  459.    unsigned char no_active =0;
  460.    while(1)
  461.       {
  462.       char Buffer[STRING_LENGTH];
  463.       int  i;
  464.       if(VK_ESCAPE == get_character_no_wait())
  465.          {
  466.          EnterCriticalSection(&GlobalCriticalSection);
  467.          Sleep(WAIT);
  468.          for(i = 0;i < ipszNetAdd; i++)
  469.             NotifyServer((char)i);
  470.          clearscreen(0);
  471.          exit(0);
  472.          LeaveCriticalSection(&GlobalCriticalSection);
  473.          }
  474.       mxyputs(58, 2, "Number of Primes", WHITE_ON_CYAN);
  475.       sprintf(Buffer, "%s:%5d", "LOCAL  ", NoPrimeLocal);
  476.       mxyputs((unsigned char)(60), (unsigned char)(4), Buffer,
  477.          WHITE_ON_CYAN);
  478.          {
  479.          no_active = 0;
  480.          EnterCriticalSection(&GlobalCriticalSection);
  481.          for(i = 0; i < ipszNetAdd; i++)
  482.             if(IsActiveServer[i])
  483.                {
  484.                sprintf(Buffer, " %7s:%5d ", pszRemoteName[i],
  485.                   NoPrimeRemote[i]);
  486.                mxyputs(59, (unsigned char)(4+1+no_active), Buffer,
  487.                   RED_ON_CYAN);
  488.                no_active++;
  489.                }
  490.          box(58, 3, 74, (unsigned char)(5 + no_active), SINGLE);
  491.          mxyputc(58, (unsigned char)(6 + no_active), (char)32, 17,
  492.             CYAN_ON_CYAN);
  493.          }
  494.       no_active = 0;
  495.       for(i = 0; i < ipszNetAdd; i++)
  496.          if(!IsActiveServer[i])
  497.             {
  498.             sprintf(Buffer, " %7s:%5d ", pszRemoteName[i], NoPrimeRemote[i]);
  499.             mxyputs(59, (unsigned char)(4+15+no_active), Buffer,
  500.                RED_ON_CYAN);
  501.             no_active ++;
  502.             }
  503.       if(no_active)
  504.          {
  505.          mxyputs(58, (unsigned char)(17), "Inactive Servers",
  506.             WHITE_ON_CYAN);
  507.          box(58, (unsigned char)(18), 74, (unsigned char)(19 + no_active),
  508.             SINGLE);
  509.          mxyputc(58, (unsigned char)(20 + no_active), (char)32, 17,
  510.             CYAN_ON_CYAN);
  511.          }
  512.       else
  513.          for(i = 0; i < 5; i++)
  514.             mxyputc(58, (unsigned char)(17 + no_active + i), (char)32, 17,
  515.                CYAN_ON_CYAN);
  516.       LeaveCriticalSection(&GlobalCriticalSection);
  517.       CurrTime = (GetTickCount() - StartTime) / 1000;
  518.       sprintf(Buffer, "Primes = %d", NoPrimeLocal + NoPrimeRemoteT);
  519.       mxyputs(58, (unsigned char)(7 + ipszNetAdd), Buffer, WHITE_ON_CYAN);
  520.       sprintf(Buffer, "Time = %d.%02d min.", CurrTime/60, CurrTime%60);
  521.       mxyputs(58, (unsigned char)(8 + ipszNetAdd), Buffer, WHITE_ON_CYAN);
  522.       sprintf(Buffer,"First = %d", StartNumber);
  523.       mxyputs(58,(unsigned char)(1+5+3+ipszNetAdd), Buffer, WHITE_ON_CYAN);
  524.       }
  525.    }
  526. void __RPC_FAR * __RPC_USER midl_user_allocate(size_t len)
  527. {
  528.     return(malloc(len));
  529. }
  530. void __RPC_USER midl_user_free(void __RPC_FAR * ptr)
  531. {
  532.     free(ptr);
  533. }