forked from microsoft/terminal
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathObjectHeader.cpp
More file actions
147 lines (125 loc) · 4.76 KB
/
Copy pathObjectHeader.cpp
File metadata and controls
147 lines (125 loc) · 4.76 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include "precomp.h"
#include "ObjectHeader.h"
#include "ObjectHandle.h"
#include "..\host\inputReadHandleData.h"
ConsoleObjectHeader::ConsoleObjectHeader() :
_ulOpenCount(0),
_ulReaderCount(0),
_ulWriterCount(0),
_ulReadShareCount(0),
_ulWriteShareCount(0)
{
}
// Routine Description:
// - This routine allocates an input or output handle from the process's handle table.
// - This routine initializes all non-type specific fields in the handle data structure.
// Arguments:
// - ulHandleType - Flag indicating input or output handle.
// - amDesired - The accesses that will be permitted to this handle after creation
// - ulShareMode - The share states that will be permitted to this handle after creation
// - ppOut - On return, filled with a pointer to the handle data structure. When returned to the API caller, cast to a handle value.
// Return Value:
// - HRESULT S_OK or appropriate error.
// Note:
// TODO: MSFT 614400 - Add concurrency SAL to enforce the lock http://osgvsowi/614400
// - The console lock must be held when calling this routine. The handle is allocated from the per-process handle table. Holding the console
// lock serializes both threads within the calling process and any other process that shares the console.
[[nodiscard]] HRESULT ConsoleObjectHeader::AllocateIoHandle(const ConsoleHandleData::HandleType ulHandleType,
const ACCESS_MASK amDesired,
const ULONG ulShareMode,
std::unique_ptr<ConsoleHandleData>& out)
{
try
{
// Allocate all necessary state.
std::unique_ptr<ConsoleHandleData> pHandleData = std::make_unique<ConsoleHandleData>(ulHandleType,
amDesired,
ulShareMode,
this);
// Check the share mode.
if (((pHandleData->IsReadAllowed()) && (_ulOpenCount > _ulReadShareCount)) ||
((!pHandleData->IsReadShared()) && (_ulReaderCount > 0)) ||
((pHandleData->IsWriteAllowed()) && (_ulOpenCount > _ulWriteShareCount)) ||
((!pHandleData->IsWriteShared()) && (_ulWriterCount > 0)))
{
RETURN_WIN32(ERROR_SHARING_VIOLATION);
}
// Update share/open counts and store handle information.
_ulOpenCount++;
if (pHandleData->IsReadAllowed())
{
_ulReaderCount++;
}
if (pHandleData->IsReadShared())
{
_ulReadShareCount++;
}
if (pHandleData->IsWriteAllowed())
{
_ulWriterCount++;
}
if (pHandleData->IsWriteShared())
{
_ulWriteShareCount++;
}
out.swap(pHandleData);
}
CATCH_RETURN();
return S_OK;
}
// Routine Description:
// - Frees and decrements ref counts of the handle associated with this object.
// Arguments:
// - pFree - Pointer to the handle data to be freed
// Return Value:
// - HRESULT S_OK or appropriate error.
[[nodiscard]] HRESULT ConsoleObjectHeader::FreeIoHandle(_In_ ConsoleHandleData* const pFree)
{
// This absolutely should not happen and our state is corrupt/bad if we try to release past 0.
THROW_HR_IF(E_NOT_VALID_STATE, !(_ulOpenCount > 0));
_ulOpenCount--;
if (pFree->IsReadAllowed())
{
_ulReaderCount--;
}
if (pFree->IsReadShared())
{
_ulReadShareCount--;
}
if (pFree->IsWriteAllowed())
{
_ulWriterCount--;
}
if (pFree->IsWriteShared())
{
_ulWriteShareCount--;
}
return S_OK;
}
// Routine Description:
// - Checks if there are any known open handles connected to this object.
// Arguments:
// - <none>
// Return Value:
// - True if there are any (>0) open handles. False if there are none (0).
bool ConsoleObjectHeader::HasAnyOpenHandles() const
{
return _ulOpenCount != 0;
}
// Routine Description:
// - Adds a fake reference to the ref counts to ensure the original screen buffer is never destroyed.
// - This is a temporary kludge to be solved in TODO http://osgvsowi/9355013
// Arguments:
// - <none>
// Return Value:
// - <none>
void ConsoleObjectHeader::IncrementOriginalScreenBuffer()
{
_ulOpenCount++;
_ulReaderCount++;
_ulReadShareCount++;
_ulWriterCount++;
_ulWriteShareCount++;
}