File: fsutil.c

package info (click to toggle)
wine 10.0~repack-12
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 326,476 kB
  • sloc: ansic: 4,155,993; perl: 23,800; yacc: 22,031; javascript: 15,872; makefile: 12,346; pascal: 9,519; objc: 6,923; lex: 5,273; xml: 3,219; python: 2,688; cpp: 1,741; sh: 871; java: 750; asm: 299; cs: 62
file content (124 lines) | stat: -rw-r--r-- 3,717 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
/*
 * Copyright 2020 Arkadiusz Hiler for CodeWeavers
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include <windows.h>
#include <stdio.h>

#include "wine/test.h"

static BOOL is_process_elevated(void)
{
    HANDLE token;
    if (OpenProcessToken( GetCurrentProcess(), TOKEN_QUERY, &token ))
    {
        TOKEN_ELEVATION_TYPE type;
        DWORD size;
        BOOL ret;

        ret = GetTokenInformation( token, TokenElevationType, &type, sizeof(type), &size );
        CloseHandle( token );
        return (ret && type == TokenElevationTypeFull);
    }
    return FALSE;
}

static DWORD runcmd(const char* cmd)
{
    STARTUPINFOA si = { sizeof(STARTUPINFOA) };
    PROCESS_INFORMATION pi;
    char* wcmd;
    DWORD rc;

    /* Create a writable copy for CreateProcessA() */
    wcmd = strdup(cmd);

    rc = CreateProcessA(NULL, wcmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
    free(wcmd);

    if (!rc)
        return 260;

    rc = WaitForSingleObject(pi.hProcess, 5000);

    if (rc == WAIT_OBJECT_0)
        GetExitCodeProcess(pi.hProcess, &rc);
    else
        TerminateProcess(pi.hProcess, 1);

    CloseHandle(pi.hThread);
    CloseHandle(pi.hProcess);

    return rc;
}

static void test_hardlink(void)
{
    DWORD rc;
    BOOL boolrc;
    HANDLE hfile;
    BY_HANDLE_FILE_INFORMATION info;

    hfile = CreateFileA("file", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
                        FILE_ATTRIBUTE_NORMAL, NULL);
    ok(hfile != INVALID_HANDLE_VALUE, "failed to create a file\n");
    CloseHandle(hfile);

    rc = runcmd("fsutil");
    if (rc == 1 && !is_process_elevated())
    {
        win_skip("Cannot run fsutil without elevated privileges on Windows <= 7\n");
        return;
    }
    ok(rc == 0, "failed to run fsutil\n");

    rc = runcmd("fsutil hardlink");
    ok(rc == 0, "failed to run fsutil hardlink\n");

    rc = runcmd("fsutil hardlink create link file");
    ok(rc == 0, "failed to create a hardlink\n");

    hfile = CreateFileA("link", GENERIC_READ, 0, NULL, OPEN_EXISTING,
                        FILE_ATTRIBUTE_NORMAL, NULL);
    ok(hfile != INVALID_HANDLE_VALUE, "failed to open the hardlink\n");
    boolrc = GetFileInformationByHandle(hfile, &info);
    ok(boolrc, "failed to get info about hardlink, error %#lx\n", GetLastError());
    CloseHandle(hfile);

    ok(info.nNumberOfLinks == 2, "our link is not a hardlink\n");

    rc = runcmd("fsutil hardlink create link file");
    ok(rc == 1, "fsutil didn't complain about already existing destination\n");

    rc = runcmd("fsutil hardlink create newlink nonexistingfile");
    ok(rc == 1, "fsutil didn't complain about nonexisting source file\n");

    boolrc = DeleteFileA("link");
    ok(boolrc, "failed to delete the hardlink, error %#lx\n", GetLastError());
    boolrc = DeleteFileA("file");
    ok(boolrc, "failed to delete the file, error %#lx\n", GetLastError());
}

START_TEST(fsutil)
{
    char tmpdir[MAX_PATH];

    GetTempPathA(MAX_PATH, tmpdir);
    SetCurrentDirectoryA(tmpdir);

    test_hardlink();
}