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