file.c

来自「一个类似windows」· C语言 代码 · 共 705 行 · 第 1/2 页

C
705
字号
/*
 * PROJECT:          ReactOS kernel
 * LICENSE:          GPL - See COPYING in the top level directory
 * FILE:             services/eventlog/file.c
 * PURPOSE:          Event logging service
 * COPYRIGHT:        Copyright 2005 Saveliy Tretiakov           
 */
 
#include "eventlog.h"

PLOGFILE _LogListHead = NULL;
extern HANDLE MyHeap;

BOOL LogfInitializeNew(PLOGFILE LogFile)
{
    DWORD dwWritten;
	EOF_RECORD EofRec;
    
    ZeroMemory(&LogFile->Header, sizeof(FILE_HEADER));
	SetFilePointer(LogFile->hFile, 0, NULL, FILE_BEGIN);
	SetEndOfFile(LogFile->hFile);
	
	LogFile->Header.SizeOfHeader = sizeof(FILE_HEADER);
	LogFile->Header.SizeOfHeader2 = sizeof(FILE_HEADER);
	LogFile->Header.FirstRecordOffset = sizeof(FILE_HEADER);
	LogFile->Header.EofOffset = sizeof(FILE_HEADER);
	LogFile->Header.MajorVersion = MAJORVER;
	LogFile->Header.MinorVersion = MINORVER;
	LogFile->Header.NextRecord = 1;

	LogFile->Header.Signature = LOGFILE_SIGNATURE;
	WriteFile(LogFile->hFile,
			  &LogFile->Header,
			  sizeof(FILE_HEADER),
			  &dwWritten,
			  NULL);

	EofRec.Ones = 0x11111111;
	EofRec.Twos = 0x22222222;
	EofRec.Threes = 0x33333333;
	EofRec.Fours = 0x44444444;
	EofRec.Size1 = sizeof(EOF_RECORD);
	EofRec.Size2 = sizeof(EOF_RECORD);
	EofRec.NextRecordNumber = LogFile->Header.NextRecord;
	EofRec.OldestRecordNumber = LogFile->Header.OldestRecord;
	EofRec.StartOffset = LogFile->Header.FirstRecordOffset;
	EofRec.EndOffset = LogFile->Header.EofOffset;

	WriteFile(LogFile->hFile, &EofRec, sizeof(EOF_RECORD), &dwWritten, NULL);

	FlushFileBuffers(LogFile->hFile);
      
    return TRUE;
}

