void SysMountVolume(const char *name) { file_handle *fh; for (fh=first_file_handle; fh && strcmp(fh->name, name); fh=fh->next) ; if (fh) MountVolume(fh); }
/* MountVolTemp Mounts a trucrypt volume temporarily (using any free drive number) Parameters: hwndDlg : HWND [in] handle to parent window volumePath : char * [in] Pointer to a string that contains the volume path driveNo : int * [out] returns the drive number (0='A',...) password : Password * [in] Pointer to the volume password Return value: int with Truecrypt error code (ERR_SUCCESS on success) */ int MountVolTemp (HWND hwndDlg, wchar_t *volumePath, int *driveNo, Password *password, int pkcs5, int pim) { MountOptions mountOptions; ZeroMemory (&mountOptions, sizeof (mountOptions)); *driveNo = GetLastAvailableDrive (); if (*driveNo == -1) { *driveNo = -2; return ERR_NO_FREE_DRIVES; } mountOptions.ReadOnly = FALSE; mountOptions.Removable = ConfigReadInt ("MountVolumesRemovable", FALSE); mountOptions.ProtectHiddenVolume = FALSE; mountOptions.PreserveTimestamp = bPreserveTimestamp; mountOptions.PartitionInInactiveSysEncScope = FALSE; mountOptions.UseBackupHeader = FALSE; if (MountVolume (hwndDlg, *driveNo, volumePath, password, pkcs5, pim, FALSE, FALSE, FALSE, TRUE, &mountOptions, FALSE, FALSE) < 1) { *driveNo = -3; return ERR_VOL_MOUNT_FAILED; } return 0; }
/* * 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; }
void SysMediaArrived(const char *path, int type) { // Replace the "cdrom" entry (we are polling, it's unique) if (type == MEDIA_CD && !PrefsFindBool("nocdrom")) PrefsReplaceString("cdrom", path); // Wait for media to be available for reading if (open_su_file_handles) { const int MAX_WAIT = 5; for (int i = 0; i < MAX_WAIT; i++) { if (access(path, R_OK) == 0) break; switch (errno) { case ENOENT: // Unlikely case EACCES: // MacOS X is mounting the media sleep(1); continue; } printf("WARNING: Cannot access %s (%s)\n", path, strerror(errno)); return; } } for (open_su_file_handle *p = open_su_file_handles; p != NULL; p = p->next) { su_file_handle * const fh = p->fh; // Re-open CD-ROM device if (fh->is_cdrom && type == MEDIA_CD) { cdrom_close(fh); if (cdrom_open(fh, path)) { fh->is_media_present = true; MountVolume(fh); } } } }
int TCFormatVolume (volatile FORMAT_VOL_PARAMETERS *volParams) { int nStatus; PCRYPTO_INFO cryptoInfo = NULL; HANDLE dev = INVALID_HANDLE_VALUE; DWORD dwError; char header[TC_VOLUME_HEADER_EFFECTIVE_SIZE]; unsigned __int64 num_sectors, startSector; fatparams ft; FILETIME ftCreationTime; FILETIME ftLastWriteTime; FILETIME ftLastAccessTime; BOOL bTimeStampValid = FALSE; BOOL bInstantRetryOtherFilesys = FALSE; char dosDev[TC_MAX_PATH] = { 0 }; char devName[MAX_PATH] = { 0 }; int driveLetter = -1; WCHAR deviceName[MAX_PATH]; uint64 dataOffset, dataAreaSize; LARGE_INTEGER offset; BOOL bFailedRequiredDASD = FALSE; HWND hwndDlg = volParams->hwndDlg; FormatSectorSize = volParams->sectorSize; if (FormatSectorSize < TC_MIN_VOLUME_SECTOR_SIZE || FormatSectorSize > TC_MAX_VOLUME_SECTOR_SIZE || FormatSectorSize % ENCRYPTION_DATA_UNIT_SIZE != 0) { Error ("SECTOR_SIZE_UNSUPPORTED", hwndDlg); return ERR_DONT_REPORT; } /* WARNING: Note that if Windows fails to format the volume as NTFS and the volume size is less than the maximum FAT size, the user is asked within this function whether he wants to instantly retry FAT format instead (to avoid having to re-create the whole container again). If the user answers yes, some of the input parameters are modified, the code below 'begin_format' is re-executed and some destructive operations that were performed during the first attempt must be (and are) skipped. Therefore, whenever adding or modifying any potentially destructive operations below 'begin_format', determine whether they (or their portions) need to be skipped during such a second attempt; if so, use the 'bInstantRetryOtherFilesys' flag to skip them. */ if (volParams->hiddenVol) { dataOffset = volParams->hiddenVolHostSize - TC_VOLUME_HEADER_GROUP_SIZE - volParams->size; } else { if (volParams->size <= TC_TOTAL_VOLUME_HEADERS_SIZE) return ERR_VOL_SIZE_WRONG; dataOffset = TC_VOLUME_DATA_OFFSET; } dataAreaSize = GetVolumeDataAreaSize (volParams->hiddenVol, volParams->size); num_sectors = dataAreaSize / FormatSectorSize; if (volParams->bDevice) { StringCbCopyA ((char *)deviceName, sizeof(deviceName), volParams->volumePath); ToUNICODE ((char *)deviceName, sizeof(deviceName)); driveLetter = GetDiskDeviceDriveLetter (deviceName); } VirtualLock (header, sizeof (header)); nStatus = CreateVolumeHeaderInMemory (hwndDlg, FALSE, header, volParams->ea, FIRST_MODE_OF_OPERATION_ID, volParams->password, volParams->pkcs5, volParams->pim, NULL, &cryptoInfo, dataAreaSize, volParams->hiddenVol ? dataAreaSize : 0, dataOffset, dataAreaSize, 0, volParams->headerFlags, FormatSectorSize, FALSE); if (nStatus != 0) { burn (header, sizeof (header)); VirtualUnlock (header, sizeof (header)); return nStatus; } begin_format: if (volParams->bDevice) { /* Device-hosted volume */ DWORD dwResult; int nPass; if (FakeDosNameForDevice (volParams->volumePath, dosDev, sizeof(dosDev), devName, sizeof(devName), FALSE) != 0) return ERR_OS_ERROR; if (IsDeviceMounted (devName)) { if ((dev = DismountDrive (devName, volParams->volumePath)) == INVALID_HANDLE_VALUE) { Error ("FORMAT_CANT_DISMOUNT_FILESYS", hwndDlg); nStatus = ERR_DONT_REPORT; goto error; } /* Gain "raw" access to the partition (it contains a live filesystem and the filesystem driver would otherwise prevent us from writing to hidden sectors). */ if (!DeviceIoControl (dev, FSCTL_ALLOW_EXTENDED_DASD_IO, NULL, 0, NULL, 0, &dwResult, NULL)) { bFailedRequiredDASD = TRUE; } } else if (IsOSAtLeast (WIN_VISTA) && driveLetter == -1) { // Windows Vista doesn't allow overwriting sectors belonging to an unformatted partition // to which no drive letter has been assigned under the system. This problem can be worked // around by assigning a drive letter to the partition temporarily. char szDriveLetter[] = { 'A', ':', 0 }; char rootPath[] = { 'A', ':', '\\', 0 }; char uniqVolName[MAX_PATH+1] = { 0 }; int tmpDriveLetter = -1; BOOL bResult = FALSE; tmpDriveLetter = GetFirstAvailableDrive (); if (tmpDriveLetter != -1) { rootPath[0] += (char) tmpDriveLetter; szDriveLetter[0] += (char) tmpDriveLetter; if (DefineDosDevice (DDD_RAW_TARGET_PATH, szDriveLetter, volParams->volumePath)) { bResult = GetVolumeNameForVolumeMountPoint (rootPath, uniqVolName, MAX_PATH); DefineDosDevice (DDD_RAW_TARGET_PATH|DDD_REMOVE_DEFINITION|DDD_EXACT_MATCH_ON_REMOVE, szDriveLetter, volParams->volumePath); if (bResult && SetVolumeMountPoint (rootPath, uniqVolName)) { // The drive letter can be removed now DeleteVolumeMountPoint (rootPath); } } } } // For extra safety, we will try to gain "raw" access to the partition. Note that this should actually be // redundant because if the filesystem was mounted, we already tried to obtain DASD above. If we failed, // bFailedRequiredDASD was set to TRUE and therefore we will perform pseudo "quick format" below. However, // for extra safety, in case IsDeviceMounted() failed to detect a live filesystem, we will blindly // send FSCTL_ALLOW_EXTENDED_DASD_IO (possibly for a second time) without checking the result. DeviceIoControl (dev, FSCTL_ALLOW_EXTENDED_DASD_IO, NULL, 0, NULL, 0, &dwResult, NULL); // If DASD is needed but we failed to obtain it, perform open - 'quick format' - close - open // so that the filesystem driver does not prevent us from formatting hidden sectors. for (nPass = (bFailedRequiredDASD ? 0 : 1); nPass < 2; nPass++) { int retryCount; retryCount = 0; // Try exclusive access mode first // Note that when exclusive access is denied, it is worth retrying (usually succeeds after a few tries). while (dev == INVALID_HANDLE_VALUE && retryCount++ < EXCL_ACCESS_MAX_AUTO_RETRIES) { dev = CreateFile (devName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); if (retryCount > 1) Sleep (EXCL_ACCESS_AUTO_RETRY_DELAY); } if (dev == INVALID_HANDLE_VALUE) { // Exclusive access denied -- retry in shared mode dev = CreateFile (devName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (dev != INVALID_HANDLE_VALUE) { if (!volParams->bForceOperation && (Silent || (IDNO == MessageBoxW (volParams->hwndDlg, GetString ("DEVICE_IN_USE_FORMAT"), lpszTitle, MB_YESNO|MB_ICONWARNING|MB_DEFBUTTON2)))) { nStatus = ERR_DONT_REPORT; goto error; } } else { handleWin32Error (volParams->hwndDlg, SRC_POS); Error ("CANT_ACCESS_VOL", hwndDlg); nStatus = ERR_DONT_REPORT; goto error; } } if (volParams->hiddenVol || bInstantRetryOtherFilesys) break; // The following "quick format" operation would damage the outer volume if (nPass == 0) { char buf [2 * TC_MAX_VOLUME_SECTOR_SIZE]; DWORD bw; // Perform pseudo "quick format" so that the filesystem driver does not prevent us from // formatting hidden sectors memset (buf, 0, sizeof (buf)); if (!WriteFile (dev, buf, sizeof (buf), &bw, NULL)) { nStatus = ERR_OS_ERROR; goto error; } FlushFileBuffers (dev); CloseHandle (dev); dev = INVALID_HANDLE_VALUE; } } if (DeviceIoControl (dev, FSCTL_IS_VOLUME_MOUNTED, NULL, 0, NULL, 0, &dwResult, NULL)) { Error ("FORMAT_CANT_DISMOUNT_FILESYS", hwndDlg); nStatus = ERR_DONT_REPORT; goto error; } } else { /* File-hosted volume */ dev = CreateFile (volParams->volumePath, GENERIC_READ | GENERIC_WRITE, (volParams->hiddenVol || bInstantRetryOtherFilesys) ? (FILE_SHARE_READ | FILE_SHARE_WRITE) : 0, NULL, (volParams->hiddenVol || bInstantRetryOtherFilesys) ? OPEN_EXISTING : CREATE_ALWAYS, 0, NULL); if (dev == INVALID_HANDLE_VALUE) { nStatus = ERR_OS_ERROR; goto error; } DisableFileCompression (dev); if (!volParams->hiddenVol && !bInstantRetryOtherFilesys) { LARGE_INTEGER volumeSize; volumeSize.QuadPart = dataAreaSize + TC_VOLUME_HEADER_GROUP_SIZE; if (volParams->sparseFileSwitch && volParams->quickFormat) { // Create as sparse file container DWORD tmp; if (!DeviceIoControl (dev, FSCTL_SET_SPARSE, NULL, 0, NULL, 0, &tmp, NULL)) { nStatus = ERR_OS_ERROR; goto error; } } // Preallocate the file if (!SetFilePointerEx (dev, volumeSize, NULL, FILE_BEGIN) || !SetEndOfFile (dev) || SetFilePointer (dev, 0, NULL, FILE_BEGIN) != 0) { nStatus = ERR_OS_ERROR; goto error; } } } if (volParams->hiddenVol && !volParams->bDevice && bPreserveTimestamp) { if (GetFileTime ((HANDLE) dev, &ftCreationTime, &ftLastAccessTime, &ftLastWriteTime) == 0) bTimeStampValid = FALSE; else bTimeStampValid = TRUE; } if (volParams->hwndDlg && volParams->bGuiMode) KillTimer (volParams->hwndDlg, TIMER_ID_RANDVIEW); /* Volume header */ // Hidden volume setup if (volParams->hiddenVol) { LARGE_INTEGER headerOffset; // Check hidden volume size if (volParams->hiddenVolHostSize < TC_MIN_HIDDEN_VOLUME_HOST_SIZE || volParams->hiddenVolHostSize > TC_MAX_HIDDEN_VOLUME_HOST_SIZE) { nStatus = ERR_VOL_SIZE_WRONG; goto error; } // Seek to hidden volume header location headerOffset.QuadPart = TC_HIDDEN_VOLUME_HEADER_OFFSET; if (!SetFilePointerEx ((HANDLE) dev, headerOffset, NULL, FILE_BEGIN)) { nStatus = ERR_OS_ERROR; goto error; } } else if (bInstantRetryOtherFilesys) { // The previous file system format failed and the user wants to try again with a different file system. // The volume header had been written successfully so we need to seek to the byte after the header. LARGE_INTEGER offset; offset.QuadPart = TC_VOLUME_DATA_OFFSET; if (!SetFilePointerEx ((HANDLE) dev, offset, NULL, FILE_BEGIN)) { nStatus = ERR_OS_ERROR; goto error; } } if (!bInstantRetryOtherFilesys) { // Write the volume header if (!WriteEffectiveVolumeHeader (volParams->bDevice, dev, header)) { nStatus = ERR_OS_ERROR; goto error; } // To prevent fragmentation, write zeroes to reserved header sectors which are going to be filled with random data if (!volParams->bDevice && !volParams->hiddenVol) { byte buf[TC_VOLUME_HEADER_GROUP_SIZE - TC_VOLUME_HEADER_EFFECTIVE_SIZE]; DWORD bytesWritten; ZeroMemory (buf, sizeof (buf)); if (!WriteFile (dev, buf, sizeof (buf), &bytesWritten, NULL)) { nStatus = ERR_OS_ERROR; goto error; } if (bytesWritten != sizeof (buf)) { nStatus = ERR_PARAMETER_INCORRECT; goto error; } } } if (volParams->hiddenVol) { // Calculate data area position of hidden volume cryptoInfo->hiddenVolumeOffset = dataOffset; // Validate the offset if (dataOffset % FormatSectorSize != 0) { nStatus = ERR_VOL_SIZE_WRONG; goto error; } volParams->quickFormat = TRUE; // To entirely format a hidden volume would be redundant } /* Data area */ startSector = dataOffset / FormatSectorSize; // Format filesystem switch (volParams->fileSystem) { case FILESYS_NONE: case FILESYS_NTFS: if (volParams->bDevice && !StartFormatWriteThread()) { nStatus = ERR_OS_ERROR; goto error; } nStatus = FormatNoFs (hwndDlg, startSector, num_sectors, dev, cryptoInfo, volParams->quickFormat); if (volParams->bDevice) StopFormatWriteThread(); break; case FILESYS_FAT: if (num_sectors > 0xFFFFffff) { nStatus = ERR_VOL_SIZE_WRONG; goto error; } // Calculate the fats, root dir etc ft.num_sectors = (unsigned int) (num_sectors); #if TC_MAX_VOLUME_SECTOR_SIZE > 0xFFFF #error TC_MAX_VOLUME_SECTOR_SIZE > 0xFFFF #endif ft.sector_size = (uint16) FormatSectorSize; ft.cluster_size = volParams->clusterSize; memcpy (ft.volume_name, "NO NAME ", 11); GetFatParams (&ft); *(volParams->realClusterSize) = ft.cluster_size * FormatSectorSize; if (volParams->bDevice && !StartFormatWriteThread()) { nStatus = ERR_OS_ERROR; goto error; } nStatus = FormatFat (hwndDlg, startSector, &ft, (void *) dev, cryptoInfo, volParams->quickFormat); if (volParams->bDevice) StopFormatWriteThread(); break; default: nStatus = ERR_PARAMETER_INCORRECT; goto error; } if (nStatus != ERR_SUCCESS) goto error; // Write header backup offset.QuadPart = volParams->hiddenVol ? volParams->hiddenVolHostSize - TC_HIDDEN_VOLUME_HEADER_OFFSET : dataAreaSize + TC_VOLUME_HEADER_GROUP_SIZE; if (!SetFilePointerEx ((HANDLE) dev, offset, NULL, FILE_BEGIN)) { nStatus = ERR_OS_ERROR; goto error; } nStatus = CreateVolumeHeaderInMemory (hwndDlg, FALSE, header, volParams->ea, FIRST_MODE_OF_OPERATION_ID, volParams->password, volParams->pkcs5, volParams->pim, cryptoInfo->master_keydata, &cryptoInfo, dataAreaSize, volParams->hiddenVol ? dataAreaSize : 0, dataOffset, dataAreaSize, 0, volParams->headerFlags, FormatSectorSize, FALSE); if (!WriteEffectiveVolumeHeader (volParams->bDevice, dev, header)) { nStatus = ERR_OS_ERROR; goto error; } // Fill reserved header sectors (including the backup header area) with random data if (!volParams->hiddenVol) { nStatus = WriteRandomDataToReservedHeaderAreas (hwndDlg, dev, cryptoInfo, dataAreaSize, FALSE, FALSE); if (nStatus != ERR_SUCCESS) goto error; } #ifndef DEBUG if (volParams->quickFormat && volParams->fileSystem != FILESYS_NTFS) Sleep (500); // User-friendly GUI #endif error: dwError = GetLastError(); burn (header, sizeof (header)); VirtualUnlock (header, sizeof (header)); if (dev != INVALID_HANDLE_VALUE) { if (!volParams->bDevice && !volParams->hiddenVol && nStatus != 0) { // Remove preallocated part before closing file handle if format failed if (SetFilePointer (dev, 0, NULL, FILE_BEGIN) == 0) SetEndOfFile (dev); } FlushFileBuffers (dev); if (bTimeStampValid) SetFileTime (dev, &ftCreationTime, &ftLastAccessTime, &ftLastWriteTime); CloseHandle (dev); dev = INVALID_HANDLE_VALUE; } if (nStatus != 0) { SetLastError(dwError); goto fv_end; } if (volParams->fileSystem == FILESYS_NTFS) { // Quick-format volume as NTFS int driveNo = GetLastAvailableDrive (); MountOptions mountOptions; int retCode; ZeroMemory (&mountOptions, sizeof (mountOptions)); if (driveNo == -1) { if (!Silent) { MessageBoxW (volParams->hwndDlg, GetString ("NO_FREE_DRIVES"), lpszTitle, ICON_HAND); MessageBoxW (volParams->hwndDlg, GetString ("FORMAT_NTFS_STOP"), lpszTitle, ICON_HAND); } nStatus = ERR_NO_FREE_DRIVES; goto fv_end; } mountOptions.ReadOnly = FALSE; mountOptions.Removable = FALSE; mountOptions.ProtectHiddenVolume = FALSE; mountOptions.PreserveTimestamp = bPreserveTimestamp; mountOptions.PartitionInInactiveSysEncScope = FALSE; mountOptions.UseBackupHeader = FALSE; if (MountVolume (volParams->hwndDlg, driveNo, volParams->volumePath, volParams->password, volParams->pkcs5, volParams->pim, FALSE, FALSE, TRUE, &mountOptions, FALSE, TRUE) < 1) { if (!Silent) { MessageBoxW (volParams->hwndDlg, GetString ("CANT_MOUNT_VOLUME"), lpszTitle, ICON_HAND); MessageBoxW (volParams->hwndDlg, GetString ("FORMAT_NTFS_STOP"), lpszTitle, ICON_HAND); } nStatus = ERR_VOL_MOUNT_FAILED; goto fv_end; } if (!Silent && !IsAdmin () && IsUacSupported ()) retCode = UacFormatNtfs (volParams->hwndDlg, driveNo, volParams->clusterSize); else retCode = FormatNtfs (driveNo, volParams->clusterSize); if (retCode != TRUE) { if (!UnmountVolumeAfterFormatExCall (volParams->hwndDlg, driveNo) && !Silent) MessageBoxW (volParams->hwndDlg, GetString ("CANT_DISMOUNT_VOLUME"), lpszTitle, ICON_HAND); if (dataAreaSize <= TC_MAX_FAT_SECTOR_COUNT * FormatSectorSize) { if (AskErrYesNo ("FORMAT_NTFS_FAILED_ASK_FAT", hwndDlg) == IDYES) { // NTFS format failed and the user wants to try FAT format immediately volParams->fileSystem = FILESYS_FAT; bInstantRetryOtherFilesys = TRUE; volParams->quickFormat = TRUE; // Volume has already been successfully TC-formatted volParams->clusterSize = 0; // Default cluster size goto begin_format; } } else Error ("FORMAT_NTFS_FAILED", hwndDlg); nStatus = ERR_DONT_REPORT; goto fv_end; } if (!UnmountVolumeAfterFormatExCall (volParams->hwndDlg, driveNo) && !Silent) MessageBoxW (volParams->hwndDlg, GetString ("CANT_DISMOUNT_VOLUME"), lpszTitle, ICON_HAND); } fv_end: dwError = GetLastError(); if (dosDev[0]) RemoveFakeDosName (volParams->volumePath, dosDev); crypto_close (cryptoInfo); SetLastError (dwError); return nStatus; }
/** * Start file open operation, mount volume when needed and according to file type * create file output stream or read directory content. * @return NS_OK when file or directory opened successfully, error code otherwise */ nsresult nsGIOInputStream::DoOpen() { nsresult rv; GError *error = nullptr; NS_ASSERTION(mHandle == nullptr, "already open"); mHandle = g_file_new_for_uri( mSpec.get() ); GFileInfo *info = g_file_query_info(mHandle, "standard::*", G_FILE_QUERY_INFO_NONE, nullptr, &error); if (error) { if (error->domain == G_IO_ERROR && error->code == G_IO_ERROR_NOT_MOUNTED) { // location is not yet mounted, try to mount g_error_free(error); if (NS_IsMainThread()) return NS_ERROR_NOT_CONNECTED; error = nullptr; rv = MountVolume(); if (rv != NS_OK) { return rv; } // get info again info = g_file_query_info(mHandle, "standard::*", G_FILE_QUERY_INFO_NONE, nullptr, &error); // second try to get file info from remote files after media mount if (!info) { g_warning("Unable to get file info: %s", error->message); rv = MapGIOResult(error); g_error_free(error); return rv; } } else { g_warning("Unable to get file info: %s", error->message); rv = MapGIOResult(error); g_error_free(error); return rv; } } // Get file type to handle directories and file differently GFileType f_type = g_file_info_get_file_type(info); if (f_type == G_FILE_TYPE_DIRECTORY) { // directory rv = DoOpenDirectory(); } else if (f_type != G_FILE_TYPE_UNKNOWN) { // file rv = DoOpenFile(info); } else { g_warning("Unable to get file type."); rv = NS_ERROR_FILE_NOT_FOUND; } if (info) g_object_unref(info); return rv; }
void AutoMounter::MessageReceived(BMessage *message) { switch (message->what) { #if _INCLUDES_CLASS_DEVICE_MAP case kAutomounterRescan: RescanDevices(); break; case kStartPolling: // PRINT(("starting the automounter\n")); fScanThread = spawn_thread(AutoMounter::WatchVolumeBinder, #if DEBUG "HiroshiLikesAtomountScan", // long story #else "AutomountScan", #endif B_LOW_PRIORITY, this); resume_thread(fScanThread); break; case kMountVolume: MountVolume(message); break; case kUnmountVolume: UnmountAndEjectVolume(message); break; case kSetAutomounterParams: { bool rescanNow = false; message->FindBool("rescanNow", &rescanNow); SetParams(message, rescanNow); WriteSettings(); break; } case kMountAllNow: RescanDevices(); MountAllNow(); break; case kSuspendAutomounter: SuspendResume(true); break; case kResumeAutomounter: SuspendResume(false); break; case kTryMountingFloppy: TryMountingFloppy(); break; case B_NODE_MONITOR: { int32 opcode; if (message->FindInt32("opcode", &opcode) != B_OK) break; switch (opcode) { case B_DEVICE_MOUNTED: { WRITELOG(("** Received Device Mounted Notification")); dev_t device; if (message->FindInt32("new device", &device) == B_OK) { Partition *partition = FindPartition(device); if (partition == NULL || partition->Mounted() != kMounted) { WRITELOG(("Device %i not in device list. Someone mounted it outside " "of Tracker", device)); // // This is the worst case. Someone has mounted // something from outside of tracker. // Unfortunately, there's no easy way to tell which // partition was just mounted (or if we even know about the device), // so stop watching all nodes, rescan to see what is now mounted, // and start watching again. // RescanDevices(); } else WRITELOG(("Found partition\n")); } else { WRITELOG(("ERROR: Could not find mounted device ID in message")); PRINT_OBJECT(*message); } break; } case B_DEVICE_UNMOUNTED: { WRITELOG(("*** Received Device Unmounted Notification")); dev_t device; if (message->FindInt32("device", &device) == B_OK) { Partition *partition = FindPartition(device); if (partition != 0) { WRITELOG(("Found device in device list. Updating state to unmounted.")); partition->SetMountState(kNotMounted); } else WRITELOG(("Unmounted device %i was not in device list", device)); } else { WRITELOG(("ERROR: Could not find unmounted device ID in message")); PRINT_OBJECT(*message); } break; } // The name of a mount point has changed case B_ENTRY_MOVED: { WRITELOG(("*** Received Mount Point Renamed Notification")); const char *newName; if (message->FindString("name", &newName) != B_OK) { WRITELOG(("ERROR: Couldn't find name field in update message")); PRINT_OBJECT(*message); break ; } // // When the node monitor reports a move, it gives the // parent device and inode that moved. The problem is // that the inode is the inode of root *in* the filesystem, // which is generally always the same number for every // filesystem of a type. // // What we'd really like is the device that the moved // volume is mounted on. Find this by using the // *new* name and directory, and then stat()ing that to // find the device. // dev_t parentDevice; if (message->FindInt32("device", &parentDevice) != B_OK) { WRITELOG(("ERROR: Couldn't find 'device' field in update" " message")); PRINT_OBJECT(*message); break; } ino_t toDirectory; if (message->FindInt64("to directory", &toDirectory)!=B_OK){ WRITELOG(("ERROR: Couldn't find 'to directory' field in update" "message")); PRINT_OBJECT(*message); break; } entry_ref root_entry(parentDevice, toDirectory, newName); BNode entryNode(&root_entry); if (entryNode.InitCheck() != B_OK) { WRITELOG(("ERROR: Couldn't create mount point entry node: %s/n", strerror(entryNode.InitCheck()))); break; } node_ref mountPointNode; if (entryNode.GetNodeRef(&mountPointNode) != B_OK) { WRITELOG(("ERROR: Couldn't get node ref for new mount point")); break; } WRITELOG(("Attempt to rename device %li to %s", mountPointNode.device, newName)); Partition *partition = FindPartition(mountPointNode.device); if (partition != NULL) { WRITELOG(("Found device, changing name.")); BVolume mountVolume(partition->VolumeDeviceID()); BDirectory mountDir; mountVolume.GetRootDirectory(&mountDir); BPath dirPath(&mountDir, 0); partition->SetMountedAt(dirPath.Path()); partition->SetVolumeName(newName); break; } else WRITELOG(("ERROR: Device %li does not appear to be present", mountPointNode.device)); } } } break; #endif default: BLooper::MessageReceived(message); break; } }
void SysMountFirstFloppy(void) { if (first_floppy) MountVolume(first_floppy); }