mirror of
https://github.com/reactos/wine.git
synced 2024-11-25 12:49:45 +00:00
kernel32: Implement SetFileValidData.
This commit is contained in:
parent
67230fc013
commit
c019083240
1
configure
vendored
1
configure
vendored
@ -12931,6 +12931,7 @@ for ac_func in \
|
|||||||
chsize \
|
chsize \
|
||||||
dlopen \
|
dlopen \
|
||||||
epoll_create \
|
epoll_create \
|
||||||
|
fallocate \
|
||||||
ffs \
|
ffs \
|
||||||
finite \
|
finite \
|
||||||
fnmatch \
|
fnmatch \
|
||||||
|
@ -1976,6 +1976,7 @@ AC_CHECK_FUNCS(\
|
|||||||
chsize \
|
chsize \
|
||||||
dlopen \
|
dlopen \
|
||||||
epoll_create \
|
epoll_create \
|
||||||
|
fallocate \
|
||||||
ffs \
|
ffs \
|
||||||
finite \
|
finite \
|
||||||
fnmatch \
|
fnmatch \
|
||||||
|
@ -40,6 +40,7 @@
|
|||||||
#include "winternl.h"
|
#include "winternl.h"
|
||||||
#include "winioctl.h"
|
#include "winioctl.h"
|
||||||
#include "wincon.h"
|
#include "wincon.h"
|
||||||
|
#include "ddk/ntddk.h"
|
||||||
#include "kernel_private.h"
|
#include "kernel_private.h"
|
||||||
|
|
||||||
#include "wine/exception.h"
|
#include "wine/exception.h"
|
||||||
@ -1086,8 +1087,15 @@ error:
|
|||||||
*/
|
*/
|
||||||
BOOL WINAPI SetFileValidData( HANDLE hFile, LONGLONG ValidDataLength )
|
BOOL WINAPI SetFileValidData( HANDLE hFile, LONGLONG ValidDataLength )
|
||||||
{
|
{
|
||||||
FIXME("stub: %p, %s\n", hFile, wine_dbgstr_longlong(ValidDataLength));
|
FILE_VALID_DATA_LENGTH_INFORMATION info;
|
||||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
IO_STATUS_BLOCK io;
|
||||||
|
NTSTATUS status;
|
||||||
|
|
||||||
|
info.ValidDataLength.QuadPart = ValidDataLength;
|
||||||
|
status = NtSetInformationFile( hFile, &io, &info, sizeof(info), FileValidDataLengthInformation );
|
||||||
|
|
||||||
|
if (status == STATUS_SUCCESS) return TRUE;
|
||||||
|
SetLastError( RtlNtStatusToDosError(status) );
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,6 +42,7 @@ static BOOL (WINAPI *pGetVolumeNameForVolumeMountPointA)(LPCSTR, LPSTR, DWORD);
|
|||||||
static DWORD (WINAPI *pQueueUserAPC)(PAPCFUNC pfnAPC, HANDLE hThread, ULONG_PTR dwData);
|
static DWORD (WINAPI *pQueueUserAPC)(PAPCFUNC pfnAPC, HANDLE hThread, ULONG_PTR dwData);
|
||||||
static BOOL (WINAPI *pGetFileInformationByHandleEx)(HANDLE, FILE_INFO_BY_HANDLE_CLASS, LPVOID, DWORD);
|
static BOOL (WINAPI *pGetFileInformationByHandleEx)(HANDLE, FILE_INFO_BY_HANDLE_CLASS, LPVOID, DWORD);
|
||||||
static HANDLE (WINAPI *pOpenFileById)(HANDLE, LPFILE_ID_DESCRIPTOR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD);
|
static HANDLE (WINAPI *pOpenFileById)(HANDLE, LPFILE_ID_DESCRIPTOR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD);
|
||||||
|
static BOOL (WINAPI *pSetFileValidData)(HANDLE, LONGLONG);
|
||||||
|
|
||||||
/* keep filename and filenameW the same */
|
/* keep filename and filenameW the same */
|
||||||
static const char filename[] = "testfile.xxx";
|
static const char filename[] = "testfile.xxx";
|
||||||
@ -78,6 +79,7 @@ static void InitFunctionPointers(void)
|
|||||||
pQueueUserAPC = (void *) GetProcAddress(hkernel32, "QueueUserAPC");
|
pQueueUserAPC = (void *) GetProcAddress(hkernel32, "QueueUserAPC");
|
||||||
pGetFileInformationByHandleEx = (void *) GetProcAddress(hkernel32, "GetFileInformationByHandleEx");
|
pGetFileInformationByHandleEx = (void *) GetProcAddress(hkernel32, "GetFileInformationByHandleEx");
|
||||||
pOpenFileById = (void *) GetProcAddress(hkernel32, "OpenFileById");
|
pOpenFileById = (void *) GetProcAddress(hkernel32, "OpenFileById");
|
||||||
|
pSetFileValidData = (void *) GetProcAddress(hkernel32, "SetFileValidData");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test__hread( void )
|
static void test__hread( void )
|
||||||
@ -3438,6 +3440,139 @@ static void test_OpenFileById(void)
|
|||||||
DeleteFile(tempFileName);
|
DeleteFile(tempFileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_SetFileValidData(void)
|
||||||
|
{
|
||||||
|
BOOL ret;
|
||||||
|
HANDLE handle;
|
||||||
|
DWORD error, count;
|
||||||
|
char path[MAX_PATH], filename[MAX_PATH];
|
||||||
|
TOKEN_PRIVILEGES privs;
|
||||||
|
HANDLE token = NULL;
|
||||||
|
|
||||||
|
if (!pSetFileValidData)
|
||||||
|
{
|
||||||
|
win_skip("SetFileValidData is missing\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
GetTempPathA(sizeof(path), path);
|
||||||
|
GetTempFileNameA(path, "tst", 0, filename);
|
||||||
|
handle = CreateFileA(filename, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
|
||||||
|
WriteFile(handle, "test", sizeof("test") - 1, &count, NULL);
|
||||||
|
CloseHandle(handle);
|
||||||
|
|
||||||
|
SetLastError(0xdeadbeef);
|
||||||
|
ret = pSetFileValidData(INVALID_HANDLE_VALUE, 0);
|
||||||
|
error = GetLastError();
|
||||||
|
ok(!ret, "SetFileValidData succeeded\n");
|
||||||
|
ok(error == ERROR_INVALID_HANDLE, "got %u\n", error);
|
||||||
|
|
||||||
|
SetLastError(0xdeadbeef);
|
||||||
|
ret = pSetFileValidData(INVALID_HANDLE_VALUE, -1);
|
||||||
|
error = GetLastError();
|
||||||
|
ok(!ret, "SetFileValidData succeeded\n");
|
||||||
|
ok(error == ERROR_INVALID_HANDLE, "got %u\n", error);
|
||||||
|
|
||||||
|
/* file opened for reading */
|
||||||
|
handle = CreateFileA(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
|
||||||
|
|
||||||
|
SetLastError(0xdeadbeef);
|
||||||
|
ret = pSetFileValidData(handle, 0);
|
||||||
|
ok(!ret, "SetFileValidData succeeded\n");
|
||||||
|
error = GetLastError();
|
||||||
|
ok(error == ERROR_ACCESS_DENIED, "got %u\n", error);
|
||||||
|
|
||||||
|
SetLastError(0xdeadbeef);
|
||||||
|
ret = pSetFileValidData(handle, -1);
|
||||||
|
error = GetLastError();
|
||||||
|
ok(!ret, "SetFileValidData succeeded\n");
|
||||||
|
ok(error == ERROR_ACCESS_DENIED, "got %u\n", error);
|
||||||
|
CloseHandle(handle);
|
||||||
|
|
||||||
|
handle = CreateFileA(filename, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
|
||||||
|
|
||||||
|
SetLastError(0xdeadbeef);
|
||||||
|
ret = pSetFileValidData(handle, 0);
|
||||||
|
error = GetLastError();
|
||||||
|
ok(!ret, "SetFileValidData succeeded\n");
|
||||||
|
todo_wine ok(error == ERROR_PRIVILEGE_NOT_HELD, "got %u\n", error);
|
||||||
|
CloseHandle(handle);
|
||||||
|
|
||||||
|
privs.PrivilegeCount = 1;
|
||||||
|
privs.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
|
||||||
|
|
||||||
|
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token) ||
|
||||||
|
!LookupPrivilegeValue(NULL, SE_MANAGE_VOLUME_NAME, &privs.Privileges[0].Luid) ||
|
||||||
|
!AdjustTokenPrivileges(token, FALSE, &privs, sizeof(privs), NULL, NULL))
|
||||||
|
{
|
||||||
|
win_skip("cannot enable SE_MANAGE_VOLUME_NAME privilege\n");
|
||||||
|
CloseHandle(token);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
handle = CreateFileA(filename, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
|
||||||
|
|
||||||
|
SetLastError(0xdeadbeef);
|
||||||
|
ret = pSetFileValidData(handle, 0);
|
||||||
|
error = GetLastError();
|
||||||
|
ok(!ret, "SetFileValidData succeeded\n");
|
||||||
|
ok(error == ERROR_INVALID_PARAMETER, "got %u\n", error);
|
||||||
|
|
||||||
|
SetLastError(0xdeadbeef);
|
||||||
|
ret = pSetFileValidData(handle, -1);
|
||||||
|
error = GetLastError();
|
||||||
|
ok(!ret, "SetFileValidData succeeded\n");
|
||||||
|
ok(error == ERROR_INVALID_PARAMETER, "got %u\n", error);
|
||||||
|
|
||||||
|
SetLastError(0xdeadbeef);
|
||||||
|
ret = pSetFileValidData(handle, 2);
|
||||||
|
error = GetLastError();
|
||||||
|
todo_wine ok(!ret, "SetFileValidData succeeded\n");
|
||||||
|
todo_wine ok(error == ERROR_INVALID_PARAMETER, "got %u\n", error);
|
||||||
|
|
||||||
|
ret = pSetFileValidData(handle, 4);
|
||||||
|
ok(ret, "SetFileValidData failed %u\n", GetLastError());
|
||||||
|
|
||||||
|
SetLastError(0xdeadbeef);
|
||||||
|
ret = pSetFileValidData(handle, 8);
|
||||||
|
error = GetLastError();
|
||||||
|
ok(!ret, "SetFileValidData succeeded\n");
|
||||||
|
ok(error == ERROR_INVALID_PARAMETER, "got %u\n", error);
|
||||||
|
|
||||||
|
count = SetFilePointer(handle, 1024, NULL, FILE_END);
|
||||||
|
ok(count != INVALID_SET_FILE_POINTER, "SetFilePointer failed %u\n", GetLastError());
|
||||||
|
ret = SetEndOfFile(handle);
|
||||||
|
ok(ret, "SetEndOfFile failed %u\n", GetLastError());
|
||||||
|
|
||||||
|
SetLastError(0xdeadbeef);
|
||||||
|
ret = pSetFileValidData(handle, 2);
|
||||||
|
error = GetLastError();
|
||||||
|
todo_wine ok(!ret, "SetFileValidData succeeded\n");
|
||||||
|
todo_wine ok(error == ERROR_INVALID_PARAMETER, "got %u\n", error);
|
||||||
|
|
||||||
|
ret = pSetFileValidData(handle, 4);
|
||||||
|
ok(ret, "SetFileValidData failed %u\n", GetLastError());
|
||||||
|
|
||||||
|
ret = pSetFileValidData(handle, 8);
|
||||||
|
ok(ret, "SetFileValidData failed %u\n", GetLastError());
|
||||||
|
|
||||||
|
ret = pSetFileValidData(handle, 4);
|
||||||
|
error = GetLastError();
|
||||||
|
todo_wine ok(!ret, "SetFileValidData succeeded\n");
|
||||||
|
todo_wine ok(error == ERROR_INVALID_PARAMETER, "got %u\n", error);
|
||||||
|
|
||||||
|
ret = pSetFileValidData(handle, 1024);
|
||||||
|
ok(ret, "SetFileValidData failed %u\n", GetLastError());
|
||||||
|
|
||||||
|
ret = pSetFileValidData(handle, 2048);
|
||||||
|
error = GetLastError();
|
||||||
|
ok(!ret, "SetFileValidData succeeded\n");
|
||||||
|
ok(error == ERROR_INVALID_PARAMETER, "got %u\n", error);
|
||||||
|
|
||||||
|
privs.Privileges[0].Attributes = 0;
|
||||||
|
AdjustTokenPrivileges(token, FALSE, &privs, sizeof(privs), NULL, NULL);
|
||||||
|
CloseHandle(token);
|
||||||
|
DeleteFile(filename);
|
||||||
|
}
|
||||||
|
|
||||||
START_TEST(file)
|
START_TEST(file)
|
||||||
{
|
{
|
||||||
InitFunctionPointers();
|
InitFunctionPointers();
|
||||||
@ -3479,4 +3614,5 @@ START_TEST(file)
|
|||||||
test_ReplaceFileW();
|
test_ReplaceFileW();
|
||||||
test_GetFileInformationByHandleEx();
|
test_GetFileInformationByHandleEx();
|
||||||
test_OpenFileById();
|
test_OpenFileById();
|
||||||
|
test_SetFileValidData();
|
||||||
}
|
}
|
||||||
|
@ -81,6 +81,7 @@
|
|||||||
|
|
||||||
#include "winternl.h"
|
#include "winternl.h"
|
||||||
#include "winioctl.h"
|
#include "winioctl.h"
|
||||||
|
#include "ddk/ntddk.h"
|
||||||
#include "ddk/ntddser.h"
|
#include "ddk/ntddser.h"
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
|
WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
|
||||||
@ -2245,6 +2246,36 @@ NTSTATUS WINAPI NtSetInformationFile(HANDLE handle, PIO_STATUS_BLOCK io,
|
|||||||
io->u.Status = STATUS_INVALID_INFO_CLASS;
|
io->u.Status = STATUS_INVALID_INFO_CLASS;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case FileValidDataLengthInformation:
|
||||||
|
if (len >= sizeof(FILE_VALID_DATA_LENGTH_INFORMATION))
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
const FILE_VALID_DATA_LENGTH_INFORMATION *info = ptr;
|
||||||
|
|
||||||
|
if ((io->u.Status = server_get_unix_fd( handle, FILE_WRITE_DATA, &fd, &needs_close, NULL, NULL )))
|
||||||
|
return io->u.Status;
|
||||||
|
|
||||||
|
if (fstat( fd, &st ) == -1) io->u.Status = FILE_GetNtStatus();
|
||||||
|
else if (info->ValidDataLength.QuadPart <= 0 || (off_t)info->ValidDataLength.QuadPart > st.st_size)
|
||||||
|
io->u.Status = STATUS_INVALID_PARAMETER;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#ifdef HAVE_FALLOCATE
|
||||||
|
if (fallocate( fd, 0, 0, (off_t)info->ValidDataLength.QuadPart ) == -1)
|
||||||
|
{
|
||||||
|
NTSTATUS status = FILE_GetNtStatus();
|
||||||
|
if (status == STATUS_NOT_SUPPORTED) WARN( "fallocate not supported on this filesystem\n" );
|
||||||
|
else io->u.Status = status;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
FIXME( "setting valid data length not supported\n" );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
if (needs_close) close( fd );
|
||||||
|
}
|
||||||
|
else io->u.Status = STATUS_INVALID_PARAMETER_3;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
FIXME("Unsupported class (%d)\n", class);
|
FIXME("Unsupported class (%d)\n", class);
|
||||||
io->u.Status = STATUS_NOT_IMPLEMENTED;
|
io->u.Status = STATUS_NOT_IMPLEMENTED;
|
||||||
|
@ -98,6 +98,9 @@
|
|||||||
/* Define to 1 if you have the `epoll_create' function. */
|
/* Define to 1 if you have the `epoll_create' function. */
|
||||||
#undef HAVE_EPOLL_CREATE
|
#undef HAVE_EPOLL_CREATE
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `fallocate' function. */
|
||||||
|
#undef HAVE_FALLOCATE
|
||||||
|
|
||||||
/* Define to 1 if you have the `ffs' function. */
|
/* Define to 1 if you have the `ffs' function. */
|
||||||
#undef HAVE_FFS
|
#undef HAVE_FFS
|
||||||
|
|
||||||
|
@ -127,6 +127,11 @@ typedef struct _IMAGE_INFO
|
|||||||
ULONG ImageSectionNumber;
|
ULONG ImageSectionNumber;
|
||||||
} IMAGE_INFO, *PIMAGE_INFO;
|
} IMAGE_INFO, *PIMAGE_INFO;
|
||||||
|
|
||||||
|
typedef struct _FILE_VALID_DATA_LENGTH_INFORMATION
|
||||||
|
{
|
||||||
|
LARGE_INTEGER ValidDataLength;
|
||||||
|
} FILE_VALID_DATA_LENGTH_INFORMATION, *PFILE_VALID_DATA_LENGTH_INFORMATION;
|
||||||
|
|
||||||
typedef VOID (WINAPI *PDRIVER_REINITIALIZE)(PDRIVER_OBJECT,PVOID,ULONG);
|
typedef VOID (WINAPI *PDRIVER_REINITIALIZE)(PDRIVER_OBJECT,PVOID,ULONG);
|
||||||
typedef VOID (WINAPI *PLOAD_IMAGE_NOTIFY_ROUTINE)(PUNICODE_STRING,HANDLE,PIMAGE_INFO);
|
typedef VOID (WINAPI *PLOAD_IMAGE_NOTIFY_ROUTINE)(PUNICODE_STRING,HANDLE,PIMAGE_INFO);
|
||||||
typedef NTSTATUS (WINAPI *PIO_QUERY_DEVICE_ROUTINE)(PVOID,PUNICODE_STRING,INTERFACE_TYPE,ULONG,
|
typedef NTSTATUS (WINAPI *PIO_QUERY_DEVICE_ROUTINE)(PVOID,PUNICODE_STRING,INTERFACE_TYPE,ULONG,
|
||||||
|
@ -2188,6 +2188,7 @@ WINADVAPI BOOL WINAPI SetFileSecurityA(LPCSTR,SECURITY_INFORMATION,PSECU
|
|||||||
WINADVAPI BOOL WINAPI SetFileSecurityW(LPCWSTR,SECURITY_INFORMATION,PSECURITY_DESCRIPTOR);
|
WINADVAPI BOOL WINAPI SetFileSecurityW(LPCWSTR,SECURITY_INFORMATION,PSECURITY_DESCRIPTOR);
|
||||||
#define SetFileSecurity WINELIB_NAME_AW(SetFileSecurity)
|
#define SetFileSecurity WINELIB_NAME_AW(SetFileSecurity)
|
||||||
WINBASEAPI BOOL WINAPI SetFileTime(HANDLE,const FILETIME*,const FILETIME*,const FILETIME*);
|
WINBASEAPI BOOL WINAPI SetFileTime(HANDLE,const FILETIME*,const FILETIME*,const FILETIME*);
|
||||||
|
WINBASEAPI BOOL WINAPI SetFileValidData(HANDLE,LONGLONG);
|
||||||
WINBASEAPI UINT WINAPI SetHandleCount(UINT);
|
WINBASEAPI UINT WINAPI SetHandleCount(UINT);
|
||||||
WINBASEAPI BOOL WINAPI SetHandleInformation(HANDLE,DWORD,DWORD);
|
WINBASEAPI BOOL WINAPI SetHandleInformation(HANDLE,DWORD,DWORD);
|
||||||
WINBASEAPI BOOL WINAPI SetInformationJobObject(HANDLE,JOBOBJECTINFOCLASS,LPVOID,DWORD);
|
WINBASEAPI BOOL WINAPI SetInformationJobObject(HANDLE,JOBOBJECTINFOCLASS,LPVOID,DWORD);
|
||||||
|
Loading…
Reference in New Issue
Block a user