console.c 55 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598
  1. /*
  2. * Server-side console management
  3. *
  4. * Copyright (C) 1998 Alexandre Julliard
  5. * 2001 Eric Pouech
  6. * Copyright 2020 Jacek Caban for CodeWeavers
  7. *
  8. *
  9. * This library is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation; either
  12. * version 2.1 of the License, or (at your option) any later version.
  13. *
  14. * This library is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with this library; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  22. */
  23. #include "config.h"
  24. #include "wine/port.h"
  25. #include <assert.h>
  26. #include <string.h>
  27. #include <stdio.h>
  28. #include <unistd.h>
  29. #include <signal.h>
  30. #include <sys/ioctl.h>
  31. #include <termios.h>
  32. #include "ntstatus.h"
  33. #define WIN32_NO_STATUS
  34. #include "handle.h"
  35. #include "process.h"
  36. #include "request.h"
  37. #include "file.h"
  38. #include "unicode.h"
  39. #include "wincon.h"
  40. #include "winternl.h"
  41. #include "wine/condrv.h"
  42. struct screen_buffer;
  43. struct history_line
  44. {
  45. data_size_t len;
  46. WCHAR text[1];
  47. };
  48. struct console
  49. {
  50. struct object obj; /* object header */
  51. int signaled; /* is console signaled */
  52. struct thread *renderer; /* console renderer thread */
  53. struct screen_buffer *active; /* active screen buffer */
  54. struct console_server *server; /* console server object */
  55. unsigned int last_id; /* id of last created console buffer */
  56. struct fd *fd; /* for bare console, attached input fd */
  57. struct async_queue ioctl_q; /* ioctl queue */
  58. struct async_queue read_q; /* read queue */
  59. };
  60. static void console_dump( struct object *obj, int verbose );
  61. static void console_destroy( struct object *obj );
  62. static int console_signaled( struct object *obj, struct wait_queue_entry *entry );
  63. static struct fd *console_get_fd( struct object *obj );
  64. static struct object *console_lookup_name( struct object *obj, struct unicode_str *name,
  65. unsigned int attr, struct object *root );
  66. static struct object *console_open_file( struct object *obj, unsigned int access,
  67. unsigned int sharing, unsigned int options );
  68. static const struct object_ops console_ops =
  69. {
  70. sizeof(struct console), /* size */
  71. &file_type, /* type */
  72. console_dump, /* dump */
  73. add_queue, /* add_queue */
  74. remove_queue, /* remove_queue */
  75. console_signaled, /* signaled */
  76. no_satisfied, /* satisfied */
  77. no_signal, /* signal */
  78. console_get_fd, /* get_fd */
  79. default_map_access, /* map_access */
  80. default_get_sd, /* get_sd */
  81. default_set_sd, /* set_sd */
  82. no_get_full_name, /* get_full_name */
  83. console_lookup_name, /* lookup_name */
  84. no_link_name, /* link_name */
  85. NULL, /* unlink_name */
  86. console_open_file, /* open_file */
  87. no_kernel_obj_list, /* get_kernel_obj_list */
  88. no_close_handle, /* close_handle */
  89. console_destroy /* destroy */
  90. };
  91. static enum server_fd_type console_get_fd_type( struct fd *fd );
  92. static void console_get_file_info( struct fd *fd, obj_handle_t handle, unsigned int info_class );
  93. static int console_get_volume_info( struct fd *fd, struct async *async, unsigned int info_class );
  94. static int console_read( struct fd *fd, struct async *async, file_pos_t pos );
  95. static int console_flush( struct fd *fd, struct async *async );
  96. static int console_ioctl( struct fd *fd, ioctl_code_t code, struct async *async );
  97. static const struct fd_ops console_fd_ops =
  98. {
  99. default_fd_get_poll_events, /* get_poll_events */
  100. default_poll_event, /* poll_event */
  101. console_get_fd_type, /* get_fd_type */
  102. console_read, /* read */
  103. no_fd_write, /* write */
  104. console_flush, /* flush */
  105. console_get_file_info, /* get_file_info */
  106. console_get_volume_info, /* get_volume_info */
  107. console_ioctl, /* ioctl */
  108. default_fd_queue_async, /* queue_async */
  109. default_fd_reselect_async /* reselect_async */
  110. };
  111. struct console_host_ioctl
  112. {
  113. unsigned int code; /* ioctl code */
  114. int output; /* output id for screen buffer ioctls */
  115. struct async *async; /* ioctl async */
  116. struct list entry; /* list entry */
  117. };
  118. struct console_server
  119. {
  120. struct object obj; /* object header */
  121. struct fd *fd; /* pseudo-fd for ioctls */
  122. struct console *console; /* attached console */
  123. struct list queue; /* ioctl queue */
  124. struct list read_queue; /* blocking read queue */
  125. int busy; /* flag if server processing an ioctl */
  126. int term_fd; /* UNIX terminal fd */
  127. struct termios termios; /* original termios */
  128. };
  129. static void console_server_dump( struct object *obj, int verbose );
  130. static void console_server_destroy( struct object *obj );
  131. static int console_server_signaled( struct object *obj, struct wait_queue_entry *entry );
  132. static struct fd *console_server_get_fd( struct object *obj );
  133. static struct object *console_server_lookup_name( struct object *obj, struct unicode_str *name,
  134. unsigned int attr, struct object *root );
  135. static struct object *console_server_open_file( struct object *obj, unsigned int access,
  136. unsigned int sharing, unsigned int options );
  137. static const struct object_ops console_server_ops =
  138. {
  139. sizeof(struct console_server), /* size */
  140. &file_type, /* type */
  141. console_server_dump, /* dump */
  142. add_queue, /* add_queue */
  143. remove_queue, /* remove_queue */
  144. console_server_signaled, /* signaled */
  145. no_satisfied, /* satisfied */
  146. no_signal, /* signal */
  147. console_server_get_fd, /* get_fd */
  148. default_map_access, /* map_access */
  149. default_get_sd, /* get_sd */
  150. default_set_sd, /* set_sd */
  151. no_get_full_name, /* get_full_name */
  152. console_server_lookup_name, /* lookup_name */
  153. no_link_name, /* link_name */
  154. NULL, /* unlink_name */
  155. console_server_open_file, /* open_file */
  156. no_kernel_obj_list, /* get_kernel_obj_list */
  157. no_close_handle, /* close_handle */
  158. console_server_destroy /* destroy */
  159. };
  160. static int console_server_ioctl( struct fd *fd, ioctl_code_t code, struct async *async );
  161. static const struct fd_ops console_server_fd_ops =
  162. {
  163. default_fd_get_poll_events, /* get_poll_events */
  164. default_poll_event, /* poll_event */
  165. console_get_fd_type, /* get_fd_type */
  166. no_fd_read, /* read */
  167. no_fd_write, /* write */
  168. no_fd_flush, /* flush */
  169. no_fd_get_file_info, /* get_file_info */
  170. no_fd_get_volume_info, /* get_volume_info */
  171. console_server_ioctl, /* ioctl */
  172. default_fd_queue_async, /* queue_async */
  173. default_fd_reselect_async /* reselect_async */
  174. };
  175. struct font_info
  176. {
  177. short int width;
  178. short int height;
  179. short int weight;
  180. short int pitch_family;
  181. WCHAR *face_name;
  182. data_size_t face_len;
  183. };
  184. struct screen_buffer
  185. {
  186. struct object obj; /* object header */
  187. struct list entry; /* entry in list of all screen buffers */
  188. struct console *input; /* associated console input */
  189. unsigned int id; /* buffer id */
  190. struct fd *fd; /* for bare console, attached output fd */
  191. struct async_queue ioctl_q; /* ioctl queue */
  192. };
  193. static void screen_buffer_dump( struct object *obj, int verbose );
  194. static void screen_buffer_destroy( struct object *obj );
  195. static int screen_buffer_add_queue( struct object *obj, struct wait_queue_entry *entry );
  196. static struct fd *screen_buffer_get_fd( struct object *obj );
  197. static struct object *screen_buffer_open_file( struct object *obj, unsigned int access,
  198. unsigned int sharing, unsigned int options );
  199. static const struct object_ops screen_buffer_ops =
  200. {
  201. sizeof(struct screen_buffer), /* size */
  202. &file_type, /* type */
  203. screen_buffer_dump, /* dump */
  204. screen_buffer_add_queue, /* add_queue */
  205. NULL, /* remove_queue */
  206. NULL, /* signaled */
  207. NULL, /* satisfied */
  208. no_signal, /* signal */
  209. screen_buffer_get_fd, /* get_fd */
  210. default_map_access, /* map_access */
  211. default_get_sd, /* get_sd */
  212. default_set_sd, /* set_sd */
  213. no_get_full_name, /* get_full_name */
  214. no_lookup_name, /* lookup_name */
  215. no_link_name, /* link_name */
  216. NULL, /* unlink_name */
  217. screen_buffer_open_file, /* open_file */
  218. no_kernel_obj_list, /* get_kernel_obj_list */
  219. no_close_handle, /* close_handle */
  220. screen_buffer_destroy /* destroy */
  221. };
  222. static int screen_buffer_write( struct fd *fd, struct async *async, file_pos_t pos );
  223. static int screen_buffer_ioctl( struct fd *fd, ioctl_code_t code, struct async *async );
  224. static const struct fd_ops screen_buffer_fd_ops =
  225. {
  226. default_fd_get_poll_events, /* get_poll_events */
  227. default_poll_event, /* poll_event */
  228. console_get_fd_type, /* get_fd_type */
  229. no_fd_read, /* read */
  230. screen_buffer_write, /* write */
  231. no_fd_flush, /* flush */
  232. console_get_file_info, /* get_file_info */
  233. console_get_volume_info, /* get_volume_info */
  234. screen_buffer_ioctl, /* ioctl */
  235. default_fd_queue_async, /* queue_async */
  236. default_fd_reselect_async /* reselect_async */
  237. };
  238. static void console_device_dump( struct object *obj, int verbose );
  239. static struct object *console_device_lookup_name( struct object *obj, struct unicode_str *name,
  240. unsigned int attr, struct object *root );
  241. static struct object *console_device_open_file( struct object *obj, unsigned int access,
  242. unsigned int sharing, unsigned int options );
  243. static const struct object_ops console_device_ops =
  244. {
  245. sizeof(struct object), /* size */
  246. &device_type, /* type */
  247. console_device_dump, /* dump */
  248. no_add_queue, /* add_queue */
  249. NULL, /* remove_queue */
  250. NULL, /* signaled */
  251. no_satisfied, /* satisfied */
  252. no_signal, /* signal */
  253. no_get_fd, /* get_fd */
  254. default_map_access, /* map_access */
  255. default_get_sd, /* get_sd */
  256. default_set_sd, /* set_sd */
  257. default_get_full_name, /* get_full_name */
  258. console_device_lookup_name, /* lookup_name */
  259. directory_link_name, /* link_name */
  260. default_unlink_name, /* unlink_name */
  261. console_device_open_file, /* open_file */
  262. no_kernel_obj_list, /* get_kernel_obj_list */
  263. no_close_handle, /* close_handle */
  264. no_destroy /* destroy */
  265. };
  266. struct console_input
  267. {
  268. struct object obj; /* object header */
  269. struct fd *fd; /* pseudo-fd */
  270. };
  271. static void console_input_dump( struct object *obj, int verbose );
  272. static struct object *console_input_open_file( struct object *obj, unsigned int access,
  273. unsigned int sharing, unsigned int options );
  274. static int console_input_add_queue( struct object *obj, struct wait_queue_entry *entry );
  275. static struct fd *console_input_get_fd( struct object *obj );
  276. static void console_input_destroy( struct object *obj );
  277. static const struct object_ops console_input_ops =
  278. {
  279. sizeof(struct console_input), /* size */
  280. &device_type, /* type */
  281. console_input_dump, /* dump */
  282. console_input_add_queue, /* add_queue */
  283. NULL, /* remove_queue */
  284. NULL, /* signaled */
  285. no_satisfied, /* satisfied */
  286. no_signal, /* signal */
  287. console_input_get_fd, /* get_fd */
  288. default_map_access, /* map_access */
  289. default_get_sd, /* get_sd */
  290. default_set_sd, /* set_sd */
  291. no_get_full_name, /* get_full_name */
  292. no_lookup_name, /* lookup_name */
  293. directory_link_name, /* link_name */
  294. default_unlink_name, /* unlink_name */
  295. console_input_open_file, /* open_file */
  296. no_kernel_obj_list, /* get_kernel_obj_list */
  297. no_close_handle, /* close_handle */
  298. console_input_destroy /* destroy */
  299. };
  300. static int console_input_read( struct fd *fd, struct async *async, file_pos_t pos );
  301. static int console_input_flush( struct fd *fd, struct async *async );
  302. static int console_input_ioctl( struct fd *fd, ioctl_code_t code, struct async *async );
  303. static const struct fd_ops console_input_fd_ops =
  304. {
  305. default_fd_get_poll_events, /* get_poll_events */
  306. default_poll_event, /* poll_event */
  307. console_get_fd_type, /* get_fd_type */
  308. console_input_read, /* read */
  309. no_fd_write, /* write */
  310. console_input_flush, /* flush */
  311. console_get_file_info, /* get_file_info */
  312. console_get_volume_info, /* get_volume_info */
  313. console_input_ioctl, /* ioctl */
  314. default_fd_queue_async, /* queue_async */
  315. default_fd_reselect_async /* reselect_async */
  316. };
  317. struct console_output
  318. {
  319. struct object obj; /* object header */
  320. struct fd *fd; /* pseudo-fd */
  321. };
  322. static void console_output_dump( struct object *obj, int verbose );
  323. static int console_output_add_queue( struct object *obj, struct wait_queue_entry *entry );
  324. static struct fd *console_output_get_fd( struct object *obj );
  325. static struct object *console_output_open_file( struct object *obj, unsigned int access,
  326. unsigned int sharing, unsigned int options );
  327. static void console_output_destroy( struct object *obj );
  328. static const struct object_ops console_output_ops =
  329. {
  330. sizeof(struct console_output), /* size */
  331. &device_type, /* type */
  332. console_output_dump, /* dump */
  333. console_output_add_queue, /* add_queue */
  334. NULL, /* remove_queue */
  335. NULL, /* signaled */
  336. no_satisfied, /* satisfied */
  337. no_signal, /* signal */
  338. console_output_get_fd, /* get_fd */
  339. default_map_access, /* map_access */
  340. default_get_sd, /* get_sd */
  341. default_set_sd, /* set_sd */
  342. no_get_full_name, /* get_full_name */
  343. no_lookup_name, /* lookup_name */
  344. directory_link_name, /* link_name */
  345. default_unlink_name, /* unlink_name */
  346. console_output_open_file, /* open_file */
  347. no_kernel_obj_list, /* get_kernel_obj_list */
  348. no_close_handle, /* close_handle */
  349. console_output_destroy /* destroy */
  350. };
  351. static int console_output_write( struct fd *fd, struct async *async, file_pos_t pos );
  352. static int console_output_ioctl( struct fd *fd, ioctl_code_t code, struct async *async );
  353. static const struct fd_ops console_output_fd_ops =
  354. {
  355. default_fd_get_poll_events, /* get_poll_events */
  356. default_poll_event, /* poll_event */
  357. console_get_fd_type, /* get_fd_type */
  358. no_fd_read, /* read */
  359. console_output_write, /* write */
  360. no_fd_flush, /* flush */
  361. console_get_file_info, /* get_file_info */
  362. console_get_volume_info, /* get_volume_info */
  363. console_output_ioctl, /* ioctl */
  364. default_fd_queue_async, /* queue_async */
  365. default_fd_reselect_async /* reselect_async */
  366. };
  367. struct console_connection
  368. {
  369. struct object obj; /* object header */
  370. struct fd *fd; /* pseudo-fd for ioctls */
  371. };
  372. static void console_connection_dump( struct object *obj, int verbose );
  373. static struct fd *console_connection_get_fd( struct object *obj );
  374. static struct object *console_connection_lookup_name( struct object *obj, struct unicode_str *name,
  375. unsigned int attr, struct object *root );
  376. static struct object *console_connection_open_file( struct object *obj, unsigned int access,
  377. unsigned int sharing, unsigned int options );
  378. static int console_connection_close_handle( struct object *obj, struct process *process, obj_handle_t handle );
  379. static void console_connection_destroy( struct object *obj );
  380. static const struct object_ops console_connection_ops =
  381. {
  382. sizeof(struct console_connection),/* size */
  383. &device_type, /* type */
  384. console_connection_dump, /* dump */
  385. no_add_queue, /* add_queue */
  386. NULL, /* remove_queue */
  387. NULL, /* signaled */
  388. no_satisfied, /* satisfied */
  389. no_signal, /* signal */
  390. console_connection_get_fd, /* get_fd */
  391. default_map_access, /* map_access */
  392. default_get_sd, /* get_sd */
  393. default_set_sd, /* set_sd */
  394. no_get_full_name, /* get_full_name */
  395. console_connection_lookup_name, /* lookup_name */
  396. directory_link_name, /* link_name */
  397. default_unlink_name, /* unlink_name */
  398. console_connection_open_file, /* open_file */
  399. no_kernel_obj_list, /* get_kernel_obj_list */
  400. console_connection_close_handle, /* close_handle */
  401. console_connection_destroy /* destroy */
  402. };
  403. static int console_connection_ioctl( struct fd *fd, ioctl_code_t code, struct async *async );
  404. static const struct fd_ops console_connection_fd_ops =
  405. {
  406. default_fd_get_poll_events, /* get_poll_events */
  407. default_poll_event, /* poll_event */
  408. console_get_fd_type, /* get_fd_type */
  409. no_fd_read, /* read */
  410. no_fd_write, /* write */
  411. no_fd_flush, /* flush */
  412. no_fd_get_file_info, /* get_file_info */
  413. no_fd_get_volume_info, /* get_volume_info */
  414. console_connection_ioctl, /* ioctl */
  415. default_fd_queue_async, /* queue_async */
  416. default_fd_reselect_async /* reselect_async */
  417. };
  418. static struct list screen_buffer_list = LIST_INIT(screen_buffer_list);
  419. static int console_signaled( struct object *obj, struct wait_queue_entry *entry )
  420. {
  421. struct console *console = (struct console*)obj;
  422. return console->signaled;
  423. }
  424. static struct fd *console_get_fd( struct object *obj )
  425. {
  426. struct console *console = (struct console *)obj;
  427. assert( obj->ops == &console_ops );
  428. return (struct fd *)grab_object( console->fd );
  429. }
  430. static enum server_fd_type console_get_fd_type( struct fd *fd )
  431. {
  432. return FD_TYPE_CHAR;
  433. }
  434. static void console_get_file_info( struct fd *fd, obj_handle_t handle, unsigned int info_class )
  435. {
  436. set_error( STATUS_INVALID_DEVICE_REQUEST );
  437. }
  438. static int console_get_volume_info( struct fd *fd, struct async *async, unsigned int info_class )
  439. {
  440. switch (info_class)
  441. {
  442. case FileFsDeviceInformation:
  443. {
  444. static const FILE_FS_DEVICE_INFORMATION device_info =
  445. {
  446. FILE_DEVICE_CONSOLE,
  447. FILE_DEVICE_ALLOW_APPCONTAINER_TRAVERSAL
  448. };
  449. if (get_reply_max_size() >= sizeof(device_info))
  450. set_reply_data( &device_info, sizeof(device_info) );
  451. else
  452. set_error( STATUS_BUFFER_TOO_SMALL );
  453. break;
  454. }
  455. default:
  456. set_error( STATUS_NOT_IMPLEMENTED );
  457. }
  458. return 0;
  459. }
  460. static struct object *create_console(void)
  461. {
  462. struct console *console;
  463. if (!(console = alloc_object( &console_ops )))
  464. return NULL;
  465. console->renderer = NULL;
  466. console->signaled = 0;
  467. console->active = NULL;
  468. console->server = NULL;
  469. console->fd = NULL;
  470. console->last_id = 0;
  471. init_async_queue( &console->ioctl_q );
  472. init_async_queue( &console->read_q );
  473. console->fd = alloc_pseudo_fd( &console_fd_ops, &console->obj, FILE_SYNCHRONOUS_IO_NONALERT );
  474. if (!console->fd)
  475. {
  476. release_object( console );
  477. return NULL;
  478. }
  479. allow_fd_caching( console->fd );
  480. return &console->obj;
  481. }
  482. static void console_host_ioctl_terminate( struct console_host_ioctl *call, unsigned int status )
  483. {
  484. if (call->async)
  485. {
  486. async_terminate( call->async, status );
  487. release_object( call->async );
  488. }
  489. free( call );
  490. }
  491. static int queue_host_ioctl( struct console_server *server, unsigned int code, unsigned int output,
  492. struct async *async, struct async_queue *queue )
  493. {
  494. struct console_host_ioctl *ioctl;
  495. if (!(ioctl = mem_alloc( sizeof(*ioctl) ))) return 0;
  496. ioctl->code = code;
  497. ioctl->output = output;
  498. ioctl->async = NULL;
  499. if (async)
  500. {
  501. ioctl->async = (struct async *)grab_object( async );
  502. queue_async( queue, async );
  503. }
  504. list_add_tail( &server->queue, &ioctl->entry );
  505. wake_up( &server->obj, 0 );
  506. if (async) set_error( STATUS_PENDING );
  507. return 1;
  508. }
  509. static void disconnect_console_server( struct console_server *server )
  510. {
  511. while (!list_empty( &server->queue ))
  512. {
  513. struct console_host_ioctl *call = LIST_ENTRY( list_head( &server->queue ), struct console_host_ioctl, entry );
  514. list_remove( &call->entry );
  515. console_host_ioctl_terminate( call, STATUS_CANCELLED );
  516. }
  517. while (!list_empty( &server->read_queue ))
  518. {
  519. struct console_host_ioctl *call = LIST_ENTRY( list_head( &server->read_queue ), struct console_host_ioctl, entry );
  520. list_remove( &call->entry );
  521. console_host_ioctl_terminate( call, STATUS_CANCELLED );
  522. }
  523. if (server->term_fd != -1)
  524. {
  525. tcsetattr( server->term_fd, TCSANOW, &server->termios );
  526. close( server->term_fd );
  527. server->term_fd = -1;
  528. }
  529. if (server->console)
  530. {
  531. assert( server->console->server == server );
  532. server->console->server = NULL;
  533. server->console = NULL;
  534. wake_up( &server->obj, 0 );
  535. }
  536. }
  537. static void set_active_screen_buffer( struct console *console, struct screen_buffer *screen_buffer )
  538. {
  539. if (console->active == screen_buffer) return;
  540. if (console->active) release_object( console->active );
  541. console->active = (struct screen_buffer *)grab_object( screen_buffer );
  542. if (console->server) queue_host_ioctl( console->server, IOCTL_CONDRV_ACTIVATE,
  543. screen_buffer->id, NULL, NULL );
  544. }
  545. static struct object *create_screen_buffer( struct console *console )
  546. {
  547. struct screen_buffer *screen_buffer;
  548. if (console->last_id == ~0)
  549. {
  550. set_error( STATUS_NO_MEMORY );
  551. return NULL;
  552. }
  553. if (!(screen_buffer = alloc_object( &screen_buffer_ops )))
  554. return NULL;
  555. screen_buffer->id = ++console->last_id;
  556. screen_buffer->input = console;
  557. init_async_queue( &screen_buffer->ioctl_q );
  558. list_add_head( &screen_buffer_list, &screen_buffer->entry );
  559. screen_buffer->fd = alloc_pseudo_fd( &screen_buffer_fd_ops, &screen_buffer->obj,
  560. FILE_SYNCHRONOUS_IO_NONALERT );
  561. if (!screen_buffer->fd)
  562. {
  563. release_object( screen_buffer );
  564. return NULL;
  565. }
  566. allow_fd_caching(screen_buffer->fd);
  567. if (console->server) queue_host_ioctl( console->server, IOCTL_CONDRV_INIT_OUTPUT,
  568. screen_buffer->id, NULL, NULL );
  569. if (!console->active) set_active_screen_buffer( console, screen_buffer );
  570. return &screen_buffer->obj;
  571. }
  572. struct thread *console_get_renderer( struct console *console )
  573. {
  574. return console->renderer;
  575. }
  576. struct console_signal_info
  577. {
  578. struct console *console;
  579. process_id_t group;
  580. int signal;
  581. };
  582. static int propagate_console_signal_cb(struct process *process, void *user)
  583. {
  584. struct console_signal_info* csi = (struct console_signal_info*)user;
  585. if (process->console == csi->console && (!csi->group || process->group_id == csi->group))
  586. {
  587. /* find a suitable thread to signal */
  588. struct thread *thread;
  589. LIST_FOR_EACH_ENTRY( thread, &process->thread_list, struct thread, proc_entry )
  590. {
  591. if (send_thread_signal( thread, csi->signal )) break;
  592. }
  593. }
  594. return FALSE;
  595. }
  596. static void propagate_console_signal( struct console *console,
  597. int sig, process_id_t group_id )
  598. {
  599. struct console_signal_info csi;
  600. if (!console)
  601. {
  602. set_error( STATUS_INVALID_PARAMETER );
  603. return;
  604. }
  605. /* FIXME: should support the other events (like CTRL_BREAK) */
  606. if (sig != CTRL_C_EVENT)
  607. {
  608. set_error( STATUS_NOT_IMPLEMENTED );
  609. return;
  610. }
  611. csi.console = console;
  612. csi.signal = SIGINT;
  613. csi.group = group_id;
  614. enum_processes(propagate_console_signal_cb, &csi);
  615. }
  616. /* dumb dump */
  617. static void console_dump( struct object *obj, int verbose )
  618. {
  619. struct console *console = (struct console *)obj;
  620. assert( obj->ops == &console_ops );
  621. fprintf( stderr, "Console input active=%p server=%p\n",
  622. console->active, console->server );
  623. }
  624. static void console_destroy( struct object *obj )
  625. {
  626. struct console *console = (struct console *)obj;
  627. struct screen_buffer *curr;
  628. assert( obj->ops == &console_ops );
  629. if (console->server)
  630. {
  631. assert( console->server->console == console );
  632. disconnect_console_server( console->server );
  633. }
  634. if (console->active) release_object( console->active );
  635. console->active = NULL;
  636. LIST_FOR_EACH_ENTRY( curr, &screen_buffer_list, struct screen_buffer, entry )
  637. {
  638. if (curr->input == console) curr->input = NULL;
  639. }
  640. free_async_queue( &console->ioctl_q );
  641. free_async_queue( &console->read_q );
  642. if (console->fd)
  643. release_object( console->fd );
  644. }
  645. static struct object *create_console_connection( struct console *console )
  646. {
  647. struct console_connection *connection;
  648. if (current->process->console)
  649. {
  650. set_error( STATUS_ACCESS_DENIED );
  651. return NULL;
  652. }
  653. if (!(connection = alloc_object( &console_connection_ops ))) return NULL;
  654. if (!(connection->fd = alloc_pseudo_fd( &console_connection_fd_ops, &connection->obj, 0 )))
  655. {
  656. release_object( connection );
  657. return NULL;
  658. }
  659. if (console)
  660. current->process->console = (struct console *)grab_object( console );
  661. return &connection->obj;
  662. }
  663. static struct object *console_lookup_name( struct object *obj, struct unicode_str *name,
  664. unsigned int attr, struct object *root )
  665. {
  666. struct console *console = (struct console *)obj;
  667. static const WCHAR connectionW[] = {'C','o','n','n','e','c','t','i','o','n'};
  668. assert( obj->ops == &console_ops );
  669. if (name->len == sizeof(connectionW) && !memcmp( name->str, connectionW, name->len ))
  670. {
  671. name->len = 0;
  672. return create_console_connection( console );
  673. }
  674. return NULL;
  675. }
  676. static struct object *console_open_file( struct object *obj, unsigned int access,
  677. unsigned int sharing, unsigned int options )
  678. {
  679. return grab_object( obj );
  680. }
  681. static void screen_buffer_dump( struct object *obj, int verbose )
  682. {
  683. struct screen_buffer *screen_buffer = (struct screen_buffer *)obj;
  684. assert( obj->ops == &screen_buffer_ops );
  685. fprintf(stderr, "Console screen buffer input=%p\n", screen_buffer->input );
  686. }
  687. static void screen_buffer_destroy( struct object *obj )
  688. {
  689. struct screen_buffer *screen_buffer = (struct screen_buffer *)obj;
  690. assert( obj->ops == &screen_buffer_ops );
  691. list_remove( &screen_buffer->entry );
  692. if (screen_buffer->input && screen_buffer->input->server)
  693. queue_host_ioctl( screen_buffer->input->server, IOCTL_CONDRV_CLOSE_OUTPUT,
  694. screen_buffer->id, NULL, NULL );
  695. if (screen_buffer->fd) release_object( screen_buffer->fd );
  696. free_async_queue( &screen_buffer->ioctl_q );
  697. }
  698. static struct object *screen_buffer_open_file( struct object *obj, unsigned int access,
  699. unsigned int sharing, unsigned int options )
  700. {
  701. return grab_object( obj );
  702. }
  703. static int screen_buffer_add_queue( struct object *obj, struct wait_queue_entry *entry )
  704. {
  705. struct screen_buffer *screen_buffer = (struct screen_buffer*)obj;
  706. if (!screen_buffer->input)
  707. {
  708. set_error( STATUS_ACCESS_DENIED );
  709. return 0;
  710. }
  711. return add_queue( &screen_buffer->input->obj, entry );
  712. }
  713. static struct fd *screen_buffer_get_fd( struct object *obj )
  714. {
  715. struct screen_buffer *screen_buffer = (struct screen_buffer*)obj;
  716. assert( obj->ops == &screen_buffer_ops );
  717. if (screen_buffer->fd)
  718. return (struct fd*)grab_object( screen_buffer->fd );
  719. set_error( STATUS_OBJECT_TYPE_MISMATCH );
  720. return NULL;
  721. }
  722. static void console_server_dump( struct object *obj, int verbose )
  723. {
  724. assert( obj->ops == &console_server_ops );
  725. fprintf( stderr, "Console server\n" );
  726. }
  727. static void console_server_destroy( struct object *obj )
  728. {
  729. struct console_server *server = (struct console_server *)obj;
  730. assert( obj->ops == &console_server_ops );
  731. disconnect_console_server( server );
  732. if (server->fd) release_object( server->fd );
  733. }
  734. static struct object *console_server_lookup_name( struct object *obj, struct unicode_str *name,
  735. unsigned int attr, struct object *root )
  736. {
  737. struct console_server *server = (struct console_server*)obj;
  738. static const WCHAR referenceW[] = {'R','e','f','e','r','e','n','c','e'};
  739. assert( obj->ops == &console_server_ops );
  740. if (name->len == sizeof(referenceW) && !memcmp( name->str, referenceW, name->len ))
  741. {
  742. struct screen_buffer *screen_buffer;
  743. name->len = 0;
  744. if (server->console)
  745. {
  746. set_error( STATUS_INVALID_HANDLE );
  747. return 0;
  748. }
  749. if (!(server->console = (struct console *)create_console())) return NULL;
  750. if (!(screen_buffer = (struct screen_buffer *)create_screen_buffer( server->console )))
  751. {
  752. release_object( server->console );
  753. server->console = NULL;
  754. return NULL;
  755. }
  756. release_object( screen_buffer );
  757. server->console->server = server;
  758. return &server->console->obj;
  759. }
  760. return NULL;
  761. }
  762. static int console_server_signaled( struct object *obj, struct wait_queue_entry *entry )
  763. {
  764. struct console_server *server = (struct console_server*)obj;
  765. assert( obj->ops == &console_server_ops );
  766. return !server->console || !list_empty( &server->queue );
  767. }
  768. static struct fd *console_server_get_fd( struct object* obj )
  769. {
  770. struct console_server *server = (struct console_server*)obj;
  771. assert( obj->ops == &console_server_ops );
  772. return (struct fd *)grab_object( server->fd );
  773. }
  774. static struct object *console_server_open_file( struct object *obj, unsigned int access,
  775. unsigned int sharing, unsigned int options )
  776. {
  777. return grab_object( obj );
  778. }
  779. static struct object *create_console_server( void )
  780. {
  781. struct console_server *server;
  782. if (!(server = alloc_object( &console_server_ops ))) return NULL;
  783. server->console = NULL;
  784. server->busy = 0;
  785. server->term_fd = -1;
  786. list_init( &server->queue );
  787. list_init( &server->read_queue );
  788. server->fd = alloc_pseudo_fd( &console_server_fd_ops, &server->obj, FILE_SYNCHRONOUS_IO_NONALERT );
  789. if (!server->fd)
  790. {
  791. release_object( server );
  792. return NULL;
  793. }
  794. allow_fd_caching(server->fd);
  795. return &server->obj;
  796. }
  797. static int is_blocking_read_ioctl( unsigned int code )
  798. {
  799. switch (code)
  800. {
  801. case IOCTL_CONDRV_READ_INPUT:
  802. case IOCTL_CONDRV_READ_CONSOLE:
  803. case IOCTL_CONDRV_READ_FILE:
  804. return 1;
  805. default:
  806. return 0;
  807. }
  808. }
  809. static int console_ioctl( struct fd *fd, ioctl_code_t code, struct async *async )
  810. {
  811. struct console *console = get_fd_user( fd );
  812. switch (code)
  813. {
  814. case IOCTL_CONDRV_CTRL_EVENT:
  815. {
  816. const struct condrv_ctrl_event *event = get_req_data();
  817. process_id_t group;
  818. if (get_req_data_size() != sizeof(*event))
  819. {
  820. set_error( STATUS_INVALID_PARAMETER );
  821. return 0;
  822. }
  823. group = event->group_id ? event->group_id : current->process->group_id;
  824. if (!group)
  825. {
  826. set_error( STATUS_INVALID_PARAMETER );
  827. return 0;
  828. }
  829. propagate_console_signal( console, event->event, group );
  830. return !get_error();
  831. }
  832. default:
  833. if (!console->server || code >> 16 != FILE_DEVICE_CONSOLE)
  834. {
  835. set_error( STATUS_INVALID_HANDLE );
  836. return 0;
  837. }
  838. return queue_host_ioctl( console->server, code, 0, async, &console->ioctl_q );
  839. }
  840. }
  841. static int console_read( struct fd *fd, struct async *async, file_pos_t pos )
  842. {
  843. struct console *console = get_fd_user( fd );
  844. if (!console->server)
  845. {
  846. set_error( STATUS_INVALID_HANDLE );
  847. return 0;
  848. }
  849. return queue_host_ioctl( console->server, IOCTL_CONDRV_READ_FILE, 0, async, &console->ioctl_q );
  850. }
  851. static int console_flush( struct fd *fd, struct async *async )
  852. {
  853. struct console *console = get_fd_user( fd );
  854. if (!console->server)
  855. {
  856. set_error( STATUS_INVALID_HANDLE );
  857. return 0;
  858. }
  859. return queue_host_ioctl( console->server, IOCTL_CONDRV_FLUSH, 0, NULL, NULL );
  860. }
  861. static int screen_buffer_write( struct fd *fd, struct async *async, file_pos_t pos )
  862. {
  863. struct screen_buffer *screen_buffer = get_fd_user( fd );
  864. struct iosb *iosb;
  865. if (!screen_buffer->input || !screen_buffer->input->server)
  866. {
  867. set_error( STATUS_INVALID_HANDLE );
  868. return 0;
  869. }
  870. if (!queue_host_ioctl( screen_buffer->input->server, IOCTL_CONDRV_WRITE_FILE,
  871. screen_buffer->id, async, &screen_buffer->ioctl_q ))
  872. return 0;
  873. /* we can't use default async handling, because write result is not
  874. * compatible with ioctl result */
  875. iosb = async_get_iosb( async );
  876. iosb->result = iosb->in_size;
  877. release_object( iosb );
  878. return 1;
  879. }
  880. static int screen_buffer_ioctl( struct fd *fd, ioctl_code_t code, struct async *async )
  881. {
  882. struct screen_buffer *screen_buffer = get_fd_user( fd );
  883. switch (code)
  884. {
  885. case IOCTL_CONDRV_ACTIVATE:
  886. if (!screen_buffer->input)
  887. {
  888. set_error( STATUS_INVALID_HANDLE );
  889. return 0;
  890. }
  891. set_active_screen_buffer( screen_buffer->input, screen_buffer );
  892. return 1;
  893. default:
  894. if (!screen_buffer->input || !screen_buffer->input->server || code >> 16 != FILE_DEVICE_CONSOLE ||
  895. is_blocking_read_ioctl( code ))
  896. {
  897. set_error( STATUS_INVALID_HANDLE );
  898. return 0;
  899. }
  900. return queue_host_ioctl( screen_buffer->input->server, code, screen_buffer->id,
  901. async, &screen_buffer->ioctl_q );
  902. }
  903. }
  904. static int console_connection_ioctl( struct fd *fd, ioctl_code_t code, struct async *async )
  905. {
  906. struct console_connection *console_connection = get_fd_user( fd );
  907. switch (code)
  908. {
  909. case IOCTL_CONDRV_BIND_PID:
  910. {
  911. struct process *process;
  912. unsigned int pid;
  913. if (get_req_data_size() != sizeof(unsigned int))
  914. {
  915. set_error( STATUS_INVALID_PARAMETER );
  916. return 0;
  917. }
  918. if (current->process->console)
  919. {
  920. set_error( STATUS_INVALID_HANDLE );
  921. return 0;
  922. }
  923. pid = *(unsigned int *)get_req_data();
  924. if (pid == ATTACH_PARENT_PROCESS) pid = current->process->parent_id;
  925. if (!(process = get_process_from_id( pid ))) return 0;
  926. if (process->console)
  927. current->process->console = (struct console *)grab_object( process->console );
  928. else set_error( STATUS_ACCESS_DENIED );
  929. release_object( process );
  930. return !get_error();
  931. }
  932. default:
  933. return default_fd_ioctl( console_connection->fd, code, async );
  934. }
  935. }
  936. static int console_server_ioctl( struct fd *fd, ioctl_code_t code, struct async *async )
  937. {
  938. struct console_server *server = get_fd_user( fd );
  939. switch (code)
  940. {
  941. case IOCTL_CONDRV_CTRL_EVENT:
  942. {
  943. const struct condrv_ctrl_event *event = get_req_data();
  944. if (get_req_data_size() != sizeof(*event))
  945. {
  946. set_error( STATUS_INVALID_PARAMETER );
  947. return 0;
  948. }
  949. if (!server->console)
  950. {
  951. set_error( STATUS_INVALID_HANDLE );
  952. return 0;
  953. }
  954. propagate_console_signal( server->console, event->event, event->group_id );
  955. return !get_error();
  956. }
  957. case IOCTL_CONDRV_SETUP_INPUT:
  958. {
  959. struct termios term;
  960. obj_handle_t handle;
  961. struct file *file;
  962. int unix_fd;
  963. if (get_req_data_size() != sizeof(unsigned int) || get_reply_max_size())
  964. {
  965. set_error( STATUS_INVALID_PARAMETER );
  966. return 0;
  967. }
  968. if (server->term_fd != -1)
  969. {
  970. tcsetattr( server->term_fd, TCSANOW, &server->termios );
  971. close( server->term_fd );
  972. server->term_fd = -1;
  973. }
  974. handle = *(unsigned int *)get_req_data();
  975. if (!handle) return 1;
  976. if (!(file = get_file_obj( current->process, handle, FILE_READ_DATA )))
  977. {
  978. return 0;
  979. }
  980. unix_fd = get_file_unix_fd( file );
  981. release_object( file );
  982. if (tcgetattr( unix_fd, &server->termios ))
  983. {
  984. file_set_error();
  985. return 0;
  986. }
  987. term = server->termios;
  988. term.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN);
  989. term.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
  990. term.c_cflag &= ~(CSIZE | PARENB);
  991. term.c_cflag |= CS8;
  992. term.c_cc[VMIN] = 1;
  993. term.c_cc[VTIME] = 0;
  994. if (tcsetattr( unix_fd, TCSANOW, &term ) || (server->term_fd = dup( unix_fd )) == -1)
  995. {
  996. file_set_error();
  997. return 0;
  998. }
  999. return 1;
  1000. }
  1001. default:
  1002. set_error( STATUS_INVALID_HANDLE );
  1003. return 0;
  1004. }
  1005. }
  1006. static void console_connection_dump( struct object *obj, int verbose )
  1007. {
  1008. fputs( "console connection\n", stderr );
  1009. }
  1010. static struct fd *console_connection_get_fd( struct object *obj )
  1011. {
  1012. struct console_connection *connection = (struct console_connection *)obj;
  1013. return (struct fd *)grab_object( connection->fd );
  1014. }
  1015. static struct object *console_connection_lookup_name( struct object *obj, struct unicode_str *name,
  1016. unsigned int attr, struct object *root )
  1017. {
  1018. static const WCHAR referenceW[] = {'R','e','f','e','r','e','n','c','e'};
  1019. if (name->len == sizeof(referenceW) && !memcmp( name->str, referenceW, name->len ))
  1020. {
  1021. if (!current->process->console)
  1022. {
  1023. set_error( STATUS_INVALID_HANDLE );
  1024. return NULL;
  1025. }
  1026. name->len = 0;
  1027. return grab_object( current->process->console );
  1028. }
  1029. return NULL;
  1030. }
  1031. static struct object *console_connection_open_file( struct object *obj, unsigned int access,
  1032. unsigned int sharing, unsigned int options )
  1033. {
  1034. return grab_object( obj );
  1035. }
  1036. static int console_connection_close_handle( struct object *obj, struct process *process, obj_handle_t handle )
  1037. {
  1038. struct console *console = process->console;
  1039. if (console)
  1040. {
  1041. process->console = NULL;
  1042. release_object( console );
  1043. }
  1044. return 1;
  1045. }
  1046. static void console_connection_destroy( struct object *obj )
  1047. {
  1048. struct console_connection *connection = (struct console_connection *)obj;
  1049. if (connection->fd) release_object( connection->fd );
  1050. }
  1051. static void console_device_dump( struct object *obj, int verbose )
  1052. {
  1053. fputs( "Console device\n", stderr );
  1054. }
  1055. static struct object *console_device_lookup_name( struct object *obj, struct unicode_str *name,
  1056. unsigned int attr, struct object *root )
  1057. {
  1058. static const WCHAR connectionW[] = {'C','o','n','n','e','c','t','i','o','n'};
  1059. static const WCHAR consoleW[] = {'C','o','n','s','o','l','e'};
  1060. static const WCHAR current_inW[] = {'C','u','r','r','e','n','t','I','n'};
  1061. static const WCHAR current_outW[] = {'C','u','r','r','e','n','t','O','u','t'};
  1062. static const WCHAR inputW[] = {'I','n','p','u','t'};
  1063. static const WCHAR outputW[] = {'O','u','t','p','u','t'};
  1064. static const WCHAR screen_bufferW[] = {'S','c','r','e','e','n','B','u','f','f','e','r'};
  1065. static const WCHAR serverW[] = {'S','e','r','v','e','r'};
  1066. if (name->len == sizeof(current_inW) && !memcmp( name->str, current_inW, name->len ))
  1067. {
  1068. if (!current->process->console)
  1069. {
  1070. set_error( STATUS_INVALID_HANDLE );
  1071. return NULL;
  1072. }
  1073. name->len = 0;
  1074. return grab_object( current->process->console );
  1075. }
  1076. if (name->len == sizeof(current_outW) && !memcmp( name->str, current_outW, name->len ))
  1077. {
  1078. if (!current->process->console || !current->process->console->active)
  1079. {
  1080. set_error( STATUS_INVALID_HANDLE );
  1081. return NULL;
  1082. }
  1083. name->len = 0;
  1084. return grab_object( current->process->console->active );
  1085. }
  1086. if (name->len == sizeof(consoleW) && !memcmp( name->str, consoleW, name->len ))
  1087. {
  1088. name->len = 0;
  1089. return grab_object( obj );
  1090. }
  1091. if (name->len == sizeof(inputW) && !memcmp( name->str, inputW, name->len ))
  1092. {
  1093. struct console_input *console_input;
  1094. name->len = 0;
  1095. if (!(console_input = alloc_object( &console_input_ops ))) return NULL;
  1096. console_input->fd = alloc_pseudo_fd( &console_input_fd_ops, &console_input->obj,
  1097. FILE_SYNCHRONOUS_IO_NONALERT );
  1098. if (!console_input->fd)
  1099. {
  1100. release_object( console_input );
  1101. return NULL;
  1102. }
  1103. return &console_input->obj;
  1104. }
  1105. if (name->len == sizeof(outputW) && !memcmp( name->str, outputW, name->len ))
  1106. {
  1107. struct console_output *console_output;
  1108. name->len = 0;
  1109. if (!(console_output = alloc_object( &console_output_ops ))) return NULL;
  1110. console_output->fd = alloc_pseudo_fd( &console_output_fd_ops, &console_output->obj,
  1111. FILE_SYNCHRONOUS_IO_NONALERT );
  1112. if (!console_output->fd)
  1113. {
  1114. release_object( console_output );
  1115. return NULL;
  1116. }
  1117. return &console_output->obj;
  1118. }
  1119. if (name->len == sizeof(screen_bufferW) && !memcmp( name->str, screen_bufferW, name->len ))
  1120. {
  1121. if (!current->process->console)
  1122. {
  1123. set_error( STATUS_INVALID_HANDLE );
  1124. return NULL;
  1125. }
  1126. name->len = 0;
  1127. return create_screen_buffer( current->process->console );
  1128. }
  1129. if (name->len == sizeof(serverW) && !memcmp( name->str, serverW, name->len ))
  1130. {
  1131. name->len = 0;
  1132. return create_console_server();
  1133. }
  1134. if (name->len == sizeof(connectionW) && !memcmp( name->str, connectionW, name->len ))
  1135. {
  1136. name->len = 0;
  1137. return create_console_connection( NULL );
  1138. }
  1139. return NULL;
  1140. }
  1141. static struct object *console_device_open_file( struct object *obj, unsigned int access,
  1142. unsigned int sharing, unsigned int options )
  1143. {
  1144. int is_output;
  1145. access = default_map_access( obj, access );
  1146. is_output = access & FILE_WRITE_DATA;
  1147. if (!current->process->console || (is_output && !current->process->console))
  1148. {
  1149. set_error( STATUS_INVALID_HANDLE );
  1150. return NULL;
  1151. }
  1152. if (is_output && (access & FILE_READ_DATA))
  1153. {
  1154. set_error( STATUS_INVALID_PARAMETER );
  1155. return NULL;
  1156. }
  1157. return is_output ? grab_object( current->process->console->active ) : grab_object( current->process->console );
  1158. }
  1159. static void console_input_dump( struct object *obj, int verbose )
  1160. {
  1161. fputs( "console Input device\n", stderr );
  1162. }
  1163. static int console_input_add_queue( struct object *obj, struct wait_queue_entry *entry )
  1164. {
  1165. if (!current->process->console)
  1166. {
  1167. set_error( STATUS_ACCESS_DENIED );
  1168. return 0;
  1169. }
  1170. return add_queue( &current->process->console->obj, entry );
  1171. }
  1172. static struct fd *console_input_get_fd( struct object *obj )
  1173. {
  1174. struct console_input *console_input = (struct console_input *)obj;
  1175. assert( obj->ops == &console_input_ops );
  1176. return (struct fd *)grab_object( console_input->fd );
  1177. }
  1178. static struct object *console_input_open_file( struct object *obj, unsigned int access,
  1179. unsigned int sharing, unsigned int options )
  1180. {
  1181. return grab_object( obj );
  1182. }
  1183. static void console_input_destroy( struct object *obj )
  1184. {
  1185. struct console_input *console_input = (struct console_input *)obj;
  1186. assert( obj->ops == &console_input_ops );
  1187. if (console_input->fd) release_object( console_input->fd );
  1188. }
  1189. static int console_input_ioctl( struct fd *fd, ioctl_code_t code, struct async *async )
  1190. {
  1191. struct console *console = current->process->console;
  1192. if (!console)
  1193. {
  1194. set_error( STATUS_INVALID_HANDLE );
  1195. return 0;
  1196. }
  1197. return console_ioctl( console->fd, code, async );
  1198. }
  1199. static int console_input_read( struct fd *fd, struct async *async, file_pos_t pos )
  1200. {
  1201. struct console *console = current->process->console;
  1202. if (!console)
  1203. {
  1204. set_error( STATUS_INVALID_HANDLE );
  1205. return 0;
  1206. }
  1207. return console_read( console->fd, async, pos );
  1208. }
  1209. static int console_input_flush( struct fd *fd, struct async *async )
  1210. {
  1211. struct console *console = current->process->console;
  1212. if (!console)
  1213. {
  1214. set_error( STATUS_INVALID_HANDLE );
  1215. return 0;
  1216. }
  1217. return console_flush( console->fd, async );
  1218. }
  1219. static void console_output_dump( struct object *obj, int verbose )
  1220. {
  1221. fputs( "console Output device\n", stderr );
  1222. }
  1223. static int console_output_add_queue( struct object *obj, struct wait_queue_entry *entry )
  1224. {
  1225. if (!current->process->console || !current->process->console->active)
  1226. {
  1227. set_error( STATUS_ACCESS_DENIED );
  1228. return 0;
  1229. }
  1230. return add_queue( &current->process->console->obj, entry );
  1231. }
  1232. static struct fd *console_output_get_fd( struct object *obj )
  1233. {
  1234. struct console_output *console_output = (struct console_output *)obj;
  1235. assert( obj->ops == &console_output_ops );
  1236. return (struct fd *)grab_object( console_output->fd );
  1237. }
  1238. static struct object *console_output_open_file( struct object *obj, unsigned int access,
  1239. unsigned int sharing, unsigned int options )
  1240. {
  1241. return grab_object( obj );
  1242. }
  1243. static void console_output_destroy( struct object *obj )
  1244. {
  1245. struct console_output *console_output = (struct console_output *)obj;
  1246. assert( obj->ops == &console_output_ops );
  1247. if (console_output->fd) release_object( console_output->fd );
  1248. }
  1249. static int console_output_ioctl( struct fd *fd, ioctl_code_t code, struct async *async )
  1250. {
  1251. struct console *console = current->process->console;
  1252. if (!console || !console->active)
  1253. {
  1254. set_error( STATUS_INVALID_HANDLE );
  1255. return 0;
  1256. }
  1257. return screen_buffer_ioctl( console->active->fd, code, async );
  1258. }
  1259. static int console_output_write( struct fd *fd, struct async *async, file_pos_t pos )
  1260. {
  1261. struct console *console = current->process->console;
  1262. if (!console || !console->active)
  1263. {
  1264. set_error( STATUS_INVALID_HANDLE );
  1265. return 0;
  1266. }
  1267. return screen_buffer_write( console->active->fd, async, pos );
  1268. }
  1269. struct object *create_console_device( struct object *root, const struct unicode_str *name,
  1270. unsigned int attr, const struct security_descriptor *sd )
  1271. {
  1272. return create_named_object( root, &console_device_ops, name, attr, sd );
  1273. }
  1274. /* retrieve the next pending console ioctl request */
  1275. DECL_HANDLER(get_next_console_request)
  1276. {
  1277. struct console_host_ioctl *ioctl = NULL, *next;
  1278. struct console_server *server;
  1279. struct iosb *iosb = NULL;
  1280. server = (struct console_server *)get_handle_obj( current->process, req->handle, 0, &console_server_ops );
  1281. if (!server) return;
  1282. if (!server->console)
  1283. {
  1284. set_error( STATUS_INVALID_HANDLE );
  1285. release_object( server );
  1286. return;
  1287. }
  1288. if (!server->console->renderer) server->console->renderer = current;
  1289. if (!req->signal) server->console->signaled = 0;
  1290. else if (!server->console->signaled)
  1291. {
  1292. server->console->signaled = 1;
  1293. wake_up( &server->console->obj, 0 );
  1294. }
  1295. if (req->read)
  1296. {
  1297. /* set result of current pending ioctl */
  1298. if (list_empty( &server->read_queue ))
  1299. {
  1300. set_error( STATUS_INVALID_HANDLE );
  1301. release_object( server );
  1302. return;
  1303. }
  1304. ioctl = LIST_ENTRY( list_head( &server->read_queue ), struct console_host_ioctl, entry );
  1305. list_remove( &ioctl->entry );
  1306. list_move_tail( &server->queue, &server->read_queue );
  1307. }
  1308. else if (server->busy)
  1309. {
  1310. /* set result of previous ioctl */
  1311. ioctl = LIST_ENTRY( list_head( &server->queue ), struct console_host_ioctl, entry );
  1312. list_remove( &ioctl->entry );
  1313. }
  1314. if (ioctl)
  1315. {
  1316. unsigned int status = req->status;
  1317. if (status == STATUS_PENDING) status = STATUS_INVALID_PARAMETER;
  1318. if (ioctl->async)
  1319. {
  1320. iosb = async_get_iosb( ioctl->async );
  1321. if (iosb->status == STATUS_PENDING)
  1322. {
  1323. iosb->status = status;
  1324. iosb->out_size = min( iosb->out_size, get_req_data_size() );
  1325. if (iosb->out_size)
  1326. {
  1327. if ((iosb->out_data = memdup( get_req_data(), iosb->out_size )))
  1328. {
  1329. iosb->result = iosb->out_size;
  1330. }
  1331. else if (!status)
  1332. {
  1333. iosb->status = STATUS_NO_MEMORY;
  1334. iosb->out_size = 0;
  1335. }
  1336. }
  1337. if (iosb->result) status = STATUS_ALERTED;
  1338. }
  1339. else
  1340. {
  1341. release_object( ioctl->async );
  1342. ioctl->async = NULL;
  1343. }
  1344. }
  1345. console_host_ioctl_terminate( ioctl, status );
  1346. if (iosb) release_object( iosb );
  1347. if (req->read)
  1348. {
  1349. release_object( server );
  1350. return;
  1351. }
  1352. server->busy = 0;
  1353. }
  1354. /* if we have a blocking read ioctl in queue head and previous blocking read is still waiting,
  1355. * move it to read queue for execution after current read is complete. move all blocking
  1356. * ioctl at the same time to preserve their order. */
  1357. if (!list_empty( &server->queue ) && !list_empty( &server->read_queue ))
  1358. {
  1359. ioctl = LIST_ENTRY( list_head( &server->queue ), struct console_host_ioctl, entry );
  1360. if (is_blocking_read_ioctl( ioctl->code ))
  1361. {
  1362. LIST_FOR_EACH_ENTRY_SAFE( ioctl, next, &server->queue, struct console_host_ioctl, entry )
  1363. {
  1364. if (!is_blocking_read_ioctl( ioctl->code )) continue;
  1365. list_remove( &ioctl->entry );
  1366. list_add_tail( &server->read_queue, &ioctl->entry );
  1367. }
  1368. }
  1369. }
  1370. /* return the next ioctl */
  1371. if (!list_empty( &server->queue ))
  1372. {
  1373. ioctl = LIST_ENTRY( list_head( &server->queue ), struct console_host_ioctl, entry );
  1374. iosb = ioctl->async ? async_get_iosb( ioctl->async ) : NULL;
  1375. if (!iosb || get_reply_max_size() >= iosb->in_size)
  1376. {
  1377. reply->code = ioctl->code;
  1378. reply->output = ioctl->output;
  1379. if (iosb)
  1380. {
  1381. reply->out_size = iosb->out_size;
  1382. set_reply_data_ptr( iosb->in_data, iosb->in_size );
  1383. iosb->in_data = NULL;
  1384. }
  1385. if (is_blocking_read_ioctl( ioctl->code ))
  1386. {
  1387. list_remove( &ioctl->entry );
  1388. assert( list_empty( &server->read_queue ));
  1389. list_add_tail( &server->read_queue, &ioctl->entry );
  1390. }
  1391. else server->busy = 1;
  1392. }
  1393. else
  1394. {
  1395. reply->out_size = iosb->in_size;
  1396. set_error( STATUS_BUFFER_OVERFLOW );
  1397. }
  1398. if (iosb) release_object( iosb );
  1399. }
  1400. else
  1401. {
  1402. set_error( STATUS_PENDING );
  1403. }
  1404. release_object( server );
  1405. }