kvm-guest-drivers-windows

Форк
0
342 строки · 7.7 Кб
1
#include "device.h"
2
#include "assert.h"
3

4
CDevice::CDevice()
5
{
6
    m_hDevice = INVALID_HANDLE_VALUE;
7
}
8

9
CDevice::~CDevice()
10
{
11
    if (m_hDevice != INVALID_HANDLE_VALUE)
12
    {
13
        CloseHandle(m_hDevice);
14
        m_hDevice = INVALID_HANDLE_VALUE;
15
    }
16
}
17

18
BOOL CDevice::Init(BOOL ovrl, UINT index)
19
{
20
    PWCHAR DevicePath = NULL;
21
    if ((DevicePath = GetDevicePath(index, (LPGUID)&GUID_VIOSERIAL_PORT)) != NULL)
22
    {
23
        m_hDevice = CreateFile(DevicePath,
24
                             GENERIC_WRITE | GENERIC_READ,
25
                             0,
26
                             NULL,
27
                             OPEN_EXISTING,
28
                             ovrl ? FILE_FLAG_OVERLAPPED : FILE_ATTRIBUTE_NORMAL,
29
                             NULL );
30

31
        if (m_hDevice != INVALID_HANDLE_VALUE)
32
        {
33
            printf("Open vioserial device  %S.\n", DevicePath);
34
            return TRUE;
35
        }
36

37
    }
38
    DWORD err = GetLastError();
39
    printf("Cannot find vioserial device. %S , error = %d\n", DevicePath, err );
40
    return FALSE;
41
}
42

43
BOOL CDevice::Write(PVOID buf, size_t *size)
44
{
45
    BOOL res = FALSE;
46
    ULONG ret = 0;
47
    DWORD bytes = *size;
48

49
    if (!buf) return FALSE;
50

51
    res = WriteFile ( m_hDevice,
52
                      buf,
53
                      bytes,
54
                      &ret,
55
                      NULL
56
                     );
57
    if (!res)
58
    {
59
        printf("Cannot write vioserial device.\n");
60
    }
61
    else if ( ret != bytes)
62
    {
63
        printf("Write vioserial device error. written = 0x%x, expected = 0x%x\n", ret, bytes);
64
        *size = ret;
65
        ret = FALSE;
66
    }
67
    return res;
68
}
69

70
BOOL CDevice::WriteEx(PVOID buf, size_t *size)
71
{
72
    BOOL res = FALSE;
73
    ULONG ret = 0;
74
    DWORD bytes = *size;
75
    OVERLAPPED  ol = {0};
76

77
    assert( buf );
78

79
    ol.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
80
    if (!ol.hEvent)
81
    {
82
        printf("Event creation failed.\n");
83
        return FALSE;
84
    }
85

86
    res = WriteFile ( m_hDevice,
87
                      buf,
88
                      bytes,
89
                      &ret,
90
                      &ol
91
                     );
92
    if (!res)
93
    {
94
        if (GetLastError() != ERROR_IO_PENDING)
95
        {
96
           printf("Write failed but isn't delayed.\n");
97
           res = FALSE;
98
        }
99
        else
100
        {
101
           if (!GetOverlappedResult(m_hDevice, &ol, &ret, TRUE))
102
           {
103
              res = FALSE;
104
           }
105
           else
106
           {
107
              *size = ret;
108
              res = TRUE;
109
           }
110
        }
111
    }
112
    else
113
    {
114
        *size = ret;
115
        res = TRUE;
116
    }
117

118
    CloseHandle( ol.hEvent );
119
    return res;
120
}
121

122
BOOL CDevice::Read(PVOID buf, size_t *size)
123
{
124
    BOOL res = FALSE;
125
    DWORD ret;
126
    DWORD bytes = *size;
127

128
    if (!buf) return FALSE;
129

130
    memset(buf, '\0', bytes);
131

132
    res = ReadFile ( m_hDevice,
133
                    buf,
134
                    bytes,
135
                    &ret,
136
                    NULL
137
                   );
138
    if (!res)
139
    {
140

141
        printf ("PerformReadTest: ReadFile failed: "
142
                "Error %d\n", GetLastError());
143
    }
144
    else if ( ret != bytes)
145
    {
146
        printf("Read vioserial device error. get = 0x%x, expected = 0x%x\n", ret, bytes);
147
        *size = ret;
148
        ret = FALSE;
149
    }
150

151
    return res;
152
}
153

