Aug 23, 2010

Meeting on 20 August

Gist:
  1. using libusb-win32 API to find the suitable USB device, and send the "bulk" characters to the bus driver.
  2. Borrow board mini arm 2440 from Simon. Windows fails to detect the existence of the board, which may due to no driver written on the board. Ka chun suggests we have to write the driver and insert it into the kernel to let the board pretend it as a HID device.
  3. Investigate usage of "linux usb gadget" which appeared as an API for linux
  4. MF made another task for me, which is being able to find out current running process by capturing the event.
  5. On August 22, sunday, google "switch foreground window event", found something useful and post below. The available source code is written in C#. I may change it into C++.

Switch Foreground window event capture [success in C#]

Here is the source code:

using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Text;

namespace ExampleApp
{
class ExampleForm : Form
{
delegate void WinEventDelegate(IntPtr hWinEventHook,
uint eventType, IntPtr hwnd, int idObject,
int idChild, uint dwEventThread, uint dwmsEventTime);

const uint WINEVENT_OUTOFCONTEXT = 0;
const uint EVENT_SYSTEM_FOREGROUND = 3;

[DllImport("user32.dll")]
static extern bool UnhookWinEvent(IntPtr hWinEventHook);
[DllImport("user32.dll")]
static extern IntPtr SetWinEventHook(uint eventMin,
uint eventMax, IntPtr hmodWinEventProc,
WinEventDelegate lpfnWinEventProc, uint idProcess,
uint idThread, uint dwFlags);
[DllImport("user32.dll")]
static extern int GetWindowText(IntPtr hWnd,
StringBuilder lpString, int nMaxCount);

[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new ExampleForm());
}

ListBox m_list;
IntPtr m_hhook;

public ExampleForm()
{
m_list = new ListBox();
m_list.IntegralHeight = false;
m_list.Dock = DockStyle.Fill;
Controls.Add(m_list);

Text = "SetWinEventHook Example";

Load += new EventHandler(Program_Load);
FormClosing +=
new FormClosingEventHandler(Program_FormClosing);
}

void Program_Load(object sender, EventArgs e)
{
m_hhook = SetWinEventHook(EVENT_SYSTEM_FOREGROUND,
EVENT_SYSTEM_FOREGROUND, IntPtr.Zero,
WinEventProc, 0, 0, WINEVENT_OUTOFCONTEXT);
}

void WinEventProc(IntPtr hWinEventHook, uint eventType,
IntPtr hwnd, int idObject, int idChild,
uint dwEventThread, uint dwmsEventTime)
{
if (eventType == EVENT_SYSTEM_FOREGROUND)
{
StringBuilder sb = new StringBuilder(500);
GetWindowText(hwnd, sb, sb.Capacity);

m_list.Items.Insert(0,
"Switched to: " + sb.ToString());
}
}

void Program_FormClosing(
object sender, FormClosingEventArgs e)
{
UnhookWinEvent(m_hhook);
}
}
}

Aug 15, 2010

