示例#1
0
VOID PkUpdateArchiveExtractCallback::Run()
{
    HRESULT result;
    IInArchive *currentArchive;

    PhAcquireQueuedLockExclusive(&Lock);

    while (!ThreadStopping)
    {
        if (!InArchive)
        {
            PhWaitForCondition(&Condition, &Lock, NULL);
            continue;
        }

        currentArchive = InArchive;

        currentArchive->AddRef();
        result = currentArchive->Extract(NULL, -1, FALSE, this);
        currentArchive->Release();

        if (result != E_ABORT && !SUCCEEDED(result))
            Result = result;
    }

    PhReleaseQueuedLockExclusive(&Lock);
}
示例#2
0
VOID PkUpdateArchiveExtractCallback::SetNewJob(IInArchive *NewInArchive, ULONG NewItemIndex, IOutStream *NewOutStream)
{
    PhAcquireQueuedLockExclusive(&Lock);

    // Wait for the current job to finish.
    while (!ThreadStopping && ItemIndex != -1)
        PhWaitForCondition(&Condition, &Lock, NULL);

    if (ThreadStopping)
        return;

    if (NewInArchive)
        NewInArchive->AddRef();
    if (InArchive)
        InArchive->Release();

    InArchive = NewInArchive;

    ItemIndex = NewItemIndex;

    if (NewOutStream)
        NewOutStream->AddRef();
    if (OutStream)
        OutStream->Release();

    OutStream = NewOutStream;

    PhPulseCondition(&Condition);

    PhReleaseQueuedLockExclusive(&Lock);
}
示例#3
0
VOID PkUpdateArchiveExtractCallback::WaitForJob()
{
    PhAcquireQueuedLockExclusive(&Lock);

    while (InArchive && ItemIndex != -1)
        PhWaitForCondition(&Condition, &Lock, NULL);

    PhReleaseQueuedLockExclusive(&Lock);
}
示例#4
0
/**
 * Waits for all queued work items to be executed.
 *
 * \param WorkQueue A work queue object.
 */
