nsresult
sbWinGetVolumePathNames(nsAString&          aVolumeGUIDPath,
                        nsTArray<nsString>& aPathNames)
{
  BOOL success;

  // Clear the list of path names.
  aPathNames.Clear();

  // Get the total length of all of the path names.  Do nothing more if the
  // length is zero.
  DWORD pathNamesLength;
  success = GetVolumePathNamesForVolumeNameW(aVolumeGUIDPath.BeginReading(),
                                             NULL,
                                             0,
                                             &pathNamesLength);
  if (!success)
    NS_ENSURE_TRUE(GetLastError() == ERROR_MORE_DATA, NS_ERROR_FAILURE);
  if (pathNamesLength == 0)
    return NS_OK;

  // Allocate memory for the path names and set it up for auto-disposal.
  WCHAR* pathNames =
           static_cast<WCHAR*>(malloc(pathNamesLength * sizeof(WCHAR)));
  NS_ENSURE_TRUE(pathNames, NS_ERROR_OUT_OF_MEMORY);
  sbAutoMemPtr<WCHAR> autoPathNames(pathNames);

  // Get the volume path names.
  success = GetVolumePathNamesForVolumeNameW(aVolumeGUIDPath.BeginReading(),
                                             pathNames,
                                             pathNamesLength,
                                             &pathNamesLength);
  NS_ENSURE_TRUE(success, NS_ERROR_FAILURE);

  // Add the names to the volume path name list.
  DWORD pathNameIndex = 0;
  while (pathNameIndex < pathNamesLength) {
    // Get the next path name.  Exit loop if no more paths.
    WCHAR* pathName = pathNames + pathNameIndex;
    if (pathName[0] == L'\0')
      break;

    // Add the path name to the list.
    aPathNames.AppendElement(pathName);

    // Add the next path name.
    pathNameIndex += wcslen(pathName) + 1;
  }

  return NS_OK;
}
Пример #2
0
	void ProcessManager::InitDriveMappings()
	{
		wchar_t volumeName[100];
		wchar_t deviceName[150];
		wchar_t pathNames[100];

		HANDLE fileHandle = FindFirstVolumeW(volumeName, sizeof(volumeName));
		if (fileHandle == INVALID_HANDLE_VALUE)
			return;
		do
		{
			auto index = wcslen(volumeName) - 1;
			volumeName[index] = L'\0';
			auto charCount = QueryDosDeviceW(&volumeName[4], deviceName, sizeof(deviceName));
			volumeName[index] = L'\\';
			DWORD returned;
			if (GetVolumePathNamesForVolumeNameW(volumeName, pathNames, sizeof(pathNames), &returned))
			{
				DriveMappings[wxString(deviceName)] = wxString(pathNames);
			}


		} while (FindNextVolumeW(fileHandle, volumeName, sizeof(volumeName)));
		FindClose(fileHandle);
	}