How to Install Winusb.sys as the Device's Function Driver

  1. Install the Windows Driver Kit.
  2. Create a driver package folder on the machine to which the USB device is connected. For example c:\UsbDevice.
  3. Copy the WinUSB co-installer (WinusbcoinstallerX.dll) from the WinDDK\BuildNumber\redist\winusb to the driver package folder.

    The WinUSB co-installer (Winusbcoinstaller.dll) installs WinUSB on the target system, if necessary. The WDK includes three versions of the co-installer depending on the system architecture: x86-based, x64-based, and Itanium-based systems. They are all named WinusbcoinstallerX.dll and are located in the appropriate subdirectory in the WinDDK\BuildNumber\redist\winusb folder.

  4. Copy the KMDF co-installer (WdfcoinstallerXXX.dll) from the WinDDK\BuildNumber\redist\wdf to the driver package folder.

    The KMDF co-installer (WdfcoinstallerXXX.dll) installs the correct version of KMDF on the target system, if necessary. The version of WinUSB co-installer must match the KMDF co-installer because KMDF-based client drivers, such as Winusb.sys, require the corresponding version of the KMDF framework to be installed properly on the system. For example, Winusbcoinstaller2.dll requires KMDF version 1.9, which is installed by Wdfcoinstaller01009.dll. The x86 and x64 versions of WdfcoinstallerXXX.dll are included with the WDK under the WinDDK\BuildNumber\redist\wdf folder. The following table shows the WinUSB co-installer and the associated KMDF co-installer to use on the target system.

    Use the following table to determine the WinUSB co-installer and the associated KMDF co-installer.

    WinUSB co-installerKMDF library versionKMDF co-installer
    Winusbcoinstaller.dllRequires KMDF version 1.5 or later.

    Wdfcoinstaller01005.dll

    Wdfcoinstaller01007.dll

    Wdfcoinstaller01009.dll

    Winusbcoinstaller2.dllRequires KMDF version 1.9 or later.Wdfcoinstaller01009.dll

  5. Write an INF that installs Winusb.sys as the function driver for the USB device.
  6. Create a signed catalog file for the package. This file is required to install WinUSB on x64 versions of Windows Vista.
  7. Attach the USB device to your computer.
  8. Run devcon.exe as follows:

    devcon.exe install inf_file.inf "hardware_id"

    • devcon.exe can be found in the \WinDDK\build_number\tools\devcon\\devcon.exe folder.
    • inf_file indicates the name of your INF.
    • hardware_id indicates the hardware identifier for the device provided by the device vendor. This can be found in the INF. For example, for the OSR USB-FX2 Learning Kit device from OSR, the identifier is USB\Vid_0547&Pid_1002.

      Note Because the hardware id contains '&', make sure that you specify the hardware id within quotes.

  9. Alternatively, you can use the Device Manager to install the driver. Follow the instructions on the Update Driver Software wizard and choose manual installation. You will need to provide the location of the driver package folder to complete the installation.
INF file sample:

Addendum to Thread "Calling WinUSB from an application"

