Пример #1
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);
}
Пример #2
0
/* 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;
}
Пример #3
0
NTSTATUS
LogfClearFile(PLOGFILE LogFile,
              PUNICODE_STRING BackupFileName)
{
    NTSTATUS Status;

    RtlAcquireResourceExclusive(&LogFile->Lock, TRUE);

    if (BackupFileName->Length > 0)
    {
        /* Write a backup file */
        Status = LogfBackupFile(LogFile,
                                BackupFileName);
        if (!NT_SUCCESS(Status))
        {
            DPRINT1("LogfBackupFile failed (Status: 0x%08lx)\n", Status);
            return Status;
        }
    }

    Status = LogfInitializeNew(LogFile,
                               LogFile->Header.MaxSize,
                               LogFile->Header.Retention);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("LogfInitializeNew failed (Status: 0x%08lx)\n", Status);
    }

    RtlReleaseResource(&LogFile->Lock);

    return Status;
}
Пример #4
0
Файл: mixer.c Проект: behda/wine
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;
}
Пример #5
0
NTSTATUS
LogfClearFile(PLOGFILE LogFile,
              PUNICODE_STRING BackupFileName)
{
    NTSTATUS Status;

    /* Lock the log file exclusive */
    RtlAcquireResourceExclusive(&LogFile->Lock, TRUE);

    if (BackupFileName->Length > 0)
    {
        /* Write a backup file */
        Status = LogfBackupFile(LogFile, BackupFileName);
        if (!NT_SUCCESS(Status))
        {
            DPRINT1("LogfBackupFile failed (Status 0x%08lx)\n", Status);
            goto Quit;
        }
    }

    Status = ElfReCreateFile(&LogFile->LogFile);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("LogfInitializeNew failed (Status 0x%08lx)\n", Status);
    }

Quit:
    /* Unlock the log file */
    RtlReleaseResource(&LogFile->Lock);
    return Status;
}
Пример #6
0
VOID
BrUnlockNetwork(
    IN PNETWORK Network,
    IN PCHAR FileName,
    IN ULONG LineNumber
    )
{
    PCHAR File;
    LONG ReturnValue;

    File = strrchr(FileName, '\\');

    if (File == NULL) {
        File = FileName;
    }


    dprintf(LOCKS, ("Releasing lock %s:%d on network %ws\n", File, LineNumber, (Network)->NetworkName.Buffer));

    //
    //  Decrement the lock count.
    //

    ReturnValue = InterlockedDecrement( &Network->LockCount );

    if ( ReturnValue < 0) {
        dprintf(LOCKS, ("Over released lock %s:%d on network %ws\n", File, LineNumber, (Network)->NetworkName.Buffer));
        KdPrint(("BROWSER: Over released lock %s:%d on network %ws\n", File, LineNumber, (Network)->NetworkName.Buffer));
    }

    RtlReleaseResource(&(Network)->Lock);

    return;
}
Пример #7
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;
}
Пример #8
0
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;
}
Пример #9
0
/* 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;
}
Пример #10
0
/* 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;
}
Пример #11
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);

	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);
}
Пример #12
0
/* Function 23 */
NTSTATUS
ElfrFlushEL(
    IELF_HANDLE LogHandle)
{
    NTSTATUS Status;
    PLOGHANDLE pLogHandle;
    PLOGFILE pLogFile;

    pLogHandle = ElfGetLogHandleEntryByHandle(LogHandle);
    if (!pLogHandle)
        return STATUS_INVALID_HANDLE;

    pLogFile = pLogHandle->LogFile;

    /* Lock the log file exclusive */
    RtlAcquireResourceExclusive(&pLogFile->Lock, TRUE);

    Status = ElfFlushFile(&pLogFile->LogFile);

    /* Unlock the log file */
    RtlReleaseResource(&pLogFile->Lock);

    return Status;
}
Пример #13
0
NTSTATUS
LogfWriteRecord(PLOGFILE LogFile,
                PEVENTLOGRECORD Record,
                SIZE_T BufSize)
{
    NTSTATUS Status;
    LARGE_INTEGER SystemTime;

    // ASSERT(sizeof(*Record) == sizeof(RecBuf));

    if (!Record || BufSize < sizeof(*Record))
        return STATUS_INVALID_PARAMETER;

    /* Lock the log file exclusive */
    RtlAcquireResourceExclusive(&LogFile->Lock, TRUE);

    /*
     * Retrieve the record written time now, that will also be compared
     * with the existing events timestamps in case the log is wrapping.
     */
    NtQuerySystemTime(&SystemTime);
    RtlTimeToSecondsSince1970(&SystemTime, &Record->TimeWritten);

    Status = ElfWriteRecord(&LogFile->LogFile, Record, BufSize);
    if (Status == STATUS_LOG_FILE_FULL)
    {
        /* The event log file is full, queue a message box for the user and exit */
        // TODO!
        DPRINT1("Log file `%S' is full!\n", LogFile->LogName);
    }

    /* Unlock the log file */
    RtlReleaseResource(&LogFile->Lock);

    return Status;
}
Пример #14
0
Файл: mixer.c Проект: behda/wine
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);
		}
	}
}
Пример #15
0
static int wine_pthread_rwlock_unlock(pthread_rwlock_t *rwlock)
{
  if (!((wine_rwlock)rwlock)->lock) return 0;
  RtlReleaseResource( ((wine_rwlock)rwlock)->lock );
  return 0;
}
Пример #16
0
VOID
LsapAuDereferenceClientContext(
    PLSAP_LOGON_PROCESS Context
    )

/*++

Routine Description:

    This routine decrements the specified context's reference count.
    If the reference count drops to zero, then the context is run-down.

    Details:

            1) Locks the context database.

            2) Decrements the context's reference count.

            3) If the reference count drops to zero, then
               rundown the logon process (close open handles
               and free the context block memory).

            4) Unlocks the context database.

Arguments:

    Context - Points to the context to be dereferenced.


Return Value:

    None.

--*/

