Hello Arkadiusz;
This patch looks in relatively good shape to me; I have a few comments and nitpicks inlined.
On 8/4/20 10:05 AM, Arkadiusz Hiler wrote:
From: Micheal Müller michael@fds-team.de
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=22749 Signed-off-by: Vijay Kiran Kamuju infyquest@gmail.com Signed-off-by: Arkadiusz Hiler ahiler@codeweavers.com
configure | 1 + configure.ac | 1 + programs/fsutil/fsutil.mc | 14 +++- programs/fsutil/main.c | 57 ++++++++++++++++- programs/fsutil/resources.h | 2 + programs/fsutil/tests/Makefile.in | 5 ++ programs/fsutil/tests/fsutil.c | 102 ++++++++++++++++++++++++++++++ 7 files changed, 179 insertions(+), 3 deletions(-) create mode 100644 programs/fsutil/tests/Makefile.in create mode 100644 programs/fsutil/tests/fsutil.c
diff --git a/configure b/configure index 244b66545e..7155852589 100755 --- a/configure +++ b/configure @@ -21417,6 +21417,7 @@ wine_fn_config_makefile programs/find enable_find wine_fn_config_makefile programs/find/tests enable_tests wine_fn_config_makefile programs/findstr enable_findstr wine_fn_config_makefile programs/fsutil enable_fsutil +wine_fn_config_makefile programs/fsutil/tests enable_tests wine_fn_config_makefile programs/hh enable_hh wine_fn_config_makefile programs/hostname enable_hostname wine_fn_config_makefile programs/icacls enable_icacls diff --git a/configure.ac b/configure.ac index 47d0471169..8e60ea315b 100644 --- a/configure.ac +++ b/configure.ac @@ -3962,6 +3962,7 @@ WINE_CONFIG_MAKEFILE(programs/find) WINE_CONFIG_MAKEFILE(programs/find/tests) WINE_CONFIG_MAKEFILE(programs/findstr) WINE_CONFIG_MAKEFILE(programs/fsutil) +WINE_CONFIG_MAKEFILE(programs/fsutil/tests) WINE_CONFIG_MAKEFILE(programs/hh) WINE_CONFIG_MAKEFILE(programs/hostname) WINE_CONFIG_MAKEFILE(programs/icacls) diff --git a/programs/fsutil/fsutil.mc b/programs/fsutil/fsutil.mc index 54c801cb2b..e904bb8644 100644 --- a/programs/fsutil/fsutil.mc +++ b/programs/fsutil/fsutil.mc @@ -23,5 +23,17 @@ SymbolicName=STRING_USAGE Language=ENU
- Supported Commands -
-[NONE] +hardlink hardlink management +. +MessageId=102 +SymbolicName=STRING_HARDLINK_USAGE +Language=ENU +- Hardlink - Supported Commands -
+create create a hardlink +. +MessageId=103 +SymbolicName=STRING_HARDLINK_CREATE_USAGE +Language=ENU +Syntax: fsutil hardlink create <new> <existing> . diff --git a/programs/fsutil/main.c b/programs/fsutil/main.c index 1d61edab75..0357d50d23 100644 --- a/programs/fsutil/main.c +++ b/programs/fsutil/main.c @@ -66,6 +66,54 @@ static int WINAPIV output_string(int msg, ...) return 0; }
+static BOOL output_error_string(DWORD error) +{
- LPWSTR pBuffer;
- if (FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_ALLOCATE_BUFFER,
NULL, error, 0, (LPWSTR)&pBuffer, 0, NULL))
- {
output_write(pBuffer, lstrlenW(pBuffer));
LocalFree(pBuffer);
return TRUE;
- }
- return FALSE;
+}
+static int create_hardlink(int argc, WCHAR *argv[]) +{
- if (argc != 5)
- {
output_string(STRING_HARDLINK_CREATE_USAGE);
return 1;
- }
- if (CreateHardLinkW(argv[3], argv[4], NULL))
return 0;
- output_error_string(GetLastError());
- return 1;
+}
+static int hardlink(int argc, WCHAR *argv[]) +{
- int ret;
- if (argc > 2)
- {
if (!_wcsicmp(argv[2], L"create"))
I think we can drop the underscore here; I'm not sure if it appears elsewhere but it's a historical artifact if so.
return create_hardlink(argc, argv);
else
{
FIXME("unsupported parameter %s\n", debugstr_w(argv[2]));
ret = 1;
}
- }
- output_string(STRING_HARDLINK_USAGE);
- return ret;
+}
int __cdecl wmain(int argc, WCHAR *argv[]) { int i, ret = 0; @@ -77,8 +125,13 @@ int __cdecl wmain(int argc, WCHAR *argv[])
if (argc > 1) {
FIXME("unsupported command %s\n", debugstr_w(argv[1]));
ret = 1;
if (!wcsicmp(argv[1], L"hardlink"))
return hardlink(argc, argv);
else
{
FIXME("unsupported command %s\n", debugstr_w(argv[1]));
ret = 1;
}
}
output_string(STRING_USAGE);
diff --git a/programs/fsutil/resources.h b/programs/fsutil/resources.h index 36b0ffc35f..56280d958a 100644 --- a/programs/fsutil/resources.h +++ b/programs/fsutil/resources.h @@ -19,3 +19,5 @@ #include <windef.h>
#define STRING_USAGE 101 +#define STRING_HARDLINK_USAGE 102 +#define STRING_HARDLINK_CREATE_USAGE 103 diff --git a/programs/fsutil/tests/Makefile.in b/programs/fsutil/tests/Makefile.in new file mode 100644 index 0000000000..5a69e47dc6 --- /dev/null +++ b/programs/fsutil/tests/Makefile.in @@ -0,0 +1,5 @@ +TESTDLL = fsutil.exe +IMPORTS = user32
+C_SRCS = \
- fsutil.c
diff --git a/programs/fsutil/tests/fsutil.c b/programs/fsutil/tests/fsutil.c new file mode 100644 index 0000000000..931c0a0cd6 --- /dev/null +++ b/programs/fsutil/tests/fsutil.c @@ -0,0 +1,102 @@ +/*
- 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 DWORD runcmd(const char* cmd) +{
- STARTUPINFOA si = { sizeof(STARTUPINFOA) };
- PROCESS_INFORMATION pi;
- char* wcmd;
- DWORD rc;
- /* Create a writable copy for CreateProcessA() */
- wcmd = HeapAlloc(GetProcessHeap(), 0, strlen(cmd) + 1);
- strcpy(wcmd, cmd);
- rc = CreateProcessA(NULL, wcmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
- HeapFree(GetProcessHeap(), 0, 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;
- 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");
- if (hfile == INVALID_HANDLE_VALUE)
- {
skip("skipping hardlink tests\n");
return;
- }
I'm personally of the opinion that these kinds of checks aren't particularly useful—if a test fails, that's already a problem and needs to be addressed.
- CloseHandle(hfile);
- 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");
- ok(GetFileInformationByHandle(hfile, &info), "faile to get info about hardlink\n");
Not particularly important, but printing the output of GetLastError() is often useful in case the test does ever fail. (Note that in that case you'll also have to move GetFileInformationByHandle() to its own line.)
- CloseHandle(hfile);
- ok(info.nNumberOfLinks == 2, "our link is not a hardlink");
- rc = runcmd("fsutil hardlink create link file");
- ok(rc != 0, "fsutil didn't complain about already existing destination\n");
Should we test the exact value of "rc" here?
- rc = runcmd("fsutil hardlink create newlink nonexistingfile");
- ok(rc != 0, "fsutil didn't complain about nonexisting source file\n");
- DeleteFileA("link");
- DeleteFileA("file");
Generally not a bad idea to check for success from DeleteFile, I think.
+}
+START_TEST(fsutil) +{
- char tmpdir[MAX_PATH];
- GetTempPathA(MAX_PATH, tmpdir);
- SetCurrentDirectoryA(tmpdir);
- trace("%s\n", tmpdir);
Is this trace() message doing anything particularly useful?
- test_hardlink();
+}