Fix extended attributes in win32.

This commit is contained in:
2020-05-02 18:30:24 +01:00
parent f38dce47d7
commit bf01b56435
3 changed files with 281 additions and 159 deletions

View File

@@ -1,5 +1,4 @@
{ {
"projectId": "032fb8bb-9e63-447f-9469-bca3ad0616f7", "projectId": "01ca2c81-5a0a-48be-97b7-e711e27f7d1f",
"projectName": "fssetter", "projectName": "setter"
"neverTrack": false
} }

View File

@@ -2146,28 +2146,30 @@ void FileAttributes(const char *path)
cRc, cRc,
aRc, aRc,
eRc); 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) void ExtendedAttributes(const char *path)
{ {
/*
BOOL ret; BOOL ret;
DWORD error; DWORD error;
OSVERSIONINFO verInfo; OSVERSIONINFO verInfo;
HINSTANCE ntdll; HMODULE ntdll;
void * func; void * func;
DWORD dwNumberOfBytesWritten; DWORD dwNumberOfBytesWritten;
DWORD rc, wRc, cRc; DWORD rc, wRc, cRc, rRc, cmp;
char message[300]; char message[300];
IO_STATUS_BLOCK eaStatus; IO_STATUS_BLOCK eaStatus;
HANDLE h; HANDLE h;
LPSTR lpRootPathName; LPSTR lpRootPathName;
DWORD dwMaxNameSize = MAX_PATH + 1;
size_t pathSize = strlen(path); size_t pathSize = strlen(path);
PVOID eaData; PFILE_FULL_EA_INFORMATION eaData;
int i;
verInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); verInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
ret = GetVersionEx(&verInfo); ret = GetVersionEx(&verInfo);
@@ -2185,50 +2187,7 @@ void ExtendedAttributes(const char *path)
return; return;
} }
lpRootPathName = malloc(dwMaxNameSize); ntdll = LoadLibraryA("ntdll.dll");
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) if(ntdll == NULL)
{ {
@@ -2243,102 +2202,263 @@ void ExtendedAttributes(const char *path)
{ {
error = GetLastError(); error = GetLastError();
printf("Error %d finding NtSetEaFile.\n", error); printf("Error %d finding NtSetEaFile.\n", error);
FreeLibrary(ntdll);
return; return;
} }
NtSetEaFile = func; 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"); printf("Creating files with extended attributes.\n");
h = CreateFileA("COMMENTS", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, rc = 0;
FILE_ATTRIBUTE_NORMAL, NULL); rc = 0; wRc = 0; cRc = 0; if(h == INVALID_HANDLE_VALUE) 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(); rc = GetLastError();
}
else else
{ {
memset(message, 0, 300); memset(message, 0, 300);
sprintf(&message, "This files has an optional .COMMENTS EA\n"); sprintf(message, "This files has an optional .COMMENTS EA\n");
ret = WriteFile(h, message, strlen(message), &dwNumberOfBytesWritten, NULL); ret = WriteFile(h, message, strlen(message), &dwNumberOfBytesWritten, NULL);
if(!ret) if(!ret)
{
wRc = GetLastError(); wRc = GetLastError();
} else
{
eaData = malloc(sizeof(CommentsEA)); eaData = malloc(sizeof(CommentsEA));
memcpy(eaData, &CommentsEA, sizeof(CommentsEA)); memcpy(eaData, &CommentsEA, sizeof(CommentsEA));
rc = NtSetEaFile(h, &eaStatus, eaData, sizeof(CommentsEA)); rc = NtSetEaFile(h, &eaStatus, eaData, sizeof(CommentsEA));
ret = CloseHandle(h);
if(!ret) free(eaData);
if(!rc)
{ {
cRc = GetLastError(); 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); free(eaData);
} }
printf("\tFile with comments = \"%s\", rc = 0x%08x, wRc = %d, cRc = %d\n", "COMMENTS", rc, wRc, cRc);
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();
} }
ret = CloseHandle(h);
if(!ret) cRc = 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 else
{ {
memset(message, 0, 300); memset(message, 0, 300);
sprintf(&message, "This files has a critical .COMMENTS EA\n"); sprintf(message, "This files has a critical .COMMENTS EA\n");
ret = WriteFile(h, message, strlen(message), &dwNumberOfBytesWritten, NULL); ret = WriteFile(h, message, strlen(message), &dwNumberOfBytesWritten, NULL);
if(!ret) if(!ret)
{
wRc = GetLastError(); wRc = GetLastError();
} else
{
eaData = malloc(sizeof(CommentsEACritical)); eaData = malloc(sizeof(CommentsEACritical));
memcpy(eaData, &CommentsEACritical, sizeof(CommentsEACritical)); memcpy(eaData, &CommentsEACritical, sizeof(CommentsEACritical));
rc = NtSetEaFile(h, &eaStatus, eaData, sizeof(CommentsEACritical)); rc = NtSetEaFile(h, &eaStatus, eaData, sizeof(CommentsEACritical));
ret = CloseHandle(h);
if(!ret) free(eaData);
if(!rc)
{ {
cRc = GetLastError(); 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); free(eaData);
} }
printf("\tFile with comments = \"%s\", rc = 0x%08x, wRc = %d, cRc = %d\n", "COMMENTS.CRT", rc, wRc, cRc);
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();
} }
ret = CloseHandle(h);
if(!ret) cRc = 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 else
{ {
memset(message, 0, 300); memset(message, 0, 300);
sprintf(&message, "This files has an optional .ICON EA\n"); sprintf(message, "This files has an optional .ICON EA\n");
ret = WriteFile(h, message, strlen(message), &dwNumberOfBytesWritten, NULL); ret = WriteFile(h, message, strlen(message), &dwNumberOfBytesWritten, NULL);
if(!ret) if(!ret)
{
wRc = GetLastError(); wRc = GetLastError();
} else
{
eaData = malloc(sizeof(IconEA)); eaData = malloc(sizeof(IconEA));
memcpy(eaData, &IconEA, sizeof(IconEA)); memcpy(eaData, &IconEA, sizeof(IconEA));
rc = NtSetEaFile(h, &eaStatus, eaData, sizeof(IconEA)); rc = NtSetEaFile(h, &eaStatus, eaData, sizeof(IconEA));
ret = CloseHandle(h);
if(!ret) free(eaData);
if(!rc)
{ {
cRc = GetLastError(); 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); 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();
}
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); FreeLibrary(ntdll);
*/
} }
void ResourceFork(const char *path) void ResourceFork(const char *path)

View File

@@ -211,7 +211,8 @@ typedef LONG NTSTATUS;
typedef struct _IO_STATUS_BLOCK typedef struct _IO_STATUS_BLOCK
{ {
union { union
{
NTSTATUS Status; NTSTATUS Status;
PVOID Pointer; PVOID Pointer;
} DUMMYUNIONNAME; } DUMMYUNIONNAME;
@@ -219,6 +220,8 @@ typedef struct _IO_STATUS_BLOCK
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK; } IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
NTSTATUS (*NtSetEaFile)(HANDLE, PIO_STATUS_BLOCK, PVOID, ULONG); 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 #ifndef FSCTL_SET_SPARSE
#define FSCTL_SET_SPARSE 0x000900C4 #define FSCTL_SET_SPARSE 0x000900C4