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

📄 init.c

📁 NXP产品LPC23XX的开发板的源文件
💻 C
📖 第 1 页 / 共 4 页
字号:
	}

	DbgPrint("***** DRV=%08x PDO=%08x FDO=%08x (%wZ) ***** \n", 
		DriverObject, PhysicalDeviceObject, *DeviceObject, &deviceObjName );
		
	// END CODEMACHINE 
	
	deviceExtension = (PDEVICE_EXTENSION) ((*DeviceObject)->DeviceExtension);
 
	RtlZeroMemory(&deviceExtension->DeviceName, sizeof(UNICODE_STRING));
	RtlZeroMemory(&deviceExtension->SymbolicLinkName, sizeof(UNICODE_STRING));

	//
	// Allocate Pool and save the nt device name in the device extension.
	//
	deviceExtension->DeviceName.Buffer =
		ExAllocatePool(PagedPool, deviceObjName.Length + sizeof(WCHAR));

	if (!deviceExtension->DeviceName.Buffer) {
		DbgPrint("Couldn't allocate memory for DeviceName\n");
		ntStatus = STATUS_INSUFFICIENT_RESOURCES;
		goto ErrorFreeBuffer;
	}

	deviceExtension->DeviceName.MaximumLength = deviceObjName.Length
		+ sizeof(WCHAR);

	//
	// Zero fill it.
	//
	RtlZeroMemory(deviceExtension->DeviceName.Buffer,
                 deviceExtension->DeviceName.MaximumLength);

	RtlAppendUnicodeStringToString(&deviceExtension->DeviceName, &deviceObjName);

    //default maximum transfer size per staged io request
    deviceExtension->MaximumTransferSize =  UsbCom_MAX_TRANSFER_SIZE ;
	
	// this event is triggered when there is no pending io of any kind and device is removed
    KeInitializeEvent(&deviceExtension->RemoveEvent, NotificationEvent, FALSE);

    // this event is triggered when self-requested power irps complete
    KeInitializeEvent(&deviceExtension->SelfRequestedPowerIrpEvent, NotificationEvent, FALSE);

	// this event is triggered when there is no pending io  (pending io count == 1 )
    KeInitializeEvent(&deviceExtension->NoPendingIoEvent, NotificationEvent, FALSE);

	// spinlock used to protect inc/dec iocount logic
	KeInitializeSpinLock (&deviceExtension->IoCountSpinLock);

	KeInitializeEvent(&deviceExtension->PendingIRPEvent, SynchronizationEvent, FALSE);
	KeInitializeEvent(&deviceExtension->PendingDpcEvent, SynchronizationEvent, FALSE);

	deviceExtension->DeviceIsOpened = FALSE;

	InitializeListHead(&deviceExtension->ReadQueue);
	InitializeListHead(&deviceExtension->WriteQueue);
	InitializeListHead(&deviceExtension->MaskQueue);
	InitializeListHead(&deviceExtension->PurgeQueue);
	InitializeListHead(&deviceExtension->StalledIrpQueue);

	//
	// Initialize the timers used to timeout operations.
	//

	KeInitializeTimer(&deviceExtension->ReadRequestTotalTimer);
	KeInitializeTimer(&deviceExtension->ReadRequestIntervalTimer);
	KeInitializeTimer(&deviceExtension->WriteRequestTotalTimer);
	KeInitializeTimer(&deviceExtension->ImmediateTotalTimer);
	KeInitializeTimer(&deviceExtension->XoffCountTimer);
	KeInitializeTimer(&deviceExtension->LowerRTSTimer);

   //
   // Intialialize the dpcs that will be used to complete
   // or timeout various IO operations.
   //
   KeInitializeDpc(&deviceExtension->CompleteWriteDpc, SerialCompleteWrite, deviceExtension);
   KeInitializeDpc(&deviceExtension->CompleteReadDpc, SerialCompleteRead, deviceExtension);
   KeInitializeDpc(&deviceExtension->TotalReadTimeoutDpc, SerialReadTimeout, deviceExtension);
   KeInitializeDpc(&deviceExtension->IntervalReadTimeoutDpc, SerialIntervalReadTimeout,
                   deviceExtension);
   KeInitializeDpc(&deviceExtension->TotalWriteTimeoutDpc, SerialWriteTimeout, deviceExtension);
