1// Licensed to the .NET Foundation under one or more agreements.
2// The .NET Foundation licenses this file to you under the MIT license.
3// See the LICENSE file in the project root for more information.
4
5/*============================================================
6**
7** Source: CreateProcessW/test1/parentprocess.c
8**
9** Purpose: Test to ensure CreateProcessW starts a new process. This test
10** launches a child process, and examines a file written by the child.
11** This process (the parent process) reads the file created by the child and
12** compares the value the child wrote to the file. (a const char *)
13**
14** Dependencies: GetCurrentDirectory
15** MultiByteToWideChar
16** wcslen
17** strlen
18** WideCharToMultiByte
19** WaitForSingleObject
20** fopen
21** fclose
22** Fail
23**
24
25**
26**=========================================================*/
27
28#define UNICODE
29#include <palsuite.h>
30
31const WCHAR szCommonFileW[] =
32 {'c','h','i','l','d','d','a','t','a','.','t','m','p','\0'};
33
34const WCHAR szChildFileW[] = u"paltest_createprocessw_test1_child";
35
36const WCHAR szPathDelimW[] = {'\\','\0'};
37
38const char *szCommonStringA = "058d2d057111a313aa82401c2e856002\0";
39
40/*
41 * Take two wide strings representing file and directory names
42 * (dirName, fileName), join the strings with the appropriate path
43 * delimiter and populate a wide character buffer (absPathName) with
44 * the resulting string.
45 *
46 * Returns: The number of wide characters in the resulting string.
47 * 0 is returned on Error.
48 */
49int
50mkAbsoluteFilenameW (
51 LPWSTR dirName,
52 DWORD dwDirLength,
53 LPCWSTR fileName,
54 DWORD dwFileLength,
55 LPWSTR absPathName )
56{
57 extern const WCHAR szPathDelimW[];
58
59 DWORD sizeDN, sizeFN, sizeAPN;
60
61 sizeDN = wcslen( dirName );
62 sizeFN = wcslen( fileName );
63 sizeAPN = (sizeDN + 1 + sizeFN + 1);
64
65 /* insure ((dirName + DELIM + fileName + \0) =< _MAX_PATH ) */
66 if ( sizeAPN > _MAX_PATH )
67 {
68 return ( 0 );
69 }
70
71 wcsncpy(absPathName, dirName, dwDirLength +1);
72 wcsncpy(absPathName, szPathDelimW, 2);
73 wcsncpy(absPathName, fileName, dwFileLength +1);
74
75 return (sizeAPN);
76
77}
78
79int __cdecl main( int argc, char **argv )
80
81{
82
83 STARTUPINFOW si;
84 PROCESS_INFORMATION pi;
85
86 static FILE * fp;
87
88 DWORD dwFileLength;
89 DWORD dwDirLength;
90 DWORD dwSize;
91
92 size_t cslen;
93
94 char szReadStringA[256];
95
96 char szAbsPathNameA[_MAX_PATH];
97 WCHAR szDirNameW[_MAX_DIR];
98 WCHAR absPathBuf[_MAX_PATH];
99 WCHAR *szAbsPathNameW;
100
101
102 if(0 != (PAL_Initialize(argc, argv)))
103 {
104 return ( FAIL );
105 }
106
107 ZeroMemory ( &si, sizeof(si) );
108 si.cb = sizeof(si);
109 ZeroMemory ( &pi, sizeof(pi) );
110
111 szAbsPathNameW=&absPathBuf[0];
112 dwFileLength = wcslen( szChildFileW );
113
114 dwDirLength = GetCurrentDirectory(_MAX_PATH, szDirNameW);
115
116 if (0 == dwDirLength)
117 {
118 Fail ("GetCurrentDirectory call failed. Could not get "
119 "current working directory\n. Exiting.\n");
120 }
121
122 dwSize = mkAbsoluteFilenameW( szDirNameW, dwDirLength, szChildFileW,
123 dwFileLength, szAbsPathNameW );
124
125 if (0 == dwSize)
126 {
127 Fail ("Palsuite Code: mkAbsoluteFilename() call failed. Could "
128 "not build absolute path name to file\n. Exiting.\n");
129 }
130
131 if ( !CreateProcessW ( NULL,
132 szAbsPathNameW,
133 NULL,
134 NULL,
135 FALSE,
136 CREATE_NEW_CONSOLE,
137 NULL,
138 NULL,
139 &si,
140 &pi )
141 )
142 {
143 Fail ( "CreateProcess call failed. GetLastError returned %d\n",
144 GetLastError() );
145 }
146
147 WaitForSingleObject ( pi.hProcess, INFINITE );
148
149 szAbsPathNameW=&absPathBuf[0];
150
151 dwFileLength = wcslen( szCommonFileW );
152
153 dwSize = mkAbsoluteFilenameW( szDirNameW, dwDirLength, szCommonFileW,
154 dwFileLength, szAbsPathNameW );
155
156 /* set the string length for the open call*/
157
158 if (0 == dwSize)
159 {
160 Fail ("Palsuite Code: mkAbsoluteFilename() call failed. Could "
161 "not build absolute path name to file\n. Exiting.\n");
162 }
163
164 WideCharToMultiByte (CP_ACP, 0, szAbsPathNameW, -1, szAbsPathNameA,
165 (dwSize + 1), NULL, NULL);
166
167 if ( NULL == ( fp = fopen ( szAbsPathNameA , "r" ) ) )
168 {
169 Fail ("%s\nunable to open %s\nfor reading. Exiting.\n", argv[0],
170 szAbsPathNameA );
171 }
172
173 cslen = strlen ( szCommonStringA );
174
175 if ( NULL == fgets( szReadStringA, (cslen + 1), fp ))
176 {
177 /*
178 * A return value of NULL indicates an error condition or an
179 * EOF condition
180 */
181 Fail ("%s\nunable to read file\n%s\nszReadStringA is %s\n"
182 "Exiting.\n", argv[0], szAbsPathNameA,
183 szReadStringA );
184 }
185
186 if ( 0 != strncmp( szReadStringA, szCommonStringA, cslen ))
187 {
188 Fail ("string comparison failed.\n szReadStringA is %s and\n"
189 "szCommonStringA is %s\n", szReadStringA,
190 szCommonStringA );
191 }
192 else
193 {
194 Trace ("string comparison passed.\n");
195 }
196
197 if (0 != (fclose ( fp )))
198 {
199 Trace ("%s unable to close file %s. This may cause a file pointer "
200 "leak. Continuing.\n", argv[0], szAbsPathNameA );
201 }
202
203 /* Close process and thread handle */
204 CloseHandle ( pi.hProcess );
205 CloseHandle ( pi.hThread );
206
207 PAL_Terminate();
208 return ( PASS );
209
210}
211