kvm-guest-drivers-windows
342 строки · 7.7 Кб
1#include "device.h"
2#include "assert.h"
3
4CDevice::CDevice()
5{
6m_hDevice = INVALID_HANDLE_VALUE;
7}
8
9CDevice::~CDevice()
10{
11if (m_hDevice != INVALID_HANDLE_VALUE)
12{
13CloseHandle(m_hDevice);
14m_hDevice = INVALID_HANDLE_VALUE;
15}
16}
17
18BOOL CDevice::Init(BOOL ovrl, UINT index)
19{
20PWCHAR DevicePath = NULL;
21if ((DevicePath = GetDevicePath(index, (LPGUID)&GUID_VIOSERIAL_PORT)) != NULL)
22{
23m_hDevice = CreateFile(DevicePath,
24GENERIC_WRITE | GENERIC_READ,
250,
26NULL,
27OPEN_EXISTING,
28ovrl ? FILE_FLAG_OVERLAPPED : FILE_ATTRIBUTE_NORMAL,
29NULL );
30
31if (m_hDevice != INVALID_HANDLE_VALUE)
32{
33printf("Open vioserial device %S.\n", DevicePath);
34return TRUE;
35}
36
37}
38DWORD err = GetLastError();
39printf("Cannot find vioserial device. %S , error = %d\n", DevicePath, err );
40return FALSE;
41}
42
43BOOL CDevice::Write(PVOID buf, size_t *size)
44{
45BOOL res = FALSE;
46ULONG ret = 0;
47DWORD bytes = *size;
48
49if (!buf) return FALSE;
50
51res = WriteFile ( m_hDevice,
52buf,
53bytes,
54&ret,
55NULL
56);
57if (!res)
58{
59printf("Cannot write vioserial device.\n");
60}
61else if ( ret != bytes)
62{
63printf("Write vioserial device error. written = 0x%x, expected = 0x%x\n", ret, bytes);
64*size = ret;
65ret = FALSE;
66}
67return res;
68}
69
70BOOL CDevice::WriteEx(PVOID buf, size_t *size)
71{
72BOOL res = FALSE;
73ULONG ret = 0;
74DWORD bytes = *size;
75OVERLAPPED ol = {0};
76
77assert( buf );
78
79ol.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
80if (!ol.hEvent)
81{
82printf("Event creation failed.\n");
83return FALSE;
84}
85
86res = WriteFile ( m_hDevice,
87buf,
88bytes,
89&ret,
90&ol
91);
92if (!res)
93{
94if (GetLastError() != ERROR_IO_PENDING)
95{
96printf("Write failed but isn't delayed.\n");
97res = FALSE;
98}
99else
100{
101if (!GetOverlappedResult(m_hDevice, &ol, &ret, TRUE))
102{
103res = FALSE;
104}
105else
106{
107*size = ret;
108res = TRUE;
109}
110}
111}
112else
113{
114*size = ret;
115res = TRUE;
116}
117
118CloseHandle( ol.hEvent );
119return res;
120}
121
122BOOL CDevice::Read(PVOID buf, size_t *size)
123{
124BOOL res = FALSE;
125DWORD ret;
126DWORD bytes = *size;
127
128if (!buf) return FALSE;
129
130memset(buf, '\0', bytes);
131
132res = ReadFile ( m_hDevice,
133buf,
134bytes,
135&ret,
136NULL
137);
138if (!res)
139{
140
141printf ("PerformReadTest: ReadFile failed: "
142"Error %d\n", GetLastError());
143}
144else if ( ret != bytes)
145{
146printf("Read vioserial device error. get = 0x%x, expected = 0x%x\n", ret, bytes);
147*size = ret;
148ret = FALSE;
149}
150
151return res;
152}
153
154BOOL CDevice::ReadEx(PVOID buf, size_t *size)
155{
156BOOL res = FALSE;
157DWORD ret;
158DWORD bytes = *size;
159OVERLAPPED ol = {0};
160
161assert(buf);
162
163memset(buf, '\0', bytes);
164
165ol.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
166if (!ol.hEvent)
167{
168printf("Event creation failed.\n");
169return FALSE;
170}
171
172res = ReadFile ( m_hDevice,
173buf,
174bytes,
175&ret,
176&ol
177);
178if (!res)
179{
180if (GetLastError() != ERROR_IO_PENDING)
181{
182printf("Write failed but isn't delayed.\n");
183res = FALSE;
184}
185else
186{
187if (!GetOverlappedResult(m_hDevice, &ol, &ret, TRUE))
188{
189res = FALSE;
190}
191else
192{
193*size = ret;
194res = TRUE;
195}
196}
197}
198else
199{
200*size = ret;
201res = TRUE;
202}
203
204CloseHandle( ol.hEvent );
205return res;
206
207
208
209
210
211
212
213
214
215
216
217
218
219if (!res)
220{
221
222printf ("PerformReadTest: ReadFile failed: "
223"Error %d\n", GetLastError());
224}
225else if ( ret != bytes)
226{
227printf("Read vioserial device error. get = 0x%x, expected = 0x%x\n", ret, bytes);
228*size = ret;
229ret = FALSE;
230}
231
232return res;
233}
234
235BOOL CDevice::GetInfo(PVOID buf, size_t *size)
236{
237BOOL res = FALSE;
238DWORD ulOutLength = *size;
239ULONG ulReturnedLength = 0;
240PVOID pBuffer = NULL;
241DWORD err;
242
243printf ("%s, buf = %p, size = %zd\n", __FUNCTION__, buf, *size);
244res = DeviceIoControl(
245m_hDevice,
246IOCTL_GET_INFORMATION,
247NULL,
2480,
249buf,
250ulOutLength,
251&ulReturnedLength,
252NULL
253);
254
255if ( !res )
256{ err = GetLastError();
257if (err != ERROR_MORE_DATA)
258{
259printf("Ioctl failed with code %d\n", err );
260}
261}
262*size = ulReturnedLength;
263return res;
264}
265
266PTCHAR CDevice::GetDevicePath(UINT index, IN LPGUID InterfaceGuid )
267{
268HDEVINFO HardwareDeviceInfo;
269SP_DEVICE_INTERFACE_DATA DeviceInterfaceData;
270PSP_DEVICE_INTERFACE_DETAIL_DATA DeviceInterfaceDetailData = NULL;
271ULONG Length, RequiredLength = 0;
272BOOL bResult;
273
274HardwareDeviceInfo = SetupDiGetClassDevs(
275InterfaceGuid,
276NULL,
277NULL,
278(DIGCF_PRESENT | DIGCF_DEVICEINTERFACE)
279);
280
281if (HardwareDeviceInfo == INVALID_HANDLE_VALUE)
282{
283printf("Cannot get class devices.\n");
284return NULL;
285}
286
287DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
288
289bResult = SetupDiEnumDeviceInterfaces(HardwareDeviceInfo,
2900,
291InterfaceGuid,
292index,
293&DeviceInterfaceData
294);
295
296if (bResult == FALSE) {
297printf("Cannot get enumerate device interfaces.\n");
298SetupDiDestroyDeviceInfoList(HardwareDeviceInfo);
299return NULL;
300}
301
302SetupDiGetDeviceInterfaceDetail(
303HardwareDeviceInfo,
304&DeviceInterfaceData,
305NULL,
3060,
307&RequiredLength,
308NULL
309);
310
311DeviceInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA) LocalAlloc(LMEM_FIXED, RequiredLength);
312
313if (DeviceInterfaceDetailData == NULL)
314{
315printf("Cannot allocate memory.\n");
316SetupDiDestroyDeviceInfoList(HardwareDeviceInfo);
317return NULL;
318}
319
320DeviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
321
322Length = RequiredLength;
323
324bResult = SetupDiGetDeviceInterfaceDetail(
325HardwareDeviceInfo,
326&DeviceInterfaceData,
327DeviceInterfaceDetailData,
328Length,
329&RequiredLength,
330NULL
331);
332
333if (bResult == FALSE)
334{
335printf("Cannot get device interface details.\n");
336SetupDiDestroyDeviceInfoList(HardwareDeviceInfo);
337LocalFree(DeviceInterfaceDetailData);
338return NULL;
339}
340
341return DeviceInterfaceDetailData->DevicePath;
342}
343