//   KeInitializeDpc(&deviceExtension->CommErrorDpc, SerialCommError, deviceExtension);
//   KeInitializeDpc(&deviceExtension->CompleteImmediateDpc, SerialCompleteImmediate,
//                   deviceExtension);
//   KeInitializeDpc(&deviceExtension->TotalImmediateTimeoutDpc, SerialTimeoutImmediate,
//                   deviceExtension);
   KeInitializeDpc(&deviceExtension->CommWaitDpc, SerialCompleteWait, deviceExtension);
   KeInitializeDpc(&deviceExtension->XoffCountTimeoutDpc, SerialTimeoutXoff, deviceExtension);
   KeInitializeDpc(&deviceExtension->XoffCountCompleteDpc, SerialCompleteXoff, deviceExtension);
   KeInitializeDpc(&deviceExtension->StartTimerLowerRTSDpc, SerialStartTimerLowerRTS,
                   deviceExtension);
   KeInitializeDpc(&deviceExtension->PerhapsLowerRTSDpc, SerialInvokePerhapsLowerRTS,
                   deviceExtension);
//   KeInitializeDpc(&deviceExtension->IsrUnlockPagesDpc, SerialUnlockPages, deviceExtension);

	//
	// Initialize the count of IRP's pending
	//

	deviceExtension->PendingIRPCnt = 1;

   //
   // Initialize the count of DPC's pending
   //

   deviceExtension->DpcCount = 1;

   //
   // Initialize the spinlock associated with fields read (& set)
   // by IO Control functions and the flags spinlock.
   //

   KeInitializeSpinLock(&deviceExtension->ControlLock);
   KeInitializeSpinLock(&deviceExtension->FlagsLock);
   KeInitializeSpinLock(&deviceExtension->IntBufferLock);


	// The workitem is never used.
	deviceExtension->WorkItem = IoAllocateWorkItem(*DeviceObject);
  
	if (deviceExtension->WorkItem == NULL) {
		DbgPrint("Insufficient memory for WorkItem Routine.\n");
		ntStatus = STATUS_INSUFFICIENT_RESOURCES;
		goto ErrorFreeBuffer;
	}

	KeInitializeMutex(&deviceExtension->CompleteRequestMutex,  0);
	
	// Create SymbolicLink name -- ComX.
	deviceExtension->CreatedSymbolicLink = FALSE;

	deviceExtension->CreatedSerialCommEntry = FALSE;

	linkName.MaximumLength = SYMBOLIC_NAME_LENGTH*sizeof(WCHAR);
	linkName.Buffer = ExAllocatePool(PagedPool, linkName.MaximumLength
                                    + sizeof(WCHAR));

	if (linkName.Buffer == NULL) {
		DbgPrint("Couldn't allocate memory for linkName\n");
		ntStatus = STATUS_INSUFFICIENT_RESOURCES;
		goto ErrorFreeBuffer;
	}

	RtlZeroMemory(linkName.Buffer, linkName.MaximumLength + sizeof(WCHAR));
	//
	// Create the "\\DosDevices\\<symbolicName>" string
	//
	RtlAppendUnicodeToString(&linkName, L"\\DosDevices\\");
	RtlAppendUnicodeToString(&linkName, pRegName);

	//
	// Allocate Pool and save the symbolic link name in the device extension.
	//
	deviceExtension->SymbolicLinkName.MaximumLength = linkName.Length + sizeof(WCHAR);
	deviceExtension->SymbolicLinkName.Buffer
		= ExAllocatePool(PagedPool, deviceExtension->SymbolicLinkName.MaximumLength);

	if (!deviceExtension->SymbolicLinkName.Buffer) {

		DbgPrint("Couldn't allocate memory for symbolic link name\n");
		ntStatus = STATUS_INSUFFICIENT_RESOURCES;
		goto ErrorFreeBuffer;
	}

	//
	// Zero fill it.
	//
	RtlZeroMemory(deviceExtension->SymbolicLinkName.Buffer,
                 deviceExtension->SymbolicLinkName.MaximumLength);

	RtlAppendUnicodeStringToString(&deviceExtension->SymbolicLinkName,
                                  &linkName);

	ntStatus = IoCreateSymbolicLink (&deviceExtension->SymbolicLinkName,
                                  &deviceExtension->DeviceName);
	if (!NT_SUCCESS(ntStatus)) {

		//
		// Oh well, couldn't create the symbolic link.  No point
		// in trying to create the device map entry.
		//
        DbgPrint("IoCreateSymbolicLink() (%wZ -> %wZ) FAIL=%08x\n", 
			&deviceExtension->SymbolicLinkName,
			&deviceExtension->DeviceName,
			ntStatus );
		goto ErrorFreeBuffer;
	}

	deviceExtension->CreatedSymbolicLink = TRUE;

	// Write comm port name to registry, USBSwt.exe will use this value
	ntStatus = RtlWriteRegistryValue(RTL_REGISTRY_DEVICEMAP, L"SERIALCOMM",
                                   deviceObjName.Buffer, REG_SZ,
                                   pRegName,
                                   regLength);

	if (!NT_SUCCESS(ntStatus)) {

		DbgPrint("Couldn't create the device map entry\n");
		goto ErrorFreeBuffer;
	}

	deviceExtension->CreatedSerialCommEntry = TRUE;
	
	// option: client can use GUID interface open our fake comm port.
    ntStatus = UsbCom_SymbolicLink( PhysicalDeviceObject, &deviceLinkUnicodeString);

    if (!NT_SUCCESS(ntStatus)) {
		DbgPrint("Couldn't register symbolic link interface!\n");
		goto ErrorFreeBuffer;
	}

    // Name buffer for our named Functional device object link
    // The name is generated based on the driver's class GUID
    RtlCopyMemory(deviceExtension->DeviceLinkNameBuffer,
                      deviceLinkUnicodeString.Buffer,
                      deviceLinkUnicodeString.Length);

	RtlInitUnicodeString ( &deviceExtension->DeviceNameLink, deviceExtension->DeviceLinkNameBuffer );

	DbgPrint ( "DO=%08x SYMBOLIC LINK = %wZ\n", (*DeviceObject), &deviceExtension->DeviceNameLink );

	// don't confuse with this lable, only ntStatus != STATUS_SUCCESS
	// means error.