BOOL LogfInitializeExisting(PLOGFILE LogFile)
{
	DWORD dwRead;
	DWORD dwRecordsNumber = 0;
	DWORD dwRecSize, dwRecSign, dwFilePointer;
	PDWORD pdwRecSize2;
	PEVENTLOGRECORD RecBuf;

	SetFilePointer(LogFile->hFile, 0, NULL, FILE_BEGIN);
	ReadFile(LogFile->hFile, 
             &LogFile->Header, 
             sizeof(FILE_HEADER), 
             &dwRead, NULL);
             
	if(dwRead != sizeof(FILE_HEADER))
	{
		DPRINT("EventLog: Invalid file %S.\n", LogFile->FileName);
		return LogfInitializeNew(LogFile);
    }
    
	if(LogFile->Header.SizeOfHeader != sizeof(FILE_HEADER) ||
		LogFile->Header.SizeOfHeader2 != sizeof(FILE_HEADER))
	{
		DPRINT("EventLog: Invalid header size in %S.\n", LogFile->FileName);
		return LogfInitializeNew(LogFile);
    }
    
    if(LogFile->Header.Signature != LOGFILE_SIGNATURE)
    {
        DPRINT("EventLog: Invalid signature %x in %S.\n", 
               LogFile->Header.Signature,
               LogFile->FileName);
        return LogfInitializeNew(LogFile);
    }

	if(LogFile->Header.EofOffset > GetFileSize(LogFile->hFile, NULL)+1)
	{
        DPRINT("EventLog: Invalid eof offset %x in %S.\n", 
               LogFile->Header.EofOffset,
               LogFile->FileName);
        return LogfInitializeNew(LogFile);
	}

	for(;;)
	{
		dwFilePointer = SetFilePointer(LogFile->hFile, 
									   0, 
									   NULL, 
									   FILE_CURRENT);

		ReadFile(LogFile->hFile, 
				 &dwRecSize, 
				 sizeof(dwRecSize), 
				 &dwRead, 
				 NULL);

		if(dwRead != sizeof(dwRecSize))
			break;

		ReadFile(LogFile->hFile,
				 &dwRecSign,
				 sizeof(dwRecSign),
				 &dwRead,
				 NULL);
		
		if(dwRead != sizeof(dwRecSize))
			break;
		
		if(dwRecSign != LOGFILE_SIGNATURE ||
		   dwRecSize + dwFilePointer > GetFileSize(LogFile->hFile, NULL)+1 ||
		   dwRecSize < sizeof(EVENTLOGRECORD))
		{
			break;
		}
		
		SetFilePointer(LogFile->hFile, -((LONG)sizeof(DWORD)*2), NULL, FILE_CURRENT);
		RecBuf = (PEVENTLOGRECORD) HeapAlloc(MyHeap, 0, dwRecSize);
		ReadFile(LogFile->hFile,
				 RecBuf,
				 dwRecSize,
				 &dwRead,
				 NULL);		
		
		if(dwRead !=  dwRecSize)
		{
			HeapFree(MyHeap, 0, RecBuf);
			break;
		}

		pdwRecSize2 = (PDWORD)(((PBYTE)RecBuf)+dwRecSize-4);
		if(*pdwRecSize2 != dwRecSize)
		{
			DPRINT("EventLog: Invalid size2 of record %d (%x) in %s\n", 
				dwRecordsNumber,
				*pdwRecSize2,
				LogFile->LogName);
			HeapFree(MyHeap, 0, RecBuf);
			break;
		}

		dwRecordsNumber++;
		
		if(!LogfAddOffsetInformation(LogFile, RecBuf->RecordNumber, dwFilePointer))
		{
			HeapFree(MyHeap, 0, RecBuf);
			return FALSE;
		}

		HeapFree(MyHeap, 0, RecBuf);
	}//for(;;)

	LogFile->Header.NextRecord = dwRecordsNumber+1;
	LogFile->Header.OldestRecord = dwRecordsNumber ? 1 : 0; //FIXME

	SetFilePointer(LogFile->hFile, 0, 0, FILE_CURRENT);
	WriteFile(LogFile->hFile,
			  &LogFile->Header,
			  sizeof(FILE_HEADER),
			  &dwRead, 
			  NULL);
	FlushFileBuffers(LogFile->hFile);
	
	return TRUE;
}