Пример #3
0
bool GetDefaultLibraryPath(PWCHAR path, DWORD length)
{
	LONG error = ERROR_SUCCESS;

	// Open the libraries key
	WCHAR keyPath[MAX_PATH] = { L"Software\\Oculus VR, LLC\\Oculus\\Libraries\\" };
	HKEY oculusKey;
	error = RegOpenKeyExW(HKEY_CURRENT_USER, keyPath, 0, KEY_READ, &oculusKey);
	if (error != ERROR_SUCCESS)
	{
		LOG("Unable to open Libraries key.");
		return false;
	}

	// Get the default library
	WCHAR guid[40] = { L'\0' };
	DWORD guidSize = sizeof(guid);
	error = RegQueryValueExW(oculusKey, L"DefaultLibrary", NULL, NULL, (PBYTE)guid, &guidSize);
	RegCloseKey(oculusKey);
	if (error != ERROR_SUCCESS)
	{
		LOG("Unable to read DefaultLibrary guid.");
		return false;
	}

	// Open the default library key
	wcsncat(keyPath, guid, MAX_PATH);
	error = RegOpenKeyExW(HKEY_CURRENT_USER, keyPath, 0, KEY_READ, &oculusKey);
	if (error != ERROR_SUCCESS)
	{
		LOG("Unable to open Library path key.");
		return false;
	}

	// Get the volume path to this library
	DWORD pathSize;
	error = RegQueryValueExW(oculusKey, L"Path", NULL, NULL, NULL, &pathSize);
	PWCHAR volumePath = (PWCHAR)malloc(pathSize);
	error = RegQueryValueExW(oculusKey, L"Path", NULL, NULL, (PBYTE)volumePath, &pathSize);
	RegCloseKey(oculusKey);
	if (error != ERROR_SUCCESS)
	{
		free(volumePath);
		LOG("Unable to read Library path.");
		return false;
	}

	// Resolve the volume path to a mount point
	DWORD total;
	WCHAR volume[50] = { L'\0' };
	wcsncpy(volume, volumePath, 49);
	GetVolumePathNamesForVolumeNameW(volume, path, length, &total);
	wcsncat(path, volumePath + 49, MAX_PATH);
	free(volumePath);

	return true;
}
Пример #4
0
list<wstring> get_volume_mount_points( const wstring& volume_guid_path ) {
	unsigned buf_size = MAX_PATH;
	unique_ptr<wchar_t[ ]> buffer( new wchar_t[ buf_size ] );
	DWORD len;
	BOOL res = GetVolumePathNamesForVolumeNameW( add_trailing_slash( volume_guid_path ).c_str( ), buffer.get( ), buf_size, &len );
	if ( !res ) {
		if ( GetLastError( ) == ERROR_MORE_DATA ) {
			buf_size = len;
			buffer.reset( new wchar_t[ buf_size ] );
			res = GetVolumePathNamesForVolumeNameW( add_trailing_slash( volume_guid_path ).c_str( ), buffer.get( ), buf_size, &len );
			}
		CHECK_SYS( res );
		}
	list<wstring> result;
	const wchar_t* path = buffer.get( );
	while ( *path ) {
		unsigned len = wcslen( path );
		result.push_back( wstring( path, len ) );
		path += len + 1;
		}
	return result;
	}
Пример #5
0
void requester_freeze(int *num_vols, void *mountpoints, ErrorSet *errset)
{
    COMPointer<IVssAsync> pAsync;
    HANDLE volume;
    HRESULT hr;
    LONG ctx;
    GUID guidSnapshotSet = GUID_NULL;
    SECURITY_DESCRIPTOR sd;
    SECURITY_ATTRIBUTES sa;
    WCHAR short_volume_name[64], *display_name = short_volume_name;
    DWORD wait_status;
    int num_fixed_drives = 0, i;
    int num_mount_points = 0;

    if (vss_ctx.pVssbc) { /* already frozen */
        *num_vols = 0;
        return;
    }

    CoInitialize(NULL);

    /* Allow unrestricted access to events */
    InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
    SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE);
    sa.nLength = sizeof(sa);
    sa.lpSecurityDescriptor = &sd;
    sa.bInheritHandle = FALSE;

    vss_ctx.hEventFrozen = CreateEvent(&sa, TRUE, FALSE, EVENT_NAME_FROZEN);
    if (!vss_ctx.hEventFrozen) {
        err_set(errset, GetLastError(), "failed to create event %s",
                EVENT_NAME_FROZEN);
        goto out;
    }
    vss_ctx.hEventThaw = CreateEvent(&sa, TRUE, FALSE, EVENT_NAME_THAW);
    if (!vss_ctx.hEventThaw) {
        err_set(errset, GetLastError(), "failed to create event %s",
                EVENT_NAME_THAW);
        goto out;
    }
    vss_ctx.hEventTimeout = CreateEvent(&sa, TRUE, FALSE, EVENT_NAME_TIMEOUT);
    if (!vss_ctx.hEventTimeout) {
        err_set(errset, GetLastError(), "failed to create event %s",
                EVENT_NAME_TIMEOUT);
        goto out;
    }

    assert(pCreateVssBackupComponents != NULL);
    hr = pCreateVssBackupComponents(&vss_ctx.pVssbc);
    if (FAILED(hr)) {
        err_set(errset, hr, "failed to create VSS backup components");
        goto out;
    }

    hr = vss_ctx.pVssbc->InitializeForBackup();
    if (FAILED(hr)) {
        err_set(errset, hr, "failed to initialize for backup");
        goto out;
    }

    hr = vss_ctx.pVssbc->SetBackupState(true, true, VSS_BT_FULL, false);
    if (FAILED(hr)) {
        err_set(errset, hr, "failed to set backup state");
        goto out;
    }

    /*
     * Currently writable snapshots are not supported.
     * To prevent the final commit (which requires to write to snapshots),
     * ATTR_NO_AUTORECOVERY and ATTR_TRANSPORTABLE are specified here.
     */
    ctx = VSS_CTX_APP_ROLLBACK | VSS_VOLSNAP_ATTR_TRANSPORTABLE |
        VSS_VOLSNAP_ATTR_NO_AUTORECOVERY | VSS_VOLSNAP_ATTR_TXF_RECOVERY;
    hr = vss_ctx.pVssbc->SetContext(ctx);
    if (hr == (HRESULT)VSS_E_UNSUPPORTED_CONTEXT) {
        /* Non-server version of Windows doesn't support ATTR_TRANSPORTABLE */
        ctx &= ~VSS_VOLSNAP_ATTR_TRANSPORTABLE;
        hr = vss_ctx.pVssbc->SetContext(ctx);
    }
    if (FAILED(hr)) {
        err_set(errset, hr, "failed to set backup context");
        goto out;
    }

    hr = vss_ctx.pVssbc->GatherWriterMetadata(pAsync.replace());
    if (SUCCEEDED(hr)) {
        hr = WaitForAsync(pAsync);
    }
    if (FAILED(hr)) {
        err_set(errset, hr, "failed to gather writer metadata");
        goto out;
    }

    AddComponents(errset);
    if (err_is_set(errset)) {
        goto out;
    }

    hr = vss_ctx.pVssbc->StartSnapshotSet(&guidSnapshotSet);
    if (FAILED(hr)) {
        err_set(errset, hr, "failed to start snapshot set");
        goto out;
    }

    if (mountpoints) {
        PWCHAR volume_name_wchar;
        for (volList *list = (volList *)mountpoints; list; list = list->next) {
            size_t len = strlen(list->value) + 1;
            size_t converted = 0;
            VSS_ID pid;

            volume_name_wchar = new wchar_t[len];
            mbstowcs_s(&converted, volume_name_wchar, len,
                       list->value, _TRUNCATE);

            hr = vss_ctx.pVssbc->AddToSnapshotSet(volume_name_wchar,
                                                  g_gProviderId, &pid);
            if (FAILED(hr)) {
                err_set(errset, hr, "failed to add %S to snapshot set",
                        volume_name_wchar);
                delete volume_name_wchar;
                goto out;
            }
            num_mount_points++;

            delete volume_name_wchar;
        }

        if (num_mount_points == 0) {
            /* If there is no valid mount points, just exit. */
            goto out;
        }
    }

    if (!mountpoints) {
        volume = FindFirstVolumeW(short_volume_name, sizeof(short_volume_name));
        if (volume == INVALID_HANDLE_VALUE) {
            err_set(errset, hr, "failed to find first volume");
            goto out;
        }

        for (;;) {
            if (GetDriveTypeW(short_volume_name) == DRIVE_FIXED) {
                VSS_ID pid;
                hr = vss_ctx.pVssbc->AddToSnapshotSet(short_volume_name,
                                                      g_gProviderId, &pid);
                if (FAILED(hr)) {
                    WCHAR volume_path_name[PATH_MAX];
                    if (GetVolumePathNamesForVolumeNameW(
                            short_volume_name, volume_path_name,
                            sizeof(volume_path_name), NULL) &&
                            *volume_path_name) {
                        display_name = volume_path_name;
                    }
                    err_set(errset, hr, "failed to add %S to snapshot set",
                            display_name);
                    FindVolumeClose(volume);
                    goto out;
                }
                num_fixed_drives++;
            }
            if (!FindNextVolumeW(volume, short_volume_name,
                                 sizeof(short_volume_name))) {
                FindVolumeClose(volume);
                break;
            }
        }

        if (num_fixed_drives == 0) {
            goto out; /* If there is no fixed drive, just exit. */
        }
    }

    hr = vss_ctx.pVssbc->PrepareForBackup(pAsync.replace());
    if (SUCCEEDED(hr)) {
        hr = WaitForAsync(pAsync);
    }
    if (FAILED(hr)) {
        err_set(errset, hr, "failed to prepare for backup");
        goto out;
    }

    hr = vss_ctx.pVssbc->GatherWriterStatus(pAsync.replace());
    if (SUCCEEDED(hr)) {
        hr = WaitForAsync(pAsync);
    }
    if (FAILED(hr)) {
        err_set(errset, hr, "failed to gather writer status");
        goto out;
    }

    /*
     * Start VSS quiescing operations.
     * CQGAVssProvider::CommitSnapshots will kick vss_ctx.hEventFrozen
     * after the applications and filesystems are frozen.
     */
    hr = vss_ctx.pVssbc->DoSnapshotSet(&vss_ctx.pAsyncSnapshot);
    if (FAILED(hr)) {
        err_set(errset, hr, "failed to do snapshot set");
        goto out;
    }

    /* Need to call QueryStatus several times to make VSS provider progress */
    for (i = 0; i < VSS_TIMEOUT_FREEZE_MSEC/VSS_TIMEOUT_EVENT_MSEC; i++) {
        HRESULT hr2 = vss_ctx.pAsyncSnapshot->QueryStatus(&hr, NULL);
        if (FAILED(hr2)) {
            err_set(errset, hr, "failed to do snapshot set");
            goto out;
        }
        if (hr != VSS_S_ASYNC_PENDING) {
            err_set(errset, E_FAIL,
                    "DoSnapshotSet exited without Frozen event");
            goto out;
        }
        wait_status = WaitForSingleObject(vss_ctx.hEventFrozen,
                                          VSS_TIMEOUT_EVENT_MSEC);
        if (wait_status != WAIT_TIMEOUT) {
            break;
        }
    }

    if (wait_status == WAIT_TIMEOUT) {
        err_set(errset, E_FAIL,
                "timeout when try to receive Frozen event from VSS provider");
        /* If we are here, VSS had timeout.
         * Don't call AbortBackup, just return directly.
         */
        goto out1;
    }

    if (wait_status != WAIT_OBJECT_0) {
        err_set(errset, E_FAIL,
                "couldn't receive Frozen event from VSS provider");
        goto out;
    }

    if (mountpoints) {
        *num_vols = vss_ctx.cFrozenVols = num_mount_points;
    } else {
        *num_vols = vss_ctx.cFrozenVols = num_fixed_drives;
    }

    return;

