Module: wine Branch: master Commit: c1dd22898136604a576c1bed8818da8ef3ed1eaf URL: http://source.winehq.org/git/wine.git/?a=commit;h=c1dd22898136604a576c1bed88...
Author: Joachim Priesner joachim.priesner@web.de Date: Thu Jan 28 17:13:22 2016 +0100
scrrun: Implement filesys_GetDrive for local drives.
Signed-off-by: Joachim Priesner joachim.priesner@web.de Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/scrrun/filesystem.c | 35 ++++++++++++++++- dlls/scrrun/tests/filesystem.c | 89 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 122 insertions(+), 2 deletions(-)
diff --git a/dlls/scrrun/filesystem.c b/dlls/scrrun/filesystem.c index 98895cc..818079e 100644 --- a/dlls/scrrun/filesystem.c +++ b/dlls/scrrun/filesystem.c @@ -3272,9 +3272,40 @@ static HRESULT WINAPI filesys_FolderExists(IFileSystem3 *iface, BSTR path, VARIA static HRESULT WINAPI filesys_GetDrive(IFileSystem3 *iface, BSTR DriveSpec, IDrive **ppdrive) { - FIXME("%p %s %p\n", iface, debugstr_w(DriveSpec), ppdrive); + UINT len; + HRESULT hr; + WCHAR driveletter; + VARIANT_BOOL drive_exists;
- return E_NOTIMPL; + TRACE("%p %s %p\n", iface, debugstr_w(DriveSpec), ppdrive); + + if (!ppdrive) + return E_POINTER; + + *ppdrive = NULL; + + /* DriveSpec may be one of: 'x', 'x:', 'x:', '\computer\share' */ + len = SysStringLen(DriveSpec); + if (!len) + return E_INVALIDARG; + else if (len <= 3) { + driveletter = toupperW(DriveSpec[0]); + if (driveletter < 'A' || driveletter > 'Z' + || (len >= 2 && DriveSpec[1] != ':') + || (len == 3 && DriveSpec[2] != '\')) + return E_INVALIDARG; + hr = IFileSystem3_DriveExists(iface, DriveSpec, &drive_exists); + if (FAILED(hr)) + return hr; + if (drive_exists == VARIANT_FALSE) + return CTL_E_DEVICEUNAVAILABLE; + return create_drive(driveletter, ppdrive); + } else { + if (DriveSpec[0] != '\' || DriveSpec[1] != '\') + return E_INVALIDARG; + FIXME("%s not implemented yet\n", debugstr_w(DriveSpec)); + return E_NOTIMPL; + } }
static HRESULT WINAPI filesys_GetFile(IFileSystem3 *iface, BSTR FilePath, diff --git a/dlls/scrrun/tests/filesystem.c b/dlls/scrrun/tests/filesystem.c index 33f403c..8457714 100644 --- a/dlls/scrrun/tests/filesystem.c +++ b/dlls/scrrun/tests/filesystem.c @@ -1953,6 +1953,94 @@ static void test_GetDriveName(void) } }
+struct getdrive_test { + const WCHAR drivespec[12]; + HRESULT res; + const WCHAR driveletter[2]; +}; + +static void test_GetDrive(void) +{ + HRESULT hr; + IDrive *drive_fixed, *drive; + BSTR dl_fixed, drivespec; + WCHAR root[] = {'?',':','\',0}; + + drive = (void*)0xdeadbeef; + hr = IFileSystem3_GetDrive(fs3, NULL, NULL); + ok(hr == E_POINTER, "got 0x%08x\n", hr); + ok(drive == (void*)0xdeadbeef, "got %p\n", drive); + + for (root[0] = 'A'; root[0] <= 'Z'; root[0]++) + if (GetDriveTypeW(root) == DRIVE_NO_ROOT_DIR) + break; + + if (root[0] > 'Z') + skip("All drive letters are occupied, skipping test for nonexisting drive.\n"); + else { + drivespec = SysAllocString(root); + drive = (void*)0xdeadbeef; + hr = IFileSystem3_GetDrive(fs3, drivespec, &drive); + ok(hr == CTL_E_DEVICEUNAVAILABLE, "got 0x%08x\n", hr); + ok(drive == NULL, "got %p\n", drive); + SysFreeString(drivespec); + } + + drive_fixed = get_fixed_drive(); + if (!drive_fixed) { + skip("No fixed drive found, skipping test.\n"); + return; + } + + hr = IDrive_get_DriveLetter(drive_fixed, &dl_fixed); + ok(hr == S_OK, "got 0x%08x\n", hr); + + if (FAILED(hr)) + skip("Could not retrieve drive letter of fixed drive, skipping test.\n"); + else { + WCHAR dl_upper = toupper(dl_fixed[0]); + WCHAR dl_lower = tolower(dl_fixed[0]); + struct getdrive_test testdata[] = { + { {dl_upper,0}, S_OK, {dl_upper,0} }, + { {dl_upper,':',0}, S_OK, {dl_upper,0} }, + { {dl_upper,':','\',0}, S_OK, {dl_upper,0} }, + { {dl_lower,':','\',0}, S_OK, {dl_upper,0} }, + { {dl_upper,'\',0}, E_INVALIDARG, { 0 } }, + { {dl_lower,'\',0}, E_INVALIDARG, { 0 } }, + { {'$',':','\',0}, E_INVALIDARG, { 0 } }, + { {'\','h','o','s','t','\','s','h','a','r','e',0}, E_INVALIDARG, { 0 } }, + { {'h','o','s','t','\','s','h','a','r','e',0}, E_INVALIDARG, { 0 } }, + { { 0 } }, + }; + struct getdrive_test *ptr = &testdata[0]; + + for (; *ptr->drivespec; ptr++) { + drivespec = SysAllocString(ptr->drivespec); + drive = (void*)0xdeadbeef; + hr = IFileSystem3_GetDrive(fs3, drivespec, &drive); + ok(hr == ptr->res, "got 0x%08x, expected 0x%08x for drive spec %s\n", + hr, ptr->res, wine_dbgstr_w(ptr->drivespec)); + ok(!lstrcmpW(ptr->drivespec, drivespec), "GetDrive modified its DriveSpec argument\n"); + SysFreeString(drivespec); + + if (*ptr->driveletter) { + BSTR driveletter; + hr = IDrive_get_DriveLetter(drive, &driveletter); + ok(hr == S_OK, "got 0x%08x for drive spec %s\n", hr, wine_dbgstr_w(ptr->drivespec)); + if (SUCCEEDED(hr)) { + ok(!lstrcmpW(ptr->driveletter, driveletter), "got %s, expected %s for drive spec %s\n", + wine_dbgstr_w(driveletter), wine_dbgstr_w(ptr->driveletter), + wine_dbgstr_w(ptr->drivespec)); + SysFreeString(driveletter); + } + IDrive_Release(drive); + } else + ok(drive == NULL, "got %p for drive spec %s\n", drive, wine_dbgstr_w(ptr->drivespec)); + } + SysFreeString(dl_fixed); + } +} + static void test_SerialNumber(void) { IDrive *drive; @@ -2111,6 +2199,7 @@ START_TEST(filesystem) test_Read(); test_DriveExists(); test_GetDriveName(); + test_GetDrive(); test_SerialNumber(); test_GetExtensionName(); test_GetSpecialFolder();