1286{
1292 ULONG FreeSpace = 0;
1295
1297
1298 if (LogFile->ReadOnly)
1300
1301
1302
1305
1306 Record->RecordNumber = LogFile->Header.CurrentRecordNumber;
1307
1308
1309 if (LogFile->Header.StartOffset <= LogFile->Header.EndOffset)
1310 FreeSpace = LogFile->Header.MaxSize - LogFile->Header.EndOffset + LogFile->Header.StartOffset -
sizeof(
EVENTLOGHEADER);
1311 else
1312 FreeSpace = LogFile->Header.StartOffset - LogFile->Header.EndOffset;
1313
1315
1316
1317 if (LogFile->Header.OldestRecordNumber == 0)
1318 LogFile->Header.OldestRecordNumber = 1;
1319
1320
1322
1323
1324
1325
1326
1327 if (LogFile->Header.StartOffset <= LogFile->Header.EndOffset)
1328 UpperBound = LogFile->Header.MaxSize;
1329 else
1330 UpperBound = LogFile->Header.StartOffset;
1331
1332
1334 {
1335 EVTLTRACE(
"The event log file has reached maximum size (0x%x), wrapping...\n"
1336 "UpperBound = 0x%x, WriteOffset = 0x%x, BufSize = 0x%x\n",
1338
1339 }
1340
1341 if ( (LogFile->Header.StartOffset < LogFile->Header.EndOffset) &&
1342 (LogFile->Header.MaxSize -
WriteOffset <
sizeof(RecBuf)) )
1343 {
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1356 UpperBound = LogFile->Header.StartOffset;
1357
1358 FreeSpace = LogFile->Header.StartOffset -
WriteOffset;
1359
1361 }
1362
1363
1364
1365
1366
1367
1368
1369
1370
1372 {
1373 ULONG OrgOldestRecordNumber, OldestRecordNumber;
1374
1375
1376
1377 OldestRecordNumber = OrgOldestRecordNumber = LogFile->Header.OldestRecordNumber;
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388 while (FreeSpace <
BufSize +
sizeof(EofRec))
1389 {
1390
1392 if (RecOffset == 0)
1393 {
1394 EVTLTRACE1(
"Record number %d cannot be found, or log file is full and cannot wrap!\n", OldestRecordNumber);
1397 }
1398
1400
1402 Status = LogFile->FileRead(LogFile,
1404 &RecBuf,
1405 sizeof(RecBuf),
1408 {
1410
1412 }
1413
1415 {
1416 EVTLTRACE1(
"The event log file is corrupted!\n");
1418 }
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432 if (LogFile->Header.Retention != 0 &&
1436 {
1437 EVTLTRACE1(
"The event log file is full and cannot wrap because of the retention policy.\n");
1440 }
1441
1442
1443
1444
1445
1446
1447
1448 OldestRecordNumber++;
1449 RecOffset += RecBuf.
Length;
1450 FreeSpace += RecBuf.
Length;
1451
1452
1453
1454
1455
1456
1457 if (LogFile->Header.MaxSize - RecOffset <
sizeof(
EVENTLOGRECORD))
1458 {
1459
1460 FreeSpace += LogFile->Header.MaxSize - RecOffset;
1461 }
1462 }
1463
1464 EVTLTRACE(
"Record will fit. FreeSpace %d, BufSize %d\n", FreeSpace,
BufSize);
1465
1466
1468
1469
1470
1471
1472
1473
1474
1475
1477 LogFile->Header.OldestRecordNumber = OldestRecordNumber;
1479 if (LogFile->Header.StartOffset == 0)
1480 {
1481
1482
1483
1484
1488 }
1489
1490 EVTLTRACE(
"MaxSize = 0x%x, StartOffset = 0x%x, WriteOffset = 0x%x, EndOffset = 0x%x, BufSize = 0x%x\n"
1491 "OldestRecordNumber = %d\n",
1492 LogFile->Header.MaxSize, LogFile->Header.StartOffset,
WriteOffset, LogFile->Header.EndOffset,
BufSize,
1493 OldestRecordNumber);
1494 }
1495
1496
1497
1498
1499
1500
1501
1502 if (LogFile->CurrentSize < LogFile->Header.MaxSize)
1503 {
1505
1506 if (WriteOffset < LogFile->
Header.EndOffset ||
NewSize > LogFile->Header.MaxSize)
1507 NewSize = LogFile->Header.MaxSize;
1508 else
1510
1511 if (
NewSize > LogFile->CurrentSize)
1512 {
1513 EVTLTRACE1(
"Expanding the log file from %lu to %lu\n",
1514 LogFile->CurrentSize,
NewSize);
1515 Status = LogFile->FileSetSize(LogFile,
NewSize, LogFile->CurrentSize);
1517 {
1520 }
1521 LogFile->CurrentSize =
NewSize;
1522 }
1523 }
1524
1525
1526 LogFile->Header.Flags &= ~ELF_LOGFILE_LOGFULL_WRITTEN;
1527
1528
1529
1530 if (WriteOffset < LogFile->
Header.EndOffset)
1531 {
1532
1533 WrittenLength =
ROUND_DOWN(LogFile->Header.MaxSize - LogFile->Header.EndOffset,
sizeof(
ULONG));
1535
1537 Status = LogFile->FileWrite(LogFile,
1539 &RecBuf,
1540 WrittenLength,
1541 &WrittenLength);
1543 {
1545
1546 }
1547 }
1548
1549
1554 &WrittenLength,
1556 &NextOffset);
1558 {
1561 }
1562
1564
1568 {
1570 }
1571
1572 LogFile->Header.CurrentRecordNumber++;
1573 if (LogFile->Header.CurrentRecordNumber == 0)
1574 LogFile->Header.CurrentRecordNumber = 1;
1575
1576
1577
1578
1579
1580
1581 LogFile->Header.EndOffset =
FileOffset.QuadPart;
1582
1585 EofRec.
EndRecord = LogFile->Header.EndOffset;
1588
1589
1591 &EofRec,
1592 sizeof(EofRec),
1593 &WrittenLength,
1595 &NextOffset);
1597 {
1600 }
1602
1603
1606 {
1609 }
1610
1612}
#define ROUND_DOWN(n, align)
static BOOL ElfpAddOffsetInformation(IN PEVTLOGFILE LogFile, IN ULONG ulNumber, IN ULONG ulOffset)
#define EVENTLOG_FILE_GRANULARITY
static BOOL ElfpDeleteOffsetInformation(IN PEVTLOGFILE LogFile, IN ULONG ulNumberMin, IN ULONG ulNumberMax)
static NTSTATUS WriteLogBuffer(IN PEVTLOGFILE LogFile, IN PVOID Buffer, IN SIZE_T Length, OUT PSIZE_T WrittenLength OPTIONAL, IN PLARGE_INTEGER ByteOffset, OUT PLARGE_INTEGER NextOffset OPTIONAL)
#define ELF_LOGFILE_LOGFULL_WRITTEN
#define ELF_LOGFILE_HEADER_WRAP
_Must_inspect_result_ _In_ USHORT NewSize
#define RtlFillMemoryUlong(dst, len, val)
#define STATUS_LOG_FILE_FULL
#define STATUS_EVENTLOG_FILE_CORRUPT
#define STATUS_ACCESS_DENIED
_Must_inspect_result_ _In_ WDFUSBPIPE _In_ WDFREQUEST _In_opt_ WDFMEMORY _In_opt_ PWDFMEMORY_OFFSET WriteOffset