Beispiel #1
0
NTSTATUS
LogfCreate(PLOGFILE *LogFile,
           WCHAR *LogName,
           PUNICODE_STRING FileName,
           ULONG ulMaxSize,
           ULONG ulRetention,
           BOOL Permanent,
           BOOL Backup)
{
    OBJECT_ATTRIBUTES ObjectAttributes;
    IO_STATUS_BLOCK IoStatusBlock;
    PLOGFILE pLogFile;
    BOOL bCreateNew = FALSE;
    NTSTATUS Status = STATUS_SUCCESS;

    pLogFile = (LOGFILE *) HeapAlloc(MyHeap, HEAP_ZERO_MEMORY, sizeof(LOGFILE));
    if (!pLogFile)
    {
        DPRINT1("Can't allocate heap!\n");
        return STATUS_NO_MEMORY;
    }

    InitializeObjectAttributes(&ObjectAttributes,
                               FileName,
                               OBJ_CASE_INSENSITIVE,
                               NULL,
                               NULL);

    Status = NtCreateFile(&pLogFile->hFile,
                          Backup ? (GENERIC_READ | SYNCHRONIZE) : (GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE),
                          &ObjectAttributes,
                          &IoStatusBlock,
                          NULL,
                          FILE_ATTRIBUTE_NORMAL,
                          FILE_SHARE_READ,
                          Backup ? FILE_OPEN : FILE_OPEN_IF,
                          FILE_SYNCHRONOUS_IO_NONALERT,
                          NULL,
                          0);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Can't create file %wZ (Status: 0x%08lx)\n", FileName, Status);
        goto fail;
    }

    bCreateNew = (IoStatusBlock.Information == FILE_CREATED) ? TRUE: FALSE;

    pLogFile->LogName =
        (WCHAR *) HeapAlloc(MyHeap,
                            HEAP_ZERO_MEMORY,
                            (lstrlenW(LogName) + 1) * sizeof(WCHAR));
    if (pLogFile->LogName == NULL)
    {
        DPRINT1("Can't allocate heap\n");
        Status = STATUS_NO_MEMORY;
        goto fail;
    }

    if (LogName)
        StringCchCopy(pLogFile->LogName,lstrlenW(LogName) + 1, LogName);

    pLogFile->FileName =
        (WCHAR *) HeapAlloc(MyHeap,
                            HEAP_ZERO_MEMORY,
                            (lstrlenW(FileName->Buffer) + 1) * sizeof(WCHAR));
    if (pLogFile->FileName == NULL)
    {
        DPRINT1("Can't allocate heap\n");
        Status = STATUS_NO_MEMORY;
        goto fail;
    }

    StringCchCopy(pLogFile->FileName, lstrlenW(FileName->Buffer) + 1, FileName->Buffer);

    pLogFile->OffsetInfo =
        (PEVENT_OFFSET_INFO) HeapAlloc(MyHeap,
                                       HEAP_ZERO_MEMORY,
                                       sizeof(EVENT_OFFSET_INFO) * 64);
    if (pLogFile->OffsetInfo == NULL)
    {
        DPRINT1("Can't allocate heap\n");
        Status = STATUS_NO_MEMORY;
        goto fail;
    }

    pLogFile->OffsetInfoSize = 64;

    pLogFile->Permanent = Permanent;

    if (bCreateNew)
        Status = LogfInitializeNew(pLogFile, ulMaxSize, ulRetention);
    else
        Status = LogfInitializeExisting(pLogFile, Backup);

    if (!NT_SUCCESS(Status))
        goto fail;

    RtlInitializeResource(&pLogFile->Lock);

    LogfListAddItem(pLogFile);

  fail:
    if (!NT_SUCCESS(Status))
    {
        if ((pLogFile->hFile != NULL) && (pLogFile->hFile != INVALID_HANDLE_VALUE))
            CloseHandle(pLogFile->hFile);

        if (pLogFile->OffsetInfo)
            HeapFree(MyHeap, 0, pLogFile->OffsetInfo);

        if (pLogFile->FileName)
            HeapFree(MyHeap, 0, pLogFile->FileName);

        if (pLogFile->LogName)
            HeapFree(MyHeap, 0, pLogFile->LogName);

        HeapFree(MyHeap, 0, pLogFile);
    }
    else
    {
        *LogFile = pLogFile;
    }

    return Status;
}
Beispiel #2
0
NTSTATUS
LogfCreate(PLOGFILE* LogFile,
           PCWSTR    LogName,
           PUNICODE_STRING FileName,
           ULONG     MaxSize,
           ULONG     Retention,
           BOOLEAN   Permanent,
           BOOLEAN   Backup)
{
    NTSTATUS Status;
    OBJECT_ATTRIBUTES ObjectAttributes;
    IO_STATUS_BLOCK IoStatusBlock;
    FILE_STANDARD_INFORMATION FileStdInfo;
    PLOGFILE pLogFile;
    SIZE_T LogNameLen;
    BOOLEAN CreateNew;

    pLogFile = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*pLogFile));
    if (!pLogFile)
    {
        DPRINT1("Cannot allocate heap!\n");
        return STATUS_NO_MEMORY;
    }

    LogNameLen = (LogName ? wcslen(LogName) : 0) + 1;
    pLogFile->LogName = RtlAllocateHeap(GetProcessHeap(),
                                        HEAP_ZERO_MEMORY,
                                        LogNameLen * sizeof(WCHAR));
    if (pLogFile->LogName == NULL)
    {
        DPRINT1("Cannot allocate heap\n");
        Status = STATUS_NO_MEMORY;
        goto Quit;
    }

    if (LogName)
        StringCchCopyW(pLogFile->LogName, LogNameLen, LogName);

    InitializeObjectAttributes(&ObjectAttributes,
                               FileName,
                               OBJ_CASE_INSENSITIVE,
                               NULL,
                               NULL);

    DPRINT1("Going to create or open %wZ\n", FileName);
    Status = NtCreateFile(&pLogFile->FileHandle,
                          Backup ? (GENERIC_READ | SYNCHRONIZE)
                                 : (GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE),
                          &ObjectAttributes,
                          &IoStatusBlock,
                          NULL,
                          FILE_ATTRIBUTE_NORMAL,
                          FILE_SHARE_READ,
                          Backup ? FILE_OPEN : FILE_OPEN_IF,
                          FILE_SYNCHRONOUS_IO_NONALERT,
                          NULL,
                          0);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Cannot create file `%wZ' (Status 0x%08lx)\n", FileName, Status);
        goto Quit;
    }

    CreateNew = (IoStatusBlock.Information == FILE_CREATED);
    DPRINT1("%wZ %s successfully\n", FileName, CreateNew ? "created" : "opened");

    /*
     * Retrieve the log file size and check whether the file is not too large;
     * this log format only supports files of theoretical size < 0xFFFFFFFF .
     *
     * As it happens that, on Windows (and ReactOS), retrieving the End-Of-File
     * information using NtQueryInformationFile with the FileEndOfFileInformation
     * class is invalid (who knows why...), use instead the FileStandardInformation
     * class, and the EndOfFile member of the returned FILE_STANDARD_INFORMATION
     * structure will give the desired information.
     */
    Status = NtQueryInformationFile(pLogFile->FileHandle,
                                    &IoStatusBlock,
                                    &FileStdInfo,
                                    sizeof(FileStdInfo),
                                    FileStandardInformation);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("EventLog: NtQueryInformationFile failed (Status 0x%08lx)\n", Status);
        goto Quit;
    }
    if (FileStdInfo.EndOfFile.HighPart != 0)
    {
        DPRINT1("EventLog: Log `%wZ' is too large.\n", FileName);
        Status = STATUS_EVENTLOG_FILE_CORRUPT; // STATUS_FILE_TOO_LARGE;
        goto Quit;
    }

    DPRINT("Initializing LogFile `%S'\n", pLogFile->LogName);

    Status = ElfCreateFile(&pLogFile->LogFile,
                           FileName,
                           FileStdInfo.EndOfFile.LowPart,
                           MaxSize,
                           Retention,
                           CreateNew,
                           Backup,
                           LogfpAlloc,
                           LogfpFree,
                           LogfpSetFileSize,
                           LogfpWriteFile,
                           LogfpReadFile,
                           LogfpFlushFile);
    if (!NT_SUCCESS(Status))
        goto Quit;

    pLogFile->Permanent = Permanent;

    RtlInitializeResource(&pLogFile->Lock);

    LogfListAddItem(pLogFile);

Quit:
    if (!NT_SUCCESS(Status))
    {
        if (pLogFile->FileHandle != NULL)
            NtClose(pLogFile->FileHandle);

        if (pLogFile->LogName)
            RtlFreeHeap(GetProcessHeap(), 0, pLogFile->LogName);

        RtlFreeHeap(GetProcessHeap(), 0, pLogFile);
    }
    else
    {
        *LogFile = pLogFile;
    }

    return Status;
}