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; }
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; }