1 /*
2  * reactos/apps/lpc/conport.c
3  *
4  * To be run in a real WNT 4.0 system with
5  * "\SmApiPort" as argument. Do not try to
6  * connect to "\Windows\ApiPort" since that
7  * reboots immeditely.
8  *
9  * Use Russinovich' HandleEx to verify
10  * conport.exe owns two unnamed LPC ports:
11  * the one created by kernel32.dll connecting
12  * to csrss.exe, and one connected to here.
13  *
14  * 19990627 (Emanuele Aliberti)
15  * 	Initial implementation.
16  * 19990704 (EA)
17  * 	Dump object's attributes moved in dumpinfo.c.
18  */
19 #include <windows.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #define PROTO_LPC
23 #include <ddk/ntddk.h>
24 #include "dumpinfo.h"
25 
26 #define LPC_CONNECT_FLAG1 0x00000001
27 #define LPC_CONNECT_FLAG2 0x00000010
28 #define LPC_CONNECT_FLAG3 0x00000100
29 #define LPC_CONNECT_FLAG4 0x00001000
30 #define LPC_CONNECT_FLAG5 0x00010000
31 
32 NTSTATUS
33 (WINAPI * ConnectPort)(
34 	OUT	PHANDLE			PortHandle,
35 	IN	PUNICODE_STRING		PortName,
36 	IN	POBJECT_ATTRIBUTES	ObjectAttributes,
37 	IN	DWORD	Unknown3,
38 	IN	DWORD	Unknown4,
39 	IN	DWORD	Unknown5,
40 	IN	DWORD	Unknown6,
41 	IN	ULONG	Flags
42 	);
43 
44 NTSTATUS
45 (WINAPI * QueryObject)(
46 	IN	HANDLE	ObjectHandle,
47 	IN	CINT	ObjectInformationClass,
48 	OUT	PVOID	ObjectInformation,
49 	IN	ULONG	Length,
50 	OUT	PULONG	ResultLength
51 	);
52 
53 NTSTATUS
54 (WINAPI * YieldExecution)(VOID);
55 
56 #define BUF_SIZE 1024
57 #define MAXARG   1000000
58 
59 
60 VOID
61 TryConnectPort(char *port_name)
62 {
63 	DWORD			Status = 0;
64 	HANDLE			Port = 0;
65 	int			i;
66 	UNICODE_STRING		PortName;
67 	OBJECT_ATTRIBUTES	ObjectAttributes;
68 	WORD			Name [BUF_SIZE] = {0};
69 	int			dwx = 0;
70 	char			* port_name_save = port_name;
71 
72 	/*
73 	 * Convert the port's name to Unicode.
74 	 */
75 	for (
76 		PortName.Length = 0;
77 		(	*port_name
78 			&& (PortName.Length < BUF_SIZE)
79 			);
80 		)
81 	{
82 		Name[PortName.Length++] = (WORD) *port_name++;
83 	}
84 	Name[PortName.Length] = 0;
85 
86 	PortName.Length = PortName.Length * sizeof (WORD);
87 	PortName.MaximumLength = PortName.Length + sizeof (WORD);
88 	PortName.Buffer = (PWSTR) Name;
89 	/*
90 	 * Prepare the port object attributes.
91 	 */
92 	ObjectAttributes.Length =
93 		sizeof (OBJECT_ATTRIBUTES);
94 	ObjectAttributes.RootDirectory =
95 		NULL;
96 	ObjectAttributes.ObjectName =
97 		NULL /*& PortName */;
98 	ObjectAttributes.Attributes =
99 		OBJ_CASE_INSENSITIVE;
100 	ObjectAttributes.SecurityDescriptor =
101 		NULL;
102 	ObjectAttributes.SecurityQualityOfService =
103 		NULL;
104 	/*
105 	 * Try to issue a connection request.
106 	 */
107 	Port = 0;
108 	Status = ConnectPort(
109 			& Port,			/* & PortHandle */
110 			& PortName,		/* & PortName */
111 			& ObjectAttributes,	/* & PortAttributes */
112 			NULL,			/* & SecurityQos */
113 			NULL,			/* & SectionInfo */
114 			NULL,			/* & MapInfo */
115 			NULL,			/* & MaxMessageSize */
116 			LPC_CONNECT_FLAG5	/* & ConnectInfoLength */
117 			);
118 	if (Status == STATUS_SUCCESS)
119 	{
120 		DumpInfo(
121 			Name,
122 			Status,
123 			"connected",
124 			Port
125 			);
126 		/* Hot waiting */
127 		for (dwx=0; dwx<MAXARG; ++dwx)
128 		{
129 			YieldExecution();
130 		}
131 		if (FALSE == CloseHandle(Port))
132 		{
133 			printf(
134 				"Could not close the port handle %08X.\n",
135 				Port
136 				);
137 		}
138 		return;
139 	}
140 	printf(
141 		"Connection to port \"%s\" failed (Status = %08X).\n",
142 		port_name_save,
143 		Status
144 		);
145 }
146 
147 
148 main( int argc, char * argv[] )
149 {
150 	HINSTANCE ntdll;
151 
152 	if (argc != 2)
153 	{
154 		printf("WNT LPC Port Connector\n");
155 		printf("Usage: %s [port_name]\n",argv[0]);
156 		exit(EXIT_FAILURE);
157 	}
158 	printf("LoadLibrary(NTDLL)\n");
159 	ntdll = LoadLibrary("NTDLL");
160 	if (ntdll == NULL)
161 	{
162 		printf("Could not load NTDLL\n");
163 		return EXIT_FAILURE;
164 	}
165 	printf("GetProcAddress(NTDLL.NtConnectPort)\n");
166 	ConnectPort = (VOID*) GetProcAddress(
167 					ntdll,
168 					"NtConnectPort"
169 					);
170 	if (ConnectPort == NULL)
171 	{
172 		FreeLibrary(ntdll);
173 		printf("Could not find NTDLL.NtConnectPort\n");
174 		return EXIT_FAILURE;
175 	}
176 	printf("GetProcAddress(NTDLL.NtQueryObject)\n");
177 	QueryObject = (VOID*) GetProcAddress(
178 					ntdll,
179 					"NtQueryObject"
180 					);
181 	if (QueryObject == NULL)
182 	{
183 		FreeLibrary(ntdll);
184 		printf("Could not find NTDLL.NtQueryObject\n");
185 		return EXIT_FAILURE;
186 	}
187 	printf("GetProcAddress(NTDLL.NtYieldExecution)\n");
188 	YieldExecution = (VOID*) GetProcAddress(
189 					ntdll,
190 					"NtYieldExecution"
191 					);
192 	if (YieldExecution == NULL)
193 	{
194 		FreeLibrary(ntdll);
195 		printf("Could not find NTDLL.NtYieldExecution\n");
196 		return EXIT_FAILURE;
197 	}
198 	printf("TryConnectPort(%s)\n",argv[1]);
199 	TryConnectPort(argv[1]);
200 	printf("Done\n");
201 	return EXIT_SUCCESS;
202 }
203 
204 /* EOF */
205