ErrorFreeBuffer: 

	if (!NT_SUCCESS(ntStatus) && (*DeviceObject != NULL)) {

		//
		// Create Device Object failed, Clean up error conditions
		//
		DbgPrint("AddDevice Error: Clean up error conditions\n");

		if (deviceExtension->WorkItem != NULL) {
			IoFreeWorkItem(deviceExtension->WorkItem);
		}
		DbgPrint("AddDevice Error: Clean up error conditions\n");

		if (deviceExtension->CreatedSymbolicLink ==  TRUE) {
			IoDeleteSymbolicLink(&deviceExtension->SymbolicLinkName);
			deviceExtension->CreatedSymbolicLink = FALSE;
		}

		if (deviceExtension->SymbolicLinkName.Buffer != NULL) {
			 ExFreePool(deviceExtension->SymbolicLinkName.Buffer);
			 deviceExtension->SymbolicLinkName.Buffer = NULL;
		}

		if (deviceExtension->DeviceName.Buffer != NULL) {
			 RtlDeleteRegistryValue(RTL_REGISTRY_DEVICEMAP, SERIAL_DEVICE_MAP,
									deviceExtension->DeviceName.Buffer);
		}

		if (deviceExtension->DeviceName.Buffer != NULL) {
			ExFreePool(deviceExtension->DeviceName.Buffer);
		}



		if (*DeviceObject) {
			IoDeleteDevice(*DeviceObject);
		}
	}

	//
	// Always clean up our temp buffers.
	//
	if (linkName.Buffer != NULL) {
		ExFreePool(linkName.Buffer);
	}

	if (pRegName != NULL) {
		ExFreePool(pRegName);
	}
	
	if (deviceObjName.Buffer != NULL) {
		ExFreePool(deviceObjName.Buffer);
	}

	//free buffer from unicode string we used to init interface
	if (deviceLinkUnicodeString.Buffer != NULL){
		IoSetDeviceInterfaceState (&deviceLinkUnicodeString, FALSE);
		ExFreePool( deviceLinkUnicodeString.Buffer );
	}

    return ntStatus;
}


NTSTATUS
UsbCom_CallUSBD(
    IN PDEVICE_OBJECT DeviceObject,
    IN PURB Urb
    )
