//=========================================================================== __fastcall TfrmDeviceSetting::TfrmDeviceSetting(TComponent* Owner) : TForm(Owner) { // ------ Заполняю Бокс Портами ------ lSerialPortListClick( NULL ); // ------ Заполняю типами устройств ------ cbDeviceType->Items->Clear(); int DeviceNameCounter = 1; while ( strcmp(DeviceNames[DeviceNameCounter], "NULL") != 0 ) { if ( DeviceNames[DeviceNameCounter][0] != 'S' && DeviceNames[DeviceNameCounter][1] != 'W' ) { if ( isDebugMode == true || strcmp(DeviceNames[DeviceNameCounter], global_GyroType) == 0 ) cbDeviceType->Items->AddObject(DeviceNames[DeviceNameCounter], (TObject*)DeviceNameCounter); } DeviceNameCounter++; if ( DeviceNameCounter > 255 ) { MessageBox(Handle, "Error in device name list", "Error", MB_OK|MB_ICONERROR|MB_TASKMODAL); break; } } Label1->Caption = ( isDebugMode == true ) ? "Samping frequency [mode 3, 4]" : "Samping frequency"; // ------ Обновление инфы на форме ------ UpdateDeviceInformation(); }
//=========================================================================== void __fastcall TfrmDeviceSetting::cbDeviceTypeChange(TObject *Sender) { if ( cbDeviceType->ItemIndex == -1 ) return; TDeviceType DeviceType = (TDeviceType)cbDeviceType->Items->Objects[cbDeviceType->ItemIndex]; // -------- Тут нечего делать, если одно и тоже ------- if ( WorkDevice != NULL ) if ( WorkDevice->DeviceType == DeviceType ) return; CBaseDevice *aNewDevice = NULL; if ( DeviceType == edtCVGx ) aNewDevice = new CCVGx (); if ( DeviceType == edtCVGx_old ) aNewDevice = new CCVGx_old (); if ( DeviceType == edtCVGx_analog ) aNewDevice = new CCVGx_analog(); if ( DeviceType == edtCVGk ) aNewDevice = new CCVGk (); if ( DeviceType == edtCVG_AFR ) aNewDevice = new CCVG_AFR(); if ( DeviceType == edtCVGx48 ) aNewDevice = new CCVGx48(); if ( DeviceType == edtCVGxm ) aNewDevice = new CCVGxm(); if ( DeviceType == edtCVGxm_GK ) aNewDevice = new CCVGxm_gk(); if ( DeviceType == edtCVGxm_fap4 ) aNewDevice = new CCVGxm_fap4(); if ( DeviceType == edtCVGx_test_rs485 ) aNewDevice = new CCVGx_test_rs485(); if ( DeviceType == edtCVG_36 ) aNewDevice = new CCVG_36(); if ( DeviceType == edtCVG_44_correct ) aNewDevice = new CCVG_44_correct(); if ( DeviceType == edtCVGxm_diff ) aNewDevice = new CCVGxm_Diff (); if ( DeviceType == edtKeithley_2700 ) aNewDevice = new CKeithley_2700 (); if ( DeviceType == edtCVGk1 ) aNewDevice = new CCVGk1(); if ( DeviceType == edtCVGk2 ) aNewDevice = new CCVGk2(); if ( DeviceType == edtUE1 ) aNewDevice = new CUE1(); // ------------ if ( aNewDevice == NULL ) return; if ( WorkDevice != NULL ) { if ( WorkDevice->ComPortName != NULL && aNewDevice->ComPortName == NULL) aNewDevice->ComPortName = strdup(WorkDevice->ComPortName); if ( WorkDevice->Storage->file_Param.FileName != NULL && aNewDevice->Storage->file_Param.FileName == NULL) aNewDevice->Storage->file_Param.FileName = strdup(WorkDevice->Storage->file_Param.FileName); } aNewDevice->DeviceType = DeviceType; // ------------ delete WorkDevice; WorkDevice = aNewDevice; SetEnableDisabled_VCL_Group(this, "pDevice", WorkDevice != NULL ); SetEnableDisabled_VCL_Group(this, "Panel1" , WorkDevice != NULL ); SetEnableDisabled_VCL_Group(this, "Panel2" , WorkDevice != NULL ); // ----- Обнавляю инфу на Диалоге ----- UpdateDeviceInformation(); // ----- Генерирую имя файла ---- bGenerateFileNameClick(Sender); }
//=========================================================================== void __fastcall TfrmDeviceSetting::FormShow(TObject *Sender) { SetEnableDisabled_VCL_Group(this, "pDevice" , WorkDevice != NULL ); SetEnableDisabled_VCL_Group(this, "Panel1" , WorkDevice != NULL ); SetEnableDisabled_VCL_Group(this, "Panel2" , WorkDevice != NULL ); isWasErrorInKeyGridValue = false; // ----------- Обновляю список фолдеров ----- cbDeviceNameDropDown ( Sender ); // -----Обновляю инфу об текущем девайсе ---- UpdateDeviceInformation(); }
NTSTATUS StartDevice( PDEVICE_OBJECT fdo, PCM_PARTIAL_RESOURCE_LIST raw, PCM_PARTIAL_RESOURCE_LIST translated ) { USB_CONFIGURATION_DESCRIPTOR tcd; PUSB_CONFIGURATION_DESCRIPTOR pcd; PUSB_STRING_DESCRIPTOR desc; HANDLE RecoveryHandle; PURB selurb; URB urb; NTSTATUS status; status = STATUS_SUCCESS; PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension; selurb = NULL; pcd = NULL; // Read our device descriptor. The only real purpose to this would be to find out how many // configurations there are so we can read their descriptors. In this simplest of examples, // there's only one configuration. KdPrint((DRIVERNAME " - Start device\n")); UsbBuildGetDescriptorRequest( &urb, sizeof(_URB_CONTROL_DESCRIPTOR_REQUEST), USB_DEVICE_DESCRIPTOR_TYPE, 0, LangId, &pdx->dd, NULL, sizeof(pdx->dd), NULL ); status = SendAwaitUrb( fdo, &urb ); if(!NT_SUCCESS(status)) { KdPrint((DRIVERNAME " - Error %X trying to retrieve device descriptor\n", status)); goto cleanup; } // allocate the buffer for the descriptor; take extra space to null terminate the bString member desc = (PUSB_STRING_DESCRIPTOR)ExAllocatePoolWithTag(NonPagedPool, sizeof(USB_STRING_DESCRIPTOR) + StringDescriptorBytes, SPOT_TAG ); if(!desc) { KdPrint((DRIVERNAME " - Unable to allocate %X bytes for string descriptor\n", sizeof(USB_STRING_DESCRIPTOR) + StringDescriptorBytes)); status = STATUS_INSUFFICIENT_RESOURCES; goto cleanup; } pdx->devHash = desc; UsbBuildGetDescriptorRequest(&urb, sizeof(_URB_CONTROL_DESCRIPTOR_REQUEST), USB_STRING_DESCRIPTOR_TYPE, DeviceId, LangId, desc, NULL, sizeof(USB_STRING_DESCRIPTOR) + StringDescriptorBytes, NULL); status = SendAwaitUrb(fdo, &urb); if(!NT_SUCCESS(status)) { KdPrint((DRIVERNAME " - Error %X trying to retrieve string descriptor for DeviceId\n", status)); goto cleanup; } // null terminate the buffer; we allocated one more wchar_t for the purpose desc->bString[ (desc->bLength / 2) - 1 ] = L'\0'; UpdateDeviceInformation( fdo ); // Read the descriptor of the first configuration. This requires two steps. The first step // reads the fixed-size configuration descriptor alone. The second step reads the // configuration descriptor plus all imbedded interface and endpoint descriptors. UsbBuildGetDescriptorRequest(&urb, sizeof(_URB_CONTROL_DESCRIPTOR_REQUEST), USB_CONFIGURATION_DESCRIPTOR_TYPE, 0, LangId, &tcd, NULL, sizeof(tcd), NULL); status = SendAwaitUrb(fdo, &urb); if(!NT_SUCCESS(status)) { KdPrint((DRIVERNAME " - Error %X trying to read configuration descriptor 1\n", status)); goto cleanup; } ULONG size = tcd.wTotalLength; pcd = (PUSB_CONFIGURATION_DESCRIPTOR) ExAllocatePoolWithTag(NonPagedPool, size, SPOT_TAG); if(!pcd) { KdPrint((DRIVERNAME " - Unable to allocate %X bytes for configuration descriptor\n", size)); status = STATUS_INSUFFICIENT_RESOURCES; goto cleanup; } UsbBuildGetDescriptorRequest(&urb, sizeof(_URB_CONTROL_DESCRIPTOR_REQUEST), USB_CONFIGURATION_DESCRIPTOR_TYPE, 0, LangId, pcd, NULL, size, NULL); status = SendAwaitUrb(fdo, &urb); if(!NT_SUCCESS(status)) { KdPrint((DRIVERNAME " - Error %X trying to read configuration descriptor 1\n", status)); goto cleanup; } // Locate the descriptor for the one and only interface we expect to find PUSB_INTERFACE_DESCRIPTOR pid = USBD_ParseConfigurationDescriptorEx(pcd, pcd, -1, -1, -1, -1, -1); ASSERT(pid); // Create a URB to use in selecting a configuration. USBD_INTERFACE_LIST_ENTRY interfaces[2] = { {pid, NULL}, {NULL, NULL}, // fence to terminate the array }; selurb = USBD_CreateConfigurationRequestEx(pcd, interfaces); if(!selurb) { KdPrint((DRIVERNAME " - Unable to create configuration request\n")); status = STATUS_INSUFFICIENT_RESOURCES; goto cleanup; } // Verify that the interface describes exactly the endpoints we expect if(pid->bNumEndpoints != 2) { KdPrint((DRIVERNAME " - %d is the wrong number of endpoints\n", pid->bNumEndpoints)); status = STATUS_DEVICE_CONFIGURATION_ERROR; goto cleanup; } PUSB_ENDPOINT_DESCRIPTOR ped = (PUSB_ENDPOINT_DESCRIPTOR) pid; ped = (PUSB_ENDPOINT_DESCRIPTOR) USBD_ParseDescriptors(pcd, tcd.wTotalLength, ped, USB_ENDPOINT_DESCRIPTOR_TYPE); if(!ped || 0 == (ped->bEndpointAddress & 0x80) || ped->bmAttributes != USB_ENDPOINT_TYPE_BULK || ped->wMaxPacketSize > 64) { KdPrint((DRIVERNAME " - Endpoint has wrong attributes\n")); status = STATUS_DEVICE_CONFIGURATION_ERROR; goto cleanup; } ++ped; if(!ped || 0 != (ped->bEndpointAddress & 0x80) || ped->bmAttributes != USB_ENDPOINT_TYPE_BULK || ped->wMaxPacketSize > 64) { KdPrint((DRIVERNAME " - Endpoint has wrong attributes\n")); status = STATUS_DEVICE_CONFIGURATION_ERROR; goto cleanup; } ++ped; PUSBD_INTERFACE_INFORMATION pii = interfaces[0].Interface; ASSERT(pii->NumberOfPipes == pid->bNumEndpoints); // Initialize the maximum transfer size for each of the endpoints. The // default would be PAGE_SIZE. The firmware itself only has a 4096-byte // ring buffer, though. We need to restrict the test applet to that many // bytes. In order to exercise the multi-segment aspect of the transfer code, // therefore, reduce the maximum transfer size to 1024 bytes. pii->Pipes[0].MaximumTransferSize = USBD_DEFAULT_MAXIMUM_TRANSFER_SIZE; pii->Pipes[1].MaximumTransferSize = USBD_DEFAULT_MAXIMUM_TRANSFER_SIZE; pdx->maxtransfer = USBD_DEFAULT_MAXIMUM_TRANSFER_SIZE; // Submit the set-configuration request status = SendAwaitUrb(fdo, selurb); if(!NT_SUCCESS(status)) { KdPrint((DRIVERNAME " - Error %X trying to select configuration\n", status)); goto cleanup; } // Save the configuration and pipe handles pdx->hconfig = selurb->UrbSelectConfiguration.ConfigurationHandle; pdx->hinpipe = pii->Pipes[0].PipeHandle; pdx->houtpipe = pii->Pipes[1].PipeHandle; // Transfer ownership of the configuration descriptor to the device extension pdx->pcd = pcd; pcd = NULL; // Enable the interface IoSetDeviceInterfaceState(&pdx->operationsInterfaceName, TRUE); // Enable the interface IoSetDeviceInterfaceState(&pdx->inquiriesInterfaceName, TRUE); // create recovery thread status = PsCreateSystemThread(&RecoveryHandle, 0, NULL, NULL, NULL, RecoveryThread, (PVOID)pdx); if(!NT_SUCCESS(status)) { KdPrint((DRIVERNAME " - PsCreateSystemThread failed with error %08x\n", status)); goto cleanup; } status = ObReferenceObjectByHandle( RecoveryHandle, SYNCHRONIZE, NULL, KernelMode, (PVOID*)&pdx->RecoveryThread, NULL ); ASSERT(NT_SUCCESS(status)); ZwClose(RecoveryHandle); // Start polling status = StartPolling(pdx); if(!NT_SUCCESS(status)) { KdPrint((DRIVERNAME " - StartPolling failed 0x%08x\n", status)); if(pdx->RecoveryThread) { // shutdown recovery thread pdx->RecoveryExit = TRUE; KeSetEvent(&pdx->RecoveryEvent, 0, FALSE); // wait for polling thread to exit KeWaitForSingleObject(pdx->RecoveryThread, Executive, KernelMode, FALSE, NULL); ObDereferenceObject(pdx->RecoveryThread); pdx->RecoveryThread = NULL; } goto cleanup; } cleanup: if(selurb) ExFreePool(selurb); if(pcd ) ExFreePool(pcd ); // get rid of return codes like STATUS_PENDING if(NT_SUCCESS(status)) { return STATUS_SUCCESS; } return status; }