Пример #1
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);
	}
Пример #2
0
/* real hardware */
static GList *
get_connected_drives (GVolumeMonitor *volume_monitor)
{
  GList *list = NULL;

#if 0
  HANDLE  find_handle;
  BOOL    found;
  wchar_t wc_name[MAX_PATH+1];
  
  find_handle = FindFirstVolumeW (wc_name, MAX_PATH);
  found = (find_handle != INVALID_HANDLE_VALUE);
  while (found)
    {
      /* I don't know what this code is supposed to do; clearly it now
       * does nothing, the returned GList is always NULL. But what was
       * this code supposed to be a start of? The volume names that
       * the FindFirstVolume/FindNextVolume loop iterates over returns
       * device names like
       *
       *   \Device\HarddiskVolume1
       *   \Device\HarddiskVolume2
       *   \Device\CdRom0
       *
       * No DOS devices there, so I don't see the point with the
       * QueryDosDevice call below. Probably this code is confusing volumes
       * with something else that does contain the mapping from DOS devices
       * to volumes.
       */
      wchar_t wc_dev_name[MAX_PATH+1];
      guint trailing = wcslen (wc_name) - 1;

      /* remove trailing backslash and leading \\?\\ */
      wc_name[trailing] = L'\0';
      if (QueryDosDeviceW (&wc_name[4], wc_dev_name, MAX_PATH))
        {
          gchar *name = g_utf16_to_utf8 (wc_dev_name, -1, NULL, NULL, NULL);
          g_print ("%s\n", name);
	  g_free (name);
	}

      found = FindNextVolumeW (find_handle, wc_name, MAX_PATH);
    }
  if (find_handle != INVALID_HANDLE_VALUE)
    FindVolumeClose (find_handle);
#endif

  return list;
}
Пример #3
0
/*
 * @implemented (Wine 13 sep 2008)
 */
HANDLE
WINAPI
FindFirstVolumeW(IN LPWSTR volume,
                 IN DWORD len)
{
    DWORD size = 1024;
    HANDLE mgr = CreateFileW( MOUNTMGR_DOS_DEVICE_NAME, 0, FILE_SHARE_READ|FILE_SHARE_WRITE,
                              NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, INVALID_HANDLE_VALUE );
    if (mgr == INVALID_HANDLE_VALUE) return INVALID_HANDLE_VALUE;

    for (;;)
    {
        MOUNTMGR_MOUNT_POINT input;
        MOUNTMGR_MOUNT_POINTS *output;

        if (!(output = RtlAllocateHeap( RtlGetProcessHeap(), 0, size )))
        {
            SetLastError( ERROR_NOT_ENOUGH_MEMORY );
            break;
        }
        memset( &input, 0, sizeof(input) );

        if (!DeviceIoControl( mgr, IOCTL_MOUNTMGR_QUERY_POINTS, &input, sizeof(input),
                              output, size, NULL, NULL ))
        {
            if (GetLastError() != ERROR_MORE_DATA) break;
            size = output->Size;
            RtlFreeHeap( RtlGetProcessHeap(), 0, output );
            continue;
        }
        CloseHandle( mgr );
        /* abuse the Size field to store the current index */
        output->Size = 0;
        if (!FindNextVolumeW( output, volume, len ))
        {
            RtlFreeHeap( RtlGetProcessHeap(), 0, output );
            return INVALID_HANDLE_VALUE;
        }
        return (HANDLE)output;
    }
    CloseHandle( mgr );
    return INVALID_HANDLE_VALUE;
}
Пример #4
0
	bool next( ) {
		if ( h_enum == INVALID_HANDLE_VALUE ) {
			h_enum = FindFirstVolumeW( volume_path.get( ), c_buf_size );
			if ( h_enum == INVALID_HANDLE_VALUE ) {
				if ( GetLastError( ) == ERROR_NO_MORE_FILES ) {
					return false;
					}
				CHECK_SYS( false );
				}
			}
		else {
			BOOL res = FindNextVolumeW( h_enum, volume_path.get( ), c_buf_size );
			if ( !res ) {
				if ( GetLastError( ) == ERROR_NO_MORE_FILES ) {
					return false;
					}
				CHECK_SYS( false );
				}
			}
		return true;
		}
Пример #5
0
/*
 * @implemented
 */
BOOL
WINAPI
FindNextVolumeA(IN HANDLE handle,
                IN LPSTR volume,
                IN DWORD len)
{
    WCHAR *buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, len * sizeof(WCHAR));
    BOOL ret;

    if (!buffer)
    {
        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
        return FALSE;
    }

    if ((ret = FindNextVolumeW( handle, buffer, len )))
    {
        if (!WideCharToMultiByte( CP_ACP, 0, buffer, -1, volume, len, NULL, NULL )) ret = FALSE;
    }

    RtlFreeHeap(RtlGetProcessHeap(), 0, buffer);
    return ret;
}
Пример #6
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();
}
Пример #7
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);
}
Пример #8
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);
}