00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
#include "precomp.h"
00022
#pragma hdrstop
00023
00024
00025
00026
00027
00028 PCONSOLE_INFORMATION InitialConsoleHandles[
CONSOLE_INITIAL_CONSOLES];
00029 PCONSOLE_INFORMATION *
ConsoleHandles;
00030 ULONG
NumberOfConsoleHandles;
00031
00032 CRITICAL_SECTION
ConsoleHandleLock;
00033
00034 ULONG
ConsoleId=47;
00035
00036
00037
00038
00039
00040 #define HandleFromIndex(i) ((HANDLE)((i & 0xFFFF) | (ConsoleId++ << 16)))
00041 #define IndexFromHandle(h) ((USHORT)((ULONG_PTR)h & 0xFFFF))
00042 #define ConsoleHandleTableLocked() (ConsoleHandleLock.OwningThread == NtCurrentTeb()->ClientId.UniqueThread)
00043
00044
VOID
00045
AddProcessToList(
00046 IN OUT
PCONSOLE_INFORMATION Console,
00047 IN OUT
PCONSOLE_PROCESS_HANDLE ProcessHandleRecord,
00048 IN HANDLE ProcessHandle
00049 );
00050
00051
VOID
00052
FreeInputHandle(
00053 IN
PHANDLE_DATA HandleData
00054 );
00055
00056
NTSTATUS
00057 InitializeConsoleHandleTable( VOID )
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075 {
00076
NTSTATUS Status;
00077
00078
Status =
RtlInitializeCriticalSectionAndSpinCount(&
ConsoleHandleLock,
00079 0x80000000);
00080
00081 RtlZeroMemory(
InitialConsoleHandles,
sizeof(
InitialConsoleHandles));
00082
ConsoleHandles =
InitialConsoleHandles;
00083
NumberOfConsoleHandles =
NELEM(
InitialConsoleHandles);
00084
00085
return Status;
00086 }
00087
00088
00089
#ifdef DEBUG
00090
00091
VOID
00092
LockConsoleHandleTable( VOID )
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113 {
00114 RtlEnterCriticalSection(&ConsoleHandleLock);
00115 }
00116
00117
00118
VOID
00119
UnlockConsoleHandleTable( VOID )
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138 {
00139 RtlLeaveCriticalSection(&ConsoleHandleLock);
00140 }
00141
00142
00143
VOID
00144
LockConsole(
00145 IN
PCONSOLE_INFORMATION Console
00146 )
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165 {
00166
ASSERT(!
ConsoleHandleTableLocked());
00167 RtlEnterCriticalSection(&(Console->ConsoleLock));
00168
ASSERT(
ConsoleLocked(Console));
00169 }
00170
00171
#endif // DEBUG
00172
00173
00174
NTSTATUS
00175 DereferenceConsoleHandle(
00176 IN HANDLE ConsoleHandle,
00177 OUT
PCONSOLE_INFORMATION *Console
00178 )
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203 {
00204 ULONG i;
00205
00206
ASSERT(
ConsoleHandleTableLocked());
00207
00208 i =
IndexFromHandle(ConsoleHandle);
00209
if ((i >=
NumberOfConsoleHandles) ||
00210 ((*Console =
ConsoleHandles[i]) ==
NULL) ||
00211 ((*Console)->ConsoleHandle != ConsoleHandle)) {
00212 *Console =
NULL;
00213
return STATUS_INVALID_HANDLE;
00214 }
00215
if ((*Console)->Flags &
CONSOLE_TERMINATING) {
00216 *Console =
NULL;
00217
return STATUS_PROCESS_IS_TERMINATING;
00218 }
00219
return STATUS_SUCCESS;
00220 }
00221
00222
NTSTATUS
00223 GrowConsoleHandleTable( VOID )
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239 {
00240
PCONSOLE_INFORMATION *NewTable;
00241
PCONSOLE_INFORMATION *OldTable;
00242 ULONG i;
00243 ULONG MaxConsoleHandles;
00244
00245
ASSERT(
ConsoleHandleTableLocked());
00246
00247 MaxConsoleHandles =
NumberOfConsoleHandles +
CONSOLE_CONSOLE_HANDLE_INCREMENT;
00248
ASSERT(MaxConsoleHandles <= 0xFFFF);
00249 NewTable = (
PCONSOLE_INFORMATION *)
ConsoleHeapAlloc(
MAKE_TAG(
HANDLE_TAG ),MaxConsoleHandles *
sizeof(
PCONSOLE_INFORMATION));
00250
if (NewTable ==
NULL) {
00251
return STATUS_NO_MEMORY;
00252 }
00253 RtlCopyMemory(NewTable,
ConsoleHandles,
00254
NumberOfConsoleHandles *
sizeof(
PCONSOLE_INFORMATION));
00255
for (i=
NumberOfConsoleHandles;i<MaxConsoleHandles;i++) {
00256 NewTable[i] =
NULL;
00257 }
00258 OldTable =
ConsoleHandles;
00259
ConsoleHandles = NewTable;
00260
NumberOfConsoleHandles = MaxConsoleHandles;
00261
if (OldTable !=
InitialConsoleHandles) {
00262
ConsoleHeapFree(OldTable);
00263 }
00264
return STATUS_SUCCESS;
00265 }
00266
00267
00268
NTSTATUS
00269 AllocateConsoleHandle(
00270 OUT PHANDLE Handle
00271 )
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291 {
00292 ULONG i;
00293
NTSTATUS Status;
00294
00295
ASSERT(
ConsoleHandleTableLocked());
00296
00297
00298
00299
00300
00301
00302
for (i=1;i<
NumberOfConsoleHandles;i++) {
00303
if (
ConsoleHandles[i] ==
NULL) {
00304
ConsoleHandles[i] = (
PCONSOLE_INFORMATION)
CONSOLE_HANDLE_ALLOCATED;
00305 *
Handle =
HandleFromIndex(i);
00306
return STATUS_SUCCESS;
00307 }
00308 }
00309
00310
00311
00312
00313
00314
Status =
GrowConsoleHandleTable();
00315
if (!
NT_SUCCESS(
Status))
00316
return Status;
00317
for ( ;i<
NumberOfConsoleHandles;i++) {
00318
if (
ConsoleHandles[i] ==
NULL) {
00319
ConsoleHandles[i] = (
PCONSOLE_INFORMATION)
CONSOLE_HANDLE_ALLOCATED;
00320 *
Handle =
HandleFromIndex(i);
00321
return STATUS_SUCCESS;
00322 }
00323 }
00324
ASSERT (
FALSE);
00325
return STATUS_UNSUCCESSFUL;
00326 }
00327
00328
00329
00330
NTSTATUS
00331 FreeConsoleHandle(
00332 IN HANDLE Handle
00333 )
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353 {
00354 ULONG i;
00355
00356
ASSERT(
ConsoleHandleTableLocked());
00357
00358
ASSERT (
Handle !=
NULL);
00359 i =
IndexFromHandle(
Handle);
00360
if ((i >=
NumberOfConsoleHandles) || (
ConsoleHandles[i] ==
NULL)) {
00361
ASSERT (
FALSE);
00362 }
else {
00363
ConsoleHandles[i] =
NULL;
00364 }
00365
return STATUS_SUCCESS;
00366 }
00367
00368
00369
NTSTATUS
00370 ValidateConsole(
00371 IN
PCONSOLE_INFORMATION Console
00372 )
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386 {
00387 ULONG i;
00388
00389
if (Console !=
NULL) {
00390
for (i = 0; i <
NumberOfConsoleHandles; i++) {
00391
if (
ConsoleHandles[i] == Console)
00392
return STATUS_SUCCESS;
00393 }
00394 }
00395
return STATUS_UNSUCCESSFUL;
00396 }
00397
00398
00399
NTSTATUS
00400 InitializeIoHandleTable(
00401 IN OUT
PCONSOLE_INFORMATION Console,
00402 OUT
PCONSOLE_PER_PROCESS_DATA ProcessData,
00403 OUT PHANDLE StdIn,
00404 OUT PHANDLE StdOut,
00405 OUT PHANDLE StdErr
00406 )
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432 {
00433 ULONG i;
00434 HANDLE
Handle;
00435
NTSTATUS Status;
00436
PHANDLE_DATA HandleData;
00437
00438
00439
00440
00441
00442
00443
if (ProcessData->HandleTablePtr != ProcessData->HandleTable) {
00444
ASSERT(ProcessData->HandleTableSize !=
CONSOLE_INITIAL_IO_HANDLES);
00445
ConsoleHeapFree(ProcessData->HandleTablePtr);
00446 ProcessData->HandleTablePtr = ProcessData->HandleTable;
00447 }
00448
00449
for (i=0;i<
CONSOLE_INITIAL_IO_HANDLES;i++) {
00450 ProcessData->HandleTable[i].HandleType =
CONSOLE_FREE_HANDLE;
00451 }
00452
00453 ProcessData->HandleTableSize =
CONSOLE_INITIAL_IO_HANDLES;
00454 ProcessData->Foo = 0xF00;
00455
00456
00457
00458
00459
00460
00461
00462
00463
Status =
AllocateIoHandle(ProcessData,
00464
CONSOLE_INPUT_HANDLE,
00465 &
Handle
00466 );
00467
if (!
NT_SUCCESS(
Status)) {
00468
return((ULONG)
Status);
00469 }
00470
Status =
DereferenceIoHandleNoCheck(ProcessData,
00471
Handle,
00472 &HandleData
00473 );
00474
ASSERT (
NT_SUCCESS(
Status));
00475
if (!
NT_SUCCESS(
Status)) {
00476
return((ULONG)
Status);
00477 }
00478
if (!
InitializeInputHandle(HandleData,
00479 &Console->
InputBuffer)) {
00480
return STATUS_NO_MEMORY;
00481 }
00482 HandleData->
HandleType |=
CONSOLE_INHERITABLE;
00483
Status =
ConsoleAddShare(GENERIC_READ | GENERIC_WRITE,
00484 FILE_SHARE_READ | FILE_SHARE_WRITE,
00485 &Console->InputBuffer.ShareAccess,
00486 HandleData
00487 );
00488
ASSERT(
NT_SUCCESS(
Status));
00489
if (!
NT_SUCCESS(
Status)) {
00490
return((ULONG)
Status);
00491 }
00492 *StdIn =
INDEX_TO_HANDLE(
Handle);
00493
00494
00495
00496
00497
00498
Status =
AllocateIoHandle(ProcessData,
00499
CONSOLE_OUTPUT_HANDLE,
00500 &
Handle
00501 );
00502
if (!
NT_SUCCESS(
Status)) {
00503
return((ULONG)
Status);
00504 }
00505
Status =
DereferenceIoHandleNoCheck(ProcessData,
00506
Handle,
00507 &HandleData
00508 );
00509
ASSERT (
NT_SUCCESS(
Status));
00510
if (!
NT_SUCCESS(
Status)) {
00511
return((ULONG)
Status);
00512 }
00513
InitializeOutputHandle(HandleData,Console->CurrentScreenBuffer);
00514 HandleData->
HandleType |=
CONSOLE_INHERITABLE;
00515
Status =
ConsoleAddShare(GENERIC_READ | GENERIC_WRITE,
00516 FILE_SHARE_READ | FILE_SHARE_WRITE,
00517 &Console->ScreenBuffers->ShareAccess,
00518 HandleData
00519 );
00520
ASSERT(
NT_SUCCESS(
Status));
00521
if (!
NT_SUCCESS(
Status)) {
00522
return((ULONG)
Status);
00523 }
00524 *StdOut =
INDEX_TO_HANDLE(
Handle);
00525
00526
00527
00528
00529
00530
Status =
AllocateIoHandle(ProcessData,
00531
CONSOLE_OUTPUT_HANDLE,
00532 &
Handle
00533 );
00534
if (!
NT_SUCCESS(
Status)) {
00535
return((ULONG)
Status);
00536 }
00537
Status =
DereferenceIoHandleNoCheck(ProcessData,
00538
Handle,
00539 &HandleData
00540 );
00541
ASSERT (
NT_SUCCESS(
Status));
00542
if (!
NT_SUCCESS(
Status)) {
00543
return((ULONG)
Status);
00544 }
00545
InitializeOutputHandle(HandleData,Console->CurrentScreenBuffer);
00546 HandleData->
HandleType |=
CONSOLE_INHERITABLE;
00547
Status =
ConsoleAddShare(GENERIC_READ | GENERIC_WRITE,
00548 FILE_SHARE_READ | FILE_SHARE_WRITE,
00549 &Console->ScreenBuffers->ShareAccess,
00550 HandleData
00551 );
00552
ASSERT(
NT_SUCCESS(
Status));
00553
if (!
NT_SUCCESS(
Status)) {
00554
return((ULONG)
Status);
00555 }
00556 *StdErr =
INDEX_TO_HANDLE(
Handle);
00557
return STATUS_SUCCESS;
00558 }
00559
00560
NTSTATUS
00561 InheritIoHandleTable(
00562 IN
PCONSOLE_INFORMATION Console,
00563 IN
PCONSOLE_PER_PROCESS_DATA ProcessData,
00564 IN
PCONSOLE_PER_PROCESS_DATA ParentProcessData
00565 )
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590 {
00591 ULONG i;
00592
NTSTATUS Status;
00593
00594
00595
00596
00597
00598
00599
00600 UNREFERENCED_PARAMETER(Console);
00601
00602
ASSERT(ParentProcessData->Foo == 0xF00);
00603
ASSERT(ParentProcessData->HandleTableSize != 0);
00604
ASSERT(ParentProcessData->HandleTableSize <= 0x0000FFFF);
00605
00606
if (ParentProcessData->HandleTableSize !=
CONSOLE_INITIAL_IO_HANDLES) {
00607 ProcessData->HandleTableSize = ParentProcessData->HandleTableSize;
00608 ProcessData->HandleTablePtr = (
PHANDLE_DATA)
ConsoleHeapAlloc(
MAKE_TAG(
HANDLE_TAG ),ProcessData->HandleTableSize *
sizeof(
HANDLE_DATA));
00609
00610
if (ProcessData->HandleTablePtr ==
NULL) {
00611 ProcessData->HandleTablePtr = ProcessData->HandleTable;
00612 ProcessData->HandleTableSize =
CONSOLE_INITIAL_IO_HANDLES;
00613
return STATUS_NO_MEMORY;
00614 }
00615 RtlCopyMemory(ProcessData->HandleTablePtr,
00616 ParentProcessData->HandleTablePtr,
00617 ProcessData->HandleTableSize *
sizeof(
HANDLE_DATA));
00618 }
00619
00620
ASSERT(!(Console->Flags &
CONSOLE_SHUTTING_DOWN));
00621
00622
00623
00624
00625
00626
Status = STATUS_SUCCESS;
00627
for (i=0;i<ProcessData->HandleTableSize;i++) {
00628
00629
if (
NT_SUCCESS(
Status) && ProcessData->HandleTablePtr[i].HandleType &
CONSOLE_INHERITABLE) {
00630
00631
if (ProcessData->HandleTablePtr[i].HandleType &
CONSOLE_INPUT_HANDLE) {
00632 ProcessData->HandleTablePtr[i].InputReadData = (
PINPUT_READ_HANDLE_DATA)
ConsoleHeapAlloc(
MAKE_TAG(
HANDLE_TAG ),
sizeof(
INPUT_READ_HANDLE_DATA));
00633
if (!ProcessData->HandleTablePtr[i].InputReadData) {
00634 ProcessData->HandleTablePtr[i].HandleType =
CONSOLE_FREE_HANDLE;
00635
Status = STATUS_NO_MEMORY;
00636
continue;
00637 }
00638 ProcessData->HandleTablePtr[i].InputReadData->InputHandleFlags = 0;
00639 ProcessData->HandleTablePtr[i].InputReadData->ReadCount = 0;
00640
Status =
RtlInitializeCriticalSection(&ProcessData->HandleTablePtr[i].InputReadData->ReadCountLock);
00641
if (!
NT_SUCCESS(
Status)) {
00642
ConsoleHeapFree(ProcessData->HandleTablePtr[i].InputReadData);
00643 ProcessData->HandleTablePtr[i].InputReadData =
NULL;
00644 ProcessData->HandleTablePtr[i].HandleType =
CONSOLE_FREE_HANDLE;
00645
continue;
00646 }
00647 }
00648 }
00649
else {
00650 ProcessData->HandleTablePtr[i].HandleType =
CONSOLE_FREE_HANDLE;
00651 }
00652 }
00653
00654
00655
00656
00657
00658
00659
if (!
NT_SUCCESS(
Status)) {
00660
for (i=0;i<ProcessData->HandleTableSize;i++) {
00661
if (ProcessData->HandleTablePtr[i].HandleType &
CONSOLE_INPUT_HANDLE) {
00662
FreeInputHandle(&ProcessData->HandleTablePtr[i]);
00663 }
00664 }
00665
if (ProcessData->HandleTableSize !=
CONSOLE_INITIAL_IO_HANDLES) {
00666
ConsoleHeapFree(ProcessData->HandleTablePtr);
00667 ProcessData->HandleTablePtr = ProcessData->HandleTable;
00668 ProcessData->HandleTableSize =
CONSOLE_INITIAL_IO_HANDLES;
00669 }
00670
return Status;
00671 }
00672
00673
00674
00675
00676
00677
00678
for (i=0;i<ProcessData->HandleTableSize;i++) {
00679
if (ProcessData->HandleTablePtr[i].HandleType !=
CONSOLE_FREE_HANDLE) {
00680
PCONSOLE_SHARE_ACCESS ShareAccess;
00681
00682
if (ProcessData->HandleTablePtr[i].HandleType &
CONSOLE_INPUT_HANDLE) {
00683 ProcessData->HandleTablePtr[i].Buffer.InputBuffer->RefCount++;
00684 ShareAccess = &ProcessData->HandleTablePtr[i].Buffer.InputBuffer->ShareAccess;
00685 }
00686
else {
00687 ProcessData->HandleTablePtr[i].Buffer.ScreenBuffer->RefCount++;
00688 ShareAccess = &ProcessData->HandleTablePtr[i].Buffer.ScreenBuffer->ShareAccess;
00689 }
00690
00691
Status =
ConsoleDupShare(ProcessData->HandleTablePtr[i].Access,
00692 ProcessData->HandleTablePtr[i].ShareAccess,
00693 ShareAccess,
00694 &ProcessData->HandleTablePtr[i]
00695 );
00696
ASSERT (
NT_SUCCESS(
Status));
00697 }
00698 }
00699
ASSERT(ProcessData->Foo == 0xF00);
00700
00701
return STATUS_SUCCESS;
00702 }
00703
00704
NTSTATUS
00705 ConsoleAddProcessRoutine(
00706 IN PCSR_PROCESS ParentProcess,
00707 IN PCSR_PROCESS Process
00708 )
00709 {
00710
PCONSOLE_PER_PROCESS_DATA ProcessData, ParentProcessData;
00711
PCONSOLE_INFORMATION Console;
00712
PCONSOLE_PROCESS_HANDLE ProcessHandleRecord;
00713
NTSTATUS Status = STATUS_SUCCESS;
00714 ULONG i;
00715
00716 ProcessData =
CONSOLE_FROMPROCESSPERPROCESSDATA(Process);
00717 ProcessData->
HandleTablePtr = ProcessData->
HandleTable;
00718 ProcessData->
HandleTableSize =
CONSOLE_INITIAL_IO_HANDLES;
00719
CONSOLE_SETCONSOLEAPPFROMPROCESSDATA(ProcessData,
FALSE);
00720
00721
if (ParentProcess) {
00722
00723 ProcessData->
RootProcess =
FALSE;
00724 ParentProcessData =
CONSOLE_FROMPROCESSPERPROCESSDATA(ParentProcess);
00725
00726
00727
00728
00729
00730
00731
if (ParentProcessData->
ConsoleHandle !=
NULL &&
00732 (Process->Flags & CSR_PROCESS_CONSOLEAPP)) {
00733
if (!(
NT_SUCCESS(
RevalidateConsole(ParentProcessData->
ConsoleHandle,
00734 &Console)))) {
00735 ProcessData->
ConsoleHandle =
NULL;
00736
return STATUS_PROCESS_IS_TERMINATING;
00737 }
00738
00739
00740
00741
00742
00743
if (Console->
Flags &
CONSOLE_SHUTTING_DOWN) {
00744
Status = STATUS_PROCESS_IS_TERMINATING;
00745 }
else {
00746 ProcessHandleRecord =
ConsoleHeapAlloc(
MAKE_TAG(
HANDLE_TAG ),
sizeof(
CONSOLE_PROCESS_HANDLE));
00747
if (ProcessHandleRecord ==
NULL) {
00748
Status = STATUS_NO_MEMORY;
00749 }
else {
00750
00751
00752
00753
00754
00755
ASSERT(ProcessData->
Foo == 0xF00);
00756
Status =
InheritIoHandleTable(Console, ProcessData, ParentProcessData);
00757
if (
NT_SUCCESS(
Status)) {
00758 ProcessHandleRecord->
Process = Process;
00759 ProcessHandleRecord->
CtrlRoutine =
NULL;
00760 ProcessHandleRecord->
PropRoutine =
NULL;
00761
AddProcessToList(Console,ProcessHandleRecord,Process->
ProcessHandle);
00762
00763
00764
00765
00766
00767 Console->
RefCount++;
00768 }
else {
00769
ConsoleHeapFree(ProcessHandleRecord);
00770 }
00771 }
00772 }
00773
if (!
NT_SUCCESS(
Status)) {
00774 ProcessData->
ConsoleHandle =
NULL;
00775
for (i=0;i<
CONSOLE_INITIAL_IO_HANDLES;i++) {
00776 ProcessData->
HandleTable[i].
HandleType =
CONSOLE_FREE_HANDLE;
00777 }
00778 }
00779
UnlockConsole(Console);
00780 }
else
00781 ProcessData->
ConsoleHandle =
NULL;
00782 }
else {
00783 ProcessData->
ConsoleHandle =
NULL;
00784 }
00785
return Status;
00786 }
00787
00788
NTSTATUS
00789 AllocateConsole(
00790 IN HANDLE ConsoleHandle,
00791 IN LPWSTR Title,
00792 IN USHORT TitleLength,
00793 IN HANDLE ClientProcessHandle,
00794 OUT PHANDLE StdIn,
00795 OUT PHANDLE StdOut,
00796 OUT PHANDLE StdErr,
00797 OUT
PCONSOLE_PER_PROCESS_DATA ProcessData,
00798 IN OUT
PCONSOLE_INFO ConsoleInfo,
00799 IN BOOLEAN WindowVisible,
00800 IN DWORD dwConsoleThreadId
00801 )
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840 {
00841
PCONSOLE_INFORMATION Console;
00842
NTSTATUS Status;
00843
BOOL Success;
00844
00845
00846
00847
00848
00849 Console = (
PCONSOLE_INFORMATION)
ConsoleHeapAlloc(
MAKE_TAG(
CONSOLE_TAG ) | HEAP_ZERO_MEMORY,
00850
sizeof(
CONSOLE_INFORMATION));
00851
if (Console ==
NULL) {
00852
return STATUS_NO_MEMORY;
00853 }
00854
ConsoleHandles[
IndexFromHandle(ConsoleHandle)] = Console;
00855
00856 Console->
Flags = WindowVisible ? 0 :
CONSOLE_NO_WINDOW;
00857 Console->hIcon = ConsoleInfo->hIcon;
00858 Console->hSmIcon = ConsoleInfo->hSmIcon;
00859 Console->iIconId = ConsoleInfo->iIconId;
00860 Console->dwHotKey = ConsoleInfo->dwHotKey;
00861
#if !defined(FE_SB)
00862
Console->CP =
OEMCP;
00863 Console->OutputCP =
ConsoleOutputCP;
00864
#endif
00865
Console->ReserveKeys = CONSOLE_NOSHORTCUTKEY;
00866 Console->ConsoleHandle = ConsoleHandle;
00867 Console->bIconInit =
TRUE;
00868 Console->VerticalClientToWindow =
VerticalClientToWindow;
00869 Console->HorizontalClientToWindow =
HorizontalClientToWindow;
00870
#if defined(FE_SB)
00871
SetConsoleCPInfo(Console,
TRUE);
00872 SetConsoleCPInfo(Console,
FALSE);
00873
#endif
00874
00875
00876
00877
00878
00879
00880
Status =
NtDuplicateObject(NtCurrentProcess(),
00881
CONSOLE_CLIENTTHREADHANDLE(CSR_SERVER_QUERYCLIENTTHREAD()),
00882 NtCurrentProcess(),
00883 &Console->ClientThreadHandle,
00884 0,
00885
FALSE,
00886 DUPLICATE_SAME_ACCESS
00887 );
00888
if (!
NT_SUCCESS(
Status)) {
00889
goto ErrorExit5;
00890 }
00891
00892
#if DBG
00893
00894
00895
00896
UnProtectHandle(Console->ClientThreadHandle);
00897
#endif // DBG
00898
00899 InitializeListHead(&Console->OutputQueue);
00900 InitializeListHead(&Console->ProcessHandleList);
00901 InitializeListHead(&Console->ExeAliasList);
00902 InitializeListHead(&Console->MessageQueue);
00903
00904
Status =
NtCreateEvent(&Console->InitEvents[
INITIALIZATION_SUCCEEDED],
00905 EVENT_ALL_ACCESS,
NULL, NotificationEvent,
FALSE);
00906
if (!
NT_SUCCESS(
Status)) {
00907
goto ErrorExit4a;
00908 }
00909
Status =
NtCreateEvent(&Console->InitEvents[
INITIALIZATION_FAILED],
00910 EVENT_ALL_ACCESS,
NULL, NotificationEvent,
FALSE);
00911
if (!
NT_SUCCESS(
Status)) {
00912
goto ErrorExit4;
00913 }
00914
Status =
RtlInitializeCriticalSection(&Console->ConsoleLock);
00915
if (!
NT_SUCCESS(
Status)) {
00916
goto ErrorExit3a;
00917 }
00918
InitializeConsoleCommandData(Console);
00919
00920
00921
00922
00923
00924
#if defined(FE_SB)
00925
Status =
CreateInputBuffer(ConsoleInfo->nInputBufferSize,
00926 &Console->InputBuffer,
00927 Console);
00928
#else
00929
Status =
CreateInputBuffer(ConsoleInfo->nInputBufferSize,
00930 &Console->InputBuffer);
00931
#endif
00932
if (!
NT_SUCCESS(
Status)) {
00933
goto ErrorExit3;
00934 }
00935
00936 Console->Title = (PWCHAR)
ConsoleHeapAlloc(
MAKE_TAG(
TITLE_TAG ),TitleLength+
sizeof(WCHAR));
00937
if (Console->Title ==
NULL) {
00938
Status = STATUS_NO_MEMORY;
00939
goto ErrorExit2;
00940 }
00941 RtlCopyMemory(Console->Title,Title,TitleLength);
00942 Console->Title[TitleLength/
sizeof(WCHAR)] = (WCHAR)0;
00943 Console->TitleLength = TitleLength;
00944
00945 Console->OriginalTitle =
TranslateConsoleTitle(Console->Title, &Console->OriginalTitleLength,
TRUE,
FALSE);
00946
if (Console->OriginalTitle ==
NULL) {
00947
Status = STATUS_NO_MEMORY;
00948
goto ErrorExit1;
00949 }
00950
00951
Status =
NtCreateEvent(&Console->TerminationEvent,
00952 EVENT_ALL_ACCESS,
NULL, NotificationEvent,
FALSE);
00953
if (!
NT_SUCCESS(
Status)) {
00954
goto ErrorExit1a;
00955 }
00956
00957
00958
00959
00960
00961
00962
Status =
DoCreateScreenBuffer(Console,
00963 ConsoleInfo);
00964
if (!
NT_SUCCESS(
Status)){
00965
goto ErrorExit1b;
00966 }
00967
00968
00969 Console->CurrentScreenBuffer = Console->ScreenBuffers;
00970
#if defined(FE_SB)
00971
#if defined(FE_IME)
00972
SetUndetermineAttribute(Console) ;
00973
#endif
00974
Status =
CreateEUDC(Console);
00975
if (!
NT_SUCCESS(
Status)){
00976
goto ErrorExit1c;
00977 }
00978
#endif
00979
Status =
InitializeIoHandleTable(Console,
00980 ProcessData,
00981 StdIn,
00982 StdOut,
00983 StdErr
00984 );
00985
if (!
NT_SUCCESS(
Status)) {
00986
goto ErrorExit0;
00987 }
00988
00989
00990
00991
00992
00993
if (!
MapHandle(ClientProcessHandle,
00994 Console->InitEvents[
INITIALIZATION_SUCCEEDED],
00995 &ConsoleInfo->InitEvents[
INITIALIZATION_SUCCEEDED]
00996 )) {
00997
Status = STATUS_NO_MEMORY;
00998
goto ErrorExit0;
00999 }
01000
if (!
MapHandle(ClientProcessHandle,
01001 Console->InitEvents[
INITIALIZATION_FAILED],
01002 &ConsoleInfo->InitEvents[
INITIALIZATION_FAILED]
01003 )) {
01004
Status = STATUS_NO_MEMORY;
01005
goto ErrorExit0;
01006 }
01007
if (!
MapHandle(ClientProcessHandle,
01008 Console->InputBuffer.InputWaitEvent,
01009 &ConsoleInfo->InputWaitHandle
01010 )) {
01011
Status = STATUS_NO_MEMORY;
01012
goto ErrorExit0;
01013 }
01014
01015 Success =
PostThreadMessage(
dwConsoleThreadId,
01016
CM_CREATE_CONSOLE_WINDOW,
01017 (WPARAM)ConsoleHandle,
01018 (LPARAM)ClientProcessHandle
01019 );
01020
if (!Success) {
01021 KdPrint((
"CONSRV: PostThreadMessage failed %d\n",GetLastError()));
01022
Status = STATUS_UNSUCCESSFUL;
01023
goto ErrorExit0;
01024 }
01025
01026
return STATUS_SUCCESS;
01027
01028 ErrorExit0: Console->ScreenBuffers->RefCount = 0;
01029
#if defined(FE_SB)
01030
if (Console->EudcInformation !=
NULL) {
01031
ConsoleHeapFree(Console->EudcInformation);
01032 }
01033 ErrorExit1c:
01034
#endif
01035
FreeScreenBuffer(Console->ScreenBuffers);
01036 ErrorExit1b:
NtClose(Console->TerminationEvent);
01037 ErrorExit1a:
ConsoleHeapFree(Console->OriginalTitle);
01038 ErrorExit1:
ConsoleHeapFree(Console->Title);
01039 ErrorExit2: Console->InputBuffer.RefCount = 0;
01040
FreeInputBuffer(&Console->InputBuffer);
01041 ErrorExit3:
RtlDeleteCriticalSection(&Console->ConsoleLock);
01042
01043 ErrorExit3a:
NtClose(Console->InitEvents[
INITIALIZATION_FAILED]);
01044 ErrorExit4:
NtClose(Console->InitEvents[
INITIALIZATION_SUCCEEDED]);
01045 ErrorExit4a:
NtClose(Console->ClientThreadHandle);
01046 ErrorExit5:
ConsoleHeapFree(Console);
01047
return Status;
01048 }
01049
01050
VOID
01051 DestroyConsole(
01052 IN
PCONSOLE_INFORMATION Console
01053 )
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070 {
01071 HANDLE ConsoleHandle = Console->ConsoleHandle;
01072
01073
01074
01075
01076
01077
ASSERT(
ConsoleLocked(Console));
01078
ASSERT(Console->hWnd ==
NULL);
01079
01080
01081
01082
01083
01084 Console->Flags |=
CONSOLE_IN_DESTRUCTION;
01085
01086
01087
01088
01089
01090 RtlLeaveCriticalSection(&Console->ConsoleLock);
01091
01092
01093
01094
01095
01096
LockConsoleHandleTable();
01097
if (Console ==
ConsoleHandles[
IndexFromHandle(ConsoleHandle)] &&
01098 Console->
ConsoleHandle == ConsoleHandle &&
01099 Console->ConsoleLock.OwningThread ==
NULL &&
01100 Console->WaitCount == 0) {
01101
01102
FreeConsoleHandle(ConsoleHandle);
01103
RtlDeleteCriticalSection(&Console->ConsoleLock);
01104
ConsoleHeapFree(Console);
01105 }
01106
UnlockConsoleHandleTable();
01107 }
01108
01109
VOID
01110 FreeCon(
01111 IN
PCONSOLE_INFORMATION Console
01112 )
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133 {
01134 HWND
hWnd;
01135
01136 Console->Flags |=
CONSOLE_TERMINATING;
01137
NtSetEvent(Console->TerminationEvent,
NULL);
01138
hWnd = Console->hWnd;
01139
01140
01141
01142
01143
01144
01145
01146
if (
hWnd !=
NULL) {
01147
UnlockConsole(Console);
01148
SendMessageTimeout(
hWnd,
CM_DESTROY_WINDOW, 0, 0, SMTO_BLOCK, 10000,
NULL);
01149 }
else {
01150
AbortCreateConsole(Console);
01151 }
01152 }
01153
01154
VOID
01155 InsertScreenBuffer(
01156 IN
PCONSOLE_INFORMATION Console,
01157 IN
PSCREEN_INFORMATION ScreenInfo
01158 )
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181 {
01182 ScreenInfo->Next = Console->ScreenBuffers;
01183 Console->ScreenBuffers = ScreenInfo;
01184 }
01185
01186
VOID
01187 RemoveScreenBuffer(
01188 IN
PCONSOLE_INFORMATION Console,
01189 IN
PSCREEN_INFORMATION ScreenInfo
01190 )
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213 {
01214
PSCREEN_INFORMATION Prev,Cur;
01215
01216
if (ScreenInfo == Console->ScreenBuffers) {
01217 Console->ScreenBuffers = ScreenInfo->Next;
01218
return;
01219 }
01220 Prev = Cur = Console->ScreenBuffers;
01221
while (Cur !=
NULL) {
01222
if (ScreenInfo == Cur)
01223
break;
01224 Prev = Cur;
01225 Cur = Cur->
Next;
01226 }
01227
ASSERT (Cur !=
NULL);
01228
if (Cur !=
NULL) {
01229 Prev->
Next = Cur->
Next;
01230 }
01231 }
01232
01233
NTSTATUS
01234 GrowIoHandleTable(
01235 IN
PCONSOLE_PER_PROCESS_DATA ProcessData
01236 )
01237
01238
01239
01240
01241
01242
01243
01244
01245
01246
01247
01248
01249
01250
01251
01252 {
01253
PHANDLE_DATA NewTable;
01254 ULONG i;
01255 ULONG MaxFileHandles;
01256
01257
ASSERT(ProcessData->Foo == 0xF00);
01258 MaxFileHandles = ProcessData->HandleTableSize +
CONSOLE_IO_HANDLE_INCREMENT;
01259 NewTable = (
PHANDLE_DATA)
ConsoleHeapAlloc(
MAKE_TAG(
HANDLE_TAG ),MaxFileHandles *
sizeof(
HANDLE_DATA));
01260
if (NewTable ==
NULL) {
01261
return STATUS_NO_MEMORY;
01262 }
01263 RtlCopyMemory(NewTable, ProcessData->HandleTablePtr,
01264 ProcessData->HandleTableSize *
sizeof(
HANDLE_DATA));
01265
for (i=ProcessData->HandleTableSize;i<MaxFileHandles;i++) {
01266 NewTable[i].
HandleType =
CONSOLE_FREE_HANDLE;
01267 }
01268
if (ProcessData->HandleTableSize !=
CONSOLE_INITIAL_IO_HANDLES) {
01269
ConsoleHeapFree(ProcessData->HandleTablePtr);
01270 }
01271 ProcessData->HandleTablePtr = NewTable;
01272 ProcessData->HandleTableSize = MaxFileHandles;
01273
ASSERT(ProcessData->Foo == 0xF00);
01274
ASSERT(ProcessData->HandleTableSize != 0);
01275
ASSERT(ProcessData->HandleTableSize <= 0x0000FFFF);
01276
return STATUS_SUCCESS;
01277 }
01278
01279
VOID
01280 FreeProcessData(
01281 IN
PCONSOLE_PER_PROCESS_DATA ProcessData
01282 )
01283
01284
01285
01286
01287
01288
01289
01290
01291
01292
01293
01294
01295
01296
01297
01298 {
01299
if (ProcessData->HandleTableSize !=
CONSOLE_INITIAL_IO_HANDLES) {
01300
ConsoleHeapFree(ProcessData->HandleTablePtr);
01301 ProcessData->HandleTablePtr = ProcessData->HandleTable;
01302 ProcessData->HandleTableSize =
CONSOLE_INITIAL_IO_HANDLES;
01303 }
01304 }
01305
01306
VOID
01307 InitializeOutputHandle(
01308
PHANDLE_DATA HandleData,
01309
PSCREEN_INFORMATION ScreenBuffer
01310 )
01311
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322
01323
01324
01325
01326
01327
01328
01329 {
01330 HandleData->
Buffer.ScreenBuffer = ScreenBuffer;
01331 HandleData->
Buffer.ScreenBuffer->RefCount++;
01332 }
01333
01334 BOOLEAN
01335 InitializeInputHandle(
01336
PHANDLE_DATA HandleData,
01337
PINPUT_INFORMATION InputBuffer
01338 )
01339
01340
01341
01342
01343
01344
01345
01346
01347
01348
01349
01350
01351
01352
01353
01354
01355
01356
01357 {
01358
NTSTATUS Status;
01359
01360 HandleData->
InputReadData = (
PINPUT_READ_HANDLE_DATA)
ConsoleHeapAlloc(
MAKE_TAG(
HANDLE_TAG ),
sizeof(
INPUT_READ_HANDLE_DATA));
01361
if (!HandleData->
InputReadData) {
01362
return FALSE;
01363 }
01364
Status =
RtlInitializeCriticalSection(&HandleData->
InputReadData->
ReadCountLock);
01365
if (!
NT_SUCCESS(
Status)) {
01366
ConsoleHeapFree(HandleData->
InputReadData);
01367 HandleData->
InputReadData =
NULL;
01368
return FALSE;
01369 }
01370 HandleData->
InputReadData->
ReadCount = 0;
01371 HandleData->
InputReadData->
InputHandleFlags = 0;
01372 HandleData->
Buffer.InputBuffer = InputBuffer;
01373 HandleData->
Buffer.InputBuffer->RefCount++;
01374
return TRUE;
01375 }
01376
01377
VOID
01378 FreeInputHandle(
01379 IN
PHANDLE_DATA HandleData
01380 )
01381 {
01382
if (HandleData->InputReadData) {
01383
RtlDeleteCriticalSection(&HandleData->InputReadData->ReadCountLock);
01384
ConsoleHeapFree(HandleData->InputReadData);
01385 HandleData->InputReadData =
NULL;
01386 }
01387 }
01388
01389
NTSTATUS
01390 AllocateIoHandle(
01391 IN
PCONSOLE_PER_PROCESS_DATA ProcessData,
01392 IN ULONG HandleType,
01393 OUT PHANDLE Handle
01394 )
01395
01396
01397
01398
01399
01400
01401
01402
01403
01404
01405
01406
01407
01408
01409
01410
01411
01412
01413
01414
01415
01416
01417
01418
01419
01420
01421
01422
01423
01424
01425
01426
01427 {
01428 ULONG i;
01429
NTSTATUS Status;
01430
01431
for (i=0;i<ProcessData->HandleTableSize;i++) {
01432
if (ProcessData->HandleTablePtr[i].HandleType ==
CONSOLE_FREE_HANDLE) {
01433 ProcessData->HandleTablePtr[i].HandleType = HandleType;
01434 *
Handle = (HANDLE) i;
01435
01436
return STATUS_SUCCESS;
01437 }
01438 }
01439
Status =
GrowIoHandleTable(ProcessData);
01440
if (!
NT_SUCCESS(
Status))
01441
return Status;
01442
for ( ;i<ProcessData->HandleTableSize;i++) {
01443
if (ProcessData->HandleTablePtr[i].HandleType ==
CONSOLE_FREE_HANDLE) {
01444 ProcessData->HandleTablePtr[i].HandleType = HandleType;
01445 *
Handle = (HANDLE) i;
01446
return STATUS_SUCCESS;
01447 }
01448 }
01449
ASSERT (
FALSE);
01450
return STATUS_UNSUCCESSFUL;
01451 }
01452
01453
01454
NTSTATUS
01455 FreeIoHandle(
01456 IN
PCONSOLE_PER_PROCESS_DATA ProcessData,
01457 IN HANDLE Handle
01458 )
01459
01460
01461
01462
01463
01464
01465
01466
01467
01468
01469
01470
01471
01472
01473
01474
01475
01476
01477
01478
01479
01480
01481
01482
01483
01484 {
01485
NTSTATUS Status;
01486
PHANDLE_DATA HandleData;
01487
01488
Status =
DereferenceIoHandleNoCheck(ProcessData,
01489
Handle,
01490 &HandleData
01491 );
01492
ASSERT (
NT_SUCCESS(
Status));
01493
if (HandleData->
HandleType &
CONSOLE_INPUT_HANDLE) {
01494
FreeInputHandle(HandleData);
01495 }
01496 HandleData->
HandleType =
CONSOLE_FREE_HANDLE;
01497
return STATUS_SUCCESS;
01498 }
01499
01500
NTSTATUS
01501 DereferenceIoHandleNoCheck(
01502 IN
PCONSOLE_PER_PROCESS_DATA ProcessData,
01503 IN HANDLE Handle,
01504 OUT
PHANDLE_DATA *HandleData
01505 )
01506
01507
01508
01509
01510
01511
01512
01513
01514
01515
01516
01517
01518
01519
01520
01521
01522
01523
01524
01525
01526 {
01527
if (((ULONG_PTR)
Handle >= ProcessData->HandleTableSize) ||
01528 (ProcessData->HandleTablePtr[(ULONG_PTR)
Handle].HandleType ==
CONSOLE_FREE_HANDLE) ) {
01529
return STATUS_INVALID_HANDLE;
01530 }
01531 *HandleData = &ProcessData->HandleTablePtr[(ULONG_PTR)
Handle];
01532
return STATUS_SUCCESS;
01533 }
01534
01535
NTSTATUS
01536 DereferenceIoHandle(
01537 IN
PCONSOLE_PER_PROCESS_DATA ProcessData,
01538 IN HANDLE Handle,
01539 IN ULONG HandleType,
01540 IN ACCESS_MASK Access,
01541 OUT
PHANDLE_DATA *HandleData
01542 )
01543
01544
01545
01546
01547
01548
01549
01550
01551
01552
01553
01554
01555
01556
01557
01558
01559
01560
01561
01562
01563 {
01564 ULONG_PTR
Index;
01565
01566
if (!
CONSOLE_HANDLE(
Handle)) {
01567
return STATUS_INVALID_HANDLE;
01568 }
01569
Index = (ULONG_PTR)
HANDLE_TO_INDEX(
Handle);
01570
if ((
Index >= ProcessData->HandleTableSize) ||
01571 (ProcessData->HandleTablePtr[
Index].HandleType ==
CONSOLE_FREE_HANDLE) ||
01572 !(ProcessData->HandleTablePtr[
Index].HandleType & HandleType) ||
01573 !(ProcessData->HandleTablePtr[
Index].Access & Access) ) {
01574
return STATUS_INVALID_HANDLE;
01575 }
01576 *HandleData = &ProcessData->HandleTablePtr[
Index];
01577
return STATUS_SUCCESS;
01578 }
01579
01580
01581 ULONG
01582 SrvVerifyConsoleIoHandle(
01583 IN OUT PCSR_API_MSG m,
01584 IN OUT PCSR_REPLY_STATUS ReplyStatus
01585 )
01586
01587
01588
01589
01590
01591
01592
01593
01594
01595
01596
01597
01598
01599
01600
01601 {
01602
PCONSOLE_VERIFYIOHANDLE_MSG a = (
PCONSOLE_VERIFYIOHANDLE_MSG)&m->u.ApiMessageData;
01603
PCONSOLE_INFORMATION Console;
01604
NTSTATUS Status;
01605
PHANDLE_DATA HandleData;
01606
PCONSOLE_PER_PROCESS_DATA ProcessData;
01607
01608 UNREFERENCED_PARAMETER(ReplyStatus);
01609
01610
Status =
ApiPreamble(a->
ConsoleHandle,
01611 &Console
01612 );
01613
if (
NT_SUCCESS(
Status)) {
01614 ProcessData =
CONSOLE_PERPROCESSDATA();
01615
Status =
DereferenceIoHandleNoCheck(ProcessData,
01616
HANDLE_TO_INDEX(a->
Handle),
01617 &HandleData
01618 );
01619
UnlockConsole(Console);
01620 }
01621 a->
Valid = (
NT_SUCCESS(
Status));
01622
return STATUS_SUCCESS;
01623 }
01624
01625
01626
NTSTATUS
01627 ApiPreamble(
01628 IN HANDLE ConsoleHandle,
01629 OUT
PCONSOLE_INFORMATION *Console
01630 )
01631 {
01632
NTSTATUS Status;
01633
01634
01635
01636
01637
01638
if (ConsoleHandle ==
NULL || ConsoleHandle !=
CONSOLE_GETCONSOLEHANDLE()) {
01639
return STATUS_INVALID_HANDLE;
01640 }
01641
01642
#ifdef i386
01643
01644
01645
01646
01647
01648
01649
01650
01651
01652
01653 RtlEnterCriticalSection(&
ConsoleVDMCriticalSection);
01654
if (
ConsoleVDMOnSwitching !=
NULL &&
01655
ConsoleVDMOnSwitching->
ConsoleHandle == ConsoleHandle &&
01656
ConsoleVDMOnSwitching->
VDMProcessId ==
CONSOLE_CLIENTPROCESSID())
01657 {
01658 KdPrint((
" ApiPreamble - Thread %lx Entered VDM CritSec\n", GetCurrentThreadId()));
01659 *Console =
ConsoleVDMOnSwitching;
01660
return STATUS_SUCCESS;
01661 }
01662 RtlLeaveCriticalSection(&
ConsoleVDMCriticalSection);
01663
#endif
01664
01665
Status =
RevalidateConsole(ConsoleHandle,
01666 Console
01667 );
01668
if (!
NT_SUCCESS(
Status)) {
01669
return((ULONG)
Status);
01670 }
01671
01672
01673
01674
01675
01676
if ((*Console)->hWnd ==
NULL || ((*Console)->Flags &
CONSOLE_TERMINATING)) {
01677 KdPrint((
"CONSRV: bogus window for console %lx\n", *Console));
01678
UnlockConsole(*Console);
01679
return STATUS_INVALID_HANDLE;
01680 }
01681
01682
return Status;
01683 }
01684
01685
NTSTATUS
01686 RevalidateConsole(
01687 IN HANDLE ConsoleHandle,
01688 OUT
PCONSOLE_INFORMATION *Console
01689 )
01690 {
01691
NTSTATUS Status;
01692
01693
LockConsoleHandleTable();
01694
Status =
DereferenceConsoleHandle(ConsoleHandle,
01695 Console
01696 );
01697
if (!
NT_SUCCESS(
Status)) {
01698
UnlockConsoleHandleTable();
01699
return Status;
01700 }
01701
01702
01703
01704
01705
01706
01707 InterlockedIncrement(&(*Console)->WaitCount);
01708
UnlockConsoleHandleTable();
01709
try {
01710
LockConsole(*Console);
01711 } except (
EXCEPTION_EXECUTE_HANDLER) {
01712 InterlockedDecrement(&(*Console)->WaitCount);
01713
return GetExceptionCode();
01714 }
01715 InterlockedDecrement(&(*Console)->WaitCount);
01716
01717
01718
01719
01720
01721
01722
if ((*Console)->Flags &
CONSOLE_IN_DESTRUCTION) {
01723
DestroyConsole(*Console);
01724 *Console =
NULL;
01725
return STATUS_INVALID_HANDLE;
01726 }
01727
01728
01729
01730
01731
01732
01733
if ((*Console)->Flags &
CONSOLE_TERMINATING) {
01734
UnlockConsole(*Console);
01735 *Console =
NULL;
01736
return STATUS_PROCESS_IS_TERMINATING;
01737 }
01738
01739
return Status;
01740 }
01741
01742
01743
#if DBG
01744
01745 BOOLEAN
01746
UnProtectHandle(
01747 HANDLE hObject
01748 )
01749 {
01750
NTSTATUS Status;
01751 OBJECT_HANDLE_FLAG_INFORMATION HandleInfo;
01752
01753
Status =
NtQueryObject(hObject,
01754 ObjectHandleFlagInformation,
01755 &HandleInfo,
01756
sizeof(HandleInfo),
01757 NULL
01758 );
01759
if (
NT_SUCCESS(Status)) {
01760 HandleInfo.ProtectFromClose =
FALSE;
01761
Status =
NtSetInformationObject(hObject,
01762 ObjectHandleFlagInformation,
01763 &HandleInfo,
01764
sizeof(HandleInfo)
01765 );
01766
if (
NT_SUCCESS(Status)) {
01767
return TRUE;
01768 }
01769 }
01770
01771
return FALSE;
01772 }
01773
01774
#endif // DBG