ENGLISH page is here.
GET DinopSearchBar
サイト内検索:
HOME
VC++ TIPS
ダウンロード
DinopExifReader
DinopSearchBar
DinopSearchBar mini
DinopTabbingBar
for Firefox
大阪湾の生き物
甲子園浜の自然
甲子園浜の干潟
甲子園浜の水中
甲子園浜の野鳥
近畿の山々
植物図鑑
箕面マップ
水中機材
カメラ
ランキング
望遠鏡の世界
顕微鏡の世界
Googleのすべて
GoogleマップAPI
ニュース
読んだ本
日記
変な料理の作り方
遺伝子操作
論文紹介
デイトレード
自動売買でFX
ネットで小遣い稼ぎ
Solaris
電子工作
その他
問い合わせ
VC++用コード集
大阪湾の生き物
水中用機材
since:2000/11/15
dinopcom@gmail.com
www.dinop.comは
だいのっぷ・どっと・こむ
と読んでください。







« CD-ROMのイジェクト(OS自動判別) | メイン | ユニコードからUTF8への変換 »

CD-ROMのイジェクト(WinNT/2000)




解説

 メディアのイジェクトはCreateFileとDeviceIoControlのIOCTL_STORAGE_EJECT_MEDIAを使う ことで、以下のように簡単に実現できる(この例ではFドライブをイジェクトしている)


	HANDLE	hDrive;
	DWORD	dw;

	hDrive = ::CreateFile("\\\\.\\F:",GENERIC_READ | GENERIC_WRITE
					,FILE_SHARE_READ | FILE_SHARE_WRITE,NULL
					,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
	::DeviceIoControl(hDrive,IOCTL_STORAGE_EJECT_MEDIA,NULL,NULL,NULL,NULL,&dw,NULL);


 しかし単純に上のやり方ではメディアが壊れる(ことがあるらしい)。そのためMicrosoftは イジェクト前にボリュームのロックなどの手順を踏むことを推奨している。



使用例


	CDnpMediaEjectNt	cEject;

	cEject.EjectVolume(_T('F'));



ソースコード


//
//	メディアのイジェクト(NT系用)
//
//	Windows NT/2000/XP系は以下のURLを参照
//		http://support.microsoft.com/kb/q165721/
//
class	CDnpMediaEjectNt
{
protected:

	//
	//	失敗時はINVALID_HANDLE_VALUE(-1)を返す
	//
	HANDLE OpenVolume(TCHAR cDriveLetter)
	{
		UINT	uDriveType;
		TCHAR	szVolumeName[8];
		TCHAR	szRootName[5];
		DWORD	dwAccessFlags;

		wsprintf(szRootName,_T("%c:\\"),cDriveLetter);

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

		case DRIVE_CDROM:
			dwAccessFlags = GENERIC_READ;
			break;

		default:
			return INVALID_HANDLE_VALUE;
		}

		wsprintf(szVolumeName,_T("\\\\.\\%c:"),cDriveLetter);

		return	::CreateFile(szVolumeName,dwAccessFlags,FILE_SHARE_READ | FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);
	}



	bool	CloseVolume(HANDLE hVolume)
	{
		return ::CloseHandle(hVolume) ? true : false;
	}



	bool	LockVolume(HANDLE hVolume,DWORD dwTimeout)
	{
		DWORD	dwBytesReturned;
		DWORD	dwStart;

		dwStart = ::GetTickCount();
		while(1)
		{
			if(::DeviceIoControl(hVolume,FSCTL_LOCK_VOLUME,NULL,0,NULL,0,&dwBytesReturned,NULL))
				return true;

			if(::GetTickCount() - dwStart > dwTimeout)
				return	false;

			::Sleep(20);
		}

		return false;
	}



	bool	DismountVolume(HANDLE hVolume)
	{
		DWORD dwBytesReturned;

		return	::DeviceIoControl(hVolume,FSCTL_DISMOUNT_VOLUME,NULL,0,NULL,0,&dwBytesReturned,NULL) ? true : false;
	}


	bool	PreventRemovalOfVolume(HANDLE hVolume,BOOL fPreventRemoval)
	{
		DWORD	dwBytesReturned;
		PREVENT_MEDIA_REMOVAL	PMRBuffer;

		PMRBuffer.PreventMediaRemoval = fPreventRemoval;

		return	::DeviceIoControl(hVolume,IOCTL_STORAGE_MEDIA_REMOVAL,&PMRBuffer, sizeof(PREVENT_MEDIA_REMOVAL),NULL, 0,&dwBytesReturned,NULL) ? true : false;
	}


	bool	AutoEjectVolume(HANDLE hVolume)
	{
		DWORD dwBytesReturned;

		return	::DeviceIoControl( hVolume,IOCTL_STORAGE_EJECT_MEDIA,NULL, 0,NULL, 0,&dwBytesReturned,NULL) ? true : false;
	}

public:


	bool	EjectVolume(TCHAR cDriveLetter,DWORD dwTimeouts)
	{
		bool	ret;
		HANDLE	hVolume;

		hVolume = OpenVolume(cDriveLetter);
		if(hVolume == INVALID_HANDLE_VALUE)
			return false;

		ret = LockVolume(hVolume,dwTimeouts);
		if(ret)
			ret = DismountVolume(hVolume);
		if(ret)
			ret = PreventRemovalOfVolume(hVolume,FALSE);
		if(ret)
			ret = AutoEjectVolume(hVolume);

		if(!CloseVolume(hVolume))
			return false;

		return	ret;
	}
};











Copyright (c) 1999-2007 issei. All rights reserved. (運営者情報