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.

660 lines
16 KiB

  1. /*++
  2. Copyright (c) 1985 - 1999, Microsoft Corporation
  3. Module Name:
  4. constubs.c
  5. Abstract:
  6. Author:
  7. KazuM Mar.05.1992
  8. Revision History:
  9. --*/
  10. #include "precomp.h"
  11. #pragma hdrstop
  12. #if defined(FE_SB)
  13. ULONG
  14. SrvGetConsoleCharType(
  15. IN OUT PCSR_API_MSG m,
  16. IN OUT PCSR_REPLY_STATUS ReplyStatus
  17. )
  18. /*++
  19. Routine Description:
  20. This routine check character type.
  21. Arguments:
  22. m - message containing api parameters
  23. ReplyStatus - Indicates whether to reply to the dll port.
  24. Return Value:
  25. --*/
  26. {
  27. NTSTATUS Status;
  28. PCONSOLE_CHAR_TYPE_MSG a = (PCONSOLE_CHAR_TYPE_MSG)&m->u.ApiMessageData;
  29. PCONSOLE_INFORMATION Console;
  30. PSCREEN_INFORMATION ScreenInfo;
  31. PHANDLE_DATA HandleData;
  32. SHORT RowIndex;
  33. PROW Row;
  34. PWCHAR Char;
  35. UNREFERENCED_PARAMETER(ReplyStatus);
  36. Status = ApiPreamble(a->ConsoleHandle, &Console);
  37. if (!NT_SUCCESS(Status)) {
  38. return Status;
  39. }
  40. Status = DereferenceIoHandle(CONSOLE_PERPROCESSDATA(),
  41. a->Handle,
  42. CONSOLE_OUTPUT_HANDLE,
  43. GENERIC_READ,
  44. &HandleData);
  45. if (NT_SUCCESS(Status)) {
  46. ScreenInfo = HandleData->Buffer.ScreenBuffer;
  47. #if DBG && defined(DBG_KATTR)
  48. BeginKAttrCheck(ScreenInfo);
  49. #endif
  50. if (a->coordCheck.X >= ScreenInfo->ScreenBufferSize.X ||
  51. a->coordCheck.Y >= ScreenInfo->ScreenBufferSize.Y) {
  52. Status = STATUS_INVALID_PARAMETER;
  53. } else {
  54. RowIndex = (ScreenInfo->BufferInfo.TextInfo.FirstRow+a->coordCheck.Y) % ScreenInfo->ScreenBufferSize.Y;
  55. Row = &ScreenInfo->BufferInfo.TextInfo.Rows[RowIndex];
  56. Char = &Row->CharRow.Chars[a->coordCheck.X];
  57. if (!CONSOLE_IS_DBCS_OUTPUTCP(ScreenInfo->Console)) {
  58. a->dwType = CHAR_TYPE_SBCS;
  59. } else if (Row->CharRow.KAttrs[a->coordCheck.X] & ATTR_TRAILING_BYTE) {
  60. a->dwType = CHAR_TYPE_TRAILING;
  61. } else if (Row->CharRow.KAttrs[a->coordCheck.X] & ATTR_LEADING_BYTE) {
  62. a->dwType = CHAR_TYPE_LEADING;
  63. } else {
  64. a->dwType = CHAR_TYPE_SBCS;
  65. }
  66. }
  67. }
  68. UnlockConsole(Console);
  69. return Status;
  70. }
  71. ULONG
  72. SrvSetConsoleLocalEUDC(
  73. IN OUT PCSR_API_MSG m,
  74. IN OUT PCSR_REPLY_STATUS ReplyStatus
  75. )
  76. /*++
  77. Routine Description:
  78. This routine sets Local EUDC Font.
  79. Arguments:
  80. m - message containing api parameters
  81. ReplyStatus - Indicates whether to reply to the dll port.
  82. Return Value:
  83. --*/
  84. {
  85. PCONSOLE_LOCAL_EUDC_MSG a = (PCONSOLE_LOCAL_EUDC_MSG)&m->u.ApiMessageData;
  86. NTSTATUS Status;
  87. PCONSOLE_INFORMATION Console;
  88. PHANDLE_DATA HandleData;
  89. CHAR Source[4];
  90. WCHAR Target[2];
  91. UNREFERENCED_PARAMETER(ReplyStatus);
  92. Status = ApiPreamble(a->ConsoleHandle, &Console);
  93. if (!NT_SUCCESS(Status)) {
  94. return Status;
  95. }
  96. Status = DereferenceIoHandle(CONSOLE_PERPROCESSDATA(),
  97. a->Handle,
  98. CONSOLE_OUTPUT_HANDLE,
  99. GENERIC_WRITE,
  100. &HandleData);
  101. if (!NT_SUCCESS(Status)) {
  102. UnlockConsole(Console);
  103. return Status;
  104. }
  105. if (!CsrValidateMessageBuffer(m, &a->FontFace, ((a->FontSize.X + 7) / 8), a->FontSize.Y)) {
  106. UnlockConsole(Console);
  107. return STATUS_INVALID_PARAMETER;
  108. }
  109. Source[0] = (char)(a->CodePoint >> 8);
  110. Source[1] = (char)(a->CodePoint & 0x00ff);
  111. Source[2] = 0;
  112. ConvertOutputToUnicode(Console->OutputCP,Source,2,Target,1);
  113. if (IsEudcRange(Console,Target[0])) {
  114. Status = RegisterLocalEUDC(Console,Target[0],a->FontSize,a->FontFace);
  115. if (NT_SUCCESS(Status)) {
  116. ((PEUDC_INFORMATION)(Console->EudcInformation))->LocalVDMEudcMode = TRUE;
  117. }
  118. } else {
  119. UnlockConsole(Console);
  120. return STATUS_INVALID_PARAMETER;
  121. }
  122. UnlockConsole(Console);
  123. return STATUS_SUCCESS;
  124. }
  125. ULONG
  126. SrvSetConsoleCursorMode(
  127. IN OUT PCSR_API_MSG m,
  128. IN OUT PCSR_REPLY_STATUS ReplyStatus
  129. )
  130. /*++
  131. Routine Description:
  132. This routine sets Cursor Mode.
  133. Arguments:
  134. m - message containing api parameters
  135. ReplyStatus - Indicates whether to reply to the dll port.
  136. Return Value:
  137. --*/
  138. {
  139. PCONSOLE_CURSOR_MODE_MSG a = (PCONSOLE_CURSOR_MODE_MSG)&m->u.ApiMessageData;
  140. NTSTATUS Status;
  141. PCONSOLE_INFORMATION Console;
  142. PHANDLE_DATA HandleData;
  143. UNREFERENCED_PARAMETER(ReplyStatus);
  144. Status = ApiPreamble(a->ConsoleHandle, &Console);
  145. if (!NT_SUCCESS(Status)) {
  146. return Status;
  147. }
  148. Status = DereferenceIoHandle(CONSOLE_PERPROCESSDATA(),
  149. a->Handle,
  150. CONSOLE_OUTPUT_HANDLE,
  151. GENERIC_WRITE,
  152. &HandleData);
  153. if (!NT_SUCCESS(Status)) {
  154. UnlockConsole(Console);
  155. return Status;
  156. }
  157. HandleData->Buffer.ScreenBuffer->BufferInfo.TextInfo.CursorBlink = (BOOLEAN)a->Blink;
  158. HandleData->Buffer.ScreenBuffer->BufferInfo.TextInfo.CursorDBEnable = (BOOLEAN)a->DBEnable;
  159. UnlockConsole(Console);
  160. return Status;
  161. }
  162. ULONG
  163. SrvGetConsoleCursorMode(
  164. IN OUT PCSR_API_MSG m,
  165. IN OUT PCSR_REPLY_STATUS ReplyStatus
  166. )
  167. /*++
  168. Routine Description:
  169. This routine gets Cursor Mode.
  170. Arguments:
  171. m - message containing api parameters
  172. ReplyStatus - Indicates whether to reply to the dll port.
  173. Return Value:
  174. --*/
  175. {
  176. PCONSOLE_CURSOR_MODE_MSG a = (PCONSOLE_CURSOR_MODE_MSG)&m->u.ApiMessageData;
  177. NTSTATUS Status;
  178. PCONSOLE_INFORMATION Console;
  179. PHANDLE_DATA HandleData;
  180. UNREFERENCED_PARAMETER(ReplyStatus);
  181. Status = ApiPreamble(a->ConsoleHandle, &Console);
  182. if (!NT_SUCCESS(Status)) {
  183. return Status;
  184. }
  185. Status = DereferenceIoHandle(CONSOLE_PERPROCESSDATA(),
  186. a->Handle,
  187. CONSOLE_OUTPUT_HANDLE,
  188. GENERIC_READ,
  189. &HandleData);
  190. if (!NT_SUCCESS(Status)) {
  191. UnlockConsole(Console);
  192. return Status;
  193. }
  194. a->Blink = HandleData->Buffer.ScreenBuffer->BufferInfo.TextInfo.CursorBlink;
  195. a->DBEnable = HandleData->Buffer.ScreenBuffer->BufferInfo.TextInfo.CursorDBEnable;
  196. UnlockConsole(Console);
  197. return Status;
  198. }
  199. ULONG
  200. SrvRegisterConsoleOS2(
  201. IN OUT PCSR_API_MSG m,
  202. IN OUT PCSR_REPLY_STATUS ReplyStatus
  203. )
  204. /*++
  205. This function calls NEC PC-98 machine's only.
  206. --*/
  207. {
  208. PCONSOLE_REGISTEROS2_MSG a = (PCONSOLE_REGISTEROS2_MSG)&m->u.ApiMessageData;
  209. NTSTATUS Status;
  210. PCONSOLE_INFORMATION Console;
  211. UNREFERENCED_PARAMETER(ReplyStatus);
  212. Status = ApiPreamble(a->ConsoleHandle, &Console);
  213. if (!NT_SUCCESS(Status)) {
  214. return Status;
  215. }
  216. #if defined(i386)
  217. if (!a->fOs2Register) {
  218. Console->Flags &= ~ CONSOLE_OS2_REGISTERED;
  219. ResizeWindow(Console->CurrentScreenBuffer, &Console->Os2SavedWindowRect, FALSE);
  220. } else {
  221. Console->Flags |= CONSOLE_OS2_REGISTERED;
  222. Console->Os2SavedWindowRect = Console->CurrentScreenBuffer->Window;
  223. }
  224. #endif
  225. UnlockConsole(Console);
  226. return Status;
  227. }
  228. ULONG
  229. SrvSetConsoleOS2OemFormat(
  230. IN OUT PCSR_API_MSG m,
  231. IN OUT PCSR_REPLY_STATUS ReplyStatus
  232. )
  233. /*++
  234. This function calls NEC PC-98 machine's only.
  235. --*/
  236. {
  237. PCONSOLE_SETOS2OEMFORMAT_MSG a = (PCONSOLE_SETOS2OEMFORMAT_MSG)&m->u.ApiMessageData;
  238. NTSTATUS Status;
  239. PCONSOLE_INFORMATION Console;
  240. UNREFERENCED_PARAMETER(ReplyStatus);
  241. Status = ApiPreamble(a->ConsoleHandle, &Console);
  242. if (!NT_SUCCESS(Status)) {
  243. return Status;
  244. }
  245. #if defined(i386)
  246. if (!a->fOs2OemFormat) {
  247. Console->Flags &= ~CONSOLE_OS2_OEM_FORMAT;
  248. } else {
  249. Console->Flags |= CONSOLE_OS2_OEM_FORMAT;
  250. }
  251. #endif
  252. UnlockConsole(Console);
  253. return Status;
  254. }
  255. #if defined(FE_IME)
  256. ULONG
  257. SrvGetConsoleNlsMode(
  258. IN OUT PCSR_API_MSG m,
  259. IN OUT PCSR_REPLY_STATUS ReplyStatus
  260. )
  261. /*++
  262. Routine Description:
  263. This routine gets NLS mode for input.
  264. Arguments:
  265. m - message containing api parameters
  266. ReplyStatus - Indicates whether to reply to the dll port.
  267. Return Value:
  268. --*/
  269. {
  270. NTSTATUS Status;
  271. PCONSOLE_NLS_MODE_MSG a = (PCONSOLE_NLS_MODE_MSG)&m->u.ApiMessageData;
  272. PCONSOLE_INFORMATION Console;
  273. PHANDLE_DATA HandleData;
  274. HANDLE hEvent = NULL;
  275. UNREFERENCED_PARAMETER(ReplyStatus);
  276. Status = ApiPreamble(a->ConsoleHandle, &Console);
  277. if (!NT_SUCCESS(Status)) {
  278. return Status;
  279. }
  280. Status = DereferenceIoHandle(CONSOLE_PERPROCESSDATA(),
  281. a->Handle,
  282. CONSOLE_INPUT_HANDLE,
  283. GENERIC_READ,
  284. &HandleData);
  285. if (!NT_SUCCESS(Status)) {
  286. goto SrvGetConsoleNlsModeFailure;
  287. }
  288. Status = NtDuplicateObject(CONSOLE_CLIENTPROCESSHANDLE(),
  289. a->hEvent,
  290. NtCurrentProcess(),
  291. &hEvent,
  292. 0,
  293. FALSE,
  294. DUPLICATE_SAME_ACCESS
  295. );
  296. if (!NT_SUCCESS(Status)) {
  297. goto SrvGetConsoleNlsModeFailure;
  298. }
  299. /*
  300. * Caller should set FALSE on a->Ready.
  301. */
  302. if (a->Ready == FALSE) {
  303. a->Ready = HandleData->Buffer.InputBuffer->ImeMode.ReadyConversion;
  304. if (a->Ready == FALSE) {
  305. /*
  306. * If not ready ImeMode.Conversion, then get conversion status
  307. * from ConIME.
  308. */
  309. Status = QueueConsoleMessage(Console,
  310. CM_GET_NLSMODE,
  311. (WPARAM)hEvent,
  312. 0L);
  313. if (!NT_SUCCESS(Status)) {
  314. goto SrvGetConsoleNlsModeFailure;
  315. }
  316. } else {
  317. if (!HandleData->Buffer.InputBuffer->ImeMode.Disable) {
  318. a->NlsMode = ImmConversionToConsole(HandleData->Buffer.InputBuffer->ImeMode.Conversion);
  319. } else {
  320. a->NlsMode = 0;
  321. }
  322. NtSetEvent(hEvent, NULL);
  323. NtClose(hEvent);
  324. }
  325. } else {
  326. if (!HandleData->Buffer.InputBuffer->ImeMode.Disable) {
  327. a->NlsMode = ImmConversionToConsole(HandleData->Buffer.InputBuffer->ImeMode.Conversion);
  328. } else {
  329. a->NlsMode = 0;
  330. }
  331. NtSetEvent(hEvent, NULL);
  332. NtClose(hEvent);
  333. }
  334. UnlockConsole(Console);
  335. return Status;
  336. SrvGetConsoleNlsModeFailure:
  337. if (hEvent) {
  338. NtSetEvent(hEvent, NULL);
  339. NtClose(hEvent);
  340. }
  341. UnlockConsole(Console);
  342. return Status;
  343. }
  344. ULONG
  345. SrvSetConsoleNlsMode(
  346. IN OUT PCSR_API_MSG m,
  347. IN OUT PCSR_REPLY_STATUS ReplyStatus
  348. )
  349. /*++
  350. Routine Description:
  351. This routine sets NLS mode for input.
  352. Arguments:
  353. m - message containing api parameters
  354. ReplyStatus - Indicates whether to reply to the dll port.
  355. Return Value:
  356. --*/
  357. {
  358. PCONSOLE_NLS_MODE_MSG a = (PCONSOLE_NLS_MODE_MSG)&m->u.ApiMessageData;
  359. NTSTATUS Status;
  360. PCONSOLE_INFORMATION Console;
  361. PHANDLE_DATA HandleData;
  362. HANDLE hEvent = NULL;
  363. UNREFERENCED_PARAMETER(ReplyStatus);
  364. Status = ApiPreamble(a->ConsoleHandle, &Console);
  365. if (!NT_SUCCESS(Status)) {
  366. return Status;
  367. }
  368. Status = DereferenceIoHandle(CONSOLE_PERPROCESSDATA(),
  369. a->Handle,
  370. CONSOLE_INPUT_HANDLE,
  371. GENERIC_WRITE,
  372. &HandleData);
  373. if (!NT_SUCCESS(Status)) {
  374. goto SrvSetConsoleNlsModeFailure;
  375. }
  376. Status = NtDuplicateObject(CONSOLE_CLIENTPROCESSHANDLE(),
  377. a->hEvent,
  378. NtCurrentProcess(),
  379. &hEvent,
  380. 0,
  381. FALSE,
  382. DUPLICATE_SAME_ACCESS
  383. );
  384. if (!NT_SUCCESS(Status)) {
  385. goto SrvSetConsoleNlsModeFailure;
  386. }
  387. Status = QueueConsoleMessage(Console,
  388. CM_SET_NLSMODE,
  389. (WPARAM)hEvent,
  390. a->NlsMode);
  391. if (!NT_SUCCESS(Status)) {
  392. goto SrvSetConsoleNlsModeFailure;
  393. }
  394. UnlockConsole(Console);
  395. return Status;
  396. SrvSetConsoleNlsModeFailure:
  397. if (hEvent) {
  398. NtSetEvent(hEvent, NULL);
  399. NtClose(hEvent);
  400. }
  401. UnlockConsole(Console);
  402. return Status;
  403. }
  404. ULONG
  405. SrvRegisterConsoleIME(
  406. IN OUT PCSR_API_MSG m,
  407. IN OUT PCSR_REPLY_STATUS ReplyStatus
  408. )
  409. /*++
  410. Routine Description:
  411. This routine register console IME on the current desktop.
  412. Arguments:
  413. m - message containing api parameters
  414. ReplyStatus - Indicates whether to reply to the dll port.
  415. Return Value:
  416. --*/
  417. {
  418. PCONSOLE_REGISTER_CONSOLEIME_MSG a = (PCONSOLE_REGISTER_CONSOLEIME_MSG)&m->u.ApiMessageData;
  419. NTSTATUS Status;
  420. PCSR_PROCESS Process;
  421. HDESK hdesk;
  422. HWINSTA hwinsta;
  423. UNICODE_STRING strDesktopName;
  424. UNREFERENCED_PARAMETER(ReplyStatus);
  425. if (!CsrValidateMessageBuffer(m, &a->Desktop, a->DesktopLength, sizeof(BYTE))) {
  426. return STATUS_INVALID_PARAMETER;
  427. }
  428. //
  429. // Connect to the windowstation and desktop.
  430. //
  431. if (!CsrImpersonateClient(NULL)) {
  432. return STATUS_BAD_IMPERSONATION_LEVEL;
  433. }
  434. Process = CSR_SERVER_QUERYCLIENTTHREAD()->Process;
  435. if (a->DesktopLength) {
  436. RtlInitUnicodeString(&strDesktopName, a->Desktop);
  437. } else {
  438. RtlInitUnicodeString(&strDesktopName, L"Default");
  439. }
  440. hdesk = NtUserResolveDesktop(Process->ProcessHandle,
  441. &strDesktopName,
  442. FALSE,
  443. &hwinsta);
  444. CsrRevertToSelf();
  445. if (hdesk == NULL) {
  446. return STATUS_UNSUCCESSFUL;
  447. }
  448. Status = ConSrvRegisterConsoleIME(Process,
  449. hdesk,
  450. hwinsta,
  451. a->hWndConsoleIME,
  452. a->dwConsoleIMEThreadId,
  453. REGCONIME_REGISTER,
  454. &a->dwConsoleThreadId);
  455. return Status;
  456. }
  457. ULONG
  458. SrvUnregisterConsoleIME(
  459. IN OUT PCSR_API_MSG m,
  460. IN OUT PCSR_REPLY_STATUS ReplyStatus
  461. )
  462. /*++
  463. Routine Description:
  464. This routine unregister console IME on the current desktop.
  465. Arguments:
  466. m - message containing api parameters
  467. ReplyStatus - Indicates whether to reply to the dll port.
  468. Return Value:
  469. --*/
  470. {
  471. PCONSOLE_UNREGISTER_CONSOLEIME_MSG a = (PCONSOLE_UNREGISTER_CONSOLEIME_MSG)&m->u.ApiMessageData;
  472. NTSTATUS Status;
  473. PCSR_PROCESS Process;
  474. PCONSOLE_PER_PROCESS_DATA ProcessData;
  475. UNREFERENCED_PARAMETER(ReplyStatus);
  476. Process = CSR_SERVER_QUERYCLIENTTHREAD()->Process;
  477. ProcessData = CONSOLE_FROMPROCESSPERPROCESSDATA(Process);
  478. /*
  479. * If ProcessData->hDesk is NULL, then the IME process was already
  480. * forcibly unregistered in ConsoleClientShutdown, so there's no work
  481. * to do.
  482. */
  483. if (ProcessData->hDesk) {
  484. Status = ConSrvRegisterConsoleIME(Process,
  485. ProcessData->hDesk,
  486. ProcessData->hWinSta,
  487. NULL,
  488. a->dwConsoleIMEThreadId,
  489. REGCONIME_UNREGISTER,
  490. NULL);
  491. } else {
  492. Status = STATUS_SUCCESS;
  493. }
  494. return Status;
  495. }
  496. #endif
  497. #endif