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: CreateProcessA/test1/parentprocess.c
8**
9** Purpose: Test to ensure CreateProcessA 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** strlen
16** WaitForSingleObject
17** fopen
18** fclose
19** Fail
20**
21
22**
23**=========================================================*/
24
25#include <palsuite.h>
26
27const char *szCommonFileA = "childdata.tmp";
28
29const char *szChildFileA = "paltest_createprocessa_test1_child";
30
31const char *szPathDelimA = "\\";
32
33const char *szCommonStringA = "058d2d057111a313aa82401c2e856002\0";
34
35/*
36 * Take two wide strings representing file and directory names
37 * (dirName, fileName), join the strings with the appropriate path
38 * delimiter and populate a wide character buffer (absPathName) with
39 * the resulting string.
40 *
41 * Returns: The number of wide characters in the resulting string.
42 * 0 is returned on Error.
43 */
44int
45mkAbsoluteFilenameA (
46 LPSTR dirName,
47 DWORD dwDirLength,
48 LPCSTR fileName,
49 DWORD dwFileLength,
50 LPSTR absPathName )
51{
52 extern const char *szPathDelimA;
53
54 DWORD sizeDN, sizeFN, sizeAPN;
55
56 sizeDN = strlen( dirName );
57 sizeFN = strlen( fileName );
58 sizeAPN = (sizeDN + 1 + sizeFN + 1);
59
60 /* insure ((dirName + DELIM + fileName + \0) =< _MAX_PATH ) */
61 if ( sizeAPN > _MAX_PATH )
62 {
63 return ( 0 );
64 }
65
66 strncpy(absPathName, dirName, dwDirLength +1);
67 strncpy(absPathName, szPathDelimA, 2);
68 strncpy(absPathName, fileName, dwFileLength +1);
69
70 return (sizeAPN);
71
72}
73
74int __cdecl main( int argc, char **argv )
75
76{
77
78 STARTUPINFO si;
79 PROCESS_INFORMATION pi;
80
81 static FILE * fp;
82
83 DWORD dwFileLength;
84 DWORD dwDirLength;
85 DWORD dwSize;
86
87 size_t cslen;
88
89 char szReadStringA[256];
90
91 char szDirNameA[_MAX_DIR];
92 char absPathBuf[_MAX_PATH];
93 char *szAbsPathNameA;
94
95
96 if(0 != (PAL_Initialize(argc, argv)))
97 {
98 return ( FAIL );
99 }
100
101 ZeroMemory ( &si, sizeof(si) );
102 si.cb = sizeof(si);
103 ZeroMemory ( &pi, sizeof(pi) );
104
105 szAbsPathNameA=&absPathBuf[0];
106 dwFileLength = strlen( szChildFileA );
107
108 dwDirLength = GetCurrentDirectory(_MAX_PATH, szDirNameA);
109
110 if (0 == dwDirLength)
111 {
112 Fail ("GetCurrentDirectory call failed. Could not get "
113 "current working directory\n. Exiting.\n");
114 }
115
116 dwSize = mkAbsoluteFilenameA( szDirNameA, dwDirLength, szChildFileA,
117 dwFileLength, szAbsPathNameA );
118
119 if (0 == dwSize)
120 {
121 Fail ("Palsuite Code: mkAbsoluteFilename() call failed. Could "
122 "not build absolute path name to file\n. Exiting.\n");
123 }
124
125 if ( !CreateProcessA ( NULL,
126 szAbsPathNameA,
127 NULL,
128 NULL,
129 FALSE,
130 CREATE_NEW_CONSOLE,
131 NULL,
132 NULL,
133 &si,
134 &pi )
135 )
136 {
137 Fail ( "CreateProcess call failed. GetLastError returned %d\n",
138 GetLastError() );
139 }
140
141 WaitForSingleObject ( pi.hProcess, INFINITE );
142
143 szAbsPathNameA=&absPathBuf[0];
144
145 dwFileLength = strlen( szCommonFileA );
146
147 dwSize = mkAbsoluteFilenameA( szDirNameA, dwDirLength, szCommonFileA,
148 dwFileLength, szAbsPathNameA );
149
150 /* set the string length for the open call*/
151
152 if (0 == dwSize)
153 {
154 Fail ("Palsuite Code: mkAbsoluteFilename() call failed. Could "
155 "not build absolute path name to file\n. Exiting.\n");
156 }
157
158 if ( NULL == ( fp = fopen ( szAbsPathNameA , "r" ) ) )
159 {
160 Fail ("%s\nunable to open %s\nfor reading. Exiting.\n", argv[0],
161 szAbsPathNameA );
162 }
163
164 cslen = strlen ( szCommonStringA );
165
166 if ( NULL == fgets( szReadStringA, (cslen + 1), fp ))
167 {
168 /*
169 * A return value of NULL indicates an error condition or an
170 * EOF condition
171 */
172 Fail ("%s\nunable to read file\n%s\nszReadStringA is %s\n"
173 "Exiting.\n", argv[0], szAbsPathNameA,
174 szReadStringA );
175
176 }
177 if ( 0 != strncmp( szReadStringA, szCommonStringA, cslen ))
178 {
179 Fail ("string comparison failed.\n szReadStringA is %s and\n"
180 "szCommonStringA is %s\n", szReadStringA,
181 szCommonStringA );
182 }
183 else
184 {
185 Trace ("string comparison passed.\n");
186 }
187
188 if (0 != (fclose ( fp )))
189 {
190 Trace ("%s unable to close file %s. This may cause a file pointer "
191 "leak. Continuing.\n", argv[0], szAbsPathNameA );
192 }
193
194 /* Close process and thread handle */
195 CloseHandle ( pi.hProcess );
196 CloseHandle ( pi.hThread );
197
198 PAL_Terminate();
199 return ( PASS );
200
201}
202