// Get symbolic link name

 ifDetail->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);

 if (!SetupDiGetDeviceInterfaceDetail(info, &ifdata, ifDetail, ReqLen, NULL, NULL)) {

  SetupDiDestroyDeviceInfoList(info);

  delete ifDetail;

  return NULL;

 }

 printf('Symbolic link is %s ',ifDetail->DevicePath):

 // Open file

 HANDLE rv = CreateFile(ifDetail->DevicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

 delete ifDetail;

 SetupDiDestroyDevicelnfoList(info);

 return rv;

}

The Win32 call to SetupDiGetClassDevs opens a 'device information set' about devices with the specified GUID. The DIGCF_PRESENT and DIGCF_INTERFACEDEVICE flags ensure that only devices that are present are found.

SetupDiEnumDeviceInterfaces is then called to retrieve a SP_INTERFACE_DEVICE_DATA context structure of information about the device instance in which you are interested. GetDeviceViaInterface tries to retrieve information about only one instance, but you might want to find all instances by incrementing the MemberIndex parameter from 0 until SetupDiEnumDeviceInterfaces fails and GetLastError returns ERROR_NO_MORE_ITEMS.

The next task is to obtain the symbolic link name for the instance that has been found. This string is in the PSP_INTERFACE_DEVICE_DETAIL_DATA ifDetail structure returned by a call to SetupDiGetDeviceInterfaceDetail. SetupDiGetDeviceInterfaceDetail must be called twice. The first call retrieves the required size for ifDetail, while the second actually gets the structure.

Eventually ifDetail->DevicePath contains the filename that is used to open a handle to the relevant Wdm1 device. This filename is passed to CreateFile and then ifDetail is deleted. Do not forget to call SetupDiDestroyDeviceInfoList on all paths to close the device information set.

The call to CreateFile in GetDeviceViaInterface uses a pretty standard set of parameters. As noted before, you can change the share and access modes, if necessary. Further, the device can be opened for overlapped nonblocking access. Overlapped access works for devices in Windows 98, NT, and Windows 2000 and lets an application issue an I/O request and get on with other work while the request is being processed. The detailed explanation of the DebugPrint Monitor program in Chapter 14 gives an example of this technique.

Running Wdm1Test

Simply run Wdm1Test.exe in the Wdm1exeRelease directory. Make sure that the Wdm1 driver is installed. Wdm1Test is a console application running in a DOS box. Press the Enter key to exit the program.

If you run Wdm1Test in W2000, the output should look like that given in Listing 5.6. The first time round, Test 2 is designed to fail; subsequent tests should succeed. In Windows 98, the output is different, as it does not seem to support the SetFilePointer function on devices, such as Wdm1.

The rest of the Wdm1Test main function performs each of these tests in turn.

1. Open the first Wdm1 device.

2. Read the first DWORD stored in the shared memory buffer. This will fail first time round, as there will be nothing in the buffer.

3. Write 0x12345678 to the start of the buffer. 0x78 is written at file pointer zero, 0x56 at one, 0x34 at two, and 0x12 at three.

4. Set the file pointer to position 3.

5. Read one byte from the file. This should be 0x12.

6. Write 0x12345678 to the buffer starting at file position 3.

7. Use an IOCTL to get the buffer size, which should be 7 (i.e., 3+4).

8. Use an IOCTL to get the entire buffer. The first word is printed and should be 0x78345678.

9. Check that issuing an IOCTL with an invalid parameter fails. The IOCTL asks for the entire buffer with a request size that is too big.

10. Use an IOCTL to zero all the bytes in the buffer. Get the entire buffer again. The first word is printed which should be 0x00000000.

11. Use an IOCTL to remove the buffer. Check that the buffer size is now zero.

12. Try to issue an invalid IOCTL code. Confirm that this fails.

13. Write 0xabcdef01 to the start of the buffer. When Wdm1Test is run next, Test 2 should find this value.

Listing 5.6 Wdm1Test output on W2000

Test 1

Symbolic link is \? oot#unknown#0003#{c0cf0640-5f6e-11d2-b677-00c0dfe4c1f3}

 Opened OK

Test 2

 Read successfully read stored value of 0xABC0EF01

Test 3

 Write 0x12345678 succeeded

Test 4

 SetFilePointer worked

Test 5

 Read successfully read stored value of 0x12

Test 6

 Write at new file pointer succeeded

Test 7

 Buffer size is 7 (4 bytes returned)

Test 8

 First DWORD of buffer is 78345678 (7 bytes returned)

Test 9

 Too big get buffer failed correctly 87

Test 10

 Zero buffer succeeded

 First DWORD of buffer is 00000000 (7 bytes returned)

Test 11

 Remove buffer succeeded

 Buffer size is 0 (4 bytes returned)

Test 12

 Unrecognised IOCTL correctly failed 1

Test 13

 SetFilePointer worked Write 0xabcdef01 succeeded

Test 14

 CloseHandle worked

 Press enter please

Wdm1Test exercises all the functions of the Wdm1 driver. It checks that things that should work do work, and things that should fail do fail.

Writing this test program showed that the Wdm1 device does behave differently in Windows 98 and Windows 2000. However, the problem does not lie in the driver itself, but is due to Windows 98 not supporting SetFilePointer for device files.

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату