BOOL BrLockNetworkShared( IN PNETWORK Network, IN PCHAR FileName, IN ULONG LineNumber ) { PCHAR File; File = strrchr(FileName, '\\'); if (File == NULL) { File = FileName; } dprintf(LOCKS, ("Acquring lock %s:%d on network %ws\n", File, LineNumber, (Network)->NetworkName.Buffer)); if (!RtlAcquireResourceShared(&(Network)->Lock, TRUE)) { dprintf(LOCKS, ("Failed to acquire lock %s:%d on network %ws\n", File, LineNumber, (Network)->NetworkName.Buffer)); return FALSE; } else { // Use InterlockedIncrement since we only have a shared lock on the // resource. InterlockedIncrement( &Network->LockCount ); dprintf(LOCKS, ("Lock %s:%d on network %ws acquired\n", File, LineNumber, (Network)->NetworkName.Buffer)); } return TRUE; }
/* Function 5 */ NTSTATUS ElfrOldestRecord( IELF_HANDLE LogHandle, PULONG OldestRecordNumber) { PLOGHANDLE pLogHandle; PLOGFILE pLogFile; pLogHandle = ElfGetLogHandleEntryByHandle(LogHandle); if (!pLogHandle) return STATUS_INVALID_HANDLE; if (!OldestRecordNumber) return STATUS_INVALID_PARAMETER; pLogFile = pLogHandle->LogFile; /* Lock the log file shared */ RtlAcquireResourceShared(&pLogFile->Lock, TRUE); *OldestRecordNumber = ElfGetOldestRecord(&pLogFile->LogFile); /* Unlock the log file */ RtlReleaseResource(&pLogFile->Lock); return STATUS_SUCCESS; }
DWORD CALLBACK DSOUND_mixthread(void *p) { DirectSoundDevice *dev = p; TRACE("(%p)\n", dev); while (dev->ref) { DWORD ret; /* * Some audio drivers are retarded and won't fire after being * stopped, add a timeout to handle this. */ ret = WaitForSingleObject(dev->sleepev, dev->sleeptime); if (ret == WAIT_FAILED) WARN("wait returned error %u %08x!\n", GetLastError(), GetLastError()); else if (ret != WAIT_OBJECT_0) WARN("wait returned %08x!\n", ret); if (!dev->ref) break; RtlAcquireResourceShared(&(dev->buffer_list_lock), TRUE); DSOUND_PerformMix(dev); RtlReleaseResource(&(dev->buffer_list_lock)); } return 0; }
void CALLBACK DSOUND_timer(UINT timerID, UINT msg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2) { DirectSoundDevice * device = (DirectSoundDevice*)dwUser; DWORD start_time = GetTickCount(); DWORD end_time; TRACE("(%d,%d,0x%lx,0x%lx,0x%lx)\n",timerID,msg,dwUser,dw1,dw2); TRACE("entering at %d\n", start_time); if (DSOUND_renderer[device->drvdesc.dnDevNode] != device) { ERR("dsound died without killing us?\n"); timeKillEvent(timerID); timeEndPeriod(DS_TIME_RES); return; } RtlAcquireResourceShared(&(device->buffer_list_lock), TRUE); if (device->ref) DSOUND_PerformMix(device); RtlReleaseResource(&(device->buffer_list_lock)); end_time = GetTickCount(); TRACE("completed processing at %d, duration = %d\n", end_time, end_time - start_time); }
static int wine_pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock) { if (!((wine_rwlock)rwlock)->lock) rwlock_real_init( rwlock ); if (!RtlAcquireResourceShared(((wine_rwlock)rwlock)->lock, FALSE)) return EBUSY; return 0; }
static int wine_pthread_rwlock_rdlock(pthread_rwlock_t *rwlock) { if (!((wine_rwlock)rwlock)->lock) rwlock_real_init( rwlock ); while(TRUE) if (RtlAcquireResourceShared(((wine_rwlock)rwlock)->lock, TRUE)) return 0; }
static DWORD DSOUND_MixToPrimary(const DirectSoundDevice *device, DWORD writepos, DWORD mixlen, BOOL mustlock, BOOL recover, BOOL *all_stopped) { INT i, len; DWORD minlen = 0; IDirectSoundBufferImpl *dsb; BOOL gotall = TRUE; /* unless we find a running buffer, all have stopped */ *all_stopped = TRUE; TRACE("(%d,%d,%d)\n", writepos, mixlen, recover); for (i = 0; i < device->nrofbuffers; i++) { dsb = device->buffers[i]; TRACE("MixToPrimary for %p, state=%d\n", dsb, dsb->state); if (dsb->buflen && dsb->state && !dsb->hwbuf) { TRACE("Checking %p, mixlen=%d\n", dsb, mixlen); if (!RtlAcquireResourceShared(&dsb->lock, mustlock)) { gotall = FALSE; continue; } /* if buffer is stopping it is stopped now */ if (dsb->state == STATE_STOPPING) { dsb->state = STATE_STOPPED; DSOUND_CheckEvent(dsb, 0, 0); } else if (dsb->state != STATE_STOPPED) { /* if recovering, reset the mix position */ if ((dsb->state == STATE_STARTING) || recover) { dsb->primary_mixpos = writepos; } /* if the buffer was starting, it must be playing now */ if (dsb->state == STATE_STARTING) dsb->state = STATE_PLAYING; /* mix next buffer into the main buffer */ len = DSOUND_MixOne(dsb, writepos, mixlen); if (!minlen) minlen = len; /* record the minimum length mixed from all buffers */ /* we only want to return the length which *all* buffers have mixed */ else if (len) minlen = (len < minlen) ? len : minlen; *all_stopped = FALSE; } RtlReleaseResource(&dsb->lock); } } TRACE("Mixed at least %d from all buffers\n", minlen); if (!gotall) return 0; return minlen; }
NTSTATUS LogfBackupFile(PLOGFILE LogFile, PUNICODE_STRING BackupFileName) { NTSTATUS Status; LOGFILE BackupLogFile; OBJECT_ATTRIBUTES ObjectAttributes; IO_STATUS_BLOCK IoStatusBlock; DPRINT1("LogfBackupFile(%p, %wZ)\n", LogFile, BackupFileName); /* Lock the log file shared */ RtlAcquireResourceShared(&LogFile->Lock, TRUE); InitializeObjectAttributes(&ObjectAttributes, BackupFileName, OBJ_CASE_INSENSITIVE, NULL, NULL); Status = NtCreateFile(&BackupLogFile.FileHandle, GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, &ObjectAttributes, &IoStatusBlock, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ, FILE_CREATE, FILE_WRITE_THROUGH | FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0); if (!NT_SUCCESS(Status)) { DPRINT("Cannot create backup file `%wZ' (Status 0x%08lx)\n", BackupFileName, Status); goto Quit; } Status = ElfBackupFile(&LogFile->LogFile, &BackupLogFile.LogFile); Quit: /* Close the backup file */ if (BackupLogFile.FileHandle != NULL) NtClose(BackupLogFile.FileHandle); /* Unlock the log file */ RtlReleaseResource(&LogFile->Lock); return Status; }
/* Function 22 */ NTSTATUS ElfrGetLogInformation( IELF_HANDLE LogHandle, ULONG InfoLevel, PBYTE Buffer, ULONG cbBufSize, PULONG pcbBytesNeeded) { NTSTATUS Status = STATUS_SUCCESS; PLOGHANDLE pLogHandle; PLOGFILE pLogFile; pLogHandle = ElfGetLogHandleEntryByHandle(LogHandle); if (!pLogHandle) return STATUS_INVALID_HANDLE; pLogFile = pLogHandle->LogFile; /* Lock the log file shared */ RtlAcquireResourceShared(&pLogFile->Lock, TRUE); switch (InfoLevel) { case EVENTLOG_FULL_INFO: { LPEVENTLOG_FULL_INFORMATION efi = (LPEVENTLOG_FULL_INFORMATION)Buffer; *pcbBytesNeeded = sizeof(EVENTLOG_FULL_INFORMATION); if (cbBufSize < sizeof(EVENTLOG_FULL_INFORMATION)) { Status = STATUS_BUFFER_TOO_SMALL; break; } efi->dwFull = !!(ElfGetFlags(&pLogFile->LogFile) & ELF_LOGFILE_LOGFULL_WRITTEN); break; } default: Status = STATUS_INVALID_LEVEL; break; } /* Unlock the log file */ RtlReleaseResource(&pLogFile->Lock); return Status; }
/* Function 4 */ NTSTATUS ElfrNumberOfRecords( IELF_HANDLE LogHandle, PULONG NumberOfRecords) { PLOGHANDLE pLogHandle; PLOGFILE pLogFile; ULONG OldestRecordNumber, CurrentRecordNumber; DPRINT("ElfrNumberOfRecords()\n"); pLogHandle = ElfGetLogHandleEntryByHandle(LogHandle); if (!pLogHandle) return STATUS_INVALID_HANDLE; if (!NumberOfRecords) return STATUS_INVALID_PARAMETER; pLogFile = pLogHandle->LogFile; /* Lock the log file shared */ RtlAcquireResourceShared(&pLogFile->Lock, TRUE); OldestRecordNumber = ElfGetOldestRecord(&pLogFile->LogFile); CurrentRecordNumber = ElfGetCurrentRecord(&pLogFile->LogFile); /* Unlock the log file */ RtlReleaseResource(&pLogFile->Lock); DPRINT("Oldest: %lu Current: %lu\n", OldestRecordNumber, CurrentRecordNumber); if (OldestRecordNumber == 0) { /* OldestRecordNumber == 0 when the log is empty */ *NumberOfRecords = 0; } else { /* The log contains events */ *NumberOfRecords = CurrentRecordNumber - OldestRecordNumber; } return STATUS_SUCCESS; }
void CALLBACK DSOUND_timer(UINT timerID, UINT msg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2) { DirectSoundDevice * device = (DirectSoundDevice*)dwUser; DWORD start_time = GetTickCount(); DWORD end_time; TRACE("(%d,%d,0x%lx,0x%lx,0x%lx)\n",timerID,msg,dwUser,dw1,dw2); TRACE("entering at %d\n", start_time); RtlAcquireResourceShared(&(device->buffer_list_lock), TRUE); if (device->ref) DSOUND_PerformMix(device); RtlReleaseResource(&(device->buffer_list_lock)); end_time = GetTickCount(); TRACE("completed processing at %d, duration = %d\n", end_time, end_time - start_time); }
static void DSOUND_MixToPrimary(const DirectSoundDevice *device, DWORD writepos, DWORD mixlen, BOOL recover, BOOL *all_stopped) { INT i; IDirectSoundBufferImpl *dsb; /* unless we find a running buffer, all have stopped */ *all_stopped = TRUE; TRACE("(%d,%d,%d)\n", writepos, mixlen, recover); for (i = 0; i < device->nrofbuffers; i++) { dsb = device->buffers[i]; TRACE("MixToPrimary for %p, state=%d\n", dsb, dsb->state); if (dsb->buflen && dsb->state) { TRACE("Checking %p, mixlen=%d\n", dsb, mixlen); RtlAcquireResourceShared(&dsb->lock, TRUE); /* if buffer is stopping it is stopped now */ if (dsb->state == STATE_STOPPING) { dsb->state = STATE_STOPPED; DSOUND_CheckEvent(dsb, 0, 0); } else if (dsb->state != STATE_STOPPED) { /* if the buffer was starting, it must be playing now */ if (dsb->state == STATE_STARTING) dsb->state = STATE_PLAYING; /* mix next buffer into the main buffer */ DSOUND_MixOne(dsb, writepos, mixlen); *all_stopped = FALSE; } RtlReleaseResource(&dsb->lock); } } }
DWORD LogfReadEvent(PLOGFILE LogFile, DWORD Flags, DWORD * RecordNumber, DWORD BufSize, PBYTE Buffer, DWORD * BytesRead, DWORD * BytesNeeded, BOOL Ansi) { DWORD dwOffset, dwRead, dwRecSize; DWORD dwBufferUsage = 0, dwRecNum; if (Flags & EVENTLOG_FORWARDS_READ && Flags & EVENTLOG_BACKWARDS_READ) return ERROR_INVALID_PARAMETER; if (!(Flags & EVENTLOG_FORWARDS_READ) && !(Flags & EVENTLOG_BACKWARDS_READ)) return ERROR_INVALID_PARAMETER; if (!Buffer || !BytesRead || !BytesNeeded) return ERROR_INVALID_PARAMETER; if ((*RecordNumber==0) && !(EVENTLOG_SEQUENTIAL_READ)) { return ERROR_INVALID_PARAMETER; } dwRecNum = *RecordNumber; RtlAcquireResourceShared(&LogFile->Lock, TRUE); *BytesRead = 0; *BytesNeeded = 0; dwOffset = LogfOffsetByNumber(LogFile, dwRecNum); if (!dwOffset) { RtlReleaseResource(&LogFile->Lock); return ERROR_HANDLE_EOF; } if (SetFilePointer(LogFile->hFile, dwOffset, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER) { DPRINT1("SetFilePointer() failed!\n"); goto Done; } if (!ReadFile(LogFile->hFile, &dwRecSize, sizeof(DWORD), &dwRead, NULL)) { DPRINT1("ReadFile() failed!\n"); goto Done; } if (dwRecSize > BufSize) { *BytesNeeded = dwRecSize; RtlReleaseResource(&LogFile->Lock); return ERROR_INSUFFICIENT_BUFFER; } if (SetFilePointer(LogFile->hFile, -((LONG) sizeof(DWORD)), NULL, FILE_CURRENT) == INVALID_SET_FILE_POINTER) { DPRINT1("SetFilePointer() failed!\n"); goto Done; } if (Ansi == TRUE) { if (!ReadAnsiLogEntry(LogFile->hFile, Buffer, dwRecSize, &dwRead)) { DPRINT1("ReadAnsiLogEntry() failed!\n"); goto Done; } } else { if (!ReadFile(LogFile->hFile, Buffer, dwRecSize, &dwRead, NULL)) { DPRINT1("ReadFile() failed!\n"); goto Done; } } dwBufferUsage += dwRead; while (dwBufferUsage <= BufSize) { if (Flags & EVENTLOG_FORWARDS_READ) dwRecNum++; else dwRecNum--; dwOffset = LogfOffsetByNumber(LogFile, dwRecNum); if (!dwOffset) break; if (SetFilePointer(LogFile->hFile, dwOffset, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER) { DPRINT1("SetFilePointer() failed!\n"); goto Done; } if (!ReadFile(LogFile->hFile, &dwRecSize, sizeof(DWORD), &dwRead, NULL)) { DPRINT1("ReadFile() failed!\n"); goto Done; } if (dwBufferUsage + dwRecSize > BufSize) break; if (SetFilePointer(LogFile->hFile, -((LONG) sizeof(DWORD)), NULL, FILE_CURRENT) == INVALID_SET_FILE_POINTER) { DPRINT1("SetFilePointer() failed!\n"); goto Done; } if (Ansi == TRUE) { if (!ReadAnsiLogEntry(LogFile->hFile, Buffer + dwBufferUsage, dwRecSize, &dwRead)) { DPRINT1("ReadAnsiLogEntry() failed!\n"); goto Done; } } else { if (!ReadFile(LogFile->hFile, Buffer + dwBufferUsage, dwRecSize, &dwRead, NULL)) { DPRINT1("ReadFile() failed!\n"); goto Done; } } dwBufferUsage += dwRead; } *BytesRead = dwBufferUsage; * RecordNumber = dwRecNum; RtlReleaseResource(&LogFile->Lock); return ERROR_SUCCESS; Done: DPRINT1("LogfReadEvent failed with %x\n",GetLastError()); RtlReleaseResource(&LogFile->Lock); return GetLastError(); }
NTSTATUS LogfBackupFile(PLOGFILE LogFile, PUNICODE_STRING BackupFileName) { OBJECT_ATTRIBUTES ObjectAttributes; IO_STATUS_BLOCK IoStatusBlock; EVENTLOGHEADER Header; EVENTLOGEOF EofRec; HANDLE FileHandle = NULL; ULONG i; LARGE_INTEGER FileOffset; NTSTATUS Status; PUCHAR Buffer = NULL; DWORD dwOffset, dwRead, dwRecSize; DPRINT1("LogfBackupFile(%p, %wZ)\n", LogFile, BackupFileName); /* Lock the log file shared */ RtlAcquireResourceShared(&LogFile->Lock, TRUE); InitializeObjectAttributes(&ObjectAttributes, BackupFileName, OBJ_CASE_INSENSITIVE, NULL, NULL); Status = NtCreateFile(&FileHandle, GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, &ObjectAttributes, &IoStatusBlock, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ, FILE_CREATE, FILE_WRITE_THROUGH | FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0); if (!NT_SUCCESS(Status)) { DPRINT("Can't create backup file %wZ (Status: 0x%08lx)\n", BackupFileName, Status); goto Done; } /* Initialize the (dirty) log file header */ Header.HeaderSize = sizeof(EVENTLOGHEADER); Header.Signature = LOGFILE_SIGNATURE; Header.MajorVersion = MAJORVER; Header.MinorVersion = MINORVER; Header.StartOffset = sizeof(EVENTLOGHEADER); Header.EndOffset = sizeof(EVENTLOGHEADER); Header.CurrentRecordNumber = 1; Header.OldestRecordNumber = 1; Header.MaxSize = LogFile->Header.MaxSize; Header.Flags = ELF_LOGFILE_HEADER_DIRTY; Header.Retention = LogFile->Header.Retention; Header.EndHeaderSize = sizeof(EVENTLOGHEADER); /* Write the (dirty) log file header */ Status = NtWriteFile(FileHandle, NULL, NULL, NULL, &IoStatusBlock, &Header, sizeof(EVENTLOGHEADER), NULL, NULL); if (!NT_SUCCESS(Status)) { DPRINT1("Failed to write the log file header (Status: 0x%08lx)\n", Status); goto Done; } for (i = LogFile->Header.OldestRecordNumber; i < LogFile->Header.CurrentRecordNumber; i++) { dwOffset = LogfOffsetByNumber(LogFile, i); if (dwOffset == 0) break; if (SetFilePointer(LogFile->hFile, dwOffset, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER) { DPRINT1("SetFilePointer() failed!\n"); goto Done; } if (!ReadFile(LogFile->hFile, &dwRecSize, sizeof(DWORD), &dwRead, NULL)) { DPRINT1("ReadFile() failed!\n"); goto Done; } if (SetFilePointer(LogFile->hFile, dwOffset, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER) { DPRINT1("SetFilePointer() failed!\n"); goto Done; } Buffer = HeapAlloc(MyHeap, 0, dwRecSize); if (Buffer == NULL) { DPRINT1("HeapAlloc() failed!\n"); goto Done; } if (!ReadFile(LogFile->hFile, Buffer, dwRecSize, &dwRead, NULL)) { DPRINT1("ReadFile() failed!\n"); goto Done; } /* Write the event record */ Status = NtWriteFile(FileHandle, NULL, NULL, NULL, &IoStatusBlock, Buffer, dwRecSize, NULL, NULL); if (!NT_SUCCESS(Status)) { DPRINT1("NtWriteFile() failed! (Status: 0x%08lx)\n", Status); goto Done; } /* Update the header information */ Header.EndOffset += dwRecSize; /* Free the buffer */ HeapFree(MyHeap, 0, Buffer); Buffer = NULL; } /* Initialize the EOF record */ EofRec.RecordSizeBeginning = sizeof(EVENTLOGEOF); EofRec.Ones = 0x11111111; EofRec.Twos = 0x22222222; EofRec.Threes = 0x33333333; EofRec.Fours = 0x44444444; EofRec.BeginRecord = sizeof(EVENTLOGHEADER); EofRec.EndRecord = Header.EndOffset; EofRec.CurrentRecordNumber = LogFile->Header.CurrentRecordNumber; EofRec.OldestRecordNumber = LogFile->Header.OldestRecordNumber; EofRec.RecordSizeEnd = sizeof(EVENTLOGEOF); /* Write the EOF record */ Status = NtWriteFile(FileHandle, NULL, NULL, NULL, &IoStatusBlock, &EofRec, sizeof(EVENTLOGEOF), NULL, NULL); if (!NT_SUCCESS(Status)) { DPRINT1("NtWriteFile() failed!\n"); goto Done; } /* Update the header information */ Header.CurrentRecordNumber = LogFile->Header.CurrentRecordNumber; Header.OldestRecordNumber = LogFile->Header.OldestRecordNumber; Header.MaxSize = Header.EndOffset + sizeof(EVENTLOGEOF); Header.Flags = 0; /* Write the (clean) log file header */ FileOffset.QuadPart = 0; Status = NtWriteFile(FileHandle, NULL, NULL, NULL, &IoStatusBlock, &Header, sizeof(EVENTLOGHEADER), &FileOffset, NULL); if (!NT_SUCCESS(Status)) { DPRINT1("NtWriteFile() failed! (Status: 0x%08lx)\n", Status); } Done: /* Free the buffer */ if (Buffer != NULL) HeapFree(MyHeap, 0, Buffer); /* Close the backup file */ if (FileHandle != NULL) NtClose(FileHandle); /* Unlock the log file */ RtlReleaseResource(&LogFile->Lock); return Status; }
NET_API_STATUS NET_API_FUNCTION NetrWkstaGetInfo( IN LPTSTR ServerName OPTIONAL, IN DWORD Level, OUT LPWKSTA_INFO WkstaInfo ) /*++ Routine Description: This function is the NetWkstaGetInfo entry point in the Workstation service. It checks the security access of the caller before returning one the information requested which is either system-wide, or redirector specific. Arguments: ServerName - Supplies the name of server to execute this function Level - Supplies the requested level of information. WkstaInfo - Returns a pointer to a buffer which contains the requested workstation information. Return Value: NET_API_STATUS - NERR_Success or reason for failure. --*/ { NET_API_STATUS status = NERR_Success; LPBYTE Buffer; ACCESS_MASK DesiredAccess; UNREFERENCED_PARAMETER(ServerName); // // Determine the desired access based on the specified info level. // switch (Level) { // // Guest access // case 100: DesiredAccess = WKSTA_CONFIG_GUEST_INFO_GET; break; // // User access // case 101: DesiredAccess = WKSTA_CONFIG_USER_INFO_GET; break; // // Admin or operator access // case 102: case 502: DesiredAccess = WKSTA_CONFIG_ADMIN_INFO_GET; break; default: return ERROR_INVALID_LEVEL; } // // Perform access validation on the caller. // if (NetpAccessCheckAndAudit( WORKSTATION_DISPLAY_NAME, // Subsystem name (LPTSTR) CONFIG_INFO_OBJECT, // Object type name ConfigurationInfoSd, // Security descriptor DesiredAccess, // Desired access &WsConfigInfoMapping // Generic mapping ) != NERR_Success) { return ERROR_ACCESS_DENIED; } // // Only allowed to proceed with get info if no one else is setting // if (! RtlAcquireResourceShared(&WsInfo.ConfigResource, TRUE)) { return NERR_InternalError; } switch (Level) { // // System-wide information // case 100: case 101: case 102: status = WsGetSystemInfo(Level, &Buffer); if (status == NERR_Success) { SET_SYSTEM_INFO_POINTER(WkstaInfo, Buffer); } break; // // Platform specific information // case 502: status = WsGetPlatformInfo( Level, (LPBYTE *) &(WkstaInfo->WkstaInfo502) ); break; // // This should have been caught earlier. // default: NetpAssert(FALSE); status = ERROR_INVALID_LEVEL; } RtlReleaseResource(&WsInfo.ConfigResource); return status; }
/* * NOTE: * 'RecordNumber' is a pointer to the record number at which the read operation * should start. If the record number is 0 and the flags given in the 'Flags' * parameter contain EVENTLOG_SEQUENTIAL_READ, an adequate record number is * computed. */ NTSTATUS LogfReadEvents(PLOGFILE LogFile, ULONG Flags, PULONG RecordNumber, ULONG BufSize, PBYTE Buffer, PULONG BytesRead, PULONG BytesNeeded, BOOLEAN Ansi) { NTSTATUS Status; ULONG RecNum; SIZE_T ReadLength, NeededSize; ULONG BufferUsage; /* Parameters validation */ /* EVENTLOG_SEQUENTIAL_READ and EVENTLOG_SEEK_READ are mutually exclusive */ if ((Flags & EVENTLOG_SEQUENTIAL_READ) && (Flags & EVENTLOG_SEEK_READ)) return STATUS_INVALID_PARAMETER; if (!(Flags & EVENTLOG_SEQUENTIAL_READ) && !(Flags & EVENTLOG_SEEK_READ)) return STATUS_INVALID_PARAMETER; /* EVENTLOG_FORWARDS_READ and EVENTLOG_BACKWARDS_READ are mutually exclusive */ if ((Flags & EVENTLOG_FORWARDS_READ) && (Flags & EVENTLOG_BACKWARDS_READ)) return STATUS_INVALID_PARAMETER; if (!(Flags & EVENTLOG_FORWARDS_READ) && !(Flags & EVENTLOG_BACKWARDS_READ)) return STATUS_INVALID_PARAMETER; if (!Buffer || !BytesRead || !BytesNeeded) return STATUS_INVALID_PARAMETER; /* In seek read mode, a record number of 0 is invalid */ if (!(Flags & EVENTLOG_SEQUENTIAL_READ) && (*RecordNumber == 0)) return STATUS_INVALID_PARAMETER; /* Lock the log file shared */ RtlAcquireResourceShared(&LogFile->Lock, TRUE); /* * In sequential read mode, a record number of 0 means we need * to determine where to start the read operation. Otherwise * we just use the provided record number. */ if ((Flags & EVENTLOG_SEQUENTIAL_READ) && (*RecordNumber == 0)) { if (Flags & EVENTLOG_FORWARDS_READ) { *RecordNumber = ElfGetOldestRecord(&LogFile->LogFile); } else // if (Flags & EVENTLOG_BACKWARDS_READ) { *RecordNumber = ElfGetCurrentRecord(&LogFile->LogFile) - 1; } } RecNum = *RecordNumber; *BytesRead = 0; *BytesNeeded = 0; BufferUsage = 0; do { Status = ReadRecord(&LogFile->LogFile, RecNum, (PEVENTLOGRECORD)(Buffer + BufferUsage), BufSize - BufferUsage, &ReadLength, &NeededSize, Ansi); if (Status == STATUS_NOT_FOUND) { if (BufferUsage == 0) { Status = STATUS_END_OF_FILE; goto Quit; } else { break; } } else if (Status == STATUS_BUFFER_TOO_SMALL) { if (BufferUsage == 0) { *BytesNeeded = NeededSize; // Status = STATUS_BUFFER_TOO_SMALL; goto Quit; } else { break; } } else if (!NT_SUCCESS(Status)) { DPRINT1("ElfReadRecord failed (Status 0x%08lx)\n", Status); goto Quit; } /* Go to the next event record */ /* * NOTE: This implicitly supposes that all the other record numbers * are consecutive (and do not jump than more than one unit); but if * it is not the case, then we would prefer here to call some * "get_next_record_number" function. */ if (Flags & EVENTLOG_FORWARDS_READ) RecNum++; else // if (Flags & EVENTLOG_BACKWARDS_READ) RecNum--; BufferUsage += ReadLength; } while (BufferUsage <= BufSize); *BytesRead = BufferUsage; *RecordNumber = RecNum; Status = STATUS_SUCCESS; Quit: /* Unlock the log file */ RtlReleaseResource(&LogFile->Lock); if (!NT_SUCCESS(Status)) DPRINT1("LogfReadEvents failed (Status 0x%08lx)\n", Status); return Status; }