PLOGFILE LogfCreate(WCHAR *LogName, 
                    WCHAR *FileName)
{
    PLOGFILE LogFile;
	BOOL bResult, bCreateNew = FALSE;
    
    LogFile = HeapAlloc(MyHeap, 
                        HEAP_ZERO_MEMORY, 
                        sizeof(LOGFILE));
    if(!LogFile)
    {
        DbgPrint("EventLog: Can't allocate heap\n");
        return NULL;
    }
    
    LogFile->hFile = CreateFile(FileName, 
                                GENERIC_READ | GENERIC_WRITE, 
                                FILE_SHARE_READ, 
                                NULL, 
                                OPEN_ALWAYS,
                                FILE_ATTRIBUTE_NORMAL | 
                                FILE_FLAG_RANDOM_ACCESS,
                                NULL);
	
    if(LogFile->hFile == INVALID_HANDLE_VALUE)
    {
		DPRINT("Can't create file %S.\n", FileName);
        HeapFree(MyHeap, 0, LogFile); 
		return NULL;
	}
	
	bCreateNew = GetLastError() == ERROR_ALREADY_EXISTS ? FALSE : TRUE;
	
	LogFile->LogName = HeapAlloc(MyHeap,
	                             HEAP_ZERO_MEMORY,
	                             (lstrlenW(LogName)+1)*sizeof(WCHAR));
    if(LogFile->LogName)
		lstrcpyW(LogFile->LogName, LogName);
	else 
	{
		DPRINT("EventLog: Can't allocate heap\n");
		HeapFree(MyHeap, 0, LogFile);
		return NULL;
	}
    
	LogFile->FileName = HeapAlloc(MyHeap,
	                             HEAP_ZERO_MEMORY,
	                             (lstrlenW(FileName)+1)*sizeof(WCHAR));
    if(LogFile->FileName)
		lstrcpyW(LogFile->FileName, FileName);
	else
	{
		DPRINT("EventLog: Can't allocate heap\n");
		HeapFree(MyHeap, 0, LogFile->LogName);
		HeapFree(MyHeap, 0, LogFile);
		return NULL;
	}


	LogFile->OffsetInfo = (PEVENT_OFFSET_INFO) 
		HeapAlloc(MyHeap, 
				  HEAP_ZERO_MEMORY,
				  sizeof(EVENT_OFFSET_INFO)*64);

	if(!LogFile->OffsetInfo)
	{
		DPRINT("EventLog: Can't allocate heap\n");
		HeapFree(MyHeap, 0, LogFile->FileName);
		HeapFree(MyHeap, 0, LogFile->LogName);
		HeapFree(MyHeap, 0, LogFile);
		return NULL;
	}

	LogFile->OffsetInfoSize = 64;

	if(bCreateNew)
		bResult = LogfInitializeNew(LogFile);
	else bResult = LogfInitializeExisting(LogFile);

	if(!bResult)
	{
		HeapFree(MyHeap, 0, LogFile->OffsetInfo);
		HeapFree(MyHeap, 0, LogFile->FileName);
		HeapFree(MyHeap, 0, LogFile->LogName);
		HeapFree(MyHeap, 0, LogFile);
		return NULL;
	}
    
    InitializeCriticalSection(&LogFile->cs);
    LogfListAddItem(LogFile);
    return LogFile;
}

VOID LogfClose(PLOGFILE LogFile)
{
	if(LogFile == NULL)
		return;

    EnterCriticalSection(&LogFile->cs);
    
    FlushFileBuffers(LogFile->hFile);
    CloseHandle(LogFile->hFile);
    
    LogfListRemoveItem(LogFile);
    DeleteCriticalSection(&LogFile->cs);
    
    HeapFree(MyHeap, 0, LogFile->LogName);
    HeapFree(MyHeap, 0, LogFile->FileName);
	HeapFree(MyHeap, 0, LogFile->OffsetInfo);
    HeapFree(MyHeap, 0, LogFile);
    
    return;
}

PLOGFILE LogfListHead()
{
    return _LogListHead;
}

PLOGFILE LogfListItemByName(WCHAR *Name)
{
    PLOGFILE Item;
    Item = LogfListHead();
    while(Item)
    {
        if(Item->LogName && lstrcmpW(Item->LogName, Name)==0)
            return Item;
        Item = (PLOGFILE)Item->Next;
    }
    return NULL;
}

/* index starting from 1 */
INT LogfListItemIndexByName(WCHAR *Name)
{
    PLOGFILE Item;
	INT i = 1;

    Item = LogfListHead();
    
	while(Item)
    {
        if(Item->LogName && lstrcmpW(Item->LogName, Name)==0)
            return i;
        Item = (PLOGFILE)Item->Next;
		i++;
    }
    
	return 0;
}

/* index starting from 1 */
PLOGFILE LogfListItemByIndex(INT Index)
{
    INT i = 1;
    PLOGFILE Item;
    Item = LogfListHead();
    while(Item)
    {
        if(i == Index) 
            return Item;
        i++;
        Item = (PLOGFILE)Item->Next;
    }
    return NULL;
}

INT LogfListItemCount()
{
    PLOGFILE Item = NULL;
    INT i = 1;
    Item = LogfListHead();
    if(Item)

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?