吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 954|回复: 7
收起左侧

[C&C++ 原创] 修改文件目录时间的代码-touch

[复制链接]
go4399 发表于 2023-11-14 11:09
本帖最后由 go4399 于 2023-11-14 11:11 编辑

使用与linux下touch一致,部分功能没有实现。支持命令行下通配符,如touch *.*

// touch.c
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>

int _dowildcard = 1; // 1 = support wildcard, 0 = not

#define CH_ATIME 1
#define CH_MTIME 2
#define CH_CTIME 4

#define TM_SET 8

static int change_times = 0;
static FILETIME atime;
static FILETIME ctime;
static FILETIME mtime;

void usage()
{
fputws(L"Usage: touch [OPTION]... FILE...\n", stdout);
fputws(L"Update the access and modification times of each FILE to the current time.\n\n\
Mandatory arguments to long options are mandatory for short options too.\n\
  -a                     change only the access time\n\
  -c                     change only the creation time\n\
  -m                     change only the modification time\n\
  -r FILE                use this file's times instead of current time\n\
  -t STAMP               use [[CC]YY]MMDDhhmm[.ss] instead of current time\n", stdout);
}

int use_reference(const wchar_t* fileName)
{
    HANDLE hFile;
    if (change_times & TM_SET)
    {
        return 0;
    }
    hFile = CreateFileW(fileName, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
    if (hFile != INVALID_HANDLE_VALUE)
    {
        if (GetFileTime(hFile, &ctime, &atime, &mtime))
        {
            change_times |= TM_SET;
        }
        CloseHandle(hFile);
    }
    return change_times & TM_SET;
}

int use_stamp(wchar_t* opt)
{
    wchar_t* p;
    SYSTEMTIME st;
    if (change_times & TM_SET)
    {
        return 0;
    }
    GetLocalTime(&st);
    st.wMilliseconds = 0;
    p = wcschr(opt, L'.');
    if (p)
    {
        if (p[3] == 0)
        {
            st.wSecond = _wtoi(p + 1);
            *p = 0;
        }
        else
        {
            return 0;
        }
    }
    else
    {
        st.wSecond = 0;
        p = opt + wcslen(opt);
    }
    if (p >= opt + 2)
    {
        p -= 2;
        st.wMinute = _wtoi(p);
        *p = 0;
        if (p >= opt + 2)
        {
            p -= 2;
            st.wHour = _wtoi(p);
            *p = 0;
            if (p >= opt + 2)
            {
                p -= 2;
                st.wDay = _wtoi(p);
                *p = 0;
                if (p >= opt + 2)
                {
                    p -= 2;
                    st.wMonth = _wtoi(p);
                    *p = 0;
                    if (p == opt)
                    {
                    }
                    else if (p == opt + 2)
                    {
                        p -= 2;
                        st.wYear = (st.wYear / 100) * 100 + _wtoi(p);
                    }
                    else if (p == opt + 4)
                    {
                        p -= 4;
                        st.wYear = _wtoi(p);
                    }
                    else
                    {
                        return 0;
                    }
                    if (SystemTimeToFileTime(&st, &ctime) && LocalFileTimeToFileTime(&ctime, &atime))
                    {
                        ctime = atime;
                        mtime = atime;
                        change_times |= TM_SET;
                    }
                }
            }
        }
    }
    return change_times & TM_SET;
}

int use_current()
{
    SYSTEMTIME st;
    if (change_times & TM_SET)
    {
        return 0;
    }
    GetSystemTime(&st);
    st.wMilliseconds = 0;
    if (SystemTimeToFileTime(&st, &atime))
    {
        ctime = atime;
        mtime = atime;
        change_times |= TM_SET;
    }
    return change_times & TM_SET;
}

int touch(const wchar_t* fileName)
{
    int ret = 0;
    HANDLE hFile = CreateFileW(fileName, FILE_WRITE_ATTRIBUTES, 0, 0, OPEN_EXISTING, 0, 0);
    if (hFile != INVALID_HANDLE_VALUE)
    {
        if (SetFileTime(hFile, change_times & CH_CTIME ? &ctime : 0, change_times & CH_ATIME ? &atime : 0, change_times & CH_MTIME ? &mtime : 0))
        {
            ret = 1;
        }
        CloseHandle(hFile);
    }
    return ret;
}

int wmain(int argc, wchar_t **argv)
{
    int ret = 1;
    int i;
    wchar_t* opt = 0;
    for (i = 1; i < argc; ++i)
    {
        opt = argv[i];
        if (opt[0] == L'-')
        {
            if (opt[1] != 0 && opt[2] == 0)
            {
                if (opt[1] == L'a')
                {
                    change_times |= CH_ATIME;
                }
                else if (opt[1] == L'c')
                {
                    change_times |= CH_CTIME;
                }
                else if (opt[1] == L'm')
                {
                    change_times |= CH_MTIME;
                }
                else if (opt[1] == L'r')
                {
                    i++;
                    if (i < argc)
                    {
                        if (!use_reference(argv[i]))
                        {
                            i = argc;
                            break;
                        }
                    }
                }
                else if (opt[1] == L't')
                {
                    i++;
                    if (i < argc)
                    {
                        if (!use_stamp(argv[i]))
                        {
                            i = argc;
                            break;
                        }
                    }
                }
                else
                {
                    i = argc;
                    break;
                }
            }
            else
            {
                i = argc;
                break;
            }
        }
        else
        {
            break;
        }
    }
    if (i == argc)
    {
        usage();
        return 0;
    }
    if (!(change_times & (CH_ATIME | CH_CTIME | CH_MTIME)))
    {
        change_times |= CH_ATIME | CH_CTIME | CH_MTIME;
    }
    use_current();
    for (; i < argc; ++i)
    {
        ret &= touch(argv[i]);
    }
    return ret;
}

免费评分

参与人数 1吾爱币 +7 热心值 +1 收起 理由
苏紫方璇 + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

Batcher 发表于 2023-11-14 14:53
感谢分享。

UnxUtils for Windows 命令行工具包里面有一个 touch.exe 可以实现类似 Linux 里面的效果:
https://unxutils.sourceforge.net/

[Asm] 纯文本查看 复制代码
C:\Test\>touch --help
Usage: touch [OPTION]... FILE...
Update the access and modification times of each FILE to the current time.

  -a                     change only the access time
  -c                     do not create any files
  -d, --date=STRING      parse STRING and use it instead of current time
  -f                     (ignored)
  -m                     change only the modification time
  -r, --reference=FILE   use this file's times instead of current time
  -t STAMP               use MMDDhhmm[[CC]YY][.ss] instead of current time
      --time=WORD        access -a, atime -a, mtime -m, modify -m, use -a
      --help             display this help and exit
      --version          output version information and exit

STAMP may be used without -t if none of -drt, nor --, are used.

C:\Test\>touch --version
touch (GNU fileutils) 3.16


[Asm] 纯文本查看 复制代码
C:\Test\>dir 1.txt | findstr "1.txt"
2023/11/11  19:36               207 1.txt

C:\Test\>touch 1.txt

C:\Test\>dir 1.txt | findstr "1.txt"
2023/11/14  14:50               207 1.txt


CoreUtils for Windows 命令行工具包里面有一个 touch.exe 可以实现类似 Linux 里面的效果:
https://gnuwin32.sourceforge.net/packages/coreutils.htm

[Asm] 纯文本查看 复制代码
C:\Test\>touch --version
touch (GNU coreutils) 5.3.0


是开源的,可以下载它的C源代码。
 楼主| go4399 发表于 2023-11-14 23:41
参考了https://ftp.gnu.org/gnu/coreutils/coreutils-9.4.tar.xz这个版本.
目的是能被win下的tinycc编译,通配符不支持UCRT
dudupangle 发表于 2023-11-15 09:10
大致看了一下。有如下问题:
1. 参数解析过于复杂了。建议优化。
2. 没有注释。
3. 函数中没有换行。分开的功能,加以添加上换行,提高可读性。
4. touch 函数逻辑有点小问题:
在CreateFileW失败的时候,返回0。0应该是代表成功。
5. 参数判断应该在参数解析之前。

 楼主| go4399 发表于 2023-11-15 09:33
dudupangle 发表于 2023-11-15 09:10
大致看了一下。有如下问题:
1. 参数解析过于复杂了。建议优化。
2. 没有注释。

4. https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilew
CreateFileW Return value:
If the function succeeds, the return value is an open handle to the specified file, device, named pipe, or mail slot.
If the function fails, the return value is INVALID_HANDLE_VALUE. To get extended error information, call GetLastError.
返回0的情况,没有说明。
dudupangle 发表于 2023-11-15 11:58
go4399 发表于 2023-11-15 09:33
4. https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilew
CreateFileW ...

我的意思是你写的touch函数返回值的含义是什么。0成功,小于0失败?你现在的逻辑是如果CreateFileW失败,返回ret。ret的初值为0。我认为这个和你的设计不相符。
 楼主| go4399 发表于 2023-11-15 14:21
本帖最后由 go4399 于 2023-11-15 14:24 编辑
dudupangle 发表于 2023-11-15 11:58
我的意思是你写的touch函数返回值的含义是什么。0成功,小于0失败?你现在的逻辑是如果CreateFileW失败, ...

touch函数,1表示成功,0表示失败
这个逻辑和原始coreutils版本一致
alwaysandforeve 发表于 2023-11-15 22:18
有个小建议:1.可以多写写注释,方便别人理解,更方便自己理解,要不等过段时间就忘了自己的想法了
我之前也写过这种,没几天就忘了很多具体的细节
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-24 18:42

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表