VOID
VIOSerialPortPnpNotifyWork(
    IN WDFWORKITEM  WorkItem
    )
{
    PRAWPDO_VIOSERIAL_PORT  pdoData = RawPdoSerialPortGetData(WorkItem);
    PVIOSERIAL_PORT         pport = pdoData->port;
    PTARGET_DEVICE_CUSTOM_NOTIFICATION  notification;
    ULONG                               requiredSize;
    NTSTATUS                            status;
    VIRTIO_PORT_STATUS_CHANGE           portStatus = {0};

    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "--> %s\n", __FUNCTION__);
    portStatus.Version = 1;
    portStatus.Reason = pport->HostConnected;

    status = RtlULongAdd((sizeof(TARGET_DEVICE_CUSTOM_NOTIFICATION) - sizeof(UCHAR)),
                                 sizeof(VIRTIO_PORT_STATUS_CHANGE),
                                 &requiredSize);

    if (NT_SUCCESS(status))
    {
        notification = (PTARGET_DEVICE_CUSTOM_NOTIFICATION)
                       ExAllocatePoolWithTag(NonPagedPool,
                                 requiredSize,
                                 VIOSERIAL_DRIVER_MEMORY_TAG);

        if (notification != NULL)
        {
            RtlZeroMemory(notification, requiredSize);
            notification->Version = 1;
            notification->Size = (USHORT)(requiredSize);
            notification->FileObject = NULL;
            notification->NameBufferOffset = -1;
            notification->Event = GUID_VIOSERIAL_PORT_CHANGE_STATUS;
            RtlCopyMemory(notification->CustomDataBuffer, &portStatus, sizeof(VIRTIO_PORT_STATUS_CHANGE));
            if(WdfDeviceGetDevicePnpState(pport->Device) == WdfDevStatePnpStarted)
            {
               status = IoReportTargetDeviceChangeAsynchronous(
                                 WdfDeviceWdmGetPhysicalDevice(pport->Device),
                                 notification,
                                 NULL,
                                 NULL);
               if (!NT_SUCCESS(status))
               {
                    TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
                                 "IoReportTargetDeviceChangeAsynchronous Failed! status = 0x%x\n", status);
               }
            }
            ExFreePoolWithTag(notification, VIOSERIAL_DRIVER_MEMORY_TAG);
        }
    }
    WdfObjectDelete(WorkItem);
    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "<-- %s\n", __FUNCTION__);
}
STATIC
PAGEABLE
VOID
messagetable_CountingCallback(
	_In_		PCMESSAGE_TABLE_ENTRY	ptEntry,
	_In_opt_	PCMESSAGE_TABLE_ENTRY	ptPreviousEntry,
	_In_		PVOID					pvContext,
	_Out_		PBOOLEAN				pbContinueEnumeration
)
{
	NTSTATUS					eStatus		= STATUS_UNSUCCESSFUL;
	PCOUNTING_CALLBACK_CONTEXT	ptContext	= (PCOUNTING_CALLBACK_CONTEXT)pvContext;

	PAGED_CODE();

#ifndef DBG
	UNREFERENCED_PARAMETER(pbContinueEnumeration);
#endif // !DBG

	ASSERT(NULL != ptEntry);
	ASSERT(NULL != pvContext);
	ASSERT(NULL != pbContinueEnumeration);
	ASSERT(*pbContinueEnumeration);

	if ((NULL == ptPreviousEntry) ||
		(1 != ptEntry->nEntryId - ptPreviousEntry->nEntryId))
	{
		// This is either the first time we entered the callback,
		// or the current ID begins a new block.
		eStatus = RtlULongAdd(ptContext->nBlocks,
							  1,
							  &(ptContext->nBlocks));
		ASSERT(NT_SUCCESS(eStatus));
	}

	// Add the size for the current string.
	eStatus = RtlSIZETAdd(ptContext->cbTotalStrings,
						  messagetable_SizeofSerializedEntry(ptEntry),
						  &(ptContext->cbTotalStrings));
	ASSERT(NT_SUCCESS(eStatus));
}
示例#3
0
文件: client.c 项目: kcrazy/winekit
NTSTATUS
BthEchoCliRetrieveServerSdpRecord(
    __in PBTHECHOSAMPLE_CLIENT_CONTEXT DevCtx,
    __out PBTH_SDP_STREAM_RESPONSE * ServerSdpRecord    
    )
