kernel32: Implement a few more classes in GetFileInformationByHandleEx.
This commit is contained in:
parent
74ef3af73d
commit
68b654ad2f
|
@ -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) );
|
||||
if (status != STATUS_SUCCESS)
|
||||
{
|
||||
SetLastError( RtlNtStatusToDosError( status ) );
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
break;
|
||||
|
||||
default:
|
||||
SetLastError( ERROR_INVALID_PARAMETER );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (status != STATUS_SUCCESS)
|
||||
{
|
||||
SetLastError( RtlNtStatusToDosError( status ) );
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue