//function check for new partition //get volume letter for each partition //and set free letter for it int CDiskRepartition::enumeratevolumes(void) { //buffer for dos device volume name char Let[4]; //buffer for GUID volume name char buf[BUFSIZE]; HANDLE hVol; BOOL bFlag = true; sprintf(Let,"%c:\\",DiskName); hVol = FindFirstVolumeA(buf, BUFSIZE ); if (hVol == INVALID_HANDLE_VALUE) { printf (TEXT("No volumes found!\n")); return (-1); } while (bFlag) { bFlag = FindNextVolumeA(hVol, buf, BUFSIZE ); if (GetVolumesLetter(buf)<65) { OutputDebugStringA(buf); SetVolumeMountPoint(Let,buf); bFlag = FindVolumeClose(hVol); return false; } } bFlag = FindVolumeClose(hVol); return true; }
int __cdecl main() { HANDLE find_handle; char vol_name[MAX_PATH+1]; flush_registry(); /* Now loop over every volume and sync them as well. */ find_handle = FindFirstVolume(vol_name, ARRAYSIZE(vol_name)); if (find_handle == INVALID_HANDLE_VALUE) xs_win_err(1, &xs_render_error_msgbox, "failed to start enumerating disk volumes"); while (1) { sync_this_volume(vol_name); if (!FindNextVolume(find_handle, vol_name, ARRAYSIZE(vol_name))) { if (GetLastError() == ERROR_NO_MORE_FILES) break; xs_win_err(1, &xs_render_error_msgbox, "failed to enumerate disk volumes"); } } FindVolumeClose(find_handle); return 0; }
bool PrintMountPoints(const char *path) { char volumeUniqueName[128]; BOOL res = GetVolumeNameForVolumeMountPointA(path, volumeUniqueName, 128); if (!res) { return false; } char buf[BUFSIZE]; // buffer for unique volume identifiers HANDLE hVol; // handle for the volume scan // Open a scan for volumes. hVol = FindFirstVolumeA(buf, BUFSIZE); // Shall we error out? if (hVol == INVALID_HANDLE_VALUE) { return false; } bool success = true; do { if (!strcmp(buf, volumeUniqueName)) { success = PrintMountPointsForVolume(hVol, path, buf); if (!success) break; } } while (FindNextVolumeA(hVol, buf, BUFSIZE)); FindVolumeClose(hVol); return success; }
/* * @implemented (Wine 13 sep 2008) */ HANDLE WINAPI FindFirstVolumeA(IN LPSTR volume, IN DWORD len) { WCHAR *buffer = NULL; HANDLE handle; buffer = RtlAllocateHeap( RtlGetProcessHeap(), 0, len * sizeof(WCHAR) ); if (!buffer) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); return INVALID_HANDLE_VALUE; } handle = FindFirstVolumeW( buffer, len ); if (handle != INVALID_HANDLE_VALUE) { if (!WideCharToMultiByte( CP_ACP, 0, buffer, -1, volume, len, NULL, NULL )) { FindVolumeClose( handle ); handle = INVALID_HANDLE_VALUE; } } RtlFreeHeap( RtlGetProcessHeap(), 0, buffer ); return handle; }
int EnumerateVolumes() { HRESULT error; WCHAR volname[MAX_PATH+1]; auto hFind = FindFirstVolume(volname, ARRAYSIZE(volname)); if (hFind==INVALID_HANDLE_VALUE) return Usage(GetLastError(), L"FindFirstVolume() failed"); while(true) { auto len = wcslen(volname); volname[len] = 0; auto v = new Volume(); v->Init(volname, len); g_volumes.push_back(shared_ptr<Volume>(v)); auto hasNext = FindNextVolume(hFind, volname, ARRAYSIZE(volname)); if (hasNext) continue; error = GetLastError(); if (error==ERROR_NO_MORE_FILES) error = 0; break; } FindVolumeClose(hFind); if (error!=0) return Usage(error, L"ProcessLv failed"); return 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; }
UINT fileManage::getVolume(WCHAR* volumePathName, UINT num) const { HANDLE findHandle = NULL; DWORD charCount = MAX_PATH+1; WCHAR volumeName[MAX_PATH+1]; WCHAR deviceName[MAX_PATH+1]; DWORD index = 0; UINT result = 0; UINT count = 0; findHandle = FindFirstVolume(volumeName, ARRAYSIZE(volumeName)); if(INVALID_HANDLE_VALUE==findHandle) return 0; while(TRUE) { index = wcslen(volumeName)-1; volumeName[index] = L'\0'; result = QueryDosDevice(&volumeName[4], deviceName, ARRAYSIZE(deviceName)); volumeName[index] = L'\\'; if(ERROR_INSUFFICIENT_BUFFER==result || 0==result) { result = 0; break; } result = retrieveDevName(deviceName); if(!result) { size_t temp = wcslen(volumePathName); if(volumePathName[temp]==L'\0') result=1; break; } result = GetVolumePathNamesForVolumeName(volumeName, volumePathName, charCount, &charCount); if(result) { if(count++==num) { size_t temp = wcslen(volumePathName); if(volumePathName[temp]==L'\0') result=1; break; } result = FindNextVolume(findHandle, volumeName, ARRAYSIZE(volumeName)); } } FindVolumeClose(findHandle); findHandle = INVALID_HANDLE_VALUE; return result; }
int dc_next_volume(vol_inf *info) { wchar_t name[MAX_PATH]; FindNextVolume( info->find, name, sizeof_w(name)); if (GetLastError() != ERROR_NO_MORE_FILES) { if (dc_get_vol_info(name, info) != ST_OK) { return dc_next_volume(info); } else { return ST_OK; } } else { FindVolumeClose(info->find); } return ST_ERROR; }
/* * Return the first GUID volume name for the associated drive or NULL if not found * See http://msdn.microsoft.com/en-us/library/cc542456.aspx * The returned string is allocated and must be freed */ char* GetLogicalName(DWORD DriveIndex, BOOL bKeepTrailingBackslash, BOOL bSilent) { BOOL success = FALSE; char volume_name[MAX_PATH]; HANDLE hDrive = INVALID_HANDLE_VALUE, hVolume = INVALID_HANDLE_VALUE; size_t len; char path[MAX_PATH]; VOLUME_DISK_EXTENTS DiskExtents; DWORD size; UINT drive_type; int i, j; static const char* ignore_device[] = { "\\Device\\CdRom", "\\Device\\Floppy" }; static const char* volume_start = "\\\\?\\"; CheckDriveIndex(DriveIndex); for (i=0; hDrive == INVALID_HANDLE_VALUE; i++) { if (i == 0) { hVolume = FindFirstVolumeA(volume_name, sizeof(volume_name)); if (hVolume == INVALID_HANDLE_VALUE) { suprintf("Could not access first GUID volume: %s\n", WindowsErrorString()); goto out; } } else { if (!FindNextVolumeA(hVolume, volume_name, sizeof(volume_name))) { if (GetLastError() != ERROR_NO_MORE_FILES) { suprintf("Could not access next GUID volume: %s\n", WindowsErrorString()); } goto out; } } // Sanity checks len = safe_strlen(volume_name); if ((len <= 1) || (safe_strnicmp(volume_name, volume_start, 4) != 0) || (volume_name[len-1] != '\\')) { suprintf("'%s' is not a GUID volume name\n", volume_name); continue; } drive_type = GetDriveTypeA(volume_name); if ((drive_type != DRIVE_REMOVABLE) && (drive_type != DRIVE_FIXED)) continue; volume_name[len-1] = 0; if (QueryDosDeviceA(&volume_name[4], path, sizeof(path)) == 0) { suprintf("Failed to get device path for GUID volume '%s': %s\n", volume_name, WindowsErrorString()); continue; } for (j=0; (j<ARRAYSIZE(ignore_device)) && (_strnicmp(path, ignore_device[j], safe_strlen(ignore_device[j])) != 0); j++); if (j < ARRAYSIZE(ignore_device)) { suprintf("Skipping GUID volume for '%s'\n", path); continue; } // If we can't have FILE_SHARE_WRITE, forget it hDrive = CreateFileA(volume_name, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hDrive == INVALID_HANDLE_VALUE) { suprintf("Could not open GUID volume '%s': %s\n", volume_name, WindowsErrorString()); continue; } if ((!DeviceIoControl(hDrive, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, NULL, 0, &DiskExtents, sizeof(DiskExtents), &size, NULL)) || (size <= 0)) { suprintf("Could not get Disk Extents: %s\n", WindowsErrorString()); safe_closehandle(hDrive); continue; } safe_closehandle(hDrive); if ((DiskExtents.NumberOfDiskExtents >= 1) && (DiskExtents.Extents[0].DiskNumber == DriveIndex)) { if (bKeepTrailingBackslash) volume_name[len-1] = '\\'; success = TRUE; break; } } out: if (hVolume != INVALID_HANDLE_VALUE) FindVolumeClose(hVolume); return (success)?safe_strdup(volume_name):NULL; }
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(); }
// This does the same as GetVolumePathNamesForVolumeNameW() on Windows XP and // later. It is built into 32 bit versions of this library to make sure that // the DLL can load correctly on Windows 2000 as well. BOOL WINAPI ImScsiLegacyGetVolumePathNamesForVolumeName( __in LPCWSTR lpszVolumeName, __out LPWSTR lpszVolumePathNames, __in DWORD cchBufferLength, __out PDWORD lpcchReturnLength) { *lpcchReturnLength = 0; DWORD dw; dw; LPWSTR cur_ptr = lpszVolumePathNames; LPWSTR end_ptr = lpszVolumePathNames + cchBufferLength; WCHAR vol_target[MAX_PATH]; wcsncpy(vol_target, lpszVolumeName + 4, 44); vol_target[44] = 0; if (!QueryDosDevice(vol_target, vol_target, _countof(vol_target))) { return FALSE; } WHeapMem<WCHAR> dosdevs(UNICODE_STRING_MAX_BYTES, HEAP_GENERATE_EXCEPTIONS); if (!QueryDosDevice(NULL, dosdevs, (DWORD)dosdevs.Count())) { return FALSE; } DWORD good = cchBufferLength >= 2; *lpcchReturnLength = 2; WCHAR dev_target[MAX_PATH]; SIZE_T length; for (LPCWSTR ptr = dosdevs; (length = wcslen(ptr)) != 0; ptr += length + 1) { if (good) { *cur_ptr = 0; } if ((length != 2) || (ptr[1] != L':') || (!QueryDosDevice(ptr, dev_target, _countof(dev_target))) || (_wcsicmp(dev_target, vol_target) != 0)) { continue; } *lpcchReturnLength += 4; if ((cur_ptr + 4) >= end_ptr) { good = FALSE; } if (good) { swprintf(cur_ptr, L"%ws\\", ptr); cur_ptr += 4; } } WCHAR vol_name[50]; HANDLE volume = FindFirstVolume(vol_name, _countof(vol_name)); if (volume == INVALID_HANDLE_VALUE) { return FALSE; } DWORD error_mode = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX); do { HANDLE vol_mnt = FindFirstVolumeMountPoint(vol_name, dosdevs, (DWORD)dosdevs.Count()); if (vol_mnt == INVALID_HANDLE_VALUE) { continue; } do { WMem<WCHAR> mnt_path; mnt_path = ImDiskAllocPrintF(L"%1!ws!%2!ws!", vol_name, dosdevs); if (!mnt_path) { continue; } WCHAR mnt_vol_name[50]; if (!GetVolumeNameForVolumeMountPoint(mnt_path, mnt_vol_name, _countof(mnt_vol_name))) { continue; } if (_wcsicmp(mnt_vol_name, lpszVolumeName) == 0) { if (ImScsiLegacyGetVolumePathNamesForVolumeName(vol_name, vol_target, _countof(vol_target), &dw)) { mnt_path = ImDiskAllocPrintF(L"%1!ws!%2!ws!", vol_target, dosdevs); } size_t len = wcslen(mnt_path) + 1; *lpcchReturnLength += (DWORD)len; if ((cur_ptr + len) >= end_ptr) { good = FALSE; } if (good) { wcscpy(cur_ptr, mnt_path); cur_ptr += len; } } } while (FindNextVolumeMountPoint(vol_mnt, dosdevs, (DWORD)dosdevs.Count())); FindVolumeMountPointClose(vol_mnt); } while (FindNextVolume(volume, vol_name, _countof(vol_name))); FindVolumeClose(volume); SetErrorMode(error_mode); if (cur_ptr >= end_ptr) { good = FALSE; } if (good) { *cur_ptr = 0; ++*lpcchReturnLength; } else { SetLastError(ERROR_MORE_DATA); } return good; }
/* * 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); }
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); }
~VolumeEnum( ) { if ( h_enum != INVALID_HANDLE_VALUE ) { FindVolumeClose( h_enum ); } }
void g_scan_drives (DWORD mask) { //pfc::hires_timer timer; //timer.start(); //profiler(scandrives); #if 0 { TCHAR volume[128], mount[512]; memset(volume, 0, sizeof(volume)); HANDLE vol = FindFirstVolume(volume, tabsize(volume)-1); if (vol != INVALID_HANDLE_VALUE) { do { console::formatter() << "Volume: " << pfc::stringcvt::string_utf8_from_wide(volume, 128); memset(mount, 0, sizeof(mount)); HANDLE hmount = FindFirstVolumeMountPoint(volume, mount, tabsize(mount)-1); if (hmount != INVALID_HANDLE_VALUE) { do { console::formatter() << "mountpoint: " << pfc::stringcvt::string_utf8_from_wide(mount, tabsize(mount)); memset(mount, 0, sizeof(mount)); } while (FindNextVolumeMountPoint(hmount, mount, tabsize(mount)-1) || GetLastError() != ERROR_NO_MORE_FILES); FindVolumeMountPointClose(hmount); } memset(volume, 0, sizeof(volume)); } while (FindNextVolume(vol, volume, tabsize(volume)-1) || GetLastError() != ERROR_NO_MORE_FILES); FindVolumeClose(vol); } } #endif if (mask) { t_volumes volumes; build_volumes_v2(volumes); t_size i =0; for (i=0; i<32; i++) { if (mask & 1<<i) { pfc::string8 drive; drive.add_byte('A'+i); pfc::array_t<WCHAR> path, itunesdb_path; path.append_single('A'+i); path.append_fromptr(L":\\", 3); { WCHAR volumename[129]; memset(volumename, 0, sizeof(volumename)); if (GetDriveType(path.get_ptr()) == DRIVE_REMOVABLE && GetVolumeNameForVolumeMountPoint(path.get_ptr(), volumename, 128)) { t_size indexvol; //if (volumes.find(volumename, 128, indexvol)) { //FIXME WTF if (volumes.find(volumename, 128, indexvol) /*&& g_check_devid_is_ipod(volumes[indexvol].disk_device_id)*/) { ipod_device_ptr_t temp = new ipod_device_t('A' + i, volumes[indexvol].model, volumes[indexvol].shuffle, volumes[indexvol].disk_device_id.get_ptr(), volumes[indexvol].volume_name.get_ptr(), volumes[indexvol].driver_symbolic_path.get_ptr(), volumes[indexvol].instance, device_properties_t()); pfc::string8 pl; try { g_get_device_xml(temp, pl); #if 0//_DEBUG { file::ptr f; abort_callback_dummy noabort; filesystem::g_open_read(f, "i:\\nano6g.plist", noabort); pfc::array_staticsize_t<char> d(pfc::downcast_guarded<t_uint32>(f->get_size_ex(noabort))); f->read(d.get_ptr(), d.get_size(), noabort); pl.set_string(d.get_ptr(), d.get_size()); } #endif g_get_artwork_info(pl, temp->m_device_properties); } catch (const pfc::exception & ex) { console::formatter() << "iPod manager: Failed to get iPod checkpoint data - " << ex.what() << ". Artwork functionality will be unavailable."; temp->m_device_properties.m_artwork_formats.remove_all(); }; //console::formatter() << "New iPod detected. Drive: " << drive << " Device Instance ID: " << pfc::stringcvt::string_utf8_from_wide(volumes[indexvol].disk_device_id); if (m_abort) g_drive_manager.add_drive(temp, *m_abort); else g_drive_manager.add_drive(temp, abort_callback_dummy()); } //else // console::formatter() << "New drive detected. Drive: " << drive << " Device Instance ID: " << pfc::stringcvt::string_utf8_from_wide(volumes[indexvol].disk_device_id);// << " Volume ID: " << pfc::stringcvt::string_utf8_from_wide(volumes[indexvol].volume_name); } } //else // console::formatter() << "Drive is not expected type or GetVolumeNameForVolumeMountPoint failed. Drive: " << drive; } } } } //console::formatter() << "old:" << timer.query(); }