/*++

Description:

    Retrive server SDP record.
    We call this function on every file open to get the PSM

Arguments:

    DevCtx - Client context
    ServerSdpRecord - SDP record retrieved

Return Value:

    NTSTATUS Status code.

--*/
{
    NTSTATUS status, statusReuse, disconnectStatus;
    WDF_MEMORY_DESCRIPTOR inMemDesc;
    WDF_MEMORY_DESCRIPTOR outMemDesc;
    WDF_REQUEST_REUSE_PARAMS ReuseParams;    
    BTH_SDP_CONNECT connect = {0};
    BTH_SDP_DISCONNECT disconnect = {0};
    BTH_SDP_SERVICE_ATTRIBUTE_SEARCH_REQUEST requestSdp = {0};
    BTH_SDP_STREAM_RESPONSE responseSdp = {0};
    ULONG requestSize;
    PBTH_SDP_STREAM_RESPONSE serverSdpRecord = NULL;
    WDFREQUEST request;
    WDF_OBJECT_ATTRIBUTES attributes;
    

    PAGED_CODE();

    //
    // Allocate the request we will use for obtaining sdp record
    // NOTE that we do it for every file open, hence we
    //
    // can't use reserve request from the context
    //
    
    WDF_OBJECT_ATTRIBUTES_INIT(&attributes);

    status = WdfRequestCreate(
        &attributes,
        DevCtx->Header.IoTarget,
        &request
        );

    if (!NT_SUCCESS(status))
    {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, 
            "Failed to allocate request for retriving server sdp record, Status code %!STATUS!\n", status);

        goto exit;        
    }

    connect.bthAddress = DevCtx->ServerBthAddress;
    connect.requestTimeout = SDP_REQUEST_TO_DEFAULT;
    connect.fSdpConnect = 0;

    //
    // Connect to the SDP service.
    //

    WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(
        &inMemDesc,
        &connect,
        sizeof(connect)
        );
    
    WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(
        &outMemDesc,
        &connect,
        sizeof(connect)
        );

    status = WdfIoTargetSendIoctlSynchronously(
        DevCtx->Header.IoTarget,
        request,
        IOCTL_BTH_SDP_CONNECT,
        &inMemDesc,
        &outMemDesc,
        NULL,   //sendOptions
        NULL    //bytesReturned
        );

    if (!NT_SUCCESS(status))
    {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, 
            "IOCTL_BTH_SDP_CONNECT failed, Status code %!STATUS!\n", status);

        goto exit1;
    }

    //
    // Obtain the required size of the SDP record
    //
    requestSdp.hConnection = connect.hConnection;
    requestSdp.uuids[0].u.uuid128 = BTHECHOSAMPLE_SVC_GUID;
    requestSdp.uuids[0].uuidType = SDP_ST_UUID128;
    requestSdp.range[0].minAttribute = 0;
    requestSdp.range[0].maxAttribute = 0xFFFF;

    WDF_REQUEST_REUSE_PARAMS_INIT(&ReuseParams, WDF_REQUEST_REUSE_NO_FLAGS, STATUS_NOT_SUPPORTED);
    statusReuse = WdfRequestReuse(request, &ReuseParams);    
    ASSERT(NT_SUCCESS(statusReuse));
    UNREFERENCED_PARAMETER(statusReuse);

    WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(
        &inMemDesc,
        &requestSdp,
        sizeof(requestSdp)
        );
    
    WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(
        &outMemDesc,
        &responseSdp,
        sizeof(responseSdp)
        );

    status = WdfIoTargetSendIoctlSynchronously(
        DevCtx->Header.IoTarget,
        request,
        IOCTL_BTH_SDP_SERVICE_ATTRIBUTE_SEARCH,
        &inMemDesc,
        &outMemDesc,
        NULL,   //sendOptions
        NULL    //bytesReturned
        );

    if (!NT_SUCCESS(status))
    {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_SDP, 
            "IOCTL_BTH_SDP_SERVICE_ATTRIBUTE_SEARCH failed while querying response size, "
            "status code %!STATUS!\n", status);

        goto exit2;
    }

    //
    // Allocate the required size for SDP record
    //

    status = RtlULongAdd(
        responseSdp.requiredSize, 
        sizeof(BTH_SDP_STREAM_RESPONSE), 
        &requestSize
        );

    if(!NT_SUCCESS(status))
    {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_SDP, 
            "SDP record size too large, status code %!STATUS!\n", status);

        goto exit2;
    }

    serverSdpRecord = ExAllocatePoolWithTag(NonPagedPool, requestSize, POOLTAG_BTHECHOSAMPLE);
    if (NULL == serverSdpRecord)
    {
        status = STATUS_INSUFFICIENT_RESOURCES;
        TraceEvents(TRACE_LEVEL_ERROR, DBG_SDP, 
            "Allocating SDP record failed, returning status code %!STATUS!\n", status); 

        goto exit2;
    }

    //
    // Send request with required size
    //
    
    WDF_REQUEST_REUSE_PARAMS_INIT(&ReuseParams, WDF_REQUEST_REUSE_NO_FLAGS, STATUS_NOT_SUPPORTED);
    statusReuse = WdfRequestReuse(request, &ReuseParams);    
    ASSERT(NT_SUCCESS(statusReuse));
    UNREFERENCED_PARAMETER(statusReuse);

    WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(
        &inMemDesc,
        &requestSdp,
        sizeof(requestSdp)
        );
    
    WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(
        &outMemDesc,
        serverSdpRecord,
        requestSize
        );

    status = WdfIoTargetSendIoctlSynchronously(
        DevCtx->Header.IoTarget,
        request,
        IOCTL_BTH_SDP_SERVICE_ATTRIBUTE_SEARCH,
        &inMemDesc,
        &outMemDesc,
        NULL,   //sendOptions
        NULL    //bytesReturned
        );

    if (!NT_SUCCESS(status))
    {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_SDP, 
            "IOCTL_BTH_SDP_SERVICE_ATTRIBUTE_SEARCH failed, status code %!STATUS!\n", status);

        ExFreePoolWithTag(serverSdpRecord, POOLTAG_BTHECHOSAMPLE);
    }
    else
    {
        *ServerSdpRecord = serverSdpRecord;
    }
    
exit2:
    
    //
    // Disconnect from SDP service.
    //
    
    WDF_REQUEST_REUSE_PARAMS_INIT(&ReuseParams, WDF_REQUEST_REUSE_NO_FLAGS, STATUS_NOT_SUPPORTED);
    statusReuse = WdfRequestReuse(request, &ReuseParams);    
    ASSERT(NT_SUCCESS(statusReuse));
    UNREFERENCED_PARAMETER(statusReuse);

    disconnect.hConnection = connect.hConnection;

    WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(
        &inMemDesc,
        &disconnect,
        sizeof(disconnect)
        );
    
    disconnectStatus = WdfIoTargetSendIoctlSynchronously(
        DevCtx->Header.IoTarget,
        request,
        IOCTL_BTH_SDP_DISCONNECT,
        &inMemDesc,
        NULL,   //outMemDesc
        NULL,   //sendOptions
        NULL    //bytesReturned
        );

    ASSERT(NT_SUCCESS(disconnectStatus)); //Disconnect should not fail

    if (!NT_SUCCESS(disconnectStatus))
    {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, 
            "IOCTL_BTH_SDP_DISCONNECT failed, Status code %!STATUS!\n", status);
    }
    
exit1:    
    WdfObjectDelete(request);
