Leaked source code of windows server 2003
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.

506 lines
24 KiB

  1. /****************************************************************************/
  2. /* nmpapi.c */
  3. /* */
  4. /* RDP Miniport API Functions */
  5. /* */
  6. /* Copyright(c) Microsoft 1998 */
  7. /****************************************************************************/
  8. #define _NTDRIVER_
  9. #ifndef FAR
  10. #define FAR
  11. #endif
  12. #include "dderror.h"
  13. #include "ntosp.h"
  14. #include "stdarg.h"
  15. #include "stdio.h"
  16. #include "zwapi.h"
  17. #undef PAGED_CODE
  18. #include "ntddvdeo.h"
  19. #include "video.h"
  20. #include "nmpapi.h"
  21. // #define TRC_FILE "nmpapi"
  22. // #include <adcgbtyp.h>
  23. // #include <adcgmcro.h>
  24. // #include <atrcapi.h>
  25. /****************************************************************************/
  26. /* Function Prototypes */
  27. /****************************************************************************/
  28. ULONG DriverEntry( PVOID Context1, PVOID Context2 );
  29. VP_STATUS MPFindAdapter( PVOID HwDeviceExtension,
  30. PVOID HwContext,
  31. PWSTR ArgumentString,
  32. PVIDEO_PORT_CONFIG_INFO ConfigInfo,
  33. PUCHAR Again );
  34. BOOLEAN MPInitialize( PVOID HwDeviceExtension );
  35. BOOLEAN MPStartIO( PVOID HwDeviceExtension,
  36. PVIDEO_REQUEST_PACKET RequestPacket );
  37. #if defined(ALLOC_PRAGMA)
  38. #pragma alloc_text(PAGE,DriverEntry)
  39. #pragma alloc_text(PAGE,MPFindAdapter)
  40. #pragma alloc_text(PAGE,MPInitialize)
  41. #pragma alloc_text(PAGE,MPStartIO)
  42. #endif
  43. /****************************************************************************/
  44. /* */
  45. /* DriverEntry */
  46. /* */
  47. /* Routine Description: */
  48. /* */
  49. /* Installable driver initialization entry point. */
  50. /* This entry point is called directly by the I/O system. */
  51. /* */
  52. /* Arguments: */
  53. /* */
  54. /* Context1 - First context value passed by the operating system. */
  55. /* This is the value with which the miniport driver */
  56. /* calls VideoPortInitialize(). */
  57. /* */
  58. /* Context2 - Second context value passed by the operating system. */
  59. /* This is the value with which the miniport driver */
  60. /* calls VideoPortInitialize(). */
  61. /* */
  62. /* Return Value: */
  63. /* */
  64. /* Status from VideoPortInitialize() */
  65. /* */
  66. /****************************************************************************/
  67. ULONG DriverEntry ( PVOID Context1, PVOID Context2 )
  68. {
  69. VIDEO_HW_INITIALIZATION_DATA hwInitData;
  70. ULONG status;
  71. ULONG initializationStatus;
  72. ULONG regValue = 0;
  73. /************************************************************************/
  74. /* first up, ensure that the DD will NOT get attached to the desktop at */
  75. /* boot time. This might happen if the registry changes were made and */
  76. /* then the machine got powered off rather than shut down cleanly */
  77. /* */
  78. /* @@@ Is it OK to just hard code this path? I notice that this _is_ */
  79. /* done elsewhere! */
  80. /************************************************************************/
  81. RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE,
  82. L"\\Registry\\Machine\\System\\CurrentControlSet"
  83. L"\\Hardware Profiles\\Current\\System"
  84. L"\\CurrentControlSet\\Services\\RDPCDD\\DEVICE0",
  85. L"Attach.ToDesktop",
  86. REG_DWORD,
  87. &regValue,
  88. sizeof(ULONG));
  89. RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE,
  90. L"\\Registry\\Machine\\System\\CurrentControlSet"
  91. L"\\Hardware Profiles\\Current\\System"
  92. L"\\CurrentControlSet\\Control\\Video"
  93. L"\\{DEB039CC-B704-4F53-B43E-9DD4432FA2E9}\\0000",
  94. L"Attach.ToDesktop",
  95. REG_DWORD,
  96. &regValue,
  97. sizeof(ULONG));
  98. /************************************************************************/
  99. /* Zero out structure. */
  100. /************************************************************************/
  101. VideoPortZeroMemory(&hwInitData, sizeof(VIDEO_HW_INITIALIZATION_DATA));
  102. /************************************************************************/
  103. /* Specify sizes of structure and extension. */
  104. /************************************************************************/
  105. hwInitData.HwInitDataSize = sizeof(VIDEO_HW_INITIALIZATION_DATA);
  106. /************************************************************************/
  107. /* Set entry points. */
  108. /************************************************************************/
  109. hwInitData.HwFindAdapter = MPFindAdapter;
  110. hwInitData.HwInitialize = MPInitialize;
  111. hwInitData.HwInterrupt = NULL;
  112. hwInitData.HwStartIO = MPStartIO;
  113. /************************************************************************/
  114. /* Determine the size we require for the device extension. */
  115. /************************************************************************/
  116. hwInitData.HwDeviceExtensionSize = sizeof(HW_DEVICE_EXTENSION);
  117. /************************************************************************/
  118. /* Once all the relevant information has been stored, call the video */
  119. /* port driver to do the initialization. */
  120. /* */
  121. /* Since we don't actually have any hardware, just claim its on the PCI */
  122. /* bus */
  123. /************************************************************************/
  124. hwInitData.AdapterInterfaceType = PCIBus;
  125. return (VideoPortInitialize(Context1,
  126. Context2,
  127. &hwInitData,
  128. NULL));
  129. } /* DriverEntry() */
  130. /****************************************************************************/
  131. /* */
  132. /* MPFindAdapter */
  133. /* */
  134. /* Routine Description: */
  135. /* */
  136. /* This routine is called to determine if the adapter for this driver */
  137. /* is present in the system. */
  138. /* If it is present, the function fills out some information describing */
  139. /* the adapter. */
  140. /* */
  141. /* Arguments: */
  142. /* */
  143. /* HwDeviceExtension - Supplies the miniport driver's adapter storage. */
  144. /* This storage is initialized to zero before this call. */
  145. /* */
  146. /* HwContext - Supplies the context value which was passed to */
  147. /* VideoPortInitialize(). */
  148. /* */
  149. /* ArgumentString - Suuplies a NULL terminated ASCII string. This string */
  150. /* originates from the user. */
  151. /* */
  152. /* ConfigInfo - Returns the configuration information structure which is */
  153. /* filled by the miniport driver. This structure is initialized with */
  154. /* any knwon configuration information (such as SystemIoBusNumber) by */
  155. /* the port driver. Where possible, drivers should have one set of */
  156. /* defaults which do not require any supplied configuration */
  157. /* information. */
  158. /* */
  159. /* Again - Indicates if the miniport driver wants the port driver to call */
  160. /* its VIDEO_HW_FIND_ADAPTER function again with a new device */
  161. /* extension and the same config info. This is used by the miniport */
  162. /* drivers which can search for several adapters on a bus. */
  163. /* */
  164. /* Return Value: */
  165. /* */
  166. /* This routine must return: */
  167. /* */
  168. /* NO_ERROR - Indicates a host adapter was found and the */
  169. /* configuration information was successfully determined. */
  170. /* */
  171. /* ERROR_INVALID_PARAMETER - Indicates an adapter was found but there */
  172. /* was an error obtaining the configuration information. If */
  173. /* possible an error should be logged. */
  174. /* */
  175. /* ERROR_DEV_NOT_EXIST - Indicates no host adapter was found for the */
  176. /* supplied configuration information. */
  177. /* */
  178. /****************************************************************************/
  179. VP_STATUS MPFindAdapter( PVOID HwDeviceExtension,
  180. PVOID HwContext,
  181. PWSTR ArgumentString,
  182. PVIDEO_PORT_CONFIG_INFO ConfigInfo,
  183. PUCHAR Again)
  184. {
  185. PHW_DEVICE_EXTENSION hwDeviceExtension = HwDeviceExtension;
  186. NTSTATUS Status;
  187. HANDLE SectionHandle;
  188. ACCESS_MASK SectionAccess;
  189. ULONGLONG SectionSize = 0x100000;
  190. /************************************************************************/
  191. /* Make sure the size of the structure is at least as large as what we */
  192. /* are expecting (check version of the config info structure). */
  193. /************************************************************************/
  194. if (ConfigInfo->Length < sizeof(VIDEO_PORT_CONFIG_INFO))
  195. {
  196. return ERROR_INVALID_PARAMETER;
  197. }
  198. /************************************************************************/
  199. /* Only create a device once. */
  200. /************************************************************************/
  201. if (mpLoaded++)
  202. {
  203. return ERROR_DEV_NOT_EXIST;
  204. }
  205. /************************************************************************/
  206. /* Clear out the Emulator entries and the state size since this driver */
  207. /* does not support them. */
  208. /************************************************************************/
  209. ConfigInfo->NumEmulatorAccessEntries = 0;
  210. ConfigInfo->EmulatorAccessEntries = NULL;
  211. ConfigInfo->EmulatorAccessEntriesContext = 0;
  212. ConfigInfo->HardwareStateSize = 0;
  213. ConfigInfo->VdmPhysicalVideoMemoryAddress.LowPart = 0x00000000;
  214. ConfigInfo->VdmPhysicalVideoMemoryAddress.HighPart = 0x00000000;
  215. ConfigInfo->VdmPhysicalVideoMemoryLength = 0x00000000;
  216. /************************************************************************/
  217. /* Initialize the current mode number. */
  218. /************************************************************************/
  219. hwDeviceExtension->CurrentModeNumber = 0;
  220. /************************************************************************/
  221. /* Indicate we do not wish to be called over */
  222. /************************************************************************/
  223. *Again = 0;
  224. /************************************************************************/
  225. /* Indicate a successful completion status. */
  226. /************************************************************************/
  227. return NO_ERROR;
  228. } /* MPFindAdapter() */
  229. /****************************************************************************/
  230. /* MPInitialize */
  231. /* */
  232. /* Routine Description: */
  233. /* */
  234. /* This routine does one time initialization of the device. */
  235. /* */
  236. /* Arguments: */
  237. /* */
  238. /* HwDeviceExtension - Supplies a pointer to the miniport's device */
  239. /* extension. */
  240. /* */
  241. /* Return Value: */
  242. /* */
  243. /* Always returns TRUE since this routine can never fail. */
  244. /* */
  245. /****************************************************************************/
  246. BOOLEAN MPInitialize( PVOID HwDeviceExtension )
  247. {
  248. ULONG i;
  249. /************************************************************************/
  250. /* Walk through the list of modes and mark the indexes properly */
  251. /************************************************************************/
  252. for (i = 0; i < mpNumModes; i++)
  253. {
  254. mpModes[i].ModeIndex = i;
  255. }
  256. return TRUE;
  257. } /* MPInitialize() */
  258. /****************************************************************************/
  259. /* */
  260. /* MPStartIO */
  261. /* */
  262. /* Routine Description: */
  263. /* */
  264. /* This routine is the main execution routine for the miniport driver. */
  265. /* It accepts a Video Request Packet, performs the request, and then */
  266. /* returns with the appropriate status. */
  267. /* */
  268. /* Arguments: */
  269. /* */
  270. /* HwDeviceExtension - Supplies a pointer to the miniport's device */
  271. /* extension. */
  272. /* */
  273. /* RequestPacket - Pointer to the video request packet. This */
  274. /* structure contains all the parameters passed to the */
  275. /* VideoIoControl function. */
  276. /* */
  277. /* Return Value: */
  278. /* */
  279. /* */
  280. /****************************************************************************/
  281. BOOLEAN MPStartIO( PVOID HwDeviceExtension,
  282. PVIDEO_REQUEST_PACKET RequestPacket )
  283. {
  284. PHW_DEVICE_EXTENSION hwDeviceExtension = HwDeviceExtension;
  285. VP_STATUS status = NO_ERROR;
  286. PVIDEO_MODE_INFORMATION modeInformation;
  287. PVIDEO_MEMORY_INFORMATION memoryInformation;
  288. PVIDEO_SHARE_MEMORY pShareMemory;
  289. PVIDEO_SHARE_MEMORY_INFORMATION pShareMemoryInformation;
  290. ULONG ulTemp;
  291. NTSTATUS ntStatus;
  292. ULONG ViewSize;
  293. PVOID ViewBase;
  294. LARGE_INTEGER ViewOffset;
  295. HANDLE sectionHandle;
  296. // DC_BEGIN_FN("MPStartIO");
  297. if ((RequestPacket == NULL) || (HwDeviceExtension == NULL))
  298. return FALSE;
  299. /************************************************************************/
  300. /* Switch on the IoContolCode in the RequestPacket. It indicates which */
  301. /* function must be performed by the driver. */
  302. /************************************************************************/
  303. switch (RequestPacket->IoControlCode)
  304. {
  305. case IOCTL_VIDEO_QUERY_CURRENT_MODE:
  306. {
  307. /****************************************************************/
  308. /* return the current mode */
  309. /****************************************************************/
  310. // TRC_DBG((TB, "MPStartIO - QueryCurrentModes"));
  311. modeInformation = RequestPacket->OutputBuffer;
  312. RequestPacket->StatusBlock->Information =
  313. sizeof(VIDEO_MODE_INFORMATION);
  314. if (RequestPacket->OutputBufferLength
  315. < RequestPacket->StatusBlock->Information)
  316. {
  317. status = ERROR_INSUFFICIENT_BUFFER;
  318. }
  319. else
  320. {
  321. *((PVIDEO_MODE_INFORMATION)RequestPacket->OutputBuffer) =
  322. mpModes[hwDeviceExtension->CurrentModeNumber];
  323. status = NO_ERROR;
  324. }
  325. }
  326. break;
  327. case IOCTL_VIDEO_QUERY_AVAIL_MODES:
  328. {
  329. /****************************************************************/
  330. /* return the mode information */
  331. /****************************************************************/
  332. UCHAR i;
  333. // TRC_DBG((TB, "MPStartIO - QueryAvailableModes"));
  334. /****************************************************************/
  335. /* check for space */
  336. /****************************************************************/
  337. RequestPacket->StatusBlock->Information =
  338. mpNumModes * sizeof(VIDEO_MODE_INFORMATION);
  339. if (RequestPacket->OutputBufferLength
  340. < RequestPacket->StatusBlock->Information)
  341. {
  342. status = ERROR_INSUFFICIENT_BUFFER;
  343. }
  344. else
  345. {
  346. modeInformation = RequestPacket->OutputBuffer;
  347. for (i = 0; i < mpNumModes; i++)
  348. {
  349. *modeInformation = mpModes[i];
  350. modeInformation++;
  351. }
  352. status = NO_ERROR;
  353. }
  354. }
  355. break;
  356. case IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES:
  357. {
  358. /****************************************************************/
  359. /* return the number of modes we support - which we claim to be */
  360. /* zero */
  361. /****************************************************************/
  362. // TRC_DBG((TB, "MPStartIO - QueryNumAvailableModes"));
  363. if (RequestPacket->OutputBufferLength <
  364. (RequestPacket->StatusBlock->Information =
  365. sizeof(VIDEO_NUM_MODES)) )
  366. {
  367. status = ERROR_INSUFFICIENT_BUFFER;
  368. }
  369. else
  370. {
  371. ((PVIDEO_NUM_MODES)RequestPacket->OutputBuffer)->NumModes = 0;
  372. ((PVIDEO_NUM_MODES)RequestPacket->OutputBuffer)
  373. ->ModeInformationLength = 0;
  374. status = NO_ERROR;
  375. }
  376. }
  377. break;
  378. case IOCTL_VIDEO_SET_CURRENT_MODE:
  379. {
  380. /****************************************************************/
  381. /* sets the current mode */
  382. /****************************************************************/
  383. // TRC_DBG((TB, "MPStartIO - SetCurrentMode"));
  384. if (RequestPacket->InputBufferLength < sizeof(VIDEO_MODE))
  385. {
  386. status = ERROR_INSUFFICIENT_BUFFER;
  387. }
  388. hwDeviceExtension->CurrentModeNumber = ((PVIDEO_MODE)
  389. (RequestPacket->InputBuffer))->RequestedMode;
  390. status = NO_ERROR;
  391. }
  392. break;
  393. case IOCTL_VIDEO_SET_COLOR_REGISTERS:
  394. {
  395. // TRC_DBG((TB, "MPStartIO - SetColorRegs"));
  396. status = NO_ERROR;
  397. }
  398. break;
  399. case IOCTL_VIDEO_RESET_DEVICE:
  400. {
  401. // TRC_DBG((TB, "MPStartIO - RESET_DEVICE"));
  402. status = NO_ERROR;
  403. }
  404. break;
  405. case IOCTL_VIDEO_MAP_VIDEO_MEMORY:
  406. case IOCTL_VIDEO_UNMAP_VIDEO_MEMORY:
  407. case IOCTL_VIDEO_SHARE_VIDEO_MEMORY:
  408. case IOCTL_VIDEO_UNSHARE_VIDEO_MEMORY:
  409. {
  410. /****************************************************************/
  411. /* might get these, but shouldn't */
  412. /****************************************************************/
  413. // TRC_ALT((TB, "Unexpected IOCtl %x",RequestPacket->IoControlCode));
  414. status = ERROR_INVALID_FUNCTION;
  415. }
  416. break;
  417. default:
  418. {
  419. /****************************************************************/
  420. /* definitely shouldn't get here */
  421. /****************************************************************/
  422. // TRC_DBG((TB, "Fell through MP startIO routine - invalid command"));
  423. status = ERROR_INVALID_FUNCTION;
  424. }
  425. break;
  426. }
  427. RequestPacket->StatusBlock->Status = status;
  428. // DC_END_FN();
  429. return TRUE;
  430. } /* MPStartIO() */