|
|
1.1 root 1: //==========================================================================//
2: // Includes //
3: //==========================================================================//
4:
5:
6: #include "perfmon.h"
7: #include "playback.h" // external declarations for this module
8:
9: #include "bookmark.h" // for BookmarkAppend
10: #include "grafdata.h" // for ResetGraph
11: #include "perfdata.h" // for UpdateLinesForSystem
12: #include "perfmops.h" // for SystemTimeDateString
13: #include "log.h"
14: #include "pmemory.h" // for MemoryAllocate
15: #include "fileutil.h"
16: #include "utils.h"
17: #include "alert.h" // for ResetAlert
18: #include "report.h" // for ResetReport
19:
20: NTSTATUS AddNamesToArray (LPTSTR pNames,
21: DWORD dwLastID,
22: LPWSTR *lpCounterId) ;
23:
24:
25: void PlaybackAddCounterName (PLOGINDEX pIndex) ;
26:
27: //==========================================================================//
28: // Macros //
29: //==========================================================================//
30:
31:
32:
33: #define PointerSeek(pBase, lFileOffset) \
34: ((PVOID) ((PBYTE) pBase + lFileOffset))
35:
36:
37: //==========================================================================//
38: // Local Functions //
39: //==========================================================================//
40:
41:
42: PVOID PlaybackSeek (long lFileOffset)
43: { // PlaybackSeek
44: return (PointerSeek (PlaybackLog.pHeader, lFileOffset)) ;
45: } // PlaybackSeek
46:
47:
48: PLOGINDEXBLOCK FirstIndexBlock (PLOGHEADER pLogHeader)
49: {
50: return ((PLOGINDEXBLOCK) PointerSeek (pLogHeader, pLogHeader->iLength)) ;
51: }
52:
53:
54: PLOGINDEX IndexFromPosition (PLOGPOSITION pLogPosition)
55: {
56: return (&pLogPosition->pIndexBlock->aIndexes [pLogPosition->iIndex]) ;
57: }
58:
59:
60: PPERFDATA DataFromIndex (PLOGINDEX pLogIndex,
61: LPTSTR lpszSystemName)
62: {
63: PPERFDATA pPerfData;
64: TCHAR szLoggedComputerName[MAX_COMPUTERNAME_LENGTH + 3] ;
65: int iNumSystem ;
66:
67: // Note: NULL lpszSystemName means return first logged system name
68: // at the specified index.
69:
70: pPerfData = PlaybackSeek (pLogIndex->lDataOffset) ;
71:
72: for (iNumSystem = 0;
73: iNumSystem < pLogIndex->iSystemsLogged;
74: iNumSystem++)
75: {
76: if ( pPerfData &&
77: pPerfData->Signature[0] == (WCHAR)'P' &&
78: pPerfData->Signature[1] == (WCHAR)'E' &&
79: pPerfData->Signature[2] == (WCHAR)'R' &&
80: pPerfData->Signature[3] == (WCHAR)'F' )
81: {
82: GetPerfComputerName(pPerfData, szLoggedComputerName) ;
83: if (!lpszSystemName || strsamei(lpszSystemName, szLoggedComputerName))
84: {
85: return pPerfData ;
86: }
87: }
88: pPerfData = (PPERFDATA)((PBYTE) pPerfData +
89: pPerfData->TotalByteLength) ;
90: }
91: return NULL ;
92: }
93:
94:
95: PPERFDATA DataFromIndexPosition (PLOGPOSITION pLogPosition,
96: LPTSTR lpszSystemName)
97: {
98: PLOGINDEX pLogIndex ;
99: // long lDataFileOffset ;
100:
101: pLogIndex = IndexFromPosition (pLogPosition) ;
102: return (DataFromIndex (pLogIndex, lpszSystemName)) ;
103: }
104:
105:
106: BOOL NextLogPosition (IN OUT PLOGPOSITION pLogPosition)
107: {
108: PLOGINDEXBLOCK pIndexBlock ;
109:
110: if (pLogPosition->pIndexBlock->iNumIndexes == 0)
111: {
112: // no data in this index block. This is most likely
113: // a corrupted log file caused by system failure...
114: return (FALSE) ;
115: }
116:
117: if (pLogPosition->iIndex == pLogPosition->pIndexBlock->iNumIndexes - 1)
118: {
119: if (pLogPosition->pIndexBlock->lNextBlockOffset)
120: {
121: pIndexBlock =
122: PlaybackSeek (pLogPosition->pIndexBlock->lNextBlockOffset) ;
123:
124: if (pIndexBlock->iNumIndexes == 0)
125: {
126: // no data in the next index block. This is most likely
127: // a corrupted log file caused by system failure...
128: return (FALSE) ;
129: }
130: else
131: {
132: pLogPosition->pIndexBlock = pIndexBlock ;
133: pLogPosition->iIndex = 0 ;
134: return (TRUE) ;
135: }
136: }
137: else
138: return (FALSE) ;
139: }
140: else
141: {
142: pLogPosition->iIndex++ ;
143: return (TRUE) ;
144: }
145: }
146:
147:
148: BOOL NextIndexPosition (IN OUT PLOGPOSITION pLogPosition,
149: BOOL bCheckForNonDataIndexes)
150: /*
151: Effect: Set pLogPosition to the next log position from
152: the current position of pLogPosition if there is one.
153:
154: Returns: Whether there was a next log position.
155: */
156: { // NextIndexPosition
157: LOGPOSITION LP ;
158: PLOGINDEX pIndex ;
159: PBOOKMARK pBookmarkDisk, pBookmark ;
160: // LONG lFilePosition ;
161:
162: pIndex = IndexFromPosition (pLogPosition) ;
163:
164: LP = *pLogPosition ;
165: pBookmark = NULL ;
166:
167: while (TRUE)
168: { // while
169: if (!NextLogPosition (&LP))
170: return (FALSE) ;
171: pIndex = IndexFromPosition (&LP) ;
172:
173: if (pIndex && bCheckForNonDataIndexes && IsCounterNameIndex (pIndex))
174: {
175: PlaybackAddCounterName (pIndex) ;
176: }
177:
178: if (pIndex && bCheckForNonDataIndexes && IsBookmarkIndex (pIndex))
179: {
180: if (pBookmark)
181: {
182: // this is the case when several bookmarks are
183: // found before any data index...
184: pBookmark->iTic = PlaybackLog.iTotalTics ;
185: BookmarkAppend (&PlaybackLog.pBookmarkFirst, pBookmark) ;
186: }
187:
188: pBookmarkDisk = PlaybackSeek (pIndex->lDataOffset) ;
189: pBookmark = MemoryAllocate (sizeof (BOOKMARK)) ;
190: *pBookmark = *pBookmarkDisk;
191: pBookmark->pBookmarkNext = NULL ;
192: }
193:
194: if (pIndex && IsDataIndex (pIndex))
195: {
196: LP.iPosition++ ;
197: *pLogPosition = LP ;
198: if (pBookmark)
199: {
200: pBookmark->iTic = PlaybackLog.iTotalTics ;
201: BookmarkAppend (&PlaybackLog.pBookmarkFirst, pBookmark) ;
202: }
203: return (TRUE) ;
204: }
205: } // while
206: } // NextIndexPosition
207:
208:
209: BOOL NextReLogIndexPosition (IN OUT PLOGPOSITION pLogPosition)
210: /*
211: Effect: Set pLogPosition to the next log position from
212: the current position of pLogPosition if there is one.
213: Will return bookmarks, counternames, or data.
214:
215: Returns: Whether there was a next relog position.
216: */
217: { // NextReLogIndexPosition
218: LOGPOSITION LP ;
219: PLOGINDEX pIndex ;
220: // LONG lFilePosition ;
221:
222: pIndex = IndexFromPosition (pLogPosition) ;
223:
224: LP = *pLogPosition ;
225:
226: if (!NextLogPosition (&LP))
227: return (FALSE) ;
228: pIndex = IndexFromPosition (&LP) ;
229:
230: if (pIndex && IsDataIndex (pIndex))
231: {
232: LP.iPosition++ ;
233: }
234: *pLogPosition = LP ;
235: return (TRUE) ;
236: } // NextReLogIndexPosition
237:
238:
239:
240:
241:
242: //==========================================================================//
243: // Exported Functions //
244: //==========================================================================//
245:
246:
247: void PlaybackInitializeInstance (void)
248: { // PlaybackInitializeInstance
249: PlaybackLog.iStatus = iPMStatusClosed ;
250: PlaybackLog.hFile = NULL ;
251:
252: PlaybackLog.szFilePath = MemoryAllocate (FilePathLen * sizeof (TCHAR)) ;
253: PlaybackLog.szFileTitle = MemoryAllocate (FilePathLen * sizeof (TCHAR)) ;
254: lstrcpy (PlaybackLog.szFilePath, szDefaultLogFileName) ;
255: lstrcpy (PlaybackLog.szFileTitle, szDefaultLogFileName) ;
256: } // PlaybackInitializeInstance
257:
258:
259: INT OpenPlayback (LPTSTR lpszFilePath, LPTSTR lpszFileTitle)
260: { // OpenPlayback
261: BOOL bFirstTime = TRUE ;
262:
263: lstrcpy (PlaybackLog.szFilePath, lpszFilePath) ;
264: lstrcpy (PlaybackLog.szFileTitle, lpszFileTitle) ;
265: PlaybackLog.hFile = FileHandleOpen (lpszFilePath) ;
266: if (!PlaybackLog.hFile || PlaybackLog.hFile == INVALID_HANDLE_VALUE)
267: {
268: return (ERR_CANT_OPEN) ;
269: }
270:
271: PlaybackLog.pHeader = (PLOGHEADER) FileMap (PlaybackLog.hFile,
272: &PlaybackLog.hMapHandle) ;
273:
274: if (!PlaybackLog.pHeader)
275: {
276: if (PlaybackLog.hMapHandle)
277: {
278: CloseHandle (PlaybackLog.hMapHandle) ;
279: }
280:
281: CloseHandle (PlaybackLog.hFile) ;
282: return (ERR_CANT_OPEN) ;
283: }
284:
285: if (!strsame (PlaybackLog.pHeader->szSignature, LogFileSignature))
286: {
287: FileUnMap((LPVOID)PlaybackLog.pHeader, PlaybackLog.hMapHandle) ;
288: CloseHandle (PlaybackLog.hFile) ;
289: return (ERR_BAD_LOG_FILE) ;
290: }
291:
292: PlaybackLog.BeginIndexPos.pIndexBlock = FirstIndexBlock (PlaybackLog.pHeader) ;
293: PlaybackLog.BeginIndexPos.iIndex = 0 ;
294: PlaybackLog.BeginIndexPos.iPosition = 0 ;
295: PlaybackLog.pBookmarkFirst = NULL ;
296:
297: PlaybackLog.iTotalTics = 1 ;
298: PlaybackLog.EndIndexPos = PlaybackLog.BeginIndexPos ;
299: while (NextIndexPosition (&PlaybackLog.EndIndexPos, TRUE))
300: {
301: if (bFirstTime)
302: {
303: // set the begin index to the first data index
304: bFirstTime = FALSE ;
305: PlaybackLog.BeginIndexPos.iIndex =
306: PlaybackLog.EndIndexPos.iIndex ;
307: }
308: else
309: {
310: PlaybackLog.iTotalTics++ ;
311: }
312: }
313:
314: if (PlaybackLog.iTotalTics == 1 )
315: {
316: // no data inside the log file. It must be a corrupted
317: // log file
318: FileUnMap((LPVOID)PlaybackLog.pHeader, PlaybackLog.hMapHandle) ;
319: CloseHandle (PlaybackLog.hFile) ;
320: return (ERR_CORRUPT_LOG) ;
321: }
322:
323: // PlaybackLog.StartIndexPos = PlaybackLog.BeginIndexPos ;
324:
325: // getthe first data index
326: if (!LogPositionN (1, &(PlaybackLog.StartIndexPos)))
327: {
328: PlaybackLog.StartIndexPos = PlaybackLog.BeginIndexPos ;
329: }
330:
331: PlaybackLog.StopIndexPos = PlaybackLog.EndIndexPos ;
332: PlaybackLog.StopIndexPos.iPosition =
333: min (PlaybackLog.StopIndexPos.iPosition,
334: PlaybackLog.iTotalTics - 1 ) ;
335:
336:
337: PlaybackLog.iSelectedTics = PlaybackLog.iTotalTics ;
338:
339: PlaybackLog.iStatus = iPMStatusPlaying ;
340: return (0) ;
341: } // OpenPlayback
342:
343:
344: void CloseInputLog (HWND hWndParent)
345: { // CloseInputLog
346: PBOOKMARK pBookmark, pNextBookmark ;
347: BOOL retCode, retCode1 ;
348: PLOGCOUNTERNAME pLogCounterName, pNextCounterName ;
349:
350: UNREFERENCED_PARAMETER (hWndParent) ;
351:
352: // free the bookmark list
353: for (pBookmark = PlaybackLog.pBookmarkFirst ;
354: pBookmark ;
355: pBookmark = pNextBookmark )
356: {
357: // save next bookmark and free current bookmark
358: pNextBookmark = pBookmark->pBookmarkNext ;
359: MemoryFree (pBookmark) ;
360: }
361: PlaybackLog.pBookmarkFirst = NULL ;
362:
363: // free all counter names stuff
364: if (PlaybackLog.pBaseCounterNames)
365: {
366: MemoryFree (PlaybackLog.pBaseCounterNames) ;
367: }
368: PlaybackLog.pBaseCounterNames = NULL ;
369: PlaybackLog.lBaseCounterNameSize = 0 ;
370: PlaybackLog.lBaseCounterNameOffset = 0 ;
371:
372: for (pLogCounterName = PlaybackLog.pLogCounterNameFirst ;
373: pLogCounterName ;
374: pLogCounterName = pNextCounterName)
375: {
376: pNextCounterName = pLogCounterName->pCounterNameNext ;
377: MemoryFree (pLogCounterName->pRemainNames) ;
378: MemoryFree (pLogCounterName) ;
379: }
380:
381: PlaybackLog.pLogCounterNameFirst = NULL ;
382:
383: retCode1 = FileUnMap((LPVOID)PlaybackLog.pHeader, PlaybackLog.hMapHandle) ;
384: retCode = CloseHandle (PlaybackLog.hFile) ;
385: PlaybackLog.iStatus = iPMStatusClosed ;
386:
387: ResetGraphView (hWndGraph) ;
388: ResetAlertView (hWndAlert) ;
389: ResetLogView (hWndLog) ;
390: ResetReportView (hWndReport) ;
391: }
392:
393:
394:
395: BOOL LogPositionN (int iIndex, PLOGPOSITION pLP)
396: { // LogPositionN
397: LOGPOSITION LP ;
398: int i ;
399:
400: LP = PlaybackLog.BeginIndexPos ;
401: for (i = 0 ;
402: i < iIndex ;
403: i++)
404: {
405: if (!NextIndexPosition (&LP, FALSE))
406: return (FALSE) ;
407: }
408:
409: *pLP = LP ;
410: return (TRUE) ;
411: } // LogPositionN
412:
413:
414: PLOGINDEX PlaybackIndexN (int iIndex)
415: {
416: LOGPOSITION LP ;
417: int i ;
418:
419: LP = PlaybackLog.BeginIndexPos ;
420: for (i = 0 ;
421: i < iIndex ;
422: i++)
423: {
424: if (!NextIndexPosition (&LP, FALSE))
425: return (NULL) ;
426: }
427:
428: return (IndexFromPosition (&LP)) ;
429: }
430:
431:
432: BOOL PlaybackLines (PPERFSYSTEM pSystemFirst,
433: PLINE pLineFirst,
434: int iLogTic)
435: { // PlaybackLines
436:
437: PLOGINDEX pLogIndex ;
438: PPERFDATA pPerfData ;
439: PPERFSYSTEM pSystem ;
440: BOOL bAnyFound ;
441:
442: pLogIndex = PlaybackIndexN (iLogTic) ;
443: if (!pLogIndex)
444: return (FALSE) ;
445:
446: bAnyFound = FALSE ;
447: for (pSystem = pSystemFirst ;
448: pSystem ;
449: pSystem = pSystem->pSystemNext)
450: { // for
451: pPerfData = DataFromIndex (pLogIndex, pSystem->sysName) ;
452: if (pPerfData)
453: {
454: UpdateLinesForSystem (pSystem->sysName,
455: pPerfData,
456: pLineFirst) ;
457: bAnyFound = TRUE ;
458: }
459: else
460: {
461: FailedLinesForSystem (pSystem->sysName,
462: pPerfData,
463: pLineFirst) ;
464: }
465: }
466: return (bAnyFound) ;
467: } // PlaybackLines
468:
469:
470:
471:
472: PPERFDATA LogDataFromPosition (PPERFSYSTEM pSystem,
473: PLOGPOSITION pLogPosition)
474: { // LogDataFromPosition
475: PLOGINDEX pLogIndex ;
476:
477:
478: if (!pLogPosition)
479: return (NULL) ;
480:
481: pLogIndex = IndexFromPosition (pLogPosition) ;
482: if (!pLogIndex)
483: return (NULL) ;
484:
485: return (DataFromIndex (pLogIndex, pSystem->sysName)) ;
486: } // LogDataFromPosition
487:
488:
489:
490: BOOL LogPositionSystemTime (PLOGPOSITION pLP, SYSTEMTIME *pSystemTime)
491: /*
492: Effect: Given a logposition, get the index entry for that position
493: and return the system time stored therein.
494: */
495: { // LogPositionSystemTime
496: PLOGINDEX pLogIndex ;
497:
498: pLogIndex = IndexFromPosition (pLP) ;
499: if (!pLogIndex)
500: return (FALSE) ;
501:
502: *pSystemTime = pLogIndex->SystemTime ;
503: } // LogPositionSystemTime
504:
505:
506: int LogPositionIntervalSeconds (PLOGPOSITION pLPStart,
507: PLOGPOSITION pLPStop)
508: /*
509: Effect: Return the time difference (in seconds) between the
510: system times of the two specified log positions.
511: */
512: { // LogPositionIntervalSeconds
513: SYSTEMTIME SystemTimeStart ;
514: SYSTEMTIME SystemTimeStop ;
515:
516:
517: if (LogPositionSystemTime (pLPStart, &SystemTimeStart) &&
518: LogPositionSystemTime (pLPStop, &SystemTimeStop))
519: return (SystemTimeDifference (&SystemTimeStart, &SystemTimeStop)) ;
520: else
521: return (0) ;
522: } // LogPositionIntervalSeconds
523:
524:
525:
526: int PlaybackSelectedSeconds (void)
527: { // PlaybackSelectedSeconds
528: return (LogPositionIntervalSeconds (&PlaybackLog.StartIndexPos,
529: &PlaybackLog.StopIndexPos)) ;
530: } // PlaybackSelectedSeconds
531:
532: void BuildLogComputerList (HWND hDlg, int DlgID)
533: {
534: PPERFDATA pPerfData;
535: int iNumSystem ;
536: HWND hListBox = GetDlgItem (hDlg, DlgID) ;
537: PLOGINDEX pLogIndex ;
538: TCHAR szLoggedComputerName[MAX_COMPUTERNAME_LENGTH + 3] ;
539:
540: pLogIndex = IndexFromPosition (&(PlaybackLog.StartIndexPos)) ;
541: pPerfData = PlaybackSeek (pLogIndex->lDataOffset) ;
542:
543: for (iNumSystem = 0;
544: iNumSystem < pLogIndex->iSystemsLogged;
545: iNumSystem++)
546: {
547: if ( pPerfData &&
548: pPerfData->Signature[0] == (WCHAR)'P' &&
549: pPerfData->Signature[1] == (WCHAR)'E' &&
550: pPerfData->Signature[2] == (WCHAR)'R' &&
551: pPerfData->Signature[3] == (WCHAR)'F' )
552: {
553: GetPerfComputerName(pPerfData, szLoggedComputerName) ;
554: LBAdd (hListBox, szLoggedComputerName) ;
555: }
556: pPerfData = (PPERFDATA)((PBYTE) pPerfData +
557: pPerfData->TotalByteLength) ;
558: }
559: } // BuildLogComputerList
560:
561: void PlaybackAddCounterName (PLOGINDEX pIndex)
562: {
563: PLOGCOUNTERNAME pLogCounterName, pListCounterName ;
564: PLOGFILECOUNTERNAME pDiskCounterName ;
565: PVOID pCounterData ;
566: BOOL bExist = FALSE ;
567:
568: pDiskCounterName = PlaybackSeek (pIndex->lDataOffset) ;
569:
570: // check we have a record for this system
571: for (pListCounterName = PlaybackLog.pLogCounterNameFirst ;
572: pListCounterName ;
573: pListCounterName = pListCounterName->pCounterNameNext)
574: {
575: if (strsamei(pDiskCounterName->szComputer,
576: pListCounterName->CounterName.szComputer))
577: {
578: // found!
579: pLogCounterName = pListCounterName ;
580: bExist = TRUE ;
581: break ;
582: }
583: }
584:
585: if (!bExist)
586: {
587: // new counter name record
588: if (!(pLogCounterName = MemoryAllocate (sizeof(LOGCOUNTERNAME))))
589: {
590: return ;
591: }
592: }
593: else
594: {
595: // free old memory in previous counter name record.
596: if (pLogCounterName->pRemainNames)
597: {
598: MemoryFree (pLogCounterName->pRemainNames) ;
599: }
600: pLogCounterName->pRemainNames = NULL ;
601: }
602:
603: pLogCounterName->CounterName = *pDiskCounterName ;
604:
605: if (pDiskCounterName->lBaseCounterNameOffset == 0)
606: {
607: // this is the base counter names,
608: // get the master copy of the counter names
609:
610: if (!(pCounterData =
611: MemoryAllocate (pDiskCounterName->lUnmatchCounterNames)))
612: {
613: MemoryFree (pLogCounterName) ;
614: return ;
615: }
616:
617: // free the old one if it exists.
618: if (PlaybackLog.pBaseCounterNames)
619: {
620: MemoryFree (PlaybackLog.pBaseCounterNames) ;
621: }
622:
623: PlaybackLog.pBaseCounterNames = pCounterData ;
624:
625: pCounterData =
626: PlaybackSeek (pDiskCounterName->lCurrentCounterNameOffset) ;
627:
628: memcpy (PlaybackLog.pBaseCounterNames,
629: pCounterData,
630: pDiskCounterName->lUnmatchCounterNames) ;
631:
632: PlaybackLog.lBaseCounterNameSize =
633: pDiskCounterName->lUnmatchCounterNames ;
634:
635: PlaybackLog.lBaseCounterNameOffset =
636: pDiskCounterName->lBaseCounterNameOffset ;
637: }
638: else if (pDiskCounterName->lUnmatchCounterNames)
639: {
640: // this is not a based system and it has extra counter names
641: // allocate a buffer to hold them
642: pLogCounterName->pRemainNames =
643: MemoryAllocate (pDiskCounterName->lUnmatchCounterNames) ;
644:
645: if (pLogCounterName->pRemainNames)
646: {
647: pCounterData =
648: PlaybackSeek (pDiskCounterName->lCurrentCounterNameOffset) ;
649:
650: memcpy(pLogCounterName->pRemainNames,
651: pCounterData,
652: pDiskCounterName->lUnmatchCounterNames) ;
653: }
654: }
655:
656: if (!bExist)
657: {
658: // now add the new counter name record to the linked list
659: if (!PlaybackLog.pLogCounterNameFirst)
660: {
661: PlaybackLog.pLogCounterNameFirst = pLogCounterName ;
662: }
663: else
664: {
665: for (pListCounterName = PlaybackLog.pLogCounterNameFirst ;
666: pListCounterName->pCounterNameNext ;
667: pListCounterName = pListCounterName->pCounterNameNext)
668: {
669: // do nothing until we get to the end of the list
670: ;
671: }
672: pListCounterName->pCounterNameNext = pLogCounterName ;
673: }
674: }
675:
676: } // PlaybackAddCounterName
677:
678:
679: LPWSTR *LogBuildNameTable (PPERFSYSTEM pSysInfo)
680: {
681:
682: DWORD dwArraySize ;
683: PLOGCOUNTERNAME pCounterName ;
684: LPWSTR *lpCounterId = NULL ;
685: LPWSTR lpCounterNames ;
686: NTSTATUS Status ;
687:
688: for (pCounterName = PlaybackLog.pLogCounterNameFirst ;
689: pCounterName ;
690: pCounterName = pCounterName->pCounterNameNext)
691: {
692: if (strsamei (pSysInfo->sysName, pCounterName->CounterName.szComputer))
693: {
694: // found the right system
695: break ;
696: }
697: }
698: if (!pCounterName)
699: {
700: goto ERROR_EXIT ;
701: }
702:
703: dwArraySize = (pCounterName->CounterName.dwLastCounterId + 1)
704: * sizeof (LPWSTR) ;
705:
706: lpCounterId = MemoryAllocate (dwArraySize +
707: pCounterName->CounterName.lMatchLength +
708: pCounterName->CounterName.lUnmatchCounterNames ) ;
709:
710: if (!lpCounterId)
711: {
712: goto ERROR_EXIT ;
713: }
714:
715: // initialize pointers into buffer
716:
717: lpCounterNames = (LPWSTR)((LPBYTE)lpCounterId + dwArraySize);
718: if (pCounterName->CounterName.lBaseCounterNameOffset == 0)
719: {
720: // this is the base system
721: memcpy(lpCounterNames,
722: PlaybackLog.pBaseCounterNames,
723: PlaybackLog.lBaseCounterNameSize) ;
724: }
725: else
726: {
727: // copy the matched portion from the base system
728: memcpy(lpCounterNames,
729: PlaybackLog.pBaseCounterNames,
730: pCounterName->CounterName.lMatchLength) ;
731:
732: // copy the unmatched portion
733: if (pCounterName->CounterName.lUnmatchCounterNames)
734: {
735: memcpy(((PBYTE)lpCounterNames +
736: pCounterName->CounterName.lMatchLength),
737: pCounterName->pRemainNames,
738: pCounterName->CounterName.lUnmatchCounterNames) ;
739: }
740: }
741:
742: Status = AddNamesToArray (lpCounterNames,
743: pCounterName->CounterName.dwLastCounterId,
744: lpCounterId) ;
745:
746: if (Status != ERROR_SUCCESS)
747: {
748: goto ERROR_EXIT ;
749: }
750:
751: pSysInfo->CounterInfo.dwLastId =
752: pCounterName->CounterName.dwLastCounterId ;
753: pSysInfo->CounterInfo.dwLangId =
754: pCounterName->CounterName.dwLangId ;
755: pSysInfo->CounterInfo.dwHelpSize = 0 ;
756: pSysInfo->CounterInfo.dwCounterSize =
757: pCounterName->CounterName.lMatchLength +
758: pCounterName->CounterName.lUnmatchCounterNames ;
759:
760: return (lpCounterId) ;
761:
762: ERROR_EXIT:
763: if (lpCounterId)
764: {
765: MemoryFree (lpCounterId) ;
766: }
767: return (NULL) ;
768: } // LogBuildNameTable
769:
770:
771:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.