home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / sdktools / winnt / perfmon / system.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-13  |  16.6 KB  |  561 lines

  1. //
  2. //  Foreign computer support needs more work (a-robw)
  3. //
  4. #ifdef FOREIGN_COMPUTER_SUPPORT
  5. #undef FOREIGN_COMPUTER_SUPPORT
  6. #endif
  7.  
  8. #include "perfmon.h"
  9. #include "system.h"     // external declarations for this file
  10.  
  11. #include "perfdata.h"
  12. #include "perfmops.h"
  13. #include "playback.h"   // for PlayingBackLog
  14. #include "pmemory.h"
  15. #include "utils.h"      // for strsame, et al
  16. #include "sizes.h"
  17.  
  18.  
  19. DWORD
  20. SystemCount(
  21.     PPERFSYSTEM pSystemFirst
  22. )
  23. {
  24.     PPERFSYSTEM       pSystem ;
  25.     DWORD           iNumSystems ;
  26.  
  27.     iNumSystems = 0 ;
  28.  
  29.     for (pSystem = pSystemFirst ;
  30.          pSystem ;
  31.          pSystem = pSystem->pSystemNext) {
  32.         iNumSystems++ ;
  33.     }
  34.  
  35.     return iNumSystems ;
  36. }
  37.  
  38.  
  39. BOOL
  40. SystemSetupThread (PPERFSYSTEM pSystem)
  41. {
  42.     DWORD           dwThreadID ;
  43.     HANDLE          hThread ;
  44.     HANDLE          hStateDataMutex ;
  45.     HANDLE          hPerfDataEvent ;
  46.     SECURITY_ATTRIBUTES  SecAttr ;
  47.     PPERFDATA       pSystemPerfData ;
  48.  
  49.  
  50.     SecAttr.nLength = sizeof (SecAttr) ;
  51.     SecAttr.bInheritHandle = TRUE ;
  52.     SecAttr.lpSecurityDescriptor = NULL ;
  53.  
  54.     hThread = CreateThread (&SecAttr, 1024L, 
  55.         (LPTHREAD_START_ROUTINE)PerfDataThread, (LPVOID)(pSystem), 0L, &dwThreadID);
  56.  
  57.     if (!hThread) {
  58.         SystemFree (pSystem, TRUE);
  59.         return (FALSE) ;
  60.     }
  61.  
  62.     // create a State Data Lock mutex
  63.     hStateDataMutex = CreateMutex (&SecAttr, FALSE, NULL);
  64.     if (!hStateDataMutex) {
  65.         CloseHandle (hThread) ;
  66.         SystemFree (pSystem, TRUE);
  67.         return (FALSE);
  68.     }
  69.     hPerfDataEvent = CreateEvent (&SecAttr, TRUE, 0L, NULL) ;
  70.     if (!hPerfDataEvent) {
  71.         CloseHandle (hStateDataMutex) ;
  72.         CloseHandle (hThread) ;
  73.         SystemFree (pSystem, TRUE);
  74.         return (FALSE);
  75.     }
  76.     
  77.     // allocate Perfdata
  78.     pSystemPerfData = (PPERFDATA) MemoryAllocate (4096L) ;
  79.     if (!pSystemPerfData) {
  80.         CloseHandle (hPerfDataEvent) ;
  81.         CloseHandle (hStateDataMutex) ;
  82.         CloseHandle (hThread) ;
  83.         SystemFree (pSystem, TRUE);
  84.         return (FALSE);
  85.     }
  86.     // now setup the pSystem..
  87.     pSystem->dwThreadID = dwThreadID ;
  88.     pSystem->hThread = hThread ;
  89.     pSystem->hPerfDataEvent = hPerfDataEvent ;
  90.     pSystem->pSystemPerfData = pSystemPerfData ;
  91.     pSystem->hStateDataMutex = hStateDataMutex ;
  92.  
  93.     return (TRUE) ;
  94. }
  95.  
  96. PPERFSYSTEM
  97. SystemCreate (
  98.     LPCTSTR lpszSystemName
  99. )
  100. {
  101.     PPERFSYSTEM     pSystem ;
  102.     PPERFDATA       pLocalPerfData;
  103.     DWORD           Status ;
  104.     DWORD           dwMemSize;
  105.     TCHAR           GlobalValueBuffer[] = L"Global" ;
  106.     TCHAR           ForeignValueBuffer[8+MAX_SYSTEM_NAME_LENGTH+1] =
  107.                     L"Foreign " ;
  108.  
  109.     // attempt to allocate system data structure
  110.  
  111.     pSystem = MemoryAllocate (sizeof (PERFSYSTEM)) ;
  112.     if (!pSystem) {
  113.         SetLastError (ERROR_OUTOFMEMORY) ;
  114.         return (NULL) ;
  115.     }
  116.  
  117.     // initialize name and help table pointers
  118.  
  119.     pSystem->CounterInfo.pNextTable = NULL;
  120.     pSystem->CounterInfo.dwLangId = 0;
  121.     pSystem->CounterInfo.dwLastId = 0;
  122.     pSystem->CounterInfo.TextString = NULL;
  123.  
  124.     lstrcpy (pSystem->sysName, lpszSystemName) ;
  125.    
  126.     // try to open key to registry, error code is in GetLastError()
  127.  
  128.     pSystem->sysDataKey = OpenSystemPerfData(lpszSystemName);
  129.  
  130.     // if a Null Key was returned then:
  131.     //  a) there's no such computer
  132.     //  b) the system is a foreign computer
  133.     //
  134.     //  before giving up, then see if it's a foreign computer
  135.  
  136.     if (!pSystem->sysDataKey) {
  137.         
  138.         // build foreign computer string
  139.  
  140.         lstrcat(ForeignValueBuffer, lpszSystemName) ;
  141.         
  142.         // assign System value name pointer to the local variable for trial
  143.  
  144.         pSystem->lpszValue = ForeignValueBuffer;
  145.  
  146.         // try to get data from the computer to see if it's for real
  147.         // otherwise, give up and return NULL
  148.  
  149.         pLocalPerfData = MemoryAllocate (STARTING_SYSINFO_SIZE);
  150.         if (pLocalPerfData == NULL) { // no mem so give up
  151.             SetLastError (ERROR_OUTOFMEMORY);
  152.             pSystem->lpszValue = NULL;
  153.             SystemFree (pSystem, TRUE);
  154.             return (NULL);
  155.         } else {
  156.             pSystem->sysDataKey = HKEY_PERFORMANCE_DATA; // local machine
  157.             bCloseLocalMachine = TRUE ;
  158.  
  159.             dwMemSize = STARTING_SYSINFO_SIZE;
  160.             Status = GetSystemPerfData (
  161.                     pSystem->sysDataKey,
  162.                     pSystem->lpszValue,
  163.                     pLocalPerfData,
  164.                     &dwMemSize);
  165.  
  166.             // success means a valid buffer came back
  167.             // more data means someone tried (so it's probably good (?)
  168.  
  169.             if (!((Status == ERROR_MORE_DATA) || (Status == ERROR_SUCCESS)) ||
  170.                 !((pLocalPerfData->Signature[0] == (WCHAR)'P') &&
  171.                   (pLocalPerfData->Signature[1] == (WCHAR)'E') &&
  172.                   (pLocalPerfData->Signature[2] == (WCHAR)'R') &&
  173.                   (pLocalPerfData->Signature[3] == (WCHAR)'F'))) {
  174.                 MemoryFree (pLocalPerfData) ;
  175.  
  176.                 // if we are reading from a setting file, let this pass thru'
  177.                 if (bDelayAddAction == TRUE) {
  178.                    pSystem->sysDataKey = NULL ;
  179.                    pSystem->FailureTime = GetTickCount();
  180.                    pSystem->dwSystemState = SYSTEM_DOWN;
  181.  
  182.                    // Free any memory that may have created
  183.                    SystemFree (pSystem, FALSE) ;
  184.  
  185.                    pSystem->lpszValue = MemoryAllocate (TEMP_BUF_LEN*sizeof(WCHAR));
  186.   
  187.                    if (!pSystem->lpszValue) {
  188.                       // unable to allocate memory
  189.                       SetLastError (ERROR_OUTOFMEMORY);
  190.                       SystemFree (pSystem, TRUE);
  191.                       return (NULL) ;
  192.                    } else {
  193.                       lstrcpy (pSystem->lpszValue, GlobalValueBuffer);
  194.                    }
  195.  
  196.                    // Setup the thread's stuff
  197.                    if (SystemSetupThread (pSystem))
  198.                       return (pSystem) ;
  199.                    else 
  200.                       return NULL;
  201.                 }
  202.                 SetLastError (ERROR_BAD_NET_NAME); // unable to find name
  203.                 SystemFree (pSystem, TRUE);
  204.                 return NULL;
  205.             }
  206.  
  207.             MemoryFree (pLocalPerfData);    // don't really need anything from it
  208.     
  209.             // ok, so we've established that a foreign data provider
  210.             // exists, now to finish the initialization.
  211.  
  212.             // change system name in structure to get counter names
  213.  
  214.             lstrcpy (pSystem->sysName, LocalComputerName);
  215.  
  216.             Status = GetSystemNames(pSystem);   // get counter names & explain text
  217.             if (Status != ERROR_SUCCESS) {
  218.                 // unable to get names so bail out
  219.                 SetLastError (Status);
  220.                 SystemFree (pSystem, TRUE);
  221.                 return (NULL) ;
  222.             }
  223.  
  224.             // restore computer name for displays, etc.
  225.  
  226.             lstrcpy (pSystem->sysName, lpszSystemName);
  227.     
  228.             // allocate value string buffer
  229.             pSystem->lpszValue = MemoryAllocate (TEMP_BUF_LEN*sizeof(WCHAR));
  230.             if (!pSystem->lpszValue) {
  231.                 // unable to allocate memory
  232.                 SetLastError (ERROR_OUTOFMEMORY);
  233.                 SystemFree (pSystem, TRUE);
  234.                 return (NULL) ;
  235.             } else {
  236.                 lstrcpy (pSystem->lpszValue, ForeignValueBuffer);
  237.             }
  238.         }
  239.     } else {
  240.         // if here, then a connection to the system's registry was established
  241.         // so continue with the system data structure initialization
  242.  
  243.         // get counter names & explain text from local computer
  244.  
  245.         Status = GetSystemNames(pSystem);   
  246.         if (Status != ERROR_SUCCESS) {
  247.             // unable to get names so bail out
  248.             SetLastError (Status);
  249.             SystemFree (pSystem, TRUE);
  250.             return (NULL) ;
  251.         }
  252.  
  253.         // allocate value string buffer
  254.         pSystem->lpszValue = MemoryAllocate(TEMP_BUF_LEN*sizeof(WCHAR));
  255.  
  256.         if (!pSystem->lpszValue) {
  257.             // unable to allocate memory
  258.             SetLastError (ERROR_OUTOFMEMORY);
  259.             SystemFree (pSystem, TRUE);
  260.             return (NULL) ;
  261.         } else {
  262.             SetSystemValueNameToGlobal (pSystem);
  263.         }
  264.     }
  265.  
  266.     // initialize remaining system pointers
  267.  
  268.     pSystem->pSystemNext = NULL ;
  269.     pSystem->FailureTime = 0;
  270.  
  271.     // setup data for thread data collection
  272.     if (!PlayingBackLog()) {
  273.         // create a thread for data collection
  274.         if (!SystemSetupThread (pSystem))
  275.            return (NULL) ;
  276.     } 
  277.  
  278.     SetLastError (ERROR_SUCCESS);
  279.  
  280.     return (pSystem) ;
  281. }  // SystemCreate
  282.  
  283. PPERFSYSTEM
  284. SystemGet (
  285.     PPERFSYSTEM pSystemFirst,
  286.     LPCTSTR lpszSystemName
  287. )
  288. {
  289.     PPERFSYSTEM       pSystem ;
  290.  
  291.     if (!pSystemFirst) {
  292.         return (NULL) ;
  293.     }
  294.     
  295.     for (pSystem = pSystemFirst ;
  296.          pSystem ;
  297.          pSystem = pSystem->pSystemNext) {
  298.         if (strsamei (pSystem->sysName, lpszSystemName)) {
  299.             return (pSystem) ;
  300.         }
  301.     }  // for
  302.  
  303.     return (NULL) ;
  304. }
  305.  
  306. PPERFSYSTEM
  307. SystemAdd (
  308.     PPPERFSYSTEM ppSystemFirst,
  309.     LPCTSTR lpszSystemName
  310. )
  311. {
  312.     PPERFSYSTEM       pSystem ;
  313.     PPERFSYSTEM       pSystemPrev ;
  314.  
  315.  
  316.     if (!*ppSystemFirst) {
  317.         *ppSystemFirst = SystemCreate (lpszSystemName) ;
  318.         return (*ppSystemFirst) ;
  319.     }
  320.  
  321.     for (pSystem = *ppSystemFirst ;
  322.          pSystem ;
  323.          pSystem = pSystem->pSystemNext) {
  324.         pSystemPrev = pSystem ;
  325.         if (strsamei (pSystem->sysName, lpszSystemName)) {
  326.             return (pSystem) ;
  327.         }
  328.     }  // for
  329.  
  330.     pSystemPrev->pSystemNext = SystemCreate (lpszSystemName) ;
  331.     return (pSystemPrev->pSystemNext) ;
  332. }
  333.  
  334. void
  335. SystemFree (
  336.     PPERFSYSTEM pSystem,
  337.     BOOL        bDeleteTheSystem
  338. )
  339. {  // SystemFree
  340.  
  341.     PCOUNTERTEXT pCounter, pNextCounter;
  342.  
  343.     if (!pSystem) {
  344.         // can't proceed
  345.         return ;
  346.     }
  347.  
  348.     if (pSystem->sysDataKey && pSystem->sysDataKey != HKEY_PERFORMANCE_DATA) {
  349.         // close the remote computer key
  350.         RegCloseKey (pSystem->sysDataKey);
  351.         pSystem->sysDataKey = 0 ;
  352.     }
  353.  
  354.     for (pCounter = pSystem->CounterInfo.pNextTable, pNextCounter = NULL;
  355.          pCounter;
  356.          pCounter = pNextCounter) {
  357.         pNextCounter = pCounter->pNextTable;
  358.         MemoryFree (pCounter);
  359.     }
  360.     pSystem->CounterInfo.pNextTable = NULL ;
  361.  
  362.     if (pSystem->CounterInfo.TextString) {
  363.         MemoryFree (pSystem->CounterInfo.TextString);
  364.         pSystem->CounterInfo.TextString = NULL ;
  365.     }
  366.  
  367.     if (pSystem->CounterInfo.HelpTextString) {
  368.         MemoryFree (pSystem->CounterInfo.HelpTextString);
  369.         pSystem->CounterInfo.HelpTextString = NULL ;
  370.     }
  371.     pSystem->CounterInfo.dwLastId = 0 ;
  372.     pSystem->CounterInfo.dwHelpSize = 0 ;
  373.     pSystem->CounterInfo.dwCounterSize = 0 ;
  374.  
  375.     if (bDeleteTheSystem) {
  376. #if 0
  377.         // cleanup all the data collection variables
  378.         if (pSystem->hPerfDataEvent)
  379.             CloseHandle (pSystem->hPerfDataEvent) ;
  380.  
  381.         if (pSystem->hStateDataMutex)
  382.             CloseHandle (pSystem->hStateDataMutex) ;
  383.  
  384.         if (pSystem->hThread)
  385.             CloseHandle (pSystem->hThread) ;
  386.  
  387.         if (pSystem->pSystemPerfData)
  388.             MemoryFree (pSystem->pSystemPerfData);
  389.  
  390.         if (pSystem->lpszValue) {
  391.             MemoryFree (pSystem->lpszValue);
  392.             pSystem->lpszValue = NULL ;
  393.         }
  394.         MemoryFree (pSystem) ;
  395. #endif
  396.         if (pSystem->hThread) {
  397.             // let the thread clean up memory
  398.             PostThreadMessage (
  399.                pSystem->dwThreadID,
  400.                WM_FREE_SYSTEM,
  401.                (WPARAM)0,
  402.                (LPARAM)0) ;
  403.         } else {
  404.             // if no thread, clean up memory here.
  405.             // Should not happen.
  406.             if (pSystem->pSystemPerfData)
  407.                 MemoryFree (pSystem->pSystemPerfData);
  408.  
  409.             if (pSystem->lpszValue) {
  410.                 MemoryFree (pSystem->lpszValue);
  411.                 pSystem->lpszValue = NULL ;
  412.             }
  413.             MemoryFree (pSystem) ;
  414.         }
  415.     }
  416. }
  417.  
  418. void
  419. DeleteUnusedSystems (
  420.     PPPERFSYSTEM  ppSystemFirst ,
  421.     int           iNoUseSystems
  422. )
  423. {
  424.     PPERFSYSTEM   pPrevSys, pCurrentSys, pNextSys ;
  425.  
  426.     // delete all the marked system from the list header until
  427.     // we hit one that is not marked
  428.     while ((*ppSystemFirst)->bSystemNoLongerNeeded) {
  429.        // delect from the list header
  430.        pCurrentSys = *ppSystemFirst ;
  431.        *ppSystemFirst = pCurrentSys->pSystemNext ;
  432.        SystemFree (pCurrentSys, TRUE) ;
  433.        iNoUseSystems-- ;
  434.        if (iNoUseSystems <= 0 || !(*ppSystemFirst)) {
  435.           // done
  436.           break ;
  437.        }
  438.     }
  439.  
  440.     if (iNoUseSystems <= 0 || !(*ppSystemFirst)) {
  441.        return ;
  442.     }
  443.  
  444.     // now walk the list and delete each marked system
  445.     for (pPrevSys = *ppSystemFirst, pCurrentSys = pPrevSys->pSystemNext ;
  446.          pCurrentSys && iNoUseSystems > 0 ;
  447.          pCurrentSys = pNextSys) {
  448.  
  449.        if (pCurrentSys->bSystemNoLongerNeeded) {
  450.           // the current system is marked, updated the list and free
  451.           // this system.  No need to change pPrevSys here
  452.           pNextSys = pPrevSys->pSystemNext = pCurrentSys->pSystemNext ;
  453.           SystemFree (pCurrentSys, TRUE) ;
  454.           iNoUseSystems-- ;
  455.        } else {
  456.           // pCurrentSys is OK, update the 2 list pointers and 
  457.           // carry on looping
  458.           pPrevSys = pCurrentSys ;
  459.           pNextSys = pCurrentSys->pSystemNext ;
  460.        }
  461.     }
  462. }
  463.  
  464. void
  465. FreeSystems (
  466.     PPERFSYSTEM pSystemFirst
  467. )
  468. {
  469.     PPERFSYSTEM    pSystem, pSystemNext ;
  470.  
  471.  
  472.     for (pSystem = pSystemFirst; 
  473.          pSystem; 
  474.          pSystem = pSystemNext) {
  475.         pSystemNext = pSystem->pSystemNext ;
  476.         SystemFree (pSystem, TRUE) ;
  477.     }
  478. }  // FreeSystems
  479.  
  480. PPERFSYSTEM
  481. GetComputer (
  482.     HDLG hDlg,
  483.     WORD wControlID,
  484.     BOOL bWarn,
  485.     PPERFDATA *ppPerfData,
  486.     PPERFSYSTEM *ppSystemFirst
  487. )
  488. /*
  489.    Effect:        Attempt to set the current computer to the one in the
  490.                   hWndComputers dialog edit box. If this computer system
  491.                   can be found, load the objects, etc. for the computer
  492.                   and set pSystem and ppPerfdata to the values for this
  493.                   system.
  494. */
  495. {  // GetComputer
  496.     TCHAR          szComputer [MAX_SYSTEM_NAME_LENGTH + 1] ;
  497.     PPERFSYSTEM    pSystem;
  498.     TCHAR          tempBuffer [LongTextLen] ;
  499.     DWORD          dwBufferSize ;
  500.     LPTSTR         pBuffer = NULL ;
  501.  
  502.     DialogText (hDlg, wControlID, szComputer) ;
  503.  
  504.     // If necessary, add the system to the lists for this view.
  505.     pSystem = SystemGet (*ppSystemFirst, szComputer) ;
  506.     if (!pSystem) {
  507.         pSystem = SystemAdd (ppSystemFirst, szComputer) ;
  508.     }
  509.  
  510.     if (!pSystem && bWarn) {
  511.         DialogSetString (hDlg, wControlID, LocalComputerName) ;
  512.  
  513.         // Note: this will succeed since the local computer is always
  514.         // available
  515.         EditSetModified (GetDlgItem(hDlg, wControlID), FALSE) ;
  516.     
  517.         pSystem = SystemGet (*ppSystemFirst, LocalComputerName) ;
  518.         if (!pSystem) {
  519.             pSystem = SystemAdd (ppSystemFirst, LocalComputerName) ;
  520.         }
  521.  
  522. //        MessageBoxResource (hDlg, IDS_COMPUTERNOTFOUND, IDS_APPNAME, MB_OK) ;
  523.         DlgErrorBox (hDlg, ERR_COMPUTERNOTFOUND) ;
  524.  
  525.         SetFocus (DialogControl(hDlg, wControlID)) ;
  526.     }
  527.  
  528.     if (pSystem) {
  529.         if (PlayingBackLog ()) {
  530.             *ppPerfData =
  531.             LogDataFromPosition (pSystem, &(PlaybackLog.StartIndexPos)) ;
  532.         } else {
  533.  
  534.             if (pSystem->lpszValue) {
  535.                // save the previous lpszValue string before 
  536.                // SetSystemValueNameToGlobal screw it up
  537.                dwBufferSize = MemorySize (pSystem->lpszValue) ;
  538.                if (dwBufferSize <= sizeof(tempBuffer)) {
  539.                   pBuffer = tempBuffer ;
  540.                } else {
  541.                   pBuffer = MemoryAllocate (dwBufferSize) ;
  542.                }
  543.                memcpy (pBuffer, pSystem->lpszValue, dwBufferSize) ;
  544.             }
  545.  
  546.             SetSystemValueNameToGlobal (pSystem);
  547.             UpdateSystemData (pSystem, ppPerfData) ;
  548.  
  549.             if (pSystem->lpszValue) {
  550.                // retore the previous lpszValue string
  551.                memcpy (pSystem->lpszValue, pBuffer, dwBufferSize) ;
  552.                if (pBuffer != tempBuffer) {
  553.                   MemoryFree (pBuffer) ;
  554.                }
  555.             }
  556.         }
  557.     }
  558.     return (pSystem) ;
  559.  
  560. }  // GetComputer
  561.