154
BOOL CDevice::ReadEx(PVOID buf, size_t *size)
155
{
156
    BOOL res = FALSE;
157
    DWORD ret;
158
    DWORD bytes = *size;
159
    OVERLAPPED  ol = {0};
160

161
    assert(buf);
162

163
    memset(buf, '\0', bytes);
164

165
    ol.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
166
    if (!ol.hEvent)
167
    {
168
        printf("Event creation failed.\n");
169
        return FALSE;
170
    }
171

172
    res = ReadFile ( m_hDevice,
173
                    buf,
174
                    bytes,
175
                    &ret,
176
                    &ol
177
                   );
178
    if (!res)
179
    {
180
        if (GetLastError() != ERROR_IO_PENDING)
181
        {
182
           printf("Write failed but isn't delayed.\n");
183
           res = FALSE;
184
        }
185
        else
186
        {
187
           if (!GetOverlappedResult(m_hDevice, &ol, &ret, TRUE))
188
           {
189
              res = FALSE;
190
           }
191
           else
192
           {
193
              *size = ret;
194
              res = TRUE;
195
           }
196
        }
197
    }
198
    else
199
    {
200
        *size = ret;
201
        res = TRUE;
202
    }
203

204
    CloseHandle( ol.hEvent );
205
    return res;
206

207

208

209

210

211

212

213

214

215

216

217

218

219
    if (!res)
220
    {
221

222
        printf ("PerformReadTest: ReadFile failed: "
223
                "Error %d\n", GetLastError());
224
    }
225
    else if ( ret != bytes)
226
    {
227
        printf("Read vioserial device error. get = 0x%x, expected = 0x%x\n", ret, bytes);
228
        *size = ret;
229
        ret = FALSE;
230
    }
231

232
    return res;
233
}
234

235
BOOL CDevice::GetInfo(PVOID buf, size_t *size)
236
{
237
    BOOL    res = FALSE;
238
    DWORD   ulOutLength = *size;
239
    ULONG   ulReturnedLength = 0;
240
    PVOID   pBuffer = NULL;
241
    DWORD   err;
242

243
    printf ("%s, buf = %p, size = %zd\n", __FUNCTION__, buf, *size);
244
    res = DeviceIoControl(
245
                             m_hDevice,
246
                             IOCTL_GET_INFORMATION,
247
                             NULL,
248
                             0,
249
                             buf,
250
                             ulOutLength,
251
                             &ulReturnedLength,
252
                             NULL
253
                             );
254

255
    if ( !res )
256
    {   err = GetLastError();
257
        if (err != ERROR_MORE_DATA)
258
        {
259
           printf("Ioctl failed with code %d\n", err );
260
        }
261
    }
262
    *size = ulReturnedLength;
263
    return res;
264
}
265

266
PTCHAR CDevice::GetDevicePath(UINT index, IN  LPGUID InterfaceGuid )
267
{
268
    HDEVINFO HardwareDeviceInfo;
269
    SP_DEVICE_INTERFACE_DATA DeviceInterfaceData;
270
    PSP_DEVICE_INTERFACE_DETAIL_DATA DeviceInterfaceDetailData = NULL;
271
    ULONG Length, RequiredLength = 0;
272
    BOOL bResult;
273

274
    HardwareDeviceInfo = SetupDiGetClassDevs(
275
                             InterfaceGuid,
276
                             NULL,
277
                             NULL,
278
                             (DIGCF_PRESENT | DIGCF_DEVICEINTERFACE)
279
                             );
280

281
    if (HardwareDeviceInfo == INVALID_HANDLE_VALUE)
282
    {
283
        printf("Cannot get class devices.\n");
284
        return NULL;
285
    }
286

287
    DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
288

289
    bResult = SetupDiEnumDeviceInterfaces(HardwareDeviceInfo,
290
                             0,
291
                             InterfaceGuid,
292
                             index,
293
                             &DeviceInterfaceData
294
                             );
295

296
    if (bResult == FALSE) {
297
        printf("Cannot get enumerate device interfaces.\n");
298
        SetupDiDestroyDeviceInfoList(HardwareDeviceInfo);
299
        return NULL;
300
    }
301

302
    SetupDiGetDeviceInterfaceDetail(
303
        HardwareDeviceInfo,
304
        &DeviceInterfaceData,
305
        NULL,
306
        0,
307
        &RequiredLength,
308
        NULL
309
        );
310

311
    DeviceInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA) LocalAlloc(LMEM_FIXED, RequiredLength);
312

313
    if (DeviceInterfaceDetailData == NULL)
314
    {
315
        printf("Cannot allocate memory.\n");
316
        SetupDiDestroyDeviceInfoList(HardwareDeviceInfo);
317
        return NULL;
318
    }
319

320
    DeviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
321

322
    Length = RequiredLength;
323

324
    bResult = SetupDiGetDeviceInterfaceDetail(
325
                             HardwareDeviceInfo,
326
                             &DeviceInterfaceData,
327
                             DeviceInterfaceDetailData,
328
                             Length,
329
                             &RequiredLength,
330
                             NULL
331
                             );
332

333
    if (bResult == FALSE)
334
    {
335
        printf("Cannot get device interface details.\n");
336
        SetupDiDestroyDeviceInfoList(HardwareDeviceInfo);
337
        LocalFree(DeviceInterfaceDetailData);
338
        return NULL;
339
    }
340

341
    return DeviceInterfaceDetailData->DevicePath;
342
}
343

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.