鏈変袱縐嶆柟寮忓彲浠ヨ璁懼鍜屽簲鐢ㄧ▼搴忎箣闂磋仈緋伙細

1.         閫氳繃涓鴻澶囧垱寤虹殑涓涓鍙烽摼錛?/span>

2.         閫氳繃杈撳嚭鍒頒竴涓帴鍙?/span>

WDM椹卞姩紼嬪簭寤鴻浣跨敤杈撳嚭鍒頒竴涓帴鍙h屼笉鎺ㄨ崘浣跨敤鍒涘緩絎﹀彿閾劇殑鏂規硶銆傝繖涓帴鍙d繚璇?/span>PDO鐨勫畨鍏紝涔熶繚璇佸畨鍏ㄥ湴鍒涘緩涓涓儫涓鐨勩佺嫭绔嬩簬璇█鐨勮闂澶囩殑鏂規硶銆?/span>

涓涓簲鐢ㄧ▼搴忎嬌鐢?/span>Win32APIs鏉ヨ皟鐢ㄨ澶囥傚湪鏌愪釜Win32 APIs鍜岃澶囧璞$殑鍒嗗彂鍑芥暟涔嬮棿瀛樺湪涓涓槧灝勫叧緋匯?/span>

鑾峰緱瀵硅澶囧璞¤闂殑絎竴姝ュ氨鏄墦寮涓涓澶囧璞$殑鍙ユ焺銆?/span>

鐢ㄧ鍙烽摼鎵撳紑涓涓澶囩殑鍙ユ焺

涓轟簡鎵撳紑涓涓澶囷紝搴旂敤紼嬪簭闇瑕佷嬌鐢?/span>CreateFile銆?/span>濡傛灉璇ヨ澶囨湁涓涓鍙烽摼鍑哄彛錛屽簲鐢ㄧ▼搴忓彲浠ョ敤涓嬮潰榪欎釜渚嬪瓙鐨勫艦寮忔墦寮鍙ユ焺錛?/span>

