Exemplo n.º 1
0
os_result_t efi_get_memory_map(
    efi_memory_descriptor_t** array,
    uintn_t* array_count,
    uintn_t* map_key,
    uintn_t* descriptor_size,
    uintn_t* descriptor_version
)
{
    os_result_t status = S_OK;
    efi_memory_descriptor_t* buffer = NULL;
    uintn_t buffer_size = sizeof(efi_memory_descriptor_t);

    while (efi_memory_grow_pool(&status, (void**)&buffer, buffer_size) == S_OK)
    {
        efi_status_t efi_call_status = fw_efi_bt->get_memory_map(&buffer_size, buffer, map_key, descriptor_size, descriptor_version);
        status = efi_get_system_status(efi_call_status);
    }

    if (OS_SUCCESS(status))
    {
        (*array) = buffer;
        (*array_count) = buffer_size / *descriptor_size;
    }

    return status;
}
Exemplo n.º 2
0
///-------------------------------------------------------------------------------------------------
///
/// \brief      Securely compares two memory blocks.
///
/// \param[in]  source1         Provides pointer to first memory block.
/// \param[in]  source2_length  Provides number of bytes in first memory block.
/// \param[in]  source2         Provides pointer to second memory block.
/// \param[in]  source2_length  Provides number of bytes in second memory block.
/// \param[out] result          Returns @c true when source1 and source2 content is equal;
///                             @c false otherwise
///
/// \retval E_INVALID_ARGUMENT  At least one invalid argument provided.
/// \retval S_OK                Operation successful.
///
///-------------------------------------------------------------------------------------------------
OS_NOLIBCALL
os_result_t rtl_memory_equals_s(
    const void* source1,
    size_t source1_length,
    const void* source2,
    size_t source2_length,
    bool* result
    )
{
    if (OS_EXPECT_FALSE(result == NULL))
    {
        return E_INVALID_ARGUMENT;
    }

    size_t compared = 0;
    os_result_t status = rtl_memory_prefix_s(source1, source1_length, source2, source2_length, &compared);

    if (OS_SUCCESS(status))
    {
        (*result) = (compared == source2_length);
    }

    return status;
}
Exemplo n.º 3
0
/*************************************************************************
*
* Function: UDFCommonShutdown()
*
* Description:
*   The actual work is performed here. Basically, all we do here is
*   internally invoke a flush on all mounted logical volumes. This, in
*   tuen, will result in all open file streams being flushed to disk.
*
* Expected Interrupt Level (for execution) :
*
*  IRQL_PASSIVE_LEVEL
*
* Return Value: Irrelevant
*
*************************************************************************/
NTSTATUS
UDFCommonShutdown(
    PtrUDFIrpContext PtrIrpContext,
    PIRP             Irp
    )
{
    NTSTATUS            RC = STATUS_SUCCESS;
    PIO_STACK_LOCATION  IrpSp = NULL;
    PVCB Vcb;
    PLIST_ENTRY Link;
    PPREVENT_MEDIA_REMOVAL_USER_IN Buf = NULL;
    LARGE_INTEGER delay;

    KdPrint(("UDFCommonShutdown\n"));

    _SEH2_TRY {
        // First, get a pointer to the current I/O stack location
        IrpSp = IoGetCurrentIrpStackLocation(Irp);
        ASSERT(IrpSp);

        Buf = (PPREVENT_MEDIA_REMOVAL_USER_IN)MyAllocatePool__(NonPagedPool, sizeof(PREVENT_MEDIA_REMOVAL_USER_IN));
        if(!Buf)
            try_return(RC = STATUS_INSUFFICIENT_RESOURCES);

        // (a) Block all new "mount volume" requests by acquiring an appropriate
        //       global resource/lock.
        // (b) Go through your linked list of mounted logical volumes and for
        //       each such volume, do the following:
        //       (i) acquire the volume resource exclusively
        //       (ii) invoke UDFFlushLogicalVolume() (internally) to flush the
        //              open data streams belonging to the volume from the system
        //              cache
        //       (iii) Invoke the physical/virtual/logical target device object
        //              on which the volume is mounted and inform this device
        //              about the shutdown request (Use IoBuildSynchronouFsdRequest()
        //              to create an IRP with MajorFunction = IRP_MJ_SHUTDOWN that you
        //              will then issue to the target device object).
        //       (iv) Wait for the completion of the shutdown processing by the target
        //              device object
        //       (v) Release the VCB resource we will have acquired in (i) above.

        // Acquire GlobalDataResource
        UDFAcquireResourceExclusive(&(UDFGlobalData.GlobalDataResource), TRUE);
        // Walk through all of the Vcb's attached to the global data.
        Link = UDFGlobalData.VCBQueue.Flink;

        while (Link != &(UDFGlobalData.VCBQueue)) {
            // Get 'next' Vcb
            Vcb = CONTAINING_RECORD( Link, VCB, NextVCB );
            // Move to the next link now since the current Vcb may be deleted.
            Link = Link->Flink;
            ASSERT(Link != Link->Flink);

            if(!(Vcb->VCBFlags & UDF_VCB_FLAGS_SHUTDOWN)) {

#ifdef UDF_DELAYED_CLOSE
                UDFAcquireResourceExclusive(&(Vcb->VCBResource), TRUE);
                KdPrint(("    UDFCommonShutdown:     set UDF_VCB_FLAGS_NO_DELAYED_CLOSE\n"));
                Vcb->VCBFlags |= UDF_VCB_FLAGS_NO_DELAYED_CLOSE;
                UDFReleaseResource(&(Vcb->VCBResource));
#endif //UDF_DELAYED_CLOSE

                // Note: UDFCloseAllDelayed() doesn't acquire DelayedCloseResource if
                // GlobalDataResource is already acquired. Thus for now we should
                // release GlobalDataResource and re-acquire it later.
                UDFReleaseResource( &(UDFGlobalData.GlobalDataResource) );
                if(Vcb->RootDirFCB && Vcb->RootDirFCB->FileInfo) {
                    KdPrint(("    UDFCommonShutdown:     UDFCloseAllSystemDelayedInDir\n"));
                    RC = UDFCloseAllSystemDelayedInDir(Vcb, Vcb->RootDirFCB->FileInfo);
                    ASSERT(OS_SUCCESS(RC));
                }

#ifdef UDF_DELAYED_CLOSE
                UDFCloseAllDelayed(Vcb);
//                UDFReleaseResource(&(UDFGlobalData.DelayedCloseResource));
#endif //UDF_DELAYED_CLOSE

                // re-acquire GlobalDataResource
                UDFAcquireResourceExclusive(&(UDFGlobalData.GlobalDataResource), TRUE);

                // disable Eject Waiter
                UDFStopEjectWaiter(Vcb);
                // Acquire Vcb resource
                UDFAcquireResourceExclusive(&(Vcb->VCBResource), TRUE);

                ASSERT(!Vcb->OverflowQueueCount);

                if(!(Vcb->VCBFlags & UDF_VCB_FLAGS_SHUTDOWN)) {

                    UDFDoDismountSequence(Vcb, Buf, FALSE);
                    if(Vcb->VCBFlags & UDF_VCB_FLAGS_REMOVABLE_MEDIA) {
                        // let drive flush all data before reset
                        delay.QuadPart = -10000000; // 1 sec
                        KeDelayExecutionThread(KernelMode, FALSE, &delay);
                    }
                    Vcb->VCBFlags |= (UDF_VCB_FLAGS_SHUTDOWN |
                                      UDF_VCB_FLAGS_VOLUME_READ_ONLY);
                }

                UDFReleaseResource(&(Vcb->VCBResource));
            }
        }
        // Once we have processed all the mounted logical volumes, we can release
        // all acquired global resources and leave (in peace :-)
        UDFReleaseResource( &(UDFGlobalData.GlobalDataResource) );
        RC = STATUS_SUCCESS;

try_exit: NOTHING;

    } _SEH2_FINALLY {

        if(Buf) MyFreePool__(Buf);
        if(!_SEH2_AbnormalTermination()) {
            Irp->IoStatus.Status = RC;
            Irp->IoStatus.Information = 0;
            // Free up the Irp Context
            UDFReleaseIrpContext(PtrIrpContext);
                // complete the IRP
            IoCompleteRequest(Irp, IO_DISK_INCREMENT);
        }

    } _SEH2_END; // end of "__finally" processing

    return(RC);
} // end UDFCommonShutdown()
Exemplo n.º 4
0
/*
    Thisd routine truncates DirIndex array
 */
