1 ////////////////////////////////////////////////////////////////////
2 // Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine
3 // All rights reserved
4 // This file was released under the GPLv2 on June 2015.
5 ////////////////////////////////////////////////////////////////////
6
7 /// Initial drive selection from command line.
8 CHAR szDisc[4] = "";
9 BOOL bChanger = FALSE;
10
11 /// Return CD-RW device type
12 JS_DEVICE_TYPE
CheckCDType(PCHAR m_szFile,PCHAR VendorId)13 CheckCDType(
14 PCHAR m_szFile,
15 PCHAR VendorId
16 )
17 {
18 HANDLE hDevice;
19 CHAR szDeviceName[256];
20 CHAR ioBuf[4096];
21 ULONG RC;
22 BOOL DvdRW = false;
23 BOOL DvdpRW = false;
24 BOOL DvdRAM = false;
25 BOOL DvdpR = false;
26 BOOL DvdR = false;
27
28 bChanger = FALSE;
29
30 // Make string representing full path
31 sprintf(szDeviceName, "\\\\.\\%s", m_szFile);
32 if (szDeviceName[strlen(szDeviceName)-1] == '\\') szDeviceName[strlen(szDeviceName)-1] = '\0';
33
34 // Open device volume
35 hDevice = OpenOurVolume(szDeviceName);
36
37 if (hDevice == ((HANDLE)-1)) {
38 strcpy(VendorId,"");
39 return BUSY;
40 } else {
41
42 // Get our cdrw.sys signature
43 RC = UDFPhSendIOCTL(IOCTL_CDRW_GET_SIGNATURE,hDevice,
44 &ioBuf,sizeof(GET_SIGNATURE_USER_OUT),
45 &ioBuf,sizeof(GET_SIGNATURE_USER_OUT),FALSE,NULL);
46
47 if (RC == 1) {
48 // Get device information
49 RC = UDFPhSendIOCTL(IOCTL_CDRW_GET_DEVICE_INFO,hDevice,
50 &ioBuf,sizeof(GET_DEVICE_INFO_USER_OUT),
51 &ioBuf,sizeof(GET_DEVICE_INFO_USER_OUT),FALSE,NULL);
52 if (RC != 1) {
53 strcpy(VendorId,"Unknown Vendor");
54 } else {
55 if(((PGET_DEVICE_INFO_USER_OUT)&ioBuf)->Features & CDRW_FEATURE_CHANGER)
56 bChanger = TRUE;
57 strcpy(VendorId,(PCHAR)&(((PGET_DEVICE_INFO_USER_OUT)&ioBuf)->VendorId[0]));
58 if (((PGET_DEVICE_INFO_USER_OUT)&ioBuf)->Features & CDRW_FEATURE_GET_CFG) {
59 DvdRW = (((PGET_DEVICE_INFO_USER_OUT)&ioBuf)->Features2[0] >> PFNUM_DVDRW_RESTRICTED_OVERWRITE) & 1;
60 DvdRAM = (((PGET_DEVICE_INFO_USER_OUT)&ioBuf)->Features2[0] >> PFNUM_DVDRAM) & 1;
61 DvdpRW = (((PGET_DEVICE_INFO_USER_OUT)&ioBuf)->Features2[0] >> PFNUM_DVDpRW) & 1;
62 DvdR = (((PGET_DEVICE_INFO_USER_OUT)&ioBuf)->Features2[0] >> PFNUM_DVDR) & 1;
63 DvdpR = (((PGET_DEVICE_INFO_USER_OUT)&ioBuf)->Features2[0] >> PFNUM_DVDpR) & 1;
64 }
65 }
66
67 // Get device capabilities
68 RC = UDFPhSendIOCTL(IOCTL_CDRW_GET_CAPABILITIES,hDevice,
69 &ioBuf,sizeof(GET_CAPABILITIES_USER_OUT),
70 &ioBuf,sizeof(GET_CAPABILITIES_USER_OUT),FALSE,NULL);
71 if(RC != 1) {
72 CloseHandle(hDevice);
73 return OTHER;
74 }
75
76 // Check capabilities
77 if(((PGET_CAPABILITIES_USER_OUT)&ioBuf)->WriteCap & (DevCap_write_cd_r | DevCap_write_cd_rw | DevCap_write_dvd_ram | DevCap_write_dvd_r) ||
78 DvdRW || DvdpRW || DvdRAM) {
79
80 if (DvdRAM || ((PGET_CAPABILITIES_USER_OUT)&ioBuf)->WriteCap & DevCap_write_dvd_ram) {
81 CloseHandle(hDevice);
82 return DVDRAM;
83 }
84 /* if (DvdR) {
85 CloseHandle(hDevice);
86 return DVDR;
87 }*/
88 if (DvdRW) {
89 CloseHandle(hDevice);
90 return DVDRW;
91 }
92 if (DvdpRW) {
93 CloseHandle(hDevice);
94 return DVDPRW;
95 }
96 /* if (DvdpR) {
97 CloseHandle(hDevice);
98 return DVDPR;
99 }*/
100 if (((PGET_CAPABILITIES_USER_OUT)&ioBuf)->WriteCap & DevCap_write_dvd_r) {
101 CloseHandle(hDevice);
102 return DVDR;
103 }
104 if (((PGET_CAPABILITIES_USER_OUT)&ioBuf)->WriteCap & DevCap_write_cd_rw) {
105 CloseHandle(hDevice);
106 return CDRW;
107 }
108 if (((PGET_CAPABILITIES_USER_OUT)&ioBuf)->WriteCap & DevCap_write_cd_r) {
109 CloseHandle(hDevice);
110 return CDR;
111 }
112 }
113 else {
114 CloseHandle(hDevice);
115 return OTHER;
116 }
117 } else {
118 strcpy(VendorId,"Unknown Vendor");
119 }
120 CloseHandle(hDevice);
121 }
122
123 return OTHER;
124 } // end CheckCDType()
125
126 /** Intialize asbtract device list via calls to CallBack function.
127 \param hDlg Not used.
128 \param hwndControl Passed to the CallBack function. See #PADD_DEVICE.
129 \param CallBack Callback function. Called on each CD device in system.
130 */
131 void
InitDeviceList(HWND hDlg,HWND hwndControl,PADD_DEVICE CallBack)132 InitDeviceList(
133 HWND hDlg,
134 HWND hwndControl,
135 PADD_DEVICE CallBack
136 )
137 {
138 char Buffer[MAX_PATH] = "";
139 char VendorId[25];
140 char seps[] = ",";
141 char* token;
142 char info[MAX_PATH];
143 bool add_drive = false;
144
145 JS_DEVICE_TYPE drive_type;
146
147 // Get all device letter in system
148 GetLogicalDriveStrings((DWORD)MAX_PATH,(LPTSTR)&Buffer);
149 token = (char *)&Buffer;
150 // Replace all zeroes with comma.
151 while (token != NULL) {
152 token = (char *)memchr(Buffer,'\0',MAX_PATH);
153 if (token) {
154 if (*(token-1) == ',') {
155 token = NULL;
156 } else {
157 *token=',';
158 }
159 }
160 }
161 // Parse string of drive letters separated by comma
162 token = strtok((char *)&Buffer,seps);
163 while (token != NULL) {
164 add_drive = false;
165 switch (GetDriveType(token)) {
166 /*
167 case DRIVE_FIXED:
168 add_drive = true;
169 break;
170 */
171 case DRIVE_CDROM:
172 // Determine CD/DVD-ROM type (R,RW,RAM,other)
173 drive_type = CheckCDType(token,&VendorId[0]);
174 add_drive = true;
175 break;
176 }
177 if (add_drive) {
178
179 // Append to drive letter VendorId
180 strncpy(info,token,strlen(token)-1);
181 info[strlen(token)-1]='\0';
182 strcat(info," ");
183 strcat(info,VendorId);
184
185 BOOL bSelect = !strcmp(strupr(szDisc),strupr(token));
186 if (drive_type != OTHER) {
187 CallBack(hwndControl,token,info,MediaTypeStrings[drive_type],bSelect);
188 } else {
189 CallBack(hwndControl,token,info,"[Unsupported]",FALSE);
190 }
191
192 }
193 // Move to the next drive letter in string
194 token = strtok(NULL,seps);
195 }
196 } // end InitDeviceList()
197
198 HANDLE
FmtAcquireDrive_(PCHAR _Drive,CHAR Level)199 FmtAcquireDrive_(
200 PCHAR _Drive,
201 CHAR Level
202 )
203 {
204 WCHAR LockName[32];
205 HANDLE evt;
206
207 WCHAR Drive[1];
208 Drive[0] = _Drive[0] & ~('a' ^ 'A');
209
210 swprintf(LockName, L"DwFmtLock_%1.1S%d", Drive, Level);
211 evt = CreatePublicEvent(LockName);
212 if(!evt) {
213 return NULL;
214 }
215 if(GetLastError() == ERROR_ALREADY_EXISTS) {
216 CloseHandle(evt);
217 return INVALID_HANDLE_VALUE;
218 }
219 return evt;
220 } // end FmtAcquireDrive_()
221
222 HANDLE
FmtAcquireDrive(PCHAR Drive,CHAR Level)223 FmtAcquireDrive(
224 PCHAR Drive,
225 CHAR Level
226 )
227 {
228 HANDLE evt;
229
230 evt = FmtAcquireDrive_(Drive, Level);
231 if(!evt || evt == INVALID_HANDLE_VALUE) {
232 return NULL;
233 }
234 return evt;
235 } // end FmtAcquireDrive()
236
237 BOOLEAN
FmtIsDriveAcquired(PCHAR Drive,CHAR Level)238 FmtIsDriveAcquired(
239 PCHAR Drive,
240 CHAR Level
241 )
242 {
243 HANDLE evt;
244
245 evt = FmtAcquireDrive_(Drive, Level);
246 if(evt == INVALID_HANDLE_VALUE) {
247 return TRUE;
248 }
249 if(evt) {
250 CloseHandle(evt);
251 }
252 return FALSE;
253 } // end FmtIsDriveAcquired()
254
255 VOID
FmtReleaseDrive(HANDLE evt)256 FmtReleaseDrive(
257 HANDLE evt
258 )
259 {
260 if(evt) {
261 CloseHandle(evt);
262 }
263 } // end FmtReleaseDrive()
264