Windows98&2k&NT
1996年的Windows Hardware Engineering Conference(WinHEC)会议上,Microsoft宣布了一种新的Windows设备驱动程序模型――Win32 Driver Model(WDM)。这种新的设备驱动程序模型将成为Windows 2000(即Windows NT 5.0)的核心。
这个消息令从事Windows设备驱动程序(VxD)开发的程序员感到沮丧(虽然大家早已预料到Windows系列与Windows NT系列最终将走到一起)。WDM将vxd的开发人员带到了一个新的起点上,什么都是新的:新的模式,新的观点。如果你曾看过DDK的汇编代码的话,你一定可以体会这个消息对VxD开发者是个沉重的打击,而对于Windows NT设备驱动程序(Kernel Mode Driver)的开发者来说,却是另一番心情――因为WDM基本等于Kernel Mode Driver+Plug and Play。
VxD将让位于WDM,现在令我们欣慰的是Microsoft宣布Windows 98(Windows 98支持VxD,推荐使用WDM方式驱动,但有些设备,如打印机等还不能用它,微软预先设想的是Windows98和Windows 2k x86版在WDM驱动上可以二进制码兼容,但实际上没有完全实现)可能会坚持到200X年(天知道,估计也就是三两年)。在这期间,掌握VxD技术的你还是可以主动要求老板给你加薪的。即使到了WDM一统天下之时,也不用灰心,因为无论是VxD还是WDM,都要求开发人员对计算机硬件有着全面而细致的了解。通过VxD的锻炼,你至少熟悉了计算机的硬件资源并对保护模式有了比较深刻的认识,这些东西都是将来从事WDM开发的硬功夫。
好了,该说说Windows NT了。在Windows NT中,80386保护模式的“保护”比Windows 95中更坚固,这个“镀金的笼子”更加结实,更加难以打破。在Windows 95中,至少应用程序I/O操作是不受限制的,而在Windows NT中,我们的应用程序连这点权限都被剥夺了。在NT中几乎不太可能进入真正的ring0层。
在Windows NT中,存在三种Device Driver:
1.“Virtual device Driver” (VDD)。通过VDD,16位应用程序,如DOS 和Win16应用程序可以访问特定的I/O端口(注意,不是直接访问,而是要通过VDD来实现访问)。
2.“GDI Driver”,提供显示和打印所需的GDI函数。
3.“Kernel Mode Driver”,实现对特定硬件的操作,比如说CreateFile, CloseHandle (对于文件对象而言), ReadFile, WriteFile, DeviceIoControl 等操作。“Kernel Mode Driver”还是Windows NT中唯一可以对硬件中断和DMA进行操作的Driver。SCSI 小端口驱动和 网卡NDIS 驱动都是Kernel Mode Driver的一种特殊形式。
Visual studio11与Windows8带来格外不同的新体验
1.启动Vs11
2.看见满目的驱动开发模板
3.选择一个驱动模式,有内核模式与用户模式两种的驱动
4.创建一个驱动程序,UMDF Driver2
5.可以看见驱动工程与驱动安装工程
6.编译驱动
7.选择继续调试
8.选择用户模式进行调试
9.设备代码描述如下
/*++ Module Name: Device.cpp Abstract: This module contains the implementation of the device driver. Environment: Windows User-Mode Driver Framework (WUDF) --*/ #include "internal.h" #include "device.tmh" HRESULT CMyDevice::CreateInstanceAndInitialize( __in IWDFDriver *FxDriver, __in IWDFDeviceInitialize * FxDeviceInit, __out CMyDevice **Device ) /*++ Routine Description: This method creates and initializs an instance of the driver's device callback object. Arguments: FxDeviceInit - the settings for the device. Device - a location to store the referenced pointer to the device object. Return Value: Status --*/ { // // Create a new instance of the device class // CComObject<CMyDevice> *pMyDevice = NULL; HRESULT hr = S_OK; TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DEVICE, "%!FUNC! Entry"); hr = CComObject<CMyDevice>::CreateInstance( &pMyDevice ); if (FAILED(hr)) { TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE, "%!FUNC! Failed to create device instance %!hresult!", hr); goto Exit; } // // Initialize the instance. This calls the WUDF framework, // which keeps a reference to the device interface for the lifespan // of the device. // hr = pMyDevice->Initialize(FxDriver, FxDeviceInit); if (FAILED(hr)) { TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE, "%!FUNC! Failed to initialize device %!hresult!", hr); goto Exit; } *Device = pMyDevice; Exit: TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DEVICE, "%!FUNC! Exit"); return hr; } HRESULT CMyDevice::Initialize( __in IWDFDriver * FxDriver, __in IWDFDeviceInitialize * FxDeviceInit ) /*++ Routine Description: This method initializes the device callback object and creates the partner device object. The method should perform any device-specific configuration that: * could fail (these can't be done in the constructor) * must be done before the partner object is created -or- * can be done after the partner object is created and which aren't influenced by any device-level parameters the parent (the driver in this case) might set. Arguments: FxDeviceInit - the settings for this device. Return Value: status. --*/ { IWDFDevice *fxDevice = NULL; HRESULT hr = S_OK; IUnknown *unknown = NULL; TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DEVICE, "%!FUNC! Entry"); // // Configure things like the locking model before we go to create our // partner device. // // // Set the locking model. // FxDeviceInit->SetLockingConstraint(None); // // Set power policy ownership. // FxDeviceInit->SetPowerPolicyOwnership(TRUE); // // Any per-device initialization which must be done before // creating the partner object. // // // Create a new FX device object and assign the new callback object to // handle any device level events that occur. // // // We pass an IUnknown reference to CreateDevice, which takes its own // reference if everything works. // hr = this->QueryInterface(__uuidof(IUnknown), (void **)&unknown); if (FAILED(hr)) { TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE, "%!FUNC! Failed to get IUnknown %!hresult!", hr); goto Exit; } hr = FxDriver->CreateDevice(FxDeviceInit, unknown, &fxDevice); DriverSafeRelease(unknown); if (FAILED(hr)) { TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE, "%!FUNC! Failed to create a framework device %!hresult!", hr); goto Exit; } // // Set our FxDevice member variable. // m_FxDevice = fxDevice; // // Drop the reference we got from CreateDevice. Since this object // is partnered with the framework object they have the same // lifespan - there is no need for an additional reference. // DriverSafeRelease(fxDevice); Exit: TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DEVICE, "%!FUNC! Exit"); return hr; } HRESULT CMyDevice::Configure( VOID ) /*++ Routine Description: This method is called after the device callback object has been initialized and returned to the driver. It would setup the device's queues and their corresponding callback objects. Arguments: FxDevice - the framework device object for which we're handling events. Return Value: status --*/ { HRESULT hr = S_OK; TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DEVICE, "%!FUNC! Entry"); // // Create and configure the I/O queue // hr = CMyIoQueue::CreateInstanceAndInitialize(m_FxDevice, this, &m_IoQueue); if (FAILED(hr)) { TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE, "%!FUNC! Failed to create and initialize queue %!hresult!", hr); goto Exit; } hr = m_IoQueue->Configure(); if (FAILED(hr)) { TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE, "%!FUNC! Failed to configure queue %!hresult!", hr); goto Exit; } // // Create Device Interface // hr = m_FxDevice->CreateDeviceInterface(&GUID_DEVINTERFACE_UMDFDriverMVP,NULL); if (FAILED(hr)) { TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE, "%!FUNC! Failed to create device interface %!hresult!", hr); goto Exit; } Exit: TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DEVICE, "%!FUNC! Exit"); return hr; } HRESULT CMyDevice::OnPrepareHardware( __in IWDFDevice * /* FxDevice */ ) /*++ Routine Description: This routine is invoked to ready the driver to talk to hardware. Arguments: FxDevice : Pointer to the WDF device interface Return Value: HRESULT --*/ { TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DEVICE, "%!FUNC! Entry"); TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DEVICE, "%!FUNC! Exit"); return S_OK; } HRESULT CMyDevice::OnReleaseHardware( __in IWDFDevice * /* FxDevice */ ) /*++ Routine Description: This routine is invoked when the device is being removed or stopped It releases all resources allocated for this device. Arguments: FxDevice - Pointer to the Device object. Return Value: HRESULT - Always succeeds. --*/ { TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DEVICE, "%!FUNC! Entry"); TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DEVICE, "%!FUNC! Exit"); return S_OK; }
10.驱动描述代码如下
/*++ Module Name: Driver.cpp Abstract: This module contains the implementation of the core driver callback object. Environment: Windows User-Mode Driver Framework (WUDF) --*/ #include "internal.h" #include "driver.tmh" HRESULT CMyDriver::OnDeviceAdd( __in IWDFDriver *FxWdfDriver, __in IWDFDeviceInitialize *FxDeviceInit ) /*++ Routine Description: The FX invokes this method when it wants to install our driver on a device stack. This method creates a device callback object, then calls the Fx to create an Fx device object and associate the new callback object with it. Arguments: FxWdfDriver - the Fx driver object. FxDeviceInit - the initialization information for the device. Return Value: status --*/ { HRESULT hr = S_OK; CMyDevice *device = NULL; // // Create device callback object // hr = CMyDevice::CreateInstanceAndInitialize(FxWdfDriver, FxDeviceInit, &device); // // Call the device's construct method. This // allows the device to create any queues or other structures that it // needs now that the corresponding fx device object has been created. // if (SUCCEEDED(hr)) { hr = device->Configure(); } return hr; }
11.用户模式的Dl代码如下
/*++ Module Name: Dllsup.cpp Abstract: This module contains the implementation of the Driver DLL entry point. Environment: Windows User-Mode Driver Framework (WUDF) --*/ #include "internal.h" #include "dllsup.tmh" // // This GUID must match the DriverCLSID value for the service binary in the INF. // For more information see http://msdn.microsoft.com/en-us/library/ff560526(VS.85).aspx // 650f6cd9-7f41-4e8c-b344-85385c57d632 // const CLSID CLSID_Driver = {0x650f6cd9,0x7f41,0x4e8c,{0xb3,0x44,0x85,0x38,0x5c,0x57,0xd6,0x32}}; HINSTANCE g_hInstance = NULL; class CMyDriverModule : public CAtlDllModuleT< CMyDriverModule > { }; CMyDriverModule _AtlModule; // // DLL Entry Point // extern "C" BOOL WINAPI DllMain( HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved ) { if (dwReason == DLL_PROCESS_ATTACH) { WPP_INIT_TRACING(MYDRIVER_TRACING_ID); g_hInstance = hInstance; DisableThreadLibraryCalls(hInstance); } else if (dwReason == DLL_PROCESS_DETACH) { WPP_CLEANUP(); } return _AtlModule.DllMain(dwReason, lpReserved); } // // Returns a class factory to create an object of the requested type // STDAPI DllGetClassObject( __in REFCLSID rclsid, __in REFIID riid, __deref_out LPVOID FAR* ppv ) { return _AtlModule.DllGetClassObject(rclsid, riid, ppv); }
赶紧下载VS11体验吧
http://www.microsoft.com/click/services/Redirect2.ashx?CR_CC=200098144