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.

566 lines
14 KiB

  1. /*--------------------------------------------------------------
  2. *
  3. * FILE: SK_EX.C
  4. *
  5. * PURPOSE: This File contains the interface routines
  6. * that connect Serial Keys to the Mouse or keyboard.
  7. *
  8. * CREATION: June 1994
  9. *
  10. * COPYRIGHT: Black Diamond Software (C) 1994
  11. *
  12. * AUTHOR: Ronald Moak
  13. *
  14. * NOTES:
  15. *
  16. * This file, and all others associated with it contains trade secrets
  17. * and information that is proprietary to Black Diamond Software.
  18. * It may not be copied copied or distributed to any person or firm
  19. * without the express written permission of Black Diamond Software.
  20. * This permission is available only in the form of a Software Source
  21. * License Agreement.
  22. *
  23. * $Header: %Z% %F% %H% %T% %I%
  24. *
  25. *--- Includes ---------------------------------------------------------*/
  26. #include <windows.h>
  27. #include <winable.h>
  28. #include "w95trace.h"
  29. #include "vars.h"
  30. #include "sk_defs.h"
  31. #include "sk_comm.h"
  32. #include "sk_ex.H"
  33. #ifdef QUEUE_BUF
  34. typedef struct _KEYQUE
  35. {
  36. BYTE VirKey;
  37. BYTE ScanCode;
  38. int Flags;
  39. } KEYQUE;
  40. #define MAXKEYS 100
  41. KEYQUE KeyQue[MAXKEYS];
  42. int KeyFront = 0; // Pointer to front of Que
  43. int KeyBack = 0; // Pointer to Back of Que
  44. #endif
  45. #define CTRL 56
  46. #define ALT 29
  47. #define DEL 83
  48. char Key[3];
  49. int Push = 0;
  50. POINT MouseAnchor;
  51. HWND MouseWnd;
  52. static HDESK s_hdeskSave = NULL;
  53. static HDESK s_hdeskUser = NULL;
  54. // Local Function Prototypes -------------------------------------
  55. static void SendAltCtrlDel();
  56. static void CheckAltCtrlDel(int scanCode);
  57. static void AddKey(BYTE VirKey, BYTE ScanCode, int Flags);
  58. /*
  59. AdjustPixels takes the point and adjusts it such that the
  60. mouse cursor moves in pixels. The system applies acceleration
  61. to the MOUSEINPUT {dx, dy} values then scales that based on mouse
  62. speed so this code converts the pixels into MOUSEINPUT {dx, dy}
  63. values.
  64. */
  65. int g_aiMouseParms[3] = {-1, -1, -1};
  66. float g_fSpeedScaleFactor = 0.0;
  67. #define MOU_THRESHOLD_1 g_aiMouseParms[0]
  68. #define MOU_THRESHOLD_2 g_aiMouseParms[1]
  69. #define MOU_ACCELERATION g_aiMouseParms[2]
  70. #define MOU_SPEED_SCALE g_fSpeedScaleFactor
  71. #ifndef SPI_GETMOUSESPEED
  72. #define SPI_GETMOUSESPEED 112
  73. #endif
  74. void AdjustPixels(int *pX, int *pY)
  75. {
  76. int iX = abs(*pX);
  77. int iY = abs(*pY);
  78. int iSignX = ((*pX) >= 0)?1:-1;
  79. int iSignY = ((*pY) >= 0)?1:-1;
  80. if (!iX && !iY)
  81. return; // optimization for {0,0} case
  82. if (MOU_THRESHOLD_1 == -1)
  83. {
  84. // This code assumes the user won't changes these settings
  85. // from mouse CPL w/o restarting the service.
  86. int iSpeed;
  87. SystemParametersInfo(SPI_GETMOUSE, 0, g_aiMouseParms, 0);
  88. SystemParametersInfo(SPI_GETMOUSESPEED, 0, &iSpeed, 0);
  89. g_fSpeedScaleFactor = (float)iSpeed/(float)10.0;
  90. }
  91. /*
  92. The system applies two tests to the specified relative mouse motion
  93. when applying acceleration. If the specified distance along either
  94. the x or y axis is greater than the first mouse threshold value, and
  95. the mouse acceleration level is not zero, the operating system doubles
  96. the distance. If the specified distance along either the x- or y-axis
  97. is greater than the second mouse threshold value, and the mouse
  98. acceleration level is equal to two, the operating system doubles the
  99. distance that resulted from applying the first threshold test. It is
  100. thus possible for the operating system to multiply relatively-specified
  101. mouse motion along the x- or y-axis by up to four times.
  102. */
  103. if (MOU_ACCELERATION)
  104. {
  105. if (iX > MOU_THRESHOLD_1)
  106. iX /= 2;
  107. if (iY > MOU_THRESHOLD_1)
  108. iY /= 2;
  109. if (MOU_ACCELERATION == 2)
  110. {
  111. if (iX > MOU_THRESHOLD_2)
  112. iX /= 2;
  113. if (iY > MOU_THRESHOLD_2)
  114. iY /= 2;
  115. }
  116. }
  117. /*
  118. Once acceleration has been applied, the system scales the resultant
  119. value by the desired mouse speed. Mouse speed can range from 1 (slowest)
  120. to 20 (fastest) and represents how much the pointer moves based on the
  121. distance the mouse moves. The default value is 10, which results in no
  122. additional modification to the mouse motion.
  123. */
  124. *pX = (int)((float)iX/MOU_SPEED_SCALE) * iSignX;
  125. *pY = (int)((float)iY/MOU_SPEED_SCALE) * iSignY;
  126. }
  127. /*---------------------------------------------------------------
  128. * Public Functions
  129. /*---------------------------------------------------------------
  130. *
  131. * FUNCTION SkEx_SetAnchor()
  132. *
  133. * TYPE Global
  134. *
  135. * PURPOSE Sets an anchor to the current mouse position within
  136. * the current window.
  137. *
  138. * INPUTS int scanCode
  139. *
  140. * RETURNS None
  141. *
  142. *---------------------------------------------------------------*/
  143. void SkEx_SetAnchor()
  144. {
  145. GetCursorPos(&MouseAnchor);
  146. DBPRINTF(TEXT("SkEx_SetAnchor( x %d y %d )\r\n"), MouseAnchor.x, MouseAnchor.y);
  147. // MouseWnd = GetActiveWindow();
  148. // ScreenToClient(MouseWnd, &MouseAnchor);
  149. }
  150. /*---------------------------------------------------------------
  151. *
  152. * FUNCTION SkEx_GetAnchor()
  153. *
  154. * TYPE Global
  155. *
  156. * PURPOSE Returns the mouse postion within the active window
  157. *
  158. * INPUTS int scanCode
  159. *
  160. * RETURNS None
  161. *
  162. *---------------------------------------------------------------*/
  163. BOOL SkEx_GetAnchor(LPPOINT Mouse)
  164. {
  165. #if 0
  166. HWND CurrentWnd;
  167. CurrentWnd = GetActiveWindow();
  168. if (CurrentWnd != MouseWnd) // Has the Active window Changed?
  169. return(FALSE); // Yes Return False
  170. ClientToScreen(MouseWnd, &MouseAnchor); // Convert Window to Screen
  171. #endif
  172. Mouse->x = MouseAnchor.x;
  173. Mouse->y = MouseAnchor.y;
  174. DBPRINTF(TEXT("SkEx_GetAnchor( x %d y %d )\r\n"), MouseAnchor.x, MouseAnchor.y);
  175. return(TRUE);
  176. }
  177. /*---------------------------------------------------------------
  178. *
  179. * FUNCTION SkEx_SendBeep()
  180. *
  181. * TYPE Global
  182. *
  183. * PURPOSE Send Keyboard Down events to the Event Manager
  184. *
  185. * INPUTS int scanCode
  186. *
  187. * RETURNS None
  188. *
  189. *---------------------------------------------------------------*/
  190. void SkEx_SendBeep()
  191. {
  192. MessageBeep(0);
  193. }
  194. /*---------------------------------------------------------------
  195. *
  196. * FUNCTION SkEx_SetBaud(int Baud)
  197. *
  198. * TYPE Global
  199. *
  200. * PURPOSE Sets the Baudrate for the current port
  201. *
  202. * INPUTS int scanCode
  203. *
  204. * RETURNS None
  205. *
  206. *---------------------------------------------------------------*/
  207. void SkEx_SetBaud(int Baud)
  208. {
  209. DBPRINTF(TEXT("SkEx_SetBaud()\r\n"));
  210. SetCommBaud(Baud);
  211. }
  212. /*---------------------------------------------------------------
  213. *
  214. * FUNCTION SkEx_SendKeyDown()
  215. *
  216. * TYPE Global
  217. *
  218. * PURPOSE Send Keyboard Down events to the Event Manager
  219. *
  220. * INPUTS int scanCode
  221. *
  222. * RETURNS None
  223. *
  224. *---------------------------------------------------------------*/
  225. void SkEx_SendKeyDown(int scanCode)
  226. {
  227. BYTE c;
  228. int Flags = 0;
  229. if (scanCode & 0xE000) // Is this and Extended Key
  230. {
  231. Flags = KEYEVENTF_EXTENDEDKEY; // Yes - Set Ext Flag
  232. scanCode &= 0x000000FF; // Clear out extended value
  233. }
  234. c = (BYTE)MapVirtualKey(scanCode, 3);
  235. if (scanCode == ALT || scanCode == CTRL || scanCode == DEL)
  236. CheckAltCtrlDel(scanCode);
  237. DBPRINTF(TEXT("SkEx_SendKeyDown(Virtual %d Scan %d Flag %d)\r\n"), c, scanCode, Flags);
  238. DeskSwitchToInput();
  239. keybd_event(c, (BYTE) scanCode, Flags, 0L);
  240. }
  241. /*---------------------------------------------------------------
  242. *
  243. * FUNCTION SkEx_SendKeyDown()
  244. *
  245. * TYPE Global
  246. *
  247. * PURPOSE Send Keyboard Up events to the Event Manager
  248. *
  249. * INPUTS int scanCode
  250. *
  251. * RETURNS None
  252. *
  253. *---------------------------------------------------------------*/
  254. void SkEx_SendKeyUp(int scanCode)
  255. {
  256. BYTE c;
  257. int Flags = 0;
  258. if (Push)
  259. {
  260. Key[0] = Key[1] = Key[2] = 0; // Clear Buffer
  261. Push = 0; // Reset AltCtrlDel
  262. }
  263. if (scanCode & 0xE000) // Is this and Extended Key
  264. {
  265. Flags = KEYEVENTF_EXTENDEDKEY; // Yes - Set Ext Flag
  266. scanCode &= 0xFF; // Clear out extended value
  267. }
  268. Flags += KEYEVENTF_KEYUP;
  269. c = (BYTE) MapVirtualKey(scanCode, 3);
  270. DBPRINTF(TEXT("SkEx_SendKeyUp(Virtual %d Scan %d Flags %d)\r\n"), c, scanCode, Flags);
  271. DeskSwitchToInput();
  272. keybd_event(c, (BYTE) scanCode, Flags, 0L);
  273. }
  274. /*---------------------------------------------------------------
  275. *
  276. * FUNCTION SkEx_SendMouse()
  277. *
  278. * TYPE Global
  279. *
  280. * PURPOSE Send Mouse Events to the Event manager
  281. *
  282. * INPUTS int scanCode
  283. *
  284. * RETURNS None
  285. *
  286. *---------------------------------------------------------------*/
  287. void SkEx_SendMouse(MOUSEKEYSPARAM *p)
  288. {
  289. INPUT input;
  290. // According to GIDEI spec, the move command specifies pixels.
  291. // SendInput adjusts the XY values based on acceleration and
  292. // mouse speed so we need to adjust them so the resulting move
  293. // is pixels.
  294. AdjustPixels(&p->Delta_X, &p->Delta_Y);
  295. DBPRINTF(TEXT("SkEx_SendMouse(Stat %d x %d y %d )\r\n"), p->Status, p->Delta_X, p->Delta_Y);
  296. memset(&input, 0, sizeof(INPUT));
  297. input.type = INPUT_MOUSE;
  298. input.mi.dx = p->Delta_X;
  299. input.mi.dy = p->Delta_Y;
  300. input.mi.dwFlags = p->Status;
  301. input.mi.dwExtraInfo = (DWORD)GetMessageExtraInfo(); // documented assignment; must be OK?
  302. DeskSwitchToInput();
  303. if (!SendInput(1, &input, sizeof(INPUT)))
  304. DBPRINTF(TEXT("SkEx_SendMouse: SendInput FAILED 0x%x\r\n"), GetLastError());
  305. }
  306. #ifdef QUEUE_BUF
  307. /*---------------------------------------------------------------
  308. *
  309. * FUNCTION SendKey()
  310. *
  311. * TYPE Global
  312. *
  313. * PURPOSE This Function Send keys from the Que to Windows NT
  314. *
  315. * INPUTS None
  316. *
  317. * RETURNS None
  318. *
  319. *---------------------------------------------------------------*/
  320. void SendKey()
  321. {
  322. if (KeyBack == KeyFront) // Are there Keys in the Que?
  323. return; // No - Exit;
  324. DBPRINTF(TEXT("SkEx_SendKey(KeyBack %d )\r\n"), KeyBack);
  325. DeskSwitchToInput();
  326. keybd_event // Process the Key Event
  327. (
  328. KeyQue[KeyBack].VirKey,
  329. KeyQue[KeyBack].ScanCode,
  330. KeyQue[KeyBack].Flags, 0L
  331. );
  332. KeyBack++; // Increment Key pointer
  333. if (KeyBack == MAXKEYS) // Are we at the End of the buffer
  334. KeyBack = 0; // Yes - Reset to start.
  335. }
  336. /*---------------------------------------------------------------
  337. * Local Functions
  338. /*---------------------------------------------------------------
  339. *
  340. * FUNCTION AddKey(BYTE VirKey, BYTE ScanCode, int Flags)
  341. *
  342. * TYPE Local
  343. *
  344. * PURPOSE Adds a key to the Key Que.
  345. *
  346. * INPUTS BYTE VirKey - Virtual Key
  347. * BYTE ScanCode-
  348. * int Flags -
  349. *
  350. * RETURNS None
  351. *
  352. *---------------------------------------------------------------*/
  353. static void AddKey(BYTE VirKey, BYTE ScanCode, int Flags)
  354. {
  355. DBPRINTF(TEXT("AddKey(KeyFront %d )\r\n"), KeyFront);
  356. // Add Keys to Que
  357. KeyQue[KeyFront].VirKey = VirKey;
  358. KeyQue[KeyFront].ScanCode = ScanCode;
  359. KeyQue[KeyFront].Flags = Flags;
  360. KeyFront++; // Point to next Que
  361. if (KeyFront == MAXKEYS) // Are we at the End of the buffer
  362. KeyFront = 0; // Yes - Reset to start.
  363. // Process the Key Event
  364. DeskSwitchToInput();
  365. keybd_event(VirKey, ScanCode, Flags, 0L);
  366. }
  367. #endif // QUE
  368. /*---------------------------------------------------------------
  369. *
  370. * FUNCTION CheckAltCtrlDel(int scanCode)
  371. *
  372. * TYPE Local
  373. *
  374. * PURPOSE Checks for the condition of Alt-Ctrl-Del key
  375. * Combination.
  376. *
  377. * INPUTS int scanCode
  378. *
  379. * RETURNS None
  380. *
  381. *---------------------------------------------------------------*/
  382. static void CheckAltCtrlDel(int scanCode)
  383. {
  384. BOOL fCtrl = FALSE;
  385. BOOL fAlt = FALSE;
  386. BOOL fDel = FALSE;
  387. int i;
  388. DBPRINTF(TEXT("CheckAltCtrlDel()\r\n"));
  389. // Push is reset back to 0 when a key-up is received. We only
  390. // have space for three keys in the Key[] buffer, so make sure
  391. // there's space before we add a key...
  392. if( Push >= 3 )
  393. return;
  394. Key[Push] = (char)scanCode; // Save Scan Code
  395. Push++; // Inc Index
  396. if (Push != 3) // Have we got 3 keys?
  397. return; // No - Exit
  398. for ( i = 0; i < 3; i++ )
  399. {
  400. switch ( Key[i] )
  401. {
  402. case CTRL: fCtrl = TRUE; break;
  403. case ALT: fAlt = TRUE; break;
  404. case DEL: fDel = TRUE; break;
  405. }
  406. }
  407. if ( fCtrl && fAlt && fDel ) // Is Buffer Alt=Ctrl=Del
  408. SendAltCtrlDel(); // Yes - Send command
  409. }
  410. /*---------------------------------------------------------------
  411. *
  412. * FUNCTION SendAltCtrlDel()
  413. *
  414. * TYPE Local
  415. *
  416. * PURPOSE Signal system reset
  417. *
  418. * INPUTS None
  419. *
  420. * RETURNS None
  421. *
  422. *---------------------------------------------------------------*/
  423. static void SendAltCtrlDel()
  424. {
  425. HWINSTA hwinsta;
  426. HDESK hdesk;
  427. HWND hwndSAS;
  428. HWINSTA hwinstaSave;
  429. HDESK hdeskSave;
  430. DBPRINTF(TEXT("SendAltCtrlDel()\r\n"));
  431. hwinstaSave = GetProcessWindowStation();
  432. hdeskSave = GetThreadDesktop(GetCurrentThreadId());
  433. hwinsta = OpenWindowStation(TEXT("WinSta0"), FALSE, MAXIMUM_ALLOWED);
  434. SetProcessWindowStation(hwinsta);
  435. hdesk = OpenDesktop(TEXT("Winlogon"), 0, FALSE, MAXIMUM_ALLOWED);
  436. SetThreadDesktop(hdesk);
  437. hwndSAS = FindWindow(NULL, TEXT("SAS window"));
  438. ////PostMessage(hwndSAS, WM_HOTKEY, 0, 0);
  439. SendMessage(hwndSAS, WM_HOTKEY, 0, 0);
  440. if (NULL != hdeskSave)
  441. {
  442. SetThreadDesktop(hdeskSave);
  443. }
  444. if (NULL != hwinstaSave)
  445. {
  446. SetProcessWindowStation(hwinstaSave);
  447. }
  448. CloseDesktop(hdesk);
  449. CloseWindowStation(hwinsta);
  450. }
  451. BOOL DeskSwitchToInput()
  452. {
  453. BOOL fOk = FALSE;
  454. HANDLE hNewDesktop;
  455. // We are switching desktops
  456. // get current Input desktop
  457. hNewDesktop = OpenInputDesktop(
  458. 0L,
  459. FALSE,
  460. MAXIMUM_ALLOWED);
  461. if (NULL == hNewDesktop)
  462. {
  463. DBPRINTF(TEXT("OpenInputDesktop failed\r\n"));
  464. }
  465. else
  466. {
  467. fOk = SetThreadDesktop(hNewDesktop); // attach thread to desktop
  468. if (!fOk)
  469. {
  470. DBPRINTF(TEXT("Failed SetThreadDesktop()\r\n"));
  471. }
  472. else
  473. {
  474. if (NULL != s_hdeskUser)
  475. {
  476. CloseDesktop(s_hdeskUser); // close old desktop
  477. }
  478. s_hdeskUser = hNewDesktop; // save desktop
  479. }
  480. }
  481. return(fOk);
  482. }