From bf01b56435d4d3460e195ee20ff7f11e7cf2ec4d Mon Sep 17 00:00:00 2001 From: Natalia Portillo Date: Sat, 2 May 2020 18:30:24 +0100 Subject: [PATCH] Fix extended attributes in win32. --- setter/codealike.json | 5 +- setter/src/win32.c | 430 +++++++++++++++++++++++++++--------------- setter/src/win32.h | 5 +- 3 files changed, 281 insertions(+), 159 deletions(-) diff --git a/setter/codealike.json b/setter/codealike.json index a82b456..68b01ce 100644 --- a/setter/codealike.json +++ b/setter/codealike.json @@ -1,5 +1,4 @@ { - "projectId": "032fb8bb-9e63-447f-9469-bca3ad0616f7", - "projectName": "fssetter", - "neverTrack": false + "projectId": "01ca2c81-5a0a-48be-97b7-e711e27f7d1f", + "projectName": "setter" } \ No newline at end of file diff --git a/setter/src/win32.c b/setter/src/win32.c index 635d3b2..382d589 100644 --- a/setter/src/win32.c +++ b/setter/src/win32.c @@ -2146,199 +2146,319 @@ void FileAttributes(const char *path) cRc, aRc, eRc); + + FreeLibrary(advapi32); } -void FilePermissions(const char *path) { /* Do nothing, not supported by target operating system */ } +void FilePermissions(const char *path) +{ /* Do nothing, not supported by target operating system */ +} -// TODO: It is not working properly void ExtendedAttributes(const char *path) { - /* - BOOL ret; - DWORD error; - OSVERSIONINFO verInfo; - HINSTANCE ntdll; - void *func; - DWORD dwNumberOfBytesWritten; - DWORD rc, wRc, cRc; - char message[300]; - IO_STATUS_BLOCK eaStatus; - HANDLE h; - LPSTR lpRootPathName; - DWORD dwMaxNameSize = MAX_PATH + 1; - size_t pathSize = strlen(path); - PVOID eaData; + BOOL ret; + DWORD error; + OSVERSIONINFO verInfo; + HMODULE ntdll; + void * func; + DWORD dwNumberOfBytesWritten; + DWORD rc, wRc, cRc, rRc, cmp; + char message[300]; + IO_STATUS_BLOCK eaStatus; + HANDLE h; + LPSTR lpRootPathName; + size_t pathSize = strlen(path); + PFILE_FULL_EA_INFORMATION eaData; + int i; - verInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - ret = GetVersionEx(&verInfo); + verInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + ret = GetVersionEx(&verInfo); + if(!ret) + { + error = GetLastError(); + printf("Error %d querying Windows version.\n", error); + return; + } + + if(verInfo.dwPlatformId != VER_PLATFORM_WIN32_NT) + { + // Not supported on Windows 9x + return; + } + + ntdll = LoadLibraryA("ntdll.dll"); + + if(ntdll == NULL) + { + error = GetLastError(); + printf("Error %d loading NTDLL.DLL.\n", error); + return; + } + + func = GetProcAddress(ntdll, "NtSetEaFile"); + + if(func == NULL) + { + error = GetLastError(); + printf("Error %d finding NtSetEaFile.\n", error); + FreeLibrary(ntdll); + return; + } + + NtSetEaFile = func; + + func = GetProcAddress(ntdll, "NtQueryEaFile"); + + if(func == NULL) + { + error = GetLastError(); + printf("Error %d finding NtQueryEaFile.\n", error); + FreeLibrary(ntdll); + return; + } + + NtQueryEaFile = func; + + lpRootPathName = malloc(dwMaxNameSize); + + if(lpRootPathName == NULL) + { + printf("Could not allocate memory.\n"); + FreeLibrary(ntdll); + return; + } + + memset(lpRootPathName, 0x00, MAX_PATH); + strcpy(lpRootPathName, path); + + if(path[pathSize - 1] != '\\') lpRootPathName[pathSize] = '\\'; + + ret = SetCurrentDirectoryA(lpRootPathName); + + if(!ret) + { + error = GetLastError(); + printf("Error %d changing to specified path.\n", error); + FreeLibrary(ntdll); + return; + } + + ret = CreateDirectoryA("XATTRS", NULL); + + if(!ret) + { + error = GetLastError(); + printf("Error %d creating working directory.\n", error); + FreeLibrary(ntdll); + return; + } + + ret = SetCurrentDirectoryA("XATTRS"); + + if(!ret) + { + error = GetLastError(); + printf("Error %d changing to working directory.\n", error); + FreeLibrary(ntdll); + return; + } + + printf("Creating files with extended attributes.\n"); + + rc = 0; + wRc = 0; + cRc = 0; + rRc = 0; + cmp = TRUE; + h = CreateFileA("COMMENTS", + GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + NULL); + rc = 0; + wRc = 0; + cRc = 0; + if(h == INVALID_HANDLE_VALUE) + rc = GetLastError(); + else + { + memset(message, 0, 300); + sprintf(message, "This files has an optional .COMMENTS EA\n"); + ret = WriteFile(h, message, strlen(message), &dwNumberOfBytesWritten, NULL); if(!ret) - { - error = GetLastError(); - printf("Error %d querying Windows version.\n", error); - return; - } - - if(verInfo.dwPlatformId != VER_PLATFORM_WIN32_NT) - { - // Not supported on Windows 9x - return; - } - - lpRootPathName = malloc(dwMaxNameSize); - - if(lpRootPathName == NULL) - { - printf("Could not allocate memory.\n"); - return; - } - - memset(lpRootPathName, 0x00, MAX_PATH); - strcpy(lpRootPathName, path); - - if(path[pathSize - 1] != '\\') - { - lpRootPathName[pathSize] = '\\'; - } - - ret = SetCurrentDirectoryA(lpRootPathName); - - if(!ret) - { - error = GetLastError(); - printf("Error %d changing to specified path.\n", error); - return; - } - - ret = CreateDirectoryA("XATTRS", NULL); - - if(!ret) - { - error = GetLastError(); - printf("Error %d creating working directory.\n", error); - return; - } - - ret = SetCurrentDirectoryA("XATTRS"); - - if(!ret) - { - error = GetLastError(); - printf("Error %d changing to working directory.\n", error); - return; - } - - ntdll = LoadLibrary("ntdll.dll"); - - if(ntdll == NULL) - { - error = GetLastError(); - printf("Error %d loading NTDLL.DLL.\n", error); - return; - } - - func = GetProcAddress(ntdll, "NtSetEaFile"); - - if(func == NULL) - { - error = GetLastError(); - printf("Error %d finding NtSetEaFile.\n", error); - return; - } - - NtSetEaFile = func; - - printf("Creating files with extended attributes.\n"); - - h = CreateFileA("COMMENTS", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, - FILE_ATTRIBUTE_NORMAL, NULL); rc = 0; wRc = 0; cRc = 0; if(h == INVALID_HANDLE_VALUE) - { - rc = GetLastError(); - } + wRc = GetLastError(); else { - memset(message, 0, 300); - sprintf(&message, "This files has an optional .COMMENTS EA\n"); - ret = WriteFile(h, message, strlen(message), &dwNumberOfBytesWritten, NULL); - if(!ret) - { - wRc = GetLastError(); - } - eaData = malloc(sizeof(CommentsEA)); memcpy(eaData, &CommentsEA, sizeof(CommentsEA)); rc = NtSetEaFile(h, &eaStatus, eaData, sizeof(CommentsEA)); - ret = CloseHandle(h); - if(!ret) - { - cRc = GetLastError(); - } + free(eaData); + + if(!rc) + { + eaData = malloc(sizeof(CommentsEA)); + memset(eaData, 0, sizeof(CommentsEA)); + rRc = NtQueryEaFile(h, &eaStatus, eaData, sizeof(CommentsEA), TRUE, NULL, 0, NULL, FALSE); + + for(i = 0; i < sizeof(CommentsEA); i++) + { + if(((unsigned char *)eaData)[i] != CommentsEA[i]) + { + cmp = FALSE; + break; + } + } + + free(eaData); + } } - printf("\tFile with comments = \"%s\", rc = 0x%08x, wRc = %d, cRc = %d\n", "COMMENTS", rc, wRc, cRc); + ret = CloseHandle(h); + if(!ret) cRc = GetLastError(); + } - h = CreateFileA("COMMENTS.CRT", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, - CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); rc = 0; wRc = 0; cRc = 0; if(h == INVALID_HANDLE_VALUE) - { - rc = GetLastError(); - } + printf("\tFile with comments = \"%s\", rc = 0x%08x, wRc = %d, cRc = %d, rRc = %d, cmp = %d\n", + "COMMENTS", + rc, + wRc, + cRc, + rRc, + cmp); + + rc = 0; + wRc = 0; + cRc = 0; + rRc = 0; + cmp = TRUE; + h = CreateFileA("COMMENTS.CRT", + GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + NULL); + rc = 0; + wRc = 0; + cRc = 0; + if(h == INVALID_HANDLE_VALUE) + rc = GetLastError(); + else + { + memset(message, 0, 300); + sprintf(message, "This files has a critical .COMMENTS EA\n"); + ret = WriteFile(h, message, strlen(message), &dwNumberOfBytesWritten, NULL); + if(!ret) + wRc = GetLastError(); else { - memset(message, 0, 300); - sprintf(&message, "This files has a critical .COMMENTS EA\n"); - ret = WriteFile(h, message, strlen(message), &dwNumberOfBytesWritten, NULL); - if(!ret) - { - wRc = GetLastError(); - } - eaData = malloc(sizeof(CommentsEACritical)); memcpy(eaData, &CommentsEACritical, sizeof(CommentsEACritical)); rc = NtSetEaFile(h, &eaStatus, eaData, sizeof(CommentsEACritical)); - ret = CloseHandle(h); - if(!ret) - { - cRc = GetLastError(); - } + free(eaData); + + if(!rc) + { + eaData = malloc(sizeof(CommentsEACritical)); + memset(eaData, 0, sizeof(CommentsEACritical)); + rRc = NtQueryEaFile(h, &eaStatus, eaData, sizeof(CommentsEACritical), TRUE, NULL, 0, NULL, FALSE); + + for(i = 0; i < sizeof(CommentsEACritical); i++) + { + if(((unsigned char *)eaData)[i] != CommentsEACritical[i]) + { + cmp = FALSE; + break; + } + } + + free(eaData); + } } - printf("\tFile with comments = \"%s\", rc = 0x%08x, wRc = %d, cRc = %d\n", "COMMENTS.CRT", rc, wRc, cRc); + ret = CloseHandle(h); + if(!ret) cRc = GetLastError(); + } - h = CreateFileA("ICON", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, - FILE_ATTRIBUTE_NORMAL, NULL); rc = 0; wRc = 0; cRc = 0; if(h == INVALID_HANDLE_VALUE) - { - rc = GetLastError(); - } + printf("\tFile with comments = \"%s\", rc = 0x%08x, wRc = %d, cRc = %d, rRc = %d, cmp = %d\n", + "COMMENTS.CRT", + rc, + wRc, + cRc, + rRc, + cmp); + + rc = 0; + wRc = 0; + cRc = 0; + rRc = 0; + cmp = TRUE; + h = CreateFileA("ICON", + GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + NULL); + rc = 0; + wRc = 0; + cRc = 0; + if(h == INVALID_HANDLE_VALUE) + rc = GetLastError(); + else + { + memset(message, 0, 300); + sprintf(message, "This files has an optional .ICON EA\n"); + ret = WriteFile(h, message, strlen(message), &dwNumberOfBytesWritten, NULL); + if(!ret) + wRc = GetLastError(); else { - memset(message, 0, 300); - sprintf(&message, "This files has an optional .ICON EA\n"); - ret = WriteFile(h, message, strlen(message), &dwNumberOfBytesWritten, NULL); - if(!ret) - { - wRc = GetLastError(); - } - eaData = malloc(sizeof(IconEA)); memcpy(eaData, &IconEA, sizeof(IconEA)); rc = NtSetEaFile(h, &eaStatus, eaData, sizeof(IconEA)); - ret = CloseHandle(h); - if(!ret) - { - cRc = GetLastError(); - } + free(eaData); + + if(!rc) + { + eaData = malloc(sizeof(IconEA)); + memset(eaData, 0, sizeof(IconEA)); + rRc = NtQueryEaFile(h, &eaStatus, eaData, sizeof(IconEA), TRUE, NULL, 0, NULL, FALSE); + + for(i = 0; i < sizeof(IconEA); i++) + { + if(((unsigned char *)eaData)[i] != IconEA[i]) + { + cmp = FALSE; + break; + } + } + + free(eaData); + } } - printf("\tFile with icon = \"%s\", rc = 0x%08x, wRc = %d, cRc = %d\n", "ICON", rc, wRc, cRc); + ret = CloseHandle(h); + if(!ret) cRc = GetLastError(); + } - FreeLibrary(ntdll); - */ + printf("\tFile with icon = \"%s\", rc = 0x%08x, wRc = %d, cRc = %d, rRc = %d, cmp = %d\n", + "ICON", + rc, + wRc, + cRc, + rRc, + cmp); + + FreeLibrary(ntdll); } void ResourceFork(const char *path) diff --git a/setter/src/win32.h b/setter/src/win32.h index d58d6b2..f4b5cd0 100644 --- a/setter/src/win32.h +++ b/setter/src/win32.h @@ -211,7 +211,8 @@ typedef LONG NTSTATUS; typedef struct _IO_STATUS_BLOCK { - union { + union + { NTSTATUS Status; PVOID Pointer; } DUMMYUNIONNAME; @@ -219,6 +220,8 @@ typedef struct _IO_STATUS_BLOCK } IO_STATUS_BLOCK, *PIO_STATUS_BLOCK; NTSTATUS (*NtSetEaFile)(HANDLE, PIO_STATUS_BLOCK, PVOID, ULONG); +NTSTATUS(*NtQueryEaFile) +(HANDLE, PIO_STATUS_BLOCK, PVOID, ULONG, BOOLEAN, PVOID, ULONG, PULONG, BOOLEAN); #ifndef FSCTL_SET_SPARSE #define FSCTL_SET_SPARSE 0x000900C4