Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/programs/fsutil/tests/fsutil.c
4389 views
1
/*
2
* Copyright 2020 Arkadiusz Hiler for CodeWeavers
3
*
4
* This library is free software; you can redistribute it and/or
5
* modify it under the terms of the GNU Lesser General Public
6
* License as published by the Free Software Foundation; either
7
* version 2.1 of the License, or (at your option) any later version.
8
*
9
* This library is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
* Lesser General Public License for more details.
13
*
14
* You should have received a copy of the GNU Lesser General Public
15
* License along with this library; if not, write to the Free Software
16
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17
*/
18
19
#include <windows.h>
20
#include <stdio.h>
21
22
#include "wine/test.h"
23
24
static BOOL is_process_elevated(void)
25
{
26
HANDLE token;
27
if (OpenProcessToken( GetCurrentProcess(), TOKEN_QUERY, &token ))
28
{
29
TOKEN_ELEVATION_TYPE type;
30
DWORD size;
31
BOOL ret;
32
33
ret = GetTokenInformation( token, TokenElevationType, &type, sizeof(type), &size );
34
CloseHandle( token );
35
return (ret && type == TokenElevationTypeFull);
36
}
37
return FALSE;
38
}
39
40
static DWORD runcmd(const char* cmd)
41
{
42
STARTUPINFOA si = { sizeof(STARTUPINFOA) };
43
PROCESS_INFORMATION pi;
44
char* wcmd;
45
DWORD rc;
46
47
/* Create a writable copy for CreateProcessA() */
48
wcmd = strdup(cmd);
49
50
rc = CreateProcessA(NULL, wcmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
51
free(wcmd);
52
53
if (!rc)
54
return 260;
55
56
rc = WaitForSingleObject(pi.hProcess, 5000);
57
58
if (rc == WAIT_OBJECT_0)
59
GetExitCodeProcess(pi.hProcess, &rc);
60
else
61
TerminateProcess(pi.hProcess, 1);
62
63
CloseHandle(pi.hThread);
64
CloseHandle(pi.hProcess);
65
66
return rc;
67
}
68
69
static void test_hardlink(void)
70
{
71
DWORD rc;
72
BOOL boolrc;
73
HANDLE hfile;
74
BY_HANDLE_FILE_INFORMATION info;
75
76
hfile = CreateFileA("file", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
77
FILE_ATTRIBUTE_NORMAL, NULL);
78
ok(hfile != INVALID_HANDLE_VALUE, "failed to create a file\n");
79
CloseHandle(hfile);
80
81
rc = runcmd("fsutil");
82
if (rc == 1 && !is_process_elevated())
83
{
84
win_skip("Cannot run fsutil without elevated privileges on Windows <= 7\n");
85
return;
86
}
87
ok(rc == 0, "failed to run fsutil\n");
88
89
rc = runcmd("fsutil hardlink");
90
ok(rc == 0, "failed to run fsutil hardlink\n");
91
92
rc = runcmd("fsutil hardlink create link file");
93
ok(rc == 0, "failed to create a hardlink\n");
94
95
hfile = CreateFileA("link", GENERIC_READ, 0, NULL, OPEN_EXISTING,
96
FILE_ATTRIBUTE_NORMAL, NULL);
97
ok(hfile != INVALID_HANDLE_VALUE, "failed to open the hardlink\n");
98
boolrc = GetFileInformationByHandle(hfile, &info);
99
ok(boolrc, "failed to get info about hardlink, error %#lx\n", GetLastError());
100
CloseHandle(hfile);
101
102
ok(info.nNumberOfLinks == 2, "our link is not a hardlink\n");
103
104
rc = runcmd("fsutil hardlink create link file");
105
ok(rc == 1, "fsutil didn't complain about already existing destination\n");
106
107
rc = runcmd("fsutil hardlink create newlink nonexistingfile");
108
ok(rc == 1, "fsutil didn't complain about nonexisting source file\n");
109
110
boolrc = DeleteFileA("link");
111
ok(boolrc, "failed to delete the hardlink, error %#lx\n", GetLastError());
112
boolrc = DeleteFileA("file");
113
ok(boolrc, "failed to delete the file, error %#lx\n", GetLastError());
114
}
115
116
START_TEST(fsutil)
117
{
118
char tmpdir[MAX_PATH];
119
120
GetTempPathA(MAX_PATH, tmpdir);
121
SetCurrentDirectoryA(tmpdir);
122
123
test_hardlink();
124
}
125
126