DOC

OutputDebugString(LMyDriver

By Tommy Cook,2014-06-09 09:45
9 views 0
OutputDebugString(LMyDriver

    Develop and Test Device Drivers

    1 Lab 1Create a stream driver

    1.1 Objectives

    In this Project, You will learn:

    ? The basic principles and functions of device drivers

    ? The program structure of the stream driver

    ? Create the stream driver in Windows CE 5.0

    1.2 Prerequisites

    Before this project, please make sure that you have the following preliminary knowledge

    ? Understand the purpose of a device driver.

    Drivers abstract the underlying hardware from the operating system. An application developer

    shouldn't need to know the specifics of your display hardware or your serial hardware. The API

    provided by Windows CE can be called directly by the developers. So you can interact with the

    hardware without needing to know what the physical hardware is. For example, to write to a serial

    port, just follow the steps:

    1. calls CreateFile( ) on COMx

    2. calls WriteFile( ) to write some bytes of data to the serial port

    3. calls CloseHandle( ) to close the serial port The same is also true of other APIs: If you want to write to a line to the display surface, you would simply call PolyLine( ), MoveToEx( ), or LineTo( ). As an application developer, for the most part, you don't need to know how the display hardware works.

    In windows CE, a driver is simply a dynamic-link library (DLL). DLLs are loaded into a parent process address space; the parent process can then call any of the interfaces exposed from

    the DLL. The driver is typically loaded by its parent process, usually the parent process is

    device.exe or gwes.exe, through a call to LoadLibrary( ) or LoadDriver( ).

    Stream drivers expose a well-known set of functions. For a stream driver, you want to be able

    to write a stream of bytes to the device, or read a stream of bytes from the device. Therefore, in the

    serial port example used earlier, you would expect the following set of functions to be exposed

    from your driver: Open, Close, Read, and Write. Stream drivers expose some additional functions:

    PowerUp, PowerDown, IOControl, Init, and DeInit.

    The following list shows the required functions

    Function Description XXX_Close Closes the device context identified by hOpenContext.

    Called by the Device Manager to de-initialize a device. XXX_Deinit

    Called by the Device Manager to initialize a device. XXX_Init

    Sends a command to a device. XXX_IOControl

    Opens a device for reading, writing, or both. An application indirectly XXX_Open

    invokes this function when it calls CreateFile to open special device

    file names.

    Ends power to the device. It is useful only with devices that can be shut XXX_PowerDown

    off under software control.

    Restores power to a device. XXX_PowerUp

    Reads data from the device identified by the open context. XXX_Read

    Moves the data pointer in the device. XXX_Seek

    Writes data to the device. XXX_Write

    1.3 Anticipated Time

    30-45 minutes

    1.4 Detailed Steps

    1. Launch Platform Builder

    2. Create new platform workspace using the Platform Wizard 3. On the File menu, click New Project or File. Select WCE Dynamic-Link Library, give it an

    appropriate name (for example, MyDriver), and then click OK.

    4. Following the wizard, click “A simple Windows CE DLL project”

    5. Click Finish to complete the wizard. At this point, the DLL contains only an empty DllMain

    function

    6. Modify the DllMain function generated by the Platform Builder as following

    BOOL APIENTRY DllMain( HANDLE hModule,

     DWORD ul_reason_for_call,

     LPVOID lpReserved

     )

    {

     switch ( ul_reason_for_call )

     {

     case DLL_PROCESS_ATTACH:

     OutputDebugString(L"MyDriver - DLL_PROCESS_ATTACH\n");

     break;

     case DLL_PROCESS_DETACH:

     OutputDebugString(L"MyDriver - DLL_PROCESS_DETACH\n");

     break;

     case DLL_THREAD_ATTACH:

     OutputDebugString(L"MyDriver - DLL_THREAD_ATTACH\n");

     break;

     case DLL_THREAD_DETACH:

     OutputDebugString(L"MyDriver - DLL_THREAD_DETACH\n");

     break; }

     return TRUE;

    }

    7. Add preceding definitions for the exposed functions of the stream interface driver.

    DWORD DEM_Init(LPCTSTR pContext, LPCVOID lpvBusContext);

    BOOL DEM_Deinit( DWORD hDeviceContext );

    DWORD DEM_Open( DWORD hDeviceContext, DWORD AccessCode, DWORD

    ShareMode );

    BOOL DEM_Close( DWORD hOpenContext );

    BOOL DEM_IOControl( DWORD hOpenContext, DWORD dwCode, PBYTE pBufIn, DWORD dwLenIn, PBYTE pBufOut, DWORD dwLenOut, PDWORD pdwActualOut ); void DEM_PowerUp( DWORD hDeviceContext );

    void DEM_PowerDown( DWORD hDeviceContext );

    DWORD DEM_Read( DWORD hOpenContext, LPVOID pBuffer, DWORD Count ); DWORD DEM_Write( DWORD hOpenContext, LPCVOID pBuffer, DWORD Count ); DWORD DEM_Seek( DWORD hOpenContext, long Amount, WORD Type );

#define IOCTL_DRIVER_DEMO 42

// Not exposed by the Device Driver

    void DBGOut(DWORD dwValue);

HANDLE hMem=NULL;

    DWORD dwCount;

    8. Add the implementation of the exposed functions.

    DWORD DEM_Init( LPCTSTR pContext, LPCVOID lpvBusContext) {

     OutputDebugString(L"MyDriver - DEM_Init - Context: ");

     OutputDebugString(pContext);

     OutputDebugString(L"\n");

     OutputDebugString(L"MyDriver - ~ DEM_Init\n");

     return 0x1234;

    }

    BOOL DEM_Deinit( DWORD hDeviceContext ) {

     OutputDebugString(L"MyDriver - DEM_Deinit\n");

     OutputDebugString(L"MyDriver - ~ DEM_Deinit\n");

     return TRUE;

    }

DWORD DEM_Open( DWORD hDeviceContext, DWORD AccessCode, DWORD

    ShareMode )

    {

     OutputDebugString(L"MyDriver - DEM_Open\n");

     OutputDebugString(L"hDeviceContext - ");

     DBGOut(hDeviceContext);

     OutputDebugString(L"\n");

     OutputDebugString(L"MyDriver - ~ DEM_Open\n");

     return 0x5678;

    }

BOOL DEM_Close( DWORD hOpenContext )

    {

     OutputDebugString(L"MyDriver - DEM_Close\n");

     OutputDebugString(L"hOpenContext - ");

     DBGOut(hOpenContext);

     OutputDebugString(L"\n");

     OutputDebugString(L"MyDriver - ~ DEM_Close\n");

     return TRUE;

    }

BOOL DEM_IOControl( DWORD hOpenContext, DWORD dwCode, PBYTE pBufIn,

    DWORD dwLenIn, PBYTE pBufOut, DWORD dwLenOut, PDWORD pdwActualOut )

    {

     OutputDebugString(L"MyDriver - DEM_IOControl\n");

     OutputDebugString(L"hOpenContext - ");

     DBGOut(hOpenContext);

     OutputDebugString(L"\n");

     switch (dwCode) {

     case IOCTL_DRIVER_DEMO:

     {

     OutputDebugString(L"DRIVER DEMO IOCTL...\n");

     // reverse the string...

     HANDLE hTemp=LocalAlloc(LPTR,dwLenIn+1);

     memset(hTemp,0x00,dwLenIn+1);

     TCHAR *tcOut=(TCHAR*)hTemp;

     TCHAR *tcIn=(TCHAR*)pBufIn;

     DWORD dwChars=dwLenIn/2;

     for (DWORD x=0;x < dwChars;x++) {

     tcOut[x]=tcIn[dwChars-x-1];

     }

     memcpy(pBufOut,hTemp,dwLenIn);

     LocalFree(hTemp);

     *pdwActualOut=dwLenIn;

     }

     break;

     default:

     OutputDebugString(L"Unknown IOCTL\n");

     break;

     }

     OutputDebugString(L"MyDriver - ~ DEM_IOControl\n");

     return TRUE;

    }

    void DEM_PowerUp( DWORD hDeviceContext ) {

     OutputDebugString(L"MyDriver - DEM_PowerUp\n");

     OutputDebugString(L"hDeviceContext - ");

     DBGOut(hDeviceContext);

     OutputDebugString(L"\n");

     OutputDebugString(L"MyDriver - ~ DEM_PowerUp\n"); }

    void DEM_PowerDown( DWORD hDeviceContext ) {

     OutputDebugString(L"MyDriver - DEM_PowerDown\n");

     OutputDebugString(L"hDeviceContext - ");

     DBGOut(hDeviceContext);

     OutputDebugString(L"\n");

     OutputDebugString(L"MyDriver - ~ DEM_PowerDown\n"); }

DWORD DEM_Read( DWORD hOpenContext, LPVOID pBuffer, DWORD Count )

    {

     DWORD dwRetCount=0xffff; // default to error

     OutputDebugString(L"MyDriver - DEM_Read\n");

     OutputDebugString(L"hOpenContext - ");

     DBGOut(hOpenContext);

     OutputDebugString(L"\n");

     if (NULL != hMem) {

     dwRetCount=dwCount;

     memcpy(pBuffer,hMem,dwCount);

     }

     OutputDebugString(L"MyDriver - ~ DEM_Read\n");

     return dwRetCount;

    }

DWORD DEM_Write( DWORD hOpenContext, LPCVOID pBuffer, DWORD Count )

    {

     OutputDebugString(L"MyDriver - DEM_Write\n");

     OutputDebugString(L"hOpenContext - ");

     DBGOut(hOpenContext);

     OutputDebugString(L"\n");

     if (NULL != hMem) {

     LocalFree(hMem);

     }

     hMem=LocalAlloc(LPTR,Count);

     memcpy(hMem,pBuffer,Count);

     dwCount=Count;

     OutputDebugString(L"MyDriver - ~ DEM_Write\n");

     return Count;

    }

DWORD DEM_Seek( DWORD hOpenContext, long Amount, WORD Type )

    {

     OutputDebugString(L"MyDriver - DEM_Seek\n");

     OutputDebugString(L"hOpenContext - ");

     DBGOut(hOpenContext);

     OutputDebugString(L"\n");

     OutputDebugString(L"MyDriver - ~ DEM_Seek\n");

     return 0;

    }

void DBGOut(DWORD dwValue)

    {

     TCHAR tcTemp[10];

     wsprintf(tcTemp,L"%ld",dwValue);

     OutputDebugString(tcTemp);

    }

    9. Add the declarations of the exposed functions. In the menu of Platform Builderchoose

    File->New Project or File -> File Tab ->Text File give the file a name such as

    MyDriver.def. The following graphics shows the content of the file

    LIBRARY MyDriver

EXPORTS

     DEM_Init

     DEM_Deinit

     DEM_Open

     DEM_Close

     DEM_IOControl

     DEM_PowerUp

     DEM_PowerDown

     DEM_Read

     DEM_Write

     DEM_Seek

    HintYou can find completed source code in MyDriver directory. This program only implement

    the interface of the stream driver and it doesnt interact with the hardware directly.

    10. Build the project, then choose Build->Open Build Release Directory”,input the

    following commanddumpbin /exports mydriver.dll. Make sure that the DLL functions have

    been exposed correctly as shown in the following graphics.

    11. Open project.reg in the Prameter View of PBadd the following definition: [HKEY_LOCAL_MACHINE\Drivers\BuiltIn\Sample]

     "Dll" = "mydriver.Dll"

     "Prefix" = "DEM"

     "Index" = dword:1

     "Order" = dword:0

     "FriendlyName" = "Demo Driver"

     "Ioctl" = dword:0

    HintThe section of registry information will conduct the system load mydriver.dll into

    device.exe when bootup. The prefix of the driver is DEMthe index is 1Then we can interact

    with the driver by calling functions such as CreateFile(LDEM1”……).

    2 Lab 2 Creating a test program for the driver 2.1 Objectives

    In this lab, you will learn:

    ? Interact with the driver using API provided by Windows CE 2.2 Prerequisites

    Same with lab 1.

    2.3 Anticipated Time

    15~30 minutes

    2.4 Detailed steps

    1. Create a typical Hello World application named as MyApp by choose File->New

    Project or File in the menu of PB

    2. Add functions to manipulate the driver

    void WriteToDriver( )

    {

     DWORD dwWritten;

     TCHAR *tcString=L"Demo String...";

     HANDLE

    hDrv=CreateFile(L"DEM1:",GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_

    ATTRIBUTE_NORMAL,NULL);

     if (INVALID_HANDLE_VALUE == hDrv) {

     OutputDebugString(L"Failed to open Driver...\n");

     } else {

     WriteFile(hDrv,(LPVOID)tcString,lstrlen(tcString)*sizeof(TCHAR

    ),&dwWritten,NULL);

     }

     CloseHandle(hDrv);

    }

void ReadFromDriver( )

    {

     DWORD dwRead;

     TCHAR tcTemp[30];

     HANDLE

    hDrv=CreateFile(L"DEM1:",GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_A

    TTRIBUTE_NORMAL,NULL);

     if (INVALID_HANDLE_VALUE == hDrv) {

     OutputDebugString(L"Failed to open Driver...\n");

     } else {

     memset(tcTemp,0x00,30*sizeof(TCHAR));

     ReadFile(hDrv,tcTemp,30,&dwRead,NULL);

     MessageBox(NULL,tcTemp,L"Demo Data",MB_OK);

     }

     CloseHandle(hDrv);

    }

void HandleIOCTL( )

    {

     HANDLE

    hDrv=CreateFile(L"DEM1:",GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_

    ATTRIBUTE_NORMAL,NULL);

     TCHAR tcBuffer[10];

     DWORD dwBytesReturned;

     lstrcpy(tcBuffer,L"Hello");

     BOOL bRet=DeviceIoControl(

     hDrv,

     IOCTL_DRIVER_DEMO,

     tcBuffer,

     lstrlen(tcBuffer)*sizeof(TCHAR),

     tcBuffer,

     lstrlen(tcBuffer)*sizeof(TCHAR),

     &dwBytesReturned,

     NULL);

     MessageBox(NULL,tcBuffer,L"IOCTL Test",MB_OK);

     CloseHandle(hDrv);

}

    HintIn this code, all of the three new functions manipulate the driver by calling the Windows CE

    AP. The functions utilized are CreateFileCloseHandle and DeviceIoControlYou can find

Report this document

For any questions or suggestions please email
cust-service@docsford.com