{
    BOOLEAN
        Success;

    NTSTATUS
        IgnoreStatus;

    //
    // Acquire exclusive access to the context list
    //

    Success = RtlAcquireResourceExclusive( &LsapAuClientContextLock, TRUE );
    ASSERT(Success);


    //
    // Decrement the reference count
    //

    ASSERT( Context->References >= 1 );
    Context->References -= 1;

    //
    // If the count dropped to zero, then run-down the context
    //

    if (Context->References == 0) {

#ifdef LSAP_AU_TRACK_CONTEXT
    DbgPrint("lsa (au): Deleting client context 0x%lx\n", Context);
#endif //LSAP_AU_TRACK_CONTEXT

#if DBG
        //
        // For debug systems, walk the list of contexts looking for a match.
        // If we find this context on the list, then ASSERT.
        //

        {
        PLIST_ENTRY
            Next;

            Next = LsapAuClientContextListHead.Flink;
            while (Next != &LsapAuClientContextListHead) {
                ASSERT((PVOID)Next != (PVOID)Context);
                Next = Next->Flink;
            }
        }
#endif //DBG

        IgnoreStatus = LsapAuRundownLogonProcess( Context );


    }

    RtlReleaseResource(&LsapAuClientContextLock);
    return;

}
Пример #17
0
BOOLEAN
LsapAuReferenceClientContext(
    PLSAP_CLIENT_REQUEST ClientRequest,
    BOOLEAN RemoveContext,
    PBOOLEAN TrustedClient
    )

/*++

Routine Description:

    This routine checks to see if the client request is from a currently
    active client, and references the context if it is valid.

    The caller may optionally request that the client's context be
    removed from the list of valid contexts - preventing future
    requests from finding this context.

    For a client's context to be valid, the request's context value
    must be on our list of active logon processes.

    NOTE: We can't require the caller's ClientId to match that of the
          caller that registered.  This is because the LM Redirector
          calls from random processes, but attaches to the process it
          did the register from before calling.  LPC considers the call
          to have come from the random process, not the attatched
          process, and so the client IDs don't match.



    Datails:

            1) Lock the context database and verifies that the
               specified context is valid.

            2) Increment the context's reference count.

            3) If requested, remove the context from the
               context list and decrement the reference count
               (to indicate it is no longer on the list).  This
               prevents future lookups from finding the context.

            4) Unlock the context database.


Arguments:

    ClientRequest - Points to the client's request whose context
        is to be referenced.  This is not necessarily a complete
        client request.  However, the context pointer and the client
        IDs are expected to be valid.

    RemoveContext - This boolean value indicates whether the caller
        wants the logon process's context to be removed from the list
        of contexts.  TRUE indicates the context is to be removed.
        FALSE indicates the context is not to be removed.


Return Value:

    TRUE - the context was found and was referenced.

    FALSE - the context was not found.

--*/

{
    BOOLEAN
        Success;

    PLIST_ENTRY
        Next;

    PLSAP_LOGON_PROCESS
        Context;


    //
    // Acquire exclusive access to the context list
    //

    Success = RtlAcquireResourceExclusive( &LsapAuClientContextLock, TRUE );
    ASSERT(Success);

    //
    // Now walk the list of contexts looking for a match.
    //

    Next = LsapAuClientContextListHead.Flink;
    while (Next != &LsapAuClientContextListHead) {

        if ((PVOID)Next ==(PVOID)(ClientRequest->LogonProcessContext)) {

            Context = (PLSAP_LOGON_PROCESS)Next;

            //
            // Found a match ... reference this context
            // (if the context is being removed, we would increment
            // and then decrement the reference, so don't bother doing
            // either - since they cancel each other out).
            //

            if (!RemoveContext) {
                Context->References += 1;
            } else {

                RemoveEntryList( Next );
#ifdef LSAP_AU_TRACK_CONTEXT
    DbgPrint("lsa (au): Removing client context 0x%lx\n", Context);
#endif //LSAP_AU_TRACK_CONTEXT
            }

            RtlReleaseResource(&LsapAuClientContextLock);

            *TrustedClient = Context->TrustedClient;

            return(TRUE);

        }


        //
        // Wasn't this one, move on to the next one.
        //

        Next = Next->Flink;
    }


    //
    // No match found
    //

#ifdef LSAP_AU_TRACK_CONTEXT
    DbgPrint("lsa\\server: (au) Call from unknown client.\n");
    Next = (PLIST_ENTRY)ClientRequest->LogonProcessContext;
    DbgPrint("             Context (0x%lx)\n", Next);
        DbgPrint("       Context Entry (0x%lx)\n", Next);
        DbgPrint("                       Flink:  0x%lx\n", Next->Flink );
        DbgPrint("                       Blink:  0x%lx\n", Next->Blink );
        DbgPrint("                         Ref:  %d\n", ((PLSAP_LOGON_PROCESS)Next)->References);
        DbgPrint("                        Proc:  0x%lx\n", ((PLSAP_LOGON_PROCESS)Next)->ClientProcess);
        DbgPrint("                        Comm:  0x%lx\n", ((PLSAP_LOGON_PROCESS)Next)->CommPort);

    Next = LsapAuClientContextListHead.Flink;
    DbgPrint("   Active context list head:  (%lx, %lx)\n",
             LsapAuClientContextListHead.Flink,
             LsapAuClientContextListHead.Blink);

    while (Next != &LsapAuClientContextListHead) {
        DbgPrint("       Context Entry (0x%lx)\n", Next);
        DbgPrint("                       Flink:  0x%lx\n", Next->Flink );
        DbgPrint("                       Blink:  0x%lx\n", Next->Blink );
        DbgPrint("                         Ref:  %d\n", ((PLSAP_LOGON_PROCESS)Next)->References);
        DbgPrint("                        Proc:  0x%lx\n", ((PLSAP_LOGON_PROCESS)Next)->ClientProcess);
        DbgPrint("                        Comm:  0x%lx\n", ((PLSAP_LOGON_PROCESS)Next)->CommPort);
        Next = Next->Flink;
    }
#endif //LSAP_AU_TRACK_CONTEXT

    ClientRequest->Request->ReturnedStatus = STATUS_INVALID_PARAMETER;
    RtlReleaseResource(&LsapAuClientContextLock);
    return(FALSE);

}
Пример #18
0
VOID
LsapAuAddClientContext(
    PLSAP_LOGON_PROCESS Context
    )

/*++

Routine Description:

    This routine adds a new client context to the list of
    valid logon process contexts.

    After adding a new context, that context has been referenced
    to allow the caller to continue using it.  Therefore, the
    caller is expected to dereference the context before completing
    the LPC call.

    This routine will initialize the Links and References fields
    of the client context.

    Details:

            1) Locks the context database.

            2) Set's the context's reference count to 2,
               one for being on the context list, one because
               the caller is using it.  This means the caller
               must call LsapAuDereferenceClientContext() after
               adding the context.

            3) Adds the context to the context list.

            4) Unlocks the context database.



Arguments:

    Context - Points to the client's request whose context
        is to be added.


Return Value:

    None.

--*/

