⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 init.c

📁 一个用wdm模型实现mode驱动的很好的程序
💻 C
📖 第 1 页 / 共 3 页
字号:
    // Read partition table
    //
    partitionList = NULL;

    ntStatus = IoReadPartitionTable(devExt->DeviceObject,
                                    ConfigData->Disk.BytesPerSector,
                                    TRUE,
                                    &partitionList);
    //
    // Check on the status of IoReadPartitionTable()
    //
    if (!NT_SUCCESS(ntStatus))  {

        //
        // IoReadPartitionTable() failed, but force success so we don't
        // unload since we still have partition 0 to support.
        //
        DbgPrint("InitializeDisk: Couldn't read the partition table - status %x\n",ntStatus);

        ntStatus = STATUS_SUCCESS;

    } else {

        //
        // IoReadPartitionTable() didn't return error, so initialize the
        // partition.
        //
        partitionPointer = &devExt->NextPartition;

        //
        // we're assuming a single partition
        //
        partitionNumber = 0;

        //
        // Create the device, with a UNICODE name such as
        // \\Device\Harddisk0\Partition1
        //
        sprintf(partitionNameBuffer,
            "\\Device\\Harddisk%d\\Partition%d",
            *(ConfigData->HardDiskCount),
            partitionNumber + 1);

        //
        // convert the Ansi string into UNICODE
        //
        RtlInitString (&partitionNameString, partitionNameBuffer);

        ntStatus = RtlAnsiStringToUnicodeString(&unicodeString,
                                        &partitionNameString,
                                        TRUE);

        //
        // if we can't get a UNICODE string, we've failed
        //
        if (!NT_SUCCESS(ntStatus)) {

            DbgPrint("InitializeDisk: Couldn't create the partition 1"
                    " partition objects\n");

            goto InitializeDiskExit;
        }

        //
        // Create the device for this partition
        //
        ntStatus = IoCreateDevice(DriverObject,
                                sizeof(PARTITION_DATA),
                                &unicodeString,
                                FILE_DEVICE_DISK,
                                0,
                                FALSE,
                                &partitionObject);

        //
        // Free the UNICODE string no matter the success of IoCreateDevice
        // (so that we don't forget to later on)
        //
        RtlFreeUnicodeString(&unicodeString);

        //
        // Now check the success of IoCreateDevice
        //
        if (!NT_SUCCESS(ntStatus)) {

            DbgPrint("InitializeDisk: Couldn't create the partition 1"
                    " partition devices\n");
            goto InitializeDiskExit;
        }


        //
        // Now initialize the partition object and data.
        //
        partitionObject->Flags |= DO_DIRECT_IO;

        partitionData = partitionObject->DeviceExtension;

        partitionData->PartitionOrdinal =
                partitionData->Pi.PartitionNumber = partitionNumber + 1;

        partitionData->Pi.PartitionType =
                partitionList->PartitionEntry[partitionNumber].PartitionType;

        partitionData->Pi.BootIndicator =
                partitionList->PartitionEntry[partitionNumber].BootIndicator;

        partitionData->Pi.StartingOffset =
                partitionList->PartitionEntry[partitionNumber].StartingOffset;

        partitionData->Pi.PartitionLength =
                partitionList->PartitionEntry[partitionNumber].PartitionLength;

        partitionData->Pi.HiddenSectors =
                partitionList->PartitionEntry[partitionNumber].HiddenSectors;

        partitionData->Partition0 = devExt;

        partitionData->NextPartition = NULL;

        *partitionPointer = partitionObject;
        partitionPointer = &partitionData->NextPartition;

    }   

InitializeDiskExit:

    //
    // We now check on the overall status as we may have reached here
    // through a "goto"
    //

    if (!NT_SUCCESS(ntStatus))  {

        //
        // Delete everything that this routine has allocated.
        //
        // First the chain of partition objects
        //

        if (devExt != NULL) 
        {

            nextPartition = devExt->NextPartition;

            while (nextPartition != NULL) 
            {

                partitionObject = nextPartition;
                partitionData =
                (PPARTITION_DATA)(partitionObject->DeviceExtension);
                nextPartition = partitionData->NextPartition;
                IoDeleteDevice(partitionObject);
            }
        }

        //
        // delete the disk device object
        //

        if (deviceObject != NULL) 
        {

            IoDeleteDevice(deviceObject);
        }

        //
        // delete the object directory.  Since it was temporary, all
        // we have to do is close this single reference
        //

        if (handle != NULL) 
        {

            ZwClose(handle);
        }

    }

    //
    // Delete the buffer allocated for the partition list.
    //

    if (partitionList != NULL) 
    {

        ExFreePool(partitionList);
    }

    //
    // and return our final status
    //

    return ntStatus;
}





