/*************************************************************************************************** ** ** MODULE: ** ** ** DESCRIPTION: ** ** ** AUTHOR: Daniel Dean. ** ** ** ** CREATED: ** ** ** ** ** (C) C O P Y R I G H T D A N I E L D E A N 1 9 9 6. ***************************************************************************************************/ #include #include #include #include #include "CLASS.H" #include "IOCTL.H" #include "resource.h" /*************************************************************************************************** ** ** IOCTLChannelDesc. ** ** DESCRIPTION: ** ** PARAMETERS: ** ** RETURNS: ** ***************************************************************************************************/ LPARAM IOCTLChannelDesc(HWND hWnd) { FARPROC lpfnProc; HINSTANCE hInstance = (HINSTANCE) GetWindowLong(hWnd, GWL_HINSTANCE); if((lpfnProc=(FARPROC)MakeProcInstance(ChannelDialogProc, hInstance)) != NULL) { DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_CHANNELDIALOG), hWnd, lpfnProc,(LPARAM)hWnd); FreeProcInstance(lpfnProc); } return SUCCESS; } /*************************************************************************************************** ** ** ChannelDialogProc() ** ** DESCRIPTION: Dialog Box procedure fot the Channel Info dialog ** ** PARAMETERS: ** ** RETURNS: ** ***************************************************************************************************/ BOOL CALLBACK ChannelDialogProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { static HWND hwndMama; static PCHILD_INFO pChildInfo; static ULONG Index = 0; static BOOL fValues = TRUE; // Are we displaying 'Value' channels? // If not we are displaying 'Button' channels HANDLE hListBox; char buff[32]; switch(uMsg) { case WM_INITDIALOG: hwndMama = (HWND)lParam; pChildInfo = (PCHILD_INFO)GetDeviceInfo(hwndMama); SendMessage(hDlg,WM_COMMAND,IDC_NEXT,0); return TRUE; case WM_COMMAND: { switch(wParam) { case IDOK: EndDialog(hDlg,0); return TRUE; case IDC_NEXT: hListBox = GetDlgItem(hDlg,IDC_ITEMLIST); SendMessage(hListBox,LB_RESETCONTENT,0,0); if( fValues ) { wsprintf(buff,"Value Channel %d",Index); SetWindowText(hDlg,buff); if( Index < pChildInfo->NumValues ) { wsprintf(buff,"UsagePage = %d",pChildInfo->pValueCaps[Index].UsagePage); SendMessage(hListBox,LB_ADDSTRING,0,(LPARAM)(LPCTSTR)buff); wsprintf(buff,"ReportID = %d",pChildInfo->pValueCaps[Index].ReportID); SendMessage(hListBox,LB_ADDSTRING,0,(LPARAM)(LPCTSTR)buff); if( pChildInfo->pValueCaps[Index].IsRange) { wsprintf(buff,"UsageMin = %d",pChildInfo->pValueCaps[Index].Range.UsageMin); SendMessage(hListBox,LB_ADDSTRING,0,(LPARAM)(LPCTSTR)buff); wsprintf(buff,"UsageMax = %d",pChildInfo->pValueCaps[Index].Range.UsageMax); SendMessage(hListBox,LB_ADDSTRING,0,(LPARAM)(LPCTSTR)buff); wsprintf(buff,"StringMin = %d",pChildInfo->pValueCaps[Index].Range.StringMin); SendMessage(hListBox,LB_ADDSTRING,0,(LPARAM)(LPCTSTR)buff); wsprintf(buff,"StringMax = %d",pChildInfo->pValueCaps[Index].Range.StringMax); SendMessage(hListBox,LB_ADDSTRING,0,(LPARAM)(LPCTSTR)buff); wsprintf(buff,"DesignatorMin = %d",pChildInfo->pValueCaps[Index].Range.DesignatorMin); SendMessage(hListBox,LB_ADDSTRING,0,(LPARAM)(LPCTSTR)buff); wsprintf(buff,"DesignatorMax = %d",pChildInfo->pValueCaps[Index].Range.DesignatorMax); SendMessage(hListBox,LB_ADDSTRING,0,(LPARAM)(LPCTSTR)buff); } else { wsprintf(buff,"Usage = %d",pChildInfo->pValueCaps[Index].NotRange.Usage); SendMessage(hListBox,LB_ADDSTRING,0,(LPARAM)(LPCTSTR)buff); wsprintf(buff,"StringIndex = %d",pChildInfo->pValueCaps[Index].NotRange.StringIndex); SendMessage(hListBox,LB_ADDSTRING,0,(LPARAM)(LPCTSTR)buff); wsprintf(buff,"DesignatorIndex = %d",pChildInfo->pValueCaps[Index].NotRange.DesignatorIndex); SendMessage(hListBox,LB_ADDSTRING,0,(LPARAM)(LPCTSTR)buff); } if( pChildInfo->pValueCaps[Index].HasNull ) { wsprintf(buff,"NULL = %d",pChildInfo->pValueCaps[Index].Null); SendMessage(hListBox,LB_ADDSTRING,0,(LPARAM)(LPCTSTR)buff); } wsprintf(buff,"LogicalMin = %d",pChildInfo->pValueCaps[Index].LogicalMin); SendMessage(hListBox,LB_ADDSTRING,0,(LPARAM)(LPCTSTR)buff); wsprintf(buff,"LogicalMax = %d",pChildInfo->pValueCaps[Index].LogicalMax); SendMessage(hListBox,LB_ADDSTRING,0,(LPARAM)(LPCTSTR)buff); wsprintf(buff,"PhysicalMin = %d",pChildInfo->pValueCaps[Index].PhysicalMin); SendMessage(hListBox,LB_ADDSTRING,0,(LPARAM)(LPCTSTR)buff); wsprintf(buff,"PhysicalMax = %d",pChildInfo->pValueCaps[Index].PhysicalMax); SendMessage(hListBox,LB_ADDSTRING,0,(LPARAM)(LPCTSTR)buff); Index++; } else { Index = 0; fValues = FALSE; } } else if( Index < pChildInfo->NumButtons ) { hListBox = GetDlgItem(hDlg,IDC_ITEMLIST); wsprintf(buff,"Button Channel %d",Index); SetWindowText(hDlg,buff); wsprintf(buff,"UsagePage = %d",pChildInfo->pValueCaps[Index].UsagePage); SendMessage(hListBox,LB_ADDSTRING,0,(LPARAM)(LPCTSTR)buff); wsprintf(buff,"ReportID = %d",pChildInfo->pValueCaps[Index].ReportID); SendMessage(hListBox,LB_ADDSTRING,0,(LPARAM)(LPCTSTR)buff); if( pChildInfo->pValueCaps[Index].IsRange) { wsprintf(buff,"UsageMin = %d",pChildInfo->pValueCaps[Index].Range.UsageMin); SendMessage(hListBox,LB_ADDSTRING,0,(LPARAM)(LPCTSTR)buff); wsprintf(buff,"UsageMax = %d",pChildInfo->pValueCaps[Index].Range.UsageMax); SendMessage(hListBox,LB_ADDSTRING,0,(LPARAM)(LPCTSTR)buff); wsprintf(buff,"StringMin = %d",pChildInfo->pValueCaps[Index].Range.StringMin); SendMessage(hListBox,LB_ADDSTRING,0,(LPARAM)(LPCTSTR)buff); wsprintf(buff,"StringMax = %d",pChildInfo->pValueCaps[Index].Range.StringMax); SendMessage(hListBox,LB_ADDSTRING,0,(LPARAM)(LPCTSTR)buff); wsprintf(buff,"DesignatorMin = %d",pChildInfo->pValueCaps[Index].Range.DesignatorMin); SendMessage(hListBox,LB_ADDSTRING,0,(LPARAM)(LPCTSTR)buff); wsprintf(buff,"DesignatorMax = %d",pChildInfo->pValueCaps[Index].Range.DesignatorMax); SendMessage(hListBox,LB_ADDSTRING,0,(LPARAM)(LPCTSTR)buff); } else { wsprintf(buff,"Usage = %d",pChildInfo->pValueCaps[Index].NotRange.Usage); SendMessage(hListBox,LB_ADDSTRING,0,(LPARAM)(LPCTSTR)buff); wsprintf(buff,"StringIndex = %d",pChildInfo->pValueCaps[Index].NotRange.StringIndex); SendMessage(hListBox,LB_ADDSTRING,0,(LPARAM)(LPCTSTR)buff); wsprintf(buff,"DesignatorIndex = %d",pChildInfo->pValueCaps[Index].NotRange.DesignatorIndex); SendMessage(hListBox,LB_ADDSTRING,0,(LPARAM)(LPCTSTR)buff); } Index++; } else { fValues = TRUE; Index = 0; } return TRUE; } }//end case WM_COMMAND }//end switch(uMsg) return FALSE; } /*************************************************************************************************** ** ** IOCTLDeviceDesc. ** ** DESCRIPTION: ** ** PARAMETERS: ** ** RETURNS: ** ***************************************************************************************************/ LPARAM IOCTLDeviceDesc(HWND hWnd) { return SUCCESS; } /*************************************************************************************************** ** ** IOCTLRead. ** ** DESCRIPTION: ** ** PARAMETERS: ** ** RETURNS: ** ***************************************************************************************************/ LPARAM IOCTLRead(HWND hWnd) { ULONG dwThreadID; HANDLE hThread; PREADTHREAD pThreadData; OutputDebugString(">>>>HIDMON.EXE: IOCTLRead() Enter\n"); // If a read or a write is in progress stop it if(GetThreadData(hWnd)) IOCTLStop(hWnd); // Get the number of bytes of data for this device // Allocate and setup a thread variables pThreadData = (PREADTHREAD) GlobalAlloc(GPTR, sizeof(READTHREAD)); if(!pThreadData) { MessageBox(hWnd,"IOCTLRead(): GlobalAlloc fialed","Ooops!",MB_OK); return FALSE; } pThreadData->hEditWin = GetEditWin(hWnd); pThreadData->ThisThread = TRUE; pThreadData->hDevice = GetDeviceHandle(hWnd); pThreadData->hWnd = hWnd; // Create Data notification thread hThread = CreateThread((LPSECURITY_ATTRIBUTES) NULL, (DWORD) 0, (LPTHREAD_START_ROUTINE) ReadWatch, (LPVOID) pThreadData, CREATE_SUSPENDED, &dwThreadID); if(!hThread) { GlobalFree(pThreadData); MessageBox(hWnd,"IOCTLRead(): CreateThread fialed","Ooops!",MB_OK); return FAILURE; } SetThreadData(hWnd, pThreadData); // Set Thread priority and start thread SetThreadPriority(hThread, THREAD_PRIORITY_TIME_CRITICAL); ResumeThread(hThread); return SUCCESS; } /*************************************************************************************************** ** ** IOCTLWrite. ** ** DESCRIPTION: ** ** PARAMETERS: ** ** RETURNS: ** ***************************************************************************************************/ LPARAM IOCTLWrite(HWND hWnd) { ULONG dwReturn = 0; OVERLAPPED Overlapped; // If a read or a write is in progress stop it if(GetThreadData(hWnd)) IOCTLStop(hWnd); // Need a way to get data froom user // Need a way to get channel number from user Overlapped.Offset = 3; Overlapped.hEvent = NULL; dwReturn = 0; WriteFile(GetDeviceHandle(hWnd), (PVOID) "Hello", sizeof("Hello"), &dwReturn, &Overlapped); return SUCCESS; } /*************************************************************************************************** ** ** IOCTLStop. ** ** DESCRIPTION: ** ** PARAMETERS: ** ** RETURNS: ** ***************************************************************************************************/ LPARAM IOCTLStop(HWND hWnd) { PREADTHREAD pThreadData; OutputDebugString(">>>>HIDMON.EXE: IOCTLStop() Enter\n"); pThreadData = GetThreadData(hWnd); if(pThreadData) { SetThreadData(hWnd, 0); pThreadData->ThisThread = FALSE; } // Allow the thread to die //Sleep(250); OutputDebugString(">>>>HIDMON.EXE: IOCTLStop() Exit\n"); return SUCCESS; } /******************************************************************************* ** ** FUNCTION: ReadWatch() ** ** PURPOSE: Read next available packet and display in child window ** ** ** *******************************************************************************/ #define MAX_CHARS_PER_LINE 128 VOID CALLBACK ReadWatch(HWND hWnd, UINT uMsg, UINT TimerID, DWORD dwTime) { PUCHAR WriteBuffer; PUCHAR ReadBuffer; ULONG NumChannels; ULONG NumBytes; ULONG LogicalReturn; READTHREAD ThreadData; OVERLAPPED OV; PCHILD_INFO pChildInfo; OutputDebugString(">>>>HIDMON.EXE: ReadWatch() Enter\n"); // Retrieve info for this child pChildInfo = (PCHILD_INFO)GetDeviceInfo(hWnd); NumChannels = pChildInfo->hidCaps->NumberInputValueCaps + pChildInfo->hidCaps->NumberInputButtonCaps; NumBytes = pChildInfo->hidCaps->InputReportByteLength; // Allocate memory for our ReadBuffer ReadBuffer = (PUCHAR) GlobalAlloc(GPTR,NumBytes); if(!ReadBuffer) return;// FALSE; // Allocate memory for our 'screen' buffer WriteBuffer = (PUCHAR) GlobalAlloc(GPTR,NumChannels*MAX_CHARS_PER_LINE); if(!WriteBuffer) { GlobalFree(ReadBuffer); return;// FALSE; } // Setup read buffer memset(ReadBuffer, 0, NumBytes); // Setup overlapped structure memset(&OV, 0, sizeof(OVERLAPPED)); // Start read LogicalReturn = ReadFileEx(GetDeviceHandle(hWnd), (LPVOID) ReadBuffer, NumBytes, &OV, NULL); // Print error message if failed if(!LogicalReturn) SendMessage(ThreadData.hEditWin, WM_SETTEXT, (WPARAM) sizeof("ReadFile FAILED!"), (LPARAM) "ReadFile FAILED!"); else if( LogicalReturn ) { PCHAR pChar = WriteBuffer; NTSTATUS rc; char tmpBuff[256],tmpBuff2[256]; ULONG i,Value; // // Parse the data from our last Read // // Clear the buffer memset(WriteBuffer,'\0',NumChannels*MAX_CHARS_PER_LINE); // Make Text strings // First do the Value channels for(i=0;ihidCaps->NumberInputValueCaps;i++) { rc = HidP_GetUsageValue(HidP_Input, pChildInfo->pValueCaps[i].UsagePage, 0, pChildInfo->pValueCaps[i].NotRange.Usage, &Value, pChildInfo->hidPPData, ReadBuffer, NumBytes ); wsprintf(tmpBuff,"Value: Usage[%02d]:[%02d] = %d\r\n", pChildInfo->pValueCaps[i].UsagePage, pChildInfo->pValueCaps[i].NotRange.Usage, Value ); strcat(WriteBuffer,tmpBuff); } // Then do the button channels for(i=0;ihidCaps->NumberInputButtonCaps;i++) { PUCHAR pUsageList; DWORD ulUsageListLen; //UCHAR TempBuff[256]; // Get the maximum usage list length ulUsageListLen = HidP_MaxUsageListLength( HidP_Input, pChildInfo->pButtonCaps[i].UsagePage, pChildInfo->hidPPData ); pUsageList = (PUCHAR)GlobalAlloc(GMEM_FIXED,ulUsageListLen); wsprintf( tmpBuff,"Buttons:[%02d]:[%02d] = ",pChildInfo->pButtonCaps[i].UsagePage, pChildInfo->pButtonCaps[i].NotRange.Usage); ulUsageListLen++; rc = HidP_GetUsages(HidP_Input, pChildInfo->pButtonCaps[i].UsagePage, pChildInfo->pButtonCaps[i].LinkCollection, pUsageList, &ulUsageListLen, pChildInfo->hidPPData, ReadBuffer, NumBytes ); // if Buttons are pressed if( ulUsageListLen ) { ULONG i; for(i=0;iNumButtons; } SendMessage(GetEditWin(hWnd),//ThreadData.hEditWin, WM_SETTEXT, (WPARAM) strlen(WriteBuffer), (LPARAM) WriteBuffer); }// end if(LogicalReturn) // GlobalFree(ReadBuffer); GlobalFree(WriteBuffer); //TESTING!! OutputDebugString(">>>>HIDMON.EXE: ReadWatch() Exit\n"); return;// TRUE; }