/*++

Routine Description:

    Passes a URB to the USBD class driver
	The client device driver passes USB request block (URB) structures 
	to the class driver as a parameter in an IRP with Irp->MajorFunction
	set to IRP_MJ_INTERNAL_DEVICE_CONTROL and the next IRP stack location 
	Parameters.DeviceIoControl.IoControlCode field set to 
	IOCTL_INTERNAL_USB_SUBMIT_URB. 

Arguments:

    DeviceObject - pointer to the physical device object (PDO)

    Urb - pointer to an already-formatted Urb request block

Return Value:

    STATUS_SUCCESS if successful,
    STATUS_UNSUCCESSFUL otherwise

--*/
{
    NTSTATUS ntStatus, status = STATUS_SUCCESS;
    PDEVICE_EXTENSION deviceExtension;
    PIRP irp;
    KEVENT event;
    IO_STATUS_BLOCK ioStatus;
    PIO_STACK_LOCATION nextStack;


    deviceExtension = DeviceObject->DeviceExtension;

    KeInitializeEvent(&event, NotificationEvent, FALSE);

    irp = IoBuildDeviceIoControlRequest(
                IOCTL_INTERNAL_USB_SUBMIT_URB,
                deviceExtension->TopOfStackDeviceObject, //Points to the next-lower driver's device object
                NULL, // optional input bufer; none needed here
                0,	  // input buffer len if used
                NULL, // optional output bufer; none needed here
                0,    // output buffer len if used
                TRUE, // If InternalDeviceControl is TRUE the target driver's Dispatch
				      //  outine for IRP_MJ_INTERNAL_DEVICE_CONTROL or IRP_MJ_SCSI 
					  // is called; otherwise, the Dispatch routine for 
					  // IRP_MJ_DEVICE_CONTROL is called.
                &event,     // event to be signalled on completion
                &ioStatus);  // Specifies an I/O status block to be set when the request is completed the lower driver. 


    //
    // As an alternative, we could call KeDelayExecutionThread, wait for some
    // period of time, and try again....but we keep it simple for right now
    //
    if (!irp) {
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    //
    // Call the class driver to perform the operation.  If the returned status
    // is PENDING, wait for the request to complete.
    //

    nextStack = IoGetNextIrpStackLocation(irp);

    //
    // pass the URB to the USB driver stack
    //
    nextStack->Parameters.Others.Argument1 = Urb;

    DbgPrint("UsbCom_CallUSBD() (%u) DO=%08x Urb=%08x Irp=%08x\n", UsbCom_CallUSBD_Counter++,
		DeviceObject, Urb, irp );
		
    ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, irp);

    //DbgPrint("UsbCom_CallUSBD() return from IoCallDriver USBD %x\n", ntStatus);

    if (ntStatus == STATUS_PENDING) {
        KeWaitForSingleObject(
                       &event,
                       Suspended,
                       KernelMode,
                       FALSE,
                       NULL);

    } else {
        ioStatus.Status = ntStatus;
    }

//    DbgPrint("exit UsbCom_CallUSBD DO=%08x Urb=%08x(%08x) Irp=%08x(%08x)\n", DeviceObject, 
//		Urb, Urb->UrbHeader.Status, irp, ioStatus.Status );

    //
    // USBD maps the error code for us
    //
    ntStatus = ioStatus.Status;

    return ntStatus;
}


NTSTATUS
UsbCom_ConfigureDevice(
    IN  PDEVICE_OBJECT DeviceObject
    )
{
    PDEVICE_EXTENSION deviceExtension;
    NTSTATUS ntStatus;
    PURB urb;
    ULONG Size;

    DbgPrint("enter UsbCom_ConfigureDevice\n");

    deviceExtension = DeviceObject->DeviceExtension;

    if ( ( urb = ExAllocatePool(NonPagedPool, sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST)) ) == NULL ) { 
		DbgPrint("UsbCom_ConfigureDevice() DO=%08x ExAllocatePool(URB_CONTROL_DESCRIPTOR_REQUEST) : FAIL\n",
						DeviceObject );
		ntStatus = STATUS_INSUFFICIENT_RESOURCES;	
		goto UsbCom_ConfigureDevice_Exit1;
	}

	if ( ( deviceExtension->UsbConfigurationDescriptor = ExAllocatePool(NonPagedPool, sizeof(USB_CONFIGURATION_DESCRIPTOR) ) ) == NULL ) {		
		DbgPrint("UsbCom_ConfigureDevice() DO=%08x ExAllocatePool(USB_CONFIGURATION_DESCRIPTOR+512) : FAIL\n",
						DeviceObject );
		ntStatus = STATUS_INSUFFICIENT_RESOURCES;	
		goto UsbCom_ConfigureDevice_Exit2;
	}

	UsbBuildGetDescriptorRequest(
		urb,
		(USHORT) sizeof (struct _URB_CONTROL_DESCRIPTOR_REQUEST),
		USB_CONFIGURATION_DESCRIPTOR_TYPE,
		0,
		0,
		deviceExtension->UsbConfigurationDescriptor,
		NULL,
		sizeof (USB_CONFIGURATION_DESCRIPTOR),
		NULL);

	ntStatus = UsbCom_CallUSBD(DeviceObject, urb);

	if (!(NT_SUCCESS(ntStatus))) {	

⌨️ 快捷键说明

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