exit:
    return status;
}
示例#4
0
文件: display.c 项目: Strongc/reactos
NTSTATUS
DsppLoadFontFile (
    _In_ PWCHAR FontFileName
    )
{
    PBL_DEVICE_DESCRIPTOR FontDevice;
    NTSTATUS Status;
    ULONG NameLength, DirectoryLength, TotalLength;
    PWCHAR FontPath, FontDirectory;
    BL_LIBRARY_PARAMETERS LibraryParameters;
    BOOLEAN CustomDirectory, CustomDevice;

    /* Initialize locals */
    CustomDirectory = TRUE;
    CustomDevice = TRUE;
    FontDevice = NULL;
    FontPath = NULL;
    FontDirectory = NULL;

    /* Check if a custom font path should be used */
    Status = BlGetBootOptionString(BlpApplicationEntry.BcdData,
                                   BcdLibraryString_FontPath,
                                   &FontDirectory);
    if (!NT_SUCCESS(Status))
    {
        /* Nope, use the one configured by the library */
        CustomDirectory = FALSE;
        RtlCopyMemory(&LibraryParameters,
                      &BlpLibraryParameters,
                      sizeof(LibraryParameters)),
        FontDirectory = LibraryParameters.FontBaseDirectory;
    }

    /* Do we still not have a font directory? */
    if (!FontDirectory)
    {
        /* Use the boot device and boot directory */
        FontDevice = BlpBootDevice;
        FontDirectory = L"\\EFI\\Microsoft\\Boot\\Fonts";
        CustomDevice = FALSE;
    }
    else
    {
        /* Otherwise, if we have a font directory, what device is the app on? */
        Status = BlGetBootOptionDevice(BlpApplicationEntry.BcdData,
                                       BcdLibraryDevice_ApplicationDevice,
                                       &FontDevice,
                                       NULL);
        if (!NT_SUCCESS(Status))
        {
            /* If we don't know the device, we can't open the path */
            goto Quickie;
        }
    }

    /* Figure out the length of the file name, and of the directory */
    NameLength = wcslen(FontFileName);
    DirectoryLength = wcslen(FontDirectory);

    /* Safely add them up*/
    Status = RtlULongAdd(NameLength, DirectoryLength, &TotalLength);
    if (!NT_SUCCESS(Status))
    {
        goto Quickie;
    }

    /* Convert to bytes */
    Status = RtlULongLongToULong(TotalLength * sizeof(WCHAR), &TotalLength);
    if (!NT_SUCCESS(Status))
    {
        goto Quickie;
    }

    /* Add a terminating NUL */
    Status = RtlULongAdd(TotalLength, sizeof(UNICODE_NULL), &TotalLength);
    if (!NT_SUCCESS(Status))
    {
        goto Quickie;
    }

    /* Allocate the final buffer for it */
    FontPath = BlMmAllocateHeap(TotalLength);
    if (!FontPath)
    {
        Status = STATUS_NO_MEMORY;
        goto Quickie;
    }

    /* Concatenate the directory with the file name */
    wcscpy(FontPath, FontDirectory);
    wcscat(FontPath, FontFileName);

    /* Try to load this font */
    Status = BfLoadFontFile(FontDevice, FontPath);

Quickie:
    /* Check if we had a custom font device allocated and free it */
    if ((CustomDevice) && (FontDevice))
    {
        BlMmFreeHeap(FontDevice);
    }

    /* Check if we had a custom font directory allocated and free it */
    if ((FontDirectory) && (CustomDirectory))
    {
        BlMmFreeHeap(FontDirectory);
    }

    /* Check if we had allocated a font path and free it */
    if (FontPath)
    {
        BlMmFreeHeap(FontPath);
    }

    /* Return back */
    return Status;
}
示例#5
0
文件: bcdopt.c 项目: Strongc/reactos
NTSTATUS
BlGetBootOptionString (
    _In_ PBL_BCD_OPTION List,
    _In_ ULONG Type,
    _Out_ PWCHAR* Value
    )
{
    NTSTATUS Status;
    PBL_BCD_OPTION Option;
    PWCHAR String, StringCopy;
    ULONG StringLength;
    BcdElementType ElementType;
    //PGUID AppIdentifier;

    /* Make sure this is a BCD_STRING */
    ElementType.PackedValue = Type;
    if (ElementType.Format != BCD_TYPE_STRING)
    {
        return STATUS_INVALID_PARAMETER;
    }

    /* Return the data */
    Option = MiscGetBootOption(List, Type);
    if (Option)
    {
        /* Extract the string */
        String = (PWCHAR)((ULONG_PTR)Option + Option->DataOffset);
        Status = STATUS_SUCCESS;
    }
    else
    {
        /* No string is present */
        String = NULL;
        Status = STATUS_NOT_FOUND;
    }

    /* Compute the data size */
    StringLength = Option->DataSize / sizeof(WCHAR);

#ifdef _SECURE_BOOT_
    /* Filter out SecureBoot Options */
    AppIdentifier = BlGetApplicationIdentifier();
    Status = BlpBootOptionCallbackString(AppIdentifier, Type, String, StringLength, &String, &StringLength);
#else
#endif

    /* Make sure we have a valid, non-filtered string */
    if (NT_SUCCESS(Status))
    {
        /* Check if we have space for one more character */
        Status = RtlULongAdd(StringLength, 1, &StringLength);
        if (NT_SUCCESS(Status))
        {
            /* Check if it's safe to multiply by two */
            Status = RtlULongMult(StringLength, sizeof(WCHAR), &StringLength);
            if (NT_SUCCESS(Status))
            {
                /* Allocate a copy for the string */
                StringCopy = BlMmAllocateHeap(StringLength);
                if (StringCopy)
                {
                    /* NULL-terminate it */
                    RtlCopyMemory(StringCopy,
                                  String,
                                  StringLength - sizeof(UNICODE_NULL));
                    StringCopy[StringLength] = UNICODE_NULL;
                    *Value = StringCopy;
                    Status = STATUS_SUCCESS;
                }
                else
                {
                    /* No memory, fail */
                    Status = STATUS_NO_MEMORY;
                }
            }
        }
    }

    /* All done */
    return Status;
}
示例#6
0
文件: enum.c 项目: kcrazy/winekit
PDRIVE_LAYOUT_INFORMATION
DiskConvertExtendedToLayout(
    IN CONST PDRIVE_LAYOUT_INFORMATION_EX LayoutEx
    )
{
    ULONG i;
    ULONG LayoutSize;
    PDRIVE_LAYOUT_INFORMATION Layout;
    PPARTITION_INFORMATION Partition;
    PPARTITION_INFORMATION_EX PartitionEx;
    NTSTATUS status;

    PAGED_CODE ();

    ASSERT ( LayoutEx );


    //
    // The only valid conversion is from an MBR extended layout structure to
    // the old structure.
    //

    if (LayoutEx->PartitionStyle != PARTITION_STYLE_MBR) {
        ASSERT ( FALSE );
        return NULL;
    }

    //
    // Use safe interger function
    //

    status = RtlULongMult(LayoutEx->PartitionCount,  sizeof(PARTITION_INFORMATION), &LayoutSize);
    if (!NT_SUCCESS(status))  {
        return NULL;
    }
    status = RtlULongAdd(LayoutSize, FIELD_OFFSET(DRIVE_LAYOUT_INFORMATION, PartitionEntry[0]),
                         &LayoutSize);
    if (!NT_SUCCESS(status))  {
        return NULL;
    }

    Layout = ExAllocatePoolWithTag (
                    NonPagedPool,
                    LayoutSize,
                    DISK_TAG_PART_LIST
                    );

    if ( Layout == NULL ) {
        return NULL;
    }

    Layout->Signature = LayoutEx->Mbr.Signature;
    Layout->PartitionCount = LayoutEx->PartitionCount;

    for (i = 0; i < LayoutEx->PartitionCount; i++) {

        Partition = &Layout->PartitionEntry[i];
        PartitionEx = &LayoutEx->PartitionEntry[i];

        Partition->StartingOffset = PartitionEx->StartingOffset;
        Partition->PartitionLength = PartitionEx->PartitionLength;
        Partition->RewritePartition = PartitionEx->RewritePartition;
        Partition->PartitionNumber = PartitionEx->PartitionNumber;

        Partition->PartitionType = PartitionEx->Mbr.PartitionType;
        Partition->BootIndicator = PartitionEx->Mbr.BootIndicator;
        Partition->RecognizedPartition = PartitionEx->Mbr.RecognizedPartition;
        Partition->HiddenSectors = PartitionEx->Mbr.HiddenSectors;
    }

    return Layout;
}
示例#7
0
文件: enum.c 项目: kcrazy/winekit
PDRIVE_LAYOUT_INFORMATION_EX
DiskConvertLayoutToExtended(
    IN CONST PDRIVE_LAYOUT_INFORMATION Layout
    )

