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 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 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 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 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 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 256 FmtReleaseDrive( 257 HANDLE evt 258 ) 259 { 260 if(evt) { 261 CloseHandle(evt); 262 } 263 } // end FmtReleaseDrive() 264