ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/Windows/cdenable/eject_nt.cpp
Revision: 1.4
Committed: 2008-01-01T09:40:34Z (16 years, 10 months ago) by gbeauche
Branch: MAIN
CVS Tags: HEAD
Changes since 1.3: +1 -1 lines
Log Message:
Happy New Year!

File Contents

# Content
1 /*
2 * eject_nt.cpp - cd eject routines for WinNT (derived from MS samples)
3 *
4 * Basilisk II (C) 1997-2008 Christian Bauer
5 *
6 * Windows platform specific code copyright (C) Lauri Pesonen
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23 #include "sysdeps.h"
24
25 #include "windows.h"
26 #include <winioctl.h>
27
28 // Prototypes
29
30 extern "C" {
31
32 #include "eject_nt.h"
33
34 LPTSTR szVolumeFormat = TEXT("\\\\.\\%c:");
35 LPTSTR szRootFormat = TEXT("%c:\\");
36 LPTSTR szErrorFormat = TEXT("Error %d: %s\n");
37
38 void ReportError(LPTSTR szMsg)
39 {
40 // _tprintf(szErrorFormat, GetLastError(), szMsg);
41 }
42
43 HANDLE OpenVolume(TCHAR cDriveLetter)
44 {
45 HANDLE hVolume;
46 UINT uDriveType;
47 TCHAR szVolumeName[8];
48 TCHAR szRootName[5];
49 DWORD dwAccessFlags;
50
51 wsprintf(szRootName, szRootFormat, cDriveLetter);
52
53 uDriveType = GetDriveType(szRootName);
54 switch(uDriveType) {
55 case DRIVE_REMOVABLE:
56 dwAccessFlags = GENERIC_READ | GENERIC_WRITE;
57 break;
58 case DRIVE_CDROM:
59 dwAccessFlags = GENERIC_READ;
60 break;
61 default:
62 // _tprintf(TEXT("Cannot eject. Drive type is incorrect.\n"));
63 return INVALID_HANDLE_VALUE;
64 }
65
66 wsprintf(szVolumeName, szVolumeFormat, cDriveLetter);
67
68 hVolume = CreateFile( szVolumeName,
69 dwAccessFlags,
70 FILE_SHARE_READ | FILE_SHARE_WRITE,
71 NULL,
72 OPEN_EXISTING,
73 0,
74 NULL );
75 if (hVolume == INVALID_HANDLE_VALUE)
76 ReportError(TEXT("CreateFile"));
77
78 return hVolume;
79 }
80
81 BOOL CloseVolume(HANDLE hVolume)
82 {
83 return CloseHandle(hVolume);
84 }
85
86 #define LOCK_TIMEOUT 1000 // 1 second
87 #define LOCK_RETRIES 20
88
89 BOOL LockVolume(HANDLE hVolume)
90 {
91 DWORD dwBytesReturned;
92 DWORD dwSleepAmount;
93 int nTryCount;
94
95 dwSleepAmount = LOCK_TIMEOUT / LOCK_RETRIES;
96
97 // Do this in a loop until a timeout period has expired
98 for (nTryCount = 0; nTryCount < LOCK_RETRIES; nTryCount++) {
99 if (DeviceIoControl(hVolume,
100 FSCTL_LOCK_VOLUME,
101 NULL, 0,
102 NULL, 0,
103 &dwBytesReturned,
104 NULL))
105 return TRUE;
106
107 Sleep(dwSleepAmount);
108 }
109
110 return FALSE;
111 }
112
113 BOOL DismountVolume(HANDLE hVolume)
114 {
115 DWORD dwBytesReturned;
116
117 return DeviceIoControl( hVolume,
118 FSCTL_DISMOUNT_VOLUME,
119 NULL, 0,
120 NULL, 0,
121 &dwBytesReturned,
122 NULL);
123 }
124
125 BOOL PreventRemovalOfVolume(HANDLE hVolume, BOOL fPreventRemoval)
126 {
127 DWORD dwBytesReturned;
128 PREVENT_MEDIA_REMOVAL PMRBuffer;
129
130 PMRBuffer.PreventMediaRemoval = fPreventRemoval;
131
132 return DeviceIoControl( hVolume,
133 IOCTL_STORAGE_MEDIA_REMOVAL,
134 &PMRBuffer, sizeof(PREVENT_MEDIA_REMOVAL),
135 NULL, 0,
136 &dwBytesReturned,
137 NULL);
138 }
139
140 BOOL AutoEjectVolume( HANDLE hVolume, BOOL reload )
141 {
142 DWORD dwBytesReturned;
143
144 return DeviceIoControl( hVolume,
145 reload ? IOCTL_STORAGE_LOAD_MEDIA : IOCTL_STORAGE_EJECT_MEDIA,
146 NULL, 0,
147 NULL, 0,
148 &dwBytesReturned,
149 NULL);
150 }
151
152 BOOL EjectVolume( TCHAR cDriveLetter, BOOL reload )
153 {
154 HANDLE hVolume;
155
156 BOOL fRemoveSafely = FALSE;
157 BOOL fAutoEject = FALSE;
158
159 // Open the volume.
160 hVolume = OpenVolume(cDriveLetter);
161 if (hVolume == INVALID_HANDLE_VALUE)
162 return FALSE;
163
164 // Lock and dismount the volume.
165 if (LockVolume(hVolume) && DismountVolume(hVolume)) {
166 fRemoveSafely = TRUE;
167
168 // Set prevent removal to false and eject the volume.
169 if (PreventRemovalOfVolume(hVolume, FALSE) &&
170 AutoEjectVolume(hVolume,reload))
171 fAutoEject = TRUE;
172 }
173
174 // Close the volume so other processes can use the drive.
175 if (!CloseVolume(hVolume))
176 return FALSE;
177
178 /*
179 if (fAutoEject)
180 printf("Media in Drive %c has been ejected safely.\n", cDriveLetter);
181 else {
182 if (fRemoveSafely)
183 printf("Media in Drive %c can be safely removed.\n", cDriveLetter);
184 }
185 */
186
187 return TRUE;
188 }
189
190 } // extern "C"