8546{
8548
8549#if (NTDDI_VERSION >= NTDDI_WINTHRESHOLD)
8550
8553
8555 PSTORAGE_HW_FIRMWARE_DOWNLOAD firmwareDownload = (PSTORAGE_HW_FIRMWARE_DOWNLOAD)
Irp->AssociatedIrp.SystemBuffer;
8565
8566
8567
8568
8569
8571
8573 goto Exit_Firmware_Download;
8574 }
8575
8576
8577
8578
8579 if ((firmwareDownload->Version < sizeof(STORAGE_HW_FIRMWARE_DOWNLOAD)) ||
8581 ((firmwareDownload->BufferSize +
FIELD_OFFSET(STORAGE_HW_FIRMWARE_DOWNLOAD, ImageBuffer)) > firmwareDownload->Size)) {
8582
8584 goto Exit_Firmware_Download;
8585 }
8586
8587
8588
8589
8592 goto Exit_Firmware_Download;
8593 }
8594
8595
8596
8597
8598
8599 if (commonExtension->
IsFdo && (fdoExtension->FunctionSupportInfo ==
NULL)) {
8600
8602 goto Exit_Firmware_Download;
8603 }
8604
8605
8606
8607
8608 if (!commonExtension->
IsFdo) {
8610 }
8611
8612 if ((firmwareDownload->Flags & STORAGE_HW_FIRMWARE_REQUEST_FLAG_CONTROLLER) != 0) {
8614 }
8615
8616 if (passDown) {
8617
8619
8624 }
8625
8626
8627
8628
8629 if (fdoExtension->FunctionSupportInfo->HwFirmwareInfo ==
NULL) {
8630 if (fdoExtension->FunctionSupportInfo->HwFirmwareGetInfoSupport ==
NotSupported) {
8632 goto Exit_Firmware_Download;
8633 } else {
8634
8635
8636
8637
8639
8641 goto Exit_Firmware_Download;
8642 }
8643 }
8644 }
8645
8646
8647
8648
8649 if (fdoExtension->FunctionSupportInfo->HwFirmwareInfo ==
NULL) {
8650 if (fdoExtension->FunctionSupportInfo->HwFirmwareGetInfoSupport ==
NotSupported) {
8652 } else {
8654 }
8655
8656 goto Exit_Firmware_Download;
8657 }
8658
8659
8660
8661
8662
8665
8666
8667
8668
8669 if ((fdoExtension->FunctionSupportInfo->HwFirmwareInfo->SupportUpgrade ==
FALSE) ||
8670 (fdoExtension->FunctionSupportInfo->HwFirmwareInfo->ImagePayloadAlignment == 0)) {
8672 goto Exit_Firmware_Download;
8673 }
8674
8675
8676
8677
8678 for (
i = 0;
i < fdoExtension->FunctionSupportInfo->HwFirmwareInfo->SlotCount;
i++) {
8679 if (fdoExtension->FunctionSupportInfo->HwFirmwareInfo->Slot[
i].SlotNumber == firmwareDownload->Slot) {
8680 break;
8681 }
8682 }
8683
8684 if ((
i >= fdoExtension->FunctionSupportInfo->HwFirmwareInfo->SlotCount) ||
8685 (fdoExtension->FunctionSupportInfo->HwFirmwareInfo->Slot[
i].ReadOnly ==
TRUE)) {
8686
8687
8688
8690 goto Exit_Firmware_Download;
8691 }
8692
8693
8694
8695
8696
8697 if ((firmwareDownload->BufferSize == 0) ||
8698 ((firmwareDownload->BufferSize % fdoExtension->FunctionSupportInfo->HwFirmwareInfo->ImagePayloadAlignment) != 0) ||
8699 (firmwareDownload->BufferSize > fdoExtension->FunctionSupportInfo->HwFirmwareInfo->ImagePayloadMaxSize) ||
8700 (firmwareDownload->BufferSize > fdoExtension->
AdapterDescriptor->MaximumTransferLength) ||
8701 ((firmwareDownload->Offset % fdoExtension->FunctionSupportInfo->HwFirmwareInfo->ImagePayloadAlignment) != 0) ||
8702 (firmwareDownload->Offset > 0xFFFFFF) ||
8703 (firmwareDownload->BufferSize > 0xFFFFFF)) {
8704
8706 goto Exit_Firmware_Download;
8707 }
8708
8709
8710
8711
8712
8713 if (((
ULONG_PTR)firmwareDownload->ImageBuffer % fdoExtension->FunctionSupportInfo->HwFirmwareInfo->ImagePayloadAlignment) != 0) {
8714
8715
8716
8717 bufferSize =
ALIGN_UP_BY(firmwareDownload->BufferSize, fdoExtension->FunctionSupportInfo->HwFirmwareInfo->ImagePayloadAlignment);
8718
8719
8720
8721
8722
8726
8727#ifdef _MSC_VER
8728#pragma prefast(suppress:6014, "The allocated memory that firmwareImageBuffer points to will be freed in ClassHwFirmwareDownloadComplete().")
8729#endif
8731
8732 if (firmwareImageBuffer ==
NULL) {
8734 goto Exit_Firmware_Download;
8735 }
8736
8738
8739 RtlCopyMemory(firmwareImageBuffer, firmwareDownload->ImageBuffer, (
ULONG)firmwareDownload->BufferSize);
8740
8741 } else {
8745
8746 firmwareImageBuffer = firmwareDownload->ImageBuffer;
8748 }
8749
8750
8751
8752
8753
8755
8758
8759 if (firmwareImageBuffer != firmwareDownload->ImageBuffer) {
8761 }
8762
8763 goto Exit_Firmware_Download;
8764 }
8765
8766
8767
8768
8770
8771 irp2->Tail.Overlay.Thread =
Irp->Tail.Overlay.Thread;
8773
8774
8775
8776
8777
8779 newStack->Parameters.Others.Argument1 =
Irp;
8781
8782
8783
8784
8785
8787 ClassHwFirmwareDownloadComplete,
8788 (firmwareImageBuffer != firmwareDownload->ImageBuffer) ? firmwareImageBuffer :
NULL,
8792
8798 newStack->Flags = irpStack->
Flags;
8799
8800
8801
8802
8803
8804
8805
8807
8808
8809
8810
8814 cdb->WRITE_BUFFER.Mode = SCSI_WRITE_BUFFER_MODE_DOWNLOAD_MICROCODE_WITH_OFFSETS_SAVE_DEFER_ACTIVATE;
8815 cdb->WRITE_BUFFER.ModeSpecific = 0;
8816 cdb->WRITE_BUFFER.BufferID = firmwareDownload->Slot;
8817
8818 cdb->WRITE_BUFFER.BufferOffset[0] = *((
PCHAR)&firmwareDownload->Offset + 2);
8819 cdb->WRITE_BUFFER.BufferOffset[1] = *((
PCHAR)&firmwareDownload->Offset + 1);
8820 cdb->WRITE_BUFFER.BufferOffset[2] = *((
PCHAR)&firmwareDownload->Offset);
8821
8825
8826
8827
8828
8831
8832
8833
8834
8836
8837
8838
8839
8840
8843 irp2,
8844 firmwareImageBuffer,
8847
8849
8850
8851
8852 if (firmwareImageBuffer != firmwareDownload->ImageBuffer) {
8854 }
8855
8856
8857
8858
8860
8862
8864
8865 goto Exit_Firmware_Download;
8866 }
8867
8869
8870Exit_Firmware_Download:
8871
8872
8873
8874
8875
8876 if (lockHeld) {
8879 }
8880
8881
8882
8883
8885
8887
8888#else
8891#endif
8892
8895
8897
8899}
#define ALIGN_UP_BY(size, align)
#define CLASSPNP_POOL_TAG_FIRMWARE
#define ClassAcquireRemoveLock(devobj, tag)
#define SRB_FLAGS_QUEUE_ACTION_ENABLE
#define SRB_HEAD_OF_QUEUE_TAG_REQUEST
#define SRB_FLAGS_NO_QUEUE_FREEZE
#define ExAllocatePoolWithTag(hernya, size, tag)
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
VOID NTAPI IoFreeIrp(IN PIRP Irp)
FORCEINLINE VOID SrbSetSrbFlags(_In_ PVOID Srb, _In_ ULONG Flags)
FORCEINLINE VOID SrbSetRequestAttribute(_In_ PVOID Srb, _In_ UCHAR RequestAttribute)
PSTORAGE_ADAPTER_DESCRIPTOR AdapterDescriptor
#define FIELD_OFFSET(t, f)
#define RtlCopyMemory(Destination, Source, Length)
#define STATUS_INSUFFICIENT_RESOURCES
FORCEINLINE VOID IoSetNextIrpStackLocation(_Inout_ PIRP Irp)