{

    BOOLEAN
        Success;

    //
    // Acquire exclusive access to the context list
    //

    Success = RtlAcquireResourceExclusive( &LsapAuClientContextLock, TRUE );
    ASSERT(Success);


    //
    // The reference count is set to 2.  1 to indicate it is on the
    // valid context list, and one for the caller.
    //

    Context->References = 2;

    //
    // Add it to the list of contexts.
    //

    InsertHeadList( &LsapAuClientContextListHead, &Context->Links );
#ifdef LSAP_AU_TRACK_CONTEXT
    DbgPrint("lsa (au): Adding client context 0x%lx\n", Context);
#endif //LSAP_AU_TRACK_CONTEXT



    //
    // Free the lock
    //

    RtlReleaseResource(&LsapAuClientContextLock);
    return;

}
Пример #19
0
HRESULT primarybuffer_SetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX passed_fmt)
{
	HRESULT err = DSERR_BUFFERLOST;
	int i;
	WAVEFORMATEX *old_fmt;
	WAVEFORMATEXTENSIBLE *fmtex;
	BOOL forced = (device->priolevel == DSSCL_WRITEPRIMARY);

	TRACE("(%p,%p)\n", device, passed_fmt);

	if (device->priolevel == DSSCL_NORMAL) {
		WARN("failed priority check!\n");
		return DSERR_PRIOLEVELNEEDED;
	}

	/* Let's be pedantic! */
	if (passed_fmt == NULL) {
		WARN("invalid parameter: passed_fmt==NULL!\n");
		return DSERR_INVALIDPARAM;
	}
	TRACE("(formattag=0x%04x,chans=%d,samplerate=%d,"
			  "bytespersec=%d,blockalign=%d,bitspersamp=%d,cbSize=%d)\n",
		  passed_fmt->wFormatTag, passed_fmt->nChannels, passed_fmt->nSamplesPerSec,
		  passed_fmt->nAvgBytesPerSec, passed_fmt->nBlockAlign,
		  passed_fmt->wBitsPerSample, passed_fmt->cbSize);

	/* **** */
	RtlAcquireResourceExclusive(&(device->buffer_list_lock), TRUE);
	EnterCriticalSection(&(device->mixlock));

	old_fmt = device->pwfx;
	device->pwfx = DSOUND_CopyFormat(passed_fmt);
	fmtex = (WAVEFORMATEXTENSIBLE *)device->pwfx;
	if (device->pwfx == NULL) {
		device->pwfx = old_fmt;
		old_fmt = NULL;
		err = DSERR_OUTOFMEMORY;
		goto done;
	}

	DSOUND_PrimaryClose(device);

	err = DSOUND_ReopenDevice(device, FALSE);
	if(SUCCEEDED(err))
		goto opened;

	/* requested format failed, so try others */
	if(device->pwfx->wFormatTag == WAVE_FORMAT_IEEE_FLOAT){
		device->pwfx->wFormatTag = WAVE_FORMAT_PCM;
		device->pwfx->wBitsPerSample = 32;
		device->pwfx->nAvgBytesPerSec = passed_fmt->nSamplesPerSec * device->pwfx->nBlockAlign;
		device->pwfx->nBlockAlign = passed_fmt->nChannels * (device->pwfx->wBitsPerSample / 8);

		err = DSOUND_ReopenDevice(device, FALSE);
		if(SUCCEEDED(err))
			goto opened;
	}

	if(device->pwfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE &&
			 IsEqualGUID(&fmtex->SubFormat, &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT)){
		fmtex->SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
		device->pwfx->wBitsPerSample = 32;
		device->pwfx->nAvgBytesPerSec = passed_fmt->nSamplesPerSec * device->pwfx->nBlockAlign;
		device->pwfx->nBlockAlign = passed_fmt->nChannels * (device->pwfx->wBitsPerSample / 8);

		err = DSOUND_ReopenDevice(device, FALSE);
		if(SUCCEEDED(err))
			goto opened;
	}

	device->pwfx->wBitsPerSample = 32;
	device->pwfx->nAvgBytesPerSec = passed_fmt->nSamplesPerSec * device->pwfx->nBlockAlign;
	device->pwfx->nBlockAlign = passed_fmt->nChannels * (device->pwfx->wBitsPerSample / 8);
	err = DSOUND_ReopenDevice(device, FALSE);
	if(SUCCEEDED(err))
		goto opened;

	device->pwfx->wBitsPerSample = 16;
	device->pwfx->nAvgBytesPerSec = passed_fmt->nSamplesPerSec * device->pwfx->nBlockAlign;
	device->pwfx->nBlockAlign = passed_fmt->nChannels * (device->pwfx->wBitsPerSample / 8);
	err = DSOUND_ReopenDevice(device, FALSE);
	if(SUCCEEDED(err))
		goto opened;

	device->pwfx->wBitsPerSample = 8;
	device->pwfx->nAvgBytesPerSec = passed_fmt->nSamplesPerSec * device->pwfx->nBlockAlign;
	device->pwfx->nBlockAlign = passed_fmt->nChannels * (device->pwfx->wBitsPerSample / 8);
	err = DSOUND_ReopenDevice(device, FALSE);
	if(SUCCEEDED(err))
		goto opened;

	device->pwfx->nChannels = (passed_fmt->nChannels == 2) ? 1 : 2;
	device->pwfx->wBitsPerSample = passed_fmt->wBitsPerSample;
	device->pwfx->nAvgBytesPerSec = passed_fmt->nSamplesPerSec * device->pwfx->nBlockAlign;
	device->pwfx->nBlockAlign = passed_fmt->nChannels * (device->pwfx->wBitsPerSample / 8);
	err = DSOUND_ReopenDevice(device, FALSE);
	if(SUCCEEDED(err))
		goto opened;

	device->pwfx->wBitsPerSample = 32;
	device->pwfx->nAvgBytesPerSec = passed_fmt->nSamplesPerSec * device->pwfx->nBlockAlign;
	device->pwfx->nBlockAlign = passed_fmt->nChannels * (device->pwfx->wBitsPerSample / 8);
	err = DSOUND_ReopenDevice(device, FALSE);
	if(SUCCEEDED(err))
		goto opened;

	device->pwfx->wBitsPerSample = 16;
	device->pwfx->nAvgBytesPerSec = passed_fmt->nSamplesPerSec * device->pwfx->nBlockAlign;
	device->pwfx->nBlockAlign = passed_fmt->nChannels * (device->pwfx->wBitsPerSample / 8);
	err = DSOUND_ReopenDevice(device, FALSE);
	if(SUCCEEDED(err))
		goto opened;

	device->pwfx->wBitsPerSample = 8;
	device->pwfx->nAvgBytesPerSec = passed_fmt->nSamplesPerSec * device->pwfx->nBlockAlign;
	device->pwfx->nBlockAlign = passed_fmt->nChannels * (device->pwfx->wBitsPerSample / 8);
	err = DSOUND_ReopenDevice(device, FALSE);
	if(SUCCEEDED(err))
		goto opened;

	WARN("No formats could be opened\n");
	goto done;

opened:
	err = DSOUND_PrimaryOpen(device);
	if (err != DS_OK) {
		WARN("DSOUND_PrimaryOpen failed\n");
		goto done;
	}

	if (passed_fmt->nSamplesPerSec/100 != device->pwfx->nSamplesPerSec/100 && forced && device->buffer)
	{
		DSOUND_PrimaryClose(device);
		device->pwfx->nSamplesPerSec = passed_fmt->nSamplesPerSec;
		err = DSOUND_ReopenDevice(device, TRUE);
		if (FAILED(err))
			WARN("DSOUND_ReopenDevice(2) failed: %08x\n", err);
		else if (FAILED((err = DSOUND_PrimaryOpen(device))))
			WARN("DSOUND_PrimaryOpen(2) failed: %08x\n", err);
	}

	device->mix_buffer_len = DSOUND_bufpos_to_mixpos(device, device->buflen);
	device->mix_buffer = HeapReAlloc(GetProcessHeap(), 0, device->mix_buffer, device->mix_buffer_len);
	FillMemory(device->mix_buffer, device->mix_buffer_len, 0);
	device->mixfunction = mixfunctions[device->pwfx->wBitsPerSample/8 - 1];
	device->normfunction = normfunctions[device->pwfx->wBitsPerSample/8 - 1];

	if (old_fmt->nSamplesPerSec != device->pwfx->nSamplesPerSec ||
			old_fmt->wBitsPerSample != device->pwfx->wBitsPerSample ||
			old_fmt->nChannels != device->pwfx->nChannels) {
		IDirectSoundBufferImpl** dsb = device->buffers;
		for (i = 0; i < device->nrofbuffers; i++, dsb++) {
			/* **** */
			RtlAcquireResourceExclusive(&(*dsb)->lock, TRUE);

			(*dsb)->freqAdjust = ((DWORD64)(*dsb)->freq << DSOUND_FREQSHIFT) / device->pwfx->nSamplesPerSec;
			DSOUND_RecalcFormat((*dsb));
			DSOUND_MixToTemporary((*dsb), 0, (*dsb)->buflen, FALSE);
			(*dsb)->primary_mixpos = 0;

			RtlReleaseResource(&(*dsb)->lock);
			/* **** */
		}
	}

done:
	LeaveCriticalSection(&(device->mixlock));
	RtlReleaseResource(&(device->buffer_list_lock));
	/* **** */

	HeapFree(GetProcessHeap(), 0, old_fmt);
	return err;
}
Пример #20
0
HRESULT primarybuffer_SetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX passed_fmt)
{
	HRESULT err = S_OK;
	WAVEFORMATEX *old_fmt;
	WAVEFORMATEXTENSIBLE *fmtex, *passed_fmtex = (WAVEFORMATEXTENSIBLE*)passed_fmt;

	TRACE("(%p,%p)\n", device, passed_fmt);

	if (device->priolevel == DSSCL_NORMAL) {
		WARN("failed priority check!\n");
		return DSERR_PRIOLEVELNEEDED;
	}

	/* Let's be pedantic! */
	if (passed_fmt == NULL) {
		WARN("invalid parameter: passed_fmt==NULL!\n");
		return DSERR_INVALIDPARAM;
	}
	TRACE("(formattag=0x%04x,chans=%d,samplerate=%d,"
			  "bytespersec=%d,blockalign=%d,bitspersamp=%d,cbSize=%d)\n",
		  passed_fmt->wFormatTag, passed_fmt->nChannels, passed_fmt->nSamplesPerSec,
		  passed_fmt->nAvgBytesPerSec, passed_fmt->nBlockAlign,
		  passed_fmt->wBitsPerSample, passed_fmt->cbSize);

	if(passed_fmt->wBitsPerSample < 8 || passed_fmt->wBitsPerSample % 8 != 0 ||
			passed_fmt->nChannels == 0 || passed_fmt->nSamplesPerSec == 0 ||
			passed_fmt->nAvgBytesPerSec == 0 ||
			passed_fmt->nBlockAlign != passed_fmt->nChannels * passed_fmt->wBitsPerSample / 8)
		return DSERR_INVALIDPARAM;

	if(passed_fmt->wFormatTag == WAVE_FORMAT_EXTENSIBLE){
		if(passed_fmtex->Samples.wValidBitsPerSample > passed_fmtex->Format.wBitsPerSample)
			return DSERR_INVALIDPARAM;
	}

	/* **** */
	RtlAcquireResourceExclusive(&(device->buffer_list_lock), TRUE);
	EnterCriticalSection(&(device->mixlock));

	old_fmt = device->primary_pwfx;
	device->primary_pwfx = DSOUND_CopyFormat(passed_fmt);
	fmtex = (WAVEFORMATEXTENSIBLE *)device->primary_pwfx;
	if (device->primary_pwfx == NULL) {
		err = DSERR_OUTOFMEMORY;
		goto out;
	}

	if (fmtex->Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE &&
			fmtex->Samples.wValidBitsPerSample == 0) {
		TRACE("Correcting 0 valid bits per sample\n");
		fmtex->Samples.wValidBitsPerSample = fmtex->Format.wBitsPerSample;
	}

	if(device->priolevel == DSSCL_WRITEPRIMARY || device->nrofbuffers == 0)
		err = DSOUND_ReopenDevice(device, TRUE);
	if (FAILED(err) && device->priolevel == DSSCL_WRITEPRIMARY) {
		ERR("No formats could be opened\n");
		HeapFree(GetProcessHeap(), 0, device->primary_pwfx);
		device->primary_pwfx = old_fmt;
	} else {
		/* ignore failures */
		err = S_OK;
		HeapFree(GetProcessHeap(), 0, old_fmt);
	}

out:
	LeaveCriticalSection(&(device->mixlock));
	RtlReleaseResource(&(device->buffer_list_lock));
	/* **** */

	return err;
}
Пример #21
0
static HRESULT DSOUND_PrimaryOpen(DirectSoundDevice *device, WAVEFORMATEX *wfx, DWORD frames, BOOL forcewave)
{
    IDirectSoundBufferImpl** dsb = device->buffers;
    LPBYTE newbuf;
    DWORD new_buflen;
    BOOL mixfloat = FALSE;
    int i;

    TRACE("(%p)\n", device);

    new_buflen = device->buflen;
    new_buflen -= new_buflen % wfx->nBlockAlign;

    if (wfx->wFormatTag == WAVE_FORMAT_IEEE_FLOAT ||
        (wfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE &&
         IsEqualGUID(&((WAVEFORMATEXTENSIBLE*)wfx)->SubFormat, &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT)))
        mixfloat = TRUE;

    /* reallocate emulated primary buffer */
    if (forcewave) {
        if (device->buffer)
            newbuf = HeapReAlloc(GetProcessHeap(), 0, device->buffer, new_buflen);
        else
            newbuf = HeapAlloc(GetProcessHeap(), 0, new_buflen);

        if (!newbuf) {
            ERR("failed to allocate primary buffer\n");
            return DSERR_OUTOFMEMORY;
        }
        FillMemory(newbuf, new_buflen, (wfx->wBitsPerSample == 8) ? 128 : 0);
    } else if (!mixfloat) {
        DWORD alloc_len = frames * sizeof(float);

        if (device->buffer)
            newbuf = HeapReAlloc(GetProcessHeap(), 0, device->buffer, alloc_len);
        else
            newbuf = HeapAlloc(GetProcessHeap(), 0, alloc_len);

        if (!newbuf) {
            ERR("failed to allocate primary buffer\n");
            return DSERR_OUTOFMEMORY;
        }
        FillMemory(newbuf, alloc_len, (wfx->wBitsPerSample == 8) ? 128 : 0);
    } else {
        HeapFree(GetProcessHeap(), 0, device->buffer);
        newbuf = NULL;
    }

    device->buffer = newbuf;
    device->buflen = new_buflen;
    HeapFree(GetProcessHeap(), 0, device->pwfx);
    device->pwfx = wfx;

    device->writelead = (wfx->nSamplesPerSec / 100) * wfx->nBlockAlign;

    TRACE("buflen: %u, fraglen: %u\n", device->buflen, device->fraglen);

    if (!mixfloat)
        device->normfunction = normfunctions[wfx->wBitsPerSample/8 - 1];
    else
        device->normfunction = NULL;

    device->playpos = 0;

    for (i = 0; i < device->nrofbuffers; i++) {
        RtlAcquireResourceExclusive(&dsb[i]->lock, TRUE);
        DSOUND_RecalcFormat(dsb[i]);
        RtlReleaseResource(&dsb[i]->lock);
    }

    return DS_OK;
}
Пример #22
0
/*
 * 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;
}
Пример #23
0
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();
}
Пример #24
0
HRESULT primarybuffer_SetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX passed_fmt)
{
	HRESULT err = S_OK;
	WAVEFORMATEX *old_fmt;
	WAVEFORMATEXTENSIBLE *fmtex, *passed_fmtex = (WAVEFORMATEXTENSIBLE*)passed_fmt;
	BOOL forced = (device->priolevel == DSSCL_WRITEPRIMARY);

	TRACE("(%p,%p)\n", device, passed_fmt);

	if (device->priolevel == DSSCL_NORMAL) {
		WARN("failed priority check!\n");
		return DSERR_PRIOLEVELNEEDED;
	}

	/* Let's be pedantic! */
	if (passed_fmt == NULL) {
		WARN("invalid parameter: passed_fmt==NULL!\n");
		return DSERR_INVALIDPARAM;
	}
	TRACE("(formattag=0x%04x,chans=%d,samplerate=%d,"
			  "bytespersec=%d,blockalign=%d,bitspersamp=%d,cbSize=%d)\n",
		  passed_fmt->wFormatTag, passed_fmt->nChannels, passed_fmt->nSamplesPerSec,
		  passed_fmt->nAvgBytesPerSec, passed_fmt->nBlockAlign,
		  passed_fmt->wBitsPerSample, passed_fmt->cbSize);

	if(passed_fmt->wBitsPerSample < 8 || passed_fmt->wBitsPerSample % 8 != 0 ||
			passed_fmt->nChannels == 0 || passed_fmt->nSamplesPerSec == 0 ||
			passed_fmt->nAvgBytesPerSec == 0 ||
			passed_fmt->nBlockAlign != passed_fmt->nChannels * passed_fmt->wBitsPerSample / 8)
		return DSERR_INVALIDPARAM;

	if(passed_fmt->wFormatTag == WAVE_FORMAT_EXTENSIBLE){
		if(passed_fmtex->Samples.wValidBitsPerSample > passed_fmtex->Format.wBitsPerSample)
			return DSERR_INVALIDPARAM;
	}

	/* **** */
	RtlAcquireResourceExclusive(&(device->buffer_list_lock), TRUE);
	EnterCriticalSection(&(device->mixlock));

	if (device->priolevel == DSSCL_WRITEPRIMARY) {
		old_fmt = device->primary_pwfx;
		device->primary_pwfx = DSOUND_CopyFormat(passed_fmt);
		fmtex = (WAVEFORMATEXTENSIBLE *)device->primary_pwfx;
		if (device->primary_pwfx == NULL) {
			err = DSERR_OUTOFMEMORY;
			goto out;
		}

		if (fmtex->Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE &&
		    fmtex->Samples.wValidBitsPerSample == 0) {
			TRACE("Correcting 0 valid bits per sample\n");
			fmtex->Samples.wValidBitsPerSample = fmtex->Format.wBitsPerSample;
		}

		DSOUND_PrimaryClose(device);

		err = DSOUND_ReopenDevice(device, forced);
		if (FAILED(err)) {
			ERR("No formats could be opened\n");
			goto done;
		}

		err = DSOUND_PrimaryOpen(device);
		if (err != DS_OK) {
			ERR("DSOUND_PrimaryOpen failed\n");
			goto done;
		}

done:
		if (err != DS_OK)
			device->primary_pwfx = old_fmt;
		else
			HeapFree(GetProcessHeap(), 0, old_fmt);
	} else if (passed_fmt->wFormatTag == WAVE_FORMAT_PCM ||
		   passed_fmt->wFormatTag == WAVE_FORMAT_IEEE_FLOAT) {
		/* Fill in "real" values to primary_pwfx */
		WAVEFORMATEX *fmt = device->primary_pwfx;

		*fmt = *device->pwfx;
		fmtex = (void*)device->pwfx;

		if (IsEqualGUID(&fmtex->SubFormat, &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT) &&
		    passed_fmt->wFormatTag == WAVE_FORMAT_IEEE_FLOAT) {
			fmt->wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
		} else {
			fmt->wFormatTag = WAVE_FORMAT_PCM;
			fmt->wBitsPerSample = 16;
		}
		fmt->nBlockAlign = fmt->nChannels * fmt->wBitsPerSample / 8;
		fmt->nAvgBytesPerSec = fmt->nBlockAlign * fmt->nSamplesPerSec;
		fmt->cbSize = 0;
	} else {
		device->primary_pwfx = HeapReAlloc(GetProcessHeap(), 0, device->primary_pwfx, sizeof(*fmtex));
		memcpy(device->primary_pwfx, device->pwfx, sizeof(*fmtex));
	}

