1 /*
2  * PROJECT:         ReactOS api tests
3  * LICENSE:         GPLv2+ - See COPYING in the top level directory
4  * PURPOSE:         Test for GetModuleFileName
5  * PROGRAMMER:      Thomas Faber <thomas.faber@reactos.org>
6  */
7 
8 #include "precomp.h"
9 
10 #include <shlwapi.h>
11 
12 static
13 VOID
14 StartChild(char **argv)
15 {
16     BOOL Success;
17     WCHAR Path[MAX_PATH];
18     PWSTR FileName;
19     PWSTR Slash;
20     WCHAR CommandLine[MAX_PATH];
21     STARTUPINFOW StartupInfo;
22     PROCESS_INFORMATION ProcessInfo;
23     DWORD Ret;
24     int Length;
25 
26     Length = MultiByteToWideChar(CP_ACP,
27                                  0,
28                                  argv[0],
29                                  -1,
30                                  Path,
31                                  sizeof(Path) / sizeof(WCHAR));
32     ok(Length > 0, "Length = %d\n", Length);
33 
34     FileName = wcsrchr(Path, '\\');
35     Slash = wcsrchr(Path, L'/');
36     if (Slash && (!FileName || Slash > FileName))
37         FileName = Slash;
38 
39     if (FileName)
40     {
41         /* It's an absolute path. Set it as current dir and get the file name */
42         FileName++;
43         FileName[-1] = L'\0';
44 
45         Success = SetCurrentDirectoryW(Path);
46         ok(Success == TRUE, "SetCurrentDirectory failed for path '%ls'\n", Path);
47 
48         trace("Starting '%ls' in path '%ls'\n", FileName, Path);
49     }
50     else
51     {
52         FileName = Path;
53         trace("Starting '%ls', which is already relative\n", FileName);
54     }
55 
56     swprintf(CommandLine, L"\"%ls\" GetModuleFileName relative", FileName);
57 
58     RtlZeroMemory(&StartupInfo, sizeof(StartupInfo));
59     StartupInfo.cb = sizeof(StartupInfo);
60 
61     Success = CreateProcessW(FileName,
62                              CommandLine,
63                              NULL,
64                              NULL,
65                              FALSE,
66                              0,
67                              NULL,
68                              NULL,
69                              &StartupInfo,
70                              &ProcessInfo);
71     if (!Success)
72     {
73         skip("CreateProcess failed with %lu\n", GetLastError());
74         return;
75     }
76     CloseHandle(ProcessInfo.hThread);
77     Ret = WaitForSingleObject(ProcessInfo.hProcess, 30 * 1000);
78     ok(Ret == WAIT_OBJECT_0, "WaitForSingleObject returns %lu\n", Ret);
79     CloseHandle(ProcessInfo.hProcess);
80 }
81 
82 static
83 VOID
84 TestGetModuleFileNameA(VOID)
85 {
86     CHAR Buffer[MAX_PATH];
87     DWORD Length;
88     BOOL Relative;
89 
90     Length = GetModuleFileNameA(NULL, Buffer, sizeof(Buffer));
91     ok(Length != 0, "Length = %lu\n", Length);
92     ok(Length < sizeof(Buffer), "Length = %lu\n", Length);
93     ok(Buffer[Length] == 0, "Buffer not null terminated\n");
94     Relative = PathIsRelativeA(Buffer);
95     ok(Relative == FALSE, "GetModuleFileNameA returned relative path: %s\n", Buffer);
96 }
97 
98 static
99 VOID
100 TestGetModuleFileNameW(VOID)
101 {
102     WCHAR Buffer[MAX_PATH];
103     DWORD Length;
104     BOOL Relative;
105 
106     Length = GetModuleFileNameW(NULL, Buffer, sizeof(Buffer) / sizeof(WCHAR));
107     ok(Length != 0, "Length = %lu\n", Length);
108     ok(Length < sizeof(Buffer) / sizeof(WCHAR), "Length = %lu\n", Length);
109     ok(Buffer[Length] == 0, "Buffer not null terminated\n");
110     Relative = PathIsRelativeW(Buffer);
111     ok(Relative == FALSE, "GetModuleFileNameW returned relative path: %ls\n", Buffer);
112 }
113 
114 START_TEST(GetModuleFileName)
115 {
116     int argc;
117     char **argv;
118 
119     argc = winetest_get_mainargs(&argv);
120     if (argc < 3)
121         StartChild(argv);
122     else
123     {
124         TestGetModuleFileNameA();
125         TestGetModuleFileNameW();
126     }
127 }
128