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 / pviewer / perfdata.c < prev    next >
C/C++ Source or Header  |  1997-10-05  |  9KB  |  343 lines

  1.  
  2. /******************************************************************************\
  3. *       This is a part of the Microsoft Source Code Samples. 
  4. *       Copyright (C) 1993-1997 Microsoft Corporation.
  5. *       All rights reserved. 
  6. *       This source code is only intended as a supplement to 
  7. *       Microsoft Development Tools and/or WinHelp documentation.
  8. *       See these sources for detailed information regarding the 
  9. *       Microsoft samples programs.
  10. \******************************************************************************/
  11.  
  12.  
  13. /******************************************************************************
  14.  
  15.                         P E R F O R M A N C E   D A T A
  16.  
  17.     Name:       perfdata.c
  18.  
  19.     Description:
  20.         This module together with objdata.c, instdata.c, and cntrdata.c
  21.         access the performance data.
  22.  
  23. ******************************************************************************/
  24.  
  25. #include <windows.h>
  26. #include <winperf.h>
  27. #include "perfdata.h"
  28. #include <stdlib.h>
  29.  
  30.  
  31.  
  32.  
  33. LPTSTR      *gPerfTitleSz;
  34. LPTSTR      TitleData;
  35.  
  36.  
  37.  
  38.  
  39. //*********************************************************************
  40. //
  41. //  GetPerfData
  42. //
  43. //      Get a new set of performance data.
  44. //
  45. //      *ppData should be NULL initially.
  46. //      This function will allocate a buffer big enough to hold the
  47. //      data requested by szObjectIndex.
  48. //
  49. //      *pDataSize specifies the initial buffer size.  If the size is
  50. //      too small, the function will increase it until it is big enough
  51. //      then return the size through *pDataSize.  Caller should
  52. //      deallocate *ppData if it is no longer being used.
  53. //
  54. //      Returns ERROR_SUCCESS if no error occurs.
  55. //
  56. //      Note: the trial and error loop is quite different from the normal
  57. //            registry operation.  Normally if the buffer is too small,
  58. //            RegQueryValueEx returns the required size.  In this case,
  59. //            the perflib, since the data is dynamic, a buffer big enough
  60. //            for the moment may not be enough for the next. Therefor,
  61. //            the required size is not returned.
  62. //
  63. //            One should start with a resonable size to avoid the overhead
  64. //            of reallocation of memory.
  65. //
  66. DWORD   GetPerfData    (HKEY        hPerfKey,
  67.                         LPTSTR      szObjectIndex,
  68.                         PPERF_DATA  *ppData,
  69.                         DWORD       *pDataSize)
  70. {
  71. DWORD   DataSize;
  72. DWORD   dwR;
  73. DWORD   Type;
  74.  
  75.  
  76.     if (!*ppData)
  77.         *ppData = (PPERF_DATA) LocalAlloc (LMEM_FIXED, *pDataSize);
  78.  
  79.  
  80.     do  {
  81.         DataSize = *pDataSize;
  82.         dwR = RegQueryValueEx (hPerfKey,
  83.                                szObjectIndex,
  84.                                NULL,
  85.                                &Type,
  86.                                (BYTE *)*ppData,
  87.                                &DataSize);
  88.  
  89.         if (dwR == ERROR_MORE_DATA)
  90.             {
  91.             LocalFree (*ppData);
  92.             *pDataSize += 1024;
  93.             *ppData = (PPERF_DATA) LocalAlloc (LMEM_FIXED, *pDataSize);
  94.             }
  95.  
  96.         if (!*ppData)
  97.             {
  98.             LocalFree (*ppData);
  99.             return ERROR_NOT_ENOUGH_MEMORY;
  100.             }
  101.  
  102.         } while (dwR == ERROR_MORE_DATA);
  103.  
  104.     return dwR;
  105. }
  106.  
  107.  
  108.  
  109.  
  110. #ifdef UNICODE
  111.  
  112. #define atoi    atoiW
  113.  
  114.  
  115. //*********************************************************************
  116. //
  117. //  atoiW
  118. //
  119. //      Unicode version of atoi.
  120. //
  121. INT atoiW (LPTSTR s)
  122. {
  123. INT i = 0;
  124.  
  125.      while (iswdigit (*s))
  126.         {
  127.           i = i*10 + (BYTE)*s - L'0';
  128.         s++;
  129.         }
  130.  
  131.     return i;
  132. }
  133.  
  134. #endif
  135.  
  136.  
  137.  
  138.  
  139. //*********************************************************************
  140. //
  141. //  GetPerfTitleSz
  142. //
  143. //      Retrieves the performance data title strings.
  144. //
  145. //       This call retrieves english version of the title strings.
  146. //
  147. //       For NT 3.1, the counter names are stored in the "Counters" value
  148. //       in the ...\perflib\009 key.  For 3.5 and later, the 009 key is no
  149. //      longer used.  The counter names should be retrieved from "Counter 009"
  150. //      value of HKEY_PERFORMANCE_KEY.
  151. //
  152. //      Caller should provide two pointers, one for buffering the title
  153. //      strings the other for indexing the title strings.  This function will
  154. //      allocate memory for the TitleBuffer and TitleSz.  To get the title
  155. //      string for a particular title index one would just index the TitleSz.
  156. //      *TitleLastIdx returns the highest index can be used.  If TitleSz[N] is
  157. //      NULL then there is no Title for index N.
  158. //
  159. //      Example:  TitleSz[20] points to titile string for title index 20.
  160. //
  161. //      When done with the TitleSz, caller should LocalFree(*TitleBuffer).
  162. //
  163. //      This function returns ERROR_SUCCESS if no error.
  164. //
  165. DWORD   GetPerfTitleSz (HKEY    hKeyMachine,
  166.                         HKEY    hKeyPerf,
  167.                         LPTSTR  *TitleBuffer,
  168.                         LPTSTR  *TitleSz[],
  169.                         DWORD   *TitleLastIdx)
  170. {
  171. HKEY      hKey1;
  172. HKEY    hKey2;
  173. DWORD   Type;
  174. DWORD   DataSize;
  175. DWORD   dwR;
  176. DWORD   Len;
  177. DWORD   Index;
  178. DWORD   dwTemp;
  179. BOOL    bNT10;
  180. LPTSTR  szCounterValueName;
  181. LPTSTR  szTitle;
  182.  
  183.  
  184.  
  185.  
  186.     // Initialize
  187.     //
  188.     hKey1        = NULL;
  189.     hKey2        = NULL;
  190.     *TitleBuffer = NULL;
  191.     *TitleSz     = NULL;
  192.  
  193.  
  194.  
  195.  
  196.     // Open the perflib key to find out the last counter's index and system version.
  197.     //
  198.     dwR = RegOpenKeyEx (hKeyMachine,
  199.                         TEXT("software\\microsoft\\windows nt\\currentversion\\perflib"),
  200.                         0,
  201.                         KEY_READ,
  202.                         &hKey1);
  203.     if (dwR != ERROR_SUCCESS)
  204.         goto done;
  205.  
  206.  
  207.  
  208.     // Get the last counter's index so we know how much memory to allocate for TitleSz
  209.     //
  210.     DataSize = sizeof (DWORD);
  211.     dwR = RegQueryValueEx (hKey1, TEXT("Last Counter"), 0, &Type, (LPBYTE)TitleLastIdx, &DataSize);
  212.     if (dwR != ERROR_SUCCESS)
  213.         goto done;
  214.  
  215.  
  216.  
  217.     // Find system version, for system earlier than 1.0a, there's no version value.
  218.     //
  219.     dwR = RegQueryValueEx (hKey1, TEXT("Version"), 0, &Type, (LPBYTE)&dwTemp, &DataSize);
  220.  
  221.     if (dwR != ERROR_SUCCESS)
  222.         // unable to read the value, assume NT 1.0
  223.         bNT10 = TRUE;
  224.     else
  225.         // found the value, so, NT 1.0a or later
  226.         bNT10 = FALSE;
  227.  
  228.  
  229.  
  230.  
  231.  
  232.  
  233.  
  234.  
  235.  
  236.     // Now, get ready for the counter names and indexes.
  237.     //
  238.     if (bNT10)
  239.         {
  240.         // NT 1.0, so make hKey2 point to ...\perflib\009 and get
  241.         //  the counters from value "Counters"
  242.         //
  243.         szCounterValueName = TEXT("Counters");
  244.         dwR = RegOpenKeyEx (hKeyMachine,
  245.                             TEXT("software\\microsoft\\windows nt\\currentversion\\perflib\\009"),
  246.                             0,
  247.                             KEY_READ,
  248.                             &hKey2);
  249.         if (dwR != ERROR_SUCCESS)
  250.             goto done;
  251.         }
  252.     else
  253.         {
  254.         // NT 1.0a or later.  Get the counters in key HKEY_PERFORMANCE_KEY
  255.         //  and from value "Counter 009"
  256.         //
  257.         szCounterValueName = TEXT("Counter 009");
  258.         hKey2 = hKeyPerf;
  259.         }
  260.  
  261.  
  262.  
  263.  
  264.  
  265.     // Find out the size of the data.
  266.     //
  267.     dwR = RegQueryValueEx (hKey2, szCounterValueName, 0, &Type, 0, &DataSize);
  268.     if (dwR != ERROR_SUCCESS)
  269.         goto done;
  270.  
  271.  
  272.  
  273.     // Allocate memory
  274.     //
  275.     *TitleBuffer = (LPTSTR)LocalAlloc (LMEM_FIXED, DataSize);
  276.     if (!*TitleBuffer)
  277.         {
  278.         dwR = ERROR_NOT_ENOUGH_MEMORY;
  279.         goto done;
  280.         }
  281.  
  282.     *TitleSz = (LPTSTR *)LocalAlloc (LPTR, (*TitleLastIdx+1) * sizeof (LPTSTR));
  283.     if (!*TitleSz)
  284.         {
  285.         dwR = ERROR_NOT_ENOUGH_MEMORY;
  286.         goto done;
  287.         }
  288.  
  289.  
  290.  
  291.  
  292.  
  293.     // Query the data
  294.     //
  295.     dwR = RegQueryValueEx (hKey2, szCounterValueName, 0, &Type, (BYTE *)*TitleBuffer, &DataSize);
  296.     if (dwR != ERROR_SUCCESS)
  297.         goto done;
  298.  
  299.  
  300.  
  301.  
  302.     // Setup the TitleSz array of pointers to point to beginning of each title string.
  303.     // TitleBuffer is type REG_MULTI_SZ.
  304.     //
  305.     szTitle = *TitleBuffer;
  306.  
  307.     while (Len = lstrlen (szTitle))
  308.         {
  309.         Index = atoi (szTitle);
  310.  
  311.         szTitle = szTitle + Len +1;
  312.  
  313.         if (Index <= *TitleLastIdx)
  314.             (*TitleSz)[Index] = szTitle;
  315.  
  316.         szTitle = szTitle + lstrlen (szTitle) +1;
  317.         }
  318.  
  319.  
  320.  
  321. done:
  322.  
  323.     // Done. Now cleanup!
  324.     //
  325.     if (dwR != ERROR_SUCCESS)
  326.         {
  327.         // There was an error, free the allocated memory
  328.         //
  329.         if (*TitleBuffer) LocalFree (*TitleBuffer);
  330.         if (*TitleSz)     LocalFree (*TitleSz);
  331.         }
  332.  
  333.     // Close the hKeys.
  334.     //
  335.     if (hKey1) RegCloseKey (hKey1);
  336.     if (hKey2 && hKey2 != hKeyPerf) RegCloseKey (hKey2);
  337.  
  338.  
  339.  
  340.     return dwR;
  341.  
  342. }
  343.