VOID PhWaitForWorkQueue(
    _Inout_ PPH_WORK_QUEUE WorkQueue
    )
{
    PhAcquireQueuedLockExclusive(&WorkQueue->QueueLock);

    while (!IsListEmpty(&WorkQueue->QueueListHead))
        PhWaitForCondition(&WorkQueue->QueueEmptyCondition, &WorkQueue->QueueLock, NULL);

    PhReleaseQueuedLockExclusive(&WorkQueue->QueueLock);
}
示例#5
0
HRESULT PkUpdateArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode)
{
    IInArchive *currentArchive;

    // This code executes with the lock held.

    currentArchive = InArchive;

    // Wait until we get a job or the archive has changed.
    while (!ThreadStopping && InArchive == currentArchive && ItemIndex == -1)
    {
        PhWaitForCondition(&Condition, &Lock, NULL);
    }

    if (InArchive != currentArchive)
        return E_ABORT;

    if (index < ItemIndex)
    {
        // Keep searching.
        *outStream = &(new PkFileStream(PkZeroFileStream, NULL))->OutStream;
        return S_OK;
    }
    else if (index == ItemIndex)
    {
        *outStream = OutStream;
        OutStream = NULL;
        ItemIndex = -1;
        PhPulseCondition(&Condition);

        return S_OK;
    }
    else
    {
        // We've gone past the item.
        return E_ABORT;
    }
}
示例#6
0
HRESULT PkFileInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
{
    NTSTATUS status;

    if (Parent->Mode == PkPipeReaderFileStream)
    {
        PkFileStream *parentPipe;
        PCHAR currentData;
        ULONG remainingSize;
        ULONG availableSize;

        parentPipe = Parent->ParentPipe;
        currentData = (PCHAR)data;
        remainingSize = size;

        PhAcquireQueuedLockExclusive(&parentPipe->PipeLock);

        while (remainingSize != 0 && parentPipe->RemainingStreamSize != 0)
        {
            if (parentPipe->ReadPosition == parentPipe->ReadableSize)
            {
                if (parentPipe->RemainingStreamSize == 0 || parentPipe->WriteReferenceCount == 0)
                    break;

                PhPulseCondition(&parentPipe->PipeCondition);
                // Wait for the writer to fill up our buffer.
                PhWaitForCondition(&parentPipe->PipeCondition, &parentPipe->PipeLock, NULL);
                continue;
            }

            availableSize = (ULONG)(parentPipe->ReadableSize - parentPipe->ReadPosition);

            if (remainingSize >= availableSize)
            {
                memcpy(currentData, (PCHAR)parentPipe->Buffer + parentPipe->ReadPosition, availableSize);
                currentData += availableSize;
                parentPipe->ReadPosition += availableSize;

                if (parentPipe->RemainingStreamSize >= availableSize)
                    parentPipe->RemainingStreamSize -= availableSize;
                else
                    parentPipe->RemainingStreamSize = 0;

                remainingSize -= availableSize;
            }
            else
            {
                memcpy(currentData, (PCHAR)parentPipe->Buffer + parentPipe->ReadPosition, remainingSize);
                currentData += availableSize;
                parentPipe->ReadPosition += remainingSize;

                if (parentPipe->RemainingStreamSize >= remainingSize)
                    parentPipe->RemainingStreamSize -= remainingSize;
                else
                    parentPipe->RemainingStreamSize = 0;

                remainingSize = 0;
            }
        }

        PhReleaseQueuedLockExclusive(&parentPipe->PipeLock);

        *processedSize = size - remainingSize;

        return S_OK;
    }
    else if (Parent->Mode == PkPipeWriterFileStream)
    {
        return E_FAIL;
    }

    if (!Parent->FileStream)
    {
        *processedSize = 0;
        return S_OK;
    }

    *processedSize = 0;
    status = PhReadFileStream(Parent->FileStream, data, size, (PULONG)processedSize);

    if (status == STATUS_END_OF_FILE)
    {
        *processedSize = 0;
        return S_OK;
    }

    if (NT_SUCCESS(status))
        return S_OK;
    else
        return E_FAIL;
}
示例#7
0
HRESULT PkFileOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
{
    NTSTATUS status;

    if (Parent->Mode == PkPipeWriterFileStream)
    {
        PkFileStream *parentPipe;
        PCHAR currentData;
        SIZE_T remainingSize;

        parentPipe = Parent->ParentPipe;
        currentData = (PCHAR)data;
        remainingSize = size;

        PhAcquireQueuedLockExclusive(&parentPipe->PipeLock);

        while (remainingSize != 0)
        {
            if (parentPipe->ReadPosition != parentPipe->ReadableSize)
            {
                if (parentPipe->ReadReferenceCount == 0)
                    break;

                // Wait for the reader to read everything.
                PhWaitForCondition(&parentPipe->PipeCondition, &parentPipe->PipeLock, NULL);
                continue;
            }

            if (remainingSize >= parentPipe->BufferSize)
            {
                memcpy(parentPipe->Buffer, currentData, parentPipe->BufferSize);
                currentData += parentPipe->BufferSize;
                parentPipe->ReadableSize = parentPipe->BufferSize;
                remainingSize -= parentPipe->BufferSize;
            }
            else
            {
                memcpy(parentPipe->Buffer, currentData, remainingSize);
                currentData += remainingSize;
                parentPipe->ReadableSize = remainingSize;
                remainingSize = 0;
            }

            parentPipe->ReadPosition = 0;
            PhPulseCondition(&parentPipe->PipeCondition);
        }

        PhReleaseQueuedLockExclusive(&parentPipe->PipeLock);

        *processedSize = size;

        return S_OK;
    }
    else if (Parent->Mode == PkPipeReaderFileStream)
    {
        return E_FAIL;
    }

    if (!Parent->FileStream)
    {
        *processedSize = size;
        return S_OK;
    }

    status = PhWriteFileStream(Parent->FileStream, (PVOID)data, size);
    *processedSize = size;

    if (NT_SUCCESS(status))
        return S_OK;
    else
        return E_FAIL;
}