/*++

Routine Description:

    Convert a DRIVE_LAYOUT_INFORMATION structure into a
    DRIVE_LAYOUT_INFORMATION_EX structure.

Arguments:

    Layout - The source DRIVE_LAYOUT_INFORMATION structure.

Return Values:

    The resultant DRIVE_LAYOUT_INFORMATION_EX structure. This buffer must
    be freed by the callee using ExFreePool.

--*/

{
    ULONG i;
    ULONG size;
    PDRIVE_LAYOUT_INFORMATION_EX layoutEx;
    NTSTATUS status;

    PAGED_CODE ();

    ASSERT ( Layout != NULL );


    //
    // Allocate enough space for a DRIVE_LAYOUT_INFORMATION_EX structure
    // plus as many PARTITION_INFORMATION_EX structures as are in the
    // source array.
    //

    //
    // Use safe interger function
    //

    status = RtlULongMult(Layout->PartitionCount, sizeof(PARTITION_INFORMATION_EX), &size);
    if (!NT_SUCCESS(status))  {
        return NULL;
    }
    status = RtlULongAdd(size, FIELD_OFFSET(DRIVE_LAYOUT_INFORMATION_EX, PartitionEntry[0]),
                         &size);
    if (!NT_SUCCESS(status))  {
        return NULL;
    }

    layoutEx = ExAllocatePoolWithTag(
                            NonPagedPool,
                            size,
                            DISK_TAG_PART_LIST
                            );

    if ( layoutEx == NULL ) {
        return NULL;
    }

    //
    // Convert the disk information.
    //

    layoutEx->PartitionStyle = PARTITION_STYLE_MBR;
    layoutEx->PartitionCount = Layout->PartitionCount;
    layoutEx->Mbr.Signature = Layout->Signature;

    for (i = 0; i < Layout->PartitionCount; i++) {

        //
        // Convert each entry.
        //

        DiskConvertPartitionToExtended (
                &Layout->PartitionEntry[i],
                &layoutEx->PartitionEntry[i]
                );
    }

    return layoutEx;
}
示例#8
0
文件: xferpkt.c 项目: kcrazy/winekit
PTRANSFER_PACKET NewTransferPacket(PDEVICE_OBJECT Fdo)
{
    PFUNCTIONAL_DEVICE_EXTENSION fdoExt = Fdo->DeviceExtension;
    PCLASS_PRIVATE_FDO_DATA fdoData = fdoExt->PrivateFdoData;
    PTRANSFER_PACKET newPkt = NULL;
    ULONG transferLength;
    NTSTATUS status = STATUS_SUCCESS;

    if (NT_SUCCESS(status)) {
        status = RtlULongAdd(fdoData->HwMaxXferLen, PAGE_SIZE, &transferLength);
        if (!NT_SUCCESS(status)) {

            TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_RW, "Integer overflow in calculating transfer packet size."));
            status = STATUS_INTEGER_OVERFLOW;
        }
    }

    /*
     *  Allocate the actual packet.
     */
    if (NT_SUCCESS(status)) {
        newPkt = ExAllocatePoolWithTag(NonPagedPool, sizeof(TRANSFER_PACKET), 'pnPC');
        if (newPkt == NULL) {
            TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_RW, "Failed to allocate transfer packet."));
            status = STATUS_INSUFFICIENT_RESOURCES;
        }
        else {
            RtlZeroMemory(newPkt, sizeof(TRANSFER_PACKET));
        }
    }

    /*
     *  Allocate Irp for the packet.
     */
    if (NT_SUCCESS(status)) {
        newPkt->Irp = IoAllocateIrp(Fdo->StackSize, FALSE);
        if (newPkt->Irp == NULL) {
            TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_RW, "Failed to allocate IRP for transfer packet."));
            status = STATUS_INSUFFICIENT_RESOURCES;
        }
    }

    /*
     * Allocate a MDL.  Add one page to the length to insure an extra page
     * entry is allocated if the buffer does not start on page boundaries.
     */
    if (NT_SUCCESS(status)) {
        newPkt->PartialMdl = IoAllocateMdl(NULL,
                                           transferLength,
                                           FALSE,
                                           FALSE,
                                           NULL);
        if (newPkt->PartialMdl == NULL) {
            TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_RW, "Failed to allocate MDL for transfer packet."));
            status = STATUS_INSUFFICIENT_RESOURCES;
        }
        else {
            ASSERT(newPkt->PartialMdl->Size >= (CSHORT)(sizeof(MDL) + BYTES_TO_PAGES(fdoData->HwMaxXferLen) * sizeof(PFN_NUMBER)));
        }

    }

    /*
     * Allocate per-packet retry history, if required
     */
    if (NT_SUCCESS(status) &&
        (fdoData->InterpretSenseInfo != NULL)
        ) {
        // attempt to allocate also the history
        ULONG historyByteCount = 0;

        // SAL annotation and ClassInitializeEx() should both catch this case
        ASSERT(fdoData->InterpretSenseInfo->HistoryCount != 0);
        __analysis_assume(fdoData->InterpretSenseInfo->HistoryCount != 0);

        historyByteCount = sizeof(SRB_HISTORY_ITEM) * fdoData->InterpretSenseInfo->HistoryCount;
        historyByteCount += sizeof(SRB_HISTORY) - sizeof(SRB_HISTORY_ITEM);

        newPkt->RetryHistory = (PSRB_HISTORY)ExAllocatePoolWithTag(NonPagedPool, historyByteCount, 'hrPC');

        if (newPkt->RetryHistory == NULL) {
            TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_RW, "Failed to allocate MDL for transfer packet."));
            status = STATUS_INSUFFICIENT_RESOURCES;
        }
        else {
            // call this routine directly once since it's the first initialization of
            // the structure and the internal maximum count field is not yet setup.
            HistoryInitializeRetryLogs(newPkt->RetryHistory, fdoData->InterpretSenseInfo->HistoryCount);
        }
    }

    /*
     *  Enqueue the packet in our static AllTransferPacketsList
     *  (just so we can find it during debugging if its stuck somewhere).
     */
    if (NT_SUCCESS(status))
    {
        KIRQL oldIrql;
        newPkt->Fdo = Fdo;
#if DBG
        newPkt->DbgPktId = InterlockedIncrement(&fdoData->DbgMaxPktId);
#endif
        KeAcquireSpinLock(&fdoData->SpinLock, &oldIrql);
        InsertTailList(&fdoData->AllTransferPacketsList, &newPkt->AllPktsListEntry);
        KeReleaseSpinLock(&fdoData->SpinLock, oldIrql);

    }
    else {
        // free any resources acquired above (in reverse order)
        if (newPkt != NULL)
        {
            FREE_POOL(newPkt->RetryHistory);
            if (newPkt->PartialMdl != NULL) { IoFreeMdl(newPkt->PartialMdl); }
            if (newPkt->Irp        != NULL) { IoFreeIrp(newPkt->Irp);        }
            FREE_POOL(newPkt);
        }
    }

    return newPkt;
}
示例#9
0
文件: bcd.c 项目: VonChenPlus/reactos
NTSTATUS
BiEnumerateElements (
    _In_ HANDLE BcdHandle,
    _In_ HANDLE ObjectHandle,
    _In_ ULONG RootElementType,
    _In_ ULONG Flags,
    _Out_opt_ PBCD_PACKED_ELEMENT Elements,
    _Inout_ PULONG ElementSize,
    _Out_ PULONG ElementCount
    )
{
    HANDLE ElementsHandle, ElementHandle;
    ULONG TotalLength, RegistryElementDataLength, RemainingLength;
    NTSTATUS Status;
    ULONG i;
    PVOID ElementData, SubObjectList, RegistryElementData;
    BcdElementType ElementType;
    PBCD_PACKED_ELEMENT PreviousElement, ElementsStart;
    ULONG SubElementCount, SubKeyCount, SubObjectCount, ElementDataLength;
    PWCHAR ElementName;
    PWCHAR* SubKeys;

    /* Assume failure */
    *ElementCount = 0;

    /* Initialize all locals that are checked at the end*/
    SubKeys = NULL;
    ElementsHandle = NULL;
    ElementHandle = NULL;
    ElementData = NULL;
    RegistryElementData = NULL;
    PreviousElement = NULL;
    ElementName = NULL;
    SubObjectList = NULL;
    TotalLength = 0;
    ElementDataLength = 0;
    SubObjectCount = 0;
    RemainingLength = 0;
    ElementsStart = Elements;

    /* Open the root object key's elements */
    Status = BiOpenKey(ObjectHandle, L"Elements", &ElementsHandle);
    if (!NT_SUCCESS(Status))
    {
        goto Quickie;
    }

    /* Enumerate all elements */
    Status = BiEnumerateSubKeys(ElementsHandle, &SubKeys, &SubKeyCount);
    if (!NT_SUCCESS(Status))
    {
        goto Quickie;
    }

    /* Iterate over each one */
    for (i = 0; i < SubKeyCount; i++)
    {
        /* Open the element */
        ElementName = SubKeys[i];
        Status = BiOpenKey(ElementsHandle, ElementName, &ElementHandle);
        if (!NT_SUCCESS(Status))
        {
            EfiPrintf(L"ELEMENT ERROR: %lx\r\n", Status);
            EfiStall(100000);
            break;
        }

        /* The name of the element is its data type */
        ElementType.PackedValue = wcstoul(SubKeys[i], NULL, 16);
        if (!(ElementType.PackedValue) || (ElementType.PackedValue == -1))
        {
            EfiPrintf(L"Value invalid\r\n");
            BiCloseKey(ElementHandle);
            ElementHandle = 0;
            continue;
        }

        /* Read the appropriate registry value type for this element */
        Status = BiGetRegistryValue(ElementHandle,
                                    L"Element",
                                    BiConvertElementFormatToValueType(
                                    ElementType.Format),
                                    &RegistryElementData,
                                    &RegistryElementDataLength);
        if (!NT_SUCCESS(Status))
        {
            EfiPrintf(L"Element invalid\r\n");
            break;
        }

        /* Now figure out how much space the converted element will need */
        ElementDataLength = 0;
        Status = BiConvertRegistryDataToElement(ObjectHandle,
                                                RegistryElementData,
                                                RegistryElementDataLength,
                                                ElementType,
                                                NULL,
                                                &ElementDataLength);
        if (Status != STATUS_BUFFER_TOO_SMALL)
        {
            break;
        }

        /* Allocate a buffer big enough for the converted element */
        ElementData = BlMmAllocateHeap(ElementDataLength);
        if (!ElementData)
        {
            Status = STATUS_INSUFFICIENT_RESOURCES;
            break;
        }

        /* And actually convert it this time around */
        Status = BiConvertRegistryDataToElement(ObjectHandle,
                                                RegistryElementData,
                                                RegistryElementDataLength,
                                                ElementType,
                                                ElementData,
                                                &ElementDataLength);
        if (!NT_SUCCESS(Status))
        {
            break;
        }

        /* Safely add space for the packed element header */
        Status = RtlULongAdd(TotalLength,
                             FIELD_OFFSET(BCD_PACKED_ELEMENT, Data),
                             &TotalLength);
        if (!NT_SUCCESS(Status))
        {
            break;
        }

        /* Safely add space for the data of the element itself */
        Status = RtlULongAdd(TotalLength, ElementDataLength, &TotalLength);
        if (!NT_SUCCESS(Status))
        {
            break;
        }

        /* One more element */
        ++*ElementCount;

        /* See how much space we were given */
        RemainingLength = *ElementSize;
        if (RemainingLength >= TotalLength)
        {
            /* Set the next pointer */
            Elements->NextEntry = (PBCD_PACKED_ELEMENT)((ULONG_PTR)ElementsStart + TotalLength);

            /* Fill this one out */
            Elements->RootType.PackedValue = RootElementType;
            Elements->Version = 1;
            Elements->Type = ElementType.PackedValue;
            Elements->Size = ElementDataLength;

            /* Add the data */
            RtlCopyMemory(Elements->Data, ElementData, ElementDataLength);
            RemainingLength -= TotalLength;

            /* Move to the next element on the next pass */
            PreviousElement = Elements;
            Elements = Elements->NextEntry;
        }
        else
        {
            /* We're out of space */
            RemainingLength = 0;
        }

        /* Are we enumerating devices, and is this a device? */
        if ((Flags & BCD_ENUMERATE_FLAG_DEVICES) &&
            (ElementType.Format == BCD_TYPE_DEVICE))
        {
            /* Yep, so go inside to enumerate it */
            Status = BiEnumerateSubElements(BcdHandle,
                                            ElementData,
                                            ElementType.PackedValue,
                                            Flags,
                                            &Elements,
                                            &ElementDataLength,
                                            &SubElementCount);
            if ((NT_SUCCESS(Status)) || (Status == STATUS_BUFFER_TOO_SMALL))
            {
                /* Safely add the length of the sub elements */
                Status = RtlULongAdd(TotalLength,
                                     ElementDataLength,
                                     &TotalLength);
                if (!NT_SUCCESS(Status))
                {
                    break;
                }

                /* Add the sub elements to the total */
                *ElementCount += SubElementCount;

                /* See if we have enough space*/
                if (*ElementSize >= TotalLength)
                {
                    /* Were there any subelements? */
                    if (SubElementCount)
                    {
                        /* Update to keep track of these new subelements */
                        ElementDataLength = *ElementSize - TotalLength;

                        /* Link the subelements into the chain */
                        PreviousElement = Elements;
                        PreviousElement->NextEntry =
                            (PBCD_PACKED_ELEMENT)((ULONG_PTR)ElementsStart +
                                                  TotalLength);
                        Elements = PreviousElement->NextEntry;
                    }
                }
                else
                {
                    /* We're out of space */
                    ElementDataLength = 0;
                }
            }
            else if ((Status != STATUS_NOT_FOUND) &&
                     (Status != STATUS_OBJECT_NAME_NOT_FOUND))
            {
                /* Fatal error trying to read the data, so fail */
                break;
            }
        }
        else if ((Flags & BCD_ENUMERATE_FLAG_DEEP) &&
                 (ElementType.PackedValue == BcdLibraryObjectList_InheritedObjects))
        {
            /* Inherited objects are requsted, so allocate a buffer for them */
            SubObjectList = BlMmAllocateHeap(ElementDataLength);
            if (!SubObjectList)
            {
                Status = STATUS_INSUFFICIENT_RESOURCES;
                break;
            }

            /* Copy the elements into the list. They are arrays of GUIDs */
            RtlCopyMemory(SubObjectList, ElementData, ElementDataLength);
            SubObjectCount = ElementDataLength / sizeof(GUID);
        }

        /* Free our local buffers */
        BlMmFreeHeap(ElementData);
        BlMmFreeHeap(RegistryElementData);
        ElementData = NULL;
        RegistryElementData = NULL;

        /* Close the key */
        BiCloseKey(ElementHandle);
        ElementHandle = NULL;
        ElementName = NULL;
    }

    /* Did we end up here with a sub object list after successful loop parsing? */
    if ((i != 0) && (i == SubKeyCount) && (SubObjectList))
    {
        /* We will actually enumerate it now, at the end */
        Status = BiEnumerateSubObjectElements(BcdHandle,
                                              SubObjectList,
                                              SubObjectCount,
                                              Flags,
                                              Elements,
                                              &RemainingLength,
                                              &SubElementCount);
        if ((NT_SUCCESS(Status)) || (Status == STATUS_BUFFER_TOO_SMALL))
        {
            /* Safely add the length of the sub elements */
            Status = RtlULongAdd(TotalLength, RemainingLength, &TotalLength);
            if ((NT_SUCCESS(Status)) && (SubElementCount))
            {
                /* Add the sub elements to the total */
                *ElementCount += SubElementCount;

                /* Don't touch PreviousElement anymore */
                PreviousElement = NULL;
            }
        }
    }

Quickie:
    /* Free the sub object list, if any */
    if (SubObjectList)
    {
        BlMmFreeHeap(SubObjectList);
    }

    /* Free any local element data */
    if (ElementData)
    {
        BlMmFreeHeap(ElementData);
    }

    /* Free any local registry data */
    if (RegistryElementData)
    {
        BlMmFreeHeap(RegistryElementData);
    }

    /* Close the handle if still opened */
    if (ElementHandle)
    {
        BiCloseKey(ElementHandle);
    }

    /* Terminate the last element, if any */
    if (PreviousElement)
    {
        PreviousElement->NextEntry = NULL;
    }

    /* Close the root handle if still opened */
    if (ElementsHandle)
    {
        BiCloseKey(ElementsHandle);
    }

    /* Set  failure code if out of space */
    if (*ElementSize < TotalLength)
    {
        Status = STATUS_BUFFER_TOO_SMALL;
    }

    /* Other errors will send a notification error */
    if (!(NT_SUCCESS(Status)) && (Status != STATUS_BUFFER_TOO_SMALL))
    {
        BiNotifyEnumerationError(ObjectHandle, ElementName, Status);
    }

    /* Finally free the subkeys array */
    if (SubKeys)
    {
        BlMmFreeHeap(SubKeys);
    }

    /* And return the required, final length and status */
    *ElementSize = TotalLength;
    return Status;
}
示例#10
0
文件: bcd.c 项目: VonChenPlus/reactos
NTSTATUS
BiEnumerateSubObjectElements (
    _In_ HANDLE BcdHandle,
    _Out_ PGUID SubObjectList,
    _In_ ULONG SubObjectCount,
    _In_ ULONG Flags,
    _Out_opt_ PBCD_PACKED_ELEMENT Elements,
    _Inout_ PULONG ElementSize,
    _Out_ PULONG ElementCount
    )
{
    NTSTATUS Status;
    ULONG SubElementCount, TotalSize, RequiredSize, CurrentSize, i;
    PBCD_PACKED_ELEMENT PreviousElement;
 
    /* Assume empty list */
    *ElementCount = 0;
    Status = STATUS_SUCCESS;

    /* Initialize variables */
    TotalSize = 0;
    PreviousElement = NULL;

    /* Set the currently remaining size based on caller's input */
    CurrentSize = *ElementSize;

    /* Iterate over every subje object */
    for (i = 0; i < SubObjectCount; i++)
    {
        /* Set the currently remaining buffer space */
        RequiredSize = CurrentSize;

        /* Enumerate the inherited sub elements */
        Status = BiEnumerateSubElements(BcdHandle,
                                        &SubObjectList[i],
                                        BcdLibraryObjectList_InheritedObjects,
                                        Flags,
                                        &Elements,
                                        &RequiredSize,
                                        &SubElementCount);
        if ((NT_SUCCESS(Status)) || (Status == STATUS_BUFFER_TOO_SMALL))
        {
            /* Safely add the length of the sub elements */
            Status = RtlULongAdd(TotalSize, RequiredSize, &TotalSize);
            if (!NT_SUCCESS(Status))
            {
                break;
            }

            /* Add the sub elements to the total */
            *ElementCount += SubElementCount;

            /* See if we have enough space*/
            if (*ElementSize >= TotalSize)
            {
                /* Were there any subelements? */
                if (SubElementCount)
                {
                    /* Update to keep track of these new subelements */
                    CurrentSize = *ElementSize - TotalSize;

                    /* Link the subelements into the chain */
                    PreviousElement = Elements;
                    PreviousElement->NextEntry =
                        (PBCD_PACKED_ELEMENT)((ULONG_PTR)Elements + TotalSize);
                    Elements = PreviousElement->NextEntry;
                }
            }
            else
            {
                /* We're out of space */
                CurrentSize = 0;
            }
        }
        else if ((Status != STATUS_NOT_FOUND) &&
                 (Status != STATUS_OBJECT_NAME_NOT_FOUND))
        {
            /* Some other fatal error, break out */
            break;
        }
        else
        {
            /* The sub element was not found, print a warning but keep going */
            BlStatusPrint(L"Ignoring missing BCD inherit object: {%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\n",
                          (&SubObjectList[i])->Data1,
                          (&SubObjectList[i])->Data2,
                          (&SubObjectList[i])->Data3,
                          (&SubObjectList[i])->Data4[0],
                          (&SubObjectList[i])->Data4[1],
                          (&SubObjectList[i])->Data4[2],
                          (&SubObjectList[i])->Data4[3],
                          (&SubObjectList[i])->Data4[4],
                          (&SubObjectList[i])->Data4[5],
                          (&SubObjectList[i])->Data4[6],
                          (&SubObjectList[i])->Data4[7],
                          (&SubObjectList[i])->Data4[8]);
            Status = STATUS_SUCCESS;
        }
    }

    /* Terminate the last element, if one was left */
    if (PreviousElement)
    {
        PreviousElement->NextEntry = NULL;
    }

    /* Set failure code if we ran out of space */
    if (*ElementSize < TotalSize)
    {
        Status = STATUS_BUFFER_TOO_SMALL;
    }

    /* Return final length and status */
    *ElementSize = TotalSize;
    return Status;
}
示例#11
0
文件: bcd.c 项目: VonChenPlus/reactos
NTSTATUS
BiConvertBcdElements (
    _In_ PBCD_PACKED_ELEMENT Elements,
    _Out_opt_ PBCD_ELEMENT Buffer,
    _Inout_ PULONG BufferSize, 
    _Inout_ PULONG ElementCount
    )
{
    NTSTATUS Status;
    ULONG ElementSize, AlignedElementSize, AlignedDataSize;
    PBCD_ELEMENT_HEADER Header;
    PVOID Data;
    BOOLEAN Exists;
    ULONG i, j, Count;

    /* Local variable to keep track of objects */
    Count = 0;

    /* Safely compute the element bytes needed */
    Status = RtlULongMult(*ElementCount, sizeof(BCD_ELEMENT), &ElementSize);
    if (!NT_SUCCESS(Status))
    {
        return Status;
    }

    /* Safely align the element size */
    Status = RtlULongAdd(ElementSize,
                         sizeof(ULONG) - 1,
                         &AlignedElementSize);
    if (!NT_SUCCESS(Status))
    {
        return Status;
    }
    AlignedElementSize = ALIGN_DOWN(AlignedElementSize, ULONG);

    /* Do a safe version of Add2Ptr to figure out where the headers will start */
    Status = RtlULongPtrAdd((ULONG_PTR)Buffer,
                            AlignedElementSize,
                            (PULONG_PTR)&Header);
    if (!NT_SUCCESS(Status))
    {
        return Status;
    }

    /* Safely compute the header bytes needed */
    Status = RtlULongMult(*ElementCount,
                          sizeof(BCD_ELEMENT_HEADER),
                          &ElementSize);
    if (!NT_SUCCESS(Status))
    {
        return Status;
    }

    /* Safely align the header size */
    Status = RtlULongAdd(ElementSize,
                         AlignedElementSize + sizeof(ULONG) - 1,
                         &AlignedElementSize);
    if (!NT_SUCCESS(Status))
    {
        return Status;
    }
    AlignedElementSize = ALIGN_DOWN(AlignedElementSize, ULONG);

    /* Do a safe version of Add2Ptr */
    Status = RtlULongPtrAdd((ULONG_PTR)Buffer,
                            AlignedElementSize,
                            (PULONG_PTR)&Data);
    if (!NT_SUCCESS(Status))
    {
        return Status;
    }

    /* Iterate over every element */
    for (i = 0; i < *ElementCount; i++)
    {
        /* Safely align the element size */
        Status = RtlULongAdd(Elements->Size,
                             sizeof(ULONG) - 1,
                             &AlignedDataSize);
        if (!NT_SUCCESS(Status))
        {
            break;
        }
        AlignedDataSize = ALIGN_DOWN(AlignedDataSize, ULONG);

        /* Safely add the size of this data element */
        Status = RtlULongAdd(AlignedElementSize,
                             AlignedDataSize,
                             &AlignedElementSize);
        if (!NT_SUCCESS(Status))
        {
            break;
        }

        /* Do we have enough space left? */
        if (*BufferSize >= AlignedElementSize)
        {
            /* Check if our root is an inherited object */
            Exists = FALSE;
            if (Elements->RootType.PackedValue == BcdLibraryObjectList_InheritedObjects)
            {
                /* Yes, scan for us in the current buffer */
                for (j = 0; j < Count; j++)
                {
                    /* Do we already exist? */
                    while (Buffer[j].Header->Type == Elements->RootType.PackedValue)
                    {
                        /* Yep */
                        Exists = TRUE;
                        break;
                    }
                }
            }

            /* Have we already found ourselves? */
            if (!Exists)
            {
                /* Nope, one more entry */
                ++Count;

                /* Write out the unpacked object */
                Buffer->Body = Data;
                Buffer->Header = Header;

                /* Fill out its header */
                Header->Size = Elements->Size;
                Header->Type = Elements->Type;
                Header->Version = Elements->Version;

                /* And copy the data */
                RtlCopyMemory(Data, Elements->Data, Header->Size);

                /* Move to the next unpacked object and header */
                ++Buffer;
                ++Header;

                /* Move to the next data entry */
                Data = (PVOID)((ULONG_PTR)Data + AlignedDataSize);
            }
        }
        else
        {
            /* Nope, set failure code, but keep going so we can return count */
            Status = STATUS_BUFFER_TOO_SMALL;
        }

        /* Move to the next element entry */
        Elements = Elements->NextEntry;
    }

    /* Return the new final buffer size and count */
    *BufferSize = AlignedElementSize;
    *ElementCount = Count;
    return Status;
}
示例#12
0
文件: nic_pm.c 项目: uri247/wdk80
NTSTATUS
NICAddWakeUpPattern(
    IN PFDO_DATA  FdoData,
    IN PVOID        InformationBuffer,
    IN UINT         InformationBufferLength,
    OUT PULONG      BytesRead,
    OUT PULONG      BytesNeeded
    )
