From c1dd22898136604a576c1bed8818da8ef3ed1eaf Mon Sep 17 00:00:00 2001 From: Joachim Priesner Date: Thu, 28 Jan 2016 17:13:22 +0100 Subject: [PATCH] scrrun: Implement filesys_GetDrive for local drives. Signed-off-by: Joachim Priesner Signed-off-by: Alexandre Julliard --- 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 98895cc3045..818079ef14f 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 33f403c0506..8457714b0f6 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();