mirror of
https://github.com/aaru-dps/fstester.git
synced 2025-12-16 19:24:39 +00:00
Fix extended attributes in win32.
This commit is contained in:
@@ -1,5 +1,4 @@
|
|||||||
{
|
{
|
||||||
"projectId": "032fb8bb-9e63-447f-9469-bca3ad0616f7",
|
"projectId": "01ca2c81-5a0a-48be-97b7-e711e27f7d1f",
|
||||||
"projectName": "fssetter",
|
"projectName": "setter"
|
||||||
"neverTrack": false
|
|
||||||
}
|
}
|
||||||
@@ -2146,199 +2146,319 @@ 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;
|
HMODULE ntdll;
|
||||||
HINSTANCE ntdll;
|
void * func;
|
||||||
void *func;
|
DWORD dwNumberOfBytesWritten;
|
||||||
DWORD dwNumberOfBytesWritten;
|
DWORD rc, wRc, cRc, rRc, cmp;
|
||||||
DWORD rc, wRc, cRc;
|
char message[300];
|
||||||
char message[300];
|
IO_STATUS_BLOCK eaStatus;
|
||||||
IO_STATUS_BLOCK eaStatus;
|
HANDLE h;
|
||||||
HANDLE h;
|
LPSTR lpRootPathName;
|
||||||
LPSTR lpRootPathName;
|
size_t pathSize = strlen(path);
|
||||||
DWORD dwMaxNameSize = MAX_PATH + 1;
|
PFILE_FULL_EA_INFORMATION eaData;
|
||||||
size_t pathSize = strlen(path);
|
int i;
|
||||||
PVOID eaData;
|
|
||||||
|
|
||||||
verInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
verInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
||||||
ret = GetVersionEx(&verInfo);
|
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)
|
if(!ret)
|
||||||
{
|
wRc = GetLastError();
|
||||||
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();
|
|
||||||
}
|
|
||||||
else
|
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));
|
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)
|
|
||||||
{
|
|
||||||
cRc = GetLastError();
|
|
||||||
}
|
|
||||||
free(eaData);
|
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,
|
printf("\tFile with comments = \"%s\", rc = 0x%08x, wRc = %d, cRc = %d, rRc = %d, cmp = %d\n",
|
||||||
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); rc = 0; wRc = 0; cRc = 0; if(h == INVALID_HANDLE_VALUE)
|
"COMMENTS",
|
||||||
{
|
rc,
|
||||||
rc = GetLastError();
|
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
|
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));
|
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)
|
|
||||||
{
|
|
||||||
cRc = GetLastError();
|
|
||||||
}
|
|
||||||
free(eaData);
|
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,
|
printf("\tFile with comments = \"%s\", rc = 0x%08x, wRc = %d, cRc = %d, rRc = %d, cmp = %d\n",
|
||||||
FILE_ATTRIBUTE_NORMAL, NULL); rc = 0; wRc = 0; cRc = 0; if(h == INVALID_HANDLE_VALUE)
|
"COMMENTS.CRT",
|
||||||
{
|
rc,
|
||||||
rc = GetLastError();
|
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
|
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));
|
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)
|
|
||||||
{
|
|
||||||
cRc = GetLastError();
|
|
||||||
}
|
|
||||||
free(eaData);
|
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)
|
void ResourceFork(const char *path)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user