[PATCH 3/5] kernel32/tests: Add a IOCTL_DVD_READ_STRUCTURE (DvdPhysicalDescriptor) test (try 2)
Alexandre Goujon
ale.goujon at gmail.com
Sun Jun 17 05:11:26 CDT 2012
and fix wine
This one superseeds my previous attempt (#87004)
---
dlls/kernel32/tests/volume.c | 91 ++++++++++++++++++++++++++++++++++++
dlls/ntdll/cdrom.c | 105 ++++++++++++++++++------------------------
2 files changed, 136 insertions(+), 60 deletions(-)
diff --git a/dlls/kernel32/tests/volume.c b/dlls/kernel32/tests/volume.c
index b459ba6..cf402ad 100644
--- a/dlls/kernel32/tests/volume.c
+++ b/dlls/kernel32/tests/volume.c
@@ -22,6 +22,17 @@
#include "winbase.h"
#include "winioctl.h"
#include <stdio.h>
+#include "ddk/ntddcdvd.h"
+
+#include <pshpack1.h>
+struct COMPLETE_DVD_LAYER_DESCRIPTOR
+{
+ DVD_DESCRIPTOR_HEADER Header;
+ DVD_LAYER_DESCRIPTOR Descriptor;
+ UCHAR Padding;
+};
+#include <poppack.h>
+C_ASSERT(sizeof(struct COMPLETE_DVD_LAYER_DESCRIPTOR) == 22);
static HINSTANCE hdll;
static BOOL (WINAPI * pGetVolumeNameForVolumeMountPointA)(LPCSTR, LPSTR, DWORD);
@@ -730,6 +741,85 @@ static void test_GetVolumePathNamesForVolumeNameW(void)
ok(error == ERROR_FILE_NOT_FOUND, "expected ERROR_FILE_NOT_FOUND got %u\n", error);
}
+static void test_dvd_read_structure(HANDLE handle)
+{
+ int i;
+ DWORD nbBytes;
+ BOOL ret;
+ DVD_READ_STRUCTURE dvdReadStructure;
+ DVD_LAYER_DESCRIPTOR dvdLayerDescriptor;
+ struct COMPLETE_DVD_LAYER_DESCRIPTOR completeDvdLayerDescriptor;
+
+ dvdReadStructure.BlockByteOffset.QuadPart = 0;
+ dvdReadStructure.SessionId = 0;
+ dvdReadStructure.LayerNumber = 0;
+
+
+ /* DvdPhysicalDescriptor */
+ dvdReadStructure.Format = 0;
+
+ SetLastError(0xdeadbeef);
+
+ /* Test whether this ioctl is supported */
+ ret = DeviceIoControl(handle, IOCTL_DVD_READ_STRUCTURE, &dvdReadStructure, sizeof(DVD_READ_STRUCTURE),
+ &completeDvdLayerDescriptor, sizeof(struct COMPLETE_DVD_LAYER_DESCRIPTOR), &nbBytes, NULL);
+ if ((!ret && GetLastError() == ERROR_INVALID_FUNCTION)
+ || (!ret && GetLastError() == ERROR_NOT_SUPPORTED))
+ {
+ skip("IOCTL_DVD_READ_STRUCTURE not supported\n");
+ return;
+ }
+
+ ok(ret || broken(GetLastError() == ERROR_NOT_READY) || broken(GetLastError() == ERROR_INVALID_PARAMETER),
+ "IOCTL_DVD_READ_STRUCTURE (DvdPhysicalDescriptor) failed, last error = %u\n", GetLastError());
+ if(!ret)
+ return;
+
+ /* Confirm there is always a header before the actual data */
+ ok( completeDvdLayerDescriptor.Header.Length == 0x0802, "Length is 0x%04x instead of 0x0802\n", completeDvdLayerDescriptor.Header.Length);
+ ok( completeDvdLayerDescriptor.Header.Reserved[0] == 0, "Reserved[0] is %x instead of 0\n", completeDvdLayerDescriptor.Header.Reserved[0]);
+ ok( completeDvdLayerDescriptor.Header.Reserved[1] == 0, "Reserved[1] is %x instead of 0\n", completeDvdLayerDescriptor.Header.Reserved[1]);
+
+ /* TODO: Also check completeDvdLayerDescriptor.Descriptor content (via IOCTL_SCSI_PASS_THROUGH_DIRECT ?) */
+
+ /* Insufficient output buffer */
+ for(i=0; i<sizeof(DVD_DESCRIPTOR_HEADER); i++)
+ {
+ SetLastError(0xdeadbeef);
+
+ ret = DeviceIoControl(handle, IOCTL_DVD_READ_STRUCTURE, &dvdReadStructure, sizeof(DVD_READ_STRUCTURE),
+ &completeDvdLayerDescriptor, i, &nbBytes, NULL);
+ ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,"IOCTL_DVD_READ_STRUCTURE should fail with small buffer\n");
+ }
+
+ SetLastError(0xdeadbeef);
+
+ /* On newer version, an output buffer of sizeof(DVD_READ_STRUCTURE) size fails.
+ I think this is to force developpers to realize that there is a header before the actual content */
+ ret = DeviceIoControl(handle, IOCTL_DVD_READ_STRUCTURE, &dvdReadStructure, sizeof(DVD_READ_STRUCTURE),
+ &dvdLayerDescriptor, sizeof(DVD_LAYER_DESCRIPTOR), &nbBytes, NULL);
+ ok( (!ret && GetLastError() == ERROR_INVALID_PARAMETER) || broken(ret) /* < Win7 */,
+ "IOCTL_DVD_READ_STRUCTURE should have failed\n");
+
+ SetLastError(0xdeadbeef);
+
+ ret = DeviceIoControl(handle, IOCTL_DVD_READ_STRUCTURE, NULL, sizeof(DVD_READ_STRUCTURE),
+ &completeDvdLayerDescriptor, sizeof(struct COMPLETE_DVD_LAYER_DESCRIPTOR), &nbBytes, NULL);
+ ok( (!ret && GetLastError() == ERROR_INVALID_PARAMETER),
+ "IOCTL_DVD_READ_STRUCTURE should have failed\n");
+
+ /* Test wrong input parameters */
+ for(i=0; i<sizeof(DVD_READ_STRUCTURE); i++)
+ {
+ SetLastError(0xdeadbeef);
+
+ ret = DeviceIoControl(handle, IOCTL_DVD_READ_STRUCTURE, &dvdReadStructure, i,
+ &completeDvdLayerDescriptor, sizeof(struct COMPLETE_DVD_LAYER_DESCRIPTOR), &nbBytes, NULL);
+ ok( (!ret && GetLastError() == ERROR_INVALID_PARAMETER),
+ "IOCTL_DVD_READ_STRUCTURE should have failed\n");
+ }
+}
+
static void test_cdrom_ioctl(void)
{
char drive_letter, drive_path[] = "A:\\", drive_full_path[] = "\\\\.\\A:";
@@ -766,6 +856,7 @@ static void test_cdrom_ioctl(void)
}
/* Add your tests here */
+ test_dvd_read_structure(handle);
CloseHandle(handle);
}
diff --git a/dlls/ntdll/cdrom.c b/dlls/ntdll/cdrom.c
index 53854a8..72157eb 100644
--- a/dlls/ntdll/cdrom.c
+++ b/dlls/ntdll/cdrom.c
@@ -225,25 +225,11 @@ static const char *iocodex(DWORD code)
*/
typedef struct
{
- UCHAR DataLength[2];
- UCHAR Reserved0[2];
- UCHAR BookVersion : 4;
- UCHAR BookType : 4;
- UCHAR MinimumRate : 4;
- UCHAR DiskSize : 4;
- UCHAR LayerType : 4;
- UCHAR TrackPath : 1;
- UCHAR NumberOfLayers : 2;
- UCHAR Reserved1 : 1;
- UCHAR TrackDensity : 4;
- UCHAR LinearDensity : 4;
- ULONG StartingDataSector;
- ULONG EndDataSector;
- ULONG EndLayerZeroSector;
- UCHAR Reserved5 : 7;
- UCHAR BCAFlag : 1;
- UCHAR Reserved6;
+ DVD_DESCRIPTOR_HEADER Header;
+ DVD_LAYER_DESCRIPTOR Descriptor;
+ UCHAR Padding;
} internal_dvd_layer_descriptor;
+C_ASSERT(sizeof(internal_dvd_layer_descriptor) == 22);
static NTSTATUS CDROM_ReadTOC(int, int, CDROM_TOC*);
@@ -2503,7 +2489,7 @@ static NTSTATUS DVD_GetRegion(int fd, PDVD_REGION region)
*
*
*/
-static NTSTATUS DVD_ReadStructure(int dev, const DVD_READ_STRUCTURE *structure, PDVD_LAYER_DESCRIPTOR layer)
+static NTSTATUS DVD_ReadStructure(int dev, const DVD_READ_STRUCTURE *structure, PDVD_LAYER_DESCRIPTOR layer, DWORD outBufferSize)
{
#ifdef DVD_READ_STRUCT
/* dvd_struct is not defined consistently across platforms */
@@ -2551,7 +2537,10 @@ static NTSTATUS DVD_ReadStructure(int dev, const DVD_READ_STRUCTURE *structure,
}
if (ioctl(dev, DVD_READ_STRUCT, &s) < 0)
+ {
+ ERR("DVD_READ_STRUCT ioctl failed : %s\n", strerror(errno));
return STATUS_INVALID_PARAMETER;
+ }
switch (structure->Format)
{
@@ -2560,26 +2549,24 @@ static NTSTATUS DVD_ReadStructure(int dev, const DVD_READ_STRUCTURE *structure,
internal_dvd_layer_descriptor *p = (internal_dvd_layer_descriptor *) layer;
struct dvd_layer *l = &s.physical.layer[s.physical.layer_num];
- p->DataLength[0] = 2;
- p->DataLength[1] = 8;
- p->Reserved0[0] = 0;
- p->Reserved0[1] = 0;
- p->BookVersion = l->book_version;
- p->BookType = l->book_type;
- p->MinimumRate = l->min_rate;
- p->DiskSize = l->disc_size;
- p->LayerType = l->layer_type;
- p->TrackPath = l->track_path;
- p->NumberOfLayers = l->nlayers;
- p->Reserved1 = 0;
- p->TrackDensity = l->track_density;
- p->LinearDensity = l->linear_density;
- p->StartingDataSector = GET_BE_DWORD(l->start_sector);
- p->EndDataSector = GET_BE_DWORD(l->end_sector);
- p->EndLayerZeroSector = GET_BE_DWORD(l->end_sector_l0);
- p->Reserved5 = 0;
- p->BCAFlag = l->bca;
- p->Reserved6 = 0;
+ p->Header.Length = 0x0802;
+ p->Header.Reserved[0] = 0;
+ p->Header.Reserved[1] = 0;
+ p->Descriptor.BookVersion = l->book_version;
+ p->Descriptor.BookType = l->book_type;
+ p->Descriptor.MinimumRate = l->min_rate;
+ p->Descriptor.DiskSize = l->disc_size;
+ p->Descriptor.LayerType = l->layer_type;
+ p->Descriptor.TrackPath = l->track_path;
+ p->Descriptor.NumberOfLayers = l->nlayers;
+ p->Descriptor.Reserved1 = 0;
+ p->Descriptor.TrackDensity = l->track_density;
+ p->Descriptor.LinearDensity = l->linear_density;
+ p->Descriptor.StartingDataSector = GET_BE_DWORD(l->start_sector);
+ p->Descriptor.EndDataSector = GET_BE_DWORD(l->end_sector);
+ p->Descriptor.EndLayerZeroSector = GET_BE_DWORD(l->end_sector_l0);
+ p->Descriptor.Reserved5 = 0;
+ p->Descriptor.BCAFlag = l->bca;
}
break;
@@ -2685,26 +2672,24 @@ static NTSTATUS DVD_ReadStructure(int dev, const DVD_READ_STRUCTURE *structure,
switch(structure->Format)
{
case DvdPhysicalDescriptor:
- nt_desc.xlayer->DataLength[0] = 2;
- nt_desc.xlayer->DataLength[1] = 8;
- nt_desc.xlayer->Reserved0[0] = 0;
- nt_desc.xlayer->Reserved0[1] = 0;
- nt_desc.xlayer->BookVersion = desc.phys.partVersion;
- nt_desc.xlayer->BookType = desc.phys.bookType;
- nt_desc.xlayer->MinimumRate = desc.phys.minimumRate;
- nt_desc.xlayer->DiskSize = desc.phys.discSize;
- nt_desc.xlayer->LayerType = desc.phys.layerType;
- nt_desc.xlayer->TrackPath = desc.phys.trackPath;
- nt_desc.xlayer->NumberOfLayers = desc.phys.numberOfLayers;
- nt_desc.xlayer->Reserved1 = 0;
- nt_desc.xlayer->TrackDensity = desc.phys.trackDensity;
- nt_desc.xlayer->LinearDensity = desc.phys.linearDensity;
- nt_desc.xlayer->BCAFlag = desc.phys.bcaFlag;
- nt_desc.xlayer->StartingDataSector = *(DWORD *)&desc.phys.zero1;
- nt_desc.xlayer->EndDataSector = *(DWORD *)&desc.phys.zero2;
- nt_desc.xlayer->EndLayerZeroSector = *(DWORD *)&desc.phys.zero3;
- nt_desc.xlayer->Reserved5 = 0;
- nt_desc.xlayer->Reserved6 = 0;
+ nt_desc.xlayer->Header.Length = 0x0802;
+ nt_desc.xlayer->Header.Reserved[0] = 0;
+ nt_desc.xlayer->Header.Reserved[1] = 0;
+ nt_desc.xlayer->Descriptor.BookVersion = desc.phys.partVersion;
+ nt_desc.xlayer->Descriptor.BookType = desc.phys.bookType;
+ nt_desc.xlayer->Descriptor.MinimumRate = desc.phys.minimumRate;
+ nt_desc.xlayer->Descriptor.DiskSize = desc.phys.discSize;
+ nt_desc.xlayer->Descriptor.LayerType = desc.phys.layerType;
+ nt_desc.xlayer->Descriptor.TrackPath = desc.phys.trackPath;
+ nt_desc.xlayer->Descriptor.NumberOfLayers = desc.phys.numberOfLayers;
+ nt_desc.xlayer->Descriptor.Reserved1 = 0;
+ nt_desc.xlayer->Descriptor.TrackDensity = desc.phys.trackDensity;
+ nt_desc.xlayer->Descriptor.LinearDensity = desc.phys.linearDensity;
+ nt_desc.xlayer->Descriptor.StartingDataSector = GET_BE_DWORD(*(DWORD *)&desc.phys.zero1);
+ nt_desc.xlayer->Descriptor.EndDataSector = GET_BE_DWORD(*(DWORD *)&desc.phys.zero2);
+ nt_desc.xlayer->Descriptor.EndLayerZeroSector = GET_BE_DWORD(*(DWORD *)&desc.phys.zero3);
+ nt_desc.xlayer->Descriptor.Reserved5 = 0;
+ nt_desc.xlayer->Descriptor.BCAFlag = desc.phys.bcaFlag;
break;
case DvdCopyrightDescriptor:
@@ -3105,7 +3090,7 @@ NTSTATUS CDROM_DeviceIoControl(HANDLE hDevice,
else
{
TRACE("doing DVD_READ_STRUCTURE\n");
- status = DVD_ReadStructure(fd, lpInBuffer, lpOutBuffer);
+ status = DVD_ReadStructure(fd, lpInBuffer, lpOutBuffer, nOutBufferSize);
}
break;
--
1.7.9.5
More information about the wine-patches
mailing list