ReactOS 0.4.15-dev-7934-g1dc8d80
bochsmp.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Bochs graphics card driver
3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4 * PURPOSE: Bochs graphics card driver
5 * COPYRIGHT: Copyright 2022 Hervé Poussineau <hpoussin@reactos.org>
6 */
7
8#include "bochsmp.h"
9
11 { 640, 480 }, // VGA
12 { 800, 600 }, // SVGA
13 { 1024, 600 }, // WSVGA
14 { 1024, 768 }, // XGA
15 { 1152, 864 }, // XGA+
16 { 1280, 720 }, // WXGA-H
17 { 1280, 768 }, // WXGA
18 { 1280, 960 }, // SXGA-
19 { 1280, 1024 }, // SXGA
20 { 1368, 768 }, // HD ready
21 { 1400, 1050 }, // SXGA+
22 { 1440, 900 }, // WSXGA
23 { 1600, 900 }, // HD+
24 { 1600, 1200 }, // UXGA
25 { 1680, 1050 }, // WSXGA+
26 { 1920, 1080 }, // FHD
27 { 2048, 1536 }, // QXGA
28 { 2560, 1440 }, // WQHD
29 { 2560, 1600 }, // WQXGA
30 { 2560, 2048 }, // QSXGA
31 { 2800, 2100 }, // QSXGA+
32 { 3200, 2400 }, // QUXGA
33 { 3840, 2160 }, // 4K UHD-1
34};
35
36CODE_SEG("PAGE")
37static VOID
39 _Inout_ PBOCHS_DEVICE_EXTENSION DeviceExtension)
40{
41 if (DeviceExtension->AvailableModeInfo)
42 {
43 VideoPortFreePool(DeviceExtension, DeviceExtension->AvailableModeInfo);
44 DeviceExtension->AvailableModeInfo = NULL;
45 }
46}
47
48CODE_SEG("PAGE")
49static VOID
51 _In_ PBOCHS_DEVICE_EXTENSION DeviceExtension,
54{
55 if (DeviceExtension->IoPorts.RangeInIoSpace)
56 {
59 }
60 else
61 {
62 VideoPortWriteRegisterUshort((PUSHORT)(DeviceExtension->IoPorts.Mapped + 0x500 + Index * 2), Value);
63 }
64}
65
66CODE_SEG("PAGE")
67static USHORT
69 _In_ PBOCHS_DEVICE_EXTENSION DeviceExtension,
71{
72 if (DeviceExtension->IoPorts.RangeInIoSpace)
73 {
75 return VideoPortReadPortUshort((PUSHORT)(DeviceExtension->IoPorts.Mapped - VBE_DISPI_IOPORT_INDEX + VBE_DISPI_IOPORT_DATA));
76 }
77 else
78 {
79 return VideoPortReadRegisterUshort((PUSHORT)(DeviceExtension->IoPorts.Mapped + 0x500 + Index * 2));
80 }
81}
82
83CODE_SEG("PAGE")
84static BOOLEAN
86 _In_ PBOCHS_DEVICE_EXTENSION DeviceExtension,
89{
90 BochsWriteDispI(DeviceExtension, Index, Value);
91 return BochsReadDispI(DeviceExtension, Index) == Value;
92}
93
94CODE_SEG("PAGE")
95static BOOLEAN
97 _In_ PBOCHS_DEVICE_EXTENSION DeviceExtension,
98 _In_ ULONG PotentialModeCount)
99{
100 ULONG i, ModeCount = 0;
101
102 for (i = 0; i < ARRAYSIZE(BochsAvailableResolutions) && ModeCount < PotentialModeCount; i++)
103 {
104 if (BochsAvailableResolutions[i].XResolution > DeviceExtension->MaxXResolution)
105 continue;
106 if (BochsAvailableResolutions[i].YResolution > DeviceExtension->MaxYResolution)
107 continue;
108 if (BochsAvailableResolutions[i].XResolution * BochsAvailableResolutions[i].YResolution * 4 > DeviceExtension->VramSize64K * 64 * 1024)
109 continue;
110 DeviceExtension->AvailableModeInfo[ModeCount++] = BochsAvailableResolutions[i];
111 }
112
113 if (ModeCount == 0)
114 {
115 VideoDebugPrint((Error, "Bochs: no suitable modes available!\n"));
116 return FALSE;
117 }
118
119 DeviceExtension->AvailableModeCount = ModeCount;
120 return TRUE;
121}
122
123CODE_SEG("PAGE")
124static BOOLEAN
126 _Inout_ PBOCHS_DEVICE_EXTENSION DeviceExtension)
127{
129 WCHAR ChipType[5];
130 ULONG SizeInBytes;
131
132 /* Detect DISPI version */
134 {
136 break;
137 }
139 {
140 VideoDebugPrint((Error, "Bochs: VBE extension signature incorrect\n"));
141 return FALSE;
142 }
143 VideoDebugPrint((Error, "Bochs: detected version 0x%04x\n", Version));
145 {
146 /* Too old (no 32 bpp support, no linear frame buffer) */
147 VideoDebugPrint((Error, "Bochs: VBE extension too old (0x%04x)\n", Version));
148 return FALSE;
149 }
150
151 if (Version <= VBE_DISPI_ID2)
152 {
153 DeviceExtension->MaxXResolution = 1024;
154 DeviceExtension->MaxYResolution = 768;
155 }
156 else
157 {
159 DeviceExtension->MaxXResolution = BochsReadDispI(DeviceExtension, VBE_DISPI_INDEX_XRES);
160 DeviceExtension->MaxYResolution = BochsReadDispI(DeviceExtension, VBE_DISPI_INDEX_YRES);
162 /* Workaround bug in QEMU bochs-display */
163 if (DeviceExtension->MaxXResolution == 0 && DeviceExtension->MaxYResolution == 0)
164 {
165 DeviceExtension->MaxXResolution = 1024;
166 DeviceExtension->MaxYResolution = 768;
167 }
168 }
170 {
171 DeviceExtension->VramSize64K = 4 * 1024 / 64; /* 4 MB */
172 }
173 else if (Version == VBE_DISPI_ID4)
174 {
175 DeviceExtension->VramSize64K = 8 * 1024 / 64; /* 8 MB */
176 }
177 else
178 {
179 DeviceExtension->VramSize64K = BochsReadDispI(DeviceExtension, VBE_DISPI_INDEX_VIDEO_MEMORY_64K);
180 }
181 VideoDebugPrint((Info, "Bochs: capabilities %dx%d (%d MB)\n",
182 DeviceExtension->MaxXResolution,
183 DeviceExtension->MaxYResolution,
184 DeviceExtension->VramSize64K * 64 / 1024));
185
186 /* Store information in registry */
187#define HEX(c) (((c) >= 0 && (c) <= 9) ? (c) + L'0' : (c) - 10 + L'A')
188 ChipType[0] = HEX((Version >> 12) & 0xf);
189 ChipType[1] = HEX((Version >> 8) & 0xf);
190 ChipType[2] = HEX((Version >> 4) & 0xf);
191 ChipType[3] = HEX(Version & 0xf);
192 ChipType[4] = UNICODE_NULL;
193 VideoPortSetRegistryParameters(DeviceExtension, L"HardwareInformation.ChipType", ChipType, sizeof(ChipType));
194 SizeInBytes = DeviceExtension->VramSize64K * 64 * 1024;
195 VideoPortSetRegistryParameters(DeviceExtension, L"HardwareInformation.MemorySize", &SizeInBytes, sizeof(SizeInBytes));
196 return TRUE;
197}
198
199CODE_SEG("PAGE")
200static VOID
202 _In_ PBOCHS_SIZE AvailableModeInfo,
205{
206 VideoDebugPrint((Info, "Bochs: Filling details of mode #%d\n", Index));
207
208 ModeInfo->Length = sizeof(*ModeInfo);
209 ModeInfo->ModeIndex = Index;
210 ModeInfo->VisScreenWidth = AvailableModeInfo->XResolution;
211 ModeInfo->VisScreenHeight = AvailableModeInfo->YResolution;
212 ModeInfo->ScreenStride = AvailableModeInfo->XResolution * 4;
213 ModeInfo->NumberOfPlanes = 1;
214 ModeInfo->BitsPerPlane = 32;
215 ModeInfo->Frequency = 60;
216
217 /* 960 DPI appears to be common */
218 ModeInfo->XMillimeter = AvailableModeInfo->XResolution * 254 / 960;
219 ModeInfo->YMillimeter = AvailableModeInfo->YResolution * 254 / 960;
220 ModeInfo->NumberRedBits = 8;
221 ModeInfo->NumberGreenBits = 8;
222 ModeInfo->NumberBlueBits = 8;
223 ModeInfo->RedMask = 0xff0000;
224 ModeInfo->GreenMask = 0x00ff00;
225 ModeInfo->BlueMask = 0x0000ff;
226
228 ModeInfo->VideoMemoryBitmapWidth = AvailableModeInfo->XResolution;
229 ModeInfo->VideoMemoryBitmapHeight = AvailableModeInfo->YResolution;
230}
231
232CODE_SEG("PAGE")
233static BOOLEAN
235 _In_ PBOCHS_DEVICE_EXTENSION DeviceExtension,
236 _In_ PVIDEO_MEMORY RequestedAddress,
237 _Out_ PVIDEO_MEMORY_INFORMATION MapInformation,
238 _Out_ PSTATUS_BLOCK StatusBlock)
239{
241 PHYSICAL_ADDRESS VideoMemory;
243
244 VideoDebugPrint((Info, "Bochs: BochsMapVideoMemory Entry\n"));
245
246 VideoMemory = DeviceExtension->FrameBuffer.RangeStart;
247 MapInformation->VideoRamBase = RequestedAddress->RequestedVirtualAddress;
248 MapInformation->VideoRamLength = 4 *
249 DeviceExtension->AvailableModeInfo[DeviceExtension->CurrentMode].XResolution *
250 DeviceExtension->AvailableModeInfo[DeviceExtension->CurrentMode].YResolution;
251
252 Status = VideoPortMapMemory(DeviceExtension,
253 VideoMemory,
254 &MapInformation->VideoRamLength,
255 &MemSpace,
256 &MapInformation->VideoRamBase);
257 if (Status != NO_ERROR)
258 {
259 VideoDebugPrint((Error, "BochsMapVideoMemory - VideoPortMapMemory failed status:%x\n", Status));
260 StatusBlock->Status = Status;
261 return FALSE;
262 }
263
264 MapInformation->FrameBufferBase = MapInformation->VideoRamBase;
265 MapInformation->FrameBufferLength = MapInformation->VideoRamLength;
266 StatusBlock->Information = sizeof(*MapInformation);
267 StatusBlock->Status = NO_ERROR;
268
269 VideoDebugPrint((Info, "Bochs:BochsMapVideoMemory Exit VideoRamBase: %p VideoRamLength: 0x%x PhysBasePtr: 0x%x\n",
270 MapInformation->VideoRamBase, MapInformation->VideoRamLength, (ULONG)VideoMemory.QuadPart));
271 return TRUE;
272}
273
274CODE_SEG("PAGE")
275static BOOLEAN NTAPI
277 _In_ PBOCHS_DEVICE_EXTENSION DeviceExtension,
278 _In_ PVIDEO_MEMORY VideoMemory,
279 _Out_ PSTATUS_BLOCK StatusBlock)
280{
282
283 VideoDebugPrint((Info, "Bochs: BochsUnmapVideoMemory Entry VideoRamBase:%p\n", VideoMemory->RequestedVirtualAddress));
284
285 Status = VideoPortUnmapMemory(DeviceExtension, VideoMemory->RequestedVirtualAddress, NULL);
286 if (Status != NO_ERROR)
287 {
288 VideoDebugPrint((Error, "Bochs: BochsUnmapVideoMemory Failed to unmap memory:%p Status:%x\n",
289 VideoMemory->RequestedVirtualAddress,
290 Status));
291 }
292
293 StatusBlock->Status = Status;
294
295 VideoDebugPrint((Info, "Bochs: BochsUnmapVideoMemory Exit status:%x\n", Status));
296 return (Status == NO_ERROR);
297}
298
299CODE_SEG("PAGE")
300static BOOLEAN
302 _In_ PBOCHS_DEVICE_EXTENSION DeviceExtension,
303 _Out_ PVIDEO_NUM_MODES AvailableModes,
304 _Out_ PSTATUS_BLOCK StatusBlock)
305{
306 AvailableModes->NumModes = DeviceExtension->AvailableModeCount;
307 AvailableModes->ModeInformationLength = sizeof(VIDEO_MODE_INFORMATION);
308
309 StatusBlock->Information = sizeof(*AvailableModes);
310 StatusBlock->Status = NO_ERROR;
311 return TRUE;
312}
313
314CODE_SEG("PAGE")
315static BOOLEAN
317 _In_ PBOCHS_DEVICE_EXTENSION DeviceExtension,
318 _Out_ PVIDEO_MODE_INFORMATION ReturnedModes,
319 _Out_ PSTATUS_BLOCK StatusBlock)
320{
321 ULONG Count;
322 PBOCHS_SIZE AvailableModeInfo;
324
325 for (Count = 0, AvailableModeInfo = DeviceExtension->AvailableModeInfo, ModeInfo = ReturnedModes;
326 Count < DeviceExtension->AvailableModeCount;
327 Count++, AvailableModeInfo++, ModeInfo++)
328 {
329 VideoPortZeroMemory(ModeInfo, sizeof(*ModeInfo));
330 BochsGetModeInfo(AvailableModeInfo, ModeInfo, Count);
331 }
332
333 StatusBlock->Information = sizeof(VIDEO_MODE_INFORMATION) * DeviceExtension->AvailableModeCount;
334 StatusBlock->Status = NO_ERROR;
335
336 return TRUE;
337}
338
339CODE_SEG("PAGE")
340static BOOLEAN
342 _In_ PBOCHS_DEVICE_EXTENSION DeviceExtension,
343 _In_ PVIDEO_MODE RequestedMode,
344 _Out_ PSTATUS_BLOCK StatusBlock)
345{
346 PBOCHS_SIZE AvailableModeInfo;
347 /* Mask the two high-order bits, which can be set to request special behavior */
348 ULONG ModeRequested = RequestedMode->RequestedMode & 0x3fffffff;
349 BOOLEAN Ret;
350
351 VideoDebugPrint((Info, "Bochs:BochsSetCurrentMode Entry\n"));
352
353 if (ModeRequested >= DeviceExtension->AvailableModeCount)
354 {
355 VideoDebugPrint((Error, "Bochs: set current mode - invalid parameter\n"));
356 StatusBlock->Status = ERROR_INVALID_PARAMETER;
357 return FALSE;
358 }
359
360 AvailableModeInfo = &DeviceExtension->AvailableModeInfo[ModeRequested];
361
362 /* Set the mode characteristics */
364 Ret = BochsWriteDispIAndCheck(DeviceExtension, VBE_DISPI_INDEX_XRES, AvailableModeInfo->XResolution) &&
365 BochsWriteDispIAndCheck(DeviceExtension, VBE_DISPI_INDEX_YRES, AvailableModeInfo->YResolution) &&
366 BochsWriteDispIAndCheck(DeviceExtension, VBE_DISPI_INDEX_BPP, 32);
367 /* Always enable screen, even if display settings change failed */
369 if (!Ret)
370 {
371 VideoDebugPrint((Error, "Bochs: failed to change mode\n"));
372 return FALSE;
373 }
374
375 /* Enable VGA (QEMU secondary-vga disables it by default) */
376 if (!DeviceExtension->IoPorts.RangeInIoSpace)
377 {
378 /* Discard AR flip-flip */
379 (VOID)VideoPortReadRegisterUshort((PUSHORT)(DeviceExtension->IoPorts.Mapped + 0x41A));
380 /* Enable display */
381 VideoPortWriteRegisterUshort((PUSHORT)(DeviceExtension->IoPorts.Mapped + 0x400), 0x20);
382 }
383
384 DeviceExtension->CurrentMode = (USHORT)ModeRequested;
385 StatusBlock->Status = NO_ERROR;
386
387 VideoDebugPrint((Info, "Bochs:BochsSetCurrentMode Exit Mode:%d\n", ModeRequested));
388 return TRUE;
389}
390
391CODE_SEG("PAGE")
392static BOOLEAN
394 _In_ PBOCHS_DEVICE_EXTENSION DeviceExtension,
395 _Out_ PVIDEO_MODE_INFORMATION VideoModeInfo,
396 _Out_ PSTATUS_BLOCK StatusBlock)
397{
398 PBOCHS_SIZE AvailableModeInfo;
399
400 if (DeviceExtension->CurrentMode > DeviceExtension->AvailableModeCount)
401 {
402 StatusBlock->Status = ERROR_INVALID_PARAMETER;
403 return FALSE;
404 }
405
406 AvailableModeInfo = &DeviceExtension->AvailableModeInfo[DeviceExtension->CurrentMode];
407 VideoPortZeroMemory(VideoModeInfo, sizeof(*VideoModeInfo));
408 BochsGetModeInfo(AvailableModeInfo, VideoModeInfo, DeviceExtension->CurrentMode);
409
410 StatusBlock->Information = sizeof(*VideoModeInfo);
411 StatusBlock->Status = NO_ERROR;
412 return TRUE;
413}
414
415CODE_SEG("PAGE")
416static BOOLEAN
418 _In_ PBOCHS_DEVICE_EXTENSION DeviceExtension,
419 _Out_ PSTATUS_BLOCK StatusBlock)
420{
421 VideoDebugPrint((Info, "Bochs:BochsResetDevice Entry\n"));
422
423 StatusBlock->Status = NO_ERROR;
424
425 VideoDebugPrint((Info, "Bochs:BochsResetDevice Exit\n"));
426 return TRUE;
427}
428
429CODE_SEG("PAGE")
430static BOOLEAN
432 _In_ PBOCHS_DEVICE_EXTENSION DeviceExtension,
433 _Out_ PULONG pChildState,
434 _Out_ PSTATUS_BLOCK StatusBlock)
435{
436 *pChildState = VIDEO_CHILD_ACTIVE;
437
438 StatusBlock->Information = sizeof(*pChildState);
439 StatusBlock->Status = NO_ERROR;
440 return TRUE;
441}
442
443CODE_SEG("PAGE")
446 _In_ PVOID HwDeviceExtension,
448 _In_ PWSTR ArgumentString,
449 _In_ PVIDEO_PORT_CONFIG_INFO ConfigInfo,
450 _In_ PUCHAR Again)
451{
452 PBOCHS_DEVICE_EXTENSION DeviceExtension = HwDeviceExtension;
453 VIDEO_ACCESS_RANGE AccessRanges[2] = {0};
454
455 if (ConfigInfo->Length < sizeof(*ConfigInfo))
457
458 if (VideoPortGetAccessRanges(DeviceExtension, 0, NULL, ARRAYSIZE(AccessRanges), AccessRanges, NULL, NULL, NULL) != NO_ERROR)
459 {
460 VideoDebugPrint((Error, "Bochs: failed to get access ranges\n"));
461 return ERROR_DEV_NOT_EXIST;
462 }
463
464 /* Framebuffer */
465 DeviceExtension->FrameBuffer.RangeStart = AccessRanges[0].RangeStart;
466 DeviceExtension->FrameBuffer.RangeLength = AccessRanges[0].RangeLength;
467 DeviceExtension->FrameBuffer.RangeInIoSpace = AccessRanges[0].RangeInIoSpace;
468
469 /* I/O ports */
470 if (AccessRanges[1].RangeLength == 0)
471 {
472 /* Set default values */
473 AccessRanges[1].RangeStart.LowPart = VBE_DISPI_IOPORT_INDEX;
474 AccessRanges[1].RangeLength = 2;
475 AccessRanges[1].RangeInIoSpace = TRUE;
476 if (VideoPortVerifyAccessRanges(DeviceExtension, 1, &AccessRanges[1]) != NO_ERROR)
477 {
478 VideoDebugPrint((Error, "Bochs: failed to claim I/O range 0x%x-0x%x\n",
481 return ERROR_DEV_NOT_EXIST;
482 }
483 }
484 else if (AccessRanges[1].RangeLength != 0x1000)
485 {
486 VideoDebugPrint((Error, "Bochs: invalid access ranges (size 0x%x)\n", AccessRanges[1].RangeLength));
487 return ERROR_DEV_NOT_EXIST;
488 }
489 DeviceExtension->IoPorts.RangeStart = AccessRanges[1].RangeStart;
490 DeviceExtension->IoPorts.RangeLength = AccessRanges[1].RangeLength;
491 DeviceExtension->IoPorts.RangeInIoSpace = AccessRanges[1].RangeInIoSpace;
492
493 DeviceExtension->IoPorts.Mapped = VideoPortGetDeviceBase(DeviceExtension,
494 DeviceExtension->IoPorts.RangeStart,
495 DeviceExtension->IoPorts.RangeLength,
496 DeviceExtension->IoPorts.RangeInIoSpace
499 if (!DeviceExtension->IoPorts.Mapped)
500 {
501 VideoDebugPrint((Error, "Bochs: failed to map dispi interface\n"));
502 return ERROR_DEV_NOT_EXIST;
503 }
504 VideoDebugPrint((Info, "Bochs: address 0x%x mapped to 0x%p\n",
505 DeviceExtension->IoPorts.RangeStart.LowPart,
506 DeviceExtension->IoPorts.Mapped));
507
508 return NO_ERROR;
509}
510
511CODE_SEG("PAGE")
514 _In_ PVOID HwDeviceExtension)
515{
516 ULONG PotentialModeCount = 0;
517 PBOCHS_DEVICE_EXTENSION DeviceExtension = HwDeviceExtension;
518
519 VideoDebugPrint((Info, "Bochs: BochsInitialize\n"));
520
521 if (!BochsGetControllerInfo(DeviceExtension))
522 {
523 BochsFreeResources(DeviceExtension);
524 return FALSE;
525 }
526
527 PotentialModeCount = ARRAYSIZE(BochsAvailableResolutions);
528 DeviceExtension->AvailableModeInfo = VideoPortAllocatePool(HwDeviceExtension,
530 PotentialModeCount * sizeof(BOCHS_SIZE),
531 BOCHS_TAG);
532 if (!DeviceExtension->AvailableModeInfo)
533 {
534 VideoDebugPrint((Error, "Bochs: insufficient resources\n"));
535 BochsFreeResources(DeviceExtension);
536 return FALSE;
537 }
538
539 if (!BochsInitializeSuitableModeInfo(DeviceExtension, PotentialModeCount))
540 {
541 BochsFreeResources(DeviceExtension);
542 return FALSE;
543 }
544
545 return TRUE;
546}
547
548CODE_SEG("PAGE")
551 _In_ PVOID HwDeviceExtension,
552 _Inout_ PVIDEO_REQUEST_PACKET RequestPacket)
553{
554 PBOCHS_DEVICE_EXTENSION DeviceExtension = HwDeviceExtension;
555
556 VideoDebugPrint((Info, "Bochs: BochsStartIO\n"));
557 RequestPacket->StatusBlock->Status = ERROR_INVALID_FUNCTION;
558
559 switch (RequestPacket->IoControlCode)
560 {
562 {
563 VideoDebugPrint((Info, "BochsStartIO - Map video memory\n"));
564 if (RequestPacket->InputBufferLength < sizeof(VIDEO_MEMORY))
565 {
566 VideoDebugPrint((Error, "BochsStartIO - invalid input parameter\n"));
567 RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER;
568 return FALSE;
569 }
570 if (RequestPacket->OutputBufferLength < sizeof(VIDEO_MEMORY_INFORMATION))
571 {
572 VideoDebugPrint((Error, "BochsStartIO - Insufficent output buffer\n"));
573 RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER;
574 return FALSE;
575 }
576 return BochsMapVideoMemory(DeviceExtension,
577 (PVIDEO_MEMORY)RequestPacket->InputBuffer,
578 (PVIDEO_MEMORY_INFORMATION)RequestPacket->OutputBuffer,
579 RequestPacket->StatusBlock);
580 }
581
583 {
584 VideoDebugPrint((Info, "BochsStartIO - Unmap video memory\n"));
585 if (RequestPacket->InputBufferLength < sizeof(VIDEO_MEMORY))
586 {
587 RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER;
588 return FALSE;
589 }
590 return BochsUnmapVideoMemory(DeviceExtension,
591 (PVIDEO_MEMORY)RequestPacket->InputBuffer,
592 RequestPacket->StatusBlock);
593 }
594
596 {
597 VideoDebugPrint((Info, "BochsStartIO - Query num available modes\n"));
598 if (RequestPacket->OutputBufferLength < sizeof(VIDEO_NUM_MODES))
599 {
600 RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER;
601 return FALSE;
602 }
603 return BochsQueryNumAvailableModes(DeviceExtension,
604 (PVIDEO_NUM_MODES)RequestPacket->OutputBuffer,
605 RequestPacket->StatusBlock);
606 }
607
609 {
610 VideoDebugPrint((Info, "BochsStartIO - Query available modes\n"));
611 if (RequestPacket->OutputBufferLength < DeviceExtension->AvailableModeCount * sizeof(VIDEO_MODE_INFORMATION))
612 {
613 RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER;
614 return FALSE;
615 }
616 return BochsQueryAvailableModes(DeviceExtension,
617 (PVIDEO_MODE_INFORMATION)RequestPacket->OutputBuffer,
618 RequestPacket->StatusBlock);
619 }
620
622 {
623 VideoDebugPrint((Info, "BochsStartIO - Set current mode\n"));
624 if (RequestPacket->InputBufferLength < sizeof(VIDEO_MODE))
625 {
626 VideoDebugPrint((Error, "Bochs: set current mode - invalid parameter\n"));
627 RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER;
628 return FALSE;
629 }
630 return BochsSetCurrentMode(DeviceExtension,
631 (PVIDEO_MODE)RequestPacket->InputBuffer,
632 RequestPacket->StatusBlock);
633 }
634
636 {
637 VideoDebugPrint((Info, "BochsStartIO - Query current mode\n"));
638 if (RequestPacket->OutputBufferLength < sizeof(VIDEO_MODE_INFORMATION))
639 {
640 RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER;
641 return FALSE;
642 }
643 return BochsQueryCurrentMode(DeviceExtension,
644 (PVIDEO_MODE_INFORMATION)RequestPacket->OutputBuffer,
645 RequestPacket->StatusBlock);
646 }
647
649 {
650 VideoDebugPrint((Info, "BochsStartIO - Reset device\n"));
651 return BochsResetDevice(DeviceExtension,
652 RequestPacket->StatusBlock);
653 }
654
656 {
657 VideoDebugPrint((Info, "BochsStartIO - Get child state\n"));
658 if (RequestPacket->OutputBufferLength < sizeof(ULONG))
659 {
660 RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER;
661 return FALSE;
662 }
663 return BochsGetChildState(DeviceExtension,
664 (PULONG)RequestPacket->OutputBuffer,
665 RequestPacket->StatusBlock);
666 }
667
668 default:
669 {
670 VideoDebugPrint((Warn, "BochsStartIO - Unknown IOCTL - 0x%08x\n",
671 RequestPacket->IoControlCode));
672 break;
673 }
674 }
675
676 return FALSE;
677}
678
679CODE_SEG("PAGE")
682 _In_ PVOID HwDeviceExtension,
683 _In_ ULONG HwId,
684 _In_ PVIDEO_POWER_MANAGEMENT VideoPowerControl)
685{
686 return NO_ERROR;
687}
688
689CODE_SEG("PAGE")
692 _In_ PVOID HwDeviceExtension,
693 _In_ ULONG HwId,
694 _Out_ PVIDEO_POWER_MANAGEMENT VideoPowerControl)
695{
697}
698
699CODE_SEG("PAGE")
702 _In_ PVOID HwDeviceExtension,
703 _In_ PVIDEO_CHILD_ENUM_INFO ChildEnumInfo,
704 _Out_ PVIDEO_CHILD_TYPE VideoChildType,
705 _Out_ PUCHAR pChildDescriptor,
706 _Out_ PULONG UId,
707 _Out_ PULONG pUnused)
708{
709 PBOCHS_DEVICE_EXTENSION DeviceExtension = HwDeviceExtension;
710
711 VideoDebugPrint((Info, "Bochs: BochsGetVideoChildDescriptor Entry\n"));
712
713 if (ChildEnumInfo->Size < sizeof(*VideoChildType))
715
716 if (ChildEnumInfo->ChildIndex == 0)
717 {
718 /* Ignore ACPI enumerations */
720 }
721
722 *pUnused = 0;
723 if (ChildEnumInfo->ChildIndex == DISPLAY_ADAPTER_HW_ID)
724 {
725 *VideoChildType = VideoChip;
727 }
728
729 if (ChildEnumInfo->ChildIndex != 1)
731
732 *UId = 0;
733 *VideoChildType = Monitor;
734
735 if (pChildDescriptor &&
736 ChildEnumInfo->ChildDescriptorSize >= VBE_EDID_SIZE &&
737 !DeviceExtension->IoPorts.RangeInIoSpace)
738 {
739 memcpy(pChildDescriptor,
740 DeviceExtension->IoPorts.Mapped,
742 }
743
744 VideoDebugPrint((Info, "Bochs: BochsGetVideoChildDescriptor Exit Uid:%d\n", ChildEnumInfo->ChildIndex));
745
747}
748
751{
752 VIDEO_HW_INITIALIZATION_DATA VideoInitData;
753
754 VideoDebugPrint((Info, "Bochs: DriverEntry\n"));
755 VideoPortZeroMemory(&VideoInitData, sizeof(VideoInitData));
756 VideoInitData.HwInitDataSize = sizeof(VideoInitData);
757 VideoInitData.HwFindAdapter = BochsFindAdapter;
758 VideoInitData.HwInitialize = BochsInitialize;
759 VideoInitData.HwStartIO = BochsStartIO;
760 VideoInitData.HwDeviceExtensionSize = sizeof(BOCHS_DEVICE_EXTENSION);
761 VideoInitData.HwSetPowerState = BochsSetPowerState;
762 VideoInitData.HwGetPowerState = BochsGetPowerState;
764
765 return VideoPortInitialize(Context1, Context2, &VideoInitData, NULL);
766}
#define CODE_SEG(...)
unsigned char BOOLEAN
#define VOID
Definition: acefi.h:82
BOOL Error
Definition: chkdsk.c:66
BOOLEAN NTAPI BochsInitialize(_In_ PVOID HwDeviceExtension)
Definition: bochsmp.c:513
static VOID BochsGetModeInfo(_In_ PBOCHS_SIZE AvailableModeInfo, _Out_ PVIDEO_MODE_INFORMATION ModeInfo, _In_ ULONG Index)
Definition: bochsmp.c:201
static BOOLEAN BochsMapVideoMemory(_In_ PBOCHS_DEVICE_EXTENSION DeviceExtension, _In_ PVIDEO_MEMORY RequestedAddress, _Out_ PVIDEO_MEMORY_INFORMATION MapInformation, _Out_ PSTATUS_BLOCK StatusBlock)
Definition: bochsmp.c:234
static BOOLEAN NTAPI BochsUnmapVideoMemory(_In_ PBOCHS_DEVICE_EXTENSION DeviceExtension, _In_ PVIDEO_MEMORY VideoMemory, _Out_ PSTATUS_BLOCK StatusBlock)
Definition: bochsmp.c:276
static BOOLEAN BochsWriteDispIAndCheck(_In_ PBOCHS_DEVICE_EXTENSION DeviceExtension, _In_ ULONG Index, _In_ USHORT Value)
Definition: bochsmp.c:85
VP_STATUS NTAPI BochsFindAdapter(_In_ PVOID HwDeviceExtension, _In_ PVOID HwContext, _In_ PWSTR ArgumentString, _In_ PVIDEO_PORT_CONFIG_INFO ConfigInfo, _In_ PUCHAR Again)
Definition: bochsmp.c:445
static BOOLEAN BochsQueryCurrentMode(_In_ PBOCHS_DEVICE_EXTENSION DeviceExtension, _Out_ PVIDEO_MODE_INFORMATION VideoModeInfo, _Out_ PSTATUS_BLOCK StatusBlock)
Definition: bochsmp.c:393
VP_STATUS NTAPI BochsGetPowerState(_In_ PVOID HwDeviceExtension, _In_ ULONG HwId, _Out_ PVIDEO_POWER_MANAGEMENT VideoPowerControl)
Definition: bochsmp.c:691
static BOOLEAN BochsGetChildState(_In_ PBOCHS_DEVICE_EXTENSION DeviceExtension, _Out_ PULONG pChildState, _Out_ PSTATUS_BLOCK StatusBlock)
Definition: bochsmp.c:431
static const BOCHS_SIZE BochsAvailableResolutions[]
Definition: bochsmp.c:10
BOOLEAN NTAPI BochsStartIO(_In_ PVOID HwDeviceExtension, _Inout_ PVIDEO_REQUEST_PACKET RequestPacket)
Definition: bochsmp.c:550
static VOID BochsFreeResources(_Inout_ PBOCHS_DEVICE_EXTENSION DeviceExtension)
Definition: bochsmp.c:38
VP_STATUS NTAPI BochsSetPowerState(_In_ PVOID HwDeviceExtension, _In_ ULONG HwId, _In_ PVIDEO_POWER_MANAGEMENT VideoPowerControl)
Definition: bochsmp.c:681
#define HEX(c)
VP_STATUS NTAPI BochsGetVideoChildDescriptor(_In_ PVOID HwDeviceExtension, _In_ PVIDEO_CHILD_ENUM_INFO ChildEnumInfo, _Out_ PVIDEO_CHILD_TYPE VideoChildType, _Out_ PUCHAR pChildDescriptor, _Out_ PULONG UId, _Out_ PULONG pUnused)
Definition: bochsmp.c:701
static BOOLEAN BochsQueryNumAvailableModes(_In_ PBOCHS_DEVICE_EXTENSION DeviceExtension, _Out_ PVIDEO_NUM_MODES AvailableModes, _Out_ PSTATUS_BLOCK StatusBlock)
Definition: bochsmp.c:301
static BOOLEAN BochsInitializeSuitableModeInfo(_In_ PBOCHS_DEVICE_EXTENSION DeviceExtension, _In_ ULONG PotentialModeCount)
Definition: bochsmp.c:96
static BOOLEAN BochsSetCurrentMode(_In_ PBOCHS_DEVICE_EXTENSION DeviceExtension, _In_ PVIDEO_MODE RequestedMode, _Out_ PSTATUS_BLOCK StatusBlock)
Definition: bochsmp.c:341
static USHORT BochsReadDispI(_In_ PBOCHS_DEVICE_EXTENSION DeviceExtension, _In_ ULONG Index)
Definition: bochsmp.c:68
static BOOLEAN BochsQueryAvailableModes(_In_ PBOCHS_DEVICE_EXTENSION DeviceExtension, _Out_ PVIDEO_MODE_INFORMATION ReturnedModes, _Out_ PSTATUS_BLOCK StatusBlock)
Definition: bochsmp.c:316
static BOOLEAN BochsResetDevice(_In_ PBOCHS_DEVICE_EXTENSION DeviceExtension, _Out_ PSTATUS_BLOCK StatusBlock)
Definition: bochsmp.c:417
static VOID BochsWriteDispI(_In_ PBOCHS_DEVICE_EXTENSION DeviceExtension, _In_ ULONG Index, _In_ USHORT Value)
Definition: bochsmp.c:50
static BOOLEAN BochsGetControllerInfo(_Inout_ PBOCHS_DEVICE_EXTENSION DeviceExtension)
Definition: bochsmp.c:125
#define VBE_DISPI_INDEX_BPP
Definition: bochsmp.h:31
#define VBE_DISPI_GETCAPS
Definition: bochsmp.h:35
#define VBE_DISPI_IOPORT_INDEX
Definition: bochsmp.h:20
#define VBE_DISPI_ENABLED
Definition: bochsmp.h:34
#define VBE_DISPI_INDEX_ID
Definition: bochsmp.h:22
#define VBE_EDID_SIZE
Definition: bochsmp.h:18
#define VBE_DISPI_IOPORT_DATA
Definition: bochsmp.h:21
#define VBE_DISPI_INDEX_XRES
Definition: bochsmp.h:29
#define VBE_DISPI_ID2
Definition: bochsmp.h:25
#define VBE_DISPI_ID4
Definition: bochsmp.h:27
#define VBE_DISPI_ID0
Definition: bochsmp.h:23
#define VBE_DISPI_DISABLED
Definition: bochsmp.h:33
#define BOCHS_TAG
Definition: bochsmp.h:39
#define VBE_DISPI_INDEX_YRES
Definition: bochsmp.h:30
#define VBE_DISPI_INDEX_ENABLE
Definition: bochsmp.h:32
#define VBE_DISPI_ID5
Definition: bochsmp.h:28
#define VBE_DISPI_INDEX_VIDEO_MEMORY_64K
Definition: bochsmp.h:37
#define VBE_DISPI_LFB_ENABLED
Definition: bochsmp.h:36
#define ERROR_DEV_NOT_EXIST
Definition: dderror.h:8
#define NO_ERROR
Definition: dderror.h:5
#define ERROR_DEVICE_REINITIALIZATION_NEEDED
Definition: dderror.h:16
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
#define ERROR_INVALID_FUNCTION
Definition: dderror.h:6
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
DRIVER_INITIALIZE DriverEntry
Definition: condrv.c:21
Status
Definition: gdiplustypes.h:25
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define _Inout_
Definition: ms_sal.h:378
#define _Out_
Definition: ms_sal.h:345
#define _In_
Definition: ms_sal.h:308
int Count
Definition: noreturn.cpp:7
#define UNICODE_NULL
#define IOCTL_VIDEO_MAP_VIDEO_MEMORY
Definition: ntddvdeo.h:173
#define VIDEO_MODE_GRAPHICS
Definition: ntddvdeo.h:364
#define IOCTL_VIDEO_UNMAP_VIDEO_MEMORY
Definition: ntddvdeo.h:248
#define VIDEO_MODE_COLOR
Definition: ntddvdeo.h:363
#define IOCTL_VIDEO_QUERY_CURRENT_MODE
Definition: ntddvdeo.h:182
#define IOCTL_VIDEO_GET_CHILD_STATE
Definition: ntddvdeo.h:164
#define IOCTL_VIDEO_SET_CURRENT_MODE
Definition: ntddvdeo.h:221
#define IOCTL_VIDEO_RESET_DEVICE
Definition: ntddvdeo.h:206
#define VIDEO_CHILD_ACTIVE
Definition: ntddvdeo.h:608
#define VIDEO_MODE_NO_OFF_SCREEN
Definition: ntddvdeo.h:368
struct _VIDEO_MODE_INFORMATION VIDEO_MODE_INFORMATION
#define IOCTL_VIDEO_QUERY_AVAIL_MODES
Definition: ntddvdeo.h:176
#define IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES
Definition: ntddvdeo.h:191
#define L(x)
Definition: ntvdm.h:50
unsigned short USHORT
Definition: pedump.c:61
_Must_inspect_result_ _In_ PVOID _In_ struct _HW_INITIALIZATION_DATA _In_ PVOID HwContext
Definition: srb.h:907
VPAPI USHORT NTAPI VideoPortReadRegisterUshort(IN PUSHORT Register)
VPAPI VOID NTAPI VideoPortZeroMemory(IN PVOID Destination, IN ULONG Length)
#define VIDEO_ENUM_INVALID_DEVICE
Definition: video.h:141
@ Warn
Definition: video.h:589
VPAPI VP_STATUS NTAPI VideoPortVerifyAccessRanges(_In_ PVOID HwDeviceExtension, _In_opt_ ULONG NumAccessRanges, _In_reads_opt_(NumAccessRanges) PVIDEO_ACCESS_RANGE AccessRanges)
Claims or releases a range of hardware resources and checks for conflicts.
Definition: resource.c:916
VPAPI VOID NTAPI VideoPortWriteRegisterUshort(IN PUSHORT Register, IN USHORT Value)
VPAPI VP_STATUS NTAPI VideoPortUnmapMemory(IN PVOID HwDeviceExtension, IN OUT PVOID VirtualAddress, IN HANDLE ProcessHandle)
LONG VP_STATUS
Definition: video.h:153
VPAPI PVOID NTAPI VideoPortGetDeviceBase(IN PVOID HwDeviceExtension, IN PHYSICAL_ADDRESS IoAddress, IN ULONG NumberOfUchars, IN UCHAR InIoSpace)
Definition: resource.c:477
#define VIDEO_ENUM_NO_MORE_DEVICES
Definition: video.h:140
VPAPI VOID NTAPI VideoPortFreePool(IN PVOID HwDeviceExtension, IN PVOID Ptr)
Definition: resource.c:1039
VPAPI ULONG NTAPI VideoPortInitialize(IN PVOID Argument1, IN PVOID Argument2, IN PVIDEO_HW_INITIALIZATION_DATA HwInitializationData, IN PVOID HwContext)
Definition: videoprt.c:740
VPAPI VP_STATUS NTAPI VideoPortMapMemory(IN PVOID HwDeviceExtension, IN PHYSICAL_ADDRESS PhysicalAddress, IN OUT PULONG Length, IN PULONG InIoSpace, IN OUT PVOID *VirtualAddress)
VPAPI USHORT NTAPI VideoPortReadPortUshort(IN PUSHORT Port)
#define DISPLAY_ADAPTER_HW_ID
Definition: video.h:115
enum _VIDEO_CHILD_TYPE * PVIDEO_CHILD_TYPE
VPAPI PVOID NTAPI VideoPortAllocatePool(IN PVOID HwDeviceExtension, IN VP_POOL_TYPE PoolType, IN SIZE_T NumberOfBytes, IN ULONG Tag)
Definition: resource.c:1024
#define VIDEO_MEMORY_SPACE_MEMORY
Definition: video.h:132
@ Monitor
Definition: video.h:270
@ VideoChip
Definition: video.h:272
VPAPI VP_STATUS NTAPI VideoPortSetRegistryParameters(IN PVOID HwDeviceExtension, IN PWSTR ValueName, IN PVOID ValueData, IN ULONG ValueLength)
Definition: videoprt.c:1081
#define VIDEO_ENUM_MORE_DEVICES
Definition: video.h:139
#define VideoDebugPrint(x)
Definition: video.h:75
VPAPI VP_STATUS NTAPI VideoPortGetAccessRanges(_In_ PVOID HwDeviceExtension, _In_opt_ ULONG NumRequestedResources, _In_reads_opt_(NumRequestedResources) PIO_RESOURCE_DESCRIPTOR RequestedResources, _In_ ULONG NumAccessRanges, _Out_writes_(NumAccessRanges) PVIDEO_ACCESS_RANGE AccessRanges, _In_ PVOID VendorId, _In_ PVOID DeviceId, _Out_ PULONG Slot)
Retrieves bus-relative (mainly PCI) hardware resources access ranges and, if possible,...
Definition: resource.c:626
VPAPI VOID NTAPI VideoPortWritePortUshort(IN PUSHORT Port, IN USHORT Value)
@ VpPagedPool
Definition: video.h:543
#define VIDEO_MEMORY_SPACE_IO
Definition: video.h:133
PHYSICAL_ADDRESS RangeStart
Definition: bochsmp.h:50
UCHAR RangeInIoSpace
Definition: bochsmp.h:52
PBOCHS_SIZE AvailableModeInfo
Definition: bochsmp.h:57
BOCHS_ADDRESS_RANGE FrameBuffer
Definition: bochsmp.h:61
ULONG AvailableModeCount
Definition: bochsmp.h:58
BOCHS_ADDRESS_RANGE IoPorts
Definition: bochsmp.h:62
USHORT YResolution
Definition: bochsmp.h:44
USHORT XResolution
Definition: bochsmp.h:43
ULONG RangeLength
Definition: video.h:216
UCHAR RangeInIoSpace
Definition: video.h:217
PHYSICAL_ADDRESS RangeStart
Definition: video.h:215
PVIDEO_HW_FIND_ADAPTER HwFindAdapter
Definition: video.h:674
PVIDEO_HW_START_IO HwStartIO
Definition: video.h:677
PVIDEO_HW_POWER_SET HwSetPowerState
Definition: video.h:683
PVIDEO_HW_POWER_GET HwGetPowerState
Definition: video.h:684
PVIDEO_HW_GET_CHILD_DESCRIPTOR HwGetVideoChildDescriptor
Definition: video.h:685
PVIDEO_HW_INITIALIZE HwInitialize
Definition: video.h:675
_In_ PNET_PNP_EVENT _In_ PTDI_PNP_CONTEXT Context1
Definition: tdikrnl.h:1095
_In_ PNET_PNP_EVENT _In_ PTDI_PNP_CONTEXT _In_ PTDI_PNP_CONTEXT Context2
Definition: tdikrnl.h:1096
uint16_t * PWSTR
Definition: typedefs.h:56
uint32_t * PULONG
Definition: typedefs.h:59
#define NTAPI
Definition: typedefs.h:36
uint16_t * PUSHORT
Definition: typedefs.h:56
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
LONGLONG QuadPart
Definition: typedefs.h:114
ULONG LowPart
Definition: typedefs.h:106
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:690
_In_ WDFCOLLECTION _In_ ULONG Index
_Must_inspect_result_ _In_ WDFDEVICE _In_ LPCGUID _Out_ PINTERFACE _In_ USHORT _In_ USHORT Version
Definition: wdffdo.h:469
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413
__wchar_t WCHAR
Definition: xmlstorage.h:180