#include <windows.h>
#include <winioctl.h>
#include <tchar.h>
#include <stdio.h> // Prototypes BOOL EjectVolume(TCHAR cDriveLetter); HANDLE OpenVolume(TCHAR cDriveLetter);
BOOL LockVolume(HANDLE hVolume);
BOOL DismountVolume(HANDLE hVolume);
BOOL PreventRemovalOfVolume(HANDLE hVolume, BOOL fPrevent);
BOOL AutoEjectVolume(HANDLE hVolume);
BOOL CloseVolume(HANDLE hVolume); LPTSTR szVolumeFormat = TEXT("\\\\.\\%c:");
LPTSTR szRootFormat = TEXT("%c:\\");
LPTSTR szErrorFormat = TEXT("Error %d: %s\n"); void ReportError(LPTSTR szMsg)
{
_tprintf(szErrorFormat, GetLastError(), szMsg);
} HANDLE OpenVolume(TCHAR cDriveLetter)
{
HANDLE hVolume;
UINT uDriveType;
TCHAR szVolumeName[8];
TCHAR szRootName[5];
DWORD dwAccessFlags; wsprintf(szRootName, szRootFormat, cDriveLetter); uDriveType = GetDriveType(szRootName);
switch(uDriveType) {
case DRIVE_REMOVABLE:
dwAccessFlags = GENERIC_READ | GENERIC_WRITE;
break;
case DRIVE_CDROM:
dwAccessFlags = GENERIC_READ;
break;
default:
_tprintf(TEXT("Cannot eject. Drive type is incorrect.\n"));
return INVALID_HANDLE_VALUE;
} wsprintf(szVolumeName, szVolumeFormat, cDriveLetter); hVolume = CreateFile( szVolumeName,
dwAccessFlags,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL );
if (hVolume == INVALID_HANDLE_VALUE)
ReportError(TEXT("CreateFile")); return hVolume;
} BOOL CloseVolume(HANDLE hVolume)
{
return CloseHandle(hVolume);
} #define LOCK_TIMEOUT 10000 // 10 Seconds
#define LOCK_RETRIES 20 BOOL LockVolume(HANDLE hVolume)
{
DWORD dwBytesReturned;
DWORD dwSleepAmount;
int nTryCount; dwSleepAmount = LOCK_TIMEOUT / LOCK_RETRIES; // Do this in a loop until a timeout period has expired
for (nTryCount = 0; nTryCount < LOCK_RETRIES; nTryCount++) {
if (DeviceIoControl(hVolume,
FSCTL_LOCK_VOLUME,
NULL, 0,
NULL, 0,
&dwBytesReturned,
NULL))
return TRUE; Sleep(dwSleepAmount);
} return FALSE;
} BOOL DismountVolume(HANDLE hVolume)
{
DWORD dwBytesReturned; return DeviceIoControl( hVolume,
FSCTL_DISMOUNT_VOLUME,
NULL, 0,
NULL, 0,
&dwBytesReturned,
NULL);
} 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);
} AutoEjectVolume(HANDLE hVolume)
{
DWORD dwBytesReturned; return DeviceIoControl( hVolume,
IOCTL_STORAGE_EJECT_MEDIA,
NULL, 0,
NULL, 0,
&dwBytesReturned,
NULL);
} BOOL EjectVolume(TCHAR cDriveLetter)
{
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))
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;
} void Usage()
{
printf("Usage: Eject <drive letter>\n\n");
return ;
} void main(int argc, char * argv[])
{
if (argc != 2) {
Usage();
return ;
} if (!EjectVolume(argv[1][0]))
printf("Failure ejecting drive %c.\n", argv[1][0]); return ;
}
解决方案 »
- Inc(A, B) PK A := A + B
- 压缩并修复Access2003的代码怎么写?
- 关于打包问题
- 急,急,急,我想把dbchart的柱图有原来的6 个 改为10个 该咋弄呀?
- 如何在delphi中提高数据库访问的速度?
- 谁有软件验收文档和Ptt? 最少200分. 参考一下, 没写过. [email protected]
- delphi调用sql存储过程的问题
- TUDPSocket怎么用??
- 请问哪里能找到delphi的汉字生成拼音的代码?
- DEV控件的安装问题
- 请教:用Socket.SendBuf发送多个包,后面的包对方收不到怎么办?
- 用 TWebBrowser; 打开一个本地的ppt文件后,如何屏蔽它产生的右键菜单??
var
RootName, VolumeName: string;
AccessFlags: DWORD;
begin
RootName := ADrive + ':' + #134; // ADrive + ':\' kills the syntax highlighting
case GetDriveType(PChar(RootName)) of
DRIVE_REMOVABLE:
AccessFlags := GENERIC_READ or GENERIC_WRITE;
DRIVE_CDROM:
AccessFlags := GENERIC_READ;
else
Result := INVALID_HANDLE_VALUE;
exit;
end;
VolumeName := Format('\\.\%s:', [ADrive]);
Result := CreateFile(PChar(VolumeName), AccessFlags,
FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);
if Result = INVALID_HANDLE_VALUE then
RaiseLastWin32Error;
end;function LockVolume(AVolumeHandle: THandle): boolean;
const
LOCK_TIMEOUT = 10 * 1000; // 10 Seconds
LOCK_RETRIES = 20;
LOCK_SLEEP = LOCK_TIMEOUT div LOCK_RETRIES;// #define FSCTL_LOCK_VOLUME CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 6, METHOD_BUFFERED, FILE_ANY_ACCESS)
FSCTL_LOCK_VOLUME = (9 shl 16) or (0 shl 14) or (6 shl 2) or 0;
var
Retries: integer;
BytesReturned: Cardinal;
begin
for Retries := 1 to LOCK_RETRIES do begin
Result := DeviceIoControl(AVolumeHandle, FSCTL_LOCK_VOLUME, nil, 0,
nil, 0, BytesReturned, nil);
if Result then
break;
Sleep(LOCK_SLEEP);
end;
end;function DismountVolume(AVolumeHandle: THandle): boolean;
const
// #define FSCTL_DISMOUNT_VOLUME CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 8, METHOD_BUFFERED, FILE_ANY_ACCESS)
FSCTL_DISMOUNT_VOLUME = (9 shl 16) or (0 shl 14) or (8 shl 2) or 0;
var
BytesReturned: Cardinal;
begin
Result := DeviceIoControl(AVolumeHandle, FSCTL_DISMOUNT_VOLUME, nil, 0,
nil, 0, BytesReturned, nil);
if not Result then
RaiseLastWin32Error;
end;function PreventRemovalOfVolume(AVolumeHandle: THandle;
APreventRemoval: boolean): boolean;
const
// #define IOCTL_STORAGE_MEDIA_REMOVAL CTL_CODE(IOCTL_STORAGE_BASE, 0x0201, METHOD_BUFFERED, FILE_READ_ACCESS)
IOCTL_STORAGE_MEDIA_REMOVAL = ($2d shl 16) or (1 shl 14) or ($201 shl 2) or 0;
type
TPreventMediaRemoval = record
PreventMediaRemoval: BOOL;
end;
var
BytesReturned: Cardinal;
PMRBuffer: TPreventMediaRemoval;
begin
PMRBuffer.PreventMediaRemoval := APreventRemoval;
Result := DeviceIoControl(AVolumeHandle, IOCTL_STORAGE_MEDIA_REMOVAL,
@PMRBuffer, SizeOf(TPreventMediaRemoval), nil, 0, BytesReturned, nil);
if not Result then
RaiseLastWin32Error;
end;function AutoEjectVolume(AVolumeHandle: THandle): boolean;
const
// #define IOCTL_STORAGE_EJECT_MEDIA CTL_CODE(IOCTL_STORAGE_BASE, 0x0202, METHOD_BUFFERED, FILE_READ_ACCESS)
IOCTL_STORAGE_EJECT_MEDIA = ($2d shl 16) or (1 shl 14) or ($202 shl 2) or 0;
var
BytesReturned: Cardinal;
begin
Result := DeviceIoControl(AVolumeHandle, IOCTL_STORAGE_EJECT_MEDIA, nil, 0,
nil, 0, BytesReturned, nil);
if not Result then
RaiseLastWin32Error;
end;function EjectVolume(ADrive: char): boolean;
var
VolumeHandle: THandle;
begin
Result := FALSE;
// Open the volume
VolumeHandle := OpenVolume(ADrive);
if VolumeHandle = INVALID_HANDLE_VALUE then
exit;
try
// Lock and dismount the volume
if LockVolume(VolumeHandle) and DismountVolume(VolumeHandle) then begin
// Set prevent removal to false and eject the volume
if PreventRemovalOfVolume(VolumeHandle, FALSE) then
AutoEjectVolume(VolumeHandle);
end;
finally
// Close the volume so other processes can use the drive
CloseHandle(VolumeHandle);
end;
end;