Kevin
Kevin

Reputation: 289

Modify file create time in windows using only C

I moving files from one folder to another in windows and want to save the original file date stamps to the new file. I can successfully copy access date and modification date using <utime.h> and <sys/stat.h> I want to also copy the create date where applicable. I see that C++ has the GetFileTime function (fileapi.h) to do this and other languages can do this. Can it be done purely in C and if so how?

Upvotes: 1

Views: 1441

Answers (2)

Kevin
Kevin

Reputation: 289

This works on my Window 10 system. Thank you for your help.

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

int main()
{

    HANDLE hFile1, hFile2;
    FILETIME ftCreate1, ftAccess1, ftWrite1, ftCreate2, ftAccess2, ftWrite2;
    SYSTEMTIME st, stUTC, stLocal;

    // file names, change accordingly
    char fname1[ ] = "C:\\PathToFile\\testfile01.txt";
    char fname2[ ] = "C:\\PathToFile\\testfile02.txt";

    BOOL bRet = FALSE;
    
    //OPEN FILES
    // open first file
    hFile1 = CreateFile(
                fname1,                 // file to open
                GENERIC_READ,           // open for reading
                FILE_SHARE_READ,        // share for reading
                NULL,                   // default security
                OPEN_EXISTING,          // existing file only
                FILE_ATTRIBUTE_NORMAL,  // normal file
                NULL                    // no attribute template
            );
    // open second file
    hFile2 = CreateFile(
                fname2,                 // file to open
                GENERIC_WRITE,          // open for writing 
                FILE_SHARE_READ,        
                NULL,                   
                OPEN_EXISTING,          
                FILE_ATTRIBUTE_NORMAL,  
                NULL                    
            );                  

    // check file handles have opened successfully
    if(hFile1 == INVALID_HANDLE_VALUE){
        printf("Could not open %s file, error %d\n", fname1, GetLastError());
        return 1;
    }
    if(hFile2 == INVALID_HANDLE_VALUE){
        printf("Could not open %s file, error %d\n", fname2, GetLastError());
        return 1;
    }
    
    // GET FILE TIMES 
    // retrieve the file times from the first file.
    if(!GetFileTime(hFile1, &ftCreate1, &ftAccess1, &ftWrite1)){
        printf("GetFileTime Failed!\n");
        return 1;
    }

    // SYSTEM TIME
    // get system time and assign to variable for saving current time - if required
    GetSystemTime(&st);                                     // gets current time
    SystemTimeToFileTime(&st, &ftAccess2);                  // converts to file time 
    
    // SET TIME ON FILE!!!
    // set file times for second file, NULL to keep existing timestamp
    if(SetFileTime(hFile2, &ftCreate1, &ftAccess2, NULL)){
        printf("SetFileTime Successful!\n");
    }else{
        printf("SetFileTime Failed!\n");
        return 1;
    }

    // PRINT
    // convert filetime to readable date format for printing to stdout
    FileTimeToSystemTime(&ftCreate1, &stUTC);
    SystemTimeToTzSpecificLocalTime(NULL, &stUTC, &stLocal);
    printf("Created: %02d/%02d/%d %02d:%02d\n", stLocal.wDay, stLocal.wMonth, stLocal.wYear, stLocal.wHour, stLocal.wMinute);   

    
    // close the file handles
    CloseHandle(hFile1);
    CloseHandle(hFile2);
    return 0;

}

Upvotes: 2

Ben Voigt
Ben Voigt

Reputation: 283893

The Windows API is designed to be called from C. Write

#include <windows.h>

in a C program and the compiler will accept usage of GetFileTime and SetFileTime. You'll then need to link with the kernel32.lib import library, which may already be in your library list by default.

C++ actually has to use extern "C" to call these functions because they aren't C++ functions at all (The header files do this automatically, based on #if __cplusplus so you don't have to worry about it. The header files also automatically mark these declarations with the stdcall calling convention on x86, you don't have to worry about that either unless you form a function pointer.)

Upvotes: 3

Related Questions