///////////////////////////////////////////////////////////////////////////////
//
//	ReportUsage
//
//    This routine builds a resource list and calls IoReportResourceUsage()
//
//	INPUTS:
//
//    ConfigData        - pointer to the configuration data
//    DriverObject      - pointer to our driver object
//
//	OUTPUTS:
//	
//    None.
//
//	RETURNS:
//
//    TRUE if no conflict was reported, otherwise FALSE
//
//      IRQL:
//
//    IRQL_PASSIVE_LEVEL
//
//	NOTES:
//
///////////////////////////////////////////////////////////////////////////////


static BOOLEAN
ReportUsage(IN PDRIVER_OBJECT DriverObject,
            IN PCONFIG_DATA ConfigData)
{

    ULONG size;
    ULONG numDesc;
    PCM_RESOURCE_LIST resourceList;
    PCM_FULL_RESOURCE_DESCRIPTOR nextDesc;
    PCM_PARTIAL_RESOURCE_DESCRIPTOR partial;
    BOOLEAN conflictDetected;

    //
    // determine the size of the resource list
    //
    size = sizeof(CM_FULL_RESOURCE_DESCRIPTOR);

    //
    // The full resource descriptor already contains one
    // partial.  Make room for two more.
    //
    // It will hold the irq "prd", the controller "csr" "prd", and
    // the controller port "prd".
    //
    size += 2*sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
    numDesc = 1;

    //
    // Now we increment the length of the resource list by field offset
    // of the first frd.   This will give us the length of what preceeds
    // the first frd in the resource list.
    //
    size += FIELD_OFFSET(CM_RESOURCE_LIST, List[0]);

    resourceList = ExAllocatePool(PagedPool, size);

    if (!resourceList) {

        return FALSE;
    }

    //
    // Zero out the field
    //
    RtlZeroMemory(resourceList, size);

    //
    // set the count in the resource list
    //
    resourceList->Count = numDesc;

    //
    // get a pointer to the first descriptor off the list
    //
    nextDesc = &resourceList->List[0];

    //
    // set the interfae and bus information
    //
    nextDesc->InterfaceType = ConfigData->InterfaceType;
    nextDesc->BusNumber = ConfigData->BusNumber;

    //
    // We only report 3 items
    //
    nextDesc->PartialResourceList.Count = 3;
    partial = &nextDesc->PartialResourceList.PartialDescriptors[0];

    //
    // fill in the ControllerBase information
    //
    partial->Type = CmResourceTypePort;
    partial->ShareDisposition = CmResourceShareDriverExclusive;
    partial->Flags = CM_RESOURCE_PORT_IO;
    partial->u.Port.Start = ConfigData->OriginalControllerBaseAddress;
    partial->u.Port.Length = ConfigData->RangeOfControllerBase;

    partial++;

    //
    // fill in the ControlPort information
    //
    partial->Type = CmResourceTypePort;
    partial->ShareDisposition = CmResourceShareDriverExclusive;
    partial->Flags = CM_RESOURCE_PORT_IO;
    partial->u.Port.Start = ConfigData->OriginalControlPortAddress;
    partial->u.Port.Length = ConfigData->RangeOfControlPort;

    partial++;

    //
    // fill in the IRQL information
    //
    partial->Type = CmResourceTypeInterrupt;
    partial->u.Interrupt.Level = ConfigData->OriginalControllerIrql;
    partial->u.Interrupt.Vector = ConfigData->OriginalControllerVector;

    partial->ShareDisposition = CmResourceShareDriverExclusive;

    partial->Flags = CM_RESOURCE_INTERRUPT_LATCHED;

    //
    // report the information to the I/O Manager
    //
    IoReportResourceUsage(NULL,
                        DriverObject,
                        resourceList,
                        size,
                        NULL,
                        NULL,
                        0,
                        FALSE,
                        &conflictDetected);

    //
    // cleanup and return
    //
    ExFreePool(resourceList);

    //
    // Note that we return the inverse of the return status of
    // IoReportResourceUsage 
    //
    return !conflictDetected;

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -