示例#1
0
BOOL EjectVolume( TCHAR cDriveLetter, BOOL reload )
{
   HANDLE hVolume;

   BOOL fRemoveSafely = FALSE;
   BOOL fAutoEject = FALSE;

   // Open the volume.
   hVolume = OpenVolume(cDriveLetter);
   if (hVolume == INVALID_HANDLE_VALUE)
       return FALSE;

   // Lock and dismount the volume.
   if (LockVolume(hVolume) && DismountVolume(hVolume)) {
       fRemoveSafely = TRUE;

       // Set prevent removal to false and eject the volume.
       if (PreventRemovalOfVolume(hVolume, FALSE) &&
           AutoEjectVolume(hVolume,reload))
           fAutoEject = TRUE;
   }

   // Close the volume so other processes can use the drive.
   if (!CloseVolume(hVolume))
       return FALSE;

   /*
	 if (fAutoEject)
       printf("Media in Drive %c has been ejected safely.\n", cDriveLetter);
   else {
       if (fRemoveSafely)
           printf("Media in Drive %c can be safely removed.\n", cDriveLetter);
   }
	 */

   return TRUE;
}
示例#2
0
文件: eject.cpp 项目: alexlav/conemu
/* Функция by Vadim Yegorov <*****@*****.**>
   Доработанная! Умеет "вставлять" диск :-)
*/
BOOL EjectVolume(wchar_t Letter,DWORD Flags)
{
	BOOL Retry=TRUE;
	BOOL fAutoEject=FALSE;
	DWORD temp;
	BOOL ReadOnly=FALSE;
	UINT uDriveType;
	DWORD dwAccessFlags;
	BOOL fRemoveSafely = FALSE;
	BOOL foundError=FALSE;
	wchar_t szRootName[8]=L"\\\\.\\ :\\";
	szRootName[4]=Letter;
	// OpenVolume
	uDriveType = FAR_GetDriveType(szRootName+4);
	szRootName[6]=0;

	switch (uDriveType)
	{
		case DRIVE_REMOVABLE:
			dwAccessFlags = GENERIC_READ | GENERIC_WRITE;
			break;
		default:

			if (IsDriveTypeCDROM(uDriveType))
			{
				dwAccessFlags = GENERIC_READ;
				break;
			}

			return FALSE;
	}

	File Disk;
	bool Opened = Disk.Open(szRootName, dwAccessFlags, FILE_SHARE_READ|FILE_SHARE_WRITE, nullptr, OPEN_EXISTING);
	if(!Opened && GetLastError()==ERROR_ACCESS_DENIED)
	{
		Opened = Disk.Open(szRootName,GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, nullptr, OPEN_EXISTING);
		ReadOnly=FALSE;
	}

	if (Opened)
	{
		while (Retry)
		{
			if (Disk.IoControl(FSCTL_LOCK_VOLUME, nullptr, 0, nullptr, 0, &temp))
			{
				foundError=FALSE;
				if (!ReadOnly)
				{
					Disk.FlushBuffers();
				}

#if 0

// TODO: ЭТОТ КУСОК НУЖНО РАСКОММЕНТИТЬ ВМЕСТЕ С ПОДЪЕМОМ ПРОЕКТА ПО USB
				/*
				  ЭТО чудо нужно для того, чтобы, скажем, имея картридер на 3 карточки,
				  дисмоунтить только 1 карточку, а не отключать все устройство!
				*/
				if (!(Flags&EJECT_LOAD_MEDIA))
				{
					if (DismountVolume(DiskHandle))
						fRemoveSafely = TRUE;
					else
						foundError=TRUE;
				}

#endif

				if (!foundError)
				{
					PREVENT_MEDIA_REMOVAL PreventMediaRemoval={FALSE};

					if (Disk.IoControl(IOCTL_STORAGE_MEDIA_REMOVAL, &PreventMediaRemoval, sizeof(PreventMediaRemoval), nullptr, 0, &temp))
					{
#if 1

						// чистой воды шаманство...
						if (Flags&EJECT_READY)
						{
							fAutoEject=Disk.IoControl(IOCTL_STORAGE_CHECK_VERIFY, nullptr, 0, 0, 0, &temp);

							// ...если ошибка = "нет доступа", то это похоже на то,
							// что диск вставлен
							// Способ экспериментальный, потому афишировать не имеет смысла.
							if (!fAutoEject && GetLastError() == ERROR_ACCESS_DENIED)
								fAutoEject=TRUE;

							Retry=FALSE;
						}
						else
#endif
							fAutoEject=Disk.IoControl((Flags&EJECT_LOAD_MEDIA)?IOCTL_STORAGE_LOAD_MEDIA:IOCTL_STORAGE_EJECT_MEDIA, nullptr, 0, nullptr, 0, &temp);
					}

					Retry=FALSE;
				}
			}
			else
				foundError=TRUE;

			if (foundError)
			{
				if (!(Flags&EJECT_NO_MESSAGE))
				{
					string strMsgText;
					strMsgText.Format(MSG(MChangeCouldNotEjectMedia),Letter);

					if (Message(MSG_WARNING|MSG_ERRORTYPE,2,MSG(MError),strMsgText,MSG(MRetry),MSG(MCancel)))
						Retry=FALSE;
				}
				else
					Retry=FALSE;
			}
			else if (!(Flags&EJECT_LOAD_MEDIA) && fRemoveSafely)
			{
				//printf("Media in Drive %c can be safely removed.\n",cDriveLetter);
				//if(Flags&EJECT_NOTIFY_AFTERREMOVE)
				;
			}
		} // END: while(Retry)

		Disk.IoControl(FSCTL_UNLOCK_VOLUME, nullptr, 0, nullptr, 0, &temp);
		Disk.Close();
	}

	return fAutoEject||fRemoveSafely; //???
}
示例#3
0
	shared_ptr <VolumeInfo> CoreUnix::MountVolume (MountOptions &options)
	{
		CoalesceSlotNumberAndMountPoint (options);

		if (IsVolumeMounted (*options.Path))
			throw VolumeAlreadyMounted (SRC_POS);

		Cipher::EnableHwSupport (!options.NoHardwareCrypto);

		shared_ptr <Volume> volume;

		while (true)
		{
			try
			{
				volume = OpenVolume (
					options.Path,
					options.PreserveTimestamps,
					options.Password,
					options.Keyfiles,
					options.Protection,
					options.ProtectionPassword,
					options.ProtectionKeyfiles,
					options.SharedAccessAllowed,
					VolumeType::Unknown,
					options.UseBackupHeaders,
					options.PartitionInSystemEncryptionScope
					);

				options.Password.reset();
			}
			catch (SystemException &e)
			{
				if (options.Protection != VolumeProtection::ReadOnly
					&& (e.GetErrorCode() == EROFS || e.GetErrorCode() == EACCES || e.GetErrorCode() == EPERM))
				{
					// Read-only filesystem
					options.Protection = VolumeProtection::ReadOnly;
					continue;
				}

				throw;
			}

			break;
		}

		if (options.Path->IsDevice())
		{
			if (volume->GetFile()->GetDeviceSectorSize() != volume->GetSectorSize())
				throw ParameterIncorrect (SRC_POS);

#if defined (TC_LINUX)
			if (volume->GetSectorSize() != TC_SECTOR_SIZE_LEGACY)
			{
				if (options.Protection == VolumeProtection::HiddenVolumeReadOnly)
					throw UnsupportedSectorSizeHiddenVolumeProtection();

				if (options.NoKernelCrypto)
					throw UnsupportedSectorSizeNoKernelCrypto();
			}
#endif
		}

		// Find a free mount point for FUSE service
		MountedFilesystemList mountedFilesystems = GetMountedFilesystems ();
		string fuseMountPoint;
		for (int i = 1; true; i++)
		{
			stringstream path;
			path << GetTempDirectory() << "/" << GetFuseMountDirPrefix() << i;
			FilesystemPath fsPath (path.str());

			bool inUse = false;

			foreach_ref (const MountedFilesystem &mf, mountedFilesystems)
			{
				if (mf.MountPoint == path.str())
				{
					inUse = true;
					break;
				}
			}

			if (!inUse)
			{
				try
				{
					if (fsPath.IsDirectory())
						fsPath.Delete();

					throw_sys_sub_if (mkdir (path.str().c_str(), S_IRUSR | S_IXUSR) == -1, path.str());

					fuseMountPoint = fsPath;
					break;
				}
				catch (...)
				{
					if (i > 255)
						throw TemporaryDirectoryFailure (SRC_POS, StringConverter::ToWide (path.str()));
				}
			}
		}

		try
		{
			FuseService::Mount (volume, options.SlotNumber, fuseMountPoint);
		}
		catch (...)
		{
			try
			{
				DirectoryPath (fuseMountPoint).Delete();
			}
			catch (...) { }
			throw;
		}

		try
		{
			// Create a mount directory if a default path has been specified
			bool mountDirCreated = false;
			string mountPoint;
			if (!options.NoFilesystem && options.MountPoint)
			{
				mountPoint = *options.MountPoint;

#ifndef TC_MACOSX
				if (mountPoint.find (GetDefaultMountPointPrefix()) == 0 && !options.MountPoint->IsDirectory())
				{
					Directory::Create (*options.MountPoint);
					try
					{
						throw_sys_sub_if (chown (mountPoint.c_str(), GetRealUserId(), GetRealGroupId()) == -1, mountPoint);
					} catch (ParameterIncorrect&) { }

					mountDirCreated = true;
				}
#endif
			}

			try
			{
				try
				{
					MountVolumeNative (volume, options, fuseMountPoint);
				}
				catch (NotApplicable&)
				{
					MountAuxVolumeImage (fuseMountPoint, options);
				}
			}
			catch (...)
			{
				if (mountDirCreated)
					remove (mountPoint.c_str());
				throw;
			}
		}
		catch (...)
		{
			try
			{
				VolumeInfoList mountedVolumes = GetMountedVolumes (*options.Path);
				if (mountedVolumes.size() > 0)
				{
					shared_ptr <VolumeInfo> mountedVolume (mountedVolumes.front());
					DismountVolume (mountedVolume);
				}
			}
			catch (...) { }
			throw;
		}

		VolumeInfoList mountedVolumes = GetMountedVolumes (*options.Path);
		if (mountedVolumes.size() != 1)
			throw ParameterIncorrect (SRC_POS);

		VolumeEventArgs eventArgs (mountedVolumes.front());
		VolumeMountedEvent.Raise (eventArgs);

		return mountedVolumes.front();
	}
