installed pty
[VSoRC/.git] / node_modules / node-pty / deps / winpty / misc / VeryLargeRead.cc
1 //
2 // 2015-09-25
3 // I measured these limits on the size of a single ReadConsoleOutputW call.
4 // The limit seems to more-or-less disppear with Windows 8, which is the first
5 // OS to stop using ALPCs for console I/O.  My guess is that the new I/O
6 // method does not use the 64KiB shared memory buffer that the ALPC method
7 // uses.
8 //
9 // I'm guessing the remaining difference between Windows 8/8.1 and Windows 10
10 // might be related to the 32-vs-64-bitness.
11 //
12 // Client OSs
13 //
14 // Windows XP 32-bit VM ==> up to 13304 characters
15 //  - 13304x1 works, but 13305x1 fails instantly
16 // Windows 7 32-bit VM ==> between 16-17 thousand characters
17 //  - 16000x1 works, 17000x1 fails instantly
18 //  - 163x100 *crashes* conhost.exe but leaves VeryLargeRead.exe running
19 // Windows 8 32-bit VM ==> between 240-250 million characters
20 //  - 10000x24000 works, but 10000x25000 does not
21 // Windows 8.1 32-bit VM ==> between 240-250 million characters
22 //  - 10000x24000 works, but 10000x25000 does not
23 // Windows 10 64-bit VM ==> no limit (tested to 576 million characters)
24 //  - 24000x24000 works
25 //  - `ver` reports [Version 10.0.10240], conhost.exe and ConhostV1.dll are
26 //    10.0.10240.16384 for file and product version.  ConhostV2.dll is
27 //    10.0.10240.16391 for file and product version.
28 //
29 // Server OSs
30 //
31 // Windows Server 2008 64-bit VM ==> 14300-14400 characters
32 //  - 14300x1 works, 14400x1 fails instantly
33 //  - This OS does not have conhost.exe.
34 //  - `ver` reports [Version 6.0.6002]
35 // Windows Server 2008 R2 64-bit VM ==> 15600-15700 characters
36 //  - 15600x1 works, 15700x1 fails instantly
37 //  - This OS has conhost.exe, and procexp.exe reveals console ALPC ports in
38 //    use in conhost.exe.
39 //  - `ver` reports [Version 6.1.7601], conhost.exe is 6.1.7601.23153 for file
40 //    and product version.
41 // Windows Server 2012 64-bit VM ==> at least 100 million characters
42 //  - 10000x10000 works (VM had only 1GiB of RAM, so I skipped larger tests)
43 //  - This OS has Windows 8's task manager and procexp.exe reveals the same
44 //    lack of ALPC ports and the same \Device\ConDrv\* files as Windows 8.
45 //  - `ver` reports [Version 6.2.9200], conhost.exe is 6.2.9200.16579 for file
46 //    and product version.
47 //
48 // To summarize:
49 //
50 // client-OS    server-OS               notes
51 // ---------------------------------------------------------------------------
52 // XP           Server 2008             CSRSS, small reads
53 // 7            Server 2008 R2          ALPC-to-conhost, small reads
54 // 8, 8.1       Server 2012             new I/O interface, large reads allowed
55 // 10           <no server OS yet>      enhanced console w/rewrapping
56 //
57 // (Presumably, Win2K, Vista, and Win2K3 behave the same as XP.  conhost.exe
58 // was announced as a Win7 feature.)
59 //
60
61 #include <windows.h>
62 #include <assert.h>
63 #include <vector>
64
65 #include "TestUtil.cc"
66
67 int main(int argc, char *argv[]) {
68     long long width = 9000;
69     long long height = 9000;
70
71     assert(argc >= 1);
72     if (argc == 4) {
73         width = atoi(argv[2]);
74         height = atoi(argv[3]);
75     } else {
76         if (argc == 3) {
77             width = atoi(argv[1]);
78             height = atoi(argv[2]);
79         }
80         wchar_t args[1024];
81         swprintf(args, 1024, L"CHILD %lld %lld", width, height);
82         startChildProcess(args);
83         return 0;
84     }
85
86     const HANDLE conout = GetStdHandle(STD_OUTPUT_HANDLE);
87
88     setWindowPos(0, 0, 1, 1);
89     setBufferSize(width, height);
90     setWindowPos(0, 0, std::min(80LL, width), std::min(50LL, height));
91
92     setCursorPos(0, 0);
93     printf("A");
94     fflush(stdout);
95     setCursorPos(width - 2, height - 1);
96     printf("B");
97     fflush(stdout);
98
99     trace("sizeof(CHAR_INFO) = %d", (int)sizeof(CHAR_INFO));
100
101     trace("Allocating buffer...");
102     CHAR_INFO *buffer = new CHAR_INFO[width * height];
103     assert(buffer != NULL);
104     memset(&buffer[0], 0, sizeof(CHAR_INFO));
105     memset(&buffer[width * height - 2], 0, sizeof(CHAR_INFO));
106
107     COORD bufSize = { width, height };
108     COORD bufCoord = { 0, 0 };
109     SMALL_RECT readRegion = { 0, 0, width - 1, height - 1 };
110     trace("ReadConsoleOutputW: calling...");
111     BOOL success = ReadConsoleOutputW(conout, buffer, bufSize, bufCoord, &readRegion);
112     trace("ReadConsoleOutputW: success=%d", success);
113
114     assert(buffer[0].Char.UnicodeChar == L'A');
115     assert(buffer[width * height - 2].Char.UnicodeChar == L'B');
116     trace("Top-left and bottom-right characters read successfully!");
117
118     Sleep(30000);
119
120     delete [] buffer;
121     return 0;
122 }