Hi. Just for completeness sake, see below for a revised version of the inf file located in the following thread: http://www.osronline.com/showThread.cfm?link=102204 It was pointed out to me by Zhao Yu from Motica that the inf file needed to be revised for copying files correctly in a cross-platform manner (by that I mean 32-bit vs. 64-bit). Zhao quotes from a WDK 6000 document: "The CopyFiles directive does not support decorating a file-list-section name with a system-defined platform extension (.nt, .ntx86, .ntia64, or .ntamd64). ". Thus, the coinstaller in the previous inf file couldn't copy the two dlls on some platforms. Plus, he requested to have a SourceDiskFiles section put in as well. The inf template below puts in place his changes. So, this should be a better inf file to use to get started... For those of you who haven't followed this thread topic, this inf file is a template that can be used to install WinUSB as the primary device driver for a device (just replace the strings, GUIDs, VID and PID). To install, place your tweaked version of this inf file in a directory, then make two subdirectories, "amd64" and "x86", and place the co-installer dlls (found in the WDK) for those particular platforms in their respective directory and off you go... Thanks Zhao! --Brian Hindman ; ================ Version section ================= [Version] Signature = "$Windows NT$" Class = MyDeviceClass ClassGuid = {11111111-2222-3333-4444-555555555555} Provider = %ProviderName% DriverVer = 05/22/2007, 6.0.1.0 ; ========== Manufacturer/Models sections =========== [Manufacturer] %ProviderName% = MyDevice_WinUSB,NTx86,NTia64,NTamd64 [MyDevice_WinUSB.NTx86] %USB\MyDevice.DeviceDesc% =USB_Install, USB\VID_xxxx&PID_xxxx [MyDevice_WinUSB.NTamd64] %USB\MyDevice.DeviceDesc% =USB_Install, USB\VID_xxxx&PID_xxxx ; ================== Installation ================== [USB_Install] Include = WinUSB.inf Needs = WinUSB.NT [USB_Install.Services] Include = WinUSB.inf AddService = WinUSB, 0x00000002, WinUSB_ServiceInstall [WinUSB_ServiceInstall] DisplayName = %WinUSB_SvcDesc% ServiceType = 1 StartType = 3 ErrorControl = 1 ServiceBinary = %12%\WinUSB.sys [USB_Install.Wdf] KmdfService = WinUSB, WinUSB_Install [WinUSB_Install] KmdfLibraryVersion = 1.5 [USB_Install.HW] AddReg = Dev_AddReg [Dev_AddReg] HKR,,DeviceInterfaceGUIDs,0x00010000,"{55555555-4444-3333-2222-111111111111}" [USB_Install.CoInstallers] AddReg = CoInstallers_AddReg CopyFiles = CoInstallers_CopyFiles [CoInstallers_AddReg] HKR, , CoInstallers32, 0x00010000, "WinUSBCoInstaller.dll", "WdfCoInstaller01005.dll, WdfCoInstaller" [CoInstallers_CopyFiles] WinUSBCoInstaller.dll WdfCoInstaller01005.dll [SourceDisksNames] 1 = %MediaDescription% [SourceDisksFiles] WinUSBCoInstaller.dll = 1, x86 WdfCoInstaller01005.dll = 1, x86 [SourceDisksFiles.amd64] WinUSBCoInstaller.dll = 1, amd64 WdfCoInstaller01005.dll = 1, amd64 [DestinationDirs] CoInstallers_CopyFiles = 11 ; ==================== Strings ===================== [Strings] ProviderName = "My Company" USB\MyDevice.DeviceDesc="My Device using WinUSB only" MediaDescription = "My Installation Media" WinUSB_SvcDesc = "WinUSB Driver Service"<br />from: <span class="Apple-style-span" style="font-family: Tahoma, geneva, lucida, 'lucida grande', arial, helvetica, sans-serif; white-space: normal; "><a href="http://www.osronline.com/showthread.cfm?link=109991">http://www.osronline.com/showthread.cfm?link=109991</a> and msdn</span>

Aug 6, 2010

winUSB

Following the whitepaper written by M$, I am now confussing with the steps that writing the INF file to load the .sys into device manager.

I searched from the Internet. It is not easy to find how I can enumerate the GUID which is a vital option in the INF file. Keep going now...

Today Meeting

Meet with MF at 122.
We have discussed issues about how the hardware were supposed to communicate.
Basically, it will be a Linux device, there will be PC to device connection.
Originally, I am going to write the device driver on windows using the WDM.
After serveral discussion with MF, we figured out that we had to finish the earliest version as soon as possible. That is, at least we can have something demonstrate to our marker before December 2010. And now I have to shift to other easier method.

There will be some suggestions from MF:
  1. The generic HID keyboard driver. But the difficulty is we do not know if PC can send any data to the keyboard thru the generic driver. That may be a potential problem we have to solve.
  2. The winUSB API. Indeed, I don't pose so much knowledge on this but I am now preferring using this API function. Mainly because it is handy and M$ has already written different API with the winUSB.sys file for us.
MF also said that what Windows has to do is simple. It only has to register the hardware (thru the driver) and send some encrypted simple message to our Linux device. The n the device will decrypt the message. Big project comes from the Linux part. That is all we included.

Aug 2, 2010

Build without VC++ directly in CMD

Source:http://hi.baidu.com/kktlxd/blog/item/291051340e6d724b251f1418.html

Also, we have to include the makefile as well as the Sources to the same directory.
Make sure that there won't be any spacing in the path of directory or the following error: http://stackoverflow.com/questions/1154660/fatal-error-u1087-cannot-have-and-dependents-for-same-target shows up...


Solution found

