Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1546 lines
44 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. fsvga.c
  5. Abstract:
  6. This is the console fullscreen driver for the VGA card.
  7. Environment:
  8. kernel mode only
  9. Notes:
  10. Revision History:
  11. --*/
  12. #include "fsvga.h"
  13. //
  14. // Use the alloc_text pragma to specify the driver initialization routines
  15. // (they can be paged out).
  16. //
  17. #if defined(ALLOC_PRAGMA)
  18. #pragma alloc_text(INIT,DriverEntry)
  19. #pragma alloc_text(INIT,FsVgaQueryDevice)
  20. #pragma alloc_text(INIT,FsVgaPeripheralCallout)
  21. #pragma alloc_text(INIT,FsVgaServiceParameters)
  22. #endif
  23. GLOBALS Globals;
  24. NTSTATUS
  25. DriverEntry(
  26. IN PDRIVER_OBJECT DriverObject,
  27. IN PUNICODE_STRING RegistryPath
  28. )
  29. /*++
  30. Routine Description:
  31. Installable driver initialization entry point.
  32. This entry point is called directly by the I/O system.
  33. Arguments:
  34. DriverObject - Pointer to driver object created by system.
  35. RegistryPath - Pointer to the Unicode name of the registry path
  36. for this driver.
  37. Return Value:
  38. The function value is the final status from the initialization operation.
  39. --*/
  40. {
  41. NTSTATUS status = STATUS_SUCCESS;
  42. ULONG uniqueErrorValue;
  43. NTSTATUS errorCode = STATUS_SUCCESS;
  44. ULONG dumpCount = 0;
  45. ULONG dumpData[DUMP_COUNT];
  46. FsVgaPrint((1,
  47. "\n\nFSVGA-FSVGAInitialize: enter\n"));
  48. //
  49. // Zero-initialize various structures.
  50. //
  51. RtlZeroMemory(&Globals, sizeof(GLOBALS));
  52. Globals.FsVgaDebug = DEFAULT_DEBUG_LEVEL;
  53. //
  54. // Query the device resource information for this driver.
  55. //
  56. FsVgaQueryDevice(&Globals.Resource);
  57. if (!(Globals.Resource.HardwarePresent & FSVGA_HARDWARE_PRESENT)) {
  58. //
  59. // There is neither a Full Screen Video attached. Free
  60. // resources and return with unsuccessful status.
  61. //
  62. FsVgaPrint((1,
  63. "FSVGA-FsVgaInitialize: No Full Screen Video attached.\n"));
  64. status = STATUS_NO_SUCH_DEVICE;
  65. errorCode = FSVGA_NO_SUCH_DEVICE;
  66. uniqueErrorValue = FSVGA_ERROR_VALUE_BASE + 4;
  67. goto FsVgaInitializeExit;
  68. }
  69. else
  70. {
  71. //
  72. // Need to ensure that the registry path is null-terminated.
  73. // Allocate pool to hold a null-terminated copy of the path.
  74. //
  75. Globals.RegistryPath.Length = RegistryPath->Length;
  76. Globals.RegistryPath.MaximumLength = RegistryPath->Length
  77. + sizeof (UNICODE_NULL);
  78. Globals.RegistryPath.Buffer = ExAllocatePool(
  79. NonPagedPool,
  80. Globals.RegistryPath.MaximumLength);
  81. if (!Globals.RegistryPath.Buffer) {
  82. FsVgaPrint((
  83. 1,
  84. "FSVGA-FsVgaInitialize: Couldn't allocate pool for registry path\n"
  85. ));
  86. status = STATUS_UNSUCCESSFUL;
  87. errorCode = FSVGA_INSUFFICIENT_RESOURCES;
  88. uniqueErrorValue = FSVGA_ERROR_VALUE_BASE + 2;
  89. dumpData[0] = 0;
  90. dumpCount = 1;
  91. goto FsVgaInitializeExit;
  92. }
  93. RtlMoveMemory(Globals.RegistryPath.Buffer,
  94. RegistryPath->Buffer,
  95. RegistryPath->Length);
  96. Globals.RegistryPath.Buffer [RegistryPath->Length / sizeof (WCHAR)] = L'\0';
  97. //
  98. // Get the service parameters (e.g., user-configurable number
  99. // of resends, polling iterations, etc.).
  100. //
  101. FsVgaServiceParameters(&Globals.Configuration,
  102. &Globals.RegistryPath);
  103. }
  104. //
  105. // Once initialization is finished, load the device map information
  106. // into the registry so that setup can determine which full screen
  107. // port are active.
  108. //
  109. if (Globals.Resource.HardwarePresent & FSVGA_HARDWARE_PRESENT) {
  110. status = RtlWriteRegistryValue(RTL_REGISTRY_DEVICEMAP,
  111. L"FullScreenVideo",
  112. DD_FULLSCREEN_VIDEO_DEVICE_NAME,
  113. REG_SZ,
  114. Globals.RegistryPath.Buffer,
  115. Globals.RegistryPath.Length);
  116. if (!NT_SUCCESS(status))
  117. {
  118. FsVgaPrint((1,
  119. "FSVGA-FSVGAInitialize: Could not store keyboard name in DeviceMap\n"));
  120. errorCode = FSVGA_NO_DEVICEMAP_CREATED;
  121. uniqueErrorValue = FSVGA_ERROR_VALUE_BASE + 90;
  122. dumpCount = 0;
  123. goto FsVgaInitializeExit;
  124. }
  125. else
  126. {
  127. FsVgaPrint((1,
  128. "FSVGA-FSVGAInitialize: Stored pointer name in DeviceMap\n"));
  129. }
  130. }
  131. ASSERT(status == STATUS_SUCCESS);
  132. //
  133. // Set up the device driver entry points.
  134. //
  135. DriverObject->MajorFunction[IRP_MJ_CREATE] = FsVgaOpenCloseDispatch;
  136. DriverObject->MajorFunction[IRP_MJ_CLOSE] = FsVgaOpenCloseDispatch;
  137. DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = FsVgaDeviceControl;
  138. DriverObject->DriverUnload = FsVgaDriverUnload;
  139. DriverObject->DriverExtension->AddDevice = FsVgaAddDevice;
  140. DriverObject->MajorFunction[IRP_MJ_PNP] = FsVgaDevicePnp;
  141. DriverObject->MajorFunction[IRP_MJ_POWER] = FsVgaDevicePower;
  142. FsVgaInitializeExit:
  143. if (errorCode != STATUS_SUCCESS)
  144. {
  145. //
  146. // Log an error/warning message.
  147. //
  148. FsVgaLogError(DriverObject,
  149. errorCode,
  150. uniqueErrorValue,
  151. status,
  152. dumpData,
  153. dumpCount
  154. );
  155. }
  156. FsVgaPrint((1,
  157. "FSVGA-FsVgaInitialize: exit\n"));
  158. return(status);
  159. }
  160. VOID
  161. FsVgaQueryDevice(
  162. IN PFSVGA_RESOURCE_INFORMATION Resource
  163. )
  164. /*++
  165. Routine Description:
  166. This routine retrieves the resource information for the video.
  167. Arguments:
  168. Resource - Pointer to the resource information.
  169. Return Value:
  170. --*/
  171. {
  172. INTERFACE_TYPE interfaceType;
  173. ULONG i;
  174. for (i = 0; i < MaximumInterfaceType; i++)
  175. {
  176. //
  177. // Get the registry information for this device.
  178. //
  179. interfaceType = i;
  180. IoQueryDeviceDescription(&interfaceType, // Bus type
  181. NULL, // Bus number
  182. NULL, // Controller type
  183. NULL, // Controller number
  184. NULL, // Peripheral type
  185. NULL, // Peripheral number
  186. FsVgaPeripheralCallout,
  187. (PVOID) Resource);
  188. if (Resource->HardwarePresent & FSVGA_HARDWARE_PRESENT)
  189. {
  190. break;
  191. }
  192. else
  193. {
  194. FsVgaPrint((1,
  195. "FSVGA-FsVgaConfiguration: IoQueryDeviceDescription for bus type %d failed\n",
  196. interfaceType));
  197. }
  198. }
  199. }
  200. NTSTATUS
  201. FsVgaPeripheralCallout(
  202. IN PVOID Context,
  203. IN PUNICODE_STRING PathName,
  204. IN INTERFACE_TYPE BusType,
  205. IN ULONG BusNumber,
  206. IN PKEY_VALUE_FULL_INFORMATION *BusInformation,
  207. IN CONFIGURATION_TYPE ControllerType,
  208. IN ULONG ControllerNumber,
  209. IN PKEY_VALUE_FULL_INFORMATION *ControllerInformation,
  210. IN CONFIGURATION_TYPE PeripheralType,
  211. IN ULONG PeripheralNumber,
  212. IN PKEY_VALUE_FULL_INFORMATION *PeripheralInformation
  213. )
  214. /*++
  215. Routine Description:
  216. This is the callout routine sent as a parameter to
  217. IoQueryDeviceDescription. It grabs the Display controller
  218. configuration information.
  219. Arguments:
  220. Context - Context parameter that was passed in by the routine
  221. that called IoQueryDeviceDescription.
  222. PathName - The full pathname for the registry key.
  223. BusType - Bus interface type (Isa, Eisa, Mca, etc.).
  224. BusNumber - The bus sub-key (0, 1, etc.).
  225. BusInformation - Pointer to the array of pointers to the full value
  226. information for the bus.
  227. ControllerType - The controller type (should be DisplayController).
  228. ControllerNumber - The controller sub-key (0, 1, etc.).
  229. ControllerInformation - Pointer to the array of pointers to the full
  230. value information for the controller key.
  231. PeripheralType - The peripheral type (should be MonitorPeripheral).
  232. PeripheralNumber - The peripheral sub-key.
  233. PeripheralInformation - Pointer to the array of pointers to the full
  234. value information for the peripheral key.
  235. Return Value:
  236. None. If successful, will have the following side-effects:
  237. - Sets DeviceObject->DeviceExtension->HardwarePresent.
  238. - Sets configuration fields in
  239. DeviceObject->DeviceExtension->Configuration.
  240. --*/
  241. {
  242. PFSVGA_RESOURCE_INFORMATION resource;
  243. NTSTATUS status = STATUS_SUCCESS;
  244. FsVgaPrint((1,
  245. "FSVGA-FsVgaPeripheralCallout: Path @ 0x%x, Bus Type 0x%x, Bus Number 0x%x\n",
  246. PathName, BusType, BusNumber));
  247. FsVgaPrint((1,
  248. " Controller Type 0x%x, Controller Number 0x%x, Controller info @ 0x%x\n",
  249. ControllerType, ControllerNumber, ControllerInformation));
  250. FsVgaPrint((1,
  251. " Peripheral Type 0x%x, Peripheral Number 0x%x, Peripheral info @ 0x%x\n",
  252. PeripheralType, PeripheralNumber, PeripheralInformation));
  253. //
  254. // If we already have the configuration information for the
  255. // keyboard peripheral, or if the peripheral identifier is missing,
  256. // just return.
  257. //
  258. resource = (PFSVGA_RESOURCE_INFORMATION) Context;
  259. if (resource->HardwarePresent & FSVGA_HARDWARE_PRESENT)
  260. {
  261. return (status);
  262. }
  263. resource->HardwarePresent |= FSVGA_HARDWARE_PRESENT;
  264. #ifdef RESOURCE_REQUIREMENTS
  265. //
  266. // Get the bus information.
  267. //
  268. resource->InterfaceType = BusType;
  269. resource->BusNumber = BusNumber;
  270. #endif
  271. return(status);
  272. }
  273. #ifdef RESOURCE_REQUIREMENTS
  274. NTSTATUS
  275. FsVgaQueryAperture(
  276. OUT PIO_RESOURCE_LIST *pApertureRequirements
  277. // OUT PFSVGA_RESOURCE_INFORMATION Resource
  278. )
  279. /*++
  280. Routine Description:
  281. Queries the possible FsVga settings.
  282. Arguments:
  283. ApertureRequirements - returns the possible FsVga settings
  284. Return Value:
  285. NTSTATUS
  286. --*/
  287. {
  288. PIO_RESOURCE_LIST Requirements;
  289. ULONG PortLength;
  290. ULONG RangeStart;
  291. ULONG i;
  292. Requirements = ExAllocatePool(PagedPool,
  293. sizeof(IO_RESOURCE_LIST) + (MaximumPortCount-1) * sizeof(IO_RESOURCE_DESCRIPTOR));
  294. if (Requirements == NULL) {
  295. FsVgaPrint((1,
  296. "FSVGA-FsVgaQueryAperture: Could not allocate resource list\n"));
  297. return STATUS_INSUFFICIENT_RESOURCES;
  298. }
  299. Requirements->Version =
  300. Requirements->Revision = 1;
  301. Requirements->Count = MaximumPortCount;
  302. for (i = 0; i < MaximumPortCount; i++) {
  303. Requirements->Descriptors[i].Option = IO_RESOURCE_PREFERRED;
  304. Requirements->Descriptors[i].Type = CmResourceTypePort;
  305. Requirements->Descriptors[i].ShareDisposition = CmResourceShareShared;
  306. Requirements->Descriptors[i].Flags = CM_RESOURCE_PORT_IO;
  307. switch (i) {
  308. case CRTCAddressPortColor:
  309. PortLength = 1;
  310. RangeStart = VGA_BASE_IO_PORT + CRTC_ADDRESS_PORT_COLOR;
  311. break;
  312. case CRTCDataPortColor:
  313. PortLength = 1;
  314. RangeStart = VGA_BASE_IO_PORT + CRTC_DATA_PORT_COLOR;
  315. break;
  316. case GRAPHAddressPort:
  317. PortLength = 2;
  318. RangeStart = VGA_BASE_IO_PORT + GRAPH_ADDRESS_PORT;
  319. break;
  320. case SEQAddressPort:
  321. PortLength = 2;
  322. RangeStart = VGA_BASE_IO_PORT + SEQ_ADDRESS_PORT;
  323. break;
  324. }
  325. Requirements->Descriptors[i].u.Port.MinimumAddress.QuadPart = RangeStart;
  326. Requirements->Descriptors[i].u.Port.MaximumAddress.QuadPart = RangeStart +
  327. (PortLength - 1);
  328. Requirements->Descriptors[i].u.Port.Alignment = 1;
  329. Requirements->Descriptors[i].u.Port.Length = PortLength;
  330. }
  331. *pApertureRequirements = Requirements;
  332. return STATUS_SUCCESS;
  333. }
  334. #endif
  335. NTSTATUS
  336. FsVgaCreateResource(
  337. IN PFSVGA_CONFIGURATION_INFORMATION configuration,
  338. OUT PCM_PARTIAL_RESOURCE_LIST *pResourceList
  339. )
  340. /*++
  341. Routine Description:
  342. Create the possible FsVga resousrce settings.
  343. Arguments:
  344. ResourceList - returns the possible FsVga settings
  345. Return Value:
  346. NTSTATUS
  347. --*/
  348. {
  349. PCM_PARTIAL_RESOURCE_LIST Requirements;
  350. ULONG PortLength;
  351. ULONG RangeStart;
  352. ULONG i;
  353. USHORT IOPort = configuration->IOPort;
  354. Requirements = ExAllocatePool(PagedPool,
  355. sizeof(CM_PARTIAL_RESOURCE_LIST) + (MaximumPortCount-1) * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
  356. if (Requirements == NULL) {
  357. FsVgaPrint((1,
  358. "FSVGA-FsVgaCreateResoursce: Could not allocate resource list\n"));
  359. return STATUS_INSUFFICIENT_RESOURCES;
  360. }
  361. Requirements->Version =
  362. Requirements->Revision = 1;
  363. Requirements->Count = MaximumPortCount;
  364. for (i = 0; i < MaximumPortCount; i++) {
  365. Requirements->PartialDescriptors[i].Type = CmResourceTypePort;
  366. Requirements->PartialDescriptors[i].ShareDisposition = CmResourceShareShared;
  367. Requirements->PartialDescriptors[i].Flags = CM_RESOURCE_PORT_IO;
  368. switch (i) {
  369. case CRTCAddressPortColor:
  370. PortLength = 1;
  371. RangeStart = IOPort + CRTC_ADDRESS_PORT_COLOR;
  372. break;
  373. case CRTCDataPortColor:
  374. PortLength = 1;
  375. RangeStart = IOPort + CRTC_DATA_PORT_COLOR;
  376. break;
  377. case GRAPHAddressPort:
  378. PortLength = 2;
  379. RangeStart = IOPort + GRAPH_ADDRESS_PORT;
  380. break;
  381. case SEQAddressPort:
  382. PortLength = 2;
  383. RangeStart = IOPort + SEQ_ADDRESS_PORT;
  384. break;
  385. }
  386. Requirements->PartialDescriptors[i].u.Port.Start.QuadPart = RangeStart;
  387. Requirements->PartialDescriptors[i].u.Port.Length = PortLength;
  388. }
  389. *pResourceList = Requirements;
  390. return STATUS_SUCCESS;
  391. }
  392. VOID
  393. FsVgaServiceParameters(
  394. IN PFSVGA_CONFIGURATION_INFORMATION configuration,
  395. IN PUNICODE_STRING RegistryPath
  396. )
  397. /*++
  398. Routine Description:
  399. This routine retrieves this driver's service parameters information
  400. from the registry.
  401. Arguments:
  402. configuration - Pointer to the configuration information.
  403. RegistryPath - Pointer to the null-terminated Unicode name of the
  404. registry path for this driver.
  405. Return Value:
  406. --*/
  407. {
  408. UNICODE_STRING parametersPath;
  409. PWSTR path;
  410. PRTL_QUERY_REGISTRY_TABLE parameters = NULL;
  411. USHORT queriesPlusOne = 5;
  412. NTSTATUS status = STATUS_SUCCESS;
  413. #define PARAMETER_MAX 256
  414. ULONG EmulationMode;
  415. ULONG HardwareCursor;
  416. ULONG HardwareScroll;
  417. ULONG IOPort;
  418. USHORT defaultEmulationMode = 0;
  419. USHORT defaultHardwareCursor = NO_HARDWARE_CURSOR;
  420. USHORT defaultHardwareScroll = NO_HARDWARE_SCROLL;
  421. USHORT defaultIOPort = VGA_BASE_IO_PORT;
  422. parametersPath.Buffer = NULL;
  423. //
  424. // Registry path is already null-terminated, so just use it.
  425. //
  426. path = RegistryPath->Buffer;
  427. //
  428. // Allocate the Rtl query table.
  429. //
  430. parameters = ExAllocatePool(PagedPool,
  431. sizeof(RTL_QUERY_REGISTRY_TABLE) * queriesPlusOne);
  432. if (!parameters)
  433. {
  434. FsVgaPrint((1,
  435. "FSVGA-FsVgaServiceParameters: Couldn't allocate table for Rtl query to parameters for %ws\n",
  436. path));
  437. status = STATUS_UNSUCCESSFUL;
  438. }
  439. else
  440. {
  441. RtlZeroMemory(parameters,
  442. sizeof(RTL_QUERY_REGISTRY_TABLE) * queriesPlusOne);
  443. //
  444. // Form a path to this driver's Parameters subkey.
  445. //
  446. RtlInitUnicodeString(&parametersPath,
  447. NULL);
  448. parametersPath.MaximumLength = RegistryPath->Length +
  449. sizeof(L"\\Parameters");
  450. parametersPath.Buffer = ExAllocatePool(PagedPool,
  451. parametersPath.MaximumLength);
  452. if (!parametersPath.Buffer)
  453. {
  454. FsVgaPrint((1,
  455. "FSVGA-FsVgaServiceParameters: Couldn't allocate string for path to parameters for %ws\n",
  456. path));
  457. status = STATUS_UNSUCCESSFUL;
  458. }
  459. }
  460. if (NT_SUCCESS(status))
  461. {
  462. //
  463. // Form the parameters path.
  464. //
  465. RtlZeroMemory(parametersPath.Buffer,
  466. parametersPath.MaximumLength);
  467. RtlAppendUnicodeToString(&parametersPath,
  468. path);
  469. RtlAppendUnicodeToString(&parametersPath,
  470. L"\\Parameters");
  471. FsVgaPrint((1,
  472. "FsVga-FsVgaServiceParameters: parameters path is %ws\n",
  473. parametersPath.Buffer));
  474. //
  475. // Gather all of the "user specified" information from
  476. // the registry.
  477. //
  478. parameters[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
  479. parameters[0].Name = L"ConsoleFullScreen.EmulationMode";
  480. parameters[0].EntryContext = &EmulationMode;
  481. parameters[0].DefaultType = REG_DWORD;
  482. parameters[0].DefaultData = &defaultEmulationMode;
  483. parameters[0].DefaultLength = sizeof(USHORT);
  484. parameters[1].Flags = RTL_QUERY_REGISTRY_DIRECT;
  485. parameters[1].Name = L"ConsoleFullScreen.HardwareCursor";
  486. parameters[1].EntryContext = &HardwareCursor;
  487. parameters[1].DefaultType = REG_DWORD;
  488. parameters[1].DefaultData = &defaultHardwareCursor;
  489. parameters[1].DefaultLength = sizeof(USHORT);
  490. parameters[2].Flags = RTL_QUERY_REGISTRY_DIRECT;
  491. parameters[2].Name = L"ConsoleFullScreen.HardwareScroll";
  492. parameters[2].EntryContext = &HardwareScroll;
  493. parameters[2].DefaultType = REG_DWORD;
  494. parameters[2].DefaultData = &defaultHardwareScroll;
  495. parameters[2].DefaultLength = sizeof(USHORT);
  496. parameters[3].Flags = RTL_QUERY_REGISTRY_DIRECT;
  497. parameters[3].Name = L"IO Port";
  498. parameters[3].EntryContext = &IOPort;
  499. parameters[3].DefaultType = REG_DWORD;
  500. parameters[3].DefaultData = &defaultIOPort;
  501. parameters[3].DefaultLength = sizeof(USHORT);
  502. status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
  503. parametersPath.Buffer,
  504. parameters,
  505. NULL,
  506. NULL);
  507. if (!NT_SUCCESS(status))
  508. {
  509. FsVgaPrint((1,
  510. "FsVga-FsVgaServiceParameters: RtlQueryRegistryValues failed with 0x%x\n",
  511. status));
  512. }
  513. }
  514. if (!NT_SUCCESS(status))
  515. {
  516. //
  517. // Go ahead and assign driver defaults.
  518. //
  519. configuration->EmulationMode = defaultEmulationMode;
  520. configuration->HardwareCursor = defaultHardwareCursor;
  521. configuration->HardwareScroll = defaultHardwareScroll;
  522. configuration->IOPort = defaultIOPort;
  523. }
  524. else
  525. {
  526. configuration->EmulationMode = (USHORT)EmulationMode;
  527. configuration->HardwareCursor = (USHORT)HardwareCursor;
  528. configuration->HardwareScroll = (USHORT)HardwareScroll;
  529. configuration->IOPort = (USHORT)IOPort;
  530. }
  531. FsVgaPrint((1,
  532. "FsVga-FsVgaServiceParameters: Emulation Mode = %d\n",
  533. configuration->EmulationMode));
  534. FsVgaPrint((1,
  535. "FsVga-FsVgaServiceParameters: Hardware Cursor = %d\n",
  536. configuration->HardwareCursor));
  537. FsVgaPrint((1,
  538. "FsVga-FsVgaServiceParameters: Hardware Scroll = %d\n",
  539. configuration->HardwareScroll));
  540. FsVgaPrint((1,
  541. "FsVga-FsVgaServiceParameters: IO Port = %x\n",
  542. configuration->IOPort));
  543. //
  544. // Free the allocated memory before returning.
  545. //
  546. if (parametersPath.Buffer)
  547. ExFreePool(parametersPath.Buffer);
  548. if (parameters)
  549. ExFreePool(parameters);
  550. }
  551. NTSTATUS
  552. FsVgaOpenCloseDispatch(
  553. IN PDEVICE_OBJECT DeviceObject,
  554. IN PIRP Irp
  555. )
  556. /*++
  557. Routine Description:
  558. This is the dispatch routine for create/open and close requests.
  559. These requests complete successfully.
  560. Arguments:
  561. DeviceObject - Pointer to the device object.
  562. Irp - Pointer to the request packet.
  563. Return Value:
  564. Status is returned.
  565. --*/
  566. {
  567. UNREFERENCED_PARAMETER(DeviceObject);
  568. FsVgaPrint((3,"FSVGA-FsVgaOpenCloseDispatch: enter\n"));
  569. PAGED_CODE();
  570. //
  571. // Complete the request with successful status.
  572. //
  573. Irp->IoStatus.Status = STATUS_SUCCESS;
  574. Irp->IoStatus.Information = 0;
  575. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  576. FsVgaPrint((3,"FSVGA-FsVgaOpenCloseDispatch: exit\n"));
  577. return(STATUS_SUCCESS);
  578. }
  579. NTSTATUS
  580. FsVgaDeviceControl(
  581. IN PDEVICE_OBJECT DeviceObject,
  582. IN PIRP Irp
  583. )
  584. /*++
  585. Routine Description:
  586. This routine is the dispatch routine for device control requests.
  587. Arguments:
  588. DeviceObject - Pointer to the device object.
  589. Irp - Pointer to the request packet.
  590. Return Value:
  591. Status is returned.
  592. --*/
  593. {
  594. PIO_STACK_LOCATION irpSp;
  595. PVOID ioBuffer;
  596. ULONG inputBufferLength;
  597. ULONG outputBufferLength;
  598. PDEVICE_EXTENSION deviceExtension;
  599. NTSTATUS status = STATUS_SUCCESS;
  600. FsVgaPrint((2,"FSVGA-FsVgaDeviceControl: enter\n"));
  601. PAGED_CODE();
  602. //
  603. // Get a pointer to the device extension.
  604. //
  605. deviceExtension = DeviceObject->DeviceExtension;
  606. //
  607. // Initialize the returned Information field.
  608. //
  609. Irp->IoStatus.Information = 0;
  610. //
  611. // Get a pointer to the current parameters for this request. The
  612. // information is contained in the current stack location.
  613. //
  614. irpSp = IoGetCurrentIrpStackLocation(Irp);
  615. //
  616. // Get the pointer to the input/output buffer and it's length
  617. //
  618. ioBuffer = Irp->AssociatedIrp.SystemBuffer;
  619. inputBufferLength = irpSp->Parameters.DeviceIoControl.InputBufferLength;
  620. outputBufferLength = irpSp->Parameters.DeviceIoControl.OutputBufferLength;
  621. //
  622. // Case on the device control subfunction that is being performed by the
  623. // requestor.
  624. //
  625. switch (irpSp->Parameters.DeviceIoControl.IoControlCode)
  626. {
  627. case IOCTL_FSVIDEO_COPY_FRAME_BUFFER:
  628. FsVgaPrint((2, "FsVgaDeviceControl - CopyFrameBuffer\n"));
  629. status = FsVgaCopyFrameBuffer(deviceExtension,
  630. (PFSVIDEO_COPY_FRAME_BUFFER) ioBuffer,
  631. inputBufferLength);
  632. break;
  633. case IOCTL_FSVIDEO_WRITE_TO_FRAME_BUFFER:
  634. FsVgaPrint((2, "FsVgaDeviceControl - WriteToFrameBuffer\n"));
  635. status = FsVgaWriteToFrameBuffer(deviceExtension,
  636. (PFSVIDEO_WRITE_TO_FRAME_BUFFER) ioBuffer,
  637. inputBufferLength);
  638. break;
  639. case IOCTL_FSVIDEO_REVERSE_MOUSE_POINTER:
  640. FsVgaPrint((2, "FsVgaDeviceControl - ReverseMousePointer\n"));
  641. status = FsVgaReverseMousePointer(deviceExtension,
  642. (PFSVIDEO_REVERSE_MOUSE_POINTER) ioBuffer,
  643. inputBufferLength);
  644. break;
  645. case IOCTL_FSVIDEO_SET_CURRENT_MODE:
  646. FsVgaPrint((2, "FsVgaDeviceControl - SetCurrentModes\n"));
  647. status = FsVgaSetMode(deviceExtension,
  648. (PFSVIDEO_MODE_INFORMATION) ioBuffer,
  649. inputBufferLength);
  650. break;
  651. case IOCTL_FSVIDEO_SET_SCREEN_INFORMATION:
  652. FsVgaPrint((2, "FsVgaDeviceControl - SetScreenInformation\n"));
  653. status = FsVgaSetScreenInformation(deviceExtension,
  654. (PFSVIDEO_SCREEN_INFORMATION) ioBuffer,
  655. inputBufferLength);
  656. break;
  657. case IOCTL_FSVIDEO_SET_CURSOR_POSITION:
  658. FsVgaPrint((2, "FsVgaDeviceControl - SetCursorPosition\n"));
  659. status = FsVgaSetCursorPosition(deviceExtension,
  660. (PFSVIDEO_CURSOR_POSITION) ioBuffer,
  661. inputBufferLength);
  662. break;
  663. case IOCTL_VIDEO_SET_CURSOR_ATTR:
  664. FsVgaPrint((2, "FsVgaDeviceControl - SetCursorAttribute\n"));
  665. status = FsVgaSetCursorAttribute(deviceExtension,
  666. (PVIDEO_CURSOR_ATTRIBUTES) ioBuffer,
  667. inputBufferLength);
  668. break;
  669. default:
  670. FsVgaPrint((1,
  671. "FSVGA-FsVgaDeviceControl: INVALID REQUEST (0x%x)\n",
  672. irpSp->Parameters.DeviceIoControl.IoControlCode));
  673. status = STATUS_INVALID_DEVICE_REQUEST;
  674. break;
  675. }
  676. Irp->IoStatus.Status = status;
  677. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  678. FsVgaPrint((2,"FSVGA-FsVgaDeviceControl: exit\n"));
  679. return(status);
  680. }
  681. NTSTATUS
  682. FsVgaCopyFrameBuffer(
  683. PDEVICE_EXTENSION DeviceExtension,
  684. PFSVIDEO_COPY_FRAME_BUFFER CopyFrameBuffer,
  685. ULONG inputBufferLength
  686. )
  687. /*++
  688. Routine Description:
  689. This routine copy the frame buffer.
  690. Arguments:
  691. DeviceExtension - Pointer to the miniport driver's device extension.
  692. CopyFrameBuffer - Pointer to the structure containing the information about the copy frame buffer.
  693. inputBufferLength - Length of the input buffer supplied by the user.
  694. Return Value:
  695. STATUS_INSUFFICIENT_BUFFER if the input buffer was not large enough
  696. for the input data.
  697. STATUS_SUCCESS if the operation completed successfully.
  698. --*/
  699. {
  700. //
  701. // Check if the size of the data in the input buffer is large enough.
  702. //
  703. if (inputBufferLength < sizeof(FSVIDEO_COPY_FRAME_BUFFER)) {
  704. return STATUS_INVALID_BUFFER_SIZE;
  705. }
  706. if (CopyFrameBuffer->SrcScreen.nNumberOfChars != CopyFrameBuffer->DestScreen.nNumberOfChars) {
  707. return STATUS_INVALID_PARAMETER;
  708. }
  709. if (! (DeviceExtension->CurrentMode.VideoMode.AttributeFlags & VIDEO_MODE_GRAPHICS))
  710. {
  711. /*
  712. * This is the TEXT frame buffer.
  713. */
  714. ULONG OffsSrc;
  715. ULONG OffsDest;
  716. PUCHAR pFrameBuf = DeviceExtension->CurrentMode.VideoMemory.FrameBufferBase;
  717. COORD ScreenSize ;
  718. COORD SrcScrnSize ;
  719. COORD SrcScrnPos ;
  720. COORD DstScrnSize ;
  721. COORD DstScrnPos ;
  722. ScreenSize = DeviceExtension->ScreenAndFont.ScreenSize ;
  723. SrcScrnSize = CopyFrameBuffer->SrcScreen.ScreenSize ;
  724. DstScrnSize = CopyFrameBuffer->DestScreen.ScreenSize ;
  725. SrcScrnPos = CopyFrameBuffer->SrcScreen.Position ;
  726. DstScrnPos = CopyFrameBuffer->DestScreen.Position ;
  727. if ((SrcScrnPos.X > ScreenSize.X) ||
  728. (SrcScrnPos.Y > ScreenSize.Y) ||
  729. (SrcScrnSize.X > ScreenSize.X) ||
  730. (DstScrnPos.X > ScreenSize.X) ||
  731. (DstScrnPos.Y > ScreenSize.Y) ||
  732. (DstScrnSize.X > ScreenSize.X) ||
  733. (SrcScrnPos.Y * SrcScrnSize.X + SrcScrnPos.X + CopyFrameBuffer->SrcScreen.nNumberOfChars
  734. > (ULONG)ScreenSize.X * ScreenSize.Y) ||
  735. (DstScrnPos.Y * DstScrnSize.X + DstScrnPos.X + CopyFrameBuffer->DestScreen.nNumberOfChars
  736. > (ULONG)ScreenSize.X * ScreenSize.Y)
  737. )
  738. {
  739. return STATUS_INVALID_BUFFER_SIZE;
  740. }
  741. OffsSrc = SCREEN_BUFFER_POINTER(CopyFrameBuffer->SrcScreen.Position.X,
  742. CopyFrameBuffer->SrcScreen.Position.Y,
  743. CopyFrameBuffer->SrcScreen.ScreenSize.X,
  744. sizeof(VGA_CHAR));
  745. OffsDest = SCREEN_BUFFER_POINTER(CopyFrameBuffer->DestScreen.Position.X,
  746. CopyFrameBuffer->DestScreen.Position.Y,
  747. CopyFrameBuffer->DestScreen.ScreenSize.X,
  748. sizeof(VGA_CHAR));
  749. RtlMoveMemory(pFrameBuf + OffsDest,
  750. pFrameBuf + OffsSrc,
  751. CopyFrameBuffer->SrcScreen.nNumberOfChars * sizeof(VGA_CHAR));
  752. }
  753. else
  754. {
  755. /*
  756. * This is the GRAPHICS frame buffer.
  757. */
  758. return FsgCopyFrameBuffer(DeviceExtension,
  759. CopyFrameBuffer,
  760. inputBufferLength);
  761. }
  762. return STATUS_SUCCESS;
  763. }
  764. NTSTATUS
  765. FsVgaWriteToFrameBuffer(
  766. PDEVICE_EXTENSION DeviceExtension,
  767. PFSVIDEO_WRITE_TO_FRAME_BUFFER WriteFrameBuffer,
  768. ULONG inputBufferLength
  769. )
  770. /*++
  771. Routine Description:
  772. This routine write the frame buffer.
  773. Arguments:
  774. DeviceExtension - Pointer to the miniport driver's device extension.
  775. WriteFrameBuffer - Pointer to the structure containing the information about the write frame buffer.
  776. inputBufferLength - Length of the input buffer supplied by the user.
  777. Return Value:
  778. STATUS_INSUFFICIENT_BUFFER if the input buffer was not large enough
  779. for the input data.
  780. STATUS_SUCCESS if the operation completed successfully.
  781. --*/
  782. {
  783. //
  784. // Check if the size of the data in the input buffer is large enough.
  785. //
  786. if (inputBufferLength < sizeof(FSVIDEO_WRITE_TO_FRAME_BUFFER)) {
  787. FsVgaPrint((1, "FsVgaWriteToFrameBuffer: Fail of STATUS_INVALID_BUFFER_SIZE\n"));
  788. return STATUS_INVALID_BUFFER_SIZE;
  789. }
  790. if (WriteFrameBuffer->DestScreen.Position.X < 0 ||
  791. WriteFrameBuffer->DestScreen.Position.X > DeviceExtension->ScreenAndFont.ScreenSize.X ||
  792. (SHORT)(WriteFrameBuffer->DestScreen.Position.X +
  793. WriteFrameBuffer->DestScreen.nNumberOfChars)
  794. > DeviceExtension->ScreenAndFont.ScreenSize.X ||
  795. WriteFrameBuffer->DestScreen.Position.Y < 0 ||
  796. WriteFrameBuffer->DestScreen.Position.Y > DeviceExtension->ScreenAndFont.ScreenSize.Y) {
  797. FsVgaPrint((1, "FsVgaWriteToFrameBuffer: Fail of STATUS_INVALID_BUFFER_SIZE\n"));
  798. return STATUS_INVALID_BUFFER_SIZE;
  799. }
  800. if (! (DeviceExtension->CurrentMode.VideoMode.AttributeFlags & VIDEO_MODE_GRAPHICS))
  801. {
  802. /*
  803. * This is the TEXT frame buffer.
  804. */
  805. ULONG Offs;
  806. PUCHAR pFrameBuf = DeviceExtension->CurrentMode.VideoMemory.FrameBufferBase;
  807. PCHAR_IMAGE_INFO pCharInfoUni = WriteFrameBuffer->SrcBuffer;
  808. PCHAR_IMAGE_INFO pCharInfoAsc;
  809. ULONG Length = WriteFrameBuffer->DestScreen.nNumberOfChars;
  810. PVOID pCapBuffer = NULL;
  811. ULONG cCapBuffer = 0;
  812. Offs = SCREEN_BUFFER_POINTER(WriteFrameBuffer->DestScreen.Position.X,
  813. WriteFrameBuffer->DestScreen.Position.Y,
  814. WriteFrameBuffer->DestScreen.ScreenSize.X,
  815. sizeof(VGA_CHAR));
  816. cCapBuffer = Length * sizeof(CHAR_IMAGE_INFO);
  817. pCapBuffer = ExAllocatePool(PagedPool, cCapBuffer);
  818. if (!pCapBuffer) {
  819. ULONG dumpData[DUMP_COUNT];
  820. FsVgaPrint((1,
  821. "FSVGA-FsVgaWriteToFrameBuffer: Could not allocate resource list\n"));
  822. //
  823. // Log an error.
  824. //
  825. dumpData[0] = cCapBuffer;
  826. FsVgaLogError(DeviceExtension->DeviceObject,
  827. FSVGA_INSUFFICIENT_RESOURCES,
  828. FSVGA_ERROR_VALUE_BASE + 200,
  829. STATUS_INSUFFICIENT_RESOURCES,
  830. dumpData,
  831. 1
  832. );
  833. return STATUS_UNSUCCESSFUL;
  834. }
  835. TranslateOutputToOem(pCapBuffer, pCharInfoUni, Length);
  836. pCharInfoAsc = pCapBuffer;
  837. pFrameBuf += Offs;
  838. while (Length--)
  839. {
  840. *pFrameBuf++ = pCharInfoAsc->CharInfo.Char.AsciiChar;
  841. *pFrameBuf++ = (UCHAR) (pCharInfoAsc->CharInfo.Attributes);
  842. pCharInfoAsc++;
  843. }
  844. ExFreePool(pCapBuffer);
  845. }
  846. else
  847. {
  848. /*
  849. * This is the GRAPHICS frame buffer.
  850. */
  851. return FsgWriteToFrameBuffer(DeviceExtension,
  852. WriteFrameBuffer,
  853. inputBufferLength);
  854. }
  855. return STATUS_SUCCESS;
  856. }
  857. NTSTATUS
  858. FsVgaReverseMousePointer(
  859. PDEVICE_EXTENSION DeviceExtension,
  860. PFSVIDEO_REVERSE_MOUSE_POINTER MouseBuffer,
  861. ULONG inputBufferLength
  862. )
  863. /*++
  864. Routine Description:
  865. This routine reverse the frame buffer for mouse pointer.
  866. Arguments:
  867. DeviceExtension - Pointer to the miniport driver's device extension.
  868. MouseBuffer - Pointer to the structure containing the information about the mouse frame buffer.
  869. inputBufferLength - Length of the input buffer supplied by the user.
  870. Return Value:
  871. STATUS_INSUFFICIENT_BUFFER if the input buffer was not large enough
  872. for the input data.
  873. STATUS_SUCCESS if the operation completed successfully.
  874. --*/
  875. {
  876. //
  877. // Check if the size of the data in the input buffer is large enough.
  878. //
  879. if (inputBufferLength < sizeof(FSVIDEO_REVERSE_MOUSE_POINTER)) {
  880. return STATUS_INVALID_BUFFER_SIZE;
  881. }
  882. if (! (DeviceExtension->CurrentMode.VideoMode.AttributeFlags & VIDEO_MODE_GRAPHICS))
  883. {
  884. /*
  885. * This is the TEXT frame buffer.
  886. */
  887. ULONG Offs;
  888. PUCHAR pFrameBuf = DeviceExtension->CurrentMode.VideoMemory.FrameBufferBase;
  889. UCHAR Attribute;
  890. Offs = SCREEN_BUFFER_POINTER(MouseBuffer->Screen.Position.X,
  891. MouseBuffer->Screen.Position.Y,
  892. MouseBuffer->Screen.ScreenSize.X,
  893. sizeof(VGA_CHAR));
  894. pFrameBuf += Offs;
  895. Attribute = (*(pFrameBuf + 1) & 0xF0) >> 4;
  896. Attribute |= (*(pFrameBuf + 1) & 0x0F) << 4;
  897. *(pFrameBuf + 1) = Attribute;
  898. }
  899. else
  900. {
  901. /*
  902. * This is the GRAPHICS frame buffer.
  903. */
  904. return FsgReverseMousePointer(DeviceExtension,
  905. MouseBuffer,
  906. inputBufferLength);
  907. }
  908. return STATUS_SUCCESS;
  909. }
  910. NTSTATUS
  911. FsVgaSetMode(
  912. PDEVICE_EXTENSION DeviceExtension,
  913. PFSVIDEO_MODE_INFORMATION ModeInformation,
  914. ULONG inputBufferLength
  915. )
  916. /*++
  917. Routine Description:
  918. This routine sets the current video information.
  919. Arguments:
  920. DeviceExtension - Pointer to the miniport driver's device extension.
  921. ModeInformation - Pointer to the structure containing the information about the
  922. full screen video.
  923. inputBufferLength - Length of the input buffer supplied by the user.
  924. Return Value:
  925. STATUS_INSUFFICIENT_BUFFER if the input buffer was not large enough
  926. for the input data.
  927. STATUS_SUCCESS if the operation completed successfully.
  928. --*/
  929. {
  930. //
  931. // Check if the size of the data in the input buffer is large enough.
  932. //
  933. if (inputBufferLength < sizeof(FSVIDEO_MODE_INFORMATION)) {
  934. return STATUS_INVALID_BUFFER_SIZE;
  935. }
  936. DeviceExtension->CurrentMode = *ModeInformation;
  937. FsVgaPrint((3, "FsVgaSetMode: Video Mode:\n"));
  938. FsVgaPrint((3, " ModeIndex = %x\n", DeviceExtension->CurrentMode.VideoMode.ModeIndex));
  939. FsVgaPrint((3, " VisScreenWidth = %d\n", DeviceExtension->CurrentMode.VideoMode.VisScreenWidth));
  940. FsVgaPrint((3, " VisScreenHeight = %d\n", DeviceExtension->CurrentMode.VideoMode.VisScreenHeight));
  941. FsVgaPrint((3, " NumberOfPlanes = %d\n", DeviceExtension->CurrentMode.VideoMode.NumberOfPlanes));
  942. FsVgaPrint((3, " BitsPerPlane = %d\n", DeviceExtension->CurrentMode.VideoMode.BitsPerPlane));
  943. FsVgaPrint((3, "FsVgaSetMode: Video Memory:\n"));
  944. FsVgaPrint((3, " VideoRamBase = %x\n", DeviceExtension->CurrentMode.VideoMemory.VideoRamBase));
  945. FsVgaPrint((3, " VideoRamLength = %x\n", DeviceExtension->CurrentMode.VideoMemory.VideoRamLength));
  946. FsVgaPrint((3, " FrameBufferBase = %x\n", DeviceExtension->CurrentMode.VideoMemory.FrameBufferBase));
  947. FsVgaPrint((3, " FrameBufferLength = %x\n", DeviceExtension->CurrentMode.VideoMemory.FrameBufferLength));
  948. return STATUS_SUCCESS;
  949. }
  950. NTSTATUS
  951. FsVgaSetScreenInformation(
  952. PDEVICE_EXTENSION DeviceExtension,
  953. PFSVIDEO_SCREEN_INFORMATION ScreenInformation,
  954. ULONG inputBufferLength
  955. )
  956. /*++
  957. Routine Description:
  958. This routine sets the screen and font information.
  959. Arguments:
  960. DeviceExtension - Pointer to the miniport driver's device extension.
  961. ScreenInformation - Pointer to the structure containing the information about the
  962. screen anf font.
  963. inputBufferLength - Length of the input buffer supplied by the user.
  964. Return Value:
  965. STATUS_INSUFFICIENT_BUFFER if the input buffer was not large enough
  966. for the input data.
  967. STATUS_SUCCESS if the operation completed successfully.
  968. --*/
  969. {
  970. //
  971. // Check if the size of the data in the input buffer is large enough.
  972. //
  973. if (inputBufferLength < sizeof(FSVIDEO_SCREEN_INFORMATION)) {
  974. return STATUS_INVALID_BUFFER_SIZE;
  975. }
  976. DeviceExtension->ScreenAndFont = *ScreenInformation;
  977. FsVgaPrint((3, "FsVgaSetScreenInformation:\n"));
  978. FsVgaPrint((3, " ScreenSize.X = %d, Y = %d\n",
  979. DeviceExtension->ScreenAndFont.ScreenSize.X,
  980. DeviceExtension->ScreenAndFont.ScreenSize.Y));
  981. FsVgaPrint((3, " FontSize.X = %d, Y = %d\n",
  982. DeviceExtension->ScreenAndFont.FontSize.X,
  983. DeviceExtension->ScreenAndFont.FontSize.Y));
  984. FsgVgaInitializeHWFlags(DeviceExtension);
  985. return STATUS_SUCCESS;
  986. }
  987. NTSTATUS
  988. FsVgaSetCursorPosition(
  989. PDEVICE_EXTENSION DeviceExtension,
  990. PFSVIDEO_CURSOR_POSITION CursorPosition,
  991. ULONG inputBufferLength
  992. )
  993. /*++
  994. Routine Description:
  995. This routine sets the cursor position.
  996. Arguments:
  997. DeviceExtension - Pointer to the miniport driver's device extension.
  998. CursorPosition - Pointer to the structure containing the information about the
  999. cursor position.
  1000. inputBufferLength - Length of the input buffer supplied by the user.
  1001. Return Value:
  1002. STATUS_INSUFFICIENT_BUFFER if the input buffer was not large enough
  1003. for the input data.
  1004. STATUS_SUCCESS if the operation completed successfully.
  1005. --*/
  1006. {
  1007. //
  1008. // Check if the size of the data in the input buffer is large enough.
  1009. //
  1010. if (inputBufferLength < sizeof(VIDEO_CURSOR_POSITION)) {
  1011. return STATUS_INVALID_BUFFER_SIZE;
  1012. }
  1013. if (DeviceExtension->CurrentMode.VideoMode.AttributeFlags & VIDEO_MODE_GRAPHICS)
  1014. {
  1015. FsgInvertCursor(DeviceExtension,FALSE);
  1016. }
  1017. DeviceExtension->EmulateInfo.CursorPosition = *CursorPosition;
  1018. if (DeviceExtension->CurrentMode.VideoMode.AttributeFlags & VIDEO_MODE_GRAPHICS)
  1019. {
  1020. FsgInvertCursor(DeviceExtension,TRUE);
  1021. return STATUS_SUCCESS;
  1022. }
  1023. else
  1024. {
  1025. /*
  1026. * If current video mode is a TEXT MODE.
  1027. * FSVGA.SYS didn't handling hardware cursor
  1028. * because I don't know device of VGA.SYS or others.
  1029. *
  1030. * In this case, by returns STATUS_UNSUCCESSFUL, caller
  1031. * do DeviceIoControl to VGA miniport driver.
  1032. */
  1033. return STATUS_UNSUCCESSFUL;
  1034. }
  1035. }
  1036. NTSTATUS
  1037. FsVgaSetCursorAttribute(
  1038. PDEVICE_EXTENSION DeviceExtension,
  1039. PVIDEO_CURSOR_ATTRIBUTES CursorAttributes,
  1040. ULONG inputBufferLength
  1041. )
  1042. /*++
  1043. Routine Description:
  1044. This routine sets the cursor attributes.
  1045. Arguments:
  1046. DeviceExtension - Pointer to the miniport driver's device extension.
  1047. CursorAttributes - Pointer to the structure containing the information about the
  1048. cursor attributes.
  1049. inputBufferLength - Length of the input buffer supplied by the user.
  1050. Return Value:
  1051. STATUS_INSUFFICIENT_BUFFER if the input buffer was not large enough
  1052. for the input data.
  1053. STATUS_SUCCESS if the operation completed successfully.
  1054. --*/
  1055. {
  1056. //
  1057. // Check if the size of the data in the input buffer is large enough.
  1058. //
  1059. if (inputBufferLength < sizeof(VIDEO_CURSOR_ATTRIBUTES)) {
  1060. return STATUS_INVALID_BUFFER_SIZE;
  1061. }
  1062. if (DeviceExtension->CurrentMode.VideoMode.AttributeFlags & VIDEO_MODE_GRAPHICS)
  1063. {
  1064. FsgInvertCursor(DeviceExtension,FALSE);
  1065. }
  1066. DeviceExtension->EmulateInfo.CursorAttributes = *CursorAttributes;
  1067. if (DeviceExtension->CurrentMode.VideoMode.AttributeFlags & VIDEO_MODE_GRAPHICS)
  1068. {
  1069. FsgInvertCursor(DeviceExtension,TRUE);
  1070. return STATUS_SUCCESS;
  1071. }
  1072. else
  1073. {
  1074. /*
  1075. * If current video mode is a TEXT MODE.
  1076. * FSVGA.SYS didn't handling hardware cursor
  1077. * because I don't know device of VGA.SYS or others.
  1078. *
  1079. * In this case, by returns STATUS_UNSUCCESSFUL, caller
  1080. * do DeviceIoControl to VGA miniport driver.
  1081. */
  1082. return STATUS_UNSUCCESSFUL;
  1083. }
  1084. }
  1085. VOID
  1086. FsVgaLogError(
  1087. IN PVOID Object,
  1088. IN NTSTATUS ErrorCode,
  1089. IN ULONG UniqueErrorValue,
  1090. IN NTSTATUS FinalStatus,
  1091. IN PULONG DumpData,
  1092. IN ULONG DumpCount
  1093. )
  1094. /*++
  1095. Routine Description:
  1096. This routine contains common code to write an error log entry. It is
  1097. called from other routines, especially FsVgaInitialize, to avoid
  1098. duplication of code. Note that some routines continue to have their
  1099. own error logging code (especially in the case where the error logging
  1100. can be localized and/or the routine has more data because there is
  1101. and IRP).
  1102. Arguments:
  1103. Object - Pointer to the device or driver object.
  1104. ErrorCode - The error code for the error log packet.
  1105. UniqueErrorValue - The unique error value for the error log packet.
  1106. FinalStatus - The final status of the operation for the error log packet.
  1107. DumpData - Pointer to an array of dump data for the error log packet.
  1108. DumpCount - The number of entries in the dump data array.
  1109. Return Value:
  1110. None.
  1111. --*/
  1112. {
  1113. PIO_ERROR_LOG_PACKET errorLogEntry;
  1114. ULONG i;
  1115. errorLogEntry = (PIO_ERROR_LOG_PACKET) IoAllocateErrorLogEntry(
  1116. (PVOID) Object,
  1117. (UCHAR) (sizeof(IO_ERROR_LOG_PACKET)
  1118. + (DumpCount * sizeof(ULONG)))
  1119. );
  1120. if (errorLogEntry != NULL) {
  1121. errorLogEntry->ErrorCode = ErrorCode;
  1122. errorLogEntry->DumpDataSize = (USHORT) (DumpCount * sizeof(ULONG));
  1123. errorLogEntry->SequenceNumber = 0;
  1124. errorLogEntry->MajorFunctionCode = 0;
  1125. errorLogEntry->IoControlCode = 0;
  1126. errorLogEntry->RetryCount = 0;
  1127. errorLogEntry->UniqueErrorValue = UniqueErrorValue;
  1128. errorLogEntry->FinalStatus = FinalStatus;
  1129. for (i = 0; i < DumpCount; i++)
  1130. errorLogEntry->DumpData[i] = DumpData[i];
  1131. IoWriteErrorLogEntry(errorLogEntry);
  1132. }
  1133. }
  1134. #if DBG
  1135. VOID
  1136. FsVgaDebugPrint(
  1137. ULONG DebugPrintLevel,
  1138. PCCHAR DebugMessage,
  1139. ...
  1140. )
  1141. /*++
  1142. Routine Description:
  1143. Debug print routine.
  1144. Arguments:
  1145. Debug print level between 0 and 3, with 3 being the most verbose.
  1146. Return Value:
  1147. None.
  1148. --*/
  1149. {
  1150. va_list ap;
  1151. va_start(ap, DebugMessage);
  1152. if (DebugPrintLevel <= Globals.FsVgaDebug) {
  1153. char buffer[128];
  1154. (VOID) vsprintf(buffer, DebugMessage, ap);
  1155. DbgPrint(buffer);
  1156. }
  1157. va_end(ap);
  1158. }
  1159. #endif