Source code of Windows XP (NT5)
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.

770 lines
18 KiB

  1. /*++
  2. Copyright (c) 1990 Microsoft Corporation
  3. Module Name:
  4. TESTWIN.C
  5. Abstract:
  6. Test program for the eventlog service. This program calls the Win
  7. APIs to test out the operation of the service.
  8. Author:
  9. Rajen Shah (rajens) 05-Aug-1991
  10. Revision History:
  11. --*/
  12. /*----------------------*/
  13. /* INCLUDES */
  14. /*----------------------*/
  15. #include <nt.h>
  16. #include <ntrtl.h>
  17. #include <nturtl.h>
  18. #include <stdio.h> // printf
  19. #include <string.h> // stricmp
  20. #include <stdlib.h>
  21. #include <windows.h>
  22. #include <netevent.h>
  23. //
  24. // Turn on NotifyChangeEventLog
  25. //
  26. #define TEST_NOTIFY 1
  27. //#define TEST_REMOTE 1
  28. #define READ_BUFFER_SIZE 1024*2 // Use 2K buffer
  29. #define SIZE_DATA_ARRAY 65
  30. //
  31. // Global buffer used to emulate "binary data" when writing an event
  32. // record.
  33. //
  34. DWORD Data[SIZE_DATA_ARRAY];
  35. // LPWSTR ServerName=L"\\\\danl2";
  36. LPWSTR ServerName=NULL;
  37. VOID
  38. Initialize (
  39. VOID
  40. )
  41. {
  42. DWORD i;
  43. // Initialize the values in the data buffer.
  44. //
  45. for (i=0; i< SIZE_DATA_ARRAY; i++)
  46. Data[i] = i;
  47. }
  48. BOOL
  49. Usage (
  50. VOID
  51. )
  52. {
  53. printf( "usage: \n" );
  54. printf( "-b <filename> Tests BackupEventLog API\n");
  55. printf( "-c Tests ClearEventLog API\n");
  56. printf( "-n Tests NotifyChangeEventlog\n");
  57. printf( "-rsb Reads event log sequentially backwards\n");
  58. printf( "-rsf Reads event log sequentially forwards\n");
  59. printf( "-rrb <record> Reads event log from <record> backwards\n");
  60. printf( "-rrf <record> Reads event log from <record> forwards\n");
  61. printf( "-w <count> Tests ReportEvent API <count> times\n");
  62. return ERROR_INVALID_PARAMETER;
  63. } // Usage
  64. BOOL
  65. WriteLogEntry ( HANDLE LogHandle, DWORD EventID )
  66. {
  67. #define NUM_STRINGS 2
  68. BOOL Status;
  69. WORD EventType, i;
  70. DWORD DataSize;
  71. PSID pUserSid;
  72. PWSTR Strings[NUM_STRINGS] = {L"StringAOne",
  73. L"StringATwo"
  74. };
  75. EventType = EVENTLOG_INFORMATION_TYPE;
  76. pUserSid = NULL;
  77. DataSize = sizeof(DWORD) * SIZE_DATA_ARRAY;
  78. for (i=0; i< SIZE_DATA_ARRAY; i++)
  79. Data[i] += i;
  80. Status = ReportEventW (
  81. LogHandle,
  82. EventType,
  83. 0, // event category
  84. EventID,
  85. pUserSid,
  86. NUM_STRINGS,
  87. DataSize,
  88. Strings,
  89. (PVOID)Data
  90. );
  91. return (Status);
  92. }
  93. DWORD
  94. WriteLogEntryMsg ( HANDLE LogHandle, DWORD EventID )
  95. /*
  96. This function requires a registry entry in the Applications section
  97. of the Eventlog for TESTWINAPP, it will use the netevent.dll message file.
  98. */
  99. {
  100. #define NUM_STRINGS 2
  101. WORD EventType;
  102. DWORD DataSize;
  103. PSID pUserSid;
  104. PWSTR Strings[NUM_STRINGS];
  105. Strings[0] = L"This is a BOGUS message for TEST purposes Ignore this substitution text";
  106. Strings[1] = L"GHOST SERVICE in the long string format - I wanted a long string to pass into this function";
  107. EventType = EVENTLOG_INFORMATION_TYPE;
  108. pUserSid = NULL;
  109. DataSize = sizeof(DWORD) * SIZE_DATA_ARRAY;
  110. if (!ReportEventW (
  111. LogHandle,
  112. EventType,
  113. 0, // event category
  114. EVENT_SERVICE_START_FAILED_NONE,
  115. pUserSid,
  116. NUM_STRINGS,
  117. 0, // DataSize
  118. Strings,
  119. (PVOID)NULL // Data
  120. )) {
  121. printf("ReportEventW failed %d\n",GetLastError());
  122. return(GetLastError());
  123. }
  124. return (NO_ERROR);
  125. }
  126. VOID
  127. DisplayEventRecords( PVOID Buffer,
  128. DWORD BufSize,
  129. ULONG *NumRecords)
  130. {
  131. PEVENTLOGRECORD pLogRecord;
  132. ANSI_STRING StringA;
  133. UNICODE_STRING StringU;
  134. PWSTR pwString;
  135. DWORD Count = 0;
  136. DWORD Offset = 0;
  137. DWORD i;
  138. pLogRecord = (PEVENTLOGRECORD) Buffer;
  139. while ((DWORD)Offset < BufSize) {
  140. printf("\nRecord # %lu\n", ++Count);
  141. printf("Length: 0x%lx TimeGenerated: 0x%lx EventID: 0x%lx EventType: 0x%x\n",
  142. pLogRecord->Length, pLogRecord->TimeGenerated, pLogRecord->EventID,
  143. pLogRecord->EventType);
  144. printf("NumStrings: 0x%x StringOffset: 0x%lx UserSidLength: 0x%lx TimeWritten: 0x%lx\n",
  145. pLogRecord->NumStrings, pLogRecord->StringOffset,
  146. pLogRecord->UserSidLength, pLogRecord->TimeWritten);
  147. printf("UserSidOffset: 0x%lx DataLength: 0x%lx DataOffset: 0x%lx \n",
  148. pLogRecord->UserSidOffset, pLogRecord->DataLength,
  149. pLogRecord->DataOffset);
  150. //
  151. // Print out module name
  152. //
  153. pwString = (PWSTR)((DWORD)pLogRecord + sizeof(EVENTLOGRECORD));
  154. RtlInitUnicodeString (&StringU, pwString);
  155. RtlUnicodeStringToAnsiString (&StringA, &StringU, TRUE);
  156. printf("ModuleName: %s ", StringA.Buffer);
  157. RtlFreeAnsiString (&StringA);
  158. //
  159. // Display ComputerName
  160. //
  161. pwString = pwString + (wcslen(pwString) + 1);
  162. RtlInitUnicodeString (&StringU, pwString);
  163. RtlUnicodeStringToAnsiString (&StringA, &StringU, TRUE);
  164. printf("ComputerName: %s\n",StringA.Buffer);
  165. RtlFreeAnsiString (&StringA);
  166. //
  167. // Display strings
  168. //
  169. pwString = (PWSTR)((DWORD)Buffer + pLogRecord->StringOffset);
  170. printf("\nStrings: \n");
  171. for (i=0; i<pLogRecord->NumStrings; i++) {
  172. RtlInitUnicodeString (&StringU, pwString);
  173. RtlUnicodeStringToAnsiString (&StringA, &StringU, TRUE);
  174. printf(" %s \n",StringA.Buffer);
  175. RtlFreeAnsiString (&StringA);
  176. pwString = (PWSTR)((DWORD)pwString + StringU.MaximumLength);
  177. }
  178. // Get next record
  179. //
  180. Offset += pLogRecord->Length;
  181. pLogRecord = (PEVENTLOGRECORD)((DWORD)Buffer + Offset);
  182. }
  183. *NumRecords = Count;
  184. }
  185. BOOL
  186. ReadFromLog ( HANDLE LogHandle,
  187. PVOID Buffer,
  188. ULONG *pBytesRead,
  189. DWORD ReadFlag,
  190. DWORD Record
  191. )
  192. {
  193. BOOL Status;
  194. DWORD MinBytesNeeded;
  195. DWORD ErrorCode;
  196. Status = ReadEventLogW (
  197. LogHandle,
  198. ReadFlag,
  199. Record,
  200. Buffer,
  201. READ_BUFFER_SIZE,
  202. pBytesRead,
  203. &MinBytesNeeded
  204. );
  205. if (!Status) {
  206. ErrorCode = GetLastError();
  207. if (ErrorCode == ERROR_HANDLE_EOF) {
  208. Status = TRUE;
  209. }
  210. else if (ErrorCode == ERROR_NO_MORE_FILES) {
  211. printf("Buffer too small. Need %lu bytes min\n", MinBytesNeeded);
  212. }
  213. else {
  214. printf("Error from ReadEventLog %d \n", ErrorCode);
  215. }
  216. }
  217. return (Status);
  218. }
  219. BOOL
  220. TestReadEventLog (DWORD Count, DWORD ReadFlag, DWORD Record)
  221. {
  222. BOOL bStatus,IStatus;
  223. DWORD status;
  224. HANDLE LogHandle;
  225. LPWSTR ModuleName;
  226. DWORD NumRecords, BytesReturned;
  227. PVOID Buffer;
  228. DWORD RecordOffset;
  229. DWORD NumberOfRecords;
  230. DWORD OldestRecord;
  231. printf("Testing ReadEventLog API to read %lu entries\n",Count);
  232. Buffer = malloc (READ_BUFFER_SIZE);
  233. //
  234. // Initialize the strings
  235. //
  236. NumRecords = Count;
  237. ModuleName = L"TESTWINAPP";
  238. //
  239. // Open the log handle
  240. //
  241. printf("OpenEventLog - ");
  242. LogHandle = OpenEventLogW (
  243. ServerName,
  244. ModuleName
  245. );
  246. if (LogHandle == NULL) {
  247. printf("Error - %d\n", GetLastError());
  248. } else {
  249. printf("SUCCESS\n");
  250. //
  251. // Get and print record information
  252. //
  253. bStatus = GetNumberOfEventLogRecords(LogHandle, & NumberOfRecords);
  254. if (bStatus) {
  255. bStatus = GetOldestEventLogRecord(LogHandle, & OldestRecord);
  256. }
  257. if (!bStatus) {
  258. printf("Query of record information failed with %X", GetLastError());
  259. return(bStatus);
  260. }
  261. printf("\nThere are %d records in the file, %d is the oldest"
  262. " record number\n", NumberOfRecords, OldestRecord);
  263. RecordOffset = Record;
  264. printf("Reading %u records\r", Count);
  265. while (Count) {
  266. //
  267. // Read from the log
  268. //
  269. bStatus = ReadFromLog ( LogHandle,
  270. Buffer,
  271. &BytesReturned,
  272. ReadFlag,
  273. RecordOffset
  274. );
  275. if (bStatus) {
  276. printf("Bytes read = 0x%lx\n", BytesReturned);
  277. printf("Read %u records\n", NumRecords);
  278. DisplayEventRecords(Buffer, BytesReturned, &NumRecords);
  279. Count -= NumRecords;
  280. RecordOffset += NumRecords;
  281. } else {
  282. break;
  283. }
  284. if (BytesReturned == 0)
  285. break;
  286. }
  287. printf("\n");
  288. if (!bStatus) {
  289. printf ("ReadFromLog Error - %d. Remaining count %lu\n", GetLastError(),
  290. Count);
  291. } else {
  292. printf ("SUCCESS\n");
  293. }
  294. printf("Calling CloseEventLog\n");
  295. IStatus = CloseEventLog (LogHandle);
  296. }
  297. return (bStatus);
  298. }
  299. BOOL
  300. TestWriteEventLog (DWORD Count)
  301. {
  302. DWORD Status=NO_ERROR;
  303. BOOL IStatus;
  304. HANDLE LogHandle;
  305. LPWSTR ModuleName;
  306. DWORD EventID = 99;
  307. DWORD WriteCount;
  308. DWORD DataNum=0;
  309. printf("Testing ReportEvent API\n");
  310. //
  311. // Initialize the strings
  312. //
  313. ModuleName = L"TESTWINAPP";
  314. printf("Calling RegisterEventSource for WRITE %lu times\n", Count);
  315. while ((Count > 0) && (Status== NO_ERROR)) {
  316. //
  317. // Open the log handle
  318. //
  319. LogHandle = RegisterEventSourceW (
  320. ServerName,
  321. ModuleName
  322. );
  323. if (LogHandle == NULL) {
  324. Status = GetLastError();
  325. printf("RegisterEventSource Failure - %d\n", Status);
  326. return(Status);
  327. } else {
  328. printf("Registered - ");
  329. WriteCount = 5;
  330. printf("Record # %u: ", Count);
  331. while ((WriteCount>0) && (Status==NO_ERROR)) {
  332. //
  333. // Write an entry into the log
  334. //
  335. Data[0] = DataNum; // Make data "unique"
  336. EventID = (EventID + DataNum) % 100; // Vary the eventids
  337. Status = WriteLogEntryMsg( LogHandle, EventID );
  338. DataNum++;
  339. WriteCount--;
  340. if (Status != NO_ERROR) {
  341. printf ("WriteLogEntry Error - %d. Remaining count %lu\n",Status,Count);
  342. } else {
  343. printf ("%d,",WriteCount);
  344. }
  345. }
  346. IStatus = DeregisterEventSource (LogHandle);
  347. printf(" - Deregistered\n");
  348. }
  349. Count--;
  350. }
  351. printf("\n");
  352. return (Status);
  353. }
  354. BOOL
  355. TestClearLogFile ()
  356. {
  357. BOOL Status, IStatus;
  358. HANDLE LogHandle;
  359. LPWSTR ModuleName, BackupName;
  360. printf("Testing ClearLogFile API\n");
  361. //
  362. // Initialize the strings
  363. //
  364. ModuleName = L"TESTWINAPP";
  365. //
  366. // Open the log handle
  367. //
  368. printf("Calling OpenEventLog for CLEAR - ");
  369. LogHandle = OpenEventLogW (
  370. NULL,
  371. ModuleName
  372. );
  373. if (LogHandle == NULL) {
  374. printf("OpenEventLog Error - %d\n", GetLastError());
  375. } else {
  376. printf("SUCCESS\n");
  377. //
  378. // Clear the log file and back it up to "view.log"
  379. //
  380. printf("Calling ClearEventLog backing up to view.log ");
  381. BackupName = L"\\\\danhi386\\roote\\view.log";
  382. Status = ClearEventLogW (
  383. LogHandle,
  384. BackupName
  385. );
  386. if (!Status) {
  387. printf ("ClearEventLog Error - %d\n", GetLastError());
  388. } else {
  389. printf ("SUCCESS\n");
  390. }
  391. //
  392. // Now just clear the file without backing it up
  393. //
  394. printf("Calling ClearEventLog with no backup ");
  395. Status = ClearEventLogW (
  396. LogHandle,
  397. NULL
  398. );
  399. if (!Status) {
  400. printf ("ClearEventLogError - %d\n", GetLastError());
  401. } else {
  402. printf ("SUCCESS\n");
  403. }
  404. printf("Calling CloseEventLog\n");
  405. IStatus = CloseEventLog (LogHandle);
  406. }
  407. return(Status);
  408. }
  409. BOOL
  410. TestBackupLogFile (LPSTR BackupFileName)
  411. {
  412. BOOL Status, IStatus;
  413. HANDLE LogHandle;
  414. LPWSTR ModuleName;
  415. ANSI_STRING AnsiString;
  416. UNICODE_STRING UnicodeString;
  417. printf("Testing BackupLogFile API\n");
  418. //
  419. // Initialize the strings
  420. //
  421. ModuleName = L"TESTWINAPP";
  422. //
  423. // Open the log handle
  424. //
  425. printf("Calling OpenEventLog for BACKUP - ");
  426. LogHandle = OpenEventLogW (
  427. NULL,
  428. ModuleName
  429. );
  430. if (LogHandle == NULL) {
  431. printf("OpenEventLog Failure %d\n", GetLastError());
  432. } else {
  433. printf("OpenEventLog SUCCESS\n");
  434. //
  435. // Backup the log file to BackupFileName
  436. //
  437. printf("Calling BackupEventLog backing up to %s ", BackupFileName);
  438. RtlInitAnsiString(&AnsiString, BackupFileName);
  439. RtlAnsiStringToUnicodeString(&UnicodeString, &AnsiString, TRUE);
  440. Status = BackupEventLogW (LogHandle, UnicodeString.Buffer);
  441. if (!Status) {
  442. printf ("BackupEventLog failure - %d\n", GetLastError());
  443. } else {
  444. printf ("SUCCESS\n");
  445. }
  446. printf("Calling CloseEventLog\n");
  447. IStatus = CloseEventLog (LogHandle);
  448. }
  449. return(Status);
  450. }
  451. VOID
  452. NotifyThread(
  453. HANDLE hEventLog)
  454. {
  455. Sleep(30000);
  456. printf("NotifyThread: Writing an event...\n");
  457. if (!WriteLogEntryMsg(hEventLog,1)) {
  458. printf("NotifyThread: WriteLogEntryMsg failed\n");
  459. }
  460. else {
  461. printf("Event was written\n");
  462. }
  463. ExitThread(NO_ERROR);
  464. }
  465. VOID
  466. TestChangeNotify(
  467. )
  468. /*++
  469. Routine Description:
  470. Arguments:
  471. Return Value:
  472. --*/
  473. {
  474. HANDLE hEvent;
  475. HANDLE hThread;
  476. HANDLE hEventLog;
  477. DWORD threadId;
  478. DWORD status;
  479. hEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
  480. if (hEvent == NULL) {
  481. printf("CreateEvent Failed %d\n",GetLastError());
  482. return;
  483. }
  484. #ifdef TEST_REMOTE
  485. hEventLog = RegisterEventSourceW(L"\\\\DANL2",L"TESTWINAPP");
  486. #else
  487. hEventLog = RegisterEventSourceW(NULL,L"TESTWINAPP");
  488. #endif
  489. if (hEventLog == NULL) {
  490. printf("OpenEventLog failed %d\n",GetLastError());
  491. }
  492. #ifdef TEST_NOTIFY
  493. if (!NotifyChangeEventLog(hEventLog,hEvent)) {
  494. printf("NotifyChangeEventLog failed %d\n",GetLastError());
  495. }
  496. #endif // TEST_NOTIFY
  497. hThread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)NotifyThread,hEventLog,0,&threadId);
  498. if (hThread == NULL) {
  499. printf("CreateThread Failed %d\n",GetLastError());
  500. CloseHandle(hEvent);
  501. return;
  502. }
  503. CloseHandle(hThread);
  504. printf("Wait for event to become signaled\n");
  505. status = WaitForSingleObject(hEvent,INFINITE);
  506. if (status == WAIT_OBJECT_0) {
  507. printf("The Event was signaled\n");
  508. }
  509. else {
  510. printf("The Event was NOT signaled\n");
  511. }
  512. return;
  513. }
  514. /****************************************************************************/
  515. DWORD __cdecl
  516. main (
  517. IN SHORT argc,
  518. IN PSZ argv[],
  519. IN PSZ envp[]
  520. )
  521. /*++
  522. *
  523. * Routine Description:
  524. *
  525. *
  526. *
  527. * Arguments:
  528. *
  529. *
  530. *
  531. *
  532. * Return Value:
  533. *
  534. *
  535. *
  536. --*/
  537. /****************************************************************************/
  538. {
  539. DWORD ReadFlags;
  540. Initialize(); // Init any data
  541. if ( argc < 2 ) {
  542. printf( "Not enough parameters\n" );
  543. return Usage( );
  544. }
  545. if ( stricmp( argv[1], "-c" ) == 0 ) {
  546. if ( argc < 3 ) {
  547. return TestClearLogFile();
  548. }
  549. }
  550. else if ( stricmp( argv[1], "-b" ) == 0 ) {
  551. if ( argc < 3 ) {
  552. printf("You must supply a filename to backup to\n");
  553. return(FALSE);
  554. }
  555. return TestBackupLogFile(argv[2]);
  556. } else if (stricmp ( argv[1], "-rsf" ) == 0 ) {
  557. ReadFlags = EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ;
  558. if ( argc < 3 ) {
  559. return TestReadEventLog(1,ReadFlags,0 );
  560. } else {
  561. return Usage();
  562. }
  563. } else if (stricmp ( argv[1], "-rsb" ) == 0 ) {
  564. ReadFlags = EVENTLOG_SEQUENTIAL_READ | EVENTLOG_BACKWARDS_READ;
  565. if ( argc < 3 ) {
  566. return TestReadEventLog(1,ReadFlags,0 );
  567. } else {
  568. return Usage();
  569. }
  570. } else if (stricmp ( argv[1], "-n" ) == 0 ) {
  571. TestChangeNotify();
  572. } else if (stricmp ( argv[1], "-rrf" ) == 0 ) {
  573. ReadFlags = EVENTLOG_SEEK_READ | EVENTLOG_FORWARDS_READ;
  574. if ( argc < 3 ) {
  575. return TestReadEventLog(1,ReadFlags ,1);
  576. } else if (argc == 3) {
  577. return (TestReadEventLog (1, ReadFlags, atoi(argv[2])));
  578. }
  579. } else if (stricmp ( argv[1], "-rrb" ) == 0 ) {
  580. ReadFlags = EVENTLOG_SEEK_READ | EVENTLOG_BACKWARDS_READ;
  581. if ( argc < 3 ) {
  582. return TestReadEventLog(1,ReadFlags, 1);
  583. } else if (argc == 3) {
  584. return (TestReadEventLog (1, ReadFlags, atoi(argv[2])));
  585. }
  586. } else if (stricmp ( argv[1], "-w" ) == 0 ) {
  587. if ( argc < 3 ) {
  588. return TestWriteEventLog(1);
  589. } else if (argc == 3) {
  590. return (TestWriteEventLog (atoi(argv[2])));
  591. }
  592. } else {
  593. return Usage();
  594. }
  595. UNREFERENCED_PARAMETER(argc);
  596. UNREFERENCED_PARAMETER(argv);
  597. UNREFERENCED_PARAMETER(envp);
  598. }