OSSTATUS
UDFDirIndexTrunc(
    IN PDIR_INDEX_HDR* _hDirNdx,
    IN uint_di d // decrement
    )
{
    uint_di j,k;

    if(d > UDF_DIR_INDEX_FRAME) {
        OSSTATUS status;
        while(d) {
            k = (d > UDF_DIR_INDEX_FRAME) ? UDF_DIR_INDEX_FRAME : d;
            if(!OS_SUCCESS(status = UDFDirIndexTrunc(_hDirNdx, k))) {
                return status;
            }
            d -= k;
        }
        return STATUS_SUCCESS;
    }

    PDIR_INDEX_HDR hDirNdx = *_hDirNdx;
    PDIR_INDEX_ITEM* FrameList;

    j = UDF_DIR_INDEX_FRAME+hDirNdx->LastFrameCount-d;
    FrameList = (PDIR_INDEX_ITEM*)(hDirNdx+1);
    k = hDirNdx->FrameCount-1;

    if(j <= UDF_DIR_INDEX_FRAME) {
        // free last frame
        if(!k && (j < 2)) {
            // someone tries to trunc. residual entries...
            return STATUS_INVALID_PARAMETER;
        }
        MyFreePool__(FrameList[k]);
        FrameList[k] = NULL;
        hDirNdx->LastFrameCount = UDF_DIR_INDEX_FRAME;
        hDirNdx->FrameCount--;
        // Truncate new last frame
        if(!MyReallocPool__((int8*)(FrameList[k-1]), UDF_DIR_INDEX_FRAME*sizeof(DIR_INDEX_ITEM),
                       (int8**)(&(FrameList[k-1])), AlignDirIndex(j)*sizeof(DIR_INDEX_ITEM) ) )
            return STATUS_INSUFFICIENT_RESOURCES;
        hDirNdx->LastFrameCount = j;
        // Truncate header
        if(!MyReallocPool__((int8*)hDirNdx, sizeof(DIR_INDEX_HDR) + (k+1)*sizeof(PDIR_INDEX_ITEM),
                       (int8**)(&hDirNdx), sizeof(DIR_INDEX_HDR) + k*sizeof(PDIR_INDEX_ITEM) ) )
            return STATUS_INSUFFICIENT_RESOURCES;

        (*_hDirNdx) = hDirNdx;

    } else {

        j -= UDF_DIR_INDEX_FRAME;
        if(!k && (j < 2)) {
            // someone tries to trunc. residual entries...
            return STATUS_INVALID_PARAMETER;
        }
        
        if(!MyReallocPool__((int8*)(FrameList[k]), AlignDirIndex(hDirNdx->LastFrameCount)*sizeof(DIR_INDEX_ITEM),
                       (int8**)(&(FrameList[k])), AlignDirIndex(j)*sizeof(DIR_INDEX_ITEM) ) )
            return STATUS_INSUFFICIENT_RESOURCES;
        hDirNdx->LastFrameCount = j;
    }
    return STATUS_SUCCESS;
} // end UDFDirIndexTrunc()