kernel32: Implement a few more classes in GetFileInformationByHandleEx.

This commit is contained in:
Martin Storsjo 2015-05-20 20:44:56 +03:00 committed by Alexandre Julliard
parent 74ef3af73d
commit 68b654ad2f
3 changed files with 107 additions and 17 deletions

View File

@ -897,8 +897,6 @@ BOOL WINAPI GetFileInformationByHandleEx( HANDLE handle, FILE_INFO_BY_HANDLE_CLA
switch (class)
{
case FileBasicInfo:
case FileStandardInfo:
case FileRenameInfo:
case FileDispositionInfo:
case FileAllocationInfo:
@ -919,31 +917,36 @@ BOOL WINAPI GetFileInformationByHandleEx( HANDLE handle, FILE_INFO_BY_HANDLE_CLA
SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
return FALSE;
case FileBasicInfo:
status = NtQueryInformationFile( handle, &io, info, size, FileBasicInformation );
break;
case FileStandardInfo:
status = NtQueryInformationFile( handle, &io, info, size, FileStandardInformation );
break;
case FileNameInfo:
status = NtQueryInformationFile( handle, &io, info, size, FileNameInformation );
if (status != STATUS_SUCCESS)
{
SetLastError( RtlNtStatusToDosError( status ) );
return FALSE;
}
return TRUE;
break;
case FileIdBothDirectoryRestartInfo:
case FileIdBothDirectoryInfo:
status = NtQueryDirectoryFile( handle, NULL, NULL, NULL, &io, info, size,
FileIdBothDirectoryInformation, FALSE, NULL,
(class == FileIdBothDirectoryRestartInfo) );
break;
default:
SetLastError( ERROR_INVALID_PARAMETER );
return FALSE;
}
if (status != STATUS_SUCCESS)
{
SetLastError( RtlNtStatusToDosError( status ) );
return FALSE;
}
return TRUE;
default:
SetLastError( ERROR_INVALID_PARAMETER );
return FALSE;
}
}

View File