示例#4
0
文件: mfmt.c 项目: mingpen/OpenNT
DWORD
_cdecl
main(
    int argc,
    char *argv[],
    char *envp[]
    )
{
    char Drive[MAX_PATH];
    HANDLE hDrive, hDiskImage;
    DISK_GEOMETRY Geometry;
    UINT i;
    char c, *p;
    LPSTR DriveName;
    BOOL fUsage = TRUE;
    BOOL fShowGeometry = FALSE;
    BOOL fDiskImage = FALSE;
    BOOL SourceIsDrive;
    LPSTR Source, Destination, DiskImage;

    if ( argc > 1 ) {
        fUsage = FALSE;
        while (--argc) {
            p = *++argv;
            if (*p == '/' || *p == '-') {
                while (c = *++p)
                switch (toupper( c )) {
                case '?':
                    fUsage = TRUE;
                    break;

                case 'C':
                    fDiskImage = TRUE;
                    argc--, argv++;
                    Source = *argv;
                    argc--, argv++;
                    Destination = *argv;
                    break;

                case 'G':
                    fShowGeometry = TRUE;
                    argc--, argv++;
                    DriveName = *argv;
                    break;

                default:
                    printf("MFMT: Invalid switch - /%c\n", c );
                    fUsage = TRUE;
                    break;
                    }
                }
            }
        }

    if ( fUsage ) {
        printf("usage: MFMT switches \n" );
        printf("            [-?] display this message\n" );
        printf("            [-g drive] shows disk geometry\n" );
        printf("            [-c source destination] produce diskimage\n" );
        ExitProcess(1);
        }

    if ( fShowGeometry ) {
        sprintf(Drive,"\\\\.\\%s",DriveName);
        hDrive = CreateFile(
                    Drive,
                    GENERIC_READ | GENERIC_WRITE,
                    0,
                    NULL,
                    OPEN_EXISTING,
                    0,
                    NULL
                    );
        if ( hDrive == INVALID_HANDLE_VALUE ) {
            printf("MFMT: Open %s failed %d\n",DriveName,GetLastError());
            ExitProcess(1);
            }

        LockVolume(hDrive);

        if ( !GetDiskGeometry(hDrive,&Geometry) ) {
            printf("MFMT: GetDiskGeometry %s failed %d\n",DriveName,GetLastError());
            ExitProcess(1);
            }
        PrintGeometry(DriveName,&Geometry);

        if ( !GetSupportedGeometrys(hDrive) ) {
            printf("MFMT: GetSupportedGeometrys %s failed %d\n",DriveName,GetLastError());
            ExitProcess(1);
            }
        printf("\nDrive %s supports the following disk geometries\n",DriveName);

        for(i=0;i<SupportedGeometryCount;i++) {
            printf("\n");
            PrintGeometry(NULL,&SupportedGeometry[i]);
            }

        printf("\n");
        ExitProcess(0);
        }

    if ( fDiskImage ) {
        SourceIsDrive = FALSE;
        if ( Source[strlen(Source)-1] == ':' ) {
            SourceIsDrive = TRUE;
            sprintf(Drive,"\\\\.\\%s",Source);
            DiskImage = Destination;
            }
        if ( Destination[strlen(Destination)-1] == ':' ) {
            if ( SourceIsDrive ) {
                printf("MFMT: Source and Destination cannot both be drives\n");
                ExitProcess(1);
                }
            SourceIsDrive = FALSE;
            sprintf(Drive,"\\\\.\\%s",Destination);
            DiskImage = Source;
            }
        else {
            if ( !SourceIsDrive ) {
                printf("MFMT: Either Source or Destination must be a drive\n");
                ExitProcess(1);
                }
            }

        //
        // Open and Lock the drive
        //

        hDrive = CreateFile(
                    Drive,
                    GENERIC_READ | GENERIC_WRITE,
                    0,
                    NULL,
                    OPEN_EXISTING,
                    0,
                    NULL
                    );
        if ( hDrive == INVALID_HANDLE_VALUE ) {
            printf("MFMT: Open %s failed %d\n",DriveName,GetLastError());
            ExitProcess(1);
            }
        LockVolume(hDrive);

        if ( !GetDiskGeometry(hDrive,&Geometry) ) {
            printf("MFMT: GetDiskGeometry %s failed %d\n",DriveName,GetLastError());
            ExitProcess(1);
            }

        if ( !GetSupportedGeometrys(hDrive) ) {
            printf("MFMT: GetSupportedGeometrys %s failed %d\n",DriveName,GetLastError());
            ExitProcess(1);
            }

        //
        // Open the disk image file
        //

        hDiskImage = CreateFile(
                        DiskImage,
                        GENERIC_READ | GENERIC_WRITE,
                        0,
                        NULL,
                        SourceIsDrive ? CREATE_ALWAYS : OPEN_EXISTING,
                        0,
                        NULL
                        );
        if ( hDiskImage == INVALID_HANDLE_VALUE ) {
            printf("MFMT: Open %s failed %d\n",DiskImage,GetLastError());
            ExitProcess(1);
            }

        //
        // Now do the copy
        //
        {
            LPVOID IoBuffer;
            BOOL b;
            DWORD BytesRead, BytesWritten;
            DWORD FileSize;
            DWORD GeometrySize;

            //
            // If we are copying from floppy to file, just do the copy
            // Otherwise, we might have to format the floppy first
            //

            if ( SourceIsDrive ) {

                //
                // Device reads must be sector aligned. VirtualAlloc will
                // garuntee alignment
                //

                GeometrySize = Geometry.Cylinders.LowPart *
                               Geometry.TracksPerCylinder *
                               Geometry.SectorsPerTrack *
                               Geometry.BytesPerSector;

                IoBuffer = VirtualAlloc(NULL,GeometrySize,MEM_COMMIT,PAGE_READWRITE);

                if ( !IoBuffer ) {
                    printf("MFMT: Buffer Allocation Failed\n");
                    ExitProcess(1);
                    }

                b = ReadFile(hDrive,IoBuffer, GeometrySize, &BytesRead, NULL);
                if (b && BytesRead){
                    b = WriteFile(hDiskImage,IoBuffer, BytesRead, &BytesWritten, NULL);
                    if ( !b || ( BytesRead != BytesWritten ) ) {
                        printf("MFMT: Fatal Write Error %d\n",GetLastError());
                        ExitProcess(1);
                        }
                    }
                else {
                    printf("MFMT: Fatal Read Error %d\n",GetLastError());
                    ExitProcess(1);
                    }
                }
            else {

                //
                // Check to see if the image will fit on the floppy. If it
                // will, then LowLevelFormat the floppy and press on
                //

                FileSize = GetFileSize(hDiskImage,NULL);

                b = FALSE;
                for(i=0;i<SupportedGeometryCount;i++) {
                    GeometrySize = SupportedGeometry[i].Cylinders.LowPart *
                                   SupportedGeometry[i].TracksPerCylinder *
                                   SupportedGeometry[i].SectorsPerTrack *
                                   SupportedGeometry[i].BytesPerSector;
                    if ( GeometrySize >= FileSize ) {

                        IoBuffer = VirtualAlloc(NULL,GeometrySize,MEM_COMMIT,PAGE_READWRITE);

                        if ( !IoBuffer ) {
                            printf("MFMT: Buffer Allocation Failed\n");
                            ExitProcess(1);
                            }

                        //
                        // Format the floppy
                        //

                        LowLevelFormat(hDrive,&SupportedGeometry[i]);

                        b = ReadFile(hDiskImage,IoBuffer, GeometrySize, &BytesRead, NULL);
                        if (b && BytesRead){
                            b = WriteFile(hDrive,IoBuffer, BytesRead, &BytesWritten, NULL);
                            if ( !b || ( BytesRead != BytesWritten ) ) {
                                printf("MFMT: Fatal Write Error %d\n",GetLastError());
                                ExitProcess(1);
                                }
                            }
                        else {
                            printf("MFMT: Fatal Read Error %d\n",GetLastError());
                            ExitProcess(1);
                            }
                        b = TRUE;
                        break;
                        }
                    }

                if ( !b ) {
                    printf("MFMT: FileSize %d is not supported on drive %s\n",FileSize,DriveName);
                    ExitProcess(1);
                    }
                }
        }

        //
        // Dismounting forces the filesystem to re-evaluate the media id
        // and geometry. This is the same as popping the floppy in and out
        // of the disk drive
        //

        DismountVolume(hDrive);
        UnlockVolume(hDrive);

        ExitProcess(0);
        }
}