To create a device driver, you can add a subproject for a Windows Embedded CE DLL to your OS design, but the most common way to do it is to add the device driver's source files inside the Drivers folder of the Board Support Package (BSP). For detailed information about configuring Windows Embedded CE subprojects, see Chapter 1, "Customizing the Operating System Design."<\/p>
A good starting point for a device driver is A Simple Windows Embedded CE DLL Subproject, which you can select on the Auto-Generated Subproject Files page in the Windows Embedded CE Subproject Wizard. It automatically creates a source code file with a definition for the DllMain entry point for the DLL, various parameter files, such as empty module-definition (.def) and registry (.reg) files, and preconfigures the Sources file to build the target DLL. For more detailed information about parameter files and the Sources file, see Chapter 2, "Building and Deploying a Run-Time Image."<\/p>
Implementing Stream Functions<\/p> <\/div>
Having created the DLL subproject, you can open the source code file in Visual Studio and add the required functions to implement the stream interface and required driver functionality. The following code listing shows the definition of the stream interface functions.<\/p>
// SampleDriver.cpp : Defines the entry point for the DLL application.<\/code> <\/p>
//<\/code> <\/p>
#include "stdafx.h"<\/code> <\/p>
BOOL APIENTRY DllMain(HANDLE hModule,<\/code> <\/p>
DWORD ul_reason_for_call, LPVOID lpReserved) {<\/code> <\/p>
return TRUE;<\/code> <\/p>
}<\/code> <\/p>
DWORD SMP_Init(LPCTSTR pContext, LPCVOID lpvBusContext) {<\/code> <\/p>
// Implement device context initialization code here.<\/code> <\/p>
return 0x1;<\/code> <\/p>
}<\/code> <\/p>
BOOL SMP_Deinit(DWORD hDeviceContext) {<\/code> <\/p>
// Implement code to close the device context here.<\/code> <\/p>
return TRUE;<\/code> <\/p>
}<\/code> <\/p>
DWORD SMP_Open(DWORD hDeviceContext, DWORD AccessCode, DWORD ShareMode) {<\/code> <\/p>
// Implement open context initialization code here.<\/code> <\/p>
return 0x2;<\/code> <\/p>
}<\/code> <\/p>
BOOL SMP_Close(DWORD hOpenContext) {<\/code> <\/p>
// Implement code to close the open context here.<\/code> <\/p>
return TRUE;<\/code> <\/p>
}<\/code> <\/p>
DWORD SMP_Write(DWORD hOpenContext, LPCVOID pBuffer, DWORD Count) {<\/code> <\/p>
// Implement the code to write to the stream device here.<\/code> <\/p>
return Count;<\/code> <\/p>
}<\/code> <\/p>
DWORD SMP_Read(DWORD hOpenContext, LPVOID pBuffer, DWORD Count) {<\/code> <\/p>
// Implement the code to read from the stream device here.<\/code> <\/p>
return Count;<\/code> <\/p>
}<\/code> <\/p>
BOOL SMP_IOControl(DWORD hOpenContext, DWORD dwCode,<\/code> <\/p>
PBYTE pBufIn, DWORD dwLenIn, PBYTE pBufOut,<\/code> <\/p>
DWORD dwLenOut, PDWORD pdwActualOut) {<\/code> <\/p>
// Implement code to handle advanced driver actions here.<\/code> <\/p>
return TRUE;<\/code> <\/p>
}<\/code> <\/p>
void SMP_PowerUp(DWORD hDeviceContext) {<\/code> <\/p>
// Implement power management code here or use IO Control.<\/code> <\/p>
return;<\/code> <\/p>
}<\/code> <\/p>
void SMP_PowerDown(DWORD hDeviceContext) {<\/code> <\/p>
// Implement power management code here or use IO Control.<\/code> <\/p>
return;<\/code> <\/p>
}<\/code> <\/p>
Exporting Stream Functions<\/p> <\/div>
Making the stream functions in the driver DLL accessible to external applications requires the linker to export the functions during the build process. C++ provides several options to accomplish this, yet for driver DLLs compatible with Device<\/p>
Manager, you must export the functions by defining them in the .def file of the DLL subproject. The linker uses the .def file to determine which functions to export and how to do so. For a standard stream driver, you must export the stream interface functions using the prefix that you specify in the driver's source code and registry settings. Figure 6-3 shows a sample .def file for the stream interface skeleton listed in the previous section.<\/p> 