@ -3821,11 +3821,15 @@ else
static void test_GetFileInformationByHandleEx(void)
{
int i;
char tempPath[MAX_PATH], tempFileName[MAX_PATH], buffer[1024];
char tempPath[MAX_PATH], tempFileName[MAX_PATH], buffer[1024], *strPtr;
BOOL ret;
DWORD ret2;
HANDLE directory;
DWORD ret2, written;
HANDLE directory, file;
FILE_ID_BOTH_DIR_INFO *bothDirInfo;
FILE_BASIC_INFO *basicInfo;
FILE_STANDARD_INFO *standardInfo;
FILE_NAME_INFO *nameInfo;
LARGE_INTEGER prevWrite;
struct {
FILE_INFO_BY_HANDLE_CLASS handleClass;
void *ptr;
@ -3888,6 +3892,68 @@ static void test_GetFileInformationByHandleEx(void)
}
CloseHandle(directory);
file = CreateFileA(tempFileName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL, OPEN_EXISTING, 0, NULL);
ok(file != INVALID_HANDLE_VALUE, "GetFileInformationByHandleEx: failed to open the temp file, "
"got error %u.\n", GetLastError());
/* Test FileBasicInfo; make sure the write time changes when a file is updated */
memset(buffer, 0xff, sizeof(buffer));
ret = pGetFileInformationByHandleEx(file, FileBasicInfo, buffer, sizeof(buffer));
ok(ret, "GetFileInformationByHandleEx: failed to get FileBasicInfo, %u\n", GetLastError());
basicInfo = (FILE_BASIC_INFO *)buffer;
prevWrite = basicInfo->LastWriteTime;
CloseHandle(file);
Sleep(30); /* Make sure a new write time is different from the previous */
/* Write something to the file, to make sure the write time has changed */
file = CreateFileA(tempFileName, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL, OPEN_EXISTING, 0, NULL);
ok(file != INVALID_HANDLE_VALUE, "GetFileInformationByHandleEx: failed to open the temp file, "
"got error %u.\n", GetLastError());
ret = WriteFile(file, tempFileName, strlen(tempFileName), &written, NULL);
ok(ret, "GetFileInformationByHandleEx: Write failed\n");
CloseHandle(file);
file = CreateFileA(tempFileName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL, OPEN_EXISTING, 0, NULL);
ok(file != INVALID_HANDLE_VALUE, "GetFileInformationByHandleEx: failed to open the temp file, "
"got error %u.\n", GetLastError());
memset(buffer, 0xff, sizeof(buffer));
ret = pGetFileInformationByHandleEx(file, FileBasicInfo, buffer, sizeof(buffer));
ok(ret, "GetFileInformationByHandleEx: failed to get FileBasicInfo, %u\n", GetLastError());
basicInfo = (FILE_BASIC_INFO *)buffer;
/* Could also check that the creation time didn't change - on windows
* it doesn't, but on wine, it does change even if it shouldn't. */
ok(basicInfo->LastWriteTime.QuadPart != prevWrite.QuadPart,
"GetFileInformationByHandleEx: last write time didn't change\n");
/* Test FileStandardInfo, check some basic parameters */
memset(buffer, 0xff, sizeof(buffer));
ret = pGetFileInformationByHandleEx(file, FileStandardInfo, buffer, sizeof(buffer));
ok(ret, "GetFileInformationByHandleEx: failed to get FileStandardInfo, %u\n", GetLastError());
standardInfo = (FILE_STANDARD_INFO *)buffer;
ok(standardInfo->NumberOfLinks == 1, "GetFileInformationByHandleEx: Unexpcted number of links\n");
ok(standardInfo->DeletePending == FALSE, "GetFileInformationByHandleEx: Unexpcted pending delete\n");
ok(standardInfo->Directory == FALSE, "GetFileInformationByHandleEx: Incorrect directory flag\n");
/* Test FileNameInfo */
memset(buffer, 0xff, sizeof(buffer));
ret = pGetFileInformationByHandleEx(file, FileNameInfo, buffer, sizeof(buffer));
ok(ret, "GetFileInformationByHandleEx: failed to get FileNameInfo, %u\n", GetLastError());
nameInfo = (FILE_NAME_INFO *)buffer;
strPtr = strchr(tempFileName, '\\');
ok(strPtr != NULL, "GetFileInformationByHandleEx: Temp filename didn't contain backslash\n");
ok(nameInfo->FileNameLength == strlen(strPtr) * 2,
"GetFileInformationByHandleEx: Incorrect file name length\n");
for (i = 0; i < nameInfo->FileNameLength/2; i++)
ok(strPtr[i] == nameInfo->FileName[i], "Incorrect filename char %d: %c vs %c\n",
i, strPtr[i], nameInfo->FileName[i]);
CloseHandle(file);
DeleteFileA(tempFileName);
}

View File

@ -823,6 +823,27 @@ typedef struct _FILE_ID_BOTH_DIR_INFO {
WCHAR FileName[1];
} FILE_ID_BOTH_DIR_INFO, *PFILE_ID_BOTH_DIR_INFO;
typedef struct _FILE_BASIC_INFO {
LARGE_INTEGER CreationTime;
LARGE_INTEGER LastAccessTime;
LARGE_INTEGER LastWriteTime;
LARGE_INTEGER ChangeTime;
DWORD FileAttributes;
} FILE_BASIC_INFO, *PFILE_BASIC_INFO;
typedef struct _FILE_STANDARD_INFO {
LARGE_INTEGER AllocationSize;
LARGE_INTEGER EndOfFile;
DWORD NumberOfLinks;
BOOLEAN DeletePending;
BOOLEAN Directory;
} FILE_STANDARD_INFO, *PFILE_STANDARD_INFO;
typedef struct _FILE_NAME_INFO {
DWORD FileNameLength;
WCHAR FileName[1];
} FILE_NAME_INFO, *PFILE_NAME_INFO;
#define PIPE_ACCESS_INBOUND 1
#define PIPE_ACCESS_OUTBOUND 2
#define PIPE_ACCESS_DUPLEX 3