hDevice = CreateFile(""""".""OMNIPORT3",
  GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ,
  NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL ,NULL
);

鏂囦歡璺緞鍚嶇殑鍓嶇紑“""."”鍛婅瘔緋葷粺鏈皟鐢ㄥ笇鏈涙墦寮涓涓澶囥傝繖涓澶囧繀欏繪湁涓涓鍙烽摼錛屼互渚垮簲鐢ㄧ▼搴忚兘澶熸墦寮瀹冦傛湁鍏崇粏鑺傛煡鐪嬫湁鍏?/span>Kdevice鍜?/span>CreateLink鐨勫唴瀹廣傚湪涓婅堪璋冪敤涓涓涓弬鏁頒腑鍓嶇紑鍚庣殑閮ㄥ垎灝辨槸榪欎釜絎﹀彿閾劇殑鍚嶅瓧銆?/span>

娉ㄦ剰錛?/span>CreatFile涓殑絎竴涓弬鏁頒笉鏄?/span>Windows 98/2000涓┍鍔ㄧ▼搴?/span>(.sys鏂囦歡)鐨勮礬寰勩傛槸鍒拌澶囧璞$殑絎﹀彿閾俱?/span>

濡傛灉浣跨敤DriverWizard浜х敓椹卞姩紼嬪簭錛屽畠閫氬父浣跨敤綾?/span>KunitizedName鏉ユ瀯鎴愯澶囩殑絎﹀彿閾俱傝繖鎰忓懗鐫絎﹀彿閾懼悕鏈変竴涓檮鍔犵殑鏁板瓧錛岄氬父鏄?/span>0銆備緥濡傦細濡傛灉閾炬帴鍚嶇О鐨勪富騫叉槸LTestDevice”閭d箞鍦?/span>CreateFile涓殑涓插氨璇ユ槸“"""".""TestDevice0”銆?/span>

濡傛灉搴旂敤紼嬪簭闇瑕佽瑕嗙洊鐨?/span>I/O錛岀鍏釜鍙傛暟(Flags)蹇呴』鎴栦笂FILE_FLAG_OVERLAPPED銆?/span>

浣跨敤涓涓緭鍑烘帴鍙f墦寮鍙ユ焺

鐢ㄨ繖縐嶆柟寮忔墦寮涓涓彞鏌勪細紼嶅井楹葷儲涓浜涖?/span>DriverWorks搴撴彁渚涗袱涓姪鎵嬬被鏉ヤ嬌鑾峰緱瀵硅鎺ュ彛鐨勮闂鏄撲竴浜涳紝榪欎袱涓被鏄?/span>CDeviceInterface, 鍜?/span> CdeviceInterfaceClass銆?/span>

CdeviceInterfaceClass綾誨皝瑁呬簡涓涓澶囦俊鎭泦錛岃淇℃伅闆嗗寘鍚簡鐗規畩綾諱腑鐨勬墍鏈夎澶囨帴鍙d俊鎭?/span>

搴旂敤紼嬪簭鑳芥湁鐢?/span>CdeviceInterfaceClass綾葷殑涓涓疄渚嬫潵鑾峰緱涓涓垨鏇村鐨?/span>CdeviceInterface綾葷殑瀹炰緥銆?/span>CdeviceInterface綾繪槸涓涓崟涓璁懼鎺ュ彛鐨勬娊璞°傚畠鐨勬垚鍛樺嚱鏁?/span>DevicePath()榪斿洖涓涓礬寰勫悕鐨勬寚閽堬紝璇ユ寚閽堝彲浠ュ湪CreateFile涓嬌鐢ㄦ潵鎵撳紑璁懼銆?/span>

涓嬮潰鐢ㄤ竴涓皬渚嬪瓙鏉ユ樉紺鴻繖浜涚被鏈鍩烘湰鐨勪嬌鐢ㄦ柟娉曪細

extern GUID TestGuid;
HANDLE OpenByInterface(
  GUID* pClassGuid,
  DWORD instance,
  PDWORD pError
)
{
  CDeviceInterfaceClass DevClass(pClassGuid, pError);
  if (*pError != ERROR_SUCCESS)
    return INVALID_HANDLE_VALUE;
  CDeviceInterface DevInterface(&DevClass, instance, pError);
  if (*pError != ERROR_SUCCESS)
    return INVALID_HANDLE_VALUE;
  cout << "The device path is "
    << DevInterface.DevicePath()
    << endl;

  HANDLE hDev;
  hDev = CreateFile(
   DevInterface.DevicePath(),
    GENERIC_READ | GENERIC_WRITE,
    FILE_SHARE_READ | FILE_SHARE_WRITE,
    NULL,
    OPEN_EXISTING,
    FILE_ATTRIBUTE_NORMAL,
    NULL
  );
  if (hDev == INVALID_HANDLE_VALUE)
    *pError = GetLastError();
  return hDev;
}

鍦ㄨ澶囦腑鎵цI/O鎿嶄綔

涓鏃﹀簲鐢ㄧ▼搴忚幏寰椾竴涓湁鏁堢殑璁懼鍙ユ焺錛屽畠灝辮兘浣跨敤Win32 APIs鏉ヤ駭鐢熷埌璁懼瀵硅薄鐨?/span>IRPs銆備笅闈㈢殑琛ㄦ樉紺轟簡榪欑瀵瑰簲鍏崇郴銆?/span>

Win32 API

DRIVER_FUNCTION_xxx
IRP_MJ_xxx

KDevice subclass member function

CreateFile

CREATE

Create

ReadFile

READ

Read

WriteFile

WRITE

Write

DeviceIoControl

DEVICE_CONTROL

DeviceControl

CloseHandle

CLOSE
CLEANUP

Close
CleanUp

闇瑕佽В閲婁竴涓嬭澶囩被鎴愬憳鐨?/span>Close鍜?/span>CleanUp錛?/span>CreateFile浣垮唴鏍鎬負璁懼鍒涘緩涓涓柊鐨勬枃浠跺璞°傝繖浣垮緱澶氫釜鍙ユ焺鍙互鏄犲皠鍚屼竴涓枃浠跺璞°傚綋榪欎釜鏂囦歡瀵硅薄鐨勬渶鍚庝竴涓敤鎴風駭鍙ユ焺琚挙閿鍚庯紝I/O綆$悊鍣ㄨ皟鐢?/span>CleanUp銆傚綋娌℃湁浠諱綍鐢ㄦ埛綰у拰鏍稿績綰х殑瀵規枃浠跺璞$殑璁塊棶鐨勬椂鍊欙紝I/O綆$悊鍣ㄨ皟鐢?/span>Close銆?/span>

濡傛灉琚墦寮鐨勮澶囦笉鏀寔鎸囧畾鐨勫姛鑳斤紝鍒欒皟鐢ㄧ浉搴旂殑Win32灝嗗紩璧烽敊璇紙鏃犳晥鍔熻兘錛夈?/span>

浠ュ墠涓?/span>Windows95緙栧啓鐨?/span>VxD鐨勫簲鐢ㄧ▼搴忎唬鐮佷腑鍙兘浼氬湪鎵撳紑璁懼鐨勬椂鍊欎嬌鐢?/span>FILE_FLAG_DELETE_ON_CLOSE灞炴с傚湪Windows NT/2000涓紝寤鴻涓嶈浣跨敤榪欎釜灞炴э紝鍥犱負瀹冨皢瀵艱嚧娌℃湁鐗規潈鐨勭敤鎴蜂紒鍥炬墦寮榪欎釜璁懼錛岃繖鏄笉鍙兘鎴愬姛鐨勩?/span>

I/O綆$悊鍣ㄥ皢ReadFile鍜?/span>WriteFile鐨?/span>buff鍙傛暟杞崲鎴?/span>IRP鍩熺殑鏂規硶渚濊禆浜庤澶囧璞$殑灞炴с傚綋璁懼璁劇疆DO_DIRECT_IO鏍囧織錛?/span>I/O綆$悊鍣ㄥ皢buff閿佷綇鍦ㄥ瓨鍌ㄥ櫒涓紝騫朵笖鍒涘緩浜嗕竴涓瓨鍌ㄥ湪IRP涓殑MDL鍩熴備竴涓澶囧彲浠ラ氳繃璋冪敤Kirp::Mdl鏉ュ瓨鍙?/span>MDL銆?/span>

褰撹澶囪緗?/span>DO_BUFFERED_IO鏍囧織錛岃澶囧璞″垎鍒氳繃KIrp::BufferedReadDest鎴?/span> KIrp::BufferedWriteSource涓鴻鎴栧啓鎿嶄綔鑾峰緱buff鍦板潃銆?/span>

褰撹澶囦笉璁劇疆DO_BUFFERED_IO鏍囧織涔熶笉璁劇疆DO_DIRECT_IO錛屽唴鏍歌緗?/span>IRP 鐨?/span>UserBuffer鍩熸潵瀵瑰簲ReadFile鎴?/span>WriteFile涓殑buff鍙傛暟銆傜劧鑰岋紝瀛樺偍鍖哄茍娌℃湁琚攣浣忚屼笖鍦板潃鍙璋冪敤榪涚▼鏈夋晥銆傞┍鍔ㄧ▼搴忓彲浠ヤ嬌鐢?/span>KIrp::UserBuffer鏉ュ瓨鍙?/span>IRP鍩熴?/span>

瀵逛簬DeviceIoControl璋冪敤錛?/span>buffer鍙傛暟鐨勮漿鎹緷璧栦簬鐗規畩鐨?/span>I/O鎺у埗浠g爜錛屽畠涓嶅湪璁懼瀵硅薄鐨勭壒鎬т腑銆傚畯CTL_CODE錛堝湪winioctl.h涓畾涔夛級鐢ㄦ潵鏋勯犳帶鍒朵唬鐮併傝繖涓畯鐨勫叾涓竴涓弬鏁版寚鏄庣紦鍐叉柟娉曟槸METHOD_BUFFERED, METHOD_IN_DIRECT, METHOD_OUT_DIRECT, 鎴?/span>METHOD_NEITHER銆備笅闈㈢殑琛ㄦ樉紺轟簡榪欎簺鏂規硶鍜屼笌涔嬪搴旂殑鑳借幏寰楄緭鍏ョ紦鍐蹭笌杈撳嚭緙撳啿鐨?/span>KIrp涓殑鎴愬憳鍑芥暟錛?/span>

Method

Input Buffer Parameter

Output Buffer Parameter

METHOD_BUFFERED

KIrp::IoctlBuffer

KIrp::IoctlBuffer

METHOD_IN_DIRECT

KIrp::IoctlBuffer

KIrp::Mdl

METHOD_OUT_DIRECT

KIrp::IoctlBuffer

KIrp::Mdl

METHOD_NEITHER

KIrp::IoctlType3InputBuffer

KIrp::UserBuffer

濡傛灉鎺у埗浠g爜鎸囨槑METHOD_BUFFERED錛岀郴緇熷垎閰嶄竴涓崟涓鐨勭紦鍐叉潵浣滀負杈撳叆涓庤緭鍑恒傞┍鍔ㄧ▼搴忓繀欏誨湪鍚戣緭鍑虹紦鍐叉斁鏁版嵁涔嬪墠鎷瘋礉杈撳叆鏁版嵁銆傞┍鍔ㄧ▼搴忛氳繃璋冪敤KIrp::IoctlBuffer鑾峰緱緙撳啿鍦板潃銆傚湪瀹屾垚鏃訛紝I/O綆$悊鍣ㄤ粠緋葷粺緙撳啿鎷瘋礉鏁版嵁鍒版彁渚涚粰Ring 3綰ц皟鐢ㄨ呬嬌鐢ㄧ殑緙撳啿涓傞┍鍔ㄧ▼搴忓繀欏誨湪緇撴潫鍓嶅瓨鍌ㄦ嫹璐濆埌IRP鐨?/span>Information鎴愬憳涓殑鏁版嵁涓暟銆?/span>

濡傛灉鎺у埗浠g爜涓嶆寚鏄?/span>METHOD_IN_DIRECT鎴?/span>METHOD_OUT_DIRECT錛屽垯DeviceIoControl鐨勫弬鏁板憟鐜頒笉鍚岀殑鍚箟銆傚弬鏁?/span>InputBuffer琚嫹璐濆埌涓涓郴緇熺紦鍐詫紝榪欎釜緙撳啿椹卞姩紼嬪簭鍙互閫氳繃璋冪敤KIrp::IoctlBuffer銆傚弬鏁?/span>OutputBuffer琚槧灝勫埌KMemory瀵硅薄錛岄┍鍔ㄧ▼搴忓榪欎釜瀵硅薄鐨勮闂氳繃璋冪敤KIrp::Mdl鏉ュ疄鐜般傚浜?/span>METHOD_OUT_DIRECT錛岃皟鐢ㄨ呭繀欏繪湁瀵圭紦鍐茬殑鍐欒闂潈闄愩?/span>

娉ㄦ剰錛屽METHOD_NEITHER錛屽唴鏍稿彧鎻愪緵铏氭嫙鍦板潃錛涘畠涓嶄細鍋氭槧灝勬潵閰嶇疆緙撳啿銆傝櫄鎷熷湴鍧鍙璋冪敤榪涚▼鏈夋晥銆?/span>

榪欓噷鏄竴涓敤METHOD_BUFFERED鐨勪緥瀛愶細

棣栧厛錛屼嬌鐢ㄥ畯CTL_CODE鏉ュ畾涔変竴涓?/span>IOCTL浠g爜錛?/span>

#define IOCTL_MYDEV_GET_FIRMWARE_REV "

CTL_CODE (FILE_DEVICE_UNKNOWN,0,METHOD_BUFFERED,FILE_ANY_ACCESS)

鐜板湪浣跨敤涓涓?/span>DeviceIoControl璋冪敤錛?/span>

BOOLEAN b;
CHAR FirmwareRev[60];
ULONG FirmwareRevSize;
b = DeviceIoControl(hDevice, IOCTL_MYDEV_GET_VERSION_STRING,
  NULL, // no input 娉ㄦ剰錛岃繖閲屾斁鐨勬槸鍖呭惈鏈夋墽琛屾搷浣滃懡浠ょ殑瀛楃涓叉寚閽?/span>
  0,

FirmwareRev,      //榪欓噷鏄?/span>output涓叉寚閽堬紝瀛樻斁浠庨┍鍔ㄧ▼搴忎腑榪斿洖鐨勫瓧絎︿覆銆?/span>

sizeof(FirmwareRev),& FirmwareRevSize,
  NULL // not overlapped I/O
 );

濡傛灉杈撳嚭緙撳啿瓚沖澶э紝璁懼鎷瘋礉涓插埌閲岄潰騫跺皢鎷瘋礉鐨勮祫緇撴潫璁劇疆鍒?/span>FirmwareRevSize涓?/span>

鍦ㄩ┍鍔ㄧ▼搴忎腑錛屼唬鐮佺湅璧鋒潵濡備笅鎵紺猴細

const char* FIRMWARE_REV = "FW 16.33 v5";
NTSTATUS MyDevice::DeviceControl( KIrp I )
{
  ULONG fwLength=0;
  switch ( I.IoctlCode() )
  {
    case IOCTL_MYDEV_GET_FIRMWARE_REV:
      fwLength = strlen(FIRMWARE_REV)+1;
      if (I.IoctlOutputBufferSize() >= fwLength)
      {
        strcpy((PCHAR)I.IoctlBuffer(),FIRMWARE_REV);
        I.Information() = fwLength;      
        return I.Complete(STATUS_SUCCESS);
      }
      else

      {
        
      }
    case . . .
   }
 }