ReactOS  0.4.14-dev-52-g6116262
handle.c
Go to the documentation of this file.
1 /*
2  * LICENSE: GPL - See COPYING in the top level directory
3  * PROJECT: ReactOS Console Server DLL
4  * FILE: win32ss/user/winsrv/consrv/handle.c
5  * PURPOSE: Console I/O Handles functions
6  * PROGRAMMERS: David Welch
7  * Jeffrey Morlan
8  * Hermes Belusca-Maito (hermes.belusca@sfr.fr)
9  */
10 
11 /* INCLUDES *******************************************************************/
12 
13 #include "consrv.h"
14 
15 #include <win/console.h>
16 
17 #define NDEBUG
18 #include <debug.h>
19 
20 /* GLOBALS ********************************************************************/
21 
22 /* Console handle */
23 typedef struct _CONSOLE_IO_HANDLE
24 {
25  PCONSOLE_IO_OBJECT Object; /* The object on which the handle points to */
30 
31 
32 /* PRIVATE FUNCTIONS **********************************************************/
33 
34 static LONG
36  IN LONG Change)
37 {
39 
40  DPRINT("AdjustHandleCounts(0x%p, %d), Object = 0x%p\n",
41  Handle, Change, Object);
42  DPRINT("\tAdjustHandleCounts(0x%p, %d), Object = 0x%p, Object->ReferenceCount = %d, Object->Type = %lu\n",
43  Handle, Change, Object, Object->ReferenceCount, Object->Type);
44 
45  if (Handle->Access & GENERIC_READ) Object->AccessRead += Change;
46  if (Handle->Access & GENERIC_WRITE) Object->AccessWrite += Change;
47  if (!(Handle->ShareMode & FILE_SHARE_READ)) Object->ExclusiveRead += Change;
48  if (!(Handle->ShareMode & FILE_SHARE_WRITE)) Object->ExclusiveWrite += Change;
49 
50  Object->ReferenceCount += Change;
51 
52  return Object->ReferenceCount;
53 }
54 
55 static VOID
57 {
59  if (Object != NULL)
60  {
61  /*
62  * If this is a input handle, notify and dereference
63  * all the waits related to this handle.
64  */
65  if (Object->Type == INPUT_BUFFER)
66  {
67  // PCONSOLE_INPUT_BUFFER InputBuffer = (PCONSOLE_INPUT_BUFFER)Object;
68  PCONSOLE Console = Object->Console;
69 
70  /*
71  * Wake up all the writing waiters related to this handle for this
72  * input buffer, if any, then dereference them and purge them all
73  * from the list.
74  * To select them amongst all the waiters for this input buffer,
75  * pass the handle pointer to the waiters, then they will check
76  * whether or not they are related to this handle and if so, they
77  * return.
78  */
79  CsrNotifyWait(&Console->ReadWaitQueue,
80  TRUE,
81  NULL,
82  (PVOID)Handle);
83  if (!IsListEmpty(&Console->ReadWaitQueue))
84  {
85  CsrDereferenceWait(&Console->ReadWaitQueue);
86  }
87  }
88 
89  /* If the last handle to a screen buffer is closed, delete it... */
90  if (AdjustHandleCounts(Handle, -1) == 0)
91  {
92  if (Object->Type == TEXTMODE_BUFFER || Object->Type == GRAPHICS_BUFFER)
93  {
95  /* ...unless it's the only buffer left. Windows allows deletion
96  * even of the last buffer, but having to deal with a lack of
97  * any active buffer might be error-prone. */
98  if (Buffer->ListEntry.Flink != Buffer->ListEntry.Blink)
100  }
101  else if (Object->Type == INPUT_BUFFER)
102  {
103  DPRINT("Closing the input buffer\n");
104  }
105  else
106  {
107  DPRINT1("Invalid object type %d\n", Object->Type);
108  }
109  }
110 
111  /* Invalidate (zero-out) this handle entry */
112  // Handle->Object = NULL;
113  // RtlZeroMemory(Handle, sizeof(*Handle));
114  }
115  RtlZeroMemory(Handle, sizeof(*Handle)); // Be sure the whole entry is invalidated.
116 }
117 
118 
119 
120 
121 
122 
123 /* Forward declaration, used in ConSrvInitHandlesTable */
125 
126 static NTSTATUS
129  OUT PHANDLE pInputHandle,
130  OUT PHANDLE pOutputHandle,
131  OUT PHANDLE pErrorHandle)
132 {
136  ErrorHandle = INVALID_HANDLE_VALUE;
137 
138  /*
139  * Initialize the handles table. Use temporary variables to store
140  * the handles values in such a way that, if we fail, we don't
141  * return to the caller invalid handle values.
142  *
143  * Insert the IO handles.
144  */
145 
146  RtlEnterCriticalSection(&ProcessData->HandleTableLock);
147 
148  /* Insert the Input handle */
149  Status = ConSrvInsertObject(ProcessData,
150  &InputHandle,
151  &Console->InputBuffer.Header,
153  TRUE,
155  if (!NT_SUCCESS(Status))
156  {
157  DPRINT1("Failed to insert the input handle\n");
158  RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
159  ConSrvFreeHandlesTable(ProcessData);
160  return Status;
161  }
162 
163  /* Insert the Output handle */
164  Status = ConSrvInsertObject(ProcessData,
165  &OutputHandle,
166  &Console->ActiveBuffer->Header,
168  TRUE,
170  if (!NT_SUCCESS(Status))
171  {
172  DPRINT1("Failed to insert the output handle\n");
173  RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
174  ConSrvFreeHandlesTable(ProcessData);
175  return Status;
176  }
177 
178  /* Insert the Error handle */
179  Status = ConSrvInsertObject(ProcessData,
180  &ErrorHandle,
181  &Console->ActiveBuffer->Header,
183  TRUE,
185  if (!NT_SUCCESS(Status))
186  {
187  DPRINT1("Failed to insert the error handle\n");
188  RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
189  ConSrvFreeHandlesTable(ProcessData);
190  return Status;
191  }
192 
193  /* Return the newly created handles */
194  *pInputHandle = InputHandle;
195  *pOutputHandle = OutputHandle;
196  *pErrorHandle = ErrorHandle;
197 
198  RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
199  return STATUS_SUCCESS;
200 }
201 
202 NTSTATUS
204  IN PCONSOLE_PROCESS_DATA TargetProcessData)
205 {
207  ULONG i, j;
208 
209  RtlEnterCriticalSection(&SourceProcessData->HandleTableLock);
210 
211  /* Inherit a handles table only if there is no already */
212  if (TargetProcessData->HandleTable != NULL /* || TargetProcessData->HandleTableSize != 0 */)
213  {
215  goto Quit;
216  }
217 
218  /* Allocate a new handle table for the child process */
219  TargetProcessData->HandleTable = ConsoleAllocHeap(HEAP_ZERO_MEMORY,
220  SourceProcessData->HandleTableSize
221  * sizeof(CONSOLE_IO_HANDLE));
222  if (TargetProcessData->HandleTable == NULL)
223  {
225  goto Quit;
226  }
227 
228  TargetProcessData->HandleTableSize = SourceProcessData->HandleTableSize;
229 
230  /*
231  * Parse the parent process' handles table and, for each handle,
232  * do a copy of it and reference it, if the handle is inheritable.
233  */
234  for (i = 0, j = 0; i < SourceProcessData->HandleTableSize; i++)
235  {
236  if (SourceProcessData->HandleTable[i].Object != NULL &&
237  SourceProcessData->HandleTable[i].Inheritable)
238  {
239  /*
240  * Copy the handle data and increment the reference count of the
241  * pointed object (via the call to ConSrvCreateHandleEntry == AdjustHandleCounts).
242  */
243  TargetProcessData->HandleTable[j] = SourceProcessData->HandleTable[i];
244  AdjustHandleCounts(&TargetProcessData->HandleTable[j], +1);
245  ++j;
246  }
247  }
248 
249 Quit:
250  RtlLeaveCriticalSection(&SourceProcessData->HandleTableLock);
251  return Status;
252 }
253 
254 static VOID
256 {
257  RtlEnterCriticalSection(&ProcessData->HandleTableLock);
258 
259  if (ProcessData->HandleTable != NULL)
260  {
261  ULONG i;
262 
263  /*
264  * ProcessData->ConsoleHandle is NULL (and the assertion fails) when
265  * ConSrvFreeHandlesTable is called in ConSrvConnect during the
266  * allocation of a new console.
267  */
268  // ASSERT(ProcessData->ConsoleHandle);
269  if (ProcessData->ConsoleHandle != NULL)
270  {
271  /* Close all the console handles */
272  for (i = 0; i < ProcessData->HandleTableSize; i++)
273  {
274  ConSrvCloseHandle(&ProcessData->HandleTable[i]);
275  }
276  }
277  /* Free the handles table memory */
278  ConsoleFreeHeap(ProcessData->HandleTable);
279  ProcessData->HandleTable = NULL;
280  }
281 
282  ProcessData->HandleTableSize = 0;
283 
284  RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
285 }
286 
287 
288 
289 
290 
291 
292 // ConSrvCreateObject
293 VOID
297 {
298  ASSERT(Object);
299  // if (!Object) return;
300 
301  Object->Type = Type;
302  Object->Console = Console;
303  Object->ReferenceCount = 0;
304 
305  Object->AccessRead = Object->AccessWrite = 0;
306  Object->ExclusiveRead = Object->ExclusiveWrite = 0;
307 }
308 
309 NTSTATUS
313  IN ULONG Access,
314  IN BOOLEAN Inheritable,
315  IN ULONG ShareMode)
316 {
317 #define IO_HANDLES_INCREMENT 2 * 3
318 
319  ULONG i = 0;
320  PCONSOLE_IO_HANDLE Block;
321 
322  // NOTE: Commented out because calling code always lock HandleTableLock before.
323  // RtlEnterCriticalSection(&ProcessData->HandleTableLock);
324 
325  ASSERT( (ProcessData->HandleTable == NULL && ProcessData->HandleTableSize == 0) ||
326  (ProcessData->HandleTable != NULL && ProcessData->HandleTableSize != 0) );
327 
328  if (ProcessData->HandleTable)
329  {
330  for (i = 0; i < ProcessData->HandleTableSize; i++)
331  {
332  if (ProcessData->HandleTable[i].Object == NULL)
333  break;
334  }
335  }
336 
337  if (i >= ProcessData->HandleTableSize)
338  {
339  /* Allocate a new handles table */
341  (ProcessData->HandleTableSize +
343  if (Block == NULL)
344  {
345  // RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
346  return STATUS_UNSUCCESSFUL;
347  }
348 
349  /* If we previously had a handles table, free it and use the new one */
350  if (ProcessData->HandleTable)
351  {
352  /* Copy the handles from the old table to the new one */
353  RtlCopyMemory(Block,
354  ProcessData->HandleTable,
355  ProcessData->HandleTableSize * sizeof(CONSOLE_IO_HANDLE));
356  ConsoleFreeHeap(ProcessData->HandleTable);
357  }
358  ProcessData->HandleTable = Block;
359  ProcessData->HandleTableSize += IO_HANDLES_INCREMENT;
360  }
361 
362  ProcessData->HandleTable[i].Object = Object;
363  ProcessData->HandleTable[i].Access = Access;
364  ProcessData->HandleTable[i].Inheritable = Inheritable;
365  ProcessData->HandleTable[i].ShareMode = ShareMode;
366  AdjustHandleCounts(&ProcessData->HandleTable[i], +1);
367  *Handle = ULongToHandle((i << 2) | 0x3);
368 
369  // RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
370 
371  return STATUS_SUCCESS;
372 }
373 
374 NTSTATUS
376  IN HANDLE Handle)
377 {
379 
380  RtlEnterCriticalSection(&ProcessData->HandleTableLock);
381 
382  ASSERT(ProcessData->HandleTable);
383  // ASSERT( (ProcessData->HandleTable == NULL && ProcessData->HandleTableSize == 0) ||
384  // (ProcessData->HandleTable != NULL && ProcessData->HandleTableSize != 0) );
385 
386  if (Index >= ProcessData->HandleTableSize ||
387  ProcessData->HandleTable[Index].Object == NULL)
388  {
389  RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
390  return STATUS_INVALID_HANDLE;
391  }
392 
393  ASSERT(ProcessData->ConsoleHandle);
394  ConSrvCloseHandle(&ProcessData->HandleTable[Index]);
395 
396  RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
397  return STATUS_SUCCESS;
398 }
399 
400 NTSTATUS
402  IN HANDLE Handle,
405  IN ULONG Access,
406  IN BOOLEAN LockConsole,
408 {
409  // NTSTATUS Status;
411  PCONSOLE_IO_HANDLE HandleEntry = NULL;
412  PCONSOLE_IO_OBJECT ObjectEntry = NULL;
413  // PCONSOLE ObjectConsole;
414 
415  ASSERT(Object);
416  if (Entry) *Entry = NULL;
417 
418  DPRINT("ConSrvGetObject -- Object: 0x%x, Handle: 0x%x\n", Object, Handle);
419 
420  RtlEnterCriticalSection(&ProcessData->HandleTableLock);
421 
422  if ( IsConsoleHandle(Handle) &&
423  Index < ProcessData->HandleTableSize )
424  {
425  HandleEntry = &ProcessData->HandleTable[Index];
426  ObjectEntry = HandleEntry->Object;
427  }
428 
429  if ( HandleEntry == NULL ||
430  ObjectEntry == NULL ||
431  (HandleEntry->Access & Access) == 0 ||
432  /*(Type != 0 && ObjectEntry->Type != Type)*/
433  (Type != 0 && (ObjectEntry->Type & Type) == 0) )
434  {
435  DPRINT("ConSrvGetObject -- Invalid handle 0x%x of type %lu with access %lu ; retrieved object 0x%x (handle 0x%x) of type %lu with access %lu\n",
436  Handle, Type, Access, ObjectEntry, HandleEntry, (ObjectEntry ? ObjectEntry->Type : 0), (HandleEntry ? HandleEntry->Access : 0));
437 
438  RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
439  return STATUS_INVALID_HANDLE;
440  }
441 
442  RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
443 
444  // Status = ConSrvGetConsole(ProcessData, &ObjectConsole, LockConsole);
445  // if (NT_SUCCESS(Status))
446  if (ConDrvValidateConsoleUnsafe(ObjectEntry->Console, CONSOLE_RUNNING, LockConsole))
447  {
448  _InterlockedIncrement(&ObjectEntry->Console->ReferenceCount);
449 
450  /* Return the objects to the caller */
451  *Object = ObjectEntry;
452  if (Entry) *Entry = HandleEntry;
453 
454  // RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
455  return STATUS_SUCCESS;
456  }
457  else
458  {
459  // RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
460  return STATUS_INVALID_HANDLE;
461  }
462 }
463 
464 VOID
466  IN BOOLEAN IsConsoleLocked)
467 {
468  ConSrvReleaseConsole(Object->Console, IsConsoleLocked);
469 }
470 
471 
472 
473 NTSTATUS
475  PHANDLE pInputHandle,
476  PHANDLE pOutputHandle,
477  PHANDLE pErrorHandle,
478  PCONSOLE_INIT_INFO ConsoleInitInfo)
479 {
481  HANDLE ConsoleHandle;
483 
484  /*
485  * We are about to create a new console. However when ConSrvNewProcess
486  * was called, we didn't know that we wanted to create a new console and
487  * therefore, we by default inherited the handles table from our parent
488  * process. It's only now that we notice that in fact we do not need
489  * them, because we've created a new console and thus we must use it.
490  *
491  * Therefore, free the handles table so that we can recreate
492  * a new one later on.
493  */
494  ConSrvFreeHandlesTable(ProcessData);
495 
496  /* Initialize a new Console owned by this process */
497  DPRINT("Initialization of console '%S' for process '%S' on desktop '%S'\n",
498  ConsoleInitInfo->ConsoleTitle ? ConsoleInitInfo->ConsoleTitle : L"n/a",
499  ConsoleInitInfo->AppName ? ConsoleInitInfo->AppName : L"n/a",
500  ConsoleInitInfo->Desktop ? ConsoleInitInfo->Desktop : L"n/a");
501  Status = ConSrvInitConsole(&ConsoleHandle,
502  &Console,
503  ConsoleInitInfo,
504  ProcessData->Process);
505  if (!NT_SUCCESS(Status))
506  {
507  DPRINT1("Console initialization failed\n");
508  return Status;
509  }
510 
511  /* Assign the new console handle */
512  ProcessData->ConsoleHandle = ConsoleHandle;
513 
514  /* Initialize the handles table */
515  Status = ConSrvInitHandlesTable(ProcessData,
516  Console,
517  pInputHandle,
518  pOutputHandle,
519  pErrorHandle);
520  if (!NT_SUCCESS(Status))
521  {
522  DPRINT1("Failed to initialize the handles table\n");
524  ProcessData->ConsoleHandle = NULL;
525  return Status;
526  }
527 
528  /* Duplicate the Initialization Events */
530  Console->InitEvents[INIT_SUCCESS],
531  ProcessData->Process->ProcessHandle,
532  &ConsoleInitInfo->ConsoleStartInfo->InitEvents[INIT_SUCCESS],
533  EVENT_ALL_ACCESS, 0, 0);
534  if (!NT_SUCCESS(Status))
535  {
536  DPRINT1("NtDuplicateObject(InitEvents[INIT_SUCCESS]) failed: %lu\n", Status);
537  ConSrvFreeHandlesTable(ProcessData);
539  ProcessData->ConsoleHandle = NULL;
540  return Status;
541  }
542 
544  Console->InitEvents[INIT_FAILURE],
545  ProcessData->Process->ProcessHandle,
546  &ConsoleInitInfo->ConsoleStartInfo->InitEvents[INIT_FAILURE],
547  EVENT_ALL_ACCESS, 0, 0);
548  if (!NT_SUCCESS(Status))
549  {
550  DPRINT1("NtDuplicateObject(InitEvents[INIT_FAILURE]) failed: %lu\n", Status);
552  ConsoleInitInfo->ConsoleStartInfo->InitEvents[INIT_SUCCESS],
554  ConSrvFreeHandlesTable(ProcessData);
556  ProcessData->ConsoleHandle = NULL;
557  return Status;
558  }
559 
560  /* Duplicate the Input Event */
562  Console->InputBuffer.ActiveEvent,
563  ProcessData->Process->ProcessHandle,
564  &ConsoleInitInfo->ConsoleStartInfo->InputWaitHandle,
565  EVENT_ALL_ACCESS, 0, 0);
566  if (!NT_SUCCESS(Status))
567  {
568  DPRINT1("NtDuplicateObject(InputWaitHandle) failed: %lu\n", Status);
570  ConsoleInitInfo->ConsoleStartInfo->InitEvents[INIT_FAILURE],
573  ConsoleInitInfo->ConsoleStartInfo->InitEvents[INIT_SUCCESS],
575  ConSrvFreeHandlesTable(ProcessData);
577  ProcessData->ConsoleHandle = NULL;
578  return Status;
579  }
580 
581  /* Mark the process as having a console */
582  ProcessData->ConsoleApp = TRUE;
583  ProcessData->Process->Flags |= CsrProcessIsConsoleApp;
584 
585  /* Return the console handle to the caller */
586  ConsoleInitInfo->ConsoleStartInfo->ConsoleHandle = ProcessData->ConsoleHandle;
587 
588  /*
589  * Insert the process into the processes list of the console,
590  * and set its foreground priority.
591  */
592  InsertHeadList(&Console->ProcessList, &ProcessData->ConsoleLink);
593  ConSrvSetProcessFocus(ProcessData->Process, Console->HasFocus);
594 
595  /* Add a reference count because the process is tied to the console */
596  _InterlockedIncrement(&Console->ReferenceCount);
597 
598  /* Update the internal info of the terminal */
600 
601  return STATUS_SUCCESS;
602 }
603 
604 NTSTATUS
606  HANDLE ConsoleHandle,
607  BOOLEAN CreateNewHandlesTable,
608  PHANDLE pInputHandle,
609  PHANDLE pOutputHandle,
610  PHANDLE pErrorHandle,
611  PCONSOLE_START_INFO ConsoleStartInfo)
612 {
615 
616  /* Validate and lock the console */
618  ConsoleHandle,
620  {
621  // FIXME: Find another status code
622  return STATUS_UNSUCCESSFUL;
623  }
624 
625  /* Inherit the console */
626  ProcessData->ConsoleHandle = ConsoleHandle;
627 
628  if (CreateNewHandlesTable)
629  {
630  /*
631  * We are about to create a new console. However when ConSrvNewProcess
632  * was called, we didn't know that we wanted to create a new console and
633  * therefore, we by default inherited the handles table from our parent
634  * process. It's only now that we notice that in fact we do not need
635  * them, because we've created a new console and thus we must use it.
636  *
637  * Therefore, free the handles table so that we can recreate
638  * a new one later on.
639  */
640  ConSrvFreeHandlesTable(ProcessData);
641 
642  /* Initialize the handles table */
643  Status = ConSrvInitHandlesTable(ProcessData,
644  Console,
645  pInputHandle,
646  pOutputHandle,
647  pErrorHandle);
648  if (!NT_SUCCESS(Status))
649  {
650  DPRINT1("Failed to initialize the handles table\n");
651  ProcessData->ConsoleHandle = NULL;
652  goto Quit;
653  }
654  }
655 
656  /* Duplicate the Initialization Events */
658  Console->InitEvents[INIT_SUCCESS],
659  ProcessData->Process->ProcessHandle,
660  &ConsoleStartInfo->InitEvents[INIT_SUCCESS],
661  EVENT_ALL_ACCESS, 0, 0);
662  if (!NT_SUCCESS(Status))
663  {
664  DPRINT1("NtDuplicateObject(InitEvents[INIT_SUCCESS]) failed: %lu\n", Status);
665  ConSrvFreeHandlesTable(ProcessData);
666  ProcessData->ConsoleHandle = NULL;
667  goto Quit;
668  }
669 
671  Console->InitEvents[INIT_FAILURE],
672  ProcessData->Process->ProcessHandle,
673  &ConsoleStartInfo->InitEvents[INIT_FAILURE],
674  EVENT_ALL_ACCESS, 0, 0);
675  if (!NT_SUCCESS(Status))
676  {
677  DPRINT1("NtDuplicateObject(InitEvents[INIT_FAILURE]) failed: %lu\n", Status);
679  ConsoleStartInfo->InitEvents[INIT_SUCCESS],
681  ConSrvFreeHandlesTable(ProcessData);
682  ProcessData->ConsoleHandle = NULL;
683  goto Quit;
684  }
685 
686  /* Duplicate the Input Event */
688  Console->InputBuffer.ActiveEvent,
689  ProcessData->Process->ProcessHandle,
690  &ConsoleStartInfo->InputWaitHandle,
691  EVENT_ALL_ACCESS, 0, 0);
692  if (!NT_SUCCESS(Status))
693  {
694  DPRINT1("NtDuplicateObject(InputWaitHandle) failed: %lu\n", Status);
696  ConsoleStartInfo->InitEvents[INIT_FAILURE],
699  ConsoleStartInfo->InitEvents[INIT_SUCCESS],
701  ConSrvFreeHandlesTable(ProcessData); // NOTE: Always free the handles table.
702  ProcessData->ConsoleHandle = NULL;
703  goto Quit;
704  }
705 
706  /* Mark the process as having a console */
707  ProcessData->ConsoleApp = TRUE;
708  ProcessData->Process->Flags |= CsrProcessIsConsoleApp;
709 
710  /* Return the console handle to the caller */
711  ConsoleStartInfo->ConsoleHandle = ProcessData->ConsoleHandle;
712 
713  /*
714  * Insert the process into the processes list of the console,
715  * and set its foreground priority.
716  */
717  InsertHeadList(&Console->ProcessList, &ProcessData->ConsoleLink);
718  ConSrvSetProcessFocus(ProcessData->Process, Console->HasFocus);
719 
720  /* Add a reference count because the process is tied to the console */
721  _InterlockedIncrement(&Console->ReferenceCount);
722 
723  /* Update the internal info of the terminal */
725 
727 
728 Quit:
729  /* Unlock the console and return */
731  return Status;
732 }
733 
734 NTSTATUS
736 {
738  PCONSOLE_PROCESS_DATA ConsoleLeaderProcess;
739 
740  DPRINT("ConSrvRemoveConsole\n");
741 
742  /* Mark the process as not having a console anymore */
743  ProcessData->ConsoleApp = FALSE;
744  ProcessData->Process->Flags &= ~CsrProcessIsConsoleApp;
745 
746  /* Validate and lock the console */
748  ProcessData->ConsoleHandle,
750  {
751  // FIXME: Find another status code
752  return STATUS_UNSUCCESSFUL;
753  }
754 
755  DPRINT("ConSrvRemoveConsole - Locking OK\n");
756 
757  /* Retrieve the console leader process */
758  ConsoleLeaderProcess = ConSrvGetConsoleLeaderProcess(Console);
759 
760  /* Close all console handles and free the handles table */
761  ConSrvFreeHandlesTable(ProcessData);
762 
763  /* Detach the process from the console */
764  ProcessData->ConsoleHandle = NULL;
765 
766  /* Remove the process from the console's list of processes */
767  RemoveEntryList(&ProcessData->ConsoleLink);
768 
769  /* Check whether the console should send a last close notification */
770  if (Console->NotifyLastClose)
771  {
772  /* If we are removing the process which wants the last close notification... */
773  if (ProcessData == Console->NotifiedLastCloseProcess)
774  {
775  /* ... just reset the flag and the pointer... */
776  Console->NotifyLastClose = FALSE;
777  Console->NotifiedLastCloseProcess = NULL;
778  }
779  /*
780  * ... otherwise, if we are removing the console leader process
781  * (that cannot be the process wanting the notification, because
782  * the previous case already dealt with it)...
783  */
784  else if (ProcessData == ConsoleLeaderProcess)
785  {
786  /*
787  * ... reset the flag first (so that we avoid multiple notifications)
788  * and then send the last close notification.
789  */
790  Console->NotifyLastClose = FALSE;
791  ConSrvConsoleCtrlEvent(CTRL_LAST_CLOSE_EVENT, Console->NotifiedLastCloseProcess);
792 
793  /* Only now, reset the pointer */
794  Console->NotifiedLastCloseProcess = NULL;
795  }
796  }
797 
798  /* Update the internal info of the terminal */
800 
801  /* Release the console */
802  DPRINT("ConSrvRemoveConsole - Decrement Console->ReferenceCount = %lu\n", Console->ReferenceCount);
804 
805  return STATUS_SUCCESS;
806 }
807 
808 
809 /* PUBLIC SERVER APIS *********************************************************/
810 
811 CSR_API(SrvOpenConsole)
812 {
813  /*
814  * This API opens a handle to either the input buffer or to
815  * a screen-buffer of the console of the current process.
816  */
817 
819  PCONSOLE_OPENCONSOLE OpenConsoleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.OpenConsoleRequest;
822 
823  DWORD DesiredAccess = OpenConsoleRequest->DesiredAccess;
824  DWORD ShareMode = OpenConsoleRequest->ShareMode;
826 
827  OpenConsoleRequest->Handle = INVALID_HANDLE_VALUE;
828 
829  Status = ConSrvGetConsole(ProcessData, &Console, TRUE);
830  if (!NT_SUCCESS(Status))
831  {
832  DPRINT1("Can't get console, status %lx\n", Status);
833  return Status;
834  }
835 
837 
838  /*
839  * Open a handle to either the active screen buffer or the input buffer.
840  */
841  if (OpenConsoleRequest->HandleType == HANDLE_OUTPUT)
842  {
843  Object = &Console->ActiveBuffer->Header;
844  }
845  else // HANDLE_INPUT
846  {
847  Object = &Console->InputBuffer.Header;
848  }
849 
850  if (((DesiredAccess & GENERIC_READ) && Object->ExclusiveRead != 0) ||
851  ((DesiredAccess & GENERIC_WRITE) && Object->ExclusiveWrite != 0) ||
852  (!(ShareMode & FILE_SHARE_READ) && Object->AccessRead != 0) ||
853  (!(ShareMode & FILE_SHARE_WRITE) && Object->AccessWrite != 0))
854  {
855  DPRINT1("Sharing violation\n");
857  }
858  else
859  {
860  Status = ConSrvInsertObject(ProcessData,
861  &OpenConsoleRequest->Handle,
862  Object,
864  OpenConsoleRequest->InheritHandle,
865  ShareMode);
866  }
867 
869 
871  return Status;
872 }
873 
874 CSR_API(SrvDuplicateHandle)
875 {
877  PCONSOLE_DUPLICATEHANDLE DuplicateHandleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.DuplicateHandleRequest;
880 
881  HANDLE SourceHandle = DuplicateHandleRequest->SourceHandle;
885 
886  DuplicateHandleRequest->TargetHandle = INVALID_HANDLE_VALUE;
887 
888  Status = ConSrvGetConsole(ProcessData, &Console, TRUE);
889  if (!NT_SUCCESS(Status))
890  {
891  DPRINT1("Can't get console, status %lx\n", Status);
892  return Status;
893  }
894 
896 
897  // ASSERT( (ProcessData->HandleTable == NULL && ProcessData->HandleTableSize == 0) ||
898  // (ProcessData->HandleTable != NULL && ProcessData->HandleTableSize != 0) );
899 
900  if (
901  Index >= ProcessData->HandleTableSize ||
902  (Entry = &ProcessData->HandleTable[Index])->Object == NULL)
903  {
904  DPRINT1("Couldn't duplicate invalid handle 0x%p\n", SourceHandle);
906  goto Quit;
907  }
908 
909  if (DuplicateHandleRequest->Options & DUPLICATE_SAME_ACCESS)
910  {
911  DesiredAccess = Entry->Access;
912  }
913  else
914  {
915  DesiredAccess = DuplicateHandleRequest->DesiredAccess;
916  /* Make sure the source handle has all the desired flags */
917  if ((Entry->Access & DesiredAccess) == 0)
918  {
919  DPRINT1("Handle 0x%p only has access %X; requested %X\n",
920  SourceHandle, Entry->Access, DesiredAccess);
922  goto Quit;
923  }
924  }
925 
926  /* Insert the new handle inside the process handles table */
927  Status = ConSrvInsertObject(ProcessData,
928  &DuplicateHandleRequest->TargetHandle,
929  Entry->Object,
931  DuplicateHandleRequest->InheritHandle,
932  Entry->ShareMode);
933  if (NT_SUCCESS(Status) &&
934  (DuplicateHandleRequest->Options & DUPLICATE_CLOSE_SOURCE))
935  {
936  /* Close the original handle if needed */
938  }
939 
940 Quit:
942 
944  return Status;
945 }
946 
947 CSR_API(SrvGetHandleInformation)
948 {
950  PCONSOLE_GETHANDLEINFO GetHandleInfoRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetHandleInfoRequest;
953 
954  HANDLE Handle = GetHandleInfoRequest->Handle;
957 
958  Status = ConSrvGetConsole(ProcessData, &Console, TRUE);
959  if (!NT_SUCCESS(Status))
960  {
961  DPRINT1("Can't get console, status %lx\n", Status);
962  return Status;
963  }
964 
966 
967  ASSERT(ProcessData->HandleTable);
968  // ASSERT( (ProcessData->HandleTable == NULL && ProcessData->HandleTableSize == 0) ||
969  // (ProcessData->HandleTable != NULL && ProcessData->HandleTableSize != 0) );
970 
971  if (!IsConsoleHandle(Handle) ||
972  Index >= ProcessData->HandleTableSize ||
973  (Entry = &ProcessData->HandleTable[Index])->Object == NULL)
974  {
976  goto Quit;
977  }
978 
979  /*
980  * Retrieve the handle information flags. The console server
981  * doesn't support HANDLE_FLAG_PROTECT_FROM_CLOSE.
982  */
983  GetHandleInfoRequest->Flags = 0;
984  if (Entry->Inheritable) GetHandleInfoRequest->Flags |= HANDLE_FLAG_INHERIT;
985 
987 
988 Quit:
990 
992  return Status;
993 }
994 
995 CSR_API(SrvSetHandleInformation)
996 {
998  PCONSOLE_SETHANDLEINFO SetHandleInfoRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetHandleInfoRequest;
1000  PCONSOLE Console;
1001 
1002  HANDLE Handle = SetHandleInfoRequest->Handle;
1003  ULONG Index = HandleToULong(Handle) >> 2;
1005 
1006  Status = ConSrvGetConsole(ProcessData, &Console, TRUE);
1007  if (!NT_SUCCESS(Status))
1008  {
1009  DPRINT1("Can't get console, status %lx\n", Status);
1010  return Status;
1011  }
1012 
1014 
1015  ASSERT(ProcessData->HandleTable);
1016  // ASSERT( (ProcessData->HandleTable == NULL && ProcessData->HandleTableSize == 0) ||
1017  // (ProcessData->HandleTable != NULL && ProcessData->HandleTableSize != 0) );
1018 
1019  if (!IsConsoleHandle(Handle) ||
1020  Index >= ProcessData->HandleTableSize ||
1021  (Entry = &ProcessData->HandleTable[Index])->Object == NULL)
1022  {
1024  goto Quit;
1025  }
1026 
1027  /*
1028  * Modify the handle information flags. The console server
1029  * doesn't support HANDLE_FLAG_PROTECT_FROM_CLOSE.
1030  */
1031  if (SetHandleInfoRequest->Mask & HANDLE_FLAG_INHERIT)
1032  {
1033  Entry->Inheritable = ((SetHandleInfoRequest->Flags & HANDLE_FLAG_INHERIT) != 0);
1034  }
1035 
1037 
1038 Quit:
1040 
1042  return Status;
1043 }
1044 
1045 CSR_API(SrvCloseHandle)
1046 {
1047  NTSTATUS Status;
1048  PCONSOLE_CLOSEHANDLE CloseHandleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.CloseHandleRequest;
1050  PCONSOLE Console;
1051 
1052  Status = ConSrvGetConsole(ProcessData, &Console, TRUE);
1053  if (!NT_SUCCESS(Status))
1054  {
1055  DPRINT1("Can't get console, status %lx\n", Status);
1056  return Status;
1057  }
1058 
1059  Status = ConSrvRemoveObject(ProcessData, CloseHandleRequest->Handle);
1060 
1062  return Status;
1063 }
1064 
1065 CSR_API(SrvVerifyConsoleIoHandle)
1066 {
1067  NTSTATUS Status;
1068  PCONSOLE_VERIFYHANDLE VerifyHandleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.VerifyHandleRequest;
1070  PCONSOLE Console;
1071 
1072  HANDLE IoHandle = VerifyHandleRequest->Handle;
1073  ULONG Index = HandleToULong(IoHandle) >> 2;
1074 
1075  VerifyHandleRequest->IsValid = FALSE;
1076 
1077  Status = ConSrvGetConsole(ProcessData, &Console, TRUE);
1078  if (!NT_SUCCESS(Status))
1079  {
1080  DPRINT1("Can't get console, status %lx\n", Status);
1081  return Status;
1082  }
1083 
1085 
1086  // ASSERT( (ProcessData->HandleTable == NULL && ProcessData->HandleTableSize == 0) ||
1087  // (ProcessData->HandleTable != NULL && ProcessData->HandleTableSize != 0) );
1088 
1089  if (!IsConsoleHandle(IoHandle) ||
1090  Index >= ProcessData->HandleTableSize ||
1091  ProcessData->HandleTable[Index].Object == NULL)
1092  {
1093  DPRINT("SrvVerifyConsoleIoHandle failed\n");
1094  }
1095  else
1096  {
1097  VerifyHandleRequest->IsValid = TRUE;
1098  }
1099 
1101 
1103  return STATUS_SUCCESS;
1104 }
1105 
1106 /* EOF */
PCONSOLE_PROCESS_DATA NTAPI ConSrvGetConsoleLeaderProcess(IN PCONSRV_CONSOLE Console)
Definition: console.c:867
HANDLE ConsoleHandle
Definition: consrv.h:45
PWCHAR Desktop
Definition: console.h:19
PCONSOLE_START_INFO ConsoleStartInfo
Definition: console.h:13
#define IN
Definition: typedefs.h:38
#define DUPLICATE_CLOSE_SOURCE
#define ULongToHandle(h)
Definition: basetsd.h:81
NTSTATUS ConSrvGetConsole(IN PCONSOLE_PROCESS_DATA ProcessData, OUT PCONSRV_CONSOLE *Console, IN BOOLEAN LockConsole)
Definition: console.c:271
#define CsrGetClientThread()
Definition: csrsrv.h:77
CONSOLE_HANDLE_TYPE HandleType
Definition: conmsg.h:674
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
struct _CONSOLE * Console
Definition: conio.h:52
static NTSTATUS ConSrvInitHandlesTable(IN OUT PCONSOLE_PROCESS_DATA ProcessData, IN PCONSOLE Console, OUT PHANDLE pInputHandle, OUT PHANDLE pOutputHandle, OUT PHANDLE pErrorHandle)
Definition: handle.c:127
HANDLE OutputHandle
Definition: apc.c:8
VOID NTAPI ConDrvDeleteScreenBuffer(PCONSOLE_SCREEN_BUFFER Buffer)
Definition: conoutput.c:123
Type
Definition: Type.h:6
struct _Entry Entry
Definition: kefuncs.h:640
static LONG AdjustHandleCounts(IN PCONSOLE_IO_HANDLE Handle, IN LONG Change)
Definition: handle.c:35
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PLIST_ENTRY Entry)
Definition: rtlfuncs.h:201
struct _CONSOLE_API_MESSAGE * PCONSOLE_API_MESSAGE
LONG NTSTATUS
Definition: precomp.h:26
HANDLE InitEvents[MAX_INIT_EVENTS]
Definition: conmsg.h:175
#define ConsoleAllocHeap(Flags, Size)
Definition: heap.h:14
NTSYSAPI NTSTATUS NTAPI RtlEnterCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
#define INVALID_HANDLE_VALUE
Definition: compat.h:391
#define HandleToULong(h)
Definition: basetsd.h:95
NTSTATUS ConSrvConsoleCtrlEvent(IN ULONG CtrlEvent, IN PCONSOLE_PROCESS_DATA ProcessData)
Definition: console.c:860
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
_In_ HANDLE SourceHandle
Definition: obfuncs.h:429
#define TEXTMODE_BUFFER
Definition: pccons.c:21
#define PCONSRV_CONSOLE
Definition: conio.h:27
VOID ConSrvReleaseConsole(IN PCONSRV_CONSOLE Console, IN BOOLEAN IsConsoleLocked)
Definition: console.c:296
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
BOOLEAN NTAPI CsrNotifyWait(IN PLIST_ENTRY WaitList, IN BOOLEAN NotifyAll, IN PVOID WaitArgument1, IN PVOID WaitArgument2)
Definition: wait.c:388
NTSTATUS ConSrvInheritConsole(PCONSOLE_PROCESS_DATA ProcessData, HANDLE ConsoleHandle, BOOLEAN CreateNewHandlesTable, PHANDLE pInputHandle, PHANDLE pOutputHandle, PHANDLE pErrorHandle, PCONSOLE_START_INFO ConsoleStartInfo)
Definition: handle.c:605
NTSTATUS ConSrvRemoveObject(IN PCONSOLE_PROCESS_DATA ProcessData, IN HANDLE Handle)
Definition: handle.c:375
#define STATUS_INVALID_HANDLE
Definition: ntstatus.h:231
#define FILE_SHARE_READ
Definition: compat.h:125
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
PWCHAR AppName
Definition: console.h:21
LIST_ENTRY ConsoleLink
Definition: consrv.h:42
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
long __cdecl _InterlockedIncrement(_Interlocked_operand_ long volatile *_Addend)
#define DUPLICATE_SAME_ACCESS
#define STATUS_SHARING_VIOLATION
Definition: udferr_usr.h:154
long LONG
Definition: pedump.c:60
NTSYSAPI NTSTATUS NTAPI RtlLeaveCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
#define EVENT_ALL_ACCESS
Definition: isotest.c:82
#define GENERIC_WRITE
Definition: nt_native.h:90
NTSTATUS ConSrvRemoveConsole(PCONSOLE_PROCESS_DATA ProcessData)
Definition: handle.c:735
HANDLE ProcessHandle
Definition: csrsrv.h:46
struct _CONSOLE_SCREEN_BUFFER * PCONSOLE_SCREEN_BUFFER
Definition: conio.h:70
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
struct _CONSOLE_IO_HANDLE CONSOLE_IO_HANDLE
void DPRINT(...)
Definition: polytest.cpp:61
#define HANDLE_FLAG_INHERIT
Definition: winbase.h:261
Definition: bufpool.h:45
#define NtCurrentProcess()
Definition: nt_native.h:1657
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
BOOLEAN NTAPI ConSrvValidateConsole(OUT PCONSRV_CONSOLE *Console, IN HANDLE ConsoleHandle, IN CONSOLE_STATE ExpectedState, IN BOOLEAN LockConsole)
Definition: console.c:167
_In_ HANDLE Handle
Definition: extypes.h:390
PWCHAR ConsoleTitle
Definition: console.h:17
ULONG ShareMode
Definition: handle.c:27
NTSTATUS NTAPI ConSrvInitConsole(OUT PHANDLE NewConsoleHandle, OUT PCONSRV_CONSOLE *NewConsole, IN OUT PCONSOLE_INIT_INFO ConsoleInitInfo, IN PCSR_PROCESS ConsoleLeaderProcess)
Definition: console.c:511
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ConsoleGetPerProcessData(Process)
Definition: consrv.h:37
PCONSOLE_IO_OBJECT Object
Definition: handle.c:25
BOOLEAN ConsoleApp
Definition: consrv.h:46
HANDLE ConsoleHandle
Definition: conmsg.h:170
static const UCHAR Index[8]
Definition: usbohci.c:18
unsigned long DWORD
Definition: ntddk_ex.h:95
PCSR_PROCESS Process
Definition: consrv.h:43
#define IsConsoleHandle(h)
Definition: console.h:14
static IUnknown Object
Definition: main.c:512
VOID NTAPI CsrDereferenceWait(IN PLIST_ENTRY WaitList)
Definition: wait.c:266
#define IO_HANDLES_INCREMENT
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
static const WCHAR L[]
Definition: oid.c:1250
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:414
#define GENERIC_READ
Definition: compat.h:124
VOID ConSrvInitObject(IN OUT PCONSOLE_IO_OBJECT Object, IN CONSOLE_IO_OBJECT_TYPE Type, IN PCONSOLE Console)
Definition: handle.c:294
CSR_API(SrvOpenConsole)
Definition: handle.c:811
Status
Definition: gdiplustypes.h:24
NTSTATUS ConSrvGetObject(IN PCONSOLE_PROCESS_DATA ProcessData, IN HANDLE Handle, OUT PCONSOLE_IO_OBJECT *Object, OUT PVOID *Entry OPTIONAL, IN ULONG Access, IN BOOLEAN LockConsole, IN CONSOLE_IO_OBJECT_TYPE Type)
Definition: handle.c:401
HANDLE InputHandle
Definition: apc.c:9
struct _CONSOLE_IO_HANDLE * PCONSOLE_IO_HANDLE
BOOLEAN NTAPI ConDrvValidateConsoleUnsafe(IN PCONSOLE Console, IN CONSOLE_STATE ExpectedState, IN BOOLEAN LockConsole)
Definition: console.c:120
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB _Outptr_result_maybenull_ PDCB _In_ PDCB _In_ PDIRENT _In_ ULONG _In_ ULONG _In_ PUNICODE_STRING _In_ PACCESS_MASK DesiredAccess
Definition: create.c:4157
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
#define CTRL_LAST_CLOSE_EVENT
Definition: wincon.h:68
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
HANDLE InputWaitHandle
Definition: conmsg.h:171
struct _CONSOLE_IO_HANDLE * HandleTable
Definition: consrv.h:50
VOID NTAPI ConSrvDeleteConsole(PCONSRV_CONSOLE Console)
Definition: console.c:771
CConsole Console
#define DPRINT1
Definition: precomp.h:8
NTSTATUS ConSrvAllocateConsole(PCONSOLE_PROCESS_DATA ProcessData, PHANDLE pInputHandle, PHANDLE pOutputHandle, PHANDLE pErrorHandle, PCONSOLE_INIT_INFO ConsoleInitInfo)
Definition: handle.c:474
BOOLEAN Inheritable
Definition: handle.c:28
#define ConsoleFreeHeap(HeapBase)
Definition: heap.h:15
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
NTSTATUS NTAPI NtDuplicateObject(IN HANDLE SourceProcessHandle, IN HANDLE SourceHandle, IN HANDLE TargetProcessHandle OPTIONAL, OUT PHANDLE TargetHandle OPTIONAL, IN ACCESS_MASK DesiredAccess, IN ULONG HandleAttributes, IN ULONG Options)
Definition: obhandle.c:3407
#define OUT
Definition: typedefs.h:39
CONSOLE_IO_OBJECT_TYPE Type
Definition: conio.h:50
VOID ConSrvReleaseObject(IN PCONSOLE_IO_OBJECT Object, IN BOOLEAN IsConsoleLocked)
Definition: handle.c:465
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
ULONG Flags
Definition: csrsrv.h:48
NTSTATUS ConSrvInsertObject(IN PCONSOLE_PROCESS_DATA ProcessData, OUT PHANDLE Handle, IN PCONSOLE_IO_OBJECT Object, IN ULONG Access, IN BOOLEAN Inheritable, IN ULONG ShareMode)
Definition: handle.c:310
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
ULONG HandleTableSize
Definition: consrv.h:49
NTSTATUS ConSrvInheritHandlesTable(IN PCONSOLE_PROCESS_DATA SourceProcessData, IN PCONSOLE_PROCESS_DATA TargetProcessData)
Definition: handle.c:203
#define TermRefreshInternalInfo(Console)
Definition: term.h:44
return STATUS_SUCCESS
Definition: btrfs.c:2966
enum _CONSOLE_IO_OBJECT_TYPE CONSOLE_IO_OBJECT_TYPE
static VOID ConSrvFreeHandlesTable(PCONSOLE_PROCESS_DATA ProcessData)
static VOID ConSrvCloseHandle(IN PCONSOLE_IO_HANDLE Handle)
Definition: handle.c:56
base of all file and directory entries
Definition: entries.h:82
VOID ConSrvSetProcessFocus(IN PCSR_PROCESS CsrProcess, IN BOOLEAN SetForeground)
Definition: console.c:944
RTL_CRITICAL_SECTION HandleTableLock
Definition: consrv.h:48
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68