/*++
Routine Description:

    This routine will allocate a local memory structure, copy the pattern,
    insert the pattern into a linked list and return success

    We are gauranteed that we wll get only one request at a time, so this is implemented
    without locks.

Arguments:

    FdoData                 FdoData structure
    InformationBuffer       Wake up Pattern
    InformationBufferLength Wake Up Pattern Length

Return Value:

    STATUS_Success - if successful.
    STATUS_UNSUCCESSFUL - if memory allocation fails.

--*/
{

    NTSTATUS             status = STATUS_UNSUCCESSFUL;
    PMP_WAKE_PATTERN        pWakeUpPattern = NULL;
    ULONG                   AllocationLength = 0;
    PNDIS_PM_PACKET_PATTERN pPmPattern = NULL;
    ULONG                   Signature = 0;
    ULONG                   CopyLength = 0;
    ULONG                   safeAddResult;

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_POWER, "--> NICAddWakeUpPattern\n");

    do
    {

        if(!FdoData->AllowWakeArming) {
            status =  STATUS_NOT_SUPPORTED;
            break;
        }

        pPmPattern = (PNDIS_PM_PACKET_PATTERN) InformationBuffer;

        if (InformationBufferLength < sizeof(NDIS_PM_PACKET_PATTERN))
        {
            status = STATUS_BUFFER_TOO_SMALL;

            *BytesNeeded = sizeof(NDIS_PM_PACKET_PATTERN);
            break;
        }

        //
        // safeAddResult = pPmPattern->PatternOffset + pPmPattern->PatternSize
        //
        status = RtlULongAdd(
            pPmPattern->PatternOffset,
            pPmPattern->PatternSize,
            &safeAddResult) ;
        if (!NT_SUCCESS(status))
        {
            break;
        }
        if (InformationBufferLength < safeAddResult)
        {
            status = STATUS_BUFFER_TOO_SMALL;

            *BytesNeeded = safeAddResult;
            break;
        }

        *BytesRead = safeAddResult;


        //
        // Calculate the e100 signature
        //
        status = MPCalculateE100PatternForFilter (
            (PUCHAR)pPmPattern+ pPmPattern->PatternOffset,
            pPmPattern->PatternSize,
            (PUCHAR)pPmPattern +sizeof(NDIS_PM_PACKET_PATTERN),
            pPmPattern->MaskSize,
            &Signature );

        if ( status != STATUS_SUCCESS)
        {
            break;
        }

        CopyLength = safeAddResult;

        //
        // Allocate the memory to hold the WakeUp Pattern
        //
        // AllocationLength = sizeof (MP_WAKE_PATTERN) + CopyLength;
        //
        status = RtlULongAdd(
            sizeof(MP_WAKE_PATTERN),
            CopyLength,
            &AllocationLength);
        if (!NT_SUCCESS(status))
        {
            break;
        }

        pWakeUpPattern = ExAllocatePoolWithTag(NonPagedPool, AllocationLength, PCIDRV_POOL_TAG);

        if (!pWakeUpPattern)
        {
            break;
        }

        //
        // Initialize pWakeUpPattern
        //
        RtlZeroMemory (pWakeUpPattern, AllocationLength);

        pWakeUpPattern->AllocationSize = AllocationLength;

        pWakeUpPattern->Signature = Signature;

        //
        // Copy the pattern into local memory
        //
        RtlMoveMemory (&pWakeUpPattern->Pattern[0], InformationBuffer, CopyLength);

        ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);

        //
        // Insert the pattern into the list
        //
       /* ExInterlockedInsertHeadList (&FdoData->PoMgmt.PatternList,
                                        &pWakeUpPattern->linkListEntry,
                                        &FdoData->Lock);
                                        */

        WdfSpinLockAcquire(FdoData->Lock);
        InsertHeadList(&FdoData->PoMgmt.PatternList,&pWakeUpPattern->linkListEntry );
        WdfSpinLockRelease(FdoData->Lock);


        status = STATUS_SUCCESS;

    } WHILE (FALSE);

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_POWER, "<-- NICAddWakeUpPattern\n");

    return status;
}