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; }
/* * Mount the volume identified by drive_guid to mountpoint drive_name */ BOOL MountVolume(char* drive_name, char *drive_guid) { char mounted_guid[52]; // You need at least 51 characters on XP if (!SetVolumeMountPointA(drive_name, drive_guid)) { // If the OS was faster than us at remounting the drive, this operation can fail // with ERROR_DIR_NOT_EMPTY. If that's the case, just check that mountpoints match if (GetLastError() == ERROR_DIR_NOT_EMPTY) { if (!GetVolumeNameForVolumeMountPointA(drive_name, mounted_guid, sizeof(mounted_guid))) { uprintf("%s already mounted, but volume GUID could not be checked: %s\n", drive_name, WindowsErrorString()); return FALSE; } if (safe_strcmp(drive_guid, mounted_guid) != 0) { uprintf("%s already mounted, but volume GUID doesn't match:\r\n expected %s, got %s\n", drive_name, drive_guid, mounted_guid); return FALSE; } uprintf("%s was already mounted as %s\n", drive_guid, drive_name); } else { return FALSE; } } return TRUE; }
void PrintDirectoryReparsePoint(const char *path) { int size = strlen(path) + 2; char *directory = (char *) malloc(size); strcpy_s(directory, size, path); NormalizeSlashes(directory, '\\'); if (directory[strlen(directory) - 1] != '\\') strcat_s(directory, size, "\\"); char volumeName[_MAX_PATH]; int rc = GetVolumeNameForVolumeMountPointA(directory, volumeName, sizeof(volumeName)); if (rc) { char volumePathNames[_MAX_PATH]; DWORD returnLength; rc = GetVolumePathNamesForVolumeNameA(volumeName, volumePathNames, sizeof(volumePathNames), &returnLength); if (rc) { char *p = volumePathNames; while (*p) { if (_stricmp(p, directory)) // if it's not the path we've already found { NormalizeSlashes(directory, '/'); NormalizeSlashes(p, '/'); puts(directory); puts(p); } p += strlen(p) + 1; } } } free(directory); }
/* * Mount the volume identified by drive_guid to mountpoint drive_name */ BOOL MountVolume(char* drive_name, char *drive_guid) { char mounted_guid[52]; // You need at least 51 characters on XP char mounted_letter[16] = {0}; DWORD size; if (drive_name[0] == '?') return FALSE; // For fixed disks, Windows may already have remounted the volume, but with a different letter // than the one we want. If that's the case, we need to unmount first. if ( (GetVolumePathNamesForVolumeNameA(drive_guid, mounted_letter, sizeof(mounted_letter), &size)) && (size > 1) && (mounted_letter[0] != drive_name[0]) ) { uprintf("Volume is already mounted, but as %c: instead of %c: - Unmounting...\n", mounted_letter[0], drive_name[0]); if (!DeleteVolumeMountPointA(mounted_letter)) uprintf("Failed to unmount volume: %s", WindowsErrorString()); // Also delete the destination mountpoint if needed (Don't care about errors) DeleteVolumeMountPointA(drive_name); Sleep(200); } if (!SetVolumeMountPointA(drive_name, drive_guid)) { // If the OS was faster than us at remounting the drive, this operation can fail // with ERROR_DIR_NOT_EMPTY. If that's the case, just check that mountpoints match if (GetLastError() == ERROR_DIR_NOT_EMPTY) { if (!GetVolumeNameForVolumeMountPointA(drive_name, mounted_guid, sizeof(mounted_guid))) { uprintf("%s already mounted, but volume GUID could not be checked: %s\n", drive_name, WindowsErrorString()); return FALSE; } if (safe_strcmp(drive_guid, mounted_guid) != 0) { uprintf("%s already mounted, but volume GUID doesn't match:\r\n expected %s, got %s\n", drive_name, drive_guid, mounted_guid); return FALSE; } uprintf("%s was already mounted as %s\n", drive_guid, drive_name); } else { return FALSE; } } return TRUE; }
/* * Issue a complete remount of the volume */ BOOL RemountVolume(char* drive_name) { char drive_guid[51]; // UDF requires a sync/flush, and it's also a good idea for other FS's FlushDrive(drive_name[0]); if (GetVolumeNameForVolumeMountPointA(drive_name, drive_guid, sizeof(drive_guid))) { if (DeleteVolumeMountPointA(drive_name)) { Sleep(200); if (MountVolume(drive_name, drive_guid)) { uprintf("Successfully remounted %s on %s\n", &drive_guid[4], drive_name); } else { uprintf("Failed to remount %s on %s\n", &drive_guid[4], drive_name); // This will leave the drive inaccessible and must be flagged as an error FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_REMOUNT_VOLUME); return FALSE; } } else { uprintf("Could not remount %s %s\n", drive_name, WindowsErrorString()); // Try to continue regardless } } return TRUE; }