static void test_define_dos_deviceA(void) { char drivestr[3]; char buf[MAX_PATH]; DWORD ret; /* Find an unused drive letter */ drivestr[1] = ':'; drivestr[2] = 0; for (drivestr[0] = 'a'; drivestr[0] <= 'z'; drivestr[0]++) { ret = QueryDosDeviceA( drivestr, buf, sizeof(buf)); if (!ret) break; } if (drivestr[0] > 'z') { skip("can't test creating a dos drive, none available\n"); return; } /* Map it to point to the current directory */ ret = GetCurrentDirectoryA(sizeof(buf), buf); ok(ret, "GetCurrentDir\n"); ret = DefineDosDeviceA(0, drivestr, buf); todo_wine ok(ret, "Could not make drive %s point to %s!\n", drivestr, buf); if (!ret) { skip("can't test removing fake drive\n"); } else { ret = DefineDosDeviceA(DDD_REMOVE_DEFINITION, drivestr, NULL); ok(ret, "Could not remove fake drive %s!\n", drivestr); } }
filePathLinkA(const string& path) :m_ntType("\\??\\") { if (path.length() > 4 && path.substr(0, 4) == "\\??\\") { m_ntType.append(path.substr(4)); } else { m_ntType.append(path); } static DWORD tick = 0; char tmpBuffer[100]; StringCbPrintfA(tmpBuffer, 100, "%x%x%x%x", GetCurrentThreadId(), GetTickCount(), rand(), ++tick); m_pathDefine = string(FS_BYPASS_DEFINE_PREFIX_A) + tmpBuffer; if (DefineDosDeviceA(DDD_RAW_TARGET_PATH, m_pathDefine.c_str(), m_ntType.c_str())) { m_pathLink = string("\\\\.\\") + FS_BYPASS_DEFINE_PREFIX_A + tmpBuffer; m_transformed = true; } else { m_pathLink = path; m_transformed = false; } }
~filePathLinkA() { if (m_transformed) { DWORD err = GetLastError(); DefineDosDeviceA(DDD_REMOVE_DEFINITION, m_pathDefine.c_str(), m_ntType.c_str()); SetLastError(err); } }
/* * Unmount a volume that was mounted by AltmountVolume() */ BOOL AltUnmountVolume(const char* drive_name) { if (drive_name == NULL) return FALSE; if (!DefineDosDeviceA(DDD_REMOVE_DEFINITION | DDD_NO_BROADCAST_SYSTEM, drive_name, NULL)) { uprintf("Could not unmount '%s': %s", drive_name, WindowsErrorString()); return FALSE; } uprintf("Successfully unmounted '%s'", drive_name); return TRUE; }
/* * Mount partition #part_nr, residing on the same disk as drive_name to an available * drive letter. Returns the newly allocated drive string. * We need to do this because, for instance, EFI System partitions are not assigned * Volume GUIDs by the OS, and we need to have a letter assigned, for when we invoke * bcdtool for Windows To Go. All in all, the process looks like this: * 1. F: = \Device\HarddiskVolume9 (SINGLE LOOKUP) * 2. Harddisk5Partition1 = \Device\HarddiskVolume9 (FULL LOOKUP) * 3. Harddisk5Partition2 = \Device\HarddiskVolume10 (SINGLE LOOKUP) * 4. DefineDosDevice(letter, \Device\HarddiskVolume10) */ char* AltMountVolume(const char* drive_name, uint8_t part_nr) { static char mounted_drive[] = "?:"; const DWORD bufsize = 65536; char *buffer = NULL, *p, target[2][MAX_PATH], *ret = NULL; size_t i; mounted_drive[0] = GetUnusedDriveLetter(); if (mounted_drive[0] == 0) { uprintf("Could not find an unused drive letter"); goto out; } target[0][0] = 0; // Convert our drive letter to something like "\Device\HarddiskVolume9" if (!QueryDosDeviceA(drive_name, target[0], MAX_PATH) || (strlen(target[0]) == 0)) { uprintf("Could not get the DOS volume name for '%s': %s", drive_name, WindowsErrorString()); goto out; } // Now parse the whole DOS device list to find the 'Harddisk#Partition#' that matches the above // TODO: realloc if someone ever manages to burst through 64K of DOS devices buffer = malloc(bufsize); if (buffer == NULL) goto out; buffer[0] = 0; if (!QueryDosDeviceA(NULL, buffer, bufsize)) { uprintf("Could not get the DOS device list: %s", WindowsErrorString()); goto out; } p = buffer; while (strlen(p) != 0) { if ((strncmp("Harddisk", p, 8) == 0) && (strstr(&p[9], "Partition") != NULL)) { target[1][0] = 0; if (QueryDosDeviceA(p, target[1], MAX_PATH) && (strlen(target[1]) != 0)) if ((strcmp(target[1], target[0]) == 0) && (p[1] != ':')) break; } p += strlen(p) + 1; } i = strlen(p); if (i == 0) { uprintf("Could not find partition mapping for %s", target[0]); goto out; } while ((--i > 0) && (isdigit(p[i]))); p[++i] = '0' + part_nr; p[++i] = 0; target[0][0] = 0; if (!QueryDosDeviceA(p, target[0], MAX_PATH) || (strlen(target[0]) == 0)) { uprintf("Could not find the DOS volume name for partition '%s': %s", p, WindowsErrorString()); goto out; } if (!DefineDosDeviceA(DDD_RAW_TARGET_PATH | DDD_NO_BROADCAST_SYSTEM, mounted_drive, target[0])) { uprintf("Could not mount '%s' to '%s': %s", target[0], mounted_drive, WindowsErrorString()); goto out; } uprintf("Successfully mounted '%s' (USB partition %d) as '%s'", target[0], part_nr, mounted_drive); ret = mounted_drive; out: safe_free(buffer); return ret; }