// DOFastDlg.cpp : implementation file // #include "stdafx.h" #include "AIOUSB.h" #include "DOFast.h" #include "DetectDialog.h" #include "DOFastDlg.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif unsigned long DeviceIndex = diOnly; ///////////////////////////////////////////////////////////////////////////// // CDOFastDlg dialog CDOFastDlg::CDOFastDlg(CWnd* pParent /*=NULL*/) : CDialog(CDOFastDlg::IDD, pParent) { //{{AFX_DATA_INIT(CDOFastDlg) m_BlurbText = _T("This sample sends files to the DIFast sample, or equivalent. Just drag-and-drop the file(s) onto this window. The protocol is simple:" "\r\n" "\r\n• 2 words: BodyLen, Intel DWord = length of file contents, in bytes." "\r\n• 1 word: NameLen = length of filename, in bytes." "\r\n• 253 words: Filename, in Windows ANSI, as words in Intel byte order." "\r\n• [BodyLen/2, round up to multiple of 256] words: File contents, as words in Intel byte order." "\r\n" "\r\nThis protocol uses the high-speed USB packet size of 512 bytes." ); //}}AFX_DATA_INIT m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); } void CDOFastDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CDOFastDlg) DDX_Control(pDX, IDC_LOGLIST, m_LogList); DDX_Text(pDX, IDC_BLURBEDIT, m_BlurbText); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CDOFastDlg, CDialog) //{{AFX_MSG_MAP(CDOFastDlg) ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_WM_DROPFILES() //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CDOFastDlg message handlers void CDOFastDlg::Log(LPCTSTR Str) { m_LogList.SetCurSel(m_LogList.AddString(Str)); } BOOL CDOFastDlg::OnInitDialog() { CDialog::OnInitDialog(); SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon unsigned long PID; unsigned long Status = QueryDeviceInfo(DeviceIndex, &PID, NULL, NULL, NULL, NULL); if ( Status != ERROR_SUCCESS ) PID = 0; switch ( PID ) { //case 0x8008: //Input-only board case 0x8009: //Output-only board //case 0x800A: //Input-only board case 0x800B: case 0x800C: //case 0x800D: //Input-only board case 0x800E: //Output-only board case 0x800F: break; default: DetectDialog MyDetectDialog; if (MyDetectDialog.DoModal() == IDOK) DeviceIndex = MyDetectDialog.index; else exit(1) ; break; } double ReadClockHz = 0; //External or "off" double WriteClockHz = 1000000; //1MHz. Change this line to change the data rate. DIO_StreamSetClocks(DeviceIndex, &ReadClockHz, &WriteClockHz); DIO_StreamOpen(DeviceIndex, false); DIO_StreamClose(DeviceIndex); unsigned char OutMask = 0x07; //A, B, and C output; D is opposite C, so it's input. unsigned long DIOData = 0xFFFFFFFF; unsigned char TristateMask = 0x00; DIO_ConfigureEx(DeviceIndex, &OutMask, &DIOData, &TristateMask); DragAcceptFiles(true); Log("Drag-and-drop files to send them."); return TRUE; // return TRUE unless you set the focus to a control } // If you add a minimize button to your dialog, you will need the code below // to draw the icon. For MFC applications using the document/view model, // this is automatically done for you by the framework. void CDOFastDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // device context for painting SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); // Center icon in client rectangle int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // Draw the icon dc.DrawIcon(x, y, m_hIcon); } else { CDialog::OnPaint(); } } HCURSOR CDOFastDlg::OnQueryDragIcon() { return (HCURSOR) m_hIcon; } //This is the function that actually sends chunks of data(frames). This // sample sends files, not realtime data, so this function just sends // chunks until it's sent the whole file or there's an error. unsigned long DoTransferData(unsigned long TransferPackets, const void *Buffer) { unsigned long BytesTransferred = 0, WordsLeft = TransferPackets * 256, Status; PUSHORT NextPt = PUSHORT(Buffer); do { Status = DIO_StreamFrame(DeviceIndex, WordsLeft, NextPt, &BytesTransferred); if ( Status != ERROR_SUCCESS ) break; //BytesTransferred will always be integral words. unsigned long WordsTransferred = BytesTransferred / 2; WordsLeft -= WordsTransferred; NextPt += WordsTransferred; } while ( WordsLeft > 0 ); return Status; } typedef struct { unsigned long BodyLen; unsigned short NameLen; char FileName[506]; } THeader; void CDOFastDlg::OnDropFiles(HDROP hDropInfo) { int Ct = DragQueryFile(hDropInfo, ULONG(-1), NULL, 0); int I; CStringArray FN; FN.SetSize(Ct); for ( I = 0; I < Ct; ++I ) { int L = DragQueryFile(hDropInfo, I, NULL, 0); char *Buf = FN[I].GetBuffer(L + 1); DragQueryFile(hDropInfo, I, Buf, L + 1); FN[I].ReleaseBuffer(L); } DragFinish(hDropInfo); DIO_StreamOpen(DeviceIndex, false); for ( I = 0; I < Ct; ++I ) { int J; CString Content; unsigned long FNLen, ContentPackets, Status; THeader HeaderBuf; { CFile MyFile(FN[I], CFile::modeRead | CFile::shareDenyNone); int Len = MyFile.GetLength(); MyFile.Read(Content.GetBufferSetLength(Len), Len); Content.ReleaseBuffer(Len); MyFile.Close(); } J = FN[I].ReverseFind('\\'); FN[I] = FN[I].Mid(J + 1); Log("Sending file " + FN[I] + "..."); FNLen = FN[I].GetLength(); HeaderBuf.NameLen = FN[I].GetLength(); HeaderBuf.BodyLen = Content.GetLength(); for ( J = 0; J < HeaderBuf.NameLen; ++J ) HeaderBuf.FileName[J] = FN[I][J] ; //Determine number of packets needed to send the file content. ContentPackets = Content.GetLength(); if ( ContentPackets & 0x1FF ) ContentPackets += 0x200; ContentPackets /= 0x200; { CString PadStr; int Len = ContentPackets * 0x200 - Content.GetLength(); PadStr.GetBuffer(Len); PadStr.ReleaseBuffer(Len); Content += PadStr; } Status = DoTransferData(1, &HeaderBuf); if ( Status != ERROR_SUCCESS ) { CString ErrorStr; ErrorStr.Format("Error %ld sending file header, aborting.", Status); Log(ErrorStr); } else { Status = DoTransferData(ContentPackets, (const char *)Content); if ( Status != ERROR_SUCCESS ) { CString ErrorStr; ErrorStr.Format("Error %ld sending file body, aborting.", Status); Log(ErrorStr); } } } DIO_StreamClose(DeviceIndex); Log("Done."); }