out:
    if (vss_ctx.pVssbc) {
        vss_ctx.pVssbc->AbortBackup();
    }

out1:
    requester_cleanup();
    CoUninitialize();
}
Пример #6
0
/*
 * File system functions
 */
JNIEXPORT void JNICALL
Java_net_rubygrapefruit_platform_internal_jni_PosixFileSystemFunctions_listFileSystems(JNIEnv *env, jclass target, jobject info, jobject result) {
    wchar_t* volumeName = (wchar_t*)malloc(sizeof(wchar_t) * (MAX_PATH+1));

    jclass info_class = env->GetObjectClass(info);
    jmethodID method = env->GetMethodID(info_class, "add", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Z)V");

    HANDLE handle = FindFirstVolumeW(volumeName, MAX_PATH+1);
    if (handle == INVALID_HANDLE_VALUE) {
        free(volumeName);
        mark_failed_with_errno(env, "could not find first volume", result);
        return;
    }

    wchar_t* deviceName = (wchar_t*)malloc(sizeof(wchar_t) * (MAX_PATH+1));
    wchar_t* pathNames = (wchar_t*)malloc(sizeof(wchar_t) * (MAX_PATH+1));
    wchar_t* fsName = (wchar_t*)malloc(sizeof(wchar_t) * (MAX_PATH+1));

    while(true) {
        // Chop off the trailing '\'
        size_t len = wcslen(volumeName);
        if (len < 5) {
            mark_failed_with_message(env, "volume name is too short", result);
            break;
        }
        volumeName[len-1] = L'\0';

        if (QueryDosDeviceW(&volumeName[4], deviceName, MAX_PATH+1) == 0) {
            mark_failed_with_errno(env, "could not query dos device", result);
            break;
        }
        volumeName[len-1] = L'\\';

        DWORD used;
        if (GetVolumePathNamesForVolumeNameW(volumeName, pathNames, MAX_PATH+1, &used) == 0) {
            // TODO - try again if the buffer is too small
            mark_failed_with_errno(env, "could not query volume paths", result);
            break;
        }

        wchar_t* cur = pathNames;
        if (cur[0] != L'\0') {
            if(GetVolumeInformationW(cur, NULL, 0, NULL, NULL, NULL, fsName, MAX_PATH+1) == 0) {
                if (GetLastError() != ERROR_NOT_READY) {
                    mark_failed_with_errno(env, "could not query volume information", result);
                    break;
                }
                wcscpy(fsName, L"unknown");
            }
            for (;cur[0] != L'\0'; cur += wcslen(cur) + 1) {
                env->CallVoidMethod(info, method, env->NewString((jchar*)deviceName, wcslen(deviceName)),
                                    env->NewString((jchar*)fsName, wcslen(fsName)), env->NewString((jchar*)cur, wcslen(cur)), JNI_FALSE);
            }
        }

        if (FindNextVolumeW(handle, volumeName, MAX_PATH) == 0) {
            if (GetLastError() != ERROR_NO_MORE_FILES) {
                mark_failed_with_errno(env, "could find next volume", result);
            }
            break;
        }
    }
    free(volumeName);
    free(deviceName);
    free(pathNames);
    free(fsName);
    FindVolumeClose(handle);
}
Пример #7
0
void WmdmLister::GuessDriveLetter(DeviceInfo* info) {
  qLog(Debug) << "Guessing drive letter for" << info->name_;

  // Windows XP puts the drive letter in brackets at the end of the name
  QRegExp drive_letter("\\(([A-Z]:)\\)$");
  if (drive_letter.indexIn(info->name_) != -1) {
    qLog(Debug) << "Looks like an XP drive" << drive_letter.cap(1);
    CheckDriveLetter(info, drive_letter.cap(1));
    return;
  }

  // Windows 7 sometimes has the drive letter as the whole name
  drive_letter = QRegExp("^([A-Z]:)\\\\$");
  if (drive_letter.indexIn(info->name_) != -1) {
    qLog(Debug) << "Looks like a win7 drive" << drive_letter.cap(1);
    CheckDriveLetter(info, drive_letter.cap(1));
    return;
  }

  // Otherwise Windows 7 uses the drive's DOS label as its whole name.
  // Let's enumerate all the volumes on the system and find one with that
  // label, then get its drive letter.  Yay!
  wchar_t volume_name[MAX_PATH + 1];
  HANDLE handle = FindFirstVolumeW(volume_name, MAX_PATH);

  forever {
    // QueryDosDeviceW doesn't allow a trailing backslash, so remove it.
    int length = wcslen(volume_name);
    volume_name[length - 1] = L'\0';

    wchar_t device_name[MAX_PATH + 1];
    QueryDosDeviceW(&volume_name[4], device_name, MAX_PATH);

    volume_name[length - 1] = L'\\';

    // Don't do cd-roms or floppies
    if (QString::fromWCharArray(device_name).contains("HarddiskVolume")) {
      wchar_t volume_path[MAX_PATH + 1];
      DWORD volume_path_length = MAX_PATH;
      GetVolumePathNamesForVolumeNameW(
          volume_name, volume_path, volume_path_length, &volume_path_length);

      if (wcslen(volume_path) == 3) {
        ScopedWCharArray name(QString(MAX_PATH + 1, '\0'));
        ScopedWCharArray type(QString(MAX_PATH + 1, '\0'));
        DWORD serial = 0;

        if (!GetVolumeInformationW(volume_path, name, MAX_PATH,
            &serial, NULL, NULL, type, MAX_PATH)) {
          qLog(Warning) << "Error getting volume information for" <<
              QString::fromWCharArray(volume_path);
        } else {
          if (name.ToString() == info->name_ && name.characters() != 0) {
            // We found it!
            qLog(Debug) << "Looks like a win7 drive name" << QString::fromWCharArray(volume_path);
            if (CheckDriveLetter(info, QString::fromWCharArray(volume_path))) {
              info->device_name_ = QString::fromWCharArray(device_name);
              info->volume_name_ = QString::fromWCharArray(volume_name);
            }
            break;
          }
        }
      }
    }

    if (!FindNextVolumeW(handle, volume_name, MAX_PATH))
      break;
  }
  FindVolumeClose(handle);
}