Õª Òª:±¾ÎĽéÉÜÁËWindows 2000 WDMÇý¶¯³ÌÐò½á¹¹¼°ÆäÔÀí£¬¸ø³öÒ»¸öÇý¶¯³ÌÐòµÄÀý×Ó
¹Ø¼ü´Ê: WDM Çý¶¯³ÌÐò
1.¸ÅÊö ÒýÈëÁËȫеÄWDM (Win32 Driver Model)µÄÇý¶¯³ÌÐò¼Ü¹¹£¬ËµÊÇм¼Êõ£¬ÆäʵÔçÔÚ1997ÄêMicrosoft¾ÍÌá³öÁ˸ÃÏî¼¼Êõ²¢ÔÚWindows 98Öеõ½Á˳ä·ÖµÄÓ¦Ó㬻»¾ä»°Ëµ£¬Windows 98Ò²Ö§³ÖWDM¡£ÕâÑùWDM¾Í³ÉΪÁËÒ»¸ö¿çƽ̨µÄÇý¶¯³ÌÐòÄ£ÐͲ»½öÈç´ËWDMÇý¶¯³ÌÐò»¹¿ÉÒÔÔÚ²»ÐÞ¸ÄÔ´´úÂëµÄÇé¿öϾ¹ýÖØÐ±àÒëºóÔÚ·ÇIntelƽ̨ÉÏÔËÐС£
2£®WDMÉ豸Çý¶¯³ÌÐòµÄÌØµãºÍÔÀí
2.1ͨÓÃÇý¶¯³ÌÐò
¶Ô»ù±¾ÉÏÒ»ÑùµÄÓ²¼þ£¬ÒòΪËûÃǹ²ÏíÒ»¸ö×ÜÏß»òÍê³ÉÀàËÆµÄÈÎÎñ£¬É豸Çý¶¯³ÌÐò¿ÉÒÔʹÓÃÕâЩ±ê×¼µÄÇý¶¯³ÌÐò¹¦ÄÜ£¬Ê¹¹«¹²×ÜÏߵĹ²ÏíÈÝÒ×£¬ÇÒ¸üÈÝÒ×д³öеÄÇý¶¯³ÌÐò£¬×ÜÏßÇý¶¯³ÌÐò£¬ÈçUSB¡¢1394£¬ºÍÀàÇý¶¯³ÌÐò¡£
(1)Win32³ÌÐò½Ó¿Ú£º ¿ÉÒÔʹÓÃWin32º¯ÊýÏñ·ÃÎÊÎļþÄÇÑù·ÃÎÊÉ豸
CreateFile() ¡¢Closehandle()¡¢ReadFile()¡¢WriteFile()¡¢DeviceIoControl£¨£©ÓÃÓÚ
·¢³öÌØÊâÇëÇ󣬿ɷ¢ËÍÊý¾Ý¸øÇý¶¯ºÍ´ÓÇý¶¯µÃµ½Êý¾Ý£¬IOCTL´úÂë¿ÉÒÔÊÇÔ¤Ïȶ¨ÒåµÄÒ²¿ÉÊÇ×Ô¼º¶¨ÒåµÄ¡£
(2)´´½¨É豸 ´ó¶àÊýWDMÉ豸¶ÔÏó¶¼ÊÇÔÚPnP¹ÜÀíÆ÷Öе÷ÓÃAddDeviceÈë¿Úʱ´´½¨£¬Õâ¸öPnP Àý³ÌÔÚ²åÈëÐÂÉ豸ºÍ°²×°InfÎļþʱ±»µ÷Ó㬴˺óһϵÁеÄPnP IRP±»·¢Ë͵½Çý¶¯³ÌÐò£¬Ö¸Ê¾É豸ӦÈçºÎÆô¶¯ºÍ²éѯËüµÄ¹¦ÄÜ
2.2WDM-µÄ¹¤×÷ÔÀí
WDMÊÇÔÚNT 4.0Çý¶¯³ÌÐò½á¹¹ÉÏ·¢Õ¹ÆðÀ´µÄ£¬ËùÒÔËüÓëNT 4.0Çý¶¯³ÌÐò¼«ÎªÏàËÆ ,µ«ÊÇËüÈ´ÓÐÁ˱¾ÖÊÉϵÄÌá¸ß£¬±ÈÈçËüÖ§³ÖUSB¡¢IEEE 1394¡¢ACPIµÈȫеÄÓ²¼þ±ê×¼¡£ ËäÈ»Windows 98ÓëWindows 2000¶¼Ö§³ÖWDM£¬¿ÉÊDz¢²»Òâζ×ÅWindows 98ϵÄVxD¿ÉÒÔÔÚ Windows 2000ÏÂÔËÐУ¬¶øNTϵÄWDMÈ´¿ÉÒÔÔÚWindows 98ÏÂÔËÐС£²»¹ýÔÏÈ×¼±¸ÔÚÁ½¸öƽ̨ÉÏͬʱÔËÐÐÐèÒª±àдÁ½¸ö½ØÈ»²»Í¬µÄÇý¶¯³ÌÐò£¬¶øÏÖÔÚÖ»ÐèÒª±àдһ¸öWDMÇý¶¯³ÌÐò¾Í ¿ÉÒÔÁË¡£Í¬NT 4.0Çý¶¯³ÌÐòÒ»Ñù£¬WDMÇý¶¯³ÌÐòÒ²ÊÇ·Ö²ãµÄ£¬¼´²»Í¬²ãÉϵÄÇý¶¯³ÌÐòÓÐ×Ų»Í¬µÄÓÅÏÈȨ£¬¶øWindows 9xϵÄVxDÔòûÓд˽ṹ¡£ÁíÍ⣬WDM»¹ÒýÈëÁ˹¦ÄÜÉ豸¶ÔÏó FDO£¨functional device object£©ÓëÎïÀíÉ豸¶ÔÏóPDO£¨physical device object£©Á½ ¸öиÅÄîÀ´ÃèÊöÓ²¼þ£¬Ò»¸öPDO´ú±íÒ»¸öÕæÊµÓ²¼þ£¬ÔÚÇý¶¯³ÌÐò¿´À´ÔòÊÇÒ»¸öFDO ¡£ ÁíÍâÖµµÃ×¢ÒâµÄÊÇ£¬Ò»¸öÓ²¼þÖ»ÔÊÐíÓÐÒ»¸öPDO£¬µ«È´¿ÉÒÔÓµÓжà¸öFDO£¬¶øÔÚÇý¶¯³ÌÐòÖÐÎÒÃDz»ÊÇÖ±½Ó²Ù×÷Ó²¼þ¶øÊDzÙ×÷ÏàÓ¦µÄPDOÓëFDO¡£ÔÚRing-3ÓëRing-0ͨѶ·½Ã棬²Ù×÷ϵͳΪÿһ¸öÓû§ÇëÇó´ò°ü³ÉÒ»¸öIRP£¨IO Request Packet£©½á¹¹£¬½«Æä·¢ËÍÖÁÇý¶¯³ÌÐò²¢Í¨¹ýʶ±ðIRPÖеÄPDOÀ´Ê¶±ðÊÇ·¢Ë͸øÄÄÒ»¸öÉ豸µÄ¡£ÁíÍ⣬ÔÚÇý¶¯³ÌÐòµÄ¼ÓÔØ·½ÃæWDM¼È²»¿¿Çý¶¯³ÌÐòÃû³ÆÒ²²»¿¿Ò»¸ö¾ßÓÐijÖÖÌØÊâÒâÒåµÄID£¬¶øÊÇÒÀ¿¿Ò»¸ö128λµÄGUIDÀ´Ê¶±ðÇý¶¯³ÌÐò£¨WindowsÏÂÐí¶à¶«Î÷¶¼ÊÇ¿¿´Ë½øÐÐʶ±ðµÄ£©¡£
2.3¡¡IRP´¦Àí
I/OÇëÇó°üIRPÊÇÇý¶¯³ÌÐò²Ù×÷µÄÖÐÐÄ£¬IRPÊÇÒ»¸öÄں˶ÔÏó£¬ËüÊÇÔ¤Ïȶ¨ÒåºÃµÄÊý¾Ý½á¹¹£¬´øÓÐÒ»×é¶ÔËü½øÐвÙ×÷µÄI/O¹ÜÀíÆ÷Àý³Ì£¬I/O¹ÜÀíÆ÷½ÓÊÜÒ»¸öI/OÇëÇó£¬È»ºó½«Ëü´«Ë͵½ºÏÊʵÄÇý¶¯³ÌÐòÕ»ÖеÄ×î¸ßÇý¶¯³ÌÐò֮ǰ£¬·ÖÅä²¢´¦Ê¼»¯Ò»¸öIRP£¬Ã¿¸öI/OÇëÇóÓÐÖ÷¹¦ÄÜ´úÂë
2.4 IRP²ÎÊý
±ÈÈçÒ»¸öдµÄI/OÇëÇóת»»³ÉÒ»¸öIRPʱ£¬I/O¹ÜÀíÆ÷ÌîдÖ÷ÒªµÄIRPÊײ¿£¬²¢¹¹ÔìµÚÒ»¸ö¸öÕ»µ¥Ôª£¬¶ÔдÇëÇóÀ´½²£¬Êײ¿°üº¬Óû§»º³åÇøÐÅÏ¢£¬¶øÕ»µ¥ÔªÔò°üº¬Ð´µÄ¾ßÌå²ÎÊý¡£Èç¹ûµ÷ÓÃÁíÒ»¸öÇý¶¯Ôò±ØÐë´´½¨ÏÂÒ»¸öÕ»µ¥Ôª¡£
Ò»¸öIRPµ½Õ»¶¥Ê±£¬Ê¹ÓÃPIO_STACK_LOCATION
IoGetCurrentIrpStackLocation(
IN PIRP Irp
);IoGetCurrentIrpStackLocation returns a pointer to the caller's stack location in the given IRP¡£
Èç¾ö¶¨ÐèÒª°ÑÕâ¸öIRPÑØÉ豸ջÏòÏ´«µÝ£¬Ê¹ÓÃIoCopyCurrentIrpStackLocationToNext or IoSkipCurrentIrpStackLocation¼òµ¥µÄ½«ÄÚÈݸ´ÖƵ½ÏÂÒ»¸öµ¥Ôª£¬Èç¹ûÒª¸ü¸ÄÏÂÒ»¸öÕ»µ¥Ôª£¬ÒªÊ¹ÓÃLOCATION
IoGetNextIrpStackLocation(IN PIRP Irp );
IoGetNextIrpStackLocation gives a higher level driver access to the next-lower driver's I/O stack location in an IRP so the caller can set it up for the lower driver.
¿ÉʹÓÃIoCallDriverµ÷ÓÃÏÂÒ»¸öÇý¶¯³ÌÐò£¬µ±×îµÍÒ»²ãµÄÇý¶¯´¦ÀíÍæºóµ÷ÓÃIoCompleteRequest£¬IRPÔÙÏòÉÏ´«µÝ·µ»ØÓû§£¬µ±IRPÏòÉÏ´«µÝʱҲ¿ÉÒÔÿ¸öÇý¶¯Óлú»áÔÙ´¦ÀíËü£¬Ã¿¸öÇý¶¯ÒªÉèÖÃIoSetCompletionRoutine¹Ò½ÓÒ»¸öÀý³Ì £¬Ò»¸öÇý¶¯²»Ò»¶¨ÒªÑØ×ÅÉ豸ջÏòÏ´«µÝIRP£¬Èç¹û×Ô¼ºÄÜ´¦Àí¾Í¾ÍʹÓÃIoCompleteRequestÍê³ÉIrP
2.5 É豸½Ó¿Ú
Óû§Ì¬Ê¹ÓÃWin32 CreateFile·ÃÎÊÇý¶¯³ÌÐò£¬dwShareModeΪ0ʱÀ´ÇëÇó¶ÀÕ¼Äں˶ÔÏóÔÚÉ豸¶ÔÏóDEVICE_OBJECT½á¹¹Öд洢É豸µÄÐÅÏ¢£¬¶ÔÓÚÓëÉ豸µÄÿ¸ö½»»¥£¬Ïà¹ØµÄDEVICE_OBJECT±»´«µÝ¸øÇý¶¯µÄ»Øµ÷Àý³Ì¡££¬µ«ÊÇ¿ª·¢Õß¿ÉÒÔÀ©Õ¹É豸½á¹¹£¬³ÆÎªÉ豸À©Õ¹
ÔÚPnP IRPÖÐÎÒÃǼÓÔØÉ豸NTSTATUS Wdm1AddDevice( IN PDRIVER_OBJECT DriverObject,Ö¸ÏòÇý¶¯³ÌÐòµÄÖ¸Õë IN PDEVICE_OBJECT pdoÖ¸ÏòÎïÀíÉ豸µÄÖ¸Õë)
{ DebugPrint("AddDevice");
status = IoCreateDevice (DriverObject,´´½¨É豸
sizeof(WDM1_DEVICE_EXTENSION),
NULL, // No Name
FILE_DEVICE_UNKNOWN,
0,
FALSE, // Not exclusive£¬TRUEΪ¶ÀÕ¼
&fdo·µ»ØµÄÐÂÉ豸¶ÔÏó);
if( !NT_SUCCESS(status)
return status;
IoAttachDeviceToDeviceStack(fdo,pdo);ÓëÉ豸ջ¹Ò½Ó
2.6¡¡É¾³ýÉ豸
NTSTATUS Wdm1Pnp( IN PDEVICE_OBJECT fdo,
IN PIRP Irp)
PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(Irp);
ULONG MinorFunction = IrpStack->MinorFunction;
if( MinorFunction==IRP_MN_REMOVE_DEVICE)
{
DebugPrint("PnP RemoveDevice"); // disable device interface
IoSetDeviceInterfaceState(&dx->ifSymLinkName, FALSE);
RtlFreeUnicodeString(&dx->ifSymLinkName);
// unattach from stack´ÓÉ豸ջÍÑÀë
if (dx->NextStackDevice)
IoDetachDevice(dx->NextStackDevice);
// delete our fdoɾ³ýÉ豸
IoDeleteDevice(fdo);
¡¡}
CreateFile IRP_MJ_Create WriteFile MJ_WRITE
CloseHandle MJ_CLOSE DeviceIoControl MJ_DEVICEIOCONTROL
ReadFile
MJ_CLOSEËùÓеķַ¢Àý³Ì¶¼ÓÐÏàͬµÄº¯ÊýÔÐÍ£¬¾ùÐè´«µÝÒ»¸öÉ豸¶ÔÏóµÄÖ¸ÕëºÍIRP£¬IRPÓÉIRPÊײ¿ºÍһϵÁеÄÕ»µ¥Ôª×é³É£¬Ã¿¸öÕ»µ¥ÔªÊÇÒ»¸öIO_STACK_LOCATION½á¹¹£¬Êײ¿ºÍÕ»µ¥ÔªÖ¸³öÒª×÷µÄ¶¯×÷ £¬Õ»ÖÐÓÐÖ÷ÒªµÄÖØÒª²ÎÊýÈçMajorFunctionºÍMinorFunction£¬Ã¿¸öÇý¶¯Ö»ÈÏʶһ¸öÕ»µ¥Ôª¡£
2.7¡¡¼´²å¼´ÓÃ
Çý¶¯±ØÐëÓÐAddDeviceÀý³Ì²¢´¦Àí¸÷ÖÖPnP IRP£º
IRP_MN_START_DEVICE·ÖÅä×ÊÔ´²¢Æô¶¯Ò»¸öÉ豸¡£
IRP_MN_STOP_DEVICE Í£Ö¹É豸½øÐÐ×ÊÔ´ÖØÐ·ÖÅä¡£