Source http://www.cnblogs.com/wubiyu/archive/2010/05/17/1737420.html

Vs2010 配置驱动开发环境

1、安装VS2010,安装WDK 7.0(DDK);

2、新建VC++->Empty Project

3、打开Configuration Manager 并新建一个名称为“ dirver ”的Solution Configuration 并将“dirver” 设为Active Solution Configuration .

4、打开View-> property Manager。

5、在"dirver" solution configuration 上点击右键,选择Add new property Sheet。取名为“dirverProperty”. 并对他进下以下设置。

5.1. C\C++ - General - Debug Information Format = Program Database (/Zi)
5.2. C\C++ - Preprocessor - Preprocessor Definitions = _X86_ [add also DBG for Debug config]
【WIN32;_DEBUG;_X86_;i386;STD_CALL;CONDITION_HANDLING;WIN32_LEAN_AND_MEAN;NT_UP;SRVDBG;DBG;_IDWBUILD;_WIN32_WINNT=0x0400;% (PreprocessorDefinitions)】
5.3. C\C++ - Code Generation - Enable C++ Exceptions = No
5.4. C\C++ - Code Generation - Basic Runtime Checks = Default
5.5. C\C++ - Code Generation - Buffer Security Check = No (/GS-)
5.6. C\C++ - Advanced - Calling Convention = __stdcall (/Gz)
5.7. C\C++ - Advanced - Compile As = Compile as C Code (/TC) [if you are going to use plain C]
5.8. Linker - General - Output File = $(OutDir)\$(ProjectName).sys
5.9. Linker - General - Enable Incremental Linking = Default
5.10. Linker - Input - Additional Dependencies = ntoskrnl.lib hal.lib $(NOINHERIT) [add here needed libs here e.g. ntoskrnl.lib hal.lib]
【不知道上面是不是笔误,应该为:ntoskrnl.lib;hal.lib;%(AdditionalDependencies)】
5.11. Linker - Input - Ignore All Default Libraries = Yes (/NODEFAULTLIB)
5.12. Linker - Manifest File - Generate Manifest = No
5.13. Linker - System - SubSystem = Native (/SUBSYSTEM:NATIVE)
5.14. Linker - System - Driver = Driver (/DRIVER)
5.15. Linker - Advanced - Entry Point = DriverEntry
5.16. Linker - Advanced - Base Address = 0x10000
5.17. Linker - Advanced - Randomized Base Address = Disable (/DYNAMICBASE:NO)
【这个也是错误的:应该置空】
5.18. Linker - Advanced - Data Execution Prevention (DEP) = Disable (/NXCOMPAT:NO)
【这个也是错误的:应该置空】

6. Config VC++ Directories
6.1 Open Open up property manager by clicking on Menu View->Property Manager.
6.2 Expand the project node and then the Configuration|Platform nodes, you will see "Microsoft.cpp..users" file for each Configuration|Platform. These are the files

for the global settings, similar to the old tools/Options/VC++ Directories.
6.3 Multi-Select "Microsoft.cpp..users", right click and bring up the property page window
6.4 In the property page window, click on "VC++ Directories" (for example) in the left pane, add new paths for the directories such as "Include Directories". separated by

semicolons
(eg:Include Directories config As:
$(ddkroot)\INC
$(ddkroot)\INC\WNET
$(ddkroot)\INC\DDK\WNET
Library Directories config As:
$(ddkroot)\LIB\WNET\I386
)
6.5 Make sure to save the settings before shutting down Visual Studio.
6.6 Re-launch Visual Studio and the new settings will be in effect.
6.7 Note: If you would like to only change the settings for one project, you can right click on the project and bring up the property page. Change the settings for “VC++

Directories”, these settings will be persisted to the project file.
七. OK. Have done. Now you can test it with simple code, e.g.:

#include "ntddk.h"

NTSTATUS
DriverEntry(PDRIVER_OBJECT DriverObject,PUNICODE_STRING RegistryPath)
{
return STATUS_UNSUCCESSFUL;
}

