[PATCH] kernel32: Basic integration of SetVolumeMountPointA/W.
Johannes Obermayr
johannesobermayr at gmx.de
Wed Nov 21 12:51:23 CST 2012
Fixes: Bug 31951 and its duplicate 31703 (crash in TomTom HOME software)
Fixes not: Bug 7711 (detecting TomTom devices)
Maybe the device detection works if wine's MountManager supports MOUNTMGR_CREATE_POINT_INPUT:
- fixme:mountmgr:mountmgr_ioctl ioctl 6dc000 not supported
- http://doxygen.reactos.org/d9/df4/drivers_2filters_2mountmgr_2device_8c_source.html#l01479
---
dlls/kernel32/kernel32.spec | 4 +-
dlls/kernel32/volume.c | 161 +++++++++++++++++++++++++++++++++++++++++++
include/winbase.h | 2 +-
3 Dateien geändert, 164 Zeilen hinzugefügt(+), 3 Zeilen entfernt(-)
diff --git a/dlls/kernel32/kernel32.spec b/dlls/kernel32/kernel32.spec
index 0bd1adc..9b16dfe 100644
--- a/dlls/kernel32/kernel32.spec
+++ b/dlls/kernel32/kernel32.spec
@@ -1179,8 +1179,8 @@
@ stub SetVDMCurrentDirectories
@ stdcall SetVolumeLabelA(str str)
@ stdcall SetVolumeLabelW(wstr wstr)
-@ stub SetVolumeMountPointA
-@ stub SetVolumeMountPointW
+@ stdcall SetVolumeMountPointA(str str)
+@ stdcall SetVolumeMountPointW(wstr wstr)
@ stdcall SetWaitableTimer(long ptr long ptr ptr long)
@ stdcall SetupComm(long long long)
@ stub ShowConsoleCursor
diff --git a/dlls/kernel32/volume.c b/dlls/kernel32/volume.c
index 200c293..d0fbf42 100644
--- a/dlls/kernel32/volume.c
+++ b/dlls/kernel32/volume.c
@@ -1098,6 +1098,167 @@ err_ret:
}
/***********************************************************************
+ * SetVolumeMountPointW (KERNEL32.@)
+ */
+BOOL WINAPI SetVolumeMountPointW(LPCWSTR path, LPCWSTR volume)
+{
+ const WCHAR prefixW[] = {'\\','D','o','s','D','e','v','i','c','e','s','\\'};
+ LPWSTR namesW = NULL;
+ UNICODE_STRING volumeU = {0};
+ DWORD buffer = MAX_PATH;
+ HANDLE mgr;
+ BOOL ret = FALSE;
+ int i;
+
+ /* This struct is a better integration of MOUNTMGR_CREATE_POINT_INPUT */
+ /* Maybe DeviceName[14] must become adapted for mounted folders support */
+ struct
+ {
+ USHORT DeviceNameOffset;
+ USHORT DeviceNameLength;
+ USHORT VolumeNameOffset;
+ USHORT VolumeNameLength;
+ WCHAR DeviceName[14]; /* 14 WCHARs: prefixW + 2 */
+ WCHAR VolumeName[48]; /* without trailing '\' */
+ } input;
+
+ TRACE("(%s, %s)\n", debugstr_w(path), debugstr_w(volume));
+
+ /* Clear input */
+ memset(&input, 0, sizeof(input));
+ /* Now prefill with always needed consts */
+ memset(&input.DeviceNameOffset, (const USHORT)((int)&input.DeviceName - (int)&input), 1);
+ memset(&input.DeviceNameLength, (const USHORT)((int)&input.VolumeName - (int)&input.DeviceName), 1);
+ memset(&input.VolumeNameOffset, (const USHORT)(input.DeviceNameOffset + input.DeviceNameLength), 1);
+ memset(&input.VolumeNameLength, (const USHORT)((strlenW(volume) - 1) * sizeof(WCHAR)), 1);
+
+ /* Begin with initial checks */
+ if (!path || !volume)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ goto free_input;
+ }
+
+ /* Abort if path has been mounted */
+ if (GetVolumeNameForVolumeMountPointW(path, namesW, MAX_PATH))
+ {
+ WARN("%s already mounts %s\n", debugstr_w(path), debugstr_w(namesW));
+ SetLastError(ERROR_DIR_NOT_EMPTY);
+ goto free_input;
+ }
+
+ /* We can use checks and error codes from GetVolumeNameForVolumeMountPointW */
+ switch (GetLastError())
+ {
+ case ERROR_INVALID_NAME:
+ case ERROR_FILENAME_EXCED_RANGE:
+ goto free_input;
+ default:
+ break;
+ }
+
+ /* Create UNICODE_STRINGs for path and volume */
+ if (RtlInitUnicodeStringEx(&volumeU, volume) != STATUS_SUCCESS)
+ goto free_input;
+
+ /* Check whether volume name is valid */
+ if (!MOUNTMGR_IS_VOLUME_NAME(&volumeU))
+ {
+ WARN("(%s, %s), invalid volume name!\n", debugstr_w(path), debugstr_w(volume));
+ SetLastError(ERROR_INVALID_NAME);
+ goto free_input;
+ }
+
+ /* Abort if volume has been mounted */
+ if (GetVolumePathNamesForVolumeNameW(volume, namesW, buffer, &buffer))
+ {
+ WARN("%s is already mounted by %s\n", debugstr_w(volume), debugstr_w(namesW));
+ SetLastError(ERROR_VOLUME_MOUNTED);
+ goto free_input;
+ }
+
+ if(strlenW(path) == 3 && path[1] == ':')
+ {
+ /* Fill input with SymlinkName */
+ memcpy(input.DeviceName, prefixW, sizeof(prefixW));
+ memset(&input.DeviceName[12], (const WCHAR)(toupper(path[0])), 1);
+ memset(&input.DeviceName[13], (const WCHAR)(':'), 1);
+
+ /* Now fill the VolumeName an make sure the 2nd WCHAR is '?' */
+ for (i = 0; i < 49; i++)
+ memset(&input.VolumeName[i], volumeU.Buffer[i], 1);
+
+ memset(&input.VolumeName[1], (const WCHAR)('?'), 1);
+
+ /* Create the handle */
+ mgr = CreateFileW(MOUNTMGR_DOS_DEVICE_NAME,
+ GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ 0,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ if (mgr == INVALID_HANDLE_VALUE)
+ {
+ WARN("Handle could not be created\n");
+ goto free_input;
+ }
+
+ /* MountManager should now be able to create the VolumeMountPoint */
+ ret = DeviceIoControl(mgr, IOCTL_MOUNTMGR_CREATE_POINT, &input, sizeof(input), 0, 0, 0, 0);
+
+ CloseHandle(mgr);
+
+ goto free_input;
+ }
+
+ FIXME("Mounted Folders are not yet supported\n");
+
+free_input:
+ HeapFree(GetProcessHeap(), 0, &input);
+
+ return ret;
+}
+
+/************************************************************************
+ * SetVolumeMountPointA (KERNEL32.@)
+ */
+BOOL WINAPI SetVolumeMountPointA(LPCSTR path, LPCSTR volume)
+{
+ BOOL ret = FALSE;
+ WCHAR *pathW, *volumeW;
+
+ TRACE("(%s, %s)\n", debugstr_a(path), debugstr_a(volume));
+
+ if (!path || !volume)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ if (!(pathW = FILE_name_AtoW(path, TRUE)))
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ return FALSE;
+ }
+
+ if (!(volumeW = FILE_name_AtoW(volume, TRUE)))
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ goto free_pathW;
+ }
+
+ ret = SetVolumeMountPointW(pathW, volumeW);
+
+ HeapFree(GetProcessHeap(), 0, volumeW);
+free_pathW:
+ HeapFree(GetProcessHeap(), 0, pathW);
+
+ return ret;
+}
+
+/***********************************************************************
* DefineDosDeviceW (KERNEL32.@)
*/
BOOL WINAPI DefineDosDeviceW( DWORD flags, LPCWSTR devname, LPCWSTR targetpath )
diff --git a/include/winbase.h b/include/winbase.h
index a9abb30..936497e 100644
--- a/include/winbase.h
+++ b/include/winbase.h
@@ -2229,7 +2229,7 @@ WINBASEAPI BOOL WINAPI SetVolumeLabelA(LPCSTR,LPCSTR);
WINBASEAPI BOOL WINAPI SetVolumeLabelW(LPCWSTR,LPCWSTR);
#define SetVolumeLabel WINELIB_NAME_AW(SetVolumeLabel)
WINBASEAPI BOOL WINAPI SetVolumeMountPointA(LPCSTR,LPCSTR);
-WINBASEAPI BOOL WINAPI SetVolumeMountPointW(LPCSTR,LPCSTR);
+WINBASEAPI BOOL WINAPI SetVolumeMountPointW(LPCWSTR,LPCWSTR);
#define SetVolumeMountPoint WINELIB_NAME_AW(SetVolumeMountPoint)
WINBASEAPI BOOL WINAPI SetWaitableTimer(HANDLE,const LARGE_INTEGER*,LONG,PTIMERAPCROUTINE,LPVOID,BOOL);
WINBASEAPI BOOL WINAPI SetupComm(HANDLE,DWORD,DWORD);
--
1.7.10.4
More information about the wine-patches
mailing list