source: release/1.4/aux/cocotron/win32/cocotron/WaltConsole/WaltConsole.c

Last change on this file was 12824, checked in by Gary Byers, 15 years ago

moved here

File size: 4.5 KB
Line 
1#include <windows.h>
2#include <psapi.h>
3#include <stdio.h>
4#include <string.h>
5
6
7struct ProcessBasicInformation {
8 DWORD ExitStatus;
9 PVOID PebBaseAddress;
10 DWORD AffinityMask;
11 DWORD BasePriority;
12 ULONG UniqueProcessId;
13 ULONG InheritedFromUniqueProcessId;
14};
15
16/* Try to get the (Windows) pid of the parent process; return it, or
17 return 0 on failure. There doesn't seem to be a higher-level way
18 to do this.
19*/
20
21typedef LONG (__stdcall *FPTR_NtQueryInformationProcess ) (HANDLE, INT, PVOID, ULONG, PULONG);
22
23ULONG
24getppid()
25{
26 ULONG ppid = 0, pid = GetCurrentProcessId();
27 HANDLE hcurrent = OpenProcess(PROCESS_QUERY_INFORMATION,FALSE,pid);
28 if (hcurrent) {
29 FPTR_NtQueryInformationProcess NtQueryInformationProcess = (FPTR_NtQueryInformationProcess) GetProcAddress(GetModuleHandleA("ntdll"), "NtQueryInformationProcess");
30 if (NtQueryInformationProcess != NULL) {
31 struct ProcessBasicInformation pbi;
32 if (NtQueryInformationProcess(hcurrent, 0, (void *)&pbi, sizeof(pbi), NULL) == 0) {
33 ppid = pbi.InheritedFromUniqueProcessId;
34 }
35 }
36 CloseHandle(hcurrent);
37 }
38 return ppid;
39}
40
41char *
42parent_process_name(ULONG ppid)
43{
44 char procname[1024], *result = NULL;
45 DWORD namelen;
46 HANDLE hprocess = OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ, FALSE, ppid);
47
48 if (hprocess) {
49 namelen = GetModuleBaseNameA(hprocess, NULL, procname, sizeof(procname)-1);
50 if (namelen && (namelen <= sizeof(procname))) {
51 result = strdup(procname);
52 }
53 CloseHandle(hprocess);
54 }
55 return result;
56}
57
58
59int
60write_pending_console_input(HANDLE input, HANDLE output)
61{
62 DWORD ninput_events, i, n, nread, nwritten;
63 char buf[1024];
64 INPUT_RECORD ir;
65
66 switch (WaitForSingleObject(input, 100)) {
67 case WAIT_TIMEOUT:
68 return 0;
69 break;
70 case WAIT_OBJECT_0:
71 ninput_events = 0;
72 if (GetNumberOfConsoleInputEvents(input, &ninput_events)) {
73 for (i = 0; i < ninput_events; i++) {
74 PeekConsoleInput(input, &ir, 1, &n);
75 if ((ir.EventType == KEY_EVENT)) {
76 if (!ReadFile(input, buf, sizeof(buf), &nread, NULL)) {
77 return -1;
78 }
79 if (!WriteFile(output, buf, nread, &nwritten, NULL)) {
80 return -1;
81 }
82 return 0;
83 } else {
84 ReadConsoleInput(input, &ir, 1, &n);
85 }
86 }
87 }
88 return 0;
89 break;
90
91 default:
92 return -1;
93 break;
94 }
95}
96
97
98int
99write_pipe_input_to_console(HANDLE hpipe, HANDLE conout)
100{
101 unsigned char buf[1024];
102 DWORD navail, n, m;
103
104 while (PeekNamedPipe(hpipe, NULL, 0, NULL, &navail, NULL) != 0) {
105 if (navail == 0) {
106 return 0;
107 }
108 if (navail > sizeof(buf)) {
109 n = sizeof(buf);
110 } else {
111 n = navail;
112 }
113 if (!ReadFile(hpipe, buf, n, &m, NULL)) {
114 return -1;
115 }
116 if (!WriteFile(conout, buf, m, &n, NULL)) {
117 return -1;
118 }
119 }
120 return -1;
121}
122
123int APIENTRY WinMain(HINSTANCE a,HINSTANCE b,LPSTR c,int d)
124{
125 HANDLE in, out, conin, conout, hppid;
126 DWORD navail, err, exitcode;
127 ULONG ppid;
128 HWND window;
129 HMENU menu;
130 char title[2048], *procname, buf[1024];
131
132 in = GetStdHandle(STD_INPUT_HANDLE);
133 out = GetStdHandle(STD_OUTPUT_HANDLE);
134
135 while (1) {
136 navail = 0;
137 if (PeekNamedPipe(in, NULL, 0, NULL, &navail, NULL) == 0) {
138 exit(0); /* error or EOF */
139 }
140 if (navail != 0) {
141 break;
142 }
143 Sleep(100);
144 }
145
146 AllocConsole();
147
148 conin = CreateFileA("CONIN$",GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
149 conout = CreateFileA("CONOUT$",GENERIC_WRITE,FILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
150
151 ppid = getppid();
152 procname = parent_process_name(ppid);
153 hppid = OpenProcess(PROCESS_QUERY_INFORMATION|SYNCHRONIZE,FALSE,ppid);
154 if (!procname) {
155 procname = "<Unknown>";
156 }
157 sprintf(title, "WaltConsole for %s (pid 0x%x)", procname, ppid);
158 SetConsoleTitleA(title);
159
160 window = GetConsoleWindow();
161 menu = GetSystemMenu(window, FALSE);
162 EnableMenuItem(menu, SC_CLOSE, MF_BYCOMMAND|MF_GRAYED);
163
164 ShowWindow(window, SW_SHOW);
165 ShowWindow(window, SW_SHOW);
166
167 do {
168 if (WaitForSingleObject(hppid, 0) == WAIT_OBJECT_0) {
169 break;
170 }
171 if (write_pipe_input_to_console(in, conout) < 0) {
172 break;
173 }
174 write_pending_console_input(conin, out);
175 } while (1);
176
177 EnableMenuItem(menu, SC_CLOSE, MF_BYCOMMAND|MF_ENABLED);
178 sprintf(buf,"\n\nProcess %s (pid 0x%x) has exited; press any key to close this window.", procname, ppid);
179 WriteFile(conout, buf, strlen(buf), &navail, NULL);
180 FlushConsoleInputBuffer(conin);
181 ReadConsoleA(conin,buf,1,&navail,NULL);
182
183}
Note: See TracBrowser for help on using the repository browser.