特别说明:
1.
Visual Studio 2010 在智能设备开发方面只支持Windows Phone OS 7.0。如果你要为Windows CE 5.0和Windows Mobile 6.5开发应用程序,请安装Visual Studio 2008。
2.
做驱动开发时,SDK的版本要和WDK的版本一致,即Win7 WDK要配Win7 SDK,否则会出现编译错误。VS2010里集成了Windows SDK 7.0A。
3.
如果出现类似如下编译错误,解决方法是:拷贝C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\sal.h,然后覆盖掉C:\WinDDK\7600.16385.1\inc\api\sal.h。

C:\Program Files\Microsoft Visual Studio 10.0\VC\include\crtdefs.h(550): error C2143: syntax error : missing ')' before 'const'
C:\Program Files\Microsoft Visual Studio 10.0\VC\include\crtdefs.h(550): error C2143: syntax error : missing '{' before 'const'
C:\Program Files\Microsoft Visual Studio 10.0\VC\include\crtdefs.h(550): error C2059: syntax error : ','
.............
C:\Program Files\Microsoft Visual Studio 10.0\VC\include\ctype.h(107): fatal error C1003: error count exceeds 100; stopping compilation

Start writing simple WDM driver

View the sample code downloaded from code project.
Starting the sample program with Visual C++ 2010 express.
Some problems encountered:

  1. Cannot directly compile the solution, have to compile each cpp file step by step, C1083 Error
  2. Cannot link to the symbol from kernal, system32. Have to set Debug->Option and Setting->Symbols->Checked the option.
  3. Device not found, still figuring out.
Problems encountered while editing HelloWDM: http://www.luocong.com/articles/show_article.asp?Article_ID=11

  1. VC2010 cannot find the path of DDK header files
  2. 1. Run VS2005
    2. Select Tools->Options->Project and Solutions->VC++ Directories For;VC2010 it is in Project->Properties
    3. On the right side choose Include file (from show directories from)
    4. Add WDKInstallationPath\BuildNumber\ inc to the list; For win7, we have to specifically identify the DDK path: C:\WinDDK\7600.16385.1\inc\ddk
    5. On the right side choose Library file (from show directories from)
    6. Add WDKInstallationPath\BuildNumber\ lib to the list
    7. Press OK

However, error msg appeared:

1>  stdafx.cpp
1>c:\program files\microsoft visual studio 10.0\vc\include\crtdefs.h(520): error C2065: '_In_opt_z_' : undeclared identifier
1>c:\program files\microsoft visual studio 10.0\vc\include\crtdefs.h(520): error C2143: syntax error : missing ')' before 'const'
1>c:\program files\microsoft visual studio 10.0\vc\include\crtdefs.h(520): warning C4229: anachronism used : modifiers on data are ignored
1>c:\program files\microsoft visual studio 10.0\vc\include\crtdefs.h(520): error C2182: '_invalid_parameter' : illegal use of type 'void'
1>c:\program files\microsoft visual studio 10.0\vc\include\crtdefs.h(520): error C2491: '_invalid_parameter' : definition of dllimport data not allowed
1>c:\program files\microsoft visual studio 10.0\vc\include\crtdefs.h(520): error C2059: syntax error : ')'


Solution from http://stackoverflow.com/questions/1356653/multiple-compiling-errors-with-basic-c-application-on-vs2010-beta-1

The problem is here: C:\WinDDK\6001.18001\inc\api\sal.h

sal.h defines annotations, which are being used in the CRT headers... The DDK includes its own sal.h, which is obsolete and dones not contain all the annotations.

There are 2 possible solutions: - change the include paths so that the "C:\Program Files\Microsoft Visual Studio 10.0\VC\include" comes before "C:\WinDDK\6001.18001\inc\api"

  • just delete "C:\WinDDK\6001.18001\inc\api\sal.h" :)