Wine-devel
Threads by month
- ----- 2026 -----
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
November 2019
- 85 participants
- 778 discussions
[PATCH v2] ddraw: Track the viewport and scissor rect in the primary stateblock.
by Zebediah Figura 25 Nov '19
by Zebediah Figura 25 Nov '19
25 Nov '19
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/ddraw/device.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/dlls/ddraw/device.c b/dlls/ddraw/device.c
index 4ad1fdb7f57..ffa029321c1 100644
--- a/dlls/ddraw/device.c
+++ b/dlls/ddraw/device.c
@@ -6961,6 +6961,17 @@ enum wined3d_depth_buffer_type d3d_device_update_depth_stencil(struct d3d_device
return WINED3D_ZB_TRUE;
}
+static void ddraw_reset_viewport_state(struct ddraw *ddraw)
+{
+ struct wined3d_viewport vp;
+ RECT rect;
+
+ wined3d_device_get_viewports(ddraw->wined3d_device, NULL, &vp);
+ wined3d_stateblock_set_viewport(ddraw->state, &vp);
+ wined3d_device_get_scissor_rects(ddraw->wined3d_device, NULL, &rect);
+ wined3d_stateblock_set_scissor_rect(ddraw->state, &rect);
+}
+
static HRESULT d3d_device_init(struct d3d_device *device, struct ddraw *ddraw,
struct ddraw_surface *target, IUnknown *rt_iface, UINT version, IUnknown *outer_unknown)
{
@@ -7039,6 +7050,7 @@ static HRESULT d3d_device_init(struct d3d_device *device, struct ddraw *ddraw,
IDirect3DDevice3_SetRenderState(&device->IDirect3DDevice3_iface,
D3DRENDERSTATE_TEXTUREMAPBLEND, D3DTBLEND_MODULATE);
}
+ ddraw_reset_viewport_state(ddraw);
return D3D_OK;
}
--
2.23.0
2
1
[PATCH v2 1/2] mountmgr: Populate HKLM\HARDWARE\DEVICEMAP\Scsi here instead of in kernel32.
by Chip Davis 25 Nov '19
by Chip Davis 25 Nov '19
25 Nov '19
Signed-off-by: Chip Davis <cdavis(a)codeweavers.com>
---
Notes:
v2: Remove redundant key creation code.
dlls/kernel32/Makefile.in | 1 -
dlls/kernel32/oldconfig.c | 407 -----------------------------------
dlls/kernel32/process.c | 1 -
dlls/mountmgr.sys/dbus.c | 185 +++++++++++++++-
dlls/mountmgr.sys/device.c | 153 ++++++++++++-
dlls/mountmgr.sys/diskarb.c | 2 +-
dlls/mountmgr.sys/mountmgr.c | 15 +-
dlls/mountmgr.sys/mountmgr.h | 36 +++-
8 files changed, 384 insertions(+), 416 deletions(-)
delete mode 100644 dlls/kernel32/oldconfig.c
diff --git a/dlls/kernel32/Makefile.in b/dlls/kernel32/Makefile.in
index 48c6c8a8ce4..22cfb11eb1a 100644
--- a/dlls/kernel32/Makefile.in
+++ b/dlls/kernel32/Makefile.in
@@ -24,7 +24,6 @@ C_SRCS = \
lzexpand.c \
module.c \
nameprep.c \
- oldconfig.c \
path.c \
powermgnt.c \
process.c \
diff --git a/dlls/kernel32/oldconfig.c b/dlls/kernel32/oldconfig.c
deleted file mode 100644
index dcce1aa6a23..00000000000
--- a/dlls/kernel32/oldconfig.c
+++ /dev/null
@@ -1,407 +0,0 @@
-/*
- * Support for converting from old configuration format
- *
- * Copyright 2005 Alexandre Julliard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * NOTES
- * This file should be removed after a suitable transition period.
- */
-
-#include "config.h"
-#include "wine/port.h"
-
-#include <stdarg.h>
-#include <sys/types.h>
-#include <stdlib.h>
-#include <stdio.h>
-#ifdef HAVE_SYS_STAT_H
-# include <sys/stat.h>
-#endif
-#include <fcntl.h>
-#ifdef HAVE_DIRENT_H
-# include <dirent.h>
-#endif
-#ifdef HAVE_SYS_IOCTL_H
-#include <sys/ioctl.h>
-#endif
-#ifdef HAVE_LINUX_HDREG_H
-# include <linux/hdreg.h>
-#endif
-
-#include "windef.h"
-#include "winbase.h"
-#include "winternl.h"
-#include "ntddscsi.h"
-#include "wine/library.h"
-#include "wine/unicode.h"
-#include "wine/debug.h"
-#include "kernel_private.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(reg);
-
-static NTSTATUS create_key( HANDLE root, const char *name, HANDLE *key, DWORD *disp )
-{
- OBJECT_ATTRIBUTES attr;
- UNICODE_STRING nameW;
- NTSTATUS status;
-
- attr.Length = sizeof(attr);
- attr.RootDirectory = root;
- attr.ObjectName = &nameW;
- attr.Attributes = 0;
- attr.SecurityDescriptor = NULL;
- attr.SecurityQualityOfService = NULL;
-
- if (!RtlCreateUnicodeStringFromAsciiz( &nameW, name )) return STATUS_NO_MEMORY;
- status = NtCreateKey( key, KEY_ALL_ACCESS, &attr, 0, NULL, REG_OPTION_VOLATILE, disp );
- if (status) ERR("Cannot create %s registry key\n", name );
- RtlFreeUnicodeString( &nameW );
- return status;
-}
-
-/******************************************************************
- * create_scsi_entry
- *
- * Initializes registry to contain scsi info about the cdrom in NT.
- * All devices (even not real scsi ones) have this info in NT.
- * NOTE: programs usually read these registry entries after sending the
- * IOCTL_SCSI_GET_ADDRESS ioctl to the cdrom
- */
-static void create_scsi_entry( PSCSI_ADDRESS scsi_addr, LPCSTR lpDriver, UINT uDriveType,
- LPSTR lpDriveName, LPSTR lpUnixDeviceName )
-{
- static UCHAR uCdromNumber = 0;
- static UCHAR uTapeNumber = 0;
-
- UNICODE_STRING nameW;
- WCHAR dataW[50];
- DWORD sizeW;
- char buffer[40];
- DWORD value;
- const char *data;
- HANDLE scsiKey;
- HANDLE portKey;
- HANDLE busKey;
- HANDLE targetKey;
- HANDLE lunKey;
- DWORD disp;
-
- if (create_key( 0, "\\Registry\\Machine\\HARDWARE\\DEVICEMAP", &scsiKey, &disp )) return;
- NtClose( scsiKey );
-
- /* Ensure there is Scsi key */
- if (create_key( 0, "\\Registry\\Machine\\HARDWARE\\DEVICEMAP\\Scsi", &scsiKey, &disp )) return;
-
- snprintf(buffer,sizeof(buffer),"Scsi Port %d",scsi_addr->PortNumber);
- if (create_key( scsiKey, buffer, &portKey, &disp )) return;
-
- RtlCreateUnicodeStringFromAsciiz( &nameW, "Driver" );
- RtlMultiByteToUnicodeN( dataW, sizeof(dataW), &sizeW, lpDriver, strlen(lpDriver)+1);
- NtSetValueKey( portKey, &nameW, 0, REG_SZ, dataW, sizeW );
- RtlFreeUnicodeString( &nameW );
- value = 10;
- RtlCreateUnicodeStringFromAsciiz( &nameW, "FirstBusTimeScanInMs" );
- NtSetValueKey( portKey,&nameW, 0, REG_DWORD, &value, sizeof(DWORD) );
- RtlFreeUnicodeString( &nameW );
-
- value = 0;
- if (strcmp(lpDriver, "atapi") == 0)
- {
-#ifdef HDIO_GET_DMA
- int fd, dma;
-
- fd = open(lpUnixDeviceName, O_RDONLY|O_NONBLOCK);
- if (fd != -1)
- {
- if (ioctl(fd, HDIO_GET_DMA, &dma) != -1) value = dma;
- close(fd);
- }
-#endif
- RtlCreateUnicodeStringFromAsciiz( &nameW, "DMAEnabled" );
- NtSetValueKey( portKey,&nameW, 0, REG_DWORD, &value, sizeof(DWORD) );
- RtlFreeUnicodeString( &nameW );
- }
-
- snprintf(buffer, sizeof(buffer),"Scsi Bus %d", scsi_addr->PathId);
- if (create_key( portKey, buffer, &busKey, &disp )) return;
-
- /* FIXME: get real controller Id for SCSI */
- if (create_key( busKey, buffer, &targetKey, &disp )) return;
- NtClose( targetKey );
-
- snprintf(buffer, sizeof(buffer),"Target Id %d", scsi_addr->TargetId);
- if (create_key( busKey, buffer, &targetKey, &disp )) return;
-
- snprintf(buffer, sizeof(buffer),"Logical Unit Id %d", scsi_addr->Lun);
- if (create_key( targetKey, buffer, &lunKey, &disp )) return;
-
- switch (uDriveType)
- {
- case DRIVE_NO_ROOT_DIR:
- default:
- data = "OtherPeripheral"; break;
- case DRIVE_FIXED:
- data = "DiskPeripheral"; break;
- case DRIVE_REMOVABLE:
- data = "TapePeripheral";
- snprintf(buffer, sizeof(buffer), "Tape%d", uTapeNumber++);
- break;
- case DRIVE_CDROM:
- data = "CdRomPeripheral";
- snprintf(buffer, sizeof(buffer), "Cdrom%d", uCdromNumber++);
- break;
- }
- RtlCreateUnicodeStringFromAsciiz( &nameW, "Type" );
- RtlMultiByteToUnicodeN( dataW, sizeof(dataW), &sizeW, data, strlen(data)+1);
- NtSetValueKey( lunKey, &nameW, 0, REG_SZ, dataW, sizeW );
- RtlFreeUnicodeString( &nameW );
-
- RtlCreateUnicodeStringFromAsciiz( &nameW, "Identifier" );
- RtlMultiByteToUnicodeN( dataW, sizeof(dataW), &sizeW, lpDriveName, strlen(lpDriveName)+1);
- NtSetValueKey( lunKey, &nameW, 0, REG_SZ, dataW, sizeW );
- RtlFreeUnicodeString( &nameW );
-
- if (uDriveType == DRIVE_CDROM || uDriveType == DRIVE_REMOVABLE)
- {
- RtlCreateUnicodeStringFromAsciiz( &nameW, "DeviceName" );
- RtlMultiByteToUnicodeN( dataW, sizeof(dataW), &sizeW, buffer, strlen(buffer)+1);
- NtSetValueKey( lunKey, &nameW, 0, REG_SZ, dataW, sizeW );
- RtlFreeUnicodeString( &nameW );
- }
-
- RtlCreateUnicodeStringFromAsciiz( &nameW, "UnixDeviceName" );
- RtlMultiByteToUnicodeN( dataW, sizeof(dataW), &sizeW, lpUnixDeviceName, strlen(lpUnixDeviceName)+1);
- NtSetValueKey( lunKey, &nameW, 0, REG_SZ, dataW, sizeW );
- RtlFreeUnicodeString( &nameW );
-
- NtClose( lunKey );
- NtClose( targetKey );
- NtClose( busKey );
- NtClose( portKey );
- NtClose( scsiKey );
-}
-
-struct LinuxProcScsiDevice
-{
- int host;
- int channel;
- int target;
- int lun;
- char vendor[9];
- char model[17];
- char rev[5];
- char type[33];
- int ansirev;
-};
-
-/*
- * we need to declare white spaces explicitly via %*1[ ],
- * as there are very dainbread CD-ROM devices out there
- * which have their manufacturer name blanked out via spaces,
- * which confuses fscanf's parsing (skips all blank spaces)
- */
-static int SCSI_getprocentry( FILE * procfile, struct LinuxProcScsiDevice * dev )
-{
- int result;
-
- result = fscanf( procfile,
- "Host:%*1[ ]scsi%d%*1[ ]Channel:%*1[ ]%d%*1[ ]Id:%*1[ ]%d%*1[ ]Lun:%*1[ ]%d\n",
- &dev->host,
- &dev->channel,
- &dev->target,
- &dev->lun );
- if( result == EOF )
- {
- /* "end of entries" return, so no TRACE() here */
- return EOF;
- }
- if( result != 4 )
- {
- ERR("bus id line scan count error (fscanf returns %d, expected 4)\n", result);
- return 0;
- }
- result = fscanf( procfile,
- " Vendor:%*1[ ]%8c%*1[ ]Model:%*1[ ]%16c%*1[ ]Rev:%*1[ ]%4c\n",
- dev->vendor,
- dev->model,
- dev->rev );
- if( result != 3 )
- {
- ERR("model line scan count error (fscanf returns %d, expected 3)\n", result);
- return 0;
- }
-
- result = fscanf( procfile,
- " Type:%*3[ ]%32c%*1[ ]ANSI SCSI%*1[ ]revision:%*1[ ]%x\n",
- dev->type,
- &dev->ansirev );
- if( result != 2 )
- {
- ERR("SCSI type line scan count error (fscanf returns %d, expected 2)\n", result);
- return 0;
- }
- /* Since we fscanf with %XXc instead of %s.. put a NULL at end */
- dev->vendor[8] = 0;
- dev->model[16] = 0;
- dev->rev[4] = 0;
- dev->type[32] = 0;
-
- return 1;
-}
-
-
-/* create the hardware registry branch */
-static void create_hardware_branch(void)
-{
- /* The following mostly will work on Linux, but should not cause
- * problems on other systems. */
- static const char procname_ide_media[] = "/proc/ide/%s/media";
- static const char procname_ide_model[] = "/proc/ide/%s/model";
- static const char procname_scsi[] = "/proc/scsi/scsi";
- DIR *idedir;
- struct dirent *dent = NULL;
- FILE *procfile = NULL;
- char cStr[40], cDevModel[40], cUnixDeviceName[40], read1[10] = "\0", read2[10] = "\0";
- SCSI_ADDRESS scsi_addr;
- UINT nType;
- struct LinuxProcScsiDevice dev;
- int result = 0, nSgNumber = 0;
- UCHAR uFirstSCSIPort = 0;
-
- /* Enumerate all ide devices first */
- idedir = opendir("/proc/ide");
- if (idedir)
- {
- while ((dent = readdir(idedir)))
- {
- if (strncmp(dent->d_name, "hd", 2) == 0)
- {
- if (snprintf(cStr, sizeof(cStr), procname_ide_media, dent->d_name) >= sizeof(cStr))
- continue;
- procfile = fopen(cStr, "r");
- if (!procfile)
- {
- ERR("Could not open %s\n", cStr);
- continue;
- } else {
- fgets(cStr, sizeof(cStr), procfile);
- fclose(procfile);
- nType = DRIVE_UNKNOWN;
- if (_strnicmp(cStr, "disk", 4) == 0) nType = DRIVE_FIXED;
- if (_strnicmp(cStr, "cdrom", 5) == 0) nType = DRIVE_CDROM;
-
- if (nType == DRIVE_UNKNOWN) continue;
- }
-
- if (snprintf(cStr, sizeof(cStr), procname_ide_model, dent->d_name) >= sizeof(cStr))
- continue;
- procfile = fopen(cStr, "r");
- if (!procfile)
- {
- ERR("Could not open %s\n", cStr);
- switch (nType)
- {
- case DRIVE_FIXED: strcpy(cDevModel, "Wine harddisk"); break;
- case DRIVE_CDROM: strcpy(cDevModel, "Wine CDROM"); break;
- }
- } else {
- fgets(cDevModel, sizeof(cDevModel), procfile);
- fclose(procfile);
- cDevModel[strlen(cDevModel) - 1] = 0;
- }
-
- if (snprintf(cUnixDeviceName, sizeof(cUnixDeviceName), "/dev/%s", dent->d_name) >= sizeof(cUnixDeviceName))
- continue;
- scsi_addr.PortNumber = (dent->d_name[2] - 'a') / 2;
- scsi_addr.PathId = 0;
- scsi_addr.TargetId = (dent->d_name[2] - 'a') % 2;
- scsi_addr.Lun = 0;
- if (scsi_addr.PortNumber + 1 > uFirstSCSIPort)
- uFirstSCSIPort = scsi_addr.PortNumber + 1;
-
- create_scsi_entry(&scsi_addr, "atapi", nType, cDevModel, cUnixDeviceName);
- }
- }
- closedir(idedir);
- }
-
- /* Now goes SCSI */
- procfile = fopen(procname_scsi, "r");
- if (!procfile)
- {
- TRACE("Could not open %s\n", procname_scsi);
- return;
- }
- fgets(cStr, 40, procfile);
- sscanf(cStr, "Attached %9s %9s", read1, read2);
-
- if (strcmp(read1, "devices:") != 0)
- {
- WARN("Incorrect %s format\n", procname_scsi);
- fclose( procfile );
- return;
- }
- if (strcmp(read2, "none") == 0)
- {
- TRACE("No SCSI devices found in %s.\n", procname_scsi);
- fclose( procfile );
- return;
- }
-
- /* Read info for one device */
- while ((result = SCSI_getprocentry(procfile, &dev)) > 0)
- {
- scsi_addr.PortNumber = dev.host;
- scsi_addr.PathId = dev.channel;
- scsi_addr.TargetId = dev.target;
- scsi_addr.Lun = dev.lun;
-
- scsi_addr.PortNumber += uFirstSCSIPort;
- if (strncmp(dev.type, "Direct-Access", 13) == 0) nType = DRIVE_FIXED;
- else if (strncmp(dev.type, "Sequential-Access", 17) == 0) nType = DRIVE_REMOVABLE;
- else if (strncmp(dev.type, "CD-ROM", 6) == 0) nType = DRIVE_CDROM;
- else if (strncmp(dev.type, "Processor", 9) == 0) nType = DRIVE_NO_ROOT_DIR;
- else if (strncmp(dev.type, "Scanner", 7) == 0) nType = DRIVE_NO_ROOT_DIR;
- else if (strncmp(dev.type, "Printer", 7) == 0) nType = DRIVE_NO_ROOT_DIR;
- else continue;
-
- strcpy(cDevModel, dev.vendor);
- strcat(cDevModel, dev.model);
- strcat(cDevModel, dev.rev);
- sprintf(cUnixDeviceName, "/dev/sg%d", nSgNumber++);
- /* FIXME: get real driver name */
- create_scsi_entry(&scsi_addr, "WINE SCSI", nType, cDevModel, cUnixDeviceName);
- }
- if( result != EOF )
- WARN("Incorrect %s format\n", procname_scsi);
- fclose( procfile );
-}
-
-
-/***********************************************************************
- * convert_old_config
- */
-void convert_old_config(void)
-{
- HANDLE key;
- DWORD disp;
-
- /* create some hardware keys (FIXME: should not be done here) */
- if (create_key( 0, "\\Registry\\Machine\\HARDWARE", &key, &disp )) return;
- NtClose( key );
- if (disp != REG_OPENED_EXISTING_KEY) create_hardware_branch();
-}
diff --git a/dlls/kernel32/process.c b/dlls/kernel32/process.c
index f68193c93dd..09c6bab3ce8 100644
--- a/dlls/kernel32/process.c
+++ b/dlls/kernel32/process.c
@@ -214,7 +214,6 @@ void * CDECL __wine_kernel_init(void)
RtlSetUnhandledExceptionFilter( UnhandledExceptionFilter );
LOCALE_Init();
- convert_old_config();
set_library_argv( __wine_main_wargv );
if (!params->CurrentDirectory.Handle) chdir("/"); /* avoid locking removable devices */
diff --git a/dlls/mountmgr.sys/dbus.c b/dlls/mountmgr.sys/dbus.c
index 4ccfb2a79ca..c6d5d0b7af4 100644
--- a/dlls/mountmgr.sys/dbus.c
+++ b/dlls/mountmgr.sys/dbus.c
@@ -101,6 +101,7 @@ static DBusConnection *connection;
DO_FUNC(libhal_ctx_set_device_removed); \
DO_FUNC(libhal_ctx_shutdown); \
DO_FUNC(libhal_device_get_property_bool); \
+ DO_FUNC(libhal_device_get_property_int); \
DO_FUNC(libhal_device_get_property_string); \
DO_FUNC(libhal_device_add_property_watch); \
DO_FUNC(libhal_device_remove_property_watch); \
@@ -318,7 +319,7 @@ static void udisks_new_device( const char *udi )
if (device)
{
- if (removable) add_dos_device( -1, udi, device, mount_point, drive_type, guid_ptr );
+ if (removable) add_dos_device( -1, udi, device, mount_point, drive_type, guid_ptr, NULL );
else if (guid_ptr) add_volume( udi, device, mount_point, DEVICE_HARDDISK_VOL, guid_ptr );
}
@@ -484,7 +485,7 @@ static void udisks2_add_device( const char *udi, DBusMessageIter *dict, DBusMess
}
if (device)
{
- if (removable) add_dos_device( -1, udi, device, mount_point, drive_type, guid_ptr );
+ if (removable) add_dos_device( -1, udi, device, mount_point, drive_type, guid_ptr, NULL );
else if (guid_ptr) add_volume( udi, device, mount_point, DEVICE_HARDDISK_VOL, guid_ptr );
}
}
@@ -582,6 +583,178 @@ static DBusHandlerResult udisks_filter( DBusConnection *ctx, DBusMessage *msg, v
#ifdef SONAME_LIBHAL
+static BOOL hal_get_ide_parameters( LibHalContext *ctx, const char *udi, SCSI_ADDRESS *scsi_addr, UCHAR *devtype, char *ident, size_t ident_size )
+{
+ DBusError error;
+ char *parent = NULL;
+ char *type = NULL;
+ char *model = NULL;
+ int host, chan;
+ BOOL ret = FALSE;
+
+ p_dbus_error_init( &error );
+
+ if (!(parent = p_libhal_device_get_property_string( ctx, udi, "info.parent", &error )))
+ goto done;
+ if ((host = p_libhal_device_get_property_int( ctx, parent, "ide.host", &error )) < 0)
+ goto done;
+ if ((chan = p_libhal_device_get_property_int( ctx, parent, "ide.channel", &error )) < 0)
+ goto done;
+
+ ret = TRUE;
+
+ if (devtype)
+ {
+ if (!(type = p_libhal_device_get_property_string( ctx, udi, "storage.drive_type", &error )))
+ *devtype = SCSI_UNKNOWN_PERIPHERAL;
+ else if (!strcmp( type, "disk" ) || !strcmp( type, "floppy" ))
+ *devtype = SCSI_DISK_PERIPHERAL;
+ else if (!strcmp( type, "tape" ))
+ *devtype = SCSI_TAPE_PERIPHERAL;
+ else if (!strcmp( type, "cdrom" ))
+ *devtype = SCSI_CDROM_PERIPHERAL;
+ else if (!strcmp( type, "raid" ))
+ *devtype = SCSI_ARRAY_PERIPHERAL;
+ else
+ *devtype = SCSI_UNKNOWN_PERIPHERAL;
+ }
+
+ if (ident)
+ {
+ if (!(model = p_libhal_device_get_property_string( ctx, udi, "storage.model", &error )))
+ p_dbus_error_free( &error ); /* ignore error */
+ else
+ lstrcpynA( ident, model, ident_size );
+ }
+
+ scsi_addr->PortNumber = host;
+ scsi_addr->PathId = 0;
+ scsi_addr->TargetId = chan;
+ scsi_addr->Lun = 0;
+
+done:
+ if (model) p_libhal_free_string( model );
+ if (type) p_libhal_free_string( type );
+ if (parent) p_libhal_free_string( parent );
+ p_dbus_error_free( &error );
+ return ret;
+}
+
+static BOOL hal_get_scsi_parameters( LibHalContext *ctx, const char *udi, SCSI_ADDRESS *scsi_addr, UCHAR *devtype, char *ident, size_t ident_size )
+{
+ DBusError error;
+ char *type = NULL;
+ char *vendor = NULL;
+ char *model = NULL;
+ int host, bus, target, lun;
+ BOOL ret = FALSE;
+
+ p_dbus_error_init( &error );
+
+ if ((host = p_libhal_device_get_property_int( ctx, udi, "scsi.host", &error )) < 0)
+ goto done;
+ if ((bus = p_libhal_device_get_property_int( ctx, udi, "scsi.bus", &error )) < 0)
+ goto done;
+ if ((target = p_libhal_device_get_property_int( ctx, udi, "scsi.target", &error )) < 0)
+ goto done;
+ if ((lun = p_libhal_device_get_property_int( ctx, udi, "scsi.lun", &error )) < 0)
+ goto done;
+
+ ret = TRUE;
+ scsi_addr->PortNumber = host;
+ scsi_addr->PathId = bus;
+ scsi_addr->TargetId = target;
+ scsi_addr->Lun = lun;
+
+ if (ident)
+ {
+ if (!(vendor = p_libhal_device_get_property_string( ctx, udi, "scsi.vendor", &error )))
+ p_dbus_error_free( &error ); /* ignore error */
+ if (!(model = p_libhal_device_get_property_string( ctx, udi, "scsi.model", &error )))
+ p_dbus_error_free( &error ); /* ignore error */
+ snprintf( ident, ident_size, "%-8s%-16s", vendor ? vendor : "WINE", model ? model : "SCSI" );
+ }
+
+ if (devtype)
+ {
+ if (!(type = p_libhal_device_get_property_string( ctx, udi, "scsi.type", &error )))
+ {
+ *devtype = SCSI_UNKNOWN_PERIPHERAL;
+ goto done;
+ }
+ if (!strcmp( type, "disk" ))
+ *devtype = SCSI_DISK_PERIPHERAL;
+ else if (!strcmp( type, "tape" ))
+ *devtype = SCSI_TAPE_PERIPHERAL;
+ else if (!strcmp( type, "printer" ))
+ *devtype = SCSI_PRINTER_PERIPHERAL;
+ else if (!strcmp( type, "processor" ))
+ *devtype = SCSI_PROCESSOR_PERIPHERAL;
+ else if (!strcmp( type, "cdrom" ))
+ *devtype = SCSI_CDROM_PERIPHERAL;
+ else if (!strcmp( type, "scanner" ))
+ *devtype = SCSI_SCANNER_PERIPHERAL;
+ else if (!strcmp( type, "medium_changer" ))
+ *devtype = SCSI_MEDIUM_CHANGER_PERIPHERAL;
+ else if (!strcmp( type, "comm" ))
+ *devtype = SCSI_COMMS_PERIPHERAL;
+ else if (!strcmp( type, "raid" ))
+ *devtype = SCSI_ARRAY_PERIPHERAL;
+ else
+ *devtype = SCSI_UNKNOWN_PERIPHERAL;
+ }
+
+done:
+ if (type) p_libhal_free_string( type );
+ if (vendor) p_libhal_free_string( vendor );
+ if (model) p_libhal_free_string( model );
+ p_dbus_error_free( &error );
+ return ret;
+}
+
+static void hal_new_ide_device( LibHalContext *ctx, const char *udi )
+{
+ SCSI_ADDRESS scsi_addr;
+ UCHAR devtype;
+ char ident[40];
+
+ if (!hal_get_ide_parameters( ctx, udi, &scsi_addr, &devtype, ident, sizeof(ident) )) return;
+ create_scsi_entry( &scsi_addr, 255, devtype == SCSI_CDROM_PERIPHERAL ? "atapi" : "WINE SCSI", devtype, ident, NULL );
+}
+
+static void hal_set_device_name( LibHalContext *ctx, const char *udi, const UNICODE_STRING *devname )
+{
+ DBusError error;
+ SCSI_ADDRESS scsi_addr;
+ char *parent = NULL;
+
+ p_dbus_error_init( &error );
+
+ if (!hal_get_ide_parameters( ctx, udi, &scsi_addr, NULL, NULL, 0 ))
+ {
+ if (!(parent = p_libhal_device_get_property_string( ctx, udi, "info.parent", &error )))
+ goto done;
+ if (!hal_get_scsi_parameters( ctx, parent, &scsi_addr, NULL, NULL, 0 ))
+ goto done;
+ }
+ set_scsi_device_name( &scsi_addr, devname );
+
+done:
+ if (parent) p_libhal_free_string( parent );
+ p_dbus_error_free( &error );
+}
+
+static void hal_new_scsi_device( LibHalContext *ctx, const char *udi )
+{
+ SCSI_ADDRESS scsi_addr;
+ UCHAR devtype;
+ char ident[40];
+
+ if (!hal_get_scsi_parameters( ctx, udi, &scsi_addr, &devtype, ident, sizeof(ident) )) return;
+ /* FIXME: get real controller Id for SCSI */
+ create_scsi_entry( &scsi_addr, 255, "WINE SCSI", devtype, ident, NULL );
+}
+
/* HAL callback for new device */
static void hal_new_device( LibHalContext *ctx, const char *udi )
{
@@ -596,6 +769,9 @@ static void hal_new_device( LibHalContext *ctx, const char *udi )
p_dbus_error_init( &error );
+ hal_new_scsi_device( ctx, udi );
+ hal_new_ide_device( ctx, udi );
+
if (!(device = p_libhal_device_get_property_string( ctx, udi, "block.device", &error )))
goto done;
@@ -619,7 +795,10 @@ static void hal_new_device( LibHalContext *ctx, const char *udi )
if (p_libhal_device_get_property_bool( ctx, parent, "storage.removable", &error ))
{
- add_dos_device( -1, udi, device, mount_point, drive_type, guid_ptr );
+ UNICODE_STRING devname;
+
+ add_dos_device( -1, udi, device, mount_point, drive_type, guid_ptr, &devname );
+ hal_set_device_name( ctx, parent, &devname );
/* add property watch for mount point */
p_libhal_device_add_property_watch( ctx, udi, &error );
}
diff --git a/dlls/mountmgr.sys/device.c b/dlls/mountmgr.sys/device.c
index e77f8904040..3369a929224 100644
--- a/dlls/mountmgr.sys/device.c
+++ b/dlls/mountmgr.sys/device.c
@@ -25,7 +25,11 @@
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
+#include <fcntl.h>
#include <sys/time.h>
+#ifdef HAVE_SYS_IOCTL_H
+# include <sys/ioctl.h>
+#endif
#define NONAMELESSUNION
@@ -60,6 +64,12 @@ static const WCHAR drives_keyW[] = {'S','o','f','t','w','a','r','e','\\',
'W','i','n','e','\\','D','r','i','v','e','s',0};
static const WCHAR ports_keyW[] = {'S','o','f','t','w','a','r','e','\\',
'W','i','n','e','\\','P','o','r','t','s',0};
+static const WCHAR scsi_keyW[] = {'H','A','R','D','W','A','R','E','\\','D','E','V','I','C','E','M','A','P','\\','S','c','s','i',0};
+static const WCHAR scsi_port_keyW[] = {'S','c','s','i',' ','P','o','r','t',' ','%','d',0};
+static const WCHAR scsi_bus_keyW[] = {'S','c','s','i',' ','B','u','s',' ','%','d',0};
+static const WCHAR target_id_keyW[] = {'T','a','r','g','e','t',' ','I','d',' ','%','d',0};
+static const WCHAR lun_keyW[] = {'L','o','g','i','c','a','l',' ','U','n','i','t',' ','I','d',' ','%','d',0};
+static const WCHAR devnameW[] = {'D','e','v','i','c','e','N','a','m','e',0};
struct disk_device
{
@@ -686,6 +696,144 @@ static void create_drive_devices(void)
RtlFreeHeap( GetProcessHeap(), 0, path );
}
+/* open the "Logical Unit" key for a given SCSI address */
+static HKEY get_scsi_device_lun_key( SCSI_ADDRESS *scsi_addr )
+{
+ WCHAR dataW[50];
+ HKEY scsi_key, port_key, bus_key, target_key, lun_key;
+
+ if (RegOpenKeyExW( HKEY_LOCAL_MACHINE, scsi_keyW, 0, KEY_READ|KEY_WRITE, &scsi_key )) return NULL;
+
+ snprintfW( dataW, sizeof(dataW)/sizeof(*dataW), scsi_port_keyW, scsi_addr->PortNumber );
+ if (RegCreateKeyExW( scsi_key, dataW, 0, NULL, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &port_key, NULL )) return NULL;
+ RegCloseKey( scsi_key );
+
+ snprintfW( dataW, sizeof(dataW)/sizeof(*dataW), scsi_bus_keyW, scsi_addr->PathId );
+ if (RegCreateKeyExW( port_key, dataW, 0, NULL, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &bus_key, NULL )) return NULL;
+ RegCloseKey( port_key );
+
+ snprintfW( dataW, sizeof(dataW)/sizeof(*dataW), target_id_keyW, scsi_addr->TargetId );
+ if (RegCreateKeyExW( bus_key, dataW, 0, NULL, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &target_key, NULL )) return NULL;
+ RegCloseKey( bus_key );
+
+ snprintfW( dataW, sizeof(dataW)/sizeof(*dataW), lun_keyW, scsi_addr->Lun );
+ if (RegCreateKeyExW( target_key, dataW, 0, NULL, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &lun_key, NULL )) return NULL;
+ RegCloseKey( target_key );
+
+ return lun_key;
+}
+
+/* fill in the "Logical Unit" key for a given SCSI address */
+void create_scsi_entry( SCSI_ADDRESS *scsi_addr, UINT init_id, const char *driver, UINT type, const char *model, const UNICODE_STRING *dev )
+{
+ static UCHAR tape_no = 0;
+ static const WCHAR tapeW[] = {'T','a','p','e','%','d',0};
+ static const WCHAR init_id_keyW[] = {'I','n','i','t','i','a','t','o','r',' ','I','d',' ','%','d',0};
+ static const WCHAR driverW[] = {'D','r','i','v','e','r',0};
+ static const WCHAR bus_time_scanW[] = {'F','i','r','s','t','B','u','s','T','i','m','e','S','c','a','n','I','n','M','s',0};
+ static const WCHAR typeW[] = {'T','y','p','e',0};
+ static const WCHAR identW[] = {'I','d','e','n','t','i','f','i','e','r',0};
+
+ WCHAR dataW[50];
+ DWORD sizeW;
+ DWORD value;
+ const char *data;
+ HKEY scsi_key;
+ HKEY port_key;
+ HKEY bus_key;
+ HKEY target_key;
+ HKEY lun_key;
+
+ if (RegOpenKeyExW( HKEY_LOCAL_MACHINE, scsi_keyW, 0, KEY_READ|KEY_WRITE, &scsi_key )) return;
+
+ snprintfW( dataW, sizeof(dataW)/sizeof(*dataW), scsi_port_keyW, scsi_addr->PortNumber );
+ if (RegCreateKeyExW( scsi_key, dataW, 0, NULL, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &port_key, NULL )) return;
+ RegCloseKey( scsi_key );
+
+ RtlMultiByteToUnicodeN( dataW, sizeof(dataW), &sizeW, driver, strlen(driver)+1);
+ RegSetValueExW( port_key, driverW, 0, REG_SZ, (const BYTE *)dataW, sizeW );
+ value = 10;
+ RegSetValueExW( port_key, bus_time_scanW, 0, REG_DWORD, (const BYTE *)&value, sizeof(value));
+
+ value = 0;
+
+ snprintfW( dataW, sizeof(dataW)/sizeof(*dataW), scsi_bus_keyW, scsi_addr->PathId );
+ if (RegCreateKeyExW( port_key, dataW, 0, NULL, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &bus_key, NULL )) return;
+ RegCloseKey( port_key );
+
+ snprintfW( dataW, sizeof(dataW)/sizeof(*dataW), init_id_keyW, init_id );
+ if (RegCreateKeyExW( bus_key, dataW, 0, NULL, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &target_key, NULL )) return;
+ RegCloseKey( target_key );
+
+ snprintfW( dataW, sizeof(dataW)/sizeof(*dataW), target_id_keyW, scsi_addr->TargetId );
+ if (RegCreateKeyExW( bus_key, dataW, 0, NULL, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &target_key, NULL )) return;
+ RegCloseKey( bus_key );
+
+ snprintfW( dataW, sizeof(dataW)/sizeof(*dataW), lun_keyW, scsi_addr->Lun );
+ if (RegCreateKeyExW( target_key, dataW, 0, NULL, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &lun_key, NULL )) return;
+ RegCloseKey( target_key );
+
+ switch (type)
+ {
+ case SCSI_DISK_PERIPHERAL: data = "DiskPeripheral"; break;
+ case SCSI_TAPE_PERIPHERAL: data = "TapePeripheral"; break;
+ case SCSI_PRINTER_PERIPHERAL: data = "PrinterPeripheral"; break;
+ case SCSI_WORM_PERIPHERAL: data = "WormPeripheral"; break;
+ case SCSI_CDROM_PERIPHERAL: data = "CdRomPeripheral"; break;
+ case SCSI_SCANNER_PERIPHERAL: data = "ScannerPeripheral"; break;
+ case SCSI_OPTICAL_DISK_PERIPHERAL: data = "OpticalDiskPeripheral"; break;
+ case SCSI_MEDIUM_CHANGER_PERIPHERAL: data = "MediumChangerPeripheral"; break;
+ case SCSI_COMMS_PERIPHERAL: data = "CommunicationsPeripheral"; break;
+ case SCSI_ASC_GRAPHICS_PERIPHERAL:
+ case SCSI_ASC_GRAPHICS2_PERIPHERAL: data = "ASCPrePressGraphicsPeripheral"; break;
+ case SCSI_ARRAY_PERIPHERAL: data = "ArrayPeripheral"; break;
+ case SCSI_ENCLOSURE_PERIPHERAL: data = "EnclosurePeripheral"; break;
+ case SCSI_REDUCED_DISK_PERIPHERAL: data = "RBCPeripheral"; break;
+ case SCSI_CARD_READER_PERIPHERAL: data = "CardReaderPeripheral"; break;
+ case SCSI_BRIDGE_PERIPHERAL: data = "BridgePeripheral"; break;
+ case SCSI_OBJECT_STORAGE_PERIPHERAL: /* Object-based storage devices */
+ case SCSI_DRIVE_CONTROLLER_PERIPHERAL: /* Automation/drive controllers */
+ case SCSI_REDUCED_CDROM_PERIPHERAL: /* Reduced-commands MM devices */
+ case SCSI_PROCESSOR_PERIPHERAL: /* Processor devices (considered to be "Other" by Windows) */
+ default: data = "OtherPeripheral"; break;
+ }
+ RtlMultiByteToUnicodeN( dataW, sizeof(dataW), &sizeW, data, strlen(data)+1);
+ RegSetValueExW( lun_key, typeW, 0, REG_SZ, (const BYTE *)dataW, sizeW );
+
+ RtlMultiByteToUnicodeN( dataW, sizeof(dataW), &sizeW, model, strlen(model)+1);
+ RegSetValueExW( lun_key, identW, 0, REG_SZ, (const BYTE *)dataW, sizeW );
+
+ if (dev)
+ {
+ WCHAR *buffer = memchrW( dev->Buffer+1, '\\', dev->Length )+1;
+ ULONG length = dev->Length - (buffer - dev->Buffer)*sizeof(WCHAR);
+ RegSetValueExW( lun_key, devnameW, 0, REG_SZ, (const BYTE *)buffer, length );
+ }
+ else if (type == SCSI_TAPE_PERIPHERAL)
+ {
+ snprintfW( dataW, sizeof(dataW)/sizeof(*dataW), tapeW, tape_no++ );
+ RegSetValueExW( lun_key, devnameW, 0, REG_SZ, (const BYTE *)dataW, strlenW( dataW ) );
+ }
+
+ RegCloseKey( lun_key );
+}
+
+/* set the "DeviceName" for a given SCSI address */
+void set_scsi_device_name( SCSI_ADDRESS *scsi_addr, const UNICODE_STRING *dev )
+{
+ HKEY lun_key;
+ WCHAR *buffer;
+ ULONG length;
+
+ lun_key = get_scsi_device_lun_key( scsi_addr );
+ buffer = memchrW( dev->Buffer+1, '\\', dev->Length )+1;
+ length = dev->Length - (buffer - dev->Buffer)*sizeof(WCHAR);
+ RegSetValueExW( lun_key, devnameW, 0, REG_SZ, (const BYTE *)buffer, length );
+
+ RegCloseKey( lun_key );
+}
+
+
/* create a new disk volume */
NTSTATUS add_volume( const char *udi, const char *device, const char *mount_point,
enum device_type type, const GUID *guid )
@@ -736,7 +884,8 @@ NTSTATUS remove_volume( const char *udi )
/* create a new dos drive */
NTSTATUS add_dos_device( int letter, const char *udi, const char *device,
- const char *mount_point, enum device_type type, const GUID *guid )
+ const char *mount_point, enum device_type type, const GUID *guid,
+ UNICODE_STRING *devname )
{
char *path, *p;
HKEY hkey;
@@ -812,6 +961,8 @@ found:
if (udi) notify = drive->drive;
+ if (devname) *devname = volume->device->name;
+
done:
if (volume) release_volume( volume );
LeaveCriticalSection( &device_section );
diff --git a/dlls/mountmgr.sys/diskarb.c b/dlls/mountmgr.sys/diskarb.c
index 7f04c5f1e06..91d2f851e86 100644
--- a/dlls/mountmgr.sys/diskarb.c
+++ b/dlls/mountmgr.sys/diskarb.c
@@ -89,7 +89,7 @@ static void appeared_callback( DADiskRef disk, void *context )
device, mount_point, wine_dbgstr_guid(guid_ptr) );
if ((ref = CFDictionaryGetValue( dict, CFSTR("DAMediaRemovable") )) && CFBooleanGetValue( ref ))
- add_dos_device( -1, device, device, mount_point, type, guid_ptr );
+ add_dos_device( -1, device, device, mount_point, type, guid_ptr, NULL );
else
if (guid_ptr) add_volume( device, device, mount_point, DEVICE_HARDDISK_VOL, guid_ptr );
diff --git a/dlls/mountmgr.sys/mountmgr.c b/dlls/mountmgr.sys/mountmgr.c
index bc2b776a92f..610e28a3420 100644
--- a/dlls/mountmgr.sys/mountmgr.c
+++ b/dlls/mountmgr.sys/mountmgr.c
@@ -268,7 +268,7 @@ static NTSTATUS define_unix_drive( const void *in_buff, SIZE_T insize )
case DRIVE_RAMDISK: type = DEVICE_RAMDISK; break;
case DRIVE_FIXED: type = DEVICE_HARDDISK_VOL; break;
}
- return add_dos_device( letter - 'a', NULL, device, mount_point, type, NULL );
+ return add_dos_device( letter - 'a', NULL, device, mount_point, type, NULL, NULL );
}
else
{
@@ -461,6 +461,8 @@ NTSTATUS WINAPI DriverEntry( DRIVER_OBJECT *driver, UNICODE_STRING *path )
static const WCHAR harddiskW[] = {'\\','D','r','i','v','e','r','\\','H','a','r','d','d','i','s','k',0};
static const WCHAR driver_serialW[] = {'\\','D','r','i','v','e','r','\\','S','e','r','i','a','l',0};
static const WCHAR driver_parallelW[] = {'\\','D','r','i','v','e','r','\\','P','a','r','a','l','l','e','l',0};
+ static const WCHAR devicemapW[] = {'H','A','R','D','W','A','R','E','\\','D','E','V','I','C','E','M','A','P',0};
+ static const WCHAR scsiW[] = {'S','c','s','i',0};
#ifdef _WIN64
static const WCHAR qualified_ports_keyW[] = {'\\','R','E','G','I','S','T','R','Y','\\',
@@ -475,6 +477,7 @@ NTSTATUS WINAPI DriverEntry( DRIVER_OBJECT *driver, UNICODE_STRING *path )
UNICODE_STRING nameW, linkW;
DEVICE_OBJECT *device;
+ HKEY devicemap_key;
NTSTATUS status;
TRACE( "%s\n", debugstr_w(path->Buffer) );
@@ -494,6 +497,16 @@ NTSTATUS WINAPI DriverEntry( DRIVER_OBJECT *driver, UNICODE_STRING *path )
RegCreateKeyExW( HKEY_LOCAL_MACHINE, mounted_devicesW, 0, NULL,
REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &mount_key, NULL );
+ if (!RegCreateKeyExW( HKEY_LOCAL_MACHINE, devicemapW, 0, NULL, REG_OPTION_VOLATILE,
+ KEY_ALL_ACCESS, NULL, &devicemap_key, NULL ))
+ {
+ HKEY scsi_key;
+ if (!RegCreateKeyExW( devicemap_key, scsiW, 0, NULL, REG_OPTION_VOLATILE,
+ KEY_ALL_ACCESS, NULL, &scsi_key, NULL ))
+ RegCloseKey( scsi_key );
+ RegCloseKey( devicemap_key );
+ }
+
RtlInitUnicodeString( &nameW, harddiskW );
status = IoCreateDriver( &nameW, harddisk_driver_entry );
diff --git a/dlls/mountmgr.sys/mountmgr.h b/dlls/mountmgr.sys/mountmgr.h
index 95386a44f84..b7fb7d86586 100644
--- a/dlls/mountmgr.sys/mountmgr.h
+++ b/dlls/mountmgr.sys/mountmgr.h
@@ -27,6 +27,7 @@
#include "winternl.h"
#include "winioctl.h"
#include "ntddstor.h"
+#include "ntddscsi.h"
#include "ntddcdrm.h"
#include "ddk/wdm.h"
#define WINE_MOUNTMGR_EXTENSIONS
@@ -53,13 +54,46 @@ extern NTSTATUS add_volume( const char *udi, const char *device, const char *mou
enum device_type type, const GUID *guid ) DECLSPEC_HIDDEN;
extern NTSTATUS remove_volume( const char *udi ) DECLSPEC_HIDDEN;
extern NTSTATUS add_dos_device( int letter, const char *udi, const char *device,
- const char *mount_point, enum device_type type, const GUID *guid ) DECLSPEC_HIDDEN;
+ const char *mount_point, enum device_type type, const GUID *guid,
+ UNICODE_STRING *devname ) DECLSPEC_HIDDEN;
extern NTSTATUS remove_dos_device( int letter, const char *udi ) DECLSPEC_HIDDEN;
extern NTSTATUS query_dos_device( int letter, enum device_type *type, char **device, char **mount_point ) DECLSPEC_HIDDEN;
extern NTSTATUS WINAPI harddisk_driver_entry( DRIVER_OBJECT *driver, UNICODE_STRING *path ) DECLSPEC_HIDDEN;
extern NTSTATUS WINAPI serial_driver_entry( DRIVER_OBJECT *driver, UNICODE_STRING *path ) DECLSPEC_HIDDEN;
extern NTSTATUS WINAPI parallel_driver_entry( DRIVER_OBJECT *driver, UNICODE_STRING *path ) DECLSPEC_HIDDEN;
+/* SCSI entry functions */
+
+enum scsi_device_type
+{
+ SCSI_DISK_PERIPHERAL = 0x00,
+ SCSI_TAPE_PERIPHERAL = 0x01,
+ SCSI_PRINTER_PERIPHERAL = 0x02,
+ SCSI_PROCESSOR_PERIPHERAL = 0x03,
+ SCSI_WORM_PERIPHERAL = 0x04,
+ SCSI_CDROM_PERIPHERAL = 0x05,
+ SCSI_SCANNER_PERIPHERAL = 0x06,
+ SCSI_OPTICAL_DISK_PERIPHERAL = 0x07,
+ SCSI_MEDIUM_CHANGER_PERIPHERAL = 0x08,
+ SCSI_COMMS_PERIPHERAL = 0x09,
+ SCSI_ASC_GRAPHICS_PERIPHERAL = 0x0A,
+ SCSI_ASC_GRAPHICS2_PERIPHERAL = 0x0B,
+ SCSI_ARRAY_PERIPHERAL = 0x0C,
+ SCSI_ENCLOSURE_PERIPHERAL = 0x0D,
+ SCSI_REDUCED_DISK_PERIPHERAL = 0x0E,
+ SCSI_CARD_READER_PERIPHERAL = 0x0F,
+ SCSI_BRIDGE_PERIPHERAL = 0x10,
+ SCSI_OBJECT_STORAGE_PERIPHERAL = 0x11,
+ SCSI_DRIVE_CONTROLLER_PERIPHERAL = 0x12,
+ SCSI_REDUCED_CDROM_PERIPHERAL = 0x15,
+ SCSI_UNKNOWN_PERIPHERAL = ~0
+};
+
+extern void create_scsi_entry( SCSI_ADDRESS *scsi_addr, UINT init_id,
+ const char *driver, UINT type, const char *drive,
+ const UNICODE_STRING *devname ) DECLSPEC_HIDDEN;
+extern void set_scsi_device_name( SCSI_ADDRESS *scsi_addr, const UNICODE_STRING *devname ) DECLSPEC_HIDDEN;
+
/* mount point functions */
struct mount_point;
--
2.21.0
2
3
[PATCH 1/2] mountmgr: Populate HKLM\HARDWARE\DEVICEMAP\Scsi here instead of in kernel32.
by Chip Davis 25 Nov '19
by Chip Davis 25 Nov '19
25 Nov '19
Signed-off-by: Chip Davis <cdavis(a)codeweavers.com>
---
dlls/kernel32/Makefile.in | 1 -
dlls/kernel32/oldconfig.c | 407 -----------------------------------
dlls/kernel32/process.c | 1 -
dlls/mountmgr.sys/dbus.c | 185 +++++++++++++++-
dlls/mountmgr.sys/device.c | 153 ++++++++++++-
dlls/mountmgr.sys/diskarb.c | 2 +-
dlls/mountmgr.sys/mountmgr.c | 23 +-
dlls/mountmgr.sys/mountmgr.h | 36 +++-
8 files changed, 392 insertions(+), 416 deletions(-)
delete mode 100644 dlls/kernel32/oldconfig.c
diff --git a/dlls/kernel32/Makefile.in b/dlls/kernel32/Makefile.in
index 48c6c8a8ce4..22cfb11eb1a 100644
--- a/dlls/kernel32/Makefile.in
+++ b/dlls/kernel32/Makefile.in
@@ -24,7 +24,6 @@ C_SRCS = \
lzexpand.c \
module.c \
nameprep.c \
- oldconfig.c \
path.c \
powermgnt.c \
process.c \
diff --git a/dlls/kernel32/oldconfig.c b/dlls/kernel32/oldconfig.c
deleted file mode 100644
index dcce1aa6a23..00000000000
--- a/dlls/kernel32/oldconfig.c
+++ /dev/null
@@ -1,407 +0,0 @@
-/*
- * Support for converting from old configuration format
- *
- * Copyright 2005 Alexandre Julliard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * NOTES
- * This file should be removed after a suitable transition period.
- */
-
-#include "config.h"
-#include "wine/port.h"
-
-#include <stdarg.h>
-#include <sys/types.h>
-#include <stdlib.h>
-#include <stdio.h>
-#ifdef HAVE_SYS_STAT_H
-# include <sys/stat.h>
-#endif
-#include <fcntl.h>
-#ifdef HAVE_DIRENT_H
-# include <dirent.h>
-#endif
-#ifdef HAVE_SYS_IOCTL_H
-#include <sys/ioctl.h>
-#endif
-#ifdef HAVE_LINUX_HDREG_H
-# include <linux/hdreg.h>
-#endif
-
-#include "windef.h"
-#include "winbase.h"
-#include "winternl.h"
-#include "ntddscsi.h"
-#include "wine/library.h"
-#include "wine/unicode.h"
-#include "wine/debug.h"
-#include "kernel_private.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(reg);
-
-static NTSTATUS create_key( HANDLE root, const char *name, HANDLE *key, DWORD *disp )
-{
- OBJECT_ATTRIBUTES attr;
- UNICODE_STRING nameW;
- NTSTATUS status;
-
- attr.Length = sizeof(attr);
- attr.RootDirectory = root;
- attr.ObjectName = &nameW;
- attr.Attributes = 0;
- attr.SecurityDescriptor = NULL;
- attr.SecurityQualityOfService = NULL;
-
- if (!RtlCreateUnicodeStringFromAsciiz( &nameW, name )) return STATUS_NO_MEMORY;
- status = NtCreateKey( key, KEY_ALL_ACCESS, &attr, 0, NULL, REG_OPTION_VOLATILE, disp );
- if (status) ERR("Cannot create %s registry key\n", name );
- RtlFreeUnicodeString( &nameW );
- return status;
-}
-
-/******************************************************************
- * create_scsi_entry
- *
- * Initializes registry to contain scsi info about the cdrom in NT.
- * All devices (even not real scsi ones) have this info in NT.
- * NOTE: programs usually read these registry entries after sending the
- * IOCTL_SCSI_GET_ADDRESS ioctl to the cdrom
- */
-static void create_scsi_entry( PSCSI_ADDRESS scsi_addr, LPCSTR lpDriver, UINT uDriveType,
- LPSTR lpDriveName, LPSTR lpUnixDeviceName )
-{
- static UCHAR uCdromNumber = 0;
- static UCHAR uTapeNumber = 0;
-
- UNICODE_STRING nameW;
- WCHAR dataW[50];
- DWORD sizeW;
- char buffer[40];
- DWORD value;
- const char *data;
- HANDLE scsiKey;
- HANDLE portKey;
- HANDLE busKey;
- HANDLE targetKey;
- HANDLE lunKey;
- DWORD disp;
-
- if (create_key( 0, "\\Registry\\Machine\\HARDWARE\\DEVICEMAP", &scsiKey, &disp )) return;
- NtClose( scsiKey );
-
- /* Ensure there is Scsi key */
- if (create_key( 0, "\\Registry\\Machine\\HARDWARE\\DEVICEMAP\\Scsi", &scsiKey, &disp )) return;
-
- snprintf(buffer,sizeof(buffer),"Scsi Port %d",scsi_addr->PortNumber);
- if (create_key( scsiKey, buffer, &portKey, &disp )) return;
-
- RtlCreateUnicodeStringFromAsciiz( &nameW, "Driver" );
- RtlMultiByteToUnicodeN( dataW, sizeof(dataW), &sizeW, lpDriver, strlen(lpDriver)+1);
- NtSetValueKey( portKey, &nameW, 0, REG_SZ, dataW, sizeW );
- RtlFreeUnicodeString( &nameW );
- value = 10;
- RtlCreateUnicodeStringFromAsciiz( &nameW, "FirstBusTimeScanInMs" );
- NtSetValueKey( portKey,&nameW, 0, REG_DWORD, &value, sizeof(DWORD) );
- RtlFreeUnicodeString( &nameW );
-
- value = 0;
- if (strcmp(lpDriver, "atapi") == 0)
- {
-#ifdef HDIO_GET_DMA
- int fd, dma;
-
- fd = open(lpUnixDeviceName, O_RDONLY|O_NONBLOCK);
- if (fd != -1)
- {
- if (ioctl(fd, HDIO_GET_DMA, &dma) != -1) value = dma;
- close(fd);
- }
-#endif
- RtlCreateUnicodeStringFromAsciiz( &nameW, "DMAEnabled" );
- NtSetValueKey( portKey,&nameW, 0, REG_DWORD, &value, sizeof(DWORD) );
- RtlFreeUnicodeString( &nameW );
- }
-
- snprintf(buffer, sizeof(buffer),"Scsi Bus %d", scsi_addr->PathId);
- if (create_key( portKey, buffer, &busKey, &disp )) return;
-
- /* FIXME: get real controller Id for SCSI */
- if (create_key( busKey, buffer, &targetKey, &disp )) return;
- NtClose( targetKey );
-
- snprintf(buffer, sizeof(buffer),"Target Id %d", scsi_addr->TargetId);
- if (create_key( busKey, buffer, &targetKey, &disp )) return;
-
- snprintf(buffer, sizeof(buffer),"Logical Unit Id %d", scsi_addr->Lun);
- if (create_key( targetKey, buffer, &lunKey, &disp )) return;
-
- switch (uDriveType)
- {
- case DRIVE_NO_ROOT_DIR:
- default:
- data = "OtherPeripheral"; break;
- case DRIVE_FIXED:
- data = "DiskPeripheral"; break;
- case DRIVE_REMOVABLE:
- data = "TapePeripheral";
- snprintf(buffer, sizeof(buffer), "Tape%d", uTapeNumber++);
- break;
- case DRIVE_CDROM:
- data = "CdRomPeripheral";
- snprintf(buffer, sizeof(buffer), "Cdrom%d", uCdromNumber++);
- break;
- }
- RtlCreateUnicodeStringFromAsciiz( &nameW, "Type" );
- RtlMultiByteToUnicodeN( dataW, sizeof(dataW), &sizeW, data, strlen(data)+1);
- NtSetValueKey( lunKey, &nameW, 0, REG_SZ, dataW, sizeW );
- RtlFreeUnicodeString( &nameW );
-
- RtlCreateUnicodeStringFromAsciiz( &nameW, "Identifier" );
- RtlMultiByteToUnicodeN( dataW, sizeof(dataW), &sizeW, lpDriveName, strlen(lpDriveName)+1);
- NtSetValueKey( lunKey, &nameW, 0, REG_SZ, dataW, sizeW );
- RtlFreeUnicodeString( &nameW );
-
- if (uDriveType == DRIVE_CDROM || uDriveType == DRIVE_REMOVABLE)
- {
- RtlCreateUnicodeStringFromAsciiz( &nameW, "DeviceName" );
- RtlMultiByteToUnicodeN( dataW, sizeof(dataW), &sizeW, buffer, strlen(buffer)+1);
- NtSetValueKey( lunKey, &nameW, 0, REG_SZ, dataW, sizeW );
- RtlFreeUnicodeString( &nameW );
- }
-
- RtlCreateUnicodeStringFromAsciiz( &nameW, "UnixDeviceName" );
- RtlMultiByteToUnicodeN( dataW, sizeof(dataW), &sizeW, lpUnixDeviceName, strlen(lpUnixDeviceName)+1);
- NtSetValueKey( lunKey, &nameW, 0, REG_SZ, dataW, sizeW );
- RtlFreeUnicodeString( &nameW );
-
- NtClose( lunKey );
- NtClose( targetKey );
- NtClose( busKey );
- NtClose( portKey );
- NtClose( scsiKey );
-}
-
-struct LinuxProcScsiDevice
-{
- int host;
- int channel;
- int target;
- int lun;
- char vendor[9];
- char model[17];
- char rev[5];
- char type[33];
- int ansirev;
-};
-
-/*
- * we need to declare white spaces explicitly via %*1[ ],
- * as there are very dainbread CD-ROM devices out there
- * which have their manufacturer name blanked out via spaces,
- * which confuses fscanf's parsing (skips all blank spaces)
- */
-static int SCSI_getprocentry( FILE * procfile, struct LinuxProcScsiDevice * dev )
-{
- int result;
-
- result = fscanf( procfile,
- "Host:%*1[ ]scsi%d%*1[ ]Channel:%*1[ ]%d%*1[ ]Id:%*1[ ]%d%*1[ ]Lun:%*1[ ]%d\n",
- &dev->host,
- &dev->channel,
- &dev->target,
- &dev->lun );
- if( result == EOF )
- {
- /* "end of entries" return, so no TRACE() here */
- return EOF;
- }
- if( result != 4 )
- {
- ERR("bus id line scan count error (fscanf returns %d, expected 4)\n", result);
- return 0;
- }
- result = fscanf( procfile,
- " Vendor:%*1[ ]%8c%*1[ ]Model:%*1[ ]%16c%*1[ ]Rev:%*1[ ]%4c\n",
- dev->vendor,
- dev->model,
- dev->rev );
- if( result != 3 )
- {
- ERR("model line scan count error (fscanf returns %d, expected 3)\n", result);
- return 0;
- }
-
- result = fscanf( procfile,
- " Type:%*3[ ]%32c%*1[ ]ANSI SCSI%*1[ ]revision:%*1[ ]%x\n",
- dev->type,
- &dev->ansirev );
- if( result != 2 )
- {
- ERR("SCSI type line scan count error (fscanf returns %d, expected 2)\n", result);
- return 0;
- }
- /* Since we fscanf with %XXc instead of %s.. put a NULL at end */
- dev->vendor[8] = 0;
- dev->model[16] = 0;
- dev->rev[4] = 0;
- dev->type[32] = 0;
-
- return 1;
-}
-
-
-/* create the hardware registry branch */
-static void create_hardware_branch(void)
-{
- /* The following mostly will work on Linux, but should not cause
- * problems on other systems. */
- static const char procname_ide_media[] = "/proc/ide/%s/media";
- static const char procname_ide_model[] = "/proc/ide/%s/model";
- static const char procname_scsi[] = "/proc/scsi/scsi";
- DIR *idedir;
- struct dirent *dent = NULL;
- FILE *procfile = NULL;
- char cStr[40], cDevModel[40], cUnixDeviceName[40], read1[10] = "\0", read2[10] = "\0";
- SCSI_ADDRESS scsi_addr;
- UINT nType;
- struct LinuxProcScsiDevice dev;
- int result = 0, nSgNumber = 0;
- UCHAR uFirstSCSIPort = 0;
-
- /* Enumerate all ide devices first */
- idedir = opendir("/proc/ide");
- if (idedir)
- {
- while ((dent = readdir(idedir)))
- {
- if (strncmp(dent->d_name, "hd", 2) == 0)
- {
- if (snprintf(cStr, sizeof(cStr), procname_ide_media, dent->d_name) >= sizeof(cStr))
- continue;
- procfile = fopen(cStr, "r");
- if (!procfile)
- {
- ERR("Could not open %s\n", cStr);
- continue;
- } else {
- fgets(cStr, sizeof(cStr), procfile);
- fclose(procfile);
- nType = DRIVE_UNKNOWN;
- if (_strnicmp(cStr, "disk", 4) == 0) nType = DRIVE_FIXED;
- if (_strnicmp(cStr, "cdrom", 5) == 0) nType = DRIVE_CDROM;
-
- if (nType == DRIVE_UNKNOWN) continue;
- }
-
- if (snprintf(cStr, sizeof(cStr), procname_ide_model, dent->d_name) >= sizeof(cStr))
- continue;
- procfile = fopen(cStr, "r");
- if (!procfile)
- {
- ERR("Could not open %s\n", cStr);
- switch (nType)
- {
- case DRIVE_FIXED: strcpy(cDevModel, "Wine harddisk"); break;
- case DRIVE_CDROM: strcpy(cDevModel, "Wine CDROM"); break;
- }
- } else {
- fgets(cDevModel, sizeof(cDevModel), procfile);
- fclose(procfile);
- cDevModel[strlen(cDevModel) - 1] = 0;
- }
-
- if (snprintf(cUnixDeviceName, sizeof(cUnixDeviceName), "/dev/%s", dent->d_name) >= sizeof(cUnixDeviceName))
- continue;
- scsi_addr.PortNumber = (dent->d_name[2] - 'a') / 2;
- scsi_addr.PathId = 0;
- scsi_addr.TargetId = (dent->d_name[2] - 'a') % 2;
- scsi_addr.Lun = 0;
- if (scsi_addr.PortNumber + 1 > uFirstSCSIPort)
- uFirstSCSIPort = scsi_addr.PortNumber + 1;
-
- create_scsi_entry(&scsi_addr, "atapi", nType, cDevModel, cUnixDeviceName);
- }
- }
- closedir(idedir);
- }
-
- /* Now goes SCSI */
- procfile = fopen(procname_scsi, "r");
- if (!procfile)
- {
- TRACE("Could not open %s\n", procname_scsi);
- return;
- }
- fgets(cStr, 40, procfile);
- sscanf(cStr, "Attached %9s %9s", read1, read2);
-
- if (strcmp(read1, "devices:") != 0)
- {
- WARN("Incorrect %s format\n", procname_scsi);
- fclose( procfile );
- return;
- }
- if (strcmp(read2, "none") == 0)
- {
- TRACE("No SCSI devices found in %s.\n", procname_scsi);
- fclose( procfile );
- return;
- }
-
- /* Read info for one device */
- while ((result = SCSI_getprocentry(procfile, &dev)) > 0)
- {
- scsi_addr.PortNumber = dev.host;
- scsi_addr.PathId = dev.channel;
- scsi_addr.TargetId = dev.target;
- scsi_addr.Lun = dev.lun;
-
- scsi_addr.PortNumber += uFirstSCSIPort;
- if (strncmp(dev.type, "Direct-Access", 13) == 0) nType = DRIVE_FIXED;
- else if (strncmp(dev.type, "Sequential-Access", 17) == 0) nType = DRIVE_REMOVABLE;
- else if (strncmp(dev.type, "CD-ROM", 6) == 0) nType = DRIVE_CDROM;
- else if (strncmp(dev.type, "Processor", 9) == 0) nType = DRIVE_NO_ROOT_DIR;
- else if (strncmp(dev.type, "Scanner", 7) == 0) nType = DRIVE_NO_ROOT_DIR;
- else if (strncmp(dev.type, "Printer", 7) == 0) nType = DRIVE_NO_ROOT_DIR;
- else continue;
-
- strcpy(cDevModel, dev.vendor);
- strcat(cDevModel, dev.model);
- strcat(cDevModel, dev.rev);
- sprintf(cUnixDeviceName, "/dev/sg%d", nSgNumber++);
- /* FIXME: get real driver name */
- create_scsi_entry(&scsi_addr, "WINE SCSI", nType, cDevModel, cUnixDeviceName);
- }
- if( result != EOF )
- WARN("Incorrect %s format\n", procname_scsi);
- fclose( procfile );
-}
-
-
-/***********************************************************************
- * convert_old_config
- */
-void convert_old_config(void)
-{
- HANDLE key;
- DWORD disp;
-
- /* create some hardware keys (FIXME: should not be done here) */
- if (create_key( 0, "\\Registry\\Machine\\HARDWARE", &key, &disp )) return;
- NtClose( key );
- if (disp != REG_OPENED_EXISTING_KEY) create_hardware_branch();
-}
diff --git a/dlls/kernel32/process.c b/dlls/kernel32/process.c
index f68193c93dd..09c6bab3ce8 100644
--- a/dlls/kernel32/process.c
+++ b/dlls/kernel32/process.c
@@ -214,7 +214,6 @@ void * CDECL __wine_kernel_init(void)
RtlSetUnhandledExceptionFilter( UnhandledExceptionFilter );
LOCALE_Init();
- convert_old_config();
set_library_argv( __wine_main_wargv );
if (!params->CurrentDirectory.Handle) chdir("/"); /* avoid locking removable devices */
diff --git a/dlls/mountmgr.sys/dbus.c b/dlls/mountmgr.sys/dbus.c
index 4ccfb2a79ca..c6d5d0b7af4 100644
--- a/dlls/mountmgr.sys/dbus.c
+++ b/dlls/mountmgr.sys/dbus.c
@@ -101,6 +101,7 @@ static DBusConnection *connection;
DO_FUNC(libhal_ctx_set_device_removed); \
DO_FUNC(libhal_ctx_shutdown); \
DO_FUNC(libhal_device_get_property_bool); \
+ DO_FUNC(libhal_device_get_property_int); \
DO_FUNC(libhal_device_get_property_string); \
DO_FUNC(libhal_device_add_property_watch); \
DO_FUNC(libhal_device_remove_property_watch); \
@@ -318,7 +319,7 @@ static void udisks_new_device( const char *udi )
if (device)
{
- if (removable) add_dos_device( -1, udi, device, mount_point, drive_type, guid_ptr );
+ if (removable) add_dos_device( -1, udi, device, mount_point, drive_type, guid_ptr, NULL );
else if (guid_ptr) add_volume( udi, device, mount_point, DEVICE_HARDDISK_VOL, guid_ptr );
}
@@ -484,7 +485,7 @@ static void udisks2_add_device( const char *udi, DBusMessageIter *dict, DBusMess
}
if (device)
{
- if (removable) add_dos_device( -1, udi, device, mount_point, drive_type, guid_ptr );
+ if (removable) add_dos_device( -1, udi, device, mount_point, drive_type, guid_ptr, NULL );
else if (guid_ptr) add_volume( udi, device, mount_point, DEVICE_HARDDISK_VOL, guid_ptr );
}
}
@@ -582,6 +583,178 @@ static DBusHandlerResult udisks_filter( DBusConnection *ctx, DBusMessage *msg, v
#ifdef SONAME_LIBHAL
+static BOOL hal_get_ide_parameters( LibHalContext *ctx, const char *udi, SCSI_ADDRESS *scsi_addr, UCHAR *devtype, char *ident, size_t ident_size )
+{
+ DBusError error;
+ char *parent = NULL;
+ char *type = NULL;
+ char *model = NULL;
+ int host, chan;
+ BOOL ret = FALSE;
+
+ p_dbus_error_init( &error );
+
+ if (!(parent = p_libhal_device_get_property_string( ctx, udi, "info.parent", &error )))
+ goto done;
+ if ((host = p_libhal_device_get_property_int( ctx, parent, "ide.host", &error )) < 0)
+ goto done;
+ if ((chan = p_libhal_device_get_property_int( ctx, parent, "ide.channel", &error )) < 0)
+ goto done;
+
+ ret = TRUE;
+
+ if (devtype)
+ {
+ if (!(type = p_libhal_device_get_property_string( ctx, udi, "storage.drive_type", &error )))
+ *devtype = SCSI_UNKNOWN_PERIPHERAL;
+ else if (!strcmp( type, "disk" ) || !strcmp( type, "floppy" ))
+ *devtype = SCSI_DISK_PERIPHERAL;
+ else if (!strcmp( type, "tape" ))
+ *devtype = SCSI_TAPE_PERIPHERAL;
+ else if (!strcmp( type, "cdrom" ))
+ *devtype = SCSI_CDROM_PERIPHERAL;
+ else if (!strcmp( type, "raid" ))
+ *devtype = SCSI_ARRAY_PERIPHERAL;
+ else
+ *devtype = SCSI_UNKNOWN_PERIPHERAL;
+ }
+
+ if (ident)
+ {
+ if (!(model = p_libhal_device_get_property_string( ctx, udi, "storage.model", &error )))
+ p_dbus_error_free( &error ); /* ignore error */
+ else
+ lstrcpynA( ident, model, ident_size );
+ }
+
+ scsi_addr->PortNumber = host;
+ scsi_addr->PathId = 0;
+ scsi_addr->TargetId = chan;
+ scsi_addr->Lun = 0;
+
+done:
+ if (model) p_libhal_free_string( model );
+ if (type) p_libhal_free_string( type );
+ if (parent) p_libhal_free_string( parent );
+ p_dbus_error_free( &error );
+ return ret;
+}
+
+static BOOL hal_get_scsi_parameters( LibHalContext *ctx, const char *udi, SCSI_ADDRESS *scsi_addr, UCHAR *devtype, char *ident, size_t ident_size )
+{
+ DBusError error;
+ char *type = NULL;
+ char *vendor = NULL;
+ char *model = NULL;
+ int host, bus, target, lun;
+ BOOL ret = FALSE;
+
+ p_dbus_error_init( &error );
+
+ if ((host = p_libhal_device_get_property_int( ctx, udi, "scsi.host", &error )) < 0)
+ goto done;
+ if ((bus = p_libhal_device_get_property_int( ctx, udi, "scsi.bus", &error )) < 0)
+ goto done;
+ if ((target = p_libhal_device_get_property_int( ctx, udi, "scsi.target", &error )) < 0)
+ goto done;
+ if ((lun = p_libhal_device_get_property_int( ctx, udi, "scsi.lun", &error )) < 0)
+ goto done;
+
+ ret = TRUE;
+ scsi_addr->PortNumber = host;
+ scsi_addr->PathId = bus;
+ scsi_addr->TargetId = target;
+ scsi_addr->Lun = lun;
+
+ if (ident)
+ {
+ if (!(vendor = p_libhal_device_get_property_string( ctx, udi, "scsi.vendor", &error )))
+ p_dbus_error_free( &error ); /* ignore error */
+ if (!(model = p_libhal_device_get_property_string( ctx, udi, "scsi.model", &error )))
+ p_dbus_error_free( &error ); /* ignore error */
+ snprintf( ident, ident_size, "%-8s%-16s", vendor ? vendor : "WINE", model ? model : "SCSI" );
+ }
+
+ if (devtype)
+ {
+ if (!(type = p_libhal_device_get_property_string( ctx, udi, "scsi.type", &error )))
+ {
+ *devtype = SCSI_UNKNOWN_PERIPHERAL;
+ goto done;
+ }
+ if (!strcmp( type, "disk" ))
+ *devtype = SCSI_DISK_PERIPHERAL;
+ else if (!strcmp( type, "tape" ))
+ *devtype = SCSI_TAPE_PERIPHERAL;
+ else if (!strcmp( type, "printer" ))
+ *devtype = SCSI_PRINTER_PERIPHERAL;
+ else if (!strcmp( type, "processor" ))
+ *devtype = SCSI_PROCESSOR_PERIPHERAL;
+ else if (!strcmp( type, "cdrom" ))
+ *devtype = SCSI_CDROM_PERIPHERAL;
+ else if (!strcmp( type, "scanner" ))
+ *devtype = SCSI_SCANNER_PERIPHERAL;
+ else if (!strcmp( type, "medium_changer" ))
+ *devtype = SCSI_MEDIUM_CHANGER_PERIPHERAL;
+ else if (!strcmp( type, "comm" ))
+ *devtype = SCSI_COMMS_PERIPHERAL;
+ else if (!strcmp( type, "raid" ))
+ *devtype = SCSI_ARRAY_PERIPHERAL;
+ else
+ *devtype = SCSI_UNKNOWN_PERIPHERAL;
+ }
+
+done:
+ if (type) p_libhal_free_string( type );
+ if (vendor) p_libhal_free_string( vendor );
+ if (model) p_libhal_free_string( model );
+ p_dbus_error_free( &error );
+ return ret;
+}
+
+static void hal_new_ide_device( LibHalContext *ctx, const char *udi )
+{
+ SCSI_ADDRESS scsi_addr;
+ UCHAR devtype;
+ char ident[40];
+
+ if (!hal_get_ide_parameters( ctx, udi, &scsi_addr, &devtype, ident, sizeof(ident) )) return;
+ create_scsi_entry( &scsi_addr, 255, devtype == SCSI_CDROM_PERIPHERAL ? "atapi" : "WINE SCSI", devtype, ident, NULL );
+}
+
+static void hal_set_device_name( LibHalContext *ctx, const char *udi, const UNICODE_STRING *devname )
+{
+ DBusError error;
+ SCSI_ADDRESS scsi_addr;
+ char *parent = NULL;
+
+ p_dbus_error_init( &error );
+
+ if (!hal_get_ide_parameters( ctx, udi, &scsi_addr, NULL, NULL, 0 ))
+ {
+ if (!(parent = p_libhal_device_get_property_string( ctx, udi, "info.parent", &error )))
+ goto done;
+ if (!hal_get_scsi_parameters( ctx, parent, &scsi_addr, NULL, NULL, 0 ))
+ goto done;
+ }
+ set_scsi_device_name( &scsi_addr, devname );
+
+done:
+ if (parent) p_libhal_free_string( parent );
+ p_dbus_error_free( &error );
+}
+
+static void hal_new_scsi_device( LibHalContext *ctx, const char *udi )
+{
+ SCSI_ADDRESS scsi_addr;
+ UCHAR devtype;
+ char ident[40];
+
+ if (!hal_get_scsi_parameters( ctx, udi, &scsi_addr, &devtype, ident, sizeof(ident) )) return;
+ /* FIXME: get real controller Id for SCSI */
+ create_scsi_entry( &scsi_addr, 255, "WINE SCSI", devtype, ident, NULL );
+}
+
/* HAL callback for new device */
static void hal_new_device( LibHalContext *ctx, const char *udi )
{
@@ -596,6 +769,9 @@ static void hal_new_device( LibHalContext *ctx, const char *udi )
p_dbus_error_init( &error );
+ hal_new_scsi_device( ctx, udi );
+ hal_new_ide_device( ctx, udi );
+
if (!(device = p_libhal_device_get_property_string( ctx, udi, "block.device", &error )))
goto done;
@@ -619,7 +795,10 @@ static void hal_new_device( LibHalContext *ctx, const char *udi )
if (p_libhal_device_get_property_bool( ctx, parent, "storage.removable", &error ))
{
- add_dos_device( -1, udi, device, mount_point, drive_type, guid_ptr );
+ UNICODE_STRING devname;
+
+ add_dos_device( -1, udi, device, mount_point, drive_type, guid_ptr, &devname );
+ hal_set_device_name( ctx, parent, &devname );
/* add property watch for mount point */
p_libhal_device_add_property_watch( ctx, udi, &error );
}
diff --git a/dlls/mountmgr.sys/device.c b/dlls/mountmgr.sys/device.c
index e77f8904040..3369a929224 100644
--- a/dlls/mountmgr.sys/device.c
+++ b/dlls/mountmgr.sys/device.c
@@ -25,7 +25,11 @@
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
+#include <fcntl.h>
#include <sys/time.h>
+#ifdef HAVE_SYS_IOCTL_H
+# include <sys/ioctl.h>
+#endif
#define NONAMELESSUNION
@@ -60,6 +64,12 @@ static const WCHAR drives_keyW[] = {'S','o','f','t','w','a','r','e','\\',
'W','i','n','e','\\','D','r','i','v','e','s',0};
static const WCHAR ports_keyW[] = {'S','o','f','t','w','a','r','e','\\',
'W','i','n','e','\\','P','o','r','t','s',0};
+static const WCHAR scsi_keyW[] = {'H','A','R','D','W','A','R','E','\\','D','E','V','I','C','E','M','A','P','\\','S','c','s','i',0};
+static const WCHAR scsi_port_keyW[] = {'S','c','s','i',' ','P','o','r','t',' ','%','d',0};
+static const WCHAR scsi_bus_keyW[] = {'S','c','s','i',' ','B','u','s',' ','%','d',0};
+static const WCHAR target_id_keyW[] = {'T','a','r','g','e','t',' ','I','d',' ','%','d',0};
+static const WCHAR lun_keyW[] = {'L','o','g','i','c','a','l',' ','U','n','i','t',' ','I','d',' ','%','d',0};
+static const WCHAR devnameW[] = {'D','e','v','i','c','e','N','a','m','e',0};
struct disk_device
{
@@ -686,6 +696,144 @@ static void create_drive_devices(void)
RtlFreeHeap( GetProcessHeap(), 0, path );
}
+/* open the "Logical Unit" key for a given SCSI address */
+static HKEY get_scsi_device_lun_key( SCSI_ADDRESS *scsi_addr )
+{
+ WCHAR dataW[50];
+ HKEY scsi_key, port_key, bus_key, target_key, lun_key;
+
+ if (RegOpenKeyExW( HKEY_LOCAL_MACHINE, scsi_keyW, 0, KEY_READ|KEY_WRITE, &scsi_key )) return NULL;
+
+ snprintfW( dataW, sizeof(dataW)/sizeof(*dataW), scsi_port_keyW, scsi_addr->PortNumber );
+ if (RegCreateKeyExW( scsi_key, dataW, 0, NULL, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &port_key, NULL )) return NULL;
+ RegCloseKey( scsi_key );
+
+ snprintfW( dataW, sizeof(dataW)/sizeof(*dataW), scsi_bus_keyW, scsi_addr->PathId );
+ if (RegCreateKeyExW( port_key, dataW, 0, NULL, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &bus_key, NULL )) return NULL;
+ RegCloseKey( port_key );
+
+ snprintfW( dataW, sizeof(dataW)/sizeof(*dataW), target_id_keyW, scsi_addr->TargetId );
+ if (RegCreateKeyExW( bus_key, dataW, 0, NULL, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &target_key, NULL )) return NULL;
+ RegCloseKey( bus_key );
+
+ snprintfW( dataW, sizeof(dataW)/sizeof(*dataW), lun_keyW, scsi_addr->Lun );
+ if (RegCreateKeyExW( target_key, dataW, 0, NULL, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &lun_key, NULL )) return NULL;
+ RegCloseKey( target_key );
+
+ return lun_key;
+}
+
+/* fill in the "Logical Unit" key for a given SCSI address */
+void create_scsi_entry( SCSI_ADDRESS *scsi_addr, UINT init_id, const char *driver, UINT type, const char *model, const UNICODE_STRING *dev )
+{
+ static UCHAR tape_no = 0;
+ static const WCHAR tapeW[] = {'T','a','p','e','%','d',0};
+ static const WCHAR init_id_keyW[] = {'I','n','i','t','i','a','t','o','r',' ','I','d',' ','%','d',0};
+ static const WCHAR driverW[] = {'D','r','i','v','e','r',0};
+ static const WCHAR bus_time_scanW[] = {'F','i','r','s','t','B','u','s','T','i','m','e','S','c','a','n','I','n','M','s',0};
+ static const WCHAR typeW[] = {'T','y','p','e',0};
+ static const WCHAR identW[] = {'I','d','e','n','t','i','f','i','e','r',0};
+
+ WCHAR dataW[50];
+ DWORD sizeW;
+ DWORD value;
+ const char *data;
+ HKEY scsi_key;
+ HKEY port_key;
+ HKEY bus_key;
+ HKEY target_key;
+ HKEY lun_key;
+
+ if (RegOpenKeyExW( HKEY_LOCAL_MACHINE, scsi_keyW, 0, KEY_READ|KEY_WRITE, &scsi_key )) return;
+
+ snprintfW( dataW, sizeof(dataW)/sizeof(*dataW), scsi_port_keyW, scsi_addr->PortNumber );
+ if (RegCreateKeyExW( scsi_key, dataW, 0, NULL, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &port_key, NULL )) return;
+ RegCloseKey( scsi_key );
+
+ RtlMultiByteToUnicodeN( dataW, sizeof(dataW), &sizeW, driver, strlen(driver)+1);
+ RegSetValueExW( port_key, driverW, 0, REG_SZ, (const BYTE *)dataW, sizeW );
+ value = 10;
+ RegSetValueExW( port_key, bus_time_scanW, 0, REG_DWORD, (const BYTE *)&value, sizeof(value));
+
+ value = 0;
+
+ snprintfW( dataW, sizeof(dataW)/sizeof(*dataW), scsi_bus_keyW, scsi_addr->PathId );
+ if (RegCreateKeyExW( port_key, dataW, 0, NULL, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &bus_key, NULL )) return;
+ RegCloseKey( port_key );
+
+ snprintfW( dataW, sizeof(dataW)/sizeof(*dataW), init_id_keyW, init_id );
+ if (RegCreateKeyExW( bus_key, dataW, 0, NULL, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &target_key, NULL )) return;
+ RegCloseKey( target_key );
+
+ snprintfW( dataW, sizeof(dataW)/sizeof(*dataW), target_id_keyW, scsi_addr->TargetId );
+ if (RegCreateKeyExW( bus_key, dataW, 0, NULL, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &target_key, NULL )) return;
+ RegCloseKey( bus_key );
+
+ snprintfW( dataW, sizeof(dataW)/sizeof(*dataW), lun_keyW, scsi_addr->Lun );
+ if (RegCreateKeyExW( target_key, dataW, 0, NULL, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &lun_key, NULL )) return;
+ RegCloseKey( target_key );
+
+ switch (type)
+ {
+ case SCSI_DISK_PERIPHERAL: data = "DiskPeripheral"; break;
+ case SCSI_TAPE_PERIPHERAL: data = "TapePeripheral"; break;
+ case SCSI_PRINTER_PERIPHERAL: data = "PrinterPeripheral"; break;
+ case SCSI_WORM_PERIPHERAL: data = "WormPeripheral"; break;
+ case SCSI_CDROM_PERIPHERAL: data = "CdRomPeripheral"; break;
+ case SCSI_SCANNER_PERIPHERAL: data = "ScannerPeripheral"; break;
+ case SCSI_OPTICAL_DISK_PERIPHERAL: data = "OpticalDiskPeripheral"; break;
+ case SCSI_MEDIUM_CHANGER_PERIPHERAL: data = "MediumChangerPeripheral"; break;
+ case SCSI_COMMS_PERIPHERAL: data = "CommunicationsPeripheral"; break;
+ case SCSI_ASC_GRAPHICS_PERIPHERAL:
+ case SCSI_ASC_GRAPHICS2_PERIPHERAL: data = "ASCPrePressGraphicsPeripheral"; break;
+ case SCSI_ARRAY_PERIPHERAL: data = "ArrayPeripheral"; break;
+ case SCSI_ENCLOSURE_PERIPHERAL: data = "EnclosurePeripheral"; break;
+ case SCSI_REDUCED_DISK_PERIPHERAL: data = "RBCPeripheral"; break;
+ case SCSI_CARD_READER_PERIPHERAL: data = "CardReaderPeripheral"; break;
+ case SCSI_BRIDGE_PERIPHERAL: data = "BridgePeripheral"; break;
+ case SCSI_OBJECT_STORAGE_PERIPHERAL: /* Object-based storage devices */
+ case SCSI_DRIVE_CONTROLLER_PERIPHERAL: /* Automation/drive controllers */
+ case SCSI_REDUCED_CDROM_PERIPHERAL: /* Reduced-commands MM devices */
+ case SCSI_PROCESSOR_PERIPHERAL: /* Processor devices (considered to be "Other" by Windows) */
+ default: data = "OtherPeripheral"; break;
+ }
+ RtlMultiByteToUnicodeN( dataW, sizeof(dataW), &sizeW, data, strlen(data)+1);
+ RegSetValueExW( lun_key, typeW, 0, REG_SZ, (const BYTE *)dataW, sizeW );
+
+ RtlMultiByteToUnicodeN( dataW, sizeof(dataW), &sizeW, model, strlen(model)+1);
+ RegSetValueExW( lun_key, identW, 0, REG_SZ, (const BYTE *)dataW, sizeW );
+
+ if (dev)
+ {
+ WCHAR *buffer = memchrW( dev->Buffer+1, '\\', dev->Length )+1;
+ ULONG length = dev->Length - (buffer - dev->Buffer)*sizeof(WCHAR);
+ RegSetValueExW( lun_key, devnameW, 0, REG_SZ, (const BYTE *)buffer, length );
+ }
+ else if (type == SCSI_TAPE_PERIPHERAL)
+ {
+ snprintfW( dataW, sizeof(dataW)/sizeof(*dataW), tapeW, tape_no++ );
+ RegSetValueExW( lun_key, devnameW, 0, REG_SZ, (const BYTE *)dataW, strlenW( dataW ) );
+ }
+
+ RegCloseKey( lun_key );
+}
+
+/* set the "DeviceName" for a given SCSI address */
+void set_scsi_device_name( SCSI_ADDRESS *scsi_addr, const UNICODE_STRING *dev )
+{
+ HKEY lun_key;
+ WCHAR *buffer;
+ ULONG length;
+
+ lun_key = get_scsi_device_lun_key( scsi_addr );
+ buffer = memchrW( dev->Buffer+1, '\\', dev->Length )+1;
+ length = dev->Length - (buffer - dev->Buffer)*sizeof(WCHAR);
+ RegSetValueExW( lun_key, devnameW, 0, REG_SZ, (const BYTE *)buffer, length );
+
+ RegCloseKey( lun_key );
+}
+
+
/* create a new disk volume */
NTSTATUS add_volume( const char *udi, const char *device, const char *mount_point,
enum device_type type, const GUID *guid )
@@ -736,7 +884,8 @@ NTSTATUS remove_volume( const char *udi )
/* create a new dos drive */
NTSTATUS add_dos_device( int letter, const char *udi, const char *device,
- const char *mount_point, enum device_type type, const GUID *guid )
+ const char *mount_point, enum device_type type, const GUID *guid,
+ UNICODE_STRING *devname )
{
char *path, *p;
HKEY hkey;
@@ -812,6 +961,8 @@ found:
if (udi) notify = drive->drive;
+ if (devname) *devname = volume->device->name;
+
done:
if (volume) release_volume( volume );
LeaveCriticalSection( &device_section );
diff --git a/dlls/mountmgr.sys/diskarb.c b/dlls/mountmgr.sys/diskarb.c
index 7f04c5f1e06..91d2f851e86 100644
--- a/dlls/mountmgr.sys/diskarb.c
+++ b/dlls/mountmgr.sys/diskarb.c
@@ -89,7 +89,7 @@ static void appeared_callback( DADiskRef disk, void *context )
device, mount_point, wine_dbgstr_guid(guid_ptr) );
if ((ref = CFDictionaryGetValue( dict, CFSTR("DAMediaRemovable") )) && CFBooleanGetValue( ref ))
- add_dos_device( -1, device, device, mount_point, type, guid_ptr );
+ add_dos_device( -1, device, device, mount_point, type, guid_ptr, NULL );
else
if (guid_ptr) add_volume( device, device, mount_point, DEVICE_HARDDISK_VOL, guid_ptr );
diff --git a/dlls/mountmgr.sys/mountmgr.c b/dlls/mountmgr.sys/mountmgr.c
index bc2b776a92f..3b90be77660 100644
--- a/dlls/mountmgr.sys/mountmgr.c
+++ b/dlls/mountmgr.sys/mountmgr.c
@@ -268,7 +268,7 @@ static NTSTATUS define_unix_drive( const void *in_buff, SIZE_T insize )
case DRIVE_RAMDISK: type = DEVICE_RAMDISK; break;
case DRIVE_FIXED: type = DEVICE_HARDDISK_VOL; break;
}
- return add_dos_device( letter - 'a', NULL, device, mount_point, type, NULL );
+ return add_dos_device( letter - 'a', NULL, device, mount_point, type, NULL, NULL );
}
else
{
@@ -461,6 +461,10 @@ NTSTATUS WINAPI DriverEntry( DRIVER_OBJECT *driver, UNICODE_STRING *path )
static const WCHAR harddiskW[] = {'\\','D','r','i','v','e','r','\\','H','a','r','d','d','i','s','k',0};
static const WCHAR driver_serialW[] = {'\\','D','r','i','v','e','r','\\','S','e','r','i','a','l',0};
static const WCHAR driver_parallelW[] = {'\\','D','r','i','v','e','r','\\','P','a','r','a','l','l','e','l',0};
+ static const WCHAR devicemapW[] = {'H','A','R','D','W','A','R','E','\\','D','E','V','I','C','E','M','A','P',0};
+ static const WCHAR parallelW[] = {'P','A','R','A','L','L','E','L',' ','P','O','R','T','S',0};
+ static const WCHAR serialW[] = {'S','E','R','I','A','L','C','O','M','M',0};
+ static const WCHAR scsiW[] = {'S','c','s','i',0};
#ifdef _WIN64
static const WCHAR qualified_ports_keyW[] = {'\\','R','E','G','I','S','T','R','Y','\\',
@@ -475,6 +479,7 @@ NTSTATUS WINAPI DriverEntry( DRIVER_OBJECT *driver, UNICODE_STRING *path )
UNICODE_STRING nameW, linkW;
DEVICE_OBJECT *device;
+ HKEY devicemap_key;
NTSTATUS status;
TRACE( "%s\n", debugstr_w(path->Buffer) );
@@ -494,6 +499,22 @@ NTSTATUS WINAPI DriverEntry( DRIVER_OBJECT *driver, UNICODE_STRING *path )
RegCreateKeyExW( HKEY_LOCAL_MACHINE, mounted_devicesW, 0, NULL,
REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &mount_key, NULL );
+ if (!RegCreateKeyExW( HKEY_LOCAL_MACHINE, devicemapW, 0, NULL, REG_OPTION_VOLATILE,
+ KEY_ALL_ACCESS, NULL, &devicemap_key, NULL ))
+ {
+ HKEY hkey;
+ if (!RegCreateKeyExW( devicemap_key, parallelW, 0, NULL, REG_OPTION_VOLATILE,
+ KEY_ALL_ACCESS, NULL, &hkey, NULL ))
+ RegCloseKey( hkey );
+ if (!RegCreateKeyExW( devicemap_key, serialW, 0, NULL, REG_OPTION_VOLATILE,
+ KEY_ALL_ACCESS, NULL, &hkey, NULL ))
+ RegCloseKey( hkey );
+ if (!RegCreateKeyExW( devicemap_key, scsiW, 0, NULL, REG_OPTION_VOLATILE,
+ KEY_ALL_ACCESS, NULL, &hkey, NULL ))
+ RegCloseKey( hkey );
+ RegCloseKey( devicemap_key );
+ }
+
RtlInitUnicodeString( &nameW, harddiskW );
status = IoCreateDriver( &nameW, harddisk_driver_entry );
diff --git a/dlls/mountmgr.sys/mountmgr.h b/dlls/mountmgr.sys/mountmgr.h
index 95386a44f84..b7fb7d86586 100644
--- a/dlls/mountmgr.sys/mountmgr.h
+++ b/dlls/mountmgr.sys/mountmgr.h
@@ -27,6 +27,7 @@
#include "winternl.h"
#include "winioctl.h"
#include "ntddstor.h"
+#include "ntddscsi.h"
#include "ntddcdrm.h"
#include "ddk/wdm.h"
#define WINE_MOUNTMGR_EXTENSIONS
@@ -53,13 +54,46 @@ extern NTSTATUS add_volume( const char *udi, const char *device, const char *mou
enum device_type type, const GUID *guid ) DECLSPEC_HIDDEN;
extern NTSTATUS remove_volume( const char *udi ) DECLSPEC_HIDDEN;
extern NTSTATUS add_dos_device( int letter, const char *udi, const char *device,
- const char *mount_point, enum device_type type, const GUID *guid ) DECLSPEC_HIDDEN;
+ const char *mount_point, enum device_type type, const GUID *guid,
+ UNICODE_STRING *devname ) DECLSPEC_HIDDEN;
extern NTSTATUS remove_dos_device( int letter, const char *udi ) DECLSPEC_HIDDEN;
extern NTSTATUS query_dos_device( int letter, enum device_type *type, char **device, char **mount_point ) DECLSPEC_HIDDEN;
extern NTSTATUS WINAPI harddisk_driver_entry( DRIVER_OBJECT *driver, UNICODE_STRING *path ) DECLSPEC_HIDDEN;
extern NTSTATUS WINAPI serial_driver_entry( DRIVER_OBJECT *driver, UNICODE_STRING *path ) DECLSPEC_HIDDEN;
extern NTSTATUS WINAPI parallel_driver_entry( DRIVER_OBJECT *driver, UNICODE_STRING *path ) DECLSPEC_HIDDEN;
+/* SCSI entry functions */
+
+enum scsi_device_type
+{
+ SCSI_DISK_PERIPHERAL = 0x00,
+ SCSI_TAPE_PERIPHERAL = 0x01,
+ SCSI_PRINTER_PERIPHERAL = 0x02,
+ SCSI_PROCESSOR_PERIPHERAL = 0x03,
+ SCSI_WORM_PERIPHERAL = 0x04,
+ SCSI_CDROM_PERIPHERAL = 0x05,
+ SCSI_SCANNER_PERIPHERAL = 0x06,
+ SCSI_OPTICAL_DISK_PERIPHERAL = 0x07,
+ SCSI_MEDIUM_CHANGER_PERIPHERAL = 0x08,
+ SCSI_COMMS_PERIPHERAL = 0x09,
+ SCSI_ASC_GRAPHICS_PERIPHERAL = 0x0A,
+ SCSI_ASC_GRAPHICS2_PERIPHERAL = 0x0B,
+ SCSI_ARRAY_PERIPHERAL = 0x0C,
+ SCSI_ENCLOSURE_PERIPHERAL = 0x0D,
+ SCSI_REDUCED_DISK_PERIPHERAL = 0x0E,
+ SCSI_CARD_READER_PERIPHERAL = 0x0F,
+ SCSI_BRIDGE_PERIPHERAL = 0x10,
+ SCSI_OBJECT_STORAGE_PERIPHERAL = 0x11,
+ SCSI_DRIVE_CONTROLLER_PERIPHERAL = 0x12,
+ SCSI_REDUCED_CDROM_PERIPHERAL = 0x15,
+ SCSI_UNKNOWN_PERIPHERAL = ~0
+};
+
+extern void create_scsi_entry( SCSI_ADDRESS *scsi_addr, UINT init_id,
+ const char *driver, UINT type, const char *drive,
+ const UNICODE_STRING *devname ) DECLSPEC_HIDDEN;
+extern void set_scsi_device_name( SCSI_ADDRESS *scsi_addr, const UNICODE_STRING *devname ) DECLSPEC_HIDDEN;
+
/* mount point functions */
struct mount_point;
--
2.21.0
3
5
This patch adds emulation for instructions protected by User-Mode
Instruction Prevention (currently implemented by AMD Ryzen 3000 CPUs and
some rare Intel CPUs).
Changes from previous patch: all code is now integrated into the
signal_*.c files, and fixed a warning in the 32-bit code.
Brendan Shanks (2):
ntdll: Add emulation for UMIP instructions.
ntdll/tests: Add tests for UMIP instructions.
dlls/ntdll/signal_i386.c | 362 +++++++++++++++++++++++++++++++-
dlls/ntdll/signal_x86_64.c | 395 ++++++++++++++++++++++++++++++++++-
dlls/ntdll/tests/exception.c | 375 +++++++++++++++++++++++++++++++++
3 files changed, 1116 insertions(+), 16 deletions(-)
--
2.23.0
3
4
[PATCH 1/2] dlls/d3d12: Fix D3D12SerializeVersionedRootSignature.
by Hans-Kristian Arntzen 25 Nov '19
by Hans-Kristian Arntzen 25 Nov '19
25 Nov '19
Use the proper versioned serializer from vkd3d.
Signed-off-by: Hans-Kristian Arntzen <post(a)arntzen-software.no>
---
dlls/d3d12/d3d12_main.c | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/dlls/d3d12/d3d12_main.c b/dlls/d3d12/d3d12_main.c
index bd680d8254..9f0fa12ee8 100644
--- a/dlls/d3d12/d3d12_main.c
+++ b/dlls/d3d12/d3d12_main.c
@@ -420,9 +420,5 @@ HRESULT WINAPI D3D12SerializeVersionedRootSignature(const D3D12_VERSIONED_ROOT_S
{
TRACE("desc %p, blob %p, error_blob %p.\n", desc, blob, error_blob);
- if (desc->Version == D3D_ROOT_SIGNATURE_VERSION_1_0)
- return vkd3d_serialize_root_signature(&desc->Desc_1_0, desc->Version, blob, error_blob);
-
- FIXME("Unsupported version %#x.\n", desc->Version);
- return E_NOTIMPL;
+ return vkd3d_serialize_versioned_root_signature(desc, blob, error_blob);
}
--
2.23.0
5
21
Factor out the magic values needed to derive the maximum image data
buffer length. If the values need to be changed in the future, the
derived value will be automatically recalculated.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=48054
Signed-off-by: Jeff Smith <whydoubt(a)gmail.com>
---
dlls/gdi32/tests/bitmap.c | 46 +++++++++++++++++++++++----------------
1 file changed, 27 insertions(+), 19 deletions(-)
diff --git a/dlls/gdi32/tests/bitmap.c b/dlls/gdi32/tests/bitmap.c
index 8fe160546c..130ef3ca3a 100644
--- a/dlls/gdi32/tests/bitmap.c
+++ b/dlls/gdi32/tests/bitmap.c
@@ -910,10 +910,18 @@ static void test_dibsections(void)
ReleaseDC(0, hdc);
}
+#define DATA_WIDTH 2
+#define DATA_HEIGHT 2
+#define MAX_PLANES 64
+#define MAX_BPP 64
+#define DATA_STRIDE_LENGTH (((DATA_WIDTH * MAX_BPP + 31) / 32) * 4)
+#define DATA_PLANE_LENGTH (DATA_STRIDE_LENGTH * DATA_HEIGHT)
+#define DATA_LENGTH (DATA_PLANE_LENGTH * MAX_PLANES)
+
static void test_dib_formats(void)
{
BITMAPINFO *bi;
- char data[256];
+ char data[DATA_LENGTH];
void *bits;
int planes, bpp, compr, format;
HBITMAP hdib, hbmp;
@@ -928,9 +936,9 @@ static void test_dib_formats(void)
memset( data, 0xaa, sizeof(data) );
- for (bpp = 0; bpp <= 64; bpp++)
+ for (bpp = 0; bpp <= MAX_BPP; bpp++)
{
- for (planes = 0; planes <= 64; planes++)
+ for (planes = 0; planes <= MAX_PLANES; planes++)
{
for (compr = 0; compr < 8; compr++)
{
@@ -949,8 +957,8 @@ static void test_dib_formats(void)
memset( bi, 0, sizeof(bi->bmiHeader) );
bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- bi->bmiHeader.biWidth = 2;
- bi->bmiHeader.biHeight = 2;
+ bi->bmiHeader.biWidth = DATA_WIDTH;
+ bi->bmiHeader.biHeight = DATA_HEIGHT;
bi->bmiHeader.biPlanes = planes;
bi->bmiHeader.biBitCount = bpp;
bi->bmiHeader.biCompression = compr;
@@ -969,8 +977,8 @@ static void test_dib_formats(void)
if (!planes) expect_ok = FALSE;
memset( bi, 0, sizeof(bi->bmiHeader) );
bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- bi->bmiHeader.biWidth = 2;
- bi->bmiHeader.biHeight = 2;
+ bi->bmiHeader.biWidth = DATA_WIDTH;
+ bi->bmiHeader.biHeight = DATA_HEIGHT;
bi->bmiHeader.biPlanes = planes;
bi->bmiHeader.biBitCount = bpp;
bi->bmiHeader.biCompression = compr;
@@ -1027,8 +1035,8 @@ static void test_dib_formats(void)
bpp, bi->bmiHeader.biBitCount );
bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- bi->bmiHeader.biWidth = 2;
- bi->bmiHeader.biHeight = 2;
+ bi->bmiHeader.biWidth = DATA_WIDTH;
+ bi->bmiHeader.biHeight = DATA_HEIGHT;
bi->bmiHeader.biPlanes = planes;
bi->bmiHeader.biBitCount = bpp;
bi->bmiHeader.biCompression = compr;
@@ -1067,8 +1075,8 @@ static void test_dib_formats(void)
memset( bi, 0, sizeof(bi->bmiHeader) );
bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- bi->bmiHeader.biWidth = 2;
- bi->bmiHeader.biHeight = 2;
+ bi->bmiHeader.biWidth = DATA_WIDTH;
+ bi->bmiHeader.biHeight = DATA_HEIGHT;
bi->bmiHeader.biPlanes = 1;
bi->bmiHeader.biBitCount = 16;
bi->bmiHeader.biCompression = BI_BITFIELDS;
@@ -1120,8 +1128,8 @@ static void test_dib_formats(void)
ret = SetDIBits(hdc, hbmp, 0, 1, data, bi, DIB_RGB_COLORS);
ok( ret, "SetDIBits failed with bad bitfields\n" );
- bi->bmiHeader.biWidth = -2;
- bi->bmiHeader.biHeight = 2;
+ bi->bmiHeader.biWidth = -DATA_HEIGHT;
+ bi->bmiHeader.biHeight = DATA_HEIGHT;
bi->bmiHeader.biBitCount = 32;
bi->bmiHeader.biCompression = BI_RGB;
hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
@@ -1144,7 +1152,7 @@ static void test_dib_formats(void)
ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with negative width\n" );
bi->bmiHeader.biWidth = 0;
- bi->bmiHeader.biHeight = 2;
+ bi->bmiHeader.biHeight = DATA_HEIGHT;
bi->bmiHeader.biBitCount = 32;
bi->bmiHeader.biCompression = BI_RGB;
hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
@@ -1167,7 +1175,7 @@ static void test_dib_formats(void)
ret = GetDIBits(hdc, hbmp, 0, 2, NULL, bi, DIB_RGB_COLORS);
ok( !ret || broken(ret), /* nt4 */ "GetDIBits succeeded with zero width\n" );
- bi->bmiHeader.biWidth = 2;
+ bi->bmiHeader.biWidth = DATA_WIDTH;
bi->bmiHeader.biHeight = 0;
bi->bmiHeader.biBitCount = 32;
bi->bmiHeader.biCompression = BI_RGB;
@@ -1193,8 +1201,8 @@ static void test_dib_formats(void)
/* some functions accept DIB_PAL_COLORS+1, but not beyond */
- bi->bmiHeader.biWidth = 2;
- bi->bmiHeader.biHeight = 2;
+ bi->bmiHeader.biWidth = DATA_WIDTH;
+ bi->bmiHeader.biHeight = DATA_HEIGHT;
bi->bmiHeader.biBitCount = 1;
bi->bmiHeader.biCompression = BI_RGB;
hdib = CreateDIBSection(hdc, bi, DIB_PAL_COLORS+1, &bits, NULL, 0);
@@ -1217,8 +1225,8 @@ static void test_dib_formats(void)
ret = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS+1);
ok( !ret, "GetDIBits succeeded with DIB_PAL_COLORS+1\n" );
- bi->bmiHeader.biWidth = 2;
- bi->bmiHeader.biHeight = 2;
+ bi->bmiHeader.biWidth = DATA_WIDTH;
+ bi->bmiHeader.biHeight = DATA_HEIGHT;
bi->bmiHeader.biBitCount = 1;
bi->bmiHeader.biCompression = BI_RGB;
hdib = CreateDIBSection(hdc, bi, DIB_PAL_COLORS+2, &bits, NULL, 0);
--
2.23.0
2
2
25 Nov '19
Signed-off-by: Chip Davis <cdavis(a)codeweavers.com>
---
Notes:
v2: Send just the tests. Attempt to fix a broken test.
v3: Remove broken test. I have no idea what Windows is doing here.
dlls/ntoskrnl.exe/tests/driver.c | 30 ++++++++++++++++++++++++++++++
dlls/ntoskrnl.exe/tests/driver.h | 1 +
dlls/ntoskrnl.exe/tests/ntoskrnl.c | 13 +++++++++++++
3 files changed, 44 insertions(+)
diff --git a/dlls/ntoskrnl.exe/tests/driver.c b/dlls/ntoskrnl.exe/tests/driver.c
index a0f63ade791..6827b74a3c9 100644
--- a/dlls/ntoskrnl.exe/tests/driver.c
+++ b/dlls/ntoskrnl.exe/tests/driver.c
@@ -1855,6 +1855,34 @@ static NTSTATUS test_load_driver_ioctl(IRP *irp, IO_STACK_LOCATION *stack, ULONG
return ZwUnloadDriver(&name);
}
+static NTSTATUS test_mismatched_status_ioctl(IRP *irp, IO_STACK_LOCATION *stack, ULONG_PTR *info)
+{
+ ULONG length = stack->Parameters.DeviceIoControl.OutputBufferLength;
+ char *buffer = irp->UserBuffer;
+
+ if (!buffer)
+ {
+ irp->IoStatus.Status = STATUS_ACCESS_VIOLATION;
+ IoCompleteRequest(irp, IO_NO_INCREMENT);
+ return STATUS_ACCESS_VIOLATION;
+ }
+
+ if (length < sizeof(teststr))
+ {
+ irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
+ IoCompleteRequest(irp, IO_NO_INCREMENT);
+ return STATUS_BUFFER_TOO_SMALL;
+ }
+
+ memcpy(buffer, teststr, sizeof(teststr));
+
+ /* This is deliberate; some broken drivers do this */
+ *info = 0;
+ irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
+ IoCompleteRequest(irp, IO_NO_INCREMENT);
+ return STATUS_SUCCESS;
+}
+
static NTSTATUS WINAPI driver_Create(DEVICE_OBJECT *device, IRP *irp)
{
IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation( irp );
@@ -1916,6 +1944,8 @@ static NTSTATUS WINAPI driver_IoControl(DEVICE_OBJECT *device, IRP *irp)
IoDetachDevice(lower_device);
status = STATUS_SUCCESS;
break;
+ case IOCTL_WINETEST_MISMATCHED_STATUS:
+ return test_mismatched_status_ioctl(irp, stack, &irp->IoStatus.Information);
default:
break;
}
diff --git a/dlls/ntoskrnl.exe/tests/driver.h b/dlls/ntoskrnl.exe/tests/driver.h
index 313d554a37b..aa9de674e2f 100644
--- a/dlls/ntoskrnl.exe/tests/driver.h
+++ b/dlls/ntoskrnl.exe/tests/driver.h
@@ -33,6 +33,7 @@
#define IOCTL_WINETEST_GET_CLOSE_COUNT CTL_CODE(FILE_DEVICE_UNKNOWN, 0x808, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_WINETEST_GET_FSCONTEXT CTL_CODE(FILE_DEVICE_UNKNOWN, 0x809, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_WINETEST_RETURN_STATUS CTL_CODE(FILE_DEVICE_UNKNOWN, 0x80a, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define IOCTL_WINETEST_MISMATCHED_STATUS CTL_CODE(FILE_DEVICE_UNKNOWN, 0x80b, METHOD_NEITHER, FILE_ANY_ACCESS)
static const char teststr[] = "Wine is not an emulator";
diff --git a/dlls/ntoskrnl.exe/tests/ntoskrnl.c b/dlls/ntoskrnl.exe/tests/ntoskrnl.c
index 76bcf0d0ce6..2535ed903e7 100644
--- a/dlls/ntoskrnl.exe/tests/ntoskrnl.c
+++ b/dlls/ntoskrnl.exe/tests/ntoskrnl.c
@@ -208,6 +208,18 @@ static void test_basic_ioctl(void)
ok(!strcmp(buf, "Wine is no"), "got '%s'\n", buf);
}
+static void test_mismatched_status_ioctl(void)
+{
+ DWORD written;
+ char buf[32];
+ BOOL res;
+
+ res = DeviceIoControl(device, IOCTL_WINETEST_MISMATCHED_STATUS, NULL, 0, buf,
+ sizeof(buf), &written, NULL);
+ todo_wine ok(res, "DeviceIoControl failed: %u\n", GetLastError());
+ todo_wine ok(!strcmp(buf, teststr), "got '%s'\n", buf);
+}
+
static void test_overlapped(void)
{
OVERLAPPED overlapped, overlapped2, *o;
@@ -514,6 +526,7 @@ START_TEST(ntoskrnl)
ok(device != INVALID_HANDLE_VALUE, "failed to open device: %u\n", GetLastError());
test_basic_ioctl();
+ test_mismatched_status_ioctl();
main_test();
test_overlapped();
test_load_driver(service2);
--
2.21.0
1
0
Based on a patch by Andrew Eikum.
Linux's CLOCK_MONOTONIC(_RAW) and macOS's mach_absolute_time all stop
counting when the computer goes to sleep/suspend/hibernate/etc. However,
Windows's GetTickCount does not stop counting. Linux's CLOCK_BOOTTIME
matches Windows's behavior, as does macOS's mach_continuous_time.
BSD's CLOCK_MONOTONIC already counts asleep time.
To avoid issues with skew and performance, this patch falls back to
mach_absolute_time on macOS if mach_continuous_time is unavailable. Note
that mach_continuous_time was introduced in macOS 10.12, meaning that if
the minimum version required is less than that, it will be linked
weakly. Therefore we must check that it is nonnull before attempting to
call it.
Signed-off-by: Chip Davis <cdavis(a)codeweavers.com>
---
configure.ac | 1 +
dlls/ntdll/time.c | 8 ++++++++
2 files changed, 9 insertions(+)
diff --git a/configure.ac b/configure.ac
index 754dbe8b36e..2a049909a65 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2206,6 +2206,7 @@ AC_CHECK_FUNCS(\
getopt_long_only \
kqueue \
lstat \
+ mach_continuous_time \
pipe2 \
poll \
port_create \
diff --git a/dlls/ntdll/time.c b/dlls/ntdll/time.c
index 91e5887b879..92415d50b04 100644
--- a/dlls/ntdll/time.c
+++ b/dlls/ntdll/time.c
@@ -111,9 +111,17 @@ static inline ULONGLONG monotonic_counter(void)
static mach_timebase_info_data_t timebase;
if (!timebase.denom) mach_timebase_info( &timebase );
+#ifdef HAVE_MACH_CONTINUOUS_TIME
+ if (mach_continuous_time != NULL)
+ return mach_continuous_time() * timebase.numer / timebase.denom / 100;
+#endif
return mach_absolute_time() * timebase.numer / timebase.denom / 100;
#elif defined(HAVE_CLOCK_GETTIME)
struct timespec ts;
+#ifdef CLOCK_BOOTTIME
+ if (!clock_gettime( CLOCK_BOOTTIME, &ts ))
+ return ts.tv_sec * (ULONGLONG)TICKSPERSEC + ts.tv_nsec / 100;
+#endif
#ifdef CLOCK_MONOTONIC_RAW
if (!clock_gettime( CLOCK_MONOTONIC_RAW, &ts ))
return ts.tv_sec * (ULONGLONG)TICKSPERSEC + ts.tv_nsec / 100;
--
2.21.0
2
2
This is the only place that's needed. Everywhere else can use 'long'.
This avoids a bunch of warnings from Clang about common standard library
functions having the wrong prototypes.
Signed-off-by: Chip Davis <cdavis(a)codeweavers.com>
---
include/msvcrt/corecrt.h | 5 +++++
include/msvcrt/math.h | 8 ++++----
2 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/include/msvcrt/corecrt.h b/include/msvcrt/corecrt.h
index c88d3e0570d..10e60d564c3 100644
--- a/include/msvcrt/corecrt.h
+++ b/include/msvcrt/corecrt.h
@@ -142,8 +142,13 @@
#ifndef _MSVCRT_LONG_DEFINED
#define _MSVCRT_LONG_DEFINED
/* we need 32-bit longs even on 64-bit */
+#ifdef __LP64__
typedef int __msvcrt_long;
typedef unsigned int __msvcrt_ulong;
+#else
+typedef long __msvcrt_long;
+typedef unsigned long __msvcrt_ulong;
+#endif
#endif
#ifndef _INTPTR_T_DEFINED
diff --git a/include/msvcrt/math.h b/include/msvcrt/math.h
index 76601de853a..68b6922458f 100644
--- a/include/msvcrt/math.h
+++ b/include/msvcrt/math.h
@@ -96,10 +96,10 @@ float __cdecl rintf(float);
float __cdecl roundf(float);
float __cdecl truncf(float);
-long __cdecl lrint(double);
-long __cdecl lrintf(float);
-long __cdecl lround(double);
-long __cdecl lroundf(float);
+__msvcrt_long __cdecl lrint(double);
+__msvcrt_long __cdecl lrintf(float);
+__msvcrt_long __cdecl lround(double);
+__msvcrt_long __cdecl lroundf(float);
double __cdecl _copysign (double, double);
double __cdecl _chgsign (double);
--
2.21.0
2
4
25 Nov '19
Signed-off-by: Jeff Smith <whydoubt(a)gmail.com>
---
dlls/msvcrt/time.c | 3 +--
dlls/ucrtbase/tests/misc.c | 8 ++++----
2 files changed, 5 insertions(+), 6 deletions(-)
diff --git a/dlls/msvcrt/time.c b/dlls/msvcrt/time.c
index 84e725747f..0d5b64a4aa 100644
--- a/dlls/msvcrt/time.c
+++ b/dlls/msvcrt/time.c
@@ -996,9 +996,8 @@ static inline BOOL strftime_int(STRFTIME_CHAR *str, MSVCRT_size_t *pos, MSVCRT_s
#endif
MSVCRT_size_t len;
- if(src<l || src>h) {
+ if(!MSVCRT_CHECK_PMT(src>=l && src<=h)) {
*str = 0;
- *MSVCRT__errno() = MSVCRT_EINVAL;
return FALSE;
}
diff --git a/dlls/ucrtbase/tests/misc.c b/dlls/ucrtbase/tests/misc.c
index 93a78a5de7..6314662eac 100644
--- a/dlls/ucrtbase/tests/misc.c
+++ b/dlls/ucrtbase/tests/misc.c
@@ -937,10 +937,10 @@ static void test_strftime(void)
{"%C", "19", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }},
{"%C", "99", { 0, 0, 0, 1, 0, 8099, 4, 0, 0 }},
{"%C", "", { 0, 0, 0, 1, 0, 8100, 4, 0, 0 }},
- {"%d", "", { 0, 0, 0, 0, 0, 70, 4, 0, 0 }, FALSE, TRUE},
+ {"%d", "", { 0, 0, 0, 0, 0, 70, 4, 0, 0 }},
{"%d", "01", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }},
{"%d", "31", { 0, 0, 0, 31, 0, 70, 4, 0, 0 }},
- {"%d", "", { 0, 0, 0, 32, 0, 70, 4, 0, 0 }, FALSE, TRUE},
+ {"%d", "", { 0, 0, 0, 32, 0, 70, 4, 0, 0 }},
{"%D", "", { 0, 0, 0, 1, 0, -1901, 4, 0, 0 }},
{"%D", "01/01/00", { 0, 0, 0, 1, 0, -1900, 4, 0, 0 }},
{"%D", "01/01/99", { 0, 0, 0, 1, 0, -1, 4, 0, 0 }},
@@ -948,10 +948,10 @@ static void test_strftime(void)
{"%D", "01/01/99", { 0, 0, 0, 1, 0, 8099, 4, 0, 0 }},
{"%D", "", { 0, 0, 0, 1, 0, 8100, 4, 0, 0 }},
{"%#D", "1/1/70", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }},
- {"%e", "", { 0, 0, 0, 0, 0, 70, 4, 0, 0 }, FALSE, TRUE},
+ {"%e", "", { 0, 0, 0, 0, 0, 70, 4, 0, 0 }},
{"%e", " 1", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }},
{"%e", "31", { 0, 0, 0, 31, 0, 70, 4, 0, 0 }},
- {"%e", "", { 0, 0, 0, 32, 0, 70, 4, 0, 0 }, FALSE, TRUE},
+ {"%e", "", { 0, 0, 0, 32, 0, 70, 4, 0, 0 }},
{"%#e", "1", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }},
{"%F", "1970-01-01", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }},
{"%#F", "1970-1-1", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }},
--
2.23.0
2
1