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