[MOUNTMGR_APITEST] Improve QueryPoints.c test (#6990)

- Use %lu instead of %lx for printf-ing last-errors;

- Don't call GetLastError() within ok, or after a previous invocation,
  when the aim is to retrieve the last-error set by a tested API.
  Instead, store its value in a local variable, that is then used in
  the ok() tests.

- Use win_skip() only for functionality that _may_ not be implemented
  in Windows/ReactOS yet, but not for unexpected situations leading to
  tests being skipped.

- Add comments; improve buffer size specifications.

- Reformat the file license header.
This commit is contained in:
Hermès Bélusca-Maïto 2025-01-06 21:51:08 +01:00
parent 2da5db933c
commit bb264f6828
No known key found for this signature in database
GPG key ID: 3B2539C65E7B93D0

View file

@ -1,68 +1,75 @@
/* /*
* PROJECT: ReactOS api tests * PROJECT: ReactOS API Tests
* LICENSE: GPLv2+ - See COPYING in the top level directory * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
* PURPOSE: Test for QueryPoints IOCTL * PURPOSE: Test for IOCTL_MOUNTMGR_QUERY_POINTS
* PROGRAMMER: Pierre Schweitzer * COPYRIGHT: Copyright 2019 Pierre Schweitzer <pierre@reactos.org>
*/ */
#include "precomp.h" #include "precomp.h"
VOID VOID
TraceMountPoint(PMOUNTMGR_MOUNT_POINTS MountPoints, TraceMountPoint(
PMOUNTMGR_MOUNT_POINT MountPoint) _In_ const MOUNTMGR_MOUNT_POINTS* MountPoints,
_In_ const MOUNTMGR_MOUNT_POINT* MountPoint)
{ {
trace("MountPoint: %p\n", MountPoint); trace("MountPoint: %p\n", MountPoint);
trace("\tSymbolicOffset: %ld\n", MountPoint->SymbolicLinkNameOffset); trace("\tSymbolicOffset: %ld\n", MountPoint->SymbolicLinkNameOffset);
trace("\tSymbolicLinkName: %.*S\n", MountPoint->SymbolicLinkNameLength / sizeof(WCHAR), (PWSTR)((ULONG_PTR)MountPoints + MountPoint->SymbolicLinkNameOffset)); trace("\tSymbolicLinkName: %.*S\n",
MountPoint->SymbolicLinkNameLength / sizeof(WCHAR),
(PWCHAR)((ULONG_PTR)MountPoints + MountPoint->SymbolicLinkNameOffset));
trace("\tDeviceOffset: %ld\n", MountPoint->DeviceNameOffset); trace("\tDeviceOffset: %ld\n", MountPoint->DeviceNameOffset);
trace("\tDeviceName: %.*S\n", MountPoint->DeviceNameLength / sizeof(WCHAR), (PWSTR)((ULONG_PTR)MountPoints + MountPoint->DeviceNameOffset)); trace("\tDeviceName: %.*S\n",
MountPoint->DeviceNameLength / sizeof(WCHAR),
(PWCHAR)((ULONG_PTR)MountPoints + MountPoint->DeviceNameOffset));
} }
START_TEST(QueryPoints) START_TEST(QueryPoints)
{ {
BOOL Ret; BOOL Ret;
HANDLE MountMgrHandle; HANDLE MountMgrHandle;
DWORD BytesReturned, Drives, i; DWORD LastError, BytesReturned, Drives, i;
struct { struct
{
MOUNTMGR_MOUNT_POINT; MOUNTMGR_MOUNT_POINT;
WCHAR Buffer[sizeof(L"\\DosDevice\\A:")]; WCHAR Buffer[sizeof("\\DosDevice\\A:")];
} SinglePoint; } SinglePoint;
MOUNTMGR_MOUNT_POINTS MountPoints; MOUNTMGR_MOUNT_POINTS MountPoints;
PMOUNTMGR_MOUNT_POINTS AllocatedPoints; PMOUNTMGR_MOUNT_POINTS AllocatedPoints;
MountMgrHandle = CreateFileW(MOUNTMGR_DOS_DEVICE_NAME, 0, MountMgrHandle = GetMountMgrHandle();
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, if (!MountMgrHandle)
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
INVALID_HANDLE_VALUE);
if (MountMgrHandle == INVALID_HANDLE_VALUE)
{ {
win_skip("MountMgr unavailable: %lx\n", GetLastError()); win_skip("MountMgr unavailable: %lu\n", GetLastError());
return; return;
} }
ZeroMemory(&SinglePoint, sizeof(SinglePoint)); ZeroMemory(&SinglePoint, sizeof(SinglePoint));
/* Retrieve the size needed to enumerate all the existing mount points */
Ret = DeviceIoControl(MountMgrHandle, IOCTL_MOUNTMGR_QUERY_POINTS, Ret = DeviceIoControl(MountMgrHandle, IOCTL_MOUNTMGR_QUERY_POINTS,
&SinglePoint, sizeof(MOUNTMGR_MOUNT_POINT), &SinglePoint, sizeof(MOUNTMGR_MOUNT_POINT), // Size without the string.
&MountPoints, sizeof(MOUNTMGR_MOUNT_POINTS), &MountPoints, sizeof(MountPoints),
&BytesReturned, NULL); &BytesReturned, NULL);
ok(Ret == FALSE, "IOCTL unexpectedly succeed\n"); LastError = GetLastError();
ok(GetLastError() == ERROR_MORE_DATA, "Unexcepted failure: %lx\n", GetLastError()); ok(Ret == FALSE, "IOCTL unexpectedly succeeded\n");
ok(LastError == ERROR_MORE_DATA, "Unexpected failure: %lu\n", LastError);
/* Allocate a suitably-sized buffer for the mount points */
AllocatedPoints = RtlAllocateHeap(RtlGetProcessHeap(), 0, MountPoints.Size); AllocatedPoints = RtlAllocateHeap(RtlGetProcessHeap(), 0, MountPoints.Size);
if (AllocatedPoints == NULL) if (AllocatedPoints == NULL)
{ {
win_skip("Insufficiant memory\n"); skip("Insufficient memory\n");
} }
else else
{ {
AllocatedPoints->NumberOfMountPoints = 0; AllocatedPoints->NumberOfMountPoints = 0;
/* Retrieve the list of all the existing mount points */
Ret = DeviceIoControl(MountMgrHandle, IOCTL_MOUNTMGR_QUERY_POINTS, Ret = DeviceIoControl(MountMgrHandle, IOCTL_MOUNTMGR_QUERY_POINTS,
&SinglePoint, sizeof(MOUNTMGR_MOUNT_POINT), &SinglePoint, sizeof(MOUNTMGR_MOUNT_POINT), // Size without the string.
AllocatedPoints, MountPoints.Size, AllocatedPoints, MountPoints.Size,
&BytesReturned, NULL); &BytesReturned, NULL);
ok(Ret == TRUE, "IOCTL unexpectedly failed %lx\n", GetLastError()); ok(Ret == TRUE, "IOCTL unexpectedly failed: %lu\n", GetLastError());
for (i = 0; i < AllocatedPoints->NumberOfMountPoints; ++i) for (i = 0; i < AllocatedPoints->NumberOfMountPoints; ++i)
{ {
@ -72,40 +79,37 @@ START_TEST(QueryPoints)
RtlFreeHeap(RtlGetProcessHeap(), 0, AllocatedPoints); RtlFreeHeap(RtlGetProcessHeap(), 0, AllocatedPoints);
} }
/* Now, find the first unused drive letter */
Drives = GetLogicalDrives(); Drives = GetLogicalDrives();
if (Drives == 0) if (Drives == 0)
{ {
win_skip("Drives map unavailable: %lx\n", GetLastError()); skip("Drives map unavailable: %lu\n", GetLastError());
goto Done; goto Done;
} }
for (i = 0; i <= 'Z'-'A'; ++i)
for (i = 0; i < 26; i++)
{ {
if (!(Drives & (1 << i))) if (!(Drives & (1 << i)))
{
break; break;
}
} }
if (i > 'Z'-'A')
if (i == 26)
{ {
win_skip("All the drive letters are in use, skipping\n"); skip("All the drive letters are in use, skipping\n");
goto Done; goto Done;
} }
SinglePoint.SymbolicLinkNameOffset = sizeof(MOUNTMGR_MOUNT_POINT); /* Check that this drive letter is not an existing mount point */
SinglePoint.SymbolicLinkNameLength = sizeof(L"\\DosDevice\\A:") - sizeof(UNICODE_NULL); SinglePoint.SymbolicLinkNameOffset = ((ULONG_PTR)&SinglePoint.Buffer - (ULONG_PTR)&SinglePoint);
StringCbPrintfW((PWSTR)((ULONG_PTR)&SinglePoint + sizeof(MOUNTMGR_MOUNT_POINT)), SinglePoint.SymbolicLinkNameLength = sizeof(SinglePoint.Buffer) - sizeof(UNICODE_NULL);
sizeof(L"\\DosDevice\\A:"), StringCbPrintfW(SinglePoint.Buffer, sizeof(SinglePoint.Buffer),
L"\\DosDevice\\%C:", L"\\DosDevice\\%C:", L'A' + i);
i + L'A');
Ret = DeviceIoControl(MountMgrHandle, IOCTL_MOUNTMGR_QUERY_POINTS, Ret = DeviceIoControl(MountMgrHandle, IOCTL_MOUNTMGR_QUERY_POINTS,
&SinglePoint, sizeof(SinglePoint), &SinglePoint, sizeof(SinglePoint),
&MountPoints, sizeof(MOUNTMGR_MOUNT_POINTS), &MountPoints, sizeof(MountPoints),
&BytesReturned, NULL); &BytesReturned, NULL);
ok(Ret == FALSE, "IOCTL unexpectedly succeed\n"); LastError = GetLastError();
ok(GetLastError() == ERROR_FILE_NOT_FOUND, "Unexcepted failure: %lx\n", GetLastError()); ok(Ret == FALSE, "IOCTL unexpectedly succeeded\n");
ok(LastError == ERROR_FILE_NOT_FOUND, "Unexpected failure: %lu\n", LastError);
Done: Done:
CloseHandle(MountMgrHandle); CloseHandle(MountMgrHandle);