out:
	LeaveCriticalSection(&(device->mixlock));
	RtlReleaseResource(&(device->buffer_list_lock));
	/* **** */

	return err;
}
Пример #25
0
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;
}
Пример #26
0
NET_API_STATUS NET_API_FUNCTION
NetrWkstaSetInfo(
    IN  LPTSTR ServerName OPTIONAL,
    IN  DWORD Level,
    IN  LPWKSTA_INFO WkstaInfo,
    OUT LPDWORD ErrorParameter OPTIONAL
    )
/*++

Routine Description:

    This function is the NetWkstaSetInfo entry point in the Workstation
    service.  It checks the security access of the caller to make sure
    that the caller is allowed to set specific workstation information.

Arguments:

    ServerName - Supplies the name of server to execute this function

    Level - Supplies the level of information.

    WkstaInfo - Supplies a pointer to union structure of pointers to
        buffer of fields to set.  The level denotes the fields supplied in
        this buffer.

    ErrorParameter - Returns the identifier to the invalid parameter if
        this function returns ERROR_INVALID_PARAMETER.

Return Value:

    NET_API_STATUS - NERR_Success or reason for failure.

--*/
{
    WKSTA_INFO_502 OriginalWksta = WSBUF;
    NET_API_STATUS status = NERR_Success;
    DWORD Parmnum;

    UNREFERENCED_PARAMETER(ServerName);

    //
    // Check for NULL input buffer
    //
    if (WkstaInfo->WkstaInfo502 == NULL) {
        RETURN_INVALID_PARAMETER(ErrorParameter, PARM_ERROR_UNKNOWN);
    }

    //
    // Only admins can set redirector configurable fields.  Validate access.
    //
    if (NetpAccessCheckAndAudit(
            WORKSTATION_DISPLAY_NAME,        // Subsystem name
            (LPTSTR) CONFIG_INFO_OBJECT,     // Object type name
            ConfigurationInfoSd,             // Security descriptor
            WKSTA_CONFIG_INFO_SET,           // Desired access
            &WsConfigInfoMapping             // Generic mapping
            ) != NERR_Success) {

        return ERROR_ACCESS_DENIED;
    }

    //
    // Serialize write access
    //
    if (! RtlAcquireResourceExclusive(&WsInfo.ConfigResource, TRUE)) {
        return NERR_InternalError;
    }

    status = WsValidateAndSetWksta(
                 Level,
                 (LPBYTE) WkstaInfo->WkstaInfo502,
                 ErrorParameter,
                 &Parmnum
                 );

    if (status != NERR_Success) {
        goto CleanExit;
    }

    //
    // Set NT redirector specific fields
    //
    status = WsUpdateRedirToMatchWksta(
                 Parmnum,
                 ErrorParameter
                 );

    if (status != NERR_Success) {
        goto CleanExit;
    }

    //
    // Make updates "sticky" (update registry to match wksta).
    //
    WsUpdateRegistryToMatchWksta(
        Level,
        (LPBYTE) WkstaInfo->WkstaInfo502,
        ErrorParameter
        );

CleanExit:
    if (status != NERR_Success) {
        WSBUF = OriginalWksta;
    }
    RtlReleaseResource(&WsInfo.ConfigResource);
    return status;
}
Пример #27
0
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;
}
Пример #28
0
static HRESULT DSOUND_PrimarySetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX wfex, BOOL forced)
{
	HRESULT err = DSERR_BUFFERLOST;
	int i;
	DWORD nSamplesPerSec, bpp, chans;
	LPWAVEFORMATEX oldpwfx;
	TRACE("(%p,%p)\n", device, wfex);

	if (device->priolevel == DSSCL_NORMAL) {
		WARN("failed priority check!\n");
		return DSERR_PRIOLEVELNEEDED;
	}

	/* Let's be pedantic! */
	if (wfex == NULL) {
		WARN("invalid parameter: wfex==NULL!\n");
		return DSERR_INVALIDPARAM;
	}
	TRACE("(formattag=0x%04x,chans=%d,samplerate=%d,"
              "bytespersec=%d,blockalign=%d,bitspersamp=%d,cbSize=%d)\n",
	      wfex->wFormatTag, wfex->nChannels, wfex->nSamplesPerSec,
	      wfex->nAvgBytesPerSec, wfex->nBlockAlign,
	      wfex->wBitsPerSample, wfex->cbSize);

	/* **** */
	RtlAcquireResourceExclusive(&(device->buffer_list_lock), TRUE);
	EnterCriticalSection(&(device->mixlock));

	nSamplesPerSec = device->pwfx->nSamplesPerSec;
	bpp = device->pwfx->wBitsPerSample;
	chans = device->pwfx->nChannels;

	oldpwfx = device->pwfx;
	device->pwfx = DSOUND_CopyFormat(wfex);
	if (device->pwfx == NULL) {
		device->pwfx = oldpwfx;
		oldpwfx = NULL;
		err = DSERR_OUTOFMEMORY;
		goto done;
	}

	if (!(device->drvdesc.dwFlags & DSDDESC_DOMMSYSTEMSETFORMAT) && device->hwbuf) {
		err = IDsDriverBuffer_SetFormat(device->hwbuf, device->pwfx);

		/* On bad format, try to re-create, big chance it will work then, only do this if we <HAVE> to */
		if (forced && (device->pwfx->nSamplesPerSec/100 != wfex->nSamplesPerSec/100 || err == DSERR_BADFORMAT))
		{
			DWORD cp_size = wfex->wFormatTag == WAVE_FORMAT_PCM ?
				sizeof(PCMWAVEFORMAT) : sizeof(WAVEFORMATEX) + wfex->cbSize;
			err = DSERR_BUFFERLOST;
			CopyMemory(device->pwfx, wfex, cp_size);
		}

		if (err != DSERR_BUFFERLOST && FAILED(err)) {
			DWORD size = DSOUND_GetFormatSize(oldpwfx);
			WARN("IDsDriverBuffer_SetFormat failed\n");
			if (!forced) {
				CopyMemory(device->pwfx, oldpwfx, size);
				err = DS_OK;
			}
			goto done;
		}

		if (err == S_FALSE)
		{
			/* ALSA specific: S_FALSE tells that recreation was successful,
			 * but size and location may be changed, and buffer has to be restarted
			 * I put it here, so if frequency doesn't match the error will be changed to DSERR_BUFFERLOST
			 * and the entire re-initialization will occur anyway
			 */
			IDsDriverBuffer_Lock(device->hwbuf, (LPVOID *)&device->buffer, &device->buflen, NULL, NULL, 0, 0, DSBLOCK_ENTIREBUFFER);
			IDsDriverBuffer_Unlock(device->hwbuf, device->buffer, 0, NULL, 0);

			if (device->state == STATE_PLAYING) device->state = STATE_STARTING;
			else if (device->state == STATE_STOPPING) device->state = STATE_STOPPED;
			device->pwplay = device->pwqueue = device->playpos = device->mixpos = 0;
			err = DS_OK;
		}
		DSOUND_RecalcPrimary(device);
	}

	if (err == DSERR_BUFFERLOST)
	{
		DSOUND_PrimaryClose(device);

		err = DSOUND_ReopenDevice(device, FALSE);
		if (FAILED(err))
		{
			WARN("DSOUND_ReopenDevice failed: %08x\n", err);
			goto done;
		}
		err = DSOUND_PrimaryOpen(device);
		if (err != DS_OK) {
			WARN("DSOUND_PrimaryOpen failed\n");
			goto done;
		}

		if (wfex->nSamplesPerSec/100 != device->pwfx->nSamplesPerSec/100 && forced && device->buffer)
		{
			DSOUND_PrimaryClose(device);
			device->pwfx->nSamplesPerSec = wfex->nSamplesPerSec;
			err = DSOUND_ReopenDevice(device, TRUE);
			if (FAILED(err))
				WARN("DSOUND_ReopenDevice(2) failed: %08x\n", err);
			else if (FAILED((err = DSOUND_PrimaryOpen(device))))
				WARN("DSOUND_PrimaryOpen(2) failed: %08x\n", err);
		}
	}

	device->mix_buffer_len = DSOUND_bufpos_to_mixpos(device, device->buflen);
	device->mix_buffer = HeapReAlloc(GetProcessHeap(), 0, device->mix_buffer, device->mix_buffer_len);
	FillMemory(device->mix_buffer, device->mix_buffer_len, 0);
	device->mixfunction = mixfunctions[device->pwfx->wBitsPerSample/8 - 1];
	device->normfunction = normfunctions[device->pwfx->wBitsPerSample/8 - 1];

	if (nSamplesPerSec != device->pwfx->nSamplesPerSec || bpp != device->pwfx->wBitsPerSample || chans != device->pwfx->nChannels) {
		IDirectSoundBufferImpl** dsb = device->buffers;
		for (i = 0; i < device->nrofbuffers; i++, dsb++) {
			/* **** */
			RtlAcquireResourceExclusive(&(*dsb)->lock, TRUE);

			(*dsb)->freqAdjust = ((DWORD64)(*dsb)->freq << DSOUND_FREQSHIFT) / device->pwfx->nSamplesPerSec;
			DSOUND_RecalcFormat((*dsb));
			DSOUND_MixToTemporary((*dsb), 0, (*dsb)->buflen, FALSE);
			(*dsb)->primary_mixpos = 0;

			RtlReleaseResource(&(*dsb)->lock);
			/* **** */
		}
	}

done:
	LeaveCriticalSection(&(device->mixlock));
	RtlReleaseResource(&(device->buffer_list_lock));
	/* **** */

	HeapFree(GetProcessHeap(), 0, oldpwfx);
	return err;
}
Пример #29
0
BOOL LogfWriteData(PLOGFILE LogFile, DWORD BufSize, PBYTE Buffer)
{
    DWORD dwWritten;
    DWORD dwRead;
    SYSTEMTIME st;
    EVENTLOGEOF EofRec;
    PEVENTLOGRECORD RecBuf;
    LARGE_INTEGER logFileSize;
    ULONG RecOffSet;
    ULONG WriteOffSet;

    if (!Buffer)
        return FALSE;

    GetSystemTime(&st);
    SystemTimeToEventTime(&st, &((PEVENTLOGRECORD) Buffer)->TimeWritten);

    RtlAcquireResourceExclusive(&LogFile->Lock, TRUE);

    if (!GetFileSizeEx(LogFile->hFile, &logFileSize))
    {
        RtlReleaseResource(&LogFile->Lock);
        return FALSE;
    }

    /* If the size of the file is over MaxSize */
    if ((logFileSize.QuadPart + BufSize)> LogFile->Header.MaxSize)
    {
        ULONG OverWriteLength = 0;
        WriteOffSet = LogfOffsetByNumber(LogFile, LogFile->Header.OldestRecordNumber);
        RecBuf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(EVENTLOGRECORD));
        /* Determine how many records need to be overwritten */
        while (TRUE)
        {
            DPRINT("EventLogFile has reached maximume size\n");

            if (!RecBuf)
            {
                DPRINT1("Failed to allocate buffer for OldestRecord!\n");
                HeapFree(GetProcessHeap(), 0, RecBuf);
                RtlReleaseResource(&LogFile->Lock);
                return FALSE;
            }

            /* Get the oldest record data */
            RecOffSet = LogfOffsetByNumber(LogFile, LogFile->Header.OldestRecordNumber);

            if (SetFilePointer(LogFile->hFile,
                               RecOffSet,
                               NULL,
                               FILE_BEGIN) == INVALID_SET_FILE_POINTER)
            {
                DPRINT1("SetFilePointer() failed! %d\n", GetLastError());
                HeapFree(GetProcessHeap(), 0, RecBuf);
                RtlReleaseResource(&LogFile->Lock);
                return FALSE;
            }

            if (!ReadFile(LogFile->hFile, RecBuf, sizeof(EVENTLOGRECORD), &dwRead, NULL))
            {
                DPRINT1("ReadFile() failed!\n");
                HeapFree(GetProcessHeap(), 0, RecBuf);
                RtlReleaseResource(&LogFile->Lock);
                return FALSE;
            }

            if (RecBuf->Reserved != LOGFILE_SIGNATURE)
            {
                DPRINT1("LogFile corrupt!\n");
                HeapFree(GetProcessHeap(), 0, RecBuf);
                RtlReleaseResource(&LogFile->Lock);
                return FALSE;
            }

            LogfDeleteOffsetInformation(LogFile,LogFile->Header.OldestRecordNumber);

            LogFile->Header.OldestRecordNumber++;

            OverWriteLength += RecBuf->Length;
            /* Check the size of the record as the record adding may be larger */
            if (OverWriteLength >= BufSize)
            {
                DPRINT("Record will fit. Length %d, BufSize %d\n", OverWriteLength, BufSize);
                LogFile->Header.StartOffset = LogfOffsetByNumber(LogFile, LogFile->Header.OldestRecordNumber);
                break;
            }
        }
        HeapFree(GetProcessHeap(), 0, RecBuf);
    }
    else
        WriteOffSet = LogFile->Header.EndOffset;

    if (SetFilePointer(LogFile->hFile,
                       WriteOffSet,
                       NULL,
                       FILE_BEGIN) == INVALID_SET_FILE_POINTER)
    {
        DPRINT1("SetFilePointer() failed! %d\n", GetLastError());
        RtlReleaseResource(&LogFile->Lock);
        return FALSE;
    }

    if (!WriteFile(LogFile->hFile, Buffer, BufSize, &dwWritten, NULL))
    {
        DPRINT1("WriteFile() failed! %d\n", GetLastError());
        RtlReleaseResource(&LogFile->Lock);
        return FALSE;
    }

    if (!LogfAddOffsetInformation(LogFile,
                                  LogFile->Header.CurrentRecordNumber,
                                  WriteOffSet))
    {
        RtlReleaseResource(&LogFile->Lock);
        return FALSE;
    }

    LogFile->Header.CurrentRecordNumber++;

    if (WriteOffSet == LogFile->Header.EndOffset)
    {
        LogFile->Header.EndOffset += dwWritten;
    }
    if (SetFilePointer(LogFile->hFile,
                       LogFile->Header.EndOffset,
                       NULL,
                       FILE_BEGIN) == INVALID_SET_FILE_POINTER)
    {
        DPRINT1("SetFilePointer() failed! %d\n", GetLastError());
        RtlReleaseResource(&LogFile->Lock);
        return FALSE;
    }

    EofRec.Ones = 0x11111111;
    EofRec.Twos = 0x22222222;
    EofRec.Threes = 0x33333333;
    EofRec.Fours = 0x44444444;
    EofRec.RecordSizeBeginning = sizeof(EVENTLOGEOF);
    EofRec.RecordSizeEnd = sizeof(EVENTLOGEOF);
    EofRec.CurrentRecordNumber = LogFile->Header.CurrentRecordNumber;
    EofRec.OldestRecordNumber = LogFile->Header.OldestRecordNumber;
    EofRec.BeginRecord = LogFile->Header.StartOffset;
    EofRec.EndRecord = LogFile->Header.EndOffset;

    if (!WriteFile(LogFile->hFile,
                   &EofRec,
                   sizeof(EVENTLOGEOF),
                   &dwWritten,
                   NULL))
    {
        DPRINT1("WriteFile() failed! %d\n", GetLastError());
        RtlReleaseResource(&LogFile->Lock);
        return FALSE;
    }

    if (SetFilePointer(LogFile->hFile, 0, NULL, FILE_BEGIN) ==
        INVALID_SET_FILE_POINTER)
    {
        DPRINT1("SetFilePointer() failed! %d\n", GetLastError());
        RtlReleaseResource(&LogFile->Lock);
        return FALSE;
    }

    if (!WriteFile(LogFile->hFile,
                   &LogFile->Header,
                   sizeof(EVENTLOGHEADER),
                   &dwWritten,
                   NULL))
    {
        DPRINT1("WriteFile failed! LastError = %d\n", GetLastError());
        RtlReleaseResource(&LogFile->Lock);
        return FALSE;
    }

    if (!FlushFileBuffers(LogFile->hFile))
    {
        DPRINT1("FlushFileBuffers() failed! %d\n", GetLastError());
        RtlReleaseResource(&LogFile->Lock);
        return FALSE;
    }

    RtlReleaseResource(&LogFile->Lock);
    return TRUE;
}
Пример #30
0
HRESULT DSOUND_PrimaryOpen(DirectSoundDevice *device)
{
	IDirectSoundBufferImpl** dsb = device->buffers;
	LPBYTE newbuf;
        int i;

	TRACE("(%p)\n", device);

	device->fraglen = DSOUND_fraglen(device);

	/* on original windows, the buffer it set to a fixed size, no matter what the settings are.
	   on windows this size is always fixed (tested on win-xp) */
	if (!device->buflen)
		device->buflen = ds_hel_buflen;
	device->buflen -= device->buflen % device->pwfx->nBlockAlign;
	while(device->buflen < device->fraglen * device->prebuf){
		device->buflen += ds_hel_buflen;
		device->buflen -= device->buflen % device->pwfx->nBlockAlign;
	}

	HeapFree(GetProcessHeap(), 0, device->mix_buffer);
	device->mix_buffer_len = (device->buflen / (device->pwfx->wBitsPerSample / 8)) * sizeof(float);
	device->mix_buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, device->mix_buffer_len);
	if (!device->mix_buffer)
		return DSERR_OUTOFMEMORY;

	if (device->state == STATE_PLAYING) device->state = STATE_STARTING;
	else if (device->state == STATE_STOPPING) device->state = STATE_STOPPED;

    /* reallocate emulated primary buffer */
    if (device->buffer)
        newbuf = HeapReAlloc(GetProcessHeap(),0,device->buffer, device->buflen);
    else
        newbuf = HeapAlloc(GetProcessHeap(),0, device->buflen);

    if (!newbuf) {
        ERR("failed to allocate primary buffer\n");
        return DSERR_OUTOFMEMORY;
        /* but the old buffer might still exist and must be re-prepared */
    }

    device->writelead = (device->pwfx->nSamplesPerSec / 100) * device->pwfx->nBlockAlign;

    device->buffer = newbuf;

    TRACE("buflen: %u, fraglen: %u, mix_buffer_len: %u\n",
            device->buflen, device->fraglen, device->mix_buffer_len);

    if(device->pwfx->wFormatTag == WAVE_FORMAT_IEEE_FLOAT ||
            (device->pwfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE &&
             IsEqualGUID(&((WAVEFORMATEXTENSIBLE*)device->pwfx)->SubFormat,
                 &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT)))
        device->normfunction = normfunctions[4];
    else
        device->normfunction = normfunctions[device->pwfx->wBitsPerSample/8 - 1];

    FillMemory(device->buffer, device->buflen, (device->pwfx->wBitsPerSample == 8) ? 128 : 0);
    FillMemory(device->mix_buffer, device->mix_buffer_len, 0);
    device->playpos = 0;

    if (device->pwfx->wFormatTag == WAVE_FORMAT_IEEE_FLOAT ||
	 (device->pwfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE &&
	  IsEqualGUID(&((WAVEFORMATEXTENSIBLE*)device->pwfx)->SubFormat, &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT)))
        device->normfunction = normfunctions[4];
    else
        device->normfunction = normfunctions[device->pwfx->wBitsPerSample/8 - 1];

    for (i = 0; i < device->nrofbuffers; i++) {
        RtlAcquireResourceExclusive(&dsb[i]->lock, TRUE);
        DSOUND_RecalcFormat(dsb[i]);
        RtlReleaseResource(&dsb